Skip to content

release: creact 0.4.1 + testing 0.1.1 (ESM fix) + create-creact-app 0.1.0 (TUI) - #16

Merged
drn1996 merged 8 commits into
releasefrom
develop
Jul 21, 2026
Merged

release: creact 0.4.1 + testing 0.1.1 (ESM fix) + create-creact-app 0.1.0 (TUI)#16
drn1996 merged 8 commits into
releasefrom
develop

Conversation

@drn1996

@drn1996 drn1996 commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Releases the create-creact-app rebuild and the ESM fix (PR #15). Merging pushes develop → release and triggers the Release workflow, which reconciles each package independently.

What this release publishes

Package npm now → this release
@creact-labs/creact 0.4.0 0.4.1 — extensioned ESM (valid under native Node ESM)
@creact-labs/testing 0.1.0 0.1.1 — extensioned ESM
create-creact-app 0.0.1 0.1.0 — interactive TUI, runnable templates, generated test

Each publishes to npm + gets a <name>@<version> tag and GitHub Release; already-released artifacts are skipped (idempotent, transient-error-safe).

Highlights

  • ESM fix: source has no .js extensions anywhere; tsc-alias emits fully-resolved .js in dist, so @creact-labs/creact / @creact-labs/testing finally load under native Node ESM (vitest/node consumers). This is what broke the 0.4.0 scaffold.
  • create-creact-app 0.1.0: @clack/prompts arrow-key TUI (colors, no typing), every memory backend runs out of the box, and index.test.ts ships using @creact-labs/testing.
  • New gate: 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@latest gives a working, tested app that runs with a plain vitest config (no workarounds).

Summary by CodeRabbit

  • New Features

    • Added an interactive project setup experience with prompts for project location and memory backend.
    • Generated projects now include Vitest testing setup, sample tests, and testing instructions.
    • Custom memory storage scaffolding now provides a runnable in-memory example.
    • Generated projects use their selected project name in the render setup.
  • Bug Fixes

    • Improved package builds and module resolution for more reliable CLI and runtime behavior.
  • Chores

    • Updated package versions and strengthened publishing validation.

drn1996 and others added 7 commits July 21, 2026 02:29
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)
@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Build 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.

Changes

Packaging and scaffolding

Layer / File(s) Summary
Build and module resolution
.github/..., packages/creact/package.json, packages/creact/src/..., packages/create-creact-app/package.json, packages/testing/package.json
Package builds now run tsc-alias, package versions are updated, and CLI imports use extensionless module specifiers.
Interactive scaffolder flow
packages/create-creact-app/src/index.ts, packages/create-creact-app/src/cli.ts, packages/create-creact-app/src/__tests__/*
The CLI uses clack prompts, TTY-based defaults, cancellation handling, and separate interactive and non-interactive output paths.
Generated project templates and tests
packages/create-creact-app/src/templates.ts, packages/create-creact-app/src/__tests__/templates.test.ts
Generated projects now include Vitest setup, project-specific render names, exported Counter code, testing documentation, and runnable custom memory persistence.
Publish artifact validation
.github/scripts/publish-packages.sh
Package publishing retains publint and adds an esm-only AreTheTypesWrong validation step.

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
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 6.25% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the release versions and the main ESM and TUI changes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch develop

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown
Contributor

🤖 Grok fallow review — proceed

Clean fallow report: no dead code, duplication, threshold breaches, audit metrics, or advisories. Release may proceed.

  • HEALTH hotspots (non-gating): packages/create-creact-app/src/index.ts accelerating (84.6, 235 churn)
  • HEALTH hotspots (non-gating): packages/creact/src/runtime/instance.ts accelerating (66.0, 817 churn)
  • HEALTH hotspots (non-gating): packages/creact/src/reactive/tracking.ts accelerating (61.6, 702 churn)
  • HEALTH hotspots (non-gating): packages/creact/src/runtime/run.ts accelerating (55.0, 935 churn)
  • HEALTH hotspots (non-gating): packages/creact/src/reactive/owner.ts accelerating (51.9, 329 churn)
  • HEALTH hotspots (non-gating): packages/creact/src/reactive/signal.ts accelerating (49.9, 456 churn)
  • HEALTH hotspots (non-gating): packages/creact/src/reactive/array.ts accelerating (38.3, 921 churn)
  • HEALTH score 82 B with deductions from hotspots (-10), unit size (-4), coupling (-2.5), dead files (-1.6) — activity/structure signals, not gate defects

Reviews the full fallow report — dead code, duplication, health, and audit. Re-runs edit this comment.

@drn1996
drn1996 merged commit 7056b7e into release Jul 21, 2026
15 of 16 checks passed

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
.github/scripts/publish-packages.sh (1)

101-101: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Pin publint for 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 pin publint to 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

📥 Commits

Reviewing files that changed from the base of the PR and between 4de9d64 and 745aed6.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (16)
  • .github/scripts/publish-packages.sh
  • packages/creact/package.json
  • packages/creact/src/__tests__/cli-logger.test.ts
  • packages/creact/src/__tests__/cli-main.test.ts
  • packages/creact/src/__tests__/cli-typecheck.test.ts
  • packages/creact/src/cli-logger.ts
  • packages/creact/src/cli-main.ts
  • packages/creact/src/cli.ts
  • packages/create-creact-app/package.json
  • packages/create-creact-app/src/__tests__/cli-entry.test.ts
  • packages/create-creact-app/src/__tests__/scaffold.test.ts
  • packages/create-creact-app/src/__tests__/templates.test.ts
  • packages/create-creact-app/src/cli.ts
  • packages/create-creact-app/src/index.ts
  • packages/create-creact-app/src/templates.ts
  • packages/testing/package.json

Comment on lines +96 to +102
# - 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

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 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 -n

Repository: 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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant