Skip to content

feat(dev): just shell-real/shell-stub — toggle the brush confined shell#238

Merged
hartsock merged 1 commit into
mainfrom
feat/shell-toggle-recipes
Jun 9, 2026
Merged

feat(dev): just shell-real/shell-stub — toggle the brush confined shell#238
hartsock merged 1 commit into
mainfrom
feat/shell-toggle-recipes

Conversation

@hartsock

@hartsock hartsock commented Jun 9, 2026

Copy link
Copy Markdown
Member

What this PR does

Adds a dev-only lever to run the real Caveats-confined brush shell locally while main stays on the publishable stub (the feat/stub-shell branch, pending reubeno/brush#1184 — see #206 / #208). Today main returns "shell tool temporarily unavailable" for run_command/shell_run; this lets a developer flip to the real shell without disturbing the crates.io-publishable default.

  • just shell-real — repoints the [patch.crates-io] agent-bridle entries at agent-bridle main (the real brush shell). Dev-only; must not be committed.
  • just shell-stub — flips back to the publishable stub branch.
  • just shell-check — guard that fails if the real-shell override is present, so the dev patch can't reach main. Wired into the pre-push hook and mirrored inline in CI's lint job (PIPELINE PARITY).

Why a recipe, not a --features flag

crates.io forbids git dependencies in any form — even optional or feature-gated. The real shell requires the brush git fork, so it can't live in a publishable manifest at all. Toggling it swaps a dependency source ([patch] target), which a cargo feature cannot do. Hence the patch-swap recipe pair + guard.

Test plan

  • just shell-check passes on the stub tree.
  • just shell-real → guard correctly fails (branch = main detected).
  • just shell-stub restores Cargo.toml byte-for-byte (clean round-trip, no residual diff).
  • Guard mirrored in three parity locations: justfile, .githooks/pre-push, ci.yml lint job.
  • No Rust code touched — build/test/coverage unaffected.

Out of scope

  • Unifying agent-bridle's stub + real shell behind one feature on a single branch (cleaner upstream, but the crates.io git-dep ban still forces the source-swap on the publishing side — separate agent-bridle issue if wanted).
  • Any change to the default (stub) behavior or the publish chain.

Closes the "let me use bash while we wait for brush" gap noted on #206.

🤖 Generated with Claude Code

While the brush fork's CommandInterceptor is unpublishable (pending
reubeno/brush#1184), main stays on agent-bridle's `feat/stub-shell`
branch so the workspace publishes to crates.io — but that makes
run_command/shell_run return "shell temporarily unavailable". This adds
a dev-only lever to run the real Caveats-confined shell locally without
disturbing the publishable default.

- `just shell-real` — repoints the [patch.crates-io] agent-bridle entries
  at agent-bridle `main` (the real brush shell). DEV ONLY; not committable.
- `just shell-stub` — flips back to the publishable stub branch.
- `just shell-check` — guard that fails if the real-shell override is
  present, so the dev patch can't reach main.

A cargo `--features` flag can't express this: crates.io forbids git deps
in any form (even optional/feature-gated), so toggling the real shell
swaps a dependency *source*, not a feature — hence a patch-swap recipe.

The guard runs in the pre-push hook and is mirrored inline in CI's lint
job (PIPELINE PARITY). Verified: guard passes on the stub tree, fails
when flipped to `main`, and shell-stub restores Cargo.toml byte-for-byte.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@hartsock hartsock merged commit 4256a31 into main Jun 9, 2026
8 checks passed
hartsock added a commit that referenced this pull request Jun 9, 2026
…238 followup) (#240)

WHAT: The `shell-real` / `shell-stub` recipes used `sed -i -E 's|...\{ git...|'`,
which only works on GNU sed. On BSD/macOS sed they fail with
`RE error: invalid repetition count(s)`. Two portability bugs compound:

1. `sed -i` takes its backup-suffix as the *next argument* on BSD, so `-i -E`
   consumes `-E` as the suffix — the regex is then parsed in BRE mode, where
   `\{` is an interval operator. `\{ git` is not a valid `{n,m}` → the error.
2. Even in ERE, `\{` is the wrong way to match a literal brace portably.

Fix (both recipes + the mirrored `shell-check` grep, and the parity copy in
.github/workflows/ci.yml):
- Match the literal brace with `[{]` (a bracket expression — literal `{` in
  both GNU and BSD ERE, never an interval).
- Replace `sed -i` with a temp-file rewrite (`sed -E '...' f > f.tmp && mv`),
  sidestepping the GNU-vs-BSD `-i` suffix difference and keeping `-E` a real flag.

WHY: Developers on macOS could not toggle the agent-bridle confined-shell patch.
GNU-only sed slipped through because CI runs on Linux.

Verified on GNU sed: shell-real → shell-check fails (exit 1, real shell present)
→ shell-stub → shell-check passes; Cargo.toml round-trips with no residue. The
`[{]` + temp-file idioms are POSIX-portable, so the same recipes work on BSD sed.

HOOK/PIPELINE PARITY: the `shell-check` grep in the justfile and the
"agent-bridle stub guard" grep in .github/workflows/ci.yml are updated together.

Co-authored-by: hartsock <hartsock@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@hartsock hartsock deleted the feat/shell-toggle-recipes branch June 10, 2026 04:19
hartsock added a commit that referenced this pull request Jun 27, 2026
…ell (#238)

While the brush fork's CommandInterceptor is unpublishable (pending
reubeno/brush#1184), main stays on agent-bridle's `feat/stub-shell`
branch so the workspace publishes to crates.io — but that makes
run_command/shell_run return "shell temporarily unavailable". This adds
a dev-only lever to run the real Caveats-confined shell locally without
disturbing the publishable default.

- `just shell-real` — repoints the [patch.crates-io] agent-bridle entries
  at agent-bridle `main` (the real brush shell). DEV ONLY; not committable.
- `just shell-stub` — flips back to the publishable stub branch.
- `just shell-check` — guard that fails if the real-shell override is
  present, so the dev patch can't reach main.

A cargo `--features` flag can't express this: crates.io forbids git deps
in any form (even optional/feature-gated), so toggling the real shell
swaps a dependency *source*, not a feature — hence a patch-swap recipe.

The guard runs in the pre-push hook and is mirrored inline in CI's lint
job (PIPELINE PARITY). Verified: guard passes on the stub tree, fails
when flipped to `main`, and shell-stub restores Cargo.toml byte-for-byte.

Co-authored-by: hartsock <hartsock@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
hartsock added a commit that referenced this pull request Jun 27, 2026
…238 followup) (#240)

WHAT: The `shell-real` / `shell-stub` recipes used `sed -i -E 's|...\{ git...|'`,
which only works on GNU sed. On BSD/macOS sed they fail with
`RE error: invalid repetition count(s)`. Two portability bugs compound:

1. `sed -i` takes its backup-suffix as the *next argument* on BSD, so `-i -E`
   consumes `-E` as the suffix — the regex is then parsed in BRE mode, where
   `\{` is an interval operator. `\{ git` is not a valid `{n,m}` → the error.
2. Even in ERE, `\{` is the wrong way to match a literal brace portably.

Fix (both recipes + the mirrored `shell-check` grep, and the parity copy in
.github/workflows/ci.yml):
- Match the literal brace with `[{]` (a bracket expression — literal `{` in
  both GNU and BSD ERE, never an interval).
- Replace `sed -i` with a temp-file rewrite (`sed -E '...' f > f.tmp && mv`),
  sidestepping the GNU-vs-BSD `-i` suffix difference and keeping `-E` a real flag.

WHY: Developers on macOS could not toggle the agent-bridle confined-shell patch.
GNU-only sed slipped through because CI runs on Linux.

Verified on GNU sed: shell-real → shell-check fails (exit 1, real shell present)
→ shell-stub → shell-check passes; Cargo.toml round-trips with no residue. The
`[{]` + temp-file idioms are POSIX-portable, so the same recipes work on BSD sed.

HOOK/PIPELINE PARITY: the `shell-check` grep in the justfile and the
"agent-bridle stub guard" grep in .github/workflows/ci.yml are updated together.

Co-authored-by: hartsock <hartsock@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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