Commit Graph
3872 Commits
Author SHA1 Message Date
Dudu-0223 d28527b91f fix(snapshot): preserve fresh cwd aliases 2026-07-27 15:46:40 +08:00
Yichen Jiang 7da7b182c9 fix: refresh model target after reconnect 2026-07-27 15:45:06 +08:00
imccyu b8d7938498 Merge branch 'master' into markdown-ui 2026-07-27 15:44:30 +08:00
imccyu 0a7c8a284d chore 2026-07-27 15:44:10 +08:00
Yichen Jiang 181ac52f8e Merge remote-tracking branch 'origin/master' into worktree/web-session-model-selector
# Conflicts:
#	packages/client/connection/src/client/fixture.ts
#	packages/client/runtime/README.i18n.yaml
#	packages/client/runtime/tests/fake-api.ts
#	packages/client/runtime/tests/session.spec.ts
#	packages/client/ui-conversation/README.i18n.yaml
#	packages/client/ui-conversation/README.md
#	packages/client/ui-conversation/README.zh.md
#	packages/host/apiproxy/README.i18n.yaml
2026-07-27 15:41:01 +08:00
Tianyi Cui 9c53cd7d07 test: stabilize timing-sensitive terminal checks 2026-07-27 15:33:36 +08:00
Tianyi Cui f6de42a886 Merge remote-tracking branch 'origin/master' into worktree/pr674-retarget-20260727 2026-07-27 15:30:30 +08:00
Yichen Jiang c3dfed668d Merge branch 'master' into worktree/llm-reasoning-effort 2026-07-27 15:30:00 +08:00
Chinesezjc ebce590bee Merge remote-tracking branch 'origin/master' into pr720 2026-07-27 15:28:46 +08:00
Dudu-0223 5eca318cdc fix(snapshot): preserve volatile id correlations 2026-07-27 15:25:50 +08:00
imccyu b241d4332c Merge branch 'master' into markdown-ui 2026-07-27 15:23:13 +08:00
Dudu-0223 82637524a3 fix(snapshot): stabilize refresh volatiles 2026-07-27 14:58:38 +08:00
imccyu 8605099282 fix: model selector width 2026-07-27 14:54:27 +08:00
NI0317 7bd96af5eb fix(workspace): make deletion recoverable 2026-07-27 14:37:04 +08:00
Chinesezjc 87c1b37dce Merge branch 'fix/pty-raw-ready-wait' into fix/pty-handoff-grace 2026-07-27 14:35:32 +08:00
Chinesezjc a5c820ea3a Merge remote-tracking branch 'origin/master' into fix/pty-handoff-grace 2026-07-27 14:15:11 +08:00
Chinesezjc f35c18f7e6 fix(pty): make the foreground-handoff grace a config field
The local PTY readiness poll held its inferred_idle fallback for exactly
one pollIntervalMs after a prompt marker, so a bash foreground handoff
that lands on the silence boundary only wins the exact stdin_read
attribution when the kernel publishes it inside that single poll. On a
slow or loaded host it does not, and the attribution flips.

handoffGraceMs replaces the hardcoded one-poll window as a validated,
deployment-owned config field defaulting to 500ms, rejected at load when
it cannot contain one readiness poll. Real-shell tests that interrupt a
send now assert the session is usable again rather than which readiness
tier observed the handoff, because no fixed grace removes the race.
2026-07-27 14:14:59 +08:00
Chinesezjc d3d66926fb fix(code-runtime): reject a maxWallMs above Node's maximum timer delay
`config.maxWallMs` is only checked for positivity, and it is handed to
`setTimeout`, which clamps any delay above 2^31-1 ms to 1 ms. A deployment
configuring a 25-day wall ceiling therefore gets the opposite of what it asked
for: every run times out on the first tick. The runtime now range-checks the
field at load against MAX_TIMER_DELAY_MS from dsh-timeout and throws, so the
misconfiguration fails loud where it is self-contained instead of silently
inverting the budget.

`computeMs` needs no matching bound: it is compared against measured event-loop
utilization rather than fed to a timer.

The test asserts both the rejection and that the boundary value itself loads.
2026-07-27 14:01:15 +08:00
kingwl 10bb6dc4fe docs(policy): align every precedence statement with the override chain
Review fix (ds-review-bot on #623): the READMEs and JSDoc still stated the
pre-baseline formulas — resolve() outranking 'the session's last
sandbox/mode event', 'effective = explicit grant ?? fold(events) ??
deployment default', and the approval README's 'last approval/policy event'
opener — which contradict the shipped semantics for a delegated fork whose
seed tail differs from its header baseline. Every statement now names the
override chain (own post-seed switches ?? inherited header baseline): both
READMEs (both languages), resolve()'s JSDoc, the session-mode module and
event-declaration docs, the raw folds re-scoped as building blocks, and
the regenerated catalogs.
2026-07-27 13:45:09 +08:00
Chinesezjc e56afd718d test(pty-local): keep the raw-mode send active until python3 prints its marker
The darwin-parity job failed intermittently on the SIGINT test with the
operation buffer holding only the echoed command line, never RAW_READY. The
harness sets idleSilenceMs to 250, so when a cold python3 start stays silent
past that bound the send settles as inferred_idle; PtySendOperation.append then
drops all later output, and the marker reaches only the scrollback.

Give the harness per-test idleSilenceMs/timeoutMs overrides and let this
scenario raise both above interpreter startup latency, so the readiness marker
lands inside the send it belongs to. waitForOutput's own deadline and the test
timeout grow to match the new bounds.

The product timings are unchanged; the pty Agent Note records why a test that
waits on an operation must outlast the child's startup.
2026-07-27 13:45:04 +08:00
imccyu 3b04941830 Merge the concurrent selector adaptation; ui-model stays the model owner
The remote side re-merged master (i18n workflow round) and restored the
pre-architecture ModelSelector package with the Session-side state
machine. Reconciliation keeps that merge's master content and reasserts
this branch's model architecture: business state lives in ui-model's
shared per-session directory (ctx.models), not on Session/
ConversationSnapshot; the input.model seat entry and the /model popup
stay the two same-source entries; the history modelTarget piggyback stays
removed. The ui-model-selector package, its roster row, and its allowlist
entry go; the smoke-real roster names ui-model.
2026-07-27 13:36:25 +08:00
Yichen Jiang 21aeff3029 Merge remote-tracking branch 'origin/master' into worktree/llm-reasoning-effort
# Conflicts:
#	.agents/notes/implemented/testing/2026-07-24-web-gui-browser-e2e-lane.i18n.yaml
#	docs/config-catalog.md
#	docs/core-data-structures/session.i18n.yaml
#	scripts/type-equiv.manifest.json
2026-07-27 13:35:10 +08:00
Turtle a7a369a7be chore(llm): bump pi-ai to 0.82.1 2026-07-27 13:25:45 +08:00
Tianyi Cui 73d2a787a7 Merge branch 'master' into nih-imp-sse 2026-07-27 13:13:57 +08:00
imccyu 3025a324cd Fix the setEffort arrow shorthand lint finding 2026-07-27 13:10:32 +08:00
imccyu 72717b7b78 Two-level model/effort selection per the MenuDropdown mock
The seat's dropdown follows figma 496:26454: the root pane is the
Model / Effort cell pair (14/22 label, value in the tertiary tone, right
chevron), each drilling into its own list — the provider-grouped model
list over the shared directory, and the High/Max effort levels. The
trigger (313:14108) shows both values: model name plus effort in the
caption tone. Effort is a client-local display echo on the shared
directory state for now — the design pairs the two as one selection, but
no wire carries a per-session effort override yet (the deepseek adapter's
reasoningEffort is deployment config); the directory state documents that
boundary, so wiring it later is a submit-path change, not a UI one.
Escape backs out of a drilled pane before closing.
2026-07-27 13:01:47 +08:00
07akioni 0d2a8a3090 Merge branch 'master' into markdown-ui 2026-07-27 12:59:37 +08:00
07akioni 55fc87a7a0 fix: cr 2026-07-27 12:58:20 +08:00
Tianyi Cui a70923ba21 fix(session-checkpoint-policy): fail fast on an impossible crash marker
vi.waitFor retries every callback throw, so the mismatch branch inside
the callback waited the full 30s deadline for a fixture that writes the
marker once and cannot recover. Terminal states (complete marker, or
content that can no longer become the expected marker) now resolve out
of the retry loop and the mismatch throws after it, restoring the old
loop's immediate failure.
2026-07-27 12:51:47 +08:00
Tianyi Cui 109b469a7e fix(tool-web): bound conversion depth and complete fetch output
Two review findings on the turndown swap, both verified empirically:

- Unclosed-tag nesting makes the synchronous turndown/domino walk
  superlinear (measured: depth 512 ~0.15s, 2k ~2s, 20k ~5s), during
  which the cooperative fetchTimeoutMs timer cannot fire. renderBody
  now preflights nesting depth with a linear tag scan and passes
  bodies past 512 levels through raw; the try/catch stays for markup
  the scan cannot see (comment-hidden tags), simulated in tests via a
  converter throw.
- Markdown escaping can expand converted HTML ~2x (100k underscores
  render as 200k chars), so provider body caps no longer bounded the
  model-visible result. formatFetchOutput now caps the complete output
  (header + body + footer) under new fetchMaxOutputChars config
  (default 200000 = 2x the local provider's default body cap), reusing
  the truncation notice.

README EN+ZH, config catalog, Agent Note EN+ZH updated; the new
web-fetch fixture is migrated to the packed layout master now
requires; tool-web coverage stays 100% per-file.
2026-07-27 12:41:36 +08:00
NI0317 187cf6f804 feat(web): delete workspace registrations 2026-07-27 12:38:11 +08:00
Chinesezjc 710a3b1686 docs(ui-conversation): document the two todo registrations in the owning README pair
The todo row and the todo plan strip were registered without a contract in this
package's README, which still described only the bash sample. Both sides now
carry the two registrations: TodoRow's `todo_write` toolview key with its
attempted-write summary and non-ok dot semantics, and TodoDock's
`conversation.input.dock` entry at `order: -1` with the dock-owned selection,
empty-hidden panel, collapse behavior, and the composer-takeover consequence
that hides the whole dock. README.i18n.yaml re-recorded.
2026-07-27 12:20:17 +08:00
Yichen Jiang bde5e26a96 Merge remote-tracking branch 'origin/master' into worktree/web-session-model-selector
# Conflicts:
#	apps/cli/package.json
#	apps/web/tests/smoke-real.e2e.ts
#	apps/web/tests/snapshots/fresh-round-trip/ui.expected.md
#	apps/web/tests/snapshots/seeded-history/ui.expected.md
#	docs/config-catalog.md
#	packages/client/connection/tests/fake-api.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/apply.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.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/input-bar.spec.tsx
#	packages/client/ui-conversation/tests/skeleton.spec.tsx
#	packages/host/apiproxy/README.md
#	packages/host/apiproxy/src/api-proxy.ts
#	pnpm-lock.yaml
#	scripts/verify-package-readme-model-experience.ts
#	tsconfig.base.json
2026-07-27 12:17:38 +08:00
imccyu b4476d24fe Settle the local gates for the model-selector round
- ui-model README pair (short-form Model Experience + audited registry
  entry + Known Limitations), recorded in the pairing manifest
- llm-deepseek README pair rebased onto master's version with this PR's
  real deltas (friendly names, 256k, selector consumers) on both sides;
  runtime/ui-conversation READMEs revert to master (their sections
  documented the removed Session state machine and control slot)
- config catalog regenerated for the ui-model roster row
- ModelDirectory.store JSDoc; ui-model files join the TODO(gui) coverage
  deferral lane beside their ui-command/ui-slash siblings
2026-07-27 12:11:54 +08:00
Chinesezjc d2bb2a809b fix(web-todo): dock-owned selection, keyboard-openable row, documented tail todos field
Three ds-review-bot round-8 findings on the todo display surfaces.

TodoPanel took the whole `useSession` hook and cast the snapshot to reach
`todos`, which put slot plumbing and an unchecked cast inside the presentation
component. The panel now takes `todos: readonly TodoItem[]`; TodoDock does the
selecting, matching the QueueDock posture the dock slot already establishes.

The todo row carried `onClick` with no keyboard route, so its details panel was
mouse-only. It now takes ToolRow's route verbatim: `role="button"`,
`tabIndex={0}`, and an Enter/Space handler that claims the event. The row stays
a `<div>` because a `<button>` flattens its inline spans.

`session.history`'s tail-only `todos` field was documented at the TS signature
but not in the apiproxy README pair, and the Agent Note claimed the feature
added no new wire vocabulary. Both README sides now state the tail/omission
semantics (an omitted field on a tail response is the empty plan, not unchanged
state), and the note records the one added field instead of denying it.

Tests: TodoPanel specs render the plain list; new TodoDock specs cover selection,
live follow, rollback-to-empty, and the registration shape; a new row spec pins
Enter/Space activation and non-activating keys.
2026-07-27 12:08:46 +08:00
07akioni 3ee2982f85 optimize chat ui 2026-07-27 12:04:12 +08:00
_Kerman d9874ae10c Merge branch 'master' into xtr/agent-loop-message-machine 2026-07-27 11:52:03 +08:00
imccyu ae0b0cc49b Fix lint findings and calibrate the seat trigger to the figma mock
- unused SessionId import and an unnecessary assertion in ui-model
- two over-length fake-api lines split
- trigger chrome calibrated against figma 313:14108's ToggleButton
  (13/20 medium secondary at 28px; chevron in label-caption = the mock's
  #ADB2B8; the mock's leading icon is invisible there, so the seat has
  none, and its 'High' effort text has no wire concept to render)
2026-07-27 11:46:39 +08:00
Chinesezjc 8ebdad5076 reset the plan when a tail history response omits the todo projection
An omitted `todos` on a tail request was treated as "no projection carried"
and preserved the prior value. Every installWindow caller is a tail request
(doOpen, its gap re-pull, repairGap; loadOlder prepends without it), which the
host answers with the full-log projection or omits only when the log holds no
todo/write — so the field's absence is the authoritative empty list. A live
write whose host crashed before persisting therefore left the rolled-back plan
on screen indefinitely; the assignment now clears it on the next open or
resync. Widened the parameter to an explicit `| undefined` so the two meanings
cannot be conflated again, and updated the JSDoc at both declaring seams plus
the bilingual README/note pair.
2026-07-27 11:41:26 +08:00
Tianyi Cui 38a05724f4 Merge remote-tracking branch 'origin/master' into worktree-process-service-seam
# Conflicts:
#	apps/cli/package.json
2026-07-27 11:36:03 +08:00
Tianyi Cui eaa9ced271 Merge remote-tracking branch 'origin/worktree-process-service-seam' into subprocess-simpl/d-one-env-channel
# Conflicts:
#	docs/cordis-catalog/services.md
#	docs/core-data-structures/subprocess.i18n.yaml
#	packages/lsp/lsp-local/src/connection.ts
#	packages/subagent/subagent-acp/README.i18n.yaml
#	packages/subprocess/subprocess-local/README.i18n.yaml
#	packages/subprocess/subprocess-local/src/spawn.ts
#	packages/subprocess/subprocess/README.i18n.yaml
#	packages/subprocess/subprocess/README.md
#	packages/subprocess/subprocess/README.zh.md
#	packages/subprocess/subprocess/tests/service.spec.ts
2026-07-27 11:31:38 +08:00
imccyu 190e49356f Revive the composer model selector on the named input.model seat
The original ModelSelector returns as the conversation.input.model seat
occupant (the named single slot the composer bar renders before its primary
button), alongside — not instead of — the /model popup. Both entries are
projections of ONE per-session directory owned by the new ModelService
(ctx.models): the same session.models load, the same selectModel submit,
the same host-reported current — a switch in either entry is what the
other shows next, asserted both ways in the plugin spec.

Trigger chrome follows figma 313:14108's composer ToggleButton (13/20
medium secondary label, 4px gap, caption chevron, 28px chip height
matching the sibling Plan/Read-only selects); the menu keeps the original
upward provider-grouped single-select with keyboard navigation. The
seat honors the owner locked bit as its disabled state.
2026-07-27 11:27:49 +08:00
kingwl 50d759c888 Merge remote-tracking branch 'origin/master' into feature/subagent-policy-inheritance
# Conflicts:
#	packages/core/session/README.i18n.yaml
#	packages/session-persistence/session-persistence-jsonl/README.i18n.yaml
#	packages/session-persistence/session-persistence-jsonl/README.md
#	packages/session-persistence/session-persistence-jsonl/README.zh.md
2026-07-27 11:26:39 +08:00
Tianyi Cui cc2f15a83d Merge remote-tracking branch 'origin/worktree-process-service-seam' into subprocess-simpl/c-one-termination-verb
# Conflicts:
#	.agents/notes/implemented/architecture/2026-07-26-subprocess-consumer-migration.i18n.yaml
#	.agents/notes/implemented/architecture/2026-07-26-subprocess-consumer-migration.md
#	.agents/notes/implemented/architecture/2026-07-26-subprocess-consumer-migration.zh.md
#	docs/cordis-catalog/services.md
#	docs/core-data-structures/subprocess.i18n.yaml
#	docs/core-data-structures/subprocess.md
#	docs/core-data-structures/subprocess.zh.md
#	packages/cordis/tool-cordis/src/api-catalog.ts
#	packages/subprocess/subprocess-local/README.i18n.yaml
#	packages/subprocess/subprocess-local/README.md
#	packages/subprocess/subprocess-local/README.zh.md
#	packages/subprocess/subprocess/README.i18n.yaml
#	packages/subprocess/subprocess/README.md
#	packages/subprocess/subprocess/README.zh.md
#	packages/subprocess/subprocess/src/index.ts
2026-07-27 11:22:21 +08:00
imccyu f2a9f4a40e retire the stale ACP plan-mapping claim in the todo note
The automation-only ACP bridge deliberately omits todo presentation (its
edge test asserts plan updates are omitted; the todo-write tool note records
the mapping's retirement). Chinese counterpart updated, pair re-recorded;
the TodoPanel header comment drops the same claim.
2026-07-27 10:43:49 +08:00
imccyu 35ce35d8a6 Merge branch 'master' into web2-todo 2026-07-27 10:37:34 +08:00
_Kerman 1e534d6482 docs: refresh generated graph, re-record i18n pairs, unfreeze archived notes
Regenerate event-producer-consumer.md after the queued-frame steering removal;
re-record the bilingual consistency records the master merge left stale; and
restore the eight archived notes the agent-loop rename had swept up (archived
notes are frozen — their archival-time path references stand).
2026-07-27 10:32:40 +08:00
imccyu c132cbdb6a Adapt session model selection to the slash/input/session architecture
- host trio kept on the merged api-proxy: session.models (provider-grouped
  advisory directory), session.selectModel (validated provider, advisory
  model), installAgentLlmTarget threaded through create/resume/ensureSession;
  the gateway declares the llm inject it reads
- history no longer piggybacks modelTarget: the current target travels on
  session.models alone (the /model popup is the sole consumer)
- new @deepseek-ai/dsh-client-ui-model plugin: /model popupSelect over the
  wire — options load the directory (group label in the detail column,
  provider-local failures listed inline), onSelect routes selectModel;
  failures ride the popup shell's error/retry surface
- ModelSelector package, conversation.composer.control slot, and the
  Session-side modelSelection state machine are removed: model selection
  belongs to the /model popup; the named conversation.input.model seat
  stays empty until a control-seat entry is designed for it
2026-07-27 10:28:45 +08:00
imccyu 8d1a3b89c7 fix runtime README pairing record left with merge conflict markers
The master merge committed the i18n.yaml with unresolved conflict hunks
(carried over from the adapt branch's own master merge); re-recorded via
verify-translation-pairing --write. 518 pairs consistent.
2026-07-27 10:25:12 +08:00
imccyu 6539c8d8fa Merge master (slash/input/session architecture) into web-session-model-selector 2026-07-27 10:23:51 +08:00