th-e77603: declarative scrape rules + aider/goose/crush/cline harnesses - #599
Merged
Merged
Conversation
…oose, crush, cline) with live pane fixtures WIP checkpoint: [[state.scrape.rules]] engine (crate::scrape), engine observation (title/alt-screen/cursor/quiet clock), paste waits for a scraped idle (th-d2a1e4), resume.mode = continue_latest, 44 real pane fixtures. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…e-CLI tests, clippy Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…_latest keeps pasted-launch flags, docs Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ing four Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
🦋 Changeset detectedLatest commit: 6200ada 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
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…the live captures Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
brentrager
added a commit
that referenced
this pull request
Sep 17, 2026
…en (#602) Version-only bump. Brent is running 0.2.2, and the two features he is waiting on have been sitting on main unreleased: the New Session screen that no longer demands a pearl id (#594) and the declarative scrape rules that add aider/goose/crush/cline plus the aider paste-timing fix (#599). Cutting 0.2.3 is what actually puts them in front of a user. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Merged
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.
Pearl th-e77603 (epic th-faa590) · fixes th-d2a1e4
Problem
SmoothFlow could only learn state for harnesses with hooks. Hookless coding CLIs (aider, goose, crush, cline…) show idle / working / needs-you only on their terminal, and the flat
[state.scrape]lists can't describe real TUIs: crush draws its permission modal over a footer that still saysesc cancel, cline's composer looks idle for the whole turn, aider streams answers with no marker at all. Andprompt_as = "paste"pasted on a 4 s timer, straight into aider's first-run question.Solution
[[state.scrape.rules]](crates/smooth-flow/src/scrape.rs): ordered rules, first match wins, evaluated before the flat lists (which keep their exact precedence). A rule ismatchregexes over a scope (tail/pane/last_line/cursor_line/title) withall,unless,unless_below,quiet_ms,changed_within_ms,alternate_screen,spinner. Pure over aPaneObservation; ANSI is stripped first.display-messageper tick for title / alt-screen / cursor row, a per-session "pane last changed" clock, the deciding rule's name in the needs-you detail, a scraped needs-you clears on the next idle, and paste waits for a scraped idle (never into a needs-you; 90 s fallback; manifests with no idle signal keep the 4 s timer).resume.mode = "continue_latest"for CLIs that only continue "the latest conversation here".aider,goose,crush,cline.Harness-Manifests.md— rule semantics + load/timing guidance, the shipped table (live vs fixture-only), how cmux and orca detect hookless state (file:line), and why Claude'sdetect.rsis expressible as rules.Verification
tests/scrape_live.rs,#[ignore]), fresh scratch$HOME, isolated installs, local mock OpenAI server (no accounts, no keys): aider 0.86.2, goose 1.50.0, crush 0.94.2, cline 3.0.61 each went launch → first-run needs-you → working → idle, steer → working → idle, tool/edit request → needs-you → deny → idle, kill + resume → back.tests/scrape_fixtures.rs(verdict + deciding rule per fixture, resize/padding/SGR invariants, time monotonicity,detect.rs-as-rules equivalence on 5 000 generated panes). Unit/property tests inscrape.rs,harness.rs,engine.rs, plus a live fake-CLI test for the paste gate and needs-you clearing.cargo test -p smooai-smooth-flowgreen (168 + 6),cargo clippy -p smooai-smooth-flow --all-targetshas no warnings in the files this PR touches. Not run locally: smooth-daemon / smooth-cli test builds (disk under 6 GiB on the build machine). Their only changes are list assertions that now countBUILTINrather than assuming four, so CI is the check for those.Harness conformance (#598) — expected failure
tests/conformance/{aider,goose,crush,cline}.tomlenrol the four in the conformance suite, with screens cut from the live captures. Once this PR is rebased onto #598,screen_problemsgets patched here to count[[state.scrape.rules]]and to feed painted screens a quiet time. Until follow-up th-5a2314 (harness-conformance: manifest-driven[steer] approve_keys/deny_keys) lands, the needs_you → approve step fails for all four. The engine approves with keystroke1; aider wantsy/Enter, goose Enter, crush Enter, cliney. This is expected, not a regression.🤖 Generated with Claude Code