Skip to content

feat(harness): add verified cline and cursor-agent crewmate adapters - #1104

Closed
adibirzu wants to merge 7 commits into
kunchenguid:mainfrom
adibirzu:local-adapters
Closed

adibirzu wants to merge 7 commits into
kunchenguid:mainfrom
adibirzu:local-adapters

Conversation

@adibirzu

@adibirzu adibirzu commented Jul 27, 2026 •

Copy link
Copy Markdown

Intent

Crewmate harness adapters for cline and cursor-agent (PR #1104), rebased onto upstream's pi-signed adapter: empirically verified launch templates, busy/idle signatures, interrupt/exit semantics, and backend idle-regex extensions, with 12-check suites per adapter. Goal: ship through the sanctioned pipeline so PR #1104 carries the no-mistakes signature and passes the Require-no-mistakes gate.

What Changed

  • Added crewmate adapters for Cline CLI 3.0.46 and Cursor CLI 2026.07 with empirically verified launch templates, busy/idle signatures, and interrupt/exit semantics: harness detection in bin/fm-harness.sh, launch templates and adapter allowlists in bin/fm-spawn.sh (including Cursor's workspace-trust gate predicates), and idle-regex extensions across the herdr, cmux, and orca backends.
  • Consolidated composer idle-placeholder and agent-glyph defaults into shared definitions in bin/fm-composer-lib.sh/bin/fm-tmux-lib.sh so all backends recognize the new adapters' idle composers (e.g. cline's "Ask anything..." and cursor's "→ Plan, search, build anything") instead of each backend carrying its own copies.
  • Added per-adapter behavior test suites (tests/fm-cline-harness.test.sh 12 checks, tests/fm-cursor-agent-harness.test.sh 14 checks) plus verification evidence docs under docs/verification/, and updated the harness-adapters SKILL.md and backend/configuration docs to register the new adapters.

Risk Assessment

✅ Low: The fix commit resolves all three round-1 warnings at the recommended shared boundary (fleet-wide idle/glyph defaults consumed by all four adapters, shared busy-default extension, and a kimi-pattern trust-gate readiness step that fails loudly), preserves the dead-shell safety rule with new test coverage, and leaves only informational nits and the honestly documented live end-to-end acceptance step.

Testing

Ran the two new adapter suites (26 checks total, all pass) plus regression suites for every shared file the change touched (composer lib, tmux busy matcher, grok/kimi adapters, cmux/herdr/orca backends — all pass), then demonstrated the adapters end-to-end against the real installed CLIs at the exact verified versions: live tmux pane captures show cline's ❯ What can I do for you? idle surface and cursor-agent's Workspace Trust dialog → a → → Plan, search, build anything idle composer, with the shipped busy/idle classifiers reading each live row correctly and cursor's self-written trust marker matching fm-spawn's pre-seed byte-shape; /quit exit verified. The end-user surface here is terminal panes, and the captured pane text is the exact surface the adapters consume (tmux capture-pane), so the pane captures are the reviewer-visible visual evidence; the only failure seen (secondmate suite) reproduces at base with CLAUDECODE=1 inherited from the session env and passes with it unset — pre-existing, not from this change. Mid-turn busy/interrupt semantics were not re-exercised live since that requires running real autonomous agent turns; those literals are covered by the suites against docs/verification captures.

Evidence: Live adapter verification transcript
# Live adapter verification — cline 3.0.46 & cursor-agent 2026.07.23 (real CLIs, tmux-driven)

Installed CLIs match the verified adapter versions exactly:
- `cline --version` → 3.0.46 (adapter verified against Cline CLI 3.0.46)
- `cursor-agent --version` → 2026.07.23-e383d2b (adapter verified against Cursor CLI 2026.07)

## cline (pane captures: cline-idle-pane.txt, cline-pending-pane.txt)
- Live `cline -i --tui` pane rendered the verified first-ready surface: glyph `❯` +
  placeholder "What can I do for you?" (matches the adapter's empirical capture).
- Shipped busy matcher on the live composer row: **not busy** (correct).
- Shipped classifier (shared FM_COMPOSER_IDLE_RE_DEFAULT) on the live placeholder: **empty** (correct).
- Typed real text into the live composer (never submitted): classifier → **pending** (correct).

## cursor-agent (pane captures: cursor-trust-dialog-pane.txt, cursor-idle-pane.txt)
- Live `cursor-agent` launch in an untrusted dir showed the blocking
  "⚠ Workspace Trust Required" dialog with "[a] Trust this workspace" — exactly the
  anchors fm-spawn's readiness gate keys on.
- Gate predicates run against the real capture: `cursor_trust_dialog_present` TRUE,
  `cursor_pane_is_past_trust` FALSE (correct ordering).
- Sent the verified `a` keypress (fm-spawn's residual-dialog answer): pane cleared to the
  verified idle composer "→ Plan, search, build anything";
  `cursor_pane_is_past_trust` → TRUE.
- Shipped busy matcher on the live idle row: **not busy**; shared-default classifier: **empty**.
- Cursor itself wrote `~/.cursor/projects/tmp-fm-adapter-e2e-cursor-ws/.workspace-trusted`
  containing `{"trustedAt": "...", "workspacePath": "/tmp/fm-adapter-e2e/cursor-ws"}` —
  byte-shape identical to the marker fm-spawn pre-seeds, validating the pre-seed bypass.
- `/quit` (the adapter's documented exit command) exited the TUI cleanly (pane gone).

Not re-exercised live: mid-turn busy footers and esc/ctrl+c interrupts (would require
running real autonomous agent turns). Those literals are validated by the 12/14-check
suites against the empirical captures in docs/verification/*.md.
Evidence: Live cline 3.0.46 idle TUI pane capture (verified ❯ + placeholder surface)

❯ What can I do for you? ClinePass: Laguna S 2.1 (free) (high) ○ Plan ● Act (Tab) shipped busy-matcher: not busy · shipped classifier: empty · typed text → pending


                                                           @@
                                                         @@@@@@
                                                    @@@@@@@@@@@@@@@@
                                                  @@@@@@@@@@@@@@@@@@@@
                                                 @@@@@@@@@@@@@@@@@@@@@@
                                                 @@@@@    @@@@    @@@@@
                                               @@@@@@     *@@@     @@@@@@
                                               @@@@@@     *@@@     @@@@@@
                                                 @@@@@    @@@@.   @@@@@
                                                 @@@@@@@@@@@@@@@@@@@@@@
                                                  @@@@@@@@@@@@@@@@@@@@
                                                    @@@@@@@@@@@@@@@@.

                                                 What can I do for you?

                             Use / for slash commands, @ for file mentions, Ctrl+P for menu

                          ────────────────────────────────────────────────────────────────────
                          ❯ What can I do for you?
                          ────────────────────────────────────────────────────────────────────

                           ClinePass: Laguna S 2.1 (free) (high)           ○ Plan ● Act (Tab)
                           ██████ (0)
                           cline-ws
                           ⏵⏵ Auto-approve all enabled (Shift+Tab)
Evidence: Live cursor-agent Workspace Trust dialog capture (the gate fm-spawn keys on)

⚠ Workspace Trust Required Do you trust the contents of this directory? /tmp/fm-adapter-e2e/cursor-ws ▶ [a] Trust this workspace gate predicates: dialog_present=TRUE, past_trust=FALSE → sent 'a'


  ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
  │                                                                                                                  │
  │  ⚠ Workspace Trust Required                                                                                      │
  │                                                                                                                  │
  │  Cursor Agent can execute code and access files in this directory.                                               │
  │                                                                                                                  │
  │  Do you trust the contents of this directory?                                                                    │
  │                                                                                                                  │
  │    /tmp/fm-adapter-e2e/cursor-ws                                                                                 │
  │                                                                                                                  │
  │                                                                                                                  │
  │  ▶ [a] Trust this workspace                                                                                      │
  │    [q] Quit                                                                                                      │
  │                                                                                                                  │
  │  Use arrow keys to navigate, Enter to select, or press the key shown                                             │
  │                                                                                                                  │
  ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
Evidence: Live cursor-agent post-trust idle composer capture

Cursor Agent v2026.07.23-e383d2b → Plan, search, build anything gate predicate past_trust=TRUE · busy-matcher: not busy · classifier: empty · /quit exits cleanly

  ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
  │                                                                                                                  │
  │  ⚠ Workspace Trust Required                                                                                      │
  │                                                                                                                  │
  │  Cursor Agent can execute code and access files in this directory.                                               │
  │                                                                                                                  │
  │  Do you trust the contents of this directory?                                                                    │
  │                                                                                                                  │
  │    /tmp/fm-adapter-e2e/cursor-ws                                                                                 │
  │                                                                                                                  │
  │                                                                                                                  │
  │    [a] Trust this workspace                                                                                      │
  │    [q] Quit                                                                                                      │
  │                                                                                                                  │
  │  ⏳ Trusting workspace...                                                                                        │
  │                                                                                                                  │
  ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯


  Cursor Agent
  v2026.07.23-e383d2b
  Tip: Use /mcp to connect Cursor to your tools and data sources.




  → Plan, search, build anything


  Auto
  /tmp/fm-adapter-e2e/cursor-ws
Evidence: Live cline typed-input pane capture (pending classification)

                                                          .@+
                                                         @@@@@.
                                                   :@@@@@@@@@@@@@@@@
                                                 #@@@@@@@@@@@@@@@@@@@@
                                                @@@@@@@@@@@@@@@@@@@@@@#
                                                @@@@@@@@@@@@@@@@@@@@@@#
                                               #@@@@@@@@@@@@@@@@@@@@@@@@*
                                               @@@@@     @@@     @@@@@@@;
                                                @@@@.   #@@@*    @@@@@*
                                                @@@@@@@@@@@@@@@@@@@@@@+
                                                 @@@@@@@@@@@@@@@@@@@@
                                                  @@@@@@@@@@@@@@@@@:

                                                 What can I do for you?

                             Use / for slash commands, @ for file mentions, Ctrl+P for menu

                          ────────────────────────────────────────────────────────────────────
                          ❯ Fix the null-pointer in the parser
                          ────────────────────────────────────────────────────────────────────

                           ClinePass: Laguna S 2.1 (free) (high)           ○ Plan ● Act (Tab)
                           ██████ (0)
                           cline-ws
                           ⏵⏵ Auto-approve all enabled (Shift+Tab)
- Outcome: ⚠️ 1 info across 1 run (8m31s)

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

⚠️ **Review** - 4 infos
  • ⚠️ .agents/skills/harness-adapters/SKILL.md:411 - cline's idle placeholder is not recognized on the tmux backend (the default session provider). SKILL.md:411 states the placeholder survives the ghost stripper (truecolor 131;137;140, luma ~136 > 128 cutoff, drawn bold) and that "the backend IDLE_RE default lists both placeholders so an empty cline composer reads empty" — but the extension was applied only to herdr/cmux/orca. The tmux classifier (fm_tmux_composer_row_state, bin/fm-tmux-lib.sh:159) passes only the unset-by-default FM_COMPOSER_IDLE_RE override, so an idle cline composer ('❯ Ask anything...') classifies as pending on tmux. Reachable consequences: (a) the away-mode pre-injection guard (pane_input_pending → fm_backend_composer_state tmux) defers escalations indefinitely — the documented afk-herdr-false-pending overnight-wedge class; (b) fm_tmux_submit_core never observes 'empty' after delivering text to a cline crewmate, and its fallback fm_pane_is_busy is called WITHOUT a harness argument so it uses FM_TMUX_BUSY_REGEX_DEFAULT (bin/fm-tmux-lib.sh:80), which lacks cline's 'esc to cancel' — every tmux text delivery to a cline crewmate reports unconfirmed ('pending') even when submission succeeded. Recommended shared boundary: add a per-harness idle-placeholder default to the tmux classifier mirroring the existing per-harness busy-regex map (or extend the shared strip/idle path), rather than a fourth backend-local patch. Marked ask-user because restricting cline supervision to the herdr backend may be the author's deliberate scope.
  • ⚠️ .agents/skills/harness-adapters/SKILL.md:433 - cursor-agent's idle-empty proof is unreachable in every backend where it was added, contradicting SKILL.md:433 ("Matched as empty via the backend IDLE_RE (the glyph-prefixed placeholder form)"). The new IDLE_RE alternates '→ Plan, search, build anything|→ Add a follow-up' (bin/backends/herdr.sh:1830, cmux.sh:544, orca.sh:266) are only consulted after a structural finder promotes a composer row, but herdr promotes only bordered rows, bare rows matching FM_BACKEND_HERDR_BARE_PROMPT_RE='^[❯›]' (herdr.sh:1834), or pi separator pairs; cmux/orca promote side-bordered rows only. Cursor's composer is an unbordered '→'-prefixed row per the verification capture, so composer_state returns 'unknown' — never 'empty' — in all three backends, and the tmux path likewise yields unknown/pending (no idle default, '→' is not a recognized glyph or composer edge). Any consumer requiring proven-empty (injection guard, cmux/orca submit-confirm loops) wedges or defers for cursor crewmates. Note also cline's IDLE_RE entries are reachable only in herdr (cmux/orca require side borders cline does not draw). Fix at the structural boundary — e.g. add the verified '→' (U+2192) agent glyph to bare-row promotion and the shared glyph classifier — weighed against the dead-shell-prompt safety rule; ask-user because leaving the glyph classifier untouched was an explicit design choice in this change.
  • ⚠️ bin/fm-spawn.sh:472 - cursor-agent is selectable as a crew adapter (launch template at bin/fm-spawn.sh:472 plus the bare-name allowlists at lines 392/601) while the workspace-trust readiness wiring is absent: nothing pre-seeds ~/.cursor/projects/<slug>/.workspace-trusted or sends 'a' after the readiness gate, and --force/--trust do not bypass the interactive dialog. A crewmate spawned into an untrusted directory blocks on the trust dialog and the argv-seeded brief never auto-runs. The change documents this honestly as the remaining acceptance step (docs/verification/cursor-agent-adapter.md, SKILL.md), so this is authorized containment, not a hidden defect — but consider either wiring the readiness step or having fm-spawn refuse/warn on cursor-agent until it lands, so a captain setting config/crew-harness=cursor-agent today does not get a silently hung spawn.
  • ℹ️ bin/fm-harness.sh:57 - Detection breadth: detect_own matches any ancestor whose command name contains 'cursor' (bin/fm-harness.sh:57, and args-substring match at line 70). The Cursor IDE desktop process is literally named 'cursor', so fm-harness.sh run from a bare terminal inside Cursor IDE (no interposed agent harness in the 8-hop ancestry walk) reports own=cursor-agent instead of unknown, and config/crew-harness 'default' would then resolve crew spawns to cursor-agent. Similarly the node-args branch matches any script path containing 'cline'/'cursor' substrings. This mirrors the pre-existing 'grok' fragility pattern, but 'cursor' has a much higher ambient-collision probability. When a real harness is present it appears earlier in the walk, so practical impact is limited; noting the tradeoff.
  • ℹ️ bin/fm-spawn.sh:392 - Partial-wiring asymmetry, documented as deliberate: fm-spawn's --secondmate parse now accepts cline|cursor-agent as bare adapter names (bin/fm-spawn.sh:392) even though the SKILL states neither is wired for secondmate launches — bin/backends/tmux.sh:184's agent-process liveness list and bin/fm-session-lock-lib.sh:12's FM_HARNESS_RE were intentionally not extended. A cline/cursor secondmate would therefore spawn, but bootstrap recovery classifies a dead one as 'unverified-harness' and will not auto-respawn it. The allowlist inclusion is needed for correct argument parsing (otherwise the name would be misparsed as a FIRSTMATE_HOME path), and the degraded recovery behavior fails conservative; informational only.

🔧 Fix: share composer idle/glyph defaults across backends; wire cursor trust gate
4 infos still open:

  • ℹ️ docs/verification/cursor-agent-adapter.md:97 - Stale test count after the fix commit: docs/verification/cursor-agent-adapter.md:97 still says "12 behavior checks (all green)" but tests/fm-cursor-agent-harness.test.sh now runs 14 checks (the fix added test_cursor_glyph_is_promoted_and_safe and test_cursor_trust_gate_wired). The cline doc's count (12) is still accurate. The intent's "12-check suites per adapter" is met and exceeded, so this is only a doc-accuracy nit — update the table cell to 14.
  • ℹ️ bin/backends/orca.sh:267 - Acknowledged tradeoff of the round-1 fix: cmux/orca now promote bare agent-glyph rows (❯ › →) for every harness, so a stray glyph-prefixed transcript line in the scan window (orca reads up to 200 lines) can be promoted as the composer where previously only bordered rows were. The failure direction is safe — the last match wins so the bottom-anchored live composer normally outranks transcript rows, a promoted stray row classifies pending/unknown which blocks injection, and a lone bare glyph reading empty mirrors the pre-existing accepted ❯/› semantics on herdr — but it is a behavior widening for existing harnesses on those backends, not just the new adapters. Informational; no action needed.
  • ℹ️ bin/fm-harness.sh:57 - Still present from round 1 (informational, unchanged by the fix commit): detect_own matches any ancestor command name containing 'cursor' (bin/fm-harness.sh:57, args-substring at line 70). The Cursor IDE desktop process is literally named 'cursor', so fm-harness.sh run from a bare terminal inside Cursor IDE with no interposed harness reports own=cursor-agent instead of unknown, and crew-harness 'default' would resolve crew spawns accordingly. Mirrors the pre-existing 'grok' fragility; when a real harness is present it appears earlier in the ancestry walk, limiting practical impact.
  • ℹ️ bin/fm-spawn.sh:392 - Still present from round 1 (informational, documented as deliberate): fm-spawn's --secondmate parse accepts cline|cursor-agent as bare adapter names (bin/fm-spawn.sh:392) while neither is wired for secondmate launches — bin/backends/tmux.sh:184's liveness list and bin/fm-session-lock-lib.sh:12's FM_HARNESS_RE were intentionally not extended. A cline/cursor secondmate would spawn but bootstrap recovery classifies a dead one as 'unverified-harness' and will not auto-respawn it; the allowlist entry is needed for correct argument parsing and the degraded recovery fails conservative.
⚠️ **Test** - 1 info
  • ℹ️ tests/fm-secondmate-harness.test.sh:162 - Pre-existing, environment-dependent: tests/fm-secondmate-harness.test.sh fails when run inside a Claude Code session because the inherited CLAUDECODE=1 env var makes bin/fm-harness.sh:38 short-circuit to 'claude' before the test's faked pi ancestry is consulted. It fails identically at the base commit fa0d85d (verified via git archive) and passes fully with env -u CLAUDECODE. Not caused by this change; noted so gate/CI runners embedded in Claude Code sessions aren't surprised.
  • bash tests/fm-cline-harness.test.sh — 12/12 checks pass
  • bash tests/fm-cursor-agent-harness.test.sh — 14/14 checks pass
  • bash tests/fm-composer-lib.test.sh and bash tests/fm-tmux-submit-busy.test.sh — pass (shared classifier/busy-matcher regression)
  • bash tests/fm-grok-harness.test.sh and bash tests/fm-kimi-harness.test.sh — pass (sibling adapters unaffected)
  • bash tests/fm-backend-cmux.test.sh, bash tests/fm-backend-herdr.test.sh, bash tests/fm-backend-orca.test.sh — pass (backends whose IDLE_RE defaults were rewired to the shared default)
  • env -u CLAUDECODE bash tests/fm-secondmate-harness.test.sh — full pass; with CLAUDECODE set it fails identically at base commit fa0d85d (verified via git archive extraction), proving the failure is pre-existing and environment-induced, not from this change
  • Manual live E2E (real CLIs at the verified versions, driven via a private tmux server): launched cline -i --tui, captured the pane, ran the shipped fm_busy_lines_match cline and fm_composer_classify_content on the live rows (placeholder → empty, typed text → pending, idle row → not busy)
  • Manual live E2E: launched cursor-agent in an untrusted scratch dir, captured the live 'Workspace Trust Required' dialog, verified fm-spawn's cursor_trust_dialog_present/cursor_pane_is_past_trust predicates against the real captures, sent the verified a keypress to clear trust into the verified '→ Plan, search, build anything' idle composer, confirmed cursor's own .workspace-trusted marker matches fm-spawn's pre-seed shape, and confirmed /quit exits cleanly
  • Cleanup verified: test-created scratch state removed (trust marker dir, tmux server, /tmp scratch), git status --porcelain clean
⚠️ **Document** - 1 info
  • ℹ️ bin/fm-spawn.sh:392 - fm-spawn.sh's secondmate argument allowlist accepts cline/cursor-agent as explicit adapter names, but the harness-adapters SKILL.md (owner) states neither is wired for secondmate launches (no backends/tmux.sh liveness entry). Documentation follows the SKILL.md owner's statement (crewmate-only); the residual code/doc tension is in executable behavior, out of scope for this documentation phase.
🔧 **Lint** - 1 issue found → auto-fixed ✅
  • ⚠️ linter found issues (exit code 1)

🔧 Fix: annotate shared composer defaults for cross-file SC2034
✅ Re-checked - no issues remain.

✅ **Push** - passed

✅ No issues found.

@adibirzu
adibirzu force-pushed the local-adapters branch 2 times, most recently from d21eeec to fe00911 Compare July 28, 2026 08:34
@adibirzu adibirzu changed the title feat(harness): add verified cline + cursor-agent crewmate adapters feat(harness): add verified cline and cursor-agent crewmate adapters Jul 28, 2026
@adibirzu
adibirzu marked this pull request as draft July 29, 2026 06:17
@adibirzu

Copy link
Copy Markdown
Author

Moving this to draft — please don't spend review time on it yet.

On re-examination the test coverage here is weaker than it looks. The 12+14 checks assert registration-level facts ("the launch template is the verified argv-seed line", "cline is recognized as a known bare adapter name", "effort maps to --thinking"), and the harness facts in docs/verification/*-adapter.md came from real tmux captures of each CLI's TUI. Both are genuine — but neither proves the thing that actually matters: no crewmate has ever been dispatched end to end through these adapters (fm-spawn → herdr ready-gate → inject → work → turn-end → teardown).

I'd rather prove that before asking you to merge it. Marking ready again once a live dispatch acceptance passes for both adapters.

The other open PRs are unaffected — #1217 (federated fleet) was accepted against three real operators with a real concurrent claim race and live quota, and #1142's Herdr behaviour suites drive a real Herdr lab.

adibirzu and others added 7 commits August 5, 2026 16:28
Adds cline as a verified FirstMate harness adapter. Every fact captured
empirically from live `cline -i --tui` panes (docs/verification/cline-adapter.md).

- fm-spawn.sh: launch_template (argv-seed `-i --tui --auto-approve true`),
  --model + effort->--thinking mapping, known-adapter allowlists
- fm-harness.sh: detect_own ancestry match (*cline*, comm + args)
- fm-tmux-lib.sh: busy signature `esc to cancel` (distinct from `esc to interrupt`)
- backends/{herdr,cmux,orca}.sh: IDLE_RE default covers cline's non-dim
  placeholders (What can I do for you? / Ask anything...)
- harness-adapters SKILL: cline knowledge section
- tests/fm-cline-harness.test.sh: 12 behavior checks (all green)

Composer/ghost/grok/secondmate-harness regressions stay green; the 5 existing
launch templates stay byte-pinned. Full live end-to-end crewmate dispatch through
herdr remains the closing acceptance step (documented).
…apter

Adds cursor-agent as a verified FirstMate harness adapter. Every fact captured
empirically from live `cursor-agent --force` panes (docs/verification/cursor-agent-adapter.md).

- fm-spawn.sh: launch_template (argv-seed `--force`), --model allowlist (effort is a
  model bracket param, no flag), known-adapter allowlists
- fm-harness.sh: detect_own ancestry match (*cursor* -> cursor-agent, comm + args)
- fm-tmux-lib.sh: busy signature `ctrl+c to stop` (distinct from pi's `Working...`)
- backends/{herdr,cmux,orca}.sh: IDLE_RE default covers cursor's → placeholders
- harness-adapters SKILL: cursor-agent knowledge (incl. the workspace-trust gate:
  --trust is headless-only; bypass via pre-seeded .workspace-trusted or `a`)
- tests/fm-cursor-agent-harness.test.sh: 12 checks (green); de-brittled the cline
  test's allowlist asserts to tolerate trailing adapters

Regressions green (composer-lib 9, composer-ghost 30, grok 3, secondmate-harness 40,
kimi 19; 5 existing launch templates byte-pinned). Trust-gate readiness wiring in
fm-spawn + full live herdr dispatch remain the closing acceptance step (documented).
The shared FM_COMPOSER_BARE_PROMPT_RE_DEFAULT this branch introduces was
'^[❯›→]', a bracket expression. Under the fleet's C/POSIX locale grep
matches bracket expressions BYTE-wise, so [❯›→] decomposes into the shared
leading UTF-8 byte (0xE2) and spuriously matches any multibyte glyph in
that range - including box-drawing corners like ╰, which misclassifies a
bordered composer's bottom border as a bare prompt row.

bin/backends/herdr.sh already carried an alternation for exactly this
reason, with the rationale in a comment. Centralising the constant without
carrying that form would have reintroduced the bug fleet-wide, for every
adapter, at the moment the default became shared.

The constant is now '^(❯|›|→)' with the rationale beside it, so a later
edit cannot quietly restore the bracket form. Verified: cline 12 ok,
cursor-agent 14 ok, composer-lib 9 ok, composer-ghost 30 ok, lint 0.
@adibirzu

Copy link
Copy Markdown
Author

Superseded by #1338 (consolidated federated-fleet + crew-routing PR): verified cline + cursor-agent adapters; folded into #1338. Closing in favor of the single consolidated PR. This can be reopened if needed.

@adibirzu adibirzu closed this Aug 11, 2026
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