Syntax highlighting, a transcript render budget, and a gated call that says so - #645
Merged
Merged
Conversation
…and a gated call that says so Three tracks, plus four fixes an adversarial review returned before any of it could merge. SYNTAX HIGHLIGHTING. Code blocks and diff rows had no colour anywhere — streamdown 2.5.0 carries no highlighter. Adds shiki behind a small seam, with an enumerated grammar list rather than the full bundle: the desktop renderer is one esbuild `outfile:` with no splitting, so a dynamic import() is INLINED, and the list is sized for that cost (~623 KB, measured). Deliberate, documented at syntaxTokens.ts:60-66, and the web host still splits per grammar. The lockfile stayed SURGICAL — two lines, no regeneration — because shiki@4.4.2 was already hoisted at the root as a transitive dep of astro at exactly the pinned version. `npm ci --dry-run` exits 0. That mattered: a regenerated lock reds the SBOM gate and blocks every PR in the repo. Token colour rides ON TOP of the diff: only `color` is set per span, so add and remove backgrounds survive, and a refused edit gets no tokens at all — colour is this card's "this happened" signal and an unapplied diff has not earned it. A RENDER BUDGET, not a virtualizer. Rows here are variable-height, interactive and hold state, and an approval card unmounted from under someone would break the one reachable exit from a parked run. So the newest N turns render fully and older tool/fleet/reasoning items fold behind an expandable summary. Approvals and the composer are never elidable. A GATED CALL NOW SAYS SO. A refused write and a write parked on an approval rendered identically, and their remedies are opposite — attach a folder vs approve. The card now reads "Needs you" for the call the decision is about, carries the server's own question, and stamps `data-tool-blocked` so a journey need not read copy. No second approve control: the ask card remains the only place a decision is taken. FIXES FROM REVIEW: 1. ci-gates was RED — three dark-wiring symbols (`_Fields.batch_id` ×2, `batch_index`). No Python changed; a new test fixture NAMED keys that were previously invisible to the scan (api-types is excluded from it), turning "unmentioned" into "mentioned but never read". The fixture is right to include them — a fixture richer than the wire is how a green suite ships over a field the client never receives — so the keys are baselined with the same reason text their siblings already carry. 2. `workspace_consent.py` asserted `"Waiting" in card["text"]` over every parked card, and the new copy renames exactly that one to "Needs you". The copy is better, so the assertion moved, not the product. 3. `MAX_HIGHLIGHTED_CHARS` 40_000 → 8_000. streamdown re-tokenizes the whole block per model delta on the main thread, so that bound is a FRAME budget, not the readability budget its comment claimed: 49ms at 40k on tsx (87ms on dense TS) is ~11fps while tokens arrive. 8k is ~10ms and still ~135 lines. 4. The budget elided the gated card — in precisely the long runs track (c) was written for. A call parked on a live decision is no longer elidable; a DENIED call still is, because that one is history. Pinned by a test verified to fail without the fix. Also corrected: both verifiers reported the desktop bundle growth as an unintended regression. It is not — syntaxTokens.ts:60-66 states the trade in advance and the grammar list was sized for it. The review caught that; splitting the desktop renderer remains available as its own change. typecheck ×4 green · desktop builds · dark-wiring 0 new · lockfile 2 lines chat-surface 4162 passed, with the same 2 pre-existing failures as a clean tree. Co-Authored-By: Claude Opus 5 <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.
Three of the six remaining UI gaps. The other three (shell execution, subagent
control, typography) are PRDs under
docs/plan/agent-execution/and landseparately — both engineering PRDs came back NEEDS-REVISION and should not be
implemented from as-is.
What lands
Syntax highlighting. There was none anywhere — streamdown 2.5.0 carries no
highlighter. Adds
shikibehind a small seam.The lockfile stayed surgical: two lines, no regeneration, because
shiki@4.4.2was already hoisted at the root as a transitive dep of astro atexactly the pinned version.
npm ci --dry-runexits 0. This was the main risk inthe change — a regenerated lock reds the SBOM gate and blocks every PR in the repo.
Token colour rides on top of the diff — only
coloris set per span, soadd/remove backgrounds survive, and a refused edit gets no tokens at all, since
colour is the card's "this happened" signal.
A render budget, not a virtualizer. Rows here are variable-height,
interactive, and hold state; an approval card unmounted from under someone would
break the one reachable exit from a parked run. So the newest N turns render
fully and older tool/fleet/reasoning items fold behind an expandable summary.
Approvals and the composer are never elidable. Cost is O(budget), not O(run) —
tested by tripling the input and asserting under double the DOM.
A gated call now says so. A refused write and a write parked on an approval
rendered identically, though the remedies are opposite — attach a folder vs
approve. Observed live, twice. The card now reads "Needs you" for the call the
decision is about, carries the server's own question, and stamps
data-tool-blockedso a journey need not read copy. No second approve control.Four defects caught before merge
ci-gateswas red — three dark-wiring symbols. No Python changed: a newtest fixture named keys previously invisible to the scan (api-types is
excluded from it), turning "unmentioned" into "mentioned but never read".
Baselined with the reason text their siblings already carry.
workspace_consent.pyasserts"Waiting"over every parked card, and the new copy renames exactly that one. The copy
is better, so the assertion moved.
whole block per model delta on the main thread, so
MAX_HIGHLIGHTED_CHARSwas a frame budget wearing a readability justification: 49 ms at 40k on
tsx, 87 ms on dense TS — ~11 fps while tokens arrive. Now 8k, ~10 ms, still
~135 lines.
written for. Fixed, and pinned by a test verified to fail without the fix.
One correction worth recording
Both verifiers reported the desktop bundle growth (+623 KB) as an unintended
regression. It is not:
syntaxTokens.ts:60-66states the trade in advance andthe grammar list was sized for it, with
htmlandjavascriptdropped for cost.The review caught that the verifiers were wrong. Splitting the desktop renderer
(
splitting: true+outdir) remains available as its own change with afile://load check.Verification
typecheck ×4 green · desktop builds ·
check_dark_wiring0 new · lockfile 2lines · chat-surface 4162 passed, with the same 2 pre-existing failures as a
clean tree (
ChatsArchive's jsdomviewBoxselector;canvasLifecycle'sdeleted Python module).
🤖 Generated with Claude Code