Skip to content

Make First Draft CLI checks shell-portable - #28

Merged
raghubetina merged 2 commits into
mainfrom
codex/portable-cli-probe-current-state-20260812
Aug 12, 2026
Merged

Make First Draft CLI checks shell-portable#28
raghubetina merged 2 commits into
mainfrom
codex/portable-cli-probe-current-state-20260812

Conversation

@raghubetina

Copy link
Copy Markdown
Contributor

Summary

  • make the Skill's CLI startup check portable across sh and zsh
  • prefer a project-owned ./bin/firstdraft wrapper in every operational block and packaged recovery reference
  • remove the ineffective Claude plugin userConfig credential bridge and prepare an unpublished 0.1.1 package identity
  • correct completed 0.1.0 rollout guidance without rewriting immutable release evidence

Why

On zsh, an unquoted scalar containing generate --help is passed as one argument. The previous synthesized probe loop therefore made a healthy CLI 0.1.0 report a top-level unknown command. Separately, Claude Code does not deliver plugin user configuration to an executable merely because its bin/ directory is on the Bash tool PATH.

Verification

  • npm run check — 64/64
  • exact CLI contract at d37d8b6775a0b97ce10bd651485bd308fed1dda2
  • deterministic 0.1.1 package SHA-256 800e9ebd63843c7c680810979c35ade37de31d5e203e89a75a09f80d3399d656
  • packed candidate exercised under both sh and zsh
  • strict Claude Code 2.1.226 plugin validation
  • prospective release-order reconciliation and npm audit
  • independent exact-tree review: no source commit/push blocker

Boundary

This PR does not publish or tag 0.1.1 and does not change the public marketplace catalog, which remains on immutable plugin 0.1.0. Package publication and catalog promotion require separate authorization and gates.

Release guidance still presented consumed package, staging, and
catalog mutations as future instructions. Mark the sequence as
historical so operators do not replay it, while preserving the
remaining public-install and v14 evidence gaps.
zsh does not split unquoted scalar values, so batching multiword
help probes made a healthy CLI look unavailable. Prefer a project
wrapper through self-contained resolver blocks, remove the ineffective
plugin configuration bridge, and prepare the 0.1.1 package identity.
@raghubetina
raghubetina merged commit 9dc5ca6 into main Aug 12, 2026
2 checks passed
@raghubetina
raghubetina deleted the codex/portable-cli-probe-current-state-20260812 branch August 12, 2026 18:31
@raghubetina

Copy link
Copy Markdown
Contributor Author

Post-merge review, hosted CI green. Three changes, each verified sensible. The portability fix addresses a
real zsh/sh divergence: zsh passes an unquoted scalar like generate --help as one word where sh
word-splits, so the synthesized probe made a healthy CLI report an unknown command; the check is now portable
across both. Preferring the project-owned ./bin/firstdraft wrapper in every operational block gives the
Skill one resolution path instead of PATH luck (and #29 then hardened the test that enforces it). Removing
the plugin userConfig credential bridge is honest deletion: Claude Code does not deliver plugin user
configuration to executables merely for being on the Bash tool PATH, so the bridge was dead weight implying a
capability that did not exist. Rollout-guidance corrections avoid rewriting immutable release evidence,
consistent with the repo's evidence rules. The unpublished 0.1.1 identity prepared here shipped via #31.

@raghubetina

Copy link
Copy Markdown
Contributor Author

The bug that motivated this PR is worth five minutes of any Rails developer's time, because it is the kind
that only bites when someone else runs your script.

In POSIX sh and bash, an unquoted variable undergoes word splitting: cmd $args with args="generate --help" runs cmd generate --help, three words. In zsh, it does not: the same line passes one word,
generate --help, spaces included, as a single argument. So a CLI health probe written and tested under sh
reported a top-level unknown command under zsh, on a perfectly healthy CLI. The machine was fine; the shell
dialect changed the parse. Fixes are boring and reliable: quote everything, use arrays for argument lists, or
pin the interpreter with a shebang instead of inheriting whatever shell the user lives in. macOS defaults to
zsh while most CI images default to bash, which is exactly how this class of bug escapes review.

The second change generalizes the same idea from shells to commands: every operational block now calls
./bin/firstdraft, a project-owned wrapper, instead of whatever firstdraft happens to be on PATH. Rails
developers know this as binstubs: bin/rails exists so you get this project's Rails, not a global one. One
resolution path, versioned with the repo, no environment roulette.

And the third is a deletion with a lesson of its own: a credential bridge that did not actually work was
removed rather than documented around. Code that implies a capability that does not exist is worse than
missing code, because someone will build on the implication.

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