Commit Graph

1294 Commits

Author SHA1 Message Date
Yichen Jiang
64fc536982 feat(web): order the shipped presets, and edit one on its own screen
The picker listed presets alphabetically by id, so the shipped set read
cordis, minimal, standard — reverse order of capability. A preset may now
declare `order` in its metadata; the shipped three declare 1/2/3 and read
standard, minimal, cordis. A preset that declares none sorts behind those
that do, then by id, so authored presets stay stable.

Editing had nowhere good to live. Inside a card it was squeezed into a
~268px column; hanging off the end of the grid it was orphaned from the card
it edits. It now replaces the list: a back link, what is being edited, and
the form at full width. One thing on screen at a time, which is what the
form's height wanted all along.

Cards in different grid rows sized independently, so a short description made
a short card. `grid-auto-rows: 1fr` makes every row the same height.

The trust badge lost its pill when the card CSS was rewritten, and `In use`
never had one; both are tags now. Icon labels moved from `title` to a drawn
tooltip — the native one waits about a second, which reads as nothing
happening.
2026-08-07 00:41:50 +08:00
Yichen Jiang
7281615d44 feat(agent-presets): give a preset a name and a description
A picker showed directory names, so the settings page could only ever list
`standard` / `core-web` / `cordis` and hope the reader knew what they meant.
A preset may now publish display text in an optional `preset.yml` beside
its composition, and the section renders cards — name, description, and the
one in use — instead of rows.

The file carries display text ONLY. `id` is the directory name and `trust`
comes from the root a preset was discovered under, so neither is writable
there: otherwise a locally authored preset could name itself into the
shipped set. It is a separate file because a composition is a top-level list
of plugin rows — YAML cannot carry sibling keys beside it, and a fake
metadata row would hand the Loader something to load.

Every read failure degrades to no metadata; absent, malformed, wrongly
typed, and blank all mean the same thing and the picker falls back to the
id. Presentation is not capability: a preset whose name is broken still
mounts.

The editor gained name and description fields above the YAML, and clearing
both removes the file rather than storing a blank name.
2026-08-07 00:41:50 +08:00
Yichen Jiang
9ac1547335 fix(web): stop leaking ask_user_question into every preset
`ui-question`'s node half called `ctx.tools.register` on the host context.
`ScopedLayers.merge()` combines the global layer with the agent's exact-scope
layer, and an unscoped registration lands in the global one — so the tool
reached every agent no matter which preset composed it. `core-web`, sold as
a two-tool benchmark surface, really presented three, and a locally authored
`bash-only` preset presented two.

Rendering a question is a host UI capability; having the tool is an agent
capability, and only a preset decides that. The node half is now empty and
the `tool-ask-user` row moved into the presets that want it. The TUI keeps
its own row, having no presets.

The web composition test now asserts the global tool layer is EMPTY, which
is the invariant that would have caught this: any tool outside a preset
reaches every agent.
2026-08-07 00:41:50 +08:00
Yichen Jiang
6758da87ae feat(web): choose the default agent preset from General settings
One settings row picking which preset new sessions are composed from.

It is deliberately a new-session preference, not a live switch: a session's
preset is fixed at creation and the host refuses to adopt an existing session
under a different one, so the row says "applies to sessions you start from now
on" rather than implying it can retune a running agent.

Options and the current value come from one `agentPreset.list` call — the
roster already reports which id an unspecified session gets, so the row needs
no settings-schema introspection, unlike the permission row it is modelled on.
The write targets only the namespace's `default` field.

The menu marks `user` rows: a locally authored preset is exactly as privileged
as the plugins it names, and presenting it identically to a shipped one would
hide that.

An empty roster reads as `unavailable` and renders nothing, because composing
no presets is a valid deployment rather than a failure — distinct from a
roster call that failed, which surfaces its message.
2026-08-07 00:38:11 +08:00
Yichen Jiang
5ed79887fb fix(web): correct the preset-layer contracts review found stale
None of these change behavior; each said something that was not true.

`SessionCwdConflict`'s doc block had been left stranded above the
`AgentPresetConflict` inserted under it, so one class carried a comment
about the other and the second carried none.

The roster comment named a `.system` directory that does not exist; the
shipped root is `config/agent-presets/`, and `system` is the trust its
entries carry.

The real-composition test attributed the disabled `api-gateway` row to
"side effects outside this process" alongside the port and the exporter.
It is disabled for a different reason — the api-proxy cannot mount in
this layer at all — and hiding that behind the same phrase would leave a
later layer unable to tell whether the line can come out.

One test claimed to refuse an adoption while asserting only that the
header records the preset; it now says what it checks.

`PERSONA_SECTION`/`PERSONA_ORDER` existed twice, once in the registry
that declares the slot and once restated in the row that replaces it —
a drift that would land a preset's persona beside the deployment's
instead of shadowing it. The registry exports them now.

The preset conflict message read "already runs agent preset undefined"
for a session that records none, which is the shape a deployment with no
roster produces; it names that case instead, with the regression that
reaches it through the gateway.

Finally, `PresetTree.write()` drops the `loader/config-update` the
inherited method emits — recorded on the override, since a future
edit-while-running flow needs its own persistence path.
2026-08-07 00:35:30 +08:00
Yichen Jiang
739042a804 feat(persona): make the agent persona a composable row
`dsh-system-prompt` owns the deployment persona as its own config and registers
that section unconditionally, so a process has exactly one. An agent preset
cannot mount the prompt registry itself, which means that without a row of its
own a preset could change an agent's tools but never its identity — and a
roster of presets that all sound the same is not worth having.

The row is scope-only by construction: mounted outside an agent scope it
collides with the registry's own `deployment:persona` registration and fails
loud. That is the correct shape rather than a gap, because the unscoped slot
already has an owner and this row exists to shadow it for one agent.

Two behaviours are pinned by test because both read the other way at a glance:
an empty persona still occupies the slot (shadowing the deployment persona away
entirely, then disappearing at render), and `assemble()` keeps section text
uninterpolated — `renderPrompt()` is the stage that resolves `{{…}}`.
2026-08-07 00:35:30 +08:00
Yichen Jiang
065257addb fix(agent-presets): bound the mount registry on a host that never reads it
Records are pruned by observation rather than by a disposal hook, for the
reason the module already states: three different owners can tear a
subtree down, and a cleared `uid` is what they share. That leaves the
pruning to whoever reads — and the only production reader is the
invariant companion, whose package is a development composition a
shipped host never loads.

So a live host pruned nothing: every session ever composed left a record
retaining its whole disposed subtree, since the fiber holds its config
and that config is the key its EntryTree is stored under.

Prune on the mount path too. Every session takes it, which bounds the
set at one generation of dead records instead of one per session.
2026-08-07 00:33:40 +08:00
Yichen Jiang
18fe174897 feat(agent-presets): compose each session's agent from a preset cordis.yml
A preset is a directory holding one `agent.cordis.yml`. Mounting it under an
agent's scope context during `setup(agentCtx)` gives that one session its own
tools and prompt sections while every other live session keeps its own.

No registry gains a tier. `dsh-tools` and `dsh-system-prompt` already file
registrations into the calling context's scope layer, and entry contexts chain
to the context a subtree was plugged into, so a composition mounted under
`agent.ctx` is that agent's alone and unwinds with it.

The mount audits itself because a directly-plugged subtree is absent from
`ctx.loader.entries()` and no boot audit covers it. It rejects an unscoped
target, a row that never became usable, and a row that published a service into
the root service realm — that last one is process-global rather than
per-session, and its collision with the next session surfaces as an unhandled
rejection `setup` never observes, leaving a half-composed agent that looks
healthy. The package invariant re-checks that rule on every service
notification, since a row publishing from a timer would escape a one-shot audit.

Raises the `packages/README.md` word ceiling from 920 to 980: the group table
must enumerate every group, and the new `preset/` row is necessary content.

Design: .agents/notes/implemented/architecture/2026-08-03-per-session-agent-presets.md
2026-08-06 21:03:18 +08:00
Turtle
a51b88d2aa Merge remote-tracking branch 'origin/master' into feat/profile-plugin-management
# Conflicts:
#	apps/cli/src/headless.ts
#	docs/event-producer-consumer.md
#	packages/host/apiproxy/README.i18n.yaml
2026-08-06 20:03:22 +08:00
Yichen Jiang
98b894f8eb Merge remote-tracking branch 'origin/master' into claude/web-llm-pi-ai-config-385e24
# Conflicts:
#	docs/event-producer-consumer.md
2026-08-06 13:03:40 +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
imccyu
e5810d450e Merge remote-tracking branch 'origin/master' into mergebot/pr1667 2026-08-06 11:42:14 +08:00
creatixchu
d0d8cd5365 Merge remote-tracking branch 'origin/master' into worktree/context-source-cards
# Conflicts:
#	examples/acp-agent/tests/snapshots/cordis-inspect-jsdoc/session.jsonl
2026-08-06 11:29:50 +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
Yichen Jiang
17c86bbb25 Merge remote-tracking branch 'origin/master' into claude/web-llm-pi-ai-config-385e24
# Conflicts:
#	packages/llm/llm-pi-ai/tests/adapter.spec.ts
#	packages/llm/llm/README.i18n.yaml
2026-08-06 10:47:36 +08:00
imccyu
e89b1e612f fix(session): address restore review feedback 2026-08-06 10:40:32 +08:00
imccyu
28df863bdd docs(jsonl): refresh generated catalogs 2026-08-06 10:40:31 +08:00
imccyu
03983ff986 perf(jsonl): scan decoded frames incrementally 2026-08-06 10:40:31 +08:00
Turtle
0556c989b5 docs: regenerate config catalog for the web-app surfaceContext field 2026-08-06 09:35:51 +08:00
Turtle
af5f528903 Merge remote-tracking branch 'origin/master' into feat/profile-plugin-management
# Conflicts:
#	apps/cli/src/headless.ts
#	packages/host/apiproxy/README.i18n.yaml
2026-08-06 06:55:42 +08:00
Turtle
07d24b005f docs: profile scheme across guides, notes, and generated catalogs; Agent Note
Update every doc referencing base.cordis.yml/web.cordis.yml, --config, -p, or
$DSH_HOME/config.yaml to the profile vocabulary with bilingual counterparts
re-recorded; regenerate the catalogs and graphs; add the
profile-plugin-bundles Agent Note recording the design and its rejected
alternatives.
2026-08-06 06:29:06 +08:00
imccyu
ede74b1926 fix(session-persistence): invalidate stale preparations 2026-08-06 04:11:58 +08:00
imccyu
2b9428f35d fix(session-persistence): satisfy preparation gates 2026-08-06 04:11:57 +08:00
imccyu
e089ef92d8 docs: document session preparation flow 2026-08-06 04:11:57 +08:00
imccyu
59df683ef1 fix(token-meter): bound projection state via logged shadow prices
The contextBreakdown and contextPressure units carried the full priced
surface, so each session's persisted projection checkpoint grew without
bound. A surface replacement is now priced by the shadow-price event
logged directly before it — compact/summary for compaction, the new
compact/prune from tool-result pruning (priced through the injected
token meter) — and the unit states shrink to a fixed handful of numbers.
Regenerate the persistence/cordis/module/config catalogs.
2026-08-06 02:50:38 +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
8247b7619a Merge remote-tracking branch 'origin/master' into worktree/context-source-cards
# Conflicts:
#	packages/client/runtime/README.i18n.yaml
#	packages/client/runtime/README.md
#	packages/client/runtime/README.zh.md
#	packages/client/ui-conversation/README.i18n.yaml
2026-08-05 19:14:56 +08:00
Yichen Jiang
f376ee23d1 fix(llm): size unknown models and refuse a section that cannot be served
Three defects surfaced while driving the Models page.

A hand-declared model needed an explicit contextWindow and maxTokens,
but a provider listing usually returns ids and nothing else — so the
page happily wrote a profile the adapter then rejected, which took the
whole namespace down silently. Capacities now fall back to the route's
`defaultContextWindow` (262,144) and `defaultMaxTokens` (32,768). Both
are guesses by construction, which is why they are route fields a
deployment corrects once rather than constants buried in the adapter;
the fallback sizes the model and never becomes a per-request cap.

That silent failure was the second defect. A schema-valid profile the
adapter could not serve was stored and only rejected later, disabling
every route in the namespace with nothing said. `dsh-settings` gains an
optional `validate` on registration — a check for what a schema cannot
express — and `llm-pi-ai` refuses an unserviceable section at the write
that produced it. A stored section that fails keeps the namespace's last
good value, as a schema failure already did, so an externally edited
document still cannot strand the owner. The plugin's own last-good
fallback goes with it: nothing reaching it can fail any more.

Third, a model with no reasoning metadata advertised the single level
`off`, which pi-ai translates to *omitting* the reasoning option — the
same request naming no effort produces. Selecting it disabled nothing,
so a provider whose default is to think kept thinking with `off` shown
as selected. Such a model now reports no reasoning capability at all,
which is the seam's way of saying the control is unavailable, and the
per-model `reasoning` flag is gone: without a thinkingLevelMap to spell
levels it could only invent them.

The protocol table narrows to the three a hand-declared route reaches
today, most-reached first so a surface offering a choice defaults to the
one gateways actually speak.
2026-08-05 18:54:23 +08:00
Yichen Jiang
4c80cab108 fix(llm): capture an immutable snapshot per pi-ai operation
Review found four defects in the declared-provider work.

`PiAiAdapter` reused one `Models` collection and mutated it whenever the
configuration changed. `Models.streamSimple()` resolves its provider
lazily — when the stream is first consumed, which is after the adapter
awaits the route's credential — so a configuration change landing in
that window let an in-flight request finish under a configuration it
never resolved against, or fail on a provider that no longer existed.
Each resolution now produces an immutable snapshot and every operation
captures one before its first await, which is what makes the seam's
per-step freeze (`llm.prepareCall()`) hold end to end: switching models
mid-reply takes effect on the next step, never inside the one in flight.

`defaultMaxTokens` was materialized from the catalog's `Model.maxTokens`.
The two answer different questions: pi-ai requires that field as the
model's output capability, while the seam's is a cap the deployment
chose to send on requests naming none, so every request had started
carrying a number nobody picked. Only an explicitly configured cap
reaches the seam now.

The configurable-provider directory was refreshed by disposing its
registration and making a new one. A candidate set the registry refuses
— a profile keyed `deepseek-official`, which llm-deepseek declares —
left the whole directory withdrawn and the Models page empty, silently,
because the settings callback contains the failure. The seam's
registration handle now carries `replace()` with the same
validate-first atomicity `registerAdapter` has.

The protocol table offered every pi-ai streaming API, including four
whose authentication a profile cannot express: Bedrock signs with SigV4
over AWS credentials and a region, Vertex needs a project, a location,
and ADC, Azure needs provider environment plus an api-version, and Codex
uses OAuth. Offering them handed back routes that cannot authenticate.
Catalog routes still reach them through their own provider.
2026-08-05 18:54:23 +08:00
Yichen Jiang
d6126c25f2 feat(llm): declare pi-ai providers instead of looking them up
A pi-ai route had to name an installed catalog provider, served that
catalog's models verbatim, and could override only the endpoint. An
OpenAI-compatible gateway, a self-hosted server, or a model newer than
the pinned pi-ai release was therefore unreachable, and a stale context
window could not be corrected without upgrading the package.

A route is now a declaration whose defaults come from the installed
catalog. `catalog.ts` merges that catalog under the profile's own model
entries, `provider.ts` builds the pi-ai Provider (reusing the catalog
provider when the route keeps its protocol, so implementations this
package cannot reconstruct keep working), and the adapter serves every
operation from one `createModels()` collection. That also retires the
`@earendil-works/pi-ai/compat` import, which pi-ai documents as a
temporary entry point it deletes with its ModelManager migration.

Credentials stay on the harness seam: the resolved key rides the request
as pi-ai's highest-priority auth override, so `Models` holds no
credential store and a named-but-missing reference still fails loud
instead of falling back to an unrelated ambient key.

A model's configured maxTokens now reaches the seam as defaultMaxTokens.
2026-08-05 18:54:23 +08:00
Huanqi Cao
8fcb392fe1 Merge origin/master into feat/pwsh-ui-parity 2026-08-05 17:41:03 +08:00
_Kerman
289a23421d Merge remote-tracking branch 'origin/master' into xtr/react-loop-simplification
# Conflicts:
#	.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
#	packages/host/apiproxy/README.i18n.yaml
2026-08-05 15:34:19 +08:00
creatixchu
e6293785bc Merge remote-tracking branch 'origin/master' into worktree/context-source-cards
# Conflicts:
#	examples/acp-agent/tests/snapshots/cordis-inspect-jsdoc/session.jsonl
#	packages/skill/tool-skill/README.i18n.yaml
2026-08-05 14:11:29 +08:00
imccyu
e4d5ec548e Merge pull request #1050 from deepseek-harness/worktree/custom-deepseek-models
feat(web): configure custom DeepSeek models, with a restyled Models card
2026-08-05 14:04:18 +08:00
Wenlu Wang
61e46f077e Merge pull request #1362 from deepseek-harness/fix/landlock-runner-failure-classification
Fix false sandbox failures from Landlock partial-enforcement notices
2026-08-05 13:59:47 +08:00
_Kerman
b76543cc1c Merge remote-tracking branch 'origin/master' into xtr/react-loop-simplification
# Conflicts:
#	apps/web/tests/markdown-images.e2e.ts
#	docs/cordis-catalog/services.md
#	docs/core-data-structures/session.i18n.yaml
#	docs/event-producer-consumer.md
#	examples/acp-agent/tests/snapshots/cordis-inspect-jsdoc/session.jsonl
#	packages/compact/compact-basic/tests/compact-basic.spec.ts
#	packages/context/time-context/tests/invariant.spec.ts
#	packages/context/time-context/tests/time-context.spec.ts
#	packages/core/agent-loop/src/invariant.ts
#	packages/core/agent-loop/tests/contract-regressions.spec.ts
#	packages/core/agent-loop/tests/request-reconstruction.spec.ts
#	packages/core/agent/tests/agent.spec.ts
#	packages/core/session/README.i18n.yaml
#	packages/core/session/src/index.ts
#	packages/core/session/tests/derived-cache.spec.ts
#	packages/core/session/tests/request-header.spec.ts
#	packages/core/session/tests/session.spec.ts
#	packages/core/session/tests/surface.spec.ts
#	packages/fs/tool-str-replace-editor/tests/tools.spec.ts
#	packages/goal/goal/tests/goal.spec.ts
#	packages/plan/plan-mode/tests/plan-mode.spec.ts
#	packages/pty/pty-local/tests/index.spec.ts
#	packages/pty/pty-local/tests/local.spec.ts
#	packages/pty/pty/tests/service.spec.ts
#	packages/pty/tool-bash-persistent/tests/loader-composition.spec.ts
#	packages/pty/tool-bash-persistent/tests/tools.spec.ts
#	packages/pty/tool-pty/tests/loader-composition.spec.ts
#	packages/pty/tool-pty/tests/tools.spec.ts
#	packages/session-title/session-title-all-messages-llm/tests/provider.spec.ts
#	packages/tasks/tasks-local/tests/tasks.spec.ts
#	packages/ui/user-approval/tests/approval.spec.ts
2026-08-05 13:53:35 +08:00
kingwl
75bd2b8aaa Merge remote-tracking branch 'origin/master' into fix/landlock-runner-failure-classification
# Conflicts:
#	.agents/notes/implemented/feature/2026-07-06-sandbox.i18n.yaml
#	.agents/notes/implemented/feature/2026-07-06-sandbox.zh.md
#	docs/core-data-structures/sandbox.i18n.yaml
#	docs/core-data-structures/sandbox.zh.md
#	docs/postmortem/README.i18n.yaml
#	docs/postmortem/README.zh.md
#	examples/acp-agent/tests/acp.snapshot.ts
#	native/landlock-run/README.i18n.yaml
#	packages/sandbox/sandbox-local/README.i18n.yaml
#	packages/sandbox/sandbox-local/README.zh.md
#	packages/sandbox/sandbox/README.i18n.yaml
2026-08-05 13:17:38 +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
imccyu
1832df038d docs(session): document creation ownership boundaries 2026-08-05 11:57:17 +08:00
Yichen Jiang
086656afae Merge remote-tracking branch 'origin/master' into worktree/custom-deepseek-models
# Conflicts:
#	packages/client/ui-models/src/client/ModelsSection.module.css
#	packages/client/ui-models/src/client/ModelsSection.tsx
2026-08-05 11:46:23 +08:00
Huanqi Cao
838e3c8cd9 fix(web): probe pwsh through the executor's path resolution
The pwsh-terminal e2e probed the bare 'pwsh' literal, which knip flagged as
an unlisted binary. Reuse resolvePwshPath from @deepseek-ai/dsh-pwsh-local
(the judgment the tool-pwsh tests already use), so the probe matches the
executor's own resolution and the reference stays indirect; record mode
skips the lane anyway, so the probe stays inert there. Regenerate the
cordis and config catalogs the seam moves left stale (line-number shifts).
2026-08-05 11:42:43 +08:00
_Kerman
97e7d68340 Merge remote-tracking branch 'origin/master' into xtr/react-loop-simplification
# Conflicts:
#	examples/acp-agent/tests/snapshots/cancel-tool-calls/session.jsonl
2026-08-05 10:39:18 +08:00
Huanqi Cao
acda0e39bc Merge remote-tracking branch 'origin/master' into feat/pwsh-tool 2026-08-04 20:39:17 +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
Hypatia May
cc89c529c6 Merge remote-tracking branch 'origin/master' into fix/landlock-runner-failure-classification 2026-08-04 19:05:33 +08:00
Huanqi Cao
39b0695d48 Merge remote-tracking branch 'origin/master' into feat/pwsh-tool
# Conflicts:
#	apps/cli/composition.md
#	docs/testing.i18n.yaml
#	docs/testing.md
#	docs/testing.zh.md
2026-08-04 17:54:45 +08:00
Hypatia May
8c72cd3a8f docs(sandbox): align final runner evidence 2026-08-04 17:45:12 +08:00
imccyu
a36c641db6 chore(docs): refresh WebSocket API catalogs 2026-08-04 16:21:09 +08:00
_Kerman
d5527da905 Merge remote-tracking branch 'origin/master' into xtr/react-loop-simplification
# Conflicts:
#	.agents/notes/implemented/feature/2026-07-28-web-terminal-card.i18n.yaml
#	.agents/notes/implemented/feature/2026-07-28-web-terminal-card.md
#	.agents/notes/implemented/feature/2026-07-28-web-terminal-card.zh.md
#	.agents/notes/implemented/feature/2026-07-30-search-render-card.i18n.yaml
#	.agents/notes/implemented/feature/2026-07-30-search-render-card.md
#	.agents/notes/implemented/feature/2026-07-30-search-render-card.zh.md
#	.agents/notes/implemented/feature/2026-07-30-web-read-card.i18n.yaml
#	.agents/notes/implemented/feature/2026-07-30-web-read-card.md
#	.agents/notes/implemented/feature/2026-07-30-web-read-card.zh.md
#	.agents/notes/implemented/feature/2026-07-30-web-result-card.i18n.yaml
#	.agents/notes/implemented/feature/2026-07-30-web-result-card.md
#	.agents/notes/implemented/feature/2026-07-30-web-result-card.zh.md
2026-08-04 15:49:07 +08:00
fz
193d918856 Merge remote-tracking branch 'origin/master' into codex/fix-headless-sigint
# Conflicts:
#	apps/cli/README.i18n.yaml
#	apps/cli/README.md
#	apps/cli/README.zh.md
#	apps/cli/config/base.cordis.yml
2026-08-04 15:18:48 +08:00