Skip to content

feat: pluggable harness adapters + native multiSelect AskUserQuestion (0.11.0)#11

Merged
AltanS merged 3 commits into
mainfrom
feat/harness-adapters-multiselect
Jul 15, 2026
Merged

feat: pluggable harness adapters + native multiSelect AskUserQuestion (0.11.0)#11
AltanS merged 3 commits into
mainfrom
feat/harness-adapters-multiselect

Conversation

@AltanS

@AltanS AltanS commented Jul 15, 2026

Copy link
Copy Markdown
Owner

Summary

Two big things ship in 0.11.0, plus UI and safety hardening:

  1. Pluggable harness adapters. The single Claude-only block-grammar gate is replaced by a HarnessAdapter registry, so open-source contributors can add codex / pi / opencode without touching the core. Claude's detectors move lib/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). See HARNESS_CONTRIBUTING.md.

  2. 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

  • Interactive prompts render in a bordered panel lifted off the terminal mirror (elevated option rows, leading key-digit badges, family-aware caption) — previously they were nearly invisible against the terminal.
  • Keys and Quick menus dock in-flow above the controls row instead of a fixed overlay; a ResizeObserver re-pins the shrunk mirror to the bottom so the prompt/cursor stays visible.
  • The "Sent" toast moves from a bottom overlay (which covered the terminal tail) to a slim row below the header.
  • The build stamp marks a dirty working tree (<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.

  • Per-pane serialization of multi-select actions — two overlapping Submit macros can no longer both auto-confirm past the review screen (closes the single-device remount path; shrinks the multi-device path to the read→send window).
  • The mid-walk identity check includes checkbox state, so an external flip aborts the walk rather than shipping a set the user never saw.
  • Toggle digits are validated against the model; the detector requires a real "Submit" row and bails past 9 options; the incomplete-answers warning is role="alert".
  • Registry prototype-chain crash guard, multi-line import-fence hole, conformance key-grammar coverage + fail-closed cohorts, dock Close-button reachability, dirty-sha robustness, long-token wrapping.

Bug fix

  • Numbered-list-in-body detection in prompt-select + wizard: a plan's numbered steps inside a dialog body no longer break menu detection — the menu is taken as the trailing 1..m run, so plan-approval prompts up-level correctly.

Verification

  • web: 694 tests (Vitest) · bridge: 168 tests (Bun) · both-side tsc clean · bun run build clean · scripts/check-version.sh ✓ (0.11.0 consistent across manifest, package.json, web/package.json, CHANGELOG).
  • The multiSelect choreography and the ~2s Submit timing were live-verified against the collie-demo sandbox session.

🤖 Generated with Claude Code

AltanS and others added 3 commits July 15, 2026 23:11
… (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>
@AltanS AltanS merged commit 9298fe1 into main Jul 15, 2026
1 check passed
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