Conversation
The scaffolded app didn't run: the "custom" memory backend was a stub whose getState/saveState threw "not implemented", so `npm run dev` crashed with `getState(<app>) not implemented`. The render stack was also hardcoded to "my-app" instead of the project name. - custom backend is now a runnable in-memory skeleton with TODOs (never throws), so every backend produces an app that runs out of the box. - the render stack name is the project directory name. - the counter logs `0` immediately instead of a brief `undefined`. Also scaffold a real test so new apps start with one: - index.test.ts uses @creact-labs/testing (renderTest/findNode/readOutput) to render the counter in isolation and assert its output — no process, no timers. - vitest.config.ts wires CReact's JSX runtime and inlines the @creact-labs packages (their published ESM uses extensionless imports, which Node's strict resolver rejects but Vite's fills in). - package.json gains a `test` script plus @creact-labs/testing and vitest. - Counter is exported so the test can render it. Verified end to end: scaffold → npm install → npm test passes for the file, sqlite, and custom backends. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace the typed readline prompt ("file, sqlite, memory, or custom?") with a
create-vite-style TUI built on @clack/prompts: an intro banner, a project-name
text prompt, and an arrow-key select for the memory backend (each option with a
one-line hint), colored via picocolors, with a Next-steps note and outro. Ctrl+C
cancels cleanly.
The interactive flow only runs on a TTY; passing a directory and/or --memory, or
running non-interactively, skips the prompts and keeps the old behaviour (so
`npm create creact-app my-app --memory=file` and CI stay non-interactive).
Bump to 0.1.0 for the new TUI + scaffolded tests.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…mports The published dist used extensionless relative imports (creact even mixed styles — the bin's cli.ts wrote "./cli-main.js" while the library wrote "./flow/error-boundary"), so Node's ESM resolver rejected @creact-labs/creact and @creact-labs/testing when loaded natively: vitest/node consumers got `Cannot find module .../flow/error-boundary`. It only worked through the creact CLI's esbuild loader — which is why the scaffolded app's test exposed it. Source now has no .js extensions anywhere; the build re-adds them: - creact, testing, and create-creact-app build with `tsc(-b) && tsc-alias --resolve-full-paths`, so dist has fully-resolved `.js` imports (valid Node ESM) while source stays extensionless. - drop the stray "./cli-main.js"-style extensions from creact's CLI cluster and create-creact-app's source, and from the scaffolded templates. - bump @creact-labs/creact 0.4.1 and @creact-labs/testing 0.1.1; the scaffold depends on the fixed versions and no longer needs the vitest deps.inline workaround. Verified: scaffold -> install the packed 0.4.1/0.1.1 -> `npm test` passes with a plain vitest config (no inline) and the app runs; 654/12/26 package tests green; zero extensionless imports remain in any dist. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
publint checks packaging metadata but not how a consumer resolves the types and runtime — it passed clean on the extensionless-import bug that broke every ESM consumer. arethetypeswrong catches exactly that; its esm-only profile fits these `type: module` packages (ignoring the expected "CJS must dynamic-import" and legacy-node10 notes). Run it alongside publint in the shared publish/verify script, so the same resolution check runs on every PR and at release. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… TTY @clack/prompts reads keystrokes from stdin but draws to stdout, so keying off process.stdin.isTTY alone could spill prompt/control output into a piped stdout. Require both streams to be a TTY before going interactive. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
testing's `tsc -b` builds packages/creact via plain tsc (not creact's build script), so the previous single tsc-alias pass rewrote only testing's dist and left the creact dist it produced with extensionless ESM imports. Run tsc-alias against creact's tsconfig as well, so a standalone `npm run build -w @creact-labs/testing` emits valid ESM for both packages. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
feat(create-creact-app): interactive TUI + tests; fix ESM (no .js in source, extensioned dist)
📝 WalkthroughWalkthroughBuild and package metadata now support full-path alias resolution and extensionless ESM imports. The scaffolding CLI adds TTY-aware prompts, Vitest-based generated projects, runnable custom memory templates, and updated package metadata. Publishing also validates ESM type resolution. ChangesPackaging and scaffolding
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant User
participant main
participant clack
participant scaffold
main->>main: Detect interactive terminal
main->>clack: Request directory and memory backend
User->>clack: Select values or cancel
clack-->>main: Return selection or cancellation
main->>scaffold: Scaffold project with resolved options
scaffold-->>main: Return generated files
main->>clack: Display completion or cancellation
Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
🤖 Grok fallow review — proceedClean fallow report: no dead code, duplication, threshold breaches, audit metrics, or advisories. Release may proceed.
Reviews the full fallow report — dead code, duplication, health, and audit. Re-runs edit this comment. |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
.github/scripts/publish-packages.sh (1)
101-101: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winPin
publintfor deterministic release validation.The new ATW command is exact-pinned, but
npx --yes publint "$dir"leaves the other release gate without a declared version. Use a lockfile-backed dependency or pinpublintto an approved version so PR and release runs cannot silently use different validator behavior.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/scripts/publish-packages.sh at line 101, Update the publint invocation in the release validation flow to use a deterministic, approved version, either by pinning the package version in the npx command or reusing a lockfile-backed dependency. Keep the existing "$dir" validation target and command behavior unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/scripts/publish-packages.sh:
- Around line 96-102: Add a Node ESM smoke-test step in the publish flow before
publishing, alongside the existing publint and attw checks. For each package
directory represented by dir, identify and import every packed public entrypoint
using Node’s ESM loader, ensuring extensionless or otherwise invalid runtime
imports fail the gate; keep the existing publint and `@arethetypeswrong` checks
intact.
---
Nitpick comments:
In @.github/scripts/publish-packages.sh:
- Line 101: Update the publint invocation in the release validation flow to use
a deterministic, approved version, either by pinning the package version in the
npx command or reusing a lockfile-backed dependency. Keep the existing "$dir"
validation target and command behavior unchanged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: e18d584f-0506-4429-ad5f-0cbe606953b6
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (16)
.github/scripts/publish-packages.shpackages/creact/package.jsonpackages/creact/src/__tests__/cli-logger.test.tspackages/creact/src/__tests__/cli-main.test.tspackages/creact/src/__tests__/cli-typecheck.test.tspackages/creact/src/cli-logger.tspackages/creact/src/cli-main.tspackages/creact/src/cli.tspackages/create-creact-app/package.jsonpackages/create-creact-app/src/__tests__/cli-entry.test.tspackages/create-creact-app/src/__tests__/scaffold.test.tspackages/create-creact-app/src/__tests__/templates.test.tspackages/create-creact-app/src/cli.tspackages/create-creact-app/src/index.tspackages/create-creact-app/src/templates.tspackages/testing/package.json
| # - arethetypeswrong: how a consumer actually RESOLVES the types/runtime. | ||
| # The esm-only profile fits these `type: module` packages (it ignores the | ||
| # expected "CJS must dynamic-import" and legacy-node10 notes). This is the | ||
| # check that catches extensionless-import / resolution breaks — the class | ||
| # of bug that shipped in 0.4.0 and broke every ESM consumer. | ||
| npx --yes publint "$dir" | ||
| npx --yes @arethetypeswrong/cli@0.18.5 --pack "$dir" --profile esm-only |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift
🧩 Analysis chain
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
tmp="$(mktemp -d)"
trap 'rm -rf "$tmp"' EXIT
cat >"$tmp/package.json" <<'EOF'
{"name":"attw-extensionless-fixture","version":"1.0.0","type":"module","exports":{".":{"types":"./index.d.ts","import":"./index.js"}}}
EOF
printf 'export const value = 1;\n' >"$tmp/dep.js"
printf 'export { value } from "./dep";\n' >"$tmp/index.js"
printf 'export declare const value: 1;\n' >"$tmp/index.d.ts"
set +e
npx --yes `@arethetypeswrong/cli`@0.18.5 --pack "$tmp" --profile esm-only
attw_status=$?
(cd "$tmp" && node --input-type=module -e 'import("./index.js")')
node_status=$?
set -e
printf 'attw=%s node=%s\n' "$attw_status" "$node_status"Repository: creact-labs/creact
Length of output: 2441
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
file=".github/scripts/publish-packages.sh"
wc -l "$file"
sed -n '70,120p' "$file" | cat -nRepository: creact-labs/creact
Length of output: 2837
Add a Node ESM smoke test before publishing. attw --profile esm-only does not execute the packed JS, so extensionless relative imports can still slip through and break consumers when Node loads the package. Import each packed public entrypoint under Node as part of the publish gate.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/scripts/publish-packages.sh around lines 96 - 102, Add a Node ESM
smoke-test step in the publish flow before publishing, alongside the existing
publint and attw checks. For each package directory represented by dir, identify
and import every packed public entrypoint using Node’s ESM loader, ensuring
extensionless or otherwise invalid runtime imports fail the gate; keep the
existing publint and `@arethetypeswrong` checks intact.
Source: MCP tools
Releases the create-creact-app rebuild and the ESM fix (PR #15). Merging pushes
develop → releaseand triggers the Release workflow, which reconciles each package independently.What this release publishes
@creact-labs/creact@creact-labs/testingcreate-creact-appEach publishes to npm + gets a
<name>@<version>tag and GitHub Release; already-released artifacts are skipped (idempotent, transient-error-safe).Highlights
.jsextensions anywhere;tsc-aliasemits fully-resolved.jsindist, so@creact-labs/creact/@creact-labs/testingfinally load under native Node ESM (vitest/node consumers). This is what broke the 0.4.0 scaffold.@clack/promptsarrow-key TUI (colors, no typing), every memory backend runs out of the box, andindex.test.tsships using@creact-labs/testing.arethetypeswrong(esm-only) runs alongside publint in the shared publish/verify script — the check that catches resolution breaks like 0.4.0, now on every PR and at release.Once published,
npm create creact-app@latestgives a working, tested app that runs with a plain vitest config (no workarounds).Summary by CodeRabbit
New Features
Bug Fixes
Chores