Skip to content

fix: restore packaged CLI startup#190

Merged
ian-pascoe merged 1 commit into
mainfrom
hotfix/package-cli-startup
Jul 2, 2026
Merged

fix: restore packaged CLI startup#190
ian-pascoe merged 1 commit into
mainfrom
hotfix/package-cli-startup

Conversation

@ian-pascoe

@ian-pascoe ian-pascoe commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Summary

The published Caplets CLI can start again after install. The Node bundles now leave jsonc-parser as a package dependency instead of embedding its UMD wrapper, which was looking for private ./impl/* files that are not present in the published dist.

This also covers the native OpenCode and Pi packages, which re-bundle core artifacts and could otherwise reintroduce the same startup failure. Build and release now run a packaged CLI smoke check so caplets --version fails the pipeline if startup regresses.

Validation

  • pnpm verify passed from the pre-push hook.
  • node packages/cli/dist/index.js --version printed 0.25.5 locally after the fix.
  • The rebuilt core, OpenCode, and Pi dist chunks import jsonc-parser as a package import instead of containing the failing ./impl/format require.

Compound Engineering
GPT--5

Summary by CodeRabbit

  • Bug Fixes
    • Fixed CLI startup so caplets --version works correctly in the built package.
    • Improved package validation during build and release to catch runtime issues earlier.
  • Chores
    • Updated versioning for several packages to patch releases.
    • Added runtime checks to build and release workflows for better package reliability.

@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: fd23b342-8aac-490e-82f9-c93768ef75ba

📥 Commits

Reviewing files that changed from the base of the PR and between 760ea73 and 3c2bd04.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (10)
  • .changeset/clever-needles-start.md
  • package.json
  • packages/core/package.json
  • packages/core/rolldown.config.ts
  • packages/core/test/telemetry-source-maps.test.ts
  • packages/opencode/package.json
  • packages/opencode/rolldown.config.ts
  • packages/pi/package.json
  • packages/pi/rolldown.config.ts
  • scripts/check-package-runtime.mjs

📝 Walkthrough

Walkthrough

This PR marks jsonc-parser as an external dependency in rolldown build configs for @caplets/core, @caplets/opencode, and @caplets/pi, adds it as a runtime dependency, introduces a new check-package-runtime.mjs script validating the built CLI's --version output, wires it into build/release scripts, updates a related test, and adds a changeset.

Changes

jsonc-parser externalization and CLI runtime validation

Layer / File(s) Summary
Externalize jsonc-parser dependency
packages/core/package.json, packages/core/rolldown.config.ts, packages/opencode/package.json, packages/opencode/rolldown.config.ts, packages/pi/package.json, packages/pi/rolldown.config.ts
Adds jsonc-parser (^3.3.1) as a dependency and marks it external in the Node build target's rolldown config for each package.
Add runtime package check script
scripts/check-package-runtime.mjs
New script spawns built CLI (packages/cli/dist/index.js) with --version, fails on non-zero exit, and validates the version output against a semver-like regex.
Wire check into build/release, update test, changeset
package.json, packages/core/test/telemetry-source-maps.test.ts, .changeset/clever-needles-start.md
build and release npm scripts now run the new runtime check; a telemetry test splits a combined assertion into two toContain checks; a changeset marks patch bumps and documents the fix.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

Poem

A parser once bundled too tight,
Now hops external, feeling light 🐇
The CLI checks its version with care,
"--version" whispered into the air,
Patch notes penned, the burrow's all right!

✨ 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 hotfix/package-cli-startup

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@ian-pascoe ian-pascoe merged commit 15e467e into main Jul 2, 2026
5 of 7 checks passed
@ian-pascoe ian-pascoe deleted the hotfix/package-cli-startup branch July 2, 2026 17:34
@greptile-apps

greptile-apps Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes the published Caplets CLI startup regression by externalizing jsonc-parser from all three Node bundles (core, opencode, pi) instead of embedding its UMD wrapper, which was resolving private ./impl/* paths absent from the published dist. A smoke-check script is added and wired into both build and release to catch this class of failure before publishing.

  • jsonc-parser is added to external in the rolldown configs for core, opencode, and pi, and added as a runtime dependency in each package.json so the package is available when Node resolves it at runtime.
  • scripts/check-package-runtime.mjs spawns the built CLI with --version and validates the output matches a semver pattern, failing the pipeline early if startup regresses.
  • The CLI's own rolldown config already externalizes @caplets/core, so no cascading re-bundling occurs; the fix at the core level is sufficient for the CLI.

Confidence Score: 4/5

Safe to merge — the fix correctly externalizes jsonc-parser across all affected bundles and the dependency is declared in every relevant package.json.

The core change is well-scoped and self-consistent: externalizing jsonc-parser in the rolldown configs, declaring it as a runtime dep, and the smoke check confirming the CLI starts correctly. The one rough edge is that spawn errors in the smoke-check script don't surface the underlying OS error message, which could slow down CI debugging if the CLI build step were ever skipped.

scripts/check-package-runtime.mjs — the spawn-error path could surface more diagnostic detail.

Important Files Changed

Filename Overview
scripts/check-package-runtime.mjs New smoke-check script that spawns the built CLI with --version and validates the output. Path calculation and version regex are correct; spawn errors are not surfaced in the error message.
packages/core/rolldown.config.ts Adds jsonc-parser to the external list for the Node bundle; the browser bundle entry correctly omits it since browser consumers bundle dependencies themselves.
packages/opencode/rolldown.config.ts Externalizes jsonc-parser consistently with the core and pi packages, preventing re-embedding of the UMD wrapper in the opencode bundle.
packages/pi/rolldown.config.ts Externalizes jsonc-parser consistently with the core and opencode packages.
package.json Wires the smoke-check script into both build and release pipelines so startup regressions fail CI before publishing.
packages/core/package.json Adds jsonc-parser as a runtime dependency, required now that the Node bundle emits it as an external import.
packages/core/test/telemetry-source-maps.test.ts Splits the release-script assertion into two toContain checks to accommodate the new smoke-check step inserted between turbo build and changeset publish; the test's actual guard (sentry scripts absent) is unchanged.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["pnpm build / pnpm release"] --> B["turbo build"]
    B --> C["core Node bundle\nexternal: jsonc-parser"]
    B --> D["opencode bundle\nexternal: jsonc-parser"]
    B --> E["pi bundle\nexternal: jsonc-parser"]
    B --> F["cli bundle\nexternal: @caplets/core"]
    C & D & E & F --> G["node scripts/check-package-runtime.mjs"]
    G --> H{"node packages/cli/dist/index.js --version"}
    H -- "exit 0 + semver output" --> I["✅ Smoke check passed"]
    H -- "exit ≠ 0 or bad output" --> J["❌ Pipeline fails"]
    I --> K["changeset publish\n(release only)"]
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    A["pnpm build / pnpm release"] --> B["turbo build"]
    B --> C["core Node bundle\nexternal: jsonc-parser"]
    B --> D["opencode bundle\nexternal: jsonc-parser"]
    B --> E["pi bundle\nexternal: jsonc-parser"]
    B --> F["cli bundle\nexternal: @caplets/core"]
    C & D & E & F --> G["node scripts/check-package-runtime.mjs"]
    G --> H{"node packages/cli/dist/index.js --version"}
    H -- "exit 0 + semver output" --> I["✅ Smoke check passed"]
    H -- "exit ≠ 0 or bad output" --> J["❌ Pipeline fails"]
    I --> K["changeset publish\n(release only)"]
Loading

Fix All in Codex

Reviews (1): Last reviewed commit: "fix: restore packaged CLI startup" | Re-trigger Greptile

Comment on lines +20 to +25
if (result.status !== 0) {
process.stderr.write("Built Caplets CLI failed to start with --version.\n");
if (result.stdout) process.stderr.write(result.stdout);
if (result.stderr) process.stderr.write(result.stderr);
process.exit(result.status ?? 1);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Spawn errors (e.g., ENOENT when packages/cli/dist/index.js doesn't exist because the CLI build step was skipped) are silently absorbed. result.error carries the OS-level message but is never written to stderr, so a "file not found" failure is indistinguishable from a CLI crash in CI logs.

Suggested change
if (result.status !== 0) {
process.stderr.write("Built Caplets CLI failed to start with --version.\n");
if (result.stdout) process.stderr.write(result.stdout);
if (result.stderr) process.stderr.write(result.stderr);
process.exit(result.status ?? 1);
}
if (result.error || result.status !== 0) {
process.stderr.write("Built Caplets CLI failed to start with --version.\n");
if (result.error) process.stderr.write(`${result.error.message}\n`);
if (result.stdout) process.stderr.write(result.stdout);
if (result.stderr) process.stderr.write(result.stderr);
process.exit(result.status ?? 1);
}

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Fix in Codex

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