Commit Graph

4472 Commits

Author SHA1 Message Date
kingwl
ea2241c2a9 docs(notes): replace the retired ACP-anchoring analogy with the injection-turn fact
The automation-only ACP refactor (#586) removed the bridge's pendingSwitches
idle-preset anchoring the inheritance note cited as precedent. Replace the
dangling analogy with the load-bearing fact a reviewer actually needs: an
injection-triggered first turn (a SessionStart hook racing the prompt)
dispatches no prompt-submit and no model request, so the one-shot stamp
listener still lands before the child's first model request.
2026-07-26 16:27:35 +08:00
Tianyi Cui
c80fddf7a6 docs(subprocess): final translation pass on the consumer-migration note 2026-07-26 16:16:43 +08:00
kingwl
be5f76b6c6 Merge remote-tracking branch 'origin/master' into feature/subagent-policy-inheritance
# Conflicts:
#	.agents/notes/implemented/feature/2026-07-06-approval-seam.i18n.yaml
#	examples/acp-agent/tests/acp.snapshot.ts
2026-07-26 16:12:38 +08:00
Chinesezjc
cdccf69f4b Merge remote-tracking branch 'origin/master' into fix/intent-draft-sync-echo 2026-07-26 16:05:46 +08:00
Tianyi Cui
3a88912a22 docs: adopt dependencies-over-hand-rolling policy from NIH audit
A repo-wide Not Invented Here audit (ten parallel domain surveys covering
every package group, scripts/, native/, vendor/ edges, python/, test
infrastructure, and CI) asked of each hand-rolled surface whether a
maintained external package or Node builtin deletes it with a net win.

Policy: new implemented process note records that a dependency which
genuinely deletes owned code is a preferred simplification (bar: net
deletion, health, boundary fit, settled seams stay); root AGENTS.md
carries the one-line rule and dsh-find-simplifications now surveys for
hand-rolled-where-a-dependency-exists candidates.

Findings, all bilingual from birth:
- proposed/simplification: eventsource-parser for llm-deepseek SSE,
  node:timers/promises for three hand-rolled sleeps, turndown (or
  minimal 'entities') for tool-web HTML->markdown, gate-script
  consolidation onto mdast/parseArgs/globSync
- proposed/testing: execa + parseArgs + loadEnvFile + vi.waitFor for
  hand-rolled test subprocess plumbing
- proposed/process: pnpm/action-setup for symmetric CI caching
- proposed/feature: evaluate landstrip before building a Windows
  sandbox launcher
- rejected/simplification: ~30 swap verdicts recorded (vscode-jsonrpc,
  p-retry, Ajv, write-file-atomic, msw, hono, better-sqlite3, wireit,
  landstrip-for-linux, YAML consolidation, ...) so the survey is not
  re-litigated from scratch

Also drops the stale prompt/ entry from the AGENTS.md layout map
(workspace instructions live in packages/context/workspace-context).
2026-07-26 15:54:36 +08:00
Tianyi Cui
3c98ade986 docs(subprocess): bilingual pair for the consumer-migration Agent Note
Adds the zh counterpart, aligns the seam note's zh side with its updated
interface bullet and follow-up sentence, records both pairs, and ratchets
the translation-pairing manifest.
2026-07-26 15:51:24 +08:00
_Kerman
3d1fe7b45f Merge remote-tracking branch 'origin/master' into xtr/agent-loop-message-machine
# Conflicts:
#	docs/event-producer-consumer.md
2026-07-26 15:46:29 +08:00
Tianyi Cui
43ff7795ec Merge remote-tracking branch 'origin/master' into web-e2e-interactions 2026-07-26 15:39:57 +08:00
Tianyi Cui
442a3dd884 Merge branch 'code-mode-ui/live-parallel' into code-mode-ui/dispatch-spill
Conflict resolution: drainDispatches composes both sides — the reworked
single-lane driver's drive() (ordered stages, mid-flight commit drain)
followed by this branch's logWork drain, so every shaped settle append
still lands inside the open run_code turn.
2026-07-26 15:31:09 +08:00
Tianyi Cui
3672cd25b4 feat(subprocess): migrate lsp-local, subagent-acp, and the env scrubs onto the seam
Review direction (tianyicui, PR #660): in a stacked PR, change all other
process-running places to use the new service.

- lsp-local: LspConnection spawns through ctx.subprocess (piped protocol
  streams + a no-spill collected stderr tail); its private process-tree
  helpers (POSIX group signalling, Windows taskkill, liveness polling) are
  deleted in favor of the seam's handle verbs, and its buildChildEnv now
  rides scrubbedParentEnv (LSP children also stop inheriting stale DSH_*).
  The plugin injects 'subprocess'; compositions/tests mount
  dsh-subprocess-local.
- subagent-acp: the ACP child spawns through the seam (piped ndjson streams,
  inherited stderr); spawn failure surfaces through done-rejection into the
  same startup race; disposal is handle.dispose with the plugin's configured
  graces. dsh-subagent-subprocess is DELETED — its dispose ladder and scrub
  are the seam's, and the isolated-config-dir helper had no consumer.
- mcp-client, pty-local, sdk-helper: adopt scrubbedParentEnv as the one
  scrub definition (their spawns stay put by ownership: the MCP SDK and
  node-pty own those calls; the SDK wizard runs outside any composition).
- Coverage: per-file 100% over every touched src file, with each v8 ignore
  carrying a platform or contract reason; new suites cover stdio
  dispositions, the dispose ladder tiers, injected-win32 tree semantics,
  waitForExit, settled-kill/terminate no-ops, and spawn-failure disposal.
- Docs: consumer-migration Agent Note (en; zh follows in this PR), seam note
  updated in place, subprocess.md rewritten for the reshaped vocabulary
  (type-equiv re-registered), READMEs and SERVICE_ROLES updated, taskkill
  added to knip ignoreBinaries.
2026-07-26 15:27:59 +08:00
Tianyi Cui
f9cc62266c fix(tools): single ordered driver lane for the sub-dispatch scheduler; validate the cap
Responding to ds-review-bot round 2 on #658 (three critical findings, one
warning — all rooted in the pump/commit split racing ordered stages):

- ONE driver lane now owns every ordered stage: the start append, prepare
  (pre-execute/guards), and the head-of-line commit (post-execute, context
  deferral, settle append). start() is awaited before the next entry can
  start, so concurrent submissions can no longer run pre-execute pipelines
  concurrently; only the around-dispatch/body stage overlaps, matching the
  native loop's fillPool sequencing.
- An exclusive call's barrier now holds through its COMMIT: later starts
  wait for the exclusive pipeline (post-execute included) to finish, the
  native exclusive-group semantics.
- drainDispatches() awaits the driver run itself, so a commit already
  mid-flight when the program returns is drained before run_code closes
  the turn — the settle event and deferred contexts land inside it.
- maxParallelSubCalls is resolved and validated at construction (positive
  integer), so direct construction can no longer wedge the pool with 0.

New tests: overlapping-submission ordered-prepare, barrier-through-commit,
drain-mid-commit, cap rejection. 96 keyless snapshots replay unchanged;
Agent Note updated (both languages).
2026-07-26 15:26:52 +08:00
Chinesezjc
8ee172de9d Merge remote-tracking branch 'origin/master' into feat/todo-multi-in-progress 2026-07-26 15:22:19 +08:00
Chinesezjc
9ef532ea34 Merge remote-tracking branch 'origin/master' into fix/intent-draft-sync-echo 2026-07-26 15:22:07 +08:00
Tianyi Cui
b4d032c1a2 docs: make bilingual pairing universal 2026-07-26 15:06:51 +08:00
Tianyi Cui
df8756ccf5 Merge remote-tracking branch 'origin/master' into worktree/i18n-complete-non-readme
# Conflicts:
#	packages/client/i18n/README.md
#	packages/client/locale/README.i18n.yaml
#	packages/client/locale/README.zh.md
#	packages/client/ui-layout/README.md
#	packages/client/ui-theme/README.md
2026-07-26 14:37:46 +08:00
_Kerman
fc8d339bf0 fix(acp): settle admission-blocked and retried prompts after the merge
The automation bridge inherited two master-era assumptions the message
machine no longer honors. A prompt blocked at pre-turn admission opens no
turn, so no turn/end could ever settle it — the bridge now watches
whenIdle() and reports a turnless slot as cancelled (the disposed-agent
guard moved to a registry identity check before send). A failed turn no
longer rejects at its turn/end either: agent.retry() closes the failed
turn and opens a successor on the same history, so the bridge holds the
terminal error and lets a retry-triggered turn/start adopt the prompt,
rejecting only at quiescence with no successor.

Also: refresh the empty-response-retry fixture for retry-as-turn logging,
adapt master-side tests to the unified send()/UserMessageData API and
registry-fact disposal, resync the doc pairs both sides touched, trim
architecture.md back under its word ceiling, and regenerate the event and
persistence catalogs.
2026-07-26 14:29:30 +08:00
Yichen Jiang
05a3cac76b Merge remote-tracking branch 'origin/worktree/llm-reasoning-effort' into worktree/llm-reasoning-effort 2026-07-26 14:23:50 +08:00
Yichen Jiang
ac792bfd78 fix(llm): honor model metadata cancellation and defaults 2026-07-26 14:23:06 +08:00
Tianyi Cui
835156b038 fix(ui-trajectory): timing provenance on sub-span lanes; assembled snapshot for both views
Responding to ds-review-bot on #664:

- SubSpanLane gains a 'timing' discriminant (measured | running | unknown).
  A settle-only replay entry (callTime null, start outside the window) was
  previously indistinguishable from a measured 0 ms span; it now renders
  hollow with a 'duration unknown' hover title, and durationMs stays null
  for anything unmeasured. Pairs with the client-runtime fix that stopped
  fabricating callTime = settle time (826c3696a on the live-parallel PR).

- The built-client Code Mode fixture snapshot now switches to the
  Trajectory and Waterfall tabs and pins the assembled rendering: three
  Sub cells with real +0.8s durations and three measured lanes with their
  hover titles — product-visible coverage through the real bundle graph,
  not just package-level jsdom fixtures.

Agent Note (both languages) updated for the timing contract; pairing
re-recorded.
2026-07-26 14:20:59 +08:00
Tianyi Cui
f936fea4a1 Merge remote-tracking branch 'origin/master' into web-e2e-interactions 2026-07-26 14:19:06 +08:00
Tianyi Cui
e678db440e fix(subprocess): finish the rename in current-state docs and graph inputs
Codex re-review (A): AGENTS.md layout tree, the architecture capability
tables (en+zh), the seam Agent Note's group-name sentence (en+zh), and the
SERVICE_ROLES entry still carried process/-era labels; regenerated the doc
graphs and config catalog from the corrected inputs.
2026-07-26 14:10:46 +08:00
Yichen Jiang
8c77ba6420 Merge remote-tracking branch 'origin/master' into worktree/web-model-request-retry 2026-07-26 14:09:43 +08:00
Yichen Jiang
a430207427 feat(web): retry transient model requests 2026-07-26 14:09:31 +08:00
_Kerman
57d90c343d Merge remote-tracking branch 'origin/master' into xtr/agent-loop-message-machine
# Conflicts:
#	.agents/notes/implemented/feature/2026-06-14-acp-agent-client-protocol.md
#	.agents/notes/implemented/feature/2026-06-14-acp-agent-client-protocol.zh.md
#	.agents/notes/implemented/feature/2026-06-30-hook-bridges.i18n.yaml
#	.agents/notes/implemented/feature/2026-06-30-interception-seams.i18n.yaml
#	.agents/notes/implemented/feature/2026-07-06-sandbox.i18n.yaml
#	.agents/notes/implemented/feature/2026-07-06-sandbox.md
#	.agents/notes/implemented/feature/2026-07-06-sandbox.zh.md
#	.agents/notes/implemented/feature/2026-07-19-model-facing-goal-tools.i18n.yaml
#	.agents/notes/implemented/feature/2026-07-19-same-session-goal-round-driver.i18n.yaml
#	.agents/notes/implemented/feature/2026-07-25-workspace-ui-product-flow.i18n.yaml
#	.agents/notes/implemented/simplification/2026-07-02-remove-stream-chunk-mirror.i18n.yaml
#	docs/architecture.i18n.yaml
#	docs/cookbook/adding-a-tool.i18n.yaml
#	docs/cookbook/extension-cookbook.i18n.yaml
#	docs/core-data-structures/llm-streaming.i18n.yaml
#	docs/core-data-structures/session.i18n.yaml
#	docs/core-data-structures/tools.i18n.yaml
#	docs/event-producer-consumer.md
#	docs/persistence-catalog.md
#	examples/acp-agent/tests/snapshots/cordis-inspect-jsdoc/stdout.expected.jsonl
#	examples/acp-agent/tests/snapshots/escalation-approved/session.jsonl
#	examples/acp-agent/tests/snapshots/escalation-rejected/session.jsonl
#	examples/acp-agent/tests/snapshots/fs-escalation-approved/session.jsonl
#	examples/acp-agent/tests/snapshots/hook-cc-pretool-ask/session.jsonl
#	examples/acp-agent/tests/snapshots/permission-switching/session.jsonl
#	examples/acp-agent/tests/snapshots/plan-mode-reject/session.jsonl
#	examples/acp-agent/tests/snapshots/plan-mode/session.jsonl
#	examples/acp-agent/tests/snapshots/session-sandbox-root/session.jsonl
#	packages/context/session-reference/README.md
#	packages/core/agent-loop/tests/agent.spec.ts
#	packages/hooks/hooks-claude/tests/coverage-cases.ts
#	packages/host/runtime/tests/host-runtime.spec.ts
#	packages/llm/llm-retry/tests/retry.spec.ts
#	packages/session-persistence/session-persistence/src/coordinator.ts
#	packages/support/acp-snapshot/README.md
#	packages/support/acp-snapshot/src/normalize.ts
#	packages/ui/acp/acp-feature-support.md
#	packages/ui/acp/src/codec.ts
#	packages/ui/acp/src/index.ts
#	packages/ui/acp/tests/bridge.spec.ts
#	packages/ui/acp/tests/codec.spec.ts
#	packages/ui/acp/tests/config-options.spec.ts
#	packages/ui/acp/tests/dispose.spec.ts
#	packages/ui/acp/tests/edges.spec.ts
#	packages/ui/acp/tests/stream-update.spec.ts
#	packages/ui/acp/tests/turns.spec.ts
2026-07-26 14:05:33 +08:00
Yichen Jiang
65aaf2eb98 Merge branch 'master' into worktree/llm-reasoning-effort 2026-07-26 14:03:34 +08:00
Yichen Jiang
8b34ccd994 chore(tui): remove temporary Anthropic test overlay 2026-07-26 14:00:37 +08:00
Yichen Jiang
15d6f4c085 feat(llm-deepseek): expose off as a dynamic reasoning effort 2026-07-26 13:42:02 +08:00
Tianyi Cui
030973e4ab Merge branch 'master' into worktree/i18n-complete-non-readme 2026-07-26 13:31:20 +08:00
Yichen Jiang
970f893d6b feat(tui): add pi-ai Anthropic example 2026-07-26 13:30:01 +08:00
imccyu
0fe9ff888d Merge origin/master into worktree-websettings
ui-sidebar shell landed on master (#643: geometry-only shell, the
browsing region moved to the sidebar.workspaces slot); this branch's
sidebar.settings foot seat re-applies on top — the hardcoded foot row
becomes the seat, the seat rides the railIn crossfade, and the shell
spec's renderSlot stub key-splits region vs settings.
2026-07-26 13:15:57 +08:00
Yichen Jiang
0d86cbcd0c Merge remote-tracking branch 'origin/master' into worktree/web-session-model-selector 2026-07-26 13:14:59 +08:00
Yichen Jiang
cba0948604 Merge remote-tracking branch 'origin/master' into worktree/web-session-model-selector
# Conflicts:
#	.agents/notes/implemented/architecture/2026-07-15-llm-model-catalog-and-acp-selection.i18n.yaml
#	.agents/notes/implemented/architecture/2026-07-23-client-plugin-loading-model.i18n.yaml
#	apps/cli/src/web.ts
#	apps/web/tests/session-title.snapshot.ts
#	apps/web/tests/smoke-fixture.e2e.ts
#	packages/client/connection/src/client/api.ts
#	packages/client/connection/src/client/fixture.ts
#	packages/client/connection/src/client/index.ts
#	packages/client/runtime/src/client/index.ts
#	packages/client/runtime/src/client/sessions/conversation.ts
#	packages/client/runtime/src/client/sessions/session.ts
#	packages/client/runtime/tests/fake-api.ts
#	packages/client/ui-conversation/src/client/contract/slots.ts
#	packages/client/ui-conversation/src/client/index.ts
#	packages/client/ui-conversation/src/client/skeleton/ConversationRoot.tsx
#	packages/client/ui-conversation/src/client/skeleton/InputBar.module.css
#	packages/client/ui-conversation/src/client/skeleton/InputBar.tsx
#	packages/client/ui-conversation/tests/chat-stats-bash-sample.spec.tsx
#	packages/client/ui-conversation/tests/chat-toolview-slot.spec.tsx
#	packages/client/ui-conversation/tests/chat-view.spec.tsx
#	packages/client/ui-conversation/tests/gate-branch-tails.spec.tsx
#	packages/client/ui-conversation/tests/skeleton-branches.spec.tsx
#	packages/client/ui-conversation/tests/skeleton.spec.tsx
#	packages/host/apiproxy/README.md
#	packages/host/apiproxy/src/api-proxy.ts
#	packages/host/apiproxy/src/api/rpc.schema.ts
#	packages/host/apiproxy/src/api/rpc.ts
#	packages/host/apiproxy/tests/api-proxy-models.spec.ts
#	packages/host/apiproxy/tests/rpc-schemas.spec.ts
#	packages/host/runtime/README.md
#	packages/llm/llm-deepseek/README.md
#	scripts/translation-pairing.manifest.json
#	tsconfig.client.json
2026-07-26 13:13:53 +08:00
Yichen Jiang
eeab643ad9 Merge remote-tracking branch 'origin/master' into worktree/llm-reasoning-effort
# Conflicts:
#	docs/architecture.i18n.yaml
#	docs/config-catalog.md
2026-07-26 13:13:31 +08:00
Tianyi Cui
4b06e9df99 Merge remote-tracking branch 'origin/master' into web-e2e-interactions 2026-07-26 13:08:39 +08:00
Yichen Jiang
73e7e27799 refactor(llm): resolve model metadata together 2026-07-26 13:07:27 +08:00
Tianyi Cui
8d078d7f64 Merge branch 'master' into worktree-ws-more 2026-07-26 13:01:36 +08:00
Tianyi Cui
ea1d8d06b3 test(web): pin every scenario end-state with an aria golden
Every spec now commits at least one golden and the interactive ones one
per distinct end-state (nine new .expected.md):

- live-interactions: cancel.expected.md (frozen partial + 已停止 marker),
  error-auth.expected.md (the prompt bubble alone — the committed artifact
  of the web-error-surface gap, the diff that flips when error rendering
  lands), retry.expected.md (indistinguishable from a clean completion —
  retries are deliberately invisible in the transcript).
- question-composer: answered.expected.md (the question resolved into its
  tool round trip plus the final reply, takeover gone) beside the existing
  waiting-state golden.
- steering: mid-steer.expected.md pins the accepted-but-INVISIBLE state
  (the loop drains steering only at the step boundary, so no interjection
  bubble exists while the question still blocks — if the client ever
  renders pending steers eagerly, this golden flips first) and
  settled.expected.md the badged bubble plus obeying reply.
- navigation-panes: waterfall.expected.md and details-open.expected.md
  (tool-name header, Input args, Output result) beside the trajectory one.
- lifecycle-chrome: reloaded.expected.md — rendering the same settled
  transcript from persistence alone IS the recovery claim.

Fixture inventories extended to the new closed sets; the Agent Note's
expected-outputs policy updated in both languages (per-end-state goldens
for interactive scenarios), pairing re-recorded.
2026-07-26 12:45:44 +08:00
Tianyi Cui
fc566119a7 refactor(subprocess): rename the process seam to subprocess and address review
Review feedback (tianyicui): 'process' is a poor service name. The family is
now packages/subprocess/ — @deepseek-ai/dsh-subprocess (ctx.subprocess,
abstract SubprocessService, Subprocess* vocabulary) and
@deepseek-ai/dsh-subprocess-local (LocalSubprocessService) — renamed
throughout code, compositions, docs (en+zh, pairs re-recorded), catalogs,
and gates. 'subprocess' is the precise term for managed OS children (the
Python-stdlib sense), avoids colliding with Node's global process object,
and reads as one system beside dsh-subagent-subprocess.

ds-review-bot findings addressed:
- kill() on a settled handle is now a no-op (no signal to a possibly-reused
  pgid, no referenced grace timer delaying exit); pinned by a spy test.
- The moved DshEnvironmentKey/DshEnvironment/CollectedOutput types get
  drift-checked type-equiv blocks on the new subprocess.md page, restoring
  their manifest registration.
- subprocess.md is registered in the core.md sub-page index (en+zh).
2026-07-26 12:43:59 +08:00
imccyu
7e20322c40 docs(notes): retitle the rejected alternative as per-feature satellite packages
The rejected shape is a settings satellite per feature; the ownerless
copy stays with ui-settings-general, which carries no feature surface.
2026-07-26 12:43:17 +08:00
imccyu
a04a223bab refactor(gui): copy-free settings shell; ui-settings-general owns ownerless copy
The shell is now a pure composition face: no dictionaries, no locale
dependency, and three new chrome content seats (settings.trigger /
settings.header / settings.close) whose slot content also carries the
accessible names (trigger text, dialog aria-labelledby, visually hidden
close label). ui-settings-general returns as the owner of copy that
belongs to no single feature: chrome content, the General section with
its item slot, and the settings dictionaries. Slot types split homes —
trigger/header/close/section live in the shell contract; the
settings.general.item entry moves to the locale package (the common
dependency of every item registrant), with ui-theme consuming it
through a re-export seam; the verbatim duplicate merges are gone and
the dependency graph is a clean DAG.
2026-07-26 12:40:17 +08:00
Tianyi Cui
8f75565f03 Merge tasks-seam diagnostics fix into the subprocess branch 2026-07-26 12:21:13 +08:00
Tianyi Cui
1bc090fe00 fix(tasks): producer diagnostics name the seam, not one implementation
Review feedback (tianyicui, PR #657 inline): the missing-service message
should mention dsh-tasks, which defines ctx.tasks, rather than promoting a
specific backend. The seam's own surfaces (README, the direct-mount fence)
keep pointing at implementations, so the pointer chain still lands on
dsh-tasks-local without the producer strings going stale when another
backend becomes the recommended default. Agent Note updated accordingly
(en+zh, re-recorded).
2026-07-26 12:17:45 +08:00
imccyu
9a4be33899 docs(notes): record slot-declaration-as-service as future work
deferRegistration() stays the shipped form; the note pins the follow-up
direction (bridge declarations into slot:<name> services, migrate
registrants to nested ctx.inject, delete the helper) and the boundaries
a separate PR must settle.
2026-07-26 12:09:38 +08:00
Tianyi Cui
a976a3e64a Merge remote-tracking branch 'origin/master' into worktree/i18n-complete-non-readme 2026-07-26 12:08:40 +08:00
Tianyi Cui
113f818084 Merge remote-tracking branch 'origin/master' into web-e2e-interactions 2026-07-26 12:03:02 +08:00
_Kerman
8432c68b6a docs: sync bilingual pairs and static gates with the message-machine refactor
The branch edited the English side of 17 doc pairs without their Chinese
counterparts. Bring every .zh.md up to date (loop.ts references now point
at agent.ts, send/steer/inject unification, context/message folded into
user/message, HookContext replaced by UserMessageData in tool decision
blocks, plan/skill delivery moved to agent/step) and re-record the pairing
hashes. Deduplicate type-equiv.manifest.json entries duplicated by the
master merge and drop entries for symbols the refactor removed. Complete
the missing JSDoc on extractSnapshotSpillPaths.
2026-07-26 11:48:06 +08:00
imccyu
08251eb180 Merge branch 'master' into worktree-ws-more 2026-07-26 11:20:05 +08:00
imccyu
15c0b6290b docs(notes): state the rejected per-section split without implementation history 2026-07-26 11:18:46 +08:00
Tianyi Cui
e715d6cc59 feat(web): Code Mode sub-calls in the trajectory and waterfall views
Trajectory: the layout fold interleaves one subtool cell per sub-dispatch
after its parent Tool cell (assistant-block calls, orphan results, and
running calls alike), indexes sequential across the interleave; settled
durations come from the start/settle pair, running sub-calls show the
em dash. New Sub tag (business tint) + 28px indent.

Waterfall: deriveSubSpans folds the dispatch index into per-turn lanes
with REAL wall time — each parent's window is first start → last settle
and every lane's offset/width is its fraction of it, so parallel
sub-calls visibly overlap; running lanes extend to the window end at
reduced opacity. Lanes draw under the owning turn row.

Both views read codeDispatches through the standard snapshot hook; no
new wire data, replay renders identically to live. Specs pin interleave
order, durations, the running arms, window fractions, and the rendered
lane.
2026-07-26 10:48:33 +08:00
Tianyi Cui
b25a60c0a6 Merge branch 'code-mode-ui/dispatch-spill' into code-mode-ui/shiki 2026-07-26 10:22:15 +08:00