Commit Graph

439 Commits

Author SHA1 Message Date
Yichen Jiang
a2ab09003f feat(web): pick a session's agent preset from the composer
A seat in the composer tool row, left of the model select, showing the preset
THIS session runs — its own recorded one, not the deployment default, because a
resumed session runs what it was created with. `SessionSummary` carries
`agentPreset` for that, alongside `cwd` and `origin`.

The switch exists only while the conversation has not started. After the first
turn the seat becomes a plain label rather than a disabled menu: a greyed
control reads as "temporarily unavailable", when in fact the choice is gone for
good. The seat never asks in that state, and the host refuses independently
with `agent-preset-locked`, so a stale client cannot slip one past it.

A rejected switch restores the previous value and surfaces the host's message
rather than leaving the seat showing something the session is not running.
2026-08-07 00:38:11 +08:00
imccyu
f9f72e2f09 fix(ui): preserve Hero tree when selecting a Workspace 2026-08-06 18:01:11 +08:00
Ziya
71e8132e76 Merge branch 'master' into feat/web-preview-badge 2026-08-05 23:29:04 -07:00
ZiyaZhang
7c1ae32e55 fix(web): address preview badge review 2026-08-05 23:26:39 -07:00
creatixchu
e90e419273 Merge remote-tracking branch 'origin/worktree/context-source-cards' into worktree/context-forms-remaining 2026-08-06 12:03:50 +08:00
creatixchu
851fe793c4 Merge remote-tracking branch 'origin/master' into worktree/context-source-cards
# Conflicts:
#	packages/client/runtime/src/client/sessions/transcript-adapter.ts
#	packages/client/ui-conversation/README.i18n.yaml
2026-08-06 12:03:15 +08:00
creatixchu
0996611cc2 Merge remote-tracking branch 'origin/worktree/context-source-cards' into worktree/context-forms-remaining 2026-08-06 11:57:49 +08:00
creatixchu
39d585e7ed Merge remote-tracking branch 'origin/master' into worktree/context-source-cards
# Conflicts:
#	packages/client/runtime/README.i18n.yaml
#	packages/client/ui-conversation/README.i18n.yaml
2026-08-06 11:57:17 +08:00
imccyu
53293210e6 Merge remote-tracking branch 'origin/master' into mergebot/pr1667 2026-08-06 11:53:33 +08:00
creatixchu
cc06d3c04b Merge remote-tracking branch 'origin/worktree/context-source-cards' into worktree/context-forms-remaining
# Conflicts:
#	apps/web/tests/snapshots/queue-actions/layout.expected.md
#	docs/cordis-catalog/events.md
#	docs/cordis-catalog/services.md
#	docs/core-data-structures/core.i18n.yaml
#	docs/core-data-structures/goal.i18n.yaml
#	docs/core-data-structures/goal.md
#	docs/core-data-structures/goal.zh.md
#	docs/event-producer-consumer.md
#	examples/acp-agent/tests/goal-snapshots/goal-session/session.expected.jsonl
#	examples/acp-agent/tests/goal-snapshots/goal-wrapup/session.expected.jsonl
#	examples/acp-agent/tests/snapshots/advanced-toolchain/session.1.jsonl
#	examples/acp-agent/tests/snapshots/advanced-toolchain/session.2.jsonl
#	examples/acp-agent/tests/snapshots/advanced-toolchain/session.jsonl
#	examples/acp-agent/tests/snapshots/bash-spill/session.jsonl
#	examples/acp-agent/tests/snapshots/bash-tool-turn/session.jsonl
#	examples/acp-agent/tests/snapshots/both-mode-turn/session.jsonl
#	examples/acp-agent/tests/snapshots/cancel-tool-calls/session.jsonl
#	examples/acp-agent/tests/snapshots/cancel/session.jsonl
#	examples/acp-agent/tests/snapshots/code-mode-turn/session.jsonl
#	examples/acp-agent/tests/snapshots/code-mode-workspace-context/session.jsonl
#	examples/acp-agent/tests/snapshots/cordis-inspect-jsdoc/session.jsonl
#	examples/acp-agent/tests/snapshots/empty-response-retry/session.jsonl
#	examples/acp-agent/tests/snapshots/error-finish/session.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-edit/session.jsonl
#	examples/acp-agent/tests/snapshots/fs-escalation-approved/session.jsonl
#	examples/acp-agent/tests/snapshots/fs-policy-reject/session.jsonl
#	examples/acp-agent/tests/snapshots/fs-read-window/session.jsonl
#	examples/acp-agent/tests/snapshots/fs-read/session.jsonl
#	examples/acp-agent/tests/snapshots/fs-write-overwrite/session.jsonl
#	examples/acp-agent/tests/snapshots/fs-write/session.jsonl
#	examples/acp-agent/tests/snapshots/hook-cc-invalid-matcher/session.jsonl
#	examples/acp-agent/tests/snapshots/hook-cc-posttool-block/session.jsonl
#	examples/acp-agent/tests/snapshots/hook-cc-posttool-context/session.jsonl
#	examples/acp-agent/tests/snapshots/hook-cc-pretool-ask/session.jsonl
#	examples/acp-agent/tests/snapshots/hook-cc-pretool-deny/session.jsonl
#	examples/acp-agent/tests/snapshots/hook-cc-promptsubmit-context/session.jsonl
#	examples/acp-agent/tests/snapshots/hook-cc-stop-continue/session.jsonl
#	examples/acp-agent/tests/snapshots/hook-codex-invalid-matcher/session.jsonl
#	examples/acp-agent/tests/snapshots/hook-codex-posttool-block/session.jsonl
#	examples/acp-agent/tests/snapshots/hook-codex-posttool-context/session.jsonl
#	examples/acp-agent/tests/snapshots/hook-codex-pretool-block/session.jsonl
#	examples/acp-agent/tests/snapshots/hook-codex-promptsubmit-context/session.jsonl
#	examples/acp-agent/tests/snapshots/hook-codex-stop-continue/session.jsonl
#	examples/acp-agent/tests/snapshots/lsp-definition/session.jsonl
#	examples/acp-agent/tests/snapshots/missing-sandbox-runner/session.jsonl
#	examples/acp-agent/tests/snapshots/multi-turn/session.jsonl
#	examples/acp-agent/tests/snapshots/packed-chunks/session.jsonl
#	examples/acp-agent/tests/snapshots/parallel-tool-calls/session.jsonl
#	examples/acp-agent/tests/snapshots/partial-landlock-child-failure/session.jsonl
#	examples/acp-agent/tests/snapshots/pty-tools/session.jsonl
#	examples/acp-agent/tests/snapshots/repeat-tool-guard/session.jsonl
#	examples/acp-agent/tests/snapshots/session-query-spill/session.jsonl
#	examples/acp-agent/tests/snapshots/session-sandbox-root/session.jsonl
#	examples/acp-agent/tests/snapshots/session-title-after-turn/session.jsonl
#	examples/acp-agent/tests/snapshots/skill-load/session.jsonl
#	examples/acp-agent/tests/snapshots/subagent-continuable/session.1.jsonl
#	examples/acp-agent/tests/snapshots/subagent-continuable/session.jsonl
#	examples/acp-agent/tests/snapshots/subagent-depth-two-rejection/session.1.jsonl
#	examples/acp-agent/tests/snapshots/subagent-depth-two-rejection/session.2.jsonl
#	examples/acp-agent/tests/snapshots/subagent-depth-two-rejection/session.jsonl
#	examples/acp-agent/tests/snapshots/subagent-fork/session.1.jsonl
#	examples/acp-agent/tests/snapshots/subagent-fork/session.jsonl
#	examples/acp-agent/tests/snapshots/subagent-list-agents/session.1.jsonl
#	examples/acp-agent/tests/snapshots/subagent-list-agents/session.jsonl
#	examples/acp-agent/tests/snapshots/subagent-mixed/session.1.jsonl
#	examples/acp-agent/tests/snapshots/subagent-mixed/session.2.jsonl
#	examples/acp-agent/tests/snapshots/subagent-mixed/session.jsonl
#	examples/acp-agent/tests/snapshots/subagent-multi/session.1.jsonl
#	examples/acp-agent/tests/snapshots/subagent-multi/session.2.jsonl
#	examples/acp-agent/tests/snapshots/subagent-multi/session.jsonl
#	examples/acp-agent/tests/snapshots/subagent-published-run-failure/session.jsonl
#	examples/acp-agent/tests/snapshots/subagent-report/session.1.jsonl
#	examples/acp-agent/tests/snapshots/subagent-report/session.jsonl
#	examples/acp-agent/tests/snapshots/subagent-spawn/session.1.jsonl
#	examples/acp-agent/tests/snapshots/subagent-spawn/session.jsonl
#	examples/acp-agent/tests/snapshots/text-turn/session.jsonl
#	examples/acp-agent/tests/snapshots/todo-write/session.jsonl
#	examples/acp-agent/tests/snapshots/tool-call-turn/session.jsonl
#	examples/acp-agent/tests/snapshots/web-fetch/session.jsonl
#	examples/acp-agent/tests/snapshots/workflow-run/session.1.jsonl
#	examples/acp-agent/tests/snapshots/workflow-run/session.jsonl
#	examples/acp-agent/tests/snapshots/workspace-context/session.jsonl
#	examples/acp-agent/tests/snapshots/workspace-edit/session.jsonl
#	examples/headless-agent/tests/snapshots/goal-tools/stream-json.expected.jsonl
#	examples/headless-agent/tests/snapshots/pty-tools/session.jsonl
#	examples/headless-agent/tests/snapshots/pty-tools/stream-json.expected.jsonl
#	examples/headless-agent/tests/subagent-inheritance-snapshots/parent-override/child.expected.jsonl
#	examples/headless-agent/tests/subagent-inheritance-snapshots/parent-override/parent.expected.jsonl
#	examples/jsonrpc-agent/tests/snapshots/persistent-tools/notifications.expected.jsonl
#	examples/jsonrpc-agent/tests/snapshots/persistent-tools/session.jsonl
#	packages/bash/tool-bash/tests/integration.spec.ts
#	packages/context/time-context/src/index.ts
#	packages/context/tmux-context/src/index.ts
#	packages/core/agent-loop/src/agent.ts
#	packages/core/system-prompt/src/index.ts
#	packages/goal/goal/src/domain.ts
#	packages/goal/goal/src/index.ts
#	packages/goal/goal/src/render.ts
#	packages/plan/plan-mode/src/index.ts
2026-08-06 11:49:03 +08:00
creatixchu
6747c2d44d Merge remote-tracking branch 'origin/master' into worktree/context-source-cards
# Conflicts:
#	.agents/notes/implemented/simplification/2026-07-31-web-ui-no-steer-entry-or-interjection-chrome.i18n.yaml
#	.agents/notes/implemented/simplification/2026-07-31-web-ui-no-steer-entry-or-interjection-chrome.md
#	.agents/notes/implemented/simplification/2026-07-31-web-ui-no-steer-entry-or-interjection-chrome.zh.md
#	apps/web/tests/seeded-history.e2e.ts
#	apps/web/tests/snapshots/queue-actions/layout.expected.md
#	docs/core-data-structures/core.i18n.yaml
#	examples/acp-agent/tests/snapshots/code-mode-workspace-context/session.jsonl
#	examples/acp-agent/tests/snapshots/cordis-inspect-jsdoc/session.jsonl
#	examples/acp-agent/tests/snapshots/skill-load/session.jsonl
#	examples/acp-agent/tests/snapshots/workspace-context/session.jsonl
#	examples/headless-agent/tests/snapshots/advanced-toolchain/session.1.jsonl
#	examples/headless-agent/tests/snapshots/advanced-toolchain/session.2.jsonl
#	examples/headless-agent/tests/snapshots/advanced-toolchain/session.jsonl
#	examples/headless-agent/tests/snapshots/pty-tools/session.jsonl
#	packages/client/runtime/README.i18n.yaml
#	packages/client/runtime/tests/history-fold.spec.ts
#	packages/client/ui-conversation/README.i18n.yaml
#	packages/client/ui-conversation/src/client/chat/MessageItem.tsx
#	packages/client/ui-conversation/tests/chat-branch-tails.spec.tsx
#	packages/context/workspace-context/src/index.ts
#	packages/context/workspace-context/tests/workspace-context.spec.ts
#	packages/skill/tool-skill/README.i18n.yaml
#	packages/skill/tool-skill/README.md
#	packages/skill/tool-skill/README.zh.md
#	packages/skill/tool-skill/src/index.ts
#	packages/skill/tool-skill/tests/tool-skill.spec.ts
2026-08-06 11:28:48 +08:00
imccyu
86965b053c feat(client): inject slot declaration lifetimes 2026-08-06 11:28:46 +08:00
imccyu
aaca2fa52f fix(web): localize stats and close stale context meter 2026-08-06 00:21:34 +08:00
imccyu
b0d1d9445e Merge remote-tracking branch 'origin/master' into mergebot/pr1667
# Conflicts:
#	apps/web/tests/snapshots/queue-actions/preserved.expected.md
#	docs/cordis-catalog/services.md
#	docs/core-data-structures/session.i18n.yaml
#	packages/client/runtime/src/client/session-history/history-fold.ts
#	packages/client/ui-conversation/README.i18n.yaml
#	packages/core/session/src/index.ts
2026-08-05 22:56:57 +08:00
Huanqi Cao
17ff1e0d4a Merge pull request #1624 from deepseek-harness/feat/pwsh-ui-parity
feat(pwsh): render pwsh calls as bash-shaped terminal cards in the Web UI
2026-08-05 22:20:11 +08:00
creatixchu
e7f2005ec7 fix(web): address the review round on the remaining context forms
- `relay` resolves its sender in `contextBody` like every other form. It was
  the one shape whose marker could claim a form the body did not render: an
  unreadable sender fell back inside the body while the row still said relay,
  contradicting the contract this PR's own note states.
- `recall` requires the retained, omitted, and truncated fields. Completeness
  is what the card exists to report, so a reference that cannot state it is
  not a readable recall — showing the label alone presents a confident card
  over unknown loss.
- The snapshot body states the supersession its producer framing line carries.
  That line is the one part of the model-facing text no section contains, and
  unlike an instruction context's `<system-reminder>` it states the form's own
  semantics rather than wrapping content.
- `GoalMessageSource` is a discriminated pair, so `{ form: 'notice' }` without
  its account no longer compiles. The guarantee this PR claims now holds at
  that seam too, not only through `ContextFormed` on plugin sources.
- Goal and tool-goal summaries are bounded by a shared `boundContextSummary`,
  which tool-tasks now uses as well. A goal objective is unbounded caller text
  in exactly the way a task label is.
- The runtime snapshot interpolates once per request: agent-loop renders the
  sections and joins them through `joinContextSections`.
- Every form's fallback branch is pinned, not only the notice one.
2026-08-05 17:39:50 +08:00
creatixchu
b7034e4a26 feat(web): declare the remaining context forms on every shipped producer
Four values complete the vocabulary, so the opaque body is reached only by
producers that genuinely promise no shape.

`snapshot` — current state a later snapshot supersedes. system-prompt now
exposes `renderContextSections()`, the named contributions
`renderContextSnapshot()` already joins for the model, so the body attributes
each part to the subsystem that produced it instead of re-splitting joined
prose. The runtime snapshot, time-context, and tmux-context declare it.

`notice` — a one-off account of what just happened, declared by tool-tasks,
goal state changes, tool-goal wrap-up, plan-mode switches, and
repeat-tool-guard. Its `summary` rides the COLLAPSED row: these five are the
majority of shipped producers and none of them needs expanding to be read.
The task summary bounds itself because its inputs are unbounded caller text.

`relay` — a message another agent addressed to this one; both subagent
sources declare it and the body names the sender above what it said.

`recall` — material lifted from another session's log. session-reference
needed no new field: its references already record retained and omitted
counts and the truncation flag, which the body shows first, because recalled
context is bounded on the way in.

`ContextFormed` is now discriminated by `form`, so a producer cannot declare
a shape without the facts that shape is presented from — a notice without its
summary, or a snapshot without its sections, fails to compile.

Only the two hook bridges stay opaque, by design: their content is whatever
an external program printed, so no shape can be promised for it. Unknown
kinds and unreadable records land there too.
2026-08-05 17:11:48 +08:00
creatixchu
5f34f782fc fix(web): address the late review batch on context bodies
- Content blocks render in the order the model received them. Partitioning
  hoisted every unknown block past the text around it, so an interleaved log
  read back in an order the model never saw.
- A delta distinguishes a newly reconciled file from a rewritten one; `set`
  and `replace` already separate them at the producer, and collapsing both to
  "updated" misread a new file.
- The superseded note states current fact in its consequences and testing
  rather than keeping claims the implementation now contradicts, per
  implemented/AGENTS.md; the decision itself stays as the record of that
  change, with the supersession pointer above it.
2026-08-05 17:08:51 +08:00
Yichen Jiang
038699bcb4 fix(web): let the context meter see a compaction
The composer ring, percentage, and `~used / capacity` header read
`contextPressure.pressureTokens`, which moves only when a request reports
usage. Compaction reports none — compact-basic summarizes through a direct
`ctx.llm.stream()` call and appends only its own `compact/*` records plus the
replacement `user/message` — so the meter was frozen across the one action
taken to change it. Driving a real `compactNow` through the agent loop:

    BEFORE compact:  ring=4%  header=~4227/100000  rows=[18, 0, 4365]
    AFTER  compact:  ring=4%  header=~4227/100000  rows=[18, 0,  286]

The composition rows fell 93%; the ring did not move, and would not until an
entire further turn completed. The panel then contradicted itself by more than
an order of magnitude at exactly the moment a reader opens it.

`contextPressure` now also publishes `projectedTokens`: the provider sample
plus the heuristic repricing of everything the surface gained or lost since
that sample, clamped at zero, folded through the shared `surface-fold.ts`. The
sample is stamped before the same event joins the surface, so an
`assistant/message` anchors against the surface its own request carried. Only
the delta is estimated, so the figure stays provider-anchored — the estimator's
CJK and JSON-schema underpricing stays out of the occupancy number — while
reacting the moment content lands or a span is shadowed. Same run after:

    BEFORE compact:  ring=4%  header=~4323/100000  (pressure=4227, projected=4323)
    AFTER  compact:  ring=0%  header=~ 244/100000  (pressure=4227, projected= 244)

`contextOccupancy` prefers the projected figure and falls back to the bare
sample, so a projection restored from a pre-field checkpoint degrades to the
old behavior rather than disappearing. `stateVersion` moves to 3.
2026-08-05 17:00:48 +08:00
creatixchu
ccd27f3775 fix(web): address the second review round on context provenance
- An empty replacement catalog is a real catalog: `renderCatalogUpdate()`
  publishes zero entries when the last skill disappears, and falling back
  would hide that every earlier name was retired.
- The opaque fallback keeps a `form` declaration this version cannot present.
  It is the one place a newer or foreign log's declared shape would otherwise
  vanish from the UI entirely, since the row marker is also absent there.
- An instruction change with an unrecognized `action` disqualifies the record.
  The action decides the word the row shows, so an unknown one would be
  presented as loaded or updated.
- The catalog list bounds itself and reports the withheld count. Entry count
  is unbounded and the scrollport bounds height, not node count.
- A catalog message keeps content blocks this version does not know, instead
  of dropping model-visible content the extensible union may carry.
- `core.md` defines `ContextFormed`, the interface actually carrying the
  optional field, beside `ContextForm`.
- The superseded-in-part bullet states the affected clauses as one rule rather
  than enumerating them; two rounds of enumeration each missed some, which is
  the shape being fragile rather than the list being wrong.
- The note records the one migration case that does not self-heal: an
  old-format catalog as the only one, with an empty current view, leaves a
  stale catalog nothing replaces.
2026-08-05 16:51:01 +08:00
Yichen Jiang
46562b2c30 fix(web): localize the context panel headline order and drop empty bar parts
The panel header concatenated a `45%` span with a `context.used` fragment, so
Chinese rendered "45% 上下文已用" against the ring's own "上下文已用 45%". The
header now renders the one localized `context.aria` sentence split around its
`{percent}` slot: each locale owns the reading's position while the reading
keeps its primary tone, and the side a locale leaves empty collapses through
`.headline:empty` instead of spending a header gap.

The bar mapped every composition row to a segment unconditionally, and
`.segment`'s 2px min-width kept each one visible, so a 0% occupancy panel
painted an ~8px filled bar over an empty context. Parts are now computed with
their widths and zero-width parts are filtered out, which also collapses the
plain and segmented branches into one map.
2026-08-05 15:59:24 +08:00
Yichen Jiang
d2aafc2a33 Merge remote-tracking branch 'origin/master' into feat/add-session-data-preview
# Conflicts:
#	docs/cordis-catalog/services.md
#	docs/core-data-structures/session.i18n.yaml
#	packages/client/ui-conversation/README.i18n.yaml
#	packages/llm/token-meter/README.i18n.yaml
2026-08-05 15:51:34 +08:00
creatixchu
ebe6ca20ad fix(web): address review findings on producer-declared context forms
- `catalogHistory` validated its durable read. `agent.session.events` is a
  JSONL/SQLite seed on resume or fork, and seed validation guarantees only a
  source object with a non-empty `kind`; a `skill-catalog` record with missing
  or wrongly shaped `entries` threw inside the step listener, failing every
  later turn of that session. It is now skipped as an unrecognizable record,
  the posture the replaced content digest had, with a regression test over six
  malformed shapes.
- The headless keyless smoke still filtered catalogs by the old plugin source,
  so the `built-bin-smoke` gate would not have found the catalog message.
- Entries record the published description unescaped. The pseudo-XML escaping
  belongs to the `<available_skills>` frame and is applied when rendering it,
  so a description containing `<` no longer reaches the card as `&lt;`.
  `escapeText` is injective, so republish semantics and the model-facing text
  are unchanged.
- Adjacent text blocks join with no separator, matching how provider adapters
  flatten them; the body no longer shows a line break the model never saw.
- Provenance fields are bounded like the text: an unknown producer may record
  an arbitrarily large value.
- Both readers are all-or-nothing, and the row's form marker reports what
  rendered rather than what was declared, so a partly unreadable record cannot
  present a confident but incomplete account.
- The catalog body consumes `update` as a replacement notice; the digest
  canonicalizes per entry as JSON, since every separator character is itself
  legal in a description.
- `core.md` documents the form axis with a `ContextForm` type-equiv block, and
  both projections assert the wiring they duplicate.
2026-08-05 14:55:21 +08:00
Yif
0073d6aaa1 feat(web): turn speed metrics and composer context meter
Assistant footers and the stats line gain TTFT/tok-per-second readings
folded from step timings; context occupancy moves off the stats line onto
a composer ring whose panel shows a heuristic system/tools/messages
breakdown from the new token-meter contextBreakdown session projection.
2026-08-05 13:54:46 +08:00
creatixchu
340c9ba576 feat(web): split context injection into producer-declared forms
Injected context reached the transcript as one anonymous shape whose
expanded body was the whole message serialized as inline JSON, so the
escaping collapsed the only readable part — the model-facing prose —
into a single line.

`MessageSource` gains an optional producer-declared `form`, a small
semantic vocabulary of information shapes independent of `kind`: kind
says who produced the context, form says what shape it is, so several
producers may share one presentation. Two values ship.

`instructions` (workspace-context) lists the reconciled files above
their text and keeps the `<system-reminder>` framing verbatim, because
the framing is part of what the model read. `catalog` moves dsh-tool-skill
off the shared plugin kind onto a `skill-catalog` source carrying the
published name/description entries, and the body lists those instead of
re-parsing `<available_skills>` out of the prose. Catalog identity moves
with it: the republish digest now covers the durable entries, deleting
the text-slicing that recovered them from a logged message.

Everything else renders the opaque body — the model-facing text with its
real line breaks, then the remaining provenance as fields. That is the
documented default, not a leftover: a resumed, forked, or foreign log
must render whether or not its producer is mounted here, which is why
the classification lives in the durable source rather than a client-side
table keyed by producer.
2026-08-05 12:15:03 +08:00
creatixchu
d060327f0c Merge remote-tracking branch 'origin/master' into worktree/context-source-cards
# Conflicts:
#	apps/web/tests/snapshots/bash-abort-row/ui.expected.md
#	packages/client/runtime/README.i18n.yaml
#	packages/client/ui-conversation/README.i18n.yaml
2026-08-05 10:40:23 +08:00
Huanqi Cao
61bd42f8f9 feat(pwsh): render pwsh calls as bash-shaped terminal cards in the Web UI
A completed pwsh foreground call now presents as the bash tool's terminal
card with the parsed exit-status pill instead of a generic console fence,
and the collapsed row classifies as the shell family (Pwsh title). The
marker-to-exit-status parse moves from dsh-tool-bash's private render
module into the @deepseek-ai/dsh-bash seam so both shell tools share one
inverse of the marker contract (the bash-env precedent). The Web UI needs
no per-tool code: the terminal-card bridge maps any card:'terminal' view.

Coverage: dsh-bash owns the parse edge cases; the tool-pwsh presenter
suite mirrors tool-bash's; the client row-model suite pins the Pwsh shell
row; the new keyless pwsh-terminal web lane seeds an authored session,
presents it through the real tool on replay, and pins the card golden.

TUI is out of scope: the TUI package was removed (ed30088adb), so the Web
surface is the only UI the gap affected; the roadmap proposal's stage 2
is updated accordingly.
2026-08-05 02:05:06 +08:00
_Kerman
694f9009ec Merge remote-tracking branch 'origin/master' into xtr/react-loop-simplification
# Conflicts:
#	.agents/notes/implemented/feature/2026-07-23-web-permission-and-approval.i18n.yaml
#	packages/client/runtime/README.i18n.yaml
#	packages/client/ui-conversation/README.i18n.yaml
2026-08-04 21:04:43 +08:00
_Kerman
674278cb17 Merge remote-tracking branch 'origin/master' into xtr/react-loop-simplification
# Conflicts:
#	packages/client/ui-conversation/src/client/queue/QueueDock.tsx
2026-08-04 19:37:51 +08:00
Turtle
76d43d616d Merge remote-tracking branch 'origin/master' into codex/session-pending-interactions
# Conflicts:
#	packages/client/connection/README.i18n.yaml
#	packages/client/connection/README.md
#	packages/client/connection/README.zh.md
2026-08-04 19:03:01 +08:00
creatixchu
fab131a366 fix(web): align the context separator with ToolRow and name the caption
Review follow-ups on the context provenance row:

- the producer name now follows ToolRow's aria-hidden separator dot instead
  of a literal middot inside the text, so the two disclosure rows expose one
  accessible-name shape;
- the English steering caption becomes the noun `Interjection`, parallel to
  the Chinese 插话 and to the label this bubble carried before;
- the history fold gets its own provenance assertion, so the mapping it
  declares separately from TranscriptAdapter is pinned on both sides;
- the superseded-in-part bullet on the no-interjection-chrome note now
  enumerates the third Decision bullet too, whose no-badge and no-IconActions
  clauses had both lapsed.
2026-08-04 18:25:44 +08:00
creatixchu
de96087923 feat(web): name context sources and mark steering in the transcript
Every logged non-user user/message collapsed into one identical
「上下文注入」 row, and mid-turn steering rendered in exactly the bubble a
turn-opening prompt uses, so the transcript could not say what had been
added or which message interrupted a running turn.

TranscriptAdapter and the history fold now attach a provenance view to
each context node, computed by contextProvenance() from the durable
source alone: a role (inject, or recall for a cross-session snapshot)
and a producer name read out of the log — instruction paths for
workspace-instructions, session titles for session-reference, the plugin
id for a plugin source, and the bare kind for any other. No client-side
table of producer names, so a renamed or newly mounted producer stays
identifiable without a client release and a foreign log projects like a
live one. ContextInjectionRow titles itself from the role and shows the
name beside it; MessageItem captions durable and pending steering
bubbles.

The caption reverses one clause of the no-interjection-chrome decision,
which removed it because the composer could not steer; composer steering
shipped afterwards without amending that note, so this change supplies
the product decision its reintroduction clause required and corrects the
stale facts left in it.

Fixes #1291
2026-08-04 17:44:18 +08:00
Turtle
00d4349eb4 feat(client): surface pending session interactions 2026-08-04 17:15:10 +08:00
_Kerman
09e909b96b Merge remote-tracking branch 'origin/master' into xtr/react-loop-simplification
# Conflicts:
#	apps/web/tests/snapshots/queue-actions/preserved.expected.md
#	packages/client/runtime/src/client/sessions/session.ts
2026-08-04 16:56:44 +08:00
ZiyaZhang
047ea50987 feat(web): add preview badge to empty hero 2026-08-04 01:46:52 -07:00
imccyu
72f82f65c9 Merge remote-tracking branch 'origin/master' into mergebot/pr1389
# Conflicts:
#	apps/web/tests/snapshots/sidebar-scrollbar/geometry.expected.md
#	packages/client/ui-conversation/src/client/chat/MessageIconActions.tsx
#	packages/client/ui-conversation/src/client/chat/message-chrome.ts
2026-08-04 16:33:55 +08:00
imccyu
e9d76dae64 fix(web): address UI polish review feedback 2026-08-04 16:25:09 +08:00
imccyu
b9f4e46462 Merge remote-tracking branch 'origin/master' into mergebot/pr1389
# Conflicts:
#	packages/client/ui-workspace/src/client/WorkspaceBrowser.module.css
2026-08-04 16:06:38 +08:00
imccyu
3be257ba1d fix(web): preserve polish accessibility contracts 2026-08-04 16:04:26 +08:00
imccyu
ad03ccbd7a Merge branch 'master' into feat/turn-running-time 2026-08-04 16:03:31 +08:00
imccyu
cc435a9c0c fix(web): use exact turn boundaries for run time 2026-08-04 15:55:07 +08:00
_Kerman
f5c599d0ca Merge remote-tracking branch 'origin/master' into xtr/react-loop-simplification 2026-08-04 15:49:22 +08:00
creatixchu
398ab58a69 Merge remote-tracking branch 'origin/master' into worktree/composer-caret-binding 2026-08-04 15:40:27 +08:00
imccyu
2a828f09da Merge remote-tracking branch 'origin/master' into feat/turn-running-time 2026-08-04 15:22:28 +08:00
creatixchu
ef2fbdfc19 fix(web): preserve focus when restoring drafts 2026-08-04 15:12:11 +08:00
_Kerman
8ed5ca5051 Merge remote-tracking branch 'origin/master' into xtr/react-loop-simplification
# Conflicts:
#	packages/client/runtime/tests/session.spec.ts
2026-08-04 14:51:07 +08:00
_Kerman
9b50311fd1 Merge remote-tracking branch 'origin/master' into xtr/react-loop-simplification 2026-08-04 14:46:18 +08:00
creatixchu
4e024da35a Merge origin/master into worktree/composer-caret-binding 2026-08-04 14:44:09 +08:00
imccyu
6f1d443c59 feat: optimize chat think 2026-08-04 14:37:35 +08:00
kingwl
9b91e5312c fix(web): narrow chat scroll provenance 2026-08-04 14:23:34 +08:00