diff --git a/docs/compatible-agents.md b/docs/compatible-agents.md index d489de559..5497bfe7d 100644 --- a/docs/compatible-agents.md +++ b/docs/compatible-agents.md @@ -103,7 +103,7 @@ Source of truth: `captureAgentRecovery` / `RecoveryHost` in `lib/src/host/recove **Must derive supported executable names and resume options from `CODING_AGENTS`.** - **Must rebuild only a known invocation plus an opaque id.** The command is *rebuilt* as label, space, captured id, never sliced from the buffer, keeping the hint's executable alias; a long option's id may follow a space or `=`, and only Claude's legacy `claude --continue` omits it. An agent's id must be a UUID unless it registers `id: 'opaque'`, whose ids begin with an ASCII alphanumeric and contain only ASCII alphanumerics, hyphens, and underscores. The invocation must end on a word break but nothing stronger (rationale). -- **Must observe a separator after the newest invocation before capturing it.** Buffer end is insufficient, even at the capture deadline; never fall back to an older hint while the newest is unterminated. Pinned by `waits through every ID split` in `lib/src/host/recovery-capture.test.ts` (rationale). +- **Must observe a separator after the newest invocation before capturing it.** Buffer end is insufficient, even at the capture deadline; never fall back to an older hint while the newest is unterminated. Pinned by `lib/src/host/recovery-capture.test.ts` (rationale). - **Must strip the scan window as a whole, in one pass, with an unterminated control swallowing the rest of it** — the string controls (OSC, DCS, SOS, PM, APC) **in either introducer form, `ESC` or bare C1**, and equally a CSI the window was cut off *inside* (rationale). **Must match every escape by its full ECMA-48 shape**, never by the Fe range (rationale). **Must share one implementation**: `stripTerminalControls` removes string controls by running `TerminalControlStreamFilter`, so the batch and streaming readers cannot disagree. - **Must strip in boundary mode**: complete non-string ESC/CSI sequences and standalone C1 controls become newlines, except SGR and charset designators. ESC and C1 counterparts must produce the same boundary. String controls and their payloads vanish; LF, CR, and TAB remain text boundaries; other C0 controls that do not move or erase text vanish. **Must discard incomplete trailing presentation controls without creating a boundary** (rationale). - **Must select the rightmost well-formed match in the last 50 lines**, newest *by position* and never by pattern order, skipping a terminated id of the wrong shape (rationale). diff --git a/docs/specs/hosted.md b/docs/specs/hosted.md index 729193d8a..e340c0024 100644 --- a/docs/specs/hosted.md +++ b/docs/specs/hosted.md @@ -59,7 +59,7 @@ Continuing past the sign-in notice is how an account agrees to the Hosted terms - **Must show the notice beside every sign-in method**, naming `TERMS_VERSION` and linking the terms and privacy policy without leaving the page. - **`TERMS_VERSION` is the policy pages' revision date** and changes with every terms revision. -- **Must record each account's first acceptance of each version**, after a sign-in that continued past the notice,, current version only. +- **Must record each account's first acceptance of each version**, after a sign-in that continued past the notice, current version only. Source of truth: `termsRoutes` in `hosted/server/terms.ts`; `TERMS_VERSION` in `hosted/server/policy-constants.ts`. diff --git a/lib/src/lib/alert-settings-model.ts b/lib/src/lib/alert-settings-model.ts index dd0f7bab1..0050ab067 100644 --- a/lib/src/lib/alert-settings-model.ts +++ b/lib/src/lib/alert-settings-model.ts @@ -13,7 +13,7 @@ import { cfg } from '../cfg'; export interface AlertSettings { /** ms — how long without typing, pointer, or wheel input before the user counts as away (the renderer's presence window). */ inactivityTimeoutMs: number; - /** Defer non-exit rings until five seconds after the last accepted output. */ + /** Defer non-exit rings while the output detector has confirmed work, until it settles. */ deferAlertsUntilQuiet: boolean; /** Speak a ring out loud after `speakDelayMs`, unless its pane is the one being looked at. */ speakEnabled: boolean; diff --git a/lib/src/lib/lath/test-fixtures.ts b/lib/src/lib/lath/test-fixtures.ts index 4e7580a77..a797300e2 100644 --- a/lib/src/lib/lath/test-fixtures.ts +++ b/lib/src/lib/lath/test-fixtures.ts @@ -4,7 +4,8 @@ import type { LeafMeta } from './persistence'; /** Build a `LeafMeta` for tests. `tabComponent` defaults from `component` the same way - * the real builders do (`terminal` → `terminal`, anything else → `surface`); `title` + * the real builders do (`terminal` → `terminal`, `tool` → `tool`, anything else → + * `surface`); `title` * defaults to `'t'`. The single builder shared by every Lath wall test suite. */ export function leafMeta(overrides: { title?: string; @@ -15,7 +16,7 @@ export function leafMeta(overrides: { const component = overrides.component ?? 'terminal'; return { component, - tabComponent: overrides.tabComponent ?? (component === 'terminal' ? 'terminal' : 'surface'), + tabComponent: overrides.tabComponent ?? (component === 'terminal' || component === 'tool' ? component : 'surface'), title: overrides.title ?? 't', ...(overrides.params ? { params: overrides.params } : {}), }; diff --git a/lib/src/remote/burrow/push-delivery.test.ts b/lib/src/remote/burrow/push-delivery.test.ts index f52eeb405..f1a0da807 100644 --- a/lib/src/remote/burrow/push-delivery.test.ts +++ b/lib/src/remote/burrow/push-delivery.test.ts @@ -72,7 +72,7 @@ function aclRecord(deliveryId: string, label: string): BurrowAclRecord { /** * A stand-in for the Burrow's seal: shape-correct, distinct per recipient, and - * free of WebCrypto, so the cases below mint no keys. The real construction is + * free of WebCrypto. The real construction is * driven with real keys in `sealed push`. */ function fakeSeal(): AlertPushDeps['seal'] { diff --git a/scripts/pairing-walkthrough/cdp.mjs b/scripts/pairing-walkthrough/cdp.mjs index a70a4e2fa..21fc69a8c 100644 --- a/scripts/pairing-walkthrough/cdp.mjs +++ b/scripts/pairing-walkthrough/cdp.mjs @@ -1,7 +1,7 @@ /** * Just enough raw CDP for the two things `agent-browser` cannot do: give the * Pocket page a virtual WebAuthn authenticator, and keep a record of everything - * that page logs (`scripts/pairing-walkthrough/README.md` → The Pocket browser). + * that page logs (`scripts/pairing-walkthrough/README.md` → Known limitations). * * The CLI has no raw-CDP verb, so this opens a WebSocket of its own to the page * target's `webSocketDebuggerUrl`. Chrome accepts that second client while diff --git a/website/src/lib/tutorial-shell.test.ts b/website/src/lib/tutorial-shell.test.ts index c5fba4743..99da62f4b 100644 --- a/website/src/lib/tutorial-shell.test.ts +++ b/website/src/lib/tutorial-shell.test.ts @@ -131,11 +131,10 @@ describe("TutorialShell program dispatch", () => { }); }); -// The playground shell drives the alert tutorial's WATCHING/command-exit demos -// (docs/specs/tutorial.md) entirely through OSC 633 shell-integration reports. -// Nothing else asserts these bytes, so a refactor could silently stop emitting -// them and leave every alert demo showing "nothing is running" while the rest -// of the suite stays green. +// The playground shell reports every command, including the Alerts section's +// `agent` and `build` programs (docs/specs/tutorial.md), through OSC 633 +// shell-integration reports. Nothing else asserts these bytes, so a refactor +// could silently stop emitting them while the rest of the suite stays green. describe("TutorialShell OSC 633 shell integration", () => { it("reports the prompt with OSC 633;A / 633;B", () => { const { output, shell } = createHarness();