Commit Graph

6354 Commits

Author SHA1 Message Date
Yichen Jiang
d7c8d197ea Merge branch 'stack/agent-profiles-7-docs' into stack/agent-profiles-8-authoring 2026-08-07 14:26:33 +08:00
Yichen Jiang
04e97d16e3 Merge branch 'stack/agent-profiles-5-web-ui' into stack/agent-profiles-6-cordis-agent 2026-08-07 14:25:59 +08:00
Yichen Jiang
5ee6b13ecb Merge branch 'stack/agent-profiles-4-settings' into stack/agent-profiles-5-web-ui 2026-08-07 14:25:59 +08:00
Yichen Jiang
6c315d2cb6 Merge branch 'stack/agent-profiles-3-wire' into stack/agent-profiles-4-settings 2026-08-07 14:25:59 +08:00
Yichen Jiang
bdf5e39986 fix(cli): give the shipped preset's todo tool its required config
master made `allowParallelInProgress` a required field on dsh-tool-todo, so
every composition must choose it. The base patch was updated with the field,
but the Web surface takes `tool-todo` from the mounted preset instead, and
that row carried no config — so the `standard` preset failed to mount and
every session on the Web surface died at setup.

Also make the preset tree's write test reach the override. Tearing the agent
down stops in the loader's own "tree is being disposed" case before any write;
a live row reconfiguring itself is the trigger that actually gets there.
2026-08-07 14:25:35 +08:00
Yichen Jiang
90734c188e Merge branch 'stack/agent-profiles-7-docs' into stack/agent-profiles-8-authoring 2026-08-07 13:39:41 +08:00
Yichen Jiang
f1f7a0cbaf Merge branch 'stack/agent-profiles-5-web-ui' into stack/agent-profiles-6-cordis-agent 2026-08-07 13:39:40 +08:00
Yichen Jiang
a184d9efde Merge branch 'stack/agent-profiles-4-settings' into stack/agent-profiles-5-web-ui 2026-08-07 13:39:40 +08:00
Yichen Jiang
e95e413115 Merge branch 'stack/agent-profiles-3-wire' into stack/agent-profiles-4-settings 2026-08-07 13:39:40 +08:00
Yichen Jiang
f3f2129154 Merge branch 'stack/agent-profiles-2-configs' into stack/agent-profiles-3-wire
# Conflicts:
#	packages/host/apiproxy/src/api-proxy.ts
#	packages/host/apiproxy/tests/api-proxy-subagents.spec.ts
2026-08-07 13:39:29 +08:00
Yichen Jiang
2e15fc0bfe Merge branch 'stack/agent-profiles-1-seam' into stack/agent-profiles-2-configs 2026-08-07 13:34:19 +08:00
Yichen Jiang
a7be2ecb0f Merge remote-tracking branch 'origin/master' into stack/agent-profiles-1-seam 2026-08-07 13:34:08 +08:00
Chinesezjc
2d5256fd91 Merge pull request #1079 from deepseek-harness/feat/code-runtime-multilang-seam
feat(code-runtime): own portable-identifier exclusions at the seam
2026-08-07 13:27:50 +08:00
Yichen Jiang
ddacc8de45 Merge pull request #1735 from deepseek-harness/worktree/provider-credential-lifecycle
fix(web): recover provider credential lifecycle
2026-08-07 13:27:18 +08:00
Yichen Jiang
c682da36ad Merge branch 'stack/agent-profiles-7-docs' into stack/agent-profiles-8-authoring 2026-08-07 13:21:57 +08:00
Yichen Jiang
e511d4202f Merge branch 'stack/agent-profiles-5-web-ui' into stack/agent-profiles-6-cordis-agent 2026-08-07 13:21:57 +08:00
Yichen Jiang
e91edd7964 Merge branch 'stack/agent-profiles-4-settings' into stack/agent-profiles-5-web-ui 2026-08-07 13:21:57 +08:00
Yichen Jiang
a0194bdab2 Merge branch 'stack/agent-profiles-3-wire' into stack/agent-profiles-4-settings
# Conflicts:
#	packages/preset/agent-presets/tests/mount.spec.ts
2026-08-07 13:21:57 +08:00
Yichen Jiang
7233d40fc9 test: cover the two locations the composition test was carrying
Moving `web-agent-presets` to the built lane took its coverage with it, and the
per-file gate named what it had been the only reach for: the session header's
`agentPreset` type check, and the preset subtree's `write()` override. Neither
belonged to a real-composition boot — a header validation case and a subtree
behaviour are package-level facts.

The `write()` test states why the override exists: the inherited method
persists the tree whenever the Loader thinks the config moved, and disposing an
agent disposes its subtree, so inheriting it truncates the shipped preset to
`[]` the first time a session ends.
2026-08-07 13:21:03 +08:00
Chinesezjc
19e21dff52 Merge remote-tracking branch 'origin/master' into feat/code-runtime-multilang-seam
# Conflicts:
#	docs/core-data-structures/code-runtime.i18n.yaml
#	packages/code-runtime/code-runtime/README.i18n.yaml
2026-08-07 13:20:34 +08:00
Chinesezjc
a9e040a126 Merge pull request #1080 from deepseek-harness/feat/py-types-code-mode
feat(tools): render a Python SDK and dispatch Code Mode by runtime language
2026-08-07 13:14:41 +08:00
creatixchu
aa831f4f5e Merge remote-tracking branch 'origin/master' into worktree/turn-tail-actions
# Conflicts:
#	packages/client/ui-conversation/README.i18n.yaml
2026-08-07 11:55:53 +08:00
Yichen Jiang
05756950a8 Merge branch 'stack/agent-profiles-7-docs' into stack/agent-profiles-8-authoring
# Conflicts:
#	packages/client/ui-agent-preset/src/client/settings-store.ts
#	packages/client/ui-agent-preset/tests/settings-store.spec.ts
#	packages/host/apiproxy/src/api-proxy.ts
#	packages/host/apiproxy/tests/api-proxy-agent-preset.spec.ts
2026-08-07 11:52:05 +08:00
Yichen Jiang
1f9cf819a5 Merge branch 'stack/agent-profiles-5-web-ui' into stack/agent-profiles-6-cordis-agent 2026-08-07 11:48:53 +08:00
Yichen Jiang
d099a24cb1 fix(web): resume the preset the log records, and serialize the switch
Six review findings on the select surface, all reachable from the wire:

**Resume read the header, not the log.** The switch was recorded as
`agent-preset/selected` and every projection resolved from it, but `agentFor`
still composed from `inspected.meta.agentPreset` — the value written once at
creation. A blank session that switched and then ran turns came back after a
restart under the ORIGINAL preset, restoring that history under the tool set it
was not produced with, which is the mismatch this feature exists to prevent.
`inspected` already carries the events.

**Cold summaries dropped the preset entirely.** `summarizeCold` hand-copied
three header fields and omitted the fourth, so a restored session reported no
preset and the picker showed the deployment default. It now uses the same
projection the attached path does.

**`select` had no gate.** Two concurrent selects both passed the blank check;
the second `unmountPresetFor` then found no record, because the first had
already removed it, and both mounts installed into one agent layer. Selects on
one session now queue, and the blank check is re-read inside the queue. This is
not turn admission — a `session.prompt` racing a switch is the agent loop's to
reserve — but it closes the select-versus-select tear-down.

**A same-id restore was skipped.** The roster is a live directory, so "the same
inputs that worked a moment ago" does not hold: a changed file is exactly how a
same-id reselect fails, and skipping the restore left the agent with no
composition at all.

**`writable` was dead state**, initialized true and never set, so the row could
never disable. It now carries `settings.describe`'s bit — a browser that may
not write settings sees the current default and no control, rather than one
whose write answers `settings-not-exposed`.

**`list` was documented as id-ordered.** It is root-precedence order with each
root's own presets sorted, first root to supply an id winning.
2026-08-07 11:45:10 +08:00
Yichen Jiang
abd2e2973b Merge branch 'master' into worktree/provider-credential-lifecycle 2026-08-07 11:37:41 +08:00
Yichen Jiang
6edd98e2b2 Merge branch 'master' into worktree/provider-credential-lifecycle 2026-08-07 11:28:22 +08:00
Chinesezjc
0567727410 Merge remote-tracking branch 'origin/master' into feat/todo-multi-in-progress
# Conflicts:
#	apps/cli/config/base.cordis.yml
#	packages/client/ui-conversation/README.i18n.yaml
2026-08-07 11:27:24 +08:00
Chinesezjc
20651af6a6 Merge branch 'master' into feat/py-types-code-mode 2026-08-07 11:23:41 +08:00
Chinesezjc
e15e3db2b1 docs(code-runtime-worker): correct __debug__ attribution in binding-global comment
The inline comment called every dunder entry "the Python backend's" slot,
but `__debug__` is a CPython compile-time constant, not a seeded slot;
align the comment with the seam declaration, which is the single home for
why each entry is reserved.
2026-08-07 11:20:05 +08:00
Chinesezjc
efdc78cba3 docs(code-runtime): fix remaining dunder/backend wording and document exports in README
- index.ts: RESERVED_ERROR_MEMBERS JSDoc now says `__x__` (non-empty
  middle), matching DUNDER_MEMBER and the derivative docs; and
  PORTABLE_RESERVED_WORDS is described as covering portable *target*
  languages (Python is a later-PR backend, not yet shipped).
- types.ts + type-equiv docs: CodeBindingNamespace.global points to
  RESERVED_BINDING_GLOBALS by name with an `e.g.` sample rather than
  enumerating the set (single home), no longer implying `__debug__` is a
  seeded slot.
- Agent Note: separate `__debug__` (CPython compile-time constant) from
  the seeded bootstrap globals.
- README (en/zh): document the four exported exclusion sets and the
  portable identifier/naming contract — no cross-package link needed.
- Regenerate cordis services catalog for the shifted source line.
2026-08-07 11:20:05 +08:00
Chinesezjc
c05db227d5 docs(code-runtime): sync Agent Note and public JSDoc with the shipped seam
- Agent Note: correct the stale worker-adoption paragraph — the worker
  consumes the seam constants directly by name (no RESERVED_WORDS /
  RESERVED_ERROR_PROPERTIES re-alias) — and describe DUNDER_MEMBER as
  `__x__` (non-empty middle).
- types.ts: document RESERVED_BINDING_GLOBALS on CodeBindingNamespace.global
  (names like `__dsh_main__` pass the identifier rule but are still refused)
  and the non-empty-middle dunder rule on memberNameProperty; propagate to
  the type-equiv derivative docs (both languages, re-recorded).
2026-08-07 11:20:05 +08:00
Chinesezjc
4dc2b197d7 test(code-runtime): correct DUNDER_MEMBER edge cases for the __.+__ pattern
`____` has an empty middle between the two `__` pairs and does not match
`/^__.+__$/`; assert that (not a match) and add `__x__` as the shortest
real dunder form that does.
2026-08-07 11:20:05 +08:00
Chinesezjc
eb03aa86fe refactor(code-runtime): address seam review — drop worker aliases, tighten dunder
- Worker consumes PORTABLE_RESERVED_WORDS / RESERVED_ERROR_MEMBERS by
  their seam names directly, dropping the local re-alias (symmetry with
  the other two imported constants).
- Split the reserved-vs-duplicate diagnostics: a backend-owned global now
  reports "reserved binding global", not the misleading "duplicate".
- DUNDER_MEMBER uses `__.+__` so a bare `__` (empty middle, not a real
  CPython dunder) is not matched; add coverage.
- Worker misuse tests add `a$b` (second-char `$`) and `lambda` (Python
  keyword) so the identifier narrowing and reserved-word adoption are
  each pinned directly, not only transitively.
- Clarify the seam JSDoc (dunder-vs-explicit-set wording, Python backend
  is a later stack PR) and record in the Agent Note the obligation to
  widen RESERVED_BINDING_GLOBALS when the bootstrap seeds more globals.
2026-08-07 11:20:05 +08:00
Chinesezjc
5d4cea9dc1 feat(code-runtime): own portable-identifier exclusions at the seam
Move the reserved-word, reserved-global, reserved-error-member, and
dunder exclusion sets from the worker backend up to the code-runtime
seam package, and narrow the portable identifier subset to drop the
JS-only `$`. Every backend now imports one contract so a binding
namespace list valid on one backend is valid on all.

Delivers only the seam extension and the worker's adoption; the Python
backend, py-types renderer, and Code Mode language dispatch are later
PRs in the stack that depend on these exports.
2026-08-07 11:20:05 +08:00
Yichen Jiang
8d6b6098cb fix(web): start a new preset blank instead of copying the default
Copying is already its own action, offered on the row being copied, so the two
routes now arrive at the same editor by whichever one the author chose. **New
preset** starting from some preset nobody named put a composition in the editor
that the author had to recognise as unwanted before deleting it — and the
preset it copied was the deployment default, which is the one least likely to
be what someone reaching for "new" wanted.

A blank draft has no source, so it names none and makes no read: the editor's
"copied from" line and header clause appear only when there is a source.
2026-08-07 11:18:22 +08:00
creatixchu
fb8f5f5eb4 Merge master into fix/conversation-column-one-axis-scroll 2026-08-07 10:51:29 +08:00
creatixchu
600ee462d5 Merge remote-tracking branch 'origin/master' into worktree/turn-tail-actions 2026-08-07 10:50:49 +08:00
imccyu
3216150ae0 fix: address review round next
- subagents.history computes its projections best-effort on both arms
  (a hostile unit's fold rejection serves the page without the block,
  matching the session-list precedent) with dual-arm coverage
- the lifecycle-witness spec probes every field of the seven-key
  witness, protecting the key list itself
- list-children's own module docs catch up with the seq-gate contract,
  and the design note records the rung-two later-event window as an
  accepted, self-healing deviation of the corruption class
2026-08-07 10:17:35 +08:00
Yichen Jiang
9fc1430b79 fix(web): offer a just-authored preset on the new-session chip
Authoring writes a FILE, not a settings field, so nothing on the wire announces
it — `settings/changed` covers the default moving, never the directory. The
chip therefore kept the roster it read when it first mounted, and a preset
authored to be used was missing from the one screen that starts sessions.

The page that changes the directory now says so, and every surface reading the
same roster re-reads it. The chip subscribes rather than being reached from the
outer scope, because it is registered later, under `conversation`/`sessions`.
2026-08-07 03:31:23 +08:00
Yichen Jiang
a7ab8b27c5 fix(web): move the new-session chip when the default preset changes
The General row and the preset page already re-read on `settings/changed`, but
the hero chip did not — so changing the default and starting a session without
reloading composed the previous default. That is the one session the setting
claims to govern ("对此后新建的会话生效"), and the chip is what decides it.

A staged pick still wins: `load()` prefers the stage over the refreshed
fallback, so a refresh never overwrites a choice the user just made.
2026-08-07 03:20:49 +08:00
Yichen Jiang
0ab035c748 fix(web): name the preset in General settings, and say 预设 in Chinese
The preference row rendered `option.id` while every other surface — the
new-session chip, the session header label, the preset cards — renders the
metadata name. So the same roster read `标准模式` on one screen and `standard`
on the next, and the id is addressing, not a label. A preset that names itself
nothing still falls back to its id, which is then all there is to say about it.

The row's Chinese copy also still ended on the English word: the section is
`Agent 预设`, so the sentence about a running session keeping its composition
says 预设 too.
2026-08-07 03:01:30 +08:00
Yichen Jiang
d89f1ced94 Merge branch 'stack/agent-profiles-7-docs' into stack/agent-profiles-8-authoring
# Conflicts:
#	apps/cli/config/agent-presets/minimal/agent.cordis.yml
#	apps/cli/config/agent-presets/standard/agent.cordis.yml
#	packages/bundle/web-app/cordis.patch.yml
2026-08-07 02:59:26 +08:00
Yichen Jiang
1ebe0aef94 Merge branch 'stack/agent-profiles-5-web-ui' into stack/agent-profiles-6-cordis-agent 2026-08-07 02:58:53 +08:00
Yichen Jiang
c4e76384f4 Merge branch 'stack/agent-profiles-4-settings' into stack/agent-profiles-5-web-ui
# Conflicts:
#	apps/cli/package.json
#	pnpm-lock.yaml
2026-08-07 02:58:53 +08:00
Yichen Jiang
31b7dc439b Merge branch 'stack/agent-profiles-3-wire' into stack/agent-profiles-4-settings 2026-08-07 02:58:16 +08:00
Yichen Jiang
89ae94d89f 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.

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 preset that wants it. The TUI keeps its own
row, having no presets.

The composition tests now assert the global tool layer is EMPTY, which is the
invariant that would have caught this: any tool outside a preset reaches every
agent. The browser lane's composition, seeded-history, and hermetic-skill
assertions address their registries through a composed agent for the same
reason — those services are per session now, and the host cannot resolve an
`isolate` realm by name.
2026-08-07 02:57:30 +08:00
Yichen Jiang
f1d09ad4d1 fix(web): keep host-plane services out of the preset, and pin the lane's skill roots
Moving the agent plane behind per-session presets took five rows with it that
the host still owns, and the Web surface stopped booting: `host-apiproxy`
injects `subagents`, so with the registry disabled here the entry never
activated and `dsh web` died at plugin-tree load.

The criterion is injection, not subject matter. A host row that injects a
service resolves it before any session exists, so there is no agent to key by:
`bash-env` (which `apps/cli/src/web.ts` injects to publish `DSH_WEB_URL`), the
`subagents` registry and its spawn/fork backends (a process singleton whose
cross-session queries the api-proxy serves, and whose provider names are
globally unique), and `tool-subagent-report` (a continuable setup on that
singleton, registered once per live session by a list that is not scope-aware)
all stay host-plane. What a preset chooses is which delegation TOOLS it sees.

The browser lane needs the second half: skill roots now resolve inside a preset,
a subtree the lane's include patches cannot reach, so the row's documented
environment fallback is pinned for the whole scaffold lifetime — presets mount
when a session is created, not at boot. Without it a developer's real
~/.dsh/skills enters replay requests and goldens while CI sees none.
2026-08-07 02:33:53 +08:00
Yichen Jiang
f56c7d6638 Merge branch 'stack/agent-profiles-7-docs' into stack/agent-profiles-8-authoring 2026-08-07 01:01:51 +08:00
Yichen Jiang
9d836c24a1 Merge branch 'stack/agent-profiles-5-web-ui' into stack/agent-profiles-6-cordis-agent 2026-08-07 01:01:50 +08:00