feat: pluggable harness adapters + native multiSelect AskUserQuestion (0.11.0)#11
Merged
Merged
Conversation
… (0.11.0) Replace the single Claude-only block-grammar gate with a HarnessAdapter registry so open-source contributors can add codex/pi/opencode. Claude's detectors move from lib/grammar/ to lib/harness/claude/; the model-generic race-guard engine (lib/harness/guard.ts) is the ONLY module allowed to touch the network, enforced by an import fence (fence.test.ts) plus a per-adapter conformance suite (conformance.ts). Contributor guide in HARNESS_CONTRIBUTING.md. Add native multiSelect AskUserQuestion (the checkbox form): options up-level to tappable checkbox rows with the terminal as the single source of truth (a digit is an XOR, no optimistic local state). Submit is a closed-loop macro that walks the pointer onto the "Submit" row and verifies a fresh read before Enter — it never blind-sends — then the review/confirm screen. Hardening from a 4-pass Fable review: - serialize actions per pane so two overlapping Submit macros can't both auto-confirm past the review screen (module-scoped in-flight lock) - the mid-walk identity check includes checkbox state, so an external flip aborts rather than shipping a set the user never saw - toggle digits validate against the model; the detector requires a real "Submit" row and bails past 9 options; the incomplete-answers warning is role="alert" UI: interactive prompts render in a bordered panel lifted off the terminal mirror (elevated rows, key-digit badges); Keys/Quick menus dock in-flow above the controls row and a ResizeObserver re-pins the shrunk mirror to the bottom so the prompt stays visible; the "Sent" toast moves to a slim row below the header; the build stamp marks a dirty tree (<sha>-dirty). Fix a numbered-list-in-body detection bug in prompt-select + wizard: the menu is taken as the trailing 1..m run, so plan-approval prompts up-level correctly. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add a GitHub Actions workflow running the same invariants the local git hooks enforce — scripts/check-version.sh, root typecheck + bridge tests, and web typecheck + Vitest — on pull_request and pushes to main. Public-repo Actions minutes are free, and the local hooks aren't installed in every checkout, so this is the only server-side gate. Not a bump-triggering path (no version bump). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Surface update-availability in the app: the bridge checks the repo's GitHub tags over anonymous HTTPS for a newer RELEASE and stamps its own sources to detect a rebuilt-but-not-restarted PROCESS, exposing both on the access-gated /api/snapshot as `update`. A footer banner links to the GitHub release (its notes carry the update commands) or shows a Herdr-plugin-action restart command; a Settings "check for updates" button forces an immediate check (POST /api/update/check); an opt-out `updates` notify pref gates a de-duped web-push (its own collapse topic, tap opens Settings). Every pushed v* tag auto-creates the GitHub release (CHANGELOG section + update commands) via .github/workflows/release.yml, so the page the banner links to always tells you how to update. User-facing update/restart are Herdr plugin actions (location-independent) — codified in CLAUDE.md. Harden "tap to update": a wedged service worker (HTTPS/PWA) serving a stale precache now triggers an unregister-then-reload bypass, but only on the online-proven path — network-failure paths keep the precache so an offline PWA still works. Folds in a Fable review (ship-with-fixes): the update push rides its own collapse topic so it can't overwrite a queued herd alert (with a test pinning the seam); the check button no longer reads a silently-failed check as "up to date"; UpdateStateStore writes atomically. Co-Authored-By: Claude Opus 4.8 <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.
Summary
Two big things ship in 0.11.0, plus UI and safety hardening:
Pluggable harness adapters. The single Claude-only block-grammar gate is replaced by a
HarnessAdapterregistry, so open-source contributors can add codex / pi / opencode without touching the core. Claude's detectors movelib/grammar/→lib/harness/claude/. The model-generic race-guard engine (lib/harness/guard.ts) is now the only module allowed to touch the network — enforced by an import fence (fence.test.ts) and a per-adapter conformance suite (conformance.ts). SeeHARNESS_CONTRIBUTING.md.Native multiSelect AskUserQuestion. Claude's checkbox questions up-level to tappable checkbox rows, with the terminal as the single source of truth (a digit is an XOR — no optimistic local state). Submit is a closed-loop macro: it walks the
❯pointer onto the "Submit" row and verifies a fresh read before ever pressing Enter — it never blind-sends — then advances to the review/confirm screen.UI
ResizeObserverre-pins the shrunk mirror to the bottom so the prompt/cursor stays visible.<sha>-dirty) so the footer never claims HEAD when the build carries uncommitted work.Safety hardening (from a 4-pass Fable review of the working tree)
All critical + medium findings implemented; low/judgment items were surfaced separately.
role="alert".Bug fix
1..mrun, so plan-approval prompts up-level correctly.Verification
web: 694 tests (Vitest) ·bridge: 168 tests (Bun) · both-sidetscclean ·bun run buildclean ·scripts/check-version.sh✓ (0.11.0 consistent across manifest,package.json,web/package.json, CHANGELOG).collie-demosandbox session.🤖 Generated with Claude Code