th-b00115: hook-capable harnesses — gemini, qwen, cursor, copilot, droid, amp, pi - #600
Open
brentrager wants to merge 3 commits into
Open
brentrager wants to merge 3 commits into
brentrager wants to merge 3 commits into
Conversation
…t, copilot, droid, amp, pi SmoothFlow knew four CLIs. These seven expose real lifecycle signals (hooks, plugins, extensions), so each gets a built-in manifest plus a th pkg overlay that maps its native events onto /api/flow/hooks. Engine: panes carry SMOOTH_FLOW_ID and hooks post it back as flow_id, so a learned-id harness binds to its row without cwd guessing; only the Claude table holds PermissionRequest open (a mapped ask gets a hook- id answered by keystroke); steer honours steer.submit_key and the new submit_delay_ms (Gemini folds an immediate Enter into the paste). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Reference matrix (orca + cmux file:line citations and each CLI's current docs), per-harness design choices, the engine changes, and exactly which harnesses were proven live vs parse-tested. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
🦋 Changeset detectedLatest commit: 3a56fcd The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
brentrager
enabled auto-merge (squash)
September 14, 2026 21:32
Both lanes fixed un-approvable hook asks. Adopt #598's rule (id assigned in the pure mapper, permission asks only; a question gets none) so the two merge cleanly. The delta kept here: the permission label is derived from the event name / notification_type, and only Claude-protocol harnesses hold PermissionRequest open. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
SmoothFlow had four built-in harnesses. Brent asked for broader harness support, using cmux and orca as reference. This lane (harness-hooked, epic th-faa590) covers the CLIs that report real lifecycle signals (hooks, plugins, extensions), so their state comes from the CLI rather than from pane scraping.
What ships
crates/smooth-flow/harnesses/):gemini,qwen,cursor-agent,copilot,droid,amp,pi. Each has binary resolution that skips cmux shims, launch/resume argv, session-id mode, steer, and kill. Scrape patterns come from real boot screens where captured.harness/amp/plugin.ts), and a Pi extension (harness/pi/extension.ts).th pkg: gemini, qwen, droid, copilot, amp, and pi are new hook-only--harnesstargets (included inall). Cursor hooks merge into~/.cursor/hooks.jsonthrough a flat-entry-aware merge. rm and status are exact.SMOOTH_FLOW_ID, and hooks post it back asflow_id. That binds CLIs that can't pre-assign a session id (Cursor, Droid, Amp) to the right row, with guards against nested or child agents.PermissionRequestopen (so Droid's hook isn't blocked for 120 s). A mapped permission ask gets ahook-<uuid>id thatflow.approveanswers by keystroke. This overlaps th-3cabf6: harness conformance contract + th harness doctor #598 (th-3cabf6), which fixed the same un-approvable-ask bug. This PR now uses th-3cabf6: harness conformance contract + th harness doctor #598's exact rule: the id is assigned in the pure mapper, permission only, a question gets none. The delta kept here: thepermissionlabel is derived from the event name ornotification_type. Gemini'sToolPermissionand Droid'sPermissionRequestsend noreason, so th-3cabf6: harness conformance contract + th harness doctor #598 alone leaves them unapprovable. Whichever PR lands second takes a trivial textual conflict inmap_manifest_event/mapped_outcome.steer.submit_keyand a newsteer.submit_delay_ms. Gemini turns an immediate Enter into a newline; measured live, it needs at least 150 ms.flow-hook.shreadssessionId,conversation_id, andworkspace_roots, and pre-answers stdout for harnesses that parse it.docs/Engineering/Harness-Manifests.md(orca + cmux file:line citations, plus each CLI's current docs), the design choices, and a proof table. The Harness-Packages table is updated.Deliberately not copied from orca: answering Cursor's gate hooks with
{"permission":"allow"}, which auto-approves every tool call.Verification
cargo test -p smooai-smooth-flow: 156 passed. New tests cover the event table for every mapped event, flow_id binding rules, the held-vs-keystroke ask split, per-manifest launch/resume/resolve, and the steer knob.cargo clippyadds no new warnings in touched files.cargo check --testspasses for smooth-cli and smooth-daemon.pkgtests and smooth-daemon route tests. Disk was at 6-11 GB machine-wide, too little to codegenth/the daemon, so CI is the first run of those.flow-hook.test.sh36/36;flow-plugins.test.mjs(Amp/Pi) ok.--session-id(conversation continued), and kill all proven from hooks.PermissionRequestapproved viath flow approve(command ran with no dialog) all proven.ToolPermissionneeds_you proven. This run exposed the steer-submit and un-approvable-ask gaps fixed here. The fixes are unit-tested; they were not re-run through a rebuilt daemon.Known pre-existing flakes on origin/main (not this PR):
opencode/plugin.test.mjsevent ordering fails about half the time, andclose_closes_the_pearl_through_thraces on the process-globalSMOOTH_TH_BIN.Pearl: th-b00115 · Epic: th-faa590
🤖 Generated with Claude Code