From 64e0fbfd6d08415200cc3ea0947ee418c5b7bd0e Mon Sep 17 00:00:00 2001 From: Hypatia May Date: Mon, 10 Aug 2026 12:16:19 +0800 Subject: [PATCH 01/15] fix(subagent): inherit parent policy overrides in continuable children A continuable background child (the default backgroundMode for both delegation tools) never received the parent session's explicit sandbox/approval overrides: materialization applied only child composition, so a danger-full-access parent produced workspace-write children whose every out-of-workspace operation raised an approval prompt. Move the one-shot driver's capture/append pair into the shared child-agent module (captureDelegatedPolicyOverrides / appendDelegatedPolicyOverrides) and call it from both paths: startContinuable captures before its first await, only fresh materialization appends the source-tagged events (after any fork seed), and a cold resume replays the persisted delegation events instead of re-capturing the parent. Adds the continuable inheritance unit suite, the ACP snapshot scenario subagent-continuable-inheritance (fails without the fix), the continuable policy-inheritance Agent Note, and the seam-level README contract, with bilingual counterparts. Fixes #1692 --- ...7-25-subagent-policy-inheritance.i18n.yaml | 4 +- .../2026-07-25-subagent-policy-inheritance.md | 4 +- ...26-07-25-subagent-policy-inheritance.zh.md | 4 +- ...able-subagent-policy-inheritance.i18n.yaml | 6 + ...continuable-subagent-policy-inheritance.md | 29 + ...tinuable-subagent-policy-inheritance.zh.md | 29 + docs/event-producer-consumer.i18n.yaml | 4 +- docs/event-producer-consumer.md | 8 +- docs/event-producer-consumer.zh.md | 8 +- docs/subsystems/subagent.i18n.yaml | 4 +- docs/subsystems/subagent.md | 10 +- docs/subsystems/subagent.zh.md | 10 +- ...ontinuable-inheritance.cordis.snapshot.yml | 46 ++ ...ubagent-continuable-inheritance.cordis.yml | 11 + examples/acp-agent/tests/acp.snapshot.ts | 15 + .../tests/fixtures/parent-sandbox-override.ts | 19 + .../input.json | 19 + .../session.1.jsonl | 21 + .../session.jsonl | 29 + .../stdout.expected.jsonl | 4 + .../tool-schemas.1.expected.json | 543 ++++++++++++++++++ knip.json | 1 + .../subagent-inprocess/README.i18n.yaml | 4 +- .../subagent/subagent-inprocess/README.md | 2 +- .../subagent/subagent-inprocess/README.zh.md | 2 +- .../subagent/subagent-inprocess/src/index.ts | 20 +- packages/subagent/subagent/README.i18n.yaml | 4 +- packages/subagent/subagent/README.md | 4 + packages/subagent/subagent/README.zh.md | 4 + packages/subagent/subagent/package.json | 15 + packages/subagent/subagent/src/child-agent.ts | 61 +- .../subagent/subagent/src/continuation.ts | 30 +- packages/subagent/subagent/src/index.ts | 4 +- .../tests/continuation-inheritance.spec.ts | 171 ++++++ packages/subagent/subagent/tsconfig.json | 9 + pnpm-lock.yaml | 9 + 36 files changed, 1106 insertions(+), 61 deletions(-) create mode 100644 .agents/notes/implemented/feature/2026-08-10-continuable-subagent-policy-inheritance.i18n.yaml create mode 100644 .agents/notes/implemented/feature/2026-08-10-continuable-subagent-policy-inheritance.md create mode 100644 .agents/notes/implemented/feature/2026-08-10-continuable-subagent-policy-inheritance.zh.md create mode 100644 examples/acp-agent/subagent-continuable-inheritance.cordis.snapshot.yml create mode 100644 examples/acp-agent/subagent-continuable-inheritance.cordis.yml create mode 100644 examples/acp-agent/tests/fixtures/parent-sandbox-override.ts create mode 100644 examples/acp-agent/tests/snapshots/subagent-continuable-inheritance/input.json create mode 100644 examples/acp-agent/tests/snapshots/subagent-continuable-inheritance/session.1.jsonl create mode 100644 examples/acp-agent/tests/snapshots/subagent-continuable-inheritance/session.jsonl create mode 100644 examples/acp-agent/tests/snapshots/subagent-continuable-inheritance/stdout.expected.jsonl create mode 100644 examples/acp-agent/tests/snapshots/subagent-continuable-inheritance/tool-schemas.1.expected.json create mode 100644 packages/subagent/subagent/tests/continuation-inheritance.spec.ts diff --git a/.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.i18n.yaml b/.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.i18n.yaml index 0308005515..616a45e1d1 100644 --- a/.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.md -2026-07-25-subagent-policy-inheritance.md: aeff83795eedead9c75de6bbb74c1da1945092ca -2026-07-25-subagent-policy-inheritance.zh.md: c26e6bf8b79c86855022c384673957fe04ff761d +2026-07-25-subagent-policy-inheritance.md: a2f4d578de857ee63df5e7741c433210d5f1ef86 +2026-07-25-subagent-policy-inheritance.zh.md: f069bf290586447afc0b7d46a41ad4de9bfcbe8f diff --git a/.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.md b/.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.md index aeff83795e..a2f4d578de 100644 --- a/.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.md +++ b/.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.md @@ -10,7 +10,7 @@ Sandbox and approval overrides are per-session log folds. An in-process subagent ## Decision -The shared in-process driver snapshots `sandboxPolicy.overrideOf(parent.session)` and `approval.overrideOf(parent.session)` before its first await. A later parent switch belongs to the parent's future; cancel-and-redelegate takes a new snapshot. Both services are optional, and only explicit session overrides are copied, never deployment defaults or one-shot grants. +The delegation boundary snapshots `sandboxPolicy.overrideOf(parent.session)` and `approval.overrideOf(parent.session)` before its first await, through the shared child-agent helpers (`captureDelegatedPolicyOverrides`/`appendDelegatedPolicyOverrides` in `dsh-subagent`), which the one-shot driver and the [continuable start](2026-08-10-continuable-subagent-policy-inheritance.md) both call. A later parent switch belongs to the parent's future; cancel-and-redelegate takes a new snapshot. Both services are optional, and only explicit session overrides are copied, never deployment defaults or one-shot grants. Each captured value becomes a source-tagged `sandbox/mode` or `approval/policy` event appended during the child factory's unpublished setup. The session constructor has already fixed `Session.firstLiveSeq` at the fork-prefix length, so the inherited facts follow fork history, reach telemetry when the child is announced, and leave `SessionHeader.seedLength` at the prefix length. Existing last-event-wins folds therefore make the delegation snapshot beat stale fork history and let a later child switch beat the snapshot. A grandchild folds its parent's logged state, so the rule composes without another inheritance mechanism. @@ -33,4 +33,4 @@ A confined child gets the ordinary denial marker. No answerer currently owns an - Spawn, fork, and nested in-process children retain a parent's explicit sandbox and approval overrides. The focused suite proves real filesystem denial, stale-fork precedence, delegation-time capture, the live-event boundary, default omission, and context disposal. - The keyless headless snapshot is the assembled regression: only the parent is `read-only`, the deployment default is `workspace-write`, and the child's persisted event plus denied disk write both fail if capture is removed. -- Each delegation adds at most two log-only events. `dsh-subagent-inprocess` has optional peer types for the two policy services; compositions without either service behave unchanged. Out-of-process children retain their own deployment policy, and a running child does not follow later parent switches. +- Each delegation adds at most two log-only events. `dsh-subagent` and `dsh-subagent-inprocess` have optional peer types for the two policy services; compositions without either service behave unchanged. Out-of-process children retain their own deployment policy, and a running child does not follow later parent switches. diff --git a/.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.zh.md b/.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.zh.md index c26e6bf8b7..f069bf2905 100644 --- a/.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.zh.md +++ b/.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.zh.md @@ -10,7 +10,7 @@ Status: implemented ## 决策 -共享的进程内驱动器在第一次 await 之前对 `sandboxPolicy.overrideOf(parent.session)` 和 `approval.overrideOf(parent.session)` 获取快照。父级后续的切换属于父级的未来;取消后重新委派会取得新快照。这两个服务均为可选,仅复制显式会话覆盖项,绝不复制部署默认值或一次性授权。 +委派边界在第一次 await 之前,经由共享的子 agent 辅助函数(`dsh-subagent` 中的 `captureDelegatedPolicyOverrides`/`appendDelegatedPolicyOverrides`)对 `sandboxPolicy.overrideOf(parent.session)` 和 `approval.overrideOf(parent.session)` 获取快照;一次性驱动器与[可继续启动](2026-08-10-continuable-subagent-policy-inheritance.md)都会调用这些辅助函数。父级后续的切换属于父级的未来;取消后重新委派会取得新快照。这两个服务均为可选,仅复制显式会话覆盖项,绝不复制部署默认值或一次性授权。 每个捕获值都会成为子 agent 工厂在未发布设置阶段追加的一条带来源标记的 `sandbox/mode` 或 `approval/policy` 事件。会话构造函数已将 `Session.firstLiveSeq` 固定为 fork 前缀的长度,因此继承事实会排在 fork 历史之后,在子 agent 公布时进入遥测,同时让 `SessionHeader.seedLength` 保持为此前缀的长度。因此,既有的末事件胜出折叠会让委派快照压过陈旧的 fork 历史,并让子 agent 后续的切换压过该快照。孙代 agent 会折叠其父级已记录的状态,因此无需另一套继承机制即可组合此规则。 @@ -33,4 +33,4 @@ Status: implemented - spawn、fork 和嵌套的进程内子 agent 会保留父级显式的沙箱与审批覆盖项。聚焦测试套件证明真实文件系统拒绝、陈旧 fork 优先级、委派时捕获、实时事件边界、默认值省略与上下文释放。 - 无密钥 headless 快照是组装后应用层面的回归测试:只有父级是 `read-only`,部署默认值是 `workspace-write`;若移除捕获,子 agent 的持久化事件与被拒的磁盘写入这两项检查都会失败。 -- 每次委派最多增加两条仅日志事件。`dsh-subagent-inprocess` 为两个策略服务提供可选 peer 类型;未组合任一服务的组合保持原有行为。进程外子 agent 仍采用自身的部署策略,正在运行的子 agent 不跟随父级后续切换。 +- 每次委派最多增加两条仅日志事件。`dsh-subagent` 和 `dsh-subagent-inprocess` 为两个策略服务提供可选 peer 类型;未组合任一服务的组合保持原有行为。进程外子 agent 仍采用自身的部署策略,正在运行的子 agent 不跟随父级后续切换。 diff --git a/.agents/notes/implemented/feature/2026-08-10-continuable-subagent-policy-inheritance.i18n.yaml b/.agents/notes/implemented/feature/2026-08-10-continuable-subagent-policy-inheritance.i18n.yaml new file mode 100644 index 0000000000..dc23421912 --- /dev/null +++ b/.agents/notes/implemented/feature/2026-08-10-continuable-subagent-policy-inheritance.i18n.yaml @@ -0,0 +1,6 @@ +# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each +# side as of the last confirmed-consistent state. Both languages carry equal authority; +# after editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-08-10-continuable-subagent-policy-inheritance.md +2026-08-10-continuable-subagent-policy-inheritance.md: 39df910a920e6995ba6048fdd2613d2c216f5ec2 +2026-08-10-continuable-subagent-policy-inheritance.zh.md: 2a977eaa9aade189213fdd20a7d888e8e62efb48 diff --git a/.agents/notes/implemented/feature/2026-08-10-continuable-subagent-policy-inheritance.md b/.agents/notes/implemented/feature/2026-08-10-continuable-subagent-policy-inheritance.md new file mode 100644 index 0000000000..39df910a92 --- /dev/null +++ b/.agents/notes/implemented/feature/2026-08-10-continuable-subagent-policy-inheritance.md @@ -0,0 +1,29 @@ +# Agent Note: Continuable subagent policy inheritance — the durable child log owns the delegation-time snapshot + +Status: implemented + +English | [中文](2026-08-10-continuable-subagent-policy-inheritance.zh.md) + +## Problem + +The one-shot in-process driver has seeded parent sandbox/approval overrides into its children since the [in-process policy-inheritance decision](2026-07-25-subagent-policy-inheritance.md), but the continuable path never did: `SubagentContinuationManager` materialization applied only child composition and the activation setup registry. The default bundle wires both delegation tools as `backgroundMode: continuable`, so in a default deployment every background child silently fell back to deployment defaults — a parent switched to `danger-full-access` produced children stuck at `workspace-write` whose every out-of-workspace operation raised an approval prompt, and a parent's unattended `'never'` approval stance reverted to prompting ([dsh-external/issues#334](https://github.com/dsh-external/issues/issues/334)). + +## Decision + +The capture/append pair moved from the one-shot driver into the seam's shared child-agent module (`dsh-subagent/src/child-agent.ts`), the declared one home for shared child composition: `captureDelegatedPolicyOverrides(parent)` snapshots `sandboxPolicy.overrideOf(parent.session)` and `approval.overrideOf(parent.session)` through optional `ctx.get`, and `appendDelegatedPolicyOverrides(childSession, overrides)` appends the `source: 'delegation'` events. The one-shot driver and the continuation manager both call them, so the two paths cannot drift. + +`startContinuable` captures before its first await (`prepareContinuable`), the same "a later parent switch belongs to the parent's future" boundary as one-shot. The snapshot travels in `MaterializeInputs.create`, so only fresh materialization appends the events during unpublished setup, after any fork seed. A cold resume passes no `create` inputs and appends nothing: the persisted child log already carries the delegation events, and replaying the log IS the state. The durable child log — not the current Activation, not the resuming parent — owns the child's effective policy, so a parent switch between residency epochs never retroactively changes a durable child. + +## Alternatives considered + +- **An activation-setup-registry contribution** (`registerContinuableSetup`) — rejected: a contribution receives only the child context, so it cannot capture the parent's overrides at the delegation boundary; the registry applies on cold resume as well as fresh creation, which would re-append or re-capture; and nothing ties a contribution's capture to the start call's synchronous prefix, so the pre-await capture guarantee would be lost. +- **Re-capturing the parent's overrides at cold resume** — rejected: a resumed child would silently change policy with the parent's later switches, breaking the snapshot-at-delegation semantic and making effective policy depend on resume timing instead of the child's own log. A parent that wants a resumed child under new policy re-delegates. +- **Importing the one-shot driver's inline logic from the continuation manager** — rejected: the Service Definition package cannot depend on its own provider package, and duplicating the capture/append pair in `continuation.ts` invites drift; `child-agent.ts` already holds every other shared composition step. +- **Seeding the events into the descriptor seed turn** — rejected: the capture value is not known when the seed is assembled for every caller, and the one-shot precedent already establishes unpublished-setup appends as the ordering that places inherited facts after fork history with `firstLiveSeq` intact. + +## Consequences + +- Default-bundle background delegation (`backgroundMode: continuable`) now inherits a parent's explicit sandbox and approval overrides; compositions without either policy service behave unchanged. +- `dsh-subagent` gains optional peer types on `dsh-sandbox-policy` and `dsh-user-approval` (the `ctx.get` pattern the one-shot driver used); `dsh-subagent-inprocess` keeps its optional peers but delegates to the shared helpers. +- The continuable suite (`packages/subagent/subagent/tests/continuation-inheritance.spec.ts`) pins fresh-start seeding, pre-await capture, default omission, cold-resume snapshot stability, and fork-seed precedence; the ACP snapshot scenario `subagent-continuable-inheritance` pins the child's delegation event and read-only runtime context through the assembled app and fails when the capture is removed. +- Out-of-process providers (`acp`, `dsh-sdk`, `claude-code`, `codex`) support no continuable children (`prepareContinuable` absent), and their one-shot children keep their own deployment policy (`inheritsParentContext = false`); cross-process policy propagation remains out of scope. diff --git a/.agents/notes/implemented/feature/2026-08-10-continuable-subagent-policy-inheritance.zh.md b/.agents/notes/implemented/feature/2026-08-10-continuable-subagent-policy-inheritance.zh.md new file mode 100644 index 0000000000..2a977eaa9a --- /dev/null +++ b/.agents/notes/implemented/feature/2026-08-10-continuable-subagent-policy-inheritance.zh.md @@ -0,0 +1,29 @@ +# Agent Note: 可继续 subagent 策略继承——持久化子日志拥有委派时快照 + +Status: implemented + +[English](2026-08-10-continuable-subagent-policy-inheritance.md) | 中文 + +## 问题 + +自[进程内策略继承决策](2026-07-25-subagent-policy-inheritance.md)以来,一次性进程内驱动器一直会把父级的沙箱/审批覆盖项注入其子级,但可继续路径从未这样做:`SubagentContinuationManager` 的物化只应用子级组合与 Activation(激活)设置注册表。默认组合包把两个委派工具都配置为 `backgroundMode: continuable`,因此在默认部署中,每个后台子 agent(智能体)都静默回退到部署默认值:切换到 `danger-full-access` 的父级产出的子 agent 卡在 `workspace-write`,每次工作区外操作都会触发审批提示;父级无人值守的 `'never'` 审批立场也退回为发起提示的行为([dsh-external/issues#334](https://github.com/dsh-external/issues/issues/334))。 + +## 决策 + +捕获/追加这对函数从一次性驱动器移入该 seam 的共享子 agent 模块(`dsh-subagent/src/child-agent.ts`),即声明的共享子级组合唯一归属之处:`captureDelegatedPolicyOverrides(parent)` 通过可选的 `ctx.get` 对 `sandboxPolicy.overrideOf(parent.session)` 与 `approval.overrideOf(parent.session)` 建立快照,`appendDelegatedPolicyOverrides(childSession, overrides)` 则追加 `source: 'delegation'` 事件。一次性驱动器与继续执行管理器都调用它们,因此两条路径不会出现偏差。 + +`startContinuable` 在其第一次 await(`prepareContinuable`)之前完成捕获,沿用与一次性路径相同的「父级后续切换属于父级的未来」边界。快照放在 `MaterializeInputs.create` 中传递,因此只有全新物化会在未发布的设置阶段、排在任何 fork 种子之后追加这些事件。冷恢复(cold resume)不传入 `create` 输入,也不追加任何内容:持久化的子日志已经携带委派事件,而回放该日志本身就是状态。子 agent 的生效策略由持久化子日志拥有,而不是当前 Activation,也不是发起恢复的父级,因此父级在驻留纪元(residency epoch)之间的切换绝不会追溯性地改变一个持久化子 agent。 + +## 考虑过的替代方案 + +- **一项 Activation 设置注册表贡献**(`registerContinuableSetup`):不予采纳。贡献只接收子级上下文,因此无法在委派边界捕获父级的覆盖项;该注册表在冷恢复与全新创建时都会应用,会导致重复追加或重复捕获;而且没有任何机制把贡献的捕获绑定到 start 调用的同步前缀,await 前捕获的保证会因此丢失。 +- **在冷恢复时重新捕获父级覆盖项**:不予采纳。恢复的子 agent 会随父级后续切换静默改变策略,这会破坏委派时快照的语义,并让生效策略取决于恢复时机而非子级自身的日志。希望恢复的子 agent 采用新策略的父级应重新委派。 +- **让继续执行管理器导入一次性驱动器的内联逻辑**:不予采纳。Service Definition 包不能依赖自己的提供方包,而在 `continuation.ts` 中复制捕获/追加这对函数会招致偏差;`child-agent.ts` 已经承载其余每个共享组合步骤。 +- **把这些事件写入描述符种子轮次**:不予采纳。种子为每个调用方组装时,捕获值尚不可知;而且一次性路径的先例已经确立:在未发布的设置阶段追加,才是把继承事实排在 fork 历史之后、同时保持 `firstLiveSeq` 不变的顺序。 + +## 后果 + +- 默认组合包的后台委派(`backgroundMode: continuable`)现在会继承父级显式的沙箱与审批覆盖项;未组合任一策略服务的组合保持原有行为。 +- `dsh-subagent` 新增针对 `dsh-sandbox-policy` 与 `dsh-user-approval` 的可选 peer 类型(即一次性驱动器所用的 `ctx.get` 模式);`dsh-subagent-inprocess` 保留自己的可选 peer,但委托给共享辅助函数。 +- 可继续测试套件(`packages/subagent/subagent/tests/continuation-inheritance.spec.ts`)锁定全新启动的种子写入、await 前捕获、默认值省略、冷恢复快照稳定性与 fork 种子优先级;ACP 快照场景 `subagent-continuable-inheritance` 经组装后的应用锁定子级的委派事件与只读运行时上下文,移除捕获时即失败。 +- 进程外提供方(`acp`、`dsh-sdk`、`claude-code`、`codex`)不支持可继续子 agent(没有 `prepareContinuable`),其一次性子 agent 保留自身的部署策略(`inheritsParentContext = false`);跨进程策略传播仍不在范围内。 diff --git a/docs/event-producer-consumer.i18n.yaml b/docs/event-producer-consumer.i18n.yaml index 0a3d6007f1..1f2e85c3d6 100644 --- a/docs/event-producer-consumer.i18n.yaml +++ b/docs/event-producer-consumer.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write docs/event-producer-consumer.md -event-producer-consumer.md: 11eecf81a4eccadf2b97026154a78e4ed8a72164 -event-producer-consumer.zh.md: 2db5e596465b4adaf98c1b05692b61de3ced47b9 +event-producer-consumer.md: e238734189d6553f9008d958bafbf9556ee23bff +event-producer-consumer.zh.md: b74a1ed334919fd6db1187d7f0e07e2b6ddc5221 diff --git a/docs/event-producer-consumer.md b/docs/event-producer-consumer.md index 11eecf81a4..e238734189 100644 --- a/docs/event-producer-consumer.md +++ b/docs/event-producer-consumer.md @@ -37,10 +37,10 @@ This matrix shows which packages dispatch each harness-owned event and which pac | `settings/document-updated` | `emit` | [`packages/settings/settings/src/index.ts:170`](../packages/settings/settings/src/index.ts) | [`settings`](../packages/settings/settings) (`events.dispatch`) | `apiproxy` | | `settings/updated` | `emit` | [`packages/settings/settings/src/index.ts:157`](../packages/settings/settings/src/index.ts) | [`settings`](../packages/settings/settings) (`events.dispatch`) | [`settings`](../packages/settings/settings) | | `skills/change` | `emit` | [`packages/skill/skill/src/index.ts:284`](../packages/skill/skill/src/index.ts) | [`skill`](../packages/skill/skill) (`events.dispatch`) | - | -| `subagent/end` | `emit` | [`packages/subagent/subagent/src/index.ts:162`](../packages/subagent/subagent/src/index.ts) | [`subagent`](../packages/subagent/subagent) (`events.dispatch`) | [`hooks-claude`](../packages/hooks/hooks-claude), `server`, [`subagent`](../packages/subagent/subagent) | -| `subagent/provider-added` | `emit` | [`packages/subagent/subagent/src/index.ts:136`](../packages/subagent/subagent/src/index.ts) | [`subagent`](../packages/subagent/subagent) (`emit`) | [`subagent`](../packages/subagent/subagent), [`tool-subagent`](../packages/subagent/tool-subagent) | -| `subagent/provider-removed` | `emit` | [`packages/subagent/subagent/src/index.ts:142`](../packages/subagent/subagent/src/index.ts) | [`subagent`](../packages/subagent/subagent) (`events.dispatch`) | [`subagent`](../packages/subagent/subagent), [`tool-subagent`](../packages/subagent/tool-subagent) | -| `subagent/start` | `emit` | [`packages/subagent/subagent/src/index.ts:153`](../packages/subagent/subagent/src/index.ts) | [`subagent`](../packages/subagent/subagent) (`events.dispatch`) | [`hooks-claude`](../packages/hooks/hooks-claude), [`subagent`](../packages/subagent/subagent) | +| `subagent/end` | `emit` | [`packages/subagent/subagent/src/index.ts:164`](../packages/subagent/subagent/src/index.ts) | [`subagent`](../packages/subagent/subagent) (`events.dispatch`) | [`hooks-claude`](../packages/hooks/hooks-claude), `server`, [`subagent`](../packages/subagent/subagent) | +| `subagent/provider-added` | `emit` | [`packages/subagent/subagent/src/index.ts:138`](../packages/subagent/subagent/src/index.ts) | [`subagent`](../packages/subagent/subagent) (`emit`) | [`subagent`](../packages/subagent/subagent), [`tool-subagent`](../packages/subagent/tool-subagent) | +| `subagent/provider-removed` | `emit` | [`packages/subagent/subagent/src/index.ts:144`](../packages/subagent/subagent/src/index.ts) | [`subagent`](../packages/subagent/subagent) (`events.dispatch`) | [`subagent`](../packages/subagent/subagent), [`tool-subagent`](../packages/subagent/tool-subagent) | +| `subagent/start` | `emit` | [`packages/subagent/subagent/src/index.ts:155`](../packages/subagent/subagent/src/index.ts) | [`subagent`](../packages/subagent/subagent) (`events.dispatch`) | [`hooks-claude`](../packages/hooks/hooks-claude), [`subagent`](../packages/subagent/subagent) | | `system-prompt/assemble` | `waterfall` | [`packages/core/system-prompt/src/index.ts:29`](../packages/core/system-prompt/src/index.ts) | [`system-prompt`](../packages/core/system-prompt) (`waterfall`) | [`agent`](../packages/core/agent), [`system-prompt`](../packages/core/system-prompt) | | `system-prompt/change` | `emit` | [`packages/core/system-prompt/src/index.ts:35`](../packages/core/system-prompt/src/index.ts) | [`system-prompt`](../packages/core/system-prompt) (`emit`) | - | | `telemetry/record` | `waterfall` | [`packages/session/session-telemetry/src/index.ts:43`](../packages/session/session-telemetry/src/index.ts) | [`session-telemetry`](../packages/session/session-telemetry) (`waterfall`) | - | diff --git a/docs/event-producer-consumer.zh.md b/docs/event-producer-consumer.zh.md index 2db5e59646..b74a1ed334 100644 --- a/docs/event-producer-consumer.zh.md +++ b/docs/event-producer-consumer.zh.md @@ -39,10 +39,10 @@ | `settings/document-updated` | `emit` | [`packages/settings/settings/src/index.ts:170`](../packages/settings/settings/src/index.ts) | [`settings`](../packages/settings/settings) (`events.dispatch`) | `apiproxy` | | `settings/updated` | `emit` | [`packages/settings/settings/src/index.ts:157`](../packages/settings/settings/src/index.ts) | [`settings`](../packages/settings/settings) (`events.dispatch`) | [`settings`](../packages/settings/settings) | | `skills/change` | `emit` | [`packages/skill/skill/src/index.ts:284`](../packages/skill/skill/src/index.ts) | [`skill`](../packages/skill/skill) (`events.dispatch`) | - | -| `subagent/end` | `emit` | [`packages/subagent/subagent/src/index.ts:162`](../packages/subagent/subagent/src/index.ts) | [`subagent`](../packages/subagent/subagent) (`events.dispatch`) | [`hooks-claude`](../packages/hooks/hooks-claude), `server`, [`subagent`](../packages/subagent/subagent) | -| `subagent/provider-added` | `emit` | [`packages/subagent/subagent/src/index.ts:136`](../packages/subagent/subagent/src/index.ts) | [`subagent`](../packages/subagent/subagent) (`emit`) | [`subagent`](../packages/subagent/subagent), [`tool-subagent`](../packages/subagent/tool-subagent) | -| `subagent/provider-removed` | `emit` | [`packages/subagent/subagent/src/index.ts:142`](../packages/subagent/subagent/src/index.ts) | [`subagent`](../packages/subagent/subagent) (`events.dispatch`) | [`subagent`](../packages/subagent/subagent), [`tool-subagent`](../packages/subagent/tool-subagent) | -| `subagent/start` | `emit` | [`packages/subagent/subagent/src/index.ts:153`](../packages/subagent/subagent/src/index.ts) | [`subagent`](../packages/subagent/subagent) (`events.dispatch`) | [`hooks-claude`](../packages/hooks/hooks-claude), [`subagent`](../packages/subagent/subagent) | +| `subagent/end` | `emit` | [`packages/subagent/subagent/src/index.ts:164`](../packages/subagent/subagent/src/index.ts) | [`subagent`](../packages/subagent/subagent) (`events.dispatch`) | [`hooks-claude`](../packages/hooks/hooks-claude), `server`, [`subagent`](../packages/subagent/subagent) | +| `subagent/provider-added` | `emit` | [`packages/subagent/subagent/src/index.ts:138`](../packages/subagent/subagent/src/index.ts) | [`subagent`](../packages/subagent/subagent) (`emit`) | [`subagent`](../packages/subagent/subagent), [`tool-subagent`](../packages/subagent/tool-subagent) | +| `subagent/provider-removed` | `emit` | [`packages/subagent/subagent/src/index.ts:144`](../packages/subagent/subagent/src/index.ts) | [`subagent`](../packages/subagent/subagent) (`events.dispatch`) | [`subagent`](../packages/subagent/subagent), [`tool-subagent`](../packages/subagent/tool-subagent) | +| `subagent/start` | `emit` | [`packages/subagent/subagent/src/index.ts:155`](../packages/subagent/subagent/src/index.ts) | [`subagent`](../packages/subagent/subagent) (`events.dispatch`) | [`hooks-claude`](../packages/hooks/hooks-claude), [`subagent`](../packages/subagent/subagent) | | `system-prompt/assemble` | `waterfall` | [`packages/core/system-prompt/src/index.ts:29`](../packages/core/system-prompt/src/index.ts) | [`system-prompt`](../packages/core/system-prompt) (`waterfall`) | [`agent`](../packages/core/agent), [`system-prompt`](../packages/core/system-prompt) | | `system-prompt/change` | `emit` | [`packages/core/system-prompt/src/index.ts:35`](../packages/core/system-prompt/src/index.ts) | [`system-prompt`](../packages/core/system-prompt) (`emit`) | - | | `telemetry/record` | `waterfall` | [`packages/session/session-telemetry/src/index.ts:43`](../packages/session/session-telemetry/src/index.ts) | [`session-telemetry`](../packages/session/session-telemetry) (`waterfall`) | - | diff --git a/docs/subsystems/subagent.i18n.yaml b/docs/subsystems/subagent.i18n.yaml index e98438900d..06b2b87fad 100644 --- a/docs/subsystems/subagent.i18n.yaml +++ b/docs/subsystems/subagent.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write docs/subsystems/subagent.md -subagent.md: 99c54e0696c9c3585c50285ecb69b14c90d83c11 -subagent.zh.md: c5a79247a81f5174662f2b5d1ed2d3c20cf6c672 +subagent.md: b554bb20180b8784e38ac14fb83769eb354b53ae +subagent.zh.md: 14e2b9b3e571c97384ccf560ce23edbeda62a305 diff --git a/docs/subsystems/subagent.md b/docs/subsystems/subagent.md index 99c54e0696..b554bb2018 100644 --- a/docs/subsystems/subagent.md +++ b/docs/subsystems/subagent.md @@ -613,7 +613,7 @@ async start(name: string, request: SubagentStartRequest): Promise Types: [Agent](core.md) · [ContentBlock](llm-streaming.md) · [MessageId](llm-streaming.md) · [SessionId](core.md) -Source: [`packages/subagent/subagent/src/index.ts:167`](../../packages/subagent/subagent/src/index.ts) +Source: [`packages/subagent/subagent/src/index.ts:169`](../../packages/subagent/subagent/src/index.ts) @@ -639,7 +639,7 @@ A published child settled. Scope-filtered dispatch uses the same delegating pare Types: [Scoped](scope.md) -Source: [`packages/subagent/subagent/src/index.ts:162`](../../packages/subagent/subagent/src/index.ts) +Source: [`packages/subagent/subagent/src/index.ts:164`](../../packages/subagent/subagent/src/index.ts) @@ -656,7 +656,7 @@ A provider became resolvable in the registry. 'subagent/provider-added'(provider: SubagentProvider): void ``` -Source: [`packages/subagent/subagent/src/index.ts:136`](../../packages/subagent/subagent/src/index.ts) +Source: [`packages/subagent/subagent/src/index.ts:138`](../../packages/subagent/subagent/src/index.ts) @@ -673,7 +673,7 @@ A provider left the registry. Accepted runs remain holder-owned. 'subagent/provider-removed'(name: string): void ``` -Source: [`packages/subagent/subagent/src/index.ts:142`](../../packages/subagent/subagent/src/index.ts) +Source: [`packages/subagent/subagent/src/index.ts:144`](../../packages/subagent/subagent/src/index.ts) @@ -697,5 +697,5 @@ A provider established a published child. For in-process providers, `ctx.agents. Types: [Scoped](scope.md) -Source: [`packages/subagent/subagent/src/index.ts:153`](../../packages/subagent/subagent/src/index.ts) +Source: [`packages/subagent/subagent/src/index.ts:155`](../../packages/subagent/subagent/src/index.ts) diff --git a/docs/subsystems/subagent.zh.md b/docs/subsystems/subagent.zh.md index c5a79247a8..14e2b9b3e5 100644 --- a/docs/subsystems/subagent.zh.md +++ b/docs/subsystems/subagent.zh.md @@ -615,7 +615,7 @@ async start(name: string, request: SubagentStartRequest): Promise Types: [Agent](core.md) · [ContentBlock](llm-streaming.md) · [MessageId](llm-streaming.md) · [SessionId](core.md) -Source: [`packages/subagent/subagent/src/index.ts:167`](../../packages/subagent/subagent/src/index.ts) +Source: [`packages/subagent/subagent/src/index.ts:169`](../../packages/subagent/subagent/src/index.ts) @@ -641,7 +641,7 @@ A published child settled. Scope-filtered dispatch uses the same delegating pare Types: [Scoped](scope.md) -Source: [`packages/subagent/subagent/src/index.ts:162`](../../packages/subagent/subagent/src/index.ts) +Source: [`packages/subagent/subagent/src/index.ts:164`](../../packages/subagent/subagent/src/index.ts) @@ -658,7 +658,7 @@ A provider became resolvable in the registry. 'subagent/provider-added'(provider: SubagentProvider): void ``` -Source: [`packages/subagent/subagent/src/index.ts:136`](../../packages/subagent/subagent/src/index.ts) +Source: [`packages/subagent/subagent/src/index.ts:138`](../../packages/subagent/subagent/src/index.ts) @@ -675,7 +675,7 @@ A provider left the registry. Accepted runs remain holder-owned. 'subagent/provider-removed'(name: string): void ``` -Source: [`packages/subagent/subagent/src/index.ts:142`](../../packages/subagent/subagent/src/index.ts) +Source: [`packages/subagent/subagent/src/index.ts:144`](../../packages/subagent/subagent/src/index.ts) @@ -699,5 +699,5 @@ A provider established a published child. For in-process providers, `ctx.agents. Types: [Scoped](scope.md) -Source: [`packages/subagent/subagent/src/index.ts:153`](../../packages/subagent/subagent/src/index.ts) +Source: [`packages/subagent/subagent/src/index.ts:155`](../../packages/subagent/subagent/src/index.ts) diff --git a/examples/acp-agent/subagent-continuable-inheritance.cordis.snapshot.yml b/examples/acp-agent/subagent-continuable-inheritance.cordis.snapshot.yml new file mode 100644 index 0000000000..089f1e3ae3 --- /dev/null +++ b/examples/acp-agent/subagent-continuable-inheritance.cordis.snapshot.yml @@ -0,0 +1,46 @@ +# Keyless counterpart to subagent-continuable-inheritance.cordis.yml: replace +# the live adapter with replay and switch the root session to read-only at +# creation. +- id: base + name: '@cordisjs/plugin-include' + config: + path: ./cordis.yml + patches: + - id: llm-deepseek + name: '@deepseek-ai/dsh-llm-deepseek' + disabled: true + - id: acp-agent + name: '@deepseek-ai/dsh-acp-demo' + config: + provider: deepseek-official + model: deepseek-v4-flash + persistenceRoot: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions' + persistenceCompression: none + workspaceContext: + maxBytes: 65536 + persona: | + You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}. Your bash tool runs under a file sandbox — a `[sandbox: file access denied …]` result is policy, not a command bug. + + Verify your work by running the code or tests. Keep answers brief and factual. + - id: sandbox + name: '@deepseek-ai/dsh-sandbox-local' + config: + runnerCommand: + - bash + - -c + - while [ "$1" != "--" ]; do shift; done; shift; exec "$@" + - passthrough-runner + runnerFailureSignatures: + - 'passthrough-runner: profile rejected' + - insert: + - id: llm-replay + name: '@deepseek-ai/dsh-llm-replay' + config: + providers: + - id: deepseek-official + name: DeepSeek + models: + - id: deepseek-v4-flash + - id: deepseek-v4-pro + - id: parent-sandbox-override + name: './tests/fixtures/parent-sandbox-override.ts' diff --git a/examples/acp-agent/subagent-continuable-inheritance.cordis.yml b/examples/acp-agent/subagent-continuable-inheritance.cordis.yml new file mode 100644 index 0000000000..5ad395650d --- /dev/null +++ b/examples/acp-agent/subagent-continuable-inheritance.cordis.yml @@ -0,0 +1,11 @@ +# Policy-inheritance overlay: the root session is switched to read-only at +# creation (the UI Access switch equivalent), so a continuable background +# child must inherit that override instead of the deployment default. +- id: base + name: '@cordisjs/plugin-include' + config: + path: ./cordis.yml + patches: + - insert: + - id: parent-sandbox-override + name: './tests/fixtures/parent-sandbox-override.ts' diff --git a/examples/acp-agent/tests/acp.snapshot.ts b/examples/acp-agent/tests/acp.snapshot.ts index af044fc58f..4add3f82e8 100644 --- a/examples/acp-agent/tests/acp.snapshot.ts +++ b/examples/acp-agent/tests/acp.snapshot.ts @@ -47,6 +47,9 @@ const SESSION_TITLE_CONFIG = fileURLToPath(new URL('../session-title.cordis.yml' const SUBAGENT_DURABILITY_FAILURE_CONFIG = fileURLToPath( new URL('../subagent-durability-failure.cordis.yml', import.meta.url), ) +const SUBAGENT_CONTINUABLE_INHERITANCE_CONFIG = fileURLToPath( + new URL('../subagent-continuable-inheritance.cordis.yml', import.meta.url), +) const LSP_CONFIG = fileURLToPath(new URL('./lsp.cordis.yml', import.meta.url)) const WEB_CONFIG = fileURLToPath(new URL('../web.cordis.yml', import.meta.url)) const FS_SEARCH_CONFIG = fileURLToPath(new URL('./fs-search.cordis.yml', import.meta.url)) @@ -315,6 +318,18 @@ const SCENARIOS: Scenario[] = [ pinsChildToolSchemas: [1], configPath: SUBAGENT_DURABILITY_FAILURE_CONFIG, }, + // Authored policy-inheritance transcript: the root session is switched to + // read-only at creation (the UI Access switch equivalent), and the + // continuable background child's log carries that override as a + // `sandbox/mode` `source: 'delegation'` event, so the child's runtime + // context states the inherited policy instead of the deployment default. + { + name: 'subagent-continuable-inheritance', + hasModelTurn: true, + recorded: false, + pinsChildToolSchemas: [1], + configPath: SUBAGENT_CONTINUABLE_INHERITANCE_CONFIG, + }, // The in-process child is published before its first follow-up fails. The // foreground tool retains both that run-result failure and an independent // published-handle disposal failure. diff --git a/examples/acp-agent/tests/fixtures/parent-sandbox-override.ts b/examples/acp-agent/tests/fixtures/parent-sandbox-override.ts new file mode 100644 index 0000000000..02698d58c6 --- /dev/null +++ b/examples/acp-agent/tests/fixtures/parent-sandbox-override.ts @@ -0,0 +1,19 @@ +import type { Context } from 'cordis' +import { setSandboxMode } from '@deepseek-ai/dsh-sandbox-policy' +import type {} from '@deepseek-ai/dsh-agent' + +export const name = 'parent-sandbox-override' + +/** + * Snapshot-only overlay: switch each ROOT session to `read-only` at creation — + * the UI "Access" switch equivalent (one runtime `sandbox/mode` event on the + * session log) — so the scenario proves a continuable background child + * inherits the parent's explicit override as a `source: 'delegation'` event + * instead of falling back to the deployment default. + */ +export function apply(ctx: Context): void { + ctx.on('agent/created', ({ agent }) => { + if (agent.session.header.parentSession !== undefined) return + setSandboxMode(agent.session, 'read-only') + }) +} diff --git a/examples/acp-agent/tests/snapshots/subagent-continuable-inheritance/input.json b/examples/acp-agent/tests/snapshots/subagent-continuable-inheritance/input.json new file mode 100644 index 0000000000..183e21b557 --- /dev/null +++ b/examples/acp-agent/tests/snapshots/subagent-continuable-inheritance/input.json @@ -0,0 +1,19 @@ +{ + "steps": [ + { + "op": "initialize" + }, + { + "op": "newSession" + }, + { + "op": "prompt", + "text": "Follow these steps exactly, then stop. 1. Call the subagent tool once with run_in_background set to true, description 'Reply with CHILD_OK', and prompt 'Reply with exactly the word CHILD_OK and nothing else.'. 2. Reply with the single word DONE. Do not use the bash tool." + }, + { + "op": "waitForSubagentTurnEnd", + "child": 1, + "minimumTurn": 1 + } + ] +} diff --git a/examples/acp-agent/tests/snapshots/subagent-continuable-inheritance/session.1.jsonl b/examples/acp-agent/tests/snapshots/subagent-continuable-inheritance/session.1.jsonl new file mode 100644 index 0000000000..478198cf0c --- /dev/null +++ b/examples/acp-agent/tests/snapshots/subagent-continuable-inheritance/session.1.jsonl @@ -0,0 +1,21 @@ +{"type":"session","version":0,"id":"33333333-3333-4333-8333-333333333333","createdAt":1789000001000,"cwd":"{{cwd}}","parentSession":"11111111-1111-4111-8111-111111111111","origin":"subagent","delegationDepth":1} +{"type":"subagent/descriptor","seq":0,"time":1786333735890,"data":{"version":2,"mode":"continuable","provider":"spawn","label":"Reply with CHILD_OK","agentProvider":"deepseek-official","agentModel":"deepseek-v4-flash"}} +{"type":"session/end-seed","seq":1,"time":1786333735890,"data":{}} +{"type":"sandbox/mode","seq":2,"time":1786333735890,"data":{"mode":"read-only","source":"delegation"}} +{"type":"agent/inbox/spliced","seq":3,"time":1786333735891,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Reply with exactly the word CHILD_OK and nothing else."}],"source":{"kind":"user"},"role":"user","id":"42af19c7-e234-4752-93d4-bd9c943c1fe7"}]}} +{"type":"turn/start","seq":4,"time":1786333735891,"data":{"turn":1}} +{"type":"agent/inbox/spliced","seq":5,"time":1786333735891,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} +{"type":"step/start","seq":6,"time":1786333735916,"data":{"turn":1,"step":1}} +{"type":"user/message","seq":7,"time":1786333735916,"data":{"content":[{"type":"text","text":"Reply with exactly the word CHILD_OK and nothing else."}],"source":{"kind":"user"},"role":"user","id":"42af19c7-e234-4752-93d4-bd9c943c1fe7"},"surfaceOp":"append"} +{"type":"user/message","seq":8,"time":1786333735916,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: read-only. Any available operation enforced by the DSH file sandbox cannot modify files in the standing mode. Do not refuse a required modification from this policy alone: try an available tool normally and follow any denial and escalation guidance it returns.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: read-only. Any available operation enforced by the DSH file sandbox cannot modify files in the standing mode. Do not refuse a required modification from this policy alone: try an available tool normally and follow any denial and escalation guidance it returns."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}]},"role":"user","id":"5f181e93-3fd7-40f3-b5f7-21674b53d7c7"},"surfaceOp":"append"} +{"type":"session/title","seq":9,"time":1786333735916,"data":{"title":"Reply with exactly the word","messageSeqs":[7],"source":{"kind":"fallback"}}} +{"type":"request/header","seq":10,"time":1786333735916,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}} +{"type":"request/context","seq":11,"time":1786333735916,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} +{"type":"assistant/chunk","seq":12,"time":1786333735920,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"text"}}} +{"type":"assistant/chunk","seq":13,"time":1786333735921,"data":{"turn":1,"step":1,"chunk":{"type":"text-delta","index":0,"text":"CHILD_OK"}}} +{"type":"assistant/chunk","seq":14,"time":1786333735921,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"CHILD_OK"}}}} +{"type":"assistant/chunk","seq":15,"time":1786333735921,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}}} +{"type":"assistant/chunk","seq":16,"time":1786333735921,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"stop"}}}} +{"type":"assistant/message","seq":17,"time":1786333735921,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"text","text":"CHILD_OK"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"e2b94008-b067-4ca7-a576-6b4a9060cd83"},"usage":{"inputTokens":10,"outputTokens":5}},"sourceEventSeqs":[12,13,14,15,16],"surfaceOp":"append"} +{"type":"step/end","seq":18,"time":1786333735921,"data":{"turn":1,"step":1}} +{"type":"turn/end","seq":19,"time":1786333735921,"data":{"turn":1,"reason":{"kind":"completed"}}} diff --git a/examples/acp-agent/tests/snapshots/subagent-continuable-inheritance/session.jsonl b/examples/acp-agent/tests/snapshots/subagent-continuable-inheritance/session.jsonl new file mode 100644 index 0000000000..0968357f90 --- /dev/null +++ b/examples/acp-agent/tests/snapshots/subagent-continuable-inheritance/session.jsonl @@ -0,0 +1,29 @@ +{"type":"session","version":0,"id":"11111111-1111-4111-8111-111111111111","createdAt":1789000000000,"cwd":"{{cwd}}","delegationDepth":0} +{"type":"sandbox/mode","seq":0,"time":1786333735842,"data":{"mode":"read-only"}} +{"type":"agent/inbox/spliced","seq":1,"time":1786333735845,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Follow these steps exactly, then stop. 1. Call the subagent tool once with run_in_background set to true, description 'Reply with CHILD_OK', and prompt 'Reply with exactly the word CHILD_OK and nothing else.'. 2. Reply with the single word DONE. Do not use the bash tool."}],"source":{"kind":"user"},"role":"user","id":"d554122c-d857-4de0-aea0-6452f260d032"}]}} +{"type":"turn/start","seq":2,"time":1786333735845,"data":{"turn":1}} +{"type":"agent/inbox/spliced","seq":3,"time":1786333735845,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} +{"type":"step/start","seq":4,"time":1786333735878,"data":{"turn":1,"step":1}} +{"type":"user/message","seq":5,"time":1786333735878,"data":{"content":[{"type":"text","text":"Follow these steps exactly, then stop. 1. Call the subagent tool once with run_in_background set to true, description 'Reply with CHILD_OK', and prompt 'Reply with exactly the word CHILD_OK and nothing else.'. 2. Reply with the single word DONE. Do not use the bash tool."}],"source":{"kind":"user"},"role":"user","id":"d554122c-d857-4de0-aea0-6452f260d032"},"surfaceOp":"append"} +{"type":"user/message","seq":6,"time":1786333735878,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: read-only. Any available operation enforced by the DSH file sandbox cannot modify files in the standing mode. Do not refuse a required modification from this policy alone: try an available tool normally and follow any denial and escalation guidance it returns.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: read-only. Any available operation enforced by the DSH file sandbox cannot modify files in the standing mode. Do not refuse a required modification from this policy alone: try an available tool normally and follow any denial and escalation guidance it returns."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}]},"role":"user","id":"9a793bfc-c155-44f8-ba56-c6843338d6be"},"surfaceOp":"append"} +{"type":"session/title","seq":7,"time":1786333735878,"data":{"title":"Follow these steps exactly, then","messageSeqs":[5],"source":{"kind":"fallback"}}} +{"type":"request/header","seq":8,"time":1786333735879,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}} +{"type":"request/context","seq":9,"time":1786333735879,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} +{"type":"assistant/chunk","seq":10,"time":1789000000000,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}}} +{"type":"assistant/chunk","seq":11,"time":1786333735884,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":0,"id":"call_bg_start","name":"subagent","argumentsDelta":"{\"description\": \"Reply with CHILD_OK\", \"prompt\": \"Reply with exactly the word CHILD_OK and nothing else.\", \"run_in_background\": true}"}}} +{"type":"assistant/chunk","seq":12,"time":1786333735884,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"call_bg_start","name":"subagent","arguments":"{\"description\": \"Reply with CHILD_OK\", \"prompt\": \"Reply with exactly the word CHILD_OK and nothing else.\", \"run_in_background\": true}"}}}} +{"type":"assistant/chunk","seq":13,"time":1786333735884,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}}} +{"type":"assistant/chunk","seq":14,"time":1786333735884,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}} +{"type":"assistant/message","seq":15,"time":1786333735884,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"tool-call","id":"call_bg_start","name":"subagent","arguments":"{\"description\": \"Reply with CHILD_OK\", \"prompt\": \"Reply with exactly the word CHILD_OK and nothing else.\", \"run_in_background\": true}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"8ab58a42-e74c-4121-a6ca-63696e592287"},"usage":{"inputTokens":10,"outputTokens":5}},"sourceEventSeqs":[10,11,12,13,14],"surfaceOp":"append"} +{"type":"tool/call","seq":16,"time":1786333735885,"data":{"turn":1,"step":1,"callId":"call_bg_start","name":"subagent","arguments":"{\"description\": \"Reply with CHILD_OK\", \"prompt\": \"Reply with exactly the word CHILD_OK and nothing else.\", \"run_in_background\": true}"}} +{"type":"tool/result","seq":17,"time":1786333735892,"data":{"turn":1,"step":1,"message":{"source":{"kind":"tool","callId":"call_bg_start"},"content":[{"type":"tool-result","toolCallId":"call_bg_start","content":[{"type":"text","text":"started subagent 33333333-3333-4333-8333-333333333333"}],"isError":false}],"role":"user","id":"3478555e-f0d0-4ec1-a7e4-a15ab24b9ecf"}},"sourceEventSeqs":[16],"surfaceOp":"append"} +{"type":"step/end","seq":18,"time":1786333735892,"data":{"turn":1,"step":1}} +{"type":"step/start","seq":19,"time":1786333735897,"data":{"turn":1,"step":2}} +{"type":"assistant/chunk","seq":20,"time":1786333735903,"data":{"turn":1,"step":2,"chunk":{"type":"block-start","index":0,"blockType":"text"}}} +{"type":"assistant/chunk","seq":21,"time":1786333735903,"data":{"turn":1,"step":2,"chunk":{"type":"text-delta","index":0,"text":"DONE"}}} +{"type":"assistant/chunk","seq":22,"time":1786333735903,"data":{"turn":1,"step":2,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"DONE"}}}} +{"type":"assistant/chunk","seq":23,"time":1786333735904,"data":{"turn":1,"step":2,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}}} +{"type":"assistant/chunk","seq":24,"time":1786333735904,"data":{"turn":1,"step":2,"chunk":{"type":"finish","reason":{"kind":"stop"}}}} +{"type":"assistant/message","seq":25,"time":1786333735904,"data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"text","text":"DONE"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"4057a08e-b50e-45e7-beb0-c74485f2b7d6"},"usage":{"inputTokens":10,"outputTokens":5}},"sourceEventSeqs":[20,21,22,23,24],"surfaceOp":"append"} +{"type":"step/end","seq":26,"time":1786333735904,"data":{"turn":1,"step":2}} +{"type":"turn/end","seq":27,"time":1786333735904,"data":{"turn":1,"reason":{"kind":"completed"}}} diff --git a/examples/acp-agent/tests/snapshots/subagent-continuable-inheritance/stdout.expected.jsonl b/examples/acp-agent/tests/snapshots/subagent-continuable-inheritance/stdout.expected.jsonl new file mode 100644 index 0000000000..82ae8907ca --- /dev/null +++ b/examples/acp-agent/tests/snapshots/subagent-continuable-inheritance/stdout.expected.jsonl @@ -0,0 +1,4 @@ +{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":1,"agentInfo":{"name":"deepseek-harness-acp","version":"0.0.1"},"agentCapabilities":{"promptCapabilities":{"image":false,"audio":false,"embeddedContext":false}},"authMethods":[]}} +{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}"}} +{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_message_chunk","content":{"type":"text","text":"DONE"}}}} +{"jsonrpc":"2.0","id":3,"result":{"stopReason":"end_turn"}} diff --git a/examples/acp-agent/tests/snapshots/subagent-continuable-inheritance/tool-schemas.1.expected.json b/examples/acp-agent/tests/snapshots/subagent-continuable-inheritance/tool-schemas.1.expected.json new file mode 100644 index 0000000000..7dd791cf27 --- /dev/null +++ b/examples/acp-agent/tests/snapshots/subagent-continuable-inheritance/tool-schemas.1.expected.json @@ -0,0 +1,543 @@ +{ + "initial": [ + { + "name": "bash", + "description": "Execute a bash command (`bash -c`) and return its stdout/stderr. Each call runs in a fresh shell: no state (cwd, variables, functions) persists between calls — pass `workdir` instead of using `cd`. Non-zero exits are reported as `[exit code: N]`. Current harness environment facts are exposed through managed `$DSH_*` variables; inspect them when needed. Commands may run under a file sandbox; a blocked file operation is reported as `[sandbox: file access denied under mode]` — a policy denial, not a bug in the command; do not retry another way. Long output is truncated to its tail; the full output is saved to a file whose path is reported when available. Set `run_in_background: true` for long-running commands: the call returns a task id immediately; read its output with `task_output` and stop it with `task_kill`. Attempting a command the sandbox may deny is safe and expected: run it and read the marker rather than assuming the denial. When a command is denied and a wider mode would let it succeed, escalate immediately in the same turn — the one sanctioned exception to a denial: retry the exact same command once with `sandbox_permissions` (the narrowest wider mode that suffices) plus a one-sentence `justification`. Do not detour through chat to ask permission first — the approval prompt raised by that retry is how the user consents. If the session states approval prompts are disabled, there is no exception: a denial is final — do not set `sandbox_permissions`. Never escalate speculatively: ground the request in a real denial — normally the one this command just hit; escalating up front is fine only when this session already denied the same access. A rejected escalation is final for that command — stop and explain, never work around it — but it does not forbid attempting or escalating other commands later.", + "parameters": { + "type": "object", + "properties": { + "command": { + "type": "string", + "description": "The bash command to execute." + }, + "description": { + "type": "string", + "description": "Clear, concise description of what this command does in active voice, 5-10 words (shown in the UI). Examples: \"ls\" → \"List files in current directory\"; \"git status\" → \"Show working tree status\"; \"npm install\" → \"Install package dependencies\"." + }, + "timeoutMs": { + "type": "number", + "description": "Timeout in milliseconds. The executor applies its configured default and cap, and kills the command on expiry." + }, + "workdir": { + "type": "string", + "description": "Working directory for this command. Defaults to the session workspace; a relative path is resolved against it." + }, + "run_in_background": { + "type": "boolean", + "description": "Run in the background and return a task id immediately (collect with task_output, stop with task_kill). No timeout applies." + }, + "sandbox_permissions": { + "type": "string", + "description": "The wider sandbox mode this command needs. Only valid as a one-shot retry of a command the sandbox just denied; requires justification and user approval.", + "enum": [ + "workspace-write", + "danger-full-access" + ] + }, + "justification": { + "type": "string", + "description": "Required with sandbox_permissions: one sentence for the user explaining why this exact command needs the wider access." + } + }, + "required": [ + "command", + "description" + ] + } + }, + { + "name": "create_goal", + "description": "Create one persisted same-session completion goal when the current direct human request is a long-running objective that should continue across autonomous goal rounds. You may infer that intent without requiring the user to say \"create a goal\". Do not use this for trivial single-turn work. Execution rejects non-human and subagent authority.", + "parameters": { + "type": "object", + "properties": { + "objective": { + "type": "string", + "description": "The concrete completion objective inferred from the direct human request." + }, + "max_goal_rounds": { + "type": "number", + "description": "Optional positive safe-integer limit on automatic continuation rounds." + } + }, + "required": [ + "objective" + ] + } + }, + { + "name": "edit", + "description": "Edit an existing UTF-8 text file by replacing literal text.", + "parameters": { + "type": "object", + "properties": { + "file_path": { + "type": "string", + "description": "Path to edit, resolved by the filesystem backend." + }, + "old_string": { + "type": "string", + "description": "Literal text to replace. Must match exactly." + }, + "new_string": { + "type": "string", + "description": "Literal replacement text. Use an empty string to delete the match." + }, + "replace_all": { + "type": "boolean", + "description": "Replace all matches. Defaults to false; when false, old_string must appear exactly once." + }, + "sandbox_permissions": { + "type": "string", + "description": "The wider sandbox mode this file operation needs. Only valid as a one-shot retry of an operation the sandbox just denied; requires justification and user approval.", + "enum": [ + "workspace-write", + "danger-full-access" + ] + }, + "justification": { + "type": "string", + "description": "Required with sandbox_permissions: one sentence for the user explaining why this exact file operation needs the wider access." + } + }, + "required": [ + "file_path", + "old_string", + "new_string" + ] + } + }, + { + "name": "get_goal", + "description": "Read the current same-session goal, including its exact id/revision, objective, phase, completed continuation rounds, round limit, blocker reason when present, and whether another continuation is armed. Call this before updating a goal.", + "parameters": { + "type": "object", + "properties": {} + } + }, + { + "name": "interrupt_agent", + "description": "Request cancellation of a background agent's current turn by its agent id. The target may be your direct child or a deeper agent created under you. Only the current turn stops: messages already queued for the agent stay parked until a later send_message, agents it started keep running, and the agent itself stays available for follow-ups. This call returns as soon as the stop request is accepted, so the target may keep running briefly; interrupting an agent that already finished is an accepted no-op.", + "parameters": { + "type": "object", + "properties": { + "agent_id": { + "type": "string", + "description": "The agent id of the running agent to interrupt." + } + }, + "required": [ + "agent_id" + ] + } + }, + { + "name": "list_agents", + "description": "List your continuable background subagents by durable id and label. Status comes from the live registry: running means the agent is working right now, idle means it is loaded but between turns (it may be waiting on agents it started), and complete means it exists only in storage — a direct child remains a `send_message` candidate in every status. The snapshot is not a delivery promise — `send_message` performs the authoritative check and may still fail. Children that could not be read are reported as diagnostics instead of being silently dropped. Scope `descendants` walks the whole tree below you in stable pre-order, annotating each entry with its durable direct-parent session id and depth. You may use `send_message` only for depth-1 entries; deeper entries are candidates for `interrupt_agent` only.", + "parameters": { + "type": "object", + "properties": { + "scope": { + "type": "string", + "description": "children (default) lists direct children only; descendants walks the complete tree below you.", + "enum": [ + "children", + "descendants" + ] + } + } + } + }, + { + "name": "ralph", + "description": "Run a foreground fresh-agent Ralph loop toward one immutable objective. Use only when the direct human explicitly asks for Ralph or fresh-agent iteration. Each round opens a new child with no parent conversation or prior child session; the shared workspace is long-term memory, and only a bounded structured report crosses rounds. The call returns when a worker reports completion or a concrete blocker, or at the round limit. Ordinary long-running same-session work belongs to goal tools.", + "parameters": { + "type": "object", + "properties": { + "objective": { + "type": "string", + "description": "The immutable completion objective for every fresh Ralph round." + }, + "maxRounds": { + "type": "number", + "description": "Optional positive safe-integer round cap, bounded by the deployment ceiling." + } + }, + "required": [ + "objective" + ] + } + }, + { + "name": "read", + "description": "Read a UTF-8 text file and return line-numbered content.", + "parameters": { + "type": "object", + "properties": { + "file_path": { + "type": "string", + "description": "Path to read, resolved by the filesystem backend." + }, + "offset": { + "type": "number", + "description": "1-based first line to return. Defaults to 1." + }, + "limit": { + "type": "number", + "description": "Maximum number of lines to return. Defaults to 2000." + } + }, + "required": [ + "file_path" + ] + } + }, + { + "name": "report", + "description": "Report selected content to the agent that started you. Call this zero or more times for progress, findings, or a final answer. Reporting does not end your turn or finish your work, and only your direct parent receives it. A failed call may still have arrived, so do not blindly repeat it.", + "parameters": { + "type": "object", + "properties": { + "output": { + "type": "string", + "description": "Self-contained content for your parent; it does not see your private work." + } + }, + "required": [ + "output" + ] + } + }, + { + "name": "send_message", + "description": "Send a message to a background subagent by its subagent id, continuing the same conversation. It becomes the subagent's next turn: if it is still working, the message waits until its current turn finishes, so it cannot redirect work already underway. This call returns no answer from the subagent — only confirmation that the message was delivered — so use it to give it more work. A failure means the message was NOT delivered.", + "parameters": { + "type": "object", + "properties": { + "subagent_id": { + "type": "string", + "description": "The subagent id returned when the background subagent was started." + }, + "message": { + "type": "string", + "description": "The message to deliver to the subagent." + } + }, + "required": [ + "subagent_id", + "message" + ] + } + }, + { + "name": "skill", + "description": "Load the full instructions for an available skill. Call this with the exact skill name from the session skill catalog before acting on a task that names or clearly matches that skill.", + "parameters": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "The exact skill name from the available skills list." + } + }, + "required": [ + "name" + ] + } + }, + { + "name": "subagent", + "description": "Delegate a self-contained task to a subagent (a separate agent that works in its own context) and return its final result. Use this to offload focused, independent work — research, a scoped implementation, an analysis — so it does not consume this conversation's context. The subagent runs to completion and you receive only its final answer, not its intermediate steps. Give it a complete, standalone prompt: it does not see this conversation. Set `run_in_background: true` to start a background subagent that keeps its conversation: you receive only its subagent id, never its result, and it works on its own. Use this for work whose result you do not need returned by this call; `send_message` sends it more work.", + "parameters": { + "type": "object", + "properties": { + "description": { + "type": "string", + "description": "A short (3-5 word) description of the delegated task, for display." + }, + "prompt": { + "type": "string", + "description": "The complete, self-contained task for the subagent. It does not share this conversation's context, so include everything it needs." + }, + "run_in_background": { + "type": "boolean", + "description": "Run as a background subagent that keeps its conversation and return only its subagent id. This call never returns its result; send it more work with send_message." + } + }, + "required": [ + "description", + "prompt" + ] + } + }, + { + "name": "subagent_fork", + "description": "Delegate a task to a subagent that inherits this conversation: a child agent seeded with all completed turns so far (it does not see the current in-flight turn), returning only its final result. Use this when the subtask builds on this conversation's context — a follow-up analysis, a review, a continuation — without consuming this conversation's context for the work itself. You receive only its final answer, not its intermediate steps. Set `run_in_background: true` to start a background subagent that keeps its conversation: you receive only its subagent id, never its result, and it works on its own. Use this for work whose result you do not need returned by this call; `send_message` sends it more work.", + "parameters": { + "type": "object", + "properties": { + "description": { + "type": "string", + "description": "A short (3-5 word) description of the delegated task, for display." + }, + "prompt": { + "type": "string", + "description": "The task for the subagent. It already sees this conversation's completed turns, so build on them freely and state only what is new." + }, + "run_in_background": { + "type": "boolean", + "description": "Run as a background subagent that keeps its conversation and return only its subagent id. This call never returns its result; send it more work with send_message." + } + }, + "required": [ + "description", + "prompt" + ] + } + }, + { + "name": "task_kill", + "description": "Request cancellation of a running background task by task id. Returns immediately; the task settles as killed once its work actually stops.", + "parameters": { + "type": "object", + "properties": { + "task_id": { + "type": "string", + "description": "Task id returned by the tool that started the background work." + }, + "reason": { + "type": "string", + "description": "Optional short reason, recorded in the log and forwarded to the task." + } + }, + "required": [ + "task_id" + ] + } + }, + { + "name": "task_list", + "description": "List your background tasks (running and finished) with their ids, kinds, and statuses.", + "parameters": { + "type": "object", + "properties": {} + } + }, + { + "name": "task_output", + "description": "Read a background task. Stream tasks return only output since the previous read; final-output tasks return their result after settlement. Every response ends with `[status: ...]`. Reads are non-blocking unless `wait: true`, which waits up to the configured cap.", + "parameters": { + "type": "object", + "properties": { + "task_id": { + "type": "string", + "description": "Task id returned by the tool that started the background work." + }, + "wait": { + "type": "boolean", + "description": "Block until the task reaches a terminal status or the timeout expires. A timed-out wait returns [status: running] and leaves the task alive." + }, + "timeout_ms": { + "type": "number", + "description": "Max wait in milliseconds (only meaningful with wait: true). Defaults to the configured wait timeout; capped by the configured maximum." + } + }, + "required": [ + "task_id" + ] + } + }, + { + "name": "todo_write", + "description": "Record and update a structured task list for the current work. Send the ENTIRE list every call — it REPLACES the previous list (there are no partial updates, no per-item edits). Use it to plan multi-step work and show progress: add one todo per concrete step before you start. Mark every todo being actively worked on `in_progress` — several at once when work genuinely runs in parallel (e.g. concurrent subagents or background commands), one for sequential work; while work remains, at least one task should be `in_progress`. Mark a todo `completed` the moment it is done (do not batch completions), and allow no `in_progress` item only once all work is complete. Skip the list for trivial single-step tasks. Statuses: `pending` (not started), `in_progress` (being worked on now), `completed` (finished).", + "parameters": { + "type": "object", + "properties": { + "todos": { + "type": "array", + "description": "The COMPLETE task list, replacing any previous list.", + "items": { + "type": "object", + "additionalProperties": false, + "properties": { + "content": { + "type": "string", + "description": "What the task is — a short imperative line." + }, + "status": { + "type": "string", + "description": "pending (not started) | in_progress (now) | completed (done).", + "enum": [ + "pending", + "in_progress", + "completed" + ] + } + }, + "required": [ + "content", + "status" + ] + } + } + }, + "required": [ + "todos" + ] + } + }, + { + "name": "update_goal", + "description": "Update the exact current goal revision. edit, pause, and resume require a direct top-level human request. During an automatic continuation of the current goal, complete and blocked are also allowed. blocked is rejected before the configured minimum round count; the model remains responsible for judging that the same condition persisted across those rounds and must explain it in blocked_reason.", + "parameters": { + "type": "object", + "properties": { + "goal_id": { + "type": "string", + "description": "Exact id returned by get_goal." + }, + "revision": { + "type": "number", + "description": "Exact positive revision returned by get_goal." + }, + "action": { + "type": "string", + "description": "edit | pause | resume | complete | blocked", + "enum": [ + "edit", + "pause", + "resume", + "complete", + "blocked" + ] + }, + "objective": { + "type": "string", + "description": "Replacement objective; valid only with action edit." + }, + "max_goal_rounds": { + "type": "number", + "description": "Replacement cap; valid only with action edit." + }, + "blocked_reason": { + "type": "string", + "description": "Concrete blocking condition; required only with action blocked." + } + }, + "required": [ + "goal_id", + "revision", + "action" + ] + } + }, + { + "name": "workflow", + "description": "Run a JavaScript workflow script that orchestrates subagents at scale. Use this for work that fans out across many independent pieces — an audit over many files, a migration, multi-angle research, adversarial verification of findings — where you write the orchestration as a script instead of delegating turn by turn.\n\nThe workflow's identity rides the `meta` parameter as JSON: required `name` (short kebab-case) and `description` strings, optional `whenToUse` string and `phases` array (`{title, detail?, provider?, model?}`). The `script` parameter is the plain JavaScript body ONLY (NOT TypeScript, and NO `export const meta` statement — meta is a parameter, not code), running with top-level await; end with `return ` — the value must be JSON-serializable and is this tool's result.\n\nScript-body hooks:\n- `agent(prompt, opts?): Promise` — run one subagent to completion. Without `opts.schema` it resolves to the child's final text; with `opts.schema` (an object-rooted JSON Schema using ONLY type/properties/required/additionalProperties/items/enum/const/oneOf — no pattern/format/numeric bounds) it resolves to the validated object. Resolves `null` when the child fails (filter with `.filter(Boolean)`). Other opts: `label` (display), `phase` (progress group), and independent `provider`/`model` LLM target overrides (either may be provided alone). Anything else (`effort`/`isolation`/`agentType`) is rejected loudly.\n- `pipeline(items, ...stages): Promise` — run each item through the stages independently with NO barrier between stages (prefer this for multi-stage work). Each stage receives `(prev, item, index)`. An ordinary stage throw drops that ITEM to `null` and skips its remaining stages.\n- `parallel(thunks): Promise` — run zero-argument functions concurrently and await ALL of them (a barrier; use only when a stage genuinely needs every prior result together). A throwing thunk resolves to `null`.\n- `phase(title)` — start a progress phase; `log(message)` — narrate progress; `args` — the tool call's `args` input, verbatim.\n\nMisused hooks (bad arguments, unknown options, unsupported schemas, tripped caps) throw errors that ALWAYS kill the script — they never dissolve into a per-item `null`.\n\nConstraints: concurrency and total-agent caps apply; no filesystem, network, timers, or Node.js APIs are provided — the agents do the work, the script only coordinates them. The run executes in the foreground: this call returns when the whole script finishes.", + "parameters": { + "type": "object", + "properties": { + "script": { + "type": "string", + "description": "The plain-JS workflow script body (top-level await allowed; NO `export const meta` statement; end with `return `)." + }, + "meta": { + "type": "object", + "description": "The workflow identity block (plain JSON — never code).", + "additionalProperties": true, + "properties": { + "name": { + "type": "string", + "description": "Short kebab-case workflow name." + }, + "description": { + "type": "string", + "description": "One-line description of what the workflow does." + }, + "whenToUse": { + "type": "string", + "description": "Optional guidance on when this workflow applies." + }, + "phases": { + "type": "array", + "description": "Optional phase declarations matched by phase() calls.", + "items": { + "type": "object", + "additionalProperties": true, + "properties": { + "title": { + "type": "string", + "description": "The phase title phase() calls match by exact string." + }, + "detail": { + "type": "string", + "description": "Optional one-line description of the phase." + }, + "provider": { + "type": "string", + "description": "Optional provider override this phase is expected to use." + }, + "model": { + "type": "string", + "description": "Optional model override this phase is expected to use." + } + }, + "required": [ + "title" + ] + } + } + }, + "required": [ + "name", + "description" + ] + }, + "args": { + "type": "object", + "description": "Optional JSON input exposed to the script as the `args` global (wrap a bare list as a field, e.g. {\"files\": [...]}).", + "additionalProperties": true + } + }, + "required": [ + "script", + "meta" + ] + } + }, + { + "name": "write", + "description": "Create or fully replace a UTF-8 text file.", + "parameters": { + "type": "object", + "properties": { + "file_path": { + "type": "string", + "description": "Path to write, resolved by the filesystem backend." + }, + "content": { + "type": "string", + "description": "Full UTF-8 text content to write." + }, + "sandbox_permissions": { + "type": "string", + "description": "The wider sandbox mode this file operation needs. Only valid as a one-shot retry of an operation the sandbox just denied; requires justification and user approval.", + "enum": [ + "workspace-write", + "danger-full-access" + ] + }, + "justification": { + "type": "string", + "description": "Required with sandbox_permissions: one sentence for the user explaining why this exact file operation needs the wider access." + } + }, + "required": [ + "file_path", + "content" + ] + } + } + ], + "changes": [] +} diff --git a/knip.json b/knip.json index 812f7446bc..9a091a068e 100644 --- a/knip.json +++ b/knip.json @@ -48,6 +48,7 @@ "headless-agent/tests/fixtures/e2b/e2b/bin.ts", "acp-agent/tests/snapshots/lsp-definition/workspace/subject.ts", "acp-agent/tests/fixtures/child-question-tripwire.ts", + "acp-agent/tests/fixtures/parent-sandbox-override.ts", "acp-agent/tests/fixtures/partial-landlock-sandbox.ts", "acp-agent/tests/fixtures/subagent-durability-failure.ts", "acp-agent/tests/fixtures/subagent-settlement-marker.ts", diff --git a/packages/subagent/subagent-inprocess/README.i18n.yaml b/packages/subagent/subagent-inprocess/README.i18n.yaml index a6a82fb47f..7598b6dc3e 100644 --- a/packages/subagent/subagent-inprocess/README.i18n.yaml +++ b/packages/subagent/subagent-inprocess/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/subagent/subagent-inprocess/README.md -README.md: 67f0cf5dd1ecb18542af56953a0eaa40988aca0d -README.zh.md: 648a160be5f1c3dcbe66a867a273a3df610dbc0a +README.md: 4189979806ccd4e7dcfee231ab3e9e2331550b0d +README.zh.md: c6a9005cbfdb9d40a54383f921671fa22a31dc32 diff --git a/packages/subagent/subagent-inprocess/README.md b/packages/subagent/subagent-inprocess/README.md index 67f0cf5dd1..4189979806 100644 --- a/packages/subagent/subagent-inprocess/README.md +++ b/packages/subagent/subagent-inprocess/README.md @@ -20,7 +20,7 @@ The child gets the parent's working-directory/session lineage and inherits the p This result boundary is valid because the provider owns an isolated child lifecycle from publication through quiescence. Steering submitted during that lifecycle belongs to the child run; the provider does not pretend the initial follow-up alone owns its output. -When the optional sandbox-policy or approval service is composed, the driver snapshots the parent's explicit session override before child creation and appends a source-tagged event during unpublished setup, after any fork history and before session publication. It never copies deployment defaults or one-shot grants; later child switches still win. See the [policy-inheritance decision](../../../.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.md). +The driver applies the seam's [delegated policy inheritance](../subagent/README.md#delegated-policy-inheritance) through the shared child-agent helpers: it captures the parent's explicit sandbox/approval overrides before child creation and appends the source-tagged events during unpublished setup, after any fork history and before session publication. See the [policy-inheritance decision](../../../.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.md). ## Cancellation and ownership diff --git a/packages/subagent/subagent-inprocess/README.zh.md b/packages/subagent/subagent-inprocess/README.zh.md index 648a160be5..c6a9005cbf 100644 --- a/packages/subagent/subagent-inprocess/README.zh.md +++ b/packages/subagent/subagent-inprocess/README.zh.md @@ -20,7 +20,7 @@ 该结果边界成立,是因为提供方拥有从发布到完全停稳的隔离子 agent 生命周期。在该生命周期内提交的 steering(中途引导)属于子运行;提供方不会声称输出只归初始 follow-up 所有。 -当组合中挂载了可选的沙箱策略或审批服务时,驱动器会在创建子 agent 前对父级的显式会话覆盖项获取快照,并在未发布的设置阶段追加一条带来源标记的事件,使其位于所有 fork 历史之后、会话发布之前。它绝不复制部署默认值或一次性授权;子 agent 后续的切换仍然优先。参见[策略继承决策](../../../.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.md)。 +驱动器通过共享的子 agent 辅助函数应用该 seam 的[委派策略继承](../subagent/README.md#delegated-policy-inheritance):它会在创建子 agent 前捕获父级的显式沙箱/审批覆盖项,并在未发布的设置阶段追加带来源标记的事件,使其位于所有 fork 历史之后、会话发布之前。参见[策略继承决策](../../../.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.md)。 ## 取消与所有权 diff --git a/packages/subagent/subagent-inprocess/src/index.ts b/packages/subagent/subagent-inprocess/src/index.ts index acb4e4d36e..f3e4bb04d2 100644 --- a/packages/subagent/subagent-inprocess/src/index.ts +++ b/packages/subagent/subagent-inprocess/src/index.ts @@ -17,8 +17,10 @@ import type { Agent, AgentHandle } from '@deepseek-ai/dsh-agent' import { findLastMessageTurnEnd, SessionId, type SessionEvent, type TurnEndReason } from '@deepseek-ai/dsh-session' import { createUserMessage, type ContentBlock } from '@deepseek-ai/dsh-llm' import { + appendDelegatedPolicyOverrides, applyChildComposition, assertSubagentMaxDepth, + captureDelegatedPolicyOverrides, childSessionMeta, resolveChildAgentOptions, resolveChildDepth, @@ -30,11 +32,6 @@ import type { SubagentRun, SubagentStopReason, } from '@deepseek-ai/dsh-subagent' -// Type-only: make `ctx.get('sandboxPolicy')` / `ctx.get('approval')` resolve -// to the policy services when composed — the driver consumes both -// opportunistically (the documented `ctx.get` pattern), never as a hard dep. -import type {} from '@deepseek-ai/dsh-sandbox-policy' -import type {} from '@deepseek-ai/dsh-user-approval' import { attachStructuredRuntime, type StructuredAttachment, @@ -111,20 +108,11 @@ export async function startInProcessRun( // Capture before the first await: a later parent switch belongs to the // parent's future. - const inheritedMode = parent.ctx.get('sandboxPolicy')?.overrideOf(parent.session) - const inheritedPolicy = parent.ctx.get('approval')?.overrideOf(parent.session) + const inherited = captureDelegatedPolicyOverrides(parent) let structured: StructuredAttachment | undefined const setup = (childCtx: Context): void => { - // Inherited overrides land on the child's own log, so its effective policy - // is reconstructable from that log alone. - const childSession = (childCtx.agent as Agent).session - if (inheritedMode !== undefined) { - childSession.append('sandbox/mode', { mode: inheritedMode, source: 'delegation' }) - } - if (inheritedPolicy !== undefined) { - childSession.append('approval/policy', { policy: inheritedPolicy, source: 'delegation' }) - } + appendDelegatedPolicyOverrides((childCtx.agent as Agent).session, inherited) applyChildComposition(childCtx, { persona: request.persona, toolFilter: request.toolFilter, diff --git a/packages/subagent/subagent/README.i18n.yaml b/packages/subagent/subagent/README.i18n.yaml index 1241aa8042..7c64fb7228 100644 --- a/packages/subagent/subagent/README.i18n.yaml +++ b/packages/subagent/subagent/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/subagent/subagent/README.md -README.md: 762030629c09305c48adebc71244655a5faa6585 -README.zh.md: 535cc25895e04e82b6667e6d2769f2dcbfa49cff +README.md: 6cea175de3d07290b293ad55ccbe60d7d918d37c +README.zh.md: c5fecd554357146d317b5f75824f40a1cb976f2c diff --git a/packages/subagent/subagent/README.md b/packages/subagent/subagent/README.md index 762030629c..6cea175de3 100644 --- a/packages/subagent/subagent/README.md +++ b/packages/subagent/subagent/README.md @@ -52,6 +52,10 @@ The seam owns the depth vocabulary shared by Service providers and Consumers: th `inheritsParentContext` is descriptive rather than enforceable. It says only whether the child sees completed parent conversation history (`fork` does; `spawn` and the out-of-process one-shot providers do not), not whether it inherits tools, services, or authority. +## Delegated policy inheritance + +Both in-process delegation paths seed the parent's explicit policy overrides into the child through the shared child-agent helpers: `captureDelegatedPolicyOverrides(parent)` snapshots `sandboxPolicy.overrideOf()` and `approval.overrideOf()` synchronously at the delegation boundary (both services are optional `ctx.get` consumers), and `appendDelegatedPolicyOverrides()` writes each captured value onto the child's own log as a `source: 'delegation'` `sandbox/mode` or `approval/policy` event during unpublished setup, after any fork seed — so fresh policy wins stale seed state, a later child switch wins the snapshot, and the child's effective policy stays reconstructable from its log alone. Deployment defaults are never copied: an unswitched parent stamps nothing and its child follows the deployment default dynamically. A continuable start captures before its first await and seeds only fresh materialization; a cold resume replays the persisted delegation events instead of re-capturing the parent, so a parent switch after creation never retroactively changes a durable child. See the [one-shot](../../../.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.md) and [continuable](../../../.agents/notes/implemented/feature/2026-08-10-continuable-subagent-policy-inheritance.md) policy-inheritance Agent Notes. + ## One-shot ownership and lifecycle `provider.start(request): Promise` is the ownership-transfer boundary; the delegation tool also uses it inside its one-shot Task-backed background path. Before fulfillment, the provider owns setup and must cancel, roll back, and quiesce unpublished resources on every failure. After fulfillment, the caller owns the run and must call `dispose()` on every path; remaining prompt and turn work belongs to `SubagentRun.result`. diff --git a/packages/subagent/subagent/README.zh.md b/packages/subagent/subagent/README.zh.md index 535cc25895..c5fecd5543 100644 --- a/packages/subagent/subagent/README.zh.md +++ b/packages/subagent/subagent/README.zh.md @@ -52,6 +52,10 @@ subagent seam 允许一个 agent(智能体)通过具名提供方把工作委 `inheritsParentContext` 只用于描述,不能强制执行。它仅说明子 agent 是否能看到父级已完成的对话历史(`fork` 可以;`spawn` 和各进程外一次性提供方不可以),不表示是否继承工具、服务或权限。 +## 委派策略继承 + +两条进程内委派路径都会通过共享的子 agent 辅助函数,把父级的显式策略覆盖项作为种子注入子 agent:`captureDelegatedPolicyOverrides(parent)` 在委派边界同步对 `sandboxPolicy.overrideOf()` 与 `approval.overrideOf()` 获取快照(这两个服务都是可选的 `ctx.get` 消费方),`appendDelegatedPolicyOverrides()` 则在未发布的设置阶段、在任何 fork 种子之后,把每个捕获值作为一条 `source: 'delegation'` 的 `sandbox/mode` 或 `approval/policy` 事件写入子 agent 自己的日志:因此新鲜策略压过陈旧的种子状态,子 agent 后续的切换压过该快照,而子 agent 的生效策略始终可以仅凭其日志重建。部署默认值绝不复制:未切换的父级不会记录任何值,其子 agent 会动态跟随部署默认值。可继续启动会在其第一次 await 之前捕获,并且只为新鲜的物化写入种子;冷恢复会重放已持久化的委派事件,而不是重新捕获父级,因此创建之后的父级切换绝不会追溯性地改变持久化子 agent。参见[一次性](../../../.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.md)与[可继续](../../../.agents/notes/implemented/feature/2026-08-10-continuable-subagent-policy-inheritance.md)两篇策略继承 Agent Note。 + ## 一次性所有权与生命周期 `provider.start(request): Promise` 是所有权转移边界;委派工具也会在其由 Task 支撑的一次性后台路径中使用它。兑现前,提供方拥有设置过程,并且每次失败时都必须取消、回滚并使未发布资源完全停稳。兑现后,调用方拥有该运行,并且必须在每条路径上调用 `dispose()`;剩余提示词和轮次工作属于 `SubagentRun.result`。 diff --git a/packages/subagent/subagent/package.json b/packages/subagent/subagent/package.json index ba1dd0fbc4..fc03f20b1a 100644 --- a/packages/subagent/subagent/package.json +++ b/packages/subagent/subagent/package.json @@ -37,6 +37,8 @@ "@deepseek-ai/dsh-brand": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-llm": "^0.0.1", + "@deepseek-ai/dsh-sandbox": "^0.0.1", + "@deepseek-ai/dsh-sandbox-policy": "^0.0.1", "@deepseek-ai/dsh-scope": "^0.0.1", "@deepseek-ai/dsh-session": "^0.0.1", "@deepseek-ai/dsh-session-persistence": "^0.0.1", @@ -44,9 +46,16 @@ "@deepseek-ai/dsh-session-projection-cache": "^0.0.1", "@deepseek-ai/dsh-tasks": "^0.0.1", "@deepseek-ai/dsh-tools": "^0.0.1", + "@deepseek-ai/dsh-user-approval": "^0.0.1", "cordis": "^4.0.0-rc.7" }, "peerDependenciesMeta": { + "@deepseek-ai/dsh-sandbox": { + "optional": true + }, + "@deepseek-ai/dsh-sandbox-policy": { + "optional": true + }, "@deepseek-ai/dsh-session-persistence": { "optional": true }, @@ -58,6 +67,9 @@ }, "@deepseek-ai/dsh-tasks": { "optional": true + }, + "@deepseek-ai/dsh-user-approval": { + "optional": true } }, "devDependencies": { @@ -65,6 +77,8 @@ "@deepseek-ai/dsh-brand": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-llm": "workspace:^", + "@deepseek-ai/dsh-sandbox": "workspace:^", + "@deepseek-ai/dsh-sandbox-policy": "workspace:^", "@deepseek-ai/dsh-scope": "workspace:^", "@deepseek-ai/dsh-session": "workspace:^", "@deepseek-ai/dsh-session-persistence": "workspace:^", @@ -74,6 +88,7 @@ "@deepseek-ai/dsh-storage-domain": "workspace:^", "@deepseek-ai/dsh-tasks": "workspace:^", "@deepseek-ai/dsh-tools": "workspace:^", + "@deepseek-ai/dsh-user-approval": "workspace:^", "cordis": "^4.0.0-rc.7" } } diff --git a/packages/subagent/subagent/src/child-agent.ts b/packages/subagent/subagent/src/child-agent.ts index c477954468..cb4e8fbd97 100644 --- a/packages/subagent/subagent/src/child-agent.ts +++ b/packages/subagent/subagent/src/child-agent.ts @@ -1,17 +1,23 @@ /** * Shared in-process child composition: the delegation-depth budget, the - * durable session metadata, the resolved child `AgentOptions`, and the scoped - * setup a child agent needs. Both the one-shot provider driver and the - * continuation manager compose children this way, so depth accounting and - * lineage stamping have one home. + * durable session metadata, the resolved child `AgentOptions`, the delegated + * policy snapshot, and the scoped setup a child agent needs. Both the one-shot + * provider driver and the continuation manager compose children this way, so + * depth accounting, lineage stamping, and policy inheritance have one home. * * @module @deepseek-ai/dsh-subagent/child-agent */ import type { Context } from 'cordis' import type { Agent, AgentOptions, CreateAgentOptions } from '@deepseek-ai/dsh-agent' -import type { SessionId } from '@deepseek-ai/dsh-session' +import type { SandboxMode } from '@deepseek-ai/dsh-sandbox' +import type { Session, SessionId } from '@deepseek-ai/dsh-session' import type { ToolRestriction } from '@deepseek-ai/dsh-tools' +import type { ApprovalPolicy } from '@deepseek-ai/dsh-user-approval' +// Type-only: make `ctx.get('sandboxPolicy')` / `ctx.get('approval')` resolve +// to the policy services when composed — delegation consumes both +// opportunistically (the documented `ctx.get` pattern), never as a hard dep. +import type {} from '@deepseek-ai/dsh-sandbox-policy' import { delegationDepthOf } from './depth.ts' /** Thrown when starting a child would exceed the requested depth cap. */ @@ -119,6 +125,51 @@ export function applyChildComposition(childCtx: Context, composition: ChildCompo if (composition.toolFilter !== undefined) childCtx.tools.restrict(composition.toolFilter) } +/** Parent-session policy overrides captured at the delegation boundary. */ +export interface DelegatedPolicyOverrides { + /** The parent session's explicit sandbox-mode override, or `undefined` without one. */ + readonly sandboxMode: SandboxMode | undefined + /** The parent session's explicit approval-policy override, or `undefined` without one. */ + readonly approvalPolicy: ApprovalPolicy | undefined +} + +/** + * Capture the parent session's explicit policy overrides for one delegation. + * Call synchronously before the child start's first await: a later parent + * switch belongs to the parent's future, not to this child. Deployment + * defaults and one-shot grants are never captured, so an unswitched parent + * leaves the child following the deployment default dynamically. + * @param parent - the delegating parent agent. + * @returns the overrides to seed into the child, each `undefined` without one. + */ +export function captureDelegatedPolicyOverrides(parent: Agent): DelegatedPolicyOverrides { + return { + sandboxMode: parent.ctx.get('sandboxPolicy')?.overrideOf(parent.session), + approvalPolicy: parent.ctx.get('approval')?.overrideOf(parent.session), + } +} + +/** + * Append captured parent overrides onto the child's own log as + * `source: 'delegation'` events inside the unpublished creation window, so the + * child's effective policy is reconstructable from its log alone. Appends land + * after any fork seed, so fresh policy wins stale seed state; later child + * switches still win over these events. + * @param childSession - the unpublished child's session. + * @param overrides - the overrides captured at delegation. + */ +export function appendDelegatedPolicyOverrides( + childSession: Session, + overrides: DelegatedPolicyOverrides, +): void { + if (overrides.sandboxMode !== undefined) { + childSession.append('sandbox/mode', { mode: overrides.sandboxMode, source: 'delegation' }) + } + if (overrides.approvalPolicy !== undefined) { + childSession.append('approval/policy', { policy: overrides.approvalPolicy, source: 'delegation' }) + } +} + /** Identity and lineage inputs shared by every in-process child creation. */ export interface ChildCreateInputs { /** The child's reserved session id. */ diff --git a/packages/subagent/subagent/src/continuation.ts b/packages/subagent/subagent/src/continuation.ts index 3425a12851..743d6d63de 100644 --- a/packages/subagent/subagent/src/continuation.ts +++ b/packages/subagent/subagent/src/continuation.ts @@ -32,11 +32,14 @@ import type { ToolRestriction } from '@deepseek-ai/dsh-tools' import { foldSubagentDescriptor, snapshotSubagentDescriptor } from './descriptor.ts' import type { SubagentDescriptorData } from './descriptor.ts' import { + appendDelegatedPolicyOverrides, applyChildComposition, + captureDelegatedPolicyOverrides, childSessionMeta, resolveChildAgentOptions, resolveChildDepth, } from './child-agent.ts' +import type { DelegatedPolicyOverrides } from './child-agent.ts' import { assertSubagentMaxDepth } from './depth.ts' import { seedDescriptorTurn } from './descriptor-seed.ts' import type { ContinuableCreateRequest, ContinuableCreateSpec, SubagentStartRequest } from './types.ts' @@ -203,8 +206,17 @@ interface MaterializeInputs { childId: SessionId provider: string parent: Agent - /** Creation inputs; absent for a cold resume, which loads the persisted session. */ - create?: { seed: readonly SessionEvent[]; meta: NonNullable } + /** + * Creation inputs; absent for a cold resume, which loads the persisted + * session — including the delegation policy events a fresh creation seeded, + * so a resume never re-captures the parent's policy. + */ + create?: { + seed: readonly SessionEvent[] + meta: NonNullable + /** Parent policy overrides captured at the delegation boundary. */ + inheritedPolicies: DelegatedPolicyOverrides + } agentOptions: AgentOptions composition: { persona?: string | undefined; toolFilter?: ToolRestriction | undefined } signal: AbortSignal @@ -341,6 +353,9 @@ export class SubagentContinuationManager { ...request.persona !== undefined ? { persona: request.persona } : {}, ...request.toolFilter !== undefined ? { toolFilter: request.toolFilter } : {}, }) + // Capture before the first await: a later parent switch belongs to the + // parent's future, not to this child. + const inheritedPolicies = captureDelegatedPolicyOverrides(parent) const prepared = await this.host.prepareContinuable(spec.provider, { sessionId: childId, @@ -357,7 +372,7 @@ export class SubagentContinuationManager { childId, provider: spec.provider, parent, - create: { seed, meta: childSessionMeta(parent, childDepth, lineageSeedLength) }, + create: { seed, meta: childSessionMeta(parent, childDepth, lineageSeedLength), inheritedPolicies }, agentOptions: resolveChildAgentOptions(parent, request.agentOptions, childDepth), composition: { persona: request.persona, toolFilter: request.toolFilter }, signal: spec.signal, @@ -878,18 +893,23 @@ export class SubagentContinuationManager { inputs: MaterializeInputs, parentLineage: readonly Agent[], ): Promise { - const { childId, provider, parent } = inputs + const { childId, provider, parent, create } = inputs // No id pre-check here: the child lock serializes each durable child, both // callers reach this only after confirming no Activation exists, and // `AgentRegistry.enter()` is the authoritative collision boundary for an id // some other owner holds — a duplicate would reject there with rollback. inputs.signal.throwIfAborted() const setup = (childCtx: Context): AgentSetupCommit => { + // Only fresh creation seeds captured parent policy onto the child's own + // log (after any fork seed, so fresh policy wins stale seed state); a + // cold resume replays those persisted events instead. + if (create !== undefined) { + appendDelegatedPolicyOverrides((childCtx.agent as Agent).session, create.inheritedPolicies) + } applyChildComposition(childCtx, inputs.composition) return this.setupRegistry.apply(childCtx) } const observer = this.host.observeActivation(provider, childId, parent) - const { create } = inputs // Agent creation owns rollback before handle transfer. A rejection leaves // no resident Activation and therefore publishes no lifecycle edge. const handle: AgentHandle = create === undefined diff --git a/packages/subagent/subagent/src/index.ts b/packages/subagent/subagent/src/index.ts index eddcf63c3c..75bcf1f12c 100644 --- a/packages/subagent/subagent/src/index.ts +++ b/packages/subagent/subagent/src/index.ts @@ -100,13 +100,15 @@ export { SubagentError } from './error.ts' export { settleRun } from './run-settlement.ts' export { assertSubagentMaxDepth, delegationDepthOf } from './depth.ts' export { + appendDelegatedPolicyOverrides, applyChildComposition, + captureDelegatedPolicyOverrides, childSessionMeta, resolveChildAgentOptions, resolveChildDepth, SubagentDepthError, } from './child-agent.ts' -export type { ChildComposition } from './child-agent.ts' +export type { ChildComposition, DelegatedPolicyOverrides } from './child-agent.ts' export type { ContinuableStart, ContinuableStartSpec, diff --git a/packages/subagent/subagent/tests/continuation-inheritance.spec.ts b/packages/subagent/subagent/tests/continuation-inheritance.spec.ts new file mode 100644 index 0000000000..246bafa1ed --- /dev/null +++ b/packages/subagent/subagent/tests/continuation-inheritance.spec.ts @@ -0,0 +1,171 @@ +/** + * Continuable-child policy inheritance: a fresh continuable start seeds the + * parent's explicit sandbox/approval overrides onto the child's own log as + * `source: 'delegation'` events, and a cold resume replays that persisted + * snapshot instead of re-capturing the parent (the one-shot + * `subagent-inprocess/tests/inheritance.spec.ts` counterpart). + */ + +import { afterEach, describe, expect, it, vi } from 'vitest' +import { mkdtempSync, rmSync } from 'node:fs' +import { tmpdir } from 'node:os' +import { join } from 'node:path' +import { Context } from 'cordis' +import type { Agent } from '@deepseek-ai/dsh-agent' +import AgentLoop from '@deepseek-ai/dsh-agent-loop' +import { mountAgentLoopTestDependencies } from '@deepseek-ai/dsh-agent-loop-testkit' +import { createUserMessage } from '@deepseek-ai/dsh-llm' +import SandboxPolicyService, { effectiveSandboxMode, setSandboxMode } from '@deepseek-ai/dsh-sandbox-policy' +import { SessionId } from '@deepseek-ai/dsh-session' +import type { SessionEvent } from '@deepseek-ai/dsh-session' +import JsonlSessionPersistence from '@deepseek-ai/dsh-session-persistence-jsonl' +import * as SubagentFork from '@deepseek-ai/dsh-subagent-fork' +import * as SubagentSpawn from '@deepseek-ai/dsh-subagent-spawn' +import ApprovalService, { effectiveApprovalPolicy, setApprovalPolicy } from '@deepseek-ai/dsh-user-approval' +import { MockAdapter, textResponse } from '../../../core/agent-loop/tests/mock-adapter.ts' +import SubagentService from '../src/index.ts' + +type Script = ConstructorParameters[0] + +const roots: string[] = [] +afterEach(() => { + for (const root of roots.splice(0)) rmSync(root, { recursive: true, force: true }) +}) + +/** Boot the continuable stack plus both policy services the manager consumes opportunistically. */ +async function setup(script: Script) { + const ctx = new Context() + await mountAgentLoopTestDependencies(ctx) + const root = mkdtempSync(join(tmpdir(), 'dsh-continuation-inherit-')) + roots.push(root) + await ctx.plugin(JsonlSessionPersistence, { root }) + await ctx.plugin(SandboxPolicyService, { mode: 'workspace-write', workspaceRoot: root }) + await ctx.plugin(ApprovalService) + await ctx.plugin(AgentLoop, { agents: [] }) + await ctx.plugin(SubagentService) + await ctx.plugin(SubagentSpawn, { providerName: 'spawn' }) + await ctx.plugin(SubagentFork, { providerName: 'fork' }) + ctx.llm.registerAdapter(['mock'], new MockAdapter(script)) + const parent = ctx.agentLoop.create(SessionId('parent'), { provider: 'mock', model: 'mock' }) + return { ctx, parent } +} + +function startSpec(parent: Agent, provider = 'spawn') { + return { + provider, + label: 'child task', + request: { prompt: [{ type: 'text' as const, text: 'child task' }], parent }, + signal: new AbortController().signal, + } +} + +/** Wait until a child's Activation is gone, i.e. its handle finished disposal. */ +async function waitNoActivation(ctx: Context, childId: SessionId): Promise { + await vi.waitFor(() => { + expect(ctx.agents.get(childId)).toBeUndefined() + }, { timeout: 5_000 }) +} + +function policyEvents(events: readonly SessionEvent[]) { + return events.filter(event => event.type === 'sandbox/mode' || event.type === 'approval/policy') +} + +describe('continuable policy inheritance', () => { + it('seeds parent overrides into a fresh continuable child', async () => { + const { ctx, parent } = await setup([textResponse('child done')]) + setSandboxMode(parent.session, 'danger-full-access') + setApprovalPolicy(parent.session, 'never') + let child: Agent | undefined + ctx.on('agent/created', ({ agent }) => { + if (agent !== parent) child = agent + }) + + const started = await ctx.subagents.startContinuable(startSpec(parent)) + // The delegation events are appended in the creation window, so they are + // already the child's effective policy at inbox acceptance. + if (child === undefined) throw new Error('expected the continuable child to be created') + expect(ctx.sandboxPolicy.overrideOf(child.session)).toBe('danger-full-access') + expect(ctx.approval.overrideOf(child.session)).toBe('never') + + await waitNoActivation(ctx, started.childId) + const loaded = await ctx.sessionPersistence.load(started.childId) + expect(policyEvents(loaded.events)).toMatchObject([ + { type: 'sandbox/mode', data: { mode: 'danger-full-access', source: 'delegation' } }, + { type: 'approval/policy', data: { policy: 'never', source: 'delegation' } }, + ]) + // Durable: a reload folds the same effective policy. + expect(effectiveSandboxMode(loaded.events)).toBe('danger-full-access') + expect(effectiveApprovalPolicy(loaded.events)).toBe('never') + }) + + it('captures policy at delegation before asynchronous child creation', async () => { + const { ctx, parent } = await setup([textResponse('child done')]) + setSandboxMode(parent.session, 'read-only') + + const starting = ctx.subagents.startContinuable(startSpec(parent)) + // A parent switch after the synchronous capture belongs to the parent's + // future, not to this child. + setSandboxMode(parent.session, 'danger-full-access') + const started = await starting + + await waitNoActivation(ctx, started.childId) + const loaded = await ctx.sessionPersistence.load(started.childId) + expect(ctx.sandboxPolicy.overrideOf(parent.session)).toBe('danger-full-access') + expect(effectiveSandboxMode(loaded.events)).toBe('read-only') + }) + + it('does not freeze deployment defaults into an unswitched child', async () => { + const { ctx, parent } = await setup([textResponse('child done')]) + + const started = await ctx.subagents.startContinuable(startSpec(parent)) + await waitNoActivation(ctx, started.childId) + + const loaded = await ctx.sessionPersistence.load(started.childId) + expect(policyEvents(loaded.events)).toEqual([]) + }) + + it('cold-resumes on the persisted snapshot without re-capturing the parent', async () => { + const { ctx, parent } = await setup([textResponse('first'), textResponse('after resume')]) + setSandboxMode(parent.session, 'read-only') + const started = await ctx.subagents.startContinuable(startSpec(parent)) + await waitNoActivation(ctx, started.childId) + + // The parent widens AFTER the child was created; the resumed child keeps + // the delegation-time snapshot from its own log. + setSandboxMode(parent.session, 'danger-full-access') + await ctx.subagents.followup(parent, started.childId, [{ type: 'text', text: 'continue please' }], { + source: { kind: 'user' }, + signal: new AbortController().signal, + }) + await waitNoActivation(ctx, started.childId) + + const loaded = await ctx.sessionPersistence.load(started.childId) + expect(loaded.events.filter(event => event.type === 'sandbox/mode')).toMatchObject([ + { data: { mode: 'read-only', source: 'delegation' } }, + ]) + expect(effectiveSandboxMode(loaded.events)).toBe('read-only') + }) + + it('places inherited events after a fork prefix so fresh policy wins stale seed state', async () => { + const { ctx, parent } = await setup([textResponse('parent turn'), textResponse('forked child')]) + // The stale mode lands inside the completed turn the fork seed replays. + setSandboxMode(parent.session, 'workspace-write') + parent.followup(createUserMessage({ + content: [{ type: 'text', text: 'parent work' }], + source: { kind: 'user' }, + })) + await parent.whenIdle() + setSandboxMode(parent.session, 'read-only') + + const started = await ctx.subagents.startContinuable(startSpec(parent, 'fork')) + await waitNoActivation(ctx, started.childId) + + const loaded = await ctx.sessionPersistence.load(started.childId) + expect(loaded.meta.seedLength).toBeGreaterThan(0) + expect(loaded.events.filter(event => event.type === 'sandbox/mode')).toMatchObject([ + { data: { mode: 'workspace-write' } }, + { data: { mode: 'read-only', source: 'delegation' } }, + ]) + expect(effectiveSandboxMode(loaded.events)).toBe('read-only') + }) +}) diff --git a/packages/subagent/subagent/tsconfig.json b/packages/subagent/subagent/tsconfig.json index c72f2ef68d..46e4e4592d 100644 --- a/packages/subagent/subagent/tsconfig.json +++ b/packages/subagent/subagent/tsconfig.json @@ -26,6 +26,15 @@ { "path": "../../core/scope" }, + { + "path": "../../interaction/user-approval" + }, + { + "path": "../../sandbox/sandbox" + }, + { + "path": "../../sandbox/sandbox-policy" + }, { "path": "../../session/session-persistence" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b08ae2da5d..d73737cfe4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5887,6 +5887,12 @@ importers: '@deepseek-ai/dsh-llm': specifier: workspace:^ version: link:../../llm/llm + '@deepseek-ai/dsh-sandbox': + specifier: workspace:^ + version: link:../../sandbox/sandbox + '@deepseek-ai/dsh-sandbox-policy': + specifier: workspace:^ + version: link:../../sandbox/sandbox-policy '@deepseek-ai/dsh-scope': specifier: workspace:^ version: link:../../core/scope @@ -5914,6 +5920,9 @@ importers: '@deepseek-ai/dsh-tools': specifier: workspace:^ version: link:../../core/tools + '@deepseek-ai/dsh-user-approval': + specifier: workspace:^ + version: link:../../interaction/user-approval cordis: specifier: ^4.0.0-rc.7 version: link:../../../vendor/cordis From 517367854331f6a9c87f05e746abb783a6badadb Mon Sep 17 00:00:00 2001 From: Hypatia May Date: Mon, 10 Aug 2026 14:45:34 +0800 Subject: [PATCH 02/15] review: symmetric policy-service type imports, drop stale inprocess peers, pin child-switch and fork-default cases - child-agent.ts declares both policy-service augmentations as explicit empty type imports, so removing the ApprovalPolicy import cannot silently degrade ctx.get('approval') typing. - dsh-subagent-inprocess no longer consumes the policy services in src, so its optional peers and tsconfig references are dropped; both policy-inheritance Agent Notes state the current ownership. - The continuable suite pins that a later child-side switch beats the delegation snapshot and that an unswitched fork parent seeds no policy events. --- ...7-25-subagent-policy-inheritance.i18n.yaml | 4 +-- .../2026-07-25-subagent-policy-inheritance.md | 2 +- ...26-07-25-subagent-policy-inheritance.zh.md | 2 +- ...able-subagent-policy-inheritance.i18n.yaml | 4 +-- ...continuable-subagent-policy-inheritance.md | 2 +- ...tinuable-subagent-policy-inheritance.zh.md | 2 +- .../subagent/subagent-inprocess/package.json | 10 ------ .../subagent/subagent-inprocess/tsconfig.json | 6 ---- packages/subagent/subagent/src/child-agent.ts | 3 ++ .../tests/continuation-inheritance.spec.ts | 36 +++++++++++++++++++ 10 files changed, 47 insertions(+), 24 deletions(-) diff --git a/.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.i18n.yaml b/.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.i18n.yaml index 616a45e1d1..48074dd7bf 100644 --- a/.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.md -2026-07-25-subagent-policy-inheritance.md: a2f4d578de857ee63df5e7741c433210d5f1ef86 -2026-07-25-subagent-policy-inheritance.zh.md: f069bf290586447afc0b7d46a41ad4de9bfcbe8f +2026-07-25-subagent-policy-inheritance.md: 910581a595f48b356eea9c6242a06159c52b3854 +2026-07-25-subagent-policy-inheritance.zh.md: a0edb3c6beb59a9fe8fdfb801ee718f7c034c296 diff --git a/.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.md b/.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.md index a2f4d578de..910581a595 100644 --- a/.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.md +++ b/.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.md @@ -33,4 +33,4 @@ A confined child gets the ordinary denial marker. No answerer currently owns an - Spawn, fork, and nested in-process children retain a parent's explicit sandbox and approval overrides. The focused suite proves real filesystem denial, stale-fork precedence, delegation-time capture, the live-event boundary, default omission, and context disposal. - The keyless headless snapshot is the assembled regression: only the parent is `read-only`, the deployment default is `workspace-write`, and the child's persisted event plus denied disk write both fail if capture is removed. -- Each delegation adds at most two log-only events. `dsh-subagent` and `dsh-subagent-inprocess` have optional peer types for the two policy services; compositions without either service behave unchanged. Out-of-process children retain their own deployment policy, and a running child does not follow later parent switches. +- Each delegation adds at most two log-only events. `dsh-subagent` owns the optional peer types for the two policy services — its shared helpers hold the `ctx.get` consumption; compositions without either service behave unchanged. Out-of-process children retain their own deployment policy, and a running child does not follow later parent switches. diff --git a/.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.zh.md b/.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.zh.md index f069bf2905..a0edb3c6be 100644 --- a/.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.zh.md +++ b/.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.zh.md @@ -33,4 +33,4 @@ Status: implemented - spawn、fork 和嵌套的进程内子 agent 会保留父级显式的沙箱与审批覆盖项。聚焦测试套件证明真实文件系统拒绝、陈旧 fork 优先级、委派时捕获、实时事件边界、默认值省略与上下文释放。 - 无密钥 headless 快照是组装后应用层面的回归测试:只有父级是 `read-only`,部署默认值是 `workspace-write`;若移除捕获,子 agent 的持久化事件与被拒的磁盘写入这两项检查都会失败。 -- 每次委派最多增加两条仅日志事件。`dsh-subagent` 和 `dsh-subagent-inprocess` 为两个策略服务提供可选 peer 类型;未组合任一服务的组合保持原有行为。进程外子 agent 仍采用自身的部署策略,正在运行的子 agent 不跟随父级后续切换。 +- 每次委派最多增加两条仅日志事件。两个策略服务的可选 peer 类型由 `dsh-subagent` 拥有——其共享辅助函数持有 `ctx.get` 消费;未组合任一服务的组合保持原有行为。进程外子 agent 仍采用自身的部署策略,正在运行的子 agent 不跟随父级后续切换。 diff --git a/.agents/notes/implemented/feature/2026-08-10-continuable-subagent-policy-inheritance.i18n.yaml b/.agents/notes/implemented/feature/2026-08-10-continuable-subagent-policy-inheritance.i18n.yaml index dc23421912..54bc9adfb4 100644 --- a/.agents/notes/implemented/feature/2026-08-10-continuable-subagent-policy-inheritance.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-08-10-continuable-subagent-policy-inheritance.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-08-10-continuable-subagent-policy-inheritance.md -2026-08-10-continuable-subagent-policy-inheritance.md: 39df910a920e6995ba6048fdd2613d2c216f5ec2 -2026-08-10-continuable-subagent-policy-inheritance.zh.md: 2a977eaa9aade189213fdd20a7d888e8e62efb48 +2026-08-10-continuable-subagent-policy-inheritance.md: 04bcd0329a4608445b672d75b6c1e56dd265b25a +2026-08-10-continuable-subagent-policy-inheritance.zh.md: 9ef457df814ed848b04f42c5891024a0890bc9dd diff --git a/.agents/notes/implemented/feature/2026-08-10-continuable-subagent-policy-inheritance.md b/.agents/notes/implemented/feature/2026-08-10-continuable-subagent-policy-inheritance.md index 39df910a92..04bcd0329a 100644 --- a/.agents/notes/implemented/feature/2026-08-10-continuable-subagent-policy-inheritance.md +++ b/.agents/notes/implemented/feature/2026-08-10-continuable-subagent-policy-inheritance.md @@ -24,6 +24,6 @@ The capture/append pair moved from the one-shot driver into the seam's shared ch ## Consequences - Default-bundle background delegation (`backgroundMode: continuable`) now inherits a parent's explicit sandbox and approval overrides; compositions without either policy service behave unchanged. -- `dsh-subagent` gains optional peer types on `dsh-sandbox-policy` and `dsh-user-approval` (the `ctx.get` pattern the one-shot driver used); `dsh-subagent-inprocess` keeps its optional peers but delegates to the shared helpers. +- `dsh-subagent` gains optional peer types on `dsh-sandbox-policy` and `dsh-user-approval` (the `ctx.get` pattern the one-shot driver used); `dsh-subagent-inprocess` drops its policy-service peers and type imports entirely and delegates to the shared helpers. - The continuable suite (`packages/subagent/subagent/tests/continuation-inheritance.spec.ts`) pins fresh-start seeding, pre-await capture, default omission, cold-resume snapshot stability, and fork-seed precedence; the ACP snapshot scenario `subagent-continuable-inheritance` pins the child's delegation event and read-only runtime context through the assembled app and fails when the capture is removed. - Out-of-process providers (`acp`, `dsh-sdk`, `claude-code`, `codex`) support no continuable children (`prepareContinuable` absent), and their one-shot children keep their own deployment policy (`inheritsParentContext = false`); cross-process policy propagation remains out of scope. diff --git a/.agents/notes/implemented/feature/2026-08-10-continuable-subagent-policy-inheritance.zh.md b/.agents/notes/implemented/feature/2026-08-10-continuable-subagent-policy-inheritance.zh.md index 2a977eaa9a..9ef457df81 100644 --- a/.agents/notes/implemented/feature/2026-08-10-continuable-subagent-policy-inheritance.zh.md +++ b/.agents/notes/implemented/feature/2026-08-10-continuable-subagent-policy-inheritance.zh.md @@ -24,6 +24,6 @@ Status: implemented ## 后果 - 默认组合包的后台委派(`backgroundMode: continuable`)现在会继承父级显式的沙箱与审批覆盖项;未组合任一策略服务的组合保持原有行为。 -- `dsh-subagent` 新增针对 `dsh-sandbox-policy` 与 `dsh-user-approval` 的可选 peer 类型(即一次性驱动器所用的 `ctx.get` 模式);`dsh-subagent-inprocess` 保留自己的可选 peer,但委托给共享辅助函数。 +- `dsh-subagent` 新增针对 `dsh-sandbox-policy` 与 `dsh-user-approval` 的可选 peer 类型(即一次性驱动器所用的 `ctx.get` 模式);`dsh-subagent-inprocess` 完全移除自己的策略服务 peer 与类型导入,委托给共享辅助函数。 - 可继续测试套件(`packages/subagent/subagent/tests/continuation-inheritance.spec.ts`)锁定全新启动的种子写入、await 前捕获、默认值省略、冷恢复快照稳定性与 fork 种子优先级;ACP 快照场景 `subagent-continuable-inheritance` 经组装后的应用锁定子级的委派事件与只读运行时上下文,移除捕获时即失败。 - 进程外提供方(`acp`、`dsh-sdk`、`claude-code`、`codex`)不支持可继续子 agent(没有 `prepareContinuable`),其一次性子 agent 保留自身的部署策略(`inheritsParentContext = false`);跨进程策略传播仍不在范围内。 diff --git a/packages/subagent/subagent-inprocess/package.json b/packages/subagent/subagent-inprocess/package.json index e18752db74..2bdbe85234 100644 --- a/packages/subagent/subagent-inprocess/package.json +++ b/packages/subagent/subagent-inprocess/package.json @@ -28,22 +28,12 @@ "@deepseek-ai/dsh-agent": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-llm": "^0.0.1", - "@deepseek-ai/dsh-sandbox-policy": "^0.0.1", "@deepseek-ai/dsh-session": "^0.0.1", "@deepseek-ai/dsh-subagent": "^0.0.1", "@deepseek-ai/dsh-system-prompt": "^0.0.1", "@deepseek-ai/dsh-tools": "^0.0.1", - "@deepseek-ai/dsh-user-approval": "^0.0.1", "cordis": "^4.0.0-rc.7" }, - "peerDependenciesMeta": { - "@deepseek-ai/dsh-sandbox-policy": { - "optional": true - }, - "@deepseek-ai/dsh-user-approval": { - "optional": true - } - }, "devDependencies": { "@deepseek-ai/dsh-agent": "workspace:^", "@deepseek-ai/dsh-agent-loop": "workspace:^", diff --git a/packages/subagent/subagent-inprocess/tsconfig.json b/packages/subagent/subagent-inprocess/tsconfig.json index 23406e362e..02fd8e53d0 100644 --- a/packages/subagent/subagent-inprocess/tsconfig.json +++ b/packages/subagent/subagent-inprocess/tsconfig.json @@ -32,14 +32,8 @@ { "path": "../../core/tools" }, - { - "path": "../../sandbox/sandbox-policy" - }, { "path": "../../support/invariants" - }, - { - "path": "../../interaction/user-approval" } ] } diff --git a/packages/subagent/subagent/src/child-agent.ts b/packages/subagent/subagent/src/child-agent.ts index cb4e8fbd97..878b831dd5 100644 --- a/packages/subagent/subagent/src/child-agent.ts +++ b/packages/subagent/subagent/src/child-agent.ts @@ -17,7 +17,10 @@ import type { ApprovalPolicy } from '@deepseek-ai/dsh-user-approval' // Type-only: make `ctx.get('sandboxPolicy')` / `ctx.get('approval')` resolve // to the policy services when composed — delegation consumes both // opportunistically (the documented `ctx.get` pattern), never as a hard dep. +// The user-approval side stays an explicit empty import so its augmentation +// does not ride the `ApprovalPolicy` import above. import type {} from '@deepseek-ai/dsh-sandbox-policy' +import type {} from '@deepseek-ai/dsh-user-approval' import { delegationDepthOf } from './depth.ts' /** Thrown when starting a child would exceed the requested depth cap. */ diff --git a/packages/subagent/subagent/tests/continuation-inheritance.spec.ts b/packages/subagent/subagent/tests/continuation-inheritance.spec.ts index 246bafa1ed..92cefa261e 100644 --- a/packages/subagent/subagent/tests/continuation-inheritance.spec.ts +++ b/packages/subagent/subagent/tests/continuation-inheritance.spec.ts @@ -124,6 +124,42 @@ describe('continuable policy inheritance', () => { expect(policyEvents(loaded.events)).toEqual([]) }) + it('does not freeze deployment defaults into an unswitched fork child either', async () => { + const { ctx, parent } = await setup([textResponse('parent turn'), textResponse('forked child')]) + parent.followup(createUserMessage({ + content: [{ type: 'text', text: 'parent work' }], + source: { kind: 'user' }, + })) + await parent.whenIdle() + + const started = await ctx.subagents.startContinuable(startSpec(parent, 'fork')) + await waitNoActivation(ctx, started.childId) + + const loaded = await ctx.sessionPersistence.load(started.childId) + expect(loaded.meta.seedLength).toBeGreaterThan(0) + expect(policyEvents(loaded.events)).toEqual([]) + }) + + it('lets a later child-side switch win over the delegation snapshot', async () => { + const { ctx, parent } = await setup([textResponse('child done')]) + setSandboxMode(parent.session, 'danger-full-access') + let child: Agent | undefined + ctx.on('agent/created', ({ agent }) => { + if (agent !== parent) child = agent + }) + + const started = await ctx.subagents.startContinuable(startSpec(parent)) + if (child === undefined) throw new Error('expected the continuable child to be created') + expect(ctx.sandboxPolicy.overrideOf(child.session)).toBe('danger-full-access') + // Last event wins: the child's own runtime switch beats the seeded snapshot. + setSandboxMode(child.session, 'read-only') + expect(ctx.sandboxPolicy.overrideOf(child.session)).toBe('read-only') + + await waitNoActivation(ctx, started.childId) + const loaded = await ctx.sessionPersistence.load(started.childId) + expect(effectiveSandboxMode(loaded.events)).toBe('read-only') + }) + it('cold-resumes on the persisted snapshot without re-capturing the parent', async () => { const { ctx, parent } = await setup([textResponse('first'), textResponse('after resume')]) setSandboxMode(parent.session, 'read-only') From f9b7a31ee287f9c4eec733acf3d80032a53d71a1 Mon Sep 17 00:00:00 2001 From: Hypatia May Date: Mon, 10 Aug 2026 14:52:16 +0800 Subject: [PATCH 03/15] docs: regenerate module graph for moved policy-service edges --- docs/module-graph.i18n.yaml | 4 ++-- docs/module-graph.md | 9 +++++---- docs/module-graph.zh.md | 9 +++++---- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/docs/module-graph.i18n.yaml b/docs/module-graph.i18n.yaml index 54453b3411..8fa40f2e65 100644 --- a/docs/module-graph.i18n.yaml +++ b/docs/module-graph.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write docs/module-graph.md -module-graph.md: c41db02165740b19a9ef751e6f50316a76df28c3 -module-graph.zh.md: 9071dbc0f2e6df8ec7edd1f3e14cd7ff063123fa +module-graph.md: 58e4ce7c23de28a85bf140b426b4ca43d8d18cf7 +module-graph.zh.md: f8605d0c94023fcf51c38e6a8d4cca80ae436220 diff --git a/docs/module-graph.md b/docs/module-graph.md index c41db02165..58e4ce7c23 100644 --- a/docs/module-graph.md +++ b/docs/module-graph.md @@ -809,6 +809,8 @@ flowchart TD pkg_subagent --> pkg_brand pkg_subagent --> pkg_invariants pkg_subagent --> pkg_llm + pkg_subagent --> pkg_sandbox + pkg_subagent --> pkg_sandbox_policy pkg_subagent --> pkg_scope pkg_subagent --> pkg_session pkg_subagent --> pkg_session_persistence @@ -816,6 +818,7 @@ flowchart TD pkg_subagent --> pkg_session_projection_cache pkg_subagent --> pkg_tasks pkg_subagent --> pkg_tools + pkg_subagent --> pkg_user_approval pkg_tool_web --> pkg_invariants pkg_tool_web --> pkg_llm pkg_tool_web --> pkg_system_prompt @@ -999,12 +1002,10 @@ flowchart TD pkg_subagent_inprocess --> pkg_agent pkg_subagent_inprocess --> pkg_invariants pkg_subagent_inprocess --> pkg_llm - pkg_subagent_inprocess --> pkg_sandbox_policy pkg_subagent_inprocess --> pkg_session pkg_subagent_inprocess --> pkg_subagent pkg_subagent_inprocess --> pkg_system_prompt pkg_subagent_inprocess --> pkg_tools - pkg_subagent_inprocess --> pkg_user_approval pkg_tool_subagent --> pkg_agent pkg_tool_subagent --> pkg_invariants pkg_tool_subagent --> pkg_llm @@ -1366,7 +1367,7 @@ flowchart TD | [`tool-str-replace-editor`](../packages/fs/tool-str-replace-editor) | `fs` | [`fs`](../packages/fs/fs), [`invariants`](../packages/support/invariants), [`sandbox`](../packages/sandbox/sandbox), [`sandbox-policy`](../packages/sandbox/sandbox-policy), [`tools`](../packages/core/tools) | | [`tool-skill`](../packages/skill/tool-skill) | `skill` | [`agent`](../packages/core/agent), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`skill`](../packages/skill/skill), [`tools`](../packages/core/tools) | | [`command-compact`](../packages/compact/command-compact) | `compact` | [`commands`](../packages/interaction/commands), [`compact`](../packages/compact/compact), [`invariants`](../packages/support/invariants) | -| [`subagent`](../packages/subagent/subagent) | `subagent` | [`agent`](../packages/core/agent), [`brand`](../packages/util/brand), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`session-projection`](../packages/session/session-projection), [`session-projection-cache`](../packages/session/session-projection-cache), [`tasks`](../packages/tasks/tasks), [`tools`](../packages/core/tools) | +| [`subagent`](../packages/subagent/subagent) | `subagent` | [`agent`](../packages/core/agent), [`brand`](../packages/util/brand), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`sandbox`](../packages/sandbox/sandbox), [`sandbox-policy`](../packages/sandbox/sandbox-policy), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`session-projection`](../packages/session/session-projection), [`session-projection-cache`](../packages/session/session-projection-cache), [`tasks`](../packages/tasks/tasks), [`tools`](../packages/core/tools), [`user-approval`](../packages/interaction/user-approval) | | [`tool-web`](../packages/web/tool-web) | `web` | [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools), [`web`](../packages/web/web) | | [`spill-policy`](../packages/spill/spill-policy) | `spill` | [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`retention`](../packages/util/retention), [`session`](../packages/core/session), [`spill`](../packages/spill/spill), [`tools`](../packages/core/tools) | | [`tool-todo`](../packages/todo/tool-todo) | `todo` | [`agent`](../packages/core/agent), [`invariants`](../packages/support/invariants), [`session`](../packages/core/session), [`session-projection`](../packages/session/session-projection), [`tools`](../packages/core/tools) | @@ -1397,7 +1398,7 @@ flowchart TD | [`compact-tool-result-prune`](../packages/compact/compact-tool-result-prune) | `compact` | [`compact`](../packages/compact/compact), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`token-meter`](../packages/llm/token-meter) | | [`subagent-acp`](../packages/subagent/subagent-acp) | `subagent` | [`agent`](../packages/core/agent), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`subagent`](../packages/subagent/subagent), [`subprocess`](../packages/subprocess/subprocess), [`timeout`](../packages/util/timeout) | | [`subagent-claude-code`](../packages/subagent/subagent-claude-code) | `subagent` | [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`subagent`](../packages/subagent/subagent), [`subprocess`](../packages/subprocess/subprocess), [`timeout`](../packages/util/timeout) | -| [`subagent-inprocess`](../packages/subagent/subagent-inprocess) | `subagent` | [`agent`](../packages/core/agent), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`sandbox-policy`](../packages/sandbox/sandbox-policy), [`session`](../packages/core/session), [`subagent`](../packages/subagent/subagent), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools), [`user-approval`](../packages/interaction/user-approval) | +| [`subagent-inprocess`](../packages/subagent/subagent-inprocess) | `subagent` | [`agent`](../packages/core/agent), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`subagent`](../packages/subagent/subagent), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools) | | [`tool-subagent`](../packages/subagent/tool-subagent) | `subagent` | [`agent`](../packages/core/agent), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`subagent`](../packages/subagent/subagent), [`tasks`](../packages/tasks/tasks), [`tools`](../packages/core/tools) | | [`tool-subagent-control`](../packages/subagent/tool-subagent-control) | `subagent` | [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`subagent`](../packages/subagent/subagent), [`tools`](../packages/core/tools) | | [`tool-subagent-report`](../packages/subagent/tool-subagent-report) | `subagent` | [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`subagent`](../packages/subagent/subagent), [`tools`](../packages/core/tools) | diff --git a/docs/module-graph.zh.md b/docs/module-graph.zh.md index 9071dbc0f2..f8605d0c94 100644 --- a/docs/module-graph.zh.md +++ b/docs/module-graph.zh.md @@ -811,6 +811,8 @@ flowchart TD pkg_subagent --> pkg_brand pkg_subagent --> pkg_invariants pkg_subagent --> pkg_llm + pkg_subagent --> pkg_sandbox + pkg_subagent --> pkg_sandbox_policy pkg_subagent --> pkg_scope pkg_subagent --> pkg_session pkg_subagent --> pkg_session_persistence @@ -818,6 +820,7 @@ flowchart TD pkg_subagent --> pkg_session_projection_cache pkg_subagent --> pkg_tasks pkg_subagent --> pkg_tools + pkg_subagent --> pkg_user_approval pkg_tool_web --> pkg_invariants pkg_tool_web --> pkg_llm pkg_tool_web --> pkg_system_prompt @@ -1001,12 +1004,10 @@ flowchart TD pkg_subagent_inprocess --> pkg_agent pkg_subagent_inprocess --> pkg_invariants pkg_subagent_inprocess --> pkg_llm - pkg_subagent_inprocess --> pkg_sandbox_policy pkg_subagent_inprocess --> pkg_session pkg_subagent_inprocess --> pkg_subagent pkg_subagent_inprocess --> pkg_system_prompt pkg_subagent_inprocess --> pkg_tools - pkg_subagent_inprocess --> pkg_user_approval pkg_tool_subagent --> pkg_agent pkg_tool_subagent --> pkg_invariants pkg_tool_subagent --> pkg_llm @@ -1368,7 +1369,7 @@ flowchart TD | [`tool-str-replace-editor`](../packages/fs/tool-str-replace-editor) | `fs` | [`fs`](../packages/fs/fs), [`invariants`](../packages/support/invariants), [`sandbox`](../packages/sandbox/sandbox), [`sandbox-policy`](../packages/sandbox/sandbox-policy), [`tools`](../packages/core/tools) | | [`tool-skill`](../packages/skill/tool-skill) | `skill` | [`agent`](../packages/core/agent), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`skill`](../packages/skill/skill), [`tools`](../packages/core/tools) | | [`command-compact`](../packages/compact/command-compact) | `compact` | [`commands`](../packages/interaction/commands), [`compact`](../packages/compact/compact), [`invariants`](../packages/support/invariants) | -| [`subagent`](../packages/subagent/subagent) | `subagent` | [`agent`](../packages/core/agent), [`brand`](../packages/util/brand), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`session-projection`](../packages/session/session-projection), [`session-projection-cache`](../packages/session/session-projection-cache), [`tasks`](../packages/tasks/tasks), [`tools`](../packages/core/tools) | +| [`subagent`](../packages/subagent/subagent) | `subagent` | [`agent`](../packages/core/agent), [`brand`](../packages/util/brand), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`sandbox`](../packages/sandbox/sandbox), [`sandbox-policy`](../packages/sandbox/sandbox-policy), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`session-projection`](../packages/session/session-projection), [`session-projection-cache`](../packages/session/session-projection-cache), [`tasks`](../packages/tasks/tasks), [`tools`](../packages/core/tools), [`user-approval`](../packages/interaction/user-approval) | | [`tool-web`](../packages/web/tool-web) | `web` | [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools), [`web`](../packages/web/web) | | [`spill-policy`](../packages/spill/spill-policy) | `spill` | [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`retention`](../packages/util/retention), [`session`](../packages/core/session), [`spill`](../packages/spill/spill), [`tools`](../packages/core/tools) | | [`tool-todo`](../packages/todo/tool-todo) | `todo` | [`agent`](../packages/core/agent), [`invariants`](../packages/support/invariants), [`session`](../packages/core/session), [`session-projection`](../packages/session/session-projection), [`tools`](../packages/core/tools) | @@ -1399,7 +1400,7 @@ flowchart TD | [`compact-tool-result-prune`](../packages/compact/compact-tool-result-prune) | `compact` | [`compact`](../packages/compact/compact), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`token-meter`](../packages/llm/token-meter) | | [`subagent-acp`](../packages/subagent/subagent-acp) | `subagent` | [`agent`](../packages/core/agent), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`subagent`](../packages/subagent/subagent), [`subprocess`](../packages/subprocess/subprocess), [`timeout`](../packages/util/timeout) | | [`subagent-claude-code`](../packages/subagent/subagent-claude-code) | `subagent` | [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`subagent`](../packages/subagent/subagent), [`subprocess`](../packages/subprocess/subprocess), [`timeout`](../packages/util/timeout) | -| [`subagent-inprocess`](../packages/subagent/subagent-inprocess) | `subagent` | [`agent`](../packages/core/agent), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`sandbox-policy`](../packages/sandbox/sandbox-policy), [`session`](../packages/core/session), [`subagent`](../packages/subagent/subagent), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools), [`user-approval`](../packages/interaction/user-approval) | +| [`subagent-inprocess`](../packages/subagent/subagent-inprocess) | `subagent` | [`agent`](../packages/core/agent), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`subagent`](../packages/subagent/subagent), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools) | | [`tool-subagent`](../packages/subagent/tool-subagent) | `subagent` | [`agent`](../packages/core/agent), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`subagent`](../packages/subagent/subagent), [`tasks`](../packages/tasks/tasks), [`tools`](../packages/core/tools) | | [`tool-subagent-control`](../packages/subagent/tool-subagent-control) | `subagent` | [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`subagent`](../packages/subagent/subagent), [`tools`](../packages/core/tools) | | [`tool-subagent-report`](../packages/subagent/tool-subagent-report) | `subagent` | [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`subagent`](../packages/subagent/subagent), [`tools`](../packages/core/tools) | From 501c3a8ab68f44628551eeac16332a53e41c94a7 Mon Sep 17 00:00:00 2001 From: Hypatia May Date: Mon, 10 Aug 2026 19:17:37 +0800 Subject: [PATCH 04/15] fix(subagent): pin delegated child approvals to 'never' within the inherited sandbox scope MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A delegated in-process child now acts only within the sandbox scope fixed at delegation: captureDelegatedPolicyOverrides still snapshots the parent's explicit sandbox override but pins the child approval policy to 'never' (instead of inheriting the parent's), so every child ask — sandbox_permissions escalations included — is rejected deterministically by ApprovalService before any answerer, with the audit pair still logged. Every in-process child additionally receives the scoped subagent:delegation runtime-context statement telling it to report a scope limitation instead of retrying. Supersedes the approval half of the policy-inheritance decision (new Agent Note cross-linked from both prior notes and the approval-seam Q&A); refreshed child snapshot fixtures carry the pinned event, and subagent-published-run-failure now persists a one-event child log. --- .../2026-07-06-approval-seam.i18n.yaml | 4 +- .../feature/2026-07-06-approval-seam.md | 2 +- .../feature/2026-07-06-approval-seam.zh.md | 2 +- ...7-25-subagent-policy-inheritance.i18n.yaml | 4 +- .../2026-07-25-subagent-policy-inheritance.md | 12 ++-- ...26-07-25-subagent-policy-inheritance.zh.md | 12 ++-- ...able-subagent-policy-inheritance.i18n.yaml | 4 +- ...continuable-subagent-policy-inheritance.md | 4 +- ...tinuable-subagent-policy-inheritance.zh.md | 4 +- ...0-subagent-approval-pinned-never.i18n.yaml | 6 ++ ...26-08-10-subagent-approval-pinned-never.md | 34 +++++++++ ...08-10-subagent-approval-pinned-never.zh.md | 34 +++++++++ .../advanced-toolchain/session.1.jsonl | 37 +++++----- .../advanced-toolchain/session.2.jsonl | 37 +++++----- .../advanced-toolchain/session.jsonl | 2 +- .../session.1.jsonl | 57 +++++++-------- .../session.jsonl | 2 +- .../session.1.jsonl | 35 ++++----- .../session.jsonl | 2 +- .../subagent-continuable/session.1.jsonl | 69 +++++++++--------- .../subagent-continuable/session.jsonl | 2 +- .../session.1.jsonl | 57 +++++++-------- .../session.2.jsonl | 57 +++++++-------- .../session.jsonl | 2 +- .../snapshots/subagent-fork/session.1.jsonl | 38 +++++----- .../subagent-list-agents/session.1.jsonl | 35 ++++----- .../subagent-list-agents/session.jsonl | 2 +- .../snapshots/subagent-mixed/session.1.jsonl | 43 +++++------ .../snapshots/subagent-mixed/session.2.jsonl | 40 ++++++----- .../snapshots/subagent-mixed/session.jsonl | 2 +- .../snapshots/subagent-multi/session.1.jsonl | 43 +++++------ .../snapshots/subagent-multi/session.2.jsonl | 45 ++++++------ .../snapshots/subagent-multi/session.jsonl | 2 +- .../session.1.jsonl | 2 + .../snapshots/subagent-report/session.1.jsonl | 55 +++++++------- .../snapshots/subagent-report/session.jsonl | 2 +- .../snapshots/subagent-spawn/session.1.jsonl | 43 +++++------ .../snapshots/subagent-spawn/session.jsonl | 2 +- .../snapshots/workflow-run/session.1.jsonl | 43 +++++------ .../snapshots/workflow-run/session.jsonl | 2 +- .../advanced-toolchain/session.1.jsonl | 27 +++---- .../advanced-toolchain/session.2.jsonl | 27 +++---- .../advanced-toolchain/session.jsonl | 28 ++++---- .../parent-override/child.expected.jsonl | 2 +- .../notifications.expected.jsonl | 63 ++++++++-------- .../snapshots/subagent-spawn/session.1.jsonl | 29 ++++---- .../subagent-inprocess/README.i18n.yaml | 4 +- .../subagent/subagent-inprocess/README.md | 2 +- .../subagent/subagent-inprocess/README.zh.md | 2 +- .../tests/inheritance.spec.ts | 71 ++++++++++++++++--- .../tests/structured.spec.ts | 5 +- packages/subagent/subagent/README.i18n.yaml | 4 +- packages/subagent/subagent/README.md | 22 ++++-- packages/subagent/subagent/README.zh.md | 22 ++++-- packages/subagent/subagent/src/child-agent.ts | 69 ++++++++++++------ .../subagent/subagent/src/continuation.ts | 12 ++-- .../tests/continuation-inheritance.spec.ts | 49 +++++++++---- .../subagent/tests/continuation.spec.ts | 4 +- .../tests/tool-subagent-control.spec.ts | 4 +- .../tests/tool-subagent-report.spec.ts | 4 +- .../verify-package-readme-model-experience.ts | 1 - 61 files changed, 781 insertions(+), 550 deletions(-) create mode 100644 .agents/notes/implemented/feature/2026-08-10-subagent-approval-pinned-never.i18n.yaml create mode 100644 .agents/notes/implemented/feature/2026-08-10-subagent-approval-pinned-never.md create mode 100644 .agents/notes/implemented/feature/2026-08-10-subagent-approval-pinned-never.zh.md create mode 100644 examples/acp-agent/tests/snapshots/subagent-published-run-failure/session.1.jsonl diff --git a/.agents/notes/implemented/feature/2026-07-06-approval-seam.i18n.yaml b/.agents/notes/implemented/feature/2026-07-06-approval-seam.i18n.yaml index c1ba01b255..ea386ac60b 100644 --- a/.agents/notes/implemented/feature/2026-07-06-approval-seam.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-07-06-approval-seam.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-07-06-approval-seam.md -2026-07-06-approval-seam.md: 7c830d93f19a40ab193cfebabca854882ab68d62 -2026-07-06-approval-seam.zh.md: 9dedfddadc23b0da44b28e8750508653ee20bb83 +2026-07-06-approval-seam.md: 8aa9986139dae77e08c166b72545bfa688a389e0 +2026-07-06-approval-seam.zh.md: ef4ccf5fd2b54888a648737866ff6f5fe1678882 diff --git a/.agents/notes/implemented/feature/2026-07-06-approval-seam.md b/.agents/notes/implemented/feature/2026-07-06-approval-seam.md index 7c830d93f1..8aa9986139 100644 --- a/.agents/notes/implemented/feature/2026-07-06-approval-seam.md +++ b/.agents/notes/implemented/feature/2026-07-06-approval-seam.md @@ -123,7 +123,7 @@ Costs and accepted limits: - **Who decides whether a call asks in the first place?** Policy producers: a hook returning `permissionDecision: ask`, any `tools/pre-execute` listener, or the sandbox escalation gate. The seam and the bridge only route and answer; neither injects its own judgment about what deserves a prompt. - **What happens when the user dismisses the prompt, or the turn aborts mid-ask?** Dismissal maps to `cancelled` with its own deny text. An already-aborted signal settles `cancelled` without dispatching; an abort during the ask discards the late answer. When both audit appends commit, either path records one pair, never two. - **What if the client answers with an option the harness never offered?** Any selection other than the offered `allow_once` maps to `rejected` — an unknown optionId from a non-conforming client can never grant. -- **How do subagents' approvals route?** An agent no answerer owns delegates through the whole waterfall and fails closed — in-process subagents are deliberately unanswerable. A `'never'` parent seeds that override into each in-process child's log ([decision](2026-07-25-subagent-policy-inheritance.md)), so the child is told up front instead of asking into the empty waterfall. `subagent-acp`'s child-side auto-answer is separate; routing a child's asks to the parent controller is deferred (§ Deferred). +- **How do subagents' approvals route?** They do not: delegation pins every in-process child to `'never'` ([approvals-pinned decision](2026-08-10-subagent-approval-pinned-never.md)), so each child ask resolves `rejected` before any answerer and the child is told up front through its runtime context. `subagent-acp`'s child-side auto-answer is separate; routing a child's asks to the parent controller is deferred (§ Deferred). - **What does `policy: 'never'` actually change at runtime?** The service resolves every ask for that session to `rejected` before dispatching any answerer (in-service, so no registration order can bypass it); the next atomic runtime-context snapshot states the policy; each successful auto-rejection records the audit pair. - **What happens across a hot reload, or when an answerer unloads mid-session?** Answerers dispose with their owning fiber, so the next ask degrades to `unavailable` instead of hanging on a dead channel; remounting re-registers the answerer with no catch-up state. - **Where does a client get approval context?** The request carries the exact `callId` and the asker's human-readable `reason`; channel adapters may correlate richer tool-call state without duplicating arguments in the approval seam. diff --git a/.agents/notes/implemented/feature/2026-07-06-approval-seam.zh.md b/.agents/notes/implemented/feature/2026-07-06-approval-seam.zh.md index 9dedfddadc..ef4ccf5fd2 100644 --- a/.agents/notes/implemented/feature/2026-07-06-approval-seam.zh.md +++ b/.agents/notes/implemented/feature/2026-07-06-approval-seam.zh.md @@ -123,7 +123,7 @@ ACP 桥只应答其会话映射所拥有的精确 agent 对象。它携带既有 - **谁决定一次调用是否需要 ask?** 策略生产者:返回 `permissionDecision: ask` 的钩子、任何 `tools/pre-execute` 监听器、或沙箱升级门禁。seam 和桥只负责路由和应答;二者都不注入自己对「什么值得弹出提示」的判断。 - **用户关闭提示或轮次在 ask 进行中中止时会发生什么?** 关闭映射为 `cancelled` 并携带自己的拒绝文本。已中止的 signal 直接结算为 `cancelled` 而不派发;ask 进行中的中止丢弃迟到的应答。当两个审计追加都提交时,任一路径都记录恰好一对事件,绝不会两对。 - **如果客户端以 harness 从未提供的选项应答呢?** 除已提供的 `allow_once` 之外的任何选项都映射为 `rejected`——来自不合规客户端的未知 optionId 永远不能授权。 -- **subagent 的审批如何路由?** 没有应答者拥有的 agent 穿过整个 waterfall 委派并失败关闭——进程内 subagent 被刻意设计为不可应答。`'never'` 父级会把该覆盖项预置到每个进程内子 agent 的日志中([决策](2026-07-25-subagent-policy-inheritance.md)),因此子 agent 一开始就会得知,而不是向空的 waterfall 发出 ask。`subagent-acp` 的子侧自动应答是独立的;将子 agent 的 ask 路由到父控制器已延后(§ 延后)。 +- **subagent 的审批如何路由?** 不路由:委派会把每个进程内子 agent 钉定为 `'never'`([审批钉定决策](2026-08-10-subagent-approval-pinned-never.md)),因此子 agent 的每次 ask 都在任何应答者之前解析为 `rejected`,子 agent 则通过其运行时上下文一开始就会得知。`subagent-acp` 的子侧自动应答是独立的;将子 agent 的 ask 路由到父控制器已延后(§ 延后)。 - **`policy: 'never'` 在运行时实际改变了什么?** 服务在派发任何应答者之前,将该会话的每次 ask 解析为 `rejected`(在服务内部,因此没有注册顺序能绕过它);下一份原子化的运行时上下文快照会声明该策略;每次成功的自动拒绝都会记录审计对。 - **热重载或应答者在会话中途卸载时会发生什么?** 应答者随其拥有的 fiber 一起 dispose,因此下一次 ask 降级为 `unavailable` 而非挂在死通道上;重新挂载会重新注册应答者,无需追赶状态。 - **客户端从哪里获得审批上下文?** 请求携带精确的 `callId` 和发起方的人类可读 `reason`;通道适配器可自行关联更丰富的工具调用状态,而无需在审批 seam 中重复携带参数。 diff --git a/.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.i18n.yaml b/.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.i18n.yaml index 48074dd7bf..dbfaaad95a 100644 --- a/.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.md -2026-07-25-subagent-policy-inheritance.md: 910581a595f48b356eea9c6242a06159c52b3854 -2026-07-25-subagent-policy-inheritance.zh.md: a0edb3c6beb59a9fe8fdfb801ee718f7c034c296 +2026-07-25-subagent-policy-inheritance.md: 34751a4e29e48c84d37425857b8b1b56c8d866eb +2026-07-25-subagent-policy-inheritance.zh.md: 5fa8edf04ed63da9b2e1b9a062ca2f649c8c96fb diff --git a/.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.md b/.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.md index 910581a595..34751a4e29 100644 --- a/.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.md +++ b/.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.md @@ -1,4 +1,4 @@ -# Agent Note: In-process subagent policy inheritance — the child starts under the parent's sandbox and approval overrides +# Agent Note: In-process subagent policy inheritance — the child starts under the parent's sandbox override Status: implemented @@ -6,11 +6,11 @@ English | [中文](2026-07-25-subagent-policy-inheritance.zh.md) ## Problem -Sandbox and approval overrides are per-session log folds. An in-process subagent gets a new session, so a spawn child once fell back to deployment defaults and a fork child saw only switches inside its completed-turn prefix. Delegation could therefore widen a parent that had switched to `read-only`, or turn a parent's unattended `'never'` approval stance back into prompting behavior. +Sandbox and approval overrides are per-session log folds. An in-process subagent gets a new session, so a spawn child once fell back to deployment defaults and a fork child saw only switches inside its completed-turn prefix. Delegation could therefore widen a parent that had switched to `read-only`. ## Decision -The delegation boundary snapshots `sandboxPolicy.overrideOf(parent.session)` and `approval.overrideOf(parent.session)` before its first await, through the shared child-agent helpers (`captureDelegatedPolicyOverrides`/`appendDelegatedPolicyOverrides` in `dsh-subagent`), which the one-shot driver and the [continuable start](2026-08-10-continuable-subagent-policy-inheritance.md) both call. A later parent switch belongs to the parent's future; cancel-and-redelegate takes a new snapshot. Both services are optional, and only explicit session overrides are copied, never deployment defaults or one-shot grants. +The delegation boundary snapshots `sandboxPolicy.overrideOf(parent.session)` before its first await, through the shared child-agent helpers (`captureDelegatedPolicyOverrides`/`appendDelegatedPolicyOverrides` in `dsh-subagent`), which the one-shot driver and the [continuable start](2026-08-10-continuable-subagent-policy-inheritance.md) both call. A later parent switch belongs to the parent's future; cancel-and-redelegate takes a new snapshot. The sandbox-policy service is optional, and only the explicit session override is copied, never deployment defaults or one-shot grants. The approval policy is not inherited: the same capture pins every child to `'never'` — the [approvals-pinned decision](2026-08-10-subagent-approval-pinned-never.md) supersedes this note's original approval-override inheritance. Each captured value becomes a source-tagged `sandbox/mode` or `approval/policy` event appended during the child factory's unpublished setup. The session constructor has already fixed `Session.firstLiveSeq` at the fork-prefix length, so the inherited facts follow fork history, reach telemetry when the child is announced, and leave `SessionHeader.seedLength` at the prefix length. Existing last-event-wins folds therefore make the delegation snapshot beat stale fork history and let a later child switch beat the snapshot. A grandchild folds its parent's logged state, so the rule composes without another inheritance mechanism. @@ -18,7 +18,7 @@ Ordinary session appends validate the inherited events before publication, and p ### What a blocked child experiences -A confined child gets the ordinary denial marker. No answerer currently owns an in-process child, so an escalation request fails closed and the child reports upward; a controller-owned parent may widen its own session and delegate again. An inherited `'never'` policy tells the child not to request escalation in its first system prompt. +A confined child gets the ordinary denial marker, and an escalation request is rejected deterministically by the child's pinned `'never'` policy; the `subagent:delegation` runtime-context statement tells the child to report the limitation instead of retrying, and a controller-owned parent may widen its own session and delegate again ([approvals-pinned decision](2026-08-10-subagent-approval-pinned-never.md)). ## Alternatives considered @@ -27,10 +27,10 @@ A confined child gets the ordinary denial marker. No answerer currently owns an - **A first-prompt listener** — rejected: it introduces listener ordering and a later timing boundary even though the creation transaction already permits log appends before publication. - **Copying deployment defaults** — rejected: defaults remain operator-owned and may change; an unswitched parent stamps nothing, so its child follows the current deployment. - **Live resolution walking `parentSession` at each call** — rejected: it breaks the "two sessions never see each other's state" isolation invariant, requires the parent session to stay loaded for the child's lifetime, and makes a mid-run parent switch retroactively change a running child. Snapshot-at-delegation is the semantic: the child keeps the policy it was handed; cancel-and-respawn picks up a tightening. -- **Forcing `'never'` or routing asks to the root controller** — rejected as inheritance behavior. A forced value forecloses a future child answerer; parent routing needs parent-chain ownership and the spawning `callId`, and remains deferred in [the approval-seam Agent Note](2026-07-06-approval-seam.md). +- **Forcing `'never'`** — originally rejected here as inheritance behavior because a forced value forecloses a future child answerer; that verdict is reversed by the [approvals-pinned decision](2026-08-10-subagent-approval-pinned-never.md), which owns the current rationale. Routing asks to the root controller needs parent-chain ownership and the spawning `callId`, and remains deferred in [the approval-seam Agent Note](2026-07-06-approval-seam.md). ## Consequences -- Spawn, fork, and nested in-process children retain a parent's explicit sandbox and approval overrides. The focused suite proves real filesystem denial, stale-fork precedence, delegation-time capture, the live-event boundary, default omission, and context disposal. +- Spawn, fork, and nested in-process children retain a parent's explicit sandbox override and are pinned to `'never'` approvals. The focused suite proves real filesystem denial, stale-fork precedence, delegation-time capture, the live-event boundary, default omission, and context disposal. - The keyless headless snapshot is the assembled regression: only the parent is `read-only`, the deployment default is `workspace-write`, and the child's persisted event plus denied disk write both fail if capture is removed. - Each delegation adds at most two log-only events. `dsh-subagent` owns the optional peer types for the two policy services — its shared helpers hold the `ctx.get` consumption; compositions without either service behave unchanged. Out-of-process children retain their own deployment policy, and a running child does not follow later parent switches. diff --git a/.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.zh.md b/.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.zh.md index a0edb3c6be..5fa8edf04e 100644 --- a/.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.zh.md +++ b/.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.zh.md @@ -1,4 +1,4 @@ -# Agent Note: 进程内 subagent 策略继承——子 agent 在父级的沙箱与审批覆盖项下启动 +# Agent Note: 进程内 subagent 策略继承——子 agent 在父级的沙箱覆盖项下启动 Status: implemented @@ -6,11 +6,11 @@ Status: implemented ## 问题 -沙箱与审批覆盖项都是按会话的日志折叠。进程内 subagent 会获得一个新会话,因此 spawn 子 agent(智能体)过去会回退到部署默认值,fork 子 agent 则只能看到其已完成轮次前缀中的切换。因此,委派可能放宽已经切换到 `read-only` 的父级,或让父级无人值守的 `'never'` 审批立场重新变成会发起提示的行为。 +沙箱与审批覆盖项都是按会话的日志折叠。进程内 subagent 会获得一个新会话,因此 spawn 子 agent(智能体)过去会回退到部署默认值,fork 子 agent 则只能看到其已完成轮次前缀中的切换。因此,委派可能放宽已经切换到 `read-only` 的父级。 ## 决策 -委派边界在第一次 await 之前,经由共享的子 agent 辅助函数(`dsh-subagent` 中的 `captureDelegatedPolicyOverrides`/`appendDelegatedPolicyOverrides`)对 `sandboxPolicy.overrideOf(parent.session)` 和 `approval.overrideOf(parent.session)` 获取快照;一次性驱动器与[可继续启动](2026-08-10-continuable-subagent-policy-inheritance.md)都会调用这些辅助函数。父级后续的切换属于父级的未来;取消后重新委派会取得新快照。这两个服务均为可选,仅复制显式会话覆盖项,绝不复制部署默认值或一次性授权。 +委派边界在第一次 await 之前,经由共享的子 agent 辅助函数(`dsh-subagent` 中的 `captureDelegatedPolicyOverrides`/`appendDelegatedPolicyOverrides`)对 `sandboxPolicy.overrideOf(parent.session)` 获取快照;一次性驱动器与[可继续启动](2026-08-10-continuable-subagent-policy-inheritance.md)都会调用这些辅助函数。父级后续的切换属于父级的未来;取消后重新委派会取得新快照。沙箱策略服务为可选,仅复制显式会话覆盖项,绝不复制部署默认值或一次性授权。审批策略不继承:同一次捕获会把每个子 agent 钉定为 `'never'`——[审批钉定决策](2026-08-10-subagent-approval-pinned-never.md)取代了本 note 原先的审批覆盖项继承。 每个捕获值都会成为子 agent 工厂在未发布设置阶段追加的一条带来源标记的 `sandbox/mode` 或 `approval/policy` 事件。会话构造函数已将 `Session.firstLiveSeq` 固定为 fork 前缀的长度,因此继承事实会排在 fork 历史之后,在子 agent 公布时进入遥测,同时让 `SessionHeader.seedLength` 保持为此前缀的长度。因此,既有的末事件胜出折叠会让委派快照压过陈旧的 fork 历史,并让子 agent 后续的切换压过该快照。孙代 agent 会折叠其父级已记录的状态,因此无需另一套继承机制即可组合此规则。 @@ -18,7 +18,7 @@ Status: implemented ### 被拦住的子 agent 会经历什么 -受限子 agent 会得到普通拒绝标记。目前没有应答器认领进程内子 agent,因此升级请求会以拒绝方式失败,由子 agent 向上汇报;由控制器持有的父 agent 可以放宽自己的会话后重新委派。继承的 `'never'` 策略会在第一份系统提示词中告知子 agent 不要请求升级。 +受限子 agent 会得到普通拒绝标记,升级请求则被子 agent 钉定的 `'never'` 策略确定性拒绝;`subagent:delegation` 运行时上下文声明告知子 agent 上报限制而不是重试,由控制器持有的父 agent 可以放宽自己的会话后重新委派([审批钉定决策](2026-08-10-subagent-approval-pinned-never.md))。 ## 考虑过的替代方案 @@ -27,10 +27,10 @@ Status: implemented - **首个提示词监听器**:不予采纳。尽管创建事务已经允许在发布前追加日志,它仍会引入监听器顺序与更晚的时序边界。 - **复制部署默认值**:不予采纳。默认值仍由运维人员拥有且可能变化;未切换的父级不会记录任何值,因此其子 agent 跟随当前部署。 - **每次调用时沿 `parentSession` 实时解析**:不予采纳。这会打破「两个会话永远看不到彼此状态」的隔离不变量,要求父会话在子 agent 的整个生命周期内保持加载,还会让父级在子 agent 运行途中做的切换追溯性地改变一个正在运行的子 agent。委派时快照才是本设计的语义:子 agent 保持它被交付时的策略;取消后重新 spawn 即可拿到收紧后的策略。 -- **强制使用 `'never'` 或把 ask 路由到根控制器**:不作为继承行为采纳。强制值会排除未来的子 agent 应答器;父级路由需要父链所有权与发起 spawn 的 `callId`,仍按[审批 seam Agent Note](2026-07-06-approval-seam.md) 所述延期。 +- **强制使用 `'never'`**:本 note 当初不作为继承行为采纳,理由是强制值会排除未来的子 agent 应答器;该结论已被[审批钉定决策](2026-08-10-subagent-approval-pinned-never.md)推翻,现行理由归其所有。把 ask 路由到根控制器需要父链所有权与发起 spawn 的 `callId`,仍按[审批 seam Agent Note](2026-07-06-approval-seam.md) 所述延期。 ## 后果 -- spawn、fork 和嵌套的进程内子 agent 会保留父级显式的沙箱与审批覆盖项。聚焦测试套件证明真实文件系统拒绝、陈旧 fork 优先级、委派时捕获、实时事件边界、默认值省略与上下文释放。 +- spawn、fork 和嵌套的进程内子 agent 会保留父级显式的沙箱覆盖项,并被钉定为 `'never'` 审批。聚焦测试套件证明真实文件系统拒绝、陈旧 fork 优先级、委派时捕获、实时事件边界、默认值省略与上下文释放。 - 无密钥 headless 快照是组装后应用层面的回归测试:只有父级是 `read-only`,部署默认值是 `workspace-write`;若移除捕获,子 agent 的持久化事件与被拒的磁盘写入这两项检查都会失败。 - 每次委派最多增加两条仅日志事件。两个策略服务的可选 peer 类型由 `dsh-subagent` 拥有——其共享辅助函数持有 `ctx.get` 消费;未组合任一服务的组合保持原有行为。进程外子 agent 仍采用自身的部署策略,正在运行的子 agent 不跟随父级后续切换。 diff --git a/.agents/notes/implemented/feature/2026-08-10-continuable-subagent-policy-inheritance.i18n.yaml b/.agents/notes/implemented/feature/2026-08-10-continuable-subagent-policy-inheritance.i18n.yaml index 54bc9adfb4..ac90a1c70d 100644 --- a/.agents/notes/implemented/feature/2026-08-10-continuable-subagent-policy-inheritance.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-08-10-continuable-subagent-policy-inheritance.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-08-10-continuable-subagent-policy-inheritance.md -2026-08-10-continuable-subagent-policy-inheritance.md: 04bcd0329a4608445b672d75b6c1e56dd265b25a -2026-08-10-continuable-subagent-policy-inheritance.zh.md: 9ef457df814ed848b04f42c5891024a0890bc9dd +2026-08-10-continuable-subagent-policy-inheritance.md: c9b75f2840eb2f124f040d138b761ee145fc6f83 +2026-08-10-continuable-subagent-policy-inheritance.zh.md: 8bd7f68c578ed827c756a415f017eb8cb61e5721 diff --git a/.agents/notes/implemented/feature/2026-08-10-continuable-subagent-policy-inheritance.md b/.agents/notes/implemented/feature/2026-08-10-continuable-subagent-policy-inheritance.md index 04bcd0329a..c9b75f2840 100644 --- a/.agents/notes/implemented/feature/2026-08-10-continuable-subagent-policy-inheritance.md +++ b/.agents/notes/implemented/feature/2026-08-10-continuable-subagent-policy-inheritance.md @@ -10,7 +10,7 @@ The one-shot in-process driver has seeded parent sandbox/approval overrides into ## Decision -The capture/append pair moved from the one-shot driver into the seam's shared child-agent module (`dsh-subagent/src/child-agent.ts`), the declared one home for shared child composition: `captureDelegatedPolicyOverrides(parent)` snapshots `sandboxPolicy.overrideOf(parent.session)` and `approval.overrideOf(parent.session)` through optional `ctx.get`, and `appendDelegatedPolicyOverrides(childSession, overrides)` appends the `source: 'delegation'` events. The one-shot driver and the continuation manager both call them, so the two paths cannot drift. +The capture/append pair moved from the one-shot driver into the seam's shared child-agent module (`dsh-subagent/src/child-agent.ts`), the declared one home for shared child composition: `captureDelegatedPolicyOverrides(parent)` snapshots `sandboxPolicy.overrideOf(parent.session)` through optional `ctx.get` and pins the child approval policy to `'never'` ([approvals-pinned decision](2026-08-10-subagent-approval-pinned-never.md)), and `appendDelegatedPolicyOverrides(childSession, overrides)` appends the `source: 'delegation'` events. The one-shot driver and the continuation manager both call them, so the two paths cannot drift. `startContinuable` captures before its first await (`prepareContinuable`), the same "a later parent switch belongs to the parent's future" boundary as one-shot. The snapshot travels in `MaterializeInputs.create`, so only fresh materialization appends the events during unpublished setup, after any fork seed. A cold resume passes no `create` inputs and appends nothing: the persisted child log already carries the delegation events, and replaying the log IS the state. The durable child log — not the current Activation, not the resuming parent — owns the child's effective policy, so a parent switch between residency epochs never retroactively changes a durable child. @@ -23,7 +23,7 @@ The capture/append pair moved from the one-shot driver into the seam's shared ch ## Consequences -- Default-bundle background delegation (`backgroundMode: continuable`) now inherits a parent's explicit sandbox and approval overrides; compositions without either policy service behave unchanged. +- Default-bundle background delegation (`backgroundMode: continuable`) now inherits a parent's explicit sandbox override and pins the child to `'never'` approvals; compositions without either policy service behave unchanged. - `dsh-subagent` gains optional peer types on `dsh-sandbox-policy` and `dsh-user-approval` (the `ctx.get` pattern the one-shot driver used); `dsh-subagent-inprocess` drops its policy-service peers and type imports entirely and delegates to the shared helpers. - The continuable suite (`packages/subagent/subagent/tests/continuation-inheritance.spec.ts`) pins fresh-start seeding, pre-await capture, default omission, cold-resume snapshot stability, and fork-seed precedence; the ACP snapshot scenario `subagent-continuable-inheritance` pins the child's delegation event and read-only runtime context through the assembled app and fails when the capture is removed. - Out-of-process providers (`acp`, `dsh-sdk`, `claude-code`, `codex`) support no continuable children (`prepareContinuable` absent), and their one-shot children keep their own deployment policy (`inheritsParentContext = false`); cross-process policy propagation remains out of scope. diff --git a/.agents/notes/implemented/feature/2026-08-10-continuable-subagent-policy-inheritance.zh.md b/.agents/notes/implemented/feature/2026-08-10-continuable-subagent-policy-inheritance.zh.md index 9ef457df81..8bd7f68c57 100644 --- a/.agents/notes/implemented/feature/2026-08-10-continuable-subagent-policy-inheritance.zh.md +++ b/.agents/notes/implemented/feature/2026-08-10-continuable-subagent-policy-inheritance.zh.md @@ -10,7 +10,7 @@ Status: implemented ## 决策 -捕获/追加这对函数从一次性驱动器移入该 seam 的共享子 agent 模块(`dsh-subagent/src/child-agent.ts`),即声明的共享子级组合唯一归属之处:`captureDelegatedPolicyOverrides(parent)` 通过可选的 `ctx.get` 对 `sandboxPolicy.overrideOf(parent.session)` 与 `approval.overrideOf(parent.session)` 建立快照,`appendDelegatedPolicyOverrides(childSession, overrides)` 则追加 `source: 'delegation'` 事件。一次性驱动器与继续执行管理器都调用它们,因此两条路径不会出现偏差。 +捕获/追加这对函数从一次性驱动器移入该 seam 的共享子 agent 模块(`dsh-subagent/src/child-agent.ts`),即声明的共享子级组合唯一归属之处:`captureDelegatedPolicyOverrides(parent)` 通过可选的 `ctx.get` 对 `sandboxPolicy.overrideOf(parent.session)` 建立快照,并把子级审批策略钉定为 `'never'`([审批钉定决策](2026-08-10-subagent-approval-pinned-never.md)),`appendDelegatedPolicyOverrides(childSession, overrides)` 则追加 `source: 'delegation'` 事件。一次性驱动器与继续执行管理器都调用它们,因此两条路径不会出现偏差。 `startContinuable` 在其第一次 await(`prepareContinuable`)之前完成捕获,沿用与一次性路径相同的「父级后续切换属于父级的未来」边界。快照放在 `MaterializeInputs.create` 中传递,因此只有全新物化会在未发布的设置阶段、排在任何 fork 种子之后追加这些事件。冷恢复(cold resume)不传入 `create` 输入,也不追加任何内容:持久化的子日志已经携带委派事件,而回放该日志本身就是状态。子 agent 的生效策略由持久化子日志拥有,而不是当前 Activation,也不是发起恢复的父级,因此父级在驻留纪元(residency epoch)之间的切换绝不会追溯性地改变一个持久化子 agent。 @@ -23,7 +23,7 @@ Status: implemented ## 后果 -- 默认组合包的后台委派(`backgroundMode: continuable`)现在会继承父级显式的沙箱与审批覆盖项;未组合任一策略服务的组合保持原有行为。 +- 默认组合包的后台委派(`backgroundMode: continuable`)现在会继承父级显式的沙箱覆盖项,并把子级钉定为 `'never'` 审批;未组合任一策略服务的组合保持原有行为。 - `dsh-subagent` 新增针对 `dsh-sandbox-policy` 与 `dsh-user-approval` 的可选 peer 类型(即一次性驱动器所用的 `ctx.get` 模式);`dsh-subagent-inprocess` 完全移除自己的策略服务 peer 与类型导入,委托给共享辅助函数。 - 可继续测试套件(`packages/subagent/subagent/tests/continuation-inheritance.spec.ts`)锁定全新启动的种子写入、await 前捕获、默认值省略、冷恢复快照稳定性与 fork 种子优先级;ACP 快照场景 `subagent-continuable-inheritance` 经组装后的应用锁定子级的委派事件与只读运行时上下文,移除捕获时即失败。 - 进程外提供方(`acp`、`dsh-sdk`、`claude-code`、`codex`)不支持可继续子 agent(没有 `prepareContinuable`),其一次性子 agent 保留自身的部署策略(`inheritsParentContext = false`);跨进程策略传播仍不在范围内。 diff --git a/.agents/notes/implemented/feature/2026-08-10-subagent-approval-pinned-never.i18n.yaml b/.agents/notes/implemented/feature/2026-08-10-subagent-approval-pinned-never.i18n.yaml new file mode 100644 index 0000000000..cde23b2552 --- /dev/null +++ b/.agents/notes/implemented/feature/2026-08-10-subagent-approval-pinned-never.i18n.yaml @@ -0,0 +1,6 @@ +# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each +# side as of the last confirmed-consistent state. Both languages carry equal authority; +# after editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-08-10-subagent-approval-pinned-never.md +2026-08-10-subagent-approval-pinned-never.md: 578dbe58cd4e0a3c97552e20f27a2818ee9c9f40 +2026-08-10-subagent-approval-pinned-never.zh.md: 45bc461505b07a4c10e063a122e8003f52afd259 diff --git a/.agents/notes/implemented/feature/2026-08-10-subagent-approval-pinned-never.md b/.agents/notes/implemented/feature/2026-08-10-subagent-approval-pinned-never.md new file mode 100644 index 0000000000..578dbe58cd --- /dev/null +++ b/.agents/notes/implemented/feature/2026-08-10-subagent-approval-pinned-never.md @@ -0,0 +1,34 @@ +# Agent Note: Delegated subagents run with approvals pinned to `'never'` + +Status: implemented + +English | [中文](2026-08-10-subagent-approval-pinned-never.zh.md) + +## Problem + +A delegated child that asked for approval had no one to ask. Under an interactive parent (`'ask'`), a background child's escalation became a pending question no product surface showed — subagent sessions are omitted from the Web sidebar, the parent's `list_agents` reports plain `running`/`idle`, and the catalog rows show only activity — so a permission-blocked child was indistinguishable from a working one; headless and unanswered compositions failed the same ask closed as `'unavailable'`. The rejection audit landed only in the child's own log, and no tool parameter or Web control can adjust a running child session's sandbox mode or approval policy ([deepseek-harness#1723](https://github.com/deepseek-harness/deepseek-harness/issues/1723)). The mechanism-heavy fix — a durable blocked-state projection, parent notices, catalog badges, and a permission write path through the subagent ownership fence — was disproportionate directly before release. + +## Decision + +A delegated child acts only within the permission scope fixed at delegation, and approval prompts are removed from its world entirely: `captureDelegatedPolicyOverrides(parent)` (`dsh-subagent/src/child-agent.ts`) still snapshots the parent session's explicit sandbox override, but pins `approvalPolicy: 'never'` whenever the approval capability is composed — it no longer reads the parent's own approval policy. `appendDelegatedPolicyOverrides()` writes the pin as the durable `approval/policy { policy: 'never', source: 'delegation' }` event on the child's log, through the same one-shot and continuable delegation paths as the sandbox snapshot, so cold resume replays it and a fork seed's stale parent policy loses to it. + +Enforcement is the existing `ApprovalService` `'never'` semantics at the one operation that decides asks: every child ask — a `sandbox_permissions` escalation from bash or fs, a hook-driven permission question, any future asker — resolves `'rejected'` deterministically before any answerer is consulted, still leaving the `approval/asked`/`approval/decided` audit pair on the child log. The child's whole permission story is therefore its sandbox scope: a `danger-full-access` parent delegates children that need no approvals, a `read-only` parent delegates children with no escape hatch, and a widening decision always belongs to the parent side (widen the parent session, then delegate or follow up again). + +Every in-process child is told, not trapped: `applyChildComposition` registers the scoped `subagent:delegation` runtime-context statement (order 120, after the `sandbox:policy` and `approval:policy` sentences) stating that the scope was fixed at start, approval-requiring operations are rejected automatically, and a task needing wider access ends with a reported limitation instead of retries. The statement is a runtime-context contribution rather than a system-prompt section, so the deployment's system prompt stays uniform across parents and children (the snapshot suite pins that uniformity) and the fact rides the same durable snapshot as the policy sentences. + +This supersedes the approval half of the [in-process delegation-policy decision](2026-07-25-subagent-policy-inheritance.md) and reverses its "forcing `'never'` forecloses a future child answerer" verdict: approval inheritance shipped, produced the invisible blocked states above, and a future child answerer now requires reversing this note first. + +## Alternatives considered + +- **Inheriting the parent's approval override** (the prior behavior) — rejected: only a parent already at `'never'` produced deterministic children; an interactive parent seeded children whose asks waited on a prompt no one was watching or failed closed `'unavailable'`, and the outcome depended on which surfaces happened to be attached. +- **Blocked-state visibility and per-child permission adjustment** (the original #1723 acceptance) — deferred, not rejected: a `list_agents` blocked annotation, parent notices over the settlement-delivery seam, catalog badges, and a subagent-routed permission channel remain the richer design, but each needs its own seam work and none is required once children cannot enter a blocked-waiting state. +- **Routing child asks to the parent controller** — still deferred in the [approval-seam Agent Note](2026-07-06-approval-seam.md): it needs parent-chain ownership and the spawning `callId`. +- **Pinning inside `ApprovalService` by session origin** — rejected: it couples the approval package to delegation vocabulary and duplicates a decision the delegation boundary already owns; the delegation-seeded event is enforceable because no current write path can switch a child session's policy (the `/permission` command requires generic Host routing, which the subagent ownership fence denies to child sessions). + +## Consequences + +- The child's sandbox inheritance is the complete delegation permission model; the `DelegatedPolicyOverrides.approvalPolicy` field narrows to `'never' | undefined` (`undefined` only without a composed approval capability). +- Model-visible: each child's runtime-context snapshot carries the `subagent:delegation` statement plus the standing disabled-approvals sentence; parent requests are unchanged. The executor-boundary test proves a child escalation is rejected without consulting a root answerer that would have granted it, with the audit pair logged. +- Boundaries: in-process one-shot, continuable, and workflow-spawned children are enforced through the shared helpers; `subagent-acp` children keep that provider's explicit machine `permission` policy; `claude-code`, `codex`, and `dsh-sdk` children run in external processes under their own composition. +- Children persisted before the pin fold to the deployment approval default on cold resume; pre-release, no migration is added. +- Snapshot fixtures record the pin: every in-process child log gains the delegation `approval/policy` event, and `subagent-published-run-failure` now persists a one-event child log where the child previously left no durable events. diff --git a/.agents/notes/implemented/feature/2026-08-10-subagent-approval-pinned-never.zh.md b/.agents/notes/implemented/feature/2026-08-10-subagent-approval-pinned-never.zh.md new file mode 100644 index 0000000000..45bc461505 --- /dev/null +++ b/.agents/notes/implemented/feature/2026-08-10-subagent-approval-pinned-never.zh.md @@ -0,0 +1,34 @@ +# Agent Note: 被委派的 subagent 以钉定为 `'never'` 的审批策略运行 + +Status: implemented + +[English](2026-08-10-subagent-approval-pinned-never.md) | 中文 + +## 问题 + +被委派的子 agent 发起审批请求时无人可问。在交互式父级(`'ask'`)之下,后台子 agent 的升级请求会变成一个任何产品界面都不展示的挂起问题——subagent 会话不进入 Web 侧边栏,父级的 `list_agents` 只报告普通的 `running`/`idle`,目录树的行也只显示活动状态——因此被权限拦住的子 agent 与正常干活的子 agent 无法区分;headless 与无应答者的组合则让同一次 ask 以 `'unavailable'` 失败关闭。拒绝的审计记录只落在子 agent 自己的日志里,而且没有任何工具参数或 Web 控件能调整一个正在运行的子会话的沙箱模式或审批策略([deepseek-harness#1723](https://github.com/deepseek-harness/deepseek-harness/issues/1723))。机制繁重的修复方案——持久化的受阻状态投影、父级通知、目录树徽标,以及穿过 subagent 所有权围栏的权限写入路径——在临近发布时代价不成比例。 + +## 决策 + +被委派的子 agent 只在委派时固定的权限范围内行动,审批提示则从它的世界中彻底移除:`captureDelegatedPolicyOverrides(parent)`(`dsh-subagent/src/child-agent.ts`)仍对父会话的显式沙箱覆盖项建立快照,但只要审批能力已组合,就把 `approvalPolicy: 'never'` 钉定下来——不再读取父级自身的审批策略。`appendDelegatedPolicyOverrides()` 把这个钉定作为持久化的 `approval/policy { policy: 'never', source: 'delegation' }` 事件写入子 agent 的日志,与沙箱快照走完全相同的一次性与可继续委派路径,因此冷恢复会重放它,fork 种子中陈旧的父级策略也会输给它。 + +强制执行沿用既有的 `ApprovalService` `'never'` 语义,落在裁决 ask 的唯一操作上:子 agent 的每次 ask——bash 或 fs 的 `sandbox_permissions` 升级、hook 驱动的权限询问、任何未来的请求方——都在咨询任何应答者之前确定性地解析为 `'rejected'`,同时仍在子日志上留下 `approval/asked`/`approval/decided` 审计对。子 agent 的全部权限故事因此就是它的沙箱范围:`danger-full-access` 父级委派出的子 agent 无需任何审批,`read-only` 父级委派出的子 agent 没有任何逃生通道,而放宽的决定始终属于父级一侧(先放宽父会话,再重新委派或继续 follow-up)。 + +每个进程内子 agent 都被告知而非被困住:`applyChildComposition` 注册作用域内的 `subagent:delegation` 运行时上下文声明(order 120,位于 `sandbox:policy` 与 `approval:policy` 语句之后),声明权限范围已在启动时固定、需要审批的操作会被自动拒绝、需要更宽访问的任务应以上报限制收尾而不是重试。该声明是运行时上下文贡献而非系统提示词 section,因此部署的系统提示词在父子之间保持统一(快照测试套件钉住了这一统一性),该事实也随策略语句乘坐同一份持久化快照。 + +本决策取代[进程内委派策略决策](2026-07-25-subagent-policy-inheritance.md)中的审批一半,并推翻其「强制 `'never'` 会排除未来的子 agent 应答器」的结论:审批继承已经落地,产生的正是上述不可见的受阻状态;未来若要引入子 agent 应答器,必须先推翻本 note。 + +## 考虑过的替代方案 + +- **继承父级的审批覆盖项**(先前的行为):不予采纳。只有已处于 `'never'` 的父级才产生确定性的子 agent;交互式父级种出的子 agent,其 ask 要么等待一个无人在看的提示,要么以 `'unavailable'` 失败关闭,结果取决于当时恰好接入了哪些界面。 +- **受阻状态可见性与逐子级权限调整**(#1723 原有的验收):延后而非否决。`list_agents` 的受阻标注、经由结算投递 seam 的父级通知、目录树徽标,以及 subagent 专用的权限通道仍是更完整的设计,但每一项都需要独立的 seam 工作;一旦子 agent 不可能进入等待审批的受阻状态,这些都不再是必需。 +- **把子 agent 的 ask 路由到父控制器**:仍按[审批 seam Agent Note](2026-07-06-approval-seam.md) 延后。它需要父链所有权与发起 spawn 的 `callId`。 +- **在 `ApprovalService` 内按会话来源钉定**:不予采纳。这会让审批包耦合委派词汇,并重复一个委派边界已经拥有的决定;委派种入的事件之所以可强制执行,是因为当前不存在任何能切换子会话策略的写入路径(`/permission` 命令要求通用 Host 路由,而 subagent 所有权围栏对子会话拒绝该路由)。 + +## 后果 + +- 子 agent 的沙箱继承就是委派权限模型的全部;`DelegatedPolicyOverrides.approvalPolicy` 字段收窄为 `'never' | undefined`(仅在未组合审批能力时为 `undefined`)。 +- 模型可见:每个子 agent 的运行时上下文快照携带 `subagent:delegation` 声明以及固定的审批已禁用语句;父级请求不变。executor 边界测试证明:即使根部有一个本会批准的应答者,子 agent 的升级仍被拒绝且不咨询该应答者,审计对照常落日志。 +- 边界:进程内一次性、可继续以及 workflow 派生的子 agent 都经由共享辅助函数强制执行;`subagent-acp` 子 agent 保留该提供方显式的机器 `permission` 策略;`claude-code`、`codex` 与 `dsh-sdk` 子 agent 运行在外部进程中,由各自的组合决定。 +- 在钉定之前持久化的子 agent 冷恢复时折叠到部署审批默认值;处于预发布阶段,不添加迁移。 +- 快照夹具记录了该钉定:每个进程内子日志都新增委派 `approval/policy` 事件,`subagent-published-run-failure` 现在会持久化一份单事件子日志,而此前该子 agent 不留任何持久化事件。 diff --git a/examples/acp-agent/tests/snapshots/advanced-toolchain/session.1.jsonl b/examples/acp-agent/tests/snapshots/advanced-toolchain/session.1.jsonl index 7908f0e71b..66be552da6 100644 --- a/examples/acp-agent/tests/snapshots/advanced-toolchain/session.1.jsonl +++ b/examples/acp-agent/tests/snapshots/advanced-toolchain/session.1.jsonl @@ -1,19 +1,20 @@ {"type":"session","version":0,"id":"22222222-2222-4222-8222-222222222222","createdAt":1783950001000,"cwd":"{{cwd}}","parentSession":"11111111-1111-4111-8111-111111111111","origin":"subagent","delegationDepth":1} -{"type":"agent/inbox/spliced","seq":0,"time":1785498801881,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Reply with exactly DIRECT_CHILD_OK and nothing else."}],"source":{"kind":"user"},"role":"user","id":"ebe0cfa0-a909-47e0-8294-28ad84a8fe77"}]}} -{"type":"turn/start","seq":1,"time":1785821418076,"data":{"turn":1}} -{"type":"agent/inbox/spliced","seq":2,"time":1785821418076,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} -{"type":"subagent/descriptor","seq":3,"time":1785821418091,"data":{"version":2,"mode":"one-shot","provider":"spawn","label":"Check direct child"}} -{"type":"step/start","seq":4,"time":1785730458555,"data":{"turn":1,"step":1}} -{"type":"user/message","seq":5,"time":1785730458555,"data":{"content":[{"type":"text","text":"Reply with exactly DIRECT_CHILD_OK and nothing else."}],"source":{"kind":"user"},"role":"user","id":"ebe0cfa0-a909-47e0-8294-28ad84a8fe77"},"surfaceOp":"append"} -{"type":"user/message","seq":6,"time":1785730458555,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}]},"role":"user","id":"f9a2d1b6-8f23-43a5-8702-d413fed40990"},"surfaceOp":"append"} -{"type":"session/title","seq":7,"time":1785730458555,"data":{"title":"Reply with exactly DIRECT_CHILD_OK and","messageSeqs":[5],"source":{"kind":"fallback"}}} -{"type":"request/header","seq":8,"time":1785730458555,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}} -{"type":"request/context","seq":9,"time":1785730458555,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} -{"type":"assistant/chunk","seq":10,"time":1783957884564,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"text"}}} -{"type":"assistant/chunk","seq":11,"time":1783957884564,"data":{"turn":1,"step":1,"chunk":{"type":"text-delta","index":0,"text":"DIRECT_CHILD_OK"}}} -{"type":"assistant/chunk","seq":12,"time":1785498801905,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"DIRECT_CHILD_OK"}}}} -{"type":"assistant/chunk","seq":13,"time":1785730458561,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}}} -{"type":"assistant/chunk","seq":14,"time":1785730458561,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"stop"}}}} -{"type":"assistant/message","seq":15,"time":1785730458561,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"text","text":"DIRECT_CHILD_OK"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"b9c977ca-2c1a-4a5e-8397-e0b9381a9943"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[10,11,12,13,14],"surfaceOp":"append"} -{"type":"step/end","seq":16,"time":1785730458561,"data":{"turn":1,"step":1}} -{"type":"turn/end","seq":17,"time":1785730458561,"data":{"turn":1,"reason":{"kind":"completed"}}} +{"type":"approval/policy","seq":0,"time":1786357538290,"data":{"policy":"never","source":"delegation"}} +{"type":"agent/inbox/spliced","seq":1,"time":1786357538290,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Reply with exactly DIRECT_CHILD_OK and nothing else."}],"source":{"kind":"user"},"role":"user","id":"ebe0cfa0-a909-47e0-8294-28ad84a8fe77"}]}} +{"type":"turn/start","seq":2,"time":1786357538290,"data":{"turn":1}} +{"type":"agent/inbox/spliced","seq":3,"time":1786357538290,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} +{"type":"subagent/descriptor","seq":4,"time":1786357538308,"data":{"version":2,"mode":"one-shot","provider":"spawn","label":"Check direct child"}} +{"type":"step/start","seq":5,"time":1786357538310,"data":{"turn":1,"step":1}} +{"type":"user/message","seq":6,"time":1785730458555,"data":{"content":[{"type":"text","text":"Reply with exactly DIRECT_CHILD_OK and nothing else."}],"source":{"kind":"user"},"role":"user","id":"ebe0cfa0-a909-47e0-8294-28ad84a8fe77"},"surfaceOp":"append"} +{"type":"user/message","seq":7,"time":1786357538310,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`).\n\nYou are a delegated subagent: your permission scope was fixed when you were started and cannot be widened from inside this session — operations that require approval are rejected automatically. When the task needs access beyond that scope, do not retry the denied operation; state the limitation in your reply so the delegating agent can handle it."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."},{"name":"subagent:delegation","text":"You are a delegated subagent: your permission scope was fixed when you were started and cannot be widened from inside this session — operations that require approval are rejected automatically. When the task needs access beyond that scope, do not retry the denied operation; state the limitation in your reply so the delegating agent can handle it."}]},"role":"user","id":"baed758f-a123-4c3d-8587-a5b7d854f71f"},"surfaceOp":"append"} +{"type":"session/title","seq":8,"time":1786357538310,"data":{"title":"Reply with exactly DIRECT_CHILD_OK and","messageSeqs":[6],"source":{"kind":"fallback"}}} +{"type":"request/header","seq":9,"time":1785730458555,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}} +{"type":"request/context","seq":10,"time":1785730458555,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} +{"type":"assistant/chunk","seq":11,"time":1783957884564,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"text"}}} +{"type":"assistant/chunk","seq":12,"time":1783957884564,"data":{"turn":1,"step":1,"chunk":{"type":"text-delta","index":0,"text":"DIRECT_CHILD_OK"}}} +{"type":"assistant/chunk","seq":13,"time":1785498801905,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"DIRECT_CHILD_OK"}}}} +{"type":"assistant/chunk","seq":14,"time":1785730458561,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}}} +{"type":"assistant/chunk","seq":15,"time":1785730458561,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"stop"}}}} +{"type":"assistant/message","seq":16,"time":1785730458561,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"text","text":"DIRECT_CHILD_OK"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"b9c977ca-2c1a-4a5e-8397-e0b9381a9943"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[11,12,13,14,15],"surfaceOp":"append"} +{"type":"step/end","seq":17,"time":1785730458561,"data":{"turn":1,"step":1}} +{"type":"turn/end","seq":18,"time":1785730458561,"data":{"turn":1,"reason":{"kind":"completed"}}} diff --git a/examples/acp-agent/tests/snapshots/advanced-toolchain/session.2.jsonl b/examples/acp-agent/tests/snapshots/advanced-toolchain/session.2.jsonl index adf877c24b..a449b90550 100644 --- a/examples/acp-agent/tests/snapshots/advanced-toolchain/session.2.jsonl +++ b/examples/acp-agent/tests/snapshots/advanced-toolchain/session.2.jsonl @@ -1,19 +1,20 @@ {"type":"session","version":0,"id":"33333333-3333-4333-8333-333333333333","createdAt":1783950002000,"cwd":"{{cwd}}","parentSession":"11111111-1111-4111-8111-111111111111","origin":"subagent","delegationDepth":1} -{"type":"agent/inbox/spliced","seq":0,"time":1785498802039,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Reply with exactly WORKFLOW_CHILD_OK and nothing else."}],"source":{"kind":"user"},"role":"user","id":"2ac2cc54-9bce-4cfa-a569-a64f51bc30a7"}]}} -{"type":"turn/start","seq":1,"time":1785821418251,"data":{"turn":1}} -{"type":"agent/inbox/spliced","seq":2,"time":1785821418251,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} -{"type":"subagent/descriptor","seq":3,"time":1785821418270,"data":{"version":2,"mode":"one-shot","provider":"spawn"}} -{"type":"step/start","seq":4,"time":1785730458703,"data":{"turn":1,"step":1}} -{"type":"user/message","seq":5,"time":1785730458703,"data":{"content":[{"type":"text","text":"Reply with exactly WORKFLOW_CHILD_OK and nothing else."}],"source":{"kind":"user"},"role":"user","id":"2ac2cc54-9bce-4cfa-a569-a64f51bc30a7"},"surfaceOp":"append"} -{"type":"user/message","seq":6,"time":1785730458703,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}]},"role":"user","id":"dfbcd587-db47-4c3d-bbe9-8c031b215fc3"},"surfaceOp":"append"} -{"type":"session/title","seq":7,"time":1785730458703,"data":{"title":"Reply with exactly WORKFLOW_CHILD_OK and","messageSeqs":[5],"source":{"kind":"fallback"}}} -{"type":"request/header","seq":8,"time":1785730458703,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}} -{"type":"request/context","seq":9,"time":1785730458703,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} -{"type":"assistant/chunk","seq":10,"time":1783957884701,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"text"}}} -{"type":"assistant/chunk","seq":11,"time":1783957884701,"data":{"turn":1,"step":1,"chunk":{"type":"text-delta","index":0,"text":"WORKFLOW_CHILD_OK"}}} -{"type":"assistant/chunk","seq":12,"time":1785498802068,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"WORKFLOW_CHILD_OK"}}}} -{"type":"assistant/chunk","seq":13,"time":1785730458709,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}}} -{"type":"assistant/chunk","seq":14,"time":1785730458709,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"stop"}}}} -{"type":"assistant/message","seq":15,"time":1785730458709,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"text","text":"WORKFLOW_CHILD_OK"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"5c33b525-4844-4272-b6f2-e036356d0e22"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[10,11,12,13,14],"surfaceOp":"append"} -{"type":"step/end","seq":16,"time":1785730458709,"data":{"turn":1,"step":1}} -{"type":"turn/end","seq":17,"time":1785730458709,"data":{"turn":1,"reason":{"kind":"completed"}}} +{"type":"approval/policy","seq":0,"time":1786357538450,"data":{"policy":"never","source":"delegation"}} +{"type":"agent/inbox/spliced","seq":1,"time":1786357538450,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Reply with exactly WORKFLOW_CHILD_OK and nothing else."}],"source":{"kind":"user"},"role":"user","id":"2ac2cc54-9bce-4cfa-a569-a64f51bc30a7"}]}} +{"type":"turn/start","seq":2,"time":1786357538450,"data":{"turn":1}} +{"type":"agent/inbox/spliced","seq":3,"time":1786357538450,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} +{"type":"subagent/descriptor","seq":4,"time":1786357538469,"data":{"version":2,"mode":"one-shot","provider":"spawn"}} +{"type":"step/start","seq":5,"time":1786357538470,"data":{"turn":1,"step":1}} +{"type":"user/message","seq":6,"time":1785730458703,"data":{"content":[{"type":"text","text":"Reply with exactly WORKFLOW_CHILD_OK and nothing else."}],"source":{"kind":"user"},"role":"user","id":"2ac2cc54-9bce-4cfa-a569-a64f51bc30a7"},"surfaceOp":"append"} +{"type":"user/message","seq":7,"time":1786357538471,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`).\n\nYou are a delegated subagent: your permission scope was fixed when you were started and cannot be widened from inside this session — operations that require approval are rejected automatically. When the task needs access beyond that scope, do not retry the denied operation; state the limitation in your reply so the delegating agent can handle it."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."},{"name":"subagent:delegation","text":"You are a delegated subagent: your permission scope was fixed when you were started and cannot be widened from inside this session — operations that require approval are rejected automatically. When the task needs access beyond that scope, do not retry the denied operation; state the limitation in your reply so the delegating agent can handle it."}]},"role":"user","id":"01f64214-c832-47ef-8e90-052047edc27d"},"surfaceOp":"append"} +{"type":"session/title","seq":8,"time":1786357538471,"data":{"title":"Reply with exactly WORKFLOW_CHILD_OK and","messageSeqs":[6],"source":{"kind":"fallback"}}} +{"type":"request/header","seq":9,"time":1785730458703,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}} +{"type":"request/context","seq":10,"time":1785730458703,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} +{"type":"assistant/chunk","seq":11,"time":1783957884701,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"text"}}} +{"type":"assistant/chunk","seq":12,"time":1783957884701,"data":{"turn":1,"step":1,"chunk":{"type":"text-delta","index":0,"text":"WORKFLOW_CHILD_OK"}}} +{"type":"assistant/chunk","seq":13,"time":1785498802068,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"WORKFLOW_CHILD_OK"}}}} +{"type":"assistant/chunk","seq":14,"time":1785730458709,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}}} +{"type":"assistant/chunk","seq":15,"time":1785730458709,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"stop"}}}} +{"type":"assistant/message","seq":16,"time":1785730458709,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"text","text":"WORKFLOW_CHILD_OK"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"5c33b525-4844-4272-b6f2-e036356d0e22"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[11,12,13,14,15],"surfaceOp":"append"} +{"type":"step/end","seq":17,"time":1785730458709,"data":{"turn":1,"step":1}} +{"type":"turn/end","seq":18,"time":1785730458709,"data":{"turn":1,"reason":{"kind":"completed"}}} diff --git a/examples/acp-agent/tests/snapshots/advanced-toolchain/session.jsonl b/examples/acp-agent/tests/snapshots/advanced-toolchain/session.jsonl index d6935b6c98..aea9e3107c 100644 --- a/examples/acp-agent/tests/snapshots/advanced-toolchain/session.jsonl +++ b/examples/acp-agent/tests/snapshots/advanced-toolchain/session.jsonl @@ -4,7 +4,7 @@ {"type":"agent/inbox/spliced","seq":2,"time":1785821417919,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} {"type":"step/start","seq":3,"time":1783957884486,"data":{"turn":1,"step":1}} {"type":"user/message","seq":4,"time":1785498801761,"data":{"content":[{"type":"text","text":"Run this advanced flow exactly once: try a no-op temporary Cordis Plugin named snapshot-marker; use run_code to inspect the live temporary Plugins through tools.cordis_inspect; delegate once to a direct spawn child; run one workflow that delegates to another spawn child; stop dyn-1; then reply with exactly ADVANCED_ACP_OK."}],"source":{"kind":"user"},"role":"user","id":"6e45782a-31be-4ba7-8c4a-7411a2027e36"},"surfaceOp":"append"} -{"type":"user/message","seq":5,"time":1785730458430,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}]},"role":"user","id":"9f38e2b8-1d4e-4c90-8896-00aa42307ea7"},"surfaceOp":"append"} +{"type":"user/message","seq":5,"time":1785730458430,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}]},"role":"user","id":"06416873-c855-452d-8996-ea5cf45223d1"},"surfaceOp":"append"} {"type":"session/title","seq":6,"time":1785730458430,"data":{"title":"Run this advanced flow exactly","messageSeqs":[4],"source":{"kind":"fallback"}}} {"type":"request/header","seq":7,"time":1785498801765,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}} {"type":"request/context","seq":8,"time":1785730458431,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} diff --git a/examples/acp-agent/tests/snapshots/subagent-child-question-rejection/session.1.jsonl b/examples/acp-agent/tests/snapshots/subagent-child-question-rejection/session.1.jsonl index 68527f63ac..857dea88b0 100644 --- a/examples/acp-agent/tests/snapshots/subagent-child-question-rejection/session.1.jsonl +++ b/examples/acp-agent/tests/snapshots/subagent-child-question-rejection/session.1.jsonl @@ -1,29 +1,30 @@ {"type":"session","version":0,"id":"55555555-5555-4555-8555-555555555555","createdAt":2001,"cwd":"{{cwd}}","parentSession":"44444444-4444-4444-8444-444444444444","origin":"subagent","delegationDepth":1} -{"type":"agent/inbox/spliced","seq":0,"time":1786173701247,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Call ask_user_question once to ask whether deployment should use the CUDA fallback. If the tool returns an error, include the unresolved question verbatim in your final result."}],"source":{"kind":"user"},"role":"user","id":"106c2785-219e-46e8-8386-497ac6a98f68"}]}} -{"type":"turn/start","seq":1,"time":1786173701247,"data":{"turn":1}} -{"type":"agent/inbox/spliced","seq":2,"time":1786173701247,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} -{"type":"subagent/descriptor","seq":3,"time":1786173701270,"data":{"version":2,"mode":"one-shot","provider":"spawn","label":"Check deployment question"}} -{"type":"step/start","seq":4,"time":1786173701272,"data":{"turn":1,"step":1}} -{"type":"user/message","seq":5,"time":1786173701272,"data":{"content":[{"type":"text","text":"Call ask_user_question once to ask whether deployment should use the CUDA fallback. If the tool returns an error, include the unresolved question verbatim in your final result."}],"source":{"kind":"user"},"role":"user","id":"106c2785-219e-46e8-8386-497ac6a98f68"},"surfaceOp":"append"} -{"type":"user/message","seq":6,"time":1786173701272,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}]},"role":"user","id":"fafefa37-7640-4c80-a00a-6a0c3ce46281"},"surfaceOp":"append"} -{"type":"session/title","seq":7,"time":1786173701272,"data":{"title":"Call ask_user_question once to ask","messageSeqs":[5],"source":{"kind":"fallback"}}} -{"type":"request/header","seq":8,"time":1786173701272,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}} -{"type":"request/context","seq":9,"time":1786173701273,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} -{"type":"assistant/chunk","seq":10,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}}} -{"type":"assistant/chunk","seq":11,"time":1786173701278,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":0,"id":"call_child_question","name":"ask_user_question","argumentsDelta":"{\"questions\":[{\"id\":\"cuda-fallback\",\"header\":\"Deployment\",\"question\":\"Should deployment use the CUDA fallback?\"}]}"}}} -{"type":"assistant/chunk","seq":12,"time":1786173701279,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"call_child_question","name":"ask_user_question","arguments":"{\"questions\":[{\"id\":\"cuda-fallback\",\"header\":\"Deployment\",\"question\":\"Should deployment use the CUDA fallback?\"}]}"}}}} -{"type":"assistant/chunk","seq":13,"time":1786173701279,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}}} -{"type":"assistant/chunk","seq":14,"time":1786173701279,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}} -{"type":"assistant/message","seq":15,"time":1786173701279,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"tool-call","id":"call_child_question","name":"ask_user_question","arguments":"{\"questions\":[{\"id\":\"cuda-fallback\",\"header\":\"Deployment\",\"question\":\"Should deployment use the CUDA fallback?\"}]}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"301e1969-74b2-45d8-a764-604b806f1c01"},"usage":{"inputTokens":10,"outputTokens":5}},"sourceEventSeqs":[10,11,12,13,14],"surfaceOp":"append"} -{"type":"tool/call","seq":16,"time":1786173701279,"data":{"turn":1,"step":1,"callId":"call_child_question","name":"ask_user_question","arguments":"{\"questions\":[{\"id\":\"cuda-fallback\",\"header\":\"Deployment\",\"question\":\"Should deployment use the CUDA fallback?\"}]}"}} -{"type":"tool/result","seq":17,"time":1786173701292,"data":{"turn":1,"step":1,"message":{"source":{"kind":"tool","callId":"call_child_question"},"content":[{"type":"tool-result","toolCallId":"call_child_question","content":[{"type":"text","text":"Error: human interaction is unavailable while the calling agent is owned by another live agent; include the unresolved question or decision in the child agent's final result"}],"isError":true}],"role":"user","id":"b9fc0a38-47bb-4335-a8e4-c881ed66bbc3"},"error":{"name":"UserInteractionError","code":"DELEGATED_CALLER"}},"sourceEventSeqs":[16],"surfaceOp":"append"} -{"type":"step/end","seq":18,"time":1786173701292,"data":{"turn":1,"step":1}} -{"type":"step/start","seq":19,"time":1786173701309,"data":{"turn":1,"step":2}} -{"type":"assistant/chunk","seq":20,"time":1786173701314,"data":{"turn":1,"step":2,"chunk":{"type":"block-start","index":0,"blockType":"text"}}} -{"type":"assistant/chunk","seq":21,"time":1786173701314,"data":{"turn":1,"step":2,"chunk":{"type":"text-delta","index":0,"text":"UNRESOLVED: Should deployment use the CUDA fallback?"}}} -{"type":"assistant/chunk","seq":22,"time":1786173701314,"data":{"turn":1,"step":2,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"UNRESOLVED: Should deployment use the CUDA fallback?"}}}} -{"type":"assistant/chunk","seq":23,"time":1786173701314,"data":{"turn":1,"step":2,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":4}}}} -{"type":"assistant/chunk","seq":24,"time":1786173701315,"data":{"turn":1,"step":2,"chunk":{"type":"finish","reason":{"kind":"stop"}}}} -{"type":"assistant/message","seq":25,"time":1786173701315,"data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"text","text":"UNRESOLVED: Should deployment use the CUDA fallback?"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"5f2ada85-5967-4ed8-9e16-eaff2af847b5"},"usage":{"inputTokens":10,"outputTokens":4}},"sourceEventSeqs":[20,21,22,23,24],"surfaceOp":"append"} -{"type":"step/end","seq":26,"time":1786173701315,"data":{"turn":1,"step":2}} -{"type":"turn/end","seq":27,"time":1786173701315,"data":{"turn":1,"reason":{"kind":"completed"}}} +{"type":"approval/policy","seq":0,"time":1786357535138,"data":{"policy":"never","source":"delegation"}} +{"type":"agent/inbox/spliced","seq":1,"time":1786357535138,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Call ask_user_question once to ask whether deployment should use the CUDA fallback. If the tool returns an error, include the unresolved question verbatim in your final result."}],"source":{"kind":"user"},"role":"user","id":"106c2785-219e-46e8-8386-497ac6a98f68"}]}} +{"type":"turn/start","seq":2,"time":1786357535138,"data":{"turn":1}} +{"type":"agent/inbox/spliced","seq":3,"time":1786357535138,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} +{"type":"subagent/descriptor","seq":4,"time":1786357535155,"data":{"version":2,"mode":"one-shot","provider":"spawn","label":"Check deployment question"}} +{"type":"step/start","seq":5,"time":1786357535158,"data":{"turn":1,"step":1}} +{"type":"user/message","seq":6,"time":1786173701272,"data":{"content":[{"type":"text","text":"Call ask_user_question once to ask whether deployment should use the CUDA fallback. If the tool returns an error, include the unresolved question verbatim in your final result."}],"source":{"kind":"user"},"role":"user","id":"106c2785-219e-46e8-8386-497ac6a98f68"},"surfaceOp":"append"} +{"type":"user/message","seq":7,"time":1786357535158,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`).\n\nYou are a delegated subagent: your permission scope was fixed when you were started and cannot be widened from inside this session — operations that require approval are rejected automatically. When the task needs access beyond that scope, do not retry the denied operation; state the limitation in your reply so the delegating agent can handle it."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."},{"name":"subagent:delegation","text":"You are a delegated subagent: your permission scope was fixed when you were started and cannot be widened from inside this session — operations that require approval are rejected automatically. When the task needs access beyond that scope, do not retry the denied operation; state the limitation in your reply so the delegating agent can handle it."}]},"role":"user","id":"d8734c8a-d956-4e3f-8d28-399adf51a203"},"surfaceOp":"append"} +{"type":"session/title","seq":8,"time":1786357535158,"data":{"title":"Call ask_user_question once to ask","messageSeqs":[6],"source":{"kind":"fallback"}}} +{"type":"request/header","seq":9,"time":1786173701272,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}} +{"type":"request/context","seq":10,"time":1786173701273,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} +{"type":"assistant/chunk","seq":11,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}}} +{"type":"assistant/chunk","seq":12,"time":1786173701278,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":0,"id":"call_child_question","name":"ask_user_question","argumentsDelta":"{\"questions\":[{\"id\":\"cuda-fallback\",\"header\":\"Deployment\",\"question\":\"Should deployment use the CUDA fallback?\"}]}"}}} +{"type":"assistant/chunk","seq":13,"time":1786173701279,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"call_child_question","name":"ask_user_question","arguments":"{\"questions\":[{\"id\":\"cuda-fallback\",\"header\":\"Deployment\",\"question\":\"Should deployment use the CUDA fallback?\"}]}"}}}} +{"type":"assistant/chunk","seq":14,"time":1786173701279,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}}} +{"type":"assistant/chunk","seq":15,"time":1786173701279,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}} +{"type":"assistant/message","seq":16,"time":1786173701279,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"tool-call","id":"call_child_question","name":"ask_user_question","arguments":"{\"questions\":[{\"id\":\"cuda-fallback\",\"header\":\"Deployment\",\"question\":\"Should deployment use the CUDA fallback?\"}]}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"301e1969-74b2-45d8-a764-604b806f1c01"},"usage":{"inputTokens":10,"outputTokens":5}},"sourceEventSeqs":[11,12,13,14,15],"surfaceOp":"append"} +{"type":"tool/call","seq":17,"time":1786173701279,"data":{"turn":1,"step":1,"callId":"call_child_question","name":"ask_user_question","arguments":"{\"questions\":[{\"id\":\"cuda-fallback\",\"header\":\"Deployment\",\"question\":\"Should deployment use the CUDA fallback?\"}]}"}} +{"type":"tool/result","seq":18,"time":1786173701292,"data":{"turn":1,"step":1,"message":{"source":{"kind":"tool","callId":"call_child_question"},"content":[{"type":"tool-result","toolCallId":"call_child_question","content":[{"type":"text","text":"Error: human interaction is unavailable while the calling agent is owned by another live agent; include the unresolved question or decision in the child agent's final result"}],"isError":true}],"role":"user","id":"b9fc0a38-47bb-4335-a8e4-c881ed66bbc3"},"error":{"name":"UserInteractionError","code":"DELEGATED_CALLER"}},"sourceEventSeqs":[17],"surfaceOp":"append"} +{"type":"step/end","seq":19,"time":1786173701292,"data":{"turn":1,"step":1}} +{"type":"step/start","seq":20,"time":1786173701309,"data":{"turn":1,"step":2}} +{"type":"assistant/chunk","seq":21,"time":1786173701314,"data":{"turn":1,"step":2,"chunk":{"type":"block-start","index":0,"blockType":"text"}}} +{"type":"assistant/chunk","seq":22,"time":1786173701314,"data":{"turn":1,"step":2,"chunk":{"type":"text-delta","index":0,"text":"UNRESOLVED: Should deployment use the CUDA fallback?"}}} +{"type":"assistant/chunk","seq":23,"time":1786173701314,"data":{"turn":1,"step":2,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"UNRESOLVED: Should deployment use the CUDA fallback?"}}}} +{"type":"assistant/chunk","seq":24,"time":1786173701314,"data":{"turn":1,"step":2,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":4}}}} +{"type":"assistant/chunk","seq":25,"time":1786173701315,"data":{"turn":1,"step":2,"chunk":{"type":"finish","reason":{"kind":"stop"}}}} +{"type":"assistant/message","seq":26,"time":1786173701315,"data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"text","text":"UNRESOLVED: Should deployment use the CUDA fallback?"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"5f2ada85-5967-4ed8-9e16-eaff2af847b5"},"usage":{"inputTokens":10,"outputTokens":4}},"sourceEventSeqs":[21,22,23,24,25],"surfaceOp":"append"} +{"type":"step/end","seq":27,"time":1786173701315,"data":{"turn":1,"step":2}} +{"type":"turn/end","seq":28,"time":1786173701315,"data":{"turn":1,"reason":{"kind":"completed"}}} diff --git a/examples/acp-agent/tests/snapshots/subagent-child-question-rejection/session.jsonl b/examples/acp-agent/tests/snapshots/subagent-child-question-rejection/session.jsonl index ed155f158f..92efdfa71a 100644 --- a/examples/acp-agent/tests/snapshots/subagent-child-question-rejection/session.jsonl +++ b/examples/acp-agent/tests/snapshots/subagent-child-question-rejection/session.jsonl @@ -4,7 +4,7 @@ {"type":"agent/inbox/spliced","seq":2,"time":1786173701175,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} {"type":"step/start","seq":3,"time":1786173701216,"data":{"turn":1,"step":1}} {"type":"user/message","seq":4,"time":1786173701216,"data":{"content":[{"type":"text","text":"Delegate one question check. Ask the child to call ask_user_question once about the CUDA fallback and return any unresolved question in its final result."}],"source":{"kind":"user"},"role":"user","id":"851bea02-2961-471a-84ec-3b068c451db0"},"surfaceOp":"append"} -{"type":"user/message","seq":5,"time":1786173701217,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}]},"role":"user","id":"8ef74c46-9e80-475c-9093-0e85ba92e346"},"surfaceOp":"append"} +{"type":"user/message","seq":5,"time":1786173701217,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}]},"role":"user","id":"e1f92805-80c9-46b7-94ac-6cdb05d23f86"},"surfaceOp":"append"} {"type":"session/title","seq":6,"time":1786173701217,"data":{"title":"Delegate one question check. Ask","messageSeqs":[4],"source":{"kind":"fallback"}}} {"type":"request/header","seq":7,"time":1786173701218,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}} {"type":"request/context","seq":8,"time":1786173701219,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} diff --git a/examples/acp-agent/tests/snapshots/subagent-continuable-inheritance/session.1.jsonl b/examples/acp-agent/tests/snapshots/subagent-continuable-inheritance/session.1.jsonl index 478198cf0c..bd9557666f 100644 --- a/examples/acp-agent/tests/snapshots/subagent-continuable-inheritance/session.1.jsonl +++ b/examples/acp-agent/tests/snapshots/subagent-continuable-inheritance/session.1.jsonl @@ -2,20 +2,21 @@ {"type":"subagent/descriptor","seq":0,"time":1786333735890,"data":{"version":2,"mode":"continuable","provider":"spawn","label":"Reply with CHILD_OK","agentProvider":"deepseek-official","agentModel":"deepseek-v4-flash"}} {"type":"session/end-seed","seq":1,"time":1786333735890,"data":{}} {"type":"sandbox/mode","seq":2,"time":1786333735890,"data":{"mode":"read-only","source":"delegation"}} -{"type":"agent/inbox/spliced","seq":3,"time":1786333735891,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Reply with exactly the word CHILD_OK and nothing else."}],"source":{"kind":"user"},"role":"user","id":"42af19c7-e234-4752-93d4-bd9c943c1fe7"}]}} -{"type":"turn/start","seq":4,"time":1786333735891,"data":{"turn":1}} -{"type":"agent/inbox/spliced","seq":5,"time":1786333735891,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} -{"type":"step/start","seq":6,"time":1786333735916,"data":{"turn":1,"step":1}} -{"type":"user/message","seq":7,"time":1786333735916,"data":{"content":[{"type":"text","text":"Reply with exactly the word CHILD_OK and nothing else."}],"source":{"kind":"user"},"role":"user","id":"42af19c7-e234-4752-93d4-bd9c943c1fe7"},"surfaceOp":"append"} -{"type":"user/message","seq":8,"time":1786333735916,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: read-only. Any available operation enforced by the DSH file sandbox cannot modify files in the standing mode. Do not refuse a required modification from this policy alone: try an available tool normally and follow any denial and escalation guidance it returns.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: read-only. Any available operation enforced by the DSH file sandbox cannot modify files in the standing mode. Do not refuse a required modification from this policy alone: try an available tool normally and follow any denial and escalation guidance it returns."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}]},"role":"user","id":"5f181e93-3fd7-40f3-b5f7-21674b53d7c7"},"surfaceOp":"append"} -{"type":"session/title","seq":9,"time":1786333735916,"data":{"title":"Reply with exactly the word","messageSeqs":[7],"source":{"kind":"fallback"}}} -{"type":"request/header","seq":10,"time":1786333735916,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}} -{"type":"request/context","seq":11,"time":1786333735916,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} -{"type":"assistant/chunk","seq":12,"time":1786333735920,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"text"}}} -{"type":"assistant/chunk","seq":13,"time":1786333735921,"data":{"turn":1,"step":1,"chunk":{"type":"text-delta","index":0,"text":"CHILD_OK"}}} -{"type":"assistant/chunk","seq":14,"time":1786333735921,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"CHILD_OK"}}}} -{"type":"assistant/chunk","seq":15,"time":1786333735921,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}}} -{"type":"assistant/chunk","seq":16,"time":1786333735921,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"stop"}}}} -{"type":"assistant/message","seq":17,"time":1786333735921,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"text","text":"CHILD_OK"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"e2b94008-b067-4ca7-a576-6b4a9060cd83"},"usage":{"inputTokens":10,"outputTokens":5}},"sourceEventSeqs":[12,13,14,15,16],"surfaceOp":"append"} -{"type":"step/end","seq":18,"time":1786333735921,"data":{"turn":1,"step":1}} -{"type":"turn/end","seq":19,"time":1786333735921,"data":{"turn":1,"reason":{"kind":"completed"}}} +{"type":"approval/policy","seq":3,"time":1786357527742,"data":{"policy":"never","source":"delegation"}} +{"type":"agent/inbox/spliced","seq":4,"time":1786357527743,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Reply with exactly the word CHILD_OK and nothing else."}],"source":{"kind":"user"},"role":"user","id":"42af19c7-e234-4752-93d4-bd9c943c1fe7"}]}} +{"type":"turn/start","seq":5,"time":1786357527743,"data":{"turn":1}} +{"type":"agent/inbox/spliced","seq":6,"time":1786357527743,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} +{"type":"step/start","seq":7,"time":1786357527768,"data":{"turn":1,"step":1}} +{"type":"user/message","seq":8,"time":1786333735916,"data":{"content":[{"type":"text","text":"Reply with exactly the word CHILD_OK and nothing else."}],"source":{"kind":"user"},"role":"user","id":"42af19c7-e234-4752-93d4-bd9c943c1fe7"},"surfaceOp":"append"} +{"type":"user/message","seq":9,"time":1786357527769,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: read-only. Any available operation enforced by the DSH file sandbox cannot modify files in the standing mode. Do not refuse a required modification from this policy alone: try an available tool normally and follow any denial and escalation guidance it returns.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`).\n\nYou are a delegated subagent: your permission scope was fixed when you were started and cannot be widened from inside this session — operations that require approval are rejected automatically. When the task needs access beyond that scope, do not retry the denied operation; state the limitation in your reply so the delegating agent can handle it."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: read-only. Any available operation enforced by the DSH file sandbox cannot modify files in the standing mode. Do not refuse a required modification from this policy alone: try an available tool normally and follow any denial and escalation guidance it returns."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."},{"name":"subagent:delegation","text":"You are a delegated subagent: your permission scope was fixed when you were started and cannot be widened from inside this session — operations that require approval are rejected automatically. When the task needs access beyond that scope, do not retry the denied operation; state the limitation in your reply so the delegating agent can handle it."}]},"role":"user","id":"1b760052-ffcb-44d2-aae2-fd73d7c444f1"},"surfaceOp":"append"} +{"type":"session/title","seq":10,"time":1786357527769,"data":{"title":"Reply with exactly the word","messageSeqs":[8],"source":{"kind":"fallback"}}} +{"type":"request/header","seq":11,"time":1786333735916,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}} +{"type":"request/context","seq":12,"time":1786333735916,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} +{"type":"assistant/chunk","seq":13,"time":1786333735920,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"text"}}} +{"type":"assistant/chunk","seq":14,"time":1786333735921,"data":{"turn":1,"step":1,"chunk":{"type":"text-delta","index":0,"text":"CHILD_OK"}}} +{"type":"assistant/chunk","seq":15,"time":1786333735921,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"CHILD_OK"}}}} +{"type":"assistant/chunk","seq":16,"time":1786333735921,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}}} +{"type":"assistant/chunk","seq":17,"time":1786333735921,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"stop"}}}} +{"type":"assistant/message","seq":18,"time":1786333735921,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"text","text":"CHILD_OK"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"e2b94008-b067-4ca7-a576-6b4a9060cd83"},"usage":{"inputTokens":10,"outputTokens":5}},"sourceEventSeqs":[13,14,15,16,17],"surfaceOp":"append"} +{"type":"step/end","seq":19,"time":1786333735921,"data":{"turn":1,"step":1}} +{"type":"turn/end","seq":20,"time":1786333735921,"data":{"turn":1,"reason":{"kind":"completed"}}} diff --git a/examples/acp-agent/tests/snapshots/subagent-continuable-inheritance/session.jsonl b/examples/acp-agent/tests/snapshots/subagent-continuable-inheritance/session.jsonl index 0968357f90..15b1748ea5 100644 --- a/examples/acp-agent/tests/snapshots/subagent-continuable-inheritance/session.jsonl +++ b/examples/acp-agent/tests/snapshots/subagent-continuable-inheritance/session.jsonl @@ -5,7 +5,7 @@ {"type":"agent/inbox/spliced","seq":3,"time":1786333735845,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} {"type":"step/start","seq":4,"time":1786333735878,"data":{"turn":1,"step":1}} {"type":"user/message","seq":5,"time":1786333735878,"data":{"content":[{"type":"text","text":"Follow these steps exactly, then stop. 1. Call the subagent tool once with run_in_background set to true, description 'Reply with CHILD_OK', and prompt 'Reply with exactly the word CHILD_OK and nothing else.'. 2. Reply with the single word DONE. Do not use the bash tool."}],"source":{"kind":"user"},"role":"user","id":"d554122c-d857-4de0-aea0-6452f260d032"},"surfaceOp":"append"} -{"type":"user/message","seq":6,"time":1786333735878,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: read-only. Any available operation enforced by the DSH file sandbox cannot modify files in the standing mode. Do not refuse a required modification from this policy alone: try an available tool normally and follow any denial and escalation guidance it returns.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: read-only. Any available operation enforced by the DSH file sandbox cannot modify files in the standing mode. Do not refuse a required modification from this policy alone: try an available tool normally and follow any denial and escalation guidance it returns."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}]},"role":"user","id":"9a793bfc-c155-44f8-ba56-c6843338d6be"},"surfaceOp":"append"} +{"type":"user/message","seq":6,"time":1786333735878,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: read-only. Any available operation enforced by the DSH file sandbox cannot modify files in the standing mode. Do not refuse a required modification from this policy alone: try an available tool normally and follow any denial and escalation guidance it returns.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: read-only. Any available operation enforced by the DSH file sandbox cannot modify files in the standing mode. Do not refuse a required modification from this policy alone: try an available tool normally and follow any denial and escalation guidance it returns."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}]},"role":"user","id":"f931abf5-bb3a-44b4-8fe2-2d06e8766184"},"surfaceOp":"append"} {"type":"session/title","seq":7,"time":1786333735878,"data":{"title":"Follow these steps exactly, then","messageSeqs":[5],"source":{"kind":"fallback"}}} {"type":"request/header","seq":8,"time":1786333735879,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}} {"type":"request/context","seq":9,"time":1786333735879,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} diff --git a/examples/acp-agent/tests/snapshots/subagent-continuable/session.1.jsonl b/examples/acp-agent/tests/snapshots/subagent-continuable/session.1.jsonl index 554de6f448..9352ca6fb9 100644 --- a/examples/acp-agent/tests/snapshots/subagent-continuable/session.1.jsonl +++ b/examples/acp-agent/tests/snapshots/subagent-continuable/session.1.jsonl @@ -1,37 +1,38 @@ {"type":"session","version":0,"id":"33333333-3333-4333-8333-333333333333","createdAt":1789000001000,"cwd":"{{cwd}}","parentSession":"11111111-1111-4111-8111-111111111111","origin":"subagent","delegationDepth":1} {"type":"subagent/descriptor","seq":0,"time":1785544945198,"data":{"version":2,"mode":"continuable","provider":"spawn","label":"Reply with CHILD_OK","agentProvider":"deepseek-official","agentModel":"deepseek-v4-flash"}} {"type":"session/end-seed","seq":1,"time":1785544945198,"data":{}} -{"type":"agent/inbox/spliced","seq":2,"time":1785730451347,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Reply with exactly the word CHILD_OK and nothing else."}],"source":{"kind":"user"},"role":"user","id":"c67a308f-d867-424e-b198-c9f464228703"}]}} -{"type":"turn/start","seq":3,"time":1785821409024,"data":{"turn":1}} -{"type":"agent/inbox/spliced","seq":4,"time":1785730917162,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} -{"type":"agent/inbox/spliced","seq":5,"time":1785730917192,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Now reply with exactly SECOND_OK."}],"source":{"kind":"coordinator","form":"relay","senderSessionId":"11111111-1111-4111-8111-111111111111"},"role":"user","id":"e7d15a94-203d-43ab-8279-4e22d5218feb"}]}} -{"type":"agent/inbox/spliced","seq":6,"time":1785821409076,"data":{"target":"next-turn","start":1,"inserted":[{"content":[{"type":"text","text":"Now reply with exactly THIRD_OK."}],"source":{"kind":"coordinator","form":"relay","senderSessionId":"11111111-1111-4111-8111-111111111111"},"role":"user","id":"755c76db-6ee8-432d-a2d0-f8a3b7914e08"}]}} -{"type":"step/start","seq":7,"time":1785730917198,"data":{"turn":1,"step":1}} -{"type":"user/message","seq":8,"time":1785730917198,"data":{"content":[{"type":"text","text":"Reply with exactly the word CHILD_OK and nothing else."}],"source":{"kind":"user"},"role":"user","id":"c67a308f-d867-424e-b198-c9f464228703"},"surfaceOp":"append"} -{"type":"user/message","seq":9,"time":1785730917198,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}]},"role":"user","id":"49acbc16-4d58-460e-8cc0-62838472dce6"},"surfaceOp":"append"} -{"type":"session/title","seq":10,"time":1785730917198,"data":{"title":"Reply with exactly the word","messageSeqs":[8],"source":{"kind":"fallback"}}} -{"type":"request/header","seq":11,"time":1785730917198,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}} -{"type":"request/context","seq":12,"time":1785730917199,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} -{"type":"assistant/chunk","seq":13,"time":1785730696668,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"text"}}} -{"type":"assistant/chunk","seq":14,"time":1789000000010,"data":{"turn":1,"step":1,"chunk":{"type":"text-delta","index":0,"text":"CHILD_OK"}}} -{"type":"assistant/chunk","seq":15,"time":1789000000011,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"CHILD_OK"}}}} -{"type":"assistant/chunk","seq":16,"time":1789000000012,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}}} -{"type":"assistant/chunk","seq":17,"time":1785730451397,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"stop"}}}} -{"type":"assistant/message","seq":18,"time":1785730696668,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"text","text":"CHILD_OK"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"178ea526-9e19-49d2-b3b0-57b682320028"},"usage":{"inputTokens":10,"outputTokens":5}},"sourceEventSeqs":[13,14,15,16,17],"surfaceOp":"append"} -{"type":"step/end","seq":19,"time":1785730696668,"data":{"turn":1,"step":1}} -{"type":"turn/end","seq":20,"time":1785730696669,"data":{"turn":1,"reason":{"kind":"completed"}}} -{"type":"turn/start","seq":21,"time":1785821409092,"data":{"turn":2}} -{"type":"agent/inbox/spliced","seq":22,"time":1785821409092,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} -{"type":"step/start","seq":23,"time":1785730696682,"data":{"turn":2,"step":1}} -{"type":"user/message","seq":24,"time":1785730696682,"data":{"content":[{"type":"text","text":"Now reply with exactly SECOND_OK."}],"source":{"kind":"coordinator","form":"relay","senderSessionId":"11111111-1111-4111-8111-111111111111"},"role":"user","id":"e7d15a94-203d-43ab-8279-4e22d5218feb"},"surfaceOp":"append"} -{"type":"assistant/chunk","seq":25,"time":1785730696686,"data":{"turn":2,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"text"}}} -{"type":"assistant/chunk","seq":26,"time":1785730696686,"data":{"turn":2,"step":1,"chunk":{"type":"text-delta","index":0,"text":"SECOND_OK"}}} -{"type":"assistant/chunk","seq":27,"time":1789000000023,"data":{"turn":2,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"SECOND_OK"}}}} -{"type":"assistant/chunk","seq":28,"time":1785730451421,"data":{"turn":2,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}}} -{"type":"assistant/chunk","seq":29,"time":1785730451421,"data":{"turn":2,"step":1,"chunk":{"type":"finish","reason":{"kind":"stop"}}}} -{"type":"assistant/message","seq":30,"time":1785730696686,"data":{"turn":2,"step":1,"message":{"role":"assistant","content":[{"type":"text","text":"SECOND_OK"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"ced209bf-5d6d-4880-b187-18cb816a150c"},"usage":{"inputTokens":10,"outputTokens":5}},"sourceEventSeqs":[25,26,27,28,29],"surfaceOp":"append"} -{"type":"step/end","seq":31,"time":1785730696686,"data":{"turn":2,"step":1}} -{"type":"turn/end","seq":32,"time":1785730696686,"data":{"turn":2,"reason":{"kind":"completed"}}} -{"type":"turn/start","seq":33,"time":1785821409110,"data":{"turn":3}} -{"type":"agent/inbox/spliced","seq":34,"time":1785821409110,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} -{"type":"turn/end","seq":35,"time":1785821409122,"data":{"turn":3,"reason":{"kind":"error","error":{"message":"snapshot disk full","code":"UNKNOWN"}}}} +{"type":"approval/policy","seq":2,"time":1786357526242,"data":{"policy":"never","source":"delegation"}} +{"type":"agent/inbox/spliced","seq":3,"time":1786357526243,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Reply with exactly the word CHILD_OK and nothing else."}],"source":{"kind":"user"},"role":"user","id":"c67a308f-d867-424e-b198-c9f464228703"}]}} +{"type":"turn/start","seq":4,"time":1786357526243,"data":{"turn":1}} +{"type":"agent/inbox/spliced","seq":5,"time":1785730917192,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} +{"type":"agent/inbox/spliced","seq":6,"time":1785821409076,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Now reply with exactly SECOND_OK."}],"source":{"kind":"coordinator","form":"relay","senderSessionId":"11111111-1111-4111-8111-111111111111"},"role":"user","id":"e7d15a94-203d-43ab-8279-4e22d5218feb"}]}} +{"type":"agent/inbox/spliced","seq":7,"time":1786357526278,"data":{"target":"next-turn","start":1,"inserted":[{"content":[{"type":"text","text":"Now reply with exactly THIRD_OK."}],"source":{"kind":"coordinator","form":"relay","senderSessionId":"11111111-1111-4111-8111-111111111111"},"role":"user","id":"755c76db-6ee8-432d-a2d0-f8a3b7914e08"}]}} +{"type":"step/start","seq":8,"time":1786357526284,"data":{"turn":1,"step":1}} +{"type":"user/message","seq":9,"time":1785730917198,"data":{"content":[{"type":"text","text":"Reply with exactly the word CHILD_OK and nothing else."}],"source":{"kind":"user"},"role":"user","id":"c67a308f-d867-424e-b198-c9f464228703"},"surfaceOp":"append"} +{"type":"user/message","seq":10,"time":1786357526284,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`).\n\nYou are a delegated subagent: your permission scope was fixed when you were started and cannot be widened from inside this session — operations that require approval are rejected automatically. When the task needs access beyond that scope, do not retry the denied operation; state the limitation in your reply so the delegating agent can handle it."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."},{"name":"subagent:delegation","text":"You are a delegated subagent: your permission scope was fixed when you were started and cannot be widened from inside this session — operations that require approval are rejected automatically. When the task needs access beyond that scope, do not retry the denied operation; state the limitation in your reply so the delegating agent can handle it."}]},"role":"user","id":"7f1d7407-d9bc-4ec6-ae42-a8767e0e1153"},"surfaceOp":"append"} +{"type":"session/title","seq":11,"time":1786357526284,"data":{"title":"Reply with exactly the word","messageSeqs":[9],"source":{"kind":"fallback"}}} +{"type":"request/header","seq":12,"time":1785730917198,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}} +{"type":"request/context","seq":13,"time":1785730917199,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} +{"type":"assistant/chunk","seq":14,"time":1785730696668,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"text"}}} +{"type":"assistant/chunk","seq":15,"time":1789000000010,"data":{"turn":1,"step":1,"chunk":{"type":"text-delta","index":0,"text":"CHILD_OK"}}} +{"type":"assistant/chunk","seq":16,"time":1789000000011,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"CHILD_OK"}}}} +{"type":"assistant/chunk","seq":17,"time":1789000000012,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}}} +{"type":"assistant/chunk","seq":18,"time":1785730451397,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"stop"}}}} +{"type":"assistant/message","seq":19,"time":1785730696668,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"text","text":"CHILD_OK"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"178ea526-9e19-49d2-b3b0-57b682320028"},"usage":{"inputTokens":10,"outputTokens":5}},"sourceEventSeqs":[14,15,16,17,18],"surfaceOp":"append"} +{"type":"step/end","seq":20,"time":1785730696668,"data":{"turn":1,"step":1}} +{"type":"turn/end","seq":21,"time":1785730696669,"data":{"turn":1,"reason":{"kind":"completed"}}} +{"type":"turn/start","seq":22,"time":1785821409092,"data":{"turn":2}} +{"type":"agent/inbox/spliced","seq":23,"time":1785821409092,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} +{"type":"step/start","seq":24,"time":1785730696682,"data":{"turn":2,"step":1}} +{"type":"user/message","seq":25,"time":1785730696682,"data":{"content":[{"type":"text","text":"Now reply with exactly SECOND_OK."}],"source":{"kind":"coordinator","form":"relay","senderSessionId":"11111111-1111-4111-8111-111111111111"},"role":"user","id":"e7d15a94-203d-43ab-8279-4e22d5218feb"},"surfaceOp":"append"} +{"type":"assistant/chunk","seq":26,"time":1785730696686,"data":{"turn":2,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"text"}}} +{"type":"assistant/chunk","seq":27,"time":1785730696686,"data":{"turn":2,"step":1,"chunk":{"type":"text-delta","index":0,"text":"SECOND_OK"}}} +{"type":"assistant/chunk","seq":28,"time":1789000000023,"data":{"turn":2,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"SECOND_OK"}}}} +{"type":"assistant/chunk","seq":29,"time":1785730451421,"data":{"turn":2,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}}} +{"type":"assistant/chunk","seq":30,"time":1785730451421,"data":{"turn":2,"step":1,"chunk":{"type":"finish","reason":{"kind":"stop"}}}} +{"type":"assistant/message","seq":31,"time":1785730696686,"data":{"turn":2,"step":1,"message":{"role":"assistant","content":[{"type":"text","text":"SECOND_OK"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"ced209bf-5d6d-4880-b187-18cb816a150c"},"usage":{"inputTokens":10,"outputTokens":5}},"sourceEventSeqs":[26,27,28,29,30],"surfaceOp":"append"} +{"type":"step/end","seq":32,"time":1785730696686,"data":{"turn":2,"step":1}} +{"type":"turn/end","seq":33,"time":1785730696686,"data":{"turn":2,"reason":{"kind":"completed"}}} +{"type":"turn/start","seq":34,"time":1785821409110,"data":{"turn":3}} +{"type":"agent/inbox/spliced","seq":35,"time":1785821409110,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} +{"type":"turn/end","seq":36,"time":1785821409122,"data":{"turn":3,"reason":{"kind":"error","error":{"message":"snapshot disk full","code":"UNKNOWN"}}}} diff --git a/examples/acp-agent/tests/snapshots/subagent-continuable/session.jsonl b/examples/acp-agent/tests/snapshots/subagent-continuable/session.jsonl index 898d4b250c..a759c35a32 100644 --- a/examples/acp-agent/tests/snapshots/subagent-continuable/session.jsonl +++ b/examples/acp-agent/tests/snapshots/subagent-continuable/session.jsonl @@ -4,7 +4,7 @@ {"type":"agent/inbox/spliced","seq":2,"time":1785821408972,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} {"type":"step/start","seq":3,"time":1785730451327,"data":{"turn":1,"step":1}} {"type":"user/message","seq":4,"time":1785730451327,"data":{"content":[{"type":"text","text":"Follow these steps exactly, then stop. 1. Call the subagent tool once with run_in_background set to true, description 'Reply with CHILD_OK', and prompt 'Reply with exactly the word CHILD_OK and nothing else.'. 2. Call send_message twice in a row, both with the subagent id from step 1: first with message 'Now reply with exactly SECOND_OK.', then with message 'Now reply with exactly THIRD_OK.'. 3. Call send_message with subagent_id exactly '22222222-2222-4222-8222-222222222222' (a subagent that does not exist) and message 'Please continue.', and observe that it fails. 4. Reply with the single word DONE. Do not use the bash tool."}],"source":{"kind":"user"},"role":"user","id":"125665d3-8c03-4190-b4f9-c27d61d245f4"},"surfaceOp":"append"} -{"type":"user/message","seq":5,"time":1785730451328,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}]},"role":"user","id":"e7521889-28d8-4434-84b2-21ff0e044fe7"},"surfaceOp":"append"} +{"type":"user/message","seq":5,"time":1785730451328,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}]},"role":"user","id":"533e9513-a329-4a36-9a8d-ddaf544b57c3"},"surfaceOp":"append"} {"type":"session/title","seq":6,"time":1785730451328,"data":{"title":"Follow these steps exactly, then","messageSeqs":[4],"source":{"kind":"fallback"}}} {"type":"request/header","seq":7,"time":1785730451329,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}} {"type":"request/context","seq":8,"time":1785730451329,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} diff --git a/examples/acp-agent/tests/snapshots/subagent-depth-two-rejection/session.1.jsonl b/examples/acp-agent/tests/snapshots/subagent-depth-two-rejection/session.1.jsonl index 8b8b8cc0c2..44d587c851 100644 --- a/examples/acp-agent/tests/snapshots/subagent-depth-two-rejection/session.1.jsonl +++ b/examples/acp-agent/tests/snapshots/subagent-depth-two-rejection/session.1.jsonl @@ -1,29 +1,30 @@ {"type":"session","version":0,"id":"22222222-2222-4222-8222-222222222222","createdAt":1001,"cwd":"{{cwd}}","parentSession":"11111111-1111-4111-8111-111111111111","origin":"subagent","delegationDepth":1} -{"type":"agent/inbox/spliced","seq":0,"time":1785498798860,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Call subagent once. Ask that child to attempt one further subagent call, then report the result."}],"source":{"kind":"user"},"role":"user","id":"a8129357-1bde-4cbd-90b4-6b8ad51d52e1"}]}} -{"type":"turn/start","seq":1,"time":1785821414174,"data":{"turn":1}} -{"type":"agent/inbox/spliced","seq":2,"time":1785821414174,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} -{"type":"subagent/descriptor","seq":3,"time":1785821414185,"data":{"version":2,"mode":"one-shot","provider":"spawn","label":"Start depth one"}} -{"type":"step/start","seq":4,"time":1785730456013,"data":{"turn":1,"step":1}} -{"type":"user/message","seq":5,"time":1785730456014,"data":{"content":[{"type":"text","text":"Call subagent once. Ask that child to attempt one further subagent call, then report the result."}],"source":{"kind":"user"},"role":"user","id":"a8129357-1bde-4cbd-90b4-6b8ad51d52e1"},"surfaceOp":"append"} -{"type":"user/message","seq":6,"time":1785730456014,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}]},"role":"user","id":"3244b13c-f211-445f-acf5-fb8d1534537c"},"surfaceOp":"append"} -{"type":"session/title","seq":7,"time":1785730456014,"data":{"title":"Call subagent once. Ask that","messageSeqs":[5],"source":{"kind":"fallback"}}} -{"type":"request/header","seq":8,"time":1785730456014,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}} -{"type":"request/context","seq":9,"time":1785730456014,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} -{"type":"assistant/chunk","seq":10,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}}} -{"type":"assistant/chunk","seq":11,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":0,"id":"call_depth_one_child","name":"subagent","argumentsDelta":"{\"description\":\"Start depth two\",\"prompt\":\"Attempt one subagent call beyond the configured cap, then report the rejection.\"}"}}} -{"type":"assistant/chunk","seq":12,"time":1785498798883,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"call_depth_one_child","name":"subagent","arguments":"{\"description\":\"Start depth two\",\"prompt\":\"Attempt one subagent call beyond the configured cap, then report the rejection.\"}"}}}} -{"type":"assistant/chunk","seq":13,"time":1785730456018,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}}} -{"type":"assistant/chunk","seq":14,"time":1785730456018,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}} -{"type":"assistant/message","seq":15,"time":1785730456018,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"tool-call","id":"call_depth_one_child","name":"subagent","arguments":"{\"description\":\"Start depth two\",\"prompt\":\"Attempt one subagent call beyond the configured cap, then report the rejection.\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"21044d12-2e0e-40e3-b47e-4920e21c3e83"},"usage":{"inputTokens":10,"outputTokens":5}},"sourceEventSeqs":[10,11,12,13,14],"surfaceOp":"append"} -{"type":"tool/call","seq":16,"time":1785730456019,"data":{"turn":1,"step":1,"callId":"call_depth_one_child","name":"subagent","arguments":"{\"description\":\"Start depth two\",\"prompt\":\"Attempt one subagent call beyond the configured cap, then report the rejection.\"}"}} -{"type":"tool/result","seq":17,"time":1785730456072,"data":{"turn":1,"step":1,"message":{"source":{"kind":"tool","callId":"call_depth_one_child"},"content":[{"type":"tool-result","toolCallId":"call_depth_one_child","content":[{"type":"text","text":"DEPTH_REJECTED"}],"isError":false}],"role":"user","id":"aa5451a8-812b-4a51-a52c-dbc5c84f16d0"}},"sourceEventSeqs":[16],"surfaceOp":"append"} -{"type":"step/end","seq":18,"time":1785730456072,"data":{"turn":1,"step":1}} -{"type":"step/start","seq":19,"time":1785730456082,"data":{"turn":1,"step":2}} -{"type":"assistant/chunk","seq":20,"time":1784540790365,"data":{"turn":1,"step":2,"chunk":{"type":"block-start","index":0,"blockType":"text"}}} -{"type":"assistant/chunk","seq":21,"time":1784540790365,"data":{"turn":1,"step":2,"chunk":{"type":"text-delta","index":0,"text":"DEPTH_ONE_DONE"}}} -{"type":"assistant/chunk","seq":22,"time":1785498798949,"data":{"turn":1,"step":2,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"DEPTH_ONE_DONE"}}}} -{"type":"assistant/chunk","seq":23,"time":1785730456086,"data":{"turn":1,"step":2,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":2}}}} -{"type":"assistant/chunk","seq":24,"time":1785730456086,"data":{"turn":1,"step":2,"chunk":{"type":"finish","reason":{"kind":"stop"}}}} -{"type":"assistant/message","seq":25,"time":1785730456086,"data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"text","text":"DEPTH_ONE_DONE"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"5a1911c6-f487-458c-b802-4a66221ec046"},"usage":{"inputTokens":10,"outputTokens":2}},"sourceEventSeqs":[20,21,22,23,24],"surfaceOp":"append"} -{"type":"step/end","seq":26,"time":1785730456086,"data":{"turn":1,"step":2}} -{"type":"turn/end","seq":27,"time":1785730456086,"data":{"turn":1,"reason":{"kind":"completed"}}} +{"type":"approval/policy","seq":0,"time":1786357533581,"data":{"policy":"never","source":"delegation"}} +{"type":"agent/inbox/spliced","seq":1,"time":1786357533582,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Call subagent once. Ask that child to attempt one further subagent call, then report the result."}],"source":{"kind":"user"},"role":"user","id":"a8129357-1bde-4cbd-90b4-6b8ad51d52e1"}]}} +{"type":"turn/start","seq":2,"time":1786357533582,"data":{"turn":1}} +{"type":"agent/inbox/spliced","seq":3,"time":1786357533582,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} +{"type":"subagent/descriptor","seq":4,"time":1786357533600,"data":{"version":2,"mode":"one-shot","provider":"spawn","label":"Start depth one"}} +{"type":"step/start","seq":5,"time":1786357533602,"data":{"turn":1,"step":1}} +{"type":"user/message","seq":6,"time":1785730456014,"data":{"content":[{"type":"text","text":"Call subagent once. Ask that child to attempt one further subagent call, then report the result."}],"source":{"kind":"user"},"role":"user","id":"a8129357-1bde-4cbd-90b4-6b8ad51d52e1"},"surfaceOp":"append"} +{"type":"user/message","seq":7,"time":1786357533602,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`).\n\nYou are a delegated subagent: your permission scope was fixed when you were started and cannot be widened from inside this session — operations that require approval are rejected automatically. When the task needs access beyond that scope, do not retry the denied operation; state the limitation in your reply so the delegating agent can handle it."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."},{"name":"subagent:delegation","text":"You are a delegated subagent: your permission scope was fixed when you were started and cannot be widened from inside this session — operations that require approval are rejected automatically. When the task needs access beyond that scope, do not retry the denied operation; state the limitation in your reply so the delegating agent can handle it."}]},"role":"user","id":"82a11d62-da49-4ad3-a243-789ea3cd7c08"},"surfaceOp":"append"} +{"type":"session/title","seq":8,"time":1786357533602,"data":{"title":"Call subagent once. Ask that","messageSeqs":[6],"source":{"kind":"fallback"}}} +{"type":"request/header","seq":9,"time":1785730456014,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}} +{"type":"request/context","seq":10,"time":1785730456014,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} +{"type":"assistant/chunk","seq":11,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}}} +{"type":"assistant/chunk","seq":12,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":0,"id":"call_depth_one_child","name":"subagent","argumentsDelta":"{\"description\":\"Start depth two\",\"prompt\":\"Attempt one subagent call beyond the configured cap, then report the rejection.\"}"}}} +{"type":"assistant/chunk","seq":13,"time":1785498798883,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"call_depth_one_child","name":"subagent","arguments":"{\"description\":\"Start depth two\",\"prompt\":\"Attempt one subagent call beyond the configured cap, then report the rejection.\"}"}}}} +{"type":"assistant/chunk","seq":14,"time":1785730456018,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}}} +{"type":"assistant/chunk","seq":15,"time":1785730456018,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}} +{"type":"assistant/message","seq":16,"time":1785730456018,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"tool-call","id":"call_depth_one_child","name":"subagent","arguments":"{\"description\":\"Start depth two\",\"prompt\":\"Attempt one subagent call beyond the configured cap, then report the rejection.\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"21044d12-2e0e-40e3-b47e-4920e21c3e83"},"usage":{"inputTokens":10,"outputTokens":5}},"sourceEventSeqs":[11,12,13,14,15],"surfaceOp":"append"} +{"type":"tool/call","seq":17,"time":1785730456019,"data":{"turn":1,"step":1,"callId":"call_depth_one_child","name":"subagent","arguments":"{\"description\":\"Start depth two\",\"prompt\":\"Attempt one subagent call beyond the configured cap, then report the rejection.\"}"}} +{"type":"tool/result","seq":18,"time":1785730456072,"data":{"turn":1,"step":1,"message":{"source":{"kind":"tool","callId":"call_depth_one_child"},"content":[{"type":"tool-result","toolCallId":"call_depth_one_child","content":[{"type":"text","text":"DEPTH_REJECTED"}],"isError":false}],"role":"user","id":"aa5451a8-812b-4a51-a52c-dbc5c84f16d0"}},"sourceEventSeqs":[17],"surfaceOp":"append"} +{"type":"step/end","seq":19,"time":1785730456072,"data":{"turn":1,"step":1}} +{"type":"step/start","seq":20,"time":1785730456082,"data":{"turn":1,"step":2}} +{"type":"assistant/chunk","seq":21,"time":1784540790365,"data":{"turn":1,"step":2,"chunk":{"type":"block-start","index":0,"blockType":"text"}}} +{"type":"assistant/chunk","seq":22,"time":1784540790365,"data":{"turn":1,"step":2,"chunk":{"type":"text-delta","index":0,"text":"DEPTH_ONE_DONE"}}} +{"type":"assistant/chunk","seq":23,"time":1785498798949,"data":{"turn":1,"step":2,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"DEPTH_ONE_DONE"}}}} +{"type":"assistant/chunk","seq":24,"time":1785730456086,"data":{"turn":1,"step":2,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":2}}}} +{"type":"assistant/chunk","seq":25,"time":1785730456086,"data":{"turn":1,"step":2,"chunk":{"type":"finish","reason":{"kind":"stop"}}}} +{"type":"assistant/message","seq":26,"time":1785730456086,"data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"text","text":"DEPTH_ONE_DONE"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"5a1911c6-f487-458c-b802-4a66221ec046"},"usage":{"inputTokens":10,"outputTokens":2}},"sourceEventSeqs":[21,22,23,24,25],"surfaceOp":"append"} +{"type":"step/end","seq":27,"time":1785730456086,"data":{"turn":1,"step":2}} +{"type":"turn/end","seq":28,"time":1785730456086,"data":{"turn":1,"reason":{"kind":"completed"}}} diff --git a/examples/acp-agent/tests/snapshots/subagent-depth-two-rejection/session.2.jsonl b/examples/acp-agent/tests/snapshots/subagent-depth-two-rejection/session.2.jsonl index 7f2ae89966..89de9b1c4f 100644 --- a/examples/acp-agent/tests/snapshots/subagent-depth-two-rejection/session.2.jsonl +++ b/examples/acp-agent/tests/snapshots/subagent-depth-two-rejection/session.2.jsonl @@ -1,29 +1,30 @@ {"type":"session","version":0,"id":"33333333-3333-4333-8333-333333333333","createdAt":1002,"cwd":"{{cwd}}","parentSession":"22222222-2222-4222-8222-222222222222","origin":"subagent","delegationDepth":2} -{"type":"agent/inbox/spliced","seq":0,"time":1785498798891,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Attempt one subagent call beyond the configured cap, then report the rejection."}],"source":{"kind":"user"},"role":"user","id":"d4dc5a16-e542-4dd9-8e82-e6b7829cfc4b"}]}} -{"type":"turn/start","seq":1,"time":1785821414201,"data":{"turn":1}} -{"type":"agent/inbox/spliced","seq":2,"time":1785821414201,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} -{"type":"subagent/descriptor","seq":3,"time":1785821414214,"data":{"version":2,"mode":"one-shot","provider":"spawn","label":"Start depth two"}} -{"type":"step/start","seq":4,"time":1785730456041,"data":{"turn":1,"step":1}} -{"type":"user/message","seq":5,"time":1785730456041,"data":{"content":[{"type":"text","text":"Attempt one subagent call beyond the configured cap, then report the rejection."}],"source":{"kind":"user"},"role":"user","id":"d4dc5a16-e542-4dd9-8e82-e6b7829cfc4b"},"surfaceOp":"append"} -{"type":"user/message","seq":6,"time":1785730456041,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}]},"role":"user","id":"4a252f7d-8523-433f-a3fc-33812be802ec"},"surfaceOp":"append"} -{"type":"session/title","seq":7,"time":1785730456041,"data":{"title":"Attempt one subagent call beyond","messageSeqs":[5],"source":{"kind":"fallback"}}} -{"type":"request/header","seq":8,"time":1785730456041,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}} -{"type":"request/context","seq":9,"time":1785730456042,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} -{"type":"assistant/chunk","seq":10,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}}} -{"type":"assistant/chunk","seq":11,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":0,"id":"call_depth_three_rejected","name":"subagent","argumentsDelta":"{\"description\":\"Exceed depth cap\",\"prompt\":\"This child must never start.\"}"}}} -{"type":"assistant/chunk","seq":12,"time":1785498798916,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"call_depth_three_rejected","name":"subagent","arguments":"{\"description\":\"Exceed depth cap\",\"prompt\":\"This child must never start.\"}"}}}} -{"type":"assistant/chunk","seq":13,"time":1785730456047,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}}} -{"type":"assistant/chunk","seq":14,"time":1785730456047,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}} -{"type":"assistant/message","seq":15,"time":1785730456047,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"tool-call","id":"call_depth_three_rejected","name":"subagent","arguments":"{\"description\":\"Exceed depth cap\",\"prompt\":\"This child must never start.\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"467433db-5dbf-42ee-94c0-25c011ce711b"},"usage":{"inputTokens":10,"outputTokens":5}},"sourceEventSeqs":[10,11,12,13,14],"surfaceOp":"append"} -{"type":"tool/call","seq":16,"time":1785730456048,"data":{"turn":1,"step":1,"callId":"call_depth_three_rejected","name":"subagent","arguments":"{\"description\":\"Exceed depth cap\",\"prompt\":\"This child must never start.\"}"}} -{"type":"tool/result","seq":17,"time":1785730456056,"data":{"turn":1,"step":1,"message":{"source":{"kind":"tool","callId":"call_depth_three_rejected"},"content":[{"type":"tool-result","toolCallId":"call_depth_three_rejected","content":[{"type":"text","text":"Error: subagent depth 3 exceeds maxDepth 2"}],"isError":true}],"role":"user","id":"9a3d59f3-542a-4400-a62c-be28dcea3bd1"}},"sourceEventSeqs":[16],"surfaceOp":"append"} -{"type":"step/end","seq":18,"time":1785730456056,"data":{"turn":1,"step":1}} -{"type":"step/start","seq":19,"time":1785730456066,"data":{"turn":1,"step":2}} -{"type":"assistant/chunk","seq":20,"time":1784540790339,"data":{"turn":1,"step":2,"chunk":{"type":"block-start","index":0,"blockType":"text"}}} -{"type":"assistant/chunk","seq":21,"time":1784540790339,"data":{"turn":1,"step":2,"chunk":{"type":"text-delta","index":0,"text":"DEPTH_REJECTED"}}} -{"type":"assistant/chunk","seq":22,"time":1785498798937,"data":{"turn":1,"step":2,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"DEPTH_REJECTED"}}}} -{"type":"assistant/chunk","seq":23,"time":1785730456070,"data":{"turn":1,"step":2,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":2}}}} -{"type":"assistant/chunk","seq":24,"time":1785730456070,"data":{"turn":1,"step":2,"chunk":{"type":"finish","reason":{"kind":"stop"}}}} -{"type":"assistant/message","seq":25,"time":1785730456070,"data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"text","text":"DEPTH_REJECTED"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"57c0ecaf-3f72-4da9-9eb9-a0726e8f097a"},"usage":{"inputTokens":10,"outputTokens":2}},"sourceEventSeqs":[20,21,22,23,24],"surfaceOp":"append"} -{"type":"step/end","seq":26,"time":1785730456071,"data":{"turn":1,"step":2}} -{"type":"turn/end","seq":27,"time":1785730456071,"data":{"turn":1,"reason":{"kind":"completed"}}} +{"type":"approval/policy","seq":0,"time":1786357533611,"data":{"policy":"never","source":"delegation"}} +{"type":"agent/inbox/spliced","seq":1,"time":1786357533611,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Attempt one subagent call beyond the configured cap, then report the rejection."}],"source":{"kind":"user"},"role":"user","id":"d4dc5a16-e542-4dd9-8e82-e6b7829cfc4b"}]}} +{"type":"turn/start","seq":2,"time":1786357533611,"data":{"turn":1}} +{"type":"agent/inbox/spliced","seq":3,"time":1786357533611,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} +{"type":"subagent/descriptor","seq":4,"time":1786357533628,"data":{"version":2,"mode":"one-shot","provider":"spawn","label":"Start depth two"}} +{"type":"step/start","seq":5,"time":1786357533630,"data":{"turn":1,"step":1}} +{"type":"user/message","seq":6,"time":1785730456041,"data":{"content":[{"type":"text","text":"Attempt one subagent call beyond the configured cap, then report the rejection."}],"source":{"kind":"user"},"role":"user","id":"d4dc5a16-e542-4dd9-8e82-e6b7829cfc4b"},"surfaceOp":"append"} +{"type":"user/message","seq":7,"time":1786357533630,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`).\n\nYou are a delegated subagent: your permission scope was fixed when you were started and cannot be widened from inside this session — operations that require approval are rejected automatically. When the task needs access beyond that scope, do not retry the denied operation; state the limitation in your reply so the delegating agent can handle it."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."},{"name":"subagent:delegation","text":"You are a delegated subagent: your permission scope was fixed when you were started and cannot be widened from inside this session — operations that require approval are rejected automatically. When the task needs access beyond that scope, do not retry the denied operation; state the limitation in your reply so the delegating agent can handle it."}]},"role":"user","id":"d5488efe-eea2-4019-8fcb-7e6e49077d8a"},"surfaceOp":"append"} +{"type":"session/title","seq":8,"time":1786357533630,"data":{"title":"Attempt one subagent call beyond","messageSeqs":[6],"source":{"kind":"fallback"}}} +{"type":"request/header","seq":9,"time":1785730456041,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}} +{"type":"request/context","seq":10,"time":1785730456042,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} +{"type":"assistant/chunk","seq":11,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}}} +{"type":"assistant/chunk","seq":12,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":0,"id":"call_depth_three_rejected","name":"subagent","argumentsDelta":"{\"description\":\"Exceed depth cap\",\"prompt\":\"This child must never start.\"}"}}} +{"type":"assistant/chunk","seq":13,"time":1785498798916,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"call_depth_three_rejected","name":"subagent","arguments":"{\"description\":\"Exceed depth cap\",\"prompt\":\"This child must never start.\"}"}}}} +{"type":"assistant/chunk","seq":14,"time":1785730456047,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}}} +{"type":"assistant/chunk","seq":15,"time":1785730456047,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}} +{"type":"assistant/message","seq":16,"time":1785730456047,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"tool-call","id":"call_depth_three_rejected","name":"subagent","arguments":"{\"description\":\"Exceed depth cap\",\"prompt\":\"This child must never start.\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"467433db-5dbf-42ee-94c0-25c011ce711b"},"usage":{"inputTokens":10,"outputTokens":5}},"sourceEventSeqs":[11,12,13,14,15],"surfaceOp":"append"} +{"type":"tool/call","seq":17,"time":1785730456048,"data":{"turn":1,"step":1,"callId":"call_depth_three_rejected","name":"subagent","arguments":"{\"description\":\"Exceed depth cap\",\"prompt\":\"This child must never start.\"}"}} +{"type":"tool/result","seq":18,"time":1785730456056,"data":{"turn":1,"step":1,"message":{"source":{"kind":"tool","callId":"call_depth_three_rejected"},"content":[{"type":"tool-result","toolCallId":"call_depth_three_rejected","content":[{"type":"text","text":"Error: subagent depth 3 exceeds maxDepth 2"}],"isError":true}],"role":"user","id":"9a3d59f3-542a-4400-a62c-be28dcea3bd1"}},"sourceEventSeqs":[17],"surfaceOp":"append"} +{"type":"step/end","seq":19,"time":1785730456056,"data":{"turn":1,"step":1}} +{"type":"step/start","seq":20,"time":1785730456066,"data":{"turn":1,"step":2}} +{"type":"assistant/chunk","seq":21,"time":1784540790339,"data":{"turn":1,"step":2,"chunk":{"type":"block-start","index":0,"blockType":"text"}}} +{"type":"assistant/chunk","seq":22,"time":1784540790339,"data":{"turn":1,"step":2,"chunk":{"type":"text-delta","index":0,"text":"DEPTH_REJECTED"}}} +{"type":"assistant/chunk","seq":23,"time":1785498798937,"data":{"turn":1,"step":2,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"DEPTH_REJECTED"}}}} +{"type":"assistant/chunk","seq":24,"time":1785730456070,"data":{"turn":1,"step":2,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":2}}}} +{"type":"assistant/chunk","seq":25,"time":1785730456070,"data":{"turn":1,"step":2,"chunk":{"type":"finish","reason":{"kind":"stop"}}}} +{"type":"assistant/message","seq":26,"time":1785730456070,"data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"text","text":"DEPTH_REJECTED"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"57c0ecaf-3f72-4da9-9eb9-a0726e8f097a"},"usage":{"inputTokens":10,"outputTokens":2}},"sourceEventSeqs":[21,22,23,24,25],"surfaceOp":"append"} +{"type":"step/end","seq":27,"time":1785730456071,"data":{"turn":1,"step":2}} +{"type":"turn/end","seq":28,"time":1785730456071,"data":{"turn":1,"reason":{"kind":"completed"}}} diff --git a/examples/acp-agent/tests/snapshots/subagent-depth-two-rejection/session.jsonl b/examples/acp-agent/tests/snapshots/subagent-depth-two-rejection/session.jsonl index 6288b6d516..ab699d7d18 100644 --- a/examples/acp-agent/tests/snapshots/subagent-depth-two-rejection/session.jsonl +++ b/examples/acp-agent/tests/snapshots/subagent-depth-two-rejection/session.jsonl @@ -4,7 +4,7 @@ {"type":"agent/inbox/spliced","seq":2,"time":1785821414127,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} {"type":"step/start","seq":3,"time":1784540790308,"data":{"turn":1,"step":1}} {"type":"user/message","seq":4,"time":1785498798839,"data":{"content":[{"type":"text","text":"Delegate through two child generations. The depth-two child must attempt one more subagent call and report the rejection."}],"source":{"kind":"user"},"role":"user","id":"b2260a25-4667-49ed-9297-16b233f22332"},"surfaceOp":"append"} -{"type":"user/message","seq":5,"time":1785730455980,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}]},"role":"user","id":"d3ba1b18-4d27-4c90-a95d-125e9ffc9f29"},"surfaceOp":"append"} +{"type":"user/message","seq":5,"time":1785730455980,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}]},"role":"user","id":"55365caf-6fcc-484b-a4b7-646914654bbb"},"surfaceOp":"append"} {"type":"session/title","seq":6,"time":1785730455980,"data":{"title":"Delegate through two child generations.","messageSeqs":[4],"source":{"kind":"fallback"}}} {"type":"request/header","seq":7,"time":1785498798841,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}} {"type":"request/context","seq":8,"time":1785730455981,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} diff --git a/examples/acp-agent/tests/snapshots/subagent-fork/session.1.jsonl b/examples/acp-agent/tests/snapshots/subagent-fork/session.1.jsonl index a56f7ccf60..c663606bbd 100644 --- a/examples/acp-agent/tests/snapshots/subagent-fork/session.1.jsonl +++ b/examples/acp-agent/tests/snapshots/subagent-fork/session.1.jsonl @@ -20,21 +20,23 @@ {"type":"step/end","seq":40,"time":1785730448979,"data":{"turn":1,"step":1}} {"type":"turn/end","seq":41,"time":1785730448979,"data":{"turn":1,"reason":{"kind":"completed"}}} {"type":"session/end-seed","seq":42,"time":1785730449008,"data":{}} -{"type":"agent/inbox/spliced","seq":43,"time":1785498796160,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"What is the project codeword mentioned earlier in this conversation? Reply with exactly that one word and nothing else."}],"source":{"kind":"user"},"role":"user","id":"d037163e-ed56-4c9c-b5d1-57df017d618c"}]}} -{"type":"turn/start","seq":44,"time":1785821406523,"data":{"turn":2}} -{"type":"agent/inbox/spliced","seq":45,"time":1785821406523,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} -{"type":"subagent/descriptor","seq":46,"time":1785821406543,"data":{"version":2,"mode":"one-shot","provider":"fork","label":"Recall project codeword"}} -{"type":"step/start","seq":47,"time":1785730449027,"data":{"turn":2,"step":1}} -{"type":"user/message","seq":48,"time":1785730449027,"data":{"content":[{"type":"text","text":"What is the project codeword mentioned earlier in this conversation? Reply with exactly that one word and nothing else."}],"source":{"kind":"user"},"role":"user","id":"d037163e-ed56-4c9c-b5d1-57df017d618c"},"surfaceOp":"append"} -{"type":"request/header","seq":49,"time":1785730449027,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"resume"}} -{"type":"assistant/chunk","seq":50,"time":1783352138046,"data":{"turn":2,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}}} -{"type":"reasoning-chunks","seq0":51,"time0":1783352138046,"data":{"turn":2,"step":1,"index":0,"dt":[0,28,1,0,0,0,0,28,0,0,0,0,28,28,1,0,0,28,0,0,29,0,0,28,1,28,1,0,0,0,0,30,2],"texts":["The"," user"," asked"," me"," to"," remember"," the"," project"," cod","ew","ord"," \"","M","ARM","AL","ADE","\""," and"," now"," they","'re"," asking"," what"," it"," is","."," I"," should"," just"," reply"," with"," that"," word","."]}} -{"type":"assistant/chunk","seq":85,"time":1783352138307,"data":{"turn":2,"step":1,"chunk":{"type":"block-start","index":1,"blockType":"text"}}} -{"type":"text-chunks","seq0":86,"time0":1783352138307,"data":{"turn":2,"step":1,"index":1,"dt":[1790166963,239266980,117223942],"texts":["M","ARM","AL","ADE"]}} -{"type":"assistant/chunk","seq":90,"time":1785498796192,"data":{"turn":2,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The user asked me to remember the project codeword \"MARMALADE\" and now they're asking what it is. I should just reply with that word."}}}} -{"type":"assistant/chunk","seq":91,"time":1785498796192,"data":{"turn":2,"step":1,"chunk":{"type":"block-end","index":1,"block":{"type":"text","text":"MARMALADE"}}}} -{"type":"assistant/chunk","seq":92,"time":1785730449034,"data":{"turn":2,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":97,"outputTokens":39,"cacheReadTokens":2816,"reasoningTokens":34}}}} -{"type":"assistant/chunk","seq":93,"time":1785730449034,"data":{"turn":2,"step":1,"chunk":{"type":"finish","reason":{"kind":"stop"}}}} -{"type":"assistant/message","seq":94,"time":1785730449034,"data":{"turn":2,"step":1,"message":{"role":"assistant","content":[{"type":"reasoning","text":"The user asked me to remember the project codeword \"MARMALADE\" and now they're asking what it is. I should just reply with that word."},{"type":"text","text":"MARMALADE"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"cdc56e00-c648-4669-92b2-7299e41cb743"},"usage":{"inputTokens":97,"outputTokens":39,"cacheReadTokens":2816,"reasoningTokens":34}},"sourceEventSeqs":[50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93],"surfaceOp":"append"} -{"type":"step/end","seq":95,"time":1785730449035,"data":{"turn":2,"step":1}} -{"type":"turn/end","seq":96,"time":1785730449035,"data":{"turn":2,"reason":{"kind":"completed"}}} +{"type":"approval/policy","seq":43,"time":1786357523264,"data":{"policy":"never","source":"delegation"}} +{"type":"agent/inbox/spliced","seq":44,"time":1786357523265,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"What is the project codeword mentioned earlier in this conversation? Reply with exactly that one word and nothing else."}],"source":{"kind":"user"},"role":"user","id":"d037163e-ed56-4c9c-b5d1-57df017d618c"}]}} +{"type":"turn/start","seq":45,"time":1786357523265,"data":{"turn":2}} +{"type":"agent/inbox/spliced","seq":46,"time":1786357523265,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} +{"type":"subagent/descriptor","seq":47,"time":1786357523283,"data":{"version":2,"mode":"one-shot","provider":"fork","label":"Recall project codeword"}} +{"type":"step/start","seq":48,"time":1786357523286,"data":{"turn":2,"step":1}} +{"type":"user/message","seq":49,"time":1786357523286,"data":{"content":[{"type":"text","text":"What is the project codeword mentioned earlier in this conversation? Reply with exactly that one word and nothing else."}],"source":{"kind":"user"},"role":"user","id":"d037163e-ed56-4c9c-b5d1-57df017d618c"},"surfaceOp":"append"} +{"type":"user/message","seq":50,"time":1786358035356,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`).\n\nYou are a delegated subagent: your permission scope was fixed when you were started and cannot be widened from inside this session — operations that require approval are rejected automatically. When the task needs access beyond that scope, do not retry the denied operation; state the limitation in your reply so the delegating agent can handle it."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."},{"name":"subagent:delegation","text":"You are a delegated subagent: your permission scope was fixed when you were started and cannot be widened from inside this session — operations that require approval are rejected automatically. When the task needs access beyond that scope, do not retry the denied operation; state the limitation in your reply so the delegating agent can handle it."}]},"role":"user","id":"257e572f-6f95-48f9-b3d7-4ea8b162f374"},"surfaceOp":"append"} +{"type":"request/header","seq":51,"time":1786358035356,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"resume"}} +{"type":"assistant/chunk","seq":52,"time":1783352138046,"data":{"turn":2,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}}} +{"type":"reasoning-chunks","seq0":53,"time0":1783352138074,"data":{"turn":2,"step":1,"index":0,"dt":[1,0,0,0,0,28,0,0,0,0,28,28,1,0,0,28,0,0,29,0,0,28,1,28,1,0,0,0,0,30,2,0,0],"texts":["The"," user"," asked"," me"," to"," remember"," the"," project"," cod","ew","ord"," \"","M","ARM","AL","ADE","\""," and"," now"," they","'re"," asking"," what"," it"," is","."," I"," should"," just"," reply"," with"," that"," word","."]}} +{"type":"assistant/chunk","seq":87,"time":1785142305270,"data":{"turn":2,"step":1,"chunk":{"type":"block-start","index":1,"blockType":"text"}}} +{"type":"text-chunks","seq0":88,"time0":1785381572250,"data":{"turn":2,"step":1,"index":1,"dt":[117223942,0,0],"texts":["M","ARM","AL","ADE"]}} +{"type":"assistant/chunk","seq":92,"time":1785730449034,"data":{"turn":2,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The user asked me to remember the project codeword \"MARMALADE\" and now they're asking what it is. I should just reply with that word."}}}} +{"type":"assistant/chunk","seq":93,"time":1785730449034,"data":{"turn":2,"step":1,"chunk":{"type":"block-end","index":1,"block":{"type":"text","text":"MARMALADE"}}}} +{"type":"assistant/chunk","seq":94,"time":1786357523292,"data":{"turn":2,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":97,"outputTokens":39,"cacheReadTokens":2816,"reasoningTokens":34}}}} +{"type":"assistant/chunk","seq":95,"time":1786358035361,"data":{"turn":2,"step":1,"chunk":{"type":"finish","reason":{"kind":"stop"}}}} +{"type":"assistant/message","seq":96,"time":1786358035361,"data":{"turn":2,"step":1,"message":{"role":"assistant","content":[{"type":"reasoning","text":"The user asked me to remember the project codeword \"MARMALADE\" and now they're asking what it is. I should just reply with that word."},{"type":"text","text":"MARMALADE"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"cdc56e00-c648-4669-92b2-7299e41cb743"},"usage":{"inputTokens":97,"outputTokens":39,"cacheReadTokens":2816,"reasoningTokens":34}},"sourceEventSeqs":[52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95],"surfaceOp":"append"} +{"type":"step/end","seq":97,"time":1786358035361,"data":{"turn":2,"step":1}} +{"type":"turn/end","seq":98,"time":1786358035361,"data":{"turn":2,"reason":{"kind":"completed"}}} diff --git a/examples/acp-agent/tests/snapshots/subagent-list-agents/session.1.jsonl b/examples/acp-agent/tests/snapshots/subagent-list-agents/session.1.jsonl index d6e54e2096..d81f1964b2 100644 --- a/examples/acp-agent/tests/snapshots/subagent-list-agents/session.1.jsonl +++ b/examples/acp-agent/tests/snapshots/subagent-list-agents/session.1.jsonl @@ -1,20 +1,21 @@ {"type":"session","version":0,"id":"33333333-3333-4333-8333-333333333333","createdAt":1789000001000,"cwd":"{{cwd}}","parentSession":"11111111-1111-4111-8111-111111111111","origin":"subagent","delegationDepth":1} {"type":"subagent/descriptor","seq":0,"time":1785531795641,"data":{"version":2,"mode":"continuable","provider":"spawn","label":"Reply with CHILD_OK","agentProvider":"deepseek-official","agentModel":"deepseek-v4-flash"}} {"type":"session/end-seed","seq":1,"time":1785531795641,"data":{}} -{"type":"agent/inbox/spliced","seq":2,"time":1785730454803,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Reply with exactly the word CHILD_OK and nothing else."}],"source":{"kind":"user"},"role":"user","id":"2a46160e-89d3-433b-bf04-66fb0313abfa"}]}} -{"type":"turn/start","seq":3,"time":1785821412774,"data":{"turn":1}} -{"type":"agent/inbox/spliced","seq":4,"time":1785821412774,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} -{"type":"step/start","seq":5,"time":1785730454835,"data":{"turn":1,"step":1}} -{"type":"user/message","seq":6,"time":1785730454835,"data":{"content":[{"type":"text","text":"Reply with exactly the word CHILD_OK and nothing else."}],"source":{"kind":"user"},"role":"user","id":"2a46160e-89d3-433b-bf04-66fb0313abfa"},"surfaceOp":"append"} -{"type":"user/message","seq":7,"time":1785730454835,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}]},"role":"user","id":"524be394-8639-4c12-a41d-799b9e0120a1"},"surfaceOp":"append"} -{"type":"session/title","seq":8,"time":1785730454835,"data":{"title":"Reply with exactly the word","messageSeqs":[6],"source":{"kind":"fallback"}}} -{"type":"request/header","seq":9,"time":1785730454835,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}} -{"type":"request/context","seq":10,"time":1785730454835,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} -{"type":"assistant/chunk","seq":11,"time":1789000000007,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"text"}}} -{"type":"assistant/chunk","seq":12,"time":1789000000008,"data":{"turn":1,"step":1,"chunk":{"type":"text-delta","index":0,"text":"CHILD_OK"}}} -{"type":"assistant/chunk","seq":13,"time":1785531795683,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"CHILD_OK"}}}} -{"type":"assistant/chunk","seq":14,"time":1785531795683,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":3}}}} -{"type":"assistant/chunk","seq":15,"time":1785730454843,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"stop"}}}} -{"type":"assistant/message","seq":16,"time":1785730454843,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"text","text":"CHILD_OK"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"f6a952dd-2d09-4b5c-b8ae-5456cfdfeab0"},"usage":{"inputTokens":10,"outputTokens":3}},"sourceEventSeqs":[11,12,13,14,15],"surfaceOp":"append"} -{"type":"step/end","seq":17,"time":1785730454843,"data":{"turn":1,"step":1}} -{"type":"turn/end","seq":18,"time":1785730454844,"data":{"turn":1,"reason":{"kind":"completed"}}} +{"type":"approval/policy","seq":2,"time":1786357532080,"data":{"policy":"never","source":"delegation"}} +{"type":"agent/inbox/spliced","seq":3,"time":1786357532080,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Reply with exactly the word CHILD_OK and nothing else."}],"source":{"kind":"user"},"role":"user","id":"2a46160e-89d3-433b-bf04-66fb0313abfa"}]}} +{"type":"turn/start","seq":4,"time":1786357532081,"data":{"turn":1}} +{"type":"agent/inbox/spliced","seq":5,"time":1786357532081,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} +{"type":"step/start","seq":6,"time":1786357532106,"data":{"turn":1,"step":1}} +{"type":"user/message","seq":7,"time":1785730454835,"data":{"content":[{"type":"text","text":"Reply with exactly the word CHILD_OK and nothing else."}],"source":{"kind":"user"},"role":"user","id":"2a46160e-89d3-433b-bf04-66fb0313abfa"},"surfaceOp":"append"} +{"type":"user/message","seq":8,"time":1786357532106,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`).\n\nYou are a delegated subagent: your permission scope was fixed when you were started and cannot be widened from inside this session — operations that require approval are rejected automatically. When the task needs access beyond that scope, do not retry the denied operation; state the limitation in your reply so the delegating agent can handle it."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."},{"name":"subagent:delegation","text":"You are a delegated subagent: your permission scope was fixed when you were started and cannot be widened from inside this session — operations that require approval are rejected automatically. When the task needs access beyond that scope, do not retry the denied operation; state the limitation in your reply so the delegating agent can handle it."}]},"role":"user","id":"5fda3f8d-fbac-4878-a9e3-9953a4e1da09"},"surfaceOp":"append"} +{"type":"session/title","seq":9,"time":1786357532106,"data":{"title":"Reply with exactly the word","messageSeqs":[7],"source":{"kind":"fallback"}}} +{"type":"request/header","seq":10,"time":1785730454835,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}} +{"type":"request/context","seq":11,"time":1785730454835,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} +{"type":"assistant/chunk","seq":12,"time":1789000000007,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"text"}}} +{"type":"assistant/chunk","seq":13,"time":1789000000008,"data":{"turn":1,"step":1,"chunk":{"type":"text-delta","index":0,"text":"CHILD_OK"}}} +{"type":"assistant/chunk","seq":14,"time":1785531795683,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"CHILD_OK"}}}} +{"type":"assistant/chunk","seq":15,"time":1785531795683,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":3}}}} +{"type":"assistant/chunk","seq":16,"time":1785730454843,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"stop"}}}} +{"type":"assistant/message","seq":17,"time":1785730454843,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"text","text":"CHILD_OK"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"f6a952dd-2d09-4b5c-b8ae-5456cfdfeab0"},"usage":{"inputTokens":10,"outputTokens":3}},"sourceEventSeqs":[12,13,14,15,16],"surfaceOp":"append"} +{"type":"step/end","seq":18,"time":1785730454843,"data":{"turn":1,"step":1}} +{"type":"turn/end","seq":19,"time":1785730454844,"data":{"turn":1,"reason":{"kind":"completed"}}} diff --git a/examples/acp-agent/tests/snapshots/subagent-list-agents/session.jsonl b/examples/acp-agent/tests/snapshots/subagent-list-agents/session.jsonl index f1deec5af9..06bd463ba8 100644 --- a/examples/acp-agent/tests/snapshots/subagent-list-agents/session.jsonl +++ b/examples/acp-agent/tests/snapshots/subagent-list-agents/session.jsonl @@ -4,7 +4,7 @@ {"type":"agent/inbox/spliced","seq":2,"time":1785821412725,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} {"type":"step/start","seq":3,"time":1785730454783,"data":{"turn":1,"step":1}} {"type":"user/message","seq":4,"time":1785730454783,"data":{"content":[{"type":"text","text":"Call the subagent tool once with run_in_background set to true, description 'Reply with CHILD_OK', and prompt 'Reply with exactly the word CHILD_OK and nothing else.'. Then reply with the single word STARTED. Do not call any other tool."}],"source":{"kind":"user"},"role":"user","id":"c2febfff-792d-4457-a944-933ff0de0570"},"surfaceOp":"append"} -{"type":"user/message","seq":5,"time":1785730454783,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}]},"role":"user","id":"cc8cb20d-5802-46a9-87b8-d3ee784f8e52"},"surfaceOp":"append"} +{"type":"user/message","seq":5,"time":1785730454783,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}]},"role":"user","id":"c9d1f853-56bc-4082-ae08-00d4bcbb04a6"},"surfaceOp":"append"} {"type":"session/title","seq":6,"time":1785730454783,"data":{"title":"Call the subagent tool once","messageSeqs":[4],"source":{"kind":"fallback"}}} {"type":"request/header","seq":7,"time":1785730454784,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}} {"type":"request/context","seq":8,"time":1785730454784,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} diff --git a/examples/acp-agent/tests/snapshots/subagent-mixed/session.1.jsonl b/examples/acp-agent/tests/snapshots/subagent-mixed/session.1.jsonl index e275607cbf..e510929344 100644 --- a/examples/acp-agent/tests/snapshots/subagent-mixed/session.1.jsonl +++ b/examples/acp-agent/tests/snapshots/subagent-mixed/session.1.jsonl @@ -1,22 +1,23 @@ {"type":"session","version":0,"id":"e4aafa18-b9e3-48d0-8aae-6c9b25dcae80","createdAt":1783352145223,"cwd":"{{cwd}}","parentSession":"959ffdf5-03e2-465e-9482-009b704632dc","origin":"subagent","delegationDepth":1} -{"type":"agent/inbox/spliced","seq":0,"time":1785498797416,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Reply with exactly the word ALPHA and nothing else."}],"source":{"kind":"user"},"role":"user","id":"73ce401a-faaf-408a-879e-7485380d537d"}]}} -{"type":"turn/start","seq":1,"time":1785821407754,"data":{"turn":1}} -{"type":"agent/inbox/spliced","seq":2,"time":1785821407754,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} -{"type":"subagent/descriptor","seq":3,"time":1785821407767,"data":{"version":2,"mode":"one-shot","provider":"spawn","label":"Reply ALPHA only"}} -{"type":"step/start","seq":4,"time":1785730450187,"data":{"turn":1,"step":1}} -{"type":"user/message","seq":5,"time":1785730450187,"data":{"content":[{"type":"text","text":"Reply with exactly the word ALPHA and nothing else."}],"source":{"kind":"user"},"role":"user","id":"73ce401a-faaf-408a-879e-7485380d537d"},"surfaceOp":"append"} -{"type":"user/message","seq":6,"time":1785730450187,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}]},"role":"user","id":"4a5a7c59-b6f8-47b0-8c09-d9a05607deac"},"surfaceOp":"append"} -{"type":"session/title","seq":7,"time":1785730450187,"data":{"title":"Reply with exactly the word","messageSeqs":[5],"source":{"kind":"fallback"}}} -{"type":"request/header","seq":8,"time":1785730450187,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}} -{"type":"request/context","seq":9,"time":1785730450188,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} -{"type":"assistant/chunk","seq":10,"time":1783352146014,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}}} -{"type":"reasoning-chunks","seq0":11,"time0":1783352146042,"data":{"turn":1,"step":1,"index":0,"dt":[1,0,0,0,28,0,0,0,0,0,29,0,0,0,0,29,0,0],"texts":["The"," user"," asked"," me"," to"," reply"," with"," exactly"," the"," word"," \"","AL","P","HA","\""," and"," nothing"," else","."]}} -{"type":"assistant/chunk","seq":30,"time":1783352146129,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":1,"blockType":"text"}}} -{"type":"text-chunks","seq0":31,"time0":1783352146129,"data":{"turn":1,"step":1,"index":1,"dt":[0,0],"texts":["AL","P","HA"]}} -{"type":"assistant/chunk","seq":34,"time":1783352146129,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The user asked me to reply with exactly the word \"ALPHA\" and nothing else."}}}} -{"type":"assistant/chunk","seq":35,"time":1785498797444,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":1,"block":{"type":"text","text":"ALPHA"}}}} -{"type":"assistant/chunk","seq":36,"time":1785730450194,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":48,"outputTokens":23,"cacheReadTokens":2816,"reasoningTokens":19}}}} -{"type":"assistant/chunk","seq":37,"time":1785730450194,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"stop"}}}} -{"type":"assistant/message","seq":38,"time":1785730450194,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"reasoning","text":"The user asked me to reply with exactly the word \"ALPHA\" and nothing else."},{"type":"text","text":"ALPHA"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"cfff210d-8dd3-4acc-bbc3-fa860baf88cf"},"usage":{"inputTokens":48,"outputTokens":23,"cacheReadTokens":2816,"reasoningTokens":19}},"sourceEventSeqs":[10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"surfaceOp":"append"} -{"type":"step/end","seq":39,"time":1785730450194,"data":{"turn":1,"step":1}} -{"type":"turn/end","seq":40,"time":1785730450195,"data":{"turn":1,"reason":{"kind":"completed"}}} +{"type":"approval/policy","seq":0,"time":1786357524735,"data":{"policy":"never","source":"delegation"}} +{"type":"agent/inbox/spliced","seq":1,"time":1786357524735,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Reply with exactly the word ALPHA and nothing else."}],"source":{"kind":"user"},"role":"user","id":"73ce401a-faaf-408a-879e-7485380d537d"}]}} +{"type":"turn/start","seq":2,"time":1786357524735,"data":{"turn":1}} +{"type":"agent/inbox/spliced","seq":3,"time":1786357524735,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} +{"type":"subagent/descriptor","seq":4,"time":1786357524752,"data":{"version":2,"mode":"one-shot","provider":"spawn","label":"Reply ALPHA only"}} +{"type":"step/start","seq":5,"time":1786357524755,"data":{"turn":1,"step":1}} +{"type":"user/message","seq":6,"time":1785730450187,"data":{"content":[{"type":"text","text":"Reply with exactly the word ALPHA and nothing else."}],"source":{"kind":"user"},"role":"user","id":"73ce401a-faaf-408a-879e-7485380d537d"},"surfaceOp":"append"} +{"type":"user/message","seq":7,"time":1786357524755,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`).\n\nYou are a delegated subagent: your permission scope was fixed when you were started and cannot be widened from inside this session — operations that require approval are rejected automatically. When the task needs access beyond that scope, do not retry the denied operation; state the limitation in your reply so the delegating agent can handle it."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."},{"name":"subagent:delegation","text":"You are a delegated subagent: your permission scope was fixed when you were started and cannot be widened from inside this session — operations that require approval are rejected automatically. When the task needs access beyond that scope, do not retry the denied operation; state the limitation in your reply so the delegating agent can handle it."}]},"role":"user","id":"56ad93fa-0cc0-4ccb-a1b4-258f4801c681"},"surfaceOp":"append"} +{"type":"session/title","seq":8,"time":1786357524755,"data":{"title":"Reply with exactly the word","messageSeqs":[6],"source":{"kind":"fallback"}}} +{"type":"request/header","seq":9,"time":1785730450187,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}} +{"type":"request/context","seq":10,"time":1785730450188,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} +{"type":"assistant/chunk","seq":11,"time":1783352146014,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}}} +{"type":"reasoning-chunks","seq0":12,"time0":1783352146042,"data":{"turn":1,"step":1,"index":0,"dt":[1,0,0,0,28,0,0,0,0,0,29,0,0,0,0,29,0,0],"texts":["The"," user"," asked"," me"," to"," reply"," with"," exactly"," the"," word"," \"","AL","P","HA","\""," and"," nothing"," else","."]}} +{"type":"assistant/chunk","seq":31,"time":1783352146129,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":1,"blockType":"text"}}} +{"type":"text-chunks","seq0":32,"time0":1783352146129,"data":{"turn":1,"step":1,"index":1,"dt":[0,0],"texts":["AL","P","HA"]}} +{"type":"assistant/chunk","seq":35,"time":1783352146129,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The user asked me to reply with exactly the word \"ALPHA\" and nothing else."}}}} +{"type":"assistant/chunk","seq":36,"time":1785498797444,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":1,"block":{"type":"text","text":"ALPHA"}}}} +{"type":"assistant/chunk","seq":37,"time":1785730450194,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":48,"outputTokens":23,"cacheReadTokens":2816,"reasoningTokens":19}}}} +{"type":"assistant/chunk","seq":38,"time":1785730450194,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"stop"}}}} +{"type":"assistant/message","seq":39,"time":1785730450194,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"reasoning","text":"The user asked me to reply with exactly the word \"ALPHA\" and nothing else."},{"type":"text","text":"ALPHA"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"cfff210d-8dd3-4acc-bbc3-fa860baf88cf"},"usage":{"inputTokens":48,"outputTokens":23,"cacheReadTokens":2816,"reasoningTokens":19}},"sourceEventSeqs":[11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38],"surfaceOp":"append"} +{"type":"step/end","seq":40,"time":1785730450194,"data":{"turn":1,"step":1}} +{"type":"turn/end","seq":41,"time":1785730450195,"data":{"turn":1,"reason":{"kind":"completed"}}} diff --git a/examples/acp-agent/tests/snapshots/subagent-mixed/session.2.jsonl b/examples/acp-agent/tests/snapshots/subagent-mixed/session.2.jsonl index fb6e5e0971..a5f4ab88a4 100644 --- a/examples/acp-agent/tests/snapshots/subagent-mixed/session.2.jsonl +++ b/examples/acp-agent/tests/snapshots/subagent-mixed/session.2.jsonl @@ -4,7 +4,7 @@ {"type":"agent/inbox/spliced","seq":2,"time":1785821407687,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} {"type":"step/start","seq":3,"time":1783352142835,"data":{"turn":1,"step":1}} {"type":"user/message","seq":4,"time":1785498797379,"data":{"content":[{"type":"text","text":"Remember this fact for later: the project codeword is SAFFRON. Reply with the single word OK and stop. Do not use any tools."}],"source":{"kind":"user"},"role":"user","id":"3d1ea7cb-c273-4c38-a765-5ff256eaaf51"},"surfaceOp":"append"} -{"type":"user/message","seq":5,"time":1785730450135,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}]},"role":"user","id":"473ecf9e-52c4-4db2-be56-1c8f7fa7d932"},"surfaceOp":"append"} +{"type":"user/message","seq":5,"time":1785730450135,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}]},"role":"user","id":"e0a9678e-ff95-49f4-b4f7-4ace69a670a3"},"surfaceOp":"append"} {"type":"session/title","seq":6,"time":1785730450135,"data":{"title":"Remember this fact for later:","messageSeqs":[4],"source":{"kind":"fallback"}}} {"type":"request/header","seq":7,"time":1785498797380,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}} {"type":"request/context","seq":8,"time":1785730450136,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} @@ -20,21 +20,23 @@ {"type":"step/end","seq":34,"time":1785730450146,"data":{"turn":1,"step":1}} {"type":"turn/end","seq":35,"time":1785730450146,"data":{"turn":1,"reason":{"kind":"completed"}}} {"type":"session/end-seed","seq":36,"time":1785730450227,"data":{}} -{"type":"agent/inbox/spliced","seq":37,"time":1785498797482,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"What is the project codeword mentioned earlier in this conversation? Reply with exactly that one word and nothing else."}],"source":{"kind":"user"},"role":"user","id":"86e9f144-764f-460d-b72b-262cffe43d77"}]}} -{"type":"turn/start","seq":38,"time":1785821407808,"data":{"turn":2}} -{"type":"agent/inbox/spliced","seq":39,"time":1785821407808,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} -{"type":"subagent/descriptor","seq":40,"time":1785821407826,"data":{"version":2,"mode":"one-shot","provider":"fork","label":"Recall project codeword"}} -{"type":"step/start","seq":41,"time":1785730450246,"data":{"turn":2,"step":1}} -{"type":"user/message","seq":42,"time":1785730450246,"data":{"content":[{"type":"text","text":"What is the project codeword mentioned earlier in this conversation? Reply with exactly that one word and nothing else."}],"source":{"kind":"user"},"role":"user","id":"86e9f144-764f-460d-b72b-262cffe43d77"},"surfaceOp":"append"} -{"type":"request/header","seq":43,"time":1785730450247,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"resume"}} -{"type":"assistant/chunk","seq":44,"time":1783352148076,"data":{"turn":2,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}}} -{"type":"reasoning-chunks","seq0":45,"time0":1783352148076,"data":{"turn":2,"step":1,"index":0,"dt":[1,0,0,0,29,0,0,0,35,0,0,0,0,26,29,31,0,30,0,0,27,1,27,0,1,0,0,31,1,0],"texts":["The"," user"," is"," asking"," me"," to"," recall"," the"," project"," cod","ew","ord"," that"," was"," mentioned"," earlier"," in"," the"," conversation","."," I"," was"," told"," to"," remember"," it",":"," SA","FF","RON","."]}} -{"type":"assistant/chunk","seq":76,"time":1783352148345,"data":{"turn":2,"step":1,"chunk":{"type":"block-start","index":1,"blockType":"text"}}} -{"type":"text-chunks","seq0":77,"time0":1785142306309,"data":{"turn":2,"step":1,"index":1,"dt":[239267243,117223959],"texts":["SA","FF","RON"]}} -{"type":"assistant/chunk","seq":80,"time":1785498797511,"data":{"turn":2,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The user is asking me to recall the project codeword that was mentioned earlier in the conversation. I was told to remember it: SAFFRON."}}}} -{"type":"assistant/chunk","seq":81,"time":1785498797511,"data":{"turn":2,"step":1,"chunk":{"type":"block-end","index":1,"block":{"type":"text","text":"SAFFRON"}}}} -{"type":"assistant/chunk","seq":82,"time":1785730450254,"data":{"turn":2,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":95,"outputTokens":35,"cacheReadTokens":2816,"reasoningTokens":31}}}} -{"type":"assistant/chunk","seq":83,"time":1785730450254,"data":{"turn":2,"step":1,"chunk":{"type":"finish","reason":{"kind":"stop"}}}} -{"type":"assistant/message","seq":84,"time":1785730450254,"data":{"turn":2,"step":1,"message":{"role":"assistant","content":[{"type":"reasoning","text":"The user is asking me to recall the project codeword that was mentioned earlier in the conversation. I was told to remember it: SAFFRON."},{"type":"text","text":"SAFFRON"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"e1f347c1-ce65-4ca9-8a9e-05e4366ef365"},"usage":{"inputTokens":95,"outputTokens":35,"cacheReadTokens":2816,"reasoningTokens":31}},"sourceEventSeqs":[44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83],"surfaceOp":"append"} -{"type":"step/end","seq":85,"time":1785730450254,"data":{"turn":2,"step":1}} -{"type":"turn/end","seq":86,"time":1785730450254,"data":{"turn":2,"reason":{"kind":"completed"}}} +{"type":"approval/policy","seq":37,"time":1786357524782,"data":{"policy":"never","source":"delegation"}} +{"type":"agent/inbox/spliced","seq":38,"time":1786357524783,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"What is the project codeword mentioned earlier in this conversation? Reply with exactly that one word and nothing else."}],"source":{"kind":"user"},"role":"user","id":"86e9f144-764f-460d-b72b-262cffe43d77"}]}} +{"type":"turn/start","seq":39,"time":1786357524783,"data":{"turn":2}} +{"type":"agent/inbox/spliced","seq":40,"time":1786357524783,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} +{"type":"subagent/descriptor","seq":41,"time":1786357524800,"data":{"version":2,"mode":"one-shot","provider":"fork","label":"Recall project codeword"}} +{"type":"step/start","seq":42,"time":1786357524803,"data":{"turn":2,"step":1}} +{"type":"user/message","seq":43,"time":1786357524803,"data":{"content":[{"type":"text","text":"What is the project codeword mentioned earlier in this conversation? Reply with exactly that one word and nothing else."}],"source":{"kind":"user"},"role":"user","id":"86e9f144-764f-460d-b72b-262cffe43d77"},"surfaceOp":"append"} +{"type":"user/message","seq":44,"time":1786358036899,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`).\n\nYou are a delegated subagent: your permission scope was fixed when you were started and cannot be widened from inside this session — operations that require approval are rejected automatically. When the task needs access beyond that scope, do not retry the denied operation; state the limitation in your reply so the delegating agent can handle it."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."},{"name":"subagent:delegation","text":"You are a delegated subagent: your permission scope was fixed when you were started and cannot be widened from inside this session — operations that require approval are rejected automatically. When the task needs access beyond that scope, do not retry the denied operation; state the limitation in your reply so the delegating agent can handle it."}]},"role":"user","id":"6ea5a774-b0da-47ff-84b7-226a4a207bbf"},"surfaceOp":"append"} +{"type":"request/header","seq":45,"time":1786358036900,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"resume"}} +{"type":"assistant/chunk","seq":46,"time":1783352148077,"data":{"turn":2,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}}} +{"type":"reasoning-chunks","seq0":47,"time0":1783352148077,"data":{"turn":2,"step":1,"index":0,"dt":[0,0,29,0,0,0,35,0,0,0,0,26,29,31,0,30,0,0,27,1,27,0,1,0,0,31,1,0,0,1790157964],"texts":["The"," user"," is"," asking"," me"," to"," recall"," the"," project"," cod","ew","ord"," that"," was"," mentioned"," earlier"," in"," the"," conversation","."," I"," was"," told"," to"," remember"," it",":"," SA","FF","RON","."]}} +{"type":"assistant/chunk","seq":78,"time":1785381573552,"data":{"turn":2,"step":1,"chunk":{"type":"block-start","index":1,"blockType":"text"}}} +{"type":"text-chunks","seq0":79,"time0":1785498797511,"data":{"turn":2,"step":1,"index":1,"dt":[0,0],"texts":["SA","FF","RON"]}} +{"type":"assistant/chunk","seq":82,"time":1785730450254,"data":{"turn":2,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The user is asking me to recall the project codeword that was mentioned earlier in the conversation. I was told to remember it: SAFFRON."}}}} +{"type":"assistant/chunk","seq":83,"time":1785730450254,"data":{"turn":2,"step":1,"chunk":{"type":"block-end","index":1,"block":{"type":"text","text":"SAFFRON"}}}} +{"type":"assistant/chunk","seq":84,"time":1786357524808,"data":{"turn":2,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":95,"outputTokens":35,"cacheReadTokens":2816,"reasoningTokens":31}}}} +{"type":"assistant/chunk","seq":85,"time":1786358036906,"data":{"turn":2,"step":1,"chunk":{"type":"finish","reason":{"kind":"stop"}}}} +{"type":"assistant/message","seq":86,"time":1786358036906,"data":{"turn":2,"step":1,"message":{"role":"assistant","content":[{"type":"reasoning","text":"The user is asking me to recall the project codeword that was mentioned earlier in the conversation. I was told to remember it: SAFFRON."},{"type":"text","text":"SAFFRON"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"e1f347c1-ce65-4ca9-8a9e-05e4366ef365"},"usage":{"inputTokens":95,"outputTokens":35,"cacheReadTokens":2816,"reasoningTokens":31}},"sourceEventSeqs":[46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85],"surfaceOp":"append"} +{"type":"step/end","seq":87,"time":1786358036906,"data":{"turn":2,"step":1}} +{"type":"turn/end","seq":88,"time":1786358036906,"data":{"turn":2,"reason":{"kind":"completed"}}} diff --git a/examples/acp-agent/tests/snapshots/subagent-mixed/session.jsonl b/examples/acp-agent/tests/snapshots/subagent-mixed/session.jsonl index fa390cf176..4963b5275b 100644 --- a/examples/acp-agent/tests/snapshots/subagent-mixed/session.jsonl +++ b/examples/acp-agent/tests/snapshots/subagent-mixed/session.jsonl @@ -4,7 +4,7 @@ {"type":"agent/inbox/spliced","seq":2,"time":1785821407687,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} {"type":"step/start","seq":3,"time":1783352142835,"data":{"turn":1,"step":1}} {"type":"user/message","seq":4,"time":1785498797379,"data":{"content":[{"type":"text","text":"Remember this fact for later: the project codeword is SAFFRON. Reply with the single word OK and stop. Do not use any tools."}],"source":{"kind":"user"},"role":"user","id":"3d1ea7cb-c273-4c38-a765-5ff256eaaf51"},"surfaceOp":"append"} -{"type":"user/message","seq":5,"time":1785730450135,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}]},"role":"user","id":"473ecf9e-52c4-4db2-be56-1c8f7fa7d932"},"surfaceOp":"append"} +{"type":"user/message","seq":5,"time":1785730450135,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}]},"role":"user","id":"e0a9678e-ff95-49f4-b4f7-4ace69a670a3"},"surfaceOp":"append"} {"type":"session/title","seq":6,"time":1785730450135,"data":{"title":"Remember this fact for later:","messageSeqs":[4],"source":{"kind":"fallback"}}} {"type":"request/header","seq":7,"time":1785498797380,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}} {"type":"request/context","seq":8,"time":1785730450136,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} diff --git a/examples/acp-agent/tests/snapshots/subagent-multi/session.1.jsonl b/examples/acp-agent/tests/snapshots/subagent-multi/session.1.jsonl index 7948013736..da79d6b23c 100644 --- a/examples/acp-agent/tests/snapshots/subagent-multi/session.1.jsonl +++ b/examples/acp-agent/tests/snapshots/subagent-multi/session.1.jsonl @@ -1,22 +1,23 @@ {"type":"session","version":0,"id":"553f8e92-aac1-4df3-8657-eacbb58f9581","createdAt":1783352127669,"cwd":"{{cwd}}","parentSession":"14dda109-5728-45ba-a002-7db9543fe50e","origin":"subagent","delegationDepth":1} -{"type":"agent/inbox/spliced","seq":0,"time":1785498794788,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Reply with exactly the word ALPHA and nothing else."}],"source":{"kind":"user"},"role":"user","id":"a287f842-f6f2-4a17-ab4c-820e41f498d5"}]}} -{"type":"turn/start","seq":1,"time":1785821405232,"data":{"turn":1}} -{"type":"agent/inbox/spliced","seq":2,"time":1785821405232,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} -{"type":"subagent/descriptor","seq":3,"time":1785821405245,"data":{"version":2,"mode":"one-shot","provider":"spawn","label":"Return ALPHA only"}} -{"type":"step/start","seq":4,"time":1785730447828,"data":{"turn":1,"step":1}} -{"type":"user/message","seq":5,"time":1785730447828,"data":{"content":[{"type":"text","text":"Reply with exactly the word ALPHA and nothing else."}],"source":{"kind":"user"},"role":"user","id":"a287f842-f6f2-4a17-ab4c-820e41f498d5"},"surfaceOp":"append"} -{"type":"user/message","seq":6,"time":1785730447828,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}]},"role":"user","id":"bab5cdff-7925-478d-b55a-daa2ef524d7c"},"surfaceOp":"append"} -{"type":"session/title","seq":7,"time":1785730447828,"data":{"title":"Reply with exactly the word","messageSeqs":[5],"source":{"kind":"fallback"}}} -{"type":"request/header","seq":8,"time":1785730447828,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}} -{"type":"request/context","seq":9,"time":1785730447828,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} -{"type":"assistant/chunk","seq":10,"time":1783352128280,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}}} -{"type":"reasoning-chunks","seq0":11,"time0":1783352128280,"data":{"turn":1,"step":1,"index":0,"dt":[0,0,0,1,19,0,0,0,0,1,31,0,0,0,0,32,1,0],"texts":["The"," user"," wants"," me"," to"," reply"," with"," exactly"," the"," word"," \"","AL","P","HA","\""," and"," nothing"," else","."]}} -{"type":"assistant/chunk","seq":30,"time":1783352128365,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":1,"blockType":"text"}}} -{"type":"text-chunks","seq0":31,"time0":1783352128365,"data":{"turn":1,"step":1,"index":1,"dt":[0,0],"texts":["AL","P","HA"]}} -{"type":"assistant/chunk","seq":34,"time":1783352128365,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The user wants me to reply with exactly the word \"ALPHA\" and nothing else."}}}} -{"type":"assistant/chunk","seq":35,"time":1785498794825,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":1,"block":{"type":"text","text":"ALPHA"}}}} -{"type":"assistant/chunk","seq":36,"time":1785730447834,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":49,"outputTokens":23,"cacheReadTokens":2816,"reasoningTokens":19}}}} -{"type":"assistant/chunk","seq":37,"time":1785730447834,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"stop"}}}} -{"type":"assistant/message","seq":38,"time":1785730447834,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"reasoning","text":"The user wants me to reply with exactly the word \"ALPHA\" and nothing else."},{"type":"text","text":"ALPHA"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"5f1e6087-da72-4a56-9bc0-ae1ac6618a8a"},"usage":{"inputTokens":49,"outputTokens":23,"cacheReadTokens":2816,"reasoningTokens":19}},"sourceEventSeqs":[10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"surfaceOp":"append"} -{"type":"step/end","seq":39,"time":1785730447834,"data":{"turn":1,"step":1}} -{"type":"turn/end","seq":40,"time":1785730447834,"data":{"turn":1,"reason":{"kind":"completed"}}} +{"type":"approval/policy","seq":0,"time":1786357521737,"data":{"policy":"never","source":"delegation"}} +{"type":"agent/inbox/spliced","seq":1,"time":1786357521737,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Reply with exactly the word ALPHA and nothing else."}],"source":{"kind":"user"},"role":"user","id":"a287f842-f6f2-4a17-ab4c-820e41f498d5"}]}} +{"type":"turn/start","seq":2,"time":1786357521737,"data":{"turn":1}} +{"type":"agent/inbox/spliced","seq":3,"time":1786357521737,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} +{"type":"subagent/descriptor","seq":4,"time":1786357521754,"data":{"version":2,"mode":"one-shot","provider":"spawn","label":"Return ALPHA only"}} +{"type":"step/start","seq":5,"time":1786357521756,"data":{"turn":1,"step":1}} +{"type":"user/message","seq":6,"time":1785730447828,"data":{"content":[{"type":"text","text":"Reply with exactly the word ALPHA and nothing else."}],"source":{"kind":"user"},"role":"user","id":"a287f842-f6f2-4a17-ab4c-820e41f498d5"},"surfaceOp":"append"} +{"type":"user/message","seq":7,"time":1786357521756,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`).\n\nYou are a delegated subagent: your permission scope was fixed when you were started and cannot be widened from inside this session — operations that require approval are rejected automatically. When the task needs access beyond that scope, do not retry the denied operation; state the limitation in your reply so the delegating agent can handle it."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."},{"name":"subagent:delegation","text":"You are a delegated subagent: your permission scope was fixed when you were started and cannot be widened from inside this session — operations that require approval are rejected automatically. When the task needs access beyond that scope, do not retry the denied operation; state the limitation in your reply so the delegating agent can handle it."}]},"role":"user","id":"f654b5a4-b4c0-4443-8eab-d84624d804f1"},"surfaceOp":"append"} +{"type":"session/title","seq":8,"time":1786357521756,"data":{"title":"Reply with exactly the word","messageSeqs":[6],"source":{"kind":"fallback"}}} +{"type":"request/header","seq":9,"time":1785730447828,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}} +{"type":"request/context","seq":10,"time":1785730447828,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} +{"type":"assistant/chunk","seq":11,"time":1783352128280,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}}} +{"type":"reasoning-chunks","seq0":12,"time0":1783352128280,"data":{"turn":1,"step":1,"index":0,"dt":[0,0,0,1,19,0,0,0,0,1,31,0,0,0,0,32,1,0],"texts":["The"," user"," wants"," me"," to"," reply"," with"," exactly"," the"," word"," \"","AL","P","HA","\""," and"," nothing"," else","."]}} +{"type":"assistant/chunk","seq":31,"time":1783352128365,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":1,"blockType":"text"}}} +{"type":"text-chunks","seq0":32,"time0":1783352128365,"data":{"turn":1,"step":1,"index":1,"dt":[0,0],"texts":["AL","P","HA"]}} +{"type":"assistant/chunk","seq":35,"time":1783352128365,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The user wants me to reply with exactly the word \"ALPHA\" and nothing else."}}}} +{"type":"assistant/chunk","seq":36,"time":1785498794825,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":1,"block":{"type":"text","text":"ALPHA"}}}} +{"type":"assistant/chunk","seq":37,"time":1785730447834,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":49,"outputTokens":23,"cacheReadTokens":2816,"reasoningTokens":19}}}} +{"type":"assistant/chunk","seq":38,"time":1785730447834,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"stop"}}}} +{"type":"assistant/message","seq":39,"time":1785730447834,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"reasoning","text":"The user wants me to reply with exactly the word \"ALPHA\" and nothing else."},{"type":"text","text":"ALPHA"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"5f1e6087-da72-4a56-9bc0-ae1ac6618a8a"},"usage":{"inputTokens":49,"outputTokens":23,"cacheReadTokens":2816,"reasoningTokens":19}},"sourceEventSeqs":[11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38],"surfaceOp":"append"} +{"type":"step/end","seq":40,"time":1785730447834,"data":{"turn":1,"step":1}} +{"type":"turn/end","seq":41,"time":1785730447834,"data":{"turn":1,"reason":{"kind":"completed"}}} diff --git a/examples/acp-agent/tests/snapshots/subagent-multi/session.2.jsonl b/examples/acp-agent/tests/snapshots/subagent-multi/session.2.jsonl index 64e58b3741..f7326e37c8 100644 --- a/examples/acp-agent/tests/snapshots/subagent-multi/session.2.jsonl +++ b/examples/acp-agent/tests/snapshots/subagent-multi/session.2.jsonl @@ -1,23 +1,24 @@ {"type":"session","version":0,"id":"5f49e80c-16fc-42c7-a617-0b6bd0680aa3","createdAt":1783352129662,"cwd":"{{cwd}}","parentSession":"14dda109-5728-45ba-a002-7db9543fe50e","origin":"subagent","delegationDepth":1} -{"type":"agent/inbox/spliced","seq":0,"time":1785498794853,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Reply with exactly the word BETA and nothing else."}],"source":{"kind":"user"},"role":"user","id":"53f6419d-8ddc-4eee-8803-5b68411336f9"}]}} -{"type":"turn/start","seq":1,"time":1785821405286,"data":{"turn":1}} -{"type":"agent/inbox/spliced","seq":2,"time":1785821405286,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} -{"type":"subagent/descriptor","seq":3,"time":1785821405299,"data":{"version":2,"mode":"one-shot","provider":"spawn","label":"Return BETA only"}} -{"type":"step/start","seq":4,"time":1785730447881,"data":{"turn":1,"step":1}} -{"type":"user/message","seq":5,"time":1785730447881,"data":{"content":[{"type":"text","text":"Reply with exactly the word BETA and nothing else."}],"source":{"kind":"user"},"role":"user","id":"53f6419d-8ddc-4eee-8803-5b68411336f9"},"surfaceOp":"append"} -{"type":"user/message","seq":6,"time":1785730447881,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}]},"role":"user","id":"036067ef-a106-4955-841c-a0d2effe51ef"},"surfaceOp":"append"} -{"type":"session/title","seq":7,"time":1785730447881,"data":{"title":"Reply with exactly the word","messageSeqs":[5],"source":{"kind":"fallback"}}} -{"type":"request/header","seq":8,"time":1785730447881,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}} -{"type":"request/context","seq":9,"time":1785730447881,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} -{"type":"assistant/chunk","seq":10,"time":1783352130413,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}}} -{"type":"reasoning-chunks","seq0":11,"time0":1783352130413,"data":{"turn":1,"step":1,"index":0,"dt":[0,0,0,0,35,0,0,0,0,0,36,0,0,0,0,0,43],"texts":["The"," user"," wants"," me"," to"," reply"," with"," exactly"," the"," word"," \"","B","ETA","\""," and"," nothing"," else","."]}} -{"type":"assistant/chunk","seq":29,"time":1783352130527,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":1,"blockType":"text"}}} -{"type":"assistant/chunk","seq":30,"time":1783352130527,"data":{"turn":1,"step":1,"chunk":{"type":"text-delta","index":1,"text":"B"}}} -{"type":"assistant/chunk","seq":31,"time":1783352130527,"data":{"turn":1,"step":1,"chunk":{"type":"text-delta","index":1,"text":"ETA"}}} -{"type":"assistant/chunk","seq":32,"time":1783352130527,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The user wants me to reply with exactly the word \"BETA\" and nothing else."}}}} -{"type":"assistant/chunk","seq":33,"time":1785498794882,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":1,"block":{"type":"text","text":"BETA"}}}} -{"type":"assistant/chunk","seq":34,"time":1785730447887,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":48,"outputTokens":21,"cacheReadTokens":2816,"reasoningTokens":18}}}} -{"type":"assistant/chunk","seq":35,"time":1785730447887,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"stop"}}}} -{"type":"assistant/message","seq":36,"time":1785730447887,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"reasoning","text":"The user wants me to reply with exactly the word \"BETA\" and nothing else."},{"type":"text","text":"BETA"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"adc4527d-efd1-4c89-b42b-826c33f2bb12"},"usage":{"inputTokens":48,"outputTokens":21,"cacheReadTokens":2816,"reasoningTokens":18}},"sourceEventSeqs":[10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35],"surfaceOp":"append"} -{"type":"step/end","seq":37,"time":1785730447887,"data":{"turn":1,"step":1}} -{"type":"turn/end","seq":38,"time":1785730447887,"data":{"turn":1,"reason":{"kind":"completed"}}} +{"type":"approval/policy","seq":0,"time":1786357521782,"data":{"policy":"never","source":"delegation"}} +{"type":"agent/inbox/spliced","seq":1,"time":1786357521783,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Reply with exactly the word BETA and nothing else."}],"source":{"kind":"user"},"role":"user","id":"53f6419d-8ddc-4eee-8803-5b68411336f9"}]}} +{"type":"turn/start","seq":2,"time":1786357521783,"data":{"turn":1}} +{"type":"agent/inbox/spliced","seq":3,"time":1786357521783,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} +{"type":"subagent/descriptor","seq":4,"time":1786357521799,"data":{"version":2,"mode":"one-shot","provider":"spawn","label":"Return BETA only"}} +{"type":"step/start","seq":5,"time":1786357521801,"data":{"turn":1,"step":1}} +{"type":"user/message","seq":6,"time":1785730447881,"data":{"content":[{"type":"text","text":"Reply with exactly the word BETA and nothing else."}],"source":{"kind":"user"},"role":"user","id":"53f6419d-8ddc-4eee-8803-5b68411336f9"},"surfaceOp":"append"} +{"type":"user/message","seq":7,"time":1786357521802,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`).\n\nYou are a delegated subagent: your permission scope was fixed when you were started and cannot be widened from inside this session — operations that require approval are rejected automatically. When the task needs access beyond that scope, do not retry the denied operation; state the limitation in your reply so the delegating agent can handle it."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."},{"name":"subagent:delegation","text":"You are a delegated subagent: your permission scope was fixed when you were started and cannot be widened from inside this session — operations that require approval are rejected automatically. When the task needs access beyond that scope, do not retry the denied operation; state the limitation in your reply so the delegating agent can handle it."}]},"role":"user","id":"05843da4-4a5f-46fc-a00f-5257b2bd271d"},"surfaceOp":"append"} +{"type":"session/title","seq":8,"time":1786357521802,"data":{"title":"Reply with exactly the word","messageSeqs":[6],"source":{"kind":"fallback"}}} +{"type":"request/header","seq":9,"time":1785730447881,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}} +{"type":"request/context","seq":10,"time":1785730447881,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} +{"type":"assistant/chunk","seq":11,"time":1783352130413,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}}} +{"type":"reasoning-chunks","seq0":12,"time0":1783352130413,"data":{"turn":1,"step":1,"index":0,"dt":[0,0,0,0,35,0,0,0,0,0,36,0,0,0,0,0,43],"texts":["The"," user"," wants"," me"," to"," reply"," with"," exactly"," the"," word"," \"","B","ETA","\""," and"," nothing"," else","."]}} +{"type":"assistant/chunk","seq":30,"time":1783352130527,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":1,"blockType":"text"}}} +{"type":"assistant/chunk","seq":31,"time":1783352130527,"data":{"turn":1,"step":1,"chunk":{"type":"text-delta","index":1,"text":"B"}}} +{"type":"assistant/chunk","seq":32,"time":1783352130527,"data":{"turn":1,"step":1,"chunk":{"type":"text-delta","index":1,"text":"ETA"}}} +{"type":"assistant/chunk","seq":33,"time":1783352130527,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The user wants me to reply with exactly the word \"BETA\" and nothing else."}}}} +{"type":"assistant/chunk","seq":34,"time":1785498794882,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":1,"block":{"type":"text","text":"BETA"}}}} +{"type":"assistant/chunk","seq":35,"time":1785730447887,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":48,"outputTokens":21,"cacheReadTokens":2816,"reasoningTokens":18}}}} +{"type":"assistant/chunk","seq":36,"time":1785730447887,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"stop"}}}} +{"type":"assistant/message","seq":37,"time":1785730447887,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"reasoning","text":"The user wants me to reply with exactly the word \"BETA\" and nothing else."},{"type":"text","text":"BETA"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"adc4527d-efd1-4c89-b42b-826c33f2bb12"},"usage":{"inputTokens":48,"outputTokens":21,"cacheReadTokens":2816,"reasoningTokens":18}},"sourceEventSeqs":[11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36],"surfaceOp":"append"} +{"type":"step/end","seq":38,"time":1785730447887,"data":{"turn":1,"step":1}} +{"type":"turn/end","seq":39,"time":1785730447887,"data":{"turn":1,"reason":{"kind":"completed"}}} diff --git a/examples/acp-agent/tests/snapshots/subagent-multi/session.jsonl b/examples/acp-agent/tests/snapshots/subagent-multi/session.jsonl index 3a48c2d760..a1337e166b 100644 --- a/examples/acp-agent/tests/snapshots/subagent-multi/session.jsonl +++ b/examples/acp-agent/tests/snapshots/subagent-multi/session.jsonl @@ -4,7 +4,7 @@ {"type":"agent/inbox/spliced","seq":2,"time":1785821405184,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} {"type":"step/start","seq":3,"time":1783352126252,"data":{"turn":1,"step":1}} {"type":"user/message","seq":4,"time":1785498794765,"data":{"content":[{"type":"text","text":"Use the subagent tool TWICE, once at a time, to delegate two subtasks to child agents. First subtask: 'Reply with exactly the word ALPHA and nothing else.' Second subtask (after the first returns): 'Reply with exactly the word BETA and nothing else.' After both subagents return, reply with the single word PARENT_DONE and stop. Do not use the bash tool."}],"source":{"kind":"user"},"role":"user","id":"07bf16df-0499-420d-9510-3204061f0122"},"surfaceOp":"append"} -{"type":"user/message","seq":5,"time":1785730447790,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}]},"role":"user","id":"9b4b262d-cbd7-4cd8-b24b-70b2b401b0fe"},"surfaceOp":"append"} +{"type":"user/message","seq":5,"time":1785730447790,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}]},"role":"user","id":"50a1100d-448e-41f2-8f99-39be199db492"},"surfaceOp":"append"} {"type":"session/title","seq":6,"time":1785730447790,"data":{"title":"Use the subagent tool TWICE,","messageSeqs":[4],"source":{"kind":"fallback"}}} {"type":"request/header","seq":7,"time":1785498794766,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}} {"type":"request/context","seq":8,"time":1785730447791,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} diff --git a/examples/acp-agent/tests/snapshots/subagent-published-run-failure/session.1.jsonl b/examples/acp-agent/tests/snapshots/subagent-published-run-failure/session.1.jsonl new file mode 100644 index 0000000000..a0433f1290 --- /dev/null +++ b/examples/acp-agent/tests/snapshots/subagent-published-run-failure/session.1.jsonl @@ -0,0 +1,2 @@ +{"type":"session","version":0,"id":"eb69342c-62b6-4320-a78b-961745f89333","createdAt":1786358409171,"cwd":"{{cwd}}","parentSession":"11111111-1111-4111-8111-111111111111","origin":"subagent","delegationDepth":1} +{"type":"approval/policy","seq":0,"time":1786358409171,"data":{"policy":"never","source":"delegation"}} diff --git a/examples/acp-agent/tests/snapshots/subagent-report/session.1.jsonl b/examples/acp-agent/tests/snapshots/subagent-report/session.1.jsonl index b9992f1519..e32d1bdee0 100644 --- a/examples/acp-agent/tests/snapshots/subagent-report/session.1.jsonl +++ b/examples/acp-agent/tests/snapshots/subagent-report/session.1.jsonl @@ -1,30 +1,31 @@ {"type":"session","version":0,"id":"33333333-3333-4333-8333-333333333333","createdAt":1789000001000,"cwd":"{{cwd}}","parentSession":"11111111-1111-4111-8111-111111111111","origin":"subagent","delegationDepth":1} {"type":"subagent/descriptor","seq":0,"time":1785594881508,"data":{"version":2,"mode":"continuable","provider":"spawn","label":"Report a finding","agentProvider":"deepseek-official","agentModel":"deepseek-v4-flash"}} {"type":"session/end-seed","seq":1,"time":1785594881508,"data":{}} -{"type":"agent/inbox/spliced","seq":2,"time":1785730453612,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Call the report tool once with output exactly CHILD_REPORT_OK, then stop."}],"source":{"kind":"user"},"role":"user","id":"9045ac78-393a-4f24-b20d-8999286dd6ce"}]}} -{"type":"turn/start","seq":3,"time":1785821411475,"data":{"turn":1}} -{"type":"agent/inbox/spliced","seq":4,"time":1785821411475,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} -{"type":"step/start","seq":5,"time":1785730453639,"data":{"turn":1,"step":1}} -{"type":"user/message","seq":6,"time":1785730453639,"data":{"content":[{"type":"text","text":"Call the report tool once with output exactly CHILD_REPORT_OK, then stop."}],"source":{"kind":"user"},"role":"user","id":"9045ac78-393a-4f24-b20d-8999286dd6ce"},"surfaceOp":"append"} -{"type":"user/message","seq":7,"time":1785730453639,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}]},"role":"user","id":"67c76a21-6142-45a6-9a49-0485f51edc8d"},"surfaceOp":"append"} -{"type":"session/title","seq":8,"time":1785730453639,"data":{"title":"Call the report tool once","messageSeqs":[6],"source":{"kind":"fallback"}}} -{"type":"request/header","seq":9,"time":1785730453639,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}} -{"type":"request/context","seq":10,"time":1785730453639,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} -{"type":"assistant/chunk","seq":11,"time":1785594881546,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}}} -{"type":"assistant/chunk","seq":12,"time":1785594881546,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":0,"id":"call_report_1","name":"report","argumentsDelta":"{\"output\": \"CHILD_REPORT_OK\"}"}}} -{"type":"assistant/chunk","seq":13,"time":1789000001010,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"call_report_1","name":"report","arguments":"{\"output\": \"CHILD_REPORT_OK\"}"}}}} -{"type":"assistant/chunk","seq":14,"time":1789000001011,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}}} -{"type":"assistant/chunk","seq":15,"time":1785730453647,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}} -{"type":"assistant/message","seq":16,"time":1785730453647,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"tool-call","id":"call_report_1","name":"report","arguments":"{\"output\": \"CHILD_REPORT_OK\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"c9e50afb-b732-41ab-b0fc-8e98948ad9ec"},"usage":{"inputTokens":10,"outputTokens":5}},"sourceEventSeqs":[11,12,13,14,15],"surfaceOp":"append"} -{"type":"tool/call","seq":17,"time":1785730453647,"data":{"turn":1,"step":1,"callId":"call_report_1","name":"report","arguments":"{\"output\": \"CHILD_REPORT_OK\"}"}} -{"type":"tool/result","seq":18,"time":1785730453654,"data":{"turn":1,"step":1,"message":{"source":{"kind":"tool","callId":"call_report_1"},"content":[{"type":"tool-result","toolCallId":"call_report_1","content":[{"type":"text","text":"report accepted by the agent that started you as message 824dc60a-f9d7-48ea-a0d4-6d56df83bd4f"}],"isError":false}],"role":"user","id":"e6764773-c667-40b5-a13f-8bdc5a9c7762"}},"sourceEventSeqs":[17],"surfaceOp":"append"} -{"type":"step/end","seq":19,"time":1785730453654,"data":{"turn":1,"step":1}} -{"type":"step/start","seq":20,"time":1785730453664,"data":{"turn":1,"step":2}} -{"type":"assistant/chunk","seq":21,"time":1785594881567,"data":{"turn":1,"step":2,"chunk":{"type":"block-start","index":0,"blockType":"text"}}} -{"type":"assistant/chunk","seq":22,"time":1785594881567,"data":{"turn":1,"step":2,"chunk":{"type":"text-delta","index":0,"text":"Reported."}}} -{"type":"assistant/chunk","seq":23,"time":1789000001020,"data":{"turn":1,"step":2,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"Reported."}}}} -{"type":"assistant/chunk","seq":24,"time":1789000001021,"data":{"turn":1,"step":2,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}}} -{"type":"assistant/chunk","seq":25,"time":1785730453668,"data":{"turn":1,"step":2,"chunk":{"type":"finish","reason":{"kind":"stop"}}}} -{"type":"assistant/message","seq":26,"time":1785730453668,"data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"text","text":"Reported."}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"96784835-2d0f-4d00-aef5-ee3a14820dd1"},"usage":{"inputTokens":10,"outputTokens":5}},"sourceEventSeqs":[21,22,23,24,25],"surfaceOp":"append"} -{"type":"step/end","seq":27,"time":1785730453668,"data":{"turn":1,"step":2}} -{"type":"turn/end","seq":28,"time":1785730453668,"data":{"turn":1,"reason":{"kind":"completed"}}} +{"type":"approval/policy","seq":2,"time":1786357530605,"data":{"policy":"never","source":"delegation"}} +{"type":"agent/inbox/spliced","seq":3,"time":1786357530605,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Call the report tool once with output exactly CHILD_REPORT_OK, then stop."}],"source":{"kind":"user"},"role":"user","id":"9045ac78-393a-4f24-b20d-8999286dd6ce"}]}} +{"type":"turn/start","seq":4,"time":1786357530605,"data":{"turn":1}} +{"type":"agent/inbox/spliced","seq":5,"time":1786357530605,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} +{"type":"step/start","seq":6,"time":1786357530633,"data":{"turn":1,"step":1}} +{"type":"user/message","seq":7,"time":1785730453639,"data":{"content":[{"type":"text","text":"Call the report tool once with output exactly CHILD_REPORT_OK, then stop."}],"source":{"kind":"user"},"role":"user","id":"9045ac78-393a-4f24-b20d-8999286dd6ce"},"surfaceOp":"append"} +{"type":"user/message","seq":8,"time":1786357530633,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`).\n\nYou are a delegated subagent: your permission scope was fixed when you were started and cannot be widened from inside this session — operations that require approval are rejected automatically. When the task needs access beyond that scope, do not retry the denied operation; state the limitation in your reply so the delegating agent can handle it."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."},{"name":"subagent:delegation","text":"You are a delegated subagent: your permission scope was fixed when you were started and cannot be widened from inside this session — operations that require approval are rejected automatically. When the task needs access beyond that scope, do not retry the denied operation; state the limitation in your reply so the delegating agent can handle it."}]},"role":"user","id":"1677b901-cce7-461a-8b2a-7f119dd9d845"},"surfaceOp":"append"} +{"type":"session/title","seq":9,"time":1786357530633,"data":{"title":"Call the report tool once","messageSeqs":[7],"source":{"kind":"fallback"}}} +{"type":"request/header","seq":10,"time":1785730453639,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}} +{"type":"request/context","seq":11,"time":1785730453639,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} +{"type":"assistant/chunk","seq":12,"time":1785594881546,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}}} +{"type":"assistant/chunk","seq":13,"time":1785594881546,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":0,"id":"call_report_1","name":"report","argumentsDelta":"{\"output\": \"CHILD_REPORT_OK\"}"}}} +{"type":"assistant/chunk","seq":14,"time":1789000001010,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"call_report_1","name":"report","arguments":"{\"output\": \"CHILD_REPORT_OK\"}"}}}} +{"type":"assistant/chunk","seq":15,"time":1789000001011,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}}} +{"type":"assistant/chunk","seq":16,"time":1785730453647,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}} +{"type":"assistant/message","seq":17,"time":1785730453647,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"tool-call","id":"call_report_1","name":"report","arguments":"{\"output\": \"CHILD_REPORT_OK\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"c9e50afb-b732-41ab-b0fc-8e98948ad9ec"},"usage":{"inputTokens":10,"outputTokens":5}},"sourceEventSeqs":[12,13,14,15,16],"surfaceOp":"append"} +{"type":"tool/call","seq":18,"time":1785730453647,"data":{"turn":1,"step":1,"callId":"call_report_1","name":"report","arguments":"{\"output\": \"CHILD_REPORT_OK\"}"}} +{"type":"tool/result","seq":19,"time":1785730453654,"data":{"turn":1,"step":1,"message":{"source":{"kind":"tool","callId":"call_report_1"},"content":[{"type":"tool-result","toolCallId":"call_report_1","content":[{"type":"text","text":"report accepted by the agent that started you as message 1f4b61e2-6c6d-4db8-836b-ac5760c5e484"}],"isError":false}],"role":"user","id":"cee5f084-bfab-423d-b8bc-1b1b7d88d4fa"}},"sourceEventSeqs":[18],"surfaceOp":"append"} +{"type":"step/end","seq":20,"time":1785730453654,"data":{"turn":1,"step":1}} +{"type":"step/start","seq":21,"time":1785730453664,"data":{"turn":1,"step":2}} +{"type":"assistant/chunk","seq":22,"time":1785594881567,"data":{"turn":1,"step":2,"chunk":{"type":"block-start","index":0,"blockType":"text"}}} +{"type":"assistant/chunk","seq":23,"time":1785594881567,"data":{"turn":1,"step":2,"chunk":{"type":"text-delta","index":0,"text":"Reported."}}} +{"type":"assistant/chunk","seq":24,"time":1789000001020,"data":{"turn":1,"step":2,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"Reported."}}}} +{"type":"assistant/chunk","seq":25,"time":1789000001021,"data":{"turn":1,"step":2,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}}} +{"type":"assistant/chunk","seq":26,"time":1785730453668,"data":{"turn":1,"step":2,"chunk":{"type":"finish","reason":{"kind":"stop"}}}} +{"type":"assistant/message","seq":27,"time":1785730453668,"data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"text","text":"Reported."}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"96784835-2d0f-4d00-aef5-ee3a14820dd1"},"usage":{"inputTokens":10,"outputTokens":5}},"sourceEventSeqs":[22,23,24,25,26],"surfaceOp":"append"} +{"type":"step/end","seq":28,"time":1785730453668,"data":{"turn":1,"step":2}} +{"type":"turn/end","seq":29,"time":1785730453668,"data":{"turn":1,"reason":{"kind":"completed"}}} diff --git a/examples/acp-agent/tests/snapshots/subagent-report/session.jsonl b/examples/acp-agent/tests/snapshots/subagent-report/session.jsonl index db5cd4a77f..eb36af2399 100644 --- a/examples/acp-agent/tests/snapshots/subagent-report/session.jsonl +++ b/examples/acp-agent/tests/snapshots/subagent-report/session.jsonl @@ -4,7 +4,7 @@ {"type":"agent/inbox/spliced","seq":2,"time":1785821411429,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} {"type":"step/start","seq":3,"time":1785730453591,"data":{"turn":1,"step":1}} {"type":"user/message","seq":4,"time":1785730453591,"data":{"content":[{"type":"text","text":"Follow these steps exactly, then stop. 1. Call the subagent tool once with run_in_background set to true, description 'Report a finding', and prompt 'Call the report tool once with output exactly CHILD_REPORT_OK, then stop.'. 2. Reply with the single word STARTED. Do not use the bash tool."}],"source":{"kind":"user"},"role":"user","id":"5cf78378-e004-4fd5-af4f-cef3b7e190ad"},"surfaceOp":"append"} -{"type":"user/message","seq":5,"time":1785730453592,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}]},"role":"user","id":"77141070-eb99-4ec0-908d-646c387982f6"},"surfaceOp":"append"} +{"type":"user/message","seq":5,"time":1785730453592,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}]},"role":"user","id":"d1a851a3-604f-4a42-8e5f-4e480857a3b4"},"surfaceOp":"append"} {"type":"session/title","seq":6,"time":1785730453592,"data":{"title":"Follow these steps exactly, then","messageSeqs":[4],"source":{"kind":"fallback"}}} {"type":"request/header","seq":7,"time":1785730453592,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}} {"type":"request/context","seq":8,"time":1785730453593,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} diff --git a/examples/acp-agent/tests/snapshots/subagent-spawn/session.1.jsonl b/examples/acp-agent/tests/snapshots/subagent-spawn/session.1.jsonl index 7fa229c2e3..5eb0455932 100644 --- a/examples/acp-agent/tests/snapshots/subagent-spawn/session.1.jsonl +++ b/examples/acp-agent/tests/snapshots/subagent-spawn/session.1.jsonl @@ -1,22 +1,23 @@ {"type":"session","version":0,"id":"ea339828-7885-42e1-9083-4355e6f1708d","createdAt":1783352120855,"cwd":"{{cwd}}","parentSession":"5138ed0d-e86e-4a7d-b75b-803307e92b17","origin":"subagent","delegationDepth":1} -{"type":"agent/inbox/spliced","seq":0,"time":1785498793648,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Reply with exactly the word CHILD_OK and nothing else."}],"source":{"kind":"user"},"role":"user","id":"54ed23d6-e960-4f36-b192-cf06e1618ea6"}]}} -{"type":"turn/start","seq":1,"time":1785821404007,"data":{"turn":1}} -{"type":"agent/inbox/spliced","seq":2,"time":1785821404007,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} -{"type":"subagent/descriptor","seq":3,"time":1785821404020,"data":{"version":2,"mode":"one-shot","provider":"spawn","label":"Reply with CHILD_OK"}} -{"type":"step/start","seq":4,"time":1785730446720,"data":{"turn":1,"step":1}} -{"type":"user/message","seq":5,"time":1785730446720,"data":{"content":[{"type":"text","text":"Reply with exactly the word CHILD_OK and nothing else."}],"source":{"kind":"user"},"role":"user","id":"54ed23d6-e960-4f36-b192-cf06e1618ea6"},"surfaceOp":"append"} -{"type":"user/message","seq":6,"time":1785730446720,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}]},"role":"user","id":"1b537017-6493-4f52-8504-01a7384e8cc6"},"surfaceOp":"append"} -{"type":"session/title","seq":7,"time":1785730446720,"data":{"title":"Reply with exactly the word","messageSeqs":[5],"source":{"kind":"fallback"}}} -{"type":"request/header","seq":8,"time":1785730446720,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}} -{"type":"request/context","seq":9,"time":1785730446721,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} -{"type":"assistant/chunk","seq":10,"time":1783352121663,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}}} -{"type":"reasoning-chunks","seq0":11,"time0":1783352121664,"data":{"turn":1,"step":1,"index":0,"dt":[0,0,0,0,27,0,0,29,0,0,27,0,0,0,0,1],"texts":["The"," user"," wants"," me"," to"," reply"," with"," exactly"," the"," word"," CH","ILD","_OK"," and"," nothing"," else","."]}} -{"type":"assistant/chunk","seq":28,"time":1783352121777,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":1,"blockType":"text"}}} -{"type":"text-chunks","seq0":29,"time0":1783352121777,"data":{"turn":1,"step":1,"index":1,"dt":[0,0],"texts":["CH","ILD","_OK"]}} -{"type":"assistant/chunk","seq":32,"time":1783352121777,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The user wants me to reply with exactly the word CHILD_OK and nothing else."}}}} -{"type":"assistant/chunk","seq":33,"time":1785498793670,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":1,"block":{"type":"text","text":"CHILD_OK"}}}} -{"type":"assistant/chunk","seq":34,"time":1785730446727,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":48,"outputTokens":21,"cacheReadTokens":2816,"reasoningTokens":17}}}} -{"type":"assistant/chunk","seq":35,"time":1785730446727,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"stop"}}}} -{"type":"assistant/message","seq":36,"time":1785730446727,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"reasoning","text":"The user wants me to reply with exactly the word CHILD_OK and nothing else."},{"type":"text","text":"CHILD_OK"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"16118fc6-2262-476e-9a4a-4b533cff09bc"},"usage":{"inputTokens":48,"outputTokens":21,"cacheReadTokens":2816,"reasoningTokens":17}},"sourceEventSeqs":[10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35],"surfaceOp":"append"} -{"type":"step/end","seq":37,"time":1785730446727,"data":{"turn":1,"step":1}} -{"type":"turn/end","seq":38,"time":1785730446727,"data":{"turn":1,"reason":{"kind":"completed"}}} +{"type":"approval/policy","seq":0,"time":1786357520283,"data":{"policy":"never","source":"delegation"}} +{"type":"agent/inbox/spliced","seq":1,"time":1786357520283,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Reply with exactly the word CHILD_OK and nothing else."}],"source":{"kind":"user"},"role":"user","id":"54ed23d6-e960-4f36-b192-cf06e1618ea6"}]}} +{"type":"turn/start","seq":2,"time":1786357520283,"data":{"turn":1}} +{"type":"agent/inbox/spliced","seq":3,"time":1786357520283,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} +{"type":"subagent/descriptor","seq":4,"time":1786357520300,"data":{"version":2,"mode":"one-shot","provider":"spawn","label":"Reply with CHILD_OK"}} +{"type":"step/start","seq":5,"time":1786357520303,"data":{"turn":1,"step":1}} +{"type":"user/message","seq":6,"time":1785730446720,"data":{"content":[{"type":"text","text":"Reply with exactly the word CHILD_OK and nothing else."}],"source":{"kind":"user"},"role":"user","id":"54ed23d6-e960-4f36-b192-cf06e1618ea6"},"surfaceOp":"append"} +{"type":"user/message","seq":7,"time":1786357520303,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`).\n\nYou are a delegated subagent: your permission scope was fixed when you were started and cannot be widened from inside this session — operations that require approval are rejected automatically. When the task needs access beyond that scope, do not retry the denied operation; state the limitation in your reply so the delegating agent can handle it."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."},{"name":"subagent:delegation","text":"You are a delegated subagent: your permission scope was fixed when you were started and cannot be widened from inside this session — operations that require approval are rejected automatically. When the task needs access beyond that scope, do not retry the denied operation; state the limitation in your reply so the delegating agent can handle it."}]},"role":"user","id":"24630f5a-f790-469f-96a6-cf234ded3759"},"surfaceOp":"append"} +{"type":"session/title","seq":8,"time":1786357520303,"data":{"title":"Reply with exactly the word","messageSeqs":[6],"source":{"kind":"fallback"}}} +{"type":"request/header","seq":9,"time":1785730446720,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}} +{"type":"request/context","seq":10,"time":1785730446721,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} +{"type":"assistant/chunk","seq":11,"time":1783352121663,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}}} +{"type":"reasoning-chunks","seq0":12,"time0":1783352121664,"data":{"turn":1,"step":1,"index":0,"dt":[0,0,0,0,27,0,0,29,0,0,27,0,0,0,0,1],"texts":["The"," user"," wants"," me"," to"," reply"," with"," exactly"," the"," word"," CH","ILD","_OK"," and"," nothing"," else","."]}} +{"type":"assistant/chunk","seq":29,"time":1783352121777,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":1,"blockType":"text"}}} +{"type":"text-chunks","seq0":30,"time0":1783352121777,"data":{"turn":1,"step":1,"index":1,"dt":[0,0],"texts":["CH","ILD","_OK"]}} +{"type":"assistant/chunk","seq":33,"time":1783352121777,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The user wants me to reply with exactly the word CHILD_OK and nothing else."}}}} +{"type":"assistant/chunk","seq":34,"time":1785498793670,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":1,"block":{"type":"text","text":"CHILD_OK"}}}} +{"type":"assistant/chunk","seq":35,"time":1785730446727,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":48,"outputTokens":21,"cacheReadTokens":2816,"reasoningTokens":17}}}} +{"type":"assistant/chunk","seq":36,"time":1785730446727,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"stop"}}}} +{"type":"assistant/message","seq":37,"time":1785730446727,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"reasoning","text":"The user wants me to reply with exactly the word CHILD_OK and nothing else."},{"type":"text","text":"CHILD_OK"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"16118fc6-2262-476e-9a4a-4b533cff09bc"},"usage":{"inputTokens":48,"outputTokens":21,"cacheReadTokens":2816,"reasoningTokens":17}},"sourceEventSeqs":[11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36],"surfaceOp":"append"} +{"type":"step/end","seq":38,"time":1785730446727,"data":{"turn":1,"step":1}} +{"type":"turn/end","seq":39,"time":1785730446727,"data":{"turn":1,"reason":{"kind":"completed"}}} diff --git a/examples/acp-agent/tests/snapshots/subagent-spawn/session.jsonl b/examples/acp-agent/tests/snapshots/subagent-spawn/session.jsonl index edf8950dac..0ac1be7454 100644 --- a/examples/acp-agent/tests/snapshots/subagent-spawn/session.jsonl +++ b/examples/acp-agent/tests/snapshots/subagent-spawn/session.jsonl @@ -4,7 +4,7 @@ {"type":"agent/inbox/spliced","seq":2,"time":1785821403947,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} {"type":"step/start","seq":3,"time":1783352119275,"data":{"turn":1,"step":1}} {"type":"user/message","seq":4,"time":1785498793625,"data":{"content":[{"type":"text","text":"Use the subagent tool exactly once to delegate this subtask to a child agent: 'Reply with exactly the word CHILD_OK and nothing else.' After the subagent returns, reply with the single word PARENT_DONE and stop. Do not use the bash tool."}],"source":{"kind":"user"},"role":"user","id":"a9485ebd-2b4a-434a-bc35-afd757ce141b"},"surfaceOp":"append"} -{"type":"user/message","seq":5,"time":1785730446685,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}]},"role":"user","id":"e40b1354-1856-48c3-a638-1be67af32920"},"surfaceOp":"append"} +{"type":"user/message","seq":5,"time":1785730446685,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}]},"role":"user","id":"bfd99a70-ad54-4073-9c0d-8a63711fe34a"},"surfaceOp":"append"} {"type":"session/title","seq":6,"time":1785730446685,"data":{"title":"Use the subagent tool exactly","messageSeqs":[4],"source":{"kind":"fallback"}}} {"type":"request/header","seq":7,"time":1785498793626,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}} {"type":"request/context","seq":8,"time":1785730446686,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} diff --git a/examples/acp-agent/tests/snapshots/workflow-run/session.1.jsonl b/examples/acp-agent/tests/snapshots/workflow-run/session.1.jsonl index 7b77a09f5e..080198e7bc 100644 --- a/examples/acp-agent/tests/snapshots/workflow-run/session.1.jsonl +++ b/examples/acp-agent/tests/snapshots/workflow-run/session.1.jsonl @@ -1,22 +1,23 @@ {"type":"session","version":0,"id":"583a4db2-3350-436c-b4a5-5615fd159052","createdAt":1783600636316,"cwd":"{{cwd}}","parentSession":"3fd7d599-56b1-493a-930d-f1fc5e1556e8","origin":"subagent","delegationDepth":1} -{"type":"agent/inbox/spliced","seq":0,"time":1785498800317,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Reply with exactly the word WF_CHILD_OK and nothing else."}],"source":{"kind":"user"},"role":"user","id":"f0f46771-663a-494a-8d40-6866a5bbe7c9"}]}} -{"type":"turn/start","seq":1,"time":1785821416523,"data":{"turn":1}} -{"type":"agent/inbox/spliced","seq":2,"time":1785821416523,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} -{"type":"subagent/descriptor","seq":3,"time":1785821416542,"data":{"version":2,"mode":"one-shot","provider":"spawn"}} -{"type":"step/start","seq":4,"time":1785730457309,"data":{"turn":1,"step":1}} -{"type":"user/message","seq":5,"time":1785730457309,"data":{"content":[{"type":"text","text":"Reply with exactly the word WF_CHILD_OK and nothing else."}],"source":{"kind":"user"},"role":"user","id":"f0f46771-663a-494a-8d40-6866a5bbe7c9"},"surfaceOp":"append"} -{"type":"user/message","seq":6,"time":1785730457309,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}]},"role":"user","id":"e076edc0-a2bf-4fc6-aa58-d44bf1e8fd00"},"surfaceOp":"append"} -{"type":"session/title","seq":7,"time":1785730457309,"data":{"title":"Reply with exactly the word","messageSeqs":[5],"source":{"kind":"fallback"}}} -{"type":"request/header","seq":8,"time":1785730457310,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}} -{"type":"request/context","seq":9,"time":1785730457310,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} -{"type":"assistant/chunk","seq":10,"time":1783600638189,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}}} -{"type":"reasoning-chunks","seq0":11,"time0":1783600638189,"data":{"turn":1,"step":1,"index":0,"dt":[0,0,0,24,0,0,0,0,29,0,0,0,0,0,34,0,0],"texts":["The"," user"," wants"," me"," to"," reply"," with"," exactly"," \"","WF","_CH","ILD","_OK","\""," and"," nothing"," else","."]}} -{"type":"assistant/chunk","seq":29,"time":1783600638276,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":1,"blockType":"text"}}} -{"type":"text-chunks","seq0":30,"time0":1783600638276,"data":{"turn":1,"step":1,"index":1,"dt":[4,0,0],"texts":["WF","_CH","ILD","_OK"]}} -{"type":"assistant/chunk","seq":34,"time":1783600638280,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The user wants me to reply with exactly \"WF_CHILD_OK\" and nothing else."}}}} -{"type":"assistant/chunk","seq":35,"time":1785498800343,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":1,"block":{"type":"text","text":"WF_CHILD_OK"}}}} -{"type":"assistant/chunk","seq":36,"time":1785730457316,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":17,"outputTokens":23,"cacheReadTokens":3072,"reasoningTokens":18}}}} -{"type":"assistant/chunk","seq":37,"time":1785730457316,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"stop"}}}} -{"type":"assistant/message","seq":38,"time":1785730457316,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"reasoning","text":"The user wants me to reply with exactly \"WF_CHILD_OK\" and nothing else."},{"type":"text","text":"WF_CHILD_OK"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"0ddaf3d1-53dc-45df-bc19-54ad72d6d7fb"},"usage":{"inputTokens":17,"outputTokens":23,"cacheReadTokens":3072,"reasoningTokens":18}},"sourceEventSeqs":[10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"surfaceOp":"append"} -{"type":"step/end","seq":39,"time":1785730457316,"data":{"turn":1,"step":1}} -{"type":"turn/end","seq":40,"time":1785730457316,"data":{"turn":1,"reason":{"kind":"completed"}}} +{"type":"approval/policy","seq":0,"time":1786357536718,"data":{"policy":"never","source":"delegation"}} +{"type":"agent/inbox/spliced","seq":1,"time":1786357536719,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Reply with exactly the word WF_CHILD_OK and nothing else."}],"source":{"kind":"user"},"role":"user","id":"f0f46771-663a-494a-8d40-6866a5bbe7c9"}]}} +{"type":"turn/start","seq":2,"time":1786357536719,"data":{"turn":1}} +{"type":"agent/inbox/spliced","seq":3,"time":1786357536719,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} +{"type":"subagent/descriptor","seq":4,"time":1786357536736,"data":{"version":2,"mode":"one-shot","provider":"spawn"}} +{"type":"step/start","seq":5,"time":1786357536738,"data":{"turn":1,"step":1}} +{"type":"user/message","seq":6,"time":1785730457309,"data":{"content":[{"type":"text","text":"Reply with exactly the word WF_CHILD_OK and nothing else."}],"source":{"kind":"user"},"role":"user","id":"f0f46771-663a-494a-8d40-6866a5bbe7c9"},"surfaceOp":"append"} +{"type":"user/message","seq":7,"time":1786357536738,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`).\n\nYou are a delegated subagent: your permission scope was fixed when you were started and cannot be widened from inside this session — operations that require approval are rejected automatically. When the task needs access beyond that scope, do not retry the denied operation; state the limitation in your reply so the delegating agent can handle it."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."},{"name":"subagent:delegation","text":"You are a delegated subagent: your permission scope was fixed when you were started and cannot be widened from inside this session — operations that require approval are rejected automatically. When the task needs access beyond that scope, do not retry the denied operation; state the limitation in your reply so the delegating agent can handle it."}]},"role":"user","id":"12bbd4dd-4040-4cc7-8acf-e526144f1ee5"},"surfaceOp":"append"} +{"type":"session/title","seq":8,"time":1786357536738,"data":{"title":"Reply with exactly the word","messageSeqs":[6],"source":{"kind":"fallback"}}} +{"type":"request/header","seq":9,"time":1785730457310,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}} +{"type":"request/context","seq":10,"time":1785730457310,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} +{"type":"assistant/chunk","seq":11,"time":1783600638189,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}}} +{"type":"reasoning-chunks","seq0":12,"time0":1783600638189,"data":{"turn":1,"step":1,"index":0,"dt":[0,0,0,24,0,0,0,0,29,0,0,0,0,0,34,0,0],"texts":["The"," user"," wants"," me"," to"," reply"," with"," exactly"," \"","WF","_CH","ILD","_OK","\""," and"," nothing"," else","."]}} +{"type":"assistant/chunk","seq":30,"time":1783600638276,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":1,"blockType":"text"}}} +{"type":"text-chunks","seq0":31,"time0":1783600638276,"data":{"turn":1,"step":1,"index":1,"dt":[4,0,0],"texts":["WF","_CH","ILD","_OK"]}} +{"type":"assistant/chunk","seq":35,"time":1783600638280,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The user wants me to reply with exactly \"WF_CHILD_OK\" and nothing else."}}}} +{"type":"assistant/chunk","seq":36,"time":1785498800343,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":1,"block":{"type":"text","text":"WF_CHILD_OK"}}}} +{"type":"assistant/chunk","seq":37,"time":1785730457316,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":17,"outputTokens":23,"cacheReadTokens":3072,"reasoningTokens":18}}}} +{"type":"assistant/chunk","seq":38,"time":1785730457316,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"stop"}}}} +{"type":"assistant/message","seq":39,"time":1785730457316,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"reasoning","text":"The user wants me to reply with exactly \"WF_CHILD_OK\" and nothing else."},{"type":"text","text":"WF_CHILD_OK"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"0ddaf3d1-53dc-45df-bc19-54ad72d6d7fb"},"usage":{"inputTokens":17,"outputTokens":23,"cacheReadTokens":3072,"reasoningTokens":18}},"sourceEventSeqs":[11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38],"surfaceOp":"append"} +{"type":"step/end","seq":40,"time":1785730457316,"data":{"turn":1,"step":1}} +{"type":"turn/end","seq":41,"time":1785730457316,"data":{"turn":1,"reason":{"kind":"completed"}}} diff --git a/examples/acp-agent/tests/snapshots/workflow-run/session.jsonl b/examples/acp-agent/tests/snapshots/workflow-run/session.jsonl index 6ee104dd0c..eff3a129a4 100644 --- a/examples/acp-agent/tests/snapshots/workflow-run/session.jsonl +++ b/examples/acp-agent/tests/snapshots/workflow-run/session.jsonl @@ -4,7 +4,7 @@ {"type":"agent/inbox/spliced","seq":2,"time":1785821416248,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} {"type":"step/start","seq":3,"time":1783600631839,"data":{"turn":1,"step":1}} {"type":"user/message","seq":4,"time":1785498800152,"data":{"content":[{"type":"text","text":"Use the workflow tool exactly once, with args omitted, meta set to { \"name\": \"snapshot-flow\", \"description\": \"one child for the snapshot\" }, and this EXACT script body (copy it verbatim):\nphase('Run')\nconst reply = await agent('Reply with exactly the word WF_CHILD_OK and nothing else.')\nreturn { reply }\nAfter the workflow returns, reply with the single word WORKFLOW_DONE and stop. Do not use any other tool."}],"source":{"kind":"user"},"role":"user","id":"5188a9c7-d3ca-4679-b8df-1443e0a0a4df"},"surfaceOp":"append"} -{"type":"user/message","seq":5,"time":1785730457160,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}]},"role":"user","id":"1c92c213-1d4f-45ad-be50-161f26a23e65"},"surfaceOp":"append"} +{"type":"user/message","seq":5,"time":1785730457160,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}]},"role":"user","id":"8f2bd7f3-ba01-4448-b00a-0d6e9c868fc3"},"surfaceOp":"append"} {"type":"session/title","seq":6,"time":1785730457160,"data":{"title":"Use the workflow tool exactly","messageSeqs":[4],"source":{"kind":"fallback"}}} {"type":"request/header","seq":7,"time":1785498800153,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}} {"type":"request/context","seq":8,"time":1785730457161,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} diff --git a/examples/headless-agent/tests/snapshots/advanced-toolchain/session.1.jsonl b/examples/headless-agent/tests/snapshots/advanced-toolchain/session.1.jsonl index 44cbf0e360..8a1c23140b 100644 --- a/examples/headless-agent/tests/snapshots/advanced-toolchain/session.1.jsonl +++ b/examples/headless-agent/tests/snapshots/advanced-toolchain/session.1.jsonl @@ -1,18 +1,19 @@ {"type":"session","version":0,"id":"22222222-2222-4222-8222-222222222222","createdAt":1783950001000,"cwd":"{{cwd}}","parentSession":"11111111-1111-4111-8111-111111111111","origin":"subagent","delegationDepth":1} -{"type":"agent/inbox/spliced","seq":0,"time":1785498583877,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Reply with exactly DIRECT_CHILD_OK and nothing else."}],"source":{"kind":"user"},"role":"user","id":"fc62f9e7-b8f6-441f-9ee8-17f1f9e4feca"}]}} +{"type":"agent/inbox/spliced","seq":0,"time":1785498583877,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Reply with exactly DIRECT_CHILD_OK and nothing else."}],"source":{"kind":"user"},"role":"user","id":"1c70f3f7-2e85-4808-8376-03d4d3bee6e6"}]}} {"type":"turn/start","seq":1,"time":1785821454445,"data":{"turn":1}} {"type":"agent/inbox/spliced","seq":2,"time":1785821454445,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} {"type":"subagent/descriptor","seq":3,"time":1785821454466,"data":{"version":2,"mode":"one-shot","provider":"spawn","label":"Check direct child"}} {"type":"step/start","seq":4,"time":1785730501506,"data":{"turn":1,"step":1}} -{"type":"user/message","seq":5,"time":1785730501506,"data":{"content":[{"type":"text","text":"Reply with exactly DIRECT_CHILD_OK and nothing else."}],"source":{"kind":"user"},"role":"user","id":"fc62f9e7-b8f6-441f-9ee8-17f1f9e4feca"},"surfaceOp":"append"} -{"type":"session/title","seq":6,"time":1785730501506,"data":{"title":"Reply with exactly DIRECT_CHILD_OK and","messageSeqs":[5],"source":{"kind":"fallback"}}} -{"type":"request/header","seq":7,"time":1785498583897,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"You are an AI agent powered by the DeepSeek Harness SDK.\n\nYou are headless-agent, a coding assistant powered by the deepseek-v4-flash model. Your working directory is {{cwd}}.\n\nVerify your work by running the code or tests. Keep answers brief and factual.\n\n\nUse the read tool — not shell commands like cat — to inspect text files. Results include line numbers. Use offset and limit to continue reading large files.\n\nUse the write tool to create files or completely replace file contents. Existing files are overwritten, so read an existing file first (the default fs-policy requires it) and prefer edit for targeted changes.\n\nUse the edit tool for targeted changes to existing UTF-8 text files. It replaces literal old_string with new_string; by default old_string must appear exactly once. If old_string appears multiple times, provide a more specific old_string or set replace_all to true. Read the file first (the default fs-policy requires it), unless you just created or edited it in this session.\n\nCheck the [exit code: N] marker on every bash result; investigate failures before moving on.\n\nTrack every background task id you start. You are notified in-session when a task finishes — do not busy-poll or sleep on one; keep working on independent steps and do not duplicate a running task's work. Before giving a final answer, collect every still-relevant task with task_output (set wait: true only when you are genuinely blocked on it), and task_kill tasks that stopped mattering.\n\nUse the workflow tool ONLY when the user explicitly asks for a workflow or for large multi-agent orchestration: you write a JavaScript script (the tool description documents the exact format) that fans work out across many subagents with phases and structured results. For one or two delegations, prefer plain subagent calls.\n\nUse the ralph tool ONLY when the direct human explicitly asks for a Ralph loop or fresh-agent iterative execution. Each Ralph round starts a fresh child with no conversation seed and uses the shared workspace as durable memory. Completion and blockers are worker reports, not independent evaluation. Use same-session goal tools for ordinary long-running objectives, and plain subagents or workflows for bounded delegation and fan-out.\n\n## Writing code for run_code\n\nPass `run_code` the body of an async TypeScript function (erasable syntax only — no `enum` or namespaces; type annotations are advisory, the code runs type-stripped). Inside the program:\n\n- Call tools as `await tools.name(args)` — quoted access for exotic names: `tools[\"my-tool\"](args)`. Every call resolves to the tool's typed canonical JSON value. Tool arguments must be lossless JSON.\n- A FAILED tool call rejects with `ToolCallError`, whose `toolName` identifies the failed tool and whose `message` is human-readable — `try/catch` it to handle and continue.\n- Independent read-only calls MAY overlap under `Promise.all` (safe calls run concurrently; mutating calls run alone, in submission order). Sequence dependent work with `await`.\n- Emit results with `return` and/or `console.log(...)`. ONLY what you print or return comes back to you — intermediate tool results never enter the conversation, so extract just what you need.\n\nThe available tools:\n\n```ts\ntype JsonValue = null | boolean | number | string | JsonValue[] | { [key: string]: JsonValue }\n\ninterface ToolArgsMap {\n /** Execute a bash command (`bash -c`) and return its stdout/stderr. Each call runs in a fresh shell: no state (cwd, variables, functions) persists between calls — pass `workdir` instead of using `cd`. Non-zero exits are reported as `[exit code: N]`. Current harness environment facts are exposed through managed `$DSH_*` variables; inspect them when needed. Commands may run under a file sandbox; a blocked file operation is reported as `[sandbox: file access denied under mode]` — a policy denial, not a bug in the command; do not retry another way. Long output is truncated to its tail; the full output is saved to a file whose path is reported when available. Set `run_in_background: true` for long-running commands: the call returns a task id immediately; read its output with `task_output` and stop it with `task_kill`. */\n bash: {\n /** The bash command to execute. */\n command: string;\n /** Clear, concise description of what this command does in active voice, 5-10 words (shown in the UI). Examples: \"ls\" → \"List files in current directory\"; \"git status\" → \"Show working tree status\"; \"npm install\" → \"Install package dependencies\". */\n description: string;\n /** Timeout in milliseconds. The executor applies its configured default and cap, and kills the command on expiry. */\n timeoutMs?: number;\n /** Working directory for this command. Defaults to the session workspace; a relative path is resolved against it. */\n workdir?: string;\n /** Run in the background and return a task id immediately (collect with task_output, stop with task_kill). No timeout applies. */\n run_in_background?: boolean;\n } & Record;\n /** Inspect the live Cordis runtime in the current DSH process. Read-only. Sections: `services` (every provided ctx service and the plugin fiber that owns it), `plugins` (all live plugin fibers with their lifecycle states), `tools` (the model-facing tools currently registered, i.e. what you can call), `temporary` (only temporary Plugins created by cordis_mount: id, name, state, provided services, awaited services, and lifetime), `api` (method signatures AND argument/return type shapes for every LIVE service — read this before writing plugin code that calls a service), `events` (every harness event with its dispatch mode and exact signature — pick listener targets here). Temporary Plugins exist only in memory, remain active across later turns, and disappear after cordis_unmount, toolset unload, or DSH restart; they are not restored automatically. The `temporary` section is a subset of `plugins`. Omit `what` to get all six sections. With `what:\"api\"` or `what:\"events\"`, pass an exact `name` to narrow to one service/event and include its original source JSDoc. */\n cordis_inspect: {\n /** Limit the report to one section. Omit for all sections. */\n what?: \"services\" | \"plugins\" | \"tools\" | \"temporary\" | \"api\" | \"events\";\n /** Exact service key or event name whose original JSDoc to include; valid only with what:\"api\" or what:\"events\". */\n name?: string;\n } & Record;\n /** Mount a temporary Cordis Plugin in the current DSH process. This creates an in-memory runtime Plugin, not an installed or configured Plugin. It remains active across later turns until cordis_unmount, toolset unload, or DSH restart. It does not create files, install a package, change cordis.yml or personal/project config, survive restart, or automatically become permanent. To keep it, ask the Agent to implement a normal local, project, or repository Plugin through the regular development workflow. It may affect other sessions in the same process; the sandbox is not a security boundary, and injected services reach the real runtime. `code` runs now as the body of an async JavaScript function in an isolated sandbox and MUST `return` a plugin. Two forms: FUNCTION form `return (ctx) => { … }` — declares no inject, so it can register tools, listen to events, and provide services, but reaching ANY service (e.g. ctx.bash) throws; use it only when you need no services. OBJECT form `return { name?, inject: ['bash', 'llm', …], apply(ctx) { … } }` — declares dependencies, and cordis activates the plugin only after the services exist; PREFER this form. You may reach ONLY the services you list in inject: an undeclared service throws even if it exists, because an undeclared dependency would not be cleaned up if its provider is unmounted. BEFORE calling a service from your code, read cordis_inspect what:\"api\" — it lists method signatures AND the type shapes of their arguments/returns (do not guess a field's type; e.g. a bash run's stdout is an object, not a string). Inside `apply`, use the standard cordis API: `ctx.on(event, listener)` to observe events (see cordis_inspect what:\"events\"), or call `harness.registerTool(ctx, harness.defineTool({ name, description, parameters: { text: { type: 'string', required: true } }, output: { schema: { type: 'string' }, render(_args, value) { return [{ type: 'text', text: value }] } }, async execute(args) { return args.text } }))` to give yourself a new tool — it becomes callable on your NEXT step. Tool parameters: each key IS a property — { type: 'string'|'number'|'integer'|'boolean'|'null'|'object'|'array'|'json', required?: true, description?, enum?, const?, items?, properties? }; every direct DSL object declares additionalProperties: true|false, and oneOf: [schema, schema, ...] replaces type for an exact-one union. A raw JSON-Schema { type: 'object', properties, required?: […] } wrapper is also accepted with open-by-default objects. A tool's `execute` MUST return the lossless JSON value declared by `output.schema`; `output.render(args, value)` separately returns Native/model content blocks. Temporary Plugins can COMPOSE: one Plugin may `ctx.provide('name', value)` a service and another may declare `inject: ['name']` to consume it — the consumer stays pending until the provider exists and returns to pending when the provider is unmounted. Everything registered inside `apply` is cleaned up automatically by cordis_unmount. Sandbox globals: `console` (tagged `[cordis:]`, writes through to the harness terminal), `harness.defineTool`, `harness.registerTool`, `btoa`, `atob`, `TextEncoder`, `TextDecoder`. Node APIs are DISABLED — do filesystem/network/timer work through the cordis services, never Node built-ins: `require`, `setTimeout`/`setInterval`, and `fetch` throw redirect errors; `process` and `Buffer` are undefined. Instead use inject: ['fs'] + ctx.fs for files, inject: ['web'] + ctx.web for HTTP, inject: ['bash'] + ctx.bash for processes, and inject: ['timer'] + ctx.setTimeout/ctx.setInterval for timing (fiber effects, auto-cleaned when unmounted) — cordis_inspect what:\"api\" shows what THIS runtime provides. Write PLAIN JavaScript, not TypeScript (no `as`, no type annotations). Cautions: (1) waterfall events (e.g. tools/pre-execute) hand the listener a trailing `next` callback which MUST be called — returning without `next()` SHORT-CIRCUITS the call; prefer plain notification events unless you intend to intercept. (2) Never await something that only resolves after the current turn (your code runs INSIDE a tool call of that turn — it would deadlock). (3) Your `ctx` is a restricted façade: you can register tools, observe events, provide/consume services, and use timers, but framework internals (ctx.root, ctx.fiber, ctx.extend, ctx.plugin, …) are withheld. It is not a security boundary though — the services you inject (e.g. ctx.bash) reach the real runtime. */\n cordis_mount: {\n /** JavaScript body returning a temporary Plugin; evaluated now and saved nowhere. */\n code: string;\n } & Record;\n /** Unmount a current-process temporary Plugin created by cordis_mount. Waits for its tools, listeners, services, timers, and other owned effects to clean up completely. Only dyn-N temporary ids are accepted; this cannot remove Loader, configured, or installed Plugins. */\n cordis_unmount: {\n /** The temporary Plugin id returned by cordis_mount (for example \"dyn-1\"); valid only in this process and invalid after unmount or restart. */\n id: string;\n } & Record;\n /** Edit an existing UTF-8 text file by replacing literal text. */\n edit: {\n /** Path to edit, resolved by the filesystem backend. */\n file_path: string;\n /** Literal text to replace. Must match exactly. */\n old_string: string;\n /** Literal replacement text. Use an empty string to delete the match. */\n new_string: string;\n /** Replace all matches. Defaults to false; when false, old_string must appear exactly once. */\n replace_all?: boolean;\n } & Record;\n /** Run a foreground fresh-agent Ralph loop toward one immutable objective. Use only when the direct human explicitly asks for Ralph or fresh-agent iteration. Each round opens a new child with no parent conversation or prior child session; the shared workspace is long-term memory, and only a bounded structured report crosses rounds. The call returns when a worker reports completion or a concrete blocker, or at the round limit. Ordinary long-running same-session work belongs to goal tools. */\n ralph: {\n /** The immutable completion objective for every fresh Ralph round. */\n objective: string;\n /** Optional positive safe-integer round cap, bounded by the deployment ceiling. */\n maxRounds?: number;\n } & Record;\n /** Read a UTF-8 text file and return line-numbered content. */\n read: {\n /** Path to read, resolved by the filesystem backend. */\n file_path: string;\n /** 1-based first line to return. Defaults to 1. */\n offset?: number;\n /** Maximum number of lines to return. Defaults to 2000. */\n limit?: number;\n } & Record;\n /** Send a message to a background subagent by its subagent id, continuing the same conversation. It becomes the subagent's next turn: if it is still working, the message waits until its current turn finishes, so it cannot redirect work already underway. This call returns no answer from the subagent — only confirmation that the message was delivered — so use it to give it more work. A failure means the message was NOT delivered. */\n send_message: {\n /** The subagent id returned when the background subagent was started. */\n subagent_id: string;\n /** The message to deliver to the subagent. */\n message: string;\n } & Record;\n /** Load the full instructions for an available skill. Call this with the exact skill name from the session skill catalog before acting on a task that names or clearly matches that skill. */\n skill: {\n /** The exact skill name from the available skills list. */\n name: string;\n } & Record;\n /** Delegate a self-contained task to a subagent (a separate agent that works in its own context) and return its final result. Use this to offload focused, independent work — research, a scoped implementation, an analysis — so it does not consume this conversation's context. The subagent runs to completion and you receive only its final answer, not its intermediate steps. Give it a complete, standalone prompt: it does not see this conversation. Set `run_in_background: true` to start a background subagent that keeps its conversation: you receive only its subagent id, never its result, and it works on its own. Use this for work whose result you do not need returned by this call; `send_message` sends it more work. */\n subagent: {\n /** A short (3-5 word) description of the delegated task, for display. */\n description: string;\n /** The complete, self-contained task for the subagent. It does not share this conversation's context, so include everything it needs. */\n prompt: string;\n /** Run as a background subagent that keeps its conversation and return only its subagent id. This call never returns its result; send it more work with send_message. */\n run_in_background?: boolean;\n } & Record;\n /** Delegate a task to a subagent that inherits this conversation: a child agent seeded with all completed turns so far (it does not see the current in-flight turn), returning only its final result. Use this when the subtask builds on this conversation's context — a follow-up analysis, a review, a continuation — without consuming this conversation's context for the work itself. You receive only its final answer, not its intermediate steps. Set `run_in_background: true` to start a background subagent that keeps its conversation: you receive only its subagent id, never its result, and it works on its own. Use this for work whose result you do not need returned by this call; `send_message` sends it more work. */\n subagent_fork: {\n /** A short (3-5 word) description of the delegated task, for display. */\n description: string;\n /** The task for the subagent. It already sees this conversation's completed turns, so build on them freely and state only what is new. */\n prompt: string;\n /** Run as a background subagent that keeps its conversation and return only its subagent id. This call never returns its result; send it more work with send_message. */\n run_in_background?: boolean;\n } & Record;\n /** Request cancellation of a running background task by task id. Returns immediately; the task settles as killed once its work actually stops. */\n task_kill: {\n /** Task id returned by the tool that started the background work. */\n task_id: string;\n /** Optional short reason, recorded in the log and forwarded to the task. */\n reason?: string;\n } & Record;\n /** List your background tasks (running and finished) with their ids, kinds, and statuses. */\n task_list: Record;\n /** Read a background task. Stream tasks return only output since the previous read; final-output tasks return their result after settlement. Every response ends with `[status: ...]`. Reads are non-blocking unless `wait: true`, which waits up to the configured cap. */\n task_output: {\n /** Task id returned by the tool that started the background work. */\n task_id: string;\n /** Block until the task reaches a terminal status or the timeout expires. A timed-out wait returns [status: running] and leaves the task alive. */\n wait?: boolean;\n /** Max wait in milliseconds (only meaningful with wait: true). Defaults to the configured wait timeout; capped by the configured maximum. */\n timeout_ms?: number;\n } & Record;\n /** Record and update a structured task list for the current work. Send the ENTIRE list every call — it REPLACES the previous list (there are no partial updates, no per-item edits). Use it to plan multi-step work and show progress: add one todo per concrete step before you start. Mark every todo being actively worked on `in_progress` — several at once when work genuinely runs in parallel (e.g. concurrent subagents or background commands), one for sequential work; while work remains, at least one task should be `in_progress`. Mark a todo `completed` the moment it is done (do not batch completions), and allow no `in_progress` item only once all work is complete. Skip the list for trivial single-step tasks. Statuses: `pending` (not started), `in_progress` (being worked on now), `completed` (finished). */\n todo_write: {\n /** The COMPLETE task list, replacing any previous list. */\n todos: ({\n /** What the task is — a short imperative line. */\n content: string;\n /** pending (not started) | in_progress (now) | completed (done). */\n status: \"pending\" | \"in_progress\" | \"completed\";\n })[];\n } & Record;\n /** Run a JavaScript workflow script that orchestrates subagents at scale. Use this for work that fans out across many independent pieces — an audit over many files, a migration, multi-angle research, adversarial verification of findings — where you write the orchestration as a script instead of delegating turn by turn. The workflow's identity rides the `meta` parameter as JSON: required `name` (short kebab-case) and `description` strings, optional `whenToUse` string and `phases` array (`{title, detail?, provider?, model?}`). The `script` parameter is the plain JavaScript body ONLY (NOT TypeScript, and NO `export const meta` statement — meta is a parameter, not code), running with top-level await; end with `return ` — the value must be JSON-serializable and is this tool's result. Script-body hooks: - `agent(prompt, opts?): Promise` — run one subagent to completion. Without `opts.schema` it resolves to the child's final text; with `opts.schema` (an object-rooted JSON Schema using ONLY type/properties/required/additionalProperties/items/enum/const/oneOf — no pattern/format/numeric bounds) it resolves to the validated object. Resolves `null` when the child fails (filter with `.filter(Boolean)`). Other opts: `label` (display), `phase` (progress group), and independent `provider`/`model` LLM target overrides (either may be provided alone). Anything else (`effort`/`isolation`/`agentType`) is rejected loudly. - `pipeline(items, ...stages): Promise` — run each item through the stages independently with NO barrier between stages (prefer this for multi-stage work). Each stage receives `(prev, item, index)`. An ordinary stage throw drops that ITEM to `null` and skips its remaining stages. - `parallel(thunks): Promise` — run zero-argument functions concurrently and await ALL of them (a barrier; use only when a stage genuinely needs every prior result together). A throwing thunk resolves to `null`. - `phase(title)` — start a progress phase; `log(message)` — narrate progress; `args` — the tool call's `args` input, verbatim. Misused hooks (bad arguments, unknown options, unsupported schemas, tripped caps) throw errors that ALWAYS kill the script — they never dissolve into a per-item `null`. Constraints: concurrency and total-agent caps apply; no filesystem, network, timers, or Node.js APIs are provided — the agents do the work, the script only coordinates them. The run executes in the foreground: this call returns when the whole script finishes. */\n workflow: {\n /** The plain-JS workflow script body (top-level await allowed; NO `export const meta` statement; end with `return `). */\n script: string;\n /** The workflow identity block (plain JSON — never code). */\n meta: {\n /** Short kebab-case workflow name. */\n name: string;\n /** One-line description of what the workflow does. */\n description: string;\n /** Optional guidance on when this workflow applies. */\n whenToUse?: string;\n /** Optional phase declarations matched by phase() calls. */\n phases?: ({\n /** The phase title phase() calls match by exact string. */\n title: string;\n /** Optional one-line description of the phase. */\n detail?: string;\n /** Optional provider override this phase is expected to use. */\n provider?: string;\n /** Optional model override this phase is expected to use. */\n model?: string;\n } & Record)[];\n } & Record;\n /** Optional JSON input exposed to the script as the `args` global (wrap a bare list as a field, e.g. {\"files\": [...]}). */\n args?: Record;\n } & Record;\n /** Create or fully replace a UTF-8 text file. */\n write: {\n /** Path to write, resolved by the filesystem backend. */\n file_path: string;\n /** Full UTF-8 text content to write. */\n content: string;\n } & Record;\n}\n\ninterface ToolOutputMap {\n bash: {\n kind: \"background\";\n taskId: string;\n } | {\n kind: \"foreground\";\n exitCode: number | null;\n signal: string | null;\n timedOut: boolean;\n aborted: boolean;\n timeoutMs: number;\n stdout: {\n text: string;\n truncated: boolean;\n spillPath?: string;\n };\n stderr: {\n text: string;\n truncated: boolean;\n spillPath?: string;\n };\n sandbox?: {\n mode: string;\n denied: boolean;\n enforcement?: string;\n runnerFailed?: boolean;\n };\n };\n cordis_inspect: string;\n cordis_mount: {\n id: string;\n pluginName: string;\n state: \"pending\" | \"loading\" | \"active\" | \"failed\" | \"disposed\" | \"unloading\";\n provides: string[];\n waitingFor: string[];\n };\n cordis_unmount: {\n id: string;\n pluginName: string;\n };\n edit: {\n path: string;\n before: string;\n after: string;\n };\n ralph: {\n runId: string;\n agentsStarted: number;\n result: JsonValue;\n };\n read: {\n path: string;\n offset: number;\n lines: {\n number: number;\n text: string;\n }[];\n totalLines: number;\n };\n send_message: {\n messageId: string;\n };\n skill: {\n name: string;\n provider: string;\n resourceBase?: {\n kind: \"directory\";\n path: string;\n } | {\n kind: \"url\";\n url: string;\n } | {\n kind: \"opaque\";\n description: string;\n };\n content: string;\n };\n subagent: {\n kind: \"background\";\n taskId: string;\n } | {\n kind: \"continuable\";\n subagentId: string;\n } | {\n kind: \"foreground\";\n runId: string;\n output: JsonValue[];\n };\n subagent_fork: {\n kind: \"background\";\n taskId: string;\n } | {\n kind: \"continuable\";\n subagentId: string;\n } | {\n kind: \"foreground\";\n runId: string;\n output: JsonValue[];\n };\n task_kill: {\n outcome: \"cancellation-requested\" | \"already-finished\";\n task: {\n id: string;\n kind: string;\n label: string;\n status: \"running\" | \"stopping\" | \"completed\" | \"killed\" | \"failed\";\n detail?: string;\n startedAt: number;\n finishedAt?: number;\n };\n };\n task_list: ({\n id: string;\n kind: string;\n label: string;\n status: \"running\" | \"stopping\" | \"completed\" | \"killed\" | \"failed\";\n detail?: string;\n startedAt: number;\n finishedAt?: number;\n })[];\n task_output: {\n text: string;\n task: {\n id: string;\n kind: string;\n label: string;\n status: \"running\" | \"stopping\" | \"completed\" | \"killed\" | \"failed\";\n detail?: string;\n startedAt: number;\n finishedAt?: number;\n };\n };\n todo_write: {\n todos: ({\n content: string;\n status: \"pending\" | \"in_progress\" | \"completed\";\n })[];\n counts: {\n pending: number;\n inProgress: number;\n completed: number;\n };\n };\n workflow: {\n runId: string;\n agentsStarted: number;\n result: JsonValue;\n };\n write: {\n path: string;\n operation: \"create\" | \"update\";\n before: string | null;\n after: string;\n };\n}\n\ntype ToolName = keyof ToolOutputMap\n\ndeclare class ToolCallError extends Error {\n readonly name: \"ToolCallError\";\n readonly toolName: ToolName;\n}\n\ndeclare const tools: {\n [K in ToolName]: (args: ToolArgsMap[K]) => Promise;\n}\n```","tools":[{"name":"bash","description":"Execute a bash command (`bash -c`) and return its stdout/stderr. Each call runs in a fresh shell: no state (cwd, variables, functions) persists between calls — pass `workdir` instead of using `cd`. Non-zero exits are reported as `[exit code: N]`. Current harness environment facts are exposed through managed `$DSH_*` variables; inspect them when needed. Commands may run under a file sandbox; a blocked file operation is reported as `[sandbox: file access denied under mode]` — a policy denial, not a bug in the command; do not retry another way. Long output is truncated to its tail; the full output is saved to a file whose path is reported when available. Set `run_in_background: true` for long-running commands: the call returns a task id immediately; read its output with `task_output` and stop it with `task_kill`.","parameters":{"type":"object","properties":{"command":{"type":"string","description":"The bash command to execute."},"description":{"type":"string","description":"Clear, concise description of what this command does in active voice, 5-10 words (shown in the UI). Examples: \"ls\" → \"List files in current directory\"; \"git status\" → \"Show working tree status\"; \"npm install\" → \"Install package dependencies\"."},"timeoutMs":{"type":"number","description":"Timeout in milliseconds. The executor applies its configured default and cap, and kills the command on expiry."},"workdir":{"type":"string","description":"Working directory for this command. Defaults to the session workspace; a relative path is resolved against it."},"run_in_background":{"type":"boolean","description":"Run in the background and return a task id immediately (collect with task_output, stop with task_kill). No timeout applies."}},"required":["command","description"]}},{"name":"cordis_inspect","description":"Inspect the live Cordis runtime in the current DSH process. Read-only. Sections: `services` (every provided ctx service and the plugin fiber that owns it), `plugins` (all live plugin fibers with their lifecycle states), `tools` (the model-facing tools currently registered, i.e. what you can call), `temporary` (only temporary Plugins created by cordis_mount: id, name, state, provided services, awaited services, and lifetime), `api` (method signatures AND argument/return type shapes for every LIVE service — read this before writing plugin code that calls a service), `events` (every harness event with its dispatch mode and exact signature — pick listener targets here). Temporary Plugins exist only in memory, remain active across later turns, and disappear after cordis_unmount, toolset unload, or DSH restart; they are not restored automatically. The `temporary` section is a subset of `plugins`. Omit `what` to get all six sections. With `what:\"api\"` or `what:\"events\"`, pass an exact `name` to narrow to one service/event and include its original source JSDoc.","parameters":{"type":"object","properties":{"what":{"type":"string","description":"Limit the report to one section. Omit for all sections.","enum":["services","plugins","tools","temporary","api","events"]},"name":{"type":"string","description":"Exact service key or event name whose original JSDoc to include; valid only with what:\"api\" or what:\"events\"."}}}},{"name":"cordis_mount","description":"Mount a temporary Cordis Plugin in the current DSH process. This creates an in-memory runtime Plugin, not an installed or configured Plugin. It remains active across later turns until cordis_unmount, toolset unload, or DSH restart. It does not create files, install a package, change cordis.yml or personal/project config, survive restart, or automatically become permanent. To keep it, ask the Agent to implement a normal local, project, or repository Plugin through the regular development workflow. It may affect other sessions in the same process; the sandbox is not a security boundary, and injected services reach the real runtime. `code` runs now as the body of an async JavaScript function in an isolated sandbox and MUST `return` a plugin. Two forms: FUNCTION form `return (ctx) => { … }` — declares no inject, so it can register tools, listen to events, and provide services, but reaching ANY service (e.g. ctx.bash) throws; use it only when you need no services. OBJECT form `return { name?, inject: ['bash', 'llm', …], apply(ctx) { … } }` — declares dependencies, and cordis activates the plugin only after the services exist; PREFER this form. You may reach ONLY the services you list in inject: an undeclared service throws even if it exists, because an undeclared dependency would not be cleaned up if its provider is unmounted. BEFORE calling a service from your code, read cordis_inspect what:\"api\" — it lists method signatures AND the type shapes of their arguments/returns (do not guess a field's type; e.g. a bash run's stdout is an object, not a string). Inside `apply`, use the standard cordis API: `ctx.on(event, listener)` to observe events (see cordis_inspect what:\"events\"), or call `harness.registerTool(ctx, harness.defineTool({ name, description, parameters: { text: { type: 'string', required: true } }, output: { schema: { type: 'string' }, render(_args, value) { return [{ type: 'text', text: value }] } }, async execute(args) { return args.text } }))` to give yourself a new tool — it becomes callable on your NEXT step. Tool parameters: each key IS a property — { type: 'string'|'number'|'integer'|'boolean'|'null'|'object'|'array'|'json', required?: true, description?, enum?, const?, items?, properties? }; every direct DSL object declares additionalProperties: true|false, and oneOf: [schema, schema, ...] replaces type for an exact-one union. A raw JSON-Schema { type: 'object', properties, required?: […] } wrapper is also accepted with open-by-default objects. A tool's `execute` MUST return the lossless JSON value declared by `output.schema`; `output.render(args, value)` separately returns Native/model content blocks. Temporary Plugins can COMPOSE: one Plugin may `ctx.provide('name', value)` a service and another may declare `inject: ['name']` to consume it — the consumer stays pending until the provider exists and returns to pending when the provider is unmounted. Everything registered inside `apply` is cleaned up automatically by cordis_unmount. Sandbox globals: `console` (tagged `[cordis:]`, writes through to the harness terminal), `harness.defineTool`, `harness.registerTool`, `btoa`, `atob`, `TextEncoder`, `TextDecoder`. Node APIs are DISABLED — do filesystem/network/timer work through the cordis services, never Node built-ins: `require`, `setTimeout`/`setInterval`, and `fetch` throw redirect errors; `process` and `Buffer` are undefined. Instead use inject: ['fs'] + ctx.fs for files, inject: ['web'] + ctx.web for HTTP, inject: ['bash'] + ctx.bash for processes, and inject: ['timer'] + ctx.setTimeout/ctx.setInterval for timing (fiber effects, auto-cleaned when unmounted) — cordis_inspect what:\"api\" shows what THIS runtime provides. Write PLAIN JavaScript, not TypeScript (no `as`, no type annotations). Cautions: (1) waterfall events (e.g. tools/pre-execute) hand the listener a trailing `next` callback which MUST be called — returning without `next()` SHORT-CIRCUITS the call; prefer plain notification events unless you intend to intercept. (2) Never await something that only resolves after the current turn (your code runs INSIDE a tool call of that turn — it would deadlock). (3) Your `ctx` is a restricted façade: you can register tools, observe events, provide/consume services, and use timers, but framework internals (ctx.root, ctx.fiber, ctx.extend, ctx.plugin, …) are withheld. It is not a security boundary though — the services you inject (e.g. ctx.bash) reach the real runtime.","parameters":{"type":"object","properties":{"code":{"type":"string","description":"JavaScript body returning a temporary Plugin; evaluated now and saved nowhere."}},"required":["code"]}},{"name":"cordis_unmount","description":"Unmount a current-process temporary Plugin created by cordis_mount. Waits for its tools, listeners, services, timers, and other owned effects to clean up completely. Only dyn-N temporary ids are accepted; this cannot remove Loader, configured, or installed Plugins.","parameters":{"type":"object","properties":{"id":{"type":"string","description":"The temporary Plugin id returned by cordis_mount (for example \"dyn-1\"); valid only in this process and invalid after unmount or restart."}},"required":["id"]}},{"name":"edit","description":"Edit an existing UTF-8 text file by replacing literal text.","parameters":{"type":"object","properties":{"file_path":{"type":"string","description":"Path to edit, resolved by the filesystem backend."},"old_string":{"type":"string","description":"Literal text to replace. Must match exactly."},"new_string":{"type":"string","description":"Literal replacement text. Use an empty string to delete the match."},"replace_all":{"type":"boolean","description":"Replace all matches. Defaults to false; when false, old_string must appear exactly once."}},"required":["file_path","old_string","new_string"]}},{"name":"ralph","description":"Run a foreground fresh-agent Ralph loop toward one immutable objective. Use only when the direct human explicitly asks for Ralph or fresh-agent iteration. Each round opens a new child with no parent conversation or prior child session; the shared workspace is long-term memory, and only a bounded structured report crosses rounds. The call returns when a worker reports completion or a concrete blocker, or at the round limit. Ordinary long-running same-session work belongs to goal tools.","parameters":{"type":"object","properties":{"objective":{"type":"string","description":"The immutable completion objective for every fresh Ralph round."},"maxRounds":{"type":"number","description":"Optional positive safe-integer round cap, bounded by the deployment ceiling."}},"required":["objective"]}},{"name":"read","description":"Read a UTF-8 text file and return line-numbered content.","parameters":{"type":"object","properties":{"file_path":{"type":"string","description":"Path to read, resolved by the filesystem backend."},"offset":{"type":"number","description":"1-based first line to return. Defaults to 1."},"limit":{"type":"number","description":"Maximum number of lines to return. Defaults to 2000."}},"required":["file_path"]}},{"name":"run_code","description":"Execute a TypeScript program against the available tools. Write the BODY of an async function (erasable syntax only; top-level `await` and `return` work) and call tools as `await tools.name(args)` per the declarations in the system prompt. Only what you print or return comes back — curate it.","parameters":{"type":"object","properties":{"code":{"type":"string","description":"The program: the body of an async TypeScript function."},"description":{"type":"string","description":"Clear, concise description of what this program does in active voice, 5-10 words (shown in the UI). Examples: \"Count TODO markers across packages\"; \"Read failing test and its fixture\"; \"Rename config key in every cordis.yml\"."}},"required":["code","description"]}},{"name":"send_message","description":"Send a message to a background subagent by its subagent id, continuing the same conversation. It becomes the subagent's next turn: if it is still working, the message waits until its current turn finishes, so it cannot redirect work already underway. This call returns no answer from the subagent — only confirmation that the message was delivered — so use it to give it more work. A failure means the message was NOT delivered.","parameters":{"type":"object","properties":{"subagent_id":{"type":"string","description":"The subagent id returned when the background subagent was started."},"message":{"type":"string","description":"The message to deliver to the subagent."}},"required":["subagent_id","message"]}},{"name":"skill","description":"Load the full instructions for an available skill. Call this with the exact skill name from the session skill catalog before acting on a task that names or clearly matches that skill.","parameters":{"type":"object","properties":{"name":{"type":"string","description":"The exact skill name from the available skills list."}},"required":["name"]}},{"name":"subagent","description":"Delegate a self-contained task to a subagent (a separate agent that works in its own context) and return its final result. Use this to offload focused, independent work — research, a scoped implementation, an analysis — so it does not consume this conversation's context. The subagent runs to completion and you receive only its final answer, not its intermediate steps. Give it a complete, standalone prompt: it does not see this conversation. Set `run_in_background: true` to start a background subagent that keeps its conversation: you receive only its subagent id, never its result, and it works on its own. Use this for work whose result you do not need returned by this call; `send_message` sends it more work.","parameters":{"type":"object","properties":{"description":{"type":"string","description":"A short (3-5 word) description of the delegated task, for display."},"prompt":{"type":"string","description":"The complete, self-contained task for the subagent. It does not share this conversation's context, so include everything it needs."},"run_in_background":{"type":"boolean","description":"Run as a background subagent that keeps its conversation and return only its subagent id. This call never returns its result; send it more work with send_message."}},"required":["description","prompt"]}},{"name":"subagent_fork","description":"Delegate a task to a subagent that inherits this conversation: a child agent seeded with all completed turns so far (it does not see the current in-flight turn), returning only its final result. Use this when the subtask builds on this conversation's context — a follow-up analysis, a review, a continuation — without consuming this conversation's context for the work itself. You receive only its final answer, not its intermediate steps. Set `run_in_background: true` to start a background subagent that keeps its conversation: you receive only its subagent id, never its result, and it works on its own. Use this for work whose result you do not need returned by this call; `send_message` sends it more work.","parameters":{"type":"object","properties":{"description":{"type":"string","description":"A short (3-5 word) description of the delegated task, for display."},"prompt":{"type":"string","description":"The task for the subagent. It already sees this conversation's completed turns, so build on them freely and state only what is new."},"run_in_background":{"type":"boolean","description":"Run as a background subagent that keeps its conversation and return only its subagent id. This call never returns its result; send it more work with send_message."}},"required":["description","prompt"]}},{"name":"task_kill","description":"Request cancellation of a running background task by task id. Returns immediately; the task settles as killed once its work actually stops.","parameters":{"type":"object","properties":{"task_id":{"type":"string","description":"Task id returned by the tool that started the background work."},"reason":{"type":"string","description":"Optional short reason, recorded in the log and forwarded to the task."}},"required":["task_id"]}},{"name":"task_list","description":"List your background tasks (running and finished) with their ids, kinds, and statuses.","parameters":{"type":"object","properties":{}}},{"name":"task_output","description":"Read a background task. Stream tasks return only output since the previous read; final-output tasks return their result after settlement. Every response ends with `[status: ...]`. Reads are non-blocking unless `wait: true`, which waits up to the configured cap.","parameters":{"type":"object","properties":{"task_id":{"type":"string","description":"Task id returned by the tool that started the background work."},"wait":{"type":"boolean","description":"Block until the task reaches a terminal status or the timeout expires. A timed-out wait returns [status: running] and leaves the task alive."},"timeout_ms":{"type":"number","description":"Max wait in milliseconds (only meaningful with wait: true). Defaults to the configured wait timeout; capped by the configured maximum."}},"required":["task_id"]}},{"name":"todo_write","description":"Record and update a structured task list for the current work. Send the ENTIRE list every call — it REPLACES the previous list (there are no partial updates, no per-item edits). Use it to plan multi-step work and show progress: add one todo per concrete step before you start. Mark every todo being actively worked on `in_progress` — several at once when work genuinely runs in parallel (e.g. concurrent subagents or background commands), one for sequential work; while work remains, at least one task should be `in_progress`. Mark a todo `completed` the moment it is done (do not batch completions), and allow no `in_progress` item only once all work is complete. Skip the list for trivial single-step tasks. Statuses: `pending` (not started), `in_progress` (being worked on now), `completed` (finished).","parameters":{"type":"object","properties":{"todos":{"type":"array","description":"The COMPLETE task list, replacing any previous list.","items":{"type":"object","additionalProperties":false,"properties":{"content":{"type":"string","description":"What the task is — a short imperative line."},"status":{"type":"string","description":"pending (not started) | in_progress (now) | completed (done).","enum":["pending","in_progress","completed"]}},"required":["content","status"]}}},"required":["todos"]}},{"name":"workflow","description":"Run a JavaScript workflow script that orchestrates subagents at scale. Use this for work that fans out across many independent pieces — an audit over many files, a migration, multi-angle research, adversarial verification of findings — where you write the orchestration as a script instead of delegating turn by turn.\n\nThe workflow's identity rides the `meta` parameter as JSON: required `name` (short kebab-case) and `description` strings, optional `whenToUse` string and `phases` array (`{title, detail?, provider?, model?}`). The `script` parameter is the plain JavaScript body ONLY (NOT TypeScript, and NO `export const meta` statement — meta is a parameter, not code), running with top-level await; end with `return ` — the value must be JSON-serializable and is this tool's result.\n\nScript-body hooks:\n- `agent(prompt, opts?): Promise` — run one subagent to completion. Without `opts.schema` it resolves to the child's final text; with `opts.schema` (an object-rooted JSON Schema using ONLY type/properties/required/additionalProperties/items/enum/const/oneOf — no pattern/format/numeric bounds) it resolves to the validated object. Resolves `null` when the child fails (filter with `.filter(Boolean)`). Other opts: `label` (display), `phase` (progress group), and independent `provider`/`model` LLM target overrides (either may be provided alone). Anything else (`effort`/`isolation`/`agentType`) is rejected loudly.\n- `pipeline(items, ...stages): Promise` — run each item through the stages independently with NO barrier between stages (prefer this for multi-stage work). Each stage receives `(prev, item, index)`. An ordinary stage throw drops that ITEM to `null` and skips its remaining stages.\n- `parallel(thunks): Promise` — run zero-argument functions concurrently and await ALL of them (a barrier; use only when a stage genuinely needs every prior result together). A throwing thunk resolves to `null`.\n- `phase(title)` — start a progress phase; `log(message)` — narrate progress; `args` — the tool call's `args` input, verbatim.\n\nMisused hooks (bad arguments, unknown options, unsupported schemas, tripped caps) throw errors that ALWAYS kill the script — they never dissolve into a per-item `null`.\n\nConstraints: concurrency and total-agent caps apply; no filesystem, network, timers, or Node.js APIs are provided — the agents do the work, the script only coordinates them. The run executes in the foreground: this call returns when the whole script finishes.","parameters":{"type":"object","properties":{"script":{"type":"string","description":"The plain-JS workflow script body (top-level await allowed; NO `export const meta` statement; end with `return `)."},"meta":{"type":"object","description":"The workflow identity block (plain JSON — never code).","additionalProperties":true,"properties":{"name":{"type":"string","description":"Short kebab-case workflow name."},"description":{"type":"string","description":"One-line description of what the workflow does."},"whenToUse":{"type":"string","description":"Optional guidance on when this workflow applies."},"phases":{"type":"array","description":"Optional phase declarations matched by phase() calls.","items":{"type":"object","additionalProperties":true,"properties":{"title":{"type":"string","description":"The phase title phase() calls match by exact string."},"detail":{"type":"string","description":"Optional one-line description of the phase."},"provider":{"type":"string","description":"Optional provider override this phase is expected to use."},"model":{"type":"string","description":"Optional model override this phase is expected to use."}},"required":["title"]}}},"required":["name","description"]},"args":{"type":"object","description":"Optional JSON input exposed to the script as the `args` global (wrap a bare list as a field, e.g. {\"files\": [...]}).","additionalProperties":true}},"required":["script","meta"]}},{"name":"write","description":"Create or fully replace a UTF-8 text file.","parameters":{"type":"object","properties":{"file_path":{"type":"string","description":"Path to write, resolved by the filesystem backend."},"content":{"type":"string","description":"Full UTF-8 text content to write."}},"required":["file_path","content"]}}]},"reason":"initial"}} -{"type":"request/context","seq":8,"time":1785730501507,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} -{"type":"assistant/chunk","seq":9,"time":1783957884564,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"text"}}} -{"type":"assistant/chunk","seq":10,"time":1783957884564,"data":{"turn":1,"step":1,"chunk":{"type":"text-delta","index":0,"text":"DIRECT_CHILD_OK"}}} -{"type":"assistant/chunk","seq":11,"time":1783957884564,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"DIRECT_CHILD_OK"}}}} -{"type":"assistant/chunk","seq":12,"time":1785498583897,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}}} -{"type":"assistant/chunk","seq":13,"time":1785730501507,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"stop"}}}} -{"type":"assistant/message","seq":14,"time":1785730501507,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"text","text":"DIRECT_CHILD_OK"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"cac680cf-1d70-4fb2-91a3-da1e3a317d2e"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[9,10,11,12,13],"surfaceOp":"append"} -{"type":"step/end","seq":15,"time":1785730501507,"data":{"turn":1,"step":1}} -{"type":"turn/end","seq":16,"time":1785730501507,"data":{"turn":1,"reason":{"kind":"completed"}}} +{"type":"user/message","seq":5,"time":1785730501506,"data":{"content":[{"type":"text","text":"Reply with exactly DIRECT_CHILD_OK and nothing else."}],"source":{"kind":"user"},"role":"user","id":"1c70f3f7-2e85-4808-8376-03d4d3bee6e6"},"surfaceOp":"append"} +{"type":"user/message","seq":6,"time":1786358103673,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nYou are a delegated subagent: your permission scope was fixed when you were started and cannot be widened from inside this session — operations that require approval are rejected automatically. When the task needs access beyond that scope, do not retry the denied operation; state the limitation in your reply so the delegating agent can handle it."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"subagent:delegation","text":"You are a delegated subagent: your permission scope was fixed when you were started and cannot be widened from inside this session — operations that require approval are rejected automatically. When the task needs access beyond that scope, do not retry the denied operation; state the limitation in your reply so the delegating agent can handle it."}]},"role":"user","id":"c9a305d4-add2-453e-8789-4e5c127725f7"},"surfaceOp":"append"} +{"type":"session/title","seq":7,"time":1786358103673,"data":{"title":"Reply with exactly DIRECT_CHILD_OK and","messageSeqs":[5],"source":{"kind":"fallback"}}} +{"type":"request/header","seq":8,"time":1785498583897,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"You are an AI agent powered by the DeepSeek Harness SDK.\n\nYou are headless-agent, a coding assistant powered by the deepseek-v4-flash model. Your working directory is {{cwd}}.\n\nVerify your work by running the code or tests. Keep answers brief and factual.\n\n\nUse the read tool — not shell commands like cat — to inspect text files. Results include line numbers. Use offset and limit to continue reading large files.\n\nUse the write tool to create files or completely replace file contents. Existing files are overwritten, so read an existing file first (the default fs-policy requires it) and prefer edit for targeted changes.\n\nUse the edit tool for targeted changes to existing UTF-8 text files. It replaces literal old_string with new_string; by default old_string must appear exactly once. If old_string appears multiple times, provide a more specific old_string or set replace_all to true. Read the file first (the default fs-policy requires it), unless you just created or edited it in this session.\n\nCheck the [exit code: N] marker on every bash result; investigate failures before moving on.\n\nTrack every background task id you start. You are notified in-session when a task finishes — do not busy-poll or sleep on one; keep working on independent steps and do not duplicate a running task's work. Before giving a final answer, collect every still-relevant task with task_output (set wait: true only when you are genuinely blocked on it), and task_kill tasks that stopped mattering.\n\nUse the workflow tool ONLY when the user explicitly asks for a workflow or for large multi-agent orchestration: you write a JavaScript script (the tool description documents the exact format) that fans work out across many subagents with phases and structured results. For one or two delegations, prefer plain subagent calls.\n\nUse the ralph tool ONLY when the direct human explicitly asks for a Ralph loop or fresh-agent iterative execution. Each Ralph round starts a fresh child with no conversation seed and uses the shared workspace as durable memory. Completion and blockers are worker reports, not independent evaluation. Use same-session goal tools for ordinary long-running objectives, and plain subagents or workflows for bounded delegation and fan-out.\n\n## Writing code for run_code\n\nPass `run_code` the body of an async TypeScript function (erasable syntax only — no `enum` or namespaces; type annotations are advisory, the code runs type-stripped). Inside the program:\n\n- Call tools as `await tools.name(args)` — quoted access for exotic names: `tools[\"my-tool\"](args)`. Every call resolves to the tool's typed canonical JSON value. Tool arguments must be lossless JSON.\n- A FAILED tool call rejects with `ToolCallError`, whose `toolName` identifies the failed tool and whose `message` is human-readable — `try/catch` it to handle and continue.\n- Independent read-only calls MAY overlap under `Promise.all` (safe calls run concurrently; mutating calls run alone, in submission order). Sequence dependent work with `await`.\n- Emit results with `return` and/or `console.log(...)`. ONLY what you print or return comes back to you — intermediate tool results never enter the conversation, so extract just what you need.\n\nThe available tools:\n\n```ts\ntype JsonValue = null | boolean | number | string | JsonValue[] | { [key: string]: JsonValue }\n\ninterface ToolArgsMap {\n /** Execute a bash command (`bash -c`) and return its stdout/stderr. Each call runs in a fresh shell: no state (cwd, variables, functions) persists between calls — pass `workdir` instead of using `cd`. Non-zero exits are reported as `[exit code: N]`. Current harness environment facts are exposed through managed `$DSH_*` variables; inspect them when needed. Commands may run under a file sandbox; a blocked file operation is reported as `[sandbox: file access denied under mode]` — a policy denial, not a bug in the command; do not retry another way. Long output is truncated to its tail; the full output is saved to a file whose path is reported when available. Set `run_in_background: true` for long-running commands: the call returns a task id immediately; read its output with `task_output` and stop it with `task_kill`. */\n bash: {\n /** The bash command to execute. */\n command: string;\n /** Clear, concise description of what this command does in active voice, 5-10 words (shown in the UI). Examples: \"ls\" → \"List files in current directory\"; \"git status\" → \"Show working tree status\"; \"npm install\" → \"Install package dependencies\". */\n description: string;\n /** Timeout in milliseconds. The executor applies its configured default and cap, and kills the command on expiry. */\n timeoutMs?: number;\n /** Working directory for this command. Defaults to the session workspace; a relative path is resolved against it. */\n workdir?: string;\n /** Run in the background and return a task id immediately (collect with task_output, stop with task_kill). No timeout applies. */\n run_in_background?: boolean;\n } & Record;\n /** Inspect the live Cordis runtime in the current DSH process. Read-only. Sections: `services` (every provided ctx service and the plugin fiber that owns it), `plugins` (all live plugin fibers with their lifecycle states), `tools` (the model-facing tools currently registered, i.e. what you can call), `temporary` (only temporary Plugins created by cordis_mount: id, name, state, provided services, awaited services, and lifetime), `api` (method signatures AND argument/return type shapes for every LIVE service — read this before writing plugin code that calls a service), `events` (every harness event with its dispatch mode and exact signature — pick listener targets here). Temporary Plugins exist only in memory, remain active across later turns, and disappear after cordis_unmount, toolset unload, or DSH restart; they are not restored automatically. The `temporary` section is a subset of `plugins`. Omit `what` to get all six sections. With `what:\"api\"` or `what:\"events\"`, pass an exact `name` to narrow to one service/event and include its original source JSDoc. */\n cordis_inspect: {\n /** Limit the report to one section. Omit for all sections. */\n what?: \"services\" | \"plugins\" | \"tools\" | \"temporary\" | \"api\" | \"events\";\n /** Exact service key or event name whose original JSDoc to include; valid only with what:\"api\" or what:\"events\". */\n name?: string;\n } & Record;\n /** Mount a temporary Cordis Plugin in the current DSH process. This creates an in-memory runtime Plugin, not an installed or configured Plugin. It remains active across later turns until cordis_unmount, toolset unload, or DSH restart. It does not create files, install a package, change cordis.yml or personal/project config, survive restart, or automatically become permanent. To keep it, ask the Agent to implement a normal local, project, or repository Plugin through the regular development workflow. It may affect other sessions in the same process; the sandbox is not a security boundary, and injected services reach the real runtime. `code` runs now as the body of an async JavaScript function in an isolated sandbox and MUST `return` a plugin. Two forms: FUNCTION form `return (ctx) => { … }` — declares no inject, so it can register tools, listen to events, and provide services, but reaching ANY service (e.g. ctx.bash) throws; use it only when you need no services. OBJECT form `return { name?, inject: ['bash', 'llm', …], apply(ctx) { … } }` — declares dependencies, and cordis activates the plugin only after the services exist; PREFER this form. You may reach ONLY the services you list in inject: an undeclared service throws even if it exists, because an undeclared dependency would not be cleaned up if its provider is unmounted. BEFORE calling a service from your code, read cordis_inspect what:\"api\" — it lists method signatures AND the type shapes of their arguments/returns (do not guess a field's type; e.g. a bash run's stdout is an object, not a string). Inside `apply`, use the standard cordis API: `ctx.on(event, listener)` to observe events (see cordis_inspect what:\"events\"), or call `harness.registerTool(ctx, harness.defineTool({ name, description, parameters: { text: { type: 'string', required: true } }, output: { schema: { type: 'string' }, render(_args, value) { return [{ type: 'text', text: value }] } }, async execute(args) { return args.text } }))` to give yourself a new tool — it becomes callable on your NEXT step. Tool parameters: each key IS a property — { type: 'string'|'number'|'integer'|'boolean'|'null'|'object'|'array'|'json', required?: true, description?, enum?, const?, items?, properties? }; every direct DSL object declares additionalProperties: true|false, and oneOf: [schema, schema, ...] replaces type for an exact-one union. A raw JSON-Schema { type: 'object', properties, required?: […] } wrapper is also accepted with open-by-default objects. A tool's `execute` MUST return the lossless JSON value declared by `output.schema`; `output.render(args, value)` separately returns Native/model content blocks. Temporary Plugins can COMPOSE: one Plugin may `ctx.provide('name', value)` a service and another may declare `inject: ['name']` to consume it — the consumer stays pending until the provider exists and returns to pending when the provider is unmounted. Everything registered inside `apply` is cleaned up automatically by cordis_unmount. Sandbox globals: `console` (tagged `[cordis:]`, writes through to the harness terminal), `harness.defineTool`, `harness.registerTool`, `btoa`, `atob`, `TextEncoder`, `TextDecoder`. Node APIs are DISABLED — do filesystem/network/timer work through the cordis services, never Node built-ins: `require`, `setTimeout`/`setInterval`, and `fetch` throw redirect errors; `process` and `Buffer` are undefined. Instead use inject: ['fs'] + ctx.fs for files, inject: ['web'] + ctx.web for HTTP, inject: ['bash'] + ctx.bash for processes, and inject: ['timer'] + ctx.setTimeout/ctx.setInterval for timing (fiber effects, auto-cleaned when unmounted) — cordis_inspect what:\"api\" shows what THIS runtime provides. Write PLAIN JavaScript, not TypeScript (no `as`, no type annotations). Cautions: (1) waterfall events (e.g. tools/pre-execute) hand the listener a trailing `next` callback which MUST be called — returning without `next()` SHORT-CIRCUITS the call; prefer plain notification events unless you intend to intercept. (2) Never await something that only resolves after the current turn (your code runs INSIDE a tool call of that turn — it would deadlock). (3) Your `ctx` is a restricted façade: you can register tools, observe events, provide/consume services, and use timers, but framework internals (ctx.root, ctx.fiber, ctx.extend, ctx.plugin, …) are withheld. It is not a security boundary though — the services you inject (e.g. ctx.bash) reach the real runtime. */\n cordis_mount: {\n /** JavaScript body returning a temporary Plugin; evaluated now and saved nowhere. */\n code: string;\n } & Record;\n /** Unmount a current-process temporary Plugin created by cordis_mount. Waits for its tools, listeners, services, timers, and other owned effects to clean up completely. Only dyn-N temporary ids are accepted; this cannot remove Loader, configured, or installed Plugins. */\n cordis_unmount: {\n /** The temporary Plugin id returned by cordis_mount (for example \"dyn-1\"); valid only in this process and invalid after unmount or restart. */\n id: string;\n } & Record;\n /** Edit an existing UTF-8 text file by replacing literal text. */\n edit: {\n /** Path to edit, resolved by the filesystem backend. */\n file_path: string;\n /** Literal text to replace. Must match exactly. */\n old_string: string;\n /** Literal replacement text. Use an empty string to delete the match. */\n new_string: string;\n /** Replace all matches. Defaults to false; when false, old_string must appear exactly once. */\n replace_all?: boolean;\n } & Record;\n /** Request cancellation of a background agent's current turn by its agent id. The target may be your direct child or a deeper agent created under you. Only the current turn stops: messages already queued for the agent stay parked until a later send_message, agents it started keep running, and the agent itself stays available for follow-ups. This call returns as soon as the stop request is accepted, so the target may keep running briefly; interrupting an agent that already finished is an accepted no-op. */\n interrupt_agent: {\n /** The agent id of the running agent to interrupt. */\n agent_id: string;\n } & Record;\n /** Run a foreground fresh-agent Ralph loop toward one immutable objective. Use only when the direct human explicitly asks for Ralph or fresh-agent iteration. Each round opens a new child with no parent conversation or prior child session; the shared workspace is long-term memory, and only a bounded structured report crosses rounds. The call returns when a worker reports completion or a concrete blocker, or at the round limit. Ordinary long-running same-session work belongs to goal tools. */\n ralph: {\n /** The immutable completion objective for every fresh Ralph round. */\n objective: string;\n /** Optional positive safe-integer round cap, bounded by the deployment ceiling. */\n maxRounds?: number;\n } & Record;\n /** Read a UTF-8 text file and return line-numbered content. */\n read: {\n /** Path to read, resolved by the filesystem backend. */\n file_path: string;\n /** 1-based first line to return. Defaults to 1. */\n offset?: number;\n /** Maximum number of lines to return. Defaults to 2000. */\n limit?: number;\n } & Record;\n /** Send a message to a background subagent by its subagent id, continuing the same conversation. It becomes the subagent's next turn: if it is still working, the message waits until its current turn finishes, so it cannot redirect work already underway. This call returns no answer from the subagent — only confirmation that the message was delivered — so use it to give it more work. A failure means the message was NOT delivered. */\n send_message: {\n /** The subagent id returned when the background subagent was started. */\n subagent_id: string;\n /** The message to deliver to the subagent. */\n message: string;\n } & Record;\n /** Load the full instructions for an available skill. Call this with the exact skill name from the session skill catalog before acting on a task that names or clearly matches that skill. */\n skill: {\n /** The exact skill name from the available skills list. */\n name: string;\n } & Record;\n /** Delegate a self-contained task to a subagent (a separate agent that works in its own context) and return its final result. Use this to offload focused, independent work — research, a scoped implementation, an analysis — so it does not consume this conversation's context. The subagent runs to completion and you receive only its final answer, not its intermediate steps. Give it a complete, standalone prompt: it does not see this conversation. Set `run_in_background: true` to start a background subagent that keeps its conversation: you receive only its subagent id, never its result, and it works on its own. Use this for work whose result you do not need returned by this call; `send_message` sends it more work. */\n subagent: {\n /** A short (3-5 word) description of the delegated task, for display. */\n description: string;\n /** The complete, self-contained task for the subagent. It does not share this conversation's context, so include everything it needs. */\n prompt: string;\n /** Run as a background subagent that keeps its conversation and return only its subagent id. This call never returns its result; send it more work with send_message. */\n run_in_background?: boolean;\n } & Record;\n /** Delegate a task to a subagent that inherits this conversation: a child agent seeded with all completed turns so far (it does not see the current in-flight turn), returning only its final result. Use this when the subtask builds on this conversation's context — a follow-up analysis, a review, a continuation — without consuming this conversation's context for the work itself. You receive only its final answer, not its intermediate steps. Set `run_in_background: true` to start a background subagent that keeps its conversation: you receive only its subagent id, never its result, and it works on its own. Use this for work whose result you do not need returned by this call; `send_message` sends it more work. */\n subagent_fork: {\n /** A short (3-5 word) description of the delegated task, for display. */\n description: string;\n /** The task for the subagent. It already sees this conversation's completed turns, so build on them freely and state only what is new. */\n prompt: string;\n /** Run as a background subagent that keeps its conversation and return only its subagent id. This call never returns its result; send it more work with send_message. */\n run_in_background?: boolean;\n } & Record;\n /** Request cancellation of a running background task by task id. Returns immediately; the task settles as killed once its work actually stops. */\n task_kill: {\n /** Task id returned by the tool that started the background work. */\n task_id: string;\n /** Optional short reason, recorded in the log and forwarded to the task. */\n reason?: string;\n } & Record;\n /** List your background tasks (running and finished) with their ids, kinds, and statuses. */\n task_list: Record;\n /** Read a background task. Stream tasks return only output since the previous read; final-output tasks return their result after settlement. Every response ends with `[status: ...]`. Reads are non-blocking unless `wait: true`, which waits up to the configured cap. */\n task_output: {\n /** Task id returned by the tool that started the background work. */\n task_id: string;\n /** Block until the task reaches a terminal status or the timeout expires. A timed-out wait returns [status: running] and leaves the task alive. */\n wait?: boolean;\n /** Max wait in milliseconds (only meaningful with wait: true). Defaults to the configured wait timeout; capped by the configured maximum. */\n timeout_ms?: number;\n } & Record;\n /** Record and update a structured task list for the current work. Send the ENTIRE list every call — it REPLACES the previous list (there are no partial updates, no per-item edits). Use it to plan multi-step work and show progress: add one todo per concrete step before you start. Mark every todo being actively worked on `in_progress` — several at once when work genuinely runs in parallel (e.g. concurrent subagents or background commands), one for sequential work; while work remains, at least one task should be `in_progress`. Mark a todo `completed` the moment it is done (do not batch completions), and allow no `in_progress` item only once all work is complete. Skip the list for trivial single-step tasks. Statuses: `pending` (not started), `in_progress` (being worked on now), `completed` (finished). */\n todo_write: {\n /** The COMPLETE task list, replacing any previous list. */\n todos: ({\n /** What the task is — a short imperative line. */\n content: string;\n /** pending (not started) | in_progress (now) | completed (done). */\n status: \"pending\" | \"in_progress\" | \"completed\";\n })[];\n } & Record;\n /** Run a JavaScript workflow script that orchestrates subagents at scale. Use this for work that fans out across many independent pieces — an audit over many files, a migration, multi-angle research, adversarial verification of findings — where you write the orchestration as a script instead of delegating turn by turn. The workflow's identity rides the `meta` parameter as JSON: required `name` (short kebab-case) and `description` strings, optional `whenToUse` string and `phases` array (`{title, detail?, provider?, model?}`). The `script` parameter is the plain JavaScript body ONLY (NOT TypeScript, and NO `export const meta` statement — meta is a parameter, not code), running with top-level await; end with `return ` — the value must be JSON-serializable and is this tool's result. Script-body hooks: - `agent(prompt, opts?): Promise` — run one subagent to completion. Without `opts.schema` it resolves to the child's final text; with `opts.schema` (an object-rooted JSON Schema using ONLY type/properties/required/additionalProperties/items/enum/const/oneOf — no pattern/format/numeric bounds) it resolves to the validated object. Resolves `null` when the child fails (filter with `.filter(Boolean)`). Other opts: `label` (display), `phase` (progress group), and independent `provider`/`model` LLM target overrides (either may be provided alone). Anything else (`effort`/`isolation`/`agentType`) is rejected loudly. - `pipeline(items, ...stages): Promise` — run each item through the stages independently with NO barrier between stages (prefer this for multi-stage work). Each stage receives `(prev, item, index)`. An ordinary stage throw drops that ITEM to `null` and skips its remaining stages. - `parallel(thunks): Promise` — run zero-argument functions concurrently and await ALL of them (a barrier; use only when a stage genuinely needs every prior result together). A throwing thunk resolves to `null`. - `phase(title)` — start a progress phase; `log(message)` — narrate progress; `args` — the tool call's `args` input, verbatim. Misused hooks (bad arguments, unknown options, unsupported schemas, tripped caps) throw errors that ALWAYS kill the script — they never dissolve into a per-item `null`. Constraints: concurrency and total-agent caps apply; no filesystem, network, timers, or Node.js APIs are provided — the agents do the work, the script only coordinates them. The run executes in the foreground: this call returns when the whole script finishes. */\n workflow: {\n /** The plain-JS workflow script body (top-level await allowed; NO `export const meta` statement; end with `return `). */\n script: string;\n /** The workflow identity block (plain JSON — never code). */\n meta: {\n /** Short kebab-case workflow name. */\n name: string;\n /** One-line description of what the workflow does. */\n description: string;\n /** Optional guidance on when this workflow applies. */\n whenToUse?: string;\n /** Optional phase declarations matched by phase() calls. */\n phases?: ({\n /** The phase title phase() calls match by exact string. */\n title: string;\n /** Optional one-line description of the phase. */\n detail?: string;\n /** Optional provider override this phase is expected to use. */\n provider?: string;\n /** Optional model override this phase is expected to use. */\n model?: string;\n } & Record)[];\n } & Record;\n /** Optional JSON input exposed to the script as the `args` global (wrap a bare list as a field, e.g. {\"files\": [...]}). */\n args?: Record;\n } & Record;\n /** Create or fully replace a UTF-8 text file. */\n write: {\n /** Path to write, resolved by the filesystem backend. */\n file_path: string;\n /** Full UTF-8 text content to write. */\n content: string;\n } & Record;\n}\n\ninterface ToolOutputMap {\n bash: {\n kind: \"background\";\n taskId: string;\n } | {\n kind: \"foreground\";\n exitCode: number | null;\n signal: string | null;\n timedOut: boolean;\n aborted: boolean;\n timeoutMs: number;\n stdout: {\n text: string;\n truncated: boolean;\n spillPath?: string;\n };\n stderr: {\n text: string;\n truncated: boolean;\n spillPath?: string;\n };\n sandbox?: {\n mode: string;\n denied: boolean;\n enforcement?: string;\n runnerFailed?: boolean;\n };\n };\n cordis_inspect: string;\n cordis_mount: {\n id: string;\n pluginName: string;\n state: \"pending\" | \"loading\" | \"active\" | \"failed\" | \"disposed\" | \"unloading\";\n provides: string[];\n waitingFor: string[];\n };\n cordis_unmount: {\n id: string;\n pluginName: string;\n };\n edit: {\n path: string;\n before: string;\n after: string;\n };\n interrupt_agent: {\n accepted: boolean;\n };\n ralph: {\n runId: string;\n agentsStarted: number;\n result: JsonValue;\n };\n read: {\n path: string;\n offset: number;\n lines: {\n number: number;\n text: string;\n }[];\n totalLines: number;\n };\n send_message: {\n messageId: string;\n };\n skill: {\n name: string;\n provider: string;\n resourceBase?: {\n kind: \"directory\";\n path: string;\n } | {\n kind: \"url\";\n url: string;\n } | {\n kind: \"opaque\";\n description: string;\n };\n content: string;\n };\n subagent: {\n kind: \"background\";\n taskId: string;\n } | {\n kind: \"continuable\";\n subagentId: string;\n } | {\n kind: \"foreground\";\n runId: string;\n output: JsonValue[];\n };\n subagent_fork: {\n kind: \"background\";\n taskId: string;\n } | {\n kind: \"continuable\";\n subagentId: string;\n } | {\n kind: \"foreground\";\n runId: string;\n output: JsonValue[];\n };\n task_kill: {\n outcome: \"cancellation-requested\" | \"already-finished\";\n task: {\n id: string;\n kind: string;\n label: string;\n status: \"running\" | \"stopping\" | \"completed\" | \"killed\" | \"failed\";\n detail?: string;\n startedAt: number;\n finishedAt?: number;\n };\n };\n task_list: ({\n id: string;\n kind: string;\n label: string;\n status: \"running\" | \"stopping\" | \"completed\" | \"killed\" | \"failed\";\n detail?: string;\n startedAt: number;\n finishedAt?: number;\n })[];\n task_output: {\n text: string;\n task: {\n id: string;\n kind: string;\n label: string;\n status: \"running\" | \"stopping\" | \"completed\" | \"killed\" | \"failed\";\n detail?: string;\n startedAt: number;\n finishedAt?: number;\n };\n };\n todo_write: {\n todos: ({\n content: string;\n status: \"pending\" | \"in_progress\" | \"completed\";\n })[];\n counts: {\n pending: number;\n inProgress: number;\n completed: number;\n };\n };\n workflow: {\n runId: string;\n agentsStarted: number;\n result: JsonValue;\n };\n write: {\n path: string;\n operation: \"create\" | \"update\";\n before: string | null;\n after: string;\n };\n}\n\ntype ToolName = keyof ToolOutputMap\n\ndeclare class ToolCallError extends Error {\n readonly name: \"ToolCallError\";\n readonly toolName: ToolName;\n}\n\ndeclare const tools: {\n [K in ToolName]: (args: ToolArgsMap[K]) => Promise;\n}\n```","tools":[{"name":"bash","description":"Execute a bash command (`bash -c`) and return its stdout/stderr. Each call runs in a fresh shell: no state (cwd, variables, functions) persists between calls — pass `workdir` instead of using `cd`. Non-zero exits are reported as `[exit code: N]`. Current harness environment facts are exposed through managed `$DSH_*` variables; inspect them when needed. Commands may run under a file sandbox; a blocked file operation is reported as `[sandbox: file access denied under mode]` — a policy denial, not a bug in the command; do not retry another way. Long output is truncated to its tail; the full output is saved to a file whose path is reported when available. Set `run_in_background: true` for long-running commands: the call returns a task id immediately; read its output with `task_output` and stop it with `task_kill`.","parameters":{"type":"object","properties":{"command":{"type":"string","description":"The bash command to execute."},"description":{"type":"string","description":"Clear, concise description of what this command does in active voice, 5-10 words (shown in the UI). Examples: \"ls\" → \"List files in current directory\"; \"git status\" → \"Show working tree status\"; \"npm install\" → \"Install package dependencies\"."},"timeoutMs":{"type":"number","description":"Timeout in milliseconds. The executor applies its configured default and cap, and kills the command on expiry."},"workdir":{"type":"string","description":"Working directory for this command. Defaults to the session workspace; a relative path is resolved against it."},"run_in_background":{"type":"boolean","description":"Run in the background and return a task id immediately (collect with task_output, stop with task_kill). No timeout applies."}},"required":["command","description"]}},{"name":"cordis_inspect","description":"Inspect the live Cordis runtime in the current DSH process. Read-only. Sections: `services` (every provided ctx service and the plugin fiber that owns it), `plugins` (all live plugin fibers with their lifecycle states), `tools` (the model-facing tools currently registered, i.e. what you can call), `temporary` (only temporary Plugins created by cordis_mount: id, name, state, provided services, awaited services, and lifetime), `api` (method signatures AND argument/return type shapes for every LIVE service — read this before writing plugin code that calls a service), `events` (every harness event with its dispatch mode and exact signature — pick listener targets here). Temporary Plugins exist only in memory, remain active across later turns, and disappear after cordis_unmount, toolset unload, or DSH restart; they are not restored automatically. The `temporary` section is a subset of `plugins`. Omit `what` to get all six sections. With `what:\"api\"` or `what:\"events\"`, pass an exact `name` to narrow to one service/event and include its original source JSDoc.","parameters":{"type":"object","properties":{"what":{"type":"string","description":"Limit the report to one section. Omit for all sections.","enum":["services","plugins","tools","temporary","api","events"]},"name":{"type":"string","description":"Exact service key or event name whose original JSDoc to include; valid only with what:\"api\" or what:\"events\"."}}}},{"name":"cordis_mount","description":"Mount a temporary Cordis Plugin in the current DSH process. This creates an in-memory runtime Plugin, not an installed or configured Plugin. It remains active across later turns until cordis_unmount, toolset unload, or DSH restart. It does not create files, install a package, change cordis.yml or personal/project config, survive restart, or automatically become permanent. To keep it, ask the Agent to implement a normal local, project, or repository Plugin through the regular development workflow. It may affect other sessions in the same process; the sandbox is not a security boundary, and injected services reach the real runtime. `code` runs now as the body of an async JavaScript function in an isolated sandbox and MUST `return` a plugin. Two forms: FUNCTION form `return (ctx) => { … }` — declares no inject, so it can register tools, listen to events, and provide services, but reaching ANY service (e.g. ctx.bash) throws; use it only when you need no services. OBJECT form `return { name?, inject: ['bash', 'llm', …], apply(ctx) { … } }` — declares dependencies, and cordis activates the plugin only after the services exist; PREFER this form. You may reach ONLY the services you list in inject: an undeclared service throws even if it exists, because an undeclared dependency would not be cleaned up if its provider is unmounted. BEFORE calling a service from your code, read cordis_inspect what:\"api\" — it lists method signatures AND the type shapes of their arguments/returns (do not guess a field's type; e.g. a bash run's stdout is an object, not a string). Inside `apply`, use the standard cordis API: `ctx.on(event, listener)` to observe events (see cordis_inspect what:\"events\"), or call `harness.registerTool(ctx, harness.defineTool({ name, description, parameters: { text: { type: 'string', required: true } }, output: { schema: { type: 'string' }, render(_args, value) { return [{ type: 'text', text: value }] } }, async execute(args) { return args.text } }))` to give yourself a new tool — it becomes callable on your NEXT step. Tool parameters: each key IS a property — { type: 'string'|'number'|'integer'|'boolean'|'null'|'object'|'array'|'json', required?: true, description?, enum?, const?, items?, properties? }; every direct DSL object declares additionalProperties: true|false, and oneOf: [schema, schema, ...] replaces type for an exact-one union. A raw JSON-Schema { type: 'object', properties, required?: […] } wrapper is also accepted with open-by-default objects. A tool's `execute` MUST return the lossless JSON value declared by `output.schema`; `output.render(args, value)` separately returns Native/model content blocks. Temporary Plugins can COMPOSE: one Plugin may `ctx.provide('name', value)` a service and another may declare `inject: ['name']` to consume it — the consumer stays pending until the provider exists and returns to pending when the provider is unmounted. Everything registered inside `apply` is cleaned up automatically by cordis_unmount. Sandbox globals: `console` (tagged `[cordis:]`, writes through to the harness terminal), `harness.defineTool`, `harness.registerTool`, `btoa`, `atob`, `TextEncoder`, `TextDecoder`. Node APIs are DISABLED — do filesystem/network/timer work through the cordis services, never Node built-ins: `require`, `setTimeout`/`setInterval`, and `fetch` throw redirect errors; `process` and `Buffer` are undefined. Instead use inject: ['fs'] + ctx.fs for files, inject: ['web'] + ctx.web for HTTP, inject: ['bash'] + ctx.bash for processes, and inject: ['timer'] + ctx.setTimeout/ctx.setInterval for timing (fiber effects, auto-cleaned when unmounted) — cordis_inspect what:\"api\" shows what THIS runtime provides. Write PLAIN JavaScript, not TypeScript (no `as`, no type annotations). Cautions: (1) waterfall events (e.g. tools/pre-execute) hand the listener a trailing `next` callback which MUST be called — returning without `next()` SHORT-CIRCUITS the call; prefer plain notification events unless you intend to intercept. (2) Never await something that only resolves after the current turn (your code runs INSIDE a tool call of that turn — it would deadlock). (3) Your `ctx` is a restricted façade: you can register tools, observe events, provide/consume services, and use timers, but framework internals (ctx.root, ctx.fiber, ctx.extend, ctx.plugin, …) are withheld. It is not a security boundary though — the services you inject (e.g. ctx.bash) reach the real runtime.","parameters":{"type":"object","properties":{"code":{"type":"string","description":"JavaScript body returning a temporary Plugin; evaluated now and saved nowhere."}},"required":["code"]}},{"name":"cordis_unmount","description":"Unmount a current-process temporary Plugin created by cordis_mount. Waits for its tools, listeners, services, timers, and other owned effects to clean up completely. Only dyn-N temporary ids are accepted; this cannot remove Loader, configured, or installed Plugins.","parameters":{"type":"object","properties":{"id":{"type":"string","description":"The temporary Plugin id returned by cordis_mount (for example \"dyn-1\"); valid only in this process and invalid after unmount or restart."}},"required":["id"]}},{"name":"edit","description":"Edit an existing UTF-8 text file by replacing literal text.","parameters":{"type":"object","properties":{"file_path":{"type":"string","description":"Path to edit, resolved by the filesystem backend."},"old_string":{"type":"string","description":"Literal text to replace. Must match exactly."},"new_string":{"type":"string","description":"Literal replacement text. Use an empty string to delete the match."},"replace_all":{"type":"boolean","description":"Replace all matches. Defaults to false; when false, old_string must appear exactly once."}},"required":["file_path","old_string","new_string"]}},{"name":"interrupt_agent","description":"Request cancellation of a background agent's current turn by its agent id. The target may be your direct child or a deeper agent created under you. Only the current turn stops: messages already queued for the agent stay parked until a later send_message, agents it started keep running, and the agent itself stays available for follow-ups. This call returns as soon as the stop request is accepted, so the target may keep running briefly; interrupting an agent that already finished is an accepted no-op.","parameters":{"type":"object","properties":{"agent_id":{"type":"string","description":"The agent id of the running agent to interrupt."}},"required":["agent_id"]}},{"name":"ralph","description":"Run a foreground fresh-agent Ralph loop toward one immutable objective. Use only when the direct human explicitly asks for Ralph or fresh-agent iteration. Each round opens a new child with no parent conversation or prior child session; the shared workspace is long-term memory, and only a bounded structured report crosses rounds. The call returns when a worker reports completion or a concrete blocker, or at the round limit. Ordinary long-running same-session work belongs to goal tools.","parameters":{"type":"object","properties":{"objective":{"type":"string","description":"The immutable completion objective for every fresh Ralph round."},"maxRounds":{"type":"number","description":"Optional positive safe-integer round cap, bounded by the deployment ceiling."}},"required":["objective"]}},{"name":"read","description":"Read a UTF-8 text file and return line-numbered content.","parameters":{"type":"object","properties":{"file_path":{"type":"string","description":"Path to read, resolved by the filesystem backend."},"offset":{"type":"number","description":"1-based first line to return. Defaults to 1."},"limit":{"type":"number","description":"Maximum number of lines to return. Defaults to 2000."}},"required":["file_path"]}},{"name":"run_code","description":"Execute a TypeScript program against the available tools. Write the BODY of an async function (erasable syntax only; top-level `await` and `return` work) and call tools as `await tools.name(args)` per the declarations in the system prompt. Only what you print or return comes back — curate it.","parameters":{"type":"object","properties":{"code":{"type":"string","description":"The program: the body of an async TypeScript function."},"description":{"type":"string","description":"Clear, concise description of what this program does in active voice, 5-10 words (shown in the UI). Examples: \"Count TODO markers across packages\"; \"Read failing test and its fixture\"; \"Rename config key in every cordis.yml\"."}},"required":["code","description"]}},{"name":"send_message","description":"Send a message to a background subagent by its subagent id, continuing the same conversation. It becomes the subagent's next turn: if it is still working, the message waits until its current turn finishes, so it cannot redirect work already underway. This call returns no answer from the subagent — only confirmation that the message was delivered — so use it to give it more work. A failure means the message was NOT delivered.","parameters":{"type":"object","properties":{"subagent_id":{"type":"string","description":"The subagent id returned when the background subagent was started."},"message":{"type":"string","description":"The message to deliver to the subagent."}},"required":["subagent_id","message"]}},{"name":"skill","description":"Load the full instructions for an available skill. Call this with the exact skill name from the session skill catalog before acting on a task that names or clearly matches that skill.","parameters":{"type":"object","properties":{"name":{"type":"string","description":"The exact skill name from the available skills list."}},"required":["name"]}},{"name":"subagent","description":"Delegate a self-contained task to a subagent (a separate agent that works in its own context) and return its final result. Use this to offload focused, independent work — research, a scoped implementation, an analysis — so it does not consume this conversation's context. The subagent runs to completion and you receive only its final answer, not its intermediate steps. Give it a complete, standalone prompt: it does not see this conversation. Set `run_in_background: true` to start a background subagent that keeps its conversation: you receive only its subagent id, never its result, and it works on its own. Use this for work whose result you do not need returned by this call; `send_message` sends it more work.","parameters":{"type":"object","properties":{"description":{"type":"string","description":"A short (3-5 word) description of the delegated task, for display."},"prompt":{"type":"string","description":"The complete, self-contained task for the subagent. It does not share this conversation's context, so include everything it needs."},"run_in_background":{"type":"boolean","description":"Run as a background subagent that keeps its conversation and return only its subagent id. This call never returns its result; send it more work with send_message."}},"required":["description","prompt"]}},{"name":"subagent_fork","description":"Delegate a task to a subagent that inherits this conversation: a child agent seeded with all completed turns so far (it does not see the current in-flight turn), returning only its final result. Use this when the subtask builds on this conversation's context — a follow-up analysis, a review, a continuation — without consuming this conversation's context for the work itself. You receive only its final answer, not its intermediate steps. Set `run_in_background: true` to start a background subagent that keeps its conversation: you receive only its subagent id, never its result, and it works on its own. Use this for work whose result you do not need returned by this call; `send_message` sends it more work.","parameters":{"type":"object","properties":{"description":{"type":"string","description":"A short (3-5 word) description of the delegated task, for display."},"prompt":{"type":"string","description":"The task for the subagent. It already sees this conversation's completed turns, so build on them freely and state only what is new."},"run_in_background":{"type":"boolean","description":"Run as a background subagent that keeps its conversation and return only its subagent id. This call never returns its result; send it more work with send_message."}},"required":["description","prompt"]}},{"name":"task_kill","description":"Request cancellation of a running background task by task id. Returns immediately; the task settles as killed once its work actually stops.","parameters":{"type":"object","properties":{"task_id":{"type":"string","description":"Task id returned by the tool that started the background work."},"reason":{"type":"string","description":"Optional short reason, recorded in the log and forwarded to the task."}},"required":["task_id"]}},{"name":"task_list","description":"List your background tasks (running and finished) with their ids, kinds, and statuses.","parameters":{"type":"object","properties":{}}},{"name":"task_output","description":"Read a background task. Stream tasks return only output since the previous read; final-output tasks return their result after settlement. Every response ends with `[status: ...]`. Reads are non-blocking unless `wait: true`, which waits up to the configured cap.","parameters":{"type":"object","properties":{"task_id":{"type":"string","description":"Task id returned by the tool that started the background work."},"wait":{"type":"boolean","description":"Block until the task reaches a terminal status or the timeout expires. A timed-out wait returns [status: running] and leaves the task alive."},"timeout_ms":{"type":"number","description":"Max wait in milliseconds (only meaningful with wait: true). Defaults to the configured wait timeout; capped by the configured maximum."}},"required":["task_id"]}},{"name":"todo_write","description":"Record and update a structured task list for the current work. Send the ENTIRE list every call — it REPLACES the previous list (there are no partial updates, no per-item edits). Use it to plan multi-step work and show progress: add one todo per concrete step before you start. Mark every todo being actively worked on `in_progress` — several at once when work genuinely runs in parallel (e.g. concurrent subagents or background commands), one for sequential work; while work remains, at least one task should be `in_progress`. Mark a todo `completed` the moment it is done (do not batch completions), and allow no `in_progress` item only once all work is complete. Skip the list for trivial single-step tasks. Statuses: `pending` (not started), `in_progress` (being worked on now), `completed` (finished).","parameters":{"type":"object","properties":{"todos":{"type":"array","description":"The COMPLETE task list, replacing any previous list.","items":{"type":"object","additionalProperties":false,"properties":{"content":{"type":"string","description":"What the task is — a short imperative line."},"status":{"type":"string","description":"pending (not started) | in_progress (now) | completed (done).","enum":["pending","in_progress","completed"]}},"required":["content","status"]}}},"required":["todos"]}},{"name":"workflow","description":"Run a JavaScript workflow script that orchestrates subagents at scale. Use this for work that fans out across many independent pieces — an audit over many files, a migration, multi-angle research, adversarial verification of findings — where you write the orchestration as a script instead of delegating turn by turn.\n\nThe workflow's identity rides the `meta` parameter as JSON: required `name` (short kebab-case) and `description` strings, optional `whenToUse` string and `phases` array (`{title, detail?, provider?, model?}`). The `script` parameter is the plain JavaScript body ONLY (NOT TypeScript, and NO `export const meta` statement — meta is a parameter, not code), running with top-level await; end with `return ` — the value must be JSON-serializable and is this tool's result.\n\nScript-body hooks:\n- `agent(prompt, opts?): Promise` — run one subagent to completion. Without `opts.schema` it resolves to the child's final text; with `opts.schema` (an object-rooted JSON Schema using ONLY type/properties/required/additionalProperties/items/enum/const/oneOf — no pattern/format/numeric bounds) it resolves to the validated object. Resolves `null` when the child fails (filter with `.filter(Boolean)`). Other opts: `label` (display), `phase` (progress group), and independent `provider`/`model` LLM target overrides (either may be provided alone). Anything else (`effort`/`isolation`/`agentType`) is rejected loudly.\n- `pipeline(items, ...stages): Promise` — run each item through the stages independently with NO barrier between stages (prefer this for multi-stage work). Each stage receives `(prev, item, index)`. An ordinary stage throw drops that ITEM to `null` and skips its remaining stages.\n- `parallel(thunks): Promise` — run zero-argument functions concurrently and await ALL of them (a barrier; use only when a stage genuinely needs every prior result together). A throwing thunk resolves to `null`.\n- `phase(title)` — start a progress phase; `log(message)` — narrate progress; `args` — the tool call's `args` input, verbatim.\n\nMisused hooks (bad arguments, unknown options, unsupported schemas, tripped caps) throw errors that ALWAYS kill the script — they never dissolve into a per-item `null`.\n\nConstraints: concurrency and total-agent caps apply; no filesystem, network, timers, or Node.js APIs are provided — the agents do the work, the script only coordinates them. The run executes in the foreground: this call returns when the whole script finishes.","parameters":{"type":"object","properties":{"script":{"type":"string","description":"The plain-JS workflow script body (top-level await allowed; NO `export const meta` statement; end with `return `)."},"meta":{"type":"object","description":"The workflow identity block (plain JSON — never code).","additionalProperties":true,"properties":{"name":{"type":"string","description":"Short kebab-case workflow name."},"description":{"type":"string","description":"One-line description of what the workflow does."},"whenToUse":{"type":"string","description":"Optional guidance on when this workflow applies."},"phases":{"type":"array","description":"Optional phase declarations matched by phase() calls.","items":{"type":"object","additionalProperties":true,"properties":{"title":{"type":"string","description":"The phase title phase() calls match by exact string."},"detail":{"type":"string","description":"Optional one-line description of the phase."},"provider":{"type":"string","description":"Optional provider override this phase is expected to use."},"model":{"type":"string","description":"Optional model override this phase is expected to use."}},"required":["title"]}}},"required":["name","description"]},"args":{"type":"object","description":"Optional JSON input exposed to the script as the `args` global (wrap a bare list as a field, e.g. {\"files\": [...]}).","additionalProperties":true}},"required":["script","meta"]}},{"name":"write","description":"Create or fully replace a UTF-8 text file.","parameters":{"type":"object","properties":{"file_path":{"type":"string","description":"Path to write, resolved by the filesystem backend."},"content":{"type":"string","description":"Full UTF-8 text content to write."}},"required":["file_path","content"]}}]},"reason":"initial"}} +{"type":"request/context","seq":9,"time":1785730501507,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} +{"type":"assistant/chunk","seq":10,"time":1783957884564,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"text"}}} +{"type":"assistant/chunk","seq":11,"time":1783957884564,"data":{"turn":1,"step":1,"chunk":{"type":"text-delta","index":0,"text":"DIRECT_CHILD_OK"}}} +{"type":"assistant/chunk","seq":12,"time":1783957884564,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"DIRECT_CHILD_OK"}}}} +{"type":"assistant/chunk","seq":13,"time":1785498583897,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}}} +{"type":"assistant/chunk","seq":14,"time":1785730501507,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"stop"}}}} +{"type":"assistant/message","seq":15,"time":1785730501507,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"text","text":"DIRECT_CHILD_OK"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"c5d4e091-9632-4535-af35-097bc74abdd3"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[10,11,12,13,14],"surfaceOp":"append"} +{"type":"step/end","seq":16,"time":1785730501507,"data":{"turn":1,"step":1}} +{"type":"turn/end","seq":17,"time":1785730501507,"data":{"turn":1,"reason":{"kind":"completed"}}} diff --git a/examples/headless-agent/tests/snapshots/advanced-toolchain/session.2.jsonl b/examples/headless-agent/tests/snapshots/advanced-toolchain/session.2.jsonl index 6988595618..8882bda5af 100644 --- a/examples/headless-agent/tests/snapshots/advanced-toolchain/session.2.jsonl +++ b/examples/headless-agent/tests/snapshots/advanced-toolchain/session.2.jsonl @@ -1,18 +1,19 @@ {"type":"session","version":0,"id":"33333333-3333-4333-8333-333333333333","createdAt":1783950002000,"cwd":"{{cwd}}","parentSession":"11111111-1111-4111-8111-111111111111","origin":"subagent","delegationDepth":1} -{"type":"agent/inbox/spliced","seq":0,"time":1785498584048,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Reply with exactly WORKFLOW_CHILD_OK and nothing else."}],"source":{"kind":"user"},"role":"user","id":"093bfc20-c6fc-4573-b172-2c6ca40c188b"}]}} +{"type":"agent/inbox/spliced","seq":0,"time":1785498584048,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Reply with exactly WORKFLOW_CHILD_OK and nothing else."}],"source":{"kind":"user"},"role":"user","id":"12fb8b24-9214-4e43-b3d3-47f2af3531f1"}]}} {"type":"turn/start","seq":1,"time":1785821454599,"data":{"turn":1}} {"type":"agent/inbox/spliced","seq":2,"time":1785821454599,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} {"type":"subagent/descriptor","seq":3,"time":1785821454618,"data":{"version":2,"mode":"one-shot","provider":"spawn"}} {"type":"step/start","seq":4,"time":1785730501645,"data":{"turn":1,"step":1}} -{"type":"user/message","seq":5,"time":1785730501645,"data":{"content":[{"type":"text","text":"Reply with exactly WORKFLOW_CHILD_OK and nothing else."}],"source":{"kind":"user"},"role":"user","id":"093bfc20-c6fc-4573-b172-2c6ca40c188b"},"surfaceOp":"append"} -{"type":"session/title","seq":6,"time":1785730501645,"data":{"title":"Reply with exactly WORKFLOW_CHILD_OK and","messageSeqs":[5],"source":{"kind":"fallback"}}} -{"type":"request/header","seq":7,"time":1785498584067,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"You are an AI agent powered by the DeepSeek Harness SDK.\n\nYou are headless-agent, a coding assistant powered by the deepseek-v4-flash model. Your working directory is {{cwd}}.\n\nVerify your work by running the code or tests. Keep answers brief and factual.\n\n\nUse the read tool — not shell commands like cat — to inspect text files. Results include line numbers. Use offset and limit to continue reading large files.\n\nUse the write tool to create files or completely replace file contents. Existing files are overwritten, so read an existing file first (the default fs-policy requires it) and prefer edit for targeted changes.\n\nUse the edit tool for targeted changes to existing UTF-8 text files. It replaces literal old_string with new_string; by default old_string must appear exactly once. If old_string appears multiple times, provide a more specific old_string or set replace_all to true. Read the file first (the default fs-policy requires it), unless you just created or edited it in this session.\n\nCheck the [exit code: N] marker on every bash result; investigate failures before moving on.\n\nTrack every background task id you start. You are notified in-session when a task finishes — do not busy-poll or sleep on one; keep working on independent steps and do not duplicate a running task's work. Before giving a final answer, collect every still-relevant task with task_output (set wait: true only when you are genuinely blocked on it), and task_kill tasks that stopped mattering.\n\nUse the workflow tool ONLY when the user explicitly asks for a workflow or for large multi-agent orchestration: you write a JavaScript script (the tool description documents the exact format) that fans work out across many subagents with phases and structured results. For one or two delegations, prefer plain subagent calls.\n\nUse the ralph tool ONLY when the direct human explicitly asks for a Ralph loop or fresh-agent iterative execution. Each Ralph round starts a fresh child with no conversation seed and uses the shared workspace as durable memory. Completion and blockers are worker reports, not independent evaluation. Use same-session goal tools for ordinary long-running objectives, and plain subagents or workflows for bounded delegation and fan-out.\n\n## Writing code for run_code\n\nPass `run_code` the body of an async TypeScript function (erasable syntax only — no `enum` or namespaces; type annotations are advisory, the code runs type-stripped). Inside the program:\n\n- Call tools as `await tools.name(args)` — quoted access for exotic names: `tools[\"my-tool\"](args)`. Every call resolves to the tool's typed canonical JSON value. Tool arguments must be lossless JSON.\n- A FAILED tool call rejects with `ToolCallError`, whose `toolName` identifies the failed tool and whose `message` is human-readable — `try/catch` it to handle and continue.\n- Independent read-only calls MAY overlap under `Promise.all` (safe calls run concurrently; mutating calls run alone, in submission order). Sequence dependent work with `await`.\n- Emit results with `return` and/or `console.log(...)`. ONLY what you print or return comes back to you — intermediate tool results never enter the conversation, so extract just what you need.\n\nThe available tools:\n\n```ts\ntype JsonValue = null | boolean | number | string | JsonValue[] | { [key: string]: JsonValue }\n\ninterface ToolArgsMap {\n /** Execute a bash command (`bash -c`) and return its stdout/stderr. Each call runs in a fresh shell: no state (cwd, variables, functions) persists between calls — pass `workdir` instead of using `cd`. Non-zero exits are reported as `[exit code: N]`. Current harness environment facts are exposed through managed `$DSH_*` variables; inspect them when needed. Commands may run under a file sandbox; a blocked file operation is reported as `[sandbox: file access denied under mode]` — a policy denial, not a bug in the command; do not retry another way. Long output is truncated to its tail; the full output is saved to a file whose path is reported when available. Set `run_in_background: true` for long-running commands: the call returns a task id immediately; read its output with `task_output` and stop it with `task_kill`. */\n bash: {\n /** The bash command to execute. */\n command: string;\n /** Clear, concise description of what this command does in active voice, 5-10 words (shown in the UI). Examples: \"ls\" → \"List files in current directory\"; \"git status\" → \"Show working tree status\"; \"npm install\" → \"Install package dependencies\". */\n description: string;\n /** Timeout in milliseconds. The executor applies its configured default and cap, and kills the command on expiry. */\n timeoutMs?: number;\n /** Working directory for this command. Defaults to the session workspace; a relative path is resolved against it. */\n workdir?: string;\n /** Run in the background and return a task id immediately (collect with task_output, stop with task_kill). No timeout applies. */\n run_in_background?: boolean;\n } & Record;\n /** Inspect the live Cordis runtime in the current DSH process. Read-only. Sections: `services` (every provided ctx service and the plugin fiber that owns it), `plugins` (all live plugin fibers with their lifecycle states), `tools` (the model-facing tools currently registered, i.e. what you can call), `temporary` (only temporary Plugins created by cordis_mount: id, name, state, provided services, awaited services, and lifetime), `api` (method signatures AND argument/return type shapes for every LIVE service — read this before writing plugin code that calls a service), `events` (every harness event with its dispatch mode and exact signature — pick listener targets here). Temporary Plugins exist only in memory, remain active across later turns, and disappear after cordis_unmount, toolset unload, or DSH restart; they are not restored automatically. The `temporary` section is a subset of `plugins`. Omit `what` to get all six sections. With `what:\"api\"` or `what:\"events\"`, pass an exact `name` to narrow to one service/event and include its original source JSDoc. */\n cordis_inspect: {\n /** Limit the report to one section. Omit for all sections. */\n what?: \"services\" | \"plugins\" | \"tools\" | \"temporary\" | \"api\" | \"events\";\n /** Exact service key or event name whose original JSDoc to include; valid only with what:\"api\" or what:\"events\". */\n name?: string;\n } & Record;\n /** Mount a temporary Cordis Plugin in the current DSH process. This creates an in-memory runtime Plugin, not an installed or configured Plugin. It remains active across later turns until cordis_unmount, toolset unload, or DSH restart. It does not create files, install a package, change cordis.yml or personal/project config, survive restart, or automatically become permanent. To keep it, ask the Agent to implement a normal local, project, or repository Plugin through the regular development workflow. It may affect other sessions in the same process; the sandbox is not a security boundary, and injected services reach the real runtime. `code` runs now as the body of an async JavaScript function in an isolated sandbox and MUST `return` a plugin. Two forms: FUNCTION form `return (ctx) => { … }` — declares no inject, so it can register tools, listen to events, and provide services, but reaching ANY service (e.g. ctx.bash) throws; use it only when you need no services. OBJECT form `return { name?, inject: ['bash', 'llm', …], apply(ctx) { … } }` — declares dependencies, and cordis activates the plugin only after the services exist; PREFER this form. You may reach ONLY the services you list in inject: an undeclared service throws even if it exists, because an undeclared dependency would not be cleaned up if its provider is unmounted. BEFORE calling a service from your code, read cordis_inspect what:\"api\" — it lists method signatures AND the type shapes of their arguments/returns (do not guess a field's type; e.g. a bash run's stdout is an object, not a string). Inside `apply`, use the standard cordis API: `ctx.on(event, listener)` to observe events (see cordis_inspect what:\"events\"), or call `harness.registerTool(ctx, harness.defineTool({ name, description, parameters: { text: { type: 'string', required: true } }, output: { schema: { type: 'string' }, render(_args, value) { return [{ type: 'text', text: value }] } }, async execute(args) { return args.text } }))` to give yourself a new tool — it becomes callable on your NEXT step. Tool parameters: each key IS a property — { type: 'string'|'number'|'integer'|'boolean'|'null'|'object'|'array'|'json', required?: true, description?, enum?, const?, items?, properties? }; every direct DSL object declares additionalProperties: true|false, and oneOf: [schema, schema, ...] replaces type for an exact-one union. A raw JSON-Schema { type: 'object', properties, required?: […] } wrapper is also accepted with open-by-default objects. A tool's `execute` MUST return the lossless JSON value declared by `output.schema`; `output.render(args, value)` separately returns Native/model content blocks. Temporary Plugins can COMPOSE: one Plugin may `ctx.provide('name', value)` a service and another may declare `inject: ['name']` to consume it — the consumer stays pending until the provider exists and returns to pending when the provider is unmounted. Everything registered inside `apply` is cleaned up automatically by cordis_unmount. Sandbox globals: `console` (tagged `[cordis:]`, writes through to the harness terminal), `harness.defineTool`, `harness.registerTool`, `btoa`, `atob`, `TextEncoder`, `TextDecoder`. Node APIs are DISABLED — do filesystem/network/timer work through the cordis services, never Node built-ins: `require`, `setTimeout`/`setInterval`, and `fetch` throw redirect errors; `process` and `Buffer` are undefined. Instead use inject: ['fs'] + ctx.fs for files, inject: ['web'] + ctx.web for HTTP, inject: ['bash'] + ctx.bash for processes, and inject: ['timer'] + ctx.setTimeout/ctx.setInterval for timing (fiber effects, auto-cleaned when unmounted) — cordis_inspect what:\"api\" shows what THIS runtime provides. Write PLAIN JavaScript, not TypeScript (no `as`, no type annotations). Cautions: (1) waterfall events (e.g. tools/pre-execute) hand the listener a trailing `next` callback which MUST be called — returning without `next()` SHORT-CIRCUITS the call; prefer plain notification events unless you intend to intercept. (2) Never await something that only resolves after the current turn (your code runs INSIDE a tool call of that turn — it would deadlock). (3) Your `ctx` is a restricted façade: you can register tools, observe events, provide/consume services, and use timers, but framework internals (ctx.root, ctx.fiber, ctx.extend, ctx.plugin, …) are withheld. It is not a security boundary though — the services you inject (e.g. ctx.bash) reach the real runtime. */\n cordis_mount: {\n /** JavaScript body returning a temporary Plugin; evaluated now and saved nowhere. */\n code: string;\n } & Record;\n /** Unmount a current-process temporary Plugin created by cordis_mount. Waits for its tools, listeners, services, timers, and other owned effects to clean up completely. Only dyn-N temporary ids are accepted; this cannot remove Loader, configured, or installed Plugins. */\n cordis_unmount: {\n /** The temporary Plugin id returned by cordis_mount (for example \"dyn-1\"); valid only in this process and invalid after unmount or restart. */\n id: string;\n } & Record;\n /** Edit an existing UTF-8 text file by replacing literal text. */\n edit: {\n /** Path to edit, resolved by the filesystem backend. */\n file_path: string;\n /** Literal text to replace. Must match exactly. */\n old_string: string;\n /** Literal replacement text. Use an empty string to delete the match. */\n new_string: string;\n /** Replace all matches. Defaults to false; when false, old_string must appear exactly once. */\n replace_all?: boolean;\n } & Record;\n /** Run a foreground fresh-agent Ralph loop toward one immutable objective. Use only when the direct human explicitly asks for Ralph or fresh-agent iteration. Each round opens a new child with no parent conversation or prior child session; the shared workspace is long-term memory, and only a bounded structured report crosses rounds. The call returns when a worker reports completion or a concrete blocker, or at the round limit. Ordinary long-running same-session work belongs to goal tools. */\n ralph: {\n /** The immutable completion objective for every fresh Ralph round. */\n objective: string;\n /** Optional positive safe-integer round cap, bounded by the deployment ceiling. */\n maxRounds?: number;\n } & Record;\n /** Read a UTF-8 text file and return line-numbered content. */\n read: {\n /** Path to read, resolved by the filesystem backend. */\n file_path: string;\n /** 1-based first line to return. Defaults to 1. */\n offset?: number;\n /** Maximum number of lines to return. Defaults to 2000. */\n limit?: number;\n } & Record;\n /** Send a message to a background subagent by its subagent id, continuing the same conversation. It becomes the subagent's next turn: if it is still working, the message waits until its current turn finishes, so it cannot redirect work already underway. This call returns no answer from the subagent — only confirmation that the message was delivered — so use it to give it more work. A failure means the message was NOT delivered. */\n send_message: {\n /** The subagent id returned when the background subagent was started. */\n subagent_id: string;\n /** The message to deliver to the subagent. */\n message: string;\n } & Record;\n /** Load the full instructions for an available skill. Call this with the exact skill name from the session skill catalog before acting on a task that names or clearly matches that skill. */\n skill: {\n /** The exact skill name from the available skills list. */\n name: string;\n } & Record;\n /** Delegate a self-contained task to a subagent (a separate agent that works in its own context) and return its final result. Use this to offload focused, independent work — research, a scoped implementation, an analysis — so it does not consume this conversation's context. The subagent runs to completion and you receive only its final answer, not its intermediate steps. Give it a complete, standalone prompt: it does not see this conversation. Set `run_in_background: true` to start a background subagent that keeps its conversation: you receive only its subagent id, never its result, and it works on its own. Use this for work whose result you do not need returned by this call; `send_message` sends it more work. */\n subagent: {\n /** A short (3-5 word) description of the delegated task, for display. */\n description: string;\n /** The complete, self-contained task for the subagent. It does not share this conversation's context, so include everything it needs. */\n prompt: string;\n /** Run as a background subagent that keeps its conversation and return only its subagent id. This call never returns its result; send it more work with send_message. */\n run_in_background?: boolean;\n } & Record;\n /** Delegate a task to a subagent that inherits this conversation: a child agent seeded with all completed turns so far (it does not see the current in-flight turn), returning only its final result. Use this when the subtask builds on this conversation's context — a follow-up analysis, a review, a continuation — without consuming this conversation's context for the work itself. You receive only its final answer, not its intermediate steps. Set `run_in_background: true` to start a background subagent that keeps its conversation: you receive only its subagent id, never its result, and it works on its own. Use this for work whose result you do not need returned by this call; `send_message` sends it more work. */\n subagent_fork: {\n /** A short (3-5 word) description of the delegated task, for display. */\n description: string;\n /** The task for the subagent. It already sees this conversation's completed turns, so build on them freely and state only what is new. */\n prompt: string;\n /** Run as a background subagent that keeps its conversation and return only its subagent id. This call never returns its result; send it more work with send_message. */\n run_in_background?: boolean;\n } & Record;\n /** Request cancellation of a running background task by task id. Returns immediately; the task settles as killed once its work actually stops. */\n task_kill: {\n /** Task id returned by the tool that started the background work. */\n task_id: string;\n /** Optional short reason, recorded in the log and forwarded to the task. */\n reason?: string;\n } & Record;\n /** List your background tasks (running and finished) with their ids, kinds, and statuses. */\n task_list: Record;\n /** Read a background task. Stream tasks return only output since the previous read; final-output tasks return their result after settlement. Every response ends with `[status: ...]`. Reads are non-blocking unless `wait: true`, which waits up to the configured cap. */\n task_output: {\n /** Task id returned by the tool that started the background work. */\n task_id: string;\n /** Block until the task reaches a terminal status or the timeout expires. A timed-out wait returns [status: running] and leaves the task alive. */\n wait?: boolean;\n /** Max wait in milliseconds (only meaningful with wait: true). Defaults to the configured wait timeout; capped by the configured maximum. */\n timeout_ms?: number;\n } & Record;\n /** Record and update a structured task list for the current work. Send the ENTIRE list every call — it REPLACES the previous list (there are no partial updates, no per-item edits). Use it to plan multi-step work and show progress: add one todo per concrete step before you start. Mark every todo being actively worked on `in_progress` — several at once when work genuinely runs in parallel (e.g. concurrent subagents or background commands), one for sequential work; while work remains, at least one task should be `in_progress`. Mark a todo `completed` the moment it is done (do not batch completions), and allow no `in_progress` item only once all work is complete. Skip the list for trivial single-step tasks. Statuses: `pending` (not started), `in_progress` (being worked on now), `completed` (finished). */\n todo_write: {\n /** The COMPLETE task list, replacing any previous list. */\n todos: ({\n /** What the task is — a short imperative line. */\n content: string;\n /** pending (not started) | in_progress (now) | completed (done). */\n status: \"pending\" | \"in_progress\" | \"completed\";\n })[];\n } & Record;\n /** Run a JavaScript workflow script that orchestrates subagents at scale. Use this for work that fans out across many independent pieces — an audit over many files, a migration, multi-angle research, adversarial verification of findings — where you write the orchestration as a script instead of delegating turn by turn. The workflow's identity rides the `meta` parameter as JSON: required `name` (short kebab-case) and `description` strings, optional `whenToUse` string and `phases` array (`{title, detail?, provider?, model?}`). The `script` parameter is the plain JavaScript body ONLY (NOT TypeScript, and NO `export const meta` statement — meta is a parameter, not code), running with top-level await; end with `return ` — the value must be JSON-serializable and is this tool's result. Script-body hooks: - `agent(prompt, opts?): Promise` — run one subagent to completion. Without `opts.schema` it resolves to the child's final text; with `opts.schema` (an object-rooted JSON Schema using ONLY type/properties/required/additionalProperties/items/enum/const/oneOf — no pattern/format/numeric bounds) it resolves to the validated object. Resolves `null` when the child fails (filter with `.filter(Boolean)`). Other opts: `label` (display), `phase` (progress group), and independent `provider`/`model` LLM target overrides (either may be provided alone). Anything else (`effort`/`isolation`/`agentType`) is rejected loudly. - `pipeline(items, ...stages): Promise` — run each item through the stages independently with NO barrier between stages (prefer this for multi-stage work). Each stage receives `(prev, item, index)`. An ordinary stage throw drops that ITEM to `null` and skips its remaining stages. - `parallel(thunks): Promise` — run zero-argument functions concurrently and await ALL of them (a barrier; use only when a stage genuinely needs every prior result together). A throwing thunk resolves to `null`. - `phase(title)` — start a progress phase; `log(message)` — narrate progress; `args` — the tool call's `args` input, verbatim. Misused hooks (bad arguments, unknown options, unsupported schemas, tripped caps) throw errors that ALWAYS kill the script — they never dissolve into a per-item `null`. Constraints: concurrency and total-agent caps apply; no filesystem, network, timers, or Node.js APIs are provided — the agents do the work, the script only coordinates them. The run executes in the foreground: this call returns when the whole script finishes. */\n workflow: {\n /** The plain-JS workflow script body (top-level await allowed; NO `export const meta` statement; end with `return `). */\n script: string;\n /** The workflow identity block (plain JSON — never code). */\n meta: {\n /** Short kebab-case workflow name. */\n name: string;\n /** One-line description of what the workflow does. */\n description: string;\n /** Optional guidance on when this workflow applies. */\n whenToUse?: string;\n /** Optional phase declarations matched by phase() calls. */\n phases?: ({\n /** The phase title phase() calls match by exact string. */\n title: string;\n /** Optional one-line description of the phase. */\n detail?: string;\n /** Optional provider override this phase is expected to use. */\n provider?: string;\n /** Optional model override this phase is expected to use. */\n model?: string;\n } & Record)[];\n } & Record;\n /** Optional JSON input exposed to the script as the `args` global (wrap a bare list as a field, e.g. {\"files\": [...]}). */\n args?: Record;\n } & Record;\n /** Create or fully replace a UTF-8 text file. */\n write: {\n /** Path to write, resolved by the filesystem backend. */\n file_path: string;\n /** Full UTF-8 text content to write. */\n content: string;\n } & Record;\n}\n\ninterface ToolOutputMap {\n bash: {\n kind: \"background\";\n taskId: string;\n } | {\n kind: \"foreground\";\n exitCode: number | null;\n signal: string | null;\n timedOut: boolean;\n aborted: boolean;\n timeoutMs: number;\n stdout: {\n text: string;\n truncated: boolean;\n spillPath?: string;\n };\n stderr: {\n text: string;\n truncated: boolean;\n spillPath?: string;\n };\n sandbox?: {\n mode: string;\n denied: boolean;\n enforcement?: string;\n runnerFailed?: boolean;\n };\n };\n cordis_inspect: string;\n cordis_mount: {\n id: string;\n pluginName: string;\n state: \"pending\" | \"loading\" | \"active\" | \"failed\" | \"disposed\" | \"unloading\";\n provides: string[];\n waitingFor: string[];\n };\n cordis_unmount: {\n id: string;\n pluginName: string;\n };\n edit: {\n path: string;\n before: string;\n after: string;\n };\n ralph: {\n runId: string;\n agentsStarted: number;\n result: JsonValue;\n };\n read: {\n path: string;\n offset: number;\n lines: {\n number: number;\n text: string;\n }[];\n totalLines: number;\n };\n send_message: {\n messageId: string;\n };\n skill: {\n name: string;\n provider: string;\n resourceBase?: {\n kind: \"directory\";\n path: string;\n } | {\n kind: \"url\";\n url: string;\n } | {\n kind: \"opaque\";\n description: string;\n };\n content: string;\n };\n subagent: {\n kind: \"background\";\n taskId: string;\n } | {\n kind: \"continuable\";\n subagentId: string;\n } | {\n kind: \"foreground\";\n runId: string;\n output: JsonValue[];\n };\n subagent_fork: {\n kind: \"background\";\n taskId: string;\n } | {\n kind: \"continuable\";\n subagentId: string;\n } | {\n kind: \"foreground\";\n runId: string;\n output: JsonValue[];\n };\n task_kill: {\n outcome: \"cancellation-requested\" | \"already-finished\";\n task: {\n id: string;\n kind: string;\n label: string;\n status: \"running\" | \"stopping\" | \"completed\" | \"killed\" | \"failed\";\n detail?: string;\n startedAt: number;\n finishedAt?: number;\n };\n };\n task_list: ({\n id: string;\n kind: string;\n label: string;\n status: \"running\" | \"stopping\" | \"completed\" | \"killed\" | \"failed\";\n detail?: string;\n startedAt: number;\n finishedAt?: number;\n })[];\n task_output: {\n text: string;\n task: {\n id: string;\n kind: string;\n label: string;\n status: \"running\" | \"stopping\" | \"completed\" | \"killed\" | \"failed\";\n detail?: string;\n startedAt: number;\n finishedAt?: number;\n };\n };\n todo_write: {\n todos: ({\n content: string;\n status: \"pending\" | \"in_progress\" | \"completed\";\n })[];\n counts: {\n pending: number;\n inProgress: number;\n completed: number;\n };\n };\n workflow: {\n runId: string;\n agentsStarted: number;\n result: JsonValue;\n };\n write: {\n path: string;\n operation: \"create\" | \"update\";\n before: string | null;\n after: string;\n };\n}\n\ntype ToolName = keyof ToolOutputMap\n\ndeclare class ToolCallError extends Error {\n readonly name: \"ToolCallError\";\n readonly toolName: ToolName;\n}\n\ndeclare const tools: {\n [K in ToolName]: (args: ToolArgsMap[K]) => Promise;\n}\n```","tools":[{"name":"bash","description":"Execute a bash command (`bash -c`) and return its stdout/stderr. Each call runs in a fresh shell: no state (cwd, variables, functions) persists between calls — pass `workdir` instead of using `cd`. Non-zero exits are reported as `[exit code: N]`. Current harness environment facts are exposed through managed `$DSH_*` variables; inspect them when needed. Commands may run under a file sandbox; a blocked file operation is reported as `[sandbox: file access denied under mode]` — a policy denial, not a bug in the command; do not retry another way. Long output is truncated to its tail; the full output is saved to a file whose path is reported when available. Set `run_in_background: true` for long-running commands: the call returns a task id immediately; read its output with `task_output` and stop it with `task_kill`.","parameters":{"type":"object","properties":{"command":{"type":"string","description":"The bash command to execute."},"description":{"type":"string","description":"Clear, concise description of what this command does in active voice, 5-10 words (shown in the UI). Examples: \"ls\" → \"List files in current directory\"; \"git status\" → \"Show working tree status\"; \"npm install\" → \"Install package dependencies\"."},"timeoutMs":{"type":"number","description":"Timeout in milliseconds. The executor applies its configured default and cap, and kills the command on expiry."},"workdir":{"type":"string","description":"Working directory for this command. Defaults to the session workspace; a relative path is resolved against it."},"run_in_background":{"type":"boolean","description":"Run in the background and return a task id immediately (collect with task_output, stop with task_kill). No timeout applies."}},"required":["command","description"]}},{"name":"cordis_inspect","description":"Inspect the live Cordis runtime in the current DSH process. Read-only. Sections: `services` (every provided ctx service and the plugin fiber that owns it), `plugins` (all live plugin fibers with their lifecycle states), `tools` (the model-facing tools currently registered, i.e. what you can call), `temporary` (only temporary Plugins created by cordis_mount: id, name, state, provided services, awaited services, and lifetime), `api` (method signatures AND argument/return type shapes for every LIVE service — read this before writing plugin code that calls a service), `events` (every harness event with its dispatch mode and exact signature — pick listener targets here). Temporary Plugins exist only in memory, remain active across later turns, and disappear after cordis_unmount, toolset unload, or DSH restart; they are not restored automatically. The `temporary` section is a subset of `plugins`. Omit `what` to get all six sections. With `what:\"api\"` or `what:\"events\"`, pass an exact `name` to narrow to one service/event and include its original source JSDoc.","parameters":{"type":"object","properties":{"what":{"type":"string","description":"Limit the report to one section. Omit for all sections.","enum":["services","plugins","tools","temporary","api","events"]},"name":{"type":"string","description":"Exact service key or event name whose original JSDoc to include; valid only with what:\"api\" or what:\"events\"."}}}},{"name":"cordis_mount","description":"Mount a temporary Cordis Plugin in the current DSH process. This creates an in-memory runtime Plugin, not an installed or configured Plugin. It remains active across later turns until cordis_unmount, toolset unload, or DSH restart. It does not create files, install a package, change cordis.yml or personal/project config, survive restart, or automatically become permanent. To keep it, ask the Agent to implement a normal local, project, or repository Plugin through the regular development workflow. It may affect other sessions in the same process; the sandbox is not a security boundary, and injected services reach the real runtime. `code` runs now as the body of an async JavaScript function in an isolated sandbox and MUST `return` a plugin. Two forms: FUNCTION form `return (ctx) => { … }` — declares no inject, so it can register tools, listen to events, and provide services, but reaching ANY service (e.g. ctx.bash) throws; use it only when you need no services. OBJECT form `return { name?, inject: ['bash', 'llm', …], apply(ctx) { … } }` — declares dependencies, and cordis activates the plugin only after the services exist; PREFER this form. You may reach ONLY the services you list in inject: an undeclared service throws even if it exists, because an undeclared dependency would not be cleaned up if its provider is unmounted. BEFORE calling a service from your code, read cordis_inspect what:\"api\" — it lists method signatures AND the type shapes of their arguments/returns (do not guess a field's type; e.g. a bash run's stdout is an object, not a string). Inside `apply`, use the standard cordis API: `ctx.on(event, listener)` to observe events (see cordis_inspect what:\"events\"), or call `harness.registerTool(ctx, harness.defineTool({ name, description, parameters: { text: { type: 'string', required: true } }, output: { schema: { type: 'string' }, render(_args, value) { return [{ type: 'text', text: value }] } }, async execute(args) { return args.text } }))` to give yourself a new tool — it becomes callable on your NEXT step. Tool parameters: each key IS a property — { type: 'string'|'number'|'integer'|'boolean'|'null'|'object'|'array'|'json', required?: true, description?, enum?, const?, items?, properties? }; every direct DSL object declares additionalProperties: true|false, and oneOf: [schema, schema, ...] replaces type for an exact-one union. A raw JSON-Schema { type: 'object', properties, required?: […] } wrapper is also accepted with open-by-default objects. A tool's `execute` MUST return the lossless JSON value declared by `output.schema`; `output.render(args, value)` separately returns Native/model content blocks. Temporary Plugins can COMPOSE: one Plugin may `ctx.provide('name', value)` a service and another may declare `inject: ['name']` to consume it — the consumer stays pending until the provider exists and returns to pending when the provider is unmounted. Everything registered inside `apply` is cleaned up automatically by cordis_unmount. Sandbox globals: `console` (tagged `[cordis:]`, writes through to the harness terminal), `harness.defineTool`, `harness.registerTool`, `btoa`, `atob`, `TextEncoder`, `TextDecoder`. Node APIs are DISABLED — do filesystem/network/timer work through the cordis services, never Node built-ins: `require`, `setTimeout`/`setInterval`, and `fetch` throw redirect errors; `process` and `Buffer` are undefined. Instead use inject: ['fs'] + ctx.fs for files, inject: ['web'] + ctx.web for HTTP, inject: ['bash'] + ctx.bash for processes, and inject: ['timer'] + ctx.setTimeout/ctx.setInterval for timing (fiber effects, auto-cleaned when unmounted) — cordis_inspect what:\"api\" shows what THIS runtime provides. Write PLAIN JavaScript, not TypeScript (no `as`, no type annotations). Cautions: (1) waterfall events (e.g. tools/pre-execute) hand the listener a trailing `next` callback which MUST be called — returning without `next()` SHORT-CIRCUITS the call; prefer plain notification events unless you intend to intercept. (2) Never await something that only resolves after the current turn (your code runs INSIDE a tool call of that turn — it would deadlock). (3) Your `ctx` is a restricted façade: you can register tools, observe events, provide/consume services, and use timers, but framework internals (ctx.root, ctx.fiber, ctx.extend, ctx.plugin, …) are withheld. It is not a security boundary though — the services you inject (e.g. ctx.bash) reach the real runtime.","parameters":{"type":"object","properties":{"code":{"type":"string","description":"JavaScript body returning a temporary Plugin; evaluated now and saved nowhere."}},"required":["code"]}},{"name":"cordis_unmount","description":"Unmount a current-process temporary Plugin created by cordis_mount. Waits for its tools, listeners, services, timers, and other owned effects to clean up completely. Only dyn-N temporary ids are accepted; this cannot remove Loader, configured, or installed Plugins.","parameters":{"type":"object","properties":{"id":{"type":"string","description":"The temporary Plugin id returned by cordis_mount (for example \"dyn-1\"); valid only in this process and invalid after unmount or restart."}},"required":["id"]}},{"name":"edit","description":"Edit an existing UTF-8 text file by replacing literal text.","parameters":{"type":"object","properties":{"file_path":{"type":"string","description":"Path to edit, resolved by the filesystem backend."},"old_string":{"type":"string","description":"Literal text to replace. Must match exactly."},"new_string":{"type":"string","description":"Literal replacement text. Use an empty string to delete the match."},"replace_all":{"type":"boolean","description":"Replace all matches. Defaults to false; when false, old_string must appear exactly once."}},"required":["file_path","old_string","new_string"]}},{"name":"ralph","description":"Run a foreground fresh-agent Ralph loop toward one immutable objective. Use only when the direct human explicitly asks for Ralph or fresh-agent iteration. Each round opens a new child with no parent conversation or prior child session; the shared workspace is long-term memory, and only a bounded structured report crosses rounds. The call returns when a worker reports completion or a concrete blocker, or at the round limit. Ordinary long-running same-session work belongs to goal tools.","parameters":{"type":"object","properties":{"objective":{"type":"string","description":"The immutable completion objective for every fresh Ralph round."},"maxRounds":{"type":"number","description":"Optional positive safe-integer round cap, bounded by the deployment ceiling."}},"required":["objective"]}},{"name":"read","description":"Read a UTF-8 text file and return line-numbered content.","parameters":{"type":"object","properties":{"file_path":{"type":"string","description":"Path to read, resolved by the filesystem backend."},"offset":{"type":"number","description":"1-based first line to return. Defaults to 1."},"limit":{"type":"number","description":"Maximum number of lines to return. Defaults to 2000."}},"required":["file_path"]}},{"name":"run_code","description":"Execute a TypeScript program against the available tools. Write the BODY of an async function (erasable syntax only; top-level `await` and `return` work) and call tools as `await tools.name(args)` per the declarations in the system prompt. Only what you print or return comes back — curate it.","parameters":{"type":"object","properties":{"code":{"type":"string","description":"The program: the body of an async TypeScript function."},"description":{"type":"string","description":"Clear, concise description of what this program does in active voice, 5-10 words (shown in the UI). Examples: \"Count TODO markers across packages\"; \"Read failing test and its fixture\"; \"Rename config key in every cordis.yml\"."}},"required":["code","description"]}},{"name":"send_message","description":"Send a message to a background subagent by its subagent id, continuing the same conversation. It becomes the subagent's next turn: if it is still working, the message waits until its current turn finishes, so it cannot redirect work already underway. This call returns no answer from the subagent — only confirmation that the message was delivered — so use it to give it more work. A failure means the message was NOT delivered.","parameters":{"type":"object","properties":{"subagent_id":{"type":"string","description":"The subagent id returned when the background subagent was started."},"message":{"type":"string","description":"The message to deliver to the subagent."}},"required":["subagent_id","message"]}},{"name":"skill","description":"Load the full instructions for an available skill. Call this with the exact skill name from the session skill catalog before acting on a task that names or clearly matches that skill.","parameters":{"type":"object","properties":{"name":{"type":"string","description":"The exact skill name from the available skills list."}},"required":["name"]}},{"name":"subagent","description":"Delegate a self-contained task to a subagent (a separate agent that works in its own context) and return its final result. Use this to offload focused, independent work — research, a scoped implementation, an analysis — so it does not consume this conversation's context. The subagent runs to completion and you receive only its final answer, not its intermediate steps. Give it a complete, standalone prompt: it does not see this conversation. Set `run_in_background: true` to start a background subagent that keeps its conversation: you receive only its subagent id, never its result, and it works on its own. Use this for work whose result you do not need returned by this call; `send_message` sends it more work.","parameters":{"type":"object","properties":{"description":{"type":"string","description":"A short (3-5 word) description of the delegated task, for display."},"prompt":{"type":"string","description":"The complete, self-contained task for the subagent. It does not share this conversation's context, so include everything it needs."},"run_in_background":{"type":"boolean","description":"Run as a background subagent that keeps its conversation and return only its subagent id. This call never returns its result; send it more work with send_message."}},"required":["description","prompt"]}},{"name":"subagent_fork","description":"Delegate a task to a subagent that inherits this conversation: a child agent seeded with all completed turns so far (it does not see the current in-flight turn), returning only its final result. Use this when the subtask builds on this conversation's context — a follow-up analysis, a review, a continuation — without consuming this conversation's context for the work itself. You receive only its final answer, not its intermediate steps. Set `run_in_background: true` to start a background subagent that keeps its conversation: you receive only its subagent id, never its result, and it works on its own. Use this for work whose result you do not need returned by this call; `send_message` sends it more work.","parameters":{"type":"object","properties":{"description":{"type":"string","description":"A short (3-5 word) description of the delegated task, for display."},"prompt":{"type":"string","description":"The task for the subagent. It already sees this conversation's completed turns, so build on them freely and state only what is new."},"run_in_background":{"type":"boolean","description":"Run as a background subagent that keeps its conversation and return only its subagent id. This call never returns its result; send it more work with send_message."}},"required":["description","prompt"]}},{"name":"task_kill","description":"Request cancellation of a running background task by task id. Returns immediately; the task settles as killed once its work actually stops.","parameters":{"type":"object","properties":{"task_id":{"type":"string","description":"Task id returned by the tool that started the background work."},"reason":{"type":"string","description":"Optional short reason, recorded in the log and forwarded to the task."}},"required":["task_id"]}},{"name":"task_list","description":"List your background tasks (running and finished) with their ids, kinds, and statuses.","parameters":{"type":"object","properties":{}}},{"name":"task_output","description":"Read a background task. Stream tasks return only output since the previous read; final-output tasks return their result after settlement. Every response ends with `[status: ...]`. Reads are non-blocking unless `wait: true`, which waits up to the configured cap.","parameters":{"type":"object","properties":{"task_id":{"type":"string","description":"Task id returned by the tool that started the background work."},"wait":{"type":"boolean","description":"Block until the task reaches a terminal status or the timeout expires. A timed-out wait returns [status: running] and leaves the task alive."},"timeout_ms":{"type":"number","description":"Max wait in milliseconds (only meaningful with wait: true). Defaults to the configured wait timeout; capped by the configured maximum."}},"required":["task_id"]}},{"name":"todo_write","description":"Record and update a structured task list for the current work. Send the ENTIRE list every call — it REPLACES the previous list (there are no partial updates, no per-item edits). Use it to plan multi-step work and show progress: add one todo per concrete step before you start. Mark every todo being actively worked on `in_progress` — several at once when work genuinely runs in parallel (e.g. concurrent subagents or background commands), one for sequential work; while work remains, at least one task should be `in_progress`. Mark a todo `completed` the moment it is done (do not batch completions), and allow no `in_progress` item only once all work is complete. Skip the list for trivial single-step tasks. Statuses: `pending` (not started), `in_progress` (being worked on now), `completed` (finished).","parameters":{"type":"object","properties":{"todos":{"type":"array","description":"The COMPLETE task list, replacing any previous list.","items":{"type":"object","additionalProperties":false,"properties":{"content":{"type":"string","description":"What the task is — a short imperative line."},"status":{"type":"string","description":"pending (not started) | in_progress (now) | completed (done).","enum":["pending","in_progress","completed"]}},"required":["content","status"]}}},"required":["todos"]}},{"name":"workflow","description":"Run a JavaScript workflow script that orchestrates subagents at scale. Use this for work that fans out across many independent pieces — an audit over many files, a migration, multi-angle research, adversarial verification of findings — where you write the orchestration as a script instead of delegating turn by turn.\n\nThe workflow's identity rides the `meta` parameter as JSON: required `name` (short kebab-case) and `description` strings, optional `whenToUse` string and `phases` array (`{title, detail?, provider?, model?}`). The `script` parameter is the plain JavaScript body ONLY (NOT TypeScript, and NO `export const meta` statement — meta is a parameter, not code), running with top-level await; end with `return ` — the value must be JSON-serializable and is this tool's result.\n\nScript-body hooks:\n- `agent(prompt, opts?): Promise` — run one subagent to completion. Without `opts.schema` it resolves to the child's final text; with `opts.schema` (an object-rooted JSON Schema using ONLY type/properties/required/additionalProperties/items/enum/const/oneOf — no pattern/format/numeric bounds) it resolves to the validated object. Resolves `null` when the child fails (filter with `.filter(Boolean)`). Other opts: `label` (display), `phase` (progress group), and independent `provider`/`model` LLM target overrides (either may be provided alone). Anything else (`effort`/`isolation`/`agentType`) is rejected loudly.\n- `pipeline(items, ...stages): Promise` — run each item through the stages independently with NO barrier between stages (prefer this for multi-stage work). Each stage receives `(prev, item, index)`. An ordinary stage throw drops that ITEM to `null` and skips its remaining stages.\n- `parallel(thunks): Promise` — run zero-argument functions concurrently and await ALL of them (a barrier; use only when a stage genuinely needs every prior result together). A throwing thunk resolves to `null`.\n- `phase(title)` — start a progress phase; `log(message)` — narrate progress; `args` — the tool call's `args` input, verbatim.\n\nMisused hooks (bad arguments, unknown options, unsupported schemas, tripped caps) throw errors that ALWAYS kill the script — they never dissolve into a per-item `null`.\n\nConstraints: concurrency and total-agent caps apply; no filesystem, network, timers, or Node.js APIs are provided — the agents do the work, the script only coordinates them. The run executes in the foreground: this call returns when the whole script finishes.","parameters":{"type":"object","properties":{"script":{"type":"string","description":"The plain-JS workflow script body (top-level await allowed; NO `export const meta` statement; end with `return `)."},"meta":{"type":"object","description":"The workflow identity block (plain JSON — never code).","additionalProperties":true,"properties":{"name":{"type":"string","description":"Short kebab-case workflow name."},"description":{"type":"string","description":"One-line description of what the workflow does."},"whenToUse":{"type":"string","description":"Optional guidance on when this workflow applies."},"phases":{"type":"array","description":"Optional phase declarations matched by phase() calls.","items":{"type":"object","additionalProperties":true,"properties":{"title":{"type":"string","description":"The phase title phase() calls match by exact string."},"detail":{"type":"string","description":"Optional one-line description of the phase."},"provider":{"type":"string","description":"Optional provider override this phase is expected to use."},"model":{"type":"string","description":"Optional model override this phase is expected to use."}},"required":["title"]}}},"required":["name","description"]},"args":{"type":"object","description":"Optional JSON input exposed to the script as the `args` global (wrap a bare list as a field, e.g. {\"files\": [...]}).","additionalProperties":true}},"required":["script","meta"]}},{"name":"write","description":"Create or fully replace a UTF-8 text file.","parameters":{"type":"object","properties":{"file_path":{"type":"string","description":"Path to write, resolved by the filesystem backend."},"content":{"type":"string","description":"Full UTF-8 text content to write."}},"required":["file_path","content"]}}]},"reason":"initial"}} -{"type":"request/context","seq":8,"time":1785730501646,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} -{"type":"assistant/chunk","seq":9,"time":1783957884701,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"text"}}} -{"type":"assistant/chunk","seq":10,"time":1783957884701,"data":{"turn":1,"step":1,"chunk":{"type":"text-delta","index":0,"text":"WORKFLOW_CHILD_OK"}}} -{"type":"assistant/chunk","seq":11,"time":1783957884701,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"WORKFLOW_CHILD_OK"}}}} -{"type":"assistant/chunk","seq":12,"time":1785498584067,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}}} -{"type":"assistant/chunk","seq":13,"time":1785730501646,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"stop"}}}} -{"type":"assistant/message","seq":14,"time":1785730501646,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"text","text":"WORKFLOW_CHILD_OK"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"2b31dae5-8939-44e1-bbcd-9f64aa637d76"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[9,10,11,12,13],"surfaceOp":"append"} -{"type":"step/end","seq":15,"time":1785730501646,"data":{"turn":1,"step":1}} -{"type":"turn/end","seq":16,"time":1785730501646,"data":{"turn":1,"reason":{"kind":"completed"}}} +{"type":"user/message","seq":5,"time":1785730501645,"data":{"content":[{"type":"text","text":"Reply with exactly WORKFLOW_CHILD_OK and nothing else."}],"source":{"kind":"user"},"role":"user","id":"12fb8b24-9214-4e43-b3d3-47f2af3531f1"},"surfaceOp":"append"} +{"type":"user/message","seq":6,"time":1786358103827,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nYou are a delegated subagent: your permission scope was fixed when you were started and cannot be widened from inside this session — operations that require approval are rejected automatically. When the task needs access beyond that scope, do not retry the denied operation; state the limitation in your reply so the delegating agent can handle it."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"subagent:delegation","text":"You are a delegated subagent: your permission scope was fixed when you were started and cannot be widened from inside this session — operations that require approval are rejected automatically. When the task needs access beyond that scope, do not retry the denied operation; state the limitation in your reply so the delegating agent can handle it."}]},"role":"user","id":"14cf8f47-3a7a-4857-a548-02fe407683fb"},"surfaceOp":"append"} +{"type":"session/title","seq":7,"time":1786358103827,"data":{"title":"Reply with exactly WORKFLOW_CHILD_OK and","messageSeqs":[5],"source":{"kind":"fallback"}}} +{"type":"request/header","seq":8,"time":1785498584067,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"You are an AI agent powered by the DeepSeek Harness SDK.\n\nYou are headless-agent, a coding assistant powered by the deepseek-v4-flash model. Your working directory is {{cwd}}.\n\nVerify your work by running the code or tests. Keep answers brief and factual.\n\n\nUse the read tool — not shell commands like cat — to inspect text files. Results include line numbers. Use offset and limit to continue reading large files.\n\nUse the write tool to create files or completely replace file contents. Existing files are overwritten, so read an existing file first (the default fs-policy requires it) and prefer edit for targeted changes.\n\nUse the edit tool for targeted changes to existing UTF-8 text files. It replaces literal old_string with new_string; by default old_string must appear exactly once. If old_string appears multiple times, provide a more specific old_string or set replace_all to true. Read the file first (the default fs-policy requires it), unless you just created or edited it in this session.\n\nCheck the [exit code: N] marker on every bash result; investigate failures before moving on.\n\nTrack every background task id you start. You are notified in-session when a task finishes — do not busy-poll or sleep on one; keep working on independent steps and do not duplicate a running task's work. Before giving a final answer, collect every still-relevant task with task_output (set wait: true only when you are genuinely blocked on it), and task_kill tasks that stopped mattering.\n\nUse the workflow tool ONLY when the user explicitly asks for a workflow or for large multi-agent orchestration: you write a JavaScript script (the tool description documents the exact format) that fans work out across many subagents with phases and structured results. For one or two delegations, prefer plain subagent calls.\n\nUse the ralph tool ONLY when the direct human explicitly asks for a Ralph loop or fresh-agent iterative execution. Each Ralph round starts a fresh child with no conversation seed and uses the shared workspace as durable memory. Completion and blockers are worker reports, not independent evaluation. Use same-session goal tools for ordinary long-running objectives, and plain subagents or workflows for bounded delegation and fan-out.\n\n## Writing code for run_code\n\nPass `run_code` the body of an async TypeScript function (erasable syntax only — no `enum` or namespaces; type annotations are advisory, the code runs type-stripped). Inside the program:\n\n- Call tools as `await tools.name(args)` — quoted access for exotic names: `tools[\"my-tool\"](args)`. Every call resolves to the tool's typed canonical JSON value. Tool arguments must be lossless JSON.\n- A FAILED tool call rejects with `ToolCallError`, whose `toolName` identifies the failed tool and whose `message` is human-readable — `try/catch` it to handle and continue.\n- Independent read-only calls MAY overlap under `Promise.all` (safe calls run concurrently; mutating calls run alone, in submission order). Sequence dependent work with `await`.\n- Emit results with `return` and/or `console.log(...)`. ONLY what you print or return comes back to you — intermediate tool results never enter the conversation, so extract just what you need.\n\nThe available tools:\n\n```ts\ntype JsonValue = null | boolean | number | string | JsonValue[] | { [key: string]: JsonValue }\n\ninterface ToolArgsMap {\n /** Execute a bash command (`bash -c`) and return its stdout/stderr. Each call runs in a fresh shell: no state (cwd, variables, functions) persists between calls — pass `workdir` instead of using `cd`. Non-zero exits are reported as `[exit code: N]`. Current harness environment facts are exposed through managed `$DSH_*` variables; inspect them when needed. Commands may run under a file sandbox; a blocked file operation is reported as `[sandbox: file access denied under mode]` — a policy denial, not a bug in the command; do not retry another way. Long output is truncated to its tail; the full output is saved to a file whose path is reported when available. Set `run_in_background: true` for long-running commands: the call returns a task id immediately; read its output with `task_output` and stop it with `task_kill`. */\n bash: {\n /** The bash command to execute. */\n command: string;\n /** Clear, concise description of what this command does in active voice, 5-10 words (shown in the UI). Examples: \"ls\" → \"List files in current directory\"; \"git status\" → \"Show working tree status\"; \"npm install\" → \"Install package dependencies\". */\n description: string;\n /** Timeout in milliseconds. The executor applies its configured default and cap, and kills the command on expiry. */\n timeoutMs?: number;\n /** Working directory for this command. Defaults to the session workspace; a relative path is resolved against it. */\n workdir?: string;\n /** Run in the background and return a task id immediately (collect with task_output, stop with task_kill). No timeout applies. */\n run_in_background?: boolean;\n } & Record;\n /** Inspect the live Cordis runtime in the current DSH process. Read-only. Sections: `services` (every provided ctx service and the plugin fiber that owns it), `plugins` (all live plugin fibers with their lifecycle states), `tools` (the model-facing tools currently registered, i.e. what you can call), `temporary` (only temporary Plugins created by cordis_mount: id, name, state, provided services, awaited services, and lifetime), `api` (method signatures AND argument/return type shapes for every LIVE service — read this before writing plugin code that calls a service), `events` (every harness event with its dispatch mode and exact signature — pick listener targets here). Temporary Plugins exist only in memory, remain active across later turns, and disappear after cordis_unmount, toolset unload, or DSH restart; they are not restored automatically. The `temporary` section is a subset of `plugins`. Omit `what` to get all six sections. With `what:\"api\"` or `what:\"events\"`, pass an exact `name` to narrow to one service/event and include its original source JSDoc. */\n cordis_inspect: {\n /** Limit the report to one section. Omit for all sections. */\n what?: \"services\" | \"plugins\" | \"tools\" | \"temporary\" | \"api\" | \"events\";\n /** Exact service key or event name whose original JSDoc to include; valid only with what:\"api\" or what:\"events\". */\n name?: string;\n } & Record;\n /** Mount a temporary Cordis Plugin in the current DSH process. This creates an in-memory runtime Plugin, not an installed or configured Plugin. It remains active across later turns until cordis_unmount, toolset unload, or DSH restart. It does not create files, install a package, change cordis.yml or personal/project config, survive restart, or automatically become permanent. To keep it, ask the Agent to implement a normal local, project, or repository Plugin through the regular development workflow. It may affect other sessions in the same process; the sandbox is not a security boundary, and injected services reach the real runtime. `code` runs now as the body of an async JavaScript function in an isolated sandbox and MUST `return` a plugin. Two forms: FUNCTION form `return (ctx) => { … }` — declares no inject, so it can register tools, listen to events, and provide services, but reaching ANY service (e.g. ctx.bash) throws; use it only when you need no services. OBJECT form `return { name?, inject: ['bash', 'llm', …], apply(ctx) { … } }` — declares dependencies, and cordis activates the plugin only after the services exist; PREFER this form. You may reach ONLY the services you list in inject: an undeclared service throws even if it exists, because an undeclared dependency would not be cleaned up if its provider is unmounted. BEFORE calling a service from your code, read cordis_inspect what:\"api\" — it lists method signatures AND the type shapes of their arguments/returns (do not guess a field's type; e.g. a bash run's stdout is an object, not a string). Inside `apply`, use the standard cordis API: `ctx.on(event, listener)` to observe events (see cordis_inspect what:\"events\"), or call `harness.registerTool(ctx, harness.defineTool({ name, description, parameters: { text: { type: 'string', required: true } }, output: { schema: { type: 'string' }, render(_args, value) { return [{ type: 'text', text: value }] } }, async execute(args) { return args.text } }))` to give yourself a new tool — it becomes callable on your NEXT step. Tool parameters: each key IS a property — { type: 'string'|'number'|'integer'|'boolean'|'null'|'object'|'array'|'json', required?: true, description?, enum?, const?, items?, properties? }; every direct DSL object declares additionalProperties: true|false, and oneOf: [schema, schema, ...] replaces type for an exact-one union. A raw JSON-Schema { type: 'object', properties, required?: […] } wrapper is also accepted with open-by-default objects. A tool's `execute` MUST return the lossless JSON value declared by `output.schema`; `output.render(args, value)` separately returns Native/model content blocks. Temporary Plugins can COMPOSE: one Plugin may `ctx.provide('name', value)` a service and another may declare `inject: ['name']` to consume it — the consumer stays pending until the provider exists and returns to pending when the provider is unmounted. Everything registered inside `apply` is cleaned up automatically by cordis_unmount. Sandbox globals: `console` (tagged `[cordis:]`, writes through to the harness terminal), `harness.defineTool`, `harness.registerTool`, `btoa`, `atob`, `TextEncoder`, `TextDecoder`. Node APIs are DISABLED — do filesystem/network/timer work through the cordis services, never Node built-ins: `require`, `setTimeout`/`setInterval`, and `fetch` throw redirect errors; `process` and `Buffer` are undefined. Instead use inject: ['fs'] + ctx.fs for files, inject: ['web'] + ctx.web for HTTP, inject: ['bash'] + ctx.bash for processes, and inject: ['timer'] + ctx.setTimeout/ctx.setInterval for timing (fiber effects, auto-cleaned when unmounted) — cordis_inspect what:\"api\" shows what THIS runtime provides. Write PLAIN JavaScript, not TypeScript (no `as`, no type annotations). Cautions: (1) waterfall events (e.g. tools/pre-execute) hand the listener a trailing `next` callback which MUST be called — returning without `next()` SHORT-CIRCUITS the call; prefer plain notification events unless you intend to intercept. (2) Never await something that only resolves after the current turn (your code runs INSIDE a tool call of that turn — it would deadlock). (3) Your `ctx` is a restricted façade: you can register tools, observe events, provide/consume services, and use timers, but framework internals (ctx.root, ctx.fiber, ctx.extend, ctx.plugin, …) are withheld. It is not a security boundary though — the services you inject (e.g. ctx.bash) reach the real runtime. */\n cordis_mount: {\n /** JavaScript body returning a temporary Plugin; evaluated now and saved nowhere. */\n code: string;\n } & Record;\n /** Unmount a current-process temporary Plugin created by cordis_mount. Waits for its tools, listeners, services, timers, and other owned effects to clean up completely. Only dyn-N temporary ids are accepted; this cannot remove Loader, configured, or installed Plugins. */\n cordis_unmount: {\n /** The temporary Plugin id returned by cordis_mount (for example \"dyn-1\"); valid only in this process and invalid after unmount or restart. */\n id: string;\n } & Record;\n /** Edit an existing UTF-8 text file by replacing literal text. */\n edit: {\n /** Path to edit, resolved by the filesystem backend. */\n file_path: string;\n /** Literal text to replace. Must match exactly. */\n old_string: string;\n /** Literal replacement text. Use an empty string to delete the match. */\n new_string: string;\n /** Replace all matches. Defaults to false; when false, old_string must appear exactly once. */\n replace_all?: boolean;\n } & Record;\n /** Request cancellation of a background agent's current turn by its agent id. The target may be your direct child or a deeper agent created under you. Only the current turn stops: messages already queued for the agent stay parked until a later send_message, agents it started keep running, and the agent itself stays available for follow-ups. This call returns as soon as the stop request is accepted, so the target may keep running briefly; interrupting an agent that already finished is an accepted no-op. */\n interrupt_agent: {\n /** The agent id of the running agent to interrupt. */\n agent_id: string;\n } & Record;\n /** Run a foreground fresh-agent Ralph loop toward one immutable objective. Use only when the direct human explicitly asks for Ralph or fresh-agent iteration. Each round opens a new child with no parent conversation or prior child session; the shared workspace is long-term memory, and only a bounded structured report crosses rounds. The call returns when a worker reports completion or a concrete blocker, or at the round limit. Ordinary long-running same-session work belongs to goal tools. */\n ralph: {\n /** The immutable completion objective for every fresh Ralph round. */\n objective: string;\n /** Optional positive safe-integer round cap, bounded by the deployment ceiling. */\n maxRounds?: number;\n } & Record;\n /** Read a UTF-8 text file and return line-numbered content. */\n read: {\n /** Path to read, resolved by the filesystem backend. */\n file_path: string;\n /** 1-based first line to return. Defaults to 1. */\n offset?: number;\n /** Maximum number of lines to return. Defaults to 2000. */\n limit?: number;\n } & Record;\n /** Send a message to a background subagent by its subagent id, continuing the same conversation. It becomes the subagent's next turn: if it is still working, the message waits until its current turn finishes, so it cannot redirect work already underway. This call returns no answer from the subagent — only confirmation that the message was delivered — so use it to give it more work. A failure means the message was NOT delivered. */\n send_message: {\n /** The subagent id returned when the background subagent was started. */\n subagent_id: string;\n /** The message to deliver to the subagent. */\n message: string;\n } & Record;\n /** Load the full instructions for an available skill. Call this with the exact skill name from the session skill catalog before acting on a task that names or clearly matches that skill. */\n skill: {\n /** The exact skill name from the available skills list. */\n name: string;\n } & Record;\n /** Delegate a self-contained task to a subagent (a separate agent that works in its own context) and return its final result. Use this to offload focused, independent work — research, a scoped implementation, an analysis — so it does not consume this conversation's context. The subagent runs to completion and you receive only its final answer, not its intermediate steps. Give it a complete, standalone prompt: it does not see this conversation. Set `run_in_background: true` to start a background subagent that keeps its conversation: you receive only its subagent id, never its result, and it works on its own. Use this for work whose result you do not need returned by this call; `send_message` sends it more work. */\n subagent: {\n /** A short (3-5 word) description of the delegated task, for display. */\n description: string;\n /** The complete, self-contained task for the subagent. It does not share this conversation's context, so include everything it needs. */\n prompt: string;\n /** Run as a background subagent that keeps its conversation and return only its subagent id. This call never returns its result; send it more work with send_message. */\n run_in_background?: boolean;\n } & Record;\n /** Delegate a task to a subagent that inherits this conversation: a child agent seeded with all completed turns so far (it does not see the current in-flight turn), returning only its final result. Use this when the subtask builds on this conversation's context — a follow-up analysis, a review, a continuation — without consuming this conversation's context for the work itself. You receive only its final answer, not its intermediate steps. Set `run_in_background: true` to start a background subagent that keeps its conversation: you receive only its subagent id, never its result, and it works on its own. Use this for work whose result you do not need returned by this call; `send_message` sends it more work. */\n subagent_fork: {\n /** A short (3-5 word) description of the delegated task, for display. */\n description: string;\n /** The task for the subagent. It already sees this conversation's completed turns, so build on them freely and state only what is new. */\n prompt: string;\n /** Run as a background subagent that keeps its conversation and return only its subagent id. This call never returns its result; send it more work with send_message. */\n run_in_background?: boolean;\n } & Record;\n /** Request cancellation of a running background task by task id. Returns immediately; the task settles as killed once its work actually stops. */\n task_kill: {\n /** Task id returned by the tool that started the background work. */\n task_id: string;\n /** Optional short reason, recorded in the log and forwarded to the task. */\n reason?: string;\n } & Record;\n /** List your background tasks (running and finished) with their ids, kinds, and statuses. */\n task_list: Record;\n /** Read a background task. Stream tasks return only output since the previous read; final-output tasks return their result after settlement. Every response ends with `[status: ...]`. Reads are non-blocking unless `wait: true`, which waits up to the configured cap. */\n task_output: {\n /** Task id returned by the tool that started the background work. */\n task_id: string;\n /** Block until the task reaches a terminal status or the timeout expires. A timed-out wait returns [status: running] and leaves the task alive. */\n wait?: boolean;\n /** Max wait in milliseconds (only meaningful with wait: true). Defaults to the configured wait timeout; capped by the configured maximum. */\n timeout_ms?: number;\n } & Record;\n /** Record and update a structured task list for the current work. Send the ENTIRE list every call — it REPLACES the previous list (there are no partial updates, no per-item edits). Use it to plan multi-step work and show progress: add one todo per concrete step before you start. Mark every todo being actively worked on `in_progress` — several at once when work genuinely runs in parallel (e.g. concurrent subagents or background commands), one for sequential work; while work remains, at least one task should be `in_progress`. Mark a todo `completed` the moment it is done (do not batch completions), and allow no `in_progress` item only once all work is complete. Skip the list for trivial single-step tasks. Statuses: `pending` (not started), `in_progress` (being worked on now), `completed` (finished). */\n todo_write: {\n /** The COMPLETE task list, replacing any previous list. */\n todos: ({\n /** What the task is — a short imperative line. */\n content: string;\n /** pending (not started) | in_progress (now) | completed (done). */\n status: \"pending\" | \"in_progress\" | \"completed\";\n })[];\n } & Record;\n /** Run a JavaScript workflow script that orchestrates subagents at scale. Use this for work that fans out across many independent pieces — an audit over many files, a migration, multi-angle research, adversarial verification of findings — where you write the orchestration as a script instead of delegating turn by turn. The workflow's identity rides the `meta` parameter as JSON: required `name` (short kebab-case) and `description` strings, optional `whenToUse` string and `phases` array (`{title, detail?, provider?, model?}`). The `script` parameter is the plain JavaScript body ONLY (NOT TypeScript, and NO `export const meta` statement — meta is a parameter, not code), running with top-level await; end with `return ` — the value must be JSON-serializable and is this tool's result. Script-body hooks: - `agent(prompt, opts?): Promise` — run one subagent to completion. Without `opts.schema` it resolves to the child's final text; with `opts.schema` (an object-rooted JSON Schema using ONLY type/properties/required/additionalProperties/items/enum/const/oneOf — no pattern/format/numeric bounds) it resolves to the validated object. Resolves `null` when the child fails (filter with `.filter(Boolean)`). Other opts: `label` (display), `phase` (progress group), and independent `provider`/`model` LLM target overrides (either may be provided alone). Anything else (`effort`/`isolation`/`agentType`) is rejected loudly. - `pipeline(items, ...stages): Promise` — run each item through the stages independently with NO barrier between stages (prefer this for multi-stage work). Each stage receives `(prev, item, index)`. An ordinary stage throw drops that ITEM to `null` and skips its remaining stages. - `parallel(thunks): Promise` — run zero-argument functions concurrently and await ALL of them (a barrier; use only when a stage genuinely needs every prior result together). A throwing thunk resolves to `null`. - `phase(title)` — start a progress phase; `log(message)` — narrate progress; `args` — the tool call's `args` input, verbatim. Misused hooks (bad arguments, unknown options, unsupported schemas, tripped caps) throw errors that ALWAYS kill the script — they never dissolve into a per-item `null`. Constraints: concurrency and total-agent caps apply; no filesystem, network, timers, or Node.js APIs are provided — the agents do the work, the script only coordinates them. The run executes in the foreground: this call returns when the whole script finishes. */\n workflow: {\n /** The plain-JS workflow script body (top-level await allowed; NO `export const meta` statement; end with `return `). */\n script: string;\n /** The workflow identity block (plain JSON — never code). */\n meta: {\n /** Short kebab-case workflow name. */\n name: string;\n /** One-line description of what the workflow does. */\n description: string;\n /** Optional guidance on when this workflow applies. */\n whenToUse?: string;\n /** Optional phase declarations matched by phase() calls. */\n phases?: ({\n /** The phase title phase() calls match by exact string. */\n title: string;\n /** Optional one-line description of the phase. */\n detail?: string;\n /** Optional provider override this phase is expected to use. */\n provider?: string;\n /** Optional model override this phase is expected to use. */\n model?: string;\n } & Record)[];\n } & Record;\n /** Optional JSON input exposed to the script as the `args` global (wrap a bare list as a field, e.g. {\"files\": [...]}). */\n args?: Record;\n } & Record;\n /** Create or fully replace a UTF-8 text file. */\n write: {\n /** Path to write, resolved by the filesystem backend. */\n file_path: string;\n /** Full UTF-8 text content to write. */\n content: string;\n } & Record;\n}\n\ninterface ToolOutputMap {\n bash: {\n kind: \"background\";\n taskId: string;\n } | {\n kind: \"foreground\";\n exitCode: number | null;\n signal: string | null;\n timedOut: boolean;\n aborted: boolean;\n timeoutMs: number;\n stdout: {\n text: string;\n truncated: boolean;\n spillPath?: string;\n };\n stderr: {\n text: string;\n truncated: boolean;\n spillPath?: string;\n };\n sandbox?: {\n mode: string;\n denied: boolean;\n enforcement?: string;\n runnerFailed?: boolean;\n };\n };\n cordis_inspect: string;\n cordis_mount: {\n id: string;\n pluginName: string;\n state: \"pending\" | \"loading\" | \"active\" | \"failed\" | \"disposed\" | \"unloading\";\n provides: string[];\n waitingFor: string[];\n };\n cordis_unmount: {\n id: string;\n pluginName: string;\n };\n edit: {\n path: string;\n before: string;\n after: string;\n };\n interrupt_agent: {\n accepted: boolean;\n };\n ralph: {\n runId: string;\n agentsStarted: number;\n result: JsonValue;\n };\n read: {\n path: string;\n offset: number;\n lines: {\n number: number;\n text: string;\n }[];\n totalLines: number;\n };\n send_message: {\n messageId: string;\n };\n skill: {\n name: string;\n provider: string;\n resourceBase?: {\n kind: \"directory\";\n path: string;\n } | {\n kind: \"url\";\n url: string;\n } | {\n kind: \"opaque\";\n description: string;\n };\n content: string;\n };\n subagent: {\n kind: \"background\";\n taskId: string;\n } | {\n kind: \"continuable\";\n subagentId: string;\n } | {\n kind: \"foreground\";\n runId: string;\n output: JsonValue[];\n };\n subagent_fork: {\n kind: \"background\";\n taskId: string;\n } | {\n kind: \"continuable\";\n subagentId: string;\n } | {\n kind: \"foreground\";\n runId: string;\n output: JsonValue[];\n };\n task_kill: {\n outcome: \"cancellation-requested\" | \"already-finished\";\n task: {\n id: string;\n kind: string;\n label: string;\n status: \"running\" | \"stopping\" | \"completed\" | \"killed\" | \"failed\";\n detail?: string;\n startedAt: number;\n finishedAt?: number;\n };\n };\n task_list: ({\n id: string;\n kind: string;\n label: string;\n status: \"running\" | \"stopping\" | \"completed\" | \"killed\" | \"failed\";\n detail?: string;\n startedAt: number;\n finishedAt?: number;\n })[];\n task_output: {\n text: string;\n task: {\n id: string;\n kind: string;\n label: string;\n status: \"running\" | \"stopping\" | \"completed\" | \"killed\" | \"failed\";\n detail?: string;\n startedAt: number;\n finishedAt?: number;\n };\n };\n todo_write: {\n todos: ({\n content: string;\n status: \"pending\" | \"in_progress\" | \"completed\";\n })[];\n counts: {\n pending: number;\n inProgress: number;\n completed: number;\n };\n };\n workflow: {\n runId: string;\n agentsStarted: number;\n result: JsonValue;\n };\n write: {\n path: string;\n operation: \"create\" | \"update\";\n before: string | null;\n after: string;\n };\n}\n\ntype ToolName = keyof ToolOutputMap\n\ndeclare class ToolCallError extends Error {\n readonly name: \"ToolCallError\";\n readonly toolName: ToolName;\n}\n\ndeclare const tools: {\n [K in ToolName]: (args: ToolArgsMap[K]) => Promise;\n}\n```","tools":[{"name":"bash","description":"Execute a bash command (`bash -c`) and return its stdout/stderr. Each call runs in a fresh shell: no state (cwd, variables, functions) persists between calls — pass `workdir` instead of using `cd`. Non-zero exits are reported as `[exit code: N]`. Current harness environment facts are exposed through managed `$DSH_*` variables; inspect them when needed. Commands may run under a file sandbox; a blocked file operation is reported as `[sandbox: file access denied under mode]` — a policy denial, not a bug in the command; do not retry another way. Long output is truncated to its tail; the full output is saved to a file whose path is reported when available. Set `run_in_background: true` for long-running commands: the call returns a task id immediately; read its output with `task_output` and stop it with `task_kill`.","parameters":{"type":"object","properties":{"command":{"type":"string","description":"The bash command to execute."},"description":{"type":"string","description":"Clear, concise description of what this command does in active voice, 5-10 words (shown in the UI). Examples: \"ls\" → \"List files in current directory\"; \"git status\" → \"Show working tree status\"; \"npm install\" → \"Install package dependencies\"."},"timeoutMs":{"type":"number","description":"Timeout in milliseconds. The executor applies its configured default and cap, and kills the command on expiry."},"workdir":{"type":"string","description":"Working directory for this command. Defaults to the session workspace; a relative path is resolved against it."},"run_in_background":{"type":"boolean","description":"Run in the background and return a task id immediately (collect with task_output, stop with task_kill). No timeout applies."}},"required":["command","description"]}},{"name":"cordis_inspect","description":"Inspect the live Cordis runtime in the current DSH process. Read-only. Sections: `services` (every provided ctx service and the plugin fiber that owns it), `plugins` (all live plugin fibers with their lifecycle states), `tools` (the model-facing tools currently registered, i.e. what you can call), `temporary` (only temporary Plugins created by cordis_mount: id, name, state, provided services, awaited services, and lifetime), `api` (method signatures AND argument/return type shapes for every LIVE service — read this before writing plugin code that calls a service), `events` (every harness event with its dispatch mode and exact signature — pick listener targets here). Temporary Plugins exist only in memory, remain active across later turns, and disappear after cordis_unmount, toolset unload, or DSH restart; they are not restored automatically. The `temporary` section is a subset of `plugins`. Omit `what` to get all six sections. With `what:\"api\"` or `what:\"events\"`, pass an exact `name` to narrow to one service/event and include its original source JSDoc.","parameters":{"type":"object","properties":{"what":{"type":"string","description":"Limit the report to one section. Omit for all sections.","enum":["services","plugins","tools","temporary","api","events"]},"name":{"type":"string","description":"Exact service key or event name whose original JSDoc to include; valid only with what:\"api\" or what:\"events\"."}}}},{"name":"cordis_mount","description":"Mount a temporary Cordis Plugin in the current DSH process. This creates an in-memory runtime Plugin, not an installed or configured Plugin. It remains active across later turns until cordis_unmount, toolset unload, or DSH restart. It does not create files, install a package, change cordis.yml or personal/project config, survive restart, or automatically become permanent. To keep it, ask the Agent to implement a normal local, project, or repository Plugin through the regular development workflow. It may affect other sessions in the same process; the sandbox is not a security boundary, and injected services reach the real runtime. `code` runs now as the body of an async JavaScript function in an isolated sandbox and MUST `return` a plugin. Two forms: FUNCTION form `return (ctx) => { … }` — declares no inject, so it can register tools, listen to events, and provide services, but reaching ANY service (e.g. ctx.bash) throws; use it only when you need no services. OBJECT form `return { name?, inject: ['bash', 'llm', …], apply(ctx) { … } }` — declares dependencies, and cordis activates the plugin only after the services exist; PREFER this form. You may reach ONLY the services you list in inject: an undeclared service throws even if it exists, because an undeclared dependency would not be cleaned up if its provider is unmounted. BEFORE calling a service from your code, read cordis_inspect what:\"api\" — it lists method signatures AND the type shapes of their arguments/returns (do not guess a field's type; e.g. a bash run's stdout is an object, not a string). Inside `apply`, use the standard cordis API: `ctx.on(event, listener)` to observe events (see cordis_inspect what:\"events\"), or call `harness.registerTool(ctx, harness.defineTool({ name, description, parameters: { text: { type: 'string', required: true } }, output: { schema: { type: 'string' }, render(_args, value) { return [{ type: 'text', text: value }] } }, async execute(args) { return args.text } }))` to give yourself a new tool — it becomes callable on your NEXT step. Tool parameters: each key IS a property — { type: 'string'|'number'|'integer'|'boolean'|'null'|'object'|'array'|'json', required?: true, description?, enum?, const?, items?, properties? }; every direct DSL object declares additionalProperties: true|false, and oneOf: [schema, schema, ...] replaces type for an exact-one union. A raw JSON-Schema { type: 'object', properties, required?: […] } wrapper is also accepted with open-by-default objects. A tool's `execute` MUST return the lossless JSON value declared by `output.schema`; `output.render(args, value)` separately returns Native/model content blocks. Temporary Plugins can COMPOSE: one Plugin may `ctx.provide('name', value)` a service and another may declare `inject: ['name']` to consume it — the consumer stays pending until the provider exists and returns to pending when the provider is unmounted. Everything registered inside `apply` is cleaned up automatically by cordis_unmount. Sandbox globals: `console` (tagged `[cordis:]`, writes through to the harness terminal), `harness.defineTool`, `harness.registerTool`, `btoa`, `atob`, `TextEncoder`, `TextDecoder`. Node APIs are DISABLED — do filesystem/network/timer work through the cordis services, never Node built-ins: `require`, `setTimeout`/`setInterval`, and `fetch` throw redirect errors; `process` and `Buffer` are undefined. Instead use inject: ['fs'] + ctx.fs for files, inject: ['web'] + ctx.web for HTTP, inject: ['bash'] + ctx.bash for processes, and inject: ['timer'] + ctx.setTimeout/ctx.setInterval for timing (fiber effects, auto-cleaned when unmounted) — cordis_inspect what:\"api\" shows what THIS runtime provides. Write PLAIN JavaScript, not TypeScript (no `as`, no type annotations). Cautions: (1) waterfall events (e.g. tools/pre-execute) hand the listener a trailing `next` callback which MUST be called — returning without `next()` SHORT-CIRCUITS the call; prefer plain notification events unless you intend to intercept. (2) Never await something that only resolves after the current turn (your code runs INSIDE a tool call of that turn — it would deadlock). (3) Your `ctx` is a restricted façade: you can register tools, observe events, provide/consume services, and use timers, but framework internals (ctx.root, ctx.fiber, ctx.extend, ctx.plugin, …) are withheld. It is not a security boundary though — the services you inject (e.g. ctx.bash) reach the real runtime.","parameters":{"type":"object","properties":{"code":{"type":"string","description":"JavaScript body returning a temporary Plugin; evaluated now and saved nowhere."}},"required":["code"]}},{"name":"cordis_unmount","description":"Unmount a current-process temporary Plugin created by cordis_mount. Waits for its tools, listeners, services, timers, and other owned effects to clean up completely. Only dyn-N temporary ids are accepted; this cannot remove Loader, configured, or installed Plugins.","parameters":{"type":"object","properties":{"id":{"type":"string","description":"The temporary Plugin id returned by cordis_mount (for example \"dyn-1\"); valid only in this process and invalid after unmount or restart."}},"required":["id"]}},{"name":"edit","description":"Edit an existing UTF-8 text file by replacing literal text.","parameters":{"type":"object","properties":{"file_path":{"type":"string","description":"Path to edit, resolved by the filesystem backend."},"old_string":{"type":"string","description":"Literal text to replace. Must match exactly."},"new_string":{"type":"string","description":"Literal replacement text. Use an empty string to delete the match."},"replace_all":{"type":"boolean","description":"Replace all matches. Defaults to false; when false, old_string must appear exactly once."}},"required":["file_path","old_string","new_string"]}},{"name":"interrupt_agent","description":"Request cancellation of a background agent's current turn by its agent id. The target may be your direct child or a deeper agent created under you. Only the current turn stops: messages already queued for the agent stay parked until a later send_message, agents it started keep running, and the agent itself stays available for follow-ups. This call returns as soon as the stop request is accepted, so the target may keep running briefly; interrupting an agent that already finished is an accepted no-op.","parameters":{"type":"object","properties":{"agent_id":{"type":"string","description":"The agent id of the running agent to interrupt."}},"required":["agent_id"]}},{"name":"ralph","description":"Run a foreground fresh-agent Ralph loop toward one immutable objective. Use only when the direct human explicitly asks for Ralph or fresh-agent iteration. Each round opens a new child with no parent conversation or prior child session; the shared workspace is long-term memory, and only a bounded structured report crosses rounds. The call returns when a worker reports completion or a concrete blocker, or at the round limit. Ordinary long-running same-session work belongs to goal tools.","parameters":{"type":"object","properties":{"objective":{"type":"string","description":"The immutable completion objective for every fresh Ralph round."},"maxRounds":{"type":"number","description":"Optional positive safe-integer round cap, bounded by the deployment ceiling."}},"required":["objective"]}},{"name":"read","description":"Read a UTF-8 text file and return line-numbered content.","parameters":{"type":"object","properties":{"file_path":{"type":"string","description":"Path to read, resolved by the filesystem backend."},"offset":{"type":"number","description":"1-based first line to return. Defaults to 1."},"limit":{"type":"number","description":"Maximum number of lines to return. Defaults to 2000."}},"required":["file_path"]}},{"name":"run_code","description":"Execute a TypeScript program against the available tools. Write the BODY of an async function (erasable syntax only; top-level `await` and `return` work) and call tools as `await tools.name(args)` per the declarations in the system prompt. Only what you print or return comes back — curate it.","parameters":{"type":"object","properties":{"code":{"type":"string","description":"The program: the body of an async TypeScript function."},"description":{"type":"string","description":"Clear, concise description of what this program does in active voice, 5-10 words (shown in the UI). Examples: \"Count TODO markers across packages\"; \"Read failing test and its fixture\"; \"Rename config key in every cordis.yml\"."}},"required":["code","description"]}},{"name":"send_message","description":"Send a message to a background subagent by its subagent id, continuing the same conversation. It becomes the subagent's next turn: if it is still working, the message waits until its current turn finishes, so it cannot redirect work already underway. This call returns no answer from the subagent — only confirmation that the message was delivered — so use it to give it more work. A failure means the message was NOT delivered.","parameters":{"type":"object","properties":{"subagent_id":{"type":"string","description":"The subagent id returned when the background subagent was started."},"message":{"type":"string","description":"The message to deliver to the subagent."}},"required":["subagent_id","message"]}},{"name":"skill","description":"Load the full instructions for an available skill. Call this with the exact skill name from the session skill catalog before acting on a task that names or clearly matches that skill.","parameters":{"type":"object","properties":{"name":{"type":"string","description":"The exact skill name from the available skills list."}},"required":["name"]}},{"name":"subagent","description":"Delegate a self-contained task to a subagent (a separate agent that works in its own context) and return its final result. Use this to offload focused, independent work — research, a scoped implementation, an analysis — so it does not consume this conversation's context. The subagent runs to completion and you receive only its final answer, not its intermediate steps. Give it a complete, standalone prompt: it does not see this conversation. Set `run_in_background: true` to start a background subagent that keeps its conversation: you receive only its subagent id, never its result, and it works on its own. Use this for work whose result you do not need returned by this call; `send_message` sends it more work.","parameters":{"type":"object","properties":{"description":{"type":"string","description":"A short (3-5 word) description of the delegated task, for display."},"prompt":{"type":"string","description":"The complete, self-contained task for the subagent. It does not share this conversation's context, so include everything it needs."},"run_in_background":{"type":"boolean","description":"Run as a background subagent that keeps its conversation and return only its subagent id. This call never returns its result; send it more work with send_message."}},"required":["description","prompt"]}},{"name":"subagent_fork","description":"Delegate a task to a subagent that inherits this conversation: a child agent seeded with all completed turns so far (it does not see the current in-flight turn), returning only its final result. Use this when the subtask builds on this conversation's context — a follow-up analysis, a review, a continuation — without consuming this conversation's context for the work itself. You receive only its final answer, not its intermediate steps. Set `run_in_background: true` to start a background subagent that keeps its conversation: you receive only its subagent id, never its result, and it works on its own. Use this for work whose result you do not need returned by this call; `send_message` sends it more work.","parameters":{"type":"object","properties":{"description":{"type":"string","description":"A short (3-5 word) description of the delegated task, for display."},"prompt":{"type":"string","description":"The task for the subagent. It already sees this conversation's completed turns, so build on them freely and state only what is new."},"run_in_background":{"type":"boolean","description":"Run as a background subagent that keeps its conversation and return only its subagent id. This call never returns its result; send it more work with send_message."}},"required":["description","prompt"]}},{"name":"task_kill","description":"Request cancellation of a running background task by task id. Returns immediately; the task settles as killed once its work actually stops.","parameters":{"type":"object","properties":{"task_id":{"type":"string","description":"Task id returned by the tool that started the background work."},"reason":{"type":"string","description":"Optional short reason, recorded in the log and forwarded to the task."}},"required":["task_id"]}},{"name":"task_list","description":"List your background tasks (running and finished) with their ids, kinds, and statuses.","parameters":{"type":"object","properties":{}}},{"name":"task_output","description":"Read a background task. Stream tasks return only output since the previous read; final-output tasks return their result after settlement. Every response ends with `[status: ...]`. Reads are non-blocking unless `wait: true`, which waits up to the configured cap.","parameters":{"type":"object","properties":{"task_id":{"type":"string","description":"Task id returned by the tool that started the background work."},"wait":{"type":"boolean","description":"Block until the task reaches a terminal status or the timeout expires. A timed-out wait returns [status: running] and leaves the task alive."},"timeout_ms":{"type":"number","description":"Max wait in milliseconds (only meaningful with wait: true). Defaults to the configured wait timeout; capped by the configured maximum."}},"required":["task_id"]}},{"name":"todo_write","description":"Record and update a structured task list for the current work. Send the ENTIRE list every call — it REPLACES the previous list (there are no partial updates, no per-item edits). Use it to plan multi-step work and show progress: add one todo per concrete step before you start. Mark every todo being actively worked on `in_progress` — several at once when work genuinely runs in parallel (e.g. concurrent subagents or background commands), one for sequential work; while work remains, at least one task should be `in_progress`. Mark a todo `completed` the moment it is done (do not batch completions), and allow no `in_progress` item only once all work is complete. Skip the list for trivial single-step tasks. Statuses: `pending` (not started), `in_progress` (being worked on now), `completed` (finished).","parameters":{"type":"object","properties":{"todos":{"type":"array","description":"The COMPLETE task list, replacing any previous list.","items":{"type":"object","additionalProperties":false,"properties":{"content":{"type":"string","description":"What the task is — a short imperative line."},"status":{"type":"string","description":"pending (not started) | in_progress (now) | completed (done).","enum":["pending","in_progress","completed"]}},"required":["content","status"]}}},"required":["todos"]}},{"name":"workflow","description":"Run a JavaScript workflow script that orchestrates subagents at scale. Use this for work that fans out across many independent pieces — an audit over many files, a migration, multi-angle research, adversarial verification of findings — where you write the orchestration as a script instead of delegating turn by turn.\n\nThe workflow's identity rides the `meta` parameter as JSON: required `name` (short kebab-case) and `description` strings, optional `whenToUse` string and `phases` array (`{title, detail?, provider?, model?}`). The `script` parameter is the plain JavaScript body ONLY (NOT TypeScript, and NO `export const meta` statement — meta is a parameter, not code), running with top-level await; end with `return ` — the value must be JSON-serializable and is this tool's result.\n\nScript-body hooks:\n- `agent(prompt, opts?): Promise` — run one subagent to completion. Without `opts.schema` it resolves to the child's final text; with `opts.schema` (an object-rooted JSON Schema using ONLY type/properties/required/additionalProperties/items/enum/const/oneOf — no pattern/format/numeric bounds) it resolves to the validated object. Resolves `null` when the child fails (filter with `.filter(Boolean)`). Other opts: `label` (display), `phase` (progress group), and independent `provider`/`model` LLM target overrides (either may be provided alone). Anything else (`effort`/`isolation`/`agentType`) is rejected loudly.\n- `pipeline(items, ...stages): Promise` — run each item through the stages independently with NO barrier between stages (prefer this for multi-stage work). Each stage receives `(prev, item, index)`. An ordinary stage throw drops that ITEM to `null` and skips its remaining stages.\n- `parallel(thunks): Promise` — run zero-argument functions concurrently and await ALL of them (a barrier; use only when a stage genuinely needs every prior result together). A throwing thunk resolves to `null`.\n- `phase(title)` — start a progress phase; `log(message)` — narrate progress; `args` — the tool call's `args` input, verbatim.\n\nMisused hooks (bad arguments, unknown options, unsupported schemas, tripped caps) throw errors that ALWAYS kill the script — they never dissolve into a per-item `null`.\n\nConstraints: concurrency and total-agent caps apply; no filesystem, network, timers, or Node.js APIs are provided — the agents do the work, the script only coordinates them. The run executes in the foreground: this call returns when the whole script finishes.","parameters":{"type":"object","properties":{"script":{"type":"string","description":"The plain-JS workflow script body (top-level await allowed; NO `export const meta` statement; end with `return `)."},"meta":{"type":"object","description":"The workflow identity block (plain JSON — never code).","additionalProperties":true,"properties":{"name":{"type":"string","description":"Short kebab-case workflow name."},"description":{"type":"string","description":"One-line description of what the workflow does."},"whenToUse":{"type":"string","description":"Optional guidance on when this workflow applies."},"phases":{"type":"array","description":"Optional phase declarations matched by phase() calls.","items":{"type":"object","additionalProperties":true,"properties":{"title":{"type":"string","description":"The phase title phase() calls match by exact string."},"detail":{"type":"string","description":"Optional one-line description of the phase."},"provider":{"type":"string","description":"Optional provider override this phase is expected to use."},"model":{"type":"string","description":"Optional model override this phase is expected to use."}},"required":["title"]}}},"required":["name","description"]},"args":{"type":"object","description":"Optional JSON input exposed to the script as the `args` global (wrap a bare list as a field, e.g. {\"files\": [...]}).","additionalProperties":true}},"required":["script","meta"]}},{"name":"write","description":"Create or fully replace a UTF-8 text file.","parameters":{"type":"object","properties":{"file_path":{"type":"string","description":"Path to write, resolved by the filesystem backend."},"content":{"type":"string","description":"Full UTF-8 text content to write."}},"required":["file_path","content"]}}]},"reason":"initial"}} +{"type":"request/context","seq":9,"time":1785730501646,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} +{"type":"assistant/chunk","seq":10,"time":1783957884701,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"text"}}} +{"type":"assistant/chunk","seq":11,"time":1783957884701,"data":{"turn":1,"step":1,"chunk":{"type":"text-delta","index":0,"text":"WORKFLOW_CHILD_OK"}}} +{"type":"assistant/chunk","seq":12,"time":1783957884701,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"WORKFLOW_CHILD_OK"}}}} +{"type":"assistant/chunk","seq":13,"time":1785498584067,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}}} +{"type":"assistant/chunk","seq":14,"time":1785730501646,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"stop"}}}} +{"type":"assistant/message","seq":15,"time":1785730501646,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"text","text":"WORKFLOW_CHILD_OK"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"bb9c39a9-3239-4ee1-939a-bab0046e3028"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[10,11,12,13,14],"surfaceOp":"append"} +{"type":"step/end","seq":16,"time":1785730501646,"data":{"turn":1,"step":1}} +{"type":"turn/end","seq":17,"time":1785730501646,"data":{"turn":1,"reason":{"kind":"completed"}}} diff --git a/examples/headless-agent/tests/snapshots/advanced-toolchain/session.jsonl b/examples/headless-agent/tests/snapshots/advanced-toolchain/session.jsonl index 646110b6d9..8f0a211969 100644 --- a/examples/headless-agent/tests/snapshots/advanced-toolchain/session.jsonl +++ b/examples/headless-agent/tests/snapshots/advanced-toolchain/session.jsonl @@ -1,20 +1,20 @@ {"type":"session","version":0,"id":"11111111-1111-4111-8111-111111111111","createdAt":1783950000000,"cwd":"{{cwd}}","delegationDepth":0} -{"type":"agent/inbox/spliced","seq":0,"time":1785498583746,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Run this advanced flow exactly once: try a no-op temporary Cordis Plugin named snapshot-marker; use run_code to inspect the live temporary Plugins through tools.cordis_inspect; delegate once to a direct spawn child; run one workflow that delegates to another spawn child; stop dyn-1; then reply with exactly ADVANCED_HEADLESS_OK."}],"source":{"kind":"user"},"role":"user","id":"d2f4f71c-78bc-4a22-908d-c08fbb3ab9ef"}]}} +{"type":"agent/inbox/spliced","seq":0,"time":1785498583746,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Run this advanced flow exactly once: try a no-op temporary Cordis Plugin named snapshot-marker; use run_code to inspect the live temporary Plugins through tools.cordis_inspect; delegate once to a direct spawn child; run one workflow that delegates to another spawn child; stop dyn-1; then reply with exactly ADVANCED_HEADLESS_OK."}],"source":{"kind":"user"},"role":"user","id":"2b5f9025-324a-4c76-b883-4af3b5c3060a"}]}} {"type":"turn/start","seq":1,"time":1785821454304,"data":{"turn":1}} {"type":"agent/inbox/spliced","seq":2,"time":1785821454304,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} {"type":"step/start","seq":3,"time":1783957884486,"data":{"turn":1,"step":1}} -{"type":"user/message","seq":4,"time":1785498583779,"data":{"content":[{"type":"text","text":"Run this advanced flow exactly once: try a no-op temporary Cordis Plugin named snapshot-marker; use run_code to inspect the live temporary Plugins through tools.cordis_inspect; delegate once to a direct spawn child; run one workflow that delegates to another spawn child; stop dyn-1; then reply with exactly ADVANCED_HEADLESS_OK."}],"source":{"kind":"user"},"role":"user","id":"d2f4f71c-78bc-4a22-908d-c08fbb3ab9ef"},"surfaceOp":"append"} +{"type":"user/message","seq":4,"time":1785498583779,"data":{"content":[{"type":"text","text":"Run this advanced flow exactly once: try a no-op temporary Cordis Plugin named snapshot-marker; use run_code to inspect the live temporary Plugins through tools.cordis_inspect; delegate once to a direct spawn child; run one workflow that delegates to another spawn child; stop dyn-1; then reply with exactly ADVANCED_HEADLESS_OK."}],"source":{"kind":"user"},"role":"user","id":"2b5f9025-324a-4c76-b883-4af3b5c3060a"},"surfaceOp":"append"} {"type":"session/title","seq":5,"time":1785498583779,"data":{"title":"Run this advanced flow exactly","messageSeqs":[4],"source":{"kind":"fallback"}}} -{"type":"request/header","seq":6,"time":1785498583782,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"You are an AI agent powered by the DeepSeek Harness SDK.\n\nYou are headless-agent, a coding assistant powered by the deepseek-v4-flash model. Your working directory is {{cwd}}.\n\nVerify your work by running the code or tests. Keep answers brief and factual.\n\n\nUse the read tool — not shell commands like cat — to inspect text files. Results include line numbers. Use offset and limit to continue reading large files.\n\nUse the write tool to create files or completely replace file contents. Existing files are overwritten, so read an existing file first (the default fs-policy requires it) and prefer edit for targeted changes.\n\nUse the edit tool for targeted changes to existing UTF-8 text files. It replaces literal old_string with new_string; by default old_string must appear exactly once. If old_string appears multiple times, provide a more specific old_string or set replace_all to true. Read the file first (the default fs-policy requires it), unless you just created or edited it in this session.\n\nCheck the [exit code: N] marker on every bash result; investigate failures before moving on.\n\nTrack every background task id you start. You are notified in-session when a task finishes — do not busy-poll or sleep on one; keep working on independent steps and do not duplicate a running task's work. Before giving a final answer, collect every still-relevant task with task_output (set wait: true only when you are genuinely blocked on it), and task_kill tasks that stopped mattering.\n\nUse the workflow tool ONLY when the user explicitly asks for a workflow or for large multi-agent orchestration: you write a JavaScript script (the tool description documents the exact format) that fans work out across many subagents with phases and structured results. For one or two delegations, prefer plain subagent calls.\n\nUse the ralph tool ONLY when the direct human explicitly asks for a Ralph loop or fresh-agent iterative execution. Each Ralph round starts a fresh child with no conversation seed and uses the shared workspace as durable memory. Completion and blockers are worker reports, not independent evaluation. Use same-session goal tools for ordinary long-running objectives, and plain subagents or workflows for bounded delegation and fan-out.\n\n## Writing code for run_code\n\nPass `run_code` the body of an async TypeScript function (erasable syntax only — no `enum` or namespaces; type annotations are advisory, the code runs type-stripped). Inside the program:\n\n- Call tools as `await tools.name(args)` — quoted access for exotic names: `tools[\"my-tool\"](args)`. Every call resolves to the tool's typed canonical JSON value. Tool arguments must be lossless JSON.\n- A FAILED tool call rejects with `ToolCallError`, whose `toolName` identifies the failed tool and whose `message` is human-readable — `try/catch` it to handle and continue.\n- Independent read-only calls MAY overlap under `Promise.all` (safe calls run concurrently; mutating calls run alone, in submission order). Sequence dependent work with `await`.\n- Emit results with `return` and/or `console.log(...)`. ONLY what you print or return comes back to you — intermediate tool results never enter the conversation, so extract just what you need.\n\nThe available tools:\n\n```ts\ntype JsonValue = null | boolean | number | string | JsonValue[] | { [key: string]: JsonValue }\n\ninterface ToolArgsMap {\n /** Execute a bash command (`bash -c`) and return its stdout/stderr. Each call runs in a fresh shell: no state (cwd, variables, functions) persists between calls — pass `workdir` instead of using `cd`. Non-zero exits are reported as `[exit code: N]`. Current harness environment facts are exposed through managed `$DSH_*` variables; inspect them when needed. Commands may run under a file sandbox; a blocked file operation is reported as `[sandbox: file access denied under mode]` — a policy denial, not a bug in the command; do not retry another way. Long output is truncated to its tail; the full output is saved to a file whose path is reported when available. Set `run_in_background: true` for long-running commands: the call returns a task id immediately; read its output with `task_output` and stop it with `task_kill`. */\n bash: {\n /** The bash command to execute. */\n command: string;\n /** Clear, concise description of what this command does in active voice, 5-10 words (shown in the UI). Examples: \"ls\" → \"List files in current directory\"; \"git status\" → \"Show working tree status\"; \"npm install\" → \"Install package dependencies\". */\n description: string;\n /** Timeout in milliseconds. The executor applies its configured default and cap, and kills the command on expiry. */\n timeoutMs?: number;\n /** Working directory for this command. Defaults to the session workspace; a relative path is resolved against it. */\n workdir?: string;\n /** Run in the background and return a task id immediately (collect with task_output, stop with task_kill). No timeout applies. */\n run_in_background?: boolean;\n } & Record;\n /** Inspect the live Cordis runtime in the current DSH process. Read-only. Sections: `services` (every provided ctx service and the plugin fiber that owns it), `plugins` (all live plugin fibers with their lifecycle states), `tools` (the model-facing tools currently registered, i.e. what you can call), `temporary` (only temporary Plugins created by cordis_mount: id, name, state, provided services, awaited services, and lifetime), `api` (method signatures AND argument/return type shapes for every LIVE service — read this before writing plugin code that calls a service), `events` (every harness event with its dispatch mode and exact signature — pick listener targets here). Temporary Plugins exist only in memory, remain active across later turns, and disappear after cordis_unmount, toolset unload, or DSH restart; they are not restored automatically. The `temporary` section is a subset of `plugins`. Omit `what` to get all six sections. With `what:\"api\"` or `what:\"events\"`, pass an exact `name` to narrow to one service/event and include its original source JSDoc. */\n cordis_inspect: {\n /** Limit the report to one section. Omit for all sections. */\n what?: \"services\" | \"plugins\" | \"tools\" | \"temporary\" | \"api\" | \"events\";\n /** Exact service key or event name whose original JSDoc to include; valid only with what:\"api\" or what:\"events\". */\n name?: string;\n } & Record;\n /** Mount a temporary Cordis Plugin in the current DSH process. This creates an in-memory runtime Plugin, not an installed or configured Plugin. It remains active across later turns until cordis_unmount, toolset unload, or DSH restart. It does not create files, install a package, change cordis.yml or personal/project config, survive restart, or automatically become permanent. To keep it, ask the Agent to implement a normal local, project, or repository Plugin through the regular development workflow. It may affect other sessions in the same process; the sandbox is not a security boundary, and injected services reach the real runtime. `code` runs now as the body of an async JavaScript function in an isolated sandbox and MUST `return` a plugin. Two forms: FUNCTION form `return (ctx) => { … }` — declares no inject, so it can register tools, listen to events, and provide services, but reaching ANY service (e.g. ctx.bash) throws; use it only when you need no services. OBJECT form `return { name?, inject: ['bash', 'llm', …], apply(ctx) { … } }` — declares dependencies, and cordis activates the plugin only after the services exist; PREFER this form. You may reach ONLY the services you list in inject: an undeclared service throws even if it exists, because an undeclared dependency would not be cleaned up if its provider is unmounted. BEFORE calling a service from your code, read cordis_inspect what:\"api\" — it lists method signatures AND the type shapes of their arguments/returns (do not guess a field's type; e.g. a bash run's stdout is an object, not a string). Inside `apply`, use the standard cordis API: `ctx.on(event, listener)` to observe events (see cordis_inspect what:\"events\"), or call `harness.registerTool(ctx, harness.defineTool({ name, description, parameters: { text: { type: 'string', required: true } }, output: { schema: { type: 'string' }, render(_args, value) { return [{ type: 'text', text: value }] } }, async execute(args) { return args.text } }))` to give yourself a new tool — it becomes callable on your NEXT step. Tool parameters: each key IS a property — { type: 'string'|'number'|'integer'|'boolean'|'null'|'object'|'array'|'json', required?: true, description?, enum?, const?, items?, properties? }; every direct DSL object declares additionalProperties: true|false, and oneOf: [schema, schema, ...] replaces type for an exact-one union. A raw JSON-Schema { type: 'object', properties, required?: […] } wrapper is also accepted with open-by-default objects. A tool's `execute` MUST return the lossless JSON value declared by `output.schema`; `output.render(args, value)` separately returns Native/model content blocks. Temporary Plugins can COMPOSE: one Plugin may `ctx.provide('name', value)` a service and another may declare `inject: ['name']` to consume it — the consumer stays pending until the provider exists and returns to pending when the provider is unmounted. Everything registered inside `apply` is cleaned up automatically by cordis_unmount. Sandbox globals: `console` (tagged `[cordis:]`, writes through to the harness terminal), `harness.defineTool`, `harness.registerTool`, `btoa`, `atob`, `TextEncoder`, `TextDecoder`. Node APIs are DISABLED — do filesystem/network/timer work through the cordis services, never Node built-ins: `require`, `setTimeout`/`setInterval`, and `fetch` throw redirect errors; `process` and `Buffer` are undefined. Instead use inject: ['fs'] + ctx.fs for files, inject: ['web'] + ctx.web for HTTP, inject: ['bash'] + ctx.bash for processes, and inject: ['timer'] + ctx.setTimeout/ctx.setInterval for timing (fiber effects, auto-cleaned when unmounted) — cordis_inspect what:\"api\" shows what THIS runtime provides. Write PLAIN JavaScript, not TypeScript (no `as`, no type annotations). Cautions: (1) waterfall events (e.g. tools/pre-execute) hand the listener a trailing `next` callback which MUST be called — returning without `next()` SHORT-CIRCUITS the call; prefer plain notification events unless you intend to intercept. (2) Never await something that only resolves after the current turn (your code runs INSIDE a tool call of that turn — it would deadlock). (3) Your `ctx` is a restricted façade: you can register tools, observe events, provide/consume services, and use timers, but framework internals (ctx.root, ctx.fiber, ctx.extend, ctx.plugin, …) are withheld. It is not a security boundary though — the services you inject (e.g. ctx.bash) reach the real runtime. */\n cordis_mount: {\n /** JavaScript body returning a temporary Plugin; evaluated now and saved nowhere. */\n code: string;\n } & Record;\n /** Unmount a current-process temporary Plugin created by cordis_mount. Waits for its tools, listeners, services, timers, and other owned effects to clean up completely. Only dyn-N temporary ids are accepted; this cannot remove Loader, configured, or installed Plugins. */\n cordis_unmount: {\n /** The temporary Plugin id returned by cordis_mount (for example \"dyn-1\"); valid only in this process and invalid after unmount or restart. */\n id: string;\n } & Record;\n /** Edit an existing UTF-8 text file by replacing literal text. */\n edit: {\n /** Path to edit, resolved by the filesystem backend. */\n file_path: string;\n /** Literal text to replace. Must match exactly. */\n old_string: string;\n /** Literal replacement text. Use an empty string to delete the match. */\n new_string: string;\n /** Replace all matches. Defaults to false; when false, old_string must appear exactly once. */\n replace_all?: boolean;\n } & Record;\n /** Run a foreground fresh-agent Ralph loop toward one immutable objective. Use only when the direct human explicitly asks for Ralph or fresh-agent iteration. Each round opens a new child with no parent conversation or prior child session; the shared workspace is long-term memory, and only a bounded structured report crosses rounds. The call returns when a worker reports completion or a concrete blocker, or at the round limit. Ordinary long-running same-session work belongs to goal tools. */\n ralph: {\n /** The immutable completion objective for every fresh Ralph round. */\n objective: string;\n /** Optional positive safe-integer round cap, bounded by the deployment ceiling. */\n maxRounds?: number;\n } & Record;\n /** Read a UTF-8 text file and return line-numbered content. */\n read: {\n /** Path to read, resolved by the filesystem backend. */\n file_path: string;\n /** 1-based first line to return. Defaults to 1. */\n offset?: number;\n /** Maximum number of lines to return. Defaults to 2000. */\n limit?: number;\n } & Record;\n /** Send a message to a background subagent by its subagent id, continuing the same conversation. It becomes the subagent's next turn: if it is still working, the message waits until its current turn finishes, so it cannot redirect work already underway. This call returns no answer from the subagent — only confirmation that the message was delivered — so use it to give it more work. A failure means the message was NOT delivered. */\n send_message: {\n /** The subagent id returned when the background subagent was started. */\n subagent_id: string;\n /** The message to deliver to the subagent. */\n message: string;\n } & Record;\n /** Load the full instructions for an available skill. Call this with the exact skill name from the session skill catalog before acting on a task that names or clearly matches that skill. */\n skill: {\n /** The exact skill name from the available skills list. */\n name: string;\n } & Record;\n /** Delegate a self-contained task to a subagent (a separate agent that works in its own context) and return its final result. Use this to offload focused, independent work — research, a scoped implementation, an analysis — so it does not consume this conversation's context. The subagent runs to completion and you receive only its final answer, not its intermediate steps. Give it a complete, standalone prompt: it does not see this conversation. Set `run_in_background: true` to start a background subagent that keeps its conversation: you receive only its subagent id, never its result, and it works on its own. Use this for work whose result you do not need returned by this call; `send_message` sends it more work. */\n subagent: {\n /** A short (3-5 word) description of the delegated task, for display. */\n description: string;\n /** The complete, self-contained task for the subagent. It does not share this conversation's context, so include everything it needs. */\n prompt: string;\n /** Run as a background subagent that keeps its conversation and return only its subagent id. This call never returns its result; send it more work with send_message. */\n run_in_background?: boolean;\n } & Record;\n /** Delegate a task to a subagent that inherits this conversation: a child agent seeded with all completed turns so far (it does not see the current in-flight turn), returning only its final result. Use this when the subtask builds on this conversation's context — a follow-up analysis, a review, a continuation — without consuming this conversation's context for the work itself. You receive only its final answer, not its intermediate steps. Set `run_in_background: true` to start a background subagent that keeps its conversation: you receive only its subagent id, never its result, and it works on its own. Use this for work whose result you do not need returned by this call; `send_message` sends it more work. */\n subagent_fork: {\n /** A short (3-5 word) description of the delegated task, for display. */\n description: string;\n /** The task for the subagent. It already sees this conversation's completed turns, so build on them freely and state only what is new. */\n prompt: string;\n /** Run as a background subagent that keeps its conversation and return only its subagent id. This call never returns its result; send it more work with send_message. */\n run_in_background?: boolean;\n } & Record;\n /** Request cancellation of a running background task by task id. Returns immediately; the task settles as killed once its work actually stops. */\n task_kill: {\n /** Task id returned by the tool that started the background work. */\n task_id: string;\n /** Optional short reason, recorded in the log and forwarded to the task. */\n reason?: string;\n } & Record;\n /** List your background tasks (running and finished) with their ids, kinds, and statuses. */\n task_list: Record;\n /** Read a background task. Stream tasks return only output since the previous read; final-output tasks return their result after settlement. Every response ends with `[status: ...]`. Reads are non-blocking unless `wait: true`, which waits up to the configured cap. */\n task_output: {\n /** Task id returned by the tool that started the background work. */\n task_id: string;\n /** Block until the task reaches a terminal status or the timeout expires. A timed-out wait returns [status: running] and leaves the task alive. */\n wait?: boolean;\n /** Max wait in milliseconds (only meaningful with wait: true). Defaults to the configured wait timeout; capped by the configured maximum. */\n timeout_ms?: number;\n } & Record;\n /** Record and update a structured task list for the current work. Send the ENTIRE list every call — it REPLACES the previous list (there are no partial updates, no per-item edits). Use it to plan multi-step work and show progress: add one todo per concrete step before you start. Mark every todo being actively worked on `in_progress` — several at once when work genuinely runs in parallel (e.g. concurrent subagents or background commands), one for sequential work; while work remains, at least one task should be `in_progress`. Mark a todo `completed` the moment it is done (do not batch completions), and allow no `in_progress` item only once all work is complete. Skip the list for trivial single-step tasks. Statuses: `pending` (not started), `in_progress` (being worked on now), `completed` (finished). */\n todo_write: {\n /** The COMPLETE task list, replacing any previous list. */\n todos: ({\n /** What the task is — a short imperative line. */\n content: string;\n /** pending (not started) | in_progress (now) | completed (done). */\n status: \"pending\" | \"in_progress\" | \"completed\";\n })[];\n } & Record;\n /** Run a JavaScript workflow script that orchestrates subagents at scale. Use this for work that fans out across many independent pieces — an audit over many files, a migration, multi-angle research, adversarial verification of findings — where you write the orchestration as a script instead of delegating turn by turn. The workflow's identity rides the `meta` parameter as JSON: required `name` (short kebab-case) and `description` strings, optional `whenToUse` string and `phases` array (`{title, detail?, provider?, model?}`). The `script` parameter is the plain JavaScript body ONLY (NOT TypeScript, and NO `export const meta` statement — meta is a parameter, not code), running with top-level await; end with `return ` — the value must be JSON-serializable and is this tool's result. Script-body hooks: - `agent(prompt, opts?): Promise` — run one subagent to completion. Without `opts.schema` it resolves to the child's final text; with `opts.schema` (an object-rooted JSON Schema using ONLY type/properties/required/additionalProperties/items/enum/const/oneOf — no pattern/format/numeric bounds) it resolves to the validated object. Resolves `null` when the child fails (filter with `.filter(Boolean)`). Other opts: `label` (display), `phase` (progress group), and independent `provider`/`model` LLM target overrides (either may be provided alone). Anything else (`effort`/`isolation`/`agentType`) is rejected loudly. - `pipeline(items, ...stages): Promise` — run each item through the stages independently with NO barrier between stages (prefer this for multi-stage work). Each stage receives `(prev, item, index)`. An ordinary stage throw drops that ITEM to `null` and skips its remaining stages. - `parallel(thunks): Promise` — run zero-argument functions concurrently and await ALL of them (a barrier; use only when a stage genuinely needs every prior result together). A throwing thunk resolves to `null`. - `phase(title)` — start a progress phase; `log(message)` — narrate progress; `args` — the tool call's `args` input, verbatim. Misused hooks (bad arguments, unknown options, unsupported schemas, tripped caps) throw errors that ALWAYS kill the script — they never dissolve into a per-item `null`. Constraints: concurrency and total-agent caps apply; no filesystem, network, timers, or Node.js APIs are provided — the agents do the work, the script only coordinates them. The run executes in the foreground: this call returns when the whole script finishes. */\n workflow: {\n /** The plain-JS workflow script body (top-level await allowed; NO `export const meta` statement; end with `return `). */\n script: string;\n /** The workflow identity block (plain JSON — never code). */\n meta: {\n /** Short kebab-case workflow name. */\n name: string;\n /** One-line description of what the workflow does. */\n description: string;\n /** Optional guidance on when this workflow applies. */\n whenToUse?: string;\n /** Optional phase declarations matched by phase() calls. */\n phases?: ({\n /** The phase title phase() calls match by exact string. */\n title: string;\n /** Optional one-line description of the phase. */\n detail?: string;\n /** Optional provider override this phase is expected to use. */\n provider?: string;\n /** Optional model override this phase is expected to use. */\n model?: string;\n } & Record)[];\n } & Record;\n /** Optional JSON input exposed to the script as the `args` global (wrap a bare list as a field, e.g. {\"files\": [...]}). */\n args?: Record;\n } & Record;\n /** Create or fully replace a UTF-8 text file. */\n write: {\n /** Path to write, resolved by the filesystem backend. */\n file_path: string;\n /** Full UTF-8 text content to write. */\n content: string;\n } & Record;\n}\n\ninterface ToolOutputMap {\n bash: {\n kind: \"background\";\n taskId: string;\n } | {\n kind: \"foreground\";\n exitCode: number | null;\n signal: string | null;\n timedOut: boolean;\n aborted: boolean;\n timeoutMs: number;\n stdout: {\n text: string;\n truncated: boolean;\n spillPath?: string;\n };\n stderr: {\n text: string;\n truncated: boolean;\n spillPath?: string;\n };\n sandbox?: {\n mode: string;\n denied: boolean;\n enforcement?: string;\n runnerFailed?: boolean;\n };\n };\n cordis_inspect: string;\n cordis_mount: {\n id: string;\n pluginName: string;\n state: \"pending\" | \"loading\" | \"active\" | \"failed\" | \"disposed\" | \"unloading\";\n provides: string[];\n waitingFor: string[];\n };\n cordis_unmount: {\n id: string;\n pluginName: string;\n };\n edit: {\n path: string;\n before: string;\n after: string;\n };\n ralph: {\n runId: string;\n agentsStarted: number;\n result: JsonValue;\n };\n read: {\n path: string;\n offset: number;\n lines: {\n number: number;\n text: string;\n }[];\n totalLines: number;\n };\n send_message: {\n messageId: string;\n };\n skill: {\n name: string;\n provider: string;\n resourceBase?: {\n kind: \"directory\";\n path: string;\n } | {\n kind: \"url\";\n url: string;\n } | {\n kind: \"opaque\";\n description: string;\n };\n content: string;\n };\n subagent: {\n kind: \"background\";\n taskId: string;\n } | {\n kind: \"continuable\";\n subagentId: string;\n } | {\n kind: \"foreground\";\n runId: string;\n output: JsonValue[];\n };\n subagent_fork: {\n kind: \"background\";\n taskId: string;\n } | {\n kind: \"continuable\";\n subagentId: string;\n } | {\n kind: \"foreground\";\n runId: string;\n output: JsonValue[];\n };\n task_kill: {\n outcome: \"cancellation-requested\" | \"already-finished\";\n task: {\n id: string;\n kind: string;\n label: string;\n status: \"running\" | \"stopping\" | \"completed\" | \"killed\" | \"failed\";\n detail?: string;\n startedAt: number;\n finishedAt?: number;\n };\n };\n task_list: ({\n id: string;\n kind: string;\n label: string;\n status: \"running\" | \"stopping\" | \"completed\" | \"killed\" | \"failed\";\n detail?: string;\n startedAt: number;\n finishedAt?: number;\n })[];\n task_output: {\n text: string;\n task: {\n id: string;\n kind: string;\n label: string;\n status: \"running\" | \"stopping\" | \"completed\" | \"killed\" | \"failed\";\n detail?: string;\n startedAt: number;\n finishedAt?: number;\n };\n };\n todo_write: {\n todos: ({\n content: string;\n status: \"pending\" | \"in_progress\" | \"completed\";\n })[];\n counts: {\n pending: number;\n inProgress: number;\n completed: number;\n };\n };\n workflow: {\n runId: string;\n agentsStarted: number;\n result: JsonValue;\n };\n write: {\n path: string;\n operation: \"create\" | \"update\";\n before: string | null;\n after: string;\n };\n}\n\ntype ToolName = keyof ToolOutputMap\n\ndeclare class ToolCallError extends Error {\n readonly name: \"ToolCallError\";\n readonly toolName: ToolName;\n}\n\ndeclare const tools: {\n [K in ToolName]: (args: ToolArgsMap[K]) => Promise;\n}\n```","tools":[{"name":"bash","description":"Execute a bash command (`bash -c`) and return its stdout/stderr. Each call runs in a fresh shell: no state (cwd, variables, functions) persists between calls — pass `workdir` instead of using `cd`. Non-zero exits are reported as `[exit code: N]`. Current harness environment facts are exposed through managed `$DSH_*` variables; inspect them when needed. Commands may run under a file sandbox; a blocked file operation is reported as `[sandbox: file access denied under mode]` — a policy denial, not a bug in the command; do not retry another way. Long output is truncated to its tail; the full output is saved to a file whose path is reported when available. Set `run_in_background: true` for long-running commands: the call returns a task id immediately; read its output with `task_output` and stop it with `task_kill`.","parameters":{"type":"object","properties":{"command":{"type":"string","description":"The bash command to execute."},"description":{"type":"string","description":"Clear, concise description of what this command does in active voice, 5-10 words (shown in the UI). Examples: \"ls\" → \"List files in current directory\"; \"git status\" → \"Show working tree status\"; \"npm install\" → \"Install package dependencies\"."},"timeoutMs":{"type":"number","description":"Timeout in milliseconds. The executor applies its configured default and cap, and kills the command on expiry."},"workdir":{"type":"string","description":"Working directory for this command. Defaults to the session workspace; a relative path is resolved against it."},"run_in_background":{"type":"boolean","description":"Run in the background and return a task id immediately (collect with task_output, stop with task_kill). No timeout applies."}},"required":["command","description"]}},{"name":"cordis_inspect","description":"Inspect the live Cordis runtime in the current DSH process. Read-only. Sections: `services` (every provided ctx service and the plugin fiber that owns it), `plugins` (all live plugin fibers with their lifecycle states), `tools` (the model-facing tools currently registered, i.e. what you can call), `temporary` (only temporary Plugins created by cordis_mount: id, name, state, provided services, awaited services, and lifetime), `api` (method signatures AND argument/return type shapes for every LIVE service — read this before writing plugin code that calls a service), `events` (every harness event with its dispatch mode and exact signature — pick listener targets here). Temporary Plugins exist only in memory, remain active across later turns, and disappear after cordis_unmount, toolset unload, or DSH restart; they are not restored automatically. The `temporary` section is a subset of `plugins`. Omit `what` to get all six sections. With `what:\"api\"` or `what:\"events\"`, pass an exact `name` to narrow to one service/event and include its original source JSDoc.","parameters":{"type":"object","properties":{"what":{"type":"string","description":"Limit the report to one section. Omit for all sections.","enum":["services","plugins","tools","temporary","api","events"]},"name":{"type":"string","description":"Exact service key or event name whose original JSDoc to include; valid only with what:\"api\" or what:\"events\"."}}}},{"name":"cordis_mount","description":"Mount a temporary Cordis Plugin in the current DSH process. This creates an in-memory runtime Plugin, not an installed or configured Plugin. It remains active across later turns until cordis_unmount, toolset unload, or DSH restart. It does not create files, install a package, change cordis.yml or personal/project config, survive restart, or automatically become permanent. To keep it, ask the Agent to implement a normal local, project, or repository Plugin through the regular development workflow. It may affect other sessions in the same process; the sandbox is not a security boundary, and injected services reach the real runtime. `code` runs now as the body of an async JavaScript function in an isolated sandbox and MUST `return` a plugin. Two forms: FUNCTION form `return (ctx) => { … }` — declares no inject, so it can register tools, listen to events, and provide services, but reaching ANY service (e.g. ctx.bash) throws; use it only when you need no services. OBJECT form `return { name?, inject: ['bash', 'llm', …], apply(ctx) { … } }` — declares dependencies, and cordis activates the plugin only after the services exist; PREFER this form. You may reach ONLY the services you list in inject: an undeclared service throws even if it exists, because an undeclared dependency would not be cleaned up if its provider is unmounted. BEFORE calling a service from your code, read cordis_inspect what:\"api\" — it lists method signatures AND the type shapes of their arguments/returns (do not guess a field's type; e.g. a bash run's stdout is an object, not a string). Inside `apply`, use the standard cordis API: `ctx.on(event, listener)` to observe events (see cordis_inspect what:\"events\"), or call `harness.registerTool(ctx, harness.defineTool({ name, description, parameters: { text: { type: 'string', required: true } }, output: { schema: { type: 'string' }, render(_args, value) { return [{ type: 'text', text: value }] } }, async execute(args) { return args.text } }))` to give yourself a new tool — it becomes callable on your NEXT step. Tool parameters: each key IS a property — { type: 'string'|'number'|'integer'|'boolean'|'null'|'object'|'array'|'json', required?: true, description?, enum?, const?, items?, properties? }; every direct DSL object declares additionalProperties: true|false, and oneOf: [schema, schema, ...] replaces type for an exact-one union. A raw JSON-Schema { type: 'object', properties, required?: […] } wrapper is also accepted with open-by-default objects. A tool's `execute` MUST return the lossless JSON value declared by `output.schema`; `output.render(args, value)` separately returns Native/model content blocks. Temporary Plugins can COMPOSE: one Plugin may `ctx.provide('name', value)` a service and another may declare `inject: ['name']` to consume it — the consumer stays pending until the provider exists and returns to pending when the provider is unmounted. Everything registered inside `apply` is cleaned up automatically by cordis_unmount. Sandbox globals: `console` (tagged `[cordis:]`, writes through to the harness terminal), `harness.defineTool`, `harness.registerTool`, `btoa`, `atob`, `TextEncoder`, `TextDecoder`. Node APIs are DISABLED — do filesystem/network/timer work through the cordis services, never Node built-ins: `require`, `setTimeout`/`setInterval`, and `fetch` throw redirect errors; `process` and `Buffer` are undefined. Instead use inject: ['fs'] + ctx.fs for files, inject: ['web'] + ctx.web for HTTP, inject: ['bash'] + ctx.bash for processes, and inject: ['timer'] + ctx.setTimeout/ctx.setInterval for timing (fiber effects, auto-cleaned when unmounted) — cordis_inspect what:\"api\" shows what THIS runtime provides. Write PLAIN JavaScript, not TypeScript (no `as`, no type annotations). Cautions: (1) waterfall events (e.g. tools/pre-execute) hand the listener a trailing `next` callback which MUST be called — returning without `next()` SHORT-CIRCUITS the call; prefer plain notification events unless you intend to intercept. (2) Never await something that only resolves after the current turn (your code runs INSIDE a tool call of that turn — it would deadlock). (3) Your `ctx` is a restricted façade: you can register tools, observe events, provide/consume services, and use timers, but framework internals (ctx.root, ctx.fiber, ctx.extend, ctx.plugin, …) are withheld. It is not a security boundary though — the services you inject (e.g. ctx.bash) reach the real runtime.","parameters":{"type":"object","properties":{"code":{"type":"string","description":"JavaScript body returning a temporary Plugin; evaluated now and saved nowhere."}},"required":["code"]}},{"name":"cordis_unmount","description":"Unmount a current-process temporary Plugin created by cordis_mount. Waits for its tools, listeners, services, timers, and other owned effects to clean up completely. Only dyn-N temporary ids are accepted; this cannot remove Loader, configured, or installed Plugins.","parameters":{"type":"object","properties":{"id":{"type":"string","description":"The temporary Plugin id returned by cordis_mount (for example \"dyn-1\"); valid only in this process and invalid after unmount or restart."}},"required":["id"]}},{"name":"edit","description":"Edit an existing UTF-8 text file by replacing literal text.","parameters":{"type":"object","properties":{"file_path":{"type":"string","description":"Path to edit, resolved by the filesystem backend."},"old_string":{"type":"string","description":"Literal text to replace. Must match exactly."},"new_string":{"type":"string","description":"Literal replacement text. Use an empty string to delete the match."},"replace_all":{"type":"boolean","description":"Replace all matches. Defaults to false; when false, old_string must appear exactly once."}},"required":["file_path","old_string","new_string"]}},{"name":"ralph","description":"Run a foreground fresh-agent Ralph loop toward one immutable objective. Use only when the direct human explicitly asks for Ralph or fresh-agent iteration. Each round opens a new child with no parent conversation or prior child session; the shared workspace is long-term memory, and only a bounded structured report crosses rounds. The call returns when a worker reports completion or a concrete blocker, or at the round limit. Ordinary long-running same-session work belongs to goal tools.","parameters":{"type":"object","properties":{"objective":{"type":"string","description":"The immutable completion objective for every fresh Ralph round."},"maxRounds":{"type":"number","description":"Optional positive safe-integer round cap, bounded by the deployment ceiling."}},"required":["objective"]}},{"name":"read","description":"Read a UTF-8 text file and return line-numbered content.","parameters":{"type":"object","properties":{"file_path":{"type":"string","description":"Path to read, resolved by the filesystem backend."},"offset":{"type":"number","description":"1-based first line to return. Defaults to 1."},"limit":{"type":"number","description":"Maximum number of lines to return. Defaults to 2000."}},"required":["file_path"]}},{"name":"run_code","description":"Execute a TypeScript program against the available tools. Write the BODY of an async function (erasable syntax only; top-level `await` and `return` work) and call tools as `await tools.name(args)` per the declarations in the system prompt. Only what you print or return comes back — curate it.","parameters":{"type":"object","properties":{"code":{"type":"string","description":"The program: the body of an async TypeScript function."},"description":{"type":"string","description":"Clear, concise description of what this program does in active voice, 5-10 words (shown in the UI). Examples: \"Count TODO markers across packages\"; \"Read failing test and its fixture\"; \"Rename config key in every cordis.yml\"."}},"required":["code","description"]}},{"name":"send_message","description":"Send a message to a background subagent by its subagent id, continuing the same conversation. It becomes the subagent's next turn: if it is still working, the message waits until its current turn finishes, so it cannot redirect work already underway. This call returns no answer from the subagent — only confirmation that the message was delivered — so use it to give it more work. A failure means the message was NOT delivered.","parameters":{"type":"object","properties":{"subagent_id":{"type":"string","description":"The subagent id returned when the background subagent was started."},"message":{"type":"string","description":"The message to deliver to the subagent."}},"required":["subagent_id","message"]}},{"name":"skill","description":"Load the full instructions for an available skill. Call this with the exact skill name from the session skill catalog before acting on a task that names or clearly matches that skill.","parameters":{"type":"object","properties":{"name":{"type":"string","description":"The exact skill name from the available skills list."}},"required":["name"]}},{"name":"subagent","description":"Delegate a self-contained task to a subagent (a separate agent that works in its own context) and return its final result. Use this to offload focused, independent work — research, a scoped implementation, an analysis — so it does not consume this conversation's context. The subagent runs to completion and you receive only its final answer, not its intermediate steps. Give it a complete, standalone prompt: it does not see this conversation. Set `run_in_background: true` to start a background subagent that keeps its conversation: you receive only its subagent id, never its result, and it works on its own. Use this for work whose result you do not need returned by this call; `send_message` sends it more work.","parameters":{"type":"object","properties":{"description":{"type":"string","description":"A short (3-5 word) description of the delegated task, for display."},"prompt":{"type":"string","description":"The complete, self-contained task for the subagent. It does not share this conversation's context, so include everything it needs."},"run_in_background":{"type":"boolean","description":"Run as a background subagent that keeps its conversation and return only its subagent id. This call never returns its result; send it more work with send_message."}},"required":["description","prompt"]}},{"name":"subagent_fork","description":"Delegate a task to a subagent that inherits this conversation: a child agent seeded with all completed turns so far (it does not see the current in-flight turn), returning only its final result. Use this when the subtask builds on this conversation's context — a follow-up analysis, a review, a continuation — without consuming this conversation's context for the work itself. You receive only its final answer, not its intermediate steps. Set `run_in_background: true` to start a background subagent that keeps its conversation: you receive only its subagent id, never its result, and it works on its own. Use this for work whose result you do not need returned by this call; `send_message` sends it more work.","parameters":{"type":"object","properties":{"description":{"type":"string","description":"A short (3-5 word) description of the delegated task, for display."},"prompt":{"type":"string","description":"The task for the subagent. It already sees this conversation's completed turns, so build on them freely and state only what is new."},"run_in_background":{"type":"boolean","description":"Run as a background subagent that keeps its conversation and return only its subagent id. This call never returns its result; send it more work with send_message."}},"required":["description","prompt"]}},{"name":"task_kill","description":"Request cancellation of a running background task by task id. Returns immediately; the task settles as killed once its work actually stops.","parameters":{"type":"object","properties":{"task_id":{"type":"string","description":"Task id returned by the tool that started the background work."},"reason":{"type":"string","description":"Optional short reason, recorded in the log and forwarded to the task."}},"required":["task_id"]}},{"name":"task_list","description":"List your background tasks (running and finished) with their ids, kinds, and statuses.","parameters":{"type":"object","properties":{}}},{"name":"task_output","description":"Read a background task. Stream tasks return only output since the previous read; final-output tasks return their result after settlement. Every response ends with `[status: ...]`. Reads are non-blocking unless `wait: true`, which waits up to the configured cap.","parameters":{"type":"object","properties":{"task_id":{"type":"string","description":"Task id returned by the tool that started the background work."},"wait":{"type":"boolean","description":"Block until the task reaches a terminal status or the timeout expires. A timed-out wait returns [status: running] and leaves the task alive."},"timeout_ms":{"type":"number","description":"Max wait in milliseconds (only meaningful with wait: true). Defaults to the configured wait timeout; capped by the configured maximum."}},"required":["task_id"]}},{"name":"todo_write","description":"Record and update a structured task list for the current work. Send the ENTIRE list every call — it REPLACES the previous list (there are no partial updates, no per-item edits). Use it to plan multi-step work and show progress: add one todo per concrete step before you start. Mark every todo being actively worked on `in_progress` — several at once when work genuinely runs in parallel (e.g. concurrent subagents or background commands), one for sequential work; while work remains, at least one task should be `in_progress`. Mark a todo `completed` the moment it is done (do not batch completions), and allow no `in_progress` item only once all work is complete. Skip the list for trivial single-step tasks. Statuses: `pending` (not started), `in_progress` (being worked on now), `completed` (finished).","parameters":{"type":"object","properties":{"todos":{"type":"array","description":"The COMPLETE task list, replacing any previous list.","items":{"type":"object","additionalProperties":false,"properties":{"content":{"type":"string","description":"What the task is — a short imperative line."},"status":{"type":"string","description":"pending (not started) | in_progress (now) | completed (done).","enum":["pending","in_progress","completed"]}},"required":["content","status"]}}},"required":["todos"]}},{"name":"workflow","description":"Run a JavaScript workflow script that orchestrates subagents at scale. Use this for work that fans out across many independent pieces — an audit over many files, a migration, multi-angle research, adversarial verification of findings — where you write the orchestration as a script instead of delegating turn by turn.\n\nThe workflow's identity rides the `meta` parameter as JSON: required `name` (short kebab-case) and `description` strings, optional `whenToUse` string and `phases` array (`{title, detail?, provider?, model?}`). The `script` parameter is the plain JavaScript body ONLY (NOT TypeScript, and NO `export const meta` statement — meta is a parameter, not code), running with top-level await; end with `return ` — the value must be JSON-serializable and is this tool's result.\n\nScript-body hooks:\n- `agent(prompt, opts?): Promise` — run one subagent to completion. Without `opts.schema` it resolves to the child's final text; with `opts.schema` (an object-rooted JSON Schema using ONLY type/properties/required/additionalProperties/items/enum/const/oneOf — no pattern/format/numeric bounds) it resolves to the validated object. Resolves `null` when the child fails (filter with `.filter(Boolean)`). Other opts: `label` (display), `phase` (progress group), and independent `provider`/`model` LLM target overrides (either may be provided alone). Anything else (`effort`/`isolation`/`agentType`) is rejected loudly.\n- `pipeline(items, ...stages): Promise` — run each item through the stages independently with NO barrier between stages (prefer this for multi-stage work). Each stage receives `(prev, item, index)`. An ordinary stage throw drops that ITEM to `null` and skips its remaining stages.\n- `parallel(thunks): Promise` — run zero-argument functions concurrently and await ALL of them (a barrier; use only when a stage genuinely needs every prior result together). A throwing thunk resolves to `null`.\n- `phase(title)` — start a progress phase; `log(message)` — narrate progress; `args` — the tool call's `args` input, verbatim.\n\nMisused hooks (bad arguments, unknown options, unsupported schemas, tripped caps) throw errors that ALWAYS kill the script — they never dissolve into a per-item `null`.\n\nConstraints: concurrency and total-agent caps apply; no filesystem, network, timers, or Node.js APIs are provided — the agents do the work, the script only coordinates them. The run executes in the foreground: this call returns when the whole script finishes.","parameters":{"type":"object","properties":{"script":{"type":"string","description":"The plain-JS workflow script body (top-level await allowed; NO `export const meta` statement; end with `return `)."},"meta":{"type":"object","description":"The workflow identity block (plain JSON — never code).","additionalProperties":true,"properties":{"name":{"type":"string","description":"Short kebab-case workflow name."},"description":{"type":"string","description":"One-line description of what the workflow does."},"whenToUse":{"type":"string","description":"Optional guidance on when this workflow applies."},"phases":{"type":"array","description":"Optional phase declarations matched by phase() calls.","items":{"type":"object","additionalProperties":true,"properties":{"title":{"type":"string","description":"The phase title phase() calls match by exact string."},"detail":{"type":"string","description":"Optional one-line description of the phase."},"provider":{"type":"string","description":"Optional provider override this phase is expected to use."},"model":{"type":"string","description":"Optional model override this phase is expected to use."}},"required":["title"]}}},"required":["name","description"]},"args":{"type":"object","description":"Optional JSON input exposed to the script as the `args` global (wrap a bare list as a field, e.g. {\"files\": [...]}).","additionalProperties":true}},"required":["script","meta"]}},{"name":"write","description":"Create or fully replace a UTF-8 text file.","parameters":{"type":"object","properties":{"file_path":{"type":"string","description":"Path to write, resolved by the filesystem backend."},"content":{"type":"string","description":"Full UTF-8 text content to write."}},"required":["file_path","content"]}}]},"reason":"initial"}} +{"type":"request/header","seq":6,"time":1785498583782,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"You are an AI agent powered by the DeepSeek Harness SDK.\n\nYou are headless-agent, a coding assistant powered by the deepseek-v4-flash model. Your working directory is {{cwd}}.\n\nVerify your work by running the code or tests. Keep answers brief and factual.\n\n\nUse the read tool — not shell commands like cat — to inspect text files. Results include line numbers. Use offset and limit to continue reading large files.\n\nUse the write tool to create files or completely replace file contents. Existing files are overwritten, so read an existing file first (the default fs-policy requires it) and prefer edit for targeted changes.\n\nUse the edit tool for targeted changes to existing UTF-8 text files. It replaces literal old_string with new_string; by default old_string must appear exactly once. If old_string appears multiple times, provide a more specific old_string or set replace_all to true. Read the file first (the default fs-policy requires it), unless you just created or edited it in this session.\n\nCheck the [exit code: N] marker on every bash result; investigate failures before moving on.\n\nTrack every background task id you start. You are notified in-session when a task finishes — do not busy-poll or sleep on one; keep working on independent steps and do not duplicate a running task's work. Before giving a final answer, collect every still-relevant task with task_output (set wait: true only when you are genuinely blocked on it), and task_kill tasks that stopped mattering.\n\nUse the workflow tool ONLY when the user explicitly asks for a workflow or for large multi-agent orchestration: you write a JavaScript script (the tool description documents the exact format) that fans work out across many subagents with phases and structured results. For one or two delegations, prefer plain subagent calls.\n\nUse the ralph tool ONLY when the direct human explicitly asks for a Ralph loop or fresh-agent iterative execution. Each Ralph round starts a fresh child with no conversation seed and uses the shared workspace as durable memory. Completion and blockers are worker reports, not independent evaluation. Use same-session goal tools for ordinary long-running objectives, and plain subagents or workflows for bounded delegation and fan-out.\n\n## Writing code for run_code\n\nPass `run_code` the body of an async TypeScript function (erasable syntax only — no `enum` or namespaces; type annotations are advisory, the code runs type-stripped). Inside the program:\n\n- Call tools as `await tools.name(args)` — quoted access for exotic names: `tools[\"my-tool\"](args)`. Every call resolves to the tool's typed canonical JSON value. Tool arguments must be lossless JSON.\n- A FAILED tool call rejects with `ToolCallError`, whose `toolName` identifies the failed tool and whose `message` is human-readable — `try/catch` it to handle and continue.\n- Independent read-only calls MAY overlap under `Promise.all` (safe calls run concurrently; mutating calls run alone, in submission order). Sequence dependent work with `await`.\n- Emit results with `return` and/or `console.log(...)`. ONLY what you print or return comes back to you — intermediate tool results never enter the conversation, so extract just what you need.\n\nThe available tools:\n\n```ts\ntype JsonValue = null | boolean | number | string | JsonValue[] | { [key: string]: JsonValue }\n\ninterface ToolArgsMap {\n /** Execute a bash command (`bash -c`) and return its stdout/stderr. Each call runs in a fresh shell: no state (cwd, variables, functions) persists between calls — pass `workdir` instead of using `cd`. Non-zero exits are reported as `[exit code: N]`. Current harness environment facts are exposed through managed `$DSH_*` variables; inspect them when needed. Commands may run under a file sandbox; a blocked file operation is reported as `[sandbox: file access denied under mode]` — a policy denial, not a bug in the command; do not retry another way. Long output is truncated to its tail; the full output is saved to a file whose path is reported when available. Set `run_in_background: true` for long-running commands: the call returns a task id immediately; read its output with `task_output` and stop it with `task_kill`. */\n bash: {\n /** The bash command to execute. */\n command: string;\n /** Clear, concise description of what this command does in active voice, 5-10 words (shown in the UI). Examples: \"ls\" → \"List files in current directory\"; \"git status\" → \"Show working tree status\"; \"npm install\" → \"Install package dependencies\". */\n description: string;\n /** Timeout in milliseconds. The executor applies its configured default and cap, and kills the command on expiry. */\n timeoutMs?: number;\n /** Working directory for this command. Defaults to the session workspace; a relative path is resolved against it. */\n workdir?: string;\n /** Run in the background and return a task id immediately (collect with task_output, stop with task_kill). No timeout applies. */\n run_in_background?: boolean;\n } & Record;\n /** Inspect the live Cordis runtime in the current DSH process. Read-only. Sections: `services` (every provided ctx service and the plugin fiber that owns it), `plugins` (all live plugin fibers with their lifecycle states), `tools` (the model-facing tools currently registered, i.e. what you can call), `temporary` (only temporary Plugins created by cordis_mount: id, name, state, provided services, awaited services, and lifetime), `api` (method signatures AND argument/return type shapes for every LIVE service — read this before writing plugin code that calls a service), `events` (every harness event with its dispatch mode and exact signature — pick listener targets here). Temporary Plugins exist only in memory, remain active across later turns, and disappear after cordis_unmount, toolset unload, or DSH restart; they are not restored automatically. The `temporary` section is a subset of `plugins`. Omit `what` to get all six sections. With `what:\"api\"` or `what:\"events\"`, pass an exact `name` to narrow to one service/event and include its original source JSDoc. */\n cordis_inspect: {\n /** Limit the report to one section. Omit for all sections. */\n what?: \"services\" | \"plugins\" | \"tools\" | \"temporary\" | \"api\" | \"events\";\n /** Exact service key or event name whose original JSDoc to include; valid only with what:\"api\" or what:\"events\". */\n name?: string;\n } & Record;\n /** Mount a temporary Cordis Plugin in the current DSH process. This creates an in-memory runtime Plugin, not an installed or configured Plugin. It remains active across later turns until cordis_unmount, toolset unload, or DSH restart. It does not create files, install a package, change cordis.yml or personal/project config, survive restart, or automatically become permanent. To keep it, ask the Agent to implement a normal local, project, or repository Plugin through the regular development workflow. It may affect other sessions in the same process; the sandbox is not a security boundary, and injected services reach the real runtime. `code` runs now as the body of an async JavaScript function in an isolated sandbox and MUST `return` a plugin. Two forms: FUNCTION form `return (ctx) => { … }` — declares no inject, so it can register tools, listen to events, and provide services, but reaching ANY service (e.g. ctx.bash) throws; use it only when you need no services. OBJECT form `return { name?, inject: ['bash', 'llm', …], apply(ctx) { … } }` — declares dependencies, and cordis activates the plugin only after the services exist; PREFER this form. You may reach ONLY the services you list in inject: an undeclared service throws even if it exists, because an undeclared dependency would not be cleaned up if its provider is unmounted. BEFORE calling a service from your code, read cordis_inspect what:\"api\" — it lists method signatures AND the type shapes of their arguments/returns (do not guess a field's type; e.g. a bash run's stdout is an object, not a string). Inside `apply`, use the standard cordis API: `ctx.on(event, listener)` to observe events (see cordis_inspect what:\"events\"), or call `harness.registerTool(ctx, harness.defineTool({ name, description, parameters: { text: { type: 'string', required: true } }, output: { schema: { type: 'string' }, render(_args, value) { return [{ type: 'text', text: value }] } }, async execute(args) { return args.text } }))` to give yourself a new tool — it becomes callable on your NEXT step. Tool parameters: each key IS a property — { type: 'string'|'number'|'integer'|'boolean'|'null'|'object'|'array'|'json', required?: true, description?, enum?, const?, items?, properties? }; every direct DSL object declares additionalProperties: true|false, and oneOf: [schema, schema, ...] replaces type for an exact-one union. A raw JSON-Schema { type: 'object', properties, required?: […] } wrapper is also accepted with open-by-default objects. A tool's `execute` MUST return the lossless JSON value declared by `output.schema`; `output.render(args, value)` separately returns Native/model content blocks. Temporary Plugins can COMPOSE: one Plugin may `ctx.provide('name', value)` a service and another may declare `inject: ['name']` to consume it — the consumer stays pending until the provider exists and returns to pending when the provider is unmounted. Everything registered inside `apply` is cleaned up automatically by cordis_unmount. Sandbox globals: `console` (tagged `[cordis:]`, writes through to the harness terminal), `harness.defineTool`, `harness.registerTool`, `btoa`, `atob`, `TextEncoder`, `TextDecoder`. Node APIs are DISABLED — do filesystem/network/timer work through the cordis services, never Node built-ins: `require`, `setTimeout`/`setInterval`, and `fetch` throw redirect errors; `process` and `Buffer` are undefined. Instead use inject: ['fs'] + ctx.fs for files, inject: ['web'] + ctx.web for HTTP, inject: ['bash'] + ctx.bash for processes, and inject: ['timer'] + ctx.setTimeout/ctx.setInterval for timing (fiber effects, auto-cleaned when unmounted) — cordis_inspect what:\"api\" shows what THIS runtime provides. Write PLAIN JavaScript, not TypeScript (no `as`, no type annotations). Cautions: (1) waterfall events (e.g. tools/pre-execute) hand the listener a trailing `next` callback which MUST be called — returning without `next()` SHORT-CIRCUITS the call; prefer plain notification events unless you intend to intercept. (2) Never await something that only resolves after the current turn (your code runs INSIDE a tool call of that turn — it would deadlock). (3) Your `ctx` is a restricted façade: you can register tools, observe events, provide/consume services, and use timers, but framework internals (ctx.root, ctx.fiber, ctx.extend, ctx.plugin, …) are withheld. It is not a security boundary though — the services you inject (e.g. ctx.bash) reach the real runtime. */\n cordis_mount: {\n /** JavaScript body returning a temporary Plugin; evaluated now and saved nowhere. */\n code: string;\n } & Record;\n /** Unmount a current-process temporary Plugin created by cordis_mount. Waits for its tools, listeners, services, timers, and other owned effects to clean up completely. Only dyn-N temporary ids are accepted; this cannot remove Loader, configured, or installed Plugins. */\n cordis_unmount: {\n /** The temporary Plugin id returned by cordis_mount (for example \"dyn-1\"); valid only in this process and invalid after unmount or restart. */\n id: string;\n } & Record;\n /** Edit an existing UTF-8 text file by replacing literal text. */\n edit: {\n /** Path to edit, resolved by the filesystem backend. */\n file_path: string;\n /** Literal text to replace. Must match exactly. */\n old_string: string;\n /** Literal replacement text. Use an empty string to delete the match. */\n new_string: string;\n /** Replace all matches. Defaults to false; when false, old_string must appear exactly once. */\n replace_all?: boolean;\n } & Record;\n /** Request cancellation of a background agent's current turn by its agent id. The target may be your direct child or a deeper agent created under you. Only the current turn stops: messages already queued for the agent stay parked until a later send_message, agents it started keep running, and the agent itself stays available for follow-ups. This call returns as soon as the stop request is accepted, so the target may keep running briefly; interrupting an agent that already finished is an accepted no-op. */\n interrupt_agent: {\n /** The agent id of the running agent to interrupt. */\n agent_id: string;\n } & Record;\n /** Run a foreground fresh-agent Ralph loop toward one immutable objective. Use only when the direct human explicitly asks for Ralph or fresh-agent iteration. Each round opens a new child with no parent conversation or prior child session; the shared workspace is long-term memory, and only a bounded structured report crosses rounds. The call returns when a worker reports completion or a concrete blocker, or at the round limit. Ordinary long-running same-session work belongs to goal tools. */\n ralph: {\n /** The immutable completion objective for every fresh Ralph round. */\n objective: string;\n /** Optional positive safe-integer round cap, bounded by the deployment ceiling. */\n maxRounds?: number;\n } & Record;\n /** Read a UTF-8 text file and return line-numbered content. */\n read: {\n /** Path to read, resolved by the filesystem backend. */\n file_path: string;\n /** 1-based first line to return. Defaults to 1. */\n offset?: number;\n /** Maximum number of lines to return. Defaults to 2000. */\n limit?: number;\n } & Record;\n /** Send a message to a background subagent by its subagent id, continuing the same conversation. It becomes the subagent's next turn: if it is still working, the message waits until its current turn finishes, so it cannot redirect work already underway. This call returns no answer from the subagent — only confirmation that the message was delivered — so use it to give it more work. A failure means the message was NOT delivered. */\n send_message: {\n /** The subagent id returned when the background subagent was started. */\n subagent_id: string;\n /** The message to deliver to the subagent. */\n message: string;\n } & Record;\n /** Load the full instructions for an available skill. Call this with the exact skill name from the session skill catalog before acting on a task that names or clearly matches that skill. */\n skill: {\n /** The exact skill name from the available skills list. */\n name: string;\n } & Record;\n /** Delegate a self-contained task to a subagent (a separate agent that works in its own context) and return its final result. Use this to offload focused, independent work — research, a scoped implementation, an analysis — so it does not consume this conversation's context. The subagent runs to completion and you receive only its final answer, not its intermediate steps. Give it a complete, standalone prompt: it does not see this conversation. Set `run_in_background: true` to start a background subagent that keeps its conversation: you receive only its subagent id, never its result, and it works on its own. Use this for work whose result you do not need returned by this call; `send_message` sends it more work. */\n subagent: {\n /** A short (3-5 word) description of the delegated task, for display. */\n description: string;\n /** The complete, self-contained task for the subagent. It does not share this conversation's context, so include everything it needs. */\n prompt: string;\n /** Run as a background subagent that keeps its conversation and return only its subagent id. This call never returns its result; send it more work with send_message. */\n run_in_background?: boolean;\n } & Record;\n /** Delegate a task to a subagent that inherits this conversation: a child agent seeded with all completed turns so far (it does not see the current in-flight turn), returning only its final result. Use this when the subtask builds on this conversation's context — a follow-up analysis, a review, a continuation — without consuming this conversation's context for the work itself. You receive only its final answer, not its intermediate steps. Set `run_in_background: true` to start a background subagent that keeps its conversation: you receive only its subagent id, never its result, and it works on its own. Use this for work whose result you do not need returned by this call; `send_message` sends it more work. */\n subagent_fork: {\n /** A short (3-5 word) description of the delegated task, for display. */\n description: string;\n /** The task for the subagent. It already sees this conversation's completed turns, so build on them freely and state only what is new. */\n prompt: string;\n /** Run as a background subagent that keeps its conversation and return only its subagent id. This call never returns its result; send it more work with send_message. */\n run_in_background?: boolean;\n } & Record;\n /** Request cancellation of a running background task by task id. Returns immediately; the task settles as killed once its work actually stops. */\n task_kill: {\n /** Task id returned by the tool that started the background work. */\n task_id: string;\n /** Optional short reason, recorded in the log and forwarded to the task. */\n reason?: string;\n } & Record;\n /** List your background tasks (running and finished) with their ids, kinds, and statuses. */\n task_list: Record;\n /** Read a background task. Stream tasks return only output since the previous read; final-output tasks return their result after settlement. Every response ends with `[status: ...]`. Reads are non-blocking unless `wait: true`, which waits up to the configured cap. */\n task_output: {\n /** Task id returned by the tool that started the background work. */\n task_id: string;\n /** Block until the task reaches a terminal status or the timeout expires. A timed-out wait returns [status: running] and leaves the task alive. */\n wait?: boolean;\n /** Max wait in milliseconds (only meaningful with wait: true). Defaults to the configured wait timeout; capped by the configured maximum. */\n timeout_ms?: number;\n } & Record;\n /** Record and update a structured task list for the current work. Send the ENTIRE list every call — it REPLACES the previous list (there are no partial updates, no per-item edits). Use it to plan multi-step work and show progress: add one todo per concrete step before you start. Mark every todo being actively worked on `in_progress` — several at once when work genuinely runs in parallel (e.g. concurrent subagents or background commands), one for sequential work; while work remains, at least one task should be `in_progress`. Mark a todo `completed` the moment it is done (do not batch completions), and allow no `in_progress` item only once all work is complete. Skip the list for trivial single-step tasks. Statuses: `pending` (not started), `in_progress` (being worked on now), `completed` (finished). */\n todo_write: {\n /** The COMPLETE task list, replacing any previous list. */\n todos: ({\n /** What the task is — a short imperative line. */\n content: string;\n /** pending (not started) | in_progress (now) | completed (done). */\n status: \"pending\" | \"in_progress\" | \"completed\";\n })[];\n } & Record;\n /** Run a JavaScript workflow script that orchestrates subagents at scale. Use this for work that fans out across many independent pieces — an audit over many files, a migration, multi-angle research, adversarial verification of findings — where you write the orchestration as a script instead of delegating turn by turn. The workflow's identity rides the `meta` parameter as JSON: required `name` (short kebab-case) and `description` strings, optional `whenToUse` string and `phases` array (`{title, detail?, provider?, model?}`). The `script` parameter is the plain JavaScript body ONLY (NOT TypeScript, and NO `export const meta` statement — meta is a parameter, not code), running with top-level await; end with `return ` — the value must be JSON-serializable and is this tool's result. Script-body hooks: - `agent(prompt, opts?): Promise` — run one subagent to completion. Without `opts.schema` it resolves to the child's final text; with `opts.schema` (an object-rooted JSON Schema using ONLY type/properties/required/additionalProperties/items/enum/const/oneOf — no pattern/format/numeric bounds) it resolves to the validated object. Resolves `null` when the child fails (filter with `.filter(Boolean)`). Other opts: `label` (display), `phase` (progress group), and independent `provider`/`model` LLM target overrides (either may be provided alone). Anything else (`effort`/`isolation`/`agentType`) is rejected loudly. - `pipeline(items, ...stages): Promise` — run each item through the stages independently with NO barrier between stages (prefer this for multi-stage work). Each stage receives `(prev, item, index)`. An ordinary stage throw drops that ITEM to `null` and skips its remaining stages. - `parallel(thunks): Promise` — run zero-argument functions concurrently and await ALL of them (a barrier; use only when a stage genuinely needs every prior result together). A throwing thunk resolves to `null`. - `phase(title)` — start a progress phase; `log(message)` — narrate progress; `args` — the tool call's `args` input, verbatim. Misused hooks (bad arguments, unknown options, unsupported schemas, tripped caps) throw errors that ALWAYS kill the script — they never dissolve into a per-item `null`. Constraints: concurrency and total-agent caps apply; no filesystem, network, timers, or Node.js APIs are provided — the agents do the work, the script only coordinates them. The run executes in the foreground: this call returns when the whole script finishes. */\n workflow: {\n /** The plain-JS workflow script body (top-level await allowed; NO `export const meta` statement; end with `return `). */\n script: string;\n /** The workflow identity block (plain JSON — never code). */\n meta: {\n /** Short kebab-case workflow name. */\n name: string;\n /** One-line description of what the workflow does. */\n description: string;\n /** Optional guidance on when this workflow applies. */\n whenToUse?: string;\n /** Optional phase declarations matched by phase() calls. */\n phases?: ({\n /** The phase title phase() calls match by exact string. */\n title: string;\n /** Optional one-line description of the phase. */\n detail?: string;\n /** Optional provider override this phase is expected to use. */\n provider?: string;\n /** Optional model override this phase is expected to use. */\n model?: string;\n } & Record)[];\n } & Record;\n /** Optional JSON input exposed to the script as the `args` global (wrap a bare list as a field, e.g. {\"files\": [...]}). */\n args?: Record;\n } & Record;\n /** Create or fully replace a UTF-8 text file. */\n write: {\n /** Path to write, resolved by the filesystem backend. */\n file_path: string;\n /** Full UTF-8 text content to write. */\n content: string;\n } & Record;\n}\n\ninterface ToolOutputMap {\n bash: {\n kind: \"background\";\n taskId: string;\n } | {\n kind: \"foreground\";\n exitCode: number | null;\n signal: string | null;\n timedOut: boolean;\n aborted: boolean;\n timeoutMs: number;\n stdout: {\n text: string;\n truncated: boolean;\n spillPath?: string;\n };\n stderr: {\n text: string;\n truncated: boolean;\n spillPath?: string;\n };\n sandbox?: {\n mode: string;\n denied: boolean;\n enforcement?: string;\n runnerFailed?: boolean;\n };\n };\n cordis_inspect: string;\n cordis_mount: {\n id: string;\n pluginName: string;\n state: \"pending\" | \"loading\" | \"active\" | \"failed\" | \"disposed\" | \"unloading\";\n provides: string[];\n waitingFor: string[];\n };\n cordis_unmount: {\n id: string;\n pluginName: string;\n };\n edit: {\n path: string;\n before: string;\n after: string;\n };\n interrupt_agent: {\n accepted: boolean;\n };\n ralph: {\n runId: string;\n agentsStarted: number;\n result: JsonValue;\n };\n read: {\n path: string;\n offset: number;\n lines: {\n number: number;\n text: string;\n }[];\n totalLines: number;\n };\n send_message: {\n messageId: string;\n };\n skill: {\n name: string;\n provider: string;\n resourceBase?: {\n kind: \"directory\";\n path: string;\n } | {\n kind: \"url\";\n url: string;\n } | {\n kind: \"opaque\";\n description: string;\n };\n content: string;\n };\n subagent: {\n kind: \"background\";\n taskId: string;\n } | {\n kind: \"continuable\";\n subagentId: string;\n } | {\n kind: \"foreground\";\n runId: string;\n output: JsonValue[];\n };\n subagent_fork: {\n kind: \"background\";\n taskId: string;\n } | {\n kind: \"continuable\";\n subagentId: string;\n } | {\n kind: \"foreground\";\n runId: string;\n output: JsonValue[];\n };\n task_kill: {\n outcome: \"cancellation-requested\" | \"already-finished\";\n task: {\n id: string;\n kind: string;\n label: string;\n status: \"running\" | \"stopping\" | \"completed\" | \"killed\" | \"failed\";\n detail?: string;\n startedAt: number;\n finishedAt?: number;\n };\n };\n task_list: ({\n id: string;\n kind: string;\n label: string;\n status: \"running\" | \"stopping\" | \"completed\" | \"killed\" | \"failed\";\n detail?: string;\n startedAt: number;\n finishedAt?: number;\n })[];\n task_output: {\n text: string;\n task: {\n id: string;\n kind: string;\n label: string;\n status: \"running\" | \"stopping\" | \"completed\" | \"killed\" | \"failed\";\n detail?: string;\n startedAt: number;\n finishedAt?: number;\n };\n };\n todo_write: {\n todos: ({\n content: string;\n status: \"pending\" | \"in_progress\" | \"completed\";\n })[];\n counts: {\n pending: number;\n inProgress: number;\n completed: number;\n };\n };\n workflow: {\n runId: string;\n agentsStarted: number;\n result: JsonValue;\n };\n write: {\n path: string;\n operation: \"create\" | \"update\";\n before: string | null;\n after: string;\n };\n}\n\ntype ToolName = keyof ToolOutputMap\n\ndeclare class ToolCallError extends Error {\n readonly name: \"ToolCallError\";\n readonly toolName: ToolName;\n}\n\ndeclare const tools: {\n [K in ToolName]: (args: ToolArgsMap[K]) => Promise;\n}\n```","tools":[{"name":"bash","description":"Execute a bash command (`bash -c`) and return its stdout/stderr. Each call runs in a fresh shell: no state (cwd, variables, functions) persists between calls — pass `workdir` instead of using `cd`. Non-zero exits are reported as `[exit code: N]`. Current harness environment facts are exposed through managed `$DSH_*` variables; inspect them when needed. Commands may run under a file sandbox; a blocked file operation is reported as `[sandbox: file access denied under mode]` — a policy denial, not a bug in the command; do not retry another way. Long output is truncated to its tail; the full output is saved to a file whose path is reported when available. Set `run_in_background: true` for long-running commands: the call returns a task id immediately; read its output with `task_output` and stop it with `task_kill`.","parameters":{"type":"object","properties":{"command":{"type":"string","description":"The bash command to execute."},"description":{"type":"string","description":"Clear, concise description of what this command does in active voice, 5-10 words (shown in the UI). Examples: \"ls\" → \"List files in current directory\"; \"git status\" → \"Show working tree status\"; \"npm install\" → \"Install package dependencies\"."},"timeoutMs":{"type":"number","description":"Timeout in milliseconds. The executor applies its configured default and cap, and kills the command on expiry."},"workdir":{"type":"string","description":"Working directory for this command. Defaults to the session workspace; a relative path is resolved against it."},"run_in_background":{"type":"boolean","description":"Run in the background and return a task id immediately (collect with task_output, stop with task_kill). No timeout applies."}},"required":["command","description"]}},{"name":"cordis_inspect","description":"Inspect the live Cordis runtime in the current DSH process. Read-only. Sections: `services` (every provided ctx service and the plugin fiber that owns it), `plugins` (all live plugin fibers with their lifecycle states), `tools` (the model-facing tools currently registered, i.e. what you can call), `temporary` (only temporary Plugins created by cordis_mount: id, name, state, provided services, awaited services, and lifetime), `api` (method signatures AND argument/return type shapes for every LIVE service — read this before writing plugin code that calls a service), `events` (every harness event with its dispatch mode and exact signature — pick listener targets here). Temporary Plugins exist only in memory, remain active across later turns, and disappear after cordis_unmount, toolset unload, or DSH restart; they are not restored automatically. The `temporary` section is a subset of `plugins`. Omit `what` to get all six sections. With `what:\"api\"` or `what:\"events\"`, pass an exact `name` to narrow to one service/event and include its original source JSDoc.","parameters":{"type":"object","properties":{"what":{"type":"string","description":"Limit the report to one section. Omit for all sections.","enum":["services","plugins","tools","temporary","api","events"]},"name":{"type":"string","description":"Exact service key or event name whose original JSDoc to include; valid only with what:\"api\" or what:\"events\"."}}}},{"name":"cordis_mount","description":"Mount a temporary Cordis Plugin in the current DSH process. This creates an in-memory runtime Plugin, not an installed or configured Plugin. It remains active across later turns until cordis_unmount, toolset unload, or DSH restart. It does not create files, install a package, change cordis.yml or personal/project config, survive restart, or automatically become permanent. To keep it, ask the Agent to implement a normal local, project, or repository Plugin through the regular development workflow. It may affect other sessions in the same process; the sandbox is not a security boundary, and injected services reach the real runtime. `code` runs now as the body of an async JavaScript function in an isolated sandbox and MUST `return` a plugin. Two forms: FUNCTION form `return (ctx) => { … }` — declares no inject, so it can register tools, listen to events, and provide services, but reaching ANY service (e.g. ctx.bash) throws; use it only when you need no services. OBJECT form `return { name?, inject: ['bash', 'llm', …], apply(ctx) { … } }` — declares dependencies, and cordis activates the plugin only after the services exist; PREFER this form. You may reach ONLY the services you list in inject: an undeclared service throws even if it exists, because an undeclared dependency would not be cleaned up if its provider is unmounted. BEFORE calling a service from your code, read cordis_inspect what:\"api\" — it lists method signatures AND the type shapes of their arguments/returns (do not guess a field's type; e.g. a bash run's stdout is an object, not a string). Inside `apply`, use the standard cordis API: `ctx.on(event, listener)` to observe events (see cordis_inspect what:\"events\"), or call `harness.registerTool(ctx, harness.defineTool({ name, description, parameters: { text: { type: 'string', required: true } }, output: { schema: { type: 'string' }, render(_args, value) { return [{ type: 'text', text: value }] } }, async execute(args) { return args.text } }))` to give yourself a new tool — it becomes callable on your NEXT step. Tool parameters: each key IS a property — { type: 'string'|'number'|'integer'|'boolean'|'null'|'object'|'array'|'json', required?: true, description?, enum?, const?, items?, properties? }; every direct DSL object declares additionalProperties: true|false, and oneOf: [schema, schema, ...] replaces type for an exact-one union. A raw JSON-Schema { type: 'object', properties, required?: […] } wrapper is also accepted with open-by-default objects. A tool's `execute` MUST return the lossless JSON value declared by `output.schema`; `output.render(args, value)` separately returns Native/model content blocks. Temporary Plugins can COMPOSE: one Plugin may `ctx.provide('name', value)` a service and another may declare `inject: ['name']` to consume it — the consumer stays pending until the provider exists and returns to pending when the provider is unmounted. Everything registered inside `apply` is cleaned up automatically by cordis_unmount. Sandbox globals: `console` (tagged `[cordis:]`, writes through to the harness terminal), `harness.defineTool`, `harness.registerTool`, `btoa`, `atob`, `TextEncoder`, `TextDecoder`. Node APIs are DISABLED — do filesystem/network/timer work through the cordis services, never Node built-ins: `require`, `setTimeout`/`setInterval`, and `fetch` throw redirect errors; `process` and `Buffer` are undefined. Instead use inject: ['fs'] + ctx.fs for files, inject: ['web'] + ctx.web for HTTP, inject: ['bash'] + ctx.bash for processes, and inject: ['timer'] + ctx.setTimeout/ctx.setInterval for timing (fiber effects, auto-cleaned when unmounted) — cordis_inspect what:\"api\" shows what THIS runtime provides. Write PLAIN JavaScript, not TypeScript (no `as`, no type annotations). Cautions: (1) waterfall events (e.g. tools/pre-execute) hand the listener a trailing `next` callback which MUST be called — returning without `next()` SHORT-CIRCUITS the call; prefer plain notification events unless you intend to intercept. (2) Never await something that only resolves after the current turn (your code runs INSIDE a tool call of that turn — it would deadlock). (3) Your `ctx` is a restricted façade: you can register tools, observe events, provide/consume services, and use timers, but framework internals (ctx.root, ctx.fiber, ctx.extend, ctx.plugin, …) are withheld. It is not a security boundary though — the services you inject (e.g. ctx.bash) reach the real runtime.","parameters":{"type":"object","properties":{"code":{"type":"string","description":"JavaScript body returning a temporary Plugin; evaluated now and saved nowhere."}},"required":["code"]}},{"name":"cordis_unmount","description":"Unmount a current-process temporary Plugin created by cordis_mount. Waits for its tools, listeners, services, timers, and other owned effects to clean up completely. Only dyn-N temporary ids are accepted; this cannot remove Loader, configured, or installed Plugins.","parameters":{"type":"object","properties":{"id":{"type":"string","description":"The temporary Plugin id returned by cordis_mount (for example \"dyn-1\"); valid only in this process and invalid after unmount or restart."}},"required":["id"]}},{"name":"edit","description":"Edit an existing UTF-8 text file by replacing literal text.","parameters":{"type":"object","properties":{"file_path":{"type":"string","description":"Path to edit, resolved by the filesystem backend."},"old_string":{"type":"string","description":"Literal text to replace. Must match exactly."},"new_string":{"type":"string","description":"Literal replacement text. Use an empty string to delete the match."},"replace_all":{"type":"boolean","description":"Replace all matches. Defaults to false; when false, old_string must appear exactly once."}},"required":["file_path","old_string","new_string"]}},{"name":"interrupt_agent","description":"Request cancellation of a background agent's current turn by its agent id. The target may be your direct child or a deeper agent created under you. Only the current turn stops: messages already queued for the agent stay parked until a later send_message, agents it started keep running, and the agent itself stays available for follow-ups. This call returns as soon as the stop request is accepted, so the target may keep running briefly; interrupting an agent that already finished is an accepted no-op.","parameters":{"type":"object","properties":{"agent_id":{"type":"string","description":"The agent id of the running agent to interrupt."}},"required":["agent_id"]}},{"name":"ralph","description":"Run a foreground fresh-agent Ralph loop toward one immutable objective. Use only when the direct human explicitly asks for Ralph or fresh-agent iteration. Each round opens a new child with no parent conversation or prior child session; the shared workspace is long-term memory, and only a bounded structured report crosses rounds. The call returns when a worker reports completion or a concrete blocker, or at the round limit. Ordinary long-running same-session work belongs to goal tools.","parameters":{"type":"object","properties":{"objective":{"type":"string","description":"The immutable completion objective for every fresh Ralph round."},"maxRounds":{"type":"number","description":"Optional positive safe-integer round cap, bounded by the deployment ceiling."}},"required":["objective"]}},{"name":"read","description":"Read a UTF-8 text file and return line-numbered content.","parameters":{"type":"object","properties":{"file_path":{"type":"string","description":"Path to read, resolved by the filesystem backend."},"offset":{"type":"number","description":"1-based first line to return. Defaults to 1."},"limit":{"type":"number","description":"Maximum number of lines to return. Defaults to 2000."}},"required":["file_path"]}},{"name":"run_code","description":"Execute a TypeScript program against the available tools. Write the BODY of an async function (erasable syntax only; top-level `await` and `return` work) and call tools as `await tools.name(args)` per the declarations in the system prompt. Only what you print or return comes back — curate it.","parameters":{"type":"object","properties":{"code":{"type":"string","description":"The program: the body of an async TypeScript function."},"description":{"type":"string","description":"Clear, concise description of what this program does in active voice, 5-10 words (shown in the UI). Examples: \"Count TODO markers across packages\"; \"Read failing test and its fixture\"; \"Rename config key in every cordis.yml\"."}},"required":["code","description"]}},{"name":"send_message","description":"Send a message to a background subagent by its subagent id, continuing the same conversation. It becomes the subagent's next turn: if it is still working, the message waits until its current turn finishes, so it cannot redirect work already underway. This call returns no answer from the subagent — only confirmation that the message was delivered — so use it to give it more work. A failure means the message was NOT delivered.","parameters":{"type":"object","properties":{"subagent_id":{"type":"string","description":"The subagent id returned when the background subagent was started."},"message":{"type":"string","description":"The message to deliver to the subagent."}},"required":["subagent_id","message"]}},{"name":"skill","description":"Load the full instructions for an available skill. Call this with the exact skill name from the session skill catalog before acting on a task that names or clearly matches that skill.","parameters":{"type":"object","properties":{"name":{"type":"string","description":"The exact skill name from the available skills list."}},"required":["name"]}},{"name":"subagent","description":"Delegate a self-contained task to a subagent (a separate agent that works in its own context) and return its final result. Use this to offload focused, independent work — research, a scoped implementation, an analysis — so it does not consume this conversation's context. The subagent runs to completion and you receive only its final answer, not its intermediate steps. Give it a complete, standalone prompt: it does not see this conversation. Set `run_in_background: true` to start a background subagent that keeps its conversation: you receive only its subagent id, never its result, and it works on its own. Use this for work whose result you do not need returned by this call; `send_message` sends it more work.","parameters":{"type":"object","properties":{"description":{"type":"string","description":"A short (3-5 word) description of the delegated task, for display."},"prompt":{"type":"string","description":"The complete, self-contained task for the subagent. It does not share this conversation's context, so include everything it needs."},"run_in_background":{"type":"boolean","description":"Run as a background subagent that keeps its conversation and return only its subagent id. This call never returns its result; send it more work with send_message."}},"required":["description","prompt"]}},{"name":"subagent_fork","description":"Delegate a task to a subagent that inherits this conversation: a child agent seeded with all completed turns so far (it does not see the current in-flight turn), returning only its final result. Use this when the subtask builds on this conversation's context — a follow-up analysis, a review, a continuation — without consuming this conversation's context for the work itself. You receive only its final answer, not its intermediate steps. Set `run_in_background: true` to start a background subagent that keeps its conversation: you receive only its subagent id, never its result, and it works on its own. Use this for work whose result you do not need returned by this call; `send_message` sends it more work.","parameters":{"type":"object","properties":{"description":{"type":"string","description":"A short (3-5 word) description of the delegated task, for display."},"prompt":{"type":"string","description":"The task for the subagent. It already sees this conversation's completed turns, so build on them freely and state only what is new."},"run_in_background":{"type":"boolean","description":"Run as a background subagent that keeps its conversation and return only its subagent id. This call never returns its result; send it more work with send_message."}},"required":["description","prompt"]}},{"name":"task_kill","description":"Request cancellation of a running background task by task id. Returns immediately; the task settles as killed once its work actually stops.","parameters":{"type":"object","properties":{"task_id":{"type":"string","description":"Task id returned by the tool that started the background work."},"reason":{"type":"string","description":"Optional short reason, recorded in the log and forwarded to the task."}},"required":["task_id"]}},{"name":"task_list","description":"List your background tasks (running and finished) with their ids, kinds, and statuses.","parameters":{"type":"object","properties":{}}},{"name":"task_output","description":"Read a background task. Stream tasks return only output since the previous read; final-output tasks return their result after settlement. Every response ends with `[status: ...]`. Reads are non-blocking unless `wait: true`, which waits up to the configured cap.","parameters":{"type":"object","properties":{"task_id":{"type":"string","description":"Task id returned by the tool that started the background work."},"wait":{"type":"boolean","description":"Block until the task reaches a terminal status or the timeout expires. A timed-out wait returns [status: running] and leaves the task alive."},"timeout_ms":{"type":"number","description":"Max wait in milliseconds (only meaningful with wait: true). Defaults to the configured wait timeout; capped by the configured maximum."}},"required":["task_id"]}},{"name":"todo_write","description":"Record and update a structured task list for the current work. Send the ENTIRE list every call — it REPLACES the previous list (there are no partial updates, no per-item edits). Use it to plan multi-step work and show progress: add one todo per concrete step before you start. Mark every todo being actively worked on `in_progress` — several at once when work genuinely runs in parallel (e.g. concurrent subagents or background commands), one for sequential work; while work remains, at least one task should be `in_progress`. Mark a todo `completed` the moment it is done (do not batch completions), and allow no `in_progress` item only once all work is complete. Skip the list for trivial single-step tasks. Statuses: `pending` (not started), `in_progress` (being worked on now), `completed` (finished).","parameters":{"type":"object","properties":{"todos":{"type":"array","description":"The COMPLETE task list, replacing any previous list.","items":{"type":"object","additionalProperties":false,"properties":{"content":{"type":"string","description":"What the task is — a short imperative line."},"status":{"type":"string","description":"pending (not started) | in_progress (now) | completed (done).","enum":["pending","in_progress","completed"]}},"required":["content","status"]}}},"required":["todos"]}},{"name":"workflow","description":"Run a JavaScript workflow script that orchestrates subagents at scale. Use this for work that fans out across many independent pieces — an audit over many files, a migration, multi-angle research, adversarial verification of findings — where you write the orchestration as a script instead of delegating turn by turn.\n\nThe workflow's identity rides the `meta` parameter as JSON: required `name` (short kebab-case) and `description` strings, optional `whenToUse` string and `phases` array (`{title, detail?, provider?, model?}`). The `script` parameter is the plain JavaScript body ONLY (NOT TypeScript, and NO `export const meta` statement — meta is a parameter, not code), running with top-level await; end with `return ` — the value must be JSON-serializable and is this tool's result.\n\nScript-body hooks:\n- `agent(prompt, opts?): Promise` — run one subagent to completion. Without `opts.schema` it resolves to the child's final text; with `opts.schema` (an object-rooted JSON Schema using ONLY type/properties/required/additionalProperties/items/enum/const/oneOf — no pattern/format/numeric bounds) it resolves to the validated object. Resolves `null` when the child fails (filter with `.filter(Boolean)`). Other opts: `label` (display), `phase` (progress group), and independent `provider`/`model` LLM target overrides (either may be provided alone). Anything else (`effort`/`isolation`/`agentType`) is rejected loudly.\n- `pipeline(items, ...stages): Promise` — run each item through the stages independently with NO barrier between stages (prefer this for multi-stage work). Each stage receives `(prev, item, index)`. An ordinary stage throw drops that ITEM to `null` and skips its remaining stages.\n- `parallel(thunks): Promise` — run zero-argument functions concurrently and await ALL of them (a barrier; use only when a stage genuinely needs every prior result together). A throwing thunk resolves to `null`.\n- `phase(title)` — start a progress phase; `log(message)` — narrate progress; `args` — the tool call's `args` input, verbatim.\n\nMisused hooks (bad arguments, unknown options, unsupported schemas, tripped caps) throw errors that ALWAYS kill the script — they never dissolve into a per-item `null`.\n\nConstraints: concurrency and total-agent caps apply; no filesystem, network, timers, or Node.js APIs are provided — the agents do the work, the script only coordinates them. The run executes in the foreground: this call returns when the whole script finishes.","parameters":{"type":"object","properties":{"script":{"type":"string","description":"The plain-JS workflow script body (top-level await allowed; NO `export const meta` statement; end with `return `)."},"meta":{"type":"object","description":"The workflow identity block (plain JSON — never code).","additionalProperties":true,"properties":{"name":{"type":"string","description":"Short kebab-case workflow name."},"description":{"type":"string","description":"One-line description of what the workflow does."},"whenToUse":{"type":"string","description":"Optional guidance on when this workflow applies."},"phases":{"type":"array","description":"Optional phase declarations matched by phase() calls.","items":{"type":"object","additionalProperties":true,"properties":{"title":{"type":"string","description":"The phase title phase() calls match by exact string."},"detail":{"type":"string","description":"Optional one-line description of the phase."},"provider":{"type":"string","description":"Optional provider override this phase is expected to use."},"model":{"type":"string","description":"Optional model override this phase is expected to use."}},"required":["title"]}}},"required":["name","description"]},"args":{"type":"object","description":"Optional JSON input exposed to the script as the `args` global (wrap a bare list as a field, e.g. {\"files\": [...]}).","additionalProperties":true}},"required":["script","meta"]}},{"name":"write","description":"Create or fully replace a UTF-8 text file.","parameters":{"type":"object","properties":{"file_path":{"type":"string","description":"Path to write, resolved by the filesystem backend."},"content":{"type":"string","description":"Full UTF-8 text content to write."}},"required":["file_path","content"]}}]},"reason":"initial"}} {"type":"request/context","seq":7,"time":1785730501403,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} {"type":"assistant/chunk","seq":8,"time":1783950000007,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}}} {"type":"assistant/chunk","seq":9,"time":1783950000008,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":0,"id":"advanced-mount","name":"cordis_mount","argumentsDelta":"{\"code\":\"return { name: 'snapshot-marker', apply() {} }\"}"}}} {"type":"assistant/chunk","seq":10,"time":1783950000009,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"advanced-mount","name":"cordis_mount","arguments":"{\"code\":\"return { name: 'snapshot-marker', apply() {} }\"}"}}}} {"type":"assistant/chunk","seq":11,"time":1785498583784,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}}} {"type":"assistant/chunk","seq":12,"time":1785730501404,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}} -{"type":"assistant/message","seq":13,"time":1785730501404,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"tool-call","id":"advanced-mount","name":"cordis_mount","arguments":"{\"code\":\"return { name: 'snapshot-marker', apply() {} }\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"e65c0ebe-8e3d-44c0-833f-68efcbc0acb5"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[8,9,10,11,12],"surfaceOp":"append"} +{"type":"assistant/message","seq":13,"time":1785730501404,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"tool-call","id":"advanced-mount","name":"cordis_mount","arguments":"{\"code\":\"return { name: 'snapshot-marker', apply() {} }\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"b596133f-aafe-4485-9871-ade1dda23373"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[8,9,10,11,12],"surfaceOp":"append"} {"type":"tool/call","seq":14,"time":1785730501404,"data":{"turn":1,"step":1,"callId":"advanced-mount","name":"cordis_mount","arguments":"{\"code\":\"return { name: 'snapshot-marker', apply() {} }\"}"}} -{"type":"tool/result","seq":15,"time":1785730501413,"data":{"turn":1,"step":1,"message":{"source":{"kind":"tool","callId":"advanced-mount"},"content":[{"type":"tool-result","toolCallId":"advanced-mount","content":[{"type":"text","text":"Temporary Plugin dyn-1 is running (plugin \"snapshot-marker\"; available until unmounted or DSH restarts)."}],"isError":false}],"role":"user","id":"abb8ecee-cb03-4a66-9477-38a52458ab05"}},"sourceEventSeqs":[14],"surfaceOp":"append"} +{"type":"tool/result","seq":15,"time":1785730501413,"data":{"turn":1,"step":1,"message":{"source":{"kind":"tool","callId":"advanced-mount"},"content":[{"type":"tool-result","toolCallId":"advanced-mount","content":[{"type":"text","text":"Temporary Plugin dyn-1 is running (plugin \"snapshot-marker\"; available until unmounted or DSH restarts)."}],"isError":false}],"role":"user","id":"99819f4a-5e53-4a6f-92f6-5be96b765bce"}},"sourceEventSeqs":[14],"surfaceOp":"append"} {"type":"step/end","seq":16,"time":1785730501413,"data":{"turn":1,"step":1}} {"type":"step/start","seq":17,"time":1785730501423,"data":{"turn":1,"step":2}} {"type":"assistant/chunk","seq":18,"time":1783950000017,"data":{"turn":1,"step":2,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}}} @@ -22,11 +22,11 @@ {"type":"assistant/chunk","seq":20,"time":1783950000019,"data":{"turn":1,"step":2,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"advanced-code","name":"run_code","arguments":"{\"code\": \"return await tools.cordis_inspect({ what: 'temporary' })\", \"description\": \"Run the scripted inspection program\"}"}}}} {"type":"assistant/chunk","seq":21,"time":1785498583804,"data":{"turn":1,"step":2,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}}} {"type":"assistant/chunk","seq":22,"time":1785730501424,"data":{"turn":1,"step":2,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}} -{"type":"assistant/message","seq":23,"time":1785730501424,"data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"tool-call","id":"advanced-code","name":"run_code","arguments":"{\"code\": \"return await tools.cordis_inspect({ what: 'temporary' })\", \"description\": \"Run the scripted inspection program\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"cdc95327-3ce1-49ea-8a92-b17e450cc455"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[18,19,20,21,22],"surfaceOp":"append"} +{"type":"assistant/message","seq":23,"time":1785730501424,"data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"tool-call","id":"advanced-code","name":"run_code","arguments":"{\"code\": \"return await tools.cordis_inspect({ what: 'temporary' })\", \"description\": \"Run the scripted inspection program\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"6697e967-e6bd-46b2-8574-18aeb914e7c6"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[18,19,20,21,22],"surfaceOp":"append"} {"type":"tool/call","seq":24,"time":1785730501424,"data":{"turn":1,"step":2,"callId":"advanced-code","name":"run_code","arguments":"{\"code\": \"return await tools.cordis_inspect({ what: 'temporary' })\", \"description\": \"Run the scripted inspection program\"}"}} {"type":"tool/code-dispatch-start","seq":25,"time":1785730501473,"data":{"rootCallId":"advanced-code","parentCallId":"advanced-code","subCallId":"advanced-code:code:1","name":"cordis_inspect","arguments":{"what":"temporary"}}} {"type":"tool/code-dispatch","seq":26,"time":1785730501474,"data":{"rootCallId":"advanced-code","parentCallId":"advanced-code","subCallId":"advanced-code:code:1","name":"cordis_inspect","arguments":{"what":"temporary"},"isError":false,"content":[{"type":"text","text":"## Temporary Plugins\n- Temporary Plugin dyn-1: snapshot-marker [running] — provides: none; waiting for: none; lifetime: until unmounted or DSH restarts"}]}} -{"type":"tool/result","seq":27,"time":1785730501475,"data":{"turn":1,"step":2,"message":{"source":{"kind":"tool","callId":"advanced-code"},"content":[{"type":"tool-result","toolCallId":"advanced-code","content":[{"type":"text","text":"## Temporary Plugins\n- Temporary Plugin dyn-1: snapshot-marker [running] — provides: none; waiting for: none; lifetime: until unmounted or DSH restarts"}],"isError":false}],"role":"user","id":"d75c7d03-cbbc-4260-ba40-8c210a3b5bbe"}},"sourceEventSeqs":[24],"surfaceOp":"append"} +{"type":"tool/result","seq":27,"time":1785730501475,"data":{"turn":1,"step":2,"message":{"source":{"kind":"tool","callId":"advanced-code"},"content":[{"type":"tool-result","toolCallId":"advanced-code","content":[{"type":"text","text":"## Temporary Plugins\n- Temporary Plugin dyn-1: snapshot-marker [running] — provides: none; waiting for: none; lifetime: until unmounted or DSH restarts"}],"isError":false}],"role":"user","id":"831070a8-3dc0-4275-9f11-0476b47b8ef2"}},"sourceEventSeqs":[24],"surfaceOp":"append"} {"type":"step/end","seq":28,"time":1785730501475,"data":{"turn":1,"step":2}} {"type":"step/start","seq":29,"time":1785730501483,"data":{"turn":1,"step":3}} {"type":"assistant/chunk","seq":30,"time":1783950000029,"data":{"turn":1,"step":3,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}}} @@ -34,9 +34,9 @@ {"type":"assistant/chunk","seq":32,"time":1785037378923,"data":{"turn":1,"step":3,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"advanced-direct-child","name":"subagent","arguments":"{\"description\":\"Check direct child\",\"prompt\":\"Reply with exactly DIRECT_CHILD_OK and nothing else.\"}"}}}} {"type":"assistant/chunk","seq":33,"time":1785498583869,"data":{"turn":1,"step":3,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}}} {"type":"assistant/chunk","seq":34,"time":1785730501484,"data":{"turn":1,"step":3,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}} -{"type":"assistant/message","seq":35,"time":1785730501484,"data":{"turn":1,"step":3,"message":{"role":"assistant","content":[{"type":"tool-call","id":"advanced-direct-child","name":"subagent","arguments":"{\"description\":\"Check direct child\",\"prompt\":\"Reply with exactly DIRECT_CHILD_OK and nothing else.\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"ba4958e9-231c-437f-a2fc-7a13f392d3ba"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[30,31,32,33,34],"surfaceOp":"append"} +{"type":"assistant/message","seq":35,"time":1785730501484,"data":{"turn":1,"step":3,"message":{"role":"assistant","content":[{"type":"tool-call","id":"advanced-direct-child","name":"subagent","arguments":"{\"description\":\"Check direct child\",\"prompt\":\"Reply with exactly DIRECT_CHILD_OK and nothing else.\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"cef24cf0-5f9e-4be2-93d8-93a0d89c6e82"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[30,31,32,33,34],"surfaceOp":"append"} {"type":"tool/call","seq":36,"time":1785730501484,"data":{"turn":1,"step":3,"callId":"advanced-direct-child","name":"subagent","arguments":"{\"description\":\"Check direct child\",\"prompt\":\"Reply with exactly DIRECT_CHILD_OK and nothing else.\"}"}} -{"type":"tool/result","seq":37,"time":1785730501508,"data":{"turn":1,"step":3,"message":{"source":{"kind":"tool","callId":"advanced-direct-child"},"content":[{"type":"tool-result","toolCallId":"advanced-direct-child","content":[{"type":"text","text":"DIRECT_CHILD_OK"}],"isError":false}],"role":"user","id":"b9ebb37d-e565-4882-95b0-5343da1d68d8"}},"sourceEventSeqs":[36],"surfaceOp":"append"} +{"type":"tool/result","seq":37,"time":1785730501508,"data":{"turn":1,"step":3,"message":{"source":{"kind":"tool","callId":"advanced-direct-child"},"content":[{"type":"tool-result","toolCallId":"advanced-direct-child","content":[{"type":"text","text":"DIRECT_CHILD_OK"}],"isError":false}],"role":"user","id":"d7ea395e-840a-46c4-a143-b6e15cf74114"}},"sourceEventSeqs":[36],"surfaceOp":"append"} {"type":"step/end","seq":38,"time":1785730501508,"data":{"turn":1,"step":3}} {"type":"step/start","seq":39,"time":1785730501521,"data":{"turn":1,"step":4}} {"type":"assistant/chunk","seq":40,"time":1783957884594,"data":{"turn":1,"step":4,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}}} @@ -44,9 +44,9 @@ {"type":"assistant/chunk","seq":42,"time":1785037378946,"data":{"turn":1,"step":4,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"advanced-workflow","name":"workflow","arguments":"{\"script\":\"phase('Delegate')\\nconst reply = await agent('Reply with exactly WORKFLOW_CHILD_OK and nothing else.', { label: 'workflow-child' })\\nreturn { reply }\",\"meta\":{\"name\":\"advanced-headless-snapshot\",\"description\":\"exercise one workflow child through the headless agent\"}}"}}}} {"type":"assistant/chunk","seq":43,"time":1785498583919,"data":{"turn":1,"step":4,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}}} {"type":"assistant/chunk","seq":44,"time":1785730501522,"data":{"turn":1,"step":4,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}} -{"type":"assistant/message","seq":45,"time":1785730501522,"data":{"turn":1,"step":4,"message":{"role":"assistant","content":[{"type":"tool-call","id":"advanced-workflow","name":"workflow","arguments":"{\"script\":\"phase('Delegate')\\nconst reply = await agent('Reply with exactly WORKFLOW_CHILD_OK and nothing else.', { label: 'workflow-child' })\\nreturn { reply }\",\"meta\":{\"name\":\"advanced-headless-snapshot\",\"description\":\"exercise one workflow child through the headless agent\"}}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"4757f4b9-9bde-488b-a54a-1bdea55dd15f"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[40,41,42,43,44],"surfaceOp":"append"} +{"type":"assistant/message","seq":45,"time":1785730501522,"data":{"turn":1,"step":4,"message":{"role":"assistant","content":[{"type":"tool-call","id":"advanced-workflow","name":"workflow","arguments":"{\"script\":\"phase('Delegate')\\nconst reply = await agent('Reply with exactly WORKFLOW_CHILD_OK and nothing else.', { label: 'workflow-child' })\\nreturn { reply }\",\"meta\":{\"name\":\"advanced-headless-snapshot\",\"description\":\"exercise one workflow child through the headless agent\"}}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"242be4fa-3293-45de-ab55-a017999f2333"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[40,41,42,43,44],"surfaceOp":"append"} {"type":"tool/call","seq":46,"time":1785730501522,"data":{"turn":1,"step":4,"callId":"advanced-workflow","name":"workflow","arguments":"{\"script\":\"phase('Delegate')\\nconst reply = await agent('Reply with exactly WORKFLOW_CHILD_OK and nothing else.', { label: 'workflow-child' })\\nreturn { reply }\",\"meta\":{\"name\":\"advanced-headless-snapshot\",\"description\":\"exercise one workflow child through the headless agent\"}}"}} -{"type":"tool/result","seq":47,"time":1785730501647,"data":{"turn":1,"step":4,"message":{"source":{"kind":"tool","callId":"advanced-workflow"},"content":[{"type":"tool-result","toolCallId":"advanced-workflow","content":[{"type":"text","text":"workflow \"advanced-headless-snapshot\" completed (1 agent).\nReturn value:\n{\n \"reply\": \"WORKFLOW_CHILD_OK\"\n}"}],"isError":false}],"role":"user","id":"35baa460-54ff-4fa1-ba9d-66b6661f84e9"}},"sourceEventSeqs":[46],"surfaceOp":"append"} +{"type":"tool/result","seq":47,"time":1785730501647,"data":{"turn":1,"step":4,"message":{"source":{"kind":"tool","callId":"advanced-workflow"},"content":[{"type":"tool-result","toolCallId":"advanced-workflow","content":[{"type":"text","text":"workflow \"advanced-headless-snapshot\" completed (1 agent).\nReturn value:\n{\n \"reply\": \"WORKFLOW_CHILD_OK\"\n}"}],"isError":false}],"role":"user","id":"ee764f11-8827-4984-acef-ec3c5880f5a0"}},"sourceEventSeqs":[46],"surfaceOp":"append"} {"type":"step/end","seq":48,"time":1785730501648,"data":{"turn":1,"step":4}} {"type":"step/start","seq":49,"time":1785730501660,"data":{"turn":1,"step":5}} {"type":"assistant/chunk","seq":50,"time":1783957884719,"data":{"turn":1,"step":5,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}}} @@ -54,9 +54,9 @@ {"type":"assistant/chunk","seq":52,"time":1785037379534,"data":{"turn":1,"step":5,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"advanced-unmount","name":"cordis_unmount","arguments":"{\"id\":\"dyn-1\"}"}}}} {"type":"assistant/chunk","seq":53,"time":1785498584085,"data":{"turn":1,"step":5,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}}} {"type":"assistant/chunk","seq":54,"time":1785730501661,"data":{"turn":1,"step":5,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}} -{"type":"assistant/message","seq":55,"time":1785730501661,"data":{"turn":1,"step":5,"message":{"role":"assistant","content":[{"type":"tool-call","id":"advanced-unmount","name":"cordis_unmount","arguments":"{\"id\":\"dyn-1\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"739166e2-ed48-4df2-a9a5-207f34058030"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[50,51,52,53,54],"surfaceOp":"append"} +{"type":"assistant/message","seq":55,"time":1785730501661,"data":{"turn":1,"step":5,"message":{"role":"assistant","content":[{"type":"tool-call","id":"advanced-unmount","name":"cordis_unmount","arguments":"{\"id\":\"dyn-1\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"6c3dab82-c2ed-492a-ab0d-f235b340a6c1"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[50,51,52,53,54],"surfaceOp":"append"} {"type":"tool/call","seq":56,"time":1785730501661,"data":{"turn":1,"step":5,"callId":"advanced-unmount","name":"cordis_unmount","arguments":"{\"id\":\"dyn-1\"}"}} -{"type":"tool/result","seq":57,"time":1785730501668,"data":{"turn":1,"step":5,"message":{"source":{"kind":"tool","callId":"advanced-unmount"},"content":[{"type":"tool-result","toolCallId":"advanced-unmount","content":[{"type":"text","text":"Temporary Plugin dyn-1 was unmounted and removed."}],"isError":false}],"role":"user","id":"98b05c06-cb77-41a9-8310-324bc72fc7a0"}},"sourceEventSeqs":[56],"surfaceOp":"append"} +{"type":"tool/result","seq":57,"time":1785730501668,"data":{"turn":1,"step":5,"message":{"source":{"kind":"tool","callId":"advanced-unmount"},"content":[{"type":"tool-result","toolCallId":"advanced-unmount","content":[{"type":"text","text":"Temporary Plugin dyn-1 was unmounted and removed."}],"isError":false}],"role":"user","id":"74554b42-640e-4119-a413-ee5ac01e546e"}},"sourceEventSeqs":[56],"surfaceOp":"append"} {"type":"step/end","seq":58,"time":1785730501668,"data":{"turn":1,"step":5}} {"type":"step/start","seq":59,"time":1785730501678,"data":{"turn":1,"step":6}} {"type":"assistant/chunk","seq":60,"time":1783957884720,"data":{"turn":1,"step":6,"chunk":{"type":"block-start","index":0,"blockType":"text"}}} @@ -64,6 +64,6 @@ {"type":"assistant/chunk","seq":62,"time":1785037379541,"data":{"turn":1,"step":6,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"ADVANCED_HEADLESS_OK"}}}} {"type":"assistant/chunk","seq":63,"time":1785498584102,"data":{"turn":1,"step":6,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}}} {"type":"assistant/chunk","seq":64,"time":1785730501679,"data":{"turn":1,"step":6,"chunk":{"type":"finish","reason":{"kind":"stop"}}}} -{"type":"assistant/message","seq":65,"time":1785730501679,"data":{"turn":1,"step":6,"message":{"role":"assistant","content":[{"type":"text","text":"ADVANCED_HEADLESS_OK"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"0a4ca8f2-92c1-4dbc-beb8-923b8791c298"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[60,61,62,63,64],"surfaceOp":"append"} +{"type":"assistant/message","seq":65,"time":1785730501679,"data":{"turn":1,"step":6,"message":{"role":"assistant","content":[{"type":"text","text":"ADVANCED_HEADLESS_OK"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"1a3bef32-0610-4891-9071-6bdc2e8a8fd2"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[60,61,62,63,64],"surfaceOp":"append"} {"type":"step/end","seq":66,"time":1785730501679,"data":{"turn":1,"step":6}} {"type":"turn/end","seq":67,"time":1785730501679,"data":{"turn":1,"reason":{"kind":"completed"}}} diff --git a/examples/headless-agent/tests/subagent-inheritance-snapshots/parent-override/child.expected.jsonl b/examples/headless-agent/tests/subagent-inheritance-snapshots/parent-override/child.expected.jsonl index dbcd59cc5a..1711b58c84 100644 --- a/examples/headless-agent/tests/subagent-inheritance-snapshots/parent-override/child.expected.jsonl +++ b/examples/headless-agent/tests/subagent-inheritance-snapshots/parent-override/child.expected.jsonl @@ -6,7 +6,7 @@ {"type":"subagent/descriptor","seq":4,"time":0,"data":{"version":2,"mode":"one-shot","provider":"spawn","label":"Delegated write probe"}} {"type":"step/start","seq":5,"time":0,"data":{"turn":1,"step":1}} {"type":"user/message","seq":6,"time":0,"data":{"content":[{"type":"text","text":"Use the write tool exactly once with file_path set to exactly the relative path inherited.txt and content escaped. If the write is denied, reply with the single word CHILD_DENIED and the denial marker line; do not retry and do not request escalation. If it succeeds, reply CHILD_WROTE."}],"source":{"kind":"user"},"role":"user","id":"{{sessionId}}"},"surfaceOp":"append"} -{"type":"user/message","seq":7,"time":0,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: read-only. Any available operation enforced by the DSH file sandbox cannot modify files in the standing mode. Do not refuse a required modification from this policy alone: try an available tool normally and follow any denial and escalation guidance it returns."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: read-only. Any available operation enforced by the DSH file sandbox cannot modify files in the standing mode. Do not refuse a required modification from this policy alone: try an available tool normally and follow any denial and escalation guidance it returns."}]},"role":"user","id":"{{sessionId}}"},"surfaceOp":"append"} +{"type":"user/message","seq":7,"time":0,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: read-only. Any available operation enforced by the DSH file sandbox cannot modify files in the standing mode. Do not refuse a required modification from this policy alone: try an available tool normally and follow any denial and escalation guidance it returns.\n\nYou are a delegated subagent: your permission scope was fixed when you were started and cannot be widened from inside this session — operations that require approval are rejected automatically. When the task needs access beyond that scope, do not retry the denied operation; state the limitation in your reply so the delegating agent can handle it."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: read-only. Any available operation enforced by the DSH file sandbox cannot modify files in the standing mode. Do not refuse a required modification from this policy alone: try an available tool normally and follow any denial and escalation guidance it returns."},{"name":"subagent:delegation","text":"You are a delegated subagent: your permission scope was fixed when you were started and cannot be widened from inside this session — operations that require approval are rejected automatically. When the task needs access beyond that scope, do not retry the denied operation; state the limitation in your reply so the delegating agent can handle it."}]},"role":"user","id":"{{sessionId}}"},"surfaceOp":"append"} {"type":"session/title","seq":8,"time":0,"data":{"title":"Use the write tool exactly","messageSeqs":[6],"source":{"kind":"fallback"}}} {"type":"request/header","seq":9,"time":0,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}} {"type":"request/context","seq":10,"time":0,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} diff --git a/examples/jsonrpc-agent/tests/snapshots/subagent-spawn/notifications.expected.jsonl b/examples/jsonrpc-agent/tests/snapshots/subagent-spawn/notifications.expected.jsonl index 434027310a..fc0a24eb66 100644 --- a/examples/jsonrpc-agent/tests/snapshots/subagent-spawn/notifications.expected.jsonl +++ b/examples/jsonrpc-agent/tests/snapshots/subagent-spawn/notifications.expected.jsonl @@ -106,37 +106,38 @@ {"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"subagent/descriptor","seq":3,"time":0,"data":{"version":2,"mode":"one-shot","provider":"spawn","label":"echo probe"}}}} {"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"step/start","seq":4,"time":0,"data":{"turn":1,"step":1}}}} {"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"user/message","seq":5,"time":0,"data":{"content":[{"type":"text","text":"Reply with exactly: child answer 42."}],"source":{"kind":"user"},"role":"user","id":"{{sessionId}}"},"surfaceOp":"append"}}} -{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"session/title","seq":6,"time":0,"data":{"title":"Reply with exactly: child answer","messageSeqs":[5],"source":{"kind":"fallback"}}}}} -{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"request/header","seq":7,"time":0,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}}}} -{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"request/context","seq":8,"time":0,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}}}} -{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":9,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}}}}} -{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":10,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":"The"}}}}} -{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":11,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" user"}}}}} -{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":12,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" wants"}}}}} -{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":13,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" me"}}}}} -{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":14,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" to"}}}}} -{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":15,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" reply"}}}}} -{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":16,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" with"}}}}} -{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":17,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" exactly"}}}}} -{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":18,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" \""}}}}} -{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":19,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":"child"}}}}} -{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":20,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" answer"}}}}} -{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":21,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" "}}}}} -{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":22,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":"42"}}}}} -{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":23,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":".\""}}}}} -{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":24,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":1,"blockType":"text"}}}}} -{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":25,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"text-delta","index":1,"text":"child"}}}}} -{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":26,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"text-delta","index":1,"text":" answer"}}}}} -{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":27,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"text-delta","index":1,"text":" "}}}}} -{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":28,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"text-delta","index":1,"text":"42"}}}}} -{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":29,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"text-delta","index":1,"text":"."}}}}} -{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":30,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The user wants me to reply with exactly \"child answer 42.\""}}}}}} -{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":31,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":1,"block":{"type":"text","text":"child answer 42."}}}}}} -{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":32,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":107,"outputTokens":20,"cacheReadTokens":1664,"reasoningTokens":14}}}}}} -{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":33,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"stop"}}}}}} -{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/message","seq":34,"time":0,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"reasoning","text":"The user wants me to reply with exactly \"child answer 42.\""},{"type":"text","text":"child answer 42."}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{sessionId}}"},"usage":{"inputTokens":107,"outputTokens":20,"cacheReadTokens":1664,"reasoningTokens":14}},"sourceEventSeqs":[9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33],"surfaceOp":"append"}}} -{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"step/end","seq":35,"time":0,"data":{"turn":1,"step":1}}}} -{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"turn/end","seq":36,"time":0,"data":{"turn":1,"reason":{"kind":"completed"}}}}} +{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"user/message","seq":6,"time":0,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nYou are a delegated subagent: your permission scope was fixed when you were started and cannot be widened from inside this session — operations that require approval are rejected automatically. When the task needs access beyond that scope, do not retry the denied operation; state the limitation in your reply so the delegating agent can handle it."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"subagent:delegation","text":"You are a delegated subagent: your permission scope was fixed when you were started and cannot be widened from inside this session — operations that require approval are rejected automatically. When the task needs access beyond that scope, do not retry the denied operation; state the limitation in your reply so the delegating agent can handle it."}]},"role":"user","id":"{{sessionId}}"},"surfaceOp":"append"}}} +{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"session/title","seq":7,"time":0,"data":{"title":"Reply with exactly: child answer","messageSeqs":[5],"source":{"kind":"fallback"}}}}} +{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"request/header","seq":8,"time":0,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}}}} +{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"request/context","seq":9,"time":0,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}}}} +{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":10,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}}}}} +{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":11,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":"The"}}}}} +{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":12,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" user"}}}}} +{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":13,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" wants"}}}}} +{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":14,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" me"}}}}} +{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":15,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" to"}}}}} +{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":16,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" reply"}}}}} +{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":17,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" with"}}}}} +{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":18,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" exactly"}}}}} +{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":19,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" \""}}}}} +{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":20,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":"child"}}}}} +{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":21,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" answer"}}}}} +{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":22,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" "}}}}} +{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":23,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":"42"}}}}} +{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":24,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":".\""}}}}} +{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":25,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":1,"blockType":"text"}}}}} +{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":26,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"text-delta","index":1,"text":"child"}}}}} +{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":27,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"text-delta","index":1,"text":" answer"}}}}} +{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":28,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"text-delta","index":1,"text":" "}}}}} +{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":29,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"text-delta","index":1,"text":"42"}}}}} +{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":30,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"text-delta","index":1,"text":"."}}}}} +{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":31,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The user wants me to reply with exactly \"child answer 42.\""}}}}}} +{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":32,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":1,"block":{"type":"text","text":"child answer 42."}}}}}} +{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":33,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":107,"outputTokens":20,"cacheReadTokens":1664,"reasoningTokens":14}}}}}} +{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":34,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"stop"}}}}}} +{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/message","seq":35,"time":0,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"reasoning","text":"The user wants me to reply with exactly \"child answer 42.\""},{"type":"text","text":"child answer 42."}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{sessionId}}"},"usage":{"inputTokens":107,"outputTokens":20,"cacheReadTokens":1664,"reasoningTokens":14}},"sourceEventSeqs":[10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],"surfaceOp":"append"}}} +{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"step/end","seq":36,"time":0,"data":{"turn":1,"step":1}}}} +{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"turn/end","seq":37,"time":0,"data":{"turn":1,"reason":{"kind":"completed"}}}}} {"method":"session.status","params":{"sessionId":"{{sessionId}}","status":"idle"}} {"method":"subagent.finished","params":{"provider":"spawn","agentId":"{{sessionId}}","parentSessionId":"{{sessionId}}","childSessionId":"{{sessionId}}","status":"ok","stopReason":"completed","lastAssistantMessage":[{"type":"reasoning","text":"The user wants me to reply with exactly \"child answer 42.\""},{"type":"text","text":"child answer 42."}]}} {"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"tool/result","seq":99,"time":0,"data":{"turn":1,"step":1,"message":{"source":{"kind":"tool","callId":"call_00_oHPNQ1nLoakoaAGXIxCM7404"},"content":[{"type":"tool-result","toolCallId":"call_00_oHPNQ1nLoakoaAGXIxCM7404","content":[{"type":"text","text":"child answer 42."}],"isError":false}],"role":"user","id":"{{sessionId}}"}},"sourceEventSeqs":[98],"surfaceOp":"append"}}} diff --git a/examples/jsonrpc-agent/tests/snapshots/subagent-spawn/session.1.jsonl b/examples/jsonrpc-agent/tests/snapshots/subagent-spawn/session.1.jsonl index 9c45784001..0e7855cd86 100644 --- a/examples/jsonrpc-agent/tests/snapshots/subagent-spawn/session.1.jsonl +++ b/examples/jsonrpc-agent/tests/snapshots/subagent-spawn/session.1.jsonl @@ -5,17 +5,18 @@ {"type":"subagent/descriptor","seq":3,"time":1785821461003,"data":{"version":2,"mode":"one-shot","provider":"spawn","label":"echo probe"}} {"type":"step/start","seq":4,"time":1785730507335,"data":{"turn":1,"step":1}} {"type":"user/message","seq":5,"time":1785730507335,"data":{"content":[{"type":"text","text":"Reply with exactly: child answer 42."}],"source":{"kind":"user"},"role":"user","id":"7ae1698c-db1d-4fca-8404-3a9dece9c1d0"},"surfaceOp":"append"} -{"type":"session/title","seq":6,"time":1785730507335,"data":{"title":"Reply with exactly: child answer","messageSeqs":[5],"source":{"kind":"fallback"}}} -{"type":"request/header","seq":7,"time":1785498591175,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}} -{"type":"request/context","seq":8,"time":1785730507336,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} -{"type":"assistant/chunk","seq":9,"time":1785097410985,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}}} -{"type":"reasoning-chunks","seq0":10,"time0":1785097411011,"data":{"turn":1,"step":1,"index":0,"dt":[0,0,24,1,0,0,0,25,0,1,0,51,0],"texts":["The"," user"," wants"," me"," to"," reply"," with"," exactly"," \"","child"," answer"," ","42",".\""]}} -{"type":"assistant/chunk","seq":24,"time":1785097411114,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":1,"blockType":"text"}}} -{"type":"text-chunks","seq0":25,"time0":1785097411114,"data":{"turn":1,"step":1,"index":1,"dt":[0,0,24,0],"texts":["child"," answer"," ","42","."]}} -{"type":"assistant/chunk","seq":30,"time":1785097411138,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The user wants me to reply with exactly \"child answer 42.\""}}}} -{"type":"assistant/chunk","seq":31,"time":1785097411138,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":1,"block":{"type":"text","text":"child answer 42."}}}} -{"type":"assistant/chunk","seq":32,"time":1785498591184,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":107,"outputTokens":20,"cacheReadTokens":1664,"reasoningTokens":14}}}} -{"type":"assistant/chunk","seq":33,"time":1785730507343,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"stop"}}}} -{"type":"assistant/message","seq":34,"time":1785730507344,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"reasoning","text":"The user wants me to reply with exactly \"child answer 42.\""},{"type":"text","text":"child answer 42."}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"3d9970cd-d000-4fd5-8712-a88c301ddb19"},"usage":{"inputTokens":107,"outputTokens":20,"cacheReadTokens":1664,"reasoningTokens":14}},"sourceEventSeqs":[9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33],"surfaceOp":"append"} -{"type":"step/end","seq":35,"time":1785730507344,"data":{"turn":1,"step":1}} -{"type":"turn/end","seq":36,"time":1785730507344,"data":{"turn":1,"reason":{"kind":"completed"}}} +{"type":"user/message","seq":6,"time":1786358111405,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nYou are a delegated subagent: your permission scope was fixed when you were started and cannot be widened from inside this session — operations that require approval are rejected automatically. When the task needs access beyond that scope, do not retry the denied operation; state the limitation in your reply so the delegating agent can handle it."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"subagent:delegation","text":"You are a delegated subagent: your permission scope was fixed when you were started and cannot be widened from inside this session — operations that require approval are rejected automatically. When the task needs access beyond that scope, do not retry the denied operation; state the limitation in your reply so the delegating agent can handle it."}]},"role":"user","id":"17bd0771-d228-4805-a797-7be9c0b59d20"},"surfaceOp":"append"} +{"type":"session/title","seq":7,"time":1786358111405,"data":{"title":"Reply with exactly: child answer","messageSeqs":[5],"source":{"kind":"fallback"}}} +{"type":"request/header","seq":8,"time":1785498591175,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}} +{"type":"request/context","seq":9,"time":1785730507336,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} +{"type":"assistant/chunk","seq":10,"time":1785097410985,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}}} +{"type":"reasoning-chunks","seq0":11,"time0":1785097411011,"data":{"turn":1,"step":1,"index":0,"dt":[0,0,24,1,0,0,0,25,0,1,0,51,0],"texts":["The"," user"," wants"," me"," to"," reply"," with"," exactly"," \"","child"," answer"," ","42",".\""]}} +{"type":"assistant/chunk","seq":25,"time":1785097411114,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":1,"blockType":"text"}}} +{"type":"text-chunks","seq0":26,"time0":1785097411114,"data":{"turn":1,"step":1,"index":1,"dt":[0,0,24,0],"texts":["child"," answer"," ","42","."]}} +{"type":"assistant/chunk","seq":31,"time":1785097411138,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The user wants me to reply with exactly \"child answer 42.\""}}}} +{"type":"assistant/chunk","seq":32,"time":1785097411138,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":1,"block":{"type":"text","text":"child answer 42."}}}} +{"type":"assistant/chunk","seq":33,"time":1785498591184,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":107,"outputTokens":20,"cacheReadTokens":1664,"reasoningTokens":14}}}} +{"type":"assistant/chunk","seq":34,"time":1785730507343,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"stop"}}}} +{"type":"assistant/message","seq":35,"time":1785730507344,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"reasoning","text":"The user wants me to reply with exactly \"child answer 42.\""},{"type":"text","text":"child answer 42."}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"3d9970cd-d000-4fd5-8712-a88c301ddb19"},"usage":{"inputTokens":107,"outputTokens":20,"cacheReadTokens":1664,"reasoningTokens":14}},"sourceEventSeqs":[10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],"surfaceOp":"append"} +{"type":"step/end","seq":36,"time":1785730507344,"data":{"turn":1,"step":1}} +{"type":"turn/end","seq":37,"time":1785730507344,"data":{"turn":1,"reason":{"kind":"completed"}}} diff --git a/packages/subagent/subagent-inprocess/README.i18n.yaml b/packages/subagent/subagent-inprocess/README.i18n.yaml index 7598b6dc3e..78106c0d6d 100644 --- a/packages/subagent/subagent-inprocess/README.i18n.yaml +++ b/packages/subagent/subagent-inprocess/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/subagent/subagent-inprocess/README.md -README.md: 4189979806ccd4e7dcfee231ab3e9e2331550b0d -README.zh.md: c6a9005cbfdb9d40a54383f921671fa22a31dc32 +README.md: 209f1e9526ff4a01af6f4c96955068de4b2b06c0 +README.zh.md: 8623be4bc1ab39aa7718de204dd0507843b0ab14 diff --git a/packages/subagent/subagent-inprocess/README.md b/packages/subagent/subagent-inprocess/README.md index 4189979806..209f1e9526 100644 --- a/packages/subagent/subagent-inprocess/README.md +++ b/packages/subagent/subagent-inprocess/README.md @@ -20,7 +20,7 @@ The child gets the parent's working-directory/session lineage and inherits the p This result boundary is valid because the provider owns an isolated child lifecycle from publication through quiescence. Steering submitted during that lifecycle belongs to the child run; the provider does not pretend the initial follow-up alone owns its output. -The driver applies the seam's [delegated policy inheritance](../subagent/README.md#delegated-policy-inheritance) through the shared child-agent helpers: it captures the parent's explicit sandbox/approval overrides before child creation and appends the source-tagged events during unpublished setup, after any fork history and before session publication. See the [policy-inheritance decision](../../../.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.md). +The driver applies the seam's [delegated policy](../subagent/README.md#delegated-policy) through the shared child-agent helpers: it captures the parent's explicit sandbox override and the `'never'` approval pin before child creation and appends the source-tagged events during unpublished setup, after any fork history and before session publication. See the [delegation-policy decision](../../../.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.md). ## Cancellation and ownership diff --git a/packages/subagent/subagent-inprocess/README.zh.md b/packages/subagent/subagent-inprocess/README.zh.md index c6a9005cbf..8623be4bc1 100644 --- a/packages/subagent/subagent-inprocess/README.zh.md +++ b/packages/subagent/subagent-inprocess/README.zh.md @@ -20,7 +20,7 @@ 该结果边界成立,是因为提供方拥有从发布到完全停稳的隔离子 agent 生命周期。在该生命周期内提交的 steering(中途引导)属于子运行;提供方不会声称输出只归初始 follow-up 所有。 -驱动器通过共享的子 agent 辅助函数应用该 seam 的[委派策略继承](../subagent/README.md#delegated-policy-inheritance):它会在创建子 agent 前捕获父级的显式沙箱/审批覆盖项,并在未发布的设置阶段追加带来源标记的事件,使其位于所有 fork 历史之后、会话发布之前。参见[策略继承决策](../../../.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.md)。 +驱动器通过共享的子 agent 辅助函数应用该 seam 的[委派策略](../subagent/README.md#delegated-policy):它会在创建子 agent 前捕获父级的显式沙箱覆盖项与 `'never'` 审批钉定,并在未发布的设置阶段追加带来源标记的事件,使其位于所有 fork 历史之后、会话发布之前。参见[委派策略决策](../../../.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.md)。 ## 取消与所有权 diff --git a/packages/subagent/subagent-inprocess/tests/inheritance.spec.ts b/packages/subagent/subagent-inprocess/tests/inheritance.spec.ts index 804249ba77..17620f7774 100644 --- a/packages/subagent/subagent-inprocess/tests/inheritance.spec.ts +++ b/packages/subagent/subagent-inprocess/tests/inheritance.spec.ts @@ -1,4 +1,7 @@ -/** Policy inheritance through child session events appended before publication. */ +/** + * Delegation policy through child session events appended before publication: + * the parent's sandbox override plus the pinned `approval/policy: never`. + */ import { afterEach, beforeEach, describe, expect, it } from 'vitest' import { mkdtemp, readFile, realpath, rm } from 'node:fs/promises' @@ -13,7 +16,7 @@ import type { ContentBlock } from '@deepseek-ai/dsh-llm' import SandboxPolicyService, { setSandboxMode } from '@deepseek-ai/dsh-sandbox-policy' import { SessionId, type SessionEvent } from '@deepseek-ai/dsh-session' import * as ToolFs from '@deepseek-ai/dsh-tool-fs' -import ApprovalService, { setApprovalPolicy } from '@deepseek-ai/dsh-user-approval' +import ApprovalService from '@deepseek-ai/dsh-user-approval' import { snapshotSubagentDescriptor } from '@deepseek-ai/dsh-subagent' import { MockAdapter, textResponse, toolCallResponse } from '../../../core/agent-loop/tests/mock-adapter.ts' import { startInProcessRun } from '../src/index.ts' @@ -76,12 +79,14 @@ function toolResultTexts(agent: Agent): string[] { } describe('in-process policy inheritance', () => { - it('records parent overrides before publishing a spawn child', async () => { + it('records the parent sandbox override and the approval pin before publishing a spawn child', async () => { const script: Script = [] const { ctx, parent } = await setupWalled(script) const blocked = join(workspace, 'spawn-blocked.txt') setSandboxMode(parent.session, 'read-only') - setApprovalPolicy(parent.session, 'never') + // The parent keeps the interactive deployment default: the child pin must + // not depend on any parent approval override. + expect(ctx.approval.overrideOf(parent.session)).toBeUndefined() const parentLogLength = parent.session.events.length script.push( toolCallResponse('write', 'write', { file_path: blocked, content: 'escaped' }), @@ -120,7 +125,11 @@ describe('in-process policy inheritance', () => { .join('\n') expect(contextText).toContain('Current DSH file policy: read-only') expect(contextText).toContain('Approval prompts are disabled') + // The delegation-scope statement is a runtime-context fact, so the + // deployment system prompt stays uniform across parents and children. + expect(contextText).toContain('You are a delegated subagent') expect(request.data.header.system).not.toContain('Approval prompts are disabled') + expect(request.data.header.system).not.toContain('You are a delegated subagent') expect(parent.session.events).toHaveLength(parentLogLength) } finally { await run.dispose() @@ -179,7 +188,7 @@ describe('in-process policy inheritance', () => { } }) - it('does not freeze deployment defaults into an unswitched child', async () => { + it('leaves an unswitched sandbox on the deployment default while still pinning approval', async () => { const script: Script = [] const { parent } = await setupWalled(script) const allowed = join(workspace, 'default-allowed.txt') @@ -193,12 +202,58 @@ describe('in-process policy inheritance', () => { await run.result const child = run.localAgent as Agent expect(await readFile(allowed, 'utf8')).toBe('fine') - expect(child.session.events.some( - event => event.type === 'sandbox/mode' || event.type === 'approval/policy', - )).toBe(false) + expect(child.session.events.some(event => event.type === 'sandbox/mode')).toBe(false) + expect(child.session.events.filter(event => event.type === 'approval/policy')).toMatchObject([ + { seq: 0, data: { policy: 'never', source: 'delegation' } }, + ]) expect(child.session.firstLiveSeq).toBe(0) } finally { await run.dispose() } }) + + it('rejects a child escalation deterministically even when an answerer would allow it', async () => { + const script: Script = [] + const { ctx, parent } = await setupWalled(script) + // A root answerer that would GRANT: the pinned 'never' must resolve + // before any answerer is consulted, so this never runs for the child. + let consulted = false + ctx.on('approval/request', () => { + consulted = true + return Promise.resolve('allowed-once' as const) + }) + const blocked = join(workspace, 'escalation-blocked.txt') + setSandboxMode(parent.session, 'read-only') + script.push( + toolCallResponse('write', 'write', { + file_path: blocked, + content: 'escaped', + sandbox_permissions: 'workspace-write', + justification: 'test escalation from a delegated child', + }), + textResponse('child done'), + ) + + const run = await startInProcessRun(spawnRequest(parent), {}) + try { + await run.result + const child = run.localAgent as Agent + + await expect(readFile(blocked, 'utf8')).rejects.toMatchObject({ code: 'ENOENT' }) + expect(consulted).toBe(false) + expect(toolResultTexts(child).join('\n')) + .toContain('the user rejected escalating this operation to "workspace-write"') + // The deterministic rejection still leaves the full audit pair on the child log. + const asked = child.session.events.find( + (event): event is SessionEvent<'approval/asked'> => event.type === 'approval/asked', + ) + const decided = child.session.events.find( + (event): event is SessionEvent<'approval/decided'> => event.type === 'approval/decided', + ) + expect(asked?.data.toolName).toBe('write') + expect(decided?.data).toMatchObject({ id: asked?.data.id, outcome: 'rejected' }) + } finally { + await run.dispose() + } + }) }) diff --git a/packages/subagent/subagent-inprocess/tests/structured.spec.ts b/packages/subagent/subagent-inprocess/tests/structured.spec.ts index 06fa641336..36e63283da 100644 --- a/packages/subagent/subagent-inprocess/tests/structured.spec.ts +++ b/packages/subagent/subagent-inprocess/tests/structured.spec.ts @@ -247,10 +247,11 @@ describe('in-process structured output', () => { const result = await run.result expect(result.stopReason).toBe('error') expect(result.structured).toBeUndefined() - // Exactly one model request and one user message: no nudge turn exists. + // Exactly one model request and one caller-supplied user message (the + // delegation runtime-context snapshot aside): no nudge turn exists. expect(adapter.requests.length).toBe(1) const child = ctx.agents.get(run.id)! - expect(child.session.events.filter(e => e.type === 'user/message').length).toBe(1) + expect(child.session.events.filter(e => e.type === 'user/message' && e.data.source.kind !== 'plugin').length).toBe(1) await run.dispose() }) diff --git a/packages/subagent/subagent/README.i18n.yaml b/packages/subagent/subagent/README.i18n.yaml index 7c64fb7228..3c89396d41 100644 --- a/packages/subagent/subagent/README.i18n.yaml +++ b/packages/subagent/subagent/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/subagent/subagent/README.md -README.md: 6cea175de3d07290b293ad55ccbe60d7d918d37c -README.zh.md: c5fecd554357146d317b5f75824f40a1cb976f2c +README.md: 30ecd187b08cd3d098ce791535914f80e4be9aed +README.zh.md: 5e32a74469a67e02a0eb927c368080768e27d508 diff --git a/packages/subagent/subagent/README.md b/packages/subagent/subagent/README.md index 6cea175de3..30ecd187b0 100644 --- a/packages/subagent/subagent/README.md +++ b/packages/subagent/subagent/README.md @@ -52,9 +52,9 @@ The seam owns the depth vocabulary shared by Service providers and Consumers: th `inheritsParentContext` is descriptive rather than enforceable. It says only whether the child sees completed parent conversation history (`fork` does; `spawn` and the out-of-process one-shot providers do not), not whether it inherits tools, services, or authority. -## Delegated policy inheritance +## Delegated policy -Both in-process delegation paths seed the parent's explicit policy overrides into the child through the shared child-agent helpers: `captureDelegatedPolicyOverrides(parent)` snapshots `sandboxPolicy.overrideOf()` and `approval.overrideOf()` synchronously at the delegation boundary (both services are optional `ctx.get` consumers), and `appendDelegatedPolicyOverrides()` writes each captured value onto the child's own log as a `source: 'delegation'` `sandbox/mode` or `approval/policy` event during unpublished setup, after any fork seed — so fresh policy wins stale seed state, a later child switch wins the snapshot, and the child's effective policy stays reconstructable from its log alone. Deployment defaults are never copied: an unswitched parent stamps nothing and its child follows the deployment default dynamically. A continuable start captures before its first await and seeds only fresh materialization; a cold resume replays the persisted delegation events instead of re-capturing the parent, so a parent switch after creation never retroactively changes a durable child. See the [one-shot](../../../.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.md) and [continuable](../../../.agents/notes/implemented/feature/2026-08-10-continuable-subagent-policy-inheritance.md) policy-inheritance Agent Notes. +Both in-process delegation paths fix the child's permission scope at the delegation boundary through the shared child-agent helpers. `captureDelegatedPolicyOverrides(parent)` snapshots the parent session's explicit sandbox override (`sandboxPolicy.overrideOf()`) and pins the child's approval policy to `'never'` whenever the approval capability is composed — regardless of the parent's own policy — so a delegated child acts only within its inherited sandbox scope and every ask (for example a `sandbox_permissions` escalation) is rejected deterministically instead of waiting on a prompt no one is watching (both services are optional `ctx.get` consumers). `appendDelegatedPolicyOverrides()` writes each value onto the child's own log as a `source: 'delegation'` `sandbox/mode` or `approval/policy` event during unpublished setup, after any fork seed — so fresh policy wins stale seed state and the child's effective policy stays reconstructable from its log alone. The sandbox deployment default is never copied: an unswitched parent stamps no `sandbox/mode` and its child follows the deployment default dynamically. A continuable start captures before its first await and seeds only fresh materialization; a cold resume replays the persisted delegation events instead of re-capturing the parent, so a parent switch after creation never retroactively changes a durable child. Every in-process child also receives a scoped runtime-context statement (`subagent:delegation`) telling it the scope is fixed and that a task needing wider access ends with a reported limitation, not retries. See the [one-shot](../../../.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.md) and [continuable](../../../.agents/notes/implemented/feature/2026-08-10-continuable-subagent-policy-inheritance.md) delegation-policy Agent Notes. ## One-shot ownership and lifecycle @@ -96,11 +96,25 @@ Continuable Activations await a best-effort final session flush without treating ## Model Experience -Indirectly, through `dsh-tool-subagent`, `dsh-tool-subagent-control`, and `dsh-tool-subagent-report`. The first owns delegation schemas, the second owns parent continuation and discovery, and the third contributes `report` only to continuable child scopes. +### Child delegation-scope statement + +#### What the model sees + +Every in-process child's runtime-context snapshot carries the `subagent:delegation` statement below, after the sandbox-policy and approval-policy sentences; parent-side rendering stays with `dsh-tool-subagent` (delegation schemas), `dsh-tool-subagent-control` (continuation and discovery), and `dsh-tool-subagent-report` (the child-scoped `report`). + +##### The delegation-scope statement + +```markdown +You are a delegated subagent: your permission scope was fixed when you were started and cannot be widened from inside this session — operations that require approval are rejected automatically. When the task needs access beyond that scope, do not retry the denied operation; state the limitation in your reply so the delegating agent can handle it. +``` + +#### Token effect + +One fixed statement in each child's runtime-context snapshot; none in the parent's requests. #### KV Cache effect -No direct invalidation; the named consumers own any request-prefix changes. +Prefix-stable within a child: the statement never changes during the child's lifetime, so it is written once into the first runtime-context snapshot. Parent-side, no direct invalidation; the named tool consumers own any request-prefix changes. ## Known Limitations and Deferred Work diff --git a/packages/subagent/subagent/README.zh.md b/packages/subagent/subagent/README.zh.md index c5fecd5543..5e32a74469 100644 --- a/packages/subagent/subagent/README.zh.md +++ b/packages/subagent/subagent/README.zh.md @@ -52,9 +52,9 @@ subagent seam 允许一个 agent(智能体)通过具名提供方把工作委 `inheritsParentContext` 只用于描述,不能强制执行。它仅说明子 agent 是否能看到父级已完成的对话历史(`fork` 可以;`spawn` 和各进程外一次性提供方不可以),不表示是否继承工具、服务或权限。 -## 委派策略继承 +## 委派策略 -两条进程内委派路径都会通过共享的子 agent 辅助函数,把父级的显式策略覆盖项作为种子注入子 agent:`captureDelegatedPolicyOverrides(parent)` 在委派边界同步对 `sandboxPolicy.overrideOf()` 与 `approval.overrideOf()` 获取快照(这两个服务都是可选的 `ctx.get` 消费方),`appendDelegatedPolicyOverrides()` 则在未发布的设置阶段、在任何 fork 种子之后,把每个捕获值作为一条 `source: 'delegation'` 的 `sandbox/mode` 或 `approval/policy` 事件写入子 agent 自己的日志:因此新鲜策略压过陈旧的种子状态,子 agent 后续的切换压过该快照,而子 agent 的生效策略始终可以仅凭其日志重建。部署默认值绝不复制:未切换的父级不会记录任何值,其子 agent 会动态跟随部署默认值。可继续启动会在其第一次 await 之前捕获,并且只为新鲜的物化写入种子;冷恢复会重放已持久化的委派事件,而不是重新捕获父级,因此创建之后的父级切换绝不会追溯性地改变持久化子 agent。参见[一次性](../../../.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.md)与[可继续](../../../.agents/notes/implemented/feature/2026-08-10-continuable-subagent-policy-inheritance.md)两篇策略继承 Agent Note。 +两条进程内委派路径都会通过共享的子 agent 辅助函数,在委派边界固定子 agent 的权限范围。`captureDelegatedPolicyOverrides(parent)` 对父会话的显式沙箱覆盖项(`sandboxPolicy.overrideOf()`)获取快照,并在审批能力已组合时把子 agent 的审批策略钉定为 `'never'`——无论父级自身的策略是什么——因此被委派的子 agent 只在其继承的沙箱范围内行动,每次请求(例如一次 `sandbox_permissions` 升级)都被确定性拒绝,而不是等待一个无人在看的提示(这两个服务都是可选的 `ctx.get` 消费方)。`appendDelegatedPolicyOverrides()` 则在未发布的设置阶段、在任何 fork 种子之后,把每个值作为一条 `source: 'delegation'` 的 `sandbox/mode` 或 `approval/policy` 事件写入子 agent 自己的日志:因此新鲜策略压过陈旧的种子状态,而子 agent 的生效策略始终可以仅凭其日志重建。沙箱的部署默认值绝不复制:未切换的父级不会记录 `sandbox/mode`,其子 agent 会动态跟随部署默认值。可继续启动会在其第一次 await 之前捕获,并且只为新鲜的物化写入种子;冷恢复会重放已持久化的委派事件,而不是重新捕获父级,因此创建之后的父级切换绝不会追溯性地改变持久化子 agent。每个进程内子 agent 还会收到一条作用域内的运行时上下文声明(`subagent:delegation`),告知其权限范围已固定,需要更宽访问的任务应以上报限制收尾,而不是重试。参见[一次性](../../../.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.md)与[可继续](../../../.agents/notes/implemented/feature/2026-08-10-continuable-subagent-policy-inheritance.md)两篇委派策略 Agent Note。 ## 一次性所有权与生命周期 @@ -96,11 +96,25 @@ subagent seam 允许一个 agent(智能体)通过具名提供方把工作委 ## 模型体验 -通过 `dsh-tool-subagent`、`dsh-tool-subagent-control` 和 `dsh-tool-subagent-report` 间接产生影响。第一个工具负责委派 schema,第二个负责父级延续和发现,第三个只向可继续子级作用域贡献 `report`。 +### 子级委派范围声明 + +#### 模型看到的内容 + +每个进程内子 agent 的运行时上下文快照都携带下方的 `subagent:delegation` 声明,位于沙箱策略与审批策略语句之后;父级侧的渲染仍归 `dsh-tool-subagent`(委派 schema)、`dsh-tool-subagent-control`(延续与发现)和 `dsh-tool-subagent-report`(子级作用域的 `report`)所有。 + +##### 委派范围声明 + +```markdown +You are a delegated subagent: your permission scope was fixed when you were started and cannot be widened from inside this session — operations that require approval are rejected automatically. When the task needs access beyond that scope, do not retry the denied operation; state the limitation in your reply so the delegating agent can handle it. +``` + +#### Token 影响 + +每个子 agent 的运行时上下文快照中一条固定声明;父级请求中没有任何新增。 #### KV Cache 影响 -不会直接使缓存失效;具名消费方共同负责请求前缀的任何变化。 +子级内部前缀稳定:该声明在子 agent 生命周期内绝不变化,因此只写入第一份运行时上下文快照一次。父级侧不会直接使缓存失效;具名工具消费方共同负责请求前缀的任何变化。 ## 已知限制与暂缓事项 diff --git a/packages/subagent/subagent/src/child-agent.ts b/packages/subagent/subagent/src/child-agent.ts index 878b831dd5..bc0cf949b9 100644 --- a/packages/subagent/subagent/src/child-agent.ts +++ b/packages/subagent/subagent/src/child-agent.ts @@ -1,9 +1,9 @@ /** * Shared in-process child composition: the delegation-depth budget, the * durable session metadata, the resolved child `AgentOptions`, the delegated - * policy snapshot, and the scoped setup a child agent needs. Both the one-shot + * policy seed, and the scoped setup a child agent needs. Both the one-shot * provider driver and the continuation manager compose children this way, so - * depth accounting, lineage stamping, and policy inheritance have one home. + * depth accounting, lineage stamping, and delegation policy have one home. * * @module @deepseek-ai/dsh-subagent/child-agent */ @@ -13,12 +13,10 @@ import type { Agent, AgentOptions, CreateAgentOptions } from '@deepseek-ai/dsh-a import type { SandboxMode } from '@deepseek-ai/dsh-sandbox' import type { Session, SessionId } from '@deepseek-ai/dsh-session' import type { ToolRestriction } from '@deepseek-ai/dsh-tools' -import type { ApprovalPolicy } from '@deepseek-ai/dsh-user-approval' // Type-only: make `ctx.get('sandboxPolicy')` / `ctx.get('approval')` resolve // to the policy services when composed — delegation consumes both -// opportunistically (the documented `ctx.get` pattern), never as a hard dep. -// The user-approval side stays an explicit empty import so its augmentation -// does not ride the `ApprovalPolicy` import above. +// opportunistically (the documented `ctx.get` pattern), never as a hard dep — +// and merge the `sandbox/mode` / `approval/policy` session-event payloads. import type {} from '@deepseek-ai/dsh-sandbox-policy' import type {} from '@deepseek-ai/dsh-user-approval' import { delegationDepthOf } from './depth.ts' @@ -115,51 +113,80 @@ export interface ChildComposition { } /** - * Apply one child's scoped composition inside its creation window: a shadowing - * persona section and a tool restriction, both owned by the child's scope and - * therefore invisible to its parent and siblings. + * Model-facing statement every in-process child receives: the permission + * scope is fixed at delegation and approval prompts are unavailable, so the + * child reports a scope limitation instead of retrying denied operations. + * A runtime-context contribution (not a system-prompt section) because it is + * a per-session fact: the deployment's system prompt stays uniform across + * parents and children, and the statement joins the same durable snapshot + * that carries the sandbox-policy and approval-policy sentences. + */ +export const SUBAGENT_DELEGATION_CONTEXT + = 'You are a delegated subagent: your permission scope was fixed when you were started and cannot be ' + + 'widened from inside this session — operations that require approval are rejected automatically. ' + + 'When the task needs access beyond that scope, do not retry the denied operation; state the ' + + 'limitation in your reply so the delegating agent can handle it.' + +/** + * Apply one child's scoped composition inside its creation window: the fixed + * delegation-scope statement, a shadowing persona section, and a tool + * restriction, all owned by the child's scope and therefore invisible to its + * parent and siblings. Both creation and cold resume pass through here, so a + * resumed child keeps the same statement. * @param childCtx - the child agent's scoped creation context. * @param composition - the persona and tool filter to install. */ export function applyChildComposition(childCtx: Context, composition: ChildComposition): void { + // After sandbox:policy (110) and approval:policy (115): scope, then policy, + // then what a delegated child does about a denial. + childCtx.systemPrompt.context({ name: 'subagent:delegation', order: 120, text: SUBAGENT_DELEGATION_CONTEXT }) if (composition.persona !== undefined) { childCtx.systemPrompt.section({ name: 'deployment:persona', order: 0, text: composition.persona }) } if (composition.toolFilter !== undefined) childCtx.tools.restrict(composition.toolFilter) } -/** Parent-session policy overrides captured at the delegation boundary. */ +/** Policy seeded onto a child session's log at the delegation boundary. */ export interface DelegatedPolicyOverrides { /** The parent session's explicit sandbox-mode override, or `undefined` without one. */ readonly sandboxMode: SandboxMode | undefined - /** The parent session's explicit approval-policy override, or `undefined` without one. */ - readonly approvalPolicy: ApprovalPolicy | undefined + /** + * The child's pinned approval policy, or `undefined` when no approval + * capability is composed. Always `'never'` with one composed: a delegated + * child acts only within the sandbox scope fixed at delegation, so the + * composed `ApprovalService` rejects every child ask deterministically + * instead of waiting on a prompt no one is watching. + */ + readonly approvalPolicy: 'never' | undefined } /** - * Capture the parent session's explicit policy overrides for one delegation. - * Call synchronously before the child start's first await: a later parent - * switch belongs to the parent's future, not to this child. Deployment - * defaults and one-shot grants are never captured, so an unswitched parent - * leaves the child following the deployment default dynamically. + * Capture the policy to seed into one delegation. Call synchronously before + * the child start's first await: a later parent switch belongs to the + * parent's future, not to this child. The sandbox scope is the parent + * session's explicit override — deployment defaults and one-shot grants are + * never captured, so an unswitched parent leaves the child following the + * deployment default dynamically. The approval policy is never inherited: it + * is pinned to `'never'` whenever the approval capability is composed, + * regardless of the parent's own policy. * @param parent - the delegating parent agent. - * @returns the overrides to seed into the child, each `undefined` without one. + * @returns the sandbox override (or `undefined` without one) and the approval pin. */ export function captureDelegatedPolicyOverrides(parent: Agent): DelegatedPolicyOverrides { return { sandboxMode: parent.ctx.get('sandboxPolicy')?.overrideOf(parent.session), - approvalPolicy: parent.ctx.get('approval')?.overrideOf(parent.session), + approvalPolicy: parent.ctx.get('approval') === undefined ? undefined : 'never', } } /** - * Append captured parent overrides onto the child's own log as + * Append the captured delegation policy onto the child's own log as * `source: 'delegation'` events inside the unpublished creation window, so the * child's effective policy is reconstructable from its log alone. Appends land * after any fork seed, so fresh policy wins stale seed state; later child * switches still win over these events. * @param childSession - the unpublished child's session. - * @param overrides - the overrides captured at delegation. + * @param overrides - the policy captured at delegation. */ export function appendDelegatedPolicyOverrides( childSession: Session, diff --git a/packages/subagent/subagent/src/continuation.ts b/packages/subagent/subagent/src/continuation.ts index 743d6d63de..2f54f90218 100644 --- a/packages/subagent/subagent/src/continuation.ts +++ b/packages/subagent/subagent/src/continuation.ts @@ -214,8 +214,8 @@ interface MaterializeInputs { create?: { seed: readonly SessionEvent[] meta: NonNullable - /** Parent policy overrides captured at the delegation boundary. */ - inheritedPolicies: DelegatedPolicyOverrides + /** Policy captured at the delegation boundary: the parent's sandbox override plus the approval pin. */ + delegatedPolicies: DelegatedPolicyOverrides } agentOptions: AgentOptions composition: { persona?: string | undefined; toolFilter?: ToolRestriction | undefined } @@ -355,7 +355,7 @@ export class SubagentContinuationManager { }) // Capture before the first await: a later parent switch belongs to the // parent's future, not to this child. - const inheritedPolicies = captureDelegatedPolicyOverrides(parent) + const delegatedPolicies = captureDelegatedPolicyOverrides(parent) const prepared = await this.host.prepareContinuable(spec.provider, { sessionId: childId, @@ -372,7 +372,7 @@ export class SubagentContinuationManager { childId, provider: spec.provider, parent, - create: { seed, meta: childSessionMeta(parent, childDepth, lineageSeedLength), inheritedPolicies }, + create: { seed, meta: childSessionMeta(parent, childDepth, lineageSeedLength), delegatedPolicies }, agentOptions: resolveChildAgentOptions(parent, request.agentOptions, childDepth), composition: { persona: request.persona, toolFilter: request.toolFilter }, signal: spec.signal, @@ -900,11 +900,11 @@ export class SubagentContinuationManager { // some other owner holds — a duplicate would reject there with rollback. inputs.signal.throwIfAborted() const setup = (childCtx: Context): AgentSetupCommit => { - // Only fresh creation seeds captured parent policy onto the child's own + // Only fresh creation seeds the delegation policy onto the child's own // log (after any fork seed, so fresh policy wins stale seed state); a // cold resume replays those persisted events instead. if (create !== undefined) { - appendDelegatedPolicyOverrides((childCtx.agent as Agent).session, create.inheritedPolicies) + appendDelegatedPolicyOverrides((childCtx.agent as Agent).session, create.delegatedPolicies) } applyChildComposition(childCtx, inputs.composition) return this.setupRegistry.apply(childCtx) diff --git a/packages/subagent/subagent/tests/continuation-inheritance.spec.ts b/packages/subagent/subagent/tests/continuation-inheritance.spec.ts index 92cefa261e..1e539c28c2 100644 --- a/packages/subagent/subagent/tests/continuation-inheritance.spec.ts +++ b/packages/subagent/subagent/tests/continuation-inheritance.spec.ts @@ -1,9 +1,9 @@ /** - * Continuable-child policy inheritance: a fresh continuable start seeds the - * parent's explicit sandbox/approval overrides onto the child's own log as - * `source: 'delegation'` events, and a cold resume replays that persisted - * snapshot instead of re-capturing the parent (the one-shot - * `subagent-inprocess/tests/inheritance.spec.ts` counterpart). + * Continuable-child delegation policy: a fresh continuable start seeds the + * parent's explicit sandbox override and the pinned `approval/policy: never` + * onto the child's own log as `source: 'delegation'` events, and a cold + * resume replays that persisted snapshot instead of re-capturing the parent + * (the one-shot `subagent-inprocess/tests/inheritance.spec.ts` counterpart). */ import { afterEach, describe, expect, it, vi } from 'vitest' @@ -21,7 +21,7 @@ import type { SessionEvent } from '@deepseek-ai/dsh-session' import JsonlSessionPersistence from '@deepseek-ai/dsh-session-persistence-jsonl' import * as SubagentFork from '@deepseek-ai/dsh-subagent-fork' import * as SubagentSpawn from '@deepseek-ai/dsh-subagent-spawn' -import ApprovalService, { effectiveApprovalPolicy, setApprovalPolicy } from '@deepseek-ai/dsh-user-approval' +import ApprovalService, { effectiveApprovalPolicy } from '@deepseek-ai/dsh-user-approval' import { MockAdapter, textResponse } from '../../../core/agent-loop/tests/mock-adapter.ts' import SubagentService from '../src/index.ts' @@ -71,10 +71,12 @@ function policyEvents(events: readonly SessionEvent[]) { } describe('continuable policy inheritance', () => { - it('seeds parent overrides into a fresh continuable child', async () => { + it('seeds the parent sandbox override and pins approval to never', async () => { const { ctx, parent } = await setup([textResponse('child done')]) setSandboxMode(parent.session, 'danger-full-access') - setApprovalPolicy(parent.session, 'never') + // The parent keeps the interactive deployment default: the child pin must + // not depend on any parent approval override. + expect(ctx.approval.overrideOf(parent.session)).toBeUndefined() let child: Agent | undefined ctx.on('agent/created', ({ agent }) => { if (agent !== parent) child = agent @@ -93,9 +95,20 @@ describe('continuable policy inheritance', () => { { type: 'sandbox/mode', data: { mode: 'danger-full-access', source: 'delegation' } }, { type: 'approval/policy', data: { policy: 'never', source: 'delegation' } }, ]) - // Durable: a reload folds the same effective policy. + // Durable: a reload folds the same effective policy; the parent keeps its own. expect(effectiveSandboxMode(loaded.events)).toBe('danger-full-access') expect(effectiveApprovalPolicy(loaded.events)).toBe('never') + expect(ctx.approval.overrideOf(parent.session)).toBeUndefined() + // The child's runtime-context snapshot states the fixed delegation scope. + const runtimeContext = loaded.events.find( + (event): event is SessionEvent<'user/message'> => event.type === 'user/message' + && event.data.source.kind === 'plugin' + && event.data.source.plugin === '@deepseek-ai/dsh-system-prompt', + ) + const contextText = runtimeContext?.data.content + .flatMap(block => block.type === 'text' ? [block.text] : []) + .join('\n') + expect(contextText).toContain('You are a delegated subagent') }) it('captures policy at delegation before asynchronous child creation', async () => { @@ -114,17 +127,20 @@ describe('continuable policy inheritance', () => { expect(effectiveSandboxMode(loaded.events)).toBe('read-only') }) - it('does not freeze deployment defaults into an unswitched child', async () => { + it('leaves an unswitched sandbox on the deployment default while still pinning approval', async () => { const { ctx, parent } = await setup([textResponse('child done')]) const started = await ctx.subagents.startContinuable(startSpec(parent)) await waitNoActivation(ctx, started.childId) const loaded = await ctx.sessionPersistence.load(started.childId) - expect(policyEvents(loaded.events)).toEqual([]) + expect(policyEvents(loaded.events)).toMatchObject([ + { type: 'approval/policy', data: { policy: 'never', source: 'delegation' } }, + ]) + expect(effectiveSandboxMode(loaded.events)).toBeUndefined() }) - it('does not freeze deployment defaults into an unswitched fork child either', async () => { + it('pins approval after the fork prefix of an unswitched fork child', async () => { const { ctx, parent } = await setup([textResponse('parent turn'), textResponse('forked child')]) parent.followup(createUserMessage({ content: [{ type: 'text', text: 'parent work' }], @@ -137,7 +153,10 @@ describe('continuable policy inheritance', () => { const loaded = await ctx.sessionPersistence.load(started.childId) expect(loaded.meta.seedLength).toBeGreaterThan(0) - expect(policyEvents(loaded.events)).toEqual([]) + expect(policyEvents(loaded.events)).toMatchObject([ + { type: 'approval/policy', data: { policy: 'never', source: 'delegation' } }, + ]) + expect(effectiveSandboxMode(loaded.events)).toBeUndefined() }) it('lets a later child-side switch win over the delegation snapshot', async () => { @@ -180,6 +199,10 @@ describe('continuable policy inheritance', () => { { data: { mode: 'read-only', source: 'delegation' } }, ]) expect(effectiveSandboxMode(loaded.events)).toBe('read-only') + // The approval pin is seeded once at creation, never re-appended on resume. + expect(loaded.events.filter(event => event.type === 'approval/policy')).toMatchObject([ + { data: { policy: 'never', source: 'delegation' } }, + ]) }) it('places inherited events after a fork prefix so fresh policy wins stale seed state', async () => { diff --git a/packages/subagent/subagent/tests/continuation.spec.ts b/packages/subagent/subagent/tests/continuation.spec.ts index 9370676f76..6e23f6ccae 100644 --- a/packages/subagent/subagent/tests/continuation.spec.ts +++ b/packages/subagent/subagent/tests/continuation.spec.ts @@ -103,9 +103,9 @@ function hasUserText(events: readonly SessionEvent[], text: string): boolean { && event.data.content.some(block => block.type === 'text' && block.text === text)) } -/** Every user-role message text in log order, for FIFO assertions. */ +/** Every caller-supplied user-role message text in log order, for FIFO assertions (framework runtime-context snapshots excluded). */ function userTexts(events: readonly SessionEvent[]): string[] { - return events.flatMap(event => event.type === 'user/message' + return events.flatMap(event => event.type === 'user/message' && event.data.source.kind !== 'plugin' ? event.data.content.flatMap(block => block.type === 'text' ? [block.text] : []) : []) } diff --git a/packages/subagent/tool-subagent-control/tests/tool-subagent-control.spec.ts b/packages/subagent/tool-subagent-control/tests/tool-subagent-control.spec.ts index c5ea8fd1b8..462b769e94 100644 --- a/packages/subagent/tool-subagent-control/tests/tool-subagent-control.spec.ts +++ b/packages/subagent/tool-subagent-control/tests/tool-subagent-control.spec.ts @@ -158,7 +158,7 @@ describe('dsh-tool-subagent-control', () => { await waitNoActivation(ctx, started.childId) const loaded = await ctx.sessionPersistence.load(started.childId) - const prompts = loaded.events.flatMap(event => event.type === 'user/message' + const prompts = loaded.events.flatMap(event => event.type === 'user/message' && event.data.source.kind !== 'plugin' ? event.data.content.flatMap(block => block.type === 'text' ? [block.text] : []) : []) // A follow-up is its own later turn, never steering inside the first one. @@ -274,7 +274,7 @@ describe('dsh-tool-subagent-control interrupt_agent', () => { expect(waking.isError).toBe(false) await waitNoActivation(ctx, started.childId) const loaded = await ctx.sessionPersistence.load(started.childId) - const prompts = loaded.events.flatMap(event => event.type === 'user/message' + const prompts = loaded.events.flatMap(event => event.type === 'user/message' && event.data.source.kind !== 'plugin' ? event.data.content.flatMap(block => block.type === 'text' ? [block.text] : []) : []) expect(prompts).toEqual(['long work', 'parked follow-up', 'wake up']) diff --git a/packages/subagent/tool-subagent-report/tests/tool-subagent-report.spec.ts b/packages/subagent/tool-subagent-report/tests/tool-subagent-report.spec.ts index 23757c2b54..c74fb94646 100644 --- a/packages/subagent/tool-subagent-report/tests/tool-subagent-report.spec.ts +++ b/packages/subagent/tool-subagent-report/tests/tool-subagent-report.spec.ts @@ -411,9 +411,9 @@ describe('dsh-tool-subagent-report', () => { }) }) -/** Prove report delivery uses ordinary logged user messages. */ +/** Prove report delivery uses ordinary logged user messages (framework runtime-context snapshots excluded). */ function userTexts(events: readonly SessionEvent[]): string[] { - return events.flatMap(event => event.type === 'user/message' + return events.flatMap(event => event.type === 'user/message' && event.data.source.kind !== 'plugin' ? event.data.content.flatMap(block => block.type === 'text' ? [block.text] : []) : []) } diff --git a/scripts/verify-package-readme-model-experience.ts b/scripts/verify-package-readme-model-experience.ts index 0a202e6142..2b962ca471 100644 --- a/scripts/verify-package-readme-model-experience.ts +++ b/scripts/verify-package-readme-model-experience.ts @@ -133,7 +133,6 @@ const SENTENCE_MODEL_EXPERIENCE: Readonly> = { 'packages/skill/skill-local': { kind: 'indirect', reason: 'The provider backend delegates model rendering to dsh-tool-skill.' }, 'packages/spill/spill': { kind: 'indirect', reason: 'The storage seam delegates model rendering to spill consumers.' }, 'packages/spill/spill-local': { kind: 'indirect', reason: 'The storage backend delegates model rendering to spill consumers.' }, - 'packages/subagent/subagent': { kind: 'indirect', reason: 'The provider registry delegates parent-model rendering to dsh-tool-subagent.' }, 'packages/support/acp-snapshot': { kind: 'none', reason: 'The test harness observes and normalizes transcripts without changing live requests.' }, 'packages/support/agent-loop-testkit': { kind: 'none', reason: 'The test helper mounts services but neither drives nor modifies model requests.' }, 'packages/support/invariants': { kind: 'none', reason: 'The observer validates requests but never rewrites their context.' }, From 8ebf02e0ac53f6b01fa6d938c650eaf245084f66 Mon Sep 17 00:00:00 2001 From: Hypatia May Date: Mon, 10 Aug 2026 19:34:17 +0800 Subject: [PATCH 05/15] docs(subagent): cite issue 1723 as plain text in the approvals-pinned note A leaked host TSX_TSCONFIG_PATH redirected the tsx gate scripts to a staging checkout and masked the verify-public-repository-links rejection of the internal issue URL; all tsx-driven gates re-verified clean with the variable unset. --- .../2026-08-10-subagent-approval-pinned-never.i18n.yaml | 4 ++-- .../feature/2026-08-10-subagent-approval-pinned-never.md | 2 +- .../feature/2026-08-10-subagent-approval-pinned-never.zh.md | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.agents/notes/implemented/feature/2026-08-10-subagent-approval-pinned-never.i18n.yaml b/.agents/notes/implemented/feature/2026-08-10-subagent-approval-pinned-never.i18n.yaml index cde23b2552..322d645a70 100644 --- a/.agents/notes/implemented/feature/2026-08-10-subagent-approval-pinned-never.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-08-10-subagent-approval-pinned-never.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-08-10-subagent-approval-pinned-never.md -2026-08-10-subagent-approval-pinned-never.md: 578dbe58cd4e0a3c97552e20f27a2818ee9c9f40 -2026-08-10-subagent-approval-pinned-never.zh.md: 45bc461505b07a4c10e063a122e8003f52afd259 +2026-08-10-subagent-approval-pinned-never.md: a21c6b966b1ad00ed63e0fe87b0ce982f0daf490 +2026-08-10-subagent-approval-pinned-never.zh.md: db44ae134d34904a53691cfe78eaa5a899cf64e0 diff --git a/.agents/notes/implemented/feature/2026-08-10-subagent-approval-pinned-never.md b/.agents/notes/implemented/feature/2026-08-10-subagent-approval-pinned-never.md index 578dbe58cd..a21c6b966b 100644 --- a/.agents/notes/implemented/feature/2026-08-10-subagent-approval-pinned-never.md +++ b/.agents/notes/implemented/feature/2026-08-10-subagent-approval-pinned-never.md @@ -6,7 +6,7 @@ English | [中文](2026-08-10-subagent-approval-pinned-never.zh.md) ## Problem -A delegated child that asked for approval had no one to ask. Under an interactive parent (`'ask'`), a background child's escalation became a pending question no product surface showed — subagent sessions are omitted from the Web sidebar, the parent's `list_agents` reports plain `running`/`idle`, and the catalog rows show only activity — so a permission-blocked child was indistinguishable from a working one; headless and unanswered compositions failed the same ask closed as `'unavailable'`. The rejection audit landed only in the child's own log, and no tool parameter or Web control can adjust a running child session's sandbox mode or approval policy ([deepseek-harness#1723](https://github.com/deepseek-harness/deepseek-harness/issues/1723)). The mechanism-heavy fix — a durable blocked-state projection, parent notices, catalog badges, and a permission write path through the subagent ownership fence — was disproportionate directly before release. +A delegated child that asked for approval had no one to ask. Under an interactive parent (`'ask'`), a background child's escalation became a pending question no product surface showed — subagent sessions are omitted from the Web sidebar, the parent's `list_agents` reports plain `running`/`idle`, and the catalog rows show only activity — so a permission-blocked child was indistinguishable from a working one; headless and unanswered compositions failed the same ask closed as `'unavailable'`. The rejection audit landed only in the child's own log, and no tool parameter or Web control can adjust a running child session's sandbox mode or approval policy (Issue #1723). The mechanism-heavy fix — a durable blocked-state projection, parent notices, catalog badges, and a permission write path through the subagent ownership fence — was disproportionate directly before release. ## Decision diff --git a/.agents/notes/implemented/feature/2026-08-10-subagent-approval-pinned-never.zh.md b/.agents/notes/implemented/feature/2026-08-10-subagent-approval-pinned-never.zh.md index 45bc461505..db44ae134d 100644 --- a/.agents/notes/implemented/feature/2026-08-10-subagent-approval-pinned-never.zh.md +++ b/.agents/notes/implemented/feature/2026-08-10-subagent-approval-pinned-never.zh.md @@ -6,7 +6,7 @@ Status: implemented ## 问题 -被委派的子 agent 发起审批请求时无人可问。在交互式父级(`'ask'`)之下,后台子 agent 的升级请求会变成一个任何产品界面都不展示的挂起问题——subagent 会话不进入 Web 侧边栏,父级的 `list_agents` 只报告普通的 `running`/`idle`,目录树的行也只显示活动状态——因此被权限拦住的子 agent 与正常干活的子 agent 无法区分;headless 与无应答者的组合则让同一次 ask 以 `'unavailable'` 失败关闭。拒绝的审计记录只落在子 agent 自己的日志里,而且没有任何工具参数或 Web 控件能调整一个正在运行的子会话的沙箱模式或审批策略([deepseek-harness#1723](https://github.com/deepseek-harness/deepseek-harness/issues/1723))。机制繁重的修复方案——持久化的受阻状态投影、父级通知、目录树徽标,以及穿过 subagent 所有权围栏的权限写入路径——在临近发布时代价不成比例。 +被委派的子 agent 发起审批请求时无人可问。在交互式父级(`'ask'`)之下,后台子 agent 的升级请求会变成一个任何产品界面都不展示的挂起问题——subagent 会话不进入 Web 侧边栏,父级的 `list_agents` 只报告普通的 `running`/`idle`,目录树的行也只显示活动状态——因此被权限拦住的子 agent 与正常干活的子 agent 无法区分;headless 与无应答者的组合则让同一次 ask 以 `'unavailable'` 失败关闭。拒绝的审计记录只落在子 agent 自己的日志里,而且没有任何工具参数或 Web 控件能调整一个正在运行的子会话的沙箱模式或审批策略(Issue #1723)。机制繁重的修复方案——持久化的受阻状态投影、父级通知、目录树徽标,以及穿过 subagent 所有权围栏的权限写入路径——在临近发布时代价不成比例。 ## 决策 From 5ba4055ed44f74d5fc4cb4f414f2f7edfdd6adc0 Mon Sep 17 00:00:00 2001 From: Hypatia May Date: Mon, 10 Aug 2026 19:46:07 +0800 Subject: [PATCH 06/15] docs(subagent): trim comments in the delegated-policy additions --- .../tests/inheritance.spec.ts | 10 ++---- .../tests/structured.spec.ts | 3 +- packages/subagent/subagent/src/child-agent.ts | 34 +++++++------------ .../tests/continuation-inheritance.spec.ts | 6 ++-- .../subagent/tests/continuation.spec.ts | 2 +- .../tests/tool-subagent-report.spec.ts | 2 +- 6 files changed, 20 insertions(+), 37 deletions(-) diff --git a/packages/subagent/subagent-inprocess/tests/inheritance.spec.ts b/packages/subagent/subagent-inprocess/tests/inheritance.spec.ts index 17620f7774..899772b964 100644 --- a/packages/subagent/subagent-inprocess/tests/inheritance.spec.ts +++ b/packages/subagent/subagent-inprocess/tests/inheritance.spec.ts @@ -84,8 +84,7 @@ describe('in-process policy inheritance', () => { const { ctx, parent } = await setupWalled(script) const blocked = join(workspace, 'spawn-blocked.txt') setSandboxMode(parent.session, 'read-only') - // The parent keeps the interactive deployment default: the child pin must - // not depend on any parent approval override. + // No parent approval override: the child pin must not depend on one. expect(ctx.approval.overrideOf(parent.session)).toBeUndefined() const parentLogLength = parent.session.events.length script.push( @@ -125,8 +124,7 @@ describe('in-process policy inheritance', () => { .join('\n') expect(contextText).toContain('Current DSH file policy: read-only') expect(contextText).toContain('Approval prompts are disabled') - // The delegation-scope statement is a runtime-context fact, so the - // deployment system prompt stays uniform across parents and children. + // The statement rides runtime context; the system prompt stays uniform. expect(contextText).toContain('You are a delegated subagent') expect(request.data.header.system).not.toContain('Approval prompts are disabled') expect(request.data.header.system).not.toContain('You are a delegated subagent') @@ -215,8 +213,7 @@ describe('in-process policy inheritance', () => { it('rejects a child escalation deterministically even when an answerer would allow it', async () => { const script: Script = [] const { ctx, parent } = await setupWalled(script) - // A root answerer that would GRANT: the pinned 'never' must resolve - // before any answerer is consulted, so this never runs for the child. + // A granting answerer proves the pin resolves before any answerer runs. let consulted = false ctx.on('approval/request', () => { consulted = true @@ -243,7 +240,6 @@ describe('in-process policy inheritance', () => { expect(consulted).toBe(false) expect(toolResultTexts(child).join('\n')) .toContain('the user rejected escalating this operation to "workspace-write"') - // The deterministic rejection still leaves the full audit pair on the child log. const asked = child.session.events.find( (event): event is SessionEvent<'approval/asked'> => event.type === 'approval/asked', ) diff --git a/packages/subagent/subagent-inprocess/tests/structured.spec.ts b/packages/subagent/subagent-inprocess/tests/structured.spec.ts index 36e63283da..eb9815b56b 100644 --- a/packages/subagent/subagent-inprocess/tests/structured.spec.ts +++ b/packages/subagent/subagent-inprocess/tests/structured.spec.ts @@ -247,8 +247,7 @@ describe('in-process structured output', () => { const result = await run.result expect(result.stopReason).toBe('error') expect(result.structured).toBeUndefined() - // Exactly one model request and one caller-supplied user message (the - // delegation runtime-context snapshot aside): no nudge turn exists. + // Exactly one model request and one caller-supplied user message: no nudge turn exists. expect(adapter.requests.length).toBe(1) const child = ctx.agents.get(run.id)! expect(child.session.events.filter(e => e.type === 'user/message' && e.data.source.kind !== 'plugin').length).toBe(1) diff --git a/packages/subagent/subagent/src/child-agent.ts b/packages/subagent/subagent/src/child-agent.ts index bc0cf949b9..d1728ad74a 100644 --- a/packages/subagent/subagent/src/child-agent.ts +++ b/packages/subagent/subagent/src/child-agent.ts @@ -113,13 +113,9 @@ export interface ChildComposition { } /** - * Model-facing statement every in-process child receives: the permission - * scope is fixed at delegation and approval prompts are unavailable, so the - * child reports a scope limitation instead of retrying denied operations. - * A runtime-context contribution (not a system-prompt section) because it is - * a per-session fact: the deployment's system prompt stays uniform across - * parents and children, and the statement joins the same durable snapshot - * that carries the sandbox-policy and approval-policy sentences. + * Model-facing delegation-scope statement for every in-process child. A + * runtime-context contribution rather than a system-prompt section, so the + * deployment's system prompt stays uniform across parents and children. */ export const SUBAGENT_DELEGATION_CONTEXT = 'You are a delegated subagent: your permission scope was fixed when you were started and cannot be ' @@ -131,14 +127,12 @@ export const SUBAGENT_DELEGATION_CONTEXT * Apply one child's scoped composition inside its creation window: the fixed * delegation-scope statement, a shadowing persona section, and a tool * restriction, all owned by the child's scope and therefore invisible to its - * parent and siblings. Both creation and cold resume pass through here, so a - * resumed child keeps the same statement. + * parent and siblings. Creation and cold resume both pass through here. * @param childCtx - the child agent's scoped creation context. * @param composition - the persona and tool filter to install. */ export function applyChildComposition(childCtx: Context, composition: ChildComposition): void { - // After sandbox:policy (110) and approval:policy (115): scope, then policy, - // then what a delegated child does about a denial. + // Order 120: after the sandbox:policy (110) and approval:policy (115) sentences. childCtx.systemPrompt.context({ name: 'subagent:delegation', order: 120, text: SUBAGENT_DELEGATION_CONTEXT }) if (composition.persona !== undefined) { childCtx.systemPrompt.section({ name: 'deployment:persona', order: 0, text: composition.persona }) @@ -151,11 +145,9 @@ export interface DelegatedPolicyOverrides { /** The parent session's explicit sandbox-mode override, or `undefined` without one. */ readonly sandboxMode: SandboxMode | undefined /** - * The child's pinned approval policy, or `undefined` when no approval - * capability is composed. Always `'never'` with one composed: a delegated - * child acts only within the sandbox scope fixed at delegation, so the - * composed `ApprovalService` rejects every child ask deterministically - * instead of waiting on a prompt no one is watching. + * `'never'` whenever the approval capability is composed, `undefined` + * otherwise: a delegated child acts only within the sandbox scope fixed at + * delegation, so its asks are rejected deterministically. */ readonly approvalPolicy: 'never' | undefined } @@ -163,12 +155,10 @@ export interface DelegatedPolicyOverrides { /** * Capture the policy to seed into one delegation. Call synchronously before * the child start's first await: a later parent switch belongs to the - * parent's future, not to this child. The sandbox scope is the parent - * session's explicit override — deployment defaults and one-shot grants are - * never captured, so an unswitched parent leaves the child following the - * deployment default dynamically. The approval policy is never inherited: it - * is pinned to `'never'` whenever the approval capability is composed, - * regardless of the parent's own policy. + * parent's future, not to this child. Only the parent session's explicit + * sandbox override is captured — never deployment defaults or one-shot + * grants — and the approval policy is pinned to `'never'` regardless of the + * parent's own policy. * @param parent - the delegating parent agent. * @returns the sandbox override (or `undefined` without one) and the approval pin. */ diff --git a/packages/subagent/subagent/tests/continuation-inheritance.spec.ts b/packages/subagent/subagent/tests/continuation-inheritance.spec.ts index 1e539c28c2..2bc63888ae 100644 --- a/packages/subagent/subagent/tests/continuation-inheritance.spec.ts +++ b/packages/subagent/subagent/tests/continuation-inheritance.spec.ts @@ -74,8 +74,7 @@ describe('continuable policy inheritance', () => { it('seeds the parent sandbox override and pins approval to never', async () => { const { ctx, parent } = await setup([textResponse('child done')]) setSandboxMode(parent.session, 'danger-full-access') - // The parent keeps the interactive deployment default: the child pin must - // not depend on any parent approval override. + // No parent approval override: the child pin must not depend on one. expect(ctx.approval.overrideOf(parent.session)).toBeUndefined() let child: Agent | undefined ctx.on('agent/created', ({ agent }) => { @@ -95,11 +94,10 @@ describe('continuable policy inheritance', () => { { type: 'sandbox/mode', data: { mode: 'danger-full-access', source: 'delegation' } }, { type: 'approval/policy', data: { policy: 'never', source: 'delegation' } }, ]) - // Durable: a reload folds the same effective policy; the parent keeps its own. + // Durable: a reload folds the same effective policy. expect(effectiveSandboxMode(loaded.events)).toBe('danger-full-access') expect(effectiveApprovalPolicy(loaded.events)).toBe('never') expect(ctx.approval.overrideOf(parent.session)).toBeUndefined() - // The child's runtime-context snapshot states the fixed delegation scope. const runtimeContext = loaded.events.find( (event): event is SessionEvent<'user/message'> => event.type === 'user/message' && event.data.source.kind === 'plugin' diff --git a/packages/subagent/subagent/tests/continuation.spec.ts b/packages/subagent/subagent/tests/continuation.spec.ts index 6e23f6ccae..da3c474aec 100644 --- a/packages/subagent/subagent/tests/continuation.spec.ts +++ b/packages/subagent/subagent/tests/continuation.spec.ts @@ -103,7 +103,7 @@ function hasUserText(events: readonly SessionEvent[], text: string): boolean { && event.data.content.some(block => block.type === 'text' && block.text === text)) } -/** Every caller-supplied user-role message text in log order, for FIFO assertions (framework runtime-context snapshots excluded). */ +/** Caller-supplied user message texts in log order (runtime-context snapshots excluded). */ function userTexts(events: readonly SessionEvent[]): string[] { return events.flatMap(event => event.type === 'user/message' && event.data.source.kind !== 'plugin' ? event.data.content.flatMap(block => block.type === 'text' ? [block.text] : []) diff --git a/packages/subagent/tool-subagent-report/tests/tool-subagent-report.spec.ts b/packages/subagent/tool-subagent-report/tests/tool-subagent-report.spec.ts index c74fb94646..47d0fb3269 100644 --- a/packages/subagent/tool-subagent-report/tests/tool-subagent-report.spec.ts +++ b/packages/subagent/tool-subagent-report/tests/tool-subagent-report.spec.ts @@ -411,7 +411,7 @@ describe('dsh-tool-subagent-report', () => { }) }) -/** Prove report delivery uses ordinary logged user messages (framework runtime-context snapshots excluded). */ +/** Prove report delivery uses ordinary logged user messages (runtime-context snapshots excluded). */ function userTexts(events: readonly SessionEvent[]): string[] { return events.flatMap(event => event.type === 'user/message' && event.data.source.kind !== 'plugin' ? event.data.content.flatMap(block => block.type === 'text' ? [block.text] : []) From 1478d3f806856b47f39b9e49c20f913a4c119605 Mon Sep 17 00:00:00 2001 From: Hypatia May Date: Mon, 10 Aug 2026 20:14:16 +0800 Subject: [PATCH 07/15] test(web): refresh subagent conversation goldens for the pinned-approval Custom chip The delegation-pinned approval/policy: never makes a child session's knobs match no preset, so the child conversation's Access chip truthfully reads Custom. --- apps/web/tests/snapshots/subagent-conversation/ui.expected.md | 2 +- .../snapshots/subagent-interrupt/offline-composer.expected.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/web/tests/snapshots/subagent-conversation/ui.expected.md b/apps/web/tests/snapshots/subagent-conversation/ui.expected.md index 27c7ec092e..d581a7ab1f 100644 --- a/apps/web/tests/snapshots/subagent-conversation/ui.expected.md +++ b/apps/web/tests/snapshots/subagent-conversation/ui.expected.md @@ -41,7 +41,7 @@ - textbox "Message the agent" - button "Commands": - img -- 'button "Access mode, current: Workspace Write"': Workspace Write +- 'button "Access mode, current: Custom"': Custom - button "6% of context used" - button "Send message" [disabled] - text: 2 turns · 2 steps LLM {{duration}} TTFT avg {{duration}} · {{throughput}} tok/s Cache hit 99% Input 15.6K tok · Output 158 tok diff --git a/apps/web/tests/snapshots/subagent-interrupt/offline-composer.expected.md b/apps/web/tests/snapshots/subagent-interrupt/offline-composer.expected.md index a977afbbea..529e6bb43d 100644 --- a/apps/web/tests/snapshots/subagent-interrupt/offline-composer.expected.md +++ b/apps/web/tests/snapshots/subagent-interrupt/offline-composer.expected.md @@ -18,6 +18,6 @@ - textbox "Parent session offline; sending is unavailable but you can still stop the run" [disabled] - button "Commands" [disabled]: - img -- 'button "Access mode, current: Workspace Write" [disabled]': Workspace Write +- 'button "Access mode, current: Custom" [disabled]': Custom - button "Stop generating" - button "Send message" [disabled] From 993550e6c851e1ae05aa7d587d10ae1626ae1191 Mon Sep 17 00:00:00 2001 From: Turtle Date: Sun, 9 Aug 2026 13:13:30 +0800 Subject: [PATCH 08/15] refactor: remove repository plugin path --- ...-manager-native-repository-cache.i18n.yaml | 6 - ...package-manager-native-repository-cache.md | 47 -- ...kage-manager-native-repository-cache.zh.md | 47 -- ...-static-repository-plugin-format.i18n.yaml | 6 - ...6-07-30-static-repository-plugin-format.md | 49 -- ...7-30-static-repository-plugin-format.zh.md | 49 -- ...-trusted-repository-package-code.i18n.yaml | 6 - ...6-08-08-trusted-repository-package-code.md | 51 -- ...8-08-trusted-repository-package-code.zh.md | 51 -- ...it-repository-plugin-preparation.i18n.yaml | 6 - ...acked-git-repository-plugin-preparation.md | 48 -- ...ed-git-repository-plugin-preparation.zh.md | 48 -- ...-self-referential-cordis-toolset.i18n.yaml | 4 +- ...6-07-08-self-referential-cordis-toolset.md | 2 +- ...7-08-self-referential-cordis-toolset.zh.md | 2 +- ...26-07-20-dsh-cli-personal-config.i18n.yaml | 4 +- .../2026-07-20-dsh-cli-personal-config.md | 4 +- .../2026-07-20-dsh-cli-personal-config.zh.md | 4 +- ...26-07-30-config-only-repository-plugins.md | 50 -- ...07-30-config-only-repository-plugins.zh.md | 50 -- ...-08-09-remove-repository-plugin.i18n.yaml} | 6 +- .../2026-08-09-remove-repository-plugin.md | 43 ++ .../2026-08-09-remove-repository-plugin.zh.md | 43 ++ ...07-17-sdk-follow-up-capabilities.i18n.yaml | 4 +- .../2026-07-17-sdk-follow-up-capabilities.md | 2 +- ...026-07-17-sdk-follow-up-capabilities.zh.md | 2 +- .github/workflows/ci.yml | 13 - THIRD_PARTY_NOTICES.md | 1 - apps/cli/composition.md | 3 - apps/cli/reference/README.i18n.yaml | 4 +- apps/cli/reference/README.md | 4 +- apps/cli/reference/README.zh.md | 4 +- .../.dsh-plugin/.mcp.json | 10 - .../.dsh-plugin/package.json | 30 - .../.dsh-plugin/src/mcp-server.ts | 19 - .../.dsh-plugin/src/plugin.ts | 59 -- .../.dsh-plugin/tsconfig.json | 13 - .../skills/github-source-proof/SKILL.md | 6 - .../github-repository-plugin.built.e2e.ts | 256 ------- docs/config-catalog.md | 18 +- docs/module-graph.md | 6 - docs/tool-catalog.md | 2 +- .../advanced-toolchain/session.1.jsonl | 2 +- .../advanced-toolchain/session.2.jsonl | 2 +- .../advanced-toolchain/session.jsonl | 2 +- .../system-prompt.expected.md | 2 +- .../tool-schemas.expected.json | 2 +- .../tests/fixtures/cli.cordis.yml | 3 - .../skills/0/repository-fixture/SKILL.md | 6 - .../fixtures/repository-plugin/dsh-plugin.mjs | 19 - .../tests/fixtures/repository-plugin/load.mjs | 13 - .../headless-agent/tests/keyless-smoke.e2e.ts | 45 +- .../advanced-toolchain/session.1.jsonl | 8 +- .../advanced-toolchain/session.2.jsonl | 8 +- .../advanced-toolchain/session.jsonl | 28 +- examples/package.json | 1 - knip.json | 14 - packages/README.i18n.yaml | 4 +- packages/README.md | 2 +- packages/README.zh.md | 2 +- .../app-boot/tests/repository-cache.spec.ts | 218 ------ packages/bundle/base/README.i18n.yaml | 4 +- packages/bundle/base/README.md | 2 +- packages/bundle/base/README.zh.md | 2 +- packages/bundle/base/cordis.patch.yml | 7 - packages/bundle/base/package.json | 1 - packages/mcp/mcp-client/src/index.ts | 4 +- packages/self-modification/README.i18n.yaml | 4 +- packages/self-modification/README.md | 3 +- packages/self-modification/README.zh.md | 3 +- .../repository-plugin/README.i18n.yaml | 6 - .../repository-plugin/README.md | 128 ---- .../repository-plugin/README.zh.md | 128 ---- .../repository-plugin/package.json | 73 -- .../repository-plugin/src/bin.ts | 12 - .../repository-plugin/src/format.ts | 249 ------- .../repository-plugin/src/index.ts | 147 ---- .../repository-plugin/src/invariant.ts | 30 - .../repository-plugin/src/mcp.ts | 156 ---- .../repository-plugin/src/source.ts | 130 ---- .../tests/mcp-format.spec.ts | 121 ---- .../tests/repository-plugin.spec.ts | 676 ------------------ .../repository-plugin/tsconfig.json | 33 - .../repository-plugin/tsdown.config.ts | 17 - .../tool-cordis/README.i18n.yaml | 4 +- .../self-modification/tool-cordis/README.md | 2 +- .../tool-cordis/README.zh.md | 2 +- .../tool-cordis/src/index.ts | 2 +- packages/skill/skill-local/README.i18n.yaml | 4 +- packages/skill/skill-local/README.md | 2 +- packages/skill/skill-local/README.zh.md | 2 +- packages/skill/skill-local/src/index.ts | 5 +- pnpm-lock.yaml | 50 -- scripts/run-gates.spec.ts | 14 +- scripts/run-gates.ts | 17 +- tsconfig.host.json | 1 - vendor/README.md | 11 +- vendor/loader/package.json | 8 +- vendor/loader/src/repository.ts | 258 ------- vendor/loader/tsdown.config.ts | 2 - 100 files changed, 171 insertions(+), 3612 deletions(-) delete mode 100644 .agents/notes/implemented/architecture/2026-07-30-package-manager-native-repository-cache.i18n.yaml delete mode 100644 .agents/notes/implemented/architecture/2026-07-30-package-manager-native-repository-cache.md delete mode 100644 .agents/notes/implemented/architecture/2026-07-30-package-manager-native-repository-cache.zh.md delete mode 100644 .agents/notes/implemented/architecture/2026-07-30-static-repository-plugin-format.i18n.yaml delete mode 100644 .agents/notes/implemented/architecture/2026-07-30-static-repository-plugin-format.md delete mode 100644 .agents/notes/implemented/architecture/2026-07-30-static-repository-plugin-format.zh.md delete mode 100644 .agents/notes/implemented/architecture/2026-08-08-trusted-repository-package-code.i18n.yaml delete mode 100644 .agents/notes/implemented/architecture/2026-08-08-trusted-repository-package-code.md delete mode 100644 .agents/notes/implemented/architecture/2026-08-08-trusted-repository-package-code.zh.md delete mode 100644 .agents/notes/implemented/bug-fix/2026-08-08-npm-backed-git-repository-plugin-preparation.i18n.yaml delete mode 100644 .agents/notes/implemented/bug-fix/2026-08-08-npm-backed-git-repository-plugin-preparation.md delete mode 100644 .agents/notes/implemented/bug-fix/2026-08-08-npm-backed-git-repository-plugin-preparation.zh.md delete mode 100644 .agents/notes/implemented/feature/2026-07-30-config-only-repository-plugins.md delete mode 100644 .agents/notes/implemented/feature/2026-07-30-config-only-repository-plugins.zh.md rename .agents/notes/implemented/{feature/2026-07-30-config-only-repository-plugins.i18n.yaml => simplification/2026-08-09-remove-repository-plugin.i18n.yaml} (56%) create mode 100644 .agents/notes/implemented/simplification/2026-08-09-remove-repository-plugin.md create mode 100644 .agents/notes/implemented/simplification/2026-08-09-remove-repository-plugin.zh.md delete mode 100644 apps/cli/tests/fixtures/github-repository-plugin/.dsh-plugin/.mcp.json delete mode 100644 apps/cli/tests/fixtures/github-repository-plugin/.dsh-plugin/package.json delete mode 100644 apps/cli/tests/fixtures/github-repository-plugin/.dsh-plugin/src/mcp-server.ts delete mode 100644 apps/cli/tests/fixtures/github-repository-plugin/.dsh-plugin/src/plugin.ts delete mode 100644 apps/cli/tests/fixtures/github-repository-plugin/.dsh-plugin/tsconfig.json delete mode 100644 apps/cli/tests/fixtures/github-repository-plugin/skills/github-source-proof/SKILL.md delete mode 100644 apps/cli/tests/github-repository-plugin.built.e2e.ts delete mode 100644 examples/headless-agent/tests/fixtures/repository-plugin/dsh-plugin-assets/skills/0/repository-fixture/SKILL.md delete mode 100644 examples/headless-agent/tests/fixtures/repository-plugin/dsh-plugin.mjs delete mode 100644 examples/headless-agent/tests/fixtures/repository-plugin/load.mjs delete mode 100644 packages/boot/app-boot/tests/repository-cache.spec.ts delete mode 100644 packages/self-modification/repository-plugin/README.i18n.yaml delete mode 100644 packages/self-modification/repository-plugin/README.md delete mode 100644 packages/self-modification/repository-plugin/README.zh.md delete mode 100644 packages/self-modification/repository-plugin/package.json delete mode 100644 packages/self-modification/repository-plugin/src/bin.ts delete mode 100644 packages/self-modification/repository-plugin/src/format.ts delete mode 100644 packages/self-modification/repository-plugin/src/index.ts delete mode 100644 packages/self-modification/repository-plugin/src/invariant.ts delete mode 100644 packages/self-modification/repository-plugin/src/mcp.ts delete mode 100644 packages/self-modification/repository-plugin/src/source.ts delete mode 100644 packages/self-modification/repository-plugin/tests/mcp-format.spec.ts delete mode 100644 packages/self-modification/repository-plugin/tests/repository-plugin.spec.ts delete mode 100644 packages/self-modification/repository-plugin/tsconfig.json delete mode 100644 packages/self-modification/repository-plugin/tsdown.config.ts delete mode 100644 vendor/loader/src/repository.ts diff --git a/.agents/notes/implemented/architecture/2026-07-30-package-manager-native-repository-cache.i18n.yaml b/.agents/notes/implemented/architecture/2026-07-30-package-manager-native-repository-cache.i18n.yaml deleted file mode 100644 index df68353802..0000000000 --- a/.agents/notes/implemented/architecture/2026-07-30-package-manager-native-repository-cache.i18n.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each -# side as of the last confirmed-consistent state. Both languages carry equal authority; -# after editing either side, bring the other along and re-record with: -# pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-07-30-package-manager-native-repository-cache.md -2026-07-30-package-manager-native-repository-cache.md: 38e7356d4abfc8eba8854f0a96700da448ff4ac4 -2026-07-30-package-manager-native-repository-cache.zh.md: 6833eeb4279c9feb9ac1860e780b8ed58b09d334 diff --git a/.agents/notes/implemented/architecture/2026-07-30-package-manager-native-repository-cache.md b/.agents/notes/implemented/architecture/2026-07-30-package-manager-native-repository-cache.md deleted file mode 100644 index 38e7356d4a..0000000000 --- a/.agents/notes/implemented/architecture/2026-07-30-package-manager-native-repository-cache.md +++ /dev/null @@ -1,47 +0,0 @@ -# Agent Note: Package-manager-native repository cache - -Status: implemented - -English | [中文](2026-07-30-package-manager-native-repository-cache.zh.md) - -## Problem - -A standalone Harness app cannot rely on a developer-owned SDK project to declare and install repository dependencies. Loading a configured GitHub repository therefore needs a persistent fetch, preparation, and cache boundary, but implementing Git transport, hosted-source syntax, package preparation, and a content store inside DSH would duplicate a package manager. Requiring a separately installed package manager would make a config-only feature depend on host setup. - -The cache also needs an update identity. A mutable branch name cannot both remain permanently cached and reflect later commits without an independent refresh protocol. - -## Decision - -Vendored `@cordisjs/plugin-loader/repository` exports `RepositoryCache`, a generic Node-only package helper with no DSH plugin-format knowledge. Keeping it on a subpath prevents browser consumers of the Loader's main entry from traversing Node filesystem and child-process imports. The caller supplies a package-manager-native source specifier and a cache root. DSH-specific callers own accepted source syntax, path selection, and the cache-root location; the [SDK project dependency workflow](../../proposed/feature/2026-07-17-sdk-follow-up-capabilities.md#external-cordis-plugin-installation) remains a separate path owned by the developer project's selected package manager. - -The Loader carries an exact runtime dependency on `pnpm@11.7.0` and invokes that package's JavaScript entry with the current Node executable. It never discovers a global executable or delegates through Corepack. Each cache miss creates an isolated project with one dependency named `repository`; pnpm owns Git/GitHub resolution, fetching, its content-addressed store, dependency installation, and lifecycle scripts in the repository's dependency graph. - -The isolated workspace sets `dangerouslyAllowAllBuilds: true`. A configured repository and its dependency graph are trusted executable code: lifecycle scripts may run before DSH reads any declared assets. The child receives ordinary host process state needed by Git and pnpm, but ambient credential-shaped (`KEY`, `PASSWORD`, `SECRET`, `TOKEN`) variables are removed. No OAuth, token forwarding, or private-repository authentication contract is added. - -The SHA-256 of the exact specifier names the cache entry. Concurrent same-process requests share one task. Installation occurs in a sibling temporary directory; only a successful install with a package directory and marker is atomically renamed into the final key. Failed staging is removed, and a competing process's already-published valid entry wins. A later process validates the marker and package directory before returning the stable `node_modules/repository` path. - -An identical specifier permanently reuses its published entry. The caller changes the ref or another part of the specifier to request a new generation; the cache does not poll remotes, reinterpret mutable refs, expire entries, or garbage-collect old generations. - -## Alternatives considered - -**Implement GitHub download, archive extraction, preparation, and caching directly.** Rejected under the [dependency policy](../process/2026-07-26-dependencies-over-hand-rolling.md): pnpm already owns hosted Git syntax, Git execution, lifecycle policy, and a shared content store. A second resolver would add more code while still needing package semantics. - -**Require `pnpm` on `PATH` or invoke Corepack.** Rejected because changing one app config must be sufficient on every supported installation. Pinning and shipping the CLI also makes the preparation policy reviewable and independent of the host's package-manager version. - -**Resolve a branch or tag again on every startup.** Rejected because it turns startup into a network refresh, changes code without a config diff, and makes rollback depend on remote state. Explicit ref changes preserve auditability even when a user deliberately chooses a mutable ref. - -**Disable repository lifecycle scripts.** Rejected because common plugin repositories need a declarative `prepare` step to validate and package their plugin subdirectory. The trust boundary is explicit configuration of executable source, not an incomplete illusion that only static files can run. - -**Introduce a Cordis repository service.** Rejected because cache lookup has no runtime contribution registry or provider variation. A small helper lets the later host own Cordis lifecycle and HMR without adding a service contract prematurely. - -## Consequences - -- Standalone apps carry pnpm's approximately 18.6 MB unpacked runtime instead of requiring a global tool or owning a Git/package implementation. -- A repository author may use ordinary package preparation, and a malicious configured repository or dependency can execute code with the scrubbed child environment and the user's filesystem authority. -- Exact specifiers make startup deterministic after the first successful install; changing cached code requires a config/ref change. -- Failed installs leave no published cache entry and may be retried. Published corruption fails loud instead of silently reinstalling under the same identity. -- Cache generations consume disk until a future explicit cache-management policy removes them. - -## Testing - -`packages/boot/app-boot/tests/repository-cache.spec.ts` covers same-process single-flight, cross-instance cache reuse, exact-specifier separation, failed-stage cleanup and retry, and boundary validation. Its real local-Git case invokes the bundled pnpm, runs the fixture repository's `prepare` script, and reads the prepared file from the installed cache entry without network access. diff --git a/.agents/notes/implemented/architecture/2026-07-30-package-manager-native-repository-cache.zh.md b/.agents/notes/implemented/architecture/2026-07-30-package-manager-native-repository-cache.zh.md deleted file mode 100644 index 6833eeb427..0000000000 --- a/.agents/notes/implemented/architecture/2026-07-30-package-manager-native-repository-cache.zh.md +++ /dev/null @@ -1,47 +0,0 @@ -# Agent Note: 包管理器原生仓库缓存 - -Status: implemented - -[English](2026-07-30-package-manager-native-repository-cache.md) | 中文 - -## 问题 - -独立运行的 Harness 应用不能依赖开发者自有的 SDK 工程来声明并安装仓库依赖。因此,加载配置中的 GitHub 仓库需要一道持久的获取、准备与缓存边界;但如果在 DSH 内实现 Git 传输、托管来源语法、包准备流程和内容存储,就会重复实现包管理器。若要求用户另行安装包管理器,则只需修改配置即可使用的功能还会依赖宿主环境的额外配置。 - -缓存还需要明确更新标识。若没有独立的刷新协议,可变分支名无法既永久缓存,又反映后续 commit。 - -## 决策 - -vendor 中的 `@cordisjs/plugin-loader/repository` 导出 `RepositoryCache`:一个不包含 DSH 插件格式知识、仅限 Node 使用的通用包辅助工具。把它保留在子路径上,可以避免 Loader 主入口的浏览器消费方在解析依赖时遍历到 Node 文件系统和子进程 import。调用方提供包管理器原生的来源 specifier 和缓存根目录。DSH 专属调用方负责规定可接受的来源语法、路径选择与缓存根目录位置;[SDK 工程依赖工作流](../../proposed/feature/2026-07-17-sdk-follow-up-capabilities.md#external-cordis-plugin-installation)仍是另一条路径,由开发者工程选定的包管理器负责。 - -Loader 将 `pnpm@11.7.0` 作为固定版本的运行时依赖,并使用当前 Node 可执行文件调用该包的 JavaScript 入口。它绝不探测全局可执行文件,也不经 Corepack 调用。每次缓存未命中都会创建一个隔离工程,其中只有一个名为 `repository` 的依赖;Git 与 GitHub 来源的解析和获取、pnpm 自身的内容寻址 store、依赖安装,以及仓库依赖图中的生命周期脚本均由 pnpm 负责。 - -隔离工作区设置 `dangerouslyAllowAllBuilds: true`。用户配置的仓库及其依赖图都属于受信任的可执行代码:DSH 读取任何已声明资产之前,生命周期脚本就可能运行。子进程会收到 Git 与 pnpm 所需的常规宿主进程状态,但会移除环境中名称形似凭据(`KEY`、`PASSWORD`、`SECRET`、`TOKEN`)的变量。该机制不新增 OAuth、token 转发或私有仓库认证约定。 - -缓存项以精确 specifier 的 SHA-256 命名。同一进程内针对相同 specifier 的并发请求共享一项任务。安装在同级临时目录中进行;只有安装成功且存在包目录和标记时,系统才会把暂存目录原子重命名为最终键对应的目录。失败的暂存目录会被删除;如果另一进程已发布有效项,则以该项为准。后续进程会先校验标记与包目录,再返回稳定的 `node_modules/repository` 路径。 - -相同的 specifier 会永久复用已发布项。调用方通过修改 ref 或 specifier 的其他部分来请求新的缓存代次;缓存不会轮询远端、重新解释可变 ref、让条目过期,也不会垃圾回收旧代次。 - -## 曾考虑的替代方案 - -**直接实现 GitHub 下载、归档解压、准备与缓存。** 根据[依赖政策](../process/2026-07-26-dependencies-over-hand-rolling.md)不予采纳:pnpm 已负责托管 Git 语法、Git 执行、生命周期政策和共享内容存储。第二套解析器会增加更多代码,却仍需实现包语义。 - -**要求 `pnpm` 位于 `PATH` 上,或调用 Corepack。** 不予采纳:在每种受支持的安装形态中,只修改一份应用配置就必须足以启用该功能。固定并随应用分发 CLI(命令行界面)还能使准备政策可供评审,并与宿主的包管理器版本无关。 - -**每次启动都重新解析分支或 tag。** 不予采纳:这会把启动变成网络刷新,在配置 diff 未变化时更改代码,并让回滚依赖远端状态。即使用户有意选择可变 ref,显式修改 ref 仍能保持可审计性。 - -**禁用仓库生命周期脚本。** 不予采纳:常见插件仓库需要声明式 `prepare` 步骤来校验并打包插件子目录。信任边界是显式配置可执行来源,而不是营造一种不完整的假象,仿佛只有静态文件能够运行。 - -**引入 Cordis 仓库服务。** 不予采纳:缓存查找没有运行时贡献注册表,也不存在提供方变体。小型 helper 让后续宿主负责 Cordis 生命周期与 HMR(热模块替换),无需过早新增服务约定。 - -## 后果 - -- 独立应用随附 pnpm 约 18.6 MB 的解压后运行时,不要求全局工具,也无需自行实现 Git 与包处理。 -- 仓库作者可以使用常规包准备流程;恶意的已配置仓库或依赖可以在经过上述清理的子进程环境中,以用户的文件系统权限执行代码。 -- 精确 specifier 使首次安装成功后的启动具有确定性;更改缓存代码必须修改配置或 ref。 -- 安装失败不会留下已发布缓存项,可以再次重试。已发布缓存损坏时会明确报错,而不会在同一标识下静默重装。 -- 缓存代次会持续占用磁盘,直到未来有明确的缓存管理政策将其移除。 - -## 测试 - -`packages/boot/app-boot/tests/repository-cache.spec.ts` 覆盖同进程 single-flight、跨实例缓存复用、精确 specifier 隔离、失败暂存清理与重试,以及边界校验。其真实本地 Git 用例会调用随附的 pnpm,运行 fixture(测试前置数据)仓库的 `prepare` 脚本,并在不访问网络的情况下,从已安装缓存项中读取准备后的文件。 diff --git a/.agents/notes/implemented/architecture/2026-07-30-static-repository-plugin-format.i18n.yaml b/.agents/notes/implemented/architecture/2026-07-30-static-repository-plugin-format.i18n.yaml deleted file mode 100644 index ff9e0f5bbc..0000000000 --- a/.agents/notes/implemented/architecture/2026-07-30-static-repository-plugin-format.i18n.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each -# side as of the last confirmed-consistent state. Both languages carry equal authority; -# after editing either side, bring the other along and re-record with: -# pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-07-30-static-repository-plugin-format.md -2026-07-30-static-repository-plugin-format.md: c66ee111eb0cac9e0d6c54581855ffc18efc8611 -2026-07-30-static-repository-plugin-format.zh.md: c85aaf44d96098eb1ccb45456cce1a15e7408fc5 diff --git a/.agents/notes/implemented/architecture/2026-07-30-static-repository-plugin-format.md b/.agents/notes/implemented/architecture/2026-07-30-static-repository-plugin-format.md deleted file mode 100644 index c66ee111eb..0000000000 --- a/.agents/notes/implemented/architecture/2026-07-30-static-repository-plugin-format.md +++ /dev/null @@ -1,49 +0,0 @@ -# Agent Note: Static repository Plugin format - -Status: implemented - -English | [中文](2026-07-30-static-repository-plugin-format.zh.md) - -## Problem - -A repository that already contains reusable skills or an MCP server declaration should be usable by standalone Harness applications without becoming a Harness SDK project or rewriting its existing layout. Popular repositories must be able to add one `.dsh-plugin` directory while keeping their current skills and `.mcp.json` elsewhere in the tree. These portable static contributions still need to reuse the existing skill and MCP lifecycle owners when the same trusted package also carries native Cordis code. - -The [package-manager-native repository cache](2026-07-30-package-manager-native-repository-cache.md) prepares an exact package source but intentionally knows nothing about DSH formats. This layer therefore needs a package-manager-compatible authoring format, a deterministic prepared artifact, and a Cordis composition that stays transactional under Loader disposal and replacement. - -## Decision - -`@deepseek-ai/dsh-repository-plugin` owns the static contribution subformat inside a `.dsh-plugin` package: skill roots and one common `.mcp.json`. Its package metadata uses `package.json#dsh.skills` for relative skill-root paths and `package.json#dsh.mcpServers` for the relative MCP document path. Each path may leave `.dsh-plugin` to reuse repository content but must remain beneath the directory containing that `.dsh-plugin`; a nested selectable Plugin therefore owns the adjacent subtree above its package without gaining access to unrelated host paths. The package may additionally declare the explicit code entry owned by the [trusted repository package decision](2026-08-08-trusted-repository-package-code.md), and at least one code or static contribution is required. - -The `.dsh-plugin` package declares the published `@deepseek-ai/dsh-repository-plugin` package as a development dependency and a non-empty `scripts.prepack` that invokes its `dsh-plugin-prepare` executable. During Git installation, pnpm installs that dependency from the selected package's own manifest; `prepack` runs after dependency installation and before pnpm packs a selected subdirectory, including a Plugin nested inside another package-manager workspace. The package may build its code first. The helper validates metadata and source types, strictly parses `.mcp.json`, copies static assets into `dsh-plugin-assets`, and writes `dsh-plugin.mjs`; the source loader revalidates the installed package's helper-bearing lifecycle metadata before importing that wrapper. A static-only package still receives an import-free wrapper containing its normalized manifest, service-derived `inject` list, and delegation to the `dsh-repository-plugin` Loader builtin. The dependency and workspace-isolation rationale is in the [Git source preparation repair](../bug-fix/2026-08-08-npm-backed-git-repository-plugin-preparation.md). - -Loading the DSH package registers that builtin as an effect. A generated wrapper mounts the builtin as its child with `import.meta.url`, so all contributions belong to the wrapper fiber and disappear on Loader removal or rollback. The builtin revalidates the prepared manifest and path containment before reading assets. It composes the existing implementations rather than registering skills or MCP tools itself. - -Each prepared skill set mounts `dsh-skill-local` with a unique `repository:` provider name, only the copied custom roots, and watching disabled. `dsh-skill-local` therefore gains two general configuration fields: `providerName` and `includeDefaultRoots`. Their defaults preserve its existing single local provider; repository instances set a distinct name and exclude project/user roots so multiple instances neither collide nor duplicate host-local discovery. - -Each `.mcp.json` server becomes one existing `dsh-mcp-client` child. The adapter accepts the common root `{ "mcpServers": ... }`; stdio definitions allow only optional `type: "stdio"`, `command`, `args`, and `env`, while HTTP definitions allow only `type: "http"`, `url`, and `headers`. Exact `${NAME}` process-environment references expand at runtime, after cache preparation; missing names fail Plugin load. HTTP maps to the client's Streamable HTTP transport, and stdio uses the prepared package directory as `cwd`. The existing client alone owns connection attempts, failure logging, remote tool synchronization, tool calls, and disconnects. Repository instances enable strict startup, so an initial connection, discovery, or tool-registration failure rejects the repository Loader generation; non-strict standalone clients retain the logged successful-plugin/no-tools behavior. - -Unknown MCP fields reject. This intentionally excludes OAuth, `auth` objects, `CLAUDE_PLUGIN_ROOT`, and a broader Claude compatibility contract. Commands, hooks, agents, rules, and other foreign manifest conventions are not inferred from static repository layout; DSH-native behavior uses the explicit trusted Cordis entry. Repository subdirectory selection and GitHub source configuration belong to the [standalone app integration](../feature/2026-07-30-config-only-repository-plugins.md), not this static adapter. - -## Alternatives considered - -**Discover an entry from `main`, `exports`, or repository layout.** Rejected because static assets do not imply that a package's ordinary entry is a Cordis Plugin. Trusted code loading is explicit through `dsh.entry` and remains outside this static adapter's ownership. - -**Teach generated wrappers to implement skills and MCP directly.** Rejected because copied runtime code would drift from `dsh-skill-local` and `dsh-mcp-client`, especially their provider invalidation, tool synchronization, failure, and teardown contracts. - -**Import Harness packages from each generated wrapper.** Rejected because repository packages should not resolve or version the application's internal dependency graph. A Loader builtin supplies one app-owned implementation and keeps generated wrappers import-free. - -**Watch prepared repository assets.** Rejected because an exact repository cache generation is immutable. Ref, subdirectory, or configuration changes select a new generation; a second watcher would create an unowned refresh identity. - -**Make every MCP connect failure a Loader update failure.** Rejected because optional standalone MCP clients deliberately contain startup failures and expose no tools. The MCP client instead owns an explicit strict-startup option, which repository adapters enable for their declared servers. - -## Consequences - -- Existing skill/MCP repositories can add a small `.dsh-plugin/package.json` without relocating their assets or adopting an SDK project. -- Prepared static output is deterministic glue, while an optional `dsh.entry` and the configured repository lifecycle remain trusted executable package-manager input rather than a sandbox. -- Multiple repository Plugins coexist through provider names and ordinary MCP server-name uniqueness; duplicate names fail through their existing registries and participate in Loader rollback. -- Cached source edits do not appear live. Another exact source/ref/path/config selection is required. -- Adding another portable static contribution kind requires an explicit format and DSH-owned runtime consumer; DSH-native behavior uses the separate explicit code entry. - -## Testing - -Focused tests prepare skills and MCP metadata, prove a static-only wrapper contains no imports, reject Work IQ-style OAuth fields, map Expo-style HTTP and DataJunction-style stdio plus environment values, and exercise missing variables. A real Loader test mounts a generated wrapper through the registered builtin, reads its skill through `ctx.skills`, removes the Loader entry, and observes provider cleanup. The CI built-entry acceptance invokes `dsh run` with a GitHub source pinned to the pull request head and observes the copied skill alongside the trusted code and MCP proofs owned by the superseding decision. diff --git a/.agents/notes/implemented/architecture/2026-07-30-static-repository-plugin-format.zh.md b/.agents/notes/implemented/architecture/2026-07-30-static-repository-plugin-format.zh.md deleted file mode 100644 index c85aaf44d9..0000000000 --- a/.agents/notes/implemented/architecture/2026-07-30-static-repository-plugin-format.zh.md +++ /dev/null @@ -1,49 +0,0 @@ -# Agent Note: 静态 repository Plugin 格式 - -状态:已实现 - -[English](2026-07-30-static-repository-plugin-format.md) | 中文 - -## 问题 - -一个已经包含可复用 skills 或 MCP server 声明的仓库,应当能被独立 Harness 应用使用,而不必先变成 Harness SDK 项目,也不应被迫改写现有布局。常见仓库只需新增一个 `.dsh-plugin` 目录,同时仍可把原有 skills 与 `.mcp.json` 放在仓库其他位置。当同一个受信任包还携带原生 Cordis 代码时,这些可移植静态贡献仍需复用现有的 skill 与 MCP 生命周期所有者。 - -[Package-manager-native repository cache](2026-07-30-package-manager-native-repository-cache.md) 会准备一个精确 package source,但有意不了解任何 DSH 格式。因此本层需要一种兼容 package manager 的创作格式、确定性的已准备产物,以及在 Loader dispose 和替换期间仍保持事务性的 Cordis 组合。 - -## 决策 - -`@deepseek-ai/dsh-repository-plugin` 负责 `.dsh-plugin` 包内的静态贡献子格式:skill 根和一个通用 `.mcp.json`。其包元数据使用 `package.json#dsh.skills` 声明相对 skill 根路径,使用 `package.json#dsh.mcpServers` 声明相对 MCP 文档路径。每条路径都可以离开 `.dsh-plugin` 以复用仓库内容,但必须留在包含该 `.dsh-plugin` 的目录之下;因此,一个嵌套且可选择的插件可以拥有其包上方相邻的子树,却不能访问无关宿主路径。该包还可以声明由[受信任 repository 包决策](2026-08-08-trusted-repository-package-code.md)负责的显式代码入口,并且至少需要一种代码或静态贡献。 - -`.dsh-plugin` 包将已发布的 `@deepseek-ai/dsh-repository-plugin` 包声明为开发依赖,并声明非空 `scripts.prepack` 来调用其 `dsh-plugin-prepare` 可执行文件。在 Git 安装期间,pnpm 会按所选包自身的 manifest(元数据清单)安装该依赖;`prepack` 会在依赖安装后、pnpm 打包选定子目录前运行,即使插件嵌套在另一个包管理器工作区内也不例外。包可以先构建其代码。该辅助程序会校验元数据与源码类型,严格解析 `.mcp.json`,把静态资源复制到 `dsh-plugin-assets`,并写入 `dsh-plugin.mjs`;源码 loader 会在导入该包装层前重新校验已安装包的生命周期元数据是否包含辅助命令。仅含静态贡献的包仍会获得无 import 包装层,其中包含规范化 manifest、由服务派生的 `inject` 列表,以及对 `dsh-repository-plugin` Loader builtin 的委托。依赖与 workspace 隔离的设计依据见[Git 源准备修复](../bug-fix/2026-08-08-npm-backed-git-repository-plugin-preparation.md)。 - -加载 DSH package 会以 effect 方式注册该 builtin。生成的包装模块使用 `import.meta.url` 把 builtin 挂载为自己的子级,因此所有贡献都归属于包装 fiber,并在 Loader 移除或回滚时消失。Builtin 会在读取资源前重新校验已准备 manifest 与路径包含关系。它只组合现有实现,而不自行注册 skills 或 MCP 工具。 - -每份已准备 skill 集合都会挂载 `dsh-skill-local`,使用唯一的 `repository:` 提供方名称、仅包含复制后的自定义根,并禁用监视。因此 `dsh-skill-local` 新增两个通用配置字段:`providerName` 和 `includeDefaultRoots`。默认值保持原有单一本地提供方行为;repository 实例设置不同名称并排除项目/用户根,使多个实例既不冲突,也不会重复宿主本地发现。 - -`.mcp.json` 中的每个 server 都变成一个现有 `dsh-mcp-client` 子级。适配层接受通用根对象 `{ "mcpServers": ... }`;stdio 定义只允许可选的 `type: "stdio"`、`command`、`args` 与 `env`,HTTP 定义只允许 `type: "http"`、`url` 与 `headers`。严格的 `${NAME}` 进程环境变量引用在运行时、cache 准备之后展开;缺失变量会使 Plugin 加载失败。HTTP 映射到 client 的 Streamable HTTP transport,stdio 使用已准备 package 目录作为 `cwd`。只有现有 client 负责连接尝试、失败日志、远端工具同步、工具调用和断开。Repository 实例会启用严格启动,因此初始连接、发现或工具注册失败会拒绝 repository Loader generation;非严格的独立 client 则保留“记录日志、Plugin 成功但不注册工具”的行为。 - -未知 MCP 字段会被拒绝。这里有意排除 OAuth、`auth` 对象、`CLAUDE_PLUGIN_ROOT` 和更广泛的 Claude 兼容约定。命令、hook、agent(智能体)、规则和其他外来 manifest 约定不会从静态 repository 布局中推断出来;DSH 原生行为使用显式的受信任 Cordis 入口。Repository 子目录选择与 GitHub 源配置属于[独立应用集成](../feature/2026-07-30-config-only-repository-plugins.md),而不是本静态适配器。 - -## 考虑过的替代方案 - -**从 `main`、`exports` 或 repository 布局中发现入口。** 拒绝,因为静态资源并不表示包的普通入口就是 Cordis 插件。受信任代码通过 `dsh.entry` 显式加载,不属于该静态适配器的职责。 - -**让生成包装模块直接实现 skills 和 MCP。** 拒绝,因为复制的运行时代码会与 `dsh-skill-local` 和 `dsh-mcp-client` 漂移,尤其是提供方失效、工具同步、失败和 teardown 约定。 - -**让每个生成包装模块 import Harness package。** 拒绝,因为 repository package 不应解析或锁定应用的内部依赖图。Loader builtin 提供一份由 app 所有的实现,并让生成包装模块保持无 import。 - -**监视已准备 repository 资源。** 拒绝,因为一个精确 repository cache generation 是不可变的。Ref、子目录或配置变化会选择新 generation;第二套 watcher 会创造一套没有所有者的刷新身份。 - -**把每次 MCP 连接失败都当作 Loader 更新失败。** 拒绝,因为可选的独立 MCP client 会有意收束启动失败,并且不暴露工具。MCP client 改为自行提供显式的严格启动选项,由 repository 适配器为其声明的 server 启用。 - -## 后果 - -- 现有 skill/MCP 仓库可以新增一个很小的 `.dsh-plugin/package.json`,无需移动资源或采用 SDK 项目。 -- 已准备的静态输出是确定性胶水;可选的 `dsh.entry` 和已配置的 repository 生命周期仍是受信任的可执行包管理器输入,而非沙箱。 -- 多个 repository Plugin 通过提供方名称和普通 MCP server-name 唯一性共存;重复名称经现有 registry 失败,并参与 Loader 回滚。 -- Cache 内的源码编辑不会实时出现;必须选择另一个精确 source/ref/path/config。 -- 新增可移植静态贡献类型必须提供显式格式和 DSH 自有运行时消费方;DSH 原生行为使用独立的显式代码入口。 - -## 测试 - -聚焦测试会准备 skill 与 MCP 元数据,证明仅含静态贡献的包装模块不含 import,拒绝 Work IQ 风格的 OAuth 字段,映射 Expo 风格 HTTP 与 DataJunction 风格 stdio 及环境变量,并覆盖缺失变量。真实 Loader 测试通过已注册 builtin 挂载生成包装模块,经 `ctx.skills` 读取其 skill,移除 Loader 条目并观察提供方清理。CI 构建入口验收会使用锁定到 PR(Pull Request)head 的 GitHub 源调用 `dsh run`,并观察已复制的 skill,以及由取代本决策的新决策所负责的受信任代码与 MCP 验证证据。 diff --git a/.agents/notes/implemented/architecture/2026-08-08-trusted-repository-package-code.i18n.yaml b/.agents/notes/implemented/architecture/2026-08-08-trusted-repository-package-code.i18n.yaml deleted file mode 100644 index 9d49d8b1c2..0000000000 --- a/.agents/notes/implemented/architecture/2026-08-08-trusted-repository-package-code.i18n.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each -# side as of the last confirmed-consistent state. Both languages carry equal authority; -# after editing either side, bring the other along and re-record with: -# pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-08-08-trusted-repository-package-code.md -2026-08-08-trusted-repository-package-code.md: 387479b3b36a8bc5e145641ae40802b3090ced70 -2026-08-08-trusted-repository-package-code.zh.md: ecc325c3dd0a9e823f1411c3a809c30ada486289 diff --git a/.agents/notes/implemented/architecture/2026-08-08-trusted-repository-package-code.md b/.agents/notes/implemented/architecture/2026-08-08-trusted-repository-package-code.md deleted file mode 100644 index 387479b3b3..0000000000 --- a/.agents/notes/implemented/architecture/2026-08-08-trusted-repository-package-code.md +++ /dev/null @@ -1,51 +0,0 @@ -# Agent Note: Trusted repository packages load Cordis code - -Status: implemented - -English | [中文](2026-08-08-trusted-repository-package-code.zh.md) - -## Problem - -The standalone repository format already installs a selected Git package and runs its dependency and lifecycle code with host authority, but it exposed only copied skills and MCP metadata to DSH. Forbidding a Cordis entry did not create a security boundary: package installation remained trusted executable code while the restriction prevented the package from contributing the Plugin behavior that the Harness architecture is designed to compose. - -A repository author also needs to keep an ordinary TypeScript npm package shape. Requiring publication to npm, pre-generated JavaScript in Git, or a DSH-owned TypeScript compiler would make a Git source less capable than the same package installed through a developer-owned SDK project. The first model request must observe any MCP tools that this package starts; background-only initial discovery makes a successful installation nondeterministic at the application boundary. - -## Decision - -A configured repository package is trusted code. Its `.dsh-plugin/package.json` may declare `dsh.entry` as a relative path to a compiled ESM Cordis Plugin inside that package, alongside or instead of `dsh.skills` and `dsh.mcpServers`. At least one contribution is required. The entry may use namespace exports or a default export and retains ordinary Cordis semantics for `name`, `inject`, `Config`, registrations, startup failure, and effect-scoped teardown. - -The package owns its npm dependencies and build toolchain. It declares the published `@deepseek-ai/dsh-repository-plugin` package to obtain the `dsh-plugin-prepare` executable. `scripts.prepack` is a non-empty package-authored command that must invoke that dependency-provided helper, but it may first run `tsc`, `tsdown`, or any other build. DSH neither injects the helper, parses the shell program, nor compiles repository source. The helper validates the metadata after the preceding build, requires the configured entry to resolve to a file within `.dsh-plugin`, validates and copies declared static assets, and writes the prepared `dsh-plugin.mjs` wrapper. The installed package must retain a `prepack` declaration containing that helper command; a missing dependency, wrapper, or build output fails before a cache generation becomes usable. - -The generated wrapper first mounts the DSH-owned static runtime for skills and MCP definitions, then dynamically imports and unwraps the explicit entry and mounts it as a child. The wrapper statically declares dependencies implied by the prepared manifest; an entry module's additional `inject` is discovered only when mounted and must already be available in the host composition. Both children must reach Cordis `ACTIVE`; an unsatisfied `inject` or startup exception rejects the repository Loader transaction instead of committing an inert generation. Loader removal, failed replacement, and parent disposal unwind the entry, skill providers, MCP clients, and their effects together. - -`dsh-mcp-client` resolves its initial connection and tool synchronization promise as part of Plugin application. Its entry is an `async function`, not an ordinary function returning a Promise: Cordis identifies prototype-bearing ordinary functions as constructors and does not treat a constructor's returned Promise as startup work. A valid server's tools therefore exist before its parent repository wrapper activates and before a one-shot application starts its first model request. Its `failOnStartupError` config preserves optional standalone servers by default while letting repository adapters require their declared servers. Repository-translated MCP clients enable that mode, so initial connection, discovery, or tool-registration failure rejects the candidate generation and rollback still closes the transport. - -## Trust boundary - -Exact refs, source containment, credential-shaped environment scrubbing, prepared manifests, and immutable cache keys protect identity and composition integrity; they do not sandbox executable package input. Repository lifecycle scripts, transitive npm dependencies, the compiled entry, and spawned MCP servers can exercise the authority available to the DSH process and the Cordis services they receive. Users must therefore trust the selected repository and should pin immutable refs and grant Git only the narrow read credential needed for acquisition. - -Model-visible behavior remains governed by the owning DSH seam. A repository entry may register tools, prompt sections, policies, commands, agents, or other effects, but anything reaching a model request still needs the corresponding logged DSH representation and lifecycle cleanup. The repository format grants code loading; it does not weaken those service contracts. - -## Alternatives considered - -**Keep code forbidden while allowing arbitrary package lifecycles.** Rejected because installation already executes trusted repository code, so the restriction added no isolation and forced Plugin authors to publish or maintain a second integration path. - -**Have DSH compile repository TypeScript.** Rejected because compiler choice, module layout, generated chunks, native dependencies, and package metadata belong to the npm package. Running the package's declared build preserves the same boundary as other Git dependencies. - -**Import `main`, `exports`, or another discovered entry implicitly.** Rejected because an npm package may contain utilities or an MCP executable that is not a Cordis Plugin. The explicit `dsh.entry` field makes code activation reviewable and lets preparation validate the packed path. - -**Add a closed manifest field for every future DSH contribution.** Rejected as the universal extension mechanism. Skills and common MCP files retain useful portable static adapters, while DSH-native behavior composes through the existing Cordis Plugin and service contracts. - -## Consequences - -- A TypeScript DSH Plugin can live in a GitHub repository, install ordinary npm dependencies, compile during `prepack`, and run without publishing the Plugin package to npm. -- Static-only repository packages remain valid and retain import-free wrappers; adding `dsh.entry` opts that package into runtime code import. -- A package build, dependency install, entry import, unmet service, or Plugin startup failure prevents the candidate generation from replacing the last good configuration. -- Initial MCP synchronization can lengthen application startup by the MCP SDK's per-request timeout, and a repository-declared server that is unavailable or cannot publish its complete tool generation prevents that candidate generation from activating. -- Repository code receives host authority, so source review and immutable pinning are operational security requirements rather than optional hardening. - -## Testing - -Repository-format tests prepare and mount default-export code entries through the real Loader, observe an entry-owned service, remove the Loader row, and observe cleanup; they also retain skill/MCP preparation, containment, damaged-package, pending-service, and rollback coverage. MCP lifecycle tests require `apply` to settle only after initial tool publication, preserve opt-in contained startup failure, and prove strict connection or tool-registration rejection still closes the client. - -The Node 24 consumer acceptance uses the actual built `dsh run` command with a fresh DSH home and an authenticated private GitHub source pinned to the pull request's exact head SHA. The test packs the current repository Plugin build with the same private-field removal and workspace-dependency pinning used for publication, serves its packument and tarball from a job-local npm registry, and directs the Git package's ordinary scoped npm resolution there. That repository package obtains `dsh-plugin-prepare` from the simulated published dependency, installs its other pinned runtime and development dependencies, type-checks and bundles TypeScript during `prepack`, prepares a skill plus a stdio MCP server and `dsh.entry`, exposes the skill and MCP schema in the first real model request, executes the MCP tool, and lets the compiled Cordis entry append a second marker to the result observed in the following request. Registry and cache assertions require npm resolution to reach the simulated publication, source files to be absent from the packed installation, and both built modules, their installed dependency, copied assets, and generated wrapper to be present. diff --git a/.agents/notes/implemented/architecture/2026-08-08-trusted-repository-package-code.zh.md b/.agents/notes/implemented/architecture/2026-08-08-trusted-repository-package-code.zh.md deleted file mode 100644 index ecc325c3dd..0000000000 --- a/.agents/notes/implemented/architecture/2026-08-08-trusted-repository-package-code.zh.md +++ /dev/null @@ -1,51 +0,0 @@ -# Agent Note: 受信任 repository 包加载 Cordis 代码 - -状态:已实现 - -[English](2026-08-08-trusted-repository-package-code.md) | 中文 - -## 问题 - -独立 repository 格式已经会安装选定的 Git 包,并以宿主权限运行其依赖和生命周期代码,但它向 DSH 暴露的只有复制后的 skill(技能)和 MCP 元数据。禁止 Cordis 入口并未建立安全边界:包安装过程仍会执行受信任代码,而这项限制却阻止包贡献 Harness 架构本就用于组合的插件行为。 - -仓库作者还需要保持普通 TypeScript NPM 包的结构。如果要求发布到 NPM、把预生成的 JavaScript 签入 Git,或使用 DSH 自有的 TypeScript 编译器,Git 源的能力就会弱于通过开发者自有 SDK 项目安装的同一个包。首个模型请求必须看到该包启动的所有 MCP 工具;仅在后台进行初始发现,会让一次成功安装在应用边界上具有不确定性。 - -## 决策 - -已配置的 repository 包是受信任代码。其 `.dsh-plugin/package.json` 可以连同 `dsh.skills` 和 `dsh.mcpServers` 声明 `dsh.entry`,也可以用它取代二者;`dsh.entry` 是指向该包内已编译 ESM Cordis 插件的相对路径。至少需要一种贡献。入口可以使用 namespace 导出或 default export,并沿用 Cordis 对 `name`、`inject`、`Config`、注册、启动失败和 effect 作用域清理的常规语义。 - -包自行负责其 NPM 依赖和构建工具链。它声明已发布的 `@deepseek-ai/dsh-repository-plugin` 包以取得 `dsh-plugin-prepare` 可执行文件。`scripts.prepack` 是由包作者编写的非空命令,必须调用该依赖提供的辅助程序,但可以先运行 `tsc`、`tsdown` 或其他任意构建。DSH 不会注入辅助程序,也不会解析该 shell 程序或编译 repository 源码。辅助程序会在前序构建之后校验元数据,要求已配置入口解析到 `.dsh-plugin` 内的文件,校验并复制已声明的静态资源,再写入已准备的 `dsh-plugin.mjs` 包装层。已安装包必须保留包含该辅助命令的 `prepack` 声明;依赖、包装层或构建输出缺失会在缓存 generation 可用前导致失败。 - -生成的包装层先挂载 DSH 自有的静态运行时来处理 skill 和 MCP 定义,再动态导入显式入口、解包其导出并将其挂载为子级。包装层会静态声明已准备 manifest(元数据清单)所隐含的依赖;入口模块的额外 `inject` 只有在挂载时才会被发现,并且此时必须已存在于宿主组合中。两个子级都必须进入 Cordis `ACTIVE`;无法满足的 `inject` 或启动异常会拒绝 repository Loader 事务,而不会提交未激活的 generation。Loader 移除、替换失败和父级 dispose(资源释放)会一并撤销入口、skill 提供方、MCP client 及其 effect。 - -`dsh-mcp-client` 会在插件应用期间完成其初始连接和工具同步 promise。其入口必须是 `async function`,而不是返回 Promise 的普通函数:Cordis 会把带 prototype 的普通函数识别为 constructor,不会把 constructor 返回的 Promise 当作启动工作。因此,有效 server 的工具会在父级 repository 包装层激活前、一次性应用发起首个模型请求前就已存在。其 `failOnStartupError` 配置默认保留独立可选 server 的行为,同时允许 repository adapter 要求已声明 server 必须可用。Repository 转换出的 MCP client 会启用该模式,因此初始连接、发现或工具注册失败会拒绝候选 generation,回滚仍会关闭 transport。 - -## 信任边界 - -精确 ref、源路径包含约束、清除名称符合凭据模式的环境变量、已准备的 manifest 和不可变缓存键,可以保护身份与组合完整性;它们不会为可执行包输入提供沙箱隔离。Repository 生命周期脚本、传递性 NPM 依赖、已编译入口和 spawn 的 MCP server 可以行使 DSH 进程可用的权限,以及它们所获 Cordis 服务授予的权限。因此,用户必须信任所选仓库,应当固定不可变 ref,并只授予 Git 获取源码所需的最小只读凭据。 - -模型可见行为仍由所属 DSH seam 管理。repository 入口可以注册工具、提示词段落、策略、命令、agent(智能体)或其他 effect,但任何进入模型请求的内容仍须具有对应的 DSH 日志表示和生命周期清理。repository 格式授予代码加载能力;它不会削弱这些服务约定。 - -## 考虑过的替代方案 - -**继续禁止代码,但允许任意包生命周期。** 拒绝,因为安装过程本就执行受信任的 repository 代码,所以该限制没有提供隔离,反而迫使插件作者发布或维护第二条集成路径。 - -**由 DSH 编译 repository TypeScript。** 拒绝,因为编译器选择、模块布局、生成分片、原生依赖和包元数据属于 NPM 包。运行包所声明的构建,可以保持与其他 Git 依赖相同的边界。 - -**隐式导入 `main`、`exports` 或其他发现的入口。** 拒绝,因为 NPM 包可能包含并非 Cordis 插件的实用工具或 MCP 可执行文件。显式 `dsh.entry` 字段使代码激活可供评审,并让准备阶段校验打包后的路径。 - -**为未来每种 DSH 贡献添加封闭 manifest 字段。** 不采用它作为通用扩展机制。skill 和通用 MCP 文件仍保留有用的可移植静态适配器;DSH 原生行为则通过现有 Cordis 插件与服务约定组合。 - -## 后果 - -- TypeScript DSH 插件可以存放在 GitHub 仓库中,安装普通 NPM 依赖,在 `prepack` 期间完成编译,并在无需把插件包发布到 NPM 的情况下运行。 -- 仅含静态贡献的 repository 包仍然有效,并保留无 import 包装层;添加 `dsh.entry` 会使该包选择启用运行时代码导入。 -- 包构建、依赖安装、入口导入、所需服务未满足或插件启动失败,都会阻止候选 generation 替换最后一个可用配置。 -- 初始 MCP 同步可能因 MCP SDK 的单次请求超时而延长应用启动时间;repository 声明的 server 不可用或无法发布完整工具 generation 时,该候选 generation 无法激活。 -- Repository 代码获得宿主权限,因此源码评审和锁定不可变 ref 是运行安全要求,而不是可选加固措施。 - -## 测试 - -repository 格式测试通过真实 Loader 准备并挂载使用 default export 的代码入口,观察入口自有服务,移除 Loader 配置项,再观察清理;测试还保留针对 skill/MCP 准备、路径包含约束、包损坏、等待服务和回滚的覆盖。MCP 生命周期测试要求 `apply` 只在初始工具发布后完成,保留可选择启用的启动失败收束行为,并证明严格连接拒绝或工具注册拒绝仍会关闭 client。 - -Node 24 消费方验收使用实际构建的 `dsh run` 命令、全新 DSH 主目录,以及锁定到 PR(Pull Request)的精确 head SHA 且经过认证的私有 GitHub 源。测试会采用发布时相同的移除 `private` 字段和固定 workspace 依赖版本流程,对当前 repository 插件构建进行打包;再由作业本地 NPM 注册表提供其 `packument` 与 tarball,并把 Git 包的常规 scoped NPM 解析指向该注册表。该 repository 包从模拟发布的依赖取得 `dsh-plugin-prepare`,安装其他固定版本的运行时依赖与开发依赖,在 `prepack` 期间对 TypeScript 进行类型检查和打包,准备一个 skill、一个 stdio MCP server 及 `dsh.entry`,在首个真实模型请求中暴露 skill 与 MCP schema,执行 MCP 工具,并让已编译 Cordis 入口向结果追加第二个标记,供后续请求观察。注册表与缓存断言要求 NPM 解析必须命中模拟发布,打包安装中不存在源码文件,同时必须存在两个已构建模块、其已安装依赖、复制资源和生成包装层。 diff --git a/.agents/notes/implemented/bug-fix/2026-08-08-npm-backed-git-repository-plugin-preparation.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-08-08-npm-backed-git-repository-plugin-preparation.i18n.yaml deleted file mode 100644 index 86e63238fa..0000000000 --- a/.agents/notes/implemented/bug-fix/2026-08-08-npm-backed-git-repository-plugin-preparation.i18n.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each -# side as of the last confirmed-consistent state. Both languages carry equal authority; -# after editing either side, bring the other along and re-record with: -# pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-08-08-npm-backed-git-repository-plugin-preparation.md -2026-08-08-npm-backed-git-repository-plugin-preparation.md: 958b932f82f4da3cf63aa911260411855e514409 -2026-08-08-npm-backed-git-repository-plugin-preparation.zh.md: d2256e0eae303c371371b9b5ba1967105aa61834 diff --git a/.agents/notes/implemented/bug-fix/2026-08-08-npm-backed-git-repository-plugin-preparation.md b/.agents/notes/implemented/bug-fix/2026-08-08-npm-backed-git-repository-plugin-preparation.md deleted file mode 100644 index 958b932f82..0000000000 --- a/.agents/notes/implemented/bug-fix/2026-08-08-npm-backed-git-repository-plugin-preparation.md +++ /dev/null @@ -1,48 +0,0 @@ -# Agent Note: npm-backed preparation makes GitHub repository Plugins self-contained - -Status: implemented - -English | [中文](2026-08-08-npm-backed-git-repository-plugin-preparation.zh.md) - -## Problem - -The repository Plugin authoring contract requires `scripts.prepack` to invoke `dsh-plugin-prepare`. Supplying that executable from the running DSH installation made a source package appear valid even when its own manifest could not obtain the helper. It therefore did not prove the behavior users need after `@deepseek-ai/dsh-repository-plugin` is published: an ordinary Git-hosted npm package must be installable and preparable from only its declared dependencies. - -A selectable `.dsh-plugin` inside a pnpm workspace has a second isolation requirement. pnpm prepares a Git-hosted package by running the repository's preferred package manager before packing the selected subdirectory. A nested `pnpm install` can join the containing workspace; when the root lockfile does not list `.dsh-plugin` as an importer, pnpm can report success without installing dependencies declared only by that package. Its TypeScript build or prepare command then fails, or a pre-generated artifact hides the missing dependency. - -The checked-in headless fixture mounts an already prepared wrapper. It proves runtime composition, not GitHub acquisition, npm resolution, or package-owned preparation. - -## Decision - -The `.dsh-plugin` package declares `@deepseek-ai/dsh-repository-plugin` as an ordinary development dependency and invokes its published `dsh-plugin-prepare` executable from `scripts.prepack`. The package may declare any other build and runtime dependencies and run arbitrary compilation before the helper. The repository Plugin package marks its Cordis and DSH peers optional so a helper-only development install resolves only the helper's actual `zod` runtime dependency; an application composition still supplies the peers used by the package's Cordis entry. - -DSH does not materialize or prepend a prepare executable. `RepositoryCache` supplies only a transaction-owned `pnpm` wrapper: the outer install runs the pinned pnpm entry directly, while pnpm's hard-coded Git-package `pnpm install` reinvokes the same entry with `--ignore-workspace`. The selected package therefore owns dependency resolution even beneath another pnpm lockfile, and normal package-manager lifecycle `PATH` construction exposes `node_modules/.bin/dsh-plugin-prepare`. The temporary pnpm wrapper disappears after the child settles. The repository remains trusted package-manager input: all dependency and lifecycle code executes under the existing trust contract. - -The Node 24 consumer lane passes an exact source derived from the pull request head repository and SHA. It uses the existing private DeepSeek Harness repository rather than creating another repository per run. A job-scoped Git configuration gives the read-only job token access to that exact private source and rewrites pnpm's SSH fallback to authenticated HTTPS. - -The built-entry acceptance also creates an in-process npm registry. It stages the current built `@deepseek-ai/dsh-repository-plugin` as a publication artifact by removing `private`, replacing workspace protocols with the release version, and packing the declared files. The registry serves the resulting packument and tarball, while a job-local npm config directs only the `@deepseek-ai` scope to it. The real built `dsh run` child then fetches the exact Git source; that package resolves the helper through npm, type-checks and bundles a TypeScript Cordis entry and MCP server, prepares the adjacent skill, and loads all three contributions. A deliberately failing host `PATH` command proves the lifecycle selected the dependency-local executable. The acceptance also requires registry resolution and inspects the immutable prepared cache, so restoring a host-injected helper cannot satisfy it. - -## Alternatives considered - -**Inject `dsh-plugin-prepare` from the running DSH installation.** Rejected because it lets an incomplete repository manifest pass and tests a host-only path that npm consumers cannot reproduce. - -**Publish the source fixture itself to npm.** Rejected because the product contract is specifically that the DSH Plugin remains Git-hosted; only the reusable preparation helper is an npm dependency. - -**Create a new private GitHub repository in every CI run.** Rejected because the pull request repository at its exact head SHA is already a real authenticated private Git remote. Per-run repository mutation would add credentials, cleanup, and eventual-consistency failure modes without changing the acquisition path. - -**Prepare after `RepositoryCache` installs the selected package.** Rejected because pnpm's packed subdirectory no longer contains sibling source assets referenced by paths such as `../skills`; preparation must happen before packlist. - -**Clone GitHub repositories in DSH and bypass pnpm's Git fetcher.** Rejected because it would duplicate ref resolution, subdirectory selection, dependency installation, packlist behavior, and cache integrity already owned by the pinned package manager. - -## Consequences - -- A repository author can commit a `.dsh-plugin` package, TypeScript source, skills, and MCP definitions to GitHub without publishing that Plugin package to npm. The package must declare the published preparation dependency. -- Private GitHub sources use the host's standard Git authentication. CI proves that path with a temporary read-only configuration rather than persistent runner credentials. -- `prepack`, not `prepare`, is part of the authoring format. It may contain arbitrary package-owned build steps but must invoke the dependency-provided helper; missing dependency or lifecycle metadata fails before a cache generation is usable. -- A selected package in a pnpm repository installs from its own manifest rather than an enclosing workspace. It cannot rely on workspace-only hoisting; ordinary registry and relative `file:` dependencies remain package-owned inputs. -- Exact source strings identify immutable cache generations; a changed ref or source configuration selects another generation. -- Package dependencies, compilation, preparation, and the trusted `dsh.entry` contribution remain owned by the repository package and the [trusted-code decision](../architecture/2026-08-08-trusted-repository-package-code.md). - -## Testing - -`packages/boot/app-boot/tests/repository-cache.spec.ts` runs a package excluded from its source repository's root pnpm lockfile through a local Git subpath and requires relative `file:` dependencies to provide both its build command and `dsh-plugin-prepare`; it also proves that visible environment survives while credential-shaped variables are scrubbed. `packages/self-modification/repository-plugin/tests/repository-plugin.spec.ts` pins helper-bearing `prepack` metadata and preparation output. `examples/headless-agent/tests/keyless-smoke.e2e.ts` keeps the checked-in prepared fixture on that source contract. `apps/cli/tests/github-repository-plugin.built.e2e.ts` is the product acceptance: simulated published helper package, job-local npm registry, fresh DSH home, exact authenticated private GitHub source, actual built `dsh run`, package-owned TypeScript build, real MCP execution, code-entry transformation, mock LLM request observation, and prepared cache inspection. diff --git a/.agents/notes/implemented/bug-fix/2026-08-08-npm-backed-git-repository-plugin-preparation.zh.md b/.agents/notes/implemented/bug-fix/2026-08-08-npm-backed-git-repository-plugin-preparation.zh.md deleted file mode 100644 index d2256e0eae..0000000000 --- a/.agents/notes/implemented/bug-fix/2026-08-08-npm-backed-git-repository-plugin-preparation.zh.md +++ /dev/null @@ -1,48 +0,0 @@ -# Agent Note: 基于 NPM 的准备机制使 GitHub repository 插件自包含 - -状态:已实现 - -[English](2026-08-08-npm-backed-git-repository-plugin-preparation.md) | 中文 - -## 问题 - -repository 插件创作约定要求 `scripts.prepack` 调用 `dsh-plugin-prepare`。如果由正在运行的 DSH 安装提供该可执行文件,即使源包自身的 manifest(元数据清单)无法取得辅助程序,它也会显得有效。因此,这并未证明 `@deepseek-ai/dsh-repository-plugin` 发布后用户所需的行为:普通 Git 托管 NPM 包必须只依靠自身声明的依赖即可安装和准备。 - -pnpm workspace 内可选择的 `.dsh-plugin` 还有另一项隔离要求。pnpm 会在打包所选子目录前运行仓库首选的包管理器,以准备 Git 托管包。嵌套的 `pnpm install` 可能加入外层 workspace;当根 lockfile 未把 `.dsh-plugin` 列为 importer 时,pnpm 可能报告成功,却未安装仅由该包声明的依赖。随后,其 TypeScript 构建或准备命令会失败;也可能因为存在预生成产物,依赖缺失被掩盖。 - -签入仓库的 headless fixture(测试前置数据)挂载的是已准备好的包装层。它证明运行时组合,而不证明 GitHub 获取、NPM 解析或包自有准备。 - -## 决策 - -`.dsh-plugin` 包将已发布的 `@deepseek-ai/dsh-repository-plugin` 声明为普通开发依赖,并在 `scripts.prepack` 中调用其已发布的 `dsh-plugin-prepare` 可执行文件。该包可以声明其他任意构建依赖与运行时依赖,并在辅助程序前执行任意编译。repository 插件包把 Cordis 与 DSH 对等依赖(peer dependency)标为可选,因此仅为使用辅助程序而进行的开发安装只会解析辅助程序实际依赖的 `zod` 运行时依赖;应用组合仍会提供该包 Cordis 入口所使用的对等依赖。 - -DSH 不会生成准备阶段可执行文件,也不会将其前置到 `PATH`。`RepositoryCache` 只提供一个由事务持有的 `pnpm` 包装脚本:外层安装直接运行锁定的 pnpm 入口,而 pnpm 为 Git 包硬编码的 `pnpm install` 会以 `--ignore-workspace` 重新调用同一入口。因此,即使位于另一个 pnpm lockfile 之下,所选包仍自行负责依赖解析,正常的包管理器生命周期 `PATH` 构造会暴露 `node_modules/.bin/dsh-plugin-prepare`。临时 pnpm 包装脚本会在子进程结算后消失。repository 仍是受信任的包管理器输入:所有依赖与生命周期代码都按既有信任约定执行。 - -Node 24 消费方 CI 任务会传入从 PR(Pull Request)head 仓库与 SHA 派生的精确源。它复用现有私有 DeepSeek Harness 仓库,而不会为每次运行新建仓库。作业作用域的 Git 配置允许只读作业 token 访问该精确私有源,并把 pnpm 的 SSH 回退改写为已认证 HTTPS。 - -构建入口验收还会创建一个进程内 NPM 注册表。它通过移除 `private`、将 workspace protocol 替换为发布版本并打包声明的文件,把当前已构建的 `@deepseek-ai/dsh-repository-plugin` 暂存为发布产物。注册表会提供由此生成的 `packument` 与 tarball,作业本地 NPM 配置则只把 `@deepseek-ai` scope 指向它。实际构建的 `dsh run` 子进程随后获取精确 Git 源;该包通过 NPM 解析辅助程序,对 TypeScript Cordis 入口和 MCP server 进行类型检查与打包,准备相邻的 skill(技能),并加载全部三类贡献。一个刻意设为失败的宿主 `PATH` 命令可以证明,该生命周期选中的是依赖内的可执行文件。验收还要求经过注册表解析并检查不可变的已准备缓存,因此恢复宿主注入的辅助程序也无法通过。 - -## 考虑过的替代方案 - -**从正在运行的 DSH 安装注入 `dsh-plugin-prepare`。** 拒绝,因为这会让 manifest 不完整的 repository 包通过,并测试 NPM 消费方无法复现的纯宿主路径。 - -**把源 fixture 本身发布到 NPM。** 拒绝,因为产品约定明确要求 DSH 插件仍托管在 Git;只有可复用的准备辅助程序是 NPM 依赖。 - -**在每次 CI 运行中创建新的私有 GitHub 仓库。** 拒绝,因为 PR 仓库的精确 head SHA 已是经过认证的真实私有 Git remote。每次运行的仓库变更会增加凭据、清理和最终一致性失败模式,却不改变获取路径。 - -**在 `RepositoryCache` 安装所选包后再准备。** 拒绝,因为 pnpm 打包后的子目录不再包含 `../skills` 等路径所引用的同仓库相邻资源;准备必须在生成 packlist 前完成。 - -**在 DSH 中克隆 GitHub 仓库并绕过 pnpm 的 Git 获取器。** 拒绝,因为这会重复实现已由锁定包管理器负责的 ref 解析、子目录选择、依赖安装、packlist 行为和缓存完整性。 - -## 后果 - -- 仓库作者可以把 `.dsh-plugin` 包、TypeScript 源码、skill 与 MCP 定义提交到 GitHub,而无需把该插件包发布到 NPM。该包必须声明已发布的准备依赖。 -- 私有 GitHub 源使用宿主的标准 Git 认证。CI 使用临时的只读配置而非运行器上的持久凭据来验证该路径。 -- 创作格式使用 `prepack` 而不是 `prepare`。其中可以包含任意包自有构建步骤,但必须调用依赖提供的辅助程序;依赖或生命周期元数据缺失时,会在缓存 generation 可用前失败。 -- pnpm 仓库中的所选包按自身 manifest 安装,而不继承外层 workspace。它不能依赖仅由 workspace 提升而可见的包;普通注册表依赖和相对 `file:` 依赖仍是包自有输入。 -- 精确源字符串标识不可变缓存 generation;改变 ref 或源配置会选择另一个 generation。 -- 包依赖、编译、准备和受信任的 `dsh.entry` 贡献仍由 repository 包和[受信任代码决策](../architecture/2026-08-08-trusted-repository-package-code.md)负责。 - -## 测试 - -`packages/boot/app-boot/tests/repository-cache.spec.ts` 会通过本地 Git 子路径运行一个未列入源仓库根 pnpm lockfile 的包,并要求相对 `file:` 依赖同时提供构建命令与 `dsh-plugin-prepare`;该测试还证明可见环境变量得以保留,而名称符合凭据模式的变量会被清除。`packages/self-modification/repository-plugin/tests/repository-plugin.spec.ts` 锁定包含辅助命令的 `prepack` 元数据与准备输出。`examples/headless-agent/tests/keyless-smoke.e2e.ts` 使签入仓库的已准备 fixture 继续符合该源格式约定。`apps/cli/tests/github-repository-plugin.built.e2e.ts` 是产品验收测试:模拟发布的辅助程序包、作业本地 NPM 注册表、全新 DSH 主目录、精确且经过认证的私有 GitHub 源、实际构建的 `dsh run`、包自有 TypeScript 构建、真实 MCP 执行、代码入口转换、mock LLM(大语言模型)请求观测,以及已准备缓存检查。 diff --git a/.agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.i18n.yaml b/.agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.i18n.yaml index 3023f86bba..da61b3fa95 100644 --- a/.agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.md -2026-07-08-self-referential-cordis-toolset.md: 5fc2fb07fcd0b00bf72c818d3806b298312cdc31 -2026-07-08-self-referential-cordis-toolset.zh.md: 8f34c97d94cad9b79a0e823406c07cdcfb38793f +2026-07-08-self-referential-cordis-toolset.md: 0d78e0adff487edae00c2422acc1ef8941e7636a +2026-07-08-self-referential-cordis-toolset.zh.md: 665387a9fb24bf0e6fc04fdfb1ced88b932742ad diff --git a/.agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.md b/.agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.md index 5fc2fb07fc..0d78e0adff 100644 --- a/.agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.md +++ b/.agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.md @@ -40,7 +40,7 @@ The boundary normalizes unambiguous JSON-Schema forms into `ParameterSchemaSpec` Every temporary Plugin is a child of one internal `cordis-dynamic` group beneath the tool plugin, so ordinary fiber disposal handles toolset reload and unload. `cordis_mount` awaits settlement; startup failure disposes the fiber before returning an error. A settled pending Plugin remains visible with its missing injections. `cordis_unmount` awaits the Plugin fiber's disposal. -Temporary Plugins exist only in process memory. They create no Plugin file, install no package, change no `cordis.yml` or personal/project configuration, do not survive restart, and have no automatic save, promote, or install path. Keeping an experiment means asking the Agent to implement a normal local, project, or repository Plugin through the regular development workflow. +Temporary Plugins exist only in process memory. They create no Plugin file, install no package, change no `cordis.yml` or personal/project configuration, do not survive restart, and have no automatic save, promote, or install path. Keeping an experiment means asking the Agent to implement a normal project Plugin or installable profile bundle through the regular development workflow. ### Cross-mount composition via provide/inject diff --git a/.agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.zh.md b/.agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.zh.md index 8f34c97d94..665387a9fb 100644 --- a/.agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.zh.md +++ b/.agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.zh.md @@ -40,7 +40,7 @@ vm 隔离了意外的全局污染,上下文门面隐藏了框架内部细节 每个临时 Plugin 都是工具插件下方内部 `cordis-dynamic` 分组的子节点,因此普通的 fiber 释放即可处理工具集重载和卸载。`cordis_mount` 会等待 settlement;启动失败时在返回错误前释放 fiber。已 settle 但处于 pending 状态的 Plugin 仍然可见,并列出其缺失的注入。`cordis_unmount` 等待 Plugin fiber 的释放完成。 -临时 Plugin 只存在于进程内存中。它不会创建 Plugin 文件、安装 package、修改 `cordis.yml` 或个人/项目配置、跨重启存续,也不存在自动保存、转正式或安装路径。若要保留实验结果,应让 Agent 通过常规开发流程实现普通的本地、项目或仓库 Plugin。 +临时 Plugin 只存在于进程内存中。它不会创建 Plugin 文件、安装 package、修改 `cordis.yml` 或个人/项目配置、跨重启存续,也不存在自动保存、转正式或安装路径。若要保留实验结果,应让 Agent 通过常规开发流程实现普通的项目 Plugin 或可安装的 profile 组合包。 ### 通过 provide/inject 实现跨挂载组合 diff --git a/.agents/notes/implemented/feature/2026-07-20-dsh-cli-personal-config.i18n.yaml b/.agents/notes/implemented/feature/2026-07-20-dsh-cli-personal-config.i18n.yaml index 445f6548b3..a08966f790 100644 --- a/.agents/notes/implemented/feature/2026-07-20-dsh-cli-personal-config.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-07-20-dsh-cli-personal-config.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-07-20-dsh-cli-personal-config.md -2026-07-20-dsh-cli-personal-config.md: f5207c5ffbd963b9b7c4a7166fa9f17a460707a9 -2026-07-20-dsh-cli-personal-config.zh.md: 24478a4b4fd5878032bf80f5b30ab9e2008da785 +2026-07-20-dsh-cli-personal-config.md: 02883c89f27e51d6091d4d65167ebdd6a96f6f51 +2026-07-20-dsh-cli-personal-config.zh.md: 6e56e892cf682ea514b036750e44dbb06e944a80 diff --git a/.agents/notes/implemented/feature/2026-07-20-dsh-cli-personal-config.md b/.agents/notes/implemented/feature/2026-07-20-dsh-cli-personal-config.md index f5207c5ffb..02883c89f2 100644 --- a/.agents/notes/implemented/feature/2026-07-20-dsh-cli-personal-config.md +++ b/.agents/notes/implemented/feature/2026-07-20-dsh-cli-personal-config.md @@ -19,7 +19,7 @@ Two coupled pieces, aligned with the `apps/` assembly tier proposed by the `dsh **Personal config (`dsh-app-boot`).** The personal overlay lives in the Harness home — `$DSH_HOME`, else `~/.dsh` — resolved by the shared [`resolveDshHome`](../architecture/2026-07-24-single-harness-home-resolver.md) (`@deepseek-ai/dsh-paths`), the same single root skills and AGENTS.md resolve against. The dsh TUI, Web, and headless surfaces consume its two optional files; the demo bins boot their committed trees verbatim: - `.env` — loaded after the invoking directory's `.env`; `process.loadEnvFile` never overrides, so precedence is ambient > project `.env` > personal `.env`. -- `config.yaml` — a top-level YAML array of `@cordisjs/plugin-include` `PatchOptions`, parsed with the include's own `!!js` dialect (`loadPersonalPatches`) and passed to `boot()`, which forwards it as the root include's `patches`. Patch semantics match the shipped surface overlays: an id-targeted patch replaces the named entry's whole `config`, `insert` appends entries, and an unmatched id is a silent no-op. The [repository Plugin integration](2026-07-30-config-only-repository-plugins.md) uses one shipped row to make an exact GitHub source list a config-only choice. +- `config.yaml` — a top-level YAML array of `@cordisjs/plugin-include` `PatchOptions`, parsed with the include's own `!!js` dialect (`loadPersonalPatches`) and passed to `boot()`, which forwards it as the root include's `patches`. Patch semantics match the shipped surface overlays: an id-targeted patch replaces the named entry's whole `config`, `insert` appends entries, and an unmatched id is a silent no-op. External packages are installed as [profile bundles](../simplification/2026-08-09-remove-repository-plugin.md); this personal layer configures the Loader rows those bundles contribute. - A missing file means no overlay; a present-but-unreadable, unparsable, or non-array file throws at boot (misconfiguration fails loud, never a silent skip). The PTY smoke's launcher isolates `$DSH_HOME` to a per-test directory, exactly as it already isolates `DSH_AGENTS_HOME`, so a developer's real personal overlay cannot leak into fixtures; only the dsh CLI reads personal config, so no other test launcher needed changes. @@ -40,7 +40,7 @@ The TUI and Web register the exact personal path through Cordis HMR after boot. ## Consequences -- `dsh` from any directory (and `pnpm run demo:tui`) can apply personal providers, models, repository Plugins, and other Loader entries with no checkout edit; verified end-to-end against a personal Anthropic proxy with Opus 4.8, including a bash tool round trip. +- `dsh` from any directory (and `pnpm run demo:tui`) can apply personal providers, models, installed bundle entries, and other Loader entries with no checkout edit; verified end-to-end against a personal Anthropic proxy with Opus 4.8, including a bash tool round trip. - Because an id-targeted patch replaces the whole `config`, a personal override restates the base fields it keeps and can drift when the base entry changes shape; the loader's entry-not-found/name-mismatch warnings and [`dsh --dump-config`](../../../../apps/cli/README.md#profiles) (which prints the composed tree those patches produce) are the diagnostics. - Personal patches resolve ids against the booted file's own tree, so nested-include overlays (Code Mode) are not personalized; live-run parity for those leaves is deferred. - `dsh-app-boot` depends on `js-yaml` and imports the include's `!!js` YAML dialect (`entryListSchema`) directly, and, like `apps/cli`, depends on `@deepseek-ai/dsh-paths` for `resolveDshHome`. diff --git a/.agents/notes/implemented/feature/2026-07-20-dsh-cli-personal-config.zh.md b/.agents/notes/implemented/feature/2026-07-20-dsh-cli-personal-config.zh.md index 24478a4b4f..6e56e892cf 100644 --- a/.agents/notes/implemented/feature/2026-07-20-dsh-cli-personal-config.zh.md +++ b/.agents/notes/implemented/feature/2026-07-20-dsh-cli-personal-config.zh.md @@ -19,7 +19,7 @@ Status: implemented **个人配置(`dsh-app-boot`)。** 个人 overlay 存放在 Harness home——`$DSH_HOME`,否则 `~/.dsh`——由共享的 [`resolveDshHome`](../architecture/2026-07-24-single-harness-home-resolver.md)(`@deepseek-ai/dsh-paths`)解析,与 skills、AGENTS.md 解析所依据的单一根目录相同。dsh 的 TUI、Web 和无头界面使用其中两个可选文件;各示例 bin 仍然逐字节按已提交的配置树启动: - `.env`——在调用目录的 `.env` 之后加载;`process.loadEnvFile` 从不覆盖已有值,因此优先级为环境变量 > 项目 `.env` > 个人 `.env`。 -- `config.yaml`——顶层 YAML 数组,元素为 `@cordisjs/plugin-include` 的 `PatchOptions`,用 include 自己的 `!!js` 方言解析(`loadPersonalPatches`)并传给 `boot()`,由它作为根 include 的 `patches` 转发。补丁语义与交付的 surface overlay 一致:按 id 定位的补丁替换该配置项的整个 `config`,`insert` 追加配置项,未匹配的 id 静默不执行任何操作。[仓库插件集成](2026-07-30-config-only-repository-plugins.md)通过一个已交付配置项,使精确 GitHub 源列表成为纯配置选择。 +- `config.yaml`——顶层 YAML 数组,元素为 `@cordisjs/plugin-include` 的 `PatchOptions`,用 include 自己的 `!!js` 方言解析(`loadPersonalPatches`)并传给 `boot()`,由它作为根 include 的 `patches` 转发。补丁语义与交付的 surface overlay 一致:按 id 定位的补丁替换该配置项的整个 `config`,`insert` 追加配置项,未匹配的 id 静默不执行任何操作。外部包作为 [profile 组合包](../simplification/2026-08-09-remove-repository-plugin.md)安装;这个个人层负责配置这些组合包提供的 Loader 配置项。 - 文件缺失即无 overlay;文件存在但不可读、不可解析或非数组则在启动时抛出(配置错误响亮失败,绝不静默跳过)。 PTY 冒烟测试的启动器把 `$DSH_HOME` 隔离到每个测试自己的目录,与它已有的 `DSH_AGENTS_HOME` 隔离方式完全一致,开发者真实的个人 overlay 不可能泄漏进 fixture;只有 dsh CLI 读取个人配置,因此其他测试启动器无需改动。 @@ -40,7 +40,7 @@ TUI 和 Web 启动后通过 Cordis HMR(热模块替换)注册确切的个人 ## Consequences -- 在任意目录运行 `dsh`(以及 `pnpm run demo:tui`),无需修改 checkout,即可应用个人提供方、模型、仓库插件和其他 Loader 配置项;已针对个人 Anthropic 代理与 Opus 4.8 端到端验证,包括一次 bash 工具往返。 +- 在任意目录运行 `dsh`(以及 `pnpm run demo:tui`),无需修改 checkout,即可应用个人提供方、模型、已安装组合包的配置项和其他 Loader 配置项;已针对个人 Anthropic 代理与 Opus 4.8 端到端验证,包括一次 bash 工具往返。 - 由于按 id 定位的补丁替换整个 `config`,个人覆盖必须复述它保留的基础字段,并可能随基础配置项形态变化而漂移;诊断手段是 loader 的「配置项未找到/名称不匹配」警告和 [`dsh --dump-config`](../../../../apps/cli/README.md#profiles)(打印这些补丁合成出的配置树)。 - 个人补丁只在被启动文件自身的树里解析 id,因此嵌套 include 的 overlay(Code Mode)不会被个性化;这些叶子的实际运行等价性暂缓。 - `dsh-app-boot` 依赖 `js-yaml`,并直接导入 include 的 `!!js` YAML 方言(`entryListSchema`);与 `apps/cli` 一样依赖 `@deepseek-ai/dsh-paths` 以获取 `resolveDshHome`。 diff --git a/.agents/notes/implemented/feature/2026-07-30-config-only-repository-plugins.md b/.agents/notes/implemented/feature/2026-07-30-config-only-repository-plugins.md deleted file mode 100644 index 35327a30e0..0000000000 --- a/.agents/notes/implemented/feature/2026-07-30-config-only-repository-plugins.md +++ /dev/null @@ -1,50 +0,0 @@ -# Agent Note: Config-only repository Plugins for standalone dsh - -Status: implemented - -English | [中文](2026-07-30-config-only-repository-plugins.zh.md) - -## Problem - -A standalone `dsh` user has no developer-owned SDK project whose `package.json`, lockfile, and `cordis.yml` can carry an external Plugin dependency. Requiring an install command or another state file would make “use this repository” a multi-step workflow, while trusted repository code still needs an exact-source, transactional lifecycle owned by the [repository package format](../architecture/2026-08-08-trusted-repository-package-code.md). Long-running TUI and Web processes also need a failed edit to preserve their usable Plugin generation and tell observers why the candidate was rejected. - -## Decision - -The shipped TUI and Web/headless `cordis.yml` trees contain an empty `repository-plugins` entry. A user changes only `$DSH_HOME/config.yaml`, replacing that entry's config with a `repositories` list. Each item uses `github:owner/repository#` plus an optional `&path:/.../.dsh-plugin`; omission selects `/.dsh-plugin`. An explicit ref is mandatory, paths are absolute within the repository and end in `.dsh-plugin`, and duplicate normalized specifiers reject before installation. There is no marketplace, discovery index, HTTPS URL vocabulary, or implicit latest generation. - -`@deepseek-ai/dsh-repository-plugin` validates and normalizes each source, then resolves it through the generic vendored [`RepositoryCache`](../architecture/2026-07-30-package-manager-native-repository-cache.md). The default cache is `$DSH_HOME/cache/repository-plugins`; `cacheDir` is the explicit deployment override. Bundled pnpm selects the configured repository subpackage, installs its dependencies, runs its package-authored `prepack`, and atomically publishes the exact specifier. The selected package's direct development dependency on `@deepseek-ai/dsh-repository-plugin` supplies `dsh-plugin-prepare` through package-local `node_modules/.bin`; the lifecycle invokes it after any package-owned build. The DSH host imports the generated `dsh-plugin.mjs` wrapper and mounts it as a child fiber; that wrapper composes static skill and MCP owners plus an explicit trusted Cordis entry when declared. - -## Live update and failure - -`dsh-app-boot` mounts the root Include through one helper that retains its exact Loader `Entry`. The TUI and Web register `$DSH_HOME/config.yaml` through Cordis HMR; headless reads the same file at startup without retaining a watcher. A watcher update rebuilds the Include patch list as immutable app-owned patches followed by the newly parsed personal patches, so Web-generated port, session-root, trust, and frontend values survive every personal edit unless a later personal patch deliberately replaces that row. - -Cordis serializes and coalesces exact-path changes. Include and Loader reconcile a candidate transactionally: success commits the new source list, while fetch, preparation, wrapper import, format, or child-Plugin failure rejects the candidate and retains or restores the last good tree. HMR normalizes the caught value to `Error`, logs it, and broadcasts the parallel `hmr/config-update-failed(filename, error)` event; observer failures cannot break refresh processing. Repository MCP servers use strict startup, so an initial connection, discovery, or tool-registration failure rejects the candidate and becomes a config-update failure; non-strict standalone MCP clients retain their contained successful-Plugin/no-tools behavior. - -An identical specifier permanently reuses its cache generation. HMR watches configuration, not cached repository code; the user changes the ref, path, or source list to select another generation. - -## Trust boundary - -Configuring a repository authorizes package-manager lifecycle code, dependencies, the explicit `dsh.entry`, and spawned MCP servers from that repository to run with the user's filesystem authority. The pnpm child removes ambient environment variables whose names contain `KEY`, `PASSWORD`, `SECRET`, or `TOKEN`, but this is credential-exposure reduction rather than a sandbox. The prepared wrapper validates composition boundaries and lifecycle state; it does not make repository code safe to run when the source is untrusted. - -## Alternatives considered - -**Require an SDK project dependency.** Rejected for the standalone app path because there is no project manifest to edit. Developer-owned SDK projects keep their native package-manager workflow as a separate capability. - -**Add a `dsh plugin install` command and installation database.** Rejected because the personal Loader overlay already owns machine-local composition. A second mutation interface and durable registry would duplicate config identity and rollback. - -**Resolve repositories directly in the DSH package.** Rejected because Git transport, GitHub subpackage selection, lifecycle execution, and content storage belong to pnpm and the generic Loader cache, not a DSH-specific adapter. - -**Watch cache contents or refresh the same ref automatically.** Rejected because one config value must identify one immutable prepared generation. Background remote resolution would change executable code without a config diff and make rollback depend on mutable remote state. - -**Broadcast an `unknown` failure payload.** Rejected at the HMR boundary. JavaScript may throw any value internally, but the public event always receives a normalized `Error`, giving observers one stable contract while retaining the original value as its cause when needed. - -## Consequences - -- A repository that adds `.dsh-plugin/package.json` can reach standalone users through one personal-config edit without changing its existing skills or `.mcp.json` layout. -- Long-running apps can add, replace, or remove configured generations without restart; rejected candidates retain the last good runtime and produce one generic Cordis event. -- First use may require Git/network access and preparation time. Later starts reuse the exact prepared cache; old generations consume disk until a separate cache-management policy exists. -- Skills and common MCP definitions retain portable static adapters, while an explicit `dsh.entry` can contribute DSH-native Cordis behavior. Format-specific compatibility shims, OAuth-bearing MCP definitions, and marketplaces remain intentionally absent. - -## Testing - -Repository-package tests pin source normalization, default and nested `.dsh-plugin` paths, cache-root resolution, duplicate rejection, prepared-wrapper loading, and disposal. App-boot tests drive exact-path add, two failure classes, recovery, removal, failure events, and generated-patch preservation through the real HMR/Include/Loader path. A keyless PTY smoke boots the shipped `dsh` composition from personal config alone and invokes a skill from a seeded immutable cache generation. diff --git a/.agents/notes/implemented/feature/2026-07-30-config-only-repository-plugins.zh.md b/.agents/notes/implemented/feature/2026-07-30-config-only-repository-plugins.zh.md deleted file mode 100644 index 5755045560..0000000000 --- a/.agents/notes/implemented/feature/2026-07-30-config-only-repository-plugins.zh.md +++ /dev/null @@ -1,50 +0,0 @@ -# Agent Note: 仅凭配置为独立 dsh 接入仓库插件 - -Status: implemented - -[English](2026-07-30-config-only-repository-plugins.md) | 中文 - -## 问题 - -独立 `dsh` 用户没有开发者自有的 SDK 项目,无法由其 `package.json`、lockfile 和 `cordis.yml` 承载外部插件依赖。若要求运行安装命令或维护另一份状态文件,「使用这个仓库」就会变成多步骤流程;受信任的 repository 代码仍需要由[repository 包格式](../architecture/2026-08-08-trusted-repository-package-code.md)负责一套锁定精确来源且具事务性的生命周期。长时间运行的 TUI 和 Web 进程还必须在编辑失败时保留仍可使用的插件版本,并向观察者说明候选配置被拒绝的原因。 - -## 决策 - -已交付的 TUI 和 Web/无头 `cordis.yml` 配置树包含一个空的 `repository-plugins` 配置项。用户只需修改 `$DSH_HOME/config.yaml`,用 `repositories` 列表替换该配置项的配置。每一项采用 `github:owner/repository#`,并可追加 `&path:/.../.dsh-plugin`;省略时选择 `/.dsh-plugin`。必须显式指定 ref;路径是仓库内的绝对路径,并以 `.dsh-plugin` 结尾;重复的规范化说明符在安装前即被拒绝。不提供插件市场、发现索引、HTTPS URL 词汇或隐式的最新版本。 - -`@deepseek-ai/dsh-repository-plugin` 校验并规范化每个源,再通过 vendor 中的通用 [`RepositoryCache`](../architecture/2026-07-30-package-manager-native-repository-cache.md) 解析。默认缓存位于 `$DSH_HOME/cache/repository-plugins`;`cacheDir` 是显式的部署覆盖项。随应用提供的 pnpm 选择已配置的 repository 子包,安装其依赖,运行包所定义的 `prepack`,并原子发布该精确说明符。所选包对 `@deepseek-ai/dsh-repository-plugin` 的直接开发依赖通过包内 `node_modules/.bin` 提供 `dsh-plugin-prepare`;该生命周期会在任何包自有构建完成后调用它。DSH 宿主会导入生成的 `dsh-plugin.mjs` 包装层并将其挂载为子 fiber;该包装层组合静态 skill(技能)与 MCP 所有者,并在声明时组合显式的受信任 Cordis 入口。 - -## 实时更新与失败 - -`dsh-app-boot` 通过一个辅助函数挂载根 Include,并保留其确切的 Loader `Entry`。TUI 和 Web 通过 Cordis HMR(热模块替换)注册 `$DSH_HOME/config.yaml`;无头模式在启动时读取同一文件,但不保留监视器。监视器更新会重新构建 Include 补丁列表,先放置不可变的应用自有补丁,再放置新解析的个人补丁。因此,Web 生成的端口、会话根目录、信任和前端值会在每次个人编辑后保留,除非后续个人补丁有意替换相应配置项。 - -Cordis 会串行处理并合并该确切路径上的变更。Include 与 Loader 以事务方式协调候选配置:成功时提交新源列表;拉取、准备、包装模块导入、格式或子插件失败时拒绝候选配置,并保留或恢复最后一个可用树。HMR 会把捕获的值规范化为 `Error`,记录错误,并广播并行的 `hmr/config-update-failed(filename, error)` 事件;观察者失败不会中断刷新处理。Repository MCP 服务器采用严格启动,因此初始连接、发现或工具注册失败会拒绝候选配置,并构成配置更新失败;非严格的独立 MCP 客户端仍保留其所收束的「插件成功加载但无工具」行为。 - -相同说明符会永久复用同一个缓存版本。HMR 监视配置,而非已缓存的仓库代码;用户必须改变 ref、路径或源列表,才能选择另一个版本。 - -## 信任边界 - -配置仓库即授权该仓库中的包管理器生命周期代码、依赖、显式 `dsh.entry` 和 spawn 的 MCP server 以用户的文件系统权限运行。pnpm 子进程会移除名称中含有 `KEY`、`PASSWORD`、`SECRET` 或 `TOKEN` 的环境变量,但这只会减少凭据暴露,并非沙箱。已准备的包装层会校验组合边界和生命周期状态;当来源不受信任时,它无法让 repository 代码变得可安全运行。 - -## 考虑过的替代方案 - -**要求声明 SDK 项目依赖。** 独立应用路径没有可编辑的项目 manifest(元数据清单),因此否决。开发者自有的 SDK 项目仍可使用原生包管理器工作流,这是一项独立能力。 - -**新增 `dsh plugin install` 命令和安装数据库。** 否决,因为个人 Loader 覆盖层已经负责机器本地组合。第二个变更接口和持久注册表会重复配置身份与回滚机制。 - -**由 DSH 包直接解析仓库。** 否决,因为 Git 传输、GitHub 子包选择、生命周期执行和内容存储属于 pnpm 与通用 Loader 缓存,而非 DSH 专用适配器。 - -**监视缓存内容,或自动刷新相同 ref。** 否决,因为一个配置值必须标识一个不可变的已准备版本。后台远端解析会在没有配置差异的情况下改变可执行代码,并使回滚依赖可变的远端状态。 - -**广播 `unknown` 失败载荷。** 在 HMR 边界否决。JavaScript 内部可以抛出任意值,但公开事件始终接收规范化的 `Error`,从而为观察者提供稳定约定,并在需要时把原始值保留为错误原因。 - -## 后果 - -- 添加 `.dsh-plugin/package.json` 的仓库只需一次个人配置编辑即可供独立用户使用,无需改变现有 skill 或 `.mcp.json` 布局。 -- 长时间运行的应用无需重启即可新增、替换或移除已配置版本;被拒绝的候选配置会保留最后一个可用运行时,并产生一个通用 Cordis 事件。 -- 首次使用可能需要 Git/网络访问和准备时间。后续启动会复用这份精确的已准备缓存;在另行制定缓存管理政策之前,旧版本会持续占用磁盘空间。 -- skill 和通用 MCP 定义保留可移植静态适配器,而显式 `dsh.entry` 可以贡献 DSH 原生 Cordis 行为。格式专用的兼容 shim、带 OAuth 的 MCP 定义和插件市场仍有意不提供。 - -## 测试 - -仓库包测试固定源规范化、默认和嵌套 `.dsh-plugin` 路径、缓存根解析、重复项拒绝、已准备包装层加载及资源释放。App-boot 测试通过真实 HMR/Include/Loader 路径驱动确切路径的新增、两类失败、恢复、移除、失败事件及生成补丁保留。一个无密钥 PTY 冒烟测试仅通过个人配置启动已交付的 `dsh` 组合,并从预置的不可变缓存版本中调用一个 skill。 diff --git a/.agents/notes/implemented/feature/2026-07-30-config-only-repository-plugins.i18n.yaml b/.agents/notes/implemented/simplification/2026-08-09-remove-repository-plugin.i18n.yaml similarity index 56% rename from .agents/notes/implemented/feature/2026-07-30-config-only-repository-plugins.i18n.yaml rename to .agents/notes/implemented/simplification/2026-08-09-remove-repository-plugin.i18n.yaml index 5985f18a06..da5b77fbd0 100644 --- a/.agents/notes/implemented/feature/2026-07-30-config-only-repository-plugins.i18n.yaml +++ b/.agents/notes/implemented/simplification/2026-08-09-remove-repository-plugin.i18n.yaml @@ -1,6 +1,6 @@ # Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: -# pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-07-30-config-only-repository-plugins.md -2026-07-30-config-only-repository-plugins.md: 35327a30e03c51311f634e05ade209ab93ae0155 -2026-07-30-config-only-repository-plugins.zh.md: 5755045560da761b59f7c65e99d551f599c2b5b3 +# pnpm run verify-translation-pairing --write .agents/notes/implemented/simplification/2026-08-09-remove-repository-plugin.md +2026-08-09-remove-repository-plugin.md: 8dd2fe95ac97bc2d8ab50043eb6c516f53d3204c +2026-08-09-remove-repository-plugin.zh.md: 832a69ff206dd91dd312625bd9218e980d890ae2 diff --git a/.agents/notes/implemented/simplification/2026-08-09-remove-repository-plugin.md b/.agents/notes/implemented/simplification/2026-08-09-remove-repository-plugin.md new file mode 100644 index 0000000000..8dd2fe95ac --- /dev/null +++ b/.agents/notes/implemented/simplification/2026-08-09-remove-repository-plugin.md @@ -0,0 +1,43 @@ +# Agent Note: Remove the dedicated repository Plugin path + +Status: implemented + +English | [中文](2026-08-09-remove-repository-plugin.zh.md) + +## Problem + +The repository Plugin path duplicated the profile bundle path for installing and composing third-party packages. It added a `.dsh-plugin` manifest, a generated wrapper, a preparation executable, a second Git/package cache, a Loader builtin, and repository-specific Skill and MCP adapters. Profile bundles already install npm or Git package specifications through the profile package manager, retain normal dependency and lifecycle semantics, and contribute an ordered `cordis.patch.yml` layer that can mount ordinary Cordis Plugins. + +The duplicate path also exposed less configuration than a bundle. Its `repositories` list selected source strings, but the generated wrapper mounted a code entry without a user-supplied Plugin config. Repository-specific preparation therefore added substantial code and CI work without becoming the general external-Plugin distribution mechanism. + +## Decision + +DeepSeek Harness has one standalone external-Plugin distribution path: installable profile bundles. `dsh plugin --profile add ` records the dependency in the profile package, and the installed package declares `dsh.bundle.patch` to contribute its patch layer. The package manager owns source acquisition, versions, dependencies, build lifecycles, and its lockfile. The bundle patch owns Cordis Plugin selection and complete Plugin config. + +The `@deepseek-ai/dsh-repository-plugin` package, `.dsh-plugin` authoring format, `dsh-plugin-prepare` executable, generated wrapper, immutable repository cache, base `repository-plugins` row, and dedicated GitHub acceptance lane are removed. The unused vendored `@cordisjs/plugin-loader/repository` subpath and its bundled pnpm dependency are removed with their only consumer. Existing repository cache directories are inert user data; DSH neither reads nor deletes them. + +Bundles compose existing owners directly. A bundle that contributes Skills mounts `@deepseek-ai/dsh-skill-local`; one that contributes MCP servers mounts `@deepseek-ai/dsh-mcp-client`; native behavior mounts an ordinary compiled Cordis Plugin. These packages retain their own validation, lifecycle, registration, and teardown contracts. No compatibility parser or migration from `.dsh-plugin` is retained under the pre-release compatibility policy. + +This note consolidates the removed repository cache, static format, config-only integration, npm-backed preparation, and trusted code-entry decisions. Their original motivation survives here: standalone users need package-manager-owned external composition, Git and npm dependencies may execute trusted lifecycle code, static Skill and MCP contributions should reuse their existing owners, and source identity belongs in the profile dependency specification and lockfile. Their implementation-specific wrappers, cache generations, and preparation protocol no longer constrain the product. + +## Alternatives considered + +**Keep repository Plugin as a convenience wrapper over bundles.** Rejected because it would preserve two install commands, two manifest formats, and two failure/cache identities for the same package. A convenience that cannot pass ordinary Plugin config also remains less capable than the mechanism it wraps. + +**Teach the repository wrapper to load a bundle patch.** Rejected because the repository cache and preparation protocol would still duplicate profile dependency installation. Bundle packages are already accepted from npm, Git, file, and link specifications through pnpm. + +**Keep the generic Loader repository cache for possible future consumers.** Rejected because it has no current consumer after the package removal and carries a pinned package-manager runtime in a vendored browser-adjacent package. A future need can choose its cache contract from current consumers rather than preserving this one speculatively. + +**Disable repository Plugin but retain its on-disk format for migration.** Rejected under the pre-release stance. Retaining a parser or compatibility loader would keep the removed contract alive without an external compatibility obligation. + +## Consequences + +- Third-party packages use one installation and composition model, with ordinary dependency declarations and full patch-level Plugin config. +- Installing or updating an external bundle is an explicit `dsh plugin` package-manager operation rather than a watched source-list edit. User patch HMR still configures rows contributed by installed bundles. +- `.dsh-plugin` packages and existing repository source-list patches stop working. Their cache files remain removable by the user but are not migrated or automatically deleted. +- The dedicated pnpm runtime, preparation executable, wrapper generator, Git credential CI setup, repository cache, and repository-specific tests disappear. +- Package-relative static assets need a bundle-owned path form so a declarative bundle can point `dsh-skill-local`, `dsh-mcp-client`, or another Plugin at files it ships without custom runtime glue. That capability is owned by the bundle format rather than a repository adapter. + +## Testing + +Static gates reject stale package, config, documentation, graph, and workspace references. The existing `dsh plugin` built-CLI acceptance covers profile initialization, package-manager installation, bundle discovery, and layer reconciliation. Bundle-specific tests own declarative asset-path resolution and real Skill/MCP composition. diff --git a/.agents/notes/implemented/simplification/2026-08-09-remove-repository-plugin.zh.md b/.agents/notes/implemented/simplification/2026-08-09-remove-repository-plugin.zh.md new file mode 100644 index 0000000000..832a69ff20 --- /dev/null +++ b/.agents/notes/implemented/simplification/2026-08-09-remove-repository-plugin.zh.md @@ -0,0 +1,43 @@ +# Agent Note: 移除专用 repository 插件路径 + +Status: implemented + +[English](2026-08-09-remove-repository-plugin.md) | 中文 + +## 问题 + +repository 插件路径与 profile 组合包路径重复实现了第三方包的安装和组合。它增加了 `.dsh-plugin` manifest(元数据清单)、生成的包装层、准备工作可执行文件、第二套 Git/包缓存、Loader 内置项,以及 repository 专用的 skill(技能)和 MCP 适配器。profile 组合包已经能通过 profile 包管理器安装 npm 或 Git 包说明符,保留正常的依赖与生命周期语义,并提供一个有序 `cordis.patch.yml` 层,其中可以挂载普通 Cordis 插件。 + +重复的路径所能提供的配置也少于组合包。其 `repositories` 列表选择源字符串,但生成的包装层挂载代码入口时无法传入用户提供的插件配置。因此,repository 专用的准备流程增加了大量代码和 CI 工作,却没有成为通用的外部插件分发机制。 + +## 决策 + +DeepSeek Harness 只保留一种独立的外部插件分发路径:可安装的 profile 组合包。`dsh plugin --profile add ` 将依赖记录到 profile 包中,安装的包通过声明 `dsh.bundle.patch` 提供自己的 patch 层。包管理器负责获取源、管理版本和依赖、运行构建生命周期,并维护锁文件。组合包 patch 负责选择 Cordis 插件并提供完整的插件配置。 + +移除 `@deepseek-ai/dsh-repository-plugin` 包、`.dsh-plugin` 编写格式、`dsh-plugin-prepare` 可执行文件、生成的包装层、不可变 repository 缓存、base 中的 `repository-plugins` 配置项,以及专用 GitHub 验收流水线。vendor 中未再使用的 `@cordisjs/plugin-loader/repository` 子路径及其随附的 pnpm 依赖,也随唯一消费方一并移除。现有 repository 缓存目录只是不会再产生作用的用户数据;DSH 既不会读取,也不会删除这些目录。 + +组合包直接组合现有归属方。提供 skill 的组合包挂载 `@deepseek-ai/dsh-skill-local`;提供 MCP 服务器的组合包挂载 `@deepseek-ai/dsh-mcp-client`;原生行为则挂载普通的已编译 Cordis 插件。这些包继续保有各自的校验、生命周期、注册和 teardown 契约。根据预发布兼容政策,不保留针对 `.dsh-plugin` 的兼容解析器或迁移机制。 + +本说明整合了已移除的 repository 缓存、静态格式、纯配置集成、由 npm 支持的准备流程和受信任代码入口决策。其原始动机保留于此:独立用户需要由包管理器负责的外部组合方式;Git 和 npm 依赖可以执行受信任的生命周期代码;静态 skill 与 MCP 贡献应复用现有归属方;来源标识应位于 profile 的依赖说明符和锁文件中。相应实现特有的包装层、缓存 generation 和准备协议不再约束产品。 + +## 曾考虑的替代方案 + +**保留 repository 插件,将其作为组合包的便利包装层。** 不予采纳,因为这会为同一个包保留两条安装命令、两种 manifest 格式,以及两套失败/缓存标识。如果一层便利包装不能传递普通的插件配置,其能力仍然不及它所包装的机制。 + +**让 repository 包装层加载组合包 patch。** 不予采纳,因为 repository 缓存和准备协议仍会重复 profile 依赖安装。组合包已经可以通过 pnpm 接受 npm、Git、file 和 link 说明符。 + +**为未来可能出现的消费方保留通用 Loader repository 缓存。** 不予采纳,因为在移除相关包后,它已无当前消费方,却仍让一个 vendor 中与浏览器相邻的包携带固定版本的包管理器运行时。未来若确有需要,可以根据届时的实际消费方选择缓存契约,无需推测性地保留现有契约。 + +**禁用 repository 插件,但保留其磁盘格式以供迁移。** 根据预发布方针,不予采纳。保留解析器或兼容 loader 会在没有外部兼容义务的情况下,让已移除的契约继续存在。 + +## 后果 + +- 第三方包统一使用一种安装与组合模型,采用普通依赖声明和完整的 patch 层插件配置。 +- 安装或更新外部组合包时,必须显式通过 `dsh plugin` 执行包管理器操作,而不是编辑受监听的源列表。用户 patch 的 HMR(热模块替换)仍可配置已安装组合包所提供的配置项。 +- `.dsh-plugin` 包和现有 repository 源列表 patch 停止工作。用户仍可自行删除其缓存文件,但系统不会迁移或自动删除这些文件。 +- 专用 pnpm 运行时、准备工作可执行文件、包装层生成器、Git 凭据 CI 设置、repository 缓存和 repository 专用测试全部消失。 +- 静态资源需要一种由组合包拥有、可相对于包解析的路径形式,使声明式组合包可以将 `dsh-skill-local`、`dsh-mcp-client` 或其他插件指向它随包交付的文件,而无需定制运行时代码。该能力归组合包格式所有,而不是 repository 适配器。 + +## 测试 + +静态门禁会拒绝残留的包、配置、文档、图和 workspace 引用。现有 `dsh plugin` 已构建 CLI(命令行界面)验收测试覆盖 profile 初始化、包管理器安装、组合包发现和层调和。组合包专用测试负责覆盖声明式资源路径解析,以及真实的 skill/MCP 组合。 diff --git a/.agents/notes/proposed/feature/2026-07-17-sdk-follow-up-capabilities.i18n.yaml b/.agents/notes/proposed/feature/2026-07-17-sdk-follow-up-capabilities.i18n.yaml index a0a0dc998d..7084931b1d 100644 --- a/.agents/notes/proposed/feature/2026-07-17-sdk-follow-up-capabilities.i18n.yaml +++ b/.agents/notes/proposed/feature/2026-07-17-sdk-follow-up-capabilities.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/proposed/feature/2026-07-17-sdk-follow-up-capabilities.md -2026-07-17-sdk-follow-up-capabilities.md: 9a17f07139014f95666789e41cacb7af180ef5d8 -2026-07-17-sdk-follow-up-capabilities.zh.md: 2431c5c3d9e45605223d9bb1843e48a3c711759e +2026-07-17-sdk-follow-up-capabilities.md: f14d46a61f5fd3e64067441c2f8340cf94746a79 +2026-07-17-sdk-follow-up-capabilities.zh.md: 2e5efba340d503d2445e408bfc43ee0d6c6bec3c diff --git a/.agents/notes/proposed/feature/2026-07-17-sdk-follow-up-capabilities.md b/.agents/notes/proposed/feature/2026-07-17-sdk-follow-up-capabilities.md index 9a17f07139..f14d46a61f 100644 --- a/.agents/notes/proposed/feature/2026-07-17-sdk-follow-up-capabilities.md +++ b/.agents/notes/proposed/feature/2026-07-17-sdk-follow-up-capabilities.md @@ -47,7 +47,7 @@ The repository ships a thin `SKILL.md` that teaches an agent to construct the st The package manager owns source parsing, version or commit resolution, integrity data, lockfile updates, and any build policy. The SDK does not download or unpack a second copy through giget or pacote. An external plugin remains a dependency under `node_modules`; local plugin scaffolding remains a separate project-creation concern. -This proposal concerns dependencies of developer-owned SDK projects. Standalone app repository caching, its bundled-pnpm policy, and its explicit preparation trust boundary are owned by the [package-manager-native repository cache](../../implemented/architecture/2026-07-30-package-manager-native-repository-cache.md). +This proposal concerns dependencies of developer-owned SDK projects. Standalone apps install external packages as [profile bundles](../../implemented/simplification/2026-08-09-remove-repository-plugin.md), with their profile package manager and lockfile owning acquisition and lifecycle policy. ## Launcher telemetry diff --git a/.agents/notes/proposed/feature/2026-07-17-sdk-follow-up-capabilities.zh.md b/.agents/notes/proposed/feature/2026-07-17-sdk-follow-up-capabilities.zh.md index 2431c5c3d9..2e5efba340 100644 --- a/.agents/notes/proposed/feature/2026-07-17-sdk-follow-up-capabilities.zh.md +++ b/.agents/notes/proposed/feature/2026-07-17-sdk-follow-up-capabilities.zh.md @@ -47,7 +47,7 @@ Create 和 config 使用相同的功能计划形状。create 通过上述命令 包管理器负责来源解析、版本或 commit 解析、`integrity` 数据、lockfile 更新和构建策略。SDK 不再通过 giget 或 pacote 下载、解压第二份副本。外部插件是 `node_modules` 下的依赖;本地插件脚手架仍属于独立的工程创建问题。 -本提案只涉及开发者自有 SDK 工程的依赖。独立应用的仓库缓存、随应用捆绑 pnpm 的政策和显式的准备流程信任边界,均由[包管理器原生仓库缓存](../../implemented/architecture/2026-07-30-package-manager-native-repository-cache.md)负责。 +本提案只涉及开发者自有 SDK 工程的依赖。独立应用将外部包安装为 [profile 组合包](../../implemented/simplification/2026-08-09-remove-repository-plugin.md),由 profile 的包管理器与 lockfile 负责获取和生命周期策略。 ## Launcher 遥测 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index eebdafaa48..98604088da 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -175,8 +175,6 @@ jobs: DSH_NODE_COMPAT_SKIP_TYPECHECK: '1' DSH_OXLINT_THREADS: '8' DSH_PUBLINT_CONCURRENCY: '8' - DSH_GITHUB_REPOSITORY_PLUGIN_SOURCE: >- - github:${{ github.event.pull_request.head.repo.full_name }}#${{ github.event.pull_request.head.sha }}&path:/apps/cli/tests/fixtures/github-repository-plugin/.dsh-plugin # Failover halves snapshot concurrency for the shared 64-core VM. DSH_SNAPSHOT_MAX_CONCURRENCY: ${{ vars.DSH_CI_FAILOVER == 'selfhosted' && github.event.pull_request.user.login != 'dependabot[bot]' && '12' || '32' }} steps: @@ -242,17 +240,6 @@ jobs: if: vars.DSH_CI_FAILOVER == 'selfhosted' && github.event.pull_request.user.login != 'dependabot[bot]' run: pnpm --filter @deepseek-ai/dsh-frontend exec playwright install chromium - - name: Configure private GitHub repository Plugin access - env: - DSH_GITHUB_SOURCE_TOKEN: ${{ github.token }} - run: | - source_config="$RUNNER_TEMP/dsh-github-source.gitconfig" - basic_auth=$(printf 'x-access-token:%s' "$DSH_GITHUB_SOURCE_TOKEN" | base64 | tr -d '\n') - git config --file "$source_config" url.https://github.com/.insteadOf git@github.com: - git config --file "$source_config" --add url.https://github.com/.insteadOf ssh://git@github.com/ - git config --file "$source_config" http.https://github.com/.extraheader "AUTHORIZATION: basic $basic_auth" - echo "GIT_CONFIG_GLOBAL=$source_config" >> "$GITHUB_ENV" - - name: Run compatibility, snapshot, and artifact gates run: pnpm run check:ci:consumers diff --git a/THIRD_PARTY_NOTICES.md b/THIRD_PARTY_NOTICES.md index fec5de6128..fd10ebc2e0 100644 --- a/THIRD_PARTY_NOTICES.md +++ b/THIRD_PARTY_NOTICES.md @@ -80,7 +80,6 @@ External packages that a workspace package resolves at runtime. `scripts/install | [`node-addon-require-builtin`](https://www.npmjs.com/package/node-addon-require-builtin) | MIT | | [`node-pty`](https://github.com/microsoft/node-pty) | MIT | | [`picomatch`](https://github.com/micromatch/picomatch) | MIT | -| [`pnpm`](https://github.com/pnpm/pnpm) | MIT | | [`react`](https://github.com/facebook/react) | MIT | | [`react-dom`](https://github.com/facebook/react) | MIT | | [`sharp`](https://github.com/lovell/sharp) | Apache-2.0 | diff --git a/apps/cli/composition.md b/apps/cli/composition.md index aef0dc6a7b..9ca8ab91bf 100644 --- a/apps/cli/composition.md +++ b/apps/cli/composition.md @@ -12,8 +12,6 @@ flowchart LR cfg --> plugin_dsh_base_timer plugin_dsh_base_hmr["hmr
@cordisjs/plugin-hmr"] cfg --> plugin_dsh_base_hmr - plugin_dsh_base_repository_plugins["repository-plugins
@deepseek-ai/dsh-repository-plugin"] - cfg --> plugin_dsh_base_repository_plugins plugin_dsh_base_llm["llm
@deepseek-ai/dsh-llm"] cfg --> plugin_dsh_base_llm plugin_dsh_base_session["session
@deepseek-ai/dsh-session"] @@ -168,7 +166,6 @@ flowchart LR | --- | --- | | `timer` | `@cordisjs/plugin-timer` | | `hmr` | `@cordisjs/plugin-hmr` | -| `repository-plugins` | `@deepseek-ai/dsh-repository-plugin` | | `llm` | `@deepseek-ai/dsh-llm` | | `session` | `@deepseek-ai/dsh-session` | | `typert` | `@deepseek-ai/dsh-typert-registry` | diff --git a/apps/cli/reference/README.i18n.yaml b/apps/cli/reference/README.i18n.yaml index 4b5aed6cd2..6aa39844d0 100644 --- a/apps/cli/reference/README.i18n.yaml +++ b/apps/cli/reference/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write apps/cli/reference/README.md -README.md: 0b5faf8993cd8065fffcfec5f240b0084508db91 -README.zh.md: b9c48c16dd4be186266d30a438329463c31aca70 +README.md: 7f0bd7b0bd50482b3ba7ee95adf6aaf1defb6d28 +README.zh.md: 55f23c5644b8b063ef12fb56fa587ff5d2eb21a2 diff --git a/apps/cli/reference/README.md b/apps/cli/reference/README.md index 0b5faf8993..7f0bd7b0bd 100644 --- a/apps/cli/reference/README.md +++ b/apps/cli/reference/README.md @@ -65,11 +65,11 @@ New sessions default to the `workspace-write` permission preset. Bash and filesy ## Shared deployment behavior -The base bundle mounts the native DeepSeek adapter, settings and credential providers, stable `web_search`, repository Plugin support, and session telemetry. Provider credentials resolve from the inherited environment, `$DSH_HOME/.credentials.yaml`, the invoking directory's `.env`, then `$DSH_HOME/.env`; the managed document is never materialized into `process.env`, while both `.env` files are ordinary launch environment layers. Search uses `DEEPSEEK_API_KEY` and accepts `DEEPSEEK_SEARCH_BASE_URL`; `web_fetch` is disabled unless a patch layer inserts a provider and enables it. +The base bundle mounts the native DeepSeek adapter, settings and credential providers, stable `web_search`, and session telemetry. Provider credentials resolve from the inherited environment, `$DSH_HOME/.credentials.yaml`, the invoking directory's `.env`, then `$DSH_HOME/.env`; the managed document is never materialized into `process.env`, while both `.env` files are ordinary launch environment layers. Search uses `DEEPSEEK_API_KEY` and accepts `DEEPSEEK_SEARCH_BASE_URL`; `web_fetch` is disabled unless a patch layer inserts a provider and enables it. Session events stream as OTLP/HTTP logs by default. `DSH_TELEMETRY_OTLP_URL` selects another collector. Any non-empty `DSH_TELEMETRY_DISABLED` disables the telemetry row before boot. The shipped base has no telemetry redaction rule, so exported records can contain message text, tool arguments and results, and workspace paths; the [telemetry Agent Note](../../../.agents/notes/implemented/feature/2026-07-31-web-telemetry-default-mount.md) owns that deployment decision. -The empty `repository-plugins` row lets profile patch layers mount prepared immutable repository Plugin generations. See the [repository Plugin contract](../../../packages/self-modification/repository-plugin/README.md#standalone-app-configuration). The CLI also ships `@deepseek-ai/dsh-mcp-client` as a dependency for patch layers, but no MCP server is enabled by default because each server command is trusted executable code outside the agent sandbox. +Install external plugin bundles through `dsh plugin --profile add `. The installed package owns its dependencies and contributes its declared `cordis.patch.yml` layer. The CLI also ships `@deepseek-ai/dsh-mcp-client` as a dependency for patch layers, but no MCP server is enabled by default because each server command is trusted executable code outside the agent sandbox. ## Source launcher diff --git a/apps/cli/reference/README.zh.md b/apps/cli/reference/README.zh.md index b9c48c16dd..55f23c5644 100644 --- a/apps/cli/reference/README.zh.md +++ b/apps/cli/reference/README.zh.md @@ -65,11 +65,11 @@ dsh web --dump-config ## 共享部署行为 -基础组合包挂载原生 DeepSeek 适配器、settings 与凭据提供方、稳定的 `web_search`、repository Plugin 支持和会话遥测。提供方凭据依次从继承环境、`$DSH_HOME/.credentials.yaml`、调用目录的 `.env` 和 `$DSH_HOME/.env` 解析;受管文档从不物化进 `process.env`,而两个 `.env` 文件都是普通启动环境层。搜索使用 `DEEPSEEK_API_KEY` 并接受 `DEEPSEEK_SEARCH_BASE_URL`;只有 patch 层插入提供方并启用 `web_fetch` 后,该工具才可用。 +基础组合包挂载原生 DeepSeek 适配器、settings 与凭据提供方、稳定的 `web_search` 和会话遥测。提供方凭据依次从继承环境、`$DSH_HOME/.credentials.yaml`、调用目录的 `.env` 和 `$DSH_HOME/.env` 解析;受管文档从不物化进 `process.env`,而两个 `.env` 文件都是普通启动环境层。搜索使用 `DEEPSEEK_API_KEY` 并接受 `DEEPSEEK_SEARCH_BASE_URL`;只有 patch 层插入提供方并启用 `web_fetch` 后,该工具才可用。 会话事件默认作为 OTLP/HTTP 日志流式发送。`DSH_TELEMETRY_OTLP_URL` 选择其他 collector。任何非空 `DSH_TELEMETRY_DISABLED` 都会在启动前禁用遥测配置行。随附基础配置没有遥测脱敏规则,因此导出的记录可能包含消息文本、工具参数与结果以及 workspace 路径;该部署决策由[遥测 Agent Note](../../../.agents/notes/implemented/feature/2026-07-31-web-telemetry-default-mount.md)负责。 -空 `repository-plugins` 行让 profile 的 patch 层能够挂载已准备的不可变 repository Plugin generation。参见 [repository Plugin 约定](../../../packages/self-modification/repository-plugin/README.md#standalone-app-configuration)。CLI 还随附 `@deepseek-ai/dsh-mcp-client` 作为供 patch 层使用的依赖,但默认不启用 MCP 服务器,因为每条服务器命令都是 agent(智能体)沙箱之外的受信任可执行代码。 +通过 `dsh plugin --profile add ` 安装外部插件组合包。安装的包拥有其依赖,并贡献其声明的 `cordis.patch.yml` 层。CLI 还随附 `@deepseek-ai/dsh-mcp-client` 作为供 patch 层使用的依赖,但默认不启用 MCP 服务器,因为每条服务器命令都是 agent(智能体)沙箱之外的受信任可执行代码。 ## 源码启动器 diff --git a/apps/cli/tests/fixtures/github-repository-plugin/.dsh-plugin/.mcp.json b/apps/cli/tests/fixtures/github-repository-plugin/.dsh-plugin/.mcp.json deleted file mode 100644 index 4851f9f1f8..0000000000 --- a/apps/cli/tests/fixtures/github-repository-plugin/.dsh-plugin/.mcp.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "mcpServers": { - "github_repository": { - "command": "node", - "args": [ - "lib/mcp-server.mjs" - ] - } - } -} diff --git a/apps/cli/tests/fixtures/github-repository-plugin/.dsh-plugin/package.json b/apps/cli/tests/fixtures/github-repository-plugin/.dsh-plugin/package.json deleted file mode 100644 index 6871a4d053..0000000000 --- a/apps/cli/tests/fixtures/github-repository-plugin/.dsh-plugin/package.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "name": "dsh-github-repository-plugin-e2e-fixture", - "version": "0.0.0", - "private": true, - "type": "module", - "files": [ - "lib", - "dsh-plugin.mjs", - "dsh-plugin-assets" - ], - "scripts": { - "prepack": "tsc --noEmit && tsdown src/plugin.ts src/mcp-server.ts --no-config --tsconfig tsconfig.json --out-dir lib --platform node --target es2024 --clean && dsh-plugin-prepare" - }, - "dsh": { - "skills": [ - "../skills" - ], - "mcpServers": "./.mcp.json", - "entry": "./lib/plugin.mjs" - }, - "dependencies": { - "@modelcontextprotocol/sdk": "1.29.0" - }, - "devDependencies": { - "@deepseek-ai/dsh-repository-plugin": "0.0.1", - "cordis": "4.0.0-rc.7", - "tsdown": "0.22.2", - "typescript": "6.0.3" - } -} diff --git a/apps/cli/tests/fixtures/github-repository-plugin/.dsh-plugin/src/mcp-server.ts b/apps/cli/tests/fixtures/github-repository-plugin/.dsh-plugin/src/mcp-server.ts deleted file mode 100644 index 78a3e008f4..0000000000 --- a/apps/cli/tests/fixtures/github-repository-plugin/.dsh-plugin/src/mcp-server.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js' -import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js' - -// The repository root's linter cannot resolve this independently installed -// Git-package dependency; the package's prepack tsc validates the SDK types. -/* oxlint-disable typescript/no-unsafe-assignment, typescript/no-unsafe-call, typescript/no-unsafe-member-access */ -const server = new McpServer({ - name: 'github-repository-plugin-e2e', - version: '0.0.0', -}) - -server.registerTool('proof', { - description: 'Proves that an MCP server compiled from the exact GitHub repository package is active.', - inputSchema: {}, -}, async () => ({ - content: [{ type: 'text', text: 'MCP_FROM_GITHUB_REPOSITORY' }], -})) - -await server.connect(new StdioServerTransport()) diff --git a/apps/cli/tests/fixtures/github-repository-plugin/.dsh-plugin/src/plugin.ts b/apps/cli/tests/fixtures/github-repository-plugin/.dsh-plugin/src/plugin.ts deleted file mode 100644 index 5106f71b2f..0000000000 --- a/apps/cli/tests/fixtures/github-repository-plugin/.dsh-plugin/src/plugin.ts +++ /dev/null @@ -1,59 +0,0 @@ -import type { Context } from 'cordis' - -const PROOF_TOOL_NAME = 'mcp__github_repository__proof' - -interface TextBlock { - readonly type: 'text' - readonly text: string -} - -interface ToolExecution { - readonly name: string -} - -interface ToolResult { - readonly isError: boolean - readonly content: readonly TextBlock[] -} - -type PostDecision = - | { readonly kind: 'accept'; readonly content?: readonly TextBlock[]; readonly value?: unknown; readonly additionalContexts?: readonly unknown[] } - | { readonly kind: 'block'; readonly feedback: readonly TextBlock[] } - -type PostListener = ( - execution: ToolExecution, - result: ToolResult, - next: () => Promise, -) => Promise - -type DshContext = Context & { - on(event: 'tools/post-execute', listener: PostListener): () => void -} - -/** Cordis plugin name used by the repository acceptance fixture. */ -export const name = 'github-repository-typescript-proof' - -/** DSH tool registry required by the post-execute contribution. */ -export const inject = ['tools'] - -/** - * Append a marker after the repository MCP proof tool succeeds. - * @param ctx - trusted DSH Cordis context supplied to the repository package. - */ -export function apply(ctx: Context): void { - const dsh = ctx as DshContext - dsh.on('tools/post-execute', async (execution, result, next): Promise => { - const decision = await next() - if (execution.name !== PROOF_TOOL_NAME || result.isError || decision.kind !== 'accept' || Object.hasOwn(decision, 'value')) { - return decision - } - return { - kind: 'accept', - content: [ - ...(decision.content ?? result.content), - { type: 'text', text: 'TS_PLUGIN_FROM_GITHUB_REPOSITORY' }, - ], - ...decision.additionalContexts === undefined ? {} : { additionalContexts: decision.additionalContexts }, - } - }) -} diff --git a/apps/cli/tests/fixtures/github-repository-plugin/.dsh-plugin/tsconfig.json b/apps/cli/tests/fixtures/github-repository-plugin/.dsh-plugin/tsconfig.json deleted file mode 100644 index 22d9301cfb..0000000000 --- a/apps/cli/tests/fixtures/github-repository-plugin/.dsh-plugin/tsconfig.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "compilerOptions": { - "target": "ES2024", - "module": "ESNext", - "moduleResolution": "Bundler", - "strict": true, - "skipLibCheck": true, - "noEmit": true - }, - "include": [ - "src/**/*.ts" - ] -} diff --git a/apps/cli/tests/fixtures/github-repository-plugin/skills/github-source-proof/SKILL.md b/apps/cli/tests/fixtures/github-repository-plugin/skills/github-source-proof/SKILL.md deleted file mode 100644 index eae668a4f9..0000000000 --- a/apps/cli/tests/fixtures/github-repository-plugin/skills/github-source-proof/SKILL.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -name: github-source-proof -description: Proves that dsh installed a private repository Plugin from an exact GitHub source. ---- - -This skill exists only in the GitHub repository source fixture. diff --git a/apps/cli/tests/github-repository-plugin.built.e2e.ts b/apps/cli/tests/github-repository-plugin.built.e2e.ts deleted file mode 100644 index 7bb4706dd7..0000000000 --- a/apps/cli/tests/github-repository-plugin.built.e2e.ts +++ /dev/null @@ -1,256 +0,0 @@ -import { createHash } from 'node:crypto' -import { cpSync, existsSync, globSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, rmSync, writeFileSync } from 'node:fs' -import { createServer } from 'node:http' -import { createRequire } from 'node:module' -import { tmpdir } from 'node:os' -import { delimiter, join } from 'node:path' -import { fileURLToPath } from 'node:url' -import { startMockLlmServer } from '@deepseek-ai/dsh-llm-mock-server' -import { execa } from 'execa' -import { describe, expect, it } from 'vitest' - -const repoRoot = fileURLToPath(new URL('../../../', import.meta.url)) -const dshBin = join(repoRoot, 'apps/cli/lib/bin.js') -const repositoryPluginPackage = join(repoRoot, 'packages/self-modification/repository-plugin') -const releasePackageNames = new Set(globSync([ - 'vendor/*/package.json', - 'packages/*/*/package.json', - 'apps/*/package.json', -], { cwd: repoRoot }).map((filename) => { - const manifest = JSON.parse(readFileSync(join(repoRoot, filename), 'utf8')) as Record - if (typeof manifest.name !== 'string') throw new Error(`workspace package name is missing: ${filename}`) - return manifest.name -})) -const source = process.env.DSH_GITHUB_REPOSITORY_PLUGIN_SOURCE -const required = process.env.DSH_REQUIRE_GITHUB_REPOSITORY_PLUGIN_E2E === '1' -const enabled = required || source !== undefined - -interface PublishedPackageRegistry { - url: string - requests: string[] - close(): Promise -} - -function publishedManifest(): Record { - const manifest = JSON.parse(readFileSync(join(repositoryPluginPackage, 'package.json'), 'utf8')) as Record - const version = manifest.version - if (typeof version !== 'string') throw new Error('repository Plugin package version is missing') - Reflect.deleteProperty(manifest, 'private') - for (const field of ['dependencies', 'devDependencies', 'optionalDependencies', 'peerDependencies']) { - const dependencies = manifest[field] - if (typeof dependencies !== 'object' || dependencies === null || Array.isArray(dependencies)) continue - const entries = dependencies as Record - for (const name of Object.keys(entries)) { - if (releasePackageNames.has(name)) { - entries[name] = version - } - } - } - return manifest -} - -async function startPublishedPackageRegistry(root: string): Promise { - const staging = join(root, 'published-repository-plugin') - const artifacts = join(root, 'npm-registry-artifacts') - mkdirSync(staging) - mkdirSync(artifacts) - cpSync(join(repositoryPluginPackage, 'lib'), join(staging, 'lib'), { recursive: true }) - for (const filename of ['README.md', 'README.zh.md', 'README.i18n.yaml']) { - cpSync(join(repositoryPluginPackage, filename), join(staging, filename)) - } - cpSync(join(repoRoot, 'LICENSE'), join(staging, 'LICENSE')) - const manifest = publishedManifest() - writeFileSync(join(staging, 'package.json'), `${JSON.stringify(manifest, undefined, 2)}\n`) - const packed = await execa('pnpm', ['pack', '--pack-destination', artifacts], { - cwd: staging, - reject: false, - }) - if (packed.exitCode !== 0) { - throw new Error(`failed to pack the simulated published prepare package:\n${packed.stderr}\n${packed.stdout}`) - } - const tarballs = readdirSync(artifacts).filter(filename => filename.endsWith('.tgz')) - if (tarballs.length !== 1) throw new Error(`expected one simulated published tarball, found ${tarballs.length}`) - const tarball = readFileSync(join(artifacts, tarballs[0]!)) - const name = manifest.name as string - const version = manifest.version as string - const requests: string[] = [] - let registryUrl = '' - const server = createServer((request, response) => { - const path = decodeURIComponent(new URL(request.url ?? '/', registryUrl).pathname) - requests.push(`${request.method ?? 'GET'} ${path}`) - if (path === `/${name}`) { - const metadata = { - name, - 'dist-tags': { latest: version }, - versions: { - [version]: { - ...manifest, - dist: { - tarball: `${registryUrl}${name}/-/${name.split('/').at(-1)}-${version}.tgz`, - shasum: createHash('sha1').update(tarball).digest('hex'), - integrity: `sha512-${createHash('sha512').update(tarball).digest('base64')}`, - }, - }, - }, - } - response.writeHead(200, { 'content-type': 'application/json' }) - response.end(JSON.stringify(metadata)) - return - } - if (path === `/${name}/-/${name.split('/').at(-1)}-${version}.tgz`) { - response.writeHead(200, { - 'content-type': 'application/octet-stream', - 'content-length': String(tarball.length), - }) - response.end(tarball) - return - } - response.writeHead(404, { 'content-type': 'application/json' }) - response.end(JSON.stringify({ error: 'not found' })) - }) - await new Promise((resolve, reject) => { - server.once('error', reject) - server.listen(0, '127.0.0.1', resolve) - }) - const address = server.address() - if (address === null || typeof address === 'string') throw new Error('simulated npm registry did not expose a TCP address') - registryUrl = `http://127.0.0.1:${address.port}/` - return { - url: registryUrl, - requests, - close: () => new Promise((resolve, reject) => { - server.close((error) => { if (error === undefined) resolve(); else reject(error) }) - }), - } -} - -describe.skipIf(!enabled)('dsh run GitHub repository Plugin installation', () => { - it('installs the published prepare dependency, then builds and runs skill, MCP, and TypeScript Plugin contributions from a private exact GitHub source', async () => { - expect(existsSync(dshBin), 'the repository Plugin acceptance must run the built dsh entry').toBe(true) - expect(source, 'DSH_GITHUB_REPOSITORY_PLUGIN_SOURCE is required by this CI lane').toMatch( - /^github:[^/\s#&]+\/[^/\s#&]+#[0-9a-f]{40}&path:\/.*\/\.dsh-plugin$/u, - ) - - const apiKey = 'github-repository-plugin-e2e-key' - const server = await startMockLlmServer({ - sequence: ['tool_call_success', 'success'], - apiKey, - toolName: 'mcp__github_repository__proof', - toolArguments: '{}', - successText: 'trusted GitHub repository package reached dsh run', - }) - const home = mkdtempSync(join(tmpdir(), 'dsh-github-repository-plugin-')) - const registry = await startPublishedPackageRegistry(home) - const npmrc = join(home, 'npmrc') - writeFileSync(npmrc, `@deepseek-ai:registry=${registry.url}\n`) - const hostBin = join(home, 'host-bin') - mkdirSync(hostBin) - writeFileSync(join(hostBin, 'dsh-plugin-prepare'), [ - '#!/bin/sh', - 'echo "host PATH supplied dsh-plugin-prepare instead of the declared npm dependency" >&2', - 'exit 91', - '', - ].join('\n'), { mode: 0o700 }) - const patch = join(home, 'github-repository-plugin.cordis.patch.yml') - writeFileSync(patch, [ - '- id: repository-plugins', - ' config:', - ' repositories:', - ` - ${JSON.stringify(source)}`, - '- id: session-title-llm', - ' disabled: true', - '', - ].join('\n')) - - try { - const result = await execa(process.execPath, [ - dshBin, - 'run', - '--patch', - patch, - 'prove the private GitHub repository Plugin is active', - ], { - cwd: repoRoot, - input: '', - timeout: 180_000, - killSignal: 'SIGKILL', - reject: false, - env: { - ...process.env, - DSH_HOME: home, - DSH_TELEMETRY_DISABLED: '1', - DEEPSEEK_API_KEY: apiKey, - DEEPSEEK_BASE_URL: server.baseURL, - NPM_CONFIG_USERCONFIG: npmrc, - // A warm runner cache could satisfy the exact tarball without - // contacting this test's registry, which would stop proving the - // unpublished package was installed through the simulated release. - PNPM_CONFIG_CACHE_DIR: join(home, 'pnpm-cache'), - PNPM_CONFIG_STORE_DIR: join(home, 'pnpm-store'), - PATH: process.env.PATH === undefined ? hostBin : `${hostBin}${delimiter}${process.env.PATH}`, - }, - }) - if (result.timedOut) { - throw new Error(`dsh GitHub repository Plugin run did not exit within 180s. stdout:\n${result.stdout}\nstderr:\n${result.stderr}`) - } - expect(result.exitCode, `${result.stderr}\nstdout:\n${result.stdout}`).toBe(0) - expect(result.stdout).toBe('trusted GitHub repository package reached dsh run') - expect(server.requests).toHaveLength(2) - const runtimeDiagnostic = `${result.stderr}\nstdout:\n${result.stdout}` - expect(registry.requests, runtimeDiagnostic).toContain('GET /@deepseek-ai/dsh-repository-plugin') - expect(registry.requests, runtimeDiagnostic).toContain('GET /@deepseek-ai/dsh-repository-plugin/-/dsh-repository-plugin-0.0.1.tgz') - const firstRequest = JSON.stringify(server.requests[0]!.body) - const secondRequest = JSON.stringify(server.requests[1]!.body) - expect(firstRequest, runtimeDiagnostic).toContain( - 'Proves that dsh installed a private repository Plugin from an exact GitHub source.', - ) - expect(firstRequest, runtimeDiagnostic).toContain('mcp__github_repository__proof') - expect(firstRequest, runtimeDiagnostic).toContain('Proves that an MCP server compiled from the exact GitHub repository package is active.') - expect(secondRequest, runtimeDiagnostic).toContain('MCP_FROM_GITHUB_REPOSITORY') - expect(secondRequest, runtimeDiagnostic).toContain('TS_PLUGIN_FROM_GITHUB_REPOSITORY') - - const cacheRoot = join(home, 'cache', 'repository-plugins') - const generations = readdirSync(cacheRoot, { withFileTypes: true }).filter(entry => entry.isDirectory()) - expect(generations).toHaveLength(1) - const installed = join(cacheRoot, generations[0]!.name, 'node_modules', 'repository') - const manifest = JSON.parse(readFileSync(join(installed, 'package.json'), 'utf8')) as Record - expect(manifest).toMatchObject({ - name: 'dsh-github-repository-plugin-e2e-fixture', - private: true, - scripts: { - prepack: 'tsc --noEmit && tsdown src/plugin.ts src/mcp-server.ts --no-config --tsconfig tsconfig.json --out-dir lib --platform node --target es2024 --clean && dsh-plugin-prepare', - }, - dsh: { - skills: ['../skills'], - mcpServers: './.mcp.json', - entry: './lib/plugin.mjs', - }, - dependencies: { - '@modelcontextprotocol/sdk': '1.29.0', - }, - devDependencies: { - '@deepseek-ai/dsh-repository-plugin': '0.0.1', - cordis: '4.0.0-rc.7', - tsdown: '0.22.2', - typescript: '6.0.3', - }, - }) - expect(readFileSync(join(installed, 'dsh-plugin-assets/skills/0/github-source-proof/SKILL.md'), 'utf8')) - .toContain('This skill exists only in the GitHub repository source fixture.') - expect(readFileSync(join(installed, 'dsh-plugin-assets/.mcp.json'), 'utf8')).toContain('lib/mcp-server.mjs') - expect(readFileSync(join(installed, 'lib/plugin.mjs'), 'utf8')).toContain('TS_PLUGIN_FROM_GITHUB_REPOSITORY') - expect(readFileSync(join(installed, 'lib/mcp-server.mjs'), 'utf8')).toContain('MCP_FROM_GITHUB_REPOSITORY') - expect(existsSync(join(installed, 'src'))).toBe(false) - const installedRequire = createRequire(join(installed, 'lib/mcp-server.mjs')) - expect(existsSync(installedRequire.resolve('@modelcontextprotocol/sdk/server/mcp.js'))).toBe(true) - const wrapper = readFileSync(join(installed, 'dsh-plugin.mjs'), 'utf8') - expect(wrapper).toContain('dsh-repository-plugin') - expect(wrapper).toContain('await import(manifest.entry)') - expect(wrapper).toContain('"entry":"./lib/plugin.mjs"') - } finally { - await server.close() - await registry.close() - rmSync(home, { recursive: true, force: true }) - } - }, 190_000) -}) diff --git a/docs/config-catalog.md b/docs/config-catalog.md index 471680f92d..842b96d950 100644 --- a/docs/config-catalog.md +++ b/docs/config-catalog.md @@ -1109,7 +1109,7 @@ export interface StreamableHttpConfig { } ``` -Source: [`packages/mcp/mcp-client/src/index.ts:100`](../packages/mcp/mcp-client/src/index.ts) +Source: [`packages/mcp/mcp-client/src/index.ts:98`](../packages/mcp/mcp-client/src/index.ts) ## `@deepseek-ai/dsh-permission` @@ -1306,22 +1306,6 @@ export interface Config { Source: [`packages/guard/repeat-tool-guard/src/index.ts:28`](../packages/guard/repeat-tool-guard/src/index.ts) -## `@deepseek-ai/dsh-repository-plugin` - -Requires: `loader` - -```ts config-catalog -/** Repository Plugin runtime and source-list configuration. */ -export interface Config { - /** GitHub repository sources with explicit refs and optional `.dsh-plugin` subpaths. */ - repositories?: string[] - /** Persistent generation cache; defaults to `$DSH_HOME/cache/repository-plugins`. */ - cacheDir?: string -} -``` - -Source: [`packages/self-modification/repository-plugin/src/index.ts:44`](../packages/self-modification/repository-plugin/src/index.ts) - ## `@deepseek-ai/dsh-sandbox-local` ```ts config-catalog diff --git a/docs/module-graph.md b/docs/module-graph.md index b596cb5649..9f2780c57a 100644 --- a/docs/module-graph.md +++ b/docs/module-graph.md @@ -253,7 +253,6 @@ flowchart TD pkg_telemetry["telemetry"] end subgraph group_self_modification["packages/self-modification"] - pkg_repository_plugin["repository-plugin"] pkg_tool_cordis["tool-cordis"] end subgraph group_session["packages/session"] @@ -1069,10 +1068,6 @@ flowchart TD pkg_sdk_protocol --> pkg_llm pkg_sdk_protocol --> pkg_session pkg_sdk_protocol --> pkg_subagent - pkg_repository_plugin --> pkg_invariants - pkg_repository_plugin --> pkg_mcp_client - pkg_repository_plugin --> pkg_paths - pkg_repository_plugin --> pkg_skill_local pkg_tool_ralph --> pkg_agent pkg_tool_ralph --> pkg_invariants pkg_tool_ralph --> pkg_llm @@ -1430,7 +1425,6 @@ flowchart TD | [`web-app`](../packages/bundle/web-app) | `bundle` | [`bash-env`](../packages/bash/bash-env), [`invariants`](../packages/support/invariants), [`system-prompt`](../packages/core/system-prompt) | | [`client-ui-conversation`](../packages/client/ui-conversation) | `client` | [`agent`](../packages/core/agent), [`attachment`](../packages/attachment/attachment), [`brand`](../packages/util/brand), [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-primitives`](../packages/client/ui-primitives), [`client-ui-slash`](../packages/client/ui-slash), [`client-ui-slots`](../packages/client/ui-slots), [`commands`](../packages/interaction/commands), [`compact`](../packages/compact/compact), [`invariants`](../packages/support/invariants), [`llm-retry`](../packages/llm/llm-retry), [`token-meter`](../packages/llm/token-meter), [`tools`](../packages/core/tools) | | [`sdk-protocol`](../packages/scaffold/protocol) | `scaffold` | [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`subagent`](../packages/subagent/subagent) | -| [`repository-plugin`](../packages/self-modification/repository-plugin) | `self-modification` | [`invariants`](../packages/support/invariants), [`mcp-client`](../packages/mcp/mcp-client), [`paths`](../packages/util/paths), [`skill-local`](../packages/skill/skill-local) | | [`tool-ralph`](../packages/workflow/tool-ralph) | `workflow` | [`agent`](../packages/core/agent), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`subagent`](../packages/subagent/subagent), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools), [`workflow`](../packages/workflow/workflow) | | [`workflow-workerthread`](../packages/workflow/workflow-workerthread) | `workflow` | [`agent`](../packages/core/agent), [`brand`](../packages/util/brand), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`subagent`](../packages/subagent/subagent), [`tools`](../packages/core/tools), [`workflow`](../packages/workflow/workflow) | | [`compact-basic`](../packages/compact/compact-basic) | `compact` | [`agent`](../packages/core/agent), [`commands`](../packages/interaction/commands), [`compact`](../packages/compact/compact), [`compact-tool-result-prune`](../packages/compact/compact-tool-result-prune), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`token-meter`](../packages/llm/token-meter) | diff --git a/docs/tool-catalog.md b/docs/tool-catalog.md index dbab9ce2f3..f61b6daeb7 100644 --- a/docs/tool-catalog.md +++ b/docs/tool-catalog.md @@ -284,7 +284,7 @@ Source: [`packages/self-modification/tool-cordis/src/index.ts`](../packages/self ### `cordis_mount` -Mount a temporary Cordis Plugin in the current DSH process. This creates an in-memory runtime Plugin, not an installed or configured Plugin. It remains active across later turns until cordis_unmount, toolset unload, or DSH restart. It does not create files, install a package, change cordis.yml or personal/project config, survive restart, or automatically become permanent. To keep it, ask the Agent to implement a normal local, project, or repository Plugin through the regular development workflow. It may affect other sessions in the same process; the sandbox is not a security boundary, and injected services reach the real runtime. `code` runs now as the body of an async JavaScript function in an isolated sandbox and MUST `return` a plugin. Two forms: FUNCTION form `return (ctx) => { … }` — declares no inject, so it can register tools, listen to events, and provide services, but reaching ANY service (e.g. ctx.bash) throws; use it only when you need no services. OBJECT form `return { name?, inject: ['bash', 'llm', …], apply(ctx) { … } }` — declares dependencies, and cordis activates the plugin only after the services exist; PREFER this form. You may reach ONLY the services you list in inject: an undeclared service throws even if it exists, because an undeclared dependency would not be cleaned up if its provider is unmounted. BEFORE calling a service from your code, read cordis_inspect what:"api" — it lists method signatures AND the type shapes of their arguments/returns (do not guess a field's type; e.g. a bash run's stdout is an object, not a string). Inside `apply`, use the standard cordis API: `ctx.on(event, listener)` to observe events (see cordis_inspect what:"events"), or call `harness.registerTool(ctx, harness.defineTool({ name, description, parameters: { text: { type: 'string', required: true } }, output: { schema: { type: 'string' }, render(_args, value) { return [{ type: 'text', text: value }] } }, async execute(args) { return args.text } }))` to give yourself a new tool — it becomes callable on your NEXT step. Tool parameters: each key IS a property — { type: 'string'|'number'|'integer'|'boolean'|'null'|'object'|'array'|'json', required?: true, description?, enum?, const?, items?, properties? }; every direct DSL object declares additionalProperties: true|false, and oneOf: [schema, schema, ...] replaces type for an exact-one union. A raw JSON-Schema { type: 'object', properties, required?: […] } wrapper is also accepted with open-by-default objects. A tool's `execute` MUST return the lossless JSON value declared by `output.schema`; `output.render(args, value)` separately returns Native/model content blocks. Temporary Plugins can COMPOSE: one Plugin may `ctx.provide('name', value)` a service and another may declare `inject: ['name']` to consume it — the consumer stays pending until the provider exists and returns to pending when the provider is unmounted. Everything registered inside `apply` is cleaned up automatically by cordis_unmount. Sandbox globals: `console` (tagged `[cordis:]`, writes through to the harness terminal), `harness.defineTool`, `harness.registerTool`, `btoa`, `atob`, `TextEncoder`, `TextDecoder`. Node APIs are DISABLED — do filesystem/network/timer work through the cordis services, never Node built-ins: `require`, `setTimeout`/`setInterval`, and `fetch` throw redirect errors; `process` and `Buffer` are undefined. Instead use inject: ['fs'] + ctx.fs for files, inject: ['web'] + ctx.web for HTTP, inject: ['bash'] + ctx.bash for processes, and inject: ['timer'] + ctx.setTimeout/ctx.setInterval for timing (fiber effects, auto-cleaned when unmounted) — cordis_inspect what:"api" shows what THIS runtime provides. Write PLAIN JavaScript, not TypeScript (no `as`, no type annotations). Cautions: (1) waterfall events (e.g. tools/pre-execute) hand the listener a trailing `next` callback which MUST be called — returning without `next()` SHORT-CIRCUITS the call; prefer plain notification events unless you intend to intercept. (2) Never await something that only resolves after the current turn (your code runs INSIDE a tool call of that turn — it would deadlock). (3) Your `ctx` is a restricted façade: you can register tools, observe events, provide/consume services, and use timers, but framework internals (ctx.root, ctx.fiber, ctx.extend, ctx.plugin, …) are withheld. It is not a security boundary though — the services you inject (e.g. ctx.bash) reach the real runtime. +Mount a temporary Cordis Plugin in the current DSH process. This creates an in-memory runtime Plugin, not an installed or configured Plugin. It remains active across later turns until cordis_unmount, toolset unload, or DSH restart. It does not create files, install a package, change cordis.yml or personal/project config, survive restart, or automatically become permanent. To keep it, ask the Agent to implement an SDK Plugin or installable profile bundle through the regular development workflow. It may affect other sessions in the same process; the sandbox is not a security boundary, and injected services reach the real runtime. `code` runs now as the body of an async JavaScript function in an isolated sandbox and MUST `return` a plugin. Two forms: FUNCTION form `return (ctx) => { … }` — declares no inject, so it can register tools, listen to events, and provide services, but reaching ANY service (e.g. ctx.bash) throws; use it only when you need no services. OBJECT form `return { name?, inject: ['bash', 'llm', …], apply(ctx) { … } }` — declares dependencies, and cordis activates the plugin only after the services exist; PREFER this form. You may reach ONLY the services you list in inject: an undeclared service throws even if it exists, because an undeclared dependency would not be cleaned up if its provider is unmounted. BEFORE calling a service from your code, read cordis_inspect what:"api" — it lists method signatures AND the type shapes of their arguments/returns (do not guess a field's type; e.g. a bash run's stdout is an object, not a string). Inside `apply`, use the standard cordis API: `ctx.on(event, listener)` to observe events (see cordis_inspect what:"events"), or call `harness.registerTool(ctx, harness.defineTool({ name, description, parameters: { text: { type: 'string', required: true } }, output: { schema: { type: 'string' }, render(_args, value) { return [{ type: 'text', text: value }] } }, async execute(args) { return args.text } }))` to give yourself a new tool — it becomes callable on your NEXT step. Tool parameters: each key IS a property — { type: 'string'|'number'|'integer'|'boolean'|'null'|'object'|'array'|'json', required?: true, description?, enum?, const?, items?, properties? }; every direct DSL object declares additionalProperties: true|false, and oneOf: [schema, schema, ...] replaces type for an exact-one union. A raw JSON-Schema { type: 'object', properties, required?: […] } wrapper is also accepted with open-by-default objects. A tool's `execute` MUST return the lossless JSON value declared by `output.schema`; `output.render(args, value)` separately returns Native/model content blocks. Temporary Plugins can COMPOSE: one Plugin may `ctx.provide('name', value)` a service and another may declare `inject: ['name']` to consume it — the consumer stays pending until the provider exists and returns to pending when the provider is unmounted. Everything registered inside `apply` is cleaned up automatically by cordis_unmount. Sandbox globals: `console` (tagged `[cordis:]`, writes through to the harness terminal), `harness.defineTool`, `harness.registerTool`, `btoa`, `atob`, `TextEncoder`, `TextDecoder`. Node APIs are DISABLED — do filesystem/network/timer work through the cordis services, never Node built-ins: `require`, `setTimeout`/`setInterval`, and `fetch` throw redirect errors; `process` and `Buffer` are undefined. Instead use inject: ['fs'] + ctx.fs for files, inject: ['web'] + ctx.web for HTTP, inject: ['bash'] + ctx.bash for processes, and inject: ['timer'] + ctx.setTimeout/ctx.setInterval for timing (fiber effects, auto-cleaned when unmounted) — cordis_inspect what:"api" shows what THIS runtime provides. Write PLAIN JavaScript, not TypeScript (no `as`, no type annotations). Cautions: (1) waterfall events (e.g. tools/pre-execute) hand the listener a trailing `next` callback which MUST be called — returning without `next()` SHORT-CIRCUITS the call; prefer plain notification events unless you intend to intercept. (2) Never await something that only resolves after the current turn (your code runs INSIDE a tool call of that turn — it would deadlock). (3) Your `ctx` is a restricted façade: you can register tools, observe events, provide/consume services, and use timers, but framework internals (ctx.root, ctx.fiber, ctx.extend, ctx.plugin, …) are withheld. It is not a security boundary though — the services you inject (e.g. ctx.bash) reach the real runtime. ```json { diff --git a/examples/acp-agent/tests/snapshots/advanced-toolchain/session.1.jsonl b/examples/acp-agent/tests/snapshots/advanced-toolchain/session.1.jsonl index 7908f0e71b..80e66c8c47 100644 --- a/examples/acp-agent/tests/snapshots/advanced-toolchain/session.1.jsonl +++ b/examples/acp-agent/tests/snapshots/advanced-toolchain/session.1.jsonl @@ -5,7 +5,7 @@ {"type":"subagent/descriptor","seq":3,"time":1785821418091,"data":{"version":2,"mode":"one-shot","provider":"spawn","label":"Check direct child"}} {"type":"step/start","seq":4,"time":1785730458555,"data":{"turn":1,"step":1}} {"type":"user/message","seq":5,"time":1785730458555,"data":{"content":[{"type":"text","text":"Reply with exactly DIRECT_CHILD_OK and nothing else."}],"source":{"kind":"user"},"role":"user","id":"ebe0cfa0-a909-47e0-8294-28ad84a8fe77"},"surfaceOp":"append"} -{"type":"user/message","seq":6,"time":1785730458555,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}]},"role":"user","id":"f9a2d1b6-8f23-43a5-8702-d413fed40990"},"surfaceOp":"append"} +{"type":"user/message","seq":6,"time":1785730458555,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}]},"role":"user","id":"c9c613c6-adfc-4ba3-b7d8-322bcb26a668"},"surfaceOp":"append"} {"type":"session/title","seq":7,"time":1785730458555,"data":{"title":"Reply with exactly DIRECT_CHILD_OK and","messageSeqs":[5],"source":{"kind":"fallback"}}} {"type":"request/header","seq":8,"time":1785730458555,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}} {"type":"request/context","seq":9,"time":1785730458555,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} diff --git a/examples/acp-agent/tests/snapshots/advanced-toolchain/session.2.jsonl b/examples/acp-agent/tests/snapshots/advanced-toolchain/session.2.jsonl index adf877c24b..ce189804c5 100644 --- a/examples/acp-agent/tests/snapshots/advanced-toolchain/session.2.jsonl +++ b/examples/acp-agent/tests/snapshots/advanced-toolchain/session.2.jsonl @@ -5,7 +5,7 @@ {"type":"subagent/descriptor","seq":3,"time":1785821418270,"data":{"version":2,"mode":"one-shot","provider":"spawn"}} {"type":"step/start","seq":4,"time":1785730458703,"data":{"turn":1,"step":1}} {"type":"user/message","seq":5,"time":1785730458703,"data":{"content":[{"type":"text","text":"Reply with exactly WORKFLOW_CHILD_OK and nothing else."}],"source":{"kind":"user"},"role":"user","id":"2ac2cc54-9bce-4cfa-a569-a64f51bc30a7"},"surfaceOp":"append"} -{"type":"user/message","seq":6,"time":1785730458703,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}]},"role":"user","id":"dfbcd587-db47-4c3d-bbe9-8c031b215fc3"},"surfaceOp":"append"} +{"type":"user/message","seq":6,"time":1785730458703,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}]},"role":"user","id":"fee5dd01-66b5-4856-9fc8-f375e0c37ae1"},"surfaceOp":"append"} {"type":"session/title","seq":7,"time":1785730458703,"data":{"title":"Reply with exactly WORKFLOW_CHILD_OK and","messageSeqs":[5],"source":{"kind":"fallback"}}} {"type":"request/header","seq":8,"time":1785730458703,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}} {"type":"request/context","seq":9,"time":1785730458703,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} diff --git a/examples/acp-agent/tests/snapshots/advanced-toolchain/session.jsonl b/examples/acp-agent/tests/snapshots/advanced-toolchain/session.jsonl index d6935b6c98..d16b9bcccb 100644 --- a/examples/acp-agent/tests/snapshots/advanced-toolchain/session.jsonl +++ b/examples/acp-agent/tests/snapshots/advanced-toolchain/session.jsonl @@ -4,7 +4,7 @@ {"type":"agent/inbox/spliced","seq":2,"time":1785821417919,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} {"type":"step/start","seq":3,"time":1783957884486,"data":{"turn":1,"step":1}} {"type":"user/message","seq":4,"time":1785498801761,"data":{"content":[{"type":"text","text":"Run this advanced flow exactly once: try a no-op temporary Cordis Plugin named snapshot-marker; use run_code to inspect the live temporary Plugins through tools.cordis_inspect; delegate once to a direct spawn child; run one workflow that delegates to another spawn child; stop dyn-1; then reply with exactly ADVANCED_ACP_OK."}],"source":{"kind":"user"},"role":"user","id":"6e45782a-31be-4ba7-8c4a-7411a2027e36"},"surfaceOp":"append"} -{"type":"user/message","seq":5,"time":1785730458430,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}]},"role":"user","id":"9f38e2b8-1d4e-4c90-8896-00aa42307ea7"},"surfaceOp":"append"} +{"type":"user/message","seq":5,"time":1785730458430,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}]},"role":"user","id":"f8ef8963-7ba4-4836-8cef-7321aa1d30cf"},"surfaceOp":"append"} {"type":"session/title","seq":6,"time":1785730458430,"data":{"title":"Run this advanced flow exactly","messageSeqs":[4],"source":{"kind":"fallback"}}} {"type":"request/header","seq":7,"time":1785498801765,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}} {"type":"request/context","seq":8,"time":1785730458431,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} diff --git a/examples/acp-agent/tests/snapshots/advanced-toolchain/system-prompt.expected.md b/examples/acp-agent/tests/snapshots/advanced-toolchain/system-prompt.expected.md index 2014dc54e3..b613fbac76 100644 --- a/examples/acp-agent/tests/snapshots/advanced-toolchain/system-prompt.expected.md +++ b/examples/acp-agent/tests/snapshots/advanced-toolchain/system-prompt.expected.md @@ -60,7 +60,7 @@ interface ToolArgsMap { /** Exact service key or event name whose original JSDoc to include; valid only with what:"api" or what:"events". */ name?: string; } & Record; - /** Mount a temporary Cordis Plugin in the current DSH process. This creates an in-memory runtime Plugin, not an installed or configured Plugin. It remains active across later turns until cordis_unmount, toolset unload, or DSH restart. It does not create files, install a package, change cordis.yml or personal/project config, survive restart, or automatically become permanent. To keep it, ask the Agent to implement a normal local, project, or repository Plugin through the regular development workflow. It may affect other sessions in the same process; the sandbox is not a security boundary, and injected services reach the real runtime. `code` runs now as the body of an async JavaScript function in an isolated sandbox and MUST `return` a plugin. Two forms: FUNCTION form `return (ctx) => { … }` — declares no inject, so it can register tools, listen to events, and provide services, but reaching ANY service (e.g. ctx.bash) throws; use it only when you need no services. OBJECT form `return { name?, inject: ['bash', 'llm', …], apply(ctx) { … } }` — declares dependencies, and cordis activates the plugin only after the services exist; PREFER this form. You may reach ONLY the services you list in inject: an undeclared service throws even if it exists, because an undeclared dependency would not be cleaned up if its provider is unmounted. BEFORE calling a service from your code, read cordis_inspect what:"api" — it lists method signatures AND the type shapes of their arguments/returns (do not guess a field's type; e.g. a bash run's stdout is an object, not a string). Inside `apply`, use the standard cordis API: `ctx.on(event, listener)` to observe events (see cordis_inspect what:"events"), or call `harness.registerTool(ctx, harness.defineTool({ name, description, parameters: { text: { type: 'string', required: true } }, output: { schema: { type: 'string' }, render(_args, value) { return [{ type: 'text', text: value }] } }, async execute(args) { return args.text } }))` to give yourself a new tool — it becomes callable on your NEXT step. Tool parameters: each key IS a property — { type: 'string'|'number'|'integer'|'boolean'|'null'|'object'|'array'|'json', required?: true, description?, enum?, const?, items?, properties? }; every direct DSL object declares additionalProperties: true|false, and oneOf: [schema, schema, ...] replaces type for an exact-one union. A raw JSON-Schema { type: 'object', properties, required?: […] } wrapper is also accepted with open-by-default objects. A tool's `execute` MUST return the lossless JSON value declared by `output.schema`; `output.render(args, value)` separately returns Native/model content blocks. Temporary Plugins can COMPOSE: one Plugin may `ctx.provide('name', value)` a service and another may declare `inject: ['name']` to consume it — the consumer stays pending until the provider exists and returns to pending when the provider is unmounted. Everything registered inside `apply` is cleaned up automatically by cordis_unmount. Sandbox globals: `console` (tagged `[cordis:]`, writes through to the harness terminal), `harness.defineTool`, `harness.registerTool`, `btoa`, `atob`, `TextEncoder`, `TextDecoder`. Node APIs are DISABLED — do filesystem/network/timer work through the cordis services, never Node built-ins: `require`, `setTimeout`/`setInterval`, and `fetch` throw redirect errors; `process` and `Buffer` are undefined. Instead use inject: ['fs'] + ctx.fs for files, inject: ['web'] + ctx.web for HTTP, inject: ['bash'] + ctx.bash for processes, and inject: ['timer'] + ctx.setTimeout/ctx.setInterval for timing (fiber effects, auto-cleaned when unmounted) — cordis_inspect what:"api" shows what THIS runtime provides. Write PLAIN JavaScript, not TypeScript (no `as`, no type annotations). Cautions: (1) waterfall events (e.g. tools/pre-execute) hand the listener a trailing `next` callback which MUST be called — returning without `next()` SHORT-CIRCUITS the call; prefer plain notification events unless you intend to intercept. (2) Never await something that only resolves after the current turn (your code runs INSIDE a tool call of that turn — it would deadlock). (3) Your `ctx` is a restricted façade: you can register tools, observe events, provide/consume services, and use timers, but framework internals (ctx.root, ctx.fiber, ctx.extend, ctx.plugin, …) are withheld. It is not a security boundary though — the services you inject (e.g. ctx.bash) reach the real runtime. */ + /** Mount a temporary Cordis Plugin in the current DSH process. This creates an in-memory runtime Plugin, not an installed or configured Plugin. It remains active across later turns until cordis_unmount, toolset unload, or DSH restart. It does not create files, install a package, change cordis.yml or personal/project config, survive restart, or automatically become permanent. To keep it, ask the Agent to implement an SDK Plugin or installable profile bundle through the regular development workflow. It may affect other sessions in the same process; the sandbox is not a security boundary, and injected services reach the real runtime. `code` runs now as the body of an async JavaScript function in an isolated sandbox and MUST `return` a plugin. Two forms: FUNCTION form `return (ctx) => { … }` — declares no inject, so it can register tools, listen to events, and provide services, but reaching ANY service (e.g. ctx.bash) throws; use it only when you need no services. OBJECT form `return { name?, inject: ['bash', 'llm', …], apply(ctx) { … } }` — declares dependencies, and cordis activates the plugin only after the services exist; PREFER this form. You may reach ONLY the services you list in inject: an undeclared service throws even if it exists, because an undeclared dependency would not be cleaned up if its provider is unmounted. BEFORE calling a service from your code, read cordis_inspect what:"api" — it lists method signatures AND the type shapes of their arguments/returns (do not guess a field's type; e.g. a bash run's stdout is an object, not a string). Inside `apply`, use the standard cordis API: `ctx.on(event, listener)` to observe events (see cordis_inspect what:"events"), or call `harness.registerTool(ctx, harness.defineTool({ name, description, parameters: { text: { type: 'string', required: true } }, output: { schema: { type: 'string' }, render(_args, value) { return [{ type: 'text', text: value }] } }, async execute(args) { return args.text } }))` to give yourself a new tool — it becomes callable on your NEXT step. Tool parameters: each key IS a property — { type: 'string'|'number'|'integer'|'boolean'|'null'|'object'|'array'|'json', required?: true, description?, enum?, const?, items?, properties? }; every direct DSL object declares additionalProperties: true|false, and oneOf: [schema, schema, ...] replaces type for an exact-one union. A raw JSON-Schema { type: 'object', properties, required?: […] } wrapper is also accepted with open-by-default objects. A tool's `execute` MUST return the lossless JSON value declared by `output.schema`; `output.render(args, value)` separately returns Native/model content blocks. Temporary Plugins can COMPOSE: one Plugin may `ctx.provide('name', value)` a service and another may declare `inject: ['name']` to consume it — the consumer stays pending until the provider exists and returns to pending when the provider is unmounted. Everything registered inside `apply` is cleaned up automatically by cordis_unmount. Sandbox globals: `console` (tagged `[cordis:]`, writes through to the harness terminal), `harness.defineTool`, `harness.registerTool`, `btoa`, `atob`, `TextEncoder`, `TextDecoder`. Node APIs are DISABLED — do filesystem/network/timer work through the cordis services, never Node built-ins: `require`, `setTimeout`/`setInterval`, and `fetch` throw redirect errors; `process` and `Buffer` are undefined. Instead use inject: ['fs'] + ctx.fs for files, inject: ['web'] + ctx.web for HTTP, inject: ['bash'] + ctx.bash for processes, and inject: ['timer'] + ctx.setTimeout/ctx.setInterval for timing (fiber effects, auto-cleaned when unmounted) — cordis_inspect what:"api" shows what THIS runtime provides. Write PLAIN JavaScript, not TypeScript (no `as`, no type annotations). Cautions: (1) waterfall events (e.g. tools/pre-execute) hand the listener a trailing `next` callback which MUST be called — returning without `next()` SHORT-CIRCUITS the call; prefer plain notification events unless you intend to intercept. (2) Never await something that only resolves after the current turn (your code runs INSIDE a tool call of that turn — it would deadlock). (3) Your `ctx` is a restricted façade: you can register tools, observe events, provide/consume services, and use timers, but framework internals (ctx.root, ctx.fiber, ctx.extend, ctx.plugin, …) are withheld. It is not a security boundary though — the services you inject (e.g. ctx.bash) reach the real runtime. */ cordis_mount: { /** JavaScript body returning a temporary Plugin; evaluated now and saved nowhere. */ code: string; diff --git a/examples/acp-agent/tests/snapshots/advanced-toolchain/tool-schemas.expected.json b/examples/acp-agent/tests/snapshots/advanced-toolchain/tool-schemas.expected.json index 403d3fbc6c..c979e1db87 100644 --- a/examples/acp-agent/tests/snapshots/advanced-toolchain/tool-schemas.expected.json +++ b/examples/acp-agent/tests/snapshots/advanced-toolchain/tool-schemas.expected.json @@ -72,7 +72,7 @@ }, { "name": "cordis_mount", - "description": "Mount a temporary Cordis Plugin in the current DSH process. This creates an in-memory runtime Plugin, not an installed or configured Plugin. It remains active across later turns until cordis_unmount, toolset unload, or DSH restart. It does not create files, install a package, change cordis.yml or personal/project config, survive restart, or automatically become permanent. To keep it, ask the Agent to implement a normal local, project, or repository Plugin through the regular development workflow. It may affect other sessions in the same process; the sandbox is not a security boundary, and injected services reach the real runtime. `code` runs now as the body of an async JavaScript function in an isolated sandbox and MUST `return` a plugin. Two forms: FUNCTION form `return (ctx) => { … }` — declares no inject, so it can register tools, listen to events, and provide services, but reaching ANY service (e.g. ctx.bash) throws; use it only when you need no services. OBJECT form `return { name?, inject: ['bash', 'llm', …], apply(ctx) { … } }` — declares dependencies, and cordis activates the plugin only after the services exist; PREFER this form. You may reach ONLY the services you list in inject: an undeclared service throws even if it exists, because an undeclared dependency would not be cleaned up if its provider is unmounted. BEFORE calling a service from your code, read cordis_inspect what:\"api\" — it lists method signatures AND the type shapes of their arguments/returns (do not guess a field's type; e.g. a bash run's stdout is an object, not a string). Inside `apply`, use the standard cordis API: `ctx.on(event, listener)` to observe events (see cordis_inspect what:\"events\"), or call `harness.registerTool(ctx, harness.defineTool({ name, description, parameters: { text: { type: 'string', required: true } }, output: { schema: { type: 'string' }, render(_args, value) { return [{ type: 'text', text: value }] } }, async execute(args) { return args.text } }))` to give yourself a new tool — it becomes callable on your NEXT step. Tool parameters: each key IS a property — { type: 'string'|'number'|'integer'|'boolean'|'null'|'object'|'array'|'json', required?: true, description?, enum?, const?, items?, properties? }; every direct DSL object declares additionalProperties: true|false, and oneOf: [schema, schema, ...] replaces type for an exact-one union. A raw JSON-Schema { type: 'object', properties, required?: […] } wrapper is also accepted with open-by-default objects. A tool's `execute` MUST return the lossless JSON value declared by `output.schema`; `output.render(args, value)` separately returns Native/model content blocks. Temporary Plugins can COMPOSE: one Plugin may `ctx.provide('name', value)` a service and another may declare `inject: ['name']` to consume it — the consumer stays pending until the provider exists and returns to pending when the provider is unmounted. Everything registered inside `apply` is cleaned up automatically by cordis_unmount. Sandbox globals: `console` (tagged `[cordis:]`, writes through to the harness terminal), `harness.defineTool`, `harness.registerTool`, `btoa`, `atob`, `TextEncoder`, `TextDecoder`. Node APIs are DISABLED — do filesystem/network/timer work through the cordis services, never Node built-ins: `require`, `setTimeout`/`setInterval`, and `fetch` throw redirect errors; `process` and `Buffer` are undefined. Instead use inject: ['fs'] + ctx.fs for files, inject: ['web'] + ctx.web for HTTP, inject: ['bash'] + ctx.bash for processes, and inject: ['timer'] + ctx.setTimeout/ctx.setInterval for timing (fiber effects, auto-cleaned when unmounted) — cordis_inspect what:\"api\" shows what THIS runtime provides. Write PLAIN JavaScript, not TypeScript (no `as`, no type annotations). Cautions: (1) waterfall events (e.g. tools/pre-execute) hand the listener a trailing `next` callback which MUST be called — returning without `next()` SHORT-CIRCUITS the call; prefer plain notification events unless you intend to intercept. (2) Never await something that only resolves after the current turn (your code runs INSIDE a tool call of that turn — it would deadlock). (3) Your `ctx` is a restricted façade: you can register tools, observe events, provide/consume services, and use timers, but framework internals (ctx.root, ctx.fiber, ctx.extend, ctx.plugin, …) are withheld. It is not a security boundary though — the services you inject (e.g. ctx.bash) reach the real runtime.", + "description": "Mount a temporary Cordis Plugin in the current DSH process. This creates an in-memory runtime Plugin, not an installed or configured Plugin. It remains active across later turns until cordis_unmount, toolset unload, or DSH restart. It does not create files, install a package, change cordis.yml or personal/project config, survive restart, or automatically become permanent. To keep it, ask the Agent to implement an SDK Plugin or installable profile bundle through the regular development workflow. It may affect other sessions in the same process; the sandbox is not a security boundary, and injected services reach the real runtime. `code` runs now as the body of an async JavaScript function in an isolated sandbox and MUST `return` a plugin. Two forms: FUNCTION form `return (ctx) => { … }` — declares no inject, so it can register tools, listen to events, and provide services, but reaching ANY service (e.g. ctx.bash) throws; use it only when you need no services. OBJECT form `return { name?, inject: ['bash', 'llm', …], apply(ctx) { … } }` — declares dependencies, and cordis activates the plugin only after the services exist; PREFER this form. You may reach ONLY the services you list in inject: an undeclared service throws even if it exists, because an undeclared dependency would not be cleaned up if its provider is unmounted. BEFORE calling a service from your code, read cordis_inspect what:\"api\" — it lists method signatures AND the type shapes of their arguments/returns (do not guess a field's type; e.g. a bash run's stdout is an object, not a string). Inside `apply`, use the standard cordis API: `ctx.on(event, listener)` to observe events (see cordis_inspect what:\"events\"), or call `harness.registerTool(ctx, harness.defineTool({ name, description, parameters: { text: { type: 'string', required: true } }, output: { schema: { type: 'string' }, render(_args, value) { return [{ type: 'text', text: value }] } }, async execute(args) { return args.text } }))` to give yourself a new tool — it becomes callable on your NEXT step. Tool parameters: each key IS a property — { type: 'string'|'number'|'integer'|'boolean'|'null'|'object'|'array'|'json', required?: true, description?, enum?, const?, items?, properties? }; every direct DSL object declares additionalProperties: true|false, and oneOf: [schema, schema, ...] replaces type for an exact-one union. A raw JSON-Schema { type: 'object', properties, required?: […] } wrapper is also accepted with open-by-default objects. A tool's `execute` MUST return the lossless JSON value declared by `output.schema`; `output.render(args, value)` separately returns Native/model content blocks. Temporary Plugins can COMPOSE: one Plugin may `ctx.provide('name', value)` a service and another may declare `inject: ['name']` to consume it — the consumer stays pending until the provider exists and returns to pending when the provider is unmounted. Everything registered inside `apply` is cleaned up automatically by cordis_unmount. Sandbox globals: `console` (tagged `[cordis:]`, writes through to the harness terminal), `harness.defineTool`, `harness.registerTool`, `btoa`, `atob`, `TextEncoder`, `TextDecoder`. Node APIs are DISABLED — do filesystem/network/timer work through the cordis services, never Node built-ins: `require`, `setTimeout`/`setInterval`, and `fetch` throw redirect errors; `process` and `Buffer` are undefined. Instead use inject: ['fs'] + ctx.fs for files, inject: ['web'] + ctx.web for HTTP, inject: ['bash'] + ctx.bash for processes, and inject: ['timer'] + ctx.setTimeout/ctx.setInterval for timing (fiber effects, auto-cleaned when unmounted) — cordis_inspect what:\"api\" shows what THIS runtime provides. Write PLAIN JavaScript, not TypeScript (no `as`, no type annotations). Cautions: (1) waterfall events (e.g. tools/pre-execute) hand the listener a trailing `next` callback which MUST be called — returning without `next()` SHORT-CIRCUITS the call; prefer plain notification events unless you intend to intercept. (2) Never await something that only resolves after the current turn (your code runs INSIDE a tool call of that turn — it would deadlock). (3) Your `ctx` is a restricted façade: you can register tools, observe events, provide/consume services, and use timers, but framework internals (ctx.root, ctx.fiber, ctx.extend, ctx.plugin, …) are withheld. It is not a security boundary though — the services you inject (e.g. ctx.bash) reach the real runtime.", "parameters": { "type": "object", "properties": { diff --git a/examples/headless-agent/tests/fixtures/cli.cordis.yml b/examples/headless-agent/tests/fixtures/cli.cordis.yml index 21a26bcd73..b9df4d29f7 100644 --- a/examples/headless-agent/tests/fixtures/cli.cordis.yml +++ b/examples/headless-agent/tests/fixtures/cli.cordis.yml @@ -1,9 +1,6 @@ - id: cli-mock-llm name: './cli-mock-llm.ts' -- id: repository-plugin-fixture - name: './repository-plugin/load.mjs' - - id: base name: '@cordisjs/plugin-include' config: diff --git a/examples/headless-agent/tests/fixtures/repository-plugin/dsh-plugin-assets/skills/0/repository-fixture/SKILL.md b/examples/headless-agent/tests/fixtures/repository-plugin/dsh-plugin-assets/skills/0/repository-fixture/SKILL.md deleted file mode 100644 index e24104e79f..0000000000 --- a/examples/headless-agent/tests/fixtures/repository-plugin/dsh-plugin-assets/skills/0/repository-fixture/SKILL.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -name: repository-fixture -description: Repository fixture skill. ---- - -Static instructions from a prepared repository plugin. diff --git a/examples/headless-agent/tests/fixtures/repository-plugin/dsh-plugin.mjs b/examples/headless-agent/tests/fixtures/repository-plugin/dsh-plugin.mjs deleted file mode 100644 index 29aa97c5ec..0000000000 --- a/examples/headless-agent/tests/fixtures/repository-plugin/dsh-plugin.mjs +++ /dev/null @@ -1,19 +0,0 @@ -// Generated by dsh-plugin-prepare. Do not edit. -const manifest = {"name":"headless-repository-fixture","skills":["dsh-plugin-assets/skills/0"]} -// Value mirror: Cordis const enum FiberState.ACTIVE; keep aligned with dsh-repository-plugin source.ts. -const FIBER_ACTIVE = 2 -export const name = "headless-repository-fixture" -export const inject = ["loader","skills"] -async function mount(ctx, plugin, label, config) { - const fiber = ctx.plugin(plugin, config) - await fiber - if (fiber.state !== FIBER_ACTIVE) { - const missing = Object.keys(fiber.inject).filter(service => fiber.ctx.get(service) === undefined) - throw new Error(`${label} did not activate (waiting for services: ${missing.join(', ') || 'unknown'})`) - } -} -export async function apply(ctx) { - const runtime = ctx.loader.builtins["dsh-repository-plugin"] - if (runtime === undefined) throw new Error("missing Cordis builtin dsh-repository-plugin") - await mount(ctx, runtime, 'repository Plugin runtime', { baseUrl: import.meta.url, manifest }) -} diff --git a/examples/headless-agent/tests/fixtures/repository-plugin/load.mjs b/examples/headless-agent/tests/fixtures/repository-plugin/load.mjs deleted file mode 100644 index 90f759876a..0000000000 --- a/examples/headless-agent/tests/fixtures/repository-plugin/load.mjs +++ /dev/null @@ -1,13 +0,0 @@ -/** - * Keyless fixture owner that mounts the runtime before its prepared wrapper. - * Cordis starts sibling Loader entries concurrently, so row order is not a dependency edge. - */ -import * as RepositoryPlugin from '@deepseek-ai/dsh-repository-plugin' -import * as PreparedPlugin from './dsh-plugin.mjs' - -export const name = 'headless-repository-fixture-loader' - -export async function apply(ctx) { - await ctx.plugin(RepositoryPlugin) - await ctx.plugin(PreparedPlugin) -} diff --git a/examples/headless-agent/tests/keyless-smoke.e2e.ts b/examples/headless-agent/tests/keyless-smoke.e2e.ts index f855c958bf..9eee7cd0ab 100644 --- a/examples/headless-agent/tests/keyless-smoke.e2e.ts +++ b/examples/headless-agent/tests/keyless-smoke.e2e.ts @@ -1,17 +1,10 @@ -import { cp, mkdir, mkdtemp, readFile, readdir, rm, writeFile } from 'node:fs/promises' -import { tmpdir } from 'node:os' +import { readFile, readdir } from 'node:fs/promises' import { zstdDecompress } from 'node:zlib' import { promisify } from 'node:util' import { join } from 'node:path' import { fileURLToPath } from 'node:url' import { describe, expect, it } from 'vitest' import { LOADER_SMOKE_TEST_TIMEOUT_MS, runLoaderSmoke } from '@deepseek-ai/dsh-loader-smoke' -import { - PREPARED_ENTRY_FILENAME, - REPOSITORY_PLUGIN_PREPARE_COMMAND, - REPOSITORY_PLUGIN_PACKAGE_NAME, - prepareDshPlugin, -} from '@deepseek-ai/dsh-repository-plugin' import type { SessionEvent } from '@deepseek-ai/dsh-session' const binScript = fileURLToPath(new URL('./fixtures/headless-driver.ts', import.meta.url)) @@ -44,16 +37,6 @@ describe('headless-agent keyless smoke', () => { const result = lines.at(-1) expect(stderr).toBe('') expect(events.some(event => event.type === 'tool/call' && event.data.name === 'bash')).toBe(true) - const catalogMessage = events.find(event => event.type === 'user/message' - && event.data.source.kind === 'skill-catalog') - const catalog = catalogMessage?.type === 'user/message' - ? catalogMessage.data.content.filter(block => block.type === 'text').map(block => block.text).join('\n') - : '' - expect(catalog.split('\n').find(line => line.includes('repository-fixture'))).toMatchInlineSnapshot( - ` - "- \`repository-fixture\`: Repository fixture skill." - `, - ) const toolResult = events.find(event => event.type === 'tool/result') expect(JSON.stringify(toolResult)).toContain('CLI_TOOL_ROUND_TRIP') expect(result).toMatchObject({ @@ -63,30 +46,4 @@ describe('headless-agent keyless smoke', () => { expect(String(result?.['output'])).toContain('CLI_TOOL_ROUND_TRIP') expect(persistedHeader).toMatchObject({ type: 'session' }) }, LOADER_SMOKE_TEST_TIMEOUT_MS) - - it('keeps the checked-in prepared wrapper identical to the generator output for its manifest', async () => { - // The fixture claims "Generated by dsh-plugin-prepare"; this pin makes the - // claim true — a wrapper-template change fails here until the fixture is - // regenerated, so the assembled smoke can never exercise stale generated fields. - const fixture = fileURLToPath(new URL('./fixtures/repository-plugin/', import.meta.url)) - const root = await mkdtemp(join(tmpdir(), 'dsh-fixture-drift-')) - try { - const plugin = join(root, '.dsh-plugin') - await mkdir(plugin, { recursive: true }) - await cp(join(fixture, 'dsh-plugin-assets/skills/0'), join(root, 'skills'), { recursive: true }) - await writeFile(join(plugin, 'package.json'), `${JSON.stringify({ - name: 'headless-repository-fixture', - version: '0.0.0', - scripts: { prepack: REPOSITORY_PLUGIN_PREPARE_COMMAND }, - devDependencies: { [REPOSITORY_PLUGIN_PACKAGE_NAME]: '0.0.1' }, - dsh: { skills: ['../skills'] }, - }, undefined, 2)}\n`) - await prepareDshPlugin(plugin) - const generated = await readFile(join(plugin, PREPARED_ENTRY_FILENAME), 'utf8') - const checkedIn = await readFile(join(fixture, PREPARED_ENTRY_FILENAME), 'utf8') - expect(checkedIn).toBe(generated) - } finally { - await rm(root, { recursive: true, force: true }) - } - }) }) diff --git a/examples/headless-agent/tests/snapshots/advanced-toolchain/session.1.jsonl b/examples/headless-agent/tests/snapshots/advanced-toolchain/session.1.jsonl index 44cbf0e360..9d88e50f42 100644 --- a/examples/headless-agent/tests/snapshots/advanced-toolchain/session.1.jsonl +++ b/examples/headless-agent/tests/snapshots/advanced-toolchain/session.1.jsonl @@ -1,18 +1,18 @@ {"type":"session","version":0,"id":"22222222-2222-4222-8222-222222222222","createdAt":1783950001000,"cwd":"{{cwd}}","parentSession":"11111111-1111-4111-8111-111111111111","origin":"subagent","delegationDepth":1} -{"type":"agent/inbox/spliced","seq":0,"time":1785498583877,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Reply with exactly DIRECT_CHILD_OK and nothing else."}],"source":{"kind":"user"},"role":"user","id":"fc62f9e7-b8f6-441f-9ee8-17f1f9e4feca"}]}} +{"type":"agent/inbox/spliced","seq":0,"time":1785498583877,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Reply with exactly DIRECT_CHILD_OK and nothing else."}],"source":{"kind":"user"},"role":"user","id":"39adeff2-d71e-402c-b2d4-37034ef34266"}]}} {"type":"turn/start","seq":1,"time":1785821454445,"data":{"turn":1}} {"type":"agent/inbox/spliced","seq":2,"time":1785821454445,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} {"type":"subagent/descriptor","seq":3,"time":1785821454466,"data":{"version":2,"mode":"one-shot","provider":"spawn","label":"Check direct child"}} {"type":"step/start","seq":4,"time":1785730501506,"data":{"turn":1,"step":1}} -{"type":"user/message","seq":5,"time":1785730501506,"data":{"content":[{"type":"text","text":"Reply with exactly DIRECT_CHILD_OK and nothing else."}],"source":{"kind":"user"},"role":"user","id":"fc62f9e7-b8f6-441f-9ee8-17f1f9e4feca"},"surfaceOp":"append"} +{"type":"user/message","seq":5,"time":1785730501506,"data":{"content":[{"type":"text","text":"Reply with exactly DIRECT_CHILD_OK and nothing else."}],"source":{"kind":"user"},"role":"user","id":"39adeff2-d71e-402c-b2d4-37034ef34266"},"surfaceOp":"append"} {"type":"session/title","seq":6,"time":1785730501506,"data":{"title":"Reply with exactly DIRECT_CHILD_OK and","messageSeqs":[5],"source":{"kind":"fallback"}}} -{"type":"request/header","seq":7,"time":1785498583897,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"You are an AI agent powered by the DeepSeek Harness SDK.\n\nYou are headless-agent, a coding assistant powered by the deepseek-v4-flash model. Your working directory is {{cwd}}.\n\nVerify your work by running the code or tests. Keep answers brief and factual.\n\n\nUse the read tool — not shell commands like cat — to inspect text files. Results include line numbers. Use offset and limit to continue reading large files.\n\nUse the write tool to create files or completely replace file contents. Existing files are overwritten, so read an existing file first (the default fs-policy requires it) and prefer edit for targeted changes.\n\nUse the edit tool for targeted changes to existing UTF-8 text files. It replaces literal old_string with new_string; by default old_string must appear exactly once. If old_string appears multiple times, provide a more specific old_string or set replace_all to true. Read the file first (the default fs-policy requires it), unless you just created or edited it in this session.\n\nCheck the [exit code: N] marker on every bash result; investigate failures before moving on.\n\nTrack every background task id you start. You are notified in-session when a task finishes — do not busy-poll or sleep on one; keep working on independent steps and do not duplicate a running task's work. Before giving a final answer, collect every still-relevant task with task_output (set wait: true only when you are genuinely blocked on it), and task_kill tasks that stopped mattering.\n\nUse the workflow tool ONLY when the user explicitly asks for a workflow or for large multi-agent orchestration: you write a JavaScript script (the tool description documents the exact format) that fans work out across many subagents with phases and structured results. For one or two delegations, prefer plain subagent calls.\n\nUse the ralph tool ONLY when the direct human explicitly asks for a Ralph loop or fresh-agent iterative execution. Each Ralph round starts a fresh child with no conversation seed and uses the shared workspace as durable memory. Completion and blockers are worker reports, not independent evaluation. Use same-session goal tools for ordinary long-running objectives, and plain subagents or workflows for bounded delegation and fan-out.\n\n## Writing code for run_code\n\nPass `run_code` the body of an async TypeScript function (erasable syntax only — no `enum` or namespaces; type annotations are advisory, the code runs type-stripped). Inside the program:\n\n- Call tools as `await tools.name(args)` — quoted access for exotic names: `tools[\"my-tool\"](args)`. Every call resolves to the tool's typed canonical JSON value. Tool arguments must be lossless JSON.\n- A FAILED tool call rejects with `ToolCallError`, whose `toolName` identifies the failed tool and whose `message` is human-readable — `try/catch` it to handle and continue.\n- Independent read-only calls MAY overlap under `Promise.all` (safe calls run concurrently; mutating calls run alone, in submission order). Sequence dependent work with `await`.\n- Emit results with `return` and/or `console.log(...)`. ONLY what you print or return comes back to you — intermediate tool results never enter the conversation, so extract just what you need.\n\nThe available tools:\n\n```ts\ntype JsonValue = null | boolean | number | string | JsonValue[] | { [key: string]: JsonValue }\n\ninterface ToolArgsMap {\n /** Execute a bash command (`bash -c`) and return its stdout/stderr. Each call runs in a fresh shell: no state (cwd, variables, functions) persists between calls — pass `workdir` instead of using `cd`. Non-zero exits are reported as `[exit code: N]`. Current harness environment facts are exposed through managed `$DSH_*` variables; inspect them when needed. Commands may run under a file sandbox; a blocked file operation is reported as `[sandbox: file access denied under mode]` — a policy denial, not a bug in the command; do not retry another way. Long output is truncated to its tail; the full output is saved to a file whose path is reported when available. Set `run_in_background: true` for long-running commands: the call returns a task id immediately; read its output with `task_output` and stop it with `task_kill`. */\n bash: {\n /** The bash command to execute. */\n command: string;\n /** Clear, concise description of what this command does in active voice, 5-10 words (shown in the UI). Examples: \"ls\" → \"List files in current directory\"; \"git status\" → \"Show working tree status\"; \"npm install\" → \"Install package dependencies\". */\n description: string;\n /** Timeout in milliseconds. The executor applies its configured default and cap, and kills the command on expiry. */\n timeoutMs?: number;\n /** Working directory for this command. Defaults to the session workspace; a relative path is resolved against it. */\n workdir?: string;\n /** Run in the background and return a task id immediately (collect with task_output, stop with task_kill). No timeout applies. */\n run_in_background?: boolean;\n } & Record;\n /** Inspect the live Cordis runtime in the current DSH process. Read-only. Sections: `services` (every provided ctx service and the plugin fiber that owns it), `plugins` (all live plugin fibers with their lifecycle states), `tools` (the model-facing tools currently registered, i.e. what you can call), `temporary` (only temporary Plugins created by cordis_mount: id, name, state, provided services, awaited services, and lifetime), `api` (method signatures AND argument/return type shapes for every LIVE service — read this before writing plugin code that calls a service), `events` (every harness event with its dispatch mode and exact signature — pick listener targets here). Temporary Plugins exist only in memory, remain active across later turns, and disappear after cordis_unmount, toolset unload, or DSH restart; they are not restored automatically. The `temporary` section is a subset of `plugins`. Omit `what` to get all six sections. With `what:\"api\"` or `what:\"events\"`, pass an exact `name` to narrow to one service/event and include its original source JSDoc. */\n cordis_inspect: {\n /** Limit the report to one section. Omit for all sections. */\n what?: \"services\" | \"plugins\" | \"tools\" | \"temporary\" | \"api\" | \"events\";\n /** Exact service key or event name whose original JSDoc to include; valid only with what:\"api\" or what:\"events\". */\n name?: string;\n } & Record;\n /** Mount a temporary Cordis Plugin in the current DSH process. This creates an in-memory runtime Plugin, not an installed or configured Plugin. It remains active across later turns until cordis_unmount, toolset unload, or DSH restart. It does not create files, install a package, change cordis.yml or personal/project config, survive restart, or automatically become permanent. To keep it, ask the Agent to implement a normal local, project, or repository Plugin through the regular development workflow. It may affect other sessions in the same process; the sandbox is not a security boundary, and injected services reach the real runtime. `code` runs now as the body of an async JavaScript function in an isolated sandbox and MUST `return` a plugin. Two forms: FUNCTION form `return (ctx) => { … }` — declares no inject, so it can register tools, listen to events, and provide services, but reaching ANY service (e.g. ctx.bash) throws; use it only when you need no services. OBJECT form `return { name?, inject: ['bash', 'llm', …], apply(ctx) { … } }` — declares dependencies, and cordis activates the plugin only after the services exist; PREFER this form. You may reach ONLY the services you list in inject: an undeclared service throws even if it exists, because an undeclared dependency would not be cleaned up if its provider is unmounted. BEFORE calling a service from your code, read cordis_inspect what:\"api\" — it lists method signatures AND the type shapes of their arguments/returns (do not guess a field's type; e.g. a bash run's stdout is an object, not a string). Inside `apply`, use the standard cordis API: `ctx.on(event, listener)` to observe events (see cordis_inspect what:\"events\"), or call `harness.registerTool(ctx, harness.defineTool({ name, description, parameters: { text: { type: 'string', required: true } }, output: { schema: { type: 'string' }, render(_args, value) { return [{ type: 'text', text: value }] } }, async execute(args) { return args.text } }))` to give yourself a new tool — it becomes callable on your NEXT step. Tool parameters: each key IS a property — { type: 'string'|'number'|'integer'|'boolean'|'null'|'object'|'array'|'json', required?: true, description?, enum?, const?, items?, properties? }; every direct DSL object declares additionalProperties: true|false, and oneOf: [schema, schema, ...] replaces type for an exact-one union. A raw JSON-Schema { type: 'object', properties, required?: […] } wrapper is also accepted with open-by-default objects. A tool's `execute` MUST return the lossless JSON value declared by `output.schema`; `output.render(args, value)` separately returns Native/model content blocks. Temporary Plugins can COMPOSE: one Plugin may `ctx.provide('name', value)` a service and another may declare `inject: ['name']` to consume it — the consumer stays pending until the provider exists and returns to pending when the provider is unmounted. Everything registered inside `apply` is cleaned up automatically by cordis_unmount. Sandbox globals: `console` (tagged `[cordis:]`, writes through to the harness terminal), `harness.defineTool`, `harness.registerTool`, `btoa`, `atob`, `TextEncoder`, `TextDecoder`. Node APIs are DISABLED — do filesystem/network/timer work through the cordis services, never Node built-ins: `require`, `setTimeout`/`setInterval`, and `fetch` throw redirect errors; `process` and `Buffer` are undefined. Instead use inject: ['fs'] + ctx.fs for files, inject: ['web'] + ctx.web for HTTP, inject: ['bash'] + ctx.bash for processes, and inject: ['timer'] + ctx.setTimeout/ctx.setInterval for timing (fiber effects, auto-cleaned when unmounted) — cordis_inspect what:\"api\" shows what THIS runtime provides. Write PLAIN JavaScript, not TypeScript (no `as`, no type annotations). Cautions: (1) waterfall events (e.g. tools/pre-execute) hand the listener a trailing `next` callback which MUST be called — returning without `next()` SHORT-CIRCUITS the call; prefer plain notification events unless you intend to intercept. (2) Never await something that only resolves after the current turn (your code runs INSIDE a tool call of that turn — it would deadlock). (3) Your `ctx` is a restricted façade: you can register tools, observe events, provide/consume services, and use timers, but framework internals (ctx.root, ctx.fiber, ctx.extend, ctx.plugin, …) are withheld. It is not a security boundary though — the services you inject (e.g. ctx.bash) reach the real runtime. */\n cordis_mount: {\n /** JavaScript body returning a temporary Plugin; evaluated now and saved nowhere. */\n code: string;\n } & Record;\n /** Unmount a current-process temporary Plugin created by cordis_mount. Waits for its tools, listeners, services, timers, and other owned effects to clean up completely. Only dyn-N temporary ids are accepted; this cannot remove Loader, configured, or installed Plugins. */\n cordis_unmount: {\n /** The temporary Plugin id returned by cordis_mount (for example \"dyn-1\"); valid only in this process and invalid after unmount or restart. */\n id: string;\n } & Record;\n /** Edit an existing UTF-8 text file by replacing literal text. */\n edit: {\n /** Path to edit, resolved by the filesystem backend. */\n file_path: string;\n /** Literal text to replace. Must match exactly. */\n old_string: string;\n /** Literal replacement text. Use an empty string to delete the match. */\n new_string: string;\n /** Replace all matches. Defaults to false; when false, old_string must appear exactly once. */\n replace_all?: boolean;\n } & Record;\n /** Run a foreground fresh-agent Ralph loop toward one immutable objective. Use only when the direct human explicitly asks for Ralph or fresh-agent iteration. Each round opens a new child with no parent conversation or prior child session; the shared workspace is long-term memory, and only a bounded structured report crosses rounds. The call returns when a worker reports completion or a concrete blocker, or at the round limit. Ordinary long-running same-session work belongs to goal tools. */\n ralph: {\n /** The immutable completion objective for every fresh Ralph round. */\n objective: string;\n /** Optional positive safe-integer round cap, bounded by the deployment ceiling. */\n maxRounds?: number;\n } & Record;\n /** Read a UTF-8 text file and return line-numbered content. */\n read: {\n /** Path to read, resolved by the filesystem backend. */\n file_path: string;\n /** 1-based first line to return. Defaults to 1. */\n offset?: number;\n /** Maximum number of lines to return. Defaults to 2000. */\n limit?: number;\n } & Record;\n /** Send a message to a background subagent by its subagent id, continuing the same conversation. It becomes the subagent's next turn: if it is still working, the message waits until its current turn finishes, so it cannot redirect work already underway. This call returns no answer from the subagent — only confirmation that the message was delivered — so use it to give it more work. A failure means the message was NOT delivered. */\n send_message: {\n /** The subagent id returned when the background subagent was started. */\n subagent_id: string;\n /** The message to deliver to the subagent. */\n message: string;\n } & Record;\n /** Load the full instructions for an available skill. Call this with the exact skill name from the session skill catalog before acting on a task that names or clearly matches that skill. */\n skill: {\n /** The exact skill name from the available skills list. */\n name: string;\n } & Record;\n /** Delegate a self-contained task to a subagent (a separate agent that works in its own context) and return its final result. Use this to offload focused, independent work — research, a scoped implementation, an analysis — so it does not consume this conversation's context. The subagent runs to completion and you receive only its final answer, not its intermediate steps. Give it a complete, standalone prompt: it does not see this conversation. Set `run_in_background: true` to start a background subagent that keeps its conversation: you receive only its subagent id, never its result, and it works on its own. Use this for work whose result you do not need returned by this call; `send_message` sends it more work. */\n subagent: {\n /** A short (3-5 word) description of the delegated task, for display. */\n description: string;\n /** The complete, self-contained task for the subagent. It does not share this conversation's context, so include everything it needs. */\n prompt: string;\n /** Run as a background subagent that keeps its conversation and return only its subagent id. This call never returns its result; send it more work with send_message. */\n run_in_background?: boolean;\n } & Record;\n /** Delegate a task to a subagent that inherits this conversation: a child agent seeded with all completed turns so far (it does not see the current in-flight turn), returning only its final result. Use this when the subtask builds on this conversation's context — a follow-up analysis, a review, a continuation — without consuming this conversation's context for the work itself. You receive only its final answer, not its intermediate steps. Set `run_in_background: true` to start a background subagent that keeps its conversation: you receive only its subagent id, never its result, and it works on its own. Use this for work whose result you do not need returned by this call; `send_message` sends it more work. */\n subagent_fork: {\n /** A short (3-5 word) description of the delegated task, for display. */\n description: string;\n /** The task for the subagent. It already sees this conversation's completed turns, so build on them freely and state only what is new. */\n prompt: string;\n /** Run as a background subagent that keeps its conversation and return only its subagent id. This call never returns its result; send it more work with send_message. */\n run_in_background?: boolean;\n } & Record;\n /** Request cancellation of a running background task by task id. Returns immediately; the task settles as killed once its work actually stops. */\n task_kill: {\n /** Task id returned by the tool that started the background work. */\n task_id: string;\n /** Optional short reason, recorded in the log and forwarded to the task. */\n reason?: string;\n } & Record;\n /** List your background tasks (running and finished) with their ids, kinds, and statuses. */\n task_list: Record;\n /** Read a background task. Stream tasks return only output since the previous read; final-output tasks return their result after settlement. Every response ends with `[status: ...]`. Reads are non-blocking unless `wait: true`, which waits up to the configured cap. */\n task_output: {\n /** Task id returned by the tool that started the background work. */\n task_id: string;\n /** Block until the task reaches a terminal status or the timeout expires. A timed-out wait returns [status: running] and leaves the task alive. */\n wait?: boolean;\n /** Max wait in milliseconds (only meaningful with wait: true). Defaults to the configured wait timeout; capped by the configured maximum. */\n timeout_ms?: number;\n } & Record;\n /** Record and update a structured task list for the current work. Send the ENTIRE list every call — it REPLACES the previous list (there are no partial updates, no per-item edits). Use it to plan multi-step work and show progress: add one todo per concrete step before you start. Mark every todo being actively worked on `in_progress` — several at once when work genuinely runs in parallel (e.g. concurrent subagents or background commands), one for sequential work; while work remains, at least one task should be `in_progress`. Mark a todo `completed` the moment it is done (do not batch completions), and allow no `in_progress` item only once all work is complete. Skip the list for trivial single-step tasks. Statuses: `pending` (not started), `in_progress` (being worked on now), `completed` (finished). */\n todo_write: {\n /** The COMPLETE task list, replacing any previous list. */\n todos: ({\n /** What the task is — a short imperative line. */\n content: string;\n /** pending (not started) | in_progress (now) | completed (done). */\n status: \"pending\" | \"in_progress\" | \"completed\";\n })[];\n } & Record;\n /** Run a JavaScript workflow script that orchestrates subagents at scale. Use this for work that fans out across many independent pieces — an audit over many files, a migration, multi-angle research, adversarial verification of findings — where you write the orchestration as a script instead of delegating turn by turn. The workflow's identity rides the `meta` parameter as JSON: required `name` (short kebab-case) and `description` strings, optional `whenToUse` string and `phases` array (`{title, detail?, provider?, model?}`). The `script` parameter is the plain JavaScript body ONLY (NOT TypeScript, and NO `export const meta` statement — meta is a parameter, not code), running with top-level await; end with `return ` — the value must be JSON-serializable and is this tool's result. Script-body hooks: - `agent(prompt, opts?): Promise` — run one subagent to completion. Without `opts.schema` it resolves to the child's final text; with `opts.schema` (an object-rooted JSON Schema using ONLY type/properties/required/additionalProperties/items/enum/const/oneOf — no pattern/format/numeric bounds) it resolves to the validated object. Resolves `null` when the child fails (filter with `.filter(Boolean)`). Other opts: `label` (display), `phase` (progress group), and independent `provider`/`model` LLM target overrides (either may be provided alone). Anything else (`effort`/`isolation`/`agentType`) is rejected loudly. - `pipeline(items, ...stages): Promise` — run each item through the stages independently with NO barrier between stages (prefer this for multi-stage work). Each stage receives `(prev, item, index)`. An ordinary stage throw drops that ITEM to `null` and skips its remaining stages. - `parallel(thunks): Promise` — run zero-argument functions concurrently and await ALL of them (a barrier; use only when a stage genuinely needs every prior result together). A throwing thunk resolves to `null`. - `phase(title)` — start a progress phase; `log(message)` — narrate progress; `args` — the tool call's `args` input, verbatim. Misused hooks (bad arguments, unknown options, unsupported schemas, tripped caps) throw errors that ALWAYS kill the script — they never dissolve into a per-item `null`. Constraints: concurrency and total-agent caps apply; no filesystem, network, timers, or Node.js APIs are provided — the agents do the work, the script only coordinates them. The run executes in the foreground: this call returns when the whole script finishes. */\n workflow: {\n /** The plain-JS workflow script body (top-level await allowed; NO `export const meta` statement; end with `return `). */\n script: string;\n /** The workflow identity block (plain JSON — never code). */\n meta: {\n /** Short kebab-case workflow name. */\n name: string;\n /** One-line description of what the workflow does. */\n description: string;\n /** Optional guidance on when this workflow applies. */\n whenToUse?: string;\n /** Optional phase declarations matched by phase() calls. */\n phases?: ({\n /** The phase title phase() calls match by exact string. */\n title: string;\n /** Optional one-line description of the phase. */\n detail?: string;\n /** Optional provider override this phase is expected to use. */\n provider?: string;\n /** Optional model override this phase is expected to use. */\n model?: string;\n } & Record)[];\n } & Record;\n /** Optional JSON input exposed to the script as the `args` global (wrap a bare list as a field, e.g. {\"files\": [...]}). */\n args?: Record;\n } & Record;\n /** Create or fully replace a UTF-8 text file. */\n write: {\n /** Path to write, resolved by the filesystem backend. */\n file_path: string;\n /** Full UTF-8 text content to write. */\n content: string;\n } & Record;\n}\n\ninterface ToolOutputMap {\n bash: {\n kind: \"background\";\n taskId: string;\n } | {\n kind: \"foreground\";\n exitCode: number | null;\n signal: string | null;\n timedOut: boolean;\n aborted: boolean;\n timeoutMs: number;\n stdout: {\n text: string;\n truncated: boolean;\n spillPath?: string;\n };\n stderr: {\n text: string;\n truncated: boolean;\n spillPath?: string;\n };\n sandbox?: {\n mode: string;\n denied: boolean;\n enforcement?: string;\n runnerFailed?: boolean;\n };\n };\n cordis_inspect: string;\n cordis_mount: {\n id: string;\n pluginName: string;\n state: \"pending\" | \"loading\" | \"active\" | \"failed\" | \"disposed\" | \"unloading\";\n provides: string[];\n waitingFor: string[];\n };\n cordis_unmount: {\n id: string;\n pluginName: string;\n };\n edit: {\n path: string;\n before: string;\n after: string;\n };\n ralph: {\n runId: string;\n agentsStarted: number;\n result: JsonValue;\n };\n read: {\n path: string;\n offset: number;\n lines: {\n number: number;\n text: string;\n }[];\n totalLines: number;\n };\n send_message: {\n messageId: string;\n };\n skill: {\n name: string;\n provider: string;\n resourceBase?: {\n kind: \"directory\";\n path: string;\n } | {\n kind: \"url\";\n url: string;\n } | {\n kind: \"opaque\";\n description: string;\n };\n content: string;\n };\n subagent: {\n kind: \"background\";\n taskId: string;\n } | {\n kind: \"continuable\";\n subagentId: string;\n } | {\n kind: \"foreground\";\n runId: string;\n output: JsonValue[];\n };\n subagent_fork: {\n kind: \"background\";\n taskId: string;\n } | {\n kind: \"continuable\";\n subagentId: string;\n } | {\n kind: \"foreground\";\n runId: string;\n output: JsonValue[];\n };\n task_kill: {\n outcome: \"cancellation-requested\" | \"already-finished\";\n task: {\n id: string;\n kind: string;\n label: string;\n status: \"running\" | \"stopping\" | \"completed\" | \"killed\" | \"failed\";\n detail?: string;\n startedAt: number;\n finishedAt?: number;\n };\n };\n task_list: ({\n id: string;\n kind: string;\n label: string;\n status: \"running\" | \"stopping\" | \"completed\" | \"killed\" | \"failed\";\n detail?: string;\n startedAt: number;\n finishedAt?: number;\n })[];\n task_output: {\n text: string;\n task: {\n id: string;\n kind: string;\n label: string;\n status: \"running\" | \"stopping\" | \"completed\" | \"killed\" | \"failed\";\n detail?: string;\n startedAt: number;\n finishedAt?: number;\n };\n };\n todo_write: {\n todos: ({\n content: string;\n status: \"pending\" | \"in_progress\" | \"completed\";\n })[];\n counts: {\n pending: number;\n inProgress: number;\n completed: number;\n };\n };\n workflow: {\n runId: string;\n agentsStarted: number;\n result: JsonValue;\n };\n write: {\n path: string;\n operation: \"create\" | \"update\";\n before: string | null;\n after: string;\n };\n}\n\ntype ToolName = keyof ToolOutputMap\n\ndeclare class ToolCallError extends Error {\n readonly name: \"ToolCallError\";\n readonly toolName: ToolName;\n}\n\ndeclare const tools: {\n [K in ToolName]: (args: ToolArgsMap[K]) => Promise;\n}\n```","tools":[{"name":"bash","description":"Execute a bash command (`bash -c`) and return its stdout/stderr. Each call runs in a fresh shell: no state (cwd, variables, functions) persists between calls — pass `workdir` instead of using `cd`. Non-zero exits are reported as `[exit code: N]`. Current harness environment facts are exposed through managed `$DSH_*` variables; inspect them when needed. Commands may run under a file sandbox; a blocked file operation is reported as `[sandbox: file access denied under mode]` — a policy denial, not a bug in the command; do not retry another way. Long output is truncated to its tail; the full output is saved to a file whose path is reported when available. Set `run_in_background: true` for long-running commands: the call returns a task id immediately; read its output with `task_output` and stop it with `task_kill`.","parameters":{"type":"object","properties":{"command":{"type":"string","description":"The bash command to execute."},"description":{"type":"string","description":"Clear, concise description of what this command does in active voice, 5-10 words (shown in the UI). Examples: \"ls\" → \"List files in current directory\"; \"git status\" → \"Show working tree status\"; \"npm install\" → \"Install package dependencies\"."},"timeoutMs":{"type":"number","description":"Timeout in milliseconds. The executor applies its configured default and cap, and kills the command on expiry."},"workdir":{"type":"string","description":"Working directory for this command. Defaults to the session workspace; a relative path is resolved against it."},"run_in_background":{"type":"boolean","description":"Run in the background and return a task id immediately (collect with task_output, stop with task_kill). No timeout applies."}},"required":["command","description"]}},{"name":"cordis_inspect","description":"Inspect the live Cordis runtime in the current DSH process. Read-only. Sections: `services` (every provided ctx service and the plugin fiber that owns it), `plugins` (all live plugin fibers with their lifecycle states), `tools` (the model-facing tools currently registered, i.e. what you can call), `temporary` (only temporary Plugins created by cordis_mount: id, name, state, provided services, awaited services, and lifetime), `api` (method signatures AND argument/return type shapes for every LIVE service — read this before writing plugin code that calls a service), `events` (every harness event with its dispatch mode and exact signature — pick listener targets here). Temporary Plugins exist only in memory, remain active across later turns, and disappear after cordis_unmount, toolset unload, or DSH restart; they are not restored automatically. The `temporary` section is a subset of `plugins`. Omit `what` to get all six sections. With `what:\"api\"` or `what:\"events\"`, pass an exact `name` to narrow to one service/event and include its original source JSDoc.","parameters":{"type":"object","properties":{"what":{"type":"string","description":"Limit the report to one section. Omit for all sections.","enum":["services","plugins","tools","temporary","api","events"]},"name":{"type":"string","description":"Exact service key or event name whose original JSDoc to include; valid only with what:\"api\" or what:\"events\"."}}}},{"name":"cordis_mount","description":"Mount a temporary Cordis Plugin in the current DSH process. This creates an in-memory runtime Plugin, not an installed or configured Plugin. It remains active across later turns until cordis_unmount, toolset unload, or DSH restart. It does not create files, install a package, change cordis.yml or personal/project config, survive restart, or automatically become permanent. To keep it, ask the Agent to implement a normal local, project, or repository Plugin through the regular development workflow. It may affect other sessions in the same process; the sandbox is not a security boundary, and injected services reach the real runtime. `code` runs now as the body of an async JavaScript function in an isolated sandbox and MUST `return` a plugin. Two forms: FUNCTION form `return (ctx) => { … }` — declares no inject, so it can register tools, listen to events, and provide services, but reaching ANY service (e.g. ctx.bash) throws; use it only when you need no services. OBJECT form `return { name?, inject: ['bash', 'llm', …], apply(ctx) { … } }` — declares dependencies, and cordis activates the plugin only after the services exist; PREFER this form. You may reach ONLY the services you list in inject: an undeclared service throws even if it exists, because an undeclared dependency would not be cleaned up if its provider is unmounted. BEFORE calling a service from your code, read cordis_inspect what:\"api\" — it lists method signatures AND the type shapes of their arguments/returns (do not guess a field's type; e.g. a bash run's stdout is an object, not a string). Inside `apply`, use the standard cordis API: `ctx.on(event, listener)` to observe events (see cordis_inspect what:\"events\"), or call `harness.registerTool(ctx, harness.defineTool({ name, description, parameters: { text: { type: 'string', required: true } }, output: { schema: { type: 'string' }, render(_args, value) { return [{ type: 'text', text: value }] } }, async execute(args) { return args.text } }))` to give yourself a new tool — it becomes callable on your NEXT step. Tool parameters: each key IS a property — { type: 'string'|'number'|'integer'|'boolean'|'null'|'object'|'array'|'json', required?: true, description?, enum?, const?, items?, properties? }; every direct DSL object declares additionalProperties: true|false, and oneOf: [schema, schema, ...] replaces type for an exact-one union. A raw JSON-Schema { type: 'object', properties, required?: […] } wrapper is also accepted with open-by-default objects. A tool's `execute` MUST return the lossless JSON value declared by `output.schema`; `output.render(args, value)` separately returns Native/model content blocks. Temporary Plugins can COMPOSE: one Plugin may `ctx.provide('name', value)` a service and another may declare `inject: ['name']` to consume it — the consumer stays pending until the provider exists and returns to pending when the provider is unmounted. Everything registered inside `apply` is cleaned up automatically by cordis_unmount. Sandbox globals: `console` (tagged `[cordis:]`, writes through to the harness terminal), `harness.defineTool`, `harness.registerTool`, `btoa`, `atob`, `TextEncoder`, `TextDecoder`. Node APIs are DISABLED — do filesystem/network/timer work through the cordis services, never Node built-ins: `require`, `setTimeout`/`setInterval`, and `fetch` throw redirect errors; `process` and `Buffer` are undefined. Instead use inject: ['fs'] + ctx.fs for files, inject: ['web'] + ctx.web for HTTP, inject: ['bash'] + ctx.bash for processes, and inject: ['timer'] + ctx.setTimeout/ctx.setInterval for timing (fiber effects, auto-cleaned when unmounted) — cordis_inspect what:\"api\" shows what THIS runtime provides. Write PLAIN JavaScript, not TypeScript (no `as`, no type annotations). Cautions: (1) waterfall events (e.g. tools/pre-execute) hand the listener a trailing `next` callback which MUST be called — returning without `next()` SHORT-CIRCUITS the call; prefer plain notification events unless you intend to intercept. (2) Never await something that only resolves after the current turn (your code runs INSIDE a tool call of that turn — it would deadlock). (3) Your `ctx` is a restricted façade: you can register tools, observe events, provide/consume services, and use timers, but framework internals (ctx.root, ctx.fiber, ctx.extend, ctx.plugin, …) are withheld. It is not a security boundary though — the services you inject (e.g. ctx.bash) reach the real runtime.","parameters":{"type":"object","properties":{"code":{"type":"string","description":"JavaScript body returning a temporary Plugin; evaluated now and saved nowhere."}},"required":["code"]}},{"name":"cordis_unmount","description":"Unmount a current-process temporary Plugin created by cordis_mount. Waits for its tools, listeners, services, timers, and other owned effects to clean up completely. Only dyn-N temporary ids are accepted; this cannot remove Loader, configured, or installed Plugins.","parameters":{"type":"object","properties":{"id":{"type":"string","description":"The temporary Plugin id returned by cordis_mount (for example \"dyn-1\"); valid only in this process and invalid after unmount or restart."}},"required":["id"]}},{"name":"edit","description":"Edit an existing UTF-8 text file by replacing literal text.","parameters":{"type":"object","properties":{"file_path":{"type":"string","description":"Path to edit, resolved by the filesystem backend."},"old_string":{"type":"string","description":"Literal text to replace. Must match exactly."},"new_string":{"type":"string","description":"Literal replacement text. Use an empty string to delete the match."},"replace_all":{"type":"boolean","description":"Replace all matches. Defaults to false; when false, old_string must appear exactly once."}},"required":["file_path","old_string","new_string"]}},{"name":"ralph","description":"Run a foreground fresh-agent Ralph loop toward one immutable objective. Use only when the direct human explicitly asks for Ralph or fresh-agent iteration. Each round opens a new child with no parent conversation or prior child session; the shared workspace is long-term memory, and only a bounded structured report crosses rounds. The call returns when a worker reports completion or a concrete blocker, or at the round limit. Ordinary long-running same-session work belongs to goal tools.","parameters":{"type":"object","properties":{"objective":{"type":"string","description":"The immutable completion objective for every fresh Ralph round."},"maxRounds":{"type":"number","description":"Optional positive safe-integer round cap, bounded by the deployment ceiling."}},"required":["objective"]}},{"name":"read","description":"Read a UTF-8 text file and return line-numbered content.","parameters":{"type":"object","properties":{"file_path":{"type":"string","description":"Path to read, resolved by the filesystem backend."},"offset":{"type":"number","description":"1-based first line to return. Defaults to 1."},"limit":{"type":"number","description":"Maximum number of lines to return. Defaults to 2000."}},"required":["file_path"]}},{"name":"run_code","description":"Execute a TypeScript program against the available tools. Write the BODY of an async function (erasable syntax only; top-level `await` and `return` work) and call tools as `await tools.name(args)` per the declarations in the system prompt. Only what you print or return comes back — curate it.","parameters":{"type":"object","properties":{"code":{"type":"string","description":"The program: the body of an async TypeScript function."},"description":{"type":"string","description":"Clear, concise description of what this program does in active voice, 5-10 words (shown in the UI). Examples: \"Count TODO markers across packages\"; \"Read failing test and its fixture\"; \"Rename config key in every cordis.yml\"."}},"required":["code","description"]}},{"name":"send_message","description":"Send a message to a background subagent by its subagent id, continuing the same conversation. It becomes the subagent's next turn: if it is still working, the message waits until its current turn finishes, so it cannot redirect work already underway. This call returns no answer from the subagent — only confirmation that the message was delivered — so use it to give it more work. A failure means the message was NOT delivered.","parameters":{"type":"object","properties":{"subagent_id":{"type":"string","description":"The subagent id returned when the background subagent was started."},"message":{"type":"string","description":"The message to deliver to the subagent."}},"required":["subagent_id","message"]}},{"name":"skill","description":"Load the full instructions for an available skill. Call this with the exact skill name from the session skill catalog before acting on a task that names or clearly matches that skill.","parameters":{"type":"object","properties":{"name":{"type":"string","description":"The exact skill name from the available skills list."}},"required":["name"]}},{"name":"subagent","description":"Delegate a self-contained task to a subagent (a separate agent that works in its own context) and return its final result. Use this to offload focused, independent work — research, a scoped implementation, an analysis — so it does not consume this conversation's context. The subagent runs to completion and you receive only its final answer, not its intermediate steps. Give it a complete, standalone prompt: it does not see this conversation. Set `run_in_background: true` to start a background subagent that keeps its conversation: you receive only its subagent id, never its result, and it works on its own. Use this for work whose result you do not need returned by this call; `send_message` sends it more work.","parameters":{"type":"object","properties":{"description":{"type":"string","description":"A short (3-5 word) description of the delegated task, for display."},"prompt":{"type":"string","description":"The complete, self-contained task for the subagent. It does not share this conversation's context, so include everything it needs."},"run_in_background":{"type":"boolean","description":"Run as a background subagent that keeps its conversation and return only its subagent id. This call never returns its result; send it more work with send_message."}},"required":["description","prompt"]}},{"name":"subagent_fork","description":"Delegate a task to a subagent that inherits this conversation: a child agent seeded with all completed turns so far (it does not see the current in-flight turn), returning only its final result. Use this when the subtask builds on this conversation's context — a follow-up analysis, a review, a continuation — without consuming this conversation's context for the work itself. You receive only its final answer, not its intermediate steps. Set `run_in_background: true` to start a background subagent that keeps its conversation: you receive only its subagent id, never its result, and it works on its own. Use this for work whose result you do not need returned by this call; `send_message` sends it more work.","parameters":{"type":"object","properties":{"description":{"type":"string","description":"A short (3-5 word) description of the delegated task, for display."},"prompt":{"type":"string","description":"The task for the subagent. It already sees this conversation's completed turns, so build on them freely and state only what is new."},"run_in_background":{"type":"boolean","description":"Run as a background subagent that keeps its conversation and return only its subagent id. This call never returns its result; send it more work with send_message."}},"required":["description","prompt"]}},{"name":"task_kill","description":"Request cancellation of a running background task by task id. Returns immediately; the task settles as killed once its work actually stops.","parameters":{"type":"object","properties":{"task_id":{"type":"string","description":"Task id returned by the tool that started the background work."},"reason":{"type":"string","description":"Optional short reason, recorded in the log and forwarded to the task."}},"required":["task_id"]}},{"name":"task_list","description":"List your background tasks (running and finished) with their ids, kinds, and statuses.","parameters":{"type":"object","properties":{}}},{"name":"task_output","description":"Read a background task. Stream tasks return only output since the previous read; final-output tasks return their result after settlement. Every response ends with `[status: ...]`. Reads are non-blocking unless `wait: true`, which waits up to the configured cap.","parameters":{"type":"object","properties":{"task_id":{"type":"string","description":"Task id returned by the tool that started the background work."},"wait":{"type":"boolean","description":"Block until the task reaches a terminal status or the timeout expires. A timed-out wait returns [status: running] and leaves the task alive."},"timeout_ms":{"type":"number","description":"Max wait in milliseconds (only meaningful with wait: true). Defaults to the configured wait timeout; capped by the configured maximum."}},"required":["task_id"]}},{"name":"todo_write","description":"Record and update a structured task list for the current work. Send the ENTIRE list every call — it REPLACES the previous list (there are no partial updates, no per-item edits). Use it to plan multi-step work and show progress: add one todo per concrete step before you start. Mark every todo being actively worked on `in_progress` — several at once when work genuinely runs in parallel (e.g. concurrent subagents or background commands), one for sequential work; while work remains, at least one task should be `in_progress`. Mark a todo `completed` the moment it is done (do not batch completions), and allow no `in_progress` item only once all work is complete. Skip the list for trivial single-step tasks. Statuses: `pending` (not started), `in_progress` (being worked on now), `completed` (finished).","parameters":{"type":"object","properties":{"todos":{"type":"array","description":"The COMPLETE task list, replacing any previous list.","items":{"type":"object","additionalProperties":false,"properties":{"content":{"type":"string","description":"What the task is — a short imperative line."},"status":{"type":"string","description":"pending (not started) | in_progress (now) | completed (done).","enum":["pending","in_progress","completed"]}},"required":["content","status"]}}},"required":["todos"]}},{"name":"workflow","description":"Run a JavaScript workflow script that orchestrates subagents at scale. Use this for work that fans out across many independent pieces — an audit over many files, a migration, multi-angle research, adversarial verification of findings — where you write the orchestration as a script instead of delegating turn by turn.\n\nThe workflow's identity rides the `meta` parameter as JSON: required `name` (short kebab-case) and `description` strings, optional `whenToUse` string and `phases` array (`{title, detail?, provider?, model?}`). The `script` parameter is the plain JavaScript body ONLY (NOT TypeScript, and NO `export const meta` statement — meta is a parameter, not code), running with top-level await; end with `return ` — the value must be JSON-serializable and is this tool's result.\n\nScript-body hooks:\n- `agent(prompt, opts?): Promise` — run one subagent to completion. Without `opts.schema` it resolves to the child's final text; with `opts.schema` (an object-rooted JSON Schema using ONLY type/properties/required/additionalProperties/items/enum/const/oneOf — no pattern/format/numeric bounds) it resolves to the validated object. Resolves `null` when the child fails (filter with `.filter(Boolean)`). Other opts: `label` (display), `phase` (progress group), and independent `provider`/`model` LLM target overrides (either may be provided alone). Anything else (`effort`/`isolation`/`agentType`) is rejected loudly.\n- `pipeline(items, ...stages): Promise` — run each item through the stages independently with NO barrier between stages (prefer this for multi-stage work). Each stage receives `(prev, item, index)`. An ordinary stage throw drops that ITEM to `null` and skips its remaining stages.\n- `parallel(thunks): Promise` — run zero-argument functions concurrently and await ALL of them (a barrier; use only when a stage genuinely needs every prior result together). A throwing thunk resolves to `null`.\n- `phase(title)` — start a progress phase; `log(message)` — narrate progress; `args` — the tool call's `args` input, verbatim.\n\nMisused hooks (bad arguments, unknown options, unsupported schemas, tripped caps) throw errors that ALWAYS kill the script — they never dissolve into a per-item `null`.\n\nConstraints: concurrency and total-agent caps apply; no filesystem, network, timers, or Node.js APIs are provided — the agents do the work, the script only coordinates them. The run executes in the foreground: this call returns when the whole script finishes.","parameters":{"type":"object","properties":{"script":{"type":"string","description":"The plain-JS workflow script body (top-level await allowed; NO `export const meta` statement; end with `return `)."},"meta":{"type":"object","description":"The workflow identity block (plain JSON — never code).","additionalProperties":true,"properties":{"name":{"type":"string","description":"Short kebab-case workflow name."},"description":{"type":"string","description":"One-line description of what the workflow does."},"whenToUse":{"type":"string","description":"Optional guidance on when this workflow applies."},"phases":{"type":"array","description":"Optional phase declarations matched by phase() calls.","items":{"type":"object","additionalProperties":true,"properties":{"title":{"type":"string","description":"The phase title phase() calls match by exact string."},"detail":{"type":"string","description":"Optional one-line description of the phase."},"provider":{"type":"string","description":"Optional provider override this phase is expected to use."},"model":{"type":"string","description":"Optional model override this phase is expected to use."}},"required":["title"]}}},"required":["name","description"]},"args":{"type":"object","description":"Optional JSON input exposed to the script as the `args` global (wrap a bare list as a field, e.g. {\"files\": [...]}).","additionalProperties":true}},"required":["script","meta"]}},{"name":"write","description":"Create or fully replace a UTF-8 text file.","parameters":{"type":"object","properties":{"file_path":{"type":"string","description":"Path to write, resolved by the filesystem backend."},"content":{"type":"string","description":"Full UTF-8 text content to write."}},"required":["file_path","content"]}}]},"reason":"initial"}} +{"type":"request/header","seq":7,"time":1785498583897,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"You are an AI agent powered by the DeepSeek Harness SDK.\n\nYou are headless-agent, a coding assistant powered by the deepseek-v4-flash model. Your working directory is {{cwd}}.\n\nVerify your work by running the code or tests. Keep answers brief and factual.\n\n\nUse the read tool — not shell commands like cat — to inspect text files. Results include line numbers. Use offset and limit to continue reading large files.\n\nUse the write tool to create files or completely replace file contents. Existing files are overwritten, so read an existing file first (the default fs-policy requires it) and prefer edit for targeted changes.\n\nUse the edit tool for targeted changes to existing UTF-8 text files. It replaces literal old_string with new_string; by default old_string must appear exactly once. If old_string appears multiple times, provide a more specific old_string or set replace_all to true. Read the file first (the default fs-policy requires it), unless you just created or edited it in this session.\n\nCheck the [exit code: N] marker on every bash result; investigate failures before moving on.\n\nTrack every background task id you start. You are notified in-session when a task finishes — do not busy-poll or sleep on one; keep working on independent steps and do not duplicate a running task's work. Before giving a final answer, collect every still-relevant task with task_output (set wait: true only when you are genuinely blocked on it), and task_kill tasks that stopped mattering.\n\nUse the workflow tool ONLY when the user explicitly asks for a workflow or for large multi-agent orchestration: you write a JavaScript script (the tool description documents the exact format) that fans work out across many subagents with phases and structured results. For one or two delegations, prefer plain subagent calls.\n\nUse the ralph tool ONLY when the direct human explicitly asks for a Ralph loop or fresh-agent iterative execution. Each Ralph round starts a fresh child with no conversation seed and uses the shared workspace as durable memory. Completion and blockers are worker reports, not independent evaluation. Use same-session goal tools for ordinary long-running objectives, and plain subagents or workflows for bounded delegation and fan-out.\n\n## Writing code for run_code\n\nPass `run_code` the body of an async TypeScript function (erasable syntax only — no `enum` or namespaces; type annotations are advisory, the code runs type-stripped). Inside the program:\n\n- Call tools as `await tools.name(args)` — quoted access for exotic names: `tools[\"my-tool\"](args)`. Every call resolves to the tool's typed canonical JSON value. Tool arguments must be lossless JSON.\n- A FAILED tool call rejects with `ToolCallError`, whose `toolName` identifies the failed tool and whose `message` is human-readable — `try/catch` it to handle and continue.\n- Independent read-only calls MAY overlap under `Promise.all` (safe calls run concurrently; mutating calls run alone, in submission order). Sequence dependent work with `await`.\n- Emit results with `return` and/or `console.log(...)`. ONLY what you print or return comes back to you — intermediate tool results never enter the conversation, so extract just what you need.\n\nThe available tools:\n\n```ts\ntype JsonValue = null | boolean | number | string | JsonValue[] | { [key: string]: JsonValue }\n\ninterface ToolArgsMap {\n /** Execute a bash command (`bash -c`) and return its stdout/stderr. Each call runs in a fresh shell: no state (cwd, variables, functions) persists between calls — pass `workdir` instead of using `cd`. Non-zero exits are reported as `[exit code: N]`. Current harness environment facts are exposed through managed `$DSH_*` variables; inspect them when needed. Commands may run under a file sandbox; a blocked file operation is reported as `[sandbox: file access denied under mode]` — a policy denial, not a bug in the command; do not retry another way. Long output is truncated to its tail; the full output is saved to a file whose path is reported when available. Set `run_in_background: true` for long-running commands: the call returns a task id immediately; read its output with `task_output` and stop it with `task_kill`. */\n bash: {\n /** The bash command to execute. */\n command: string;\n /** Clear, concise description of what this command does in active voice, 5-10 words (shown in the UI). Examples: \"ls\" → \"List files in current directory\"; \"git status\" → \"Show working tree status\"; \"npm install\" → \"Install package dependencies\". */\n description: string;\n /** Timeout in milliseconds. The executor applies its configured default and cap, and kills the command on expiry. */\n timeoutMs?: number;\n /** Working directory for this command. Defaults to the session workspace; a relative path is resolved against it. */\n workdir?: string;\n /** Run in the background and return a task id immediately (collect with task_output, stop with task_kill). No timeout applies. */\n run_in_background?: boolean;\n } & Record;\n /** Inspect the live Cordis runtime in the current DSH process. Read-only. Sections: `services` (every provided ctx service and the plugin fiber that owns it), `plugins` (all live plugin fibers with their lifecycle states), `tools` (the model-facing tools currently registered, i.e. what you can call), `temporary` (only temporary Plugins created by cordis_mount: id, name, state, provided services, awaited services, and lifetime), `api` (method signatures AND argument/return type shapes for every LIVE service — read this before writing plugin code that calls a service), `events` (every harness event with its dispatch mode and exact signature — pick listener targets here). Temporary Plugins exist only in memory, remain active across later turns, and disappear after cordis_unmount, toolset unload, or DSH restart; they are not restored automatically. The `temporary` section is a subset of `plugins`. Omit `what` to get all six sections. With `what:\"api\"` or `what:\"events\"`, pass an exact `name` to narrow to one service/event and include its original source JSDoc. */\n cordis_inspect: {\n /** Limit the report to one section. Omit for all sections. */\n what?: \"services\" | \"plugins\" | \"tools\" | \"temporary\" | \"api\" | \"events\";\n /** Exact service key or event name whose original JSDoc to include; valid only with what:\"api\" or what:\"events\". */\n name?: string;\n } & Record;\n /** Mount a temporary Cordis Plugin in the current DSH process. This creates an in-memory runtime Plugin, not an installed or configured Plugin. It remains active across later turns until cordis_unmount, toolset unload, or DSH restart. It does not create files, install a package, change cordis.yml or personal/project config, survive restart, or automatically become permanent. To keep it, ask the Agent to implement an SDK Plugin or installable profile bundle through the regular development workflow. It may affect other sessions in the same process; the sandbox is not a security boundary, and injected services reach the real runtime. `code` runs now as the body of an async JavaScript function in an isolated sandbox and MUST `return` a plugin. Two forms: FUNCTION form `return (ctx) => { … }` — declares no inject, so it can register tools, listen to events, and provide services, but reaching ANY service (e.g. ctx.bash) throws; use it only when you need no services. OBJECT form `return { name?, inject: ['bash', 'llm', …], apply(ctx) { … } }` — declares dependencies, and cordis activates the plugin only after the services exist; PREFER this form. You may reach ONLY the services you list in inject: an undeclared service throws even if it exists, because an undeclared dependency would not be cleaned up if its provider is unmounted. BEFORE calling a service from your code, read cordis_inspect what:\"api\" — it lists method signatures AND the type shapes of their arguments/returns (do not guess a field's type; e.g. a bash run's stdout is an object, not a string). Inside `apply`, use the standard cordis API: `ctx.on(event, listener)` to observe events (see cordis_inspect what:\"events\"), or call `harness.registerTool(ctx, harness.defineTool({ name, description, parameters: { text: { type: 'string', required: true } }, output: { schema: { type: 'string' }, render(_args, value) { return [{ type: 'text', text: value }] } }, async execute(args) { return args.text } }))` to give yourself a new tool — it becomes callable on your NEXT step. Tool parameters: each key IS a property — { type: 'string'|'number'|'integer'|'boolean'|'null'|'object'|'array'|'json', required?: true, description?, enum?, const?, items?, properties? }; every direct DSL object declares additionalProperties: true|false, and oneOf: [schema, schema, ...] replaces type for an exact-one union. A raw JSON-Schema { type: 'object', properties, required?: […] } wrapper is also accepted with open-by-default objects. A tool's `execute` MUST return the lossless JSON value declared by `output.schema`; `output.render(args, value)` separately returns Native/model content blocks. Temporary Plugins can COMPOSE: one Plugin may `ctx.provide('name', value)` a service and another may declare `inject: ['name']` to consume it — the consumer stays pending until the provider exists and returns to pending when the provider is unmounted. Everything registered inside `apply` is cleaned up automatically by cordis_unmount. Sandbox globals: `console` (tagged `[cordis:]`, writes through to the harness terminal), `harness.defineTool`, `harness.registerTool`, `btoa`, `atob`, `TextEncoder`, `TextDecoder`. Node APIs are DISABLED — do filesystem/network/timer work through the cordis services, never Node built-ins: `require`, `setTimeout`/`setInterval`, and `fetch` throw redirect errors; `process` and `Buffer` are undefined. Instead use inject: ['fs'] + ctx.fs for files, inject: ['web'] + ctx.web for HTTP, inject: ['bash'] + ctx.bash for processes, and inject: ['timer'] + ctx.setTimeout/ctx.setInterval for timing (fiber effects, auto-cleaned when unmounted) — cordis_inspect what:\"api\" shows what THIS runtime provides. Write PLAIN JavaScript, not TypeScript (no `as`, no type annotations). Cautions: (1) waterfall events (e.g. tools/pre-execute) hand the listener a trailing `next` callback which MUST be called — returning without `next()` SHORT-CIRCUITS the call; prefer plain notification events unless you intend to intercept. (2) Never await something that only resolves after the current turn (your code runs INSIDE a tool call of that turn — it would deadlock). (3) Your `ctx` is a restricted façade: you can register tools, observe events, provide/consume services, and use timers, but framework internals (ctx.root, ctx.fiber, ctx.extend, ctx.plugin, …) are withheld. It is not a security boundary though — the services you inject (e.g. ctx.bash) reach the real runtime. */\n cordis_mount: {\n /** JavaScript body returning a temporary Plugin; evaluated now and saved nowhere. */\n code: string;\n } & Record;\n /** Unmount a current-process temporary Plugin created by cordis_mount. Waits for its tools, listeners, services, timers, and other owned effects to clean up completely. Only dyn-N temporary ids are accepted; this cannot remove Loader, configured, or installed Plugins. */\n cordis_unmount: {\n /** The temporary Plugin id returned by cordis_mount (for example \"dyn-1\"); valid only in this process and invalid after unmount or restart. */\n id: string;\n } & Record;\n /** Edit an existing UTF-8 text file by replacing literal text. */\n edit: {\n /** Path to edit, resolved by the filesystem backend. */\n file_path: string;\n /** Literal text to replace. Must match exactly. */\n old_string: string;\n /** Literal replacement text. Use an empty string to delete the match. */\n new_string: string;\n /** Replace all matches. Defaults to false; when false, old_string must appear exactly once. */\n replace_all?: boolean;\n } & Record;\n /** Request cancellation of a background agent's current turn by its agent id. The target may be your direct child or a deeper agent created under you. Only the current turn stops: messages already queued for the agent stay parked until a later send_message, agents it started keep running, and the agent itself stays available for follow-ups. This call returns as soon as the stop request is accepted, so the target may keep running briefly; interrupting an agent that already finished is an accepted no-op. */\n interrupt_agent: {\n /** The agent id of the running agent to interrupt. */\n agent_id: string;\n } & Record;\n /** Run a foreground fresh-agent Ralph loop toward one immutable objective. Use only when the direct human explicitly asks for Ralph or fresh-agent iteration. Each round opens a new child with no parent conversation or prior child session; the shared workspace is long-term memory, and only a bounded structured report crosses rounds. The call returns when a worker reports completion or a concrete blocker, or at the round limit. Ordinary long-running same-session work belongs to goal tools. */\n ralph: {\n /** The immutable completion objective for every fresh Ralph round. */\n objective: string;\n /** Optional positive safe-integer round cap, bounded by the deployment ceiling. */\n maxRounds?: number;\n } & Record;\n /** Read a UTF-8 text file and return line-numbered content. */\n read: {\n /** Path to read, resolved by the filesystem backend. */\n file_path: string;\n /** 1-based first line to return. Defaults to 1. */\n offset?: number;\n /** Maximum number of lines to return. Defaults to 2000. */\n limit?: number;\n } & Record;\n /** Send a message to a background subagent by its subagent id, continuing the same conversation. It becomes the subagent's next turn: if it is still working, the message waits until its current turn finishes, so it cannot redirect work already underway. This call returns no answer from the subagent — only confirmation that the message was delivered — so use it to give it more work. A failure means the message was NOT delivered. */\n send_message: {\n /** The subagent id returned when the background subagent was started. */\n subagent_id: string;\n /** The message to deliver to the subagent. */\n message: string;\n } & Record;\n /** Load the full instructions for an available skill. Call this with the exact skill name from the session skill catalog before acting on a task that names or clearly matches that skill. */\n skill: {\n /** The exact skill name from the available skills list. */\n name: string;\n } & Record;\n /** Delegate a self-contained task to a subagent (a separate agent that works in its own context) and return its final result. Use this to offload focused, independent work — research, a scoped implementation, an analysis — so it does not consume this conversation's context. The subagent runs to completion and you receive only its final answer, not its intermediate steps. Give it a complete, standalone prompt: it does not see this conversation. Set `run_in_background: true` to start a background subagent that keeps its conversation: you receive only its subagent id, never its result, and it works on its own. Use this for work whose result you do not need returned by this call; `send_message` sends it more work. */\n subagent: {\n /** A short (3-5 word) description of the delegated task, for display. */\n description: string;\n /** The complete, self-contained task for the subagent. It does not share this conversation's context, so include everything it needs. */\n prompt: string;\n /** Run as a background subagent that keeps its conversation and return only its subagent id. This call never returns its result; send it more work with send_message. */\n run_in_background?: boolean;\n } & Record;\n /** Delegate a task to a subagent that inherits this conversation: a child agent seeded with all completed turns so far (it does not see the current in-flight turn), returning only its final result. Use this when the subtask builds on this conversation's context — a follow-up analysis, a review, a continuation — without consuming this conversation's context for the work itself. You receive only its final answer, not its intermediate steps. Set `run_in_background: true` to start a background subagent that keeps its conversation: you receive only its subagent id, never its result, and it works on its own. Use this for work whose result you do not need returned by this call; `send_message` sends it more work. */\n subagent_fork: {\n /** A short (3-5 word) description of the delegated task, for display. */\n description: string;\n /** The task for the subagent. It already sees this conversation's completed turns, so build on them freely and state only what is new. */\n prompt: string;\n /** Run as a background subagent that keeps its conversation and return only its subagent id. This call never returns its result; send it more work with send_message. */\n run_in_background?: boolean;\n } & Record;\n /** Request cancellation of a running background task by task id. Returns immediately; the task settles as killed once its work actually stops. */\n task_kill: {\n /** Task id returned by the tool that started the background work. */\n task_id: string;\n /** Optional short reason, recorded in the log and forwarded to the task. */\n reason?: string;\n } & Record;\n /** List your background tasks (running and finished) with their ids, kinds, and statuses. */\n task_list: Record;\n /** Read a background task. Stream tasks return only output since the previous read; final-output tasks return their result after settlement. Every response ends with `[status: ...]`. Reads are non-blocking unless `wait: true`, which waits up to the configured cap. */\n task_output: {\n /** Task id returned by the tool that started the background work. */\n task_id: string;\n /** Block until the task reaches a terminal status or the timeout expires. A timed-out wait returns [status: running] and leaves the task alive. */\n wait?: boolean;\n /** Max wait in milliseconds (only meaningful with wait: true). Defaults to the configured wait timeout; capped by the configured maximum. */\n timeout_ms?: number;\n } & Record;\n /** Record and update a structured task list for the current work. Send the ENTIRE list every call — it REPLACES the previous list (there are no partial updates, no per-item edits). Use it to plan multi-step work and show progress: add one todo per concrete step before you start. Mark every todo being actively worked on `in_progress` — several at once when work genuinely runs in parallel (e.g. concurrent subagents or background commands), one for sequential work; while work remains, at least one task should be `in_progress`. Mark a todo `completed` the moment it is done (do not batch completions), and allow no `in_progress` item only once all work is complete. Skip the list for trivial single-step tasks. Statuses: `pending` (not started), `in_progress` (being worked on now), `completed` (finished). */\n todo_write: {\n /** The COMPLETE task list, replacing any previous list. */\n todos: ({\n /** What the task is — a short imperative line. */\n content: string;\n /** pending (not started) | in_progress (now) | completed (done). */\n status: \"pending\" | \"in_progress\" | \"completed\";\n })[];\n } & Record;\n /** Run a JavaScript workflow script that orchestrates subagents at scale. Use this for work that fans out across many independent pieces — an audit over many files, a migration, multi-angle research, adversarial verification of findings — where you write the orchestration as a script instead of delegating turn by turn. The workflow's identity rides the `meta` parameter as JSON: required `name` (short kebab-case) and `description` strings, optional `whenToUse` string and `phases` array (`{title, detail?, provider?, model?}`). The `script` parameter is the plain JavaScript body ONLY (NOT TypeScript, and NO `export const meta` statement — meta is a parameter, not code), running with top-level await; end with `return ` — the value must be JSON-serializable and is this tool's result. Script-body hooks: - `agent(prompt, opts?): Promise` — run one subagent to completion. Without `opts.schema` it resolves to the child's final text; with `opts.schema` (an object-rooted JSON Schema using ONLY type/properties/required/additionalProperties/items/enum/const/oneOf — no pattern/format/numeric bounds) it resolves to the validated object. Resolves `null` when the child fails (filter with `.filter(Boolean)`). Other opts: `label` (display), `phase` (progress group), and independent `provider`/`model` LLM target overrides (either may be provided alone). Anything else (`effort`/`isolation`/`agentType`) is rejected loudly. - `pipeline(items, ...stages): Promise` — run each item through the stages independently with NO barrier between stages (prefer this for multi-stage work). Each stage receives `(prev, item, index)`. An ordinary stage throw drops that ITEM to `null` and skips its remaining stages. - `parallel(thunks): Promise` — run zero-argument functions concurrently and await ALL of them (a barrier; use only when a stage genuinely needs every prior result together). A throwing thunk resolves to `null`. - `phase(title)` — start a progress phase; `log(message)` — narrate progress; `args` — the tool call's `args` input, verbatim. Misused hooks (bad arguments, unknown options, unsupported schemas, tripped caps) throw errors that ALWAYS kill the script — they never dissolve into a per-item `null`. Constraints: concurrency and total-agent caps apply; no filesystem, network, timers, or Node.js APIs are provided — the agents do the work, the script only coordinates them. The run executes in the foreground: this call returns when the whole script finishes. */\n workflow: {\n /** The plain-JS workflow script body (top-level await allowed; NO `export const meta` statement; end with `return `). */\n script: string;\n /** The workflow identity block (plain JSON — never code). */\n meta: {\n /** Short kebab-case workflow name. */\n name: string;\n /** One-line description of what the workflow does. */\n description: string;\n /** Optional guidance on when this workflow applies. */\n whenToUse?: string;\n /** Optional phase declarations matched by phase() calls. */\n phases?: ({\n /** The phase title phase() calls match by exact string. */\n title: string;\n /** Optional one-line description of the phase. */\n detail?: string;\n /** Optional provider override this phase is expected to use. */\n provider?: string;\n /** Optional model override this phase is expected to use. */\n model?: string;\n } & Record)[];\n } & Record;\n /** Optional JSON input exposed to the script as the `args` global (wrap a bare list as a field, e.g. {\"files\": [...]}). */\n args?: Record;\n } & Record;\n /** Create or fully replace a UTF-8 text file. */\n write: {\n /** Path to write, resolved by the filesystem backend. */\n file_path: string;\n /** Full UTF-8 text content to write. */\n content: string;\n } & Record;\n}\n\ninterface ToolOutputMap {\n bash: {\n kind: \"background\";\n taskId: string;\n } | {\n kind: \"foreground\";\n exitCode: number | null;\n signal: string | null;\n timedOut: boolean;\n aborted: boolean;\n timeoutMs: number;\n stdout: {\n text: string;\n truncated: boolean;\n spillPath?: string;\n };\n stderr: {\n text: string;\n truncated: boolean;\n spillPath?: string;\n };\n sandbox?: {\n mode: string;\n denied: boolean;\n enforcement?: string;\n runnerFailed?: boolean;\n };\n };\n cordis_inspect: string;\n cordis_mount: {\n id: string;\n pluginName: string;\n state: \"pending\" | \"loading\" | \"active\" | \"failed\" | \"disposed\" | \"unloading\";\n provides: string[];\n waitingFor: string[];\n };\n cordis_unmount: {\n id: string;\n pluginName: string;\n };\n edit: {\n path: string;\n before: string;\n after: string;\n };\n interrupt_agent: {\n accepted: boolean;\n };\n ralph: {\n runId: string;\n agentsStarted: number;\n result: JsonValue;\n };\n read: {\n path: string;\n offset: number;\n lines: {\n number: number;\n text: string;\n }[];\n totalLines: number;\n };\n send_message: {\n messageId: string;\n };\n skill: {\n name: string;\n provider: string;\n resourceBase?: {\n kind: \"directory\";\n path: string;\n } | {\n kind: \"url\";\n url: string;\n } | {\n kind: \"opaque\";\n description: string;\n };\n content: string;\n };\n subagent: {\n kind: \"background\";\n taskId: string;\n } | {\n kind: \"continuable\";\n subagentId: string;\n } | {\n kind: \"foreground\";\n runId: string;\n output: JsonValue[];\n };\n subagent_fork: {\n kind: \"background\";\n taskId: string;\n } | {\n kind: \"continuable\";\n subagentId: string;\n } | {\n kind: \"foreground\";\n runId: string;\n output: JsonValue[];\n };\n task_kill: {\n outcome: \"cancellation-requested\" | \"already-finished\";\n task: {\n id: string;\n kind: string;\n label: string;\n status: \"running\" | \"stopping\" | \"completed\" | \"killed\" | \"failed\";\n detail?: string;\n startedAt: number;\n finishedAt?: number;\n };\n };\n task_list: ({\n id: string;\n kind: string;\n label: string;\n status: \"running\" | \"stopping\" | \"completed\" | \"killed\" | \"failed\";\n detail?: string;\n startedAt: number;\n finishedAt?: number;\n })[];\n task_output: {\n text: string;\n task: {\n id: string;\n kind: string;\n label: string;\n status: \"running\" | \"stopping\" | \"completed\" | \"killed\" | \"failed\";\n detail?: string;\n startedAt: number;\n finishedAt?: number;\n };\n };\n todo_write: {\n todos: ({\n content: string;\n status: \"pending\" | \"in_progress\" | \"completed\";\n })[];\n counts: {\n pending: number;\n inProgress: number;\n completed: number;\n };\n };\n workflow: {\n runId: string;\n agentsStarted: number;\n result: JsonValue;\n };\n write: {\n path: string;\n operation: \"create\" | \"update\";\n before: string | null;\n after: string;\n };\n}\n\ntype ToolName = keyof ToolOutputMap\n\ndeclare class ToolCallError extends Error {\n readonly name: \"ToolCallError\";\n readonly toolName: ToolName;\n}\n\ndeclare const tools: {\n [K in ToolName]: (args: ToolArgsMap[K]) => Promise;\n}\n```","tools":[{"name":"bash","description":"Execute a bash command (`bash -c`) and return its stdout/stderr. Each call runs in a fresh shell: no state (cwd, variables, functions) persists between calls — pass `workdir` instead of using `cd`. Non-zero exits are reported as `[exit code: N]`. Current harness environment facts are exposed through managed `$DSH_*` variables; inspect them when needed. Commands may run under a file sandbox; a blocked file operation is reported as `[sandbox: file access denied under mode]` — a policy denial, not a bug in the command; do not retry another way. Long output is truncated to its tail; the full output is saved to a file whose path is reported when available. Set `run_in_background: true` for long-running commands: the call returns a task id immediately; read its output with `task_output` and stop it with `task_kill`.","parameters":{"type":"object","properties":{"command":{"type":"string","description":"The bash command to execute."},"description":{"type":"string","description":"Clear, concise description of what this command does in active voice, 5-10 words (shown in the UI). Examples: \"ls\" → \"List files in current directory\"; \"git status\" → \"Show working tree status\"; \"npm install\" → \"Install package dependencies\"."},"timeoutMs":{"type":"number","description":"Timeout in milliseconds. The executor applies its configured default and cap, and kills the command on expiry."},"workdir":{"type":"string","description":"Working directory for this command. Defaults to the session workspace; a relative path is resolved against it."},"run_in_background":{"type":"boolean","description":"Run in the background and return a task id immediately (collect with task_output, stop with task_kill). No timeout applies."}},"required":["command","description"]}},{"name":"cordis_inspect","description":"Inspect the live Cordis runtime in the current DSH process. Read-only. Sections: `services` (every provided ctx service and the plugin fiber that owns it), `plugins` (all live plugin fibers with their lifecycle states), `tools` (the model-facing tools currently registered, i.e. what you can call), `temporary` (only temporary Plugins created by cordis_mount: id, name, state, provided services, awaited services, and lifetime), `api` (method signatures AND argument/return type shapes for every LIVE service — read this before writing plugin code that calls a service), `events` (every harness event with its dispatch mode and exact signature — pick listener targets here). Temporary Plugins exist only in memory, remain active across later turns, and disappear after cordis_unmount, toolset unload, or DSH restart; they are not restored automatically. The `temporary` section is a subset of `plugins`. Omit `what` to get all six sections. With `what:\"api\"` or `what:\"events\"`, pass an exact `name` to narrow to one service/event and include its original source JSDoc.","parameters":{"type":"object","properties":{"what":{"type":"string","description":"Limit the report to one section. Omit for all sections.","enum":["services","plugins","tools","temporary","api","events"]},"name":{"type":"string","description":"Exact service key or event name whose original JSDoc to include; valid only with what:\"api\" or what:\"events\"."}}}},{"name":"cordis_mount","description":"Mount a temporary Cordis Plugin in the current DSH process. This creates an in-memory runtime Plugin, not an installed or configured Plugin. It remains active across later turns until cordis_unmount, toolset unload, or DSH restart. It does not create files, install a package, change cordis.yml or personal/project config, survive restart, or automatically become permanent. To keep it, ask the Agent to implement an SDK Plugin or installable profile bundle through the regular development workflow. It may affect other sessions in the same process; the sandbox is not a security boundary, and injected services reach the real runtime. `code` runs now as the body of an async JavaScript function in an isolated sandbox and MUST `return` a plugin. Two forms: FUNCTION form `return (ctx) => { … }` — declares no inject, so it can register tools, listen to events, and provide services, but reaching ANY service (e.g. ctx.bash) throws; use it only when you need no services. OBJECT form `return { name?, inject: ['bash', 'llm', …], apply(ctx) { … } }` — declares dependencies, and cordis activates the plugin only after the services exist; PREFER this form. You may reach ONLY the services you list in inject: an undeclared service throws even if it exists, because an undeclared dependency would not be cleaned up if its provider is unmounted. BEFORE calling a service from your code, read cordis_inspect what:\"api\" — it lists method signatures AND the type shapes of their arguments/returns (do not guess a field's type; e.g. a bash run's stdout is an object, not a string). Inside `apply`, use the standard cordis API: `ctx.on(event, listener)` to observe events (see cordis_inspect what:\"events\"), or call `harness.registerTool(ctx, harness.defineTool({ name, description, parameters: { text: { type: 'string', required: true } }, output: { schema: { type: 'string' }, render(_args, value) { return [{ type: 'text', text: value }] } }, async execute(args) { return args.text } }))` to give yourself a new tool — it becomes callable on your NEXT step. Tool parameters: each key IS a property — { type: 'string'|'number'|'integer'|'boolean'|'null'|'object'|'array'|'json', required?: true, description?, enum?, const?, items?, properties? }; every direct DSL object declares additionalProperties: true|false, and oneOf: [schema, schema, ...] replaces type for an exact-one union. A raw JSON-Schema { type: 'object', properties, required?: […] } wrapper is also accepted with open-by-default objects. A tool's `execute` MUST return the lossless JSON value declared by `output.schema`; `output.render(args, value)` separately returns Native/model content blocks. Temporary Plugins can COMPOSE: one Plugin may `ctx.provide('name', value)` a service and another may declare `inject: ['name']` to consume it — the consumer stays pending until the provider exists and returns to pending when the provider is unmounted. Everything registered inside `apply` is cleaned up automatically by cordis_unmount. Sandbox globals: `console` (tagged `[cordis:]`, writes through to the harness terminal), `harness.defineTool`, `harness.registerTool`, `btoa`, `atob`, `TextEncoder`, `TextDecoder`. Node APIs are DISABLED — do filesystem/network/timer work through the cordis services, never Node built-ins: `require`, `setTimeout`/`setInterval`, and `fetch` throw redirect errors; `process` and `Buffer` are undefined. Instead use inject: ['fs'] + ctx.fs for files, inject: ['web'] + ctx.web for HTTP, inject: ['bash'] + ctx.bash for processes, and inject: ['timer'] + ctx.setTimeout/ctx.setInterval for timing (fiber effects, auto-cleaned when unmounted) — cordis_inspect what:\"api\" shows what THIS runtime provides. Write PLAIN JavaScript, not TypeScript (no `as`, no type annotations). Cautions: (1) waterfall events (e.g. tools/pre-execute) hand the listener a trailing `next` callback which MUST be called — returning without `next()` SHORT-CIRCUITS the call; prefer plain notification events unless you intend to intercept. (2) Never await something that only resolves after the current turn (your code runs INSIDE a tool call of that turn — it would deadlock). (3) Your `ctx` is a restricted façade: you can register tools, observe events, provide/consume services, and use timers, but framework internals (ctx.root, ctx.fiber, ctx.extend, ctx.plugin, …) are withheld. It is not a security boundary though — the services you inject (e.g. ctx.bash) reach the real runtime.","parameters":{"type":"object","properties":{"code":{"type":"string","description":"JavaScript body returning a temporary Plugin; evaluated now and saved nowhere."}},"required":["code"]}},{"name":"cordis_unmount","description":"Unmount a current-process temporary Plugin created by cordis_mount. Waits for its tools, listeners, services, timers, and other owned effects to clean up completely. Only dyn-N temporary ids are accepted; this cannot remove Loader, configured, or installed Plugins.","parameters":{"type":"object","properties":{"id":{"type":"string","description":"The temporary Plugin id returned by cordis_mount (for example \"dyn-1\"); valid only in this process and invalid after unmount or restart."}},"required":["id"]}},{"name":"edit","description":"Edit an existing UTF-8 text file by replacing literal text.","parameters":{"type":"object","properties":{"file_path":{"type":"string","description":"Path to edit, resolved by the filesystem backend."},"old_string":{"type":"string","description":"Literal text to replace. Must match exactly."},"new_string":{"type":"string","description":"Literal replacement text. Use an empty string to delete the match."},"replace_all":{"type":"boolean","description":"Replace all matches. Defaults to false; when false, old_string must appear exactly once."}},"required":["file_path","old_string","new_string"]}},{"name":"interrupt_agent","description":"Request cancellation of a background agent's current turn by its agent id. The target may be your direct child or a deeper agent created under you. Only the current turn stops: messages already queued for the agent stay parked until a later send_message, agents it started keep running, and the agent itself stays available for follow-ups. This call returns as soon as the stop request is accepted, so the target may keep running briefly; interrupting an agent that already finished is an accepted no-op.","parameters":{"type":"object","properties":{"agent_id":{"type":"string","description":"The agent id of the running agent to interrupt."}},"required":["agent_id"]}},{"name":"ralph","description":"Run a foreground fresh-agent Ralph loop toward one immutable objective. Use only when the direct human explicitly asks for Ralph or fresh-agent iteration. Each round opens a new child with no parent conversation or prior child session; the shared workspace is long-term memory, and only a bounded structured report crosses rounds. The call returns when a worker reports completion or a concrete blocker, or at the round limit. Ordinary long-running same-session work belongs to goal tools.","parameters":{"type":"object","properties":{"objective":{"type":"string","description":"The immutable completion objective for every fresh Ralph round."},"maxRounds":{"type":"number","description":"Optional positive safe-integer round cap, bounded by the deployment ceiling."}},"required":["objective"]}},{"name":"read","description":"Read a UTF-8 text file and return line-numbered content.","parameters":{"type":"object","properties":{"file_path":{"type":"string","description":"Path to read, resolved by the filesystem backend."},"offset":{"type":"number","description":"1-based first line to return. Defaults to 1."},"limit":{"type":"number","description":"Maximum number of lines to return. Defaults to 2000."}},"required":["file_path"]}},{"name":"run_code","description":"Execute a TypeScript program against the available tools. Write the BODY of an async function (erasable syntax only; top-level `await` and `return` work) and call tools as `await tools.name(args)` per the declarations in the system prompt. Only what you print or return comes back — curate it.","parameters":{"type":"object","properties":{"code":{"type":"string","description":"The program: the body of an async TypeScript function."},"description":{"type":"string","description":"Clear, concise description of what this program does in active voice, 5-10 words (shown in the UI). Examples: \"Count TODO markers across packages\"; \"Read failing test and its fixture\"; \"Rename config key in every cordis.yml\"."}},"required":["code","description"]}},{"name":"send_message","description":"Send a message to a background subagent by its subagent id, continuing the same conversation. It becomes the subagent's next turn: if it is still working, the message waits until its current turn finishes, so it cannot redirect work already underway. This call returns no answer from the subagent — only confirmation that the message was delivered — so use it to give it more work. A failure means the message was NOT delivered.","parameters":{"type":"object","properties":{"subagent_id":{"type":"string","description":"The subagent id returned when the background subagent was started."},"message":{"type":"string","description":"The message to deliver to the subagent."}},"required":["subagent_id","message"]}},{"name":"skill","description":"Load the full instructions for an available skill. Call this with the exact skill name from the session skill catalog before acting on a task that names or clearly matches that skill.","parameters":{"type":"object","properties":{"name":{"type":"string","description":"The exact skill name from the available skills list."}},"required":["name"]}},{"name":"subagent","description":"Delegate a self-contained task to a subagent (a separate agent that works in its own context) and return its final result. Use this to offload focused, independent work — research, a scoped implementation, an analysis — so it does not consume this conversation's context. The subagent runs to completion and you receive only its final answer, not its intermediate steps. Give it a complete, standalone prompt: it does not see this conversation. Set `run_in_background: true` to start a background subagent that keeps its conversation: you receive only its subagent id, never its result, and it works on its own. Use this for work whose result you do not need returned by this call; `send_message` sends it more work.","parameters":{"type":"object","properties":{"description":{"type":"string","description":"A short (3-5 word) description of the delegated task, for display."},"prompt":{"type":"string","description":"The complete, self-contained task for the subagent. It does not share this conversation's context, so include everything it needs."},"run_in_background":{"type":"boolean","description":"Run as a background subagent that keeps its conversation and return only its subagent id. This call never returns its result; send it more work with send_message."}},"required":["description","prompt"]}},{"name":"subagent_fork","description":"Delegate a task to a subagent that inherits this conversation: a child agent seeded with all completed turns so far (it does not see the current in-flight turn), returning only its final result. Use this when the subtask builds on this conversation's context — a follow-up analysis, a review, a continuation — without consuming this conversation's context for the work itself. You receive only its final answer, not its intermediate steps. Set `run_in_background: true` to start a background subagent that keeps its conversation: you receive only its subagent id, never its result, and it works on its own. Use this for work whose result you do not need returned by this call; `send_message` sends it more work.","parameters":{"type":"object","properties":{"description":{"type":"string","description":"A short (3-5 word) description of the delegated task, for display."},"prompt":{"type":"string","description":"The task for the subagent. It already sees this conversation's completed turns, so build on them freely and state only what is new."},"run_in_background":{"type":"boolean","description":"Run as a background subagent that keeps its conversation and return only its subagent id. This call never returns its result; send it more work with send_message."}},"required":["description","prompt"]}},{"name":"task_kill","description":"Request cancellation of a running background task by task id. Returns immediately; the task settles as killed once its work actually stops.","parameters":{"type":"object","properties":{"task_id":{"type":"string","description":"Task id returned by the tool that started the background work."},"reason":{"type":"string","description":"Optional short reason, recorded in the log and forwarded to the task."}},"required":["task_id"]}},{"name":"task_list","description":"List your background tasks (running and finished) with their ids, kinds, and statuses.","parameters":{"type":"object","properties":{}}},{"name":"task_output","description":"Read a background task. Stream tasks return only output since the previous read; final-output tasks return their result after settlement. Every response ends with `[status: ...]`. Reads are non-blocking unless `wait: true`, which waits up to the configured cap.","parameters":{"type":"object","properties":{"task_id":{"type":"string","description":"Task id returned by the tool that started the background work."},"wait":{"type":"boolean","description":"Block until the task reaches a terminal status or the timeout expires. A timed-out wait returns [status: running] and leaves the task alive."},"timeout_ms":{"type":"number","description":"Max wait in milliseconds (only meaningful with wait: true). Defaults to the configured wait timeout; capped by the configured maximum."}},"required":["task_id"]}},{"name":"todo_write","description":"Record and update a structured task list for the current work. Send the ENTIRE list every call — it REPLACES the previous list (there are no partial updates, no per-item edits). Use it to plan multi-step work and show progress: add one todo per concrete step before you start. Mark every todo being actively worked on `in_progress` — several at once when work genuinely runs in parallel (e.g. concurrent subagents or background commands), one for sequential work; while work remains, at least one task should be `in_progress`. Mark a todo `completed` the moment it is done (do not batch completions), and allow no `in_progress` item only once all work is complete. Skip the list for trivial single-step tasks. Statuses: `pending` (not started), `in_progress` (being worked on now), `completed` (finished).","parameters":{"type":"object","properties":{"todos":{"type":"array","description":"The COMPLETE task list, replacing any previous list.","items":{"type":"object","additionalProperties":false,"properties":{"content":{"type":"string","description":"What the task is — a short imperative line."},"status":{"type":"string","description":"pending (not started) | in_progress (now) | completed (done).","enum":["pending","in_progress","completed"]}},"required":["content","status"]}}},"required":["todos"]}},{"name":"workflow","description":"Run a JavaScript workflow script that orchestrates subagents at scale. Use this for work that fans out across many independent pieces — an audit over many files, a migration, multi-angle research, adversarial verification of findings — where you write the orchestration as a script instead of delegating turn by turn.\n\nThe workflow's identity rides the `meta` parameter as JSON: required `name` (short kebab-case) and `description` strings, optional `whenToUse` string and `phases` array (`{title, detail?, provider?, model?}`). The `script` parameter is the plain JavaScript body ONLY (NOT TypeScript, and NO `export const meta` statement — meta is a parameter, not code), running with top-level await; end with `return ` — the value must be JSON-serializable and is this tool's result.\n\nScript-body hooks:\n- `agent(prompt, opts?): Promise` — run one subagent to completion. Without `opts.schema` it resolves to the child's final text; with `opts.schema` (an object-rooted JSON Schema using ONLY type/properties/required/additionalProperties/items/enum/const/oneOf — no pattern/format/numeric bounds) it resolves to the validated object. Resolves `null` when the child fails (filter with `.filter(Boolean)`). Other opts: `label` (display), `phase` (progress group), and independent `provider`/`model` LLM target overrides (either may be provided alone). Anything else (`effort`/`isolation`/`agentType`) is rejected loudly.\n- `pipeline(items, ...stages): Promise` — run each item through the stages independently with NO barrier between stages (prefer this for multi-stage work). Each stage receives `(prev, item, index)`. An ordinary stage throw drops that ITEM to `null` and skips its remaining stages.\n- `parallel(thunks): Promise` — run zero-argument functions concurrently and await ALL of them (a barrier; use only when a stage genuinely needs every prior result together). A throwing thunk resolves to `null`.\n- `phase(title)` — start a progress phase; `log(message)` — narrate progress; `args` — the tool call's `args` input, verbatim.\n\nMisused hooks (bad arguments, unknown options, unsupported schemas, tripped caps) throw errors that ALWAYS kill the script — they never dissolve into a per-item `null`.\n\nConstraints: concurrency and total-agent caps apply; no filesystem, network, timers, or Node.js APIs are provided — the agents do the work, the script only coordinates them. The run executes in the foreground: this call returns when the whole script finishes.","parameters":{"type":"object","properties":{"script":{"type":"string","description":"The plain-JS workflow script body (top-level await allowed; NO `export const meta` statement; end with `return `)."},"meta":{"type":"object","description":"The workflow identity block (plain JSON — never code).","additionalProperties":true,"properties":{"name":{"type":"string","description":"Short kebab-case workflow name."},"description":{"type":"string","description":"One-line description of what the workflow does."},"whenToUse":{"type":"string","description":"Optional guidance on when this workflow applies."},"phases":{"type":"array","description":"Optional phase declarations matched by phase() calls.","items":{"type":"object","additionalProperties":true,"properties":{"title":{"type":"string","description":"The phase title phase() calls match by exact string."},"detail":{"type":"string","description":"Optional one-line description of the phase."},"provider":{"type":"string","description":"Optional provider override this phase is expected to use."},"model":{"type":"string","description":"Optional model override this phase is expected to use."}},"required":["title"]}}},"required":["name","description"]},"args":{"type":"object","description":"Optional JSON input exposed to the script as the `args` global (wrap a bare list as a field, e.g. {\"files\": [...]}).","additionalProperties":true}},"required":["script","meta"]}},{"name":"write","description":"Create or fully replace a UTF-8 text file.","parameters":{"type":"object","properties":{"file_path":{"type":"string","description":"Path to write, resolved by the filesystem backend."},"content":{"type":"string","description":"Full UTF-8 text content to write."}},"required":["file_path","content"]}}]},"reason":"initial"}} {"type":"request/context","seq":8,"time":1785730501507,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} {"type":"assistant/chunk","seq":9,"time":1783957884564,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"text"}}} {"type":"assistant/chunk","seq":10,"time":1783957884564,"data":{"turn":1,"step":1,"chunk":{"type":"text-delta","index":0,"text":"DIRECT_CHILD_OK"}}} {"type":"assistant/chunk","seq":11,"time":1783957884564,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"DIRECT_CHILD_OK"}}}} {"type":"assistant/chunk","seq":12,"time":1785498583897,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}}} {"type":"assistant/chunk","seq":13,"time":1785730501507,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"stop"}}}} -{"type":"assistant/message","seq":14,"time":1785730501507,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"text","text":"DIRECT_CHILD_OK"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"cac680cf-1d70-4fb2-91a3-da1e3a317d2e"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[9,10,11,12,13],"surfaceOp":"append"} +{"type":"assistant/message","seq":14,"time":1785730501507,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"text","text":"DIRECT_CHILD_OK"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"5a6c9f8f-37db-4fb5-bedd-29c6b69d815a"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[9,10,11,12,13],"surfaceOp":"append"} {"type":"step/end","seq":15,"time":1785730501507,"data":{"turn":1,"step":1}} {"type":"turn/end","seq":16,"time":1785730501507,"data":{"turn":1,"reason":{"kind":"completed"}}} diff --git a/examples/headless-agent/tests/snapshots/advanced-toolchain/session.2.jsonl b/examples/headless-agent/tests/snapshots/advanced-toolchain/session.2.jsonl index 6988595618..984e662d91 100644 --- a/examples/headless-agent/tests/snapshots/advanced-toolchain/session.2.jsonl +++ b/examples/headless-agent/tests/snapshots/advanced-toolchain/session.2.jsonl @@ -1,18 +1,18 @@ {"type":"session","version":0,"id":"33333333-3333-4333-8333-333333333333","createdAt":1783950002000,"cwd":"{{cwd}}","parentSession":"11111111-1111-4111-8111-111111111111","origin":"subagent","delegationDepth":1} -{"type":"agent/inbox/spliced","seq":0,"time":1785498584048,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Reply with exactly WORKFLOW_CHILD_OK and nothing else."}],"source":{"kind":"user"},"role":"user","id":"093bfc20-c6fc-4573-b172-2c6ca40c188b"}]}} +{"type":"agent/inbox/spliced","seq":0,"time":1785498584048,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Reply with exactly WORKFLOW_CHILD_OK and nothing else."}],"source":{"kind":"user"},"role":"user","id":"97e45fc6-61b8-443f-bd01-7fb0b8263eba"}]}} {"type":"turn/start","seq":1,"time":1785821454599,"data":{"turn":1}} {"type":"agent/inbox/spliced","seq":2,"time":1785821454599,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} {"type":"subagent/descriptor","seq":3,"time":1785821454618,"data":{"version":2,"mode":"one-shot","provider":"spawn"}} {"type":"step/start","seq":4,"time":1785730501645,"data":{"turn":1,"step":1}} -{"type":"user/message","seq":5,"time":1785730501645,"data":{"content":[{"type":"text","text":"Reply with exactly WORKFLOW_CHILD_OK and nothing else."}],"source":{"kind":"user"},"role":"user","id":"093bfc20-c6fc-4573-b172-2c6ca40c188b"},"surfaceOp":"append"} +{"type":"user/message","seq":5,"time":1785730501645,"data":{"content":[{"type":"text","text":"Reply with exactly WORKFLOW_CHILD_OK and nothing else."}],"source":{"kind":"user"},"role":"user","id":"97e45fc6-61b8-443f-bd01-7fb0b8263eba"},"surfaceOp":"append"} {"type":"session/title","seq":6,"time":1785730501645,"data":{"title":"Reply with exactly WORKFLOW_CHILD_OK and","messageSeqs":[5],"source":{"kind":"fallback"}}} -{"type":"request/header","seq":7,"time":1785498584067,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"You are an AI agent powered by the DeepSeek Harness SDK.\n\nYou are headless-agent, a coding assistant powered by the deepseek-v4-flash model. Your working directory is {{cwd}}.\n\nVerify your work by running the code or tests. Keep answers brief and factual.\n\n\nUse the read tool — not shell commands like cat — to inspect text files. Results include line numbers. Use offset and limit to continue reading large files.\n\nUse the write tool to create files or completely replace file contents. Existing files are overwritten, so read an existing file first (the default fs-policy requires it) and prefer edit for targeted changes.\n\nUse the edit tool for targeted changes to existing UTF-8 text files. It replaces literal old_string with new_string; by default old_string must appear exactly once. If old_string appears multiple times, provide a more specific old_string or set replace_all to true. Read the file first (the default fs-policy requires it), unless you just created or edited it in this session.\n\nCheck the [exit code: N] marker on every bash result; investigate failures before moving on.\n\nTrack every background task id you start. You are notified in-session when a task finishes — do not busy-poll or sleep on one; keep working on independent steps and do not duplicate a running task's work. Before giving a final answer, collect every still-relevant task with task_output (set wait: true only when you are genuinely blocked on it), and task_kill tasks that stopped mattering.\n\nUse the workflow tool ONLY when the user explicitly asks for a workflow or for large multi-agent orchestration: you write a JavaScript script (the tool description documents the exact format) that fans work out across many subagents with phases and structured results. For one or two delegations, prefer plain subagent calls.\n\nUse the ralph tool ONLY when the direct human explicitly asks for a Ralph loop or fresh-agent iterative execution. Each Ralph round starts a fresh child with no conversation seed and uses the shared workspace as durable memory. Completion and blockers are worker reports, not independent evaluation. Use same-session goal tools for ordinary long-running objectives, and plain subagents or workflows for bounded delegation and fan-out.\n\n## Writing code for run_code\n\nPass `run_code` the body of an async TypeScript function (erasable syntax only — no `enum` or namespaces; type annotations are advisory, the code runs type-stripped). Inside the program:\n\n- Call tools as `await tools.name(args)` — quoted access for exotic names: `tools[\"my-tool\"](args)`. Every call resolves to the tool's typed canonical JSON value. Tool arguments must be lossless JSON.\n- A FAILED tool call rejects with `ToolCallError`, whose `toolName` identifies the failed tool and whose `message` is human-readable — `try/catch` it to handle and continue.\n- Independent read-only calls MAY overlap under `Promise.all` (safe calls run concurrently; mutating calls run alone, in submission order). Sequence dependent work with `await`.\n- Emit results with `return` and/or `console.log(...)`. ONLY what you print or return comes back to you — intermediate tool results never enter the conversation, so extract just what you need.\n\nThe available tools:\n\n```ts\ntype JsonValue = null | boolean | number | string | JsonValue[] | { [key: string]: JsonValue }\n\ninterface ToolArgsMap {\n /** Execute a bash command (`bash -c`) and return its stdout/stderr. Each call runs in a fresh shell: no state (cwd, variables, functions) persists between calls — pass `workdir` instead of using `cd`. Non-zero exits are reported as `[exit code: N]`. Current harness environment facts are exposed through managed `$DSH_*` variables; inspect them when needed. Commands may run under a file sandbox; a blocked file operation is reported as `[sandbox: file access denied under mode]` — a policy denial, not a bug in the command; do not retry another way. Long output is truncated to its tail; the full output is saved to a file whose path is reported when available. Set `run_in_background: true` for long-running commands: the call returns a task id immediately; read its output with `task_output` and stop it with `task_kill`. */\n bash: {\n /** The bash command to execute. */\n command: string;\n /** Clear, concise description of what this command does in active voice, 5-10 words (shown in the UI). Examples: \"ls\" → \"List files in current directory\"; \"git status\" → \"Show working tree status\"; \"npm install\" → \"Install package dependencies\". */\n description: string;\n /** Timeout in milliseconds. The executor applies its configured default and cap, and kills the command on expiry. */\n timeoutMs?: number;\n /** Working directory for this command. Defaults to the session workspace; a relative path is resolved against it. */\n workdir?: string;\n /** Run in the background and return a task id immediately (collect with task_output, stop with task_kill). No timeout applies. */\n run_in_background?: boolean;\n } & Record;\n /** Inspect the live Cordis runtime in the current DSH process. Read-only. Sections: `services` (every provided ctx service and the plugin fiber that owns it), `plugins` (all live plugin fibers with their lifecycle states), `tools` (the model-facing tools currently registered, i.e. what you can call), `temporary` (only temporary Plugins created by cordis_mount: id, name, state, provided services, awaited services, and lifetime), `api` (method signatures AND argument/return type shapes for every LIVE service — read this before writing plugin code that calls a service), `events` (every harness event with its dispatch mode and exact signature — pick listener targets here). Temporary Plugins exist only in memory, remain active across later turns, and disappear after cordis_unmount, toolset unload, or DSH restart; they are not restored automatically. The `temporary` section is a subset of `plugins`. Omit `what` to get all six sections. With `what:\"api\"` or `what:\"events\"`, pass an exact `name` to narrow to one service/event and include its original source JSDoc. */\n cordis_inspect: {\n /** Limit the report to one section. Omit for all sections. */\n what?: \"services\" | \"plugins\" | \"tools\" | \"temporary\" | \"api\" | \"events\";\n /** Exact service key or event name whose original JSDoc to include; valid only with what:\"api\" or what:\"events\". */\n name?: string;\n } & Record;\n /** Mount a temporary Cordis Plugin in the current DSH process. This creates an in-memory runtime Plugin, not an installed or configured Plugin. It remains active across later turns until cordis_unmount, toolset unload, or DSH restart. It does not create files, install a package, change cordis.yml or personal/project config, survive restart, or automatically become permanent. To keep it, ask the Agent to implement a normal local, project, or repository Plugin through the regular development workflow. It may affect other sessions in the same process; the sandbox is not a security boundary, and injected services reach the real runtime. `code` runs now as the body of an async JavaScript function in an isolated sandbox and MUST `return` a plugin. Two forms: FUNCTION form `return (ctx) => { … }` — declares no inject, so it can register tools, listen to events, and provide services, but reaching ANY service (e.g. ctx.bash) throws; use it only when you need no services. OBJECT form `return { name?, inject: ['bash', 'llm', …], apply(ctx) { … } }` — declares dependencies, and cordis activates the plugin only after the services exist; PREFER this form. You may reach ONLY the services you list in inject: an undeclared service throws even if it exists, because an undeclared dependency would not be cleaned up if its provider is unmounted. BEFORE calling a service from your code, read cordis_inspect what:\"api\" — it lists method signatures AND the type shapes of their arguments/returns (do not guess a field's type; e.g. a bash run's stdout is an object, not a string). Inside `apply`, use the standard cordis API: `ctx.on(event, listener)` to observe events (see cordis_inspect what:\"events\"), or call `harness.registerTool(ctx, harness.defineTool({ name, description, parameters: { text: { type: 'string', required: true } }, output: { schema: { type: 'string' }, render(_args, value) { return [{ type: 'text', text: value }] } }, async execute(args) { return args.text } }))` to give yourself a new tool — it becomes callable on your NEXT step. Tool parameters: each key IS a property — { type: 'string'|'number'|'integer'|'boolean'|'null'|'object'|'array'|'json', required?: true, description?, enum?, const?, items?, properties? }; every direct DSL object declares additionalProperties: true|false, and oneOf: [schema, schema, ...] replaces type for an exact-one union. A raw JSON-Schema { type: 'object', properties, required?: […] } wrapper is also accepted with open-by-default objects. A tool's `execute` MUST return the lossless JSON value declared by `output.schema`; `output.render(args, value)` separately returns Native/model content blocks. Temporary Plugins can COMPOSE: one Plugin may `ctx.provide('name', value)` a service and another may declare `inject: ['name']` to consume it — the consumer stays pending until the provider exists and returns to pending when the provider is unmounted. Everything registered inside `apply` is cleaned up automatically by cordis_unmount. Sandbox globals: `console` (tagged `[cordis:]`, writes through to the harness terminal), `harness.defineTool`, `harness.registerTool`, `btoa`, `atob`, `TextEncoder`, `TextDecoder`. Node APIs are DISABLED — do filesystem/network/timer work through the cordis services, never Node built-ins: `require`, `setTimeout`/`setInterval`, and `fetch` throw redirect errors; `process` and `Buffer` are undefined. Instead use inject: ['fs'] + ctx.fs for files, inject: ['web'] + ctx.web for HTTP, inject: ['bash'] + ctx.bash for processes, and inject: ['timer'] + ctx.setTimeout/ctx.setInterval for timing (fiber effects, auto-cleaned when unmounted) — cordis_inspect what:\"api\" shows what THIS runtime provides. Write PLAIN JavaScript, not TypeScript (no `as`, no type annotations). Cautions: (1) waterfall events (e.g. tools/pre-execute) hand the listener a trailing `next` callback which MUST be called — returning without `next()` SHORT-CIRCUITS the call; prefer plain notification events unless you intend to intercept. (2) Never await something that only resolves after the current turn (your code runs INSIDE a tool call of that turn — it would deadlock). (3) Your `ctx` is a restricted façade: you can register tools, observe events, provide/consume services, and use timers, but framework internals (ctx.root, ctx.fiber, ctx.extend, ctx.plugin, …) are withheld. It is not a security boundary though — the services you inject (e.g. ctx.bash) reach the real runtime. */\n cordis_mount: {\n /** JavaScript body returning a temporary Plugin; evaluated now and saved nowhere. */\n code: string;\n } & Record;\n /** Unmount a current-process temporary Plugin created by cordis_mount. Waits for its tools, listeners, services, timers, and other owned effects to clean up completely. Only dyn-N temporary ids are accepted; this cannot remove Loader, configured, or installed Plugins. */\n cordis_unmount: {\n /** The temporary Plugin id returned by cordis_mount (for example \"dyn-1\"); valid only in this process and invalid after unmount or restart. */\n id: string;\n } & Record;\n /** Edit an existing UTF-8 text file by replacing literal text. */\n edit: {\n /** Path to edit, resolved by the filesystem backend. */\n file_path: string;\n /** Literal text to replace. Must match exactly. */\n old_string: string;\n /** Literal replacement text. Use an empty string to delete the match. */\n new_string: string;\n /** Replace all matches. Defaults to false; when false, old_string must appear exactly once. */\n replace_all?: boolean;\n } & Record;\n /** Run a foreground fresh-agent Ralph loop toward one immutable objective. Use only when the direct human explicitly asks for Ralph or fresh-agent iteration. Each round opens a new child with no parent conversation or prior child session; the shared workspace is long-term memory, and only a bounded structured report crosses rounds. The call returns when a worker reports completion or a concrete blocker, or at the round limit. Ordinary long-running same-session work belongs to goal tools. */\n ralph: {\n /** The immutable completion objective for every fresh Ralph round. */\n objective: string;\n /** Optional positive safe-integer round cap, bounded by the deployment ceiling. */\n maxRounds?: number;\n } & Record;\n /** Read a UTF-8 text file and return line-numbered content. */\n read: {\n /** Path to read, resolved by the filesystem backend. */\n file_path: string;\n /** 1-based first line to return. Defaults to 1. */\n offset?: number;\n /** Maximum number of lines to return. Defaults to 2000. */\n limit?: number;\n } & Record;\n /** Send a message to a background subagent by its subagent id, continuing the same conversation. It becomes the subagent's next turn: if it is still working, the message waits until its current turn finishes, so it cannot redirect work already underway. This call returns no answer from the subagent — only confirmation that the message was delivered — so use it to give it more work. A failure means the message was NOT delivered. */\n send_message: {\n /** The subagent id returned when the background subagent was started. */\n subagent_id: string;\n /** The message to deliver to the subagent. */\n message: string;\n } & Record;\n /** Load the full instructions for an available skill. Call this with the exact skill name from the session skill catalog before acting on a task that names or clearly matches that skill. */\n skill: {\n /** The exact skill name from the available skills list. */\n name: string;\n } & Record;\n /** Delegate a self-contained task to a subagent (a separate agent that works in its own context) and return its final result. Use this to offload focused, independent work — research, a scoped implementation, an analysis — so it does not consume this conversation's context. The subagent runs to completion and you receive only its final answer, not its intermediate steps. Give it a complete, standalone prompt: it does not see this conversation. Set `run_in_background: true` to start a background subagent that keeps its conversation: you receive only its subagent id, never its result, and it works on its own. Use this for work whose result you do not need returned by this call; `send_message` sends it more work. */\n subagent: {\n /** A short (3-5 word) description of the delegated task, for display. */\n description: string;\n /** The complete, self-contained task for the subagent. It does not share this conversation's context, so include everything it needs. */\n prompt: string;\n /** Run as a background subagent that keeps its conversation and return only its subagent id. This call never returns its result; send it more work with send_message. */\n run_in_background?: boolean;\n } & Record;\n /** Delegate a task to a subagent that inherits this conversation: a child agent seeded with all completed turns so far (it does not see the current in-flight turn), returning only its final result. Use this when the subtask builds on this conversation's context — a follow-up analysis, a review, a continuation — without consuming this conversation's context for the work itself. You receive only its final answer, not its intermediate steps. Set `run_in_background: true` to start a background subagent that keeps its conversation: you receive only its subagent id, never its result, and it works on its own. Use this for work whose result you do not need returned by this call; `send_message` sends it more work. */\n subagent_fork: {\n /** A short (3-5 word) description of the delegated task, for display. */\n description: string;\n /** The task for the subagent. It already sees this conversation's completed turns, so build on them freely and state only what is new. */\n prompt: string;\n /** Run as a background subagent that keeps its conversation and return only its subagent id. This call never returns its result; send it more work with send_message. */\n run_in_background?: boolean;\n } & Record;\n /** Request cancellation of a running background task by task id. Returns immediately; the task settles as killed once its work actually stops. */\n task_kill: {\n /** Task id returned by the tool that started the background work. */\n task_id: string;\n /** Optional short reason, recorded in the log and forwarded to the task. */\n reason?: string;\n } & Record;\n /** List your background tasks (running and finished) with their ids, kinds, and statuses. */\n task_list: Record;\n /** Read a background task. Stream tasks return only output since the previous read; final-output tasks return their result after settlement. Every response ends with `[status: ...]`. Reads are non-blocking unless `wait: true`, which waits up to the configured cap. */\n task_output: {\n /** Task id returned by the tool that started the background work. */\n task_id: string;\n /** Block until the task reaches a terminal status or the timeout expires. A timed-out wait returns [status: running] and leaves the task alive. */\n wait?: boolean;\n /** Max wait in milliseconds (only meaningful with wait: true). Defaults to the configured wait timeout; capped by the configured maximum. */\n timeout_ms?: number;\n } & Record;\n /** Record and update a structured task list for the current work. Send the ENTIRE list every call — it REPLACES the previous list (there are no partial updates, no per-item edits). Use it to plan multi-step work and show progress: add one todo per concrete step before you start. Mark every todo being actively worked on `in_progress` — several at once when work genuinely runs in parallel (e.g. concurrent subagents or background commands), one for sequential work; while work remains, at least one task should be `in_progress`. Mark a todo `completed` the moment it is done (do not batch completions), and allow no `in_progress` item only once all work is complete. Skip the list for trivial single-step tasks. Statuses: `pending` (not started), `in_progress` (being worked on now), `completed` (finished). */\n todo_write: {\n /** The COMPLETE task list, replacing any previous list. */\n todos: ({\n /** What the task is — a short imperative line. */\n content: string;\n /** pending (not started) | in_progress (now) | completed (done). */\n status: \"pending\" | \"in_progress\" | \"completed\";\n })[];\n } & Record;\n /** Run a JavaScript workflow script that orchestrates subagents at scale. Use this for work that fans out across many independent pieces — an audit over many files, a migration, multi-angle research, adversarial verification of findings — where you write the orchestration as a script instead of delegating turn by turn. The workflow's identity rides the `meta` parameter as JSON: required `name` (short kebab-case) and `description` strings, optional `whenToUse` string and `phases` array (`{title, detail?, provider?, model?}`). The `script` parameter is the plain JavaScript body ONLY (NOT TypeScript, and NO `export const meta` statement — meta is a parameter, not code), running with top-level await; end with `return ` — the value must be JSON-serializable and is this tool's result. Script-body hooks: - `agent(prompt, opts?): Promise` — run one subagent to completion. Without `opts.schema` it resolves to the child's final text; with `opts.schema` (an object-rooted JSON Schema using ONLY type/properties/required/additionalProperties/items/enum/const/oneOf — no pattern/format/numeric bounds) it resolves to the validated object. Resolves `null` when the child fails (filter with `.filter(Boolean)`). Other opts: `label` (display), `phase` (progress group), and independent `provider`/`model` LLM target overrides (either may be provided alone). Anything else (`effort`/`isolation`/`agentType`) is rejected loudly. - `pipeline(items, ...stages): Promise` — run each item through the stages independently with NO barrier between stages (prefer this for multi-stage work). Each stage receives `(prev, item, index)`. An ordinary stage throw drops that ITEM to `null` and skips its remaining stages. - `parallel(thunks): Promise` — run zero-argument functions concurrently and await ALL of them (a barrier; use only when a stage genuinely needs every prior result together). A throwing thunk resolves to `null`. - `phase(title)` — start a progress phase; `log(message)` — narrate progress; `args` — the tool call's `args` input, verbatim. Misused hooks (bad arguments, unknown options, unsupported schemas, tripped caps) throw errors that ALWAYS kill the script — they never dissolve into a per-item `null`. Constraints: concurrency and total-agent caps apply; no filesystem, network, timers, or Node.js APIs are provided — the agents do the work, the script only coordinates them. The run executes in the foreground: this call returns when the whole script finishes. */\n workflow: {\n /** The plain-JS workflow script body (top-level await allowed; NO `export const meta` statement; end with `return `). */\n script: string;\n /** The workflow identity block (plain JSON — never code). */\n meta: {\n /** Short kebab-case workflow name. */\n name: string;\n /** One-line description of what the workflow does. */\n description: string;\n /** Optional guidance on when this workflow applies. */\n whenToUse?: string;\n /** Optional phase declarations matched by phase() calls. */\n phases?: ({\n /** The phase title phase() calls match by exact string. */\n title: string;\n /** Optional one-line description of the phase. */\n detail?: string;\n /** Optional provider override this phase is expected to use. */\n provider?: string;\n /** Optional model override this phase is expected to use. */\n model?: string;\n } & Record)[];\n } & Record;\n /** Optional JSON input exposed to the script as the `args` global (wrap a bare list as a field, e.g. {\"files\": [...]}). */\n args?: Record;\n } & Record;\n /** Create or fully replace a UTF-8 text file. */\n write: {\n /** Path to write, resolved by the filesystem backend. */\n file_path: string;\n /** Full UTF-8 text content to write. */\n content: string;\n } & Record;\n}\n\ninterface ToolOutputMap {\n bash: {\n kind: \"background\";\n taskId: string;\n } | {\n kind: \"foreground\";\n exitCode: number | null;\n signal: string | null;\n timedOut: boolean;\n aborted: boolean;\n timeoutMs: number;\n stdout: {\n text: string;\n truncated: boolean;\n spillPath?: string;\n };\n stderr: {\n text: string;\n truncated: boolean;\n spillPath?: string;\n };\n sandbox?: {\n mode: string;\n denied: boolean;\n enforcement?: string;\n runnerFailed?: boolean;\n };\n };\n cordis_inspect: string;\n cordis_mount: {\n id: string;\n pluginName: string;\n state: \"pending\" | \"loading\" | \"active\" | \"failed\" | \"disposed\" | \"unloading\";\n provides: string[];\n waitingFor: string[];\n };\n cordis_unmount: {\n id: string;\n pluginName: string;\n };\n edit: {\n path: string;\n before: string;\n after: string;\n };\n ralph: {\n runId: string;\n agentsStarted: number;\n result: JsonValue;\n };\n read: {\n path: string;\n offset: number;\n lines: {\n number: number;\n text: string;\n }[];\n totalLines: number;\n };\n send_message: {\n messageId: string;\n };\n skill: {\n name: string;\n provider: string;\n resourceBase?: {\n kind: \"directory\";\n path: string;\n } | {\n kind: \"url\";\n url: string;\n } | {\n kind: \"opaque\";\n description: string;\n };\n content: string;\n };\n subagent: {\n kind: \"background\";\n taskId: string;\n } | {\n kind: \"continuable\";\n subagentId: string;\n } | {\n kind: \"foreground\";\n runId: string;\n output: JsonValue[];\n };\n subagent_fork: {\n kind: \"background\";\n taskId: string;\n } | {\n kind: \"continuable\";\n subagentId: string;\n } | {\n kind: \"foreground\";\n runId: string;\n output: JsonValue[];\n };\n task_kill: {\n outcome: \"cancellation-requested\" | \"already-finished\";\n task: {\n id: string;\n kind: string;\n label: string;\n status: \"running\" | \"stopping\" | \"completed\" | \"killed\" | \"failed\";\n detail?: string;\n startedAt: number;\n finishedAt?: number;\n };\n };\n task_list: ({\n id: string;\n kind: string;\n label: string;\n status: \"running\" | \"stopping\" | \"completed\" | \"killed\" | \"failed\";\n detail?: string;\n startedAt: number;\n finishedAt?: number;\n })[];\n task_output: {\n text: string;\n task: {\n id: string;\n kind: string;\n label: string;\n status: \"running\" | \"stopping\" | \"completed\" | \"killed\" | \"failed\";\n detail?: string;\n startedAt: number;\n finishedAt?: number;\n };\n };\n todo_write: {\n todos: ({\n content: string;\n status: \"pending\" | \"in_progress\" | \"completed\";\n })[];\n counts: {\n pending: number;\n inProgress: number;\n completed: number;\n };\n };\n workflow: {\n runId: string;\n agentsStarted: number;\n result: JsonValue;\n };\n write: {\n path: string;\n operation: \"create\" | \"update\";\n before: string | null;\n after: string;\n };\n}\n\ntype ToolName = keyof ToolOutputMap\n\ndeclare class ToolCallError extends Error {\n readonly name: \"ToolCallError\";\n readonly toolName: ToolName;\n}\n\ndeclare const tools: {\n [K in ToolName]: (args: ToolArgsMap[K]) => Promise;\n}\n```","tools":[{"name":"bash","description":"Execute a bash command (`bash -c`) and return its stdout/stderr. Each call runs in a fresh shell: no state (cwd, variables, functions) persists between calls — pass `workdir` instead of using `cd`. Non-zero exits are reported as `[exit code: N]`. Current harness environment facts are exposed through managed `$DSH_*` variables; inspect them when needed. Commands may run under a file sandbox; a blocked file operation is reported as `[sandbox: file access denied under mode]` — a policy denial, not a bug in the command; do not retry another way. Long output is truncated to its tail; the full output is saved to a file whose path is reported when available. Set `run_in_background: true` for long-running commands: the call returns a task id immediately; read its output with `task_output` and stop it with `task_kill`.","parameters":{"type":"object","properties":{"command":{"type":"string","description":"The bash command to execute."},"description":{"type":"string","description":"Clear, concise description of what this command does in active voice, 5-10 words (shown in the UI). Examples: \"ls\" → \"List files in current directory\"; \"git status\" → \"Show working tree status\"; \"npm install\" → \"Install package dependencies\"."},"timeoutMs":{"type":"number","description":"Timeout in milliseconds. The executor applies its configured default and cap, and kills the command on expiry."},"workdir":{"type":"string","description":"Working directory for this command. Defaults to the session workspace; a relative path is resolved against it."},"run_in_background":{"type":"boolean","description":"Run in the background and return a task id immediately (collect with task_output, stop with task_kill). No timeout applies."}},"required":["command","description"]}},{"name":"cordis_inspect","description":"Inspect the live Cordis runtime in the current DSH process. Read-only. Sections: `services` (every provided ctx service and the plugin fiber that owns it), `plugins` (all live plugin fibers with their lifecycle states), `tools` (the model-facing tools currently registered, i.e. what you can call), `temporary` (only temporary Plugins created by cordis_mount: id, name, state, provided services, awaited services, and lifetime), `api` (method signatures AND argument/return type shapes for every LIVE service — read this before writing plugin code that calls a service), `events` (every harness event with its dispatch mode and exact signature — pick listener targets here). Temporary Plugins exist only in memory, remain active across later turns, and disappear after cordis_unmount, toolset unload, or DSH restart; they are not restored automatically. The `temporary` section is a subset of `plugins`. Omit `what` to get all six sections. With `what:\"api\"` or `what:\"events\"`, pass an exact `name` to narrow to one service/event and include its original source JSDoc.","parameters":{"type":"object","properties":{"what":{"type":"string","description":"Limit the report to one section. Omit for all sections.","enum":["services","plugins","tools","temporary","api","events"]},"name":{"type":"string","description":"Exact service key or event name whose original JSDoc to include; valid only with what:\"api\" or what:\"events\"."}}}},{"name":"cordis_mount","description":"Mount a temporary Cordis Plugin in the current DSH process. This creates an in-memory runtime Plugin, not an installed or configured Plugin. It remains active across later turns until cordis_unmount, toolset unload, or DSH restart. It does not create files, install a package, change cordis.yml or personal/project config, survive restart, or automatically become permanent. To keep it, ask the Agent to implement a normal local, project, or repository Plugin through the regular development workflow. It may affect other sessions in the same process; the sandbox is not a security boundary, and injected services reach the real runtime. `code` runs now as the body of an async JavaScript function in an isolated sandbox and MUST `return` a plugin. Two forms: FUNCTION form `return (ctx) => { … }` — declares no inject, so it can register tools, listen to events, and provide services, but reaching ANY service (e.g. ctx.bash) throws; use it only when you need no services. OBJECT form `return { name?, inject: ['bash', 'llm', …], apply(ctx) { … } }` — declares dependencies, and cordis activates the plugin only after the services exist; PREFER this form. You may reach ONLY the services you list in inject: an undeclared service throws even if it exists, because an undeclared dependency would not be cleaned up if its provider is unmounted. BEFORE calling a service from your code, read cordis_inspect what:\"api\" — it lists method signatures AND the type shapes of their arguments/returns (do not guess a field's type; e.g. a bash run's stdout is an object, not a string). Inside `apply`, use the standard cordis API: `ctx.on(event, listener)` to observe events (see cordis_inspect what:\"events\"), or call `harness.registerTool(ctx, harness.defineTool({ name, description, parameters: { text: { type: 'string', required: true } }, output: { schema: { type: 'string' }, render(_args, value) { return [{ type: 'text', text: value }] } }, async execute(args) { return args.text } }))` to give yourself a new tool — it becomes callable on your NEXT step. Tool parameters: each key IS a property — { type: 'string'|'number'|'integer'|'boolean'|'null'|'object'|'array'|'json', required?: true, description?, enum?, const?, items?, properties? }; every direct DSL object declares additionalProperties: true|false, and oneOf: [schema, schema, ...] replaces type for an exact-one union. A raw JSON-Schema { type: 'object', properties, required?: […] } wrapper is also accepted with open-by-default objects. A tool's `execute` MUST return the lossless JSON value declared by `output.schema`; `output.render(args, value)` separately returns Native/model content blocks. Temporary Plugins can COMPOSE: one Plugin may `ctx.provide('name', value)` a service and another may declare `inject: ['name']` to consume it — the consumer stays pending until the provider exists and returns to pending when the provider is unmounted. Everything registered inside `apply` is cleaned up automatically by cordis_unmount. Sandbox globals: `console` (tagged `[cordis:]`, writes through to the harness terminal), `harness.defineTool`, `harness.registerTool`, `btoa`, `atob`, `TextEncoder`, `TextDecoder`. Node APIs are DISABLED — do filesystem/network/timer work through the cordis services, never Node built-ins: `require`, `setTimeout`/`setInterval`, and `fetch` throw redirect errors; `process` and `Buffer` are undefined. Instead use inject: ['fs'] + ctx.fs for files, inject: ['web'] + ctx.web for HTTP, inject: ['bash'] + ctx.bash for processes, and inject: ['timer'] + ctx.setTimeout/ctx.setInterval for timing (fiber effects, auto-cleaned when unmounted) — cordis_inspect what:\"api\" shows what THIS runtime provides. Write PLAIN JavaScript, not TypeScript (no `as`, no type annotations). Cautions: (1) waterfall events (e.g. tools/pre-execute) hand the listener a trailing `next` callback which MUST be called — returning without `next()` SHORT-CIRCUITS the call; prefer plain notification events unless you intend to intercept. (2) Never await something that only resolves after the current turn (your code runs INSIDE a tool call of that turn — it would deadlock). (3) Your `ctx` is a restricted façade: you can register tools, observe events, provide/consume services, and use timers, but framework internals (ctx.root, ctx.fiber, ctx.extend, ctx.plugin, …) are withheld. It is not a security boundary though — the services you inject (e.g. ctx.bash) reach the real runtime.","parameters":{"type":"object","properties":{"code":{"type":"string","description":"JavaScript body returning a temporary Plugin; evaluated now and saved nowhere."}},"required":["code"]}},{"name":"cordis_unmount","description":"Unmount a current-process temporary Plugin created by cordis_mount. Waits for its tools, listeners, services, timers, and other owned effects to clean up completely. Only dyn-N temporary ids are accepted; this cannot remove Loader, configured, or installed Plugins.","parameters":{"type":"object","properties":{"id":{"type":"string","description":"The temporary Plugin id returned by cordis_mount (for example \"dyn-1\"); valid only in this process and invalid after unmount or restart."}},"required":["id"]}},{"name":"edit","description":"Edit an existing UTF-8 text file by replacing literal text.","parameters":{"type":"object","properties":{"file_path":{"type":"string","description":"Path to edit, resolved by the filesystem backend."},"old_string":{"type":"string","description":"Literal text to replace. Must match exactly."},"new_string":{"type":"string","description":"Literal replacement text. Use an empty string to delete the match."},"replace_all":{"type":"boolean","description":"Replace all matches. Defaults to false; when false, old_string must appear exactly once."}},"required":["file_path","old_string","new_string"]}},{"name":"ralph","description":"Run a foreground fresh-agent Ralph loop toward one immutable objective. Use only when the direct human explicitly asks for Ralph or fresh-agent iteration. Each round opens a new child with no parent conversation or prior child session; the shared workspace is long-term memory, and only a bounded structured report crosses rounds. The call returns when a worker reports completion or a concrete blocker, or at the round limit. Ordinary long-running same-session work belongs to goal tools.","parameters":{"type":"object","properties":{"objective":{"type":"string","description":"The immutable completion objective for every fresh Ralph round."},"maxRounds":{"type":"number","description":"Optional positive safe-integer round cap, bounded by the deployment ceiling."}},"required":["objective"]}},{"name":"read","description":"Read a UTF-8 text file and return line-numbered content.","parameters":{"type":"object","properties":{"file_path":{"type":"string","description":"Path to read, resolved by the filesystem backend."},"offset":{"type":"number","description":"1-based first line to return. Defaults to 1."},"limit":{"type":"number","description":"Maximum number of lines to return. Defaults to 2000."}},"required":["file_path"]}},{"name":"run_code","description":"Execute a TypeScript program against the available tools. Write the BODY of an async function (erasable syntax only; top-level `await` and `return` work) and call tools as `await tools.name(args)` per the declarations in the system prompt. Only what you print or return comes back — curate it.","parameters":{"type":"object","properties":{"code":{"type":"string","description":"The program: the body of an async TypeScript function."},"description":{"type":"string","description":"Clear, concise description of what this program does in active voice, 5-10 words (shown in the UI). Examples: \"Count TODO markers across packages\"; \"Read failing test and its fixture\"; \"Rename config key in every cordis.yml\"."}},"required":["code","description"]}},{"name":"send_message","description":"Send a message to a background subagent by its subagent id, continuing the same conversation. It becomes the subagent's next turn: if it is still working, the message waits until its current turn finishes, so it cannot redirect work already underway. This call returns no answer from the subagent — only confirmation that the message was delivered — so use it to give it more work. A failure means the message was NOT delivered.","parameters":{"type":"object","properties":{"subagent_id":{"type":"string","description":"The subagent id returned when the background subagent was started."},"message":{"type":"string","description":"The message to deliver to the subagent."}},"required":["subagent_id","message"]}},{"name":"skill","description":"Load the full instructions for an available skill. Call this with the exact skill name from the session skill catalog before acting on a task that names or clearly matches that skill.","parameters":{"type":"object","properties":{"name":{"type":"string","description":"The exact skill name from the available skills list."}},"required":["name"]}},{"name":"subagent","description":"Delegate a self-contained task to a subagent (a separate agent that works in its own context) and return its final result. Use this to offload focused, independent work — research, a scoped implementation, an analysis — so it does not consume this conversation's context. The subagent runs to completion and you receive only its final answer, not its intermediate steps. Give it a complete, standalone prompt: it does not see this conversation. Set `run_in_background: true` to start a background subagent that keeps its conversation: you receive only its subagent id, never its result, and it works on its own. Use this for work whose result you do not need returned by this call; `send_message` sends it more work.","parameters":{"type":"object","properties":{"description":{"type":"string","description":"A short (3-5 word) description of the delegated task, for display."},"prompt":{"type":"string","description":"The complete, self-contained task for the subagent. It does not share this conversation's context, so include everything it needs."},"run_in_background":{"type":"boolean","description":"Run as a background subagent that keeps its conversation and return only its subagent id. This call never returns its result; send it more work with send_message."}},"required":["description","prompt"]}},{"name":"subagent_fork","description":"Delegate a task to a subagent that inherits this conversation: a child agent seeded with all completed turns so far (it does not see the current in-flight turn), returning only its final result. Use this when the subtask builds on this conversation's context — a follow-up analysis, a review, a continuation — without consuming this conversation's context for the work itself. You receive only its final answer, not its intermediate steps. Set `run_in_background: true` to start a background subagent that keeps its conversation: you receive only its subagent id, never its result, and it works on its own. Use this for work whose result you do not need returned by this call; `send_message` sends it more work.","parameters":{"type":"object","properties":{"description":{"type":"string","description":"A short (3-5 word) description of the delegated task, for display."},"prompt":{"type":"string","description":"The task for the subagent. It already sees this conversation's completed turns, so build on them freely and state only what is new."},"run_in_background":{"type":"boolean","description":"Run as a background subagent that keeps its conversation and return only its subagent id. This call never returns its result; send it more work with send_message."}},"required":["description","prompt"]}},{"name":"task_kill","description":"Request cancellation of a running background task by task id. Returns immediately; the task settles as killed once its work actually stops.","parameters":{"type":"object","properties":{"task_id":{"type":"string","description":"Task id returned by the tool that started the background work."},"reason":{"type":"string","description":"Optional short reason, recorded in the log and forwarded to the task."}},"required":["task_id"]}},{"name":"task_list","description":"List your background tasks (running and finished) with their ids, kinds, and statuses.","parameters":{"type":"object","properties":{}}},{"name":"task_output","description":"Read a background task. Stream tasks return only output since the previous read; final-output tasks return their result after settlement. Every response ends with `[status: ...]`. Reads are non-blocking unless `wait: true`, which waits up to the configured cap.","parameters":{"type":"object","properties":{"task_id":{"type":"string","description":"Task id returned by the tool that started the background work."},"wait":{"type":"boolean","description":"Block until the task reaches a terminal status or the timeout expires. A timed-out wait returns [status: running] and leaves the task alive."},"timeout_ms":{"type":"number","description":"Max wait in milliseconds (only meaningful with wait: true). Defaults to the configured wait timeout; capped by the configured maximum."}},"required":["task_id"]}},{"name":"todo_write","description":"Record and update a structured task list for the current work. Send the ENTIRE list every call — it REPLACES the previous list (there are no partial updates, no per-item edits). Use it to plan multi-step work and show progress: add one todo per concrete step before you start. Mark every todo being actively worked on `in_progress` — several at once when work genuinely runs in parallel (e.g. concurrent subagents or background commands), one for sequential work; while work remains, at least one task should be `in_progress`. Mark a todo `completed` the moment it is done (do not batch completions), and allow no `in_progress` item only once all work is complete. Skip the list for trivial single-step tasks. Statuses: `pending` (not started), `in_progress` (being worked on now), `completed` (finished).","parameters":{"type":"object","properties":{"todos":{"type":"array","description":"The COMPLETE task list, replacing any previous list.","items":{"type":"object","additionalProperties":false,"properties":{"content":{"type":"string","description":"What the task is — a short imperative line."},"status":{"type":"string","description":"pending (not started) | in_progress (now) | completed (done).","enum":["pending","in_progress","completed"]}},"required":["content","status"]}}},"required":["todos"]}},{"name":"workflow","description":"Run a JavaScript workflow script that orchestrates subagents at scale. Use this for work that fans out across many independent pieces — an audit over many files, a migration, multi-angle research, adversarial verification of findings — where you write the orchestration as a script instead of delegating turn by turn.\n\nThe workflow's identity rides the `meta` parameter as JSON: required `name` (short kebab-case) and `description` strings, optional `whenToUse` string and `phases` array (`{title, detail?, provider?, model?}`). The `script` parameter is the plain JavaScript body ONLY (NOT TypeScript, and NO `export const meta` statement — meta is a parameter, not code), running with top-level await; end with `return ` — the value must be JSON-serializable and is this tool's result.\n\nScript-body hooks:\n- `agent(prompt, opts?): Promise` — run one subagent to completion. Without `opts.schema` it resolves to the child's final text; with `opts.schema` (an object-rooted JSON Schema using ONLY type/properties/required/additionalProperties/items/enum/const/oneOf — no pattern/format/numeric bounds) it resolves to the validated object. Resolves `null` when the child fails (filter with `.filter(Boolean)`). Other opts: `label` (display), `phase` (progress group), and independent `provider`/`model` LLM target overrides (either may be provided alone). Anything else (`effort`/`isolation`/`agentType`) is rejected loudly.\n- `pipeline(items, ...stages): Promise` — run each item through the stages independently with NO barrier between stages (prefer this for multi-stage work). Each stage receives `(prev, item, index)`. An ordinary stage throw drops that ITEM to `null` and skips its remaining stages.\n- `parallel(thunks): Promise` — run zero-argument functions concurrently and await ALL of them (a barrier; use only when a stage genuinely needs every prior result together). A throwing thunk resolves to `null`.\n- `phase(title)` — start a progress phase; `log(message)` — narrate progress; `args` — the tool call's `args` input, verbatim.\n\nMisused hooks (bad arguments, unknown options, unsupported schemas, tripped caps) throw errors that ALWAYS kill the script — they never dissolve into a per-item `null`.\n\nConstraints: concurrency and total-agent caps apply; no filesystem, network, timers, or Node.js APIs are provided — the agents do the work, the script only coordinates them. The run executes in the foreground: this call returns when the whole script finishes.","parameters":{"type":"object","properties":{"script":{"type":"string","description":"The plain-JS workflow script body (top-level await allowed; NO `export const meta` statement; end with `return `)."},"meta":{"type":"object","description":"The workflow identity block (plain JSON — never code).","additionalProperties":true,"properties":{"name":{"type":"string","description":"Short kebab-case workflow name."},"description":{"type":"string","description":"One-line description of what the workflow does."},"whenToUse":{"type":"string","description":"Optional guidance on when this workflow applies."},"phases":{"type":"array","description":"Optional phase declarations matched by phase() calls.","items":{"type":"object","additionalProperties":true,"properties":{"title":{"type":"string","description":"The phase title phase() calls match by exact string."},"detail":{"type":"string","description":"Optional one-line description of the phase."},"provider":{"type":"string","description":"Optional provider override this phase is expected to use."},"model":{"type":"string","description":"Optional model override this phase is expected to use."}},"required":["title"]}}},"required":["name","description"]},"args":{"type":"object","description":"Optional JSON input exposed to the script as the `args` global (wrap a bare list as a field, e.g. {\"files\": [...]}).","additionalProperties":true}},"required":["script","meta"]}},{"name":"write","description":"Create or fully replace a UTF-8 text file.","parameters":{"type":"object","properties":{"file_path":{"type":"string","description":"Path to write, resolved by the filesystem backend."},"content":{"type":"string","description":"Full UTF-8 text content to write."}},"required":["file_path","content"]}}]},"reason":"initial"}} +{"type":"request/header","seq":7,"time":1785498584067,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"You are an AI agent powered by the DeepSeek Harness SDK.\n\nYou are headless-agent, a coding assistant powered by the deepseek-v4-flash model. Your working directory is {{cwd}}.\n\nVerify your work by running the code or tests. Keep answers brief and factual.\n\n\nUse the read tool — not shell commands like cat — to inspect text files. Results include line numbers. Use offset and limit to continue reading large files.\n\nUse the write tool to create files or completely replace file contents. Existing files are overwritten, so read an existing file first (the default fs-policy requires it) and prefer edit for targeted changes.\n\nUse the edit tool for targeted changes to existing UTF-8 text files. It replaces literal old_string with new_string; by default old_string must appear exactly once. If old_string appears multiple times, provide a more specific old_string or set replace_all to true. Read the file first (the default fs-policy requires it), unless you just created or edited it in this session.\n\nCheck the [exit code: N] marker on every bash result; investigate failures before moving on.\n\nTrack every background task id you start. You are notified in-session when a task finishes — do not busy-poll or sleep on one; keep working on independent steps and do not duplicate a running task's work. Before giving a final answer, collect every still-relevant task with task_output (set wait: true only when you are genuinely blocked on it), and task_kill tasks that stopped mattering.\n\nUse the workflow tool ONLY when the user explicitly asks for a workflow or for large multi-agent orchestration: you write a JavaScript script (the tool description documents the exact format) that fans work out across many subagents with phases and structured results. For one or two delegations, prefer plain subagent calls.\n\nUse the ralph tool ONLY when the direct human explicitly asks for a Ralph loop or fresh-agent iterative execution. Each Ralph round starts a fresh child with no conversation seed and uses the shared workspace as durable memory. Completion and blockers are worker reports, not independent evaluation. Use same-session goal tools for ordinary long-running objectives, and plain subagents or workflows for bounded delegation and fan-out.\n\n## Writing code for run_code\n\nPass `run_code` the body of an async TypeScript function (erasable syntax only — no `enum` or namespaces; type annotations are advisory, the code runs type-stripped). Inside the program:\n\n- Call tools as `await tools.name(args)` — quoted access for exotic names: `tools[\"my-tool\"](args)`. Every call resolves to the tool's typed canonical JSON value. Tool arguments must be lossless JSON.\n- A FAILED tool call rejects with `ToolCallError`, whose `toolName` identifies the failed tool and whose `message` is human-readable — `try/catch` it to handle and continue.\n- Independent read-only calls MAY overlap under `Promise.all` (safe calls run concurrently; mutating calls run alone, in submission order). Sequence dependent work with `await`.\n- Emit results with `return` and/or `console.log(...)`. ONLY what you print or return comes back to you — intermediate tool results never enter the conversation, so extract just what you need.\n\nThe available tools:\n\n```ts\ntype JsonValue = null | boolean | number | string | JsonValue[] | { [key: string]: JsonValue }\n\ninterface ToolArgsMap {\n /** Execute a bash command (`bash -c`) and return its stdout/stderr. Each call runs in a fresh shell: no state (cwd, variables, functions) persists between calls — pass `workdir` instead of using `cd`. Non-zero exits are reported as `[exit code: N]`. Current harness environment facts are exposed through managed `$DSH_*` variables; inspect them when needed. Commands may run under a file sandbox; a blocked file operation is reported as `[sandbox: file access denied under mode]` — a policy denial, not a bug in the command; do not retry another way. Long output is truncated to its tail; the full output is saved to a file whose path is reported when available. Set `run_in_background: true` for long-running commands: the call returns a task id immediately; read its output with `task_output` and stop it with `task_kill`. */\n bash: {\n /** The bash command to execute. */\n command: string;\n /** Clear, concise description of what this command does in active voice, 5-10 words (shown in the UI). Examples: \"ls\" → \"List files in current directory\"; \"git status\" → \"Show working tree status\"; \"npm install\" → \"Install package dependencies\". */\n description: string;\n /** Timeout in milliseconds. The executor applies its configured default and cap, and kills the command on expiry. */\n timeoutMs?: number;\n /** Working directory for this command. Defaults to the session workspace; a relative path is resolved against it. */\n workdir?: string;\n /** Run in the background and return a task id immediately (collect with task_output, stop with task_kill). No timeout applies. */\n run_in_background?: boolean;\n } & Record;\n /** Inspect the live Cordis runtime in the current DSH process. Read-only. Sections: `services` (every provided ctx service and the plugin fiber that owns it), `plugins` (all live plugin fibers with their lifecycle states), `tools` (the model-facing tools currently registered, i.e. what you can call), `temporary` (only temporary Plugins created by cordis_mount: id, name, state, provided services, awaited services, and lifetime), `api` (method signatures AND argument/return type shapes for every LIVE service — read this before writing plugin code that calls a service), `events` (every harness event with its dispatch mode and exact signature — pick listener targets here). Temporary Plugins exist only in memory, remain active across later turns, and disappear after cordis_unmount, toolset unload, or DSH restart; they are not restored automatically. The `temporary` section is a subset of `plugins`. Omit `what` to get all six sections. With `what:\"api\"` or `what:\"events\"`, pass an exact `name` to narrow to one service/event and include its original source JSDoc. */\n cordis_inspect: {\n /** Limit the report to one section. Omit for all sections. */\n what?: \"services\" | \"plugins\" | \"tools\" | \"temporary\" | \"api\" | \"events\";\n /** Exact service key or event name whose original JSDoc to include; valid only with what:\"api\" or what:\"events\". */\n name?: string;\n } & Record;\n /** Mount a temporary Cordis Plugin in the current DSH process. This creates an in-memory runtime Plugin, not an installed or configured Plugin. It remains active across later turns until cordis_unmount, toolset unload, or DSH restart. It does not create files, install a package, change cordis.yml or personal/project config, survive restart, or automatically become permanent. To keep it, ask the Agent to implement an SDK Plugin or installable profile bundle through the regular development workflow. It may affect other sessions in the same process; the sandbox is not a security boundary, and injected services reach the real runtime. `code` runs now as the body of an async JavaScript function in an isolated sandbox and MUST `return` a plugin. Two forms: FUNCTION form `return (ctx) => { … }` — declares no inject, so it can register tools, listen to events, and provide services, but reaching ANY service (e.g. ctx.bash) throws; use it only when you need no services. OBJECT form `return { name?, inject: ['bash', 'llm', …], apply(ctx) { … } }` — declares dependencies, and cordis activates the plugin only after the services exist; PREFER this form. You may reach ONLY the services you list in inject: an undeclared service throws even if it exists, because an undeclared dependency would not be cleaned up if its provider is unmounted. BEFORE calling a service from your code, read cordis_inspect what:\"api\" — it lists method signatures AND the type shapes of their arguments/returns (do not guess a field's type; e.g. a bash run's stdout is an object, not a string). Inside `apply`, use the standard cordis API: `ctx.on(event, listener)` to observe events (see cordis_inspect what:\"events\"), or call `harness.registerTool(ctx, harness.defineTool({ name, description, parameters: { text: { type: 'string', required: true } }, output: { schema: { type: 'string' }, render(_args, value) { return [{ type: 'text', text: value }] } }, async execute(args) { return args.text } }))` to give yourself a new tool — it becomes callable on your NEXT step. Tool parameters: each key IS a property — { type: 'string'|'number'|'integer'|'boolean'|'null'|'object'|'array'|'json', required?: true, description?, enum?, const?, items?, properties? }; every direct DSL object declares additionalProperties: true|false, and oneOf: [schema, schema, ...] replaces type for an exact-one union. A raw JSON-Schema { type: 'object', properties, required?: […] } wrapper is also accepted with open-by-default objects. A tool's `execute` MUST return the lossless JSON value declared by `output.schema`; `output.render(args, value)` separately returns Native/model content blocks. Temporary Plugins can COMPOSE: one Plugin may `ctx.provide('name', value)` a service and another may declare `inject: ['name']` to consume it — the consumer stays pending until the provider exists and returns to pending when the provider is unmounted. Everything registered inside `apply` is cleaned up automatically by cordis_unmount. Sandbox globals: `console` (tagged `[cordis:]`, writes through to the harness terminal), `harness.defineTool`, `harness.registerTool`, `btoa`, `atob`, `TextEncoder`, `TextDecoder`. Node APIs are DISABLED — do filesystem/network/timer work through the cordis services, never Node built-ins: `require`, `setTimeout`/`setInterval`, and `fetch` throw redirect errors; `process` and `Buffer` are undefined. Instead use inject: ['fs'] + ctx.fs for files, inject: ['web'] + ctx.web for HTTP, inject: ['bash'] + ctx.bash for processes, and inject: ['timer'] + ctx.setTimeout/ctx.setInterval for timing (fiber effects, auto-cleaned when unmounted) — cordis_inspect what:\"api\" shows what THIS runtime provides. Write PLAIN JavaScript, not TypeScript (no `as`, no type annotations). Cautions: (1) waterfall events (e.g. tools/pre-execute) hand the listener a trailing `next` callback which MUST be called — returning without `next()` SHORT-CIRCUITS the call; prefer plain notification events unless you intend to intercept. (2) Never await something that only resolves after the current turn (your code runs INSIDE a tool call of that turn — it would deadlock). (3) Your `ctx` is a restricted façade: you can register tools, observe events, provide/consume services, and use timers, but framework internals (ctx.root, ctx.fiber, ctx.extend, ctx.plugin, …) are withheld. It is not a security boundary though — the services you inject (e.g. ctx.bash) reach the real runtime. */\n cordis_mount: {\n /** JavaScript body returning a temporary Plugin; evaluated now and saved nowhere. */\n code: string;\n } & Record;\n /** Unmount a current-process temporary Plugin created by cordis_mount. Waits for its tools, listeners, services, timers, and other owned effects to clean up completely. Only dyn-N temporary ids are accepted; this cannot remove Loader, configured, or installed Plugins. */\n cordis_unmount: {\n /** The temporary Plugin id returned by cordis_mount (for example \"dyn-1\"); valid only in this process and invalid after unmount or restart. */\n id: string;\n } & Record;\n /** Edit an existing UTF-8 text file by replacing literal text. */\n edit: {\n /** Path to edit, resolved by the filesystem backend. */\n file_path: string;\n /** Literal text to replace. Must match exactly. */\n old_string: string;\n /** Literal replacement text. Use an empty string to delete the match. */\n new_string: string;\n /** Replace all matches. Defaults to false; when false, old_string must appear exactly once. */\n replace_all?: boolean;\n } & Record;\n /** Request cancellation of a background agent's current turn by its agent id. The target may be your direct child or a deeper agent created under you. Only the current turn stops: messages already queued for the agent stay parked until a later send_message, agents it started keep running, and the agent itself stays available for follow-ups. This call returns as soon as the stop request is accepted, so the target may keep running briefly; interrupting an agent that already finished is an accepted no-op. */\n interrupt_agent: {\n /** The agent id of the running agent to interrupt. */\n agent_id: string;\n } & Record;\n /** Run a foreground fresh-agent Ralph loop toward one immutable objective. Use only when the direct human explicitly asks for Ralph or fresh-agent iteration. Each round opens a new child with no parent conversation or prior child session; the shared workspace is long-term memory, and only a bounded structured report crosses rounds. The call returns when a worker reports completion or a concrete blocker, or at the round limit. Ordinary long-running same-session work belongs to goal tools. */\n ralph: {\n /** The immutable completion objective for every fresh Ralph round. */\n objective: string;\n /** Optional positive safe-integer round cap, bounded by the deployment ceiling. */\n maxRounds?: number;\n } & Record;\n /** Read a UTF-8 text file and return line-numbered content. */\n read: {\n /** Path to read, resolved by the filesystem backend. */\n file_path: string;\n /** 1-based first line to return. Defaults to 1. */\n offset?: number;\n /** Maximum number of lines to return. Defaults to 2000. */\n limit?: number;\n } & Record;\n /** Send a message to a background subagent by its subagent id, continuing the same conversation. It becomes the subagent's next turn: if it is still working, the message waits until its current turn finishes, so it cannot redirect work already underway. This call returns no answer from the subagent — only confirmation that the message was delivered — so use it to give it more work. A failure means the message was NOT delivered. */\n send_message: {\n /** The subagent id returned when the background subagent was started. */\n subagent_id: string;\n /** The message to deliver to the subagent. */\n message: string;\n } & Record;\n /** Load the full instructions for an available skill. Call this with the exact skill name from the session skill catalog before acting on a task that names or clearly matches that skill. */\n skill: {\n /** The exact skill name from the available skills list. */\n name: string;\n } & Record;\n /** Delegate a self-contained task to a subagent (a separate agent that works in its own context) and return its final result. Use this to offload focused, independent work — research, a scoped implementation, an analysis — so it does not consume this conversation's context. The subagent runs to completion and you receive only its final answer, not its intermediate steps. Give it a complete, standalone prompt: it does not see this conversation. Set `run_in_background: true` to start a background subagent that keeps its conversation: you receive only its subagent id, never its result, and it works on its own. Use this for work whose result you do not need returned by this call; `send_message` sends it more work. */\n subagent: {\n /** A short (3-5 word) description of the delegated task, for display. */\n description: string;\n /** The complete, self-contained task for the subagent. It does not share this conversation's context, so include everything it needs. */\n prompt: string;\n /** Run as a background subagent that keeps its conversation and return only its subagent id. This call never returns its result; send it more work with send_message. */\n run_in_background?: boolean;\n } & Record;\n /** Delegate a task to a subagent that inherits this conversation: a child agent seeded with all completed turns so far (it does not see the current in-flight turn), returning only its final result. Use this when the subtask builds on this conversation's context — a follow-up analysis, a review, a continuation — without consuming this conversation's context for the work itself. You receive only its final answer, not its intermediate steps. Set `run_in_background: true` to start a background subagent that keeps its conversation: you receive only its subagent id, never its result, and it works on its own. Use this for work whose result you do not need returned by this call; `send_message` sends it more work. */\n subagent_fork: {\n /** A short (3-5 word) description of the delegated task, for display. */\n description: string;\n /** The task for the subagent. It already sees this conversation's completed turns, so build on them freely and state only what is new. */\n prompt: string;\n /** Run as a background subagent that keeps its conversation and return only its subagent id. This call never returns its result; send it more work with send_message. */\n run_in_background?: boolean;\n } & Record;\n /** Request cancellation of a running background task by task id. Returns immediately; the task settles as killed once its work actually stops. */\n task_kill: {\n /** Task id returned by the tool that started the background work. */\n task_id: string;\n /** Optional short reason, recorded in the log and forwarded to the task. */\n reason?: string;\n } & Record;\n /** List your background tasks (running and finished) with their ids, kinds, and statuses. */\n task_list: Record;\n /** Read a background task. Stream tasks return only output since the previous read; final-output tasks return their result after settlement. Every response ends with `[status: ...]`. Reads are non-blocking unless `wait: true`, which waits up to the configured cap. */\n task_output: {\n /** Task id returned by the tool that started the background work. */\n task_id: string;\n /** Block until the task reaches a terminal status or the timeout expires. A timed-out wait returns [status: running] and leaves the task alive. */\n wait?: boolean;\n /** Max wait in milliseconds (only meaningful with wait: true). Defaults to the configured wait timeout; capped by the configured maximum. */\n timeout_ms?: number;\n } & Record;\n /** Record and update a structured task list for the current work. Send the ENTIRE list every call — it REPLACES the previous list (there are no partial updates, no per-item edits). Use it to plan multi-step work and show progress: add one todo per concrete step before you start. Mark every todo being actively worked on `in_progress` — several at once when work genuinely runs in parallel (e.g. concurrent subagents or background commands), one for sequential work; while work remains, at least one task should be `in_progress`. Mark a todo `completed` the moment it is done (do not batch completions), and allow no `in_progress` item only once all work is complete. Skip the list for trivial single-step tasks. Statuses: `pending` (not started), `in_progress` (being worked on now), `completed` (finished). */\n todo_write: {\n /** The COMPLETE task list, replacing any previous list. */\n todos: ({\n /** What the task is — a short imperative line. */\n content: string;\n /** pending (not started) | in_progress (now) | completed (done). */\n status: \"pending\" | \"in_progress\" | \"completed\";\n })[];\n } & Record;\n /** Run a JavaScript workflow script that orchestrates subagents at scale. Use this for work that fans out across many independent pieces — an audit over many files, a migration, multi-angle research, adversarial verification of findings — where you write the orchestration as a script instead of delegating turn by turn. The workflow's identity rides the `meta` parameter as JSON: required `name` (short kebab-case) and `description` strings, optional `whenToUse` string and `phases` array (`{title, detail?, provider?, model?}`). The `script` parameter is the plain JavaScript body ONLY (NOT TypeScript, and NO `export const meta` statement — meta is a parameter, not code), running with top-level await; end with `return ` — the value must be JSON-serializable and is this tool's result. Script-body hooks: - `agent(prompt, opts?): Promise` — run one subagent to completion. Without `opts.schema` it resolves to the child's final text; with `opts.schema` (an object-rooted JSON Schema using ONLY type/properties/required/additionalProperties/items/enum/const/oneOf — no pattern/format/numeric bounds) it resolves to the validated object. Resolves `null` when the child fails (filter with `.filter(Boolean)`). Other opts: `label` (display), `phase` (progress group), and independent `provider`/`model` LLM target overrides (either may be provided alone). Anything else (`effort`/`isolation`/`agentType`) is rejected loudly. - `pipeline(items, ...stages): Promise` — run each item through the stages independently with NO barrier between stages (prefer this for multi-stage work). Each stage receives `(prev, item, index)`. An ordinary stage throw drops that ITEM to `null` and skips its remaining stages. - `parallel(thunks): Promise` — run zero-argument functions concurrently and await ALL of them (a barrier; use only when a stage genuinely needs every prior result together). A throwing thunk resolves to `null`. - `phase(title)` — start a progress phase; `log(message)` — narrate progress; `args` — the tool call's `args` input, verbatim. Misused hooks (bad arguments, unknown options, unsupported schemas, tripped caps) throw errors that ALWAYS kill the script — they never dissolve into a per-item `null`. Constraints: concurrency and total-agent caps apply; no filesystem, network, timers, or Node.js APIs are provided — the agents do the work, the script only coordinates them. The run executes in the foreground: this call returns when the whole script finishes. */\n workflow: {\n /** The plain-JS workflow script body (top-level await allowed; NO `export const meta` statement; end with `return `). */\n script: string;\n /** The workflow identity block (plain JSON — never code). */\n meta: {\n /** Short kebab-case workflow name. */\n name: string;\n /** One-line description of what the workflow does. */\n description: string;\n /** Optional guidance on when this workflow applies. */\n whenToUse?: string;\n /** Optional phase declarations matched by phase() calls. */\n phases?: ({\n /** The phase title phase() calls match by exact string. */\n title: string;\n /** Optional one-line description of the phase. */\n detail?: string;\n /** Optional provider override this phase is expected to use. */\n provider?: string;\n /** Optional model override this phase is expected to use. */\n model?: string;\n } & Record)[];\n } & Record;\n /** Optional JSON input exposed to the script as the `args` global (wrap a bare list as a field, e.g. {\"files\": [...]}). */\n args?: Record;\n } & Record;\n /** Create or fully replace a UTF-8 text file. */\n write: {\n /** Path to write, resolved by the filesystem backend. */\n file_path: string;\n /** Full UTF-8 text content to write. */\n content: string;\n } & Record;\n}\n\ninterface ToolOutputMap {\n bash: {\n kind: \"background\";\n taskId: string;\n } | {\n kind: \"foreground\";\n exitCode: number | null;\n signal: string | null;\n timedOut: boolean;\n aborted: boolean;\n timeoutMs: number;\n stdout: {\n text: string;\n truncated: boolean;\n spillPath?: string;\n };\n stderr: {\n text: string;\n truncated: boolean;\n spillPath?: string;\n };\n sandbox?: {\n mode: string;\n denied: boolean;\n enforcement?: string;\n runnerFailed?: boolean;\n };\n };\n cordis_inspect: string;\n cordis_mount: {\n id: string;\n pluginName: string;\n state: \"pending\" | \"loading\" | \"active\" | \"failed\" | \"disposed\" | \"unloading\";\n provides: string[];\n waitingFor: string[];\n };\n cordis_unmount: {\n id: string;\n pluginName: string;\n };\n edit: {\n path: string;\n before: string;\n after: string;\n };\n interrupt_agent: {\n accepted: boolean;\n };\n ralph: {\n runId: string;\n agentsStarted: number;\n result: JsonValue;\n };\n read: {\n path: string;\n offset: number;\n lines: {\n number: number;\n text: string;\n }[];\n totalLines: number;\n };\n send_message: {\n messageId: string;\n };\n skill: {\n name: string;\n provider: string;\n resourceBase?: {\n kind: \"directory\";\n path: string;\n } | {\n kind: \"url\";\n url: string;\n } | {\n kind: \"opaque\";\n description: string;\n };\n content: string;\n };\n subagent: {\n kind: \"background\";\n taskId: string;\n } | {\n kind: \"continuable\";\n subagentId: string;\n } | {\n kind: \"foreground\";\n runId: string;\n output: JsonValue[];\n };\n subagent_fork: {\n kind: \"background\";\n taskId: string;\n } | {\n kind: \"continuable\";\n subagentId: string;\n } | {\n kind: \"foreground\";\n runId: string;\n output: JsonValue[];\n };\n task_kill: {\n outcome: \"cancellation-requested\" | \"already-finished\";\n task: {\n id: string;\n kind: string;\n label: string;\n status: \"running\" | \"stopping\" | \"completed\" | \"killed\" | \"failed\";\n detail?: string;\n startedAt: number;\n finishedAt?: number;\n };\n };\n task_list: ({\n id: string;\n kind: string;\n label: string;\n status: \"running\" | \"stopping\" | \"completed\" | \"killed\" | \"failed\";\n detail?: string;\n startedAt: number;\n finishedAt?: number;\n })[];\n task_output: {\n text: string;\n task: {\n id: string;\n kind: string;\n label: string;\n status: \"running\" | \"stopping\" | \"completed\" | \"killed\" | \"failed\";\n detail?: string;\n startedAt: number;\n finishedAt?: number;\n };\n };\n todo_write: {\n todos: ({\n content: string;\n status: \"pending\" | \"in_progress\" | \"completed\";\n })[];\n counts: {\n pending: number;\n inProgress: number;\n completed: number;\n };\n };\n workflow: {\n runId: string;\n agentsStarted: number;\n result: JsonValue;\n };\n write: {\n path: string;\n operation: \"create\" | \"update\";\n before: string | null;\n after: string;\n };\n}\n\ntype ToolName = keyof ToolOutputMap\n\ndeclare class ToolCallError extends Error {\n readonly name: \"ToolCallError\";\n readonly toolName: ToolName;\n}\n\ndeclare const tools: {\n [K in ToolName]: (args: ToolArgsMap[K]) => Promise;\n}\n```","tools":[{"name":"bash","description":"Execute a bash command (`bash -c`) and return its stdout/stderr. Each call runs in a fresh shell: no state (cwd, variables, functions) persists between calls — pass `workdir` instead of using `cd`. Non-zero exits are reported as `[exit code: N]`. Current harness environment facts are exposed through managed `$DSH_*` variables; inspect them when needed. Commands may run under a file sandbox; a blocked file operation is reported as `[sandbox: file access denied under mode]` — a policy denial, not a bug in the command; do not retry another way. Long output is truncated to its tail; the full output is saved to a file whose path is reported when available. Set `run_in_background: true` for long-running commands: the call returns a task id immediately; read its output with `task_output` and stop it with `task_kill`.","parameters":{"type":"object","properties":{"command":{"type":"string","description":"The bash command to execute."},"description":{"type":"string","description":"Clear, concise description of what this command does in active voice, 5-10 words (shown in the UI). Examples: \"ls\" → \"List files in current directory\"; \"git status\" → \"Show working tree status\"; \"npm install\" → \"Install package dependencies\"."},"timeoutMs":{"type":"number","description":"Timeout in milliseconds. The executor applies its configured default and cap, and kills the command on expiry."},"workdir":{"type":"string","description":"Working directory for this command. Defaults to the session workspace; a relative path is resolved against it."},"run_in_background":{"type":"boolean","description":"Run in the background and return a task id immediately (collect with task_output, stop with task_kill). No timeout applies."}},"required":["command","description"]}},{"name":"cordis_inspect","description":"Inspect the live Cordis runtime in the current DSH process. Read-only. Sections: `services` (every provided ctx service and the plugin fiber that owns it), `plugins` (all live plugin fibers with their lifecycle states), `tools` (the model-facing tools currently registered, i.e. what you can call), `temporary` (only temporary Plugins created by cordis_mount: id, name, state, provided services, awaited services, and lifetime), `api` (method signatures AND argument/return type shapes for every LIVE service — read this before writing plugin code that calls a service), `events` (every harness event with its dispatch mode and exact signature — pick listener targets here). Temporary Plugins exist only in memory, remain active across later turns, and disappear after cordis_unmount, toolset unload, or DSH restart; they are not restored automatically. The `temporary` section is a subset of `plugins`. Omit `what` to get all six sections. With `what:\"api\"` or `what:\"events\"`, pass an exact `name` to narrow to one service/event and include its original source JSDoc.","parameters":{"type":"object","properties":{"what":{"type":"string","description":"Limit the report to one section. Omit for all sections.","enum":["services","plugins","tools","temporary","api","events"]},"name":{"type":"string","description":"Exact service key or event name whose original JSDoc to include; valid only with what:\"api\" or what:\"events\"."}}}},{"name":"cordis_mount","description":"Mount a temporary Cordis Plugin in the current DSH process. This creates an in-memory runtime Plugin, not an installed or configured Plugin. It remains active across later turns until cordis_unmount, toolset unload, or DSH restart. It does not create files, install a package, change cordis.yml or personal/project config, survive restart, or automatically become permanent. To keep it, ask the Agent to implement an SDK Plugin or installable profile bundle through the regular development workflow. It may affect other sessions in the same process; the sandbox is not a security boundary, and injected services reach the real runtime. `code` runs now as the body of an async JavaScript function in an isolated sandbox and MUST `return` a plugin. Two forms: FUNCTION form `return (ctx) => { … }` — declares no inject, so it can register tools, listen to events, and provide services, but reaching ANY service (e.g. ctx.bash) throws; use it only when you need no services. OBJECT form `return { name?, inject: ['bash', 'llm', …], apply(ctx) { … } }` — declares dependencies, and cordis activates the plugin only after the services exist; PREFER this form. You may reach ONLY the services you list in inject: an undeclared service throws even if it exists, because an undeclared dependency would not be cleaned up if its provider is unmounted. BEFORE calling a service from your code, read cordis_inspect what:\"api\" — it lists method signatures AND the type shapes of their arguments/returns (do not guess a field's type; e.g. a bash run's stdout is an object, not a string). Inside `apply`, use the standard cordis API: `ctx.on(event, listener)` to observe events (see cordis_inspect what:\"events\"), or call `harness.registerTool(ctx, harness.defineTool({ name, description, parameters: { text: { type: 'string', required: true } }, output: { schema: { type: 'string' }, render(_args, value) { return [{ type: 'text', text: value }] } }, async execute(args) { return args.text } }))` to give yourself a new tool — it becomes callable on your NEXT step. Tool parameters: each key IS a property — { type: 'string'|'number'|'integer'|'boolean'|'null'|'object'|'array'|'json', required?: true, description?, enum?, const?, items?, properties? }; every direct DSL object declares additionalProperties: true|false, and oneOf: [schema, schema, ...] replaces type for an exact-one union. A raw JSON-Schema { type: 'object', properties, required?: […] } wrapper is also accepted with open-by-default objects. A tool's `execute` MUST return the lossless JSON value declared by `output.schema`; `output.render(args, value)` separately returns Native/model content blocks. Temporary Plugins can COMPOSE: one Plugin may `ctx.provide('name', value)` a service and another may declare `inject: ['name']` to consume it — the consumer stays pending until the provider exists and returns to pending when the provider is unmounted. Everything registered inside `apply` is cleaned up automatically by cordis_unmount. Sandbox globals: `console` (tagged `[cordis:]`, writes through to the harness terminal), `harness.defineTool`, `harness.registerTool`, `btoa`, `atob`, `TextEncoder`, `TextDecoder`. Node APIs are DISABLED — do filesystem/network/timer work through the cordis services, never Node built-ins: `require`, `setTimeout`/`setInterval`, and `fetch` throw redirect errors; `process` and `Buffer` are undefined. Instead use inject: ['fs'] + ctx.fs for files, inject: ['web'] + ctx.web for HTTP, inject: ['bash'] + ctx.bash for processes, and inject: ['timer'] + ctx.setTimeout/ctx.setInterval for timing (fiber effects, auto-cleaned when unmounted) — cordis_inspect what:\"api\" shows what THIS runtime provides. Write PLAIN JavaScript, not TypeScript (no `as`, no type annotations). Cautions: (1) waterfall events (e.g. tools/pre-execute) hand the listener a trailing `next` callback which MUST be called — returning without `next()` SHORT-CIRCUITS the call; prefer plain notification events unless you intend to intercept. (2) Never await something that only resolves after the current turn (your code runs INSIDE a tool call of that turn — it would deadlock). (3) Your `ctx` is a restricted façade: you can register tools, observe events, provide/consume services, and use timers, but framework internals (ctx.root, ctx.fiber, ctx.extend, ctx.plugin, …) are withheld. It is not a security boundary though — the services you inject (e.g. ctx.bash) reach the real runtime.","parameters":{"type":"object","properties":{"code":{"type":"string","description":"JavaScript body returning a temporary Plugin; evaluated now and saved nowhere."}},"required":["code"]}},{"name":"cordis_unmount","description":"Unmount a current-process temporary Plugin created by cordis_mount. Waits for its tools, listeners, services, timers, and other owned effects to clean up completely. Only dyn-N temporary ids are accepted; this cannot remove Loader, configured, or installed Plugins.","parameters":{"type":"object","properties":{"id":{"type":"string","description":"The temporary Plugin id returned by cordis_mount (for example \"dyn-1\"); valid only in this process and invalid after unmount or restart."}},"required":["id"]}},{"name":"edit","description":"Edit an existing UTF-8 text file by replacing literal text.","parameters":{"type":"object","properties":{"file_path":{"type":"string","description":"Path to edit, resolved by the filesystem backend."},"old_string":{"type":"string","description":"Literal text to replace. Must match exactly."},"new_string":{"type":"string","description":"Literal replacement text. Use an empty string to delete the match."},"replace_all":{"type":"boolean","description":"Replace all matches. Defaults to false; when false, old_string must appear exactly once."}},"required":["file_path","old_string","new_string"]}},{"name":"interrupt_agent","description":"Request cancellation of a background agent's current turn by its agent id. The target may be your direct child or a deeper agent created under you. Only the current turn stops: messages already queued for the agent stay parked until a later send_message, agents it started keep running, and the agent itself stays available for follow-ups. This call returns as soon as the stop request is accepted, so the target may keep running briefly; interrupting an agent that already finished is an accepted no-op.","parameters":{"type":"object","properties":{"agent_id":{"type":"string","description":"The agent id of the running agent to interrupt."}},"required":["agent_id"]}},{"name":"ralph","description":"Run a foreground fresh-agent Ralph loop toward one immutable objective. Use only when the direct human explicitly asks for Ralph or fresh-agent iteration. Each round opens a new child with no parent conversation or prior child session; the shared workspace is long-term memory, and only a bounded structured report crosses rounds. The call returns when a worker reports completion or a concrete blocker, or at the round limit. Ordinary long-running same-session work belongs to goal tools.","parameters":{"type":"object","properties":{"objective":{"type":"string","description":"The immutable completion objective for every fresh Ralph round."},"maxRounds":{"type":"number","description":"Optional positive safe-integer round cap, bounded by the deployment ceiling."}},"required":["objective"]}},{"name":"read","description":"Read a UTF-8 text file and return line-numbered content.","parameters":{"type":"object","properties":{"file_path":{"type":"string","description":"Path to read, resolved by the filesystem backend."},"offset":{"type":"number","description":"1-based first line to return. Defaults to 1."},"limit":{"type":"number","description":"Maximum number of lines to return. Defaults to 2000."}},"required":["file_path"]}},{"name":"run_code","description":"Execute a TypeScript program against the available tools. Write the BODY of an async function (erasable syntax only; top-level `await` and `return` work) and call tools as `await tools.name(args)` per the declarations in the system prompt. Only what you print or return comes back — curate it.","parameters":{"type":"object","properties":{"code":{"type":"string","description":"The program: the body of an async TypeScript function."},"description":{"type":"string","description":"Clear, concise description of what this program does in active voice, 5-10 words (shown in the UI). Examples: \"Count TODO markers across packages\"; \"Read failing test and its fixture\"; \"Rename config key in every cordis.yml\"."}},"required":["code","description"]}},{"name":"send_message","description":"Send a message to a background subagent by its subagent id, continuing the same conversation. It becomes the subagent's next turn: if it is still working, the message waits until its current turn finishes, so it cannot redirect work already underway. This call returns no answer from the subagent — only confirmation that the message was delivered — so use it to give it more work. A failure means the message was NOT delivered.","parameters":{"type":"object","properties":{"subagent_id":{"type":"string","description":"The subagent id returned when the background subagent was started."},"message":{"type":"string","description":"The message to deliver to the subagent."}},"required":["subagent_id","message"]}},{"name":"skill","description":"Load the full instructions for an available skill. Call this with the exact skill name from the session skill catalog before acting on a task that names or clearly matches that skill.","parameters":{"type":"object","properties":{"name":{"type":"string","description":"The exact skill name from the available skills list."}},"required":["name"]}},{"name":"subagent","description":"Delegate a self-contained task to a subagent (a separate agent that works in its own context) and return its final result. Use this to offload focused, independent work — research, a scoped implementation, an analysis — so it does not consume this conversation's context. The subagent runs to completion and you receive only its final answer, not its intermediate steps. Give it a complete, standalone prompt: it does not see this conversation. Set `run_in_background: true` to start a background subagent that keeps its conversation: you receive only its subagent id, never its result, and it works on its own. Use this for work whose result you do not need returned by this call; `send_message` sends it more work.","parameters":{"type":"object","properties":{"description":{"type":"string","description":"A short (3-5 word) description of the delegated task, for display."},"prompt":{"type":"string","description":"The complete, self-contained task for the subagent. It does not share this conversation's context, so include everything it needs."},"run_in_background":{"type":"boolean","description":"Run as a background subagent that keeps its conversation and return only its subagent id. This call never returns its result; send it more work with send_message."}},"required":["description","prompt"]}},{"name":"subagent_fork","description":"Delegate a task to a subagent that inherits this conversation: a child agent seeded with all completed turns so far (it does not see the current in-flight turn), returning only its final result. Use this when the subtask builds on this conversation's context — a follow-up analysis, a review, a continuation — without consuming this conversation's context for the work itself. You receive only its final answer, not its intermediate steps. Set `run_in_background: true` to start a background subagent that keeps its conversation: you receive only its subagent id, never its result, and it works on its own. Use this for work whose result you do not need returned by this call; `send_message` sends it more work.","parameters":{"type":"object","properties":{"description":{"type":"string","description":"A short (3-5 word) description of the delegated task, for display."},"prompt":{"type":"string","description":"The task for the subagent. It already sees this conversation's completed turns, so build on them freely and state only what is new."},"run_in_background":{"type":"boolean","description":"Run as a background subagent that keeps its conversation and return only its subagent id. This call never returns its result; send it more work with send_message."}},"required":["description","prompt"]}},{"name":"task_kill","description":"Request cancellation of a running background task by task id. Returns immediately; the task settles as killed once its work actually stops.","parameters":{"type":"object","properties":{"task_id":{"type":"string","description":"Task id returned by the tool that started the background work."},"reason":{"type":"string","description":"Optional short reason, recorded in the log and forwarded to the task."}},"required":["task_id"]}},{"name":"task_list","description":"List your background tasks (running and finished) with their ids, kinds, and statuses.","parameters":{"type":"object","properties":{}}},{"name":"task_output","description":"Read a background task. Stream tasks return only output since the previous read; final-output tasks return their result after settlement. Every response ends with `[status: ...]`. Reads are non-blocking unless `wait: true`, which waits up to the configured cap.","parameters":{"type":"object","properties":{"task_id":{"type":"string","description":"Task id returned by the tool that started the background work."},"wait":{"type":"boolean","description":"Block until the task reaches a terminal status or the timeout expires. A timed-out wait returns [status: running] and leaves the task alive."},"timeout_ms":{"type":"number","description":"Max wait in milliseconds (only meaningful with wait: true). Defaults to the configured wait timeout; capped by the configured maximum."}},"required":["task_id"]}},{"name":"todo_write","description":"Record and update a structured task list for the current work. Send the ENTIRE list every call — it REPLACES the previous list (there are no partial updates, no per-item edits). Use it to plan multi-step work and show progress: add one todo per concrete step before you start. Mark every todo being actively worked on `in_progress` — several at once when work genuinely runs in parallel (e.g. concurrent subagents or background commands), one for sequential work; while work remains, at least one task should be `in_progress`. Mark a todo `completed` the moment it is done (do not batch completions), and allow no `in_progress` item only once all work is complete. Skip the list for trivial single-step tasks. Statuses: `pending` (not started), `in_progress` (being worked on now), `completed` (finished).","parameters":{"type":"object","properties":{"todos":{"type":"array","description":"The COMPLETE task list, replacing any previous list.","items":{"type":"object","additionalProperties":false,"properties":{"content":{"type":"string","description":"What the task is — a short imperative line."},"status":{"type":"string","description":"pending (not started) | in_progress (now) | completed (done).","enum":["pending","in_progress","completed"]}},"required":["content","status"]}}},"required":["todos"]}},{"name":"workflow","description":"Run a JavaScript workflow script that orchestrates subagents at scale. Use this for work that fans out across many independent pieces — an audit over many files, a migration, multi-angle research, adversarial verification of findings — where you write the orchestration as a script instead of delegating turn by turn.\n\nThe workflow's identity rides the `meta` parameter as JSON: required `name` (short kebab-case) and `description` strings, optional `whenToUse` string and `phases` array (`{title, detail?, provider?, model?}`). The `script` parameter is the plain JavaScript body ONLY (NOT TypeScript, and NO `export const meta` statement — meta is a parameter, not code), running with top-level await; end with `return ` — the value must be JSON-serializable and is this tool's result.\n\nScript-body hooks:\n- `agent(prompt, opts?): Promise` — run one subagent to completion. Without `opts.schema` it resolves to the child's final text; with `opts.schema` (an object-rooted JSON Schema using ONLY type/properties/required/additionalProperties/items/enum/const/oneOf — no pattern/format/numeric bounds) it resolves to the validated object. Resolves `null` when the child fails (filter with `.filter(Boolean)`). Other opts: `label` (display), `phase` (progress group), and independent `provider`/`model` LLM target overrides (either may be provided alone). Anything else (`effort`/`isolation`/`agentType`) is rejected loudly.\n- `pipeline(items, ...stages): Promise` — run each item through the stages independently with NO barrier between stages (prefer this for multi-stage work). Each stage receives `(prev, item, index)`. An ordinary stage throw drops that ITEM to `null` and skips its remaining stages.\n- `parallel(thunks): Promise` — run zero-argument functions concurrently and await ALL of them (a barrier; use only when a stage genuinely needs every prior result together). A throwing thunk resolves to `null`.\n- `phase(title)` — start a progress phase; `log(message)` — narrate progress; `args` — the tool call's `args` input, verbatim.\n\nMisused hooks (bad arguments, unknown options, unsupported schemas, tripped caps) throw errors that ALWAYS kill the script — they never dissolve into a per-item `null`.\n\nConstraints: concurrency and total-agent caps apply; no filesystem, network, timers, or Node.js APIs are provided — the agents do the work, the script only coordinates them. The run executes in the foreground: this call returns when the whole script finishes.","parameters":{"type":"object","properties":{"script":{"type":"string","description":"The plain-JS workflow script body (top-level await allowed; NO `export const meta` statement; end with `return `)."},"meta":{"type":"object","description":"The workflow identity block (plain JSON — never code).","additionalProperties":true,"properties":{"name":{"type":"string","description":"Short kebab-case workflow name."},"description":{"type":"string","description":"One-line description of what the workflow does."},"whenToUse":{"type":"string","description":"Optional guidance on when this workflow applies."},"phases":{"type":"array","description":"Optional phase declarations matched by phase() calls.","items":{"type":"object","additionalProperties":true,"properties":{"title":{"type":"string","description":"The phase title phase() calls match by exact string."},"detail":{"type":"string","description":"Optional one-line description of the phase."},"provider":{"type":"string","description":"Optional provider override this phase is expected to use."},"model":{"type":"string","description":"Optional model override this phase is expected to use."}},"required":["title"]}}},"required":["name","description"]},"args":{"type":"object","description":"Optional JSON input exposed to the script as the `args` global (wrap a bare list as a field, e.g. {\"files\": [...]}).","additionalProperties":true}},"required":["script","meta"]}},{"name":"write","description":"Create or fully replace a UTF-8 text file.","parameters":{"type":"object","properties":{"file_path":{"type":"string","description":"Path to write, resolved by the filesystem backend."},"content":{"type":"string","description":"Full UTF-8 text content to write."}},"required":["file_path","content"]}}]},"reason":"initial"}} {"type":"request/context","seq":8,"time":1785730501646,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} {"type":"assistant/chunk","seq":9,"time":1783957884701,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"text"}}} {"type":"assistant/chunk","seq":10,"time":1783957884701,"data":{"turn":1,"step":1,"chunk":{"type":"text-delta","index":0,"text":"WORKFLOW_CHILD_OK"}}} {"type":"assistant/chunk","seq":11,"time":1783957884701,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"WORKFLOW_CHILD_OK"}}}} {"type":"assistant/chunk","seq":12,"time":1785498584067,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}}} {"type":"assistant/chunk","seq":13,"time":1785730501646,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"stop"}}}} -{"type":"assistant/message","seq":14,"time":1785730501646,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"text","text":"WORKFLOW_CHILD_OK"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"2b31dae5-8939-44e1-bbcd-9f64aa637d76"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[9,10,11,12,13],"surfaceOp":"append"} +{"type":"assistant/message","seq":14,"time":1785730501646,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"text","text":"WORKFLOW_CHILD_OK"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"64227683-7d01-49bd-aa9c-16c64e5b6a66"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[9,10,11,12,13],"surfaceOp":"append"} {"type":"step/end","seq":15,"time":1785730501646,"data":{"turn":1,"step":1}} {"type":"turn/end","seq":16,"time":1785730501646,"data":{"turn":1,"reason":{"kind":"completed"}}} diff --git a/examples/headless-agent/tests/snapshots/advanced-toolchain/session.jsonl b/examples/headless-agent/tests/snapshots/advanced-toolchain/session.jsonl index 646110b6d9..f479122d66 100644 --- a/examples/headless-agent/tests/snapshots/advanced-toolchain/session.jsonl +++ b/examples/headless-agent/tests/snapshots/advanced-toolchain/session.jsonl @@ -1,20 +1,20 @@ {"type":"session","version":0,"id":"11111111-1111-4111-8111-111111111111","createdAt":1783950000000,"cwd":"{{cwd}}","delegationDepth":0} -{"type":"agent/inbox/spliced","seq":0,"time":1785498583746,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Run this advanced flow exactly once: try a no-op temporary Cordis Plugin named snapshot-marker; use run_code to inspect the live temporary Plugins through tools.cordis_inspect; delegate once to a direct spawn child; run one workflow that delegates to another spawn child; stop dyn-1; then reply with exactly ADVANCED_HEADLESS_OK."}],"source":{"kind":"user"},"role":"user","id":"d2f4f71c-78bc-4a22-908d-c08fbb3ab9ef"}]}} +{"type":"agent/inbox/spliced","seq":0,"time":1785498583746,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Run this advanced flow exactly once: try a no-op temporary Cordis Plugin named snapshot-marker; use run_code to inspect the live temporary Plugins through tools.cordis_inspect; delegate once to a direct spawn child; run one workflow that delegates to another spawn child; stop dyn-1; then reply with exactly ADVANCED_HEADLESS_OK."}],"source":{"kind":"user"},"role":"user","id":"286bdfe0-d81d-4511-a0b1-b706dc025a64"}]}} {"type":"turn/start","seq":1,"time":1785821454304,"data":{"turn":1}} {"type":"agent/inbox/spliced","seq":2,"time":1785821454304,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}} {"type":"step/start","seq":3,"time":1783957884486,"data":{"turn":1,"step":1}} -{"type":"user/message","seq":4,"time":1785498583779,"data":{"content":[{"type":"text","text":"Run this advanced flow exactly once: try a no-op temporary Cordis Plugin named snapshot-marker; use run_code to inspect the live temporary Plugins through tools.cordis_inspect; delegate once to a direct spawn child; run one workflow that delegates to another spawn child; stop dyn-1; then reply with exactly ADVANCED_HEADLESS_OK."}],"source":{"kind":"user"},"role":"user","id":"d2f4f71c-78bc-4a22-908d-c08fbb3ab9ef"},"surfaceOp":"append"} +{"type":"user/message","seq":4,"time":1785498583779,"data":{"content":[{"type":"text","text":"Run this advanced flow exactly once: try a no-op temporary Cordis Plugin named snapshot-marker; use run_code to inspect the live temporary Plugins through tools.cordis_inspect; delegate once to a direct spawn child; run one workflow that delegates to another spawn child; stop dyn-1; then reply with exactly ADVANCED_HEADLESS_OK."}],"source":{"kind":"user"},"role":"user","id":"286bdfe0-d81d-4511-a0b1-b706dc025a64"},"surfaceOp":"append"} {"type":"session/title","seq":5,"time":1785498583779,"data":{"title":"Run this advanced flow exactly","messageSeqs":[4],"source":{"kind":"fallback"}}} -{"type":"request/header","seq":6,"time":1785498583782,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"You are an AI agent powered by the DeepSeek Harness SDK.\n\nYou are headless-agent, a coding assistant powered by the deepseek-v4-flash model. Your working directory is {{cwd}}.\n\nVerify your work by running the code or tests. Keep answers brief and factual.\n\n\nUse the read tool — not shell commands like cat — to inspect text files. Results include line numbers. Use offset and limit to continue reading large files.\n\nUse the write tool to create files or completely replace file contents. Existing files are overwritten, so read an existing file first (the default fs-policy requires it) and prefer edit for targeted changes.\n\nUse the edit tool for targeted changes to existing UTF-8 text files. It replaces literal old_string with new_string; by default old_string must appear exactly once. If old_string appears multiple times, provide a more specific old_string or set replace_all to true. Read the file first (the default fs-policy requires it), unless you just created or edited it in this session.\n\nCheck the [exit code: N] marker on every bash result; investigate failures before moving on.\n\nTrack every background task id you start. You are notified in-session when a task finishes — do not busy-poll or sleep on one; keep working on independent steps and do not duplicate a running task's work. Before giving a final answer, collect every still-relevant task with task_output (set wait: true only when you are genuinely blocked on it), and task_kill tasks that stopped mattering.\n\nUse the workflow tool ONLY when the user explicitly asks for a workflow or for large multi-agent orchestration: you write a JavaScript script (the tool description documents the exact format) that fans work out across many subagents with phases and structured results. For one or two delegations, prefer plain subagent calls.\n\nUse the ralph tool ONLY when the direct human explicitly asks for a Ralph loop or fresh-agent iterative execution. Each Ralph round starts a fresh child with no conversation seed and uses the shared workspace as durable memory. Completion and blockers are worker reports, not independent evaluation. Use same-session goal tools for ordinary long-running objectives, and plain subagents or workflows for bounded delegation and fan-out.\n\n## Writing code for run_code\n\nPass `run_code` the body of an async TypeScript function (erasable syntax only — no `enum` or namespaces; type annotations are advisory, the code runs type-stripped). Inside the program:\n\n- Call tools as `await tools.name(args)` — quoted access for exotic names: `tools[\"my-tool\"](args)`. Every call resolves to the tool's typed canonical JSON value. Tool arguments must be lossless JSON.\n- A FAILED tool call rejects with `ToolCallError`, whose `toolName` identifies the failed tool and whose `message` is human-readable — `try/catch` it to handle and continue.\n- Independent read-only calls MAY overlap under `Promise.all` (safe calls run concurrently; mutating calls run alone, in submission order). Sequence dependent work with `await`.\n- Emit results with `return` and/or `console.log(...)`. ONLY what you print or return comes back to you — intermediate tool results never enter the conversation, so extract just what you need.\n\nThe available tools:\n\n```ts\ntype JsonValue = null | boolean | number | string | JsonValue[] | { [key: string]: JsonValue }\n\ninterface ToolArgsMap {\n /** Execute a bash command (`bash -c`) and return its stdout/stderr. Each call runs in a fresh shell: no state (cwd, variables, functions) persists between calls — pass `workdir` instead of using `cd`. Non-zero exits are reported as `[exit code: N]`. Current harness environment facts are exposed through managed `$DSH_*` variables; inspect them when needed. Commands may run under a file sandbox; a blocked file operation is reported as `[sandbox: file access denied under mode]` — a policy denial, not a bug in the command; do not retry another way. Long output is truncated to its tail; the full output is saved to a file whose path is reported when available. Set `run_in_background: true` for long-running commands: the call returns a task id immediately; read its output with `task_output` and stop it with `task_kill`. */\n bash: {\n /** The bash command to execute. */\n command: string;\n /** Clear, concise description of what this command does in active voice, 5-10 words (shown in the UI). Examples: \"ls\" → \"List files in current directory\"; \"git status\" → \"Show working tree status\"; \"npm install\" → \"Install package dependencies\". */\n description: string;\n /** Timeout in milliseconds. The executor applies its configured default and cap, and kills the command on expiry. */\n timeoutMs?: number;\n /** Working directory for this command. Defaults to the session workspace; a relative path is resolved against it. */\n workdir?: string;\n /** Run in the background and return a task id immediately (collect with task_output, stop with task_kill). No timeout applies. */\n run_in_background?: boolean;\n } & Record;\n /** Inspect the live Cordis runtime in the current DSH process. Read-only. Sections: `services` (every provided ctx service and the plugin fiber that owns it), `plugins` (all live plugin fibers with their lifecycle states), `tools` (the model-facing tools currently registered, i.e. what you can call), `temporary` (only temporary Plugins created by cordis_mount: id, name, state, provided services, awaited services, and lifetime), `api` (method signatures AND argument/return type shapes for every LIVE service — read this before writing plugin code that calls a service), `events` (every harness event with its dispatch mode and exact signature — pick listener targets here). Temporary Plugins exist only in memory, remain active across later turns, and disappear after cordis_unmount, toolset unload, or DSH restart; they are not restored automatically. The `temporary` section is a subset of `plugins`. Omit `what` to get all six sections. With `what:\"api\"` or `what:\"events\"`, pass an exact `name` to narrow to one service/event and include its original source JSDoc. */\n cordis_inspect: {\n /** Limit the report to one section. Omit for all sections. */\n what?: \"services\" | \"plugins\" | \"tools\" | \"temporary\" | \"api\" | \"events\";\n /** Exact service key or event name whose original JSDoc to include; valid only with what:\"api\" or what:\"events\". */\n name?: string;\n } & Record;\n /** Mount a temporary Cordis Plugin in the current DSH process. This creates an in-memory runtime Plugin, not an installed or configured Plugin. It remains active across later turns until cordis_unmount, toolset unload, or DSH restart. It does not create files, install a package, change cordis.yml or personal/project config, survive restart, or automatically become permanent. To keep it, ask the Agent to implement a normal local, project, or repository Plugin through the regular development workflow. It may affect other sessions in the same process; the sandbox is not a security boundary, and injected services reach the real runtime. `code` runs now as the body of an async JavaScript function in an isolated sandbox and MUST `return` a plugin. Two forms: FUNCTION form `return (ctx) => { … }` — declares no inject, so it can register tools, listen to events, and provide services, but reaching ANY service (e.g. ctx.bash) throws; use it only when you need no services. OBJECT form `return { name?, inject: ['bash', 'llm', …], apply(ctx) { … } }` — declares dependencies, and cordis activates the plugin only after the services exist; PREFER this form. You may reach ONLY the services you list in inject: an undeclared service throws even if it exists, because an undeclared dependency would not be cleaned up if its provider is unmounted. BEFORE calling a service from your code, read cordis_inspect what:\"api\" — it lists method signatures AND the type shapes of their arguments/returns (do not guess a field's type; e.g. a bash run's stdout is an object, not a string). Inside `apply`, use the standard cordis API: `ctx.on(event, listener)` to observe events (see cordis_inspect what:\"events\"), or call `harness.registerTool(ctx, harness.defineTool({ name, description, parameters: { text: { type: 'string', required: true } }, output: { schema: { type: 'string' }, render(_args, value) { return [{ type: 'text', text: value }] } }, async execute(args) { return args.text } }))` to give yourself a new tool — it becomes callable on your NEXT step. Tool parameters: each key IS a property — { type: 'string'|'number'|'integer'|'boolean'|'null'|'object'|'array'|'json', required?: true, description?, enum?, const?, items?, properties? }; every direct DSL object declares additionalProperties: true|false, and oneOf: [schema, schema, ...] replaces type for an exact-one union. A raw JSON-Schema { type: 'object', properties, required?: […] } wrapper is also accepted with open-by-default objects. A tool's `execute` MUST return the lossless JSON value declared by `output.schema`; `output.render(args, value)` separately returns Native/model content blocks. Temporary Plugins can COMPOSE: one Plugin may `ctx.provide('name', value)` a service and another may declare `inject: ['name']` to consume it — the consumer stays pending until the provider exists and returns to pending when the provider is unmounted. Everything registered inside `apply` is cleaned up automatically by cordis_unmount. Sandbox globals: `console` (tagged `[cordis:]`, writes through to the harness terminal), `harness.defineTool`, `harness.registerTool`, `btoa`, `atob`, `TextEncoder`, `TextDecoder`. Node APIs are DISABLED — do filesystem/network/timer work through the cordis services, never Node built-ins: `require`, `setTimeout`/`setInterval`, and `fetch` throw redirect errors; `process` and `Buffer` are undefined. Instead use inject: ['fs'] + ctx.fs for files, inject: ['web'] + ctx.web for HTTP, inject: ['bash'] + ctx.bash for processes, and inject: ['timer'] + ctx.setTimeout/ctx.setInterval for timing (fiber effects, auto-cleaned when unmounted) — cordis_inspect what:\"api\" shows what THIS runtime provides. Write PLAIN JavaScript, not TypeScript (no `as`, no type annotations). Cautions: (1) waterfall events (e.g. tools/pre-execute) hand the listener a trailing `next` callback which MUST be called — returning without `next()` SHORT-CIRCUITS the call; prefer plain notification events unless you intend to intercept. (2) Never await something that only resolves after the current turn (your code runs INSIDE a tool call of that turn — it would deadlock). (3) Your `ctx` is a restricted façade: you can register tools, observe events, provide/consume services, and use timers, but framework internals (ctx.root, ctx.fiber, ctx.extend, ctx.plugin, …) are withheld. It is not a security boundary though — the services you inject (e.g. ctx.bash) reach the real runtime. */\n cordis_mount: {\n /** JavaScript body returning a temporary Plugin; evaluated now and saved nowhere. */\n code: string;\n } & Record;\n /** Unmount a current-process temporary Plugin created by cordis_mount. Waits for its tools, listeners, services, timers, and other owned effects to clean up completely. Only dyn-N temporary ids are accepted; this cannot remove Loader, configured, or installed Plugins. */\n cordis_unmount: {\n /** The temporary Plugin id returned by cordis_mount (for example \"dyn-1\"); valid only in this process and invalid after unmount or restart. */\n id: string;\n } & Record;\n /** Edit an existing UTF-8 text file by replacing literal text. */\n edit: {\n /** Path to edit, resolved by the filesystem backend. */\n file_path: string;\n /** Literal text to replace. Must match exactly. */\n old_string: string;\n /** Literal replacement text. Use an empty string to delete the match. */\n new_string: string;\n /** Replace all matches. Defaults to false; when false, old_string must appear exactly once. */\n replace_all?: boolean;\n } & Record;\n /** Run a foreground fresh-agent Ralph loop toward one immutable objective. Use only when the direct human explicitly asks for Ralph or fresh-agent iteration. Each round opens a new child with no parent conversation or prior child session; the shared workspace is long-term memory, and only a bounded structured report crosses rounds. The call returns when a worker reports completion or a concrete blocker, or at the round limit. Ordinary long-running same-session work belongs to goal tools. */\n ralph: {\n /** The immutable completion objective for every fresh Ralph round. */\n objective: string;\n /** Optional positive safe-integer round cap, bounded by the deployment ceiling. */\n maxRounds?: number;\n } & Record;\n /** Read a UTF-8 text file and return line-numbered content. */\n read: {\n /** Path to read, resolved by the filesystem backend. */\n file_path: string;\n /** 1-based first line to return. Defaults to 1. */\n offset?: number;\n /** Maximum number of lines to return. Defaults to 2000. */\n limit?: number;\n } & Record;\n /** Send a message to a background subagent by its subagent id, continuing the same conversation. It becomes the subagent's next turn: if it is still working, the message waits until its current turn finishes, so it cannot redirect work already underway. This call returns no answer from the subagent — only confirmation that the message was delivered — so use it to give it more work. A failure means the message was NOT delivered. */\n send_message: {\n /** The subagent id returned when the background subagent was started. */\n subagent_id: string;\n /** The message to deliver to the subagent. */\n message: string;\n } & Record;\n /** Load the full instructions for an available skill. Call this with the exact skill name from the session skill catalog before acting on a task that names or clearly matches that skill. */\n skill: {\n /** The exact skill name from the available skills list. */\n name: string;\n } & Record;\n /** Delegate a self-contained task to a subagent (a separate agent that works in its own context) and return its final result. Use this to offload focused, independent work — research, a scoped implementation, an analysis — so it does not consume this conversation's context. The subagent runs to completion and you receive only its final answer, not its intermediate steps. Give it a complete, standalone prompt: it does not see this conversation. Set `run_in_background: true` to start a background subagent that keeps its conversation: you receive only its subagent id, never its result, and it works on its own. Use this for work whose result you do not need returned by this call; `send_message` sends it more work. */\n subagent: {\n /** A short (3-5 word) description of the delegated task, for display. */\n description: string;\n /** The complete, self-contained task for the subagent. It does not share this conversation's context, so include everything it needs. */\n prompt: string;\n /** Run as a background subagent that keeps its conversation and return only its subagent id. This call never returns its result; send it more work with send_message. */\n run_in_background?: boolean;\n } & Record;\n /** Delegate a task to a subagent that inherits this conversation: a child agent seeded with all completed turns so far (it does not see the current in-flight turn), returning only its final result. Use this when the subtask builds on this conversation's context — a follow-up analysis, a review, a continuation — without consuming this conversation's context for the work itself. You receive only its final answer, not its intermediate steps. Set `run_in_background: true` to start a background subagent that keeps its conversation: you receive only its subagent id, never its result, and it works on its own. Use this for work whose result you do not need returned by this call; `send_message` sends it more work. */\n subagent_fork: {\n /** A short (3-5 word) description of the delegated task, for display. */\n description: string;\n /** The task for the subagent. It already sees this conversation's completed turns, so build on them freely and state only what is new. */\n prompt: string;\n /** Run as a background subagent that keeps its conversation and return only its subagent id. This call never returns its result; send it more work with send_message. */\n run_in_background?: boolean;\n } & Record;\n /** Request cancellation of a running background task by task id. Returns immediately; the task settles as killed once its work actually stops. */\n task_kill: {\n /** Task id returned by the tool that started the background work. */\n task_id: string;\n /** Optional short reason, recorded in the log and forwarded to the task. */\n reason?: string;\n } & Record;\n /** List your background tasks (running and finished) with their ids, kinds, and statuses. */\n task_list: Record;\n /** Read a background task. Stream tasks return only output since the previous read; final-output tasks return their result after settlement. Every response ends with `[status: ...]`. Reads are non-blocking unless `wait: true`, which waits up to the configured cap. */\n task_output: {\n /** Task id returned by the tool that started the background work. */\n task_id: string;\n /** Block until the task reaches a terminal status or the timeout expires. A timed-out wait returns [status: running] and leaves the task alive. */\n wait?: boolean;\n /** Max wait in milliseconds (only meaningful with wait: true). Defaults to the configured wait timeout; capped by the configured maximum. */\n timeout_ms?: number;\n } & Record;\n /** Record and update a structured task list for the current work. Send the ENTIRE list every call — it REPLACES the previous list (there are no partial updates, no per-item edits). Use it to plan multi-step work and show progress: add one todo per concrete step before you start. Mark every todo being actively worked on `in_progress` — several at once when work genuinely runs in parallel (e.g. concurrent subagents or background commands), one for sequential work; while work remains, at least one task should be `in_progress`. Mark a todo `completed` the moment it is done (do not batch completions), and allow no `in_progress` item only once all work is complete. Skip the list for trivial single-step tasks. Statuses: `pending` (not started), `in_progress` (being worked on now), `completed` (finished). */\n todo_write: {\n /** The COMPLETE task list, replacing any previous list. */\n todos: ({\n /** What the task is — a short imperative line. */\n content: string;\n /** pending (not started) | in_progress (now) | completed (done). */\n status: \"pending\" | \"in_progress\" | \"completed\";\n })[];\n } & Record;\n /** Run a JavaScript workflow script that orchestrates subagents at scale. Use this for work that fans out across many independent pieces — an audit over many files, a migration, multi-angle research, adversarial verification of findings — where you write the orchestration as a script instead of delegating turn by turn. The workflow's identity rides the `meta` parameter as JSON: required `name` (short kebab-case) and `description` strings, optional `whenToUse` string and `phases` array (`{title, detail?, provider?, model?}`). The `script` parameter is the plain JavaScript body ONLY (NOT TypeScript, and NO `export const meta` statement — meta is a parameter, not code), running with top-level await; end with `return ` — the value must be JSON-serializable and is this tool's result. Script-body hooks: - `agent(prompt, opts?): Promise` — run one subagent to completion. Without `opts.schema` it resolves to the child's final text; with `opts.schema` (an object-rooted JSON Schema using ONLY type/properties/required/additionalProperties/items/enum/const/oneOf — no pattern/format/numeric bounds) it resolves to the validated object. Resolves `null` when the child fails (filter with `.filter(Boolean)`). Other opts: `label` (display), `phase` (progress group), and independent `provider`/`model` LLM target overrides (either may be provided alone). Anything else (`effort`/`isolation`/`agentType`) is rejected loudly. - `pipeline(items, ...stages): Promise` — run each item through the stages independently with NO barrier between stages (prefer this for multi-stage work). Each stage receives `(prev, item, index)`. An ordinary stage throw drops that ITEM to `null` and skips its remaining stages. - `parallel(thunks): Promise` — run zero-argument functions concurrently and await ALL of them (a barrier; use only when a stage genuinely needs every prior result together). A throwing thunk resolves to `null`. - `phase(title)` — start a progress phase; `log(message)` — narrate progress; `args` — the tool call's `args` input, verbatim. Misused hooks (bad arguments, unknown options, unsupported schemas, tripped caps) throw errors that ALWAYS kill the script — they never dissolve into a per-item `null`. Constraints: concurrency and total-agent caps apply; no filesystem, network, timers, or Node.js APIs are provided — the agents do the work, the script only coordinates them. The run executes in the foreground: this call returns when the whole script finishes. */\n workflow: {\n /** The plain-JS workflow script body (top-level await allowed; NO `export const meta` statement; end with `return `). */\n script: string;\n /** The workflow identity block (plain JSON — never code). */\n meta: {\n /** Short kebab-case workflow name. */\n name: string;\n /** One-line description of what the workflow does. */\n description: string;\n /** Optional guidance on when this workflow applies. */\n whenToUse?: string;\n /** Optional phase declarations matched by phase() calls. */\n phases?: ({\n /** The phase title phase() calls match by exact string. */\n title: string;\n /** Optional one-line description of the phase. */\n detail?: string;\n /** Optional provider override this phase is expected to use. */\n provider?: string;\n /** Optional model override this phase is expected to use. */\n model?: string;\n } & Record)[];\n } & Record;\n /** Optional JSON input exposed to the script as the `args` global (wrap a bare list as a field, e.g. {\"files\": [...]}). */\n args?: Record;\n } & Record;\n /** Create or fully replace a UTF-8 text file. */\n write: {\n /** Path to write, resolved by the filesystem backend. */\n file_path: string;\n /** Full UTF-8 text content to write. */\n content: string;\n } & Record;\n}\n\ninterface ToolOutputMap {\n bash: {\n kind: \"background\";\n taskId: string;\n } | {\n kind: \"foreground\";\n exitCode: number | null;\n signal: string | null;\n timedOut: boolean;\n aborted: boolean;\n timeoutMs: number;\n stdout: {\n text: string;\n truncated: boolean;\n spillPath?: string;\n };\n stderr: {\n text: string;\n truncated: boolean;\n spillPath?: string;\n };\n sandbox?: {\n mode: string;\n denied: boolean;\n enforcement?: string;\n runnerFailed?: boolean;\n };\n };\n cordis_inspect: string;\n cordis_mount: {\n id: string;\n pluginName: string;\n state: \"pending\" | \"loading\" | \"active\" | \"failed\" | \"disposed\" | \"unloading\";\n provides: string[];\n waitingFor: string[];\n };\n cordis_unmount: {\n id: string;\n pluginName: string;\n };\n edit: {\n path: string;\n before: string;\n after: string;\n };\n ralph: {\n runId: string;\n agentsStarted: number;\n result: JsonValue;\n };\n read: {\n path: string;\n offset: number;\n lines: {\n number: number;\n text: string;\n }[];\n totalLines: number;\n };\n send_message: {\n messageId: string;\n };\n skill: {\n name: string;\n provider: string;\n resourceBase?: {\n kind: \"directory\";\n path: string;\n } | {\n kind: \"url\";\n url: string;\n } | {\n kind: \"opaque\";\n description: string;\n };\n content: string;\n };\n subagent: {\n kind: \"background\";\n taskId: string;\n } | {\n kind: \"continuable\";\n subagentId: string;\n } | {\n kind: \"foreground\";\n runId: string;\n output: JsonValue[];\n };\n subagent_fork: {\n kind: \"background\";\n taskId: string;\n } | {\n kind: \"continuable\";\n subagentId: string;\n } | {\n kind: \"foreground\";\n runId: string;\n output: JsonValue[];\n };\n task_kill: {\n outcome: \"cancellation-requested\" | \"already-finished\";\n task: {\n id: string;\n kind: string;\n label: string;\n status: \"running\" | \"stopping\" | \"completed\" | \"killed\" | \"failed\";\n detail?: string;\n startedAt: number;\n finishedAt?: number;\n };\n };\n task_list: ({\n id: string;\n kind: string;\n label: string;\n status: \"running\" | \"stopping\" | \"completed\" | \"killed\" | \"failed\";\n detail?: string;\n startedAt: number;\n finishedAt?: number;\n })[];\n task_output: {\n text: string;\n task: {\n id: string;\n kind: string;\n label: string;\n status: \"running\" | \"stopping\" | \"completed\" | \"killed\" | \"failed\";\n detail?: string;\n startedAt: number;\n finishedAt?: number;\n };\n };\n todo_write: {\n todos: ({\n content: string;\n status: \"pending\" | \"in_progress\" | \"completed\";\n })[];\n counts: {\n pending: number;\n inProgress: number;\n completed: number;\n };\n };\n workflow: {\n runId: string;\n agentsStarted: number;\n result: JsonValue;\n };\n write: {\n path: string;\n operation: \"create\" | \"update\";\n before: string | null;\n after: string;\n };\n}\n\ntype ToolName = keyof ToolOutputMap\n\ndeclare class ToolCallError extends Error {\n readonly name: \"ToolCallError\";\n readonly toolName: ToolName;\n}\n\ndeclare const tools: {\n [K in ToolName]: (args: ToolArgsMap[K]) => Promise;\n}\n```","tools":[{"name":"bash","description":"Execute a bash command (`bash -c`) and return its stdout/stderr. Each call runs in a fresh shell: no state (cwd, variables, functions) persists between calls — pass `workdir` instead of using `cd`. Non-zero exits are reported as `[exit code: N]`. Current harness environment facts are exposed through managed `$DSH_*` variables; inspect them when needed. Commands may run under a file sandbox; a blocked file operation is reported as `[sandbox: file access denied under mode]` — a policy denial, not a bug in the command; do not retry another way. Long output is truncated to its tail; the full output is saved to a file whose path is reported when available. Set `run_in_background: true` for long-running commands: the call returns a task id immediately; read its output with `task_output` and stop it with `task_kill`.","parameters":{"type":"object","properties":{"command":{"type":"string","description":"The bash command to execute."},"description":{"type":"string","description":"Clear, concise description of what this command does in active voice, 5-10 words (shown in the UI). Examples: \"ls\" → \"List files in current directory\"; \"git status\" → \"Show working tree status\"; \"npm install\" → \"Install package dependencies\"."},"timeoutMs":{"type":"number","description":"Timeout in milliseconds. The executor applies its configured default and cap, and kills the command on expiry."},"workdir":{"type":"string","description":"Working directory for this command. Defaults to the session workspace; a relative path is resolved against it."},"run_in_background":{"type":"boolean","description":"Run in the background and return a task id immediately (collect with task_output, stop with task_kill). No timeout applies."}},"required":["command","description"]}},{"name":"cordis_inspect","description":"Inspect the live Cordis runtime in the current DSH process. Read-only. Sections: `services` (every provided ctx service and the plugin fiber that owns it), `plugins` (all live plugin fibers with their lifecycle states), `tools` (the model-facing tools currently registered, i.e. what you can call), `temporary` (only temporary Plugins created by cordis_mount: id, name, state, provided services, awaited services, and lifetime), `api` (method signatures AND argument/return type shapes for every LIVE service — read this before writing plugin code that calls a service), `events` (every harness event with its dispatch mode and exact signature — pick listener targets here). Temporary Plugins exist only in memory, remain active across later turns, and disappear after cordis_unmount, toolset unload, or DSH restart; they are not restored automatically. The `temporary` section is a subset of `plugins`. Omit `what` to get all six sections. With `what:\"api\"` or `what:\"events\"`, pass an exact `name` to narrow to one service/event and include its original source JSDoc.","parameters":{"type":"object","properties":{"what":{"type":"string","description":"Limit the report to one section. Omit for all sections.","enum":["services","plugins","tools","temporary","api","events"]},"name":{"type":"string","description":"Exact service key or event name whose original JSDoc to include; valid only with what:\"api\" or what:\"events\"."}}}},{"name":"cordis_mount","description":"Mount a temporary Cordis Plugin in the current DSH process. This creates an in-memory runtime Plugin, not an installed or configured Plugin. It remains active across later turns until cordis_unmount, toolset unload, or DSH restart. It does not create files, install a package, change cordis.yml or personal/project config, survive restart, or automatically become permanent. To keep it, ask the Agent to implement a normal local, project, or repository Plugin through the regular development workflow. It may affect other sessions in the same process; the sandbox is not a security boundary, and injected services reach the real runtime. `code` runs now as the body of an async JavaScript function in an isolated sandbox and MUST `return` a plugin. Two forms: FUNCTION form `return (ctx) => { … }` — declares no inject, so it can register tools, listen to events, and provide services, but reaching ANY service (e.g. ctx.bash) throws; use it only when you need no services. OBJECT form `return { name?, inject: ['bash', 'llm', …], apply(ctx) { … } }` — declares dependencies, and cordis activates the plugin only after the services exist; PREFER this form. You may reach ONLY the services you list in inject: an undeclared service throws even if it exists, because an undeclared dependency would not be cleaned up if its provider is unmounted. BEFORE calling a service from your code, read cordis_inspect what:\"api\" — it lists method signatures AND the type shapes of their arguments/returns (do not guess a field's type; e.g. a bash run's stdout is an object, not a string). Inside `apply`, use the standard cordis API: `ctx.on(event, listener)` to observe events (see cordis_inspect what:\"events\"), or call `harness.registerTool(ctx, harness.defineTool({ name, description, parameters: { text: { type: 'string', required: true } }, output: { schema: { type: 'string' }, render(_args, value) { return [{ type: 'text', text: value }] } }, async execute(args) { return args.text } }))` to give yourself a new tool — it becomes callable on your NEXT step. Tool parameters: each key IS a property — { type: 'string'|'number'|'integer'|'boolean'|'null'|'object'|'array'|'json', required?: true, description?, enum?, const?, items?, properties? }; every direct DSL object declares additionalProperties: true|false, and oneOf: [schema, schema, ...] replaces type for an exact-one union. A raw JSON-Schema { type: 'object', properties, required?: […] } wrapper is also accepted with open-by-default objects. A tool's `execute` MUST return the lossless JSON value declared by `output.schema`; `output.render(args, value)` separately returns Native/model content blocks. Temporary Plugins can COMPOSE: one Plugin may `ctx.provide('name', value)` a service and another may declare `inject: ['name']` to consume it — the consumer stays pending until the provider exists and returns to pending when the provider is unmounted. Everything registered inside `apply` is cleaned up automatically by cordis_unmount. Sandbox globals: `console` (tagged `[cordis:]`, writes through to the harness terminal), `harness.defineTool`, `harness.registerTool`, `btoa`, `atob`, `TextEncoder`, `TextDecoder`. Node APIs are DISABLED — do filesystem/network/timer work through the cordis services, never Node built-ins: `require`, `setTimeout`/`setInterval`, and `fetch` throw redirect errors; `process` and `Buffer` are undefined. Instead use inject: ['fs'] + ctx.fs for files, inject: ['web'] + ctx.web for HTTP, inject: ['bash'] + ctx.bash for processes, and inject: ['timer'] + ctx.setTimeout/ctx.setInterval for timing (fiber effects, auto-cleaned when unmounted) — cordis_inspect what:\"api\" shows what THIS runtime provides. Write PLAIN JavaScript, not TypeScript (no `as`, no type annotations). Cautions: (1) waterfall events (e.g. tools/pre-execute) hand the listener a trailing `next` callback which MUST be called — returning without `next()` SHORT-CIRCUITS the call; prefer plain notification events unless you intend to intercept. (2) Never await something that only resolves after the current turn (your code runs INSIDE a tool call of that turn — it would deadlock). (3) Your `ctx` is a restricted façade: you can register tools, observe events, provide/consume services, and use timers, but framework internals (ctx.root, ctx.fiber, ctx.extend, ctx.plugin, …) are withheld. It is not a security boundary though — the services you inject (e.g. ctx.bash) reach the real runtime.","parameters":{"type":"object","properties":{"code":{"type":"string","description":"JavaScript body returning a temporary Plugin; evaluated now and saved nowhere."}},"required":["code"]}},{"name":"cordis_unmount","description":"Unmount a current-process temporary Plugin created by cordis_mount. Waits for its tools, listeners, services, timers, and other owned effects to clean up completely. Only dyn-N temporary ids are accepted; this cannot remove Loader, configured, or installed Plugins.","parameters":{"type":"object","properties":{"id":{"type":"string","description":"The temporary Plugin id returned by cordis_mount (for example \"dyn-1\"); valid only in this process and invalid after unmount or restart."}},"required":["id"]}},{"name":"edit","description":"Edit an existing UTF-8 text file by replacing literal text.","parameters":{"type":"object","properties":{"file_path":{"type":"string","description":"Path to edit, resolved by the filesystem backend."},"old_string":{"type":"string","description":"Literal text to replace. Must match exactly."},"new_string":{"type":"string","description":"Literal replacement text. Use an empty string to delete the match."},"replace_all":{"type":"boolean","description":"Replace all matches. Defaults to false; when false, old_string must appear exactly once."}},"required":["file_path","old_string","new_string"]}},{"name":"ralph","description":"Run a foreground fresh-agent Ralph loop toward one immutable objective. Use only when the direct human explicitly asks for Ralph or fresh-agent iteration. Each round opens a new child with no parent conversation or prior child session; the shared workspace is long-term memory, and only a bounded structured report crosses rounds. The call returns when a worker reports completion or a concrete blocker, or at the round limit. Ordinary long-running same-session work belongs to goal tools.","parameters":{"type":"object","properties":{"objective":{"type":"string","description":"The immutable completion objective for every fresh Ralph round."},"maxRounds":{"type":"number","description":"Optional positive safe-integer round cap, bounded by the deployment ceiling."}},"required":["objective"]}},{"name":"read","description":"Read a UTF-8 text file and return line-numbered content.","parameters":{"type":"object","properties":{"file_path":{"type":"string","description":"Path to read, resolved by the filesystem backend."},"offset":{"type":"number","description":"1-based first line to return. Defaults to 1."},"limit":{"type":"number","description":"Maximum number of lines to return. Defaults to 2000."}},"required":["file_path"]}},{"name":"run_code","description":"Execute a TypeScript program against the available tools. Write the BODY of an async function (erasable syntax only; top-level `await` and `return` work) and call tools as `await tools.name(args)` per the declarations in the system prompt. Only what you print or return comes back — curate it.","parameters":{"type":"object","properties":{"code":{"type":"string","description":"The program: the body of an async TypeScript function."},"description":{"type":"string","description":"Clear, concise description of what this program does in active voice, 5-10 words (shown in the UI). Examples: \"Count TODO markers across packages\"; \"Read failing test and its fixture\"; \"Rename config key in every cordis.yml\"."}},"required":["code","description"]}},{"name":"send_message","description":"Send a message to a background subagent by its subagent id, continuing the same conversation. It becomes the subagent's next turn: if it is still working, the message waits until its current turn finishes, so it cannot redirect work already underway. This call returns no answer from the subagent — only confirmation that the message was delivered — so use it to give it more work. A failure means the message was NOT delivered.","parameters":{"type":"object","properties":{"subagent_id":{"type":"string","description":"The subagent id returned when the background subagent was started."},"message":{"type":"string","description":"The message to deliver to the subagent."}},"required":["subagent_id","message"]}},{"name":"skill","description":"Load the full instructions for an available skill. Call this with the exact skill name from the session skill catalog before acting on a task that names or clearly matches that skill.","parameters":{"type":"object","properties":{"name":{"type":"string","description":"The exact skill name from the available skills list."}},"required":["name"]}},{"name":"subagent","description":"Delegate a self-contained task to a subagent (a separate agent that works in its own context) and return its final result. Use this to offload focused, independent work — research, a scoped implementation, an analysis — so it does not consume this conversation's context. The subagent runs to completion and you receive only its final answer, not its intermediate steps. Give it a complete, standalone prompt: it does not see this conversation. Set `run_in_background: true` to start a background subagent that keeps its conversation: you receive only its subagent id, never its result, and it works on its own. Use this for work whose result you do not need returned by this call; `send_message` sends it more work.","parameters":{"type":"object","properties":{"description":{"type":"string","description":"A short (3-5 word) description of the delegated task, for display."},"prompt":{"type":"string","description":"The complete, self-contained task for the subagent. It does not share this conversation's context, so include everything it needs."},"run_in_background":{"type":"boolean","description":"Run as a background subagent that keeps its conversation and return only its subagent id. This call never returns its result; send it more work with send_message."}},"required":["description","prompt"]}},{"name":"subagent_fork","description":"Delegate a task to a subagent that inherits this conversation: a child agent seeded with all completed turns so far (it does not see the current in-flight turn), returning only its final result. Use this when the subtask builds on this conversation's context — a follow-up analysis, a review, a continuation — without consuming this conversation's context for the work itself. You receive only its final answer, not its intermediate steps. Set `run_in_background: true` to start a background subagent that keeps its conversation: you receive only its subagent id, never its result, and it works on its own. Use this for work whose result you do not need returned by this call; `send_message` sends it more work.","parameters":{"type":"object","properties":{"description":{"type":"string","description":"A short (3-5 word) description of the delegated task, for display."},"prompt":{"type":"string","description":"The task for the subagent. It already sees this conversation's completed turns, so build on them freely and state only what is new."},"run_in_background":{"type":"boolean","description":"Run as a background subagent that keeps its conversation and return only its subagent id. This call never returns its result; send it more work with send_message."}},"required":["description","prompt"]}},{"name":"task_kill","description":"Request cancellation of a running background task by task id. Returns immediately; the task settles as killed once its work actually stops.","parameters":{"type":"object","properties":{"task_id":{"type":"string","description":"Task id returned by the tool that started the background work."},"reason":{"type":"string","description":"Optional short reason, recorded in the log and forwarded to the task."}},"required":["task_id"]}},{"name":"task_list","description":"List your background tasks (running and finished) with their ids, kinds, and statuses.","parameters":{"type":"object","properties":{}}},{"name":"task_output","description":"Read a background task. Stream tasks return only output since the previous read; final-output tasks return their result after settlement. Every response ends with `[status: ...]`. Reads are non-blocking unless `wait: true`, which waits up to the configured cap.","parameters":{"type":"object","properties":{"task_id":{"type":"string","description":"Task id returned by the tool that started the background work."},"wait":{"type":"boolean","description":"Block until the task reaches a terminal status or the timeout expires. A timed-out wait returns [status: running] and leaves the task alive."},"timeout_ms":{"type":"number","description":"Max wait in milliseconds (only meaningful with wait: true). Defaults to the configured wait timeout; capped by the configured maximum."}},"required":["task_id"]}},{"name":"todo_write","description":"Record and update a structured task list for the current work. Send the ENTIRE list every call — it REPLACES the previous list (there are no partial updates, no per-item edits). Use it to plan multi-step work and show progress: add one todo per concrete step before you start. Mark every todo being actively worked on `in_progress` — several at once when work genuinely runs in parallel (e.g. concurrent subagents or background commands), one for sequential work; while work remains, at least one task should be `in_progress`. Mark a todo `completed` the moment it is done (do not batch completions), and allow no `in_progress` item only once all work is complete. Skip the list for trivial single-step tasks. Statuses: `pending` (not started), `in_progress` (being worked on now), `completed` (finished).","parameters":{"type":"object","properties":{"todos":{"type":"array","description":"The COMPLETE task list, replacing any previous list.","items":{"type":"object","additionalProperties":false,"properties":{"content":{"type":"string","description":"What the task is — a short imperative line."},"status":{"type":"string","description":"pending (not started) | in_progress (now) | completed (done).","enum":["pending","in_progress","completed"]}},"required":["content","status"]}}},"required":["todos"]}},{"name":"workflow","description":"Run a JavaScript workflow script that orchestrates subagents at scale. Use this for work that fans out across many independent pieces — an audit over many files, a migration, multi-angle research, adversarial verification of findings — where you write the orchestration as a script instead of delegating turn by turn.\n\nThe workflow's identity rides the `meta` parameter as JSON: required `name` (short kebab-case) and `description` strings, optional `whenToUse` string and `phases` array (`{title, detail?, provider?, model?}`). The `script` parameter is the plain JavaScript body ONLY (NOT TypeScript, and NO `export const meta` statement — meta is a parameter, not code), running with top-level await; end with `return ` — the value must be JSON-serializable and is this tool's result.\n\nScript-body hooks:\n- `agent(prompt, opts?): Promise` — run one subagent to completion. Without `opts.schema` it resolves to the child's final text; with `opts.schema` (an object-rooted JSON Schema using ONLY type/properties/required/additionalProperties/items/enum/const/oneOf — no pattern/format/numeric bounds) it resolves to the validated object. Resolves `null` when the child fails (filter with `.filter(Boolean)`). Other opts: `label` (display), `phase` (progress group), and independent `provider`/`model` LLM target overrides (either may be provided alone). Anything else (`effort`/`isolation`/`agentType`) is rejected loudly.\n- `pipeline(items, ...stages): Promise` — run each item through the stages independently with NO barrier between stages (prefer this for multi-stage work). Each stage receives `(prev, item, index)`. An ordinary stage throw drops that ITEM to `null` and skips its remaining stages.\n- `parallel(thunks): Promise` — run zero-argument functions concurrently and await ALL of them (a barrier; use only when a stage genuinely needs every prior result together). A throwing thunk resolves to `null`.\n- `phase(title)` — start a progress phase; `log(message)` — narrate progress; `args` — the tool call's `args` input, verbatim.\n\nMisused hooks (bad arguments, unknown options, unsupported schemas, tripped caps) throw errors that ALWAYS kill the script — they never dissolve into a per-item `null`.\n\nConstraints: concurrency and total-agent caps apply; no filesystem, network, timers, or Node.js APIs are provided — the agents do the work, the script only coordinates them. The run executes in the foreground: this call returns when the whole script finishes.","parameters":{"type":"object","properties":{"script":{"type":"string","description":"The plain-JS workflow script body (top-level await allowed; NO `export const meta` statement; end with `return `)."},"meta":{"type":"object","description":"The workflow identity block (plain JSON — never code).","additionalProperties":true,"properties":{"name":{"type":"string","description":"Short kebab-case workflow name."},"description":{"type":"string","description":"One-line description of what the workflow does."},"whenToUse":{"type":"string","description":"Optional guidance on when this workflow applies."},"phases":{"type":"array","description":"Optional phase declarations matched by phase() calls.","items":{"type":"object","additionalProperties":true,"properties":{"title":{"type":"string","description":"The phase title phase() calls match by exact string."},"detail":{"type":"string","description":"Optional one-line description of the phase."},"provider":{"type":"string","description":"Optional provider override this phase is expected to use."},"model":{"type":"string","description":"Optional model override this phase is expected to use."}},"required":["title"]}}},"required":["name","description"]},"args":{"type":"object","description":"Optional JSON input exposed to the script as the `args` global (wrap a bare list as a field, e.g. {\"files\": [...]}).","additionalProperties":true}},"required":["script","meta"]}},{"name":"write","description":"Create or fully replace a UTF-8 text file.","parameters":{"type":"object","properties":{"file_path":{"type":"string","description":"Path to write, resolved by the filesystem backend."},"content":{"type":"string","description":"Full UTF-8 text content to write."}},"required":["file_path","content"]}}]},"reason":"initial"}} +{"type":"request/header","seq":6,"time":1785498583782,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"You are an AI agent powered by the DeepSeek Harness SDK.\n\nYou are headless-agent, a coding assistant powered by the deepseek-v4-flash model. Your working directory is {{cwd}}.\n\nVerify your work by running the code or tests. Keep answers brief and factual.\n\n\nUse the read tool — not shell commands like cat — to inspect text files. Results include line numbers. Use offset and limit to continue reading large files.\n\nUse the write tool to create files or completely replace file contents. Existing files are overwritten, so read an existing file first (the default fs-policy requires it) and prefer edit for targeted changes.\n\nUse the edit tool for targeted changes to existing UTF-8 text files. It replaces literal old_string with new_string; by default old_string must appear exactly once. If old_string appears multiple times, provide a more specific old_string or set replace_all to true. Read the file first (the default fs-policy requires it), unless you just created or edited it in this session.\n\nCheck the [exit code: N] marker on every bash result; investigate failures before moving on.\n\nTrack every background task id you start. You are notified in-session when a task finishes — do not busy-poll or sleep on one; keep working on independent steps and do not duplicate a running task's work. Before giving a final answer, collect every still-relevant task with task_output (set wait: true only when you are genuinely blocked on it), and task_kill tasks that stopped mattering.\n\nUse the workflow tool ONLY when the user explicitly asks for a workflow or for large multi-agent orchestration: you write a JavaScript script (the tool description documents the exact format) that fans work out across many subagents with phases and structured results. For one or two delegations, prefer plain subagent calls.\n\nUse the ralph tool ONLY when the direct human explicitly asks for a Ralph loop or fresh-agent iterative execution. Each Ralph round starts a fresh child with no conversation seed and uses the shared workspace as durable memory. Completion and blockers are worker reports, not independent evaluation. Use same-session goal tools for ordinary long-running objectives, and plain subagents or workflows for bounded delegation and fan-out.\n\n## Writing code for run_code\n\nPass `run_code` the body of an async TypeScript function (erasable syntax only — no `enum` or namespaces; type annotations are advisory, the code runs type-stripped). Inside the program:\n\n- Call tools as `await tools.name(args)` — quoted access for exotic names: `tools[\"my-tool\"](args)`. Every call resolves to the tool's typed canonical JSON value. Tool arguments must be lossless JSON.\n- A FAILED tool call rejects with `ToolCallError`, whose `toolName` identifies the failed tool and whose `message` is human-readable — `try/catch` it to handle and continue.\n- Independent read-only calls MAY overlap under `Promise.all` (safe calls run concurrently; mutating calls run alone, in submission order). Sequence dependent work with `await`.\n- Emit results with `return` and/or `console.log(...)`. ONLY what you print or return comes back to you — intermediate tool results never enter the conversation, so extract just what you need.\n\nThe available tools:\n\n```ts\ntype JsonValue = null | boolean | number | string | JsonValue[] | { [key: string]: JsonValue }\n\ninterface ToolArgsMap {\n /** Execute a bash command (`bash -c`) and return its stdout/stderr. Each call runs in a fresh shell: no state (cwd, variables, functions) persists between calls — pass `workdir` instead of using `cd`. Non-zero exits are reported as `[exit code: N]`. Current harness environment facts are exposed through managed `$DSH_*` variables; inspect them when needed. Commands may run under a file sandbox; a blocked file operation is reported as `[sandbox: file access denied under mode]` — a policy denial, not a bug in the command; do not retry another way. Long output is truncated to its tail; the full output is saved to a file whose path is reported when available. Set `run_in_background: true` for long-running commands: the call returns a task id immediately; read its output with `task_output` and stop it with `task_kill`. */\n bash: {\n /** The bash command to execute. */\n command: string;\n /** Clear, concise description of what this command does in active voice, 5-10 words (shown in the UI). Examples: \"ls\" → \"List files in current directory\"; \"git status\" → \"Show working tree status\"; \"npm install\" → \"Install package dependencies\". */\n description: string;\n /** Timeout in milliseconds. The executor applies its configured default and cap, and kills the command on expiry. */\n timeoutMs?: number;\n /** Working directory for this command. Defaults to the session workspace; a relative path is resolved against it. */\n workdir?: string;\n /** Run in the background and return a task id immediately (collect with task_output, stop with task_kill). No timeout applies. */\n run_in_background?: boolean;\n } & Record;\n /** Inspect the live Cordis runtime in the current DSH process. Read-only. Sections: `services` (every provided ctx service and the plugin fiber that owns it), `plugins` (all live plugin fibers with their lifecycle states), `tools` (the model-facing tools currently registered, i.e. what you can call), `temporary` (only temporary Plugins created by cordis_mount: id, name, state, provided services, awaited services, and lifetime), `api` (method signatures AND argument/return type shapes for every LIVE service — read this before writing plugin code that calls a service), `events` (every harness event with its dispatch mode and exact signature — pick listener targets here). Temporary Plugins exist only in memory, remain active across later turns, and disappear after cordis_unmount, toolset unload, or DSH restart; they are not restored automatically. The `temporary` section is a subset of `plugins`. Omit `what` to get all six sections. With `what:\"api\"` or `what:\"events\"`, pass an exact `name` to narrow to one service/event and include its original source JSDoc. */\n cordis_inspect: {\n /** Limit the report to one section. Omit for all sections. */\n what?: \"services\" | \"plugins\" | \"tools\" | \"temporary\" | \"api\" | \"events\";\n /** Exact service key or event name whose original JSDoc to include; valid only with what:\"api\" or what:\"events\". */\n name?: string;\n } & Record;\n /** Mount a temporary Cordis Plugin in the current DSH process. This creates an in-memory runtime Plugin, not an installed or configured Plugin. It remains active across later turns until cordis_unmount, toolset unload, or DSH restart. It does not create files, install a package, change cordis.yml or personal/project config, survive restart, or automatically become permanent. To keep it, ask the Agent to implement an SDK Plugin or installable profile bundle through the regular development workflow. It may affect other sessions in the same process; the sandbox is not a security boundary, and injected services reach the real runtime. `code` runs now as the body of an async JavaScript function in an isolated sandbox and MUST `return` a plugin. Two forms: FUNCTION form `return (ctx) => { … }` — declares no inject, so it can register tools, listen to events, and provide services, but reaching ANY service (e.g. ctx.bash) throws; use it only when you need no services. OBJECT form `return { name?, inject: ['bash', 'llm', …], apply(ctx) { … } }` — declares dependencies, and cordis activates the plugin only after the services exist; PREFER this form. You may reach ONLY the services you list in inject: an undeclared service throws even if it exists, because an undeclared dependency would not be cleaned up if its provider is unmounted. BEFORE calling a service from your code, read cordis_inspect what:\"api\" — it lists method signatures AND the type shapes of their arguments/returns (do not guess a field's type; e.g. a bash run's stdout is an object, not a string). Inside `apply`, use the standard cordis API: `ctx.on(event, listener)` to observe events (see cordis_inspect what:\"events\"), or call `harness.registerTool(ctx, harness.defineTool({ name, description, parameters: { text: { type: 'string', required: true } }, output: { schema: { type: 'string' }, render(_args, value) { return [{ type: 'text', text: value }] } }, async execute(args) { return args.text } }))` to give yourself a new tool — it becomes callable on your NEXT step. Tool parameters: each key IS a property — { type: 'string'|'number'|'integer'|'boolean'|'null'|'object'|'array'|'json', required?: true, description?, enum?, const?, items?, properties? }; every direct DSL object declares additionalProperties: true|false, and oneOf: [schema, schema, ...] replaces type for an exact-one union. A raw JSON-Schema { type: 'object', properties, required?: […] } wrapper is also accepted with open-by-default objects. A tool's `execute` MUST return the lossless JSON value declared by `output.schema`; `output.render(args, value)` separately returns Native/model content blocks. Temporary Plugins can COMPOSE: one Plugin may `ctx.provide('name', value)` a service and another may declare `inject: ['name']` to consume it — the consumer stays pending until the provider exists and returns to pending when the provider is unmounted. Everything registered inside `apply` is cleaned up automatically by cordis_unmount. Sandbox globals: `console` (tagged `[cordis:]`, writes through to the harness terminal), `harness.defineTool`, `harness.registerTool`, `btoa`, `atob`, `TextEncoder`, `TextDecoder`. Node APIs are DISABLED — do filesystem/network/timer work through the cordis services, never Node built-ins: `require`, `setTimeout`/`setInterval`, and `fetch` throw redirect errors; `process` and `Buffer` are undefined. Instead use inject: ['fs'] + ctx.fs for files, inject: ['web'] + ctx.web for HTTP, inject: ['bash'] + ctx.bash for processes, and inject: ['timer'] + ctx.setTimeout/ctx.setInterval for timing (fiber effects, auto-cleaned when unmounted) — cordis_inspect what:\"api\" shows what THIS runtime provides. Write PLAIN JavaScript, not TypeScript (no `as`, no type annotations). Cautions: (1) waterfall events (e.g. tools/pre-execute) hand the listener a trailing `next` callback which MUST be called — returning without `next()` SHORT-CIRCUITS the call; prefer plain notification events unless you intend to intercept. (2) Never await something that only resolves after the current turn (your code runs INSIDE a tool call of that turn — it would deadlock). (3) Your `ctx` is a restricted façade: you can register tools, observe events, provide/consume services, and use timers, but framework internals (ctx.root, ctx.fiber, ctx.extend, ctx.plugin, …) are withheld. It is not a security boundary though — the services you inject (e.g. ctx.bash) reach the real runtime. */\n cordis_mount: {\n /** JavaScript body returning a temporary Plugin; evaluated now and saved nowhere. */\n code: string;\n } & Record;\n /** Unmount a current-process temporary Plugin created by cordis_mount. Waits for its tools, listeners, services, timers, and other owned effects to clean up completely. Only dyn-N temporary ids are accepted; this cannot remove Loader, configured, or installed Plugins. */\n cordis_unmount: {\n /** The temporary Plugin id returned by cordis_mount (for example \"dyn-1\"); valid only in this process and invalid after unmount or restart. */\n id: string;\n } & Record;\n /** Edit an existing UTF-8 text file by replacing literal text. */\n edit: {\n /** Path to edit, resolved by the filesystem backend. */\n file_path: string;\n /** Literal text to replace. Must match exactly. */\n old_string: string;\n /** Literal replacement text. Use an empty string to delete the match. */\n new_string: string;\n /** Replace all matches. Defaults to false; when false, old_string must appear exactly once. */\n replace_all?: boolean;\n } & Record;\n /** Request cancellation of a background agent's current turn by its agent id. The target may be your direct child or a deeper agent created under you. Only the current turn stops: messages already queued for the agent stay parked until a later send_message, agents it started keep running, and the agent itself stays available for follow-ups. This call returns as soon as the stop request is accepted, so the target may keep running briefly; interrupting an agent that already finished is an accepted no-op. */\n interrupt_agent: {\n /** The agent id of the running agent to interrupt. */\n agent_id: string;\n } & Record;\n /** Run a foreground fresh-agent Ralph loop toward one immutable objective. Use only when the direct human explicitly asks for Ralph or fresh-agent iteration. Each round opens a new child with no parent conversation or prior child session; the shared workspace is long-term memory, and only a bounded structured report crosses rounds. The call returns when a worker reports completion or a concrete blocker, or at the round limit. Ordinary long-running same-session work belongs to goal tools. */\n ralph: {\n /** The immutable completion objective for every fresh Ralph round. */\n objective: string;\n /** Optional positive safe-integer round cap, bounded by the deployment ceiling. */\n maxRounds?: number;\n } & Record;\n /** Read a UTF-8 text file and return line-numbered content. */\n read: {\n /** Path to read, resolved by the filesystem backend. */\n file_path: string;\n /** 1-based first line to return. Defaults to 1. */\n offset?: number;\n /** Maximum number of lines to return. Defaults to 2000. */\n limit?: number;\n } & Record;\n /** Send a message to a background subagent by its subagent id, continuing the same conversation. It becomes the subagent's next turn: if it is still working, the message waits until its current turn finishes, so it cannot redirect work already underway. This call returns no answer from the subagent — only confirmation that the message was delivered — so use it to give it more work. A failure means the message was NOT delivered. */\n send_message: {\n /** The subagent id returned when the background subagent was started. */\n subagent_id: string;\n /** The message to deliver to the subagent. */\n message: string;\n } & Record;\n /** Load the full instructions for an available skill. Call this with the exact skill name from the session skill catalog before acting on a task that names or clearly matches that skill. */\n skill: {\n /** The exact skill name from the available skills list. */\n name: string;\n } & Record;\n /** Delegate a self-contained task to a subagent (a separate agent that works in its own context) and return its final result. Use this to offload focused, independent work — research, a scoped implementation, an analysis — so it does not consume this conversation's context. The subagent runs to completion and you receive only its final answer, not its intermediate steps. Give it a complete, standalone prompt: it does not see this conversation. Set `run_in_background: true` to start a background subagent that keeps its conversation: you receive only its subagent id, never its result, and it works on its own. Use this for work whose result you do not need returned by this call; `send_message` sends it more work. */\n subagent: {\n /** A short (3-5 word) description of the delegated task, for display. */\n description: string;\n /** The complete, self-contained task for the subagent. It does not share this conversation's context, so include everything it needs. */\n prompt: string;\n /** Run as a background subagent that keeps its conversation and return only its subagent id. This call never returns its result; send it more work with send_message. */\n run_in_background?: boolean;\n } & Record;\n /** Delegate a task to a subagent that inherits this conversation: a child agent seeded with all completed turns so far (it does not see the current in-flight turn), returning only its final result. Use this when the subtask builds on this conversation's context — a follow-up analysis, a review, a continuation — without consuming this conversation's context for the work itself. You receive only its final answer, not its intermediate steps. Set `run_in_background: true` to start a background subagent that keeps its conversation: you receive only its subagent id, never its result, and it works on its own. Use this for work whose result you do not need returned by this call; `send_message` sends it more work. */\n subagent_fork: {\n /** A short (3-5 word) description of the delegated task, for display. */\n description: string;\n /** The task for the subagent. It already sees this conversation's completed turns, so build on them freely and state only what is new. */\n prompt: string;\n /** Run as a background subagent that keeps its conversation and return only its subagent id. This call never returns its result; send it more work with send_message. */\n run_in_background?: boolean;\n } & Record;\n /** Request cancellation of a running background task by task id. Returns immediately; the task settles as killed once its work actually stops. */\n task_kill: {\n /** Task id returned by the tool that started the background work. */\n task_id: string;\n /** Optional short reason, recorded in the log and forwarded to the task. */\n reason?: string;\n } & Record;\n /** List your background tasks (running and finished) with their ids, kinds, and statuses. */\n task_list: Record;\n /** Read a background task. Stream tasks return only output since the previous read; final-output tasks return their result after settlement. Every response ends with `[status: ...]`. Reads are non-blocking unless `wait: true`, which waits up to the configured cap. */\n task_output: {\n /** Task id returned by the tool that started the background work. */\n task_id: string;\n /** Block until the task reaches a terminal status or the timeout expires. A timed-out wait returns [status: running] and leaves the task alive. */\n wait?: boolean;\n /** Max wait in milliseconds (only meaningful with wait: true). Defaults to the configured wait timeout; capped by the configured maximum. */\n timeout_ms?: number;\n } & Record;\n /** Record and update a structured task list for the current work. Send the ENTIRE list every call — it REPLACES the previous list (there are no partial updates, no per-item edits). Use it to plan multi-step work and show progress: add one todo per concrete step before you start. Mark every todo being actively worked on `in_progress` — several at once when work genuinely runs in parallel (e.g. concurrent subagents or background commands), one for sequential work; while work remains, at least one task should be `in_progress`. Mark a todo `completed` the moment it is done (do not batch completions), and allow no `in_progress` item only once all work is complete. Skip the list for trivial single-step tasks. Statuses: `pending` (not started), `in_progress` (being worked on now), `completed` (finished). */\n todo_write: {\n /** The COMPLETE task list, replacing any previous list. */\n todos: ({\n /** What the task is — a short imperative line. */\n content: string;\n /** pending (not started) | in_progress (now) | completed (done). */\n status: \"pending\" | \"in_progress\" | \"completed\";\n })[];\n } & Record;\n /** Run a JavaScript workflow script that orchestrates subagents at scale. Use this for work that fans out across many independent pieces — an audit over many files, a migration, multi-angle research, adversarial verification of findings — where you write the orchestration as a script instead of delegating turn by turn. The workflow's identity rides the `meta` parameter as JSON: required `name` (short kebab-case) and `description` strings, optional `whenToUse` string and `phases` array (`{title, detail?, provider?, model?}`). The `script` parameter is the plain JavaScript body ONLY (NOT TypeScript, and NO `export const meta` statement — meta is a parameter, not code), running with top-level await; end with `return ` — the value must be JSON-serializable and is this tool's result. Script-body hooks: - `agent(prompt, opts?): Promise` — run one subagent to completion. Without `opts.schema` it resolves to the child's final text; with `opts.schema` (an object-rooted JSON Schema using ONLY type/properties/required/additionalProperties/items/enum/const/oneOf — no pattern/format/numeric bounds) it resolves to the validated object. Resolves `null` when the child fails (filter with `.filter(Boolean)`). Other opts: `label` (display), `phase` (progress group), and independent `provider`/`model` LLM target overrides (either may be provided alone). Anything else (`effort`/`isolation`/`agentType`) is rejected loudly. - `pipeline(items, ...stages): Promise` — run each item through the stages independently with NO barrier between stages (prefer this for multi-stage work). Each stage receives `(prev, item, index)`. An ordinary stage throw drops that ITEM to `null` and skips its remaining stages. - `parallel(thunks): Promise` — run zero-argument functions concurrently and await ALL of them (a barrier; use only when a stage genuinely needs every prior result together). A throwing thunk resolves to `null`. - `phase(title)` — start a progress phase; `log(message)` — narrate progress; `args` — the tool call's `args` input, verbatim. Misused hooks (bad arguments, unknown options, unsupported schemas, tripped caps) throw errors that ALWAYS kill the script — they never dissolve into a per-item `null`. Constraints: concurrency and total-agent caps apply; no filesystem, network, timers, or Node.js APIs are provided — the agents do the work, the script only coordinates them. The run executes in the foreground: this call returns when the whole script finishes. */\n workflow: {\n /** The plain-JS workflow script body (top-level await allowed; NO `export const meta` statement; end with `return `). */\n script: string;\n /** The workflow identity block (plain JSON — never code). */\n meta: {\n /** Short kebab-case workflow name. */\n name: string;\n /** One-line description of what the workflow does. */\n description: string;\n /** Optional guidance on when this workflow applies. */\n whenToUse?: string;\n /** Optional phase declarations matched by phase() calls. */\n phases?: ({\n /** The phase title phase() calls match by exact string. */\n title: string;\n /** Optional one-line description of the phase. */\n detail?: string;\n /** Optional provider override this phase is expected to use. */\n provider?: string;\n /** Optional model override this phase is expected to use. */\n model?: string;\n } & Record)[];\n } & Record;\n /** Optional JSON input exposed to the script as the `args` global (wrap a bare list as a field, e.g. {\"files\": [...]}). */\n args?: Record;\n } & Record;\n /** Create or fully replace a UTF-8 text file. */\n write: {\n /** Path to write, resolved by the filesystem backend. */\n file_path: string;\n /** Full UTF-8 text content to write. */\n content: string;\n } & Record;\n}\n\ninterface ToolOutputMap {\n bash: {\n kind: \"background\";\n taskId: string;\n } | {\n kind: \"foreground\";\n exitCode: number | null;\n signal: string | null;\n timedOut: boolean;\n aborted: boolean;\n timeoutMs: number;\n stdout: {\n text: string;\n truncated: boolean;\n spillPath?: string;\n };\n stderr: {\n text: string;\n truncated: boolean;\n spillPath?: string;\n };\n sandbox?: {\n mode: string;\n denied: boolean;\n enforcement?: string;\n runnerFailed?: boolean;\n };\n };\n cordis_inspect: string;\n cordis_mount: {\n id: string;\n pluginName: string;\n state: \"pending\" | \"loading\" | \"active\" | \"failed\" | \"disposed\" | \"unloading\";\n provides: string[];\n waitingFor: string[];\n };\n cordis_unmount: {\n id: string;\n pluginName: string;\n };\n edit: {\n path: string;\n before: string;\n after: string;\n };\n interrupt_agent: {\n accepted: boolean;\n };\n ralph: {\n runId: string;\n agentsStarted: number;\n result: JsonValue;\n };\n read: {\n path: string;\n offset: number;\n lines: {\n number: number;\n text: string;\n }[];\n totalLines: number;\n };\n send_message: {\n messageId: string;\n };\n skill: {\n name: string;\n provider: string;\n resourceBase?: {\n kind: \"directory\";\n path: string;\n } | {\n kind: \"url\";\n url: string;\n } | {\n kind: \"opaque\";\n description: string;\n };\n content: string;\n };\n subagent: {\n kind: \"background\";\n taskId: string;\n } | {\n kind: \"continuable\";\n subagentId: string;\n } | {\n kind: \"foreground\";\n runId: string;\n output: JsonValue[];\n };\n subagent_fork: {\n kind: \"background\";\n taskId: string;\n } | {\n kind: \"continuable\";\n subagentId: string;\n } | {\n kind: \"foreground\";\n runId: string;\n output: JsonValue[];\n };\n task_kill: {\n outcome: \"cancellation-requested\" | \"already-finished\";\n task: {\n id: string;\n kind: string;\n label: string;\n status: \"running\" | \"stopping\" | \"completed\" | \"killed\" | \"failed\";\n detail?: string;\n startedAt: number;\n finishedAt?: number;\n };\n };\n task_list: ({\n id: string;\n kind: string;\n label: string;\n status: \"running\" | \"stopping\" | \"completed\" | \"killed\" | \"failed\";\n detail?: string;\n startedAt: number;\n finishedAt?: number;\n })[];\n task_output: {\n text: string;\n task: {\n id: string;\n kind: string;\n label: string;\n status: \"running\" | \"stopping\" | \"completed\" | \"killed\" | \"failed\";\n detail?: string;\n startedAt: number;\n finishedAt?: number;\n };\n };\n todo_write: {\n todos: ({\n content: string;\n status: \"pending\" | \"in_progress\" | \"completed\";\n })[];\n counts: {\n pending: number;\n inProgress: number;\n completed: number;\n };\n };\n workflow: {\n runId: string;\n agentsStarted: number;\n result: JsonValue;\n };\n write: {\n path: string;\n operation: \"create\" | \"update\";\n before: string | null;\n after: string;\n };\n}\n\ntype ToolName = keyof ToolOutputMap\n\ndeclare class ToolCallError extends Error {\n readonly name: \"ToolCallError\";\n readonly toolName: ToolName;\n}\n\ndeclare const tools: {\n [K in ToolName]: (args: ToolArgsMap[K]) => Promise;\n}\n```","tools":[{"name":"bash","description":"Execute a bash command (`bash -c`) and return its stdout/stderr. Each call runs in a fresh shell: no state (cwd, variables, functions) persists between calls — pass `workdir` instead of using `cd`. Non-zero exits are reported as `[exit code: N]`. Current harness environment facts are exposed through managed `$DSH_*` variables; inspect them when needed. Commands may run under a file sandbox; a blocked file operation is reported as `[sandbox: file access denied under mode]` — a policy denial, not a bug in the command; do not retry another way. Long output is truncated to its tail; the full output is saved to a file whose path is reported when available. Set `run_in_background: true` for long-running commands: the call returns a task id immediately; read its output with `task_output` and stop it with `task_kill`.","parameters":{"type":"object","properties":{"command":{"type":"string","description":"The bash command to execute."},"description":{"type":"string","description":"Clear, concise description of what this command does in active voice, 5-10 words (shown in the UI). Examples: \"ls\" → \"List files in current directory\"; \"git status\" → \"Show working tree status\"; \"npm install\" → \"Install package dependencies\"."},"timeoutMs":{"type":"number","description":"Timeout in milliseconds. The executor applies its configured default and cap, and kills the command on expiry."},"workdir":{"type":"string","description":"Working directory for this command. Defaults to the session workspace; a relative path is resolved against it."},"run_in_background":{"type":"boolean","description":"Run in the background and return a task id immediately (collect with task_output, stop with task_kill). No timeout applies."}},"required":["command","description"]}},{"name":"cordis_inspect","description":"Inspect the live Cordis runtime in the current DSH process. Read-only. Sections: `services` (every provided ctx service and the plugin fiber that owns it), `plugins` (all live plugin fibers with their lifecycle states), `tools` (the model-facing tools currently registered, i.e. what you can call), `temporary` (only temporary Plugins created by cordis_mount: id, name, state, provided services, awaited services, and lifetime), `api` (method signatures AND argument/return type shapes for every LIVE service — read this before writing plugin code that calls a service), `events` (every harness event with its dispatch mode and exact signature — pick listener targets here). Temporary Plugins exist only in memory, remain active across later turns, and disappear after cordis_unmount, toolset unload, or DSH restart; they are not restored automatically. The `temporary` section is a subset of `plugins`. Omit `what` to get all six sections. With `what:\"api\"` or `what:\"events\"`, pass an exact `name` to narrow to one service/event and include its original source JSDoc.","parameters":{"type":"object","properties":{"what":{"type":"string","description":"Limit the report to one section. Omit for all sections.","enum":["services","plugins","tools","temporary","api","events"]},"name":{"type":"string","description":"Exact service key or event name whose original JSDoc to include; valid only with what:\"api\" or what:\"events\"."}}}},{"name":"cordis_mount","description":"Mount a temporary Cordis Plugin in the current DSH process. This creates an in-memory runtime Plugin, not an installed or configured Plugin. It remains active across later turns until cordis_unmount, toolset unload, or DSH restart. It does not create files, install a package, change cordis.yml or personal/project config, survive restart, or automatically become permanent. To keep it, ask the Agent to implement an SDK Plugin or installable profile bundle through the regular development workflow. It may affect other sessions in the same process; the sandbox is not a security boundary, and injected services reach the real runtime. `code` runs now as the body of an async JavaScript function in an isolated sandbox and MUST `return` a plugin. Two forms: FUNCTION form `return (ctx) => { … }` — declares no inject, so it can register tools, listen to events, and provide services, but reaching ANY service (e.g. ctx.bash) throws; use it only when you need no services. OBJECT form `return { name?, inject: ['bash', 'llm', …], apply(ctx) { … } }` — declares dependencies, and cordis activates the plugin only after the services exist; PREFER this form. You may reach ONLY the services you list in inject: an undeclared service throws even if it exists, because an undeclared dependency would not be cleaned up if its provider is unmounted. BEFORE calling a service from your code, read cordis_inspect what:\"api\" — it lists method signatures AND the type shapes of their arguments/returns (do not guess a field's type; e.g. a bash run's stdout is an object, not a string). Inside `apply`, use the standard cordis API: `ctx.on(event, listener)` to observe events (see cordis_inspect what:\"events\"), or call `harness.registerTool(ctx, harness.defineTool({ name, description, parameters: { text: { type: 'string', required: true } }, output: { schema: { type: 'string' }, render(_args, value) { return [{ type: 'text', text: value }] } }, async execute(args) { return args.text } }))` to give yourself a new tool — it becomes callable on your NEXT step. Tool parameters: each key IS a property — { type: 'string'|'number'|'integer'|'boolean'|'null'|'object'|'array'|'json', required?: true, description?, enum?, const?, items?, properties? }; every direct DSL object declares additionalProperties: true|false, and oneOf: [schema, schema, ...] replaces type for an exact-one union. A raw JSON-Schema { type: 'object', properties, required?: […] } wrapper is also accepted with open-by-default objects. A tool's `execute` MUST return the lossless JSON value declared by `output.schema`; `output.render(args, value)` separately returns Native/model content blocks. Temporary Plugins can COMPOSE: one Plugin may `ctx.provide('name', value)` a service and another may declare `inject: ['name']` to consume it — the consumer stays pending until the provider exists and returns to pending when the provider is unmounted. Everything registered inside `apply` is cleaned up automatically by cordis_unmount. Sandbox globals: `console` (tagged `[cordis:]`, writes through to the harness terminal), `harness.defineTool`, `harness.registerTool`, `btoa`, `atob`, `TextEncoder`, `TextDecoder`. Node APIs are DISABLED — do filesystem/network/timer work through the cordis services, never Node built-ins: `require`, `setTimeout`/`setInterval`, and `fetch` throw redirect errors; `process` and `Buffer` are undefined. Instead use inject: ['fs'] + ctx.fs for files, inject: ['web'] + ctx.web for HTTP, inject: ['bash'] + ctx.bash for processes, and inject: ['timer'] + ctx.setTimeout/ctx.setInterval for timing (fiber effects, auto-cleaned when unmounted) — cordis_inspect what:\"api\" shows what THIS runtime provides. Write PLAIN JavaScript, not TypeScript (no `as`, no type annotations). Cautions: (1) waterfall events (e.g. tools/pre-execute) hand the listener a trailing `next` callback which MUST be called — returning without `next()` SHORT-CIRCUITS the call; prefer plain notification events unless you intend to intercept. (2) Never await something that only resolves after the current turn (your code runs INSIDE a tool call of that turn — it would deadlock). (3) Your `ctx` is a restricted façade: you can register tools, observe events, provide/consume services, and use timers, but framework internals (ctx.root, ctx.fiber, ctx.extend, ctx.plugin, …) are withheld. It is not a security boundary though — the services you inject (e.g. ctx.bash) reach the real runtime.","parameters":{"type":"object","properties":{"code":{"type":"string","description":"JavaScript body returning a temporary Plugin; evaluated now and saved nowhere."}},"required":["code"]}},{"name":"cordis_unmount","description":"Unmount a current-process temporary Plugin created by cordis_mount. Waits for its tools, listeners, services, timers, and other owned effects to clean up completely. Only dyn-N temporary ids are accepted; this cannot remove Loader, configured, or installed Plugins.","parameters":{"type":"object","properties":{"id":{"type":"string","description":"The temporary Plugin id returned by cordis_mount (for example \"dyn-1\"); valid only in this process and invalid after unmount or restart."}},"required":["id"]}},{"name":"edit","description":"Edit an existing UTF-8 text file by replacing literal text.","parameters":{"type":"object","properties":{"file_path":{"type":"string","description":"Path to edit, resolved by the filesystem backend."},"old_string":{"type":"string","description":"Literal text to replace. Must match exactly."},"new_string":{"type":"string","description":"Literal replacement text. Use an empty string to delete the match."},"replace_all":{"type":"boolean","description":"Replace all matches. Defaults to false; when false, old_string must appear exactly once."}},"required":["file_path","old_string","new_string"]}},{"name":"interrupt_agent","description":"Request cancellation of a background agent's current turn by its agent id. The target may be your direct child or a deeper agent created under you. Only the current turn stops: messages already queued for the agent stay parked until a later send_message, agents it started keep running, and the agent itself stays available for follow-ups. This call returns as soon as the stop request is accepted, so the target may keep running briefly; interrupting an agent that already finished is an accepted no-op.","parameters":{"type":"object","properties":{"agent_id":{"type":"string","description":"The agent id of the running agent to interrupt."}},"required":["agent_id"]}},{"name":"ralph","description":"Run a foreground fresh-agent Ralph loop toward one immutable objective. Use only when the direct human explicitly asks for Ralph or fresh-agent iteration. Each round opens a new child with no parent conversation or prior child session; the shared workspace is long-term memory, and only a bounded structured report crosses rounds. The call returns when a worker reports completion or a concrete blocker, or at the round limit. Ordinary long-running same-session work belongs to goal tools.","parameters":{"type":"object","properties":{"objective":{"type":"string","description":"The immutable completion objective for every fresh Ralph round."},"maxRounds":{"type":"number","description":"Optional positive safe-integer round cap, bounded by the deployment ceiling."}},"required":["objective"]}},{"name":"read","description":"Read a UTF-8 text file and return line-numbered content.","parameters":{"type":"object","properties":{"file_path":{"type":"string","description":"Path to read, resolved by the filesystem backend."},"offset":{"type":"number","description":"1-based first line to return. Defaults to 1."},"limit":{"type":"number","description":"Maximum number of lines to return. Defaults to 2000."}},"required":["file_path"]}},{"name":"run_code","description":"Execute a TypeScript program against the available tools. Write the BODY of an async function (erasable syntax only; top-level `await` and `return` work) and call tools as `await tools.name(args)` per the declarations in the system prompt. Only what you print or return comes back — curate it.","parameters":{"type":"object","properties":{"code":{"type":"string","description":"The program: the body of an async TypeScript function."},"description":{"type":"string","description":"Clear, concise description of what this program does in active voice, 5-10 words (shown in the UI). Examples: \"Count TODO markers across packages\"; \"Read failing test and its fixture\"; \"Rename config key in every cordis.yml\"."}},"required":["code","description"]}},{"name":"send_message","description":"Send a message to a background subagent by its subagent id, continuing the same conversation. It becomes the subagent's next turn: if it is still working, the message waits until its current turn finishes, so it cannot redirect work already underway. This call returns no answer from the subagent — only confirmation that the message was delivered — so use it to give it more work. A failure means the message was NOT delivered.","parameters":{"type":"object","properties":{"subagent_id":{"type":"string","description":"The subagent id returned when the background subagent was started."},"message":{"type":"string","description":"The message to deliver to the subagent."}},"required":["subagent_id","message"]}},{"name":"skill","description":"Load the full instructions for an available skill. Call this with the exact skill name from the session skill catalog before acting on a task that names or clearly matches that skill.","parameters":{"type":"object","properties":{"name":{"type":"string","description":"The exact skill name from the available skills list."}},"required":["name"]}},{"name":"subagent","description":"Delegate a self-contained task to a subagent (a separate agent that works in its own context) and return its final result. Use this to offload focused, independent work — research, a scoped implementation, an analysis — so it does not consume this conversation's context. The subagent runs to completion and you receive only its final answer, not its intermediate steps. Give it a complete, standalone prompt: it does not see this conversation. Set `run_in_background: true` to start a background subagent that keeps its conversation: you receive only its subagent id, never its result, and it works on its own. Use this for work whose result you do not need returned by this call; `send_message` sends it more work.","parameters":{"type":"object","properties":{"description":{"type":"string","description":"A short (3-5 word) description of the delegated task, for display."},"prompt":{"type":"string","description":"The complete, self-contained task for the subagent. It does not share this conversation's context, so include everything it needs."},"run_in_background":{"type":"boolean","description":"Run as a background subagent that keeps its conversation and return only its subagent id. This call never returns its result; send it more work with send_message."}},"required":["description","prompt"]}},{"name":"subagent_fork","description":"Delegate a task to a subagent that inherits this conversation: a child agent seeded with all completed turns so far (it does not see the current in-flight turn), returning only its final result. Use this when the subtask builds on this conversation's context — a follow-up analysis, a review, a continuation — without consuming this conversation's context for the work itself. You receive only its final answer, not its intermediate steps. Set `run_in_background: true` to start a background subagent that keeps its conversation: you receive only its subagent id, never its result, and it works on its own. Use this for work whose result you do not need returned by this call; `send_message` sends it more work.","parameters":{"type":"object","properties":{"description":{"type":"string","description":"A short (3-5 word) description of the delegated task, for display."},"prompt":{"type":"string","description":"The task for the subagent. It already sees this conversation's completed turns, so build on them freely and state only what is new."},"run_in_background":{"type":"boolean","description":"Run as a background subagent that keeps its conversation and return only its subagent id. This call never returns its result; send it more work with send_message."}},"required":["description","prompt"]}},{"name":"task_kill","description":"Request cancellation of a running background task by task id. Returns immediately; the task settles as killed once its work actually stops.","parameters":{"type":"object","properties":{"task_id":{"type":"string","description":"Task id returned by the tool that started the background work."},"reason":{"type":"string","description":"Optional short reason, recorded in the log and forwarded to the task."}},"required":["task_id"]}},{"name":"task_list","description":"List your background tasks (running and finished) with their ids, kinds, and statuses.","parameters":{"type":"object","properties":{}}},{"name":"task_output","description":"Read a background task. Stream tasks return only output since the previous read; final-output tasks return their result after settlement. Every response ends with `[status: ...]`. Reads are non-blocking unless `wait: true`, which waits up to the configured cap.","parameters":{"type":"object","properties":{"task_id":{"type":"string","description":"Task id returned by the tool that started the background work."},"wait":{"type":"boolean","description":"Block until the task reaches a terminal status or the timeout expires. A timed-out wait returns [status: running] and leaves the task alive."},"timeout_ms":{"type":"number","description":"Max wait in milliseconds (only meaningful with wait: true). Defaults to the configured wait timeout; capped by the configured maximum."}},"required":["task_id"]}},{"name":"todo_write","description":"Record and update a structured task list for the current work. Send the ENTIRE list every call — it REPLACES the previous list (there are no partial updates, no per-item edits). Use it to plan multi-step work and show progress: add one todo per concrete step before you start. Mark every todo being actively worked on `in_progress` — several at once when work genuinely runs in parallel (e.g. concurrent subagents or background commands), one for sequential work; while work remains, at least one task should be `in_progress`. Mark a todo `completed` the moment it is done (do not batch completions), and allow no `in_progress` item only once all work is complete. Skip the list for trivial single-step tasks. Statuses: `pending` (not started), `in_progress` (being worked on now), `completed` (finished).","parameters":{"type":"object","properties":{"todos":{"type":"array","description":"The COMPLETE task list, replacing any previous list.","items":{"type":"object","additionalProperties":false,"properties":{"content":{"type":"string","description":"What the task is — a short imperative line."},"status":{"type":"string","description":"pending (not started) | in_progress (now) | completed (done).","enum":["pending","in_progress","completed"]}},"required":["content","status"]}}},"required":["todos"]}},{"name":"workflow","description":"Run a JavaScript workflow script that orchestrates subagents at scale. Use this for work that fans out across many independent pieces — an audit over many files, a migration, multi-angle research, adversarial verification of findings — where you write the orchestration as a script instead of delegating turn by turn.\n\nThe workflow's identity rides the `meta` parameter as JSON: required `name` (short kebab-case) and `description` strings, optional `whenToUse` string and `phases` array (`{title, detail?, provider?, model?}`). The `script` parameter is the plain JavaScript body ONLY (NOT TypeScript, and NO `export const meta` statement — meta is a parameter, not code), running with top-level await; end with `return ` — the value must be JSON-serializable and is this tool's result.\n\nScript-body hooks:\n- `agent(prompt, opts?): Promise` — run one subagent to completion. Without `opts.schema` it resolves to the child's final text; with `opts.schema` (an object-rooted JSON Schema using ONLY type/properties/required/additionalProperties/items/enum/const/oneOf — no pattern/format/numeric bounds) it resolves to the validated object. Resolves `null` when the child fails (filter with `.filter(Boolean)`). Other opts: `label` (display), `phase` (progress group), and independent `provider`/`model` LLM target overrides (either may be provided alone). Anything else (`effort`/`isolation`/`agentType`) is rejected loudly.\n- `pipeline(items, ...stages): Promise` — run each item through the stages independently with NO barrier between stages (prefer this for multi-stage work). Each stage receives `(prev, item, index)`. An ordinary stage throw drops that ITEM to `null` and skips its remaining stages.\n- `parallel(thunks): Promise` — run zero-argument functions concurrently and await ALL of them (a barrier; use only when a stage genuinely needs every prior result together). A throwing thunk resolves to `null`.\n- `phase(title)` — start a progress phase; `log(message)` — narrate progress; `args` — the tool call's `args` input, verbatim.\n\nMisused hooks (bad arguments, unknown options, unsupported schemas, tripped caps) throw errors that ALWAYS kill the script — they never dissolve into a per-item `null`.\n\nConstraints: concurrency and total-agent caps apply; no filesystem, network, timers, or Node.js APIs are provided — the agents do the work, the script only coordinates them. The run executes in the foreground: this call returns when the whole script finishes.","parameters":{"type":"object","properties":{"script":{"type":"string","description":"The plain-JS workflow script body (top-level await allowed; NO `export const meta` statement; end with `return `)."},"meta":{"type":"object","description":"The workflow identity block (plain JSON — never code).","additionalProperties":true,"properties":{"name":{"type":"string","description":"Short kebab-case workflow name."},"description":{"type":"string","description":"One-line description of what the workflow does."},"whenToUse":{"type":"string","description":"Optional guidance on when this workflow applies."},"phases":{"type":"array","description":"Optional phase declarations matched by phase() calls.","items":{"type":"object","additionalProperties":true,"properties":{"title":{"type":"string","description":"The phase title phase() calls match by exact string."},"detail":{"type":"string","description":"Optional one-line description of the phase."},"provider":{"type":"string","description":"Optional provider override this phase is expected to use."},"model":{"type":"string","description":"Optional model override this phase is expected to use."}},"required":["title"]}}},"required":["name","description"]},"args":{"type":"object","description":"Optional JSON input exposed to the script as the `args` global (wrap a bare list as a field, e.g. {\"files\": [...]}).","additionalProperties":true}},"required":["script","meta"]}},{"name":"write","description":"Create or fully replace a UTF-8 text file.","parameters":{"type":"object","properties":{"file_path":{"type":"string","description":"Path to write, resolved by the filesystem backend."},"content":{"type":"string","description":"Full UTF-8 text content to write."}},"required":["file_path","content"]}}]},"reason":"initial"}} {"type":"request/context","seq":7,"time":1785730501403,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}} {"type":"assistant/chunk","seq":8,"time":1783950000007,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}}} {"type":"assistant/chunk","seq":9,"time":1783950000008,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":0,"id":"advanced-mount","name":"cordis_mount","argumentsDelta":"{\"code\":\"return { name: 'snapshot-marker', apply() {} }\"}"}}} {"type":"assistant/chunk","seq":10,"time":1783950000009,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"advanced-mount","name":"cordis_mount","arguments":"{\"code\":\"return { name: 'snapshot-marker', apply() {} }\"}"}}}} {"type":"assistant/chunk","seq":11,"time":1785498583784,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}}} {"type":"assistant/chunk","seq":12,"time":1785730501404,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}} -{"type":"assistant/message","seq":13,"time":1785730501404,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"tool-call","id":"advanced-mount","name":"cordis_mount","arguments":"{\"code\":\"return { name: 'snapshot-marker', apply() {} }\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"e65c0ebe-8e3d-44c0-833f-68efcbc0acb5"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[8,9,10,11,12],"surfaceOp":"append"} +{"type":"assistant/message","seq":13,"time":1785730501404,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"tool-call","id":"advanced-mount","name":"cordis_mount","arguments":"{\"code\":\"return { name: 'snapshot-marker', apply() {} }\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"93f733e0-c190-4a3d-80a4-f534ddf325e9"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[8,9,10,11,12],"surfaceOp":"append"} {"type":"tool/call","seq":14,"time":1785730501404,"data":{"turn":1,"step":1,"callId":"advanced-mount","name":"cordis_mount","arguments":"{\"code\":\"return { name: 'snapshot-marker', apply() {} }\"}"}} -{"type":"tool/result","seq":15,"time":1785730501413,"data":{"turn":1,"step":1,"message":{"source":{"kind":"tool","callId":"advanced-mount"},"content":[{"type":"tool-result","toolCallId":"advanced-mount","content":[{"type":"text","text":"Temporary Plugin dyn-1 is running (plugin \"snapshot-marker\"; available until unmounted or DSH restarts)."}],"isError":false}],"role":"user","id":"abb8ecee-cb03-4a66-9477-38a52458ab05"}},"sourceEventSeqs":[14],"surfaceOp":"append"} +{"type":"tool/result","seq":15,"time":1785730501413,"data":{"turn":1,"step":1,"message":{"source":{"kind":"tool","callId":"advanced-mount"},"content":[{"type":"tool-result","toolCallId":"advanced-mount","content":[{"type":"text","text":"Temporary Plugin dyn-1 is running (plugin \"snapshot-marker\"; available until unmounted or DSH restarts)."}],"isError":false}],"role":"user","id":"10d97131-ca23-4af0-ab53-7aa386c08c12"}},"sourceEventSeqs":[14],"surfaceOp":"append"} {"type":"step/end","seq":16,"time":1785730501413,"data":{"turn":1,"step":1}} {"type":"step/start","seq":17,"time":1785730501423,"data":{"turn":1,"step":2}} {"type":"assistant/chunk","seq":18,"time":1783950000017,"data":{"turn":1,"step":2,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}}} @@ -22,11 +22,11 @@ {"type":"assistant/chunk","seq":20,"time":1783950000019,"data":{"turn":1,"step":2,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"advanced-code","name":"run_code","arguments":"{\"code\": \"return await tools.cordis_inspect({ what: 'temporary' })\", \"description\": \"Run the scripted inspection program\"}"}}}} {"type":"assistant/chunk","seq":21,"time":1785498583804,"data":{"turn":1,"step":2,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}}} {"type":"assistant/chunk","seq":22,"time":1785730501424,"data":{"turn":1,"step":2,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}} -{"type":"assistant/message","seq":23,"time":1785730501424,"data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"tool-call","id":"advanced-code","name":"run_code","arguments":"{\"code\": \"return await tools.cordis_inspect({ what: 'temporary' })\", \"description\": \"Run the scripted inspection program\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"cdc95327-3ce1-49ea-8a92-b17e450cc455"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[18,19,20,21,22],"surfaceOp":"append"} +{"type":"assistant/message","seq":23,"time":1785730501424,"data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"tool-call","id":"advanced-code","name":"run_code","arguments":"{\"code\": \"return await tools.cordis_inspect({ what: 'temporary' })\", \"description\": \"Run the scripted inspection program\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"8b483937-d8d4-409e-9698-6adc1dbb4992"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[18,19,20,21,22],"surfaceOp":"append"} {"type":"tool/call","seq":24,"time":1785730501424,"data":{"turn":1,"step":2,"callId":"advanced-code","name":"run_code","arguments":"{\"code\": \"return await tools.cordis_inspect({ what: 'temporary' })\", \"description\": \"Run the scripted inspection program\"}"}} {"type":"tool/code-dispatch-start","seq":25,"time":1785730501473,"data":{"rootCallId":"advanced-code","parentCallId":"advanced-code","subCallId":"advanced-code:code:1","name":"cordis_inspect","arguments":{"what":"temporary"}}} {"type":"tool/code-dispatch","seq":26,"time":1785730501474,"data":{"rootCallId":"advanced-code","parentCallId":"advanced-code","subCallId":"advanced-code:code:1","name":"cordis_inspect","arguments":{"what":"temporary"},"isError":false,"content":[{"type":"text","text":"## Temporary Plugins\n- Temporary Plugin dyn-1: snapshot-marker [running] — provides: none; waiting for: none; lifetime: until unmounted or DSH restarts"}]}} -{"type":"tool/result","seq":27,"time":1785730501475,"data":{"turn":1,"step":2,"message":{"source":{"kind":"tool","callId":"advanced-code"},"content":[{"type":"tool-result","toolCallId":"advanced-code","content":[{"type":"text","text":"## Temporary Plugins\n- Temporary Plugin dyn-1: snapshot-marker [running] — provides: none; waiting for: none; lifetime: until unmounted or DSH restarts"}],"isError":false}],"role":"user","id":"d75c7d03-cbbc-4260-ba40-8c210a3b5bbe"}},"sourceEventSeqs":[24],"surfaceOp":"append"} +{"type":"tool/result","seq":27,"time":1785730501475,"data":{"turn":1,"step":2,"message":{"source":{"kind":"tool","callId":"advanced-code"},"content":[{"type":"tool-result","toolCallId":"advanced-code","content":[{"type":"text","text":"## Temporary Plugins\n- Temporary Plugin dyn-1: snapshot-marker [running] — provides: none; waiting for: none; lifetime: until unmounted or DSH restarts"}],"isError":false}],"role":"user","id":"8556d6ea-03a1-4965-8d5b-90361a578a2c"}},"sourceEventSeqs":[24],"surfaceOp":"append"} {"type":"step/end","seq":28,"time":1785730501475,"data":{"turn":1,"step":2}} {"type":"step/start","seq":29,"time":1785730501483,"data":{"turn":1,"step":3}} {"type":"assistant/chunk","seq":30,"time":1783950000029,"data":{"turn":1,"step":3,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}}} @@ -34,9 +34,9 @@ {"type":"assistant/chunk","seq":32,"time":1785037378923,"data":{"turn":1,"step":3,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"advanced-direct-child","name":"subagent","arguments":"{\"description\":\"Check direct child\",\"prompt\":\"Reply with exactly DIRECT_CHILD_OK and nothing else.\"}"}}}} {"type":"assistant/chunk","seq":33,"time":1785498583869,"data":{"turn":1,"step":3,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}}} {"type":"assistant/chunk","seq":34,"time":1785730501484,"data":{"turn":1,"step":3,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}} -{"type":"assistant/message","seq":35,"time":1785730501484,"data":{"turn":1,"step":3,"message":{"role":"assistant","content":[{"type":"tool-call","id":"advanced-direct-child","name":"subagent","arguments":"{\"description\":\"Check direct child\",\"prompt\":\"Reply with exactly DIRECT_CHILD_OK and nothing else.\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"ba4958e9-231c-437f-a2fc-7a13f392d3ba"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[30,31,32,33,34],"surfaceOp":"append"} +{"type":"assistant/message","seq":35,"time":1785730501484,"data":{"turn":1,"step":3,"message":{"role":"assistant","content":[{"type":"tool-call","id":"advanced-direct-child","name":"subagent","arguments":"{\"description\":\"Check direct child\",\"prompt\":\"Reply with exactly DIRECT_CHILD_OK and nothing else.\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"4507f38e-aabb-424d-921f-fcb4fc270711"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[30,31,32,33,34],"surfaceOp":"append"} {"type":"tool/call","seq":36,"time":1785730501484,"data":{"turn":1,"step":3,"callId":"advanced-direct-child","name":"subagent","arguments":"{\"description\":\"Check direct child\",\"prompt\":\"Reply with exactly DIRECT_CHILD_OK and nothing else.\"}"}} -{"type":"tool/result","seq":37,"time":1785730501508,"data":{"turn":1,"step":3,"message":{"source":{"kind":"tool","callId":"advanced-direct-child"},"content":[{"type":"tool-result","toolCallId":"advanced-direct-child","content":[{"type":"text","text":"DIRECT_CHILD_OK"}],"isError":false}],"role":"user","id":"b9ebb37d-e565-4882-95b0-5343da1d68d8"}},"sourceEventSeqs":[36],"surfaceOp":"append"} +{"type":"tool/result","seq":37,"time":1785730501508,"data":{"turn":1,"step":3,"message":{"source":{"kind":"tool","callId":"advanced-direct-child"},"content":[{"type":"tool-result","toolCallId":"advanced-direct-child","content":[{"type":"text","text":"DIRECT_CHILD_OK"}],"isError":false}],"role":"user","id":"001fd41e-56fc-4a5b-9180-78f4120f5b85"}},"sourceEventSeqs":[36],"surfaceOp":"append"} {"type":"step/end","seq":38,"time":1785730501508,"data":{"turn":1,"step":3}} {"type":"step/start","seq":39,"time":1785730501521,"data":{"turn":1,"step":4}} {"type":"assistant/chunk","seq":40,"time":1783957884594,"data":{"turn":1,"step":4,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}}} @@ -44,9 +44,9 @@ {"type":"assistant/chunk","seq":42,"time":1785037378946,"data":{"turn":1,"step":4,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"advanced-workflow","name":"workflow","arguments":"{\"script\":\"phase('Delegate')\\nconst reply = await agent('Reply with exactly WORKFLOW_CHILD_OK and nothing else.', { label: 'workflow-child' })\\nreturn { reply }\",\"meta\":{\"name\":\"advanced-headless-snapshot\",\"description\":\"exercise one workflow child through the headless agent\"}}"}}}} {"type":"assistant/chunk","seq":43,"time":1785498583919,"data":{"turn":1,"step":4,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}}} {"type":"assistant/chunk","seq":44,"time":1785730501522,"data":{"turn":1,"step":4,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}} -{"type":"assistant/message","seq":45,"time":1785730501522,"data":{"turn":1,"step":4,"message":{"role":"assistant","content":[{"type":"tool-call","id":"advanced-workflow","name":"workflow","arguments":"{\"script\":\"phase('Delegate')\\nconst reply = await agent('Reply with exactly WORKFLOW_CHILD_OK and nothing else.', { label: 'workflow-child' })\\nreturn { reply }\",\"meta\":{\"name\":\"advanced-headless-snapshot\",\"description\":\"exercise one workflow child through the headless agent\"}}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"4757f4b9-9bde-488b-a54a-1bdea55dd15f"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[40,41,42,43,44],"surfaceOp":"append"} +{"type":"assistant/message","seq":45,"time":1785730501522,"data":{"turn":1,"step":4,"message":{"role":"assistant","content":[{"type":"tool-call","id":"advanced-workflow","name":"workflow","arguments":"{\"script\":\"phase('Delegate')\\nconst reply = await agent('Reply with exactly WORKFLOW_CHILD_OK and nothing else.', { label: 'workflow-child' })\\nreturn { reply }\",\"meta\":{\"name\":\"advanced-headless-snapshot\",\"description\":\"exercise one workflow child through the headless agent\"}}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"59ccdc72-932c-4dc9-83a9-56d1b05fb930"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[40,41,42,43,44],"surfaceOp":"append"} {"type":"tool/call","seq":46,"time":1785730501522,"data":{"turn":1,"step":4,"callId":"advanced-workflow","name":"workflow","arguments":"{\"script\":\"phase('Delegate')\\nconst reply = await agent('Reply with exactly WORKFLOW_CHILD_OK and nothing else.', { label: 'workflow-child' })\\nreturn { reply }\",\"meta\":{\"name\":\"advanced-headless-snapshot\",\"description\":\"exercise one workflow child through the headless agent\"}}"}} -{"type":"tool/result","seq":47,"time":1785730501647,"data":{"turn":1,"step":4,"message":{"source":{"kind":"tool","callId":"advanced-workflow"},"content":[{"type":"tool-result","toolCallId":"advanced-workflow","content":[{"type":"text","text":"workflow \"advanced-headless-snapshot\" completed (1 agent).\nReturn value:\n{\n \"reply\": \"WORKFLOW_CHILD_OK\"\n}"}],"isError":false}],"role":"user","id":"35baa460-54ff-4fa1-ba9d-66b6661f84e9"}},"sourceEventSeqs":[46],"surfaceOp":"append"} +{"type":"tool/result","seq":47,"time":1785730501647,"data":{"turn":1,"step":4,"message":{"source":{"kind":"tool","callId":"advanced-workflow"},"content":[{"type":"tool-result","toolCallId":"advanced-workflow","content":[{"type":"text","text":"workflow \"advanced-headless-snapshot\" completed (1 agent).\nReturn value:\n{\n \"reply\": \"WORKFLOW_CHILD_OK\"\n}"}],"isError":false}],"role":"user","id":"00e81f53-1914-4236-8056-07e7592dc4df"}},"sourceEventSeqs":[46],"surfaceOp":"append"} {"type":"step/end","seq":48,"time":1785730501648,"data":{"turn":1,"step":4}} {"type":"step/start","seq":49,"time":1785730501660,"data":{"turn":1,"step":5}} {"type":"assistant/chunk","seq":50,"time":1783957884719,"data":{"turn":1,"step":5,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}}} @@ -54,9 +54,9 @@ {"type":"assistant/chunk","seq":52,"time":1785037379534,"data":{"turn":1,"step":5,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"advanced-unmount","name":"cordis_unmount","arguments":"{\"id\":\"dyn-1\"}"}}}} {"type":"assistant/chunk","seq":53,"time":1785498584085,"data":{"turn":1,"step":5,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}}} {"type":"assistant/chunk","seq":54,"time":1785730501661,"data":{"turn":1,"step":5,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}} -{"type":"assistant/message","seq":55,"time":1785730501661,"data":{"turn":1,"step":5,"message":{"role":"assistant","content":[{"type":"tool-call","id":"advanced-unmount","name":"cordis_unmount","arguments":"{\"id\":\"dyn-1\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"739166e2-ed48-4df2-a9a5-207f34058030"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[50,51,52,53,54],"surfaceOp":"append"} +{"type":"assistant/message","seq":55,"time":1785730501661,"data":{"turn":1,"step":5,"message":{"role":"assistant","content":[{"type":"tool-call","id":"advanced-unmount","name":"cordis_unmount","arguments":"{\"id\":\"dyn-1\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"d4c2df8c-860c-45c0-976c-2e92d1700284"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[50,51,52,53,54],"surfaceOp":"append"} {"type":"tool/call","seq":56,"time":1785730501661,"data":{"turn":1,"step":5,"callId":"advanced-unmount","name":"cordis_unmount","arguments":"{\"id\":\"dyn-1\"}"}} -{"type":"tool/result","seq":57,"time":1785730501668,"data":{"turn":1,"step":5,"message":{"source":{"kind":"tool","callId":"advanced-unmount"},"content":[{"type":"tool-result","toolCallId":"advanced-unmount","content":[{"type":"text","text":"Temporary Plugin dyn-1 was unmounted and removed."}],"isError":false}],"role":"user","id":"98b05c06-cb77-41a9-8310-324bc72fc7a0"}},"sourceEventSeqs":[56],"surfaceOp":"append"} +{"type":"tool/result","seq":57,"time":1785730501668,"data":{"turn":1,"step":5,"message":{"source":{"kind":"tool","callId":"advanced-unmount"},"content":[{"type":"tool-result","toolCallId":"advanced-unmount","content":[{"type":"text","text":"Temporary Plugin dyn-1 was unmounted and removed."}],"isError":false}],"role":"user","id":"134abbb7-24c4-48d6-93b2-f0be788b5f7d"}},"sourceEventSeqs":[56],"surfaceOp":"append"} {"type":"step/end","seq":58,"time":1785730501668,"data":{"turn":1,"step":5}} {"type":"step/start","seq":59,"time":1785730501678,"data":{"turn":1,"step":6}} {"type":"assistant/chunk","seq":60,"time":1783957884720,"data":{"turn":1,"step":6,"chunk":{"type":"block-start","index":0,"blockType":"text"}}} @@ -64,6 +64,6 @@ {"type":"assistant/chunk","seq":62,"time":1785037379541,"data":{"turn":1,"step":6,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"ADVANCED_HEADLESS_OK"}}}} {"type":"assistant/chunk","seq":63,"time":1785498584102,"data":{"turn":1,"step":6,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}}} {"type":"assistant/chunk","seq":64,"time":1785730501679,"data":{"turn":1,"step":6,"chunk":{"type":"finish","reason":{"kind":"stop"}}}} -{"type":"assistant/message","seq":65,"time":1785730501679,"data":{"turn":1,"step":6,"message":{"role":"assistant","content":[{"type":"text","text":"ADVANCED_HEADLESS_OK"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"0a4ca8f2-92c1-4dbc-beb8-923b8791c298"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[60,61,62,63,64],"surfaceOp":"append"} +{"type":"assistant/message","seq":65,"time":1785730501679,"data":{"turn":1,"step":6,"message":{"role":"assistant","content":[{"type":"text","text":"ADVANCED_HEADLESS_OK"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"6157c734-e26c-457b-9d72-92b2f9bcf8a0"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[60,61,62,63,64],"surfaceOp":"append"} {"type":"step/end","seq":66,"time":1785730501679,"data":{"turn":1,"step":6}} {"type":"turn/end","seq":67,"time":1785730501679,"data":{"turn":1,"reason":{"kind":"completed"}}} diff --git a/examples/package.json b/examples/package.json index 48ac39f5ca..4e684d9d80 100644 --- a/examples/package.json +++ b/examples/package.json @@ -50,7 +50,6 @@ "@deepseek-ai/dsh-pty-local": "workspace:*", "@deepseek-ai/dsh-pwsh-local": "workspace:*", "@deepseek-ai/dsh-repeat-tool-guard": "workspace:*", - "@deepseek-ai/dsh-repository-plugin": "workspace:*", "@deepseek-ai/dsh-sandbox": "workspace:*", "@deepseek-ai/dsh-sandbox-local": "workspace:*", "@deepseek-ai/dsh-sandbox-policy": "workspace:^", diff --git a/knip.json b/knip.json index 249d21d857..512ec350e4 100644 --- a/knip.json +++ b/knip.json @@ -717,20 +717,6 @@ "@deepseek-ai/.+" ] }, - "apps/cli/tests/fixtures/github-repository-plugin/.dsh-plugin": { - "entry": [ - "src/*.ts" - ], - "project": [ - "src/**/*.ts" - ], - "ignoreDependencies": [ - "@deepseek-ai/dsh-repository-plugin" - ], - "ignoreBinaries": [ - "dsh-plugin-prepare" - ] - }, "packages/client/modules": { "entry": [ "tests/**/*.spec.ts" diff --git a/packages/README.i18n.yaml b/packages/README.i18n.yaml index d77d9ed870..b4c191a1d0 100644 --- a/packages/README.i18n.yaml +++ b/packages/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/README.md -README.md: c246534a26cd7297f2ba8885099c8b517a5dc2b0 -README.zh.md: 4139874d3ebbf82fad8680a3721a1cf35a553706 +README.md: 19d6e5ba7b554f59bd66e213f8a53389761fc735 +README.zh.md: 17f58a2922e9019af054b0dccb6c4d9199fd1a9d diff --git a/packages/README.md b/packages/README.md index c246534a26..19d6e5ba7b 100644 --- a/packages/README.md +++ b/packages/README.md @@ -38,7 +38,7 @@ Groups hold `packages///`; names stay `@deepseek-ai/dsh-`. **Gr | [`preset/`](preset/README.md) | Per-session agent composition from preset `cordis.yml` files | Product — stable surface | | [`guard/`](guard/README.md) | Loop-hygiene guards: advisory repeat-call reminders + the `tools/execute` deadline enforcer | Product — stable surface | | [`bundle/`](bundle/README.md) | Installable `dsh --profile` patch layers | Product — stable surface | -| [`self-modification/`](self-modification/README.md) | Agent runtime self-modification: live plugin/service inspection, model-written plugin mount/unmount ([design](../.agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.md)), restricted repository Plugin loading | Product — stable surface | +| [`self-modification/`](self-modification/README.md) | Agent runtime self-modification: live plugin/service inspection and model-written plugin mount/unmount ([design](../.agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.md)) | Product — stable surface | | [`hooks/`](hooks/README.md) | Hook bridges + the shared Claude Code / Codex wire-protocol library | Product — stable surface | | [`session/`](session/README.md) | Durable session data plane: persistence seam + JSONL/SQLite backends, projection seam, log-backed titles, session reporting | Product — stable surface | | [`session-query/`](session-query/README.md) | Session retrieval family: logical corpus, bounded reads, lineage, event relationships, semantic filtering, and SQLite full-text search | Product — stable surface | diff --git a/packages/README.zh.md b/packages/README.zh.md index 4139874d3e..17f58a2922 100644 --- a/packages/README.zh.md +++ b/packages/README.zh.md @@ -38,7 +38,7 @@ npm scope 为 `@deepseek-ai/dsh-*`;Cordis `Service` 子类和函数插件通 | [`preset/`](preset/README.md) | 由 preset `cordis.yml` 按会话组装 agent | 产品:稳定接口 | | [`guard/`](guard/README.md) | 循环卫生守卫:建议性重复调用提醒 + `tools/execute` 截止时间强制执行器 | 产品:稳定接口 | | [`bundle/`](bundle/README.md) | 可安装的 `dsh --profile` 补丁层 | 产品:稳定接口 | -| [`self-modification/`](self-modification/README.md) | agent 运行时自修改:实时插件/服务检查、模型所写插件挂载/卸载([设计](../.agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.md))、受限仓库插件加载 | 产品:稳定接口 | +| [`self-modification/`](self-modification/README.md) | agent 运行时自修改:实时插件/服务检查和模型所写插件挂载/卸载([设计](../.agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.md)) | 产品:稳定接口 | | [`hooks/`](hooks/README.md) | 钩子桥接 + 共享 Claude Code/Codex 协议格式库 | 产品:稳定接口 | | [`session/`](session/README.md) | 持久会话数据平面:持久化 seam + JSONL/SQLite 后端、投影 seam、日志支持的标题、会话上报 | 产品:稳定接口 | | [`session-query/`](session-query/README.md) | 会话检索系列:逻辑语料库、有界读取、血缘、事件关系、语义过滤和 SQLite 全文搜索 | 产品:稳定接口 | diff --git a/packages/boot/app-boot/tests/repository-cache.spec.ts b/packages/boot/app-boot/tests/repository-cache.spec.ts deleted file mode 100644 index 71aa90a440..0000000000 --- a/packages/boot/app-boot/tests/repository-cache.spec.ts +++ /dev/null @@ -1,218 +0,0 @@ -import { execFile } from 'node:child_process' -import { createHash } from 'node:crypto' -import { mkdtemp, mkdir, readFile, readdir, rm, writeFile } from 'node:fs/promises' -import { tmpdir } from 'node:os' -import { delimiter, join } from 'node:path' -import { pathToFileURL } from 'node:url' -import { promisify } from 'node:util' -import { afterEach, describe, expect, it, vi } from 'vitest' -import { BUNDLED_PNPM_VERSION, RepositoryCache, type RepositoryInstall } from '@cordisjs/plugin-loader/repository' - -const execFileAsync = promisify(execFile) -const roots: string[] = [] - -/** Normalize Git's platform checkout line endings for source-content assertions. */ -const lf = (text: string): string => text.replace(/\r\n/g, '\n') - -async function temporaryRoot(name: string): Promise { - const root = await mkdtemp(join(tmpdir(), `cordis-${name}-`)) - roots.push(root) - return root -} - -async function fakePackage(directory: string): Promise { - const target = join(directory, 'node_modules', 'repository') - await mkdir(target, { recursive: true }) - await writeFile(join(target, 'package.json'), '{"name":"fixture"}\n') -} - -afterEach(async () => { - vi.unstubAllEnvs() - await Promise.all(roots.splice(0).map(root => rm(root, { recursive: true, force: true }))) -}) - -describe('RepositoryCache', () => { - it('single-flights and permanently reuses an exact specifier', async () => { - const root = await temporaryRoot('repository-cache') - const calls: string[] = [] - const install: RepositoryInstall = async (directory) => { - calls.push(directory) - await fakePackage(directory) - } - const cache = new RepositoryCache(root, { install }) - const specifier = 'github:owner/repository#0123456789abcdef' - - const [first, concurrent] = await Promise.all([cache.resolve(specifier), cache.resolve(specifier)]) - expect(concurrent).toBe(first) - expect(calls).toHaveLength(1) - - const reopened = new RepositoryCache(root, { install: async () => { throw new Error('cache miss') } }) - expect(await reopened.resolve(specifier)).toBe(first) - expect(JSON.parse(await readFile(join(first, '..', '..', 'package.json'), 'utf8'))).toMatchObject({ - packageManager: `pnpm@${BUNDLED_PNPM_VERSION}`, - dependencies: { repository: specifier }, - }) - - const second = await cache.resolve('github:owner/repository#fedcba9876543210') - expect(second).not.toBe(first) - expect(calls).toHaveLength(2) - }) - - it('accepts the valid winner when independent cache instances race', async () => { - const root = await temporaryRoot('repository-race') - const bothStarted = Promise.withResolvers() - let starts = 0 - const install: RepositoryInstall = async (directory) => { - await fakePackage(directory) - starts += 1 - if (starts === 2) bothStarted.resolve(undefined) - await bothStarted.promise - } - const specifier = 'github:owner/repository#race' - - const [first, second] = await Promise.all([ - new RepositoryCache(root, { install }).resolve(specifier), - new RepositoryCache(root, { install }).resolve(specifier), - ]) - - expect(second).toBe(first) - expect(starts).toBe(2) - expect(await readdir(root)).toHaveLength(1) - }) - - it('removes a failed staging tree and permits an exact retry', async () => { - const root = await temporaryRoot('repository-retry') - let attempts = 0 - const cache = new RepositoryCache(root, { install: async (directory) => { - attempts += 1 - if (attempts === 1) throw new Error('install failed') - await fakePackage(directory) - } }) - - await expect(cache.resolve('github:owner/repository#ref')).rejects.toThrow('failed to prepare repository') - expect(await readdir(root)).toEqual([]) - await expect(cache.resolve('github:owner/repository#ref')).resolves.toContain('node_modules') - expect(attempts).toBe(2) - }) - - it('rejects empty or padded specifiers before touching the cache', async () => { - const root = await temporaryRoot('repository-input') - const cache = new RepositoryCache(root, { install: fakePackage }) - expect(() => cache.resolve('')).toThrow('non-empty unpadded string') - expect(() => cache.resolve(' github:owner/repository#ref')).toThrow('non-empty unpadded string') - await expect(readdir(root)).resolves.toEqual([]) - }) - - it('fails loud on a corrupt published marker instead of reinstalling it', async () => { - const root = await temporaryRoot('repository-corrupt') - const specifier = 'github:owner/repository#corrupt' - const key = createHash('sha256').update(specifier).digest('hex') - const entry = join(root, key) - await mkdir(join(entry, 'node_modules', 'repository'), { recursive: true }) - await writeFile(join(entry, '.repository-cache.json'), '{}\n') - const cache = new RepositoryCache(root, { install: async () => { throw new Error('must not reinstall') } }) - - await expect(cache.resolve(specifier)).rejects.toThrow('repository cache marker is invalid') - }) - - it('isolates and prepares a .dsh-plugin Git subpath from an enclosing pnpm workspace', { timeout: 60_000 }, async () => { - const root = await temporaryRoot('repository-pnpm') - const repository = join(root, 'source') - await mkdir(join(repository, '.dsh-plugin'), { recursive: true }) - await mkdir(join(repository, '.dsh-plugin', 'build-helper'), { recursive: true }) - await mkdir(join(repository, '.dsh-plugin', 'prepare-helper'), { recursive: true }) - await mkdir(join(repository, 'skills', 'fixture'), { recursive: true }) - const shadowPnpm = join(root, 'shadow-pnpm') - await mkdir(shadowPnpm) - await writeFile(join(shadowPnpm, 'pnpm'), '#!/bin/sh\nexit 99\n', { mode: 0o700 }) - await writeFile(join(shadowPnpm, 'pnpm.bat'), '@exit /b 99\r\n') - await writeFile(join(repository, 'package.json'), `${JSON.stringify({ - name: 'repository-fixture', - private: true, - version: '1.0.0', - packageManager: `pnpm@${BUNDLED_PNPM_VERSION}`, - })}\n`) - await writeFile(join(repository, 'pnpm-workspace.yaml'), 'packages: []\n') - await writeFile(join(repository, 'pnpm-lock.yaml'), [ - "lockfileVersion: '9.0'", - 'settings:', - ' autoInstallPeers: true', - ' excludeLinksFromLockfile: false', - 'importers:', - ' .: {}', - '', - ].join('\n')) - await writeFile(join(repository, '.dsh-plugin', 'build-helper', 'package.json'), `${JSON.stringify({ - name: 'repository-build-helper', - version: '1.0.0', - bin: 'index.js', - })}\n`) - await writeFile(join(repository, '.dsh-plugin', 'build-helper', 'index.js'), [ - '#!/usr/bin/env node', - "require('node:fs').writeFileSync('dependency-built.txt', 'dependency available\\n')", - '', - ].join('\n'), { mode: 0o700 }) - await writeFile(join(repository, '.dsh-plugin', 'prepare-helper', 'package.json'), `${JSON.stringify({ - name: 'repository-prepare-helper', - version: '1.0.0', - bin: { 'dsh-plugin-prepare': 'index.js' }, - })}\n`) - await writeFile(join(repository, '.dsh-plugin', 'prepare-helper', 'index.js'), [ - '#!/usr/bin/env node', - "const { cpSync, mkdirSync, writeFileSync } = require('node:fs')", - "mkdirSync('dsh-plugin-assets/skills', { recursive: true })", - "cpSync('../skills', 'dsh-plugin-assets/skills/0', { recursive: true })", - "writeFileSync('dsh-plugin.mjs', 'export function apply() {}\\n')", - "writeFileSync('prepared.txt', `${process.env.REPOSITORY_TEST_VISIBLE ?? 'absent'}|${process.env.REPOSITORY_TEST_TOKEN ?? 'absent'}|${process.env.PNPM_CONFIG_IGNORE_WORKSPACE ?? 'absent'}\\n`)", - "writeFileSync('environment.json', `${JSON.stringify({ path: process.env.PATH, pathExt: process.env.PATHEXT })}\\n`)", - '', - ].join('\n'), { mode: 0o700 }) - await writeFile(join(repository, 'skills', 'fixture', 'SKILL.md'), 'repository skill source\n') - await writeFile(join(repository, '.dsh-plugin', 'package.json'), `${JSON.stringify({ - name: 'repository-plugin-fixture', - version: '1.0.0', - scripts: { - // The fixture owns dependency installation, not platform-specific - // node_modules/.bin shim generation during pnpm's Git preparation. - prepack: [ - 'node ./node_modules/repository-build-helper/index.js', - 'node ./node_modules/repository-prepare-helper/index.js', - ].join(' && '), - }, - devDependencies: { - 'repository-build-helper': 'file:./build-helper', - 'repository-prepare-helper': 'file:./prepare-helper', - }, - dsh: { skills: ['../skills'] }, - })}\n`) - await execFileAsync('git', ['init', '--quiet'], { cwd: repository }) - await execFileAsync('git', ['add', '.'], { cwd: repository }) - await execFileAsync('git', [ - '-c', 'user.name=Repository Fixture', - '-c', 'user.email=repository@example.invalid', - 'commit', '--quiet', '-m', 'fixture', - ], { cwd: repository }) - const { stdout } = await execFileAsync('git', ['rev-parse', 'HEAD'], { cwd: repository, encoding: 'utf8' }) - const specifier = `git+${pathToFileURL(repository).href}#${stdout.trim()}&path:/.dsh-plugin` - vi.stubEnv('REPOSITORY_TEST_VISIBLE', 'visible') - vi.stubEnv('REPOSITORY_TEST_TOKEN', 'hidden') - vi.stubEnv('PNPM_HOME', shadowPnpm) - vi.stubEnv('PATH', [shadowPnpm, ...(process.env.PATH === undefined ? [] : [process.env.PATH])].join(delimiter)) - vi.stubEnv('PATHEXT', '.BAT;.CMD;.EXE') - - const installed = await new RepositoryCache(join(root, 'cache')).resolve(specifier) - await expect(readFile(join(installed, 'dependency-built.txt'), 'utf8')).resolves.toBe('dependency available\n') - await expect(readFile(join(installed, 'prepared.txt'), 'utf8')).resolves.toBe('visible|absent|true\n') - const environment = JSON.parse(await readFile(join(installed, 'environment.json'), 'utf8')) as { - path: string - pathExt: string - } - expect(environment.path.split(delimiter)).not.toContain(shadowPnpm) - expect(environment.pathExt.split(';')[0]?.toUpperCase()).toBe('.CMD') - await expect(readFile(join(installed, 'dsh-plugin.mjs'), 'utf8')).resolves.toContain('export function apply') - expect(lf(await readFile(join(installed, 'dsh-plugin-assets/skills/0/fixture/SKILL.md'), 'utf8'))) - .toBe('repository skill source\n') - await expect(readFile(join(installed, 'package.json'), 'utf8')) - .resolves.toContain('repository-plugin-fixture') - }) -}) diff --git a/packages/bundle/base/README.i18n.yaml b/packages/bundle/base/README.i18n.yaml index 29786ca332..dd08db1425 100644 --- a/packages/bundle/base/README.i18n.yaml +++ b/packages/bundle/base/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/bundle/base/README.md -README.md: 2a87b01ad4819750a58163f8c472e61ea633588e -README.zh.md: dc79895355546812aa3371487190724f169c6260 +README.md: 70ecc181da8f0c120b8da0d55f68d47bf22d5820 +README.zh.md: 11f10bf561429c11471ff57d08950677e4924b40 diff --git a/packages/bundle/base/README.md b/packages/bundle/base/README.md index 2a87b01ad4..70ecc181da 100644 --- a/packages/bundle/base/README.md +++ b/packages/bundle/base/README.md @@ -2,7 +2,7 @@ English | [中文](README.zh.md) -The shared dsh core as a profile bundle: [`cordis.patch.yml`](cordis.patch.yml) inserts every base plugin row — model adapters, the shared [`agent-default-model`](../../core/agent-default-model/README.md) selection, tools, persistence, policy, settings/credentials, repository Plugins, telemetry — over the empty profile root, as the first layer of every profile's `dsh.profile.bundles` list. Later bundle layers (e.g. [`dsh-web-app`](../web-app/README.md)) and the user's profile `cordis.patch.yml` override these rows by id; a patch replaces a row's whole `config`, so mode-specific values live in mode bundles, not here. The package has no runtime API; the profile composer resolves the patch through the `dsh.bundle.patch` manifest field, never through code. +The shared dsh core as a profile bundle: [`cordis.patch.yml`](cordis.patch.yml) inserts every base plugin row — model adapters, the shared [`agent-default-model`](../../core/agent-default-model/README.md) selection, tools, persistence, policy, settings/credentials, and telemetry — over the empty profile root, as the first layer of every profile's `dsh.profile.bundles` list. Later bundle layers (e.g. [`dsh-web-app`](../web-app/README.md)) and the user's profile `cordis.patch.yml` override these rows by id; a patch replaces a row's whole `config`, so mode-specific values live in mode bundles, not here. The package has no runtime API; the profile composer resolves the patch through the `dsh.bundle.patch` manifest field, never through code. Windows hosts booting a shipped profile additionally receive [`windows.cordis.patch.yml`](windows.cordis.patch.yml): it disables the POSIX-only bash stack (`bash-sandbox`/`tool-bash`) and inserts the sandbox-confined PowerShell stack (`@deepseek-ai/dsh-pwsh-sandbox`, `@deepseek-ai/dsh-tool-pwsh`). The permission surface stays exactly as on POSIX: `sandbox`/`sandbox-policy` enforce the file-effect policy through the Windows ACL restricted-token runner (the win32 chain of `dsh-sandbox-local` → `@deepseek-ai/dsh-sandbox-windows-acl`), the permission switcher and the approval service run unchanged, and `fs-sandbox` keeps fencing `ctx.fs` writes — mounting `dsh-fs-local` alongside it would double-register `ctx.fs` and fail the load. The launcher applies the layer between the bundle layers and the user layers on win32 hosts; a Windows host that prefers the unconfined local pwsh executor or full access overrides these rows through its profile or home `cordis.patch.yml` (the bash-restore recipe must be complete: disable `pwsh-sandbox`/`tool-pwsh` AND re-enable `bash-sandbox`/`tool-bash` — both executor families register the same `bash` service, so an incomplete recipe fails loud at load). POSIX hosts never receive it. diff --git a/packages/bundle/base/README.zh.md b/packages/bundle/base/README.zh.md index dc79895355..11f10bf561 100644 --- a/packages/bundle/base/README.zh.md +++ b/packages/bundle/base/README.zh.md @@ -2,7 +2,7 @@ [English](README.md) | 中文 -以 profile 组合包形式交付的共享 dsh 核心:[`cordis.patch.yml`](cordis.patch.yml) 在空的 profile 根之上插入全部基础插件行——模型适配器、共享的 [`agent-default-model`](../../core/agent-default-model/README.md) 选择、工具、持久化、策略、settings/credentials、repository 插件、遥测——作为每个 profile 的 `dsh.profile.bundles` 列表中的第一层。后续的组合包层(例如 [`dsh-web-app`](../web-app/README.md))和用户 profile 的 `cordis.patch.yml` 按 id 覆盖这些行;patch 会替换目标行的整个 `config`,因此模式专属的值放在各模式组合包中,而不是这里。该包没有运行时 API;profile 组合器通过 manifest(元数据清单)的 `dsh.bundle.patch` 字段解析 patch,绝不通过代码。 +以 profile 组合包形式交付的共享 dsh 核心:[`cordis.patch.yml`](cordis.patch.yml) 在空的 profile 根之上插入全部基础插件行——模型适配器、共享的 [`agent-default-model`](../../core/agent-default-model/README.md) 选择、工具、持久化、策略、settings/credentials 和遥测——作为每个 profile 的 `dsh.profile.bundles` 列表中的第一层。后续的组合包层(例如 [`dsh-web-app`](../web-app/README.md))和用户 profile 的 `cordis.patch.yml` 按 id 覆盖这些行;patch 会替换目标行的整个 `config`,因此模式专属的值放在各模式组合包中,而不是这里。该包没有运行时 API;profile 组合器通过 manifest(元数据清单)的 `dsh.bundle.patch` 字段解析 patch,绝不通过代码。 启动交付 profile 的 Windows 主机还会额外收到 [`windows.cordis.patch.yml`](windows.cordis.patch.yml):它禁用仅 POSIX 的 bash 栈(`bash-sandbox`/`tool-bash`),并插入沙盒受限的 PowerShell 栈(`@deepseek-ai/dsh-pwsh-sandbox`、`@deepseek-ai/dsh-tool-pwsh`)。权限面与 POSIX 完全一致:`sandbox`/`sandbox-policy` 通过 Windows ACL 受限令牌 runner(`dsh-sandbox-local` 的 win32 链 → `@deepseek-ai/dsh-sandbox-windows-acl`)执行文件效果策略,权限切换器与 approval 服务原样运行,`fs-sandbox` 继续围栏 `ctx.fs` 写入——在其旁再挂载 `dsh-fs-local` 会重复注册 `ctx.fs` 并在加载时失败。启动器在 win32 主机上把该层应用于 bundle 层与用户层之间;偏好不限权本地 pwsh 执行器或完整访问的 Windows 主机通过其 profile 或 home 的 `cordis.patch.yml` 覆盖这些行(bash 恢复配方必须完整:禁用 `pwsh-sandbox`/`tool-pwsh` 并重新启用 `bash-sandbox`/`tool-bash`——两个执行器家族注册同一个 `bash` 服务,配方不完整会在加载时 fail loud)。POSIX 主机永远不会收到它。 diff --git a/packages/bundle/base/cordis.patch.yml b/packages/bundle/base/cordis.patch.yml index 400fa766d7..66612f70fd 100644 --- a/packages/bundle/base/cordis.patch.yml +++ b/packages/bundle/base/cordis.patch.yml @@ -21,13 +21,6 @@ config: root: ['.'] - # The profile's cordis.patch.yml replaces this row's config to select exact GitHub - # repository Plugin generations. The app registers the DSH-owned runtime even - # when the list is empty so a later personal-config edit can load - # transactionally; one-shot headless runs consume the startup value only. - - id: repository-plugins - name: '@deepseek-ai/dsh-repository-plugin' - - id: llm name: '@deepseek-ai/dsh-llm' diff --git a/packages/bundle/base/package.json b/packages/bundle/base/package.json index 4713dfa216..def597150e 100644 --- a/packages/bundle/base/package.json +++ b/packages/bundle/base/package.json @@ -63,7 +63,6 @@ "@deepseek-ai/dsh-plan-mode": "workspace:^", "@deepseek-ai/dsh-pwsh-sandbox": "workspace:^", "@deepseek-ai/dsh-repeat-tool-guard": "workspace:^", - "@deepseek-ai/dsh-repository-plugin": "workspace:^", "@deepseek-ai/dsh-sandbox-local": "workspace:^", "@deepseek-ai/dsh-sandbox-policy": "workspace:^", "@deepseek-ai/dsh-session": "workspace:^", diff --git a/packages/mcp/mcp-client/src/index.ts b/packages/mcp/mcp-client/src/index.ts index 0fe7dd9de3..ece8c7857f 100644 --- a/packages/mcp/mcp-client/src/index.ts +++ b/packages/mcp/mcp-client/src/index.ts @@ -36,9 +36,7 @@ const DEFAULT_TOOL_CALL_TIMEOUT_MS = 60_000 /** * Valid `serverName`: 1–32 chars of `[A-Za-z0-9_-]`. Kept well under the * 64-char public-name budget so typical raw tool names survive unhashed. - * Exported so upstream producers of Config inputs (repository-plugin's - * `.mcp.json` prepare-time validation) reject the same names this registry - * would. + * Exported so config producers can reject the same names this registry would. */ export const SERVER_NAME_PATTERN = /^[A-Za-z0-9_-]{1,32}$/ diff --git a/packages/self-modification/README.i18n.yaml b/packages/self-modification/README.i18n.yaml index e6e0fa54c8..5a4ae4b3b4 100644 --- a/packages/self-modification/README.i18n.yaml +++ b/packages/self-modification/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/self-modification/README.md -README.md: c94f9ac9a79709e418448d9e440c38296e759335 -README.zh.md: 44b5d9ff4cb09fb4a4e44f446894c9925a62ec51 +README.md: 2f409f779ae32c9eedc9c57dbb6476c0639205ca +README.zh.md: 09c34c18b66803c544d7a572820c2001405fb6dd diff --git a/packages/self-modification/README.md b/packages/self-modification/README.md index c94f9ac9a7..2f409f779a 100644 --- a/packages/self-modification/README.md +++ b/packages/self-modification/README.md @@ -2,9 +2,8 @@ English | [中文](README.zh.md) -Model-facing tools over the live cordis runtime the agent itself runs inside: inspect the loaded plugins and service surface, mount model-written plugins, and dispose them again — plus the restricted repository Plugin runtime. Design home: [the toolset Agent Note](../../.agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.md). +Model-facing tools over the live cordis runtime the agent itself runs inside: inspect the loaded plugins and service surface, mount model-written plugins, and dispose them again. The group is the landing zone for future self-modification packages. Design home: [the toolset Agent Note](../../.agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.md). | Package | Role | ctx key | |---|---|---| | [`tool-cordis/`](tool-cordis/README.md) | Model-facing runtime inspection and temporary-plugin tools | registers on `ctx.tools` | -| [`repository-plugin/`](repository-plugin/README.md) | Repository skill and MCP composition | registers a Loader builtin | diff --git a/packages/self-modification/README.zh.md b/packages/self-modification/README.zh.md index 44b5d9ff4c..09c34c18b6 100644 --- a/packages/self-modification/README.zh.md +++ b/packages/self-modification/README.zh.md @@ -2,9 +2,8 @@ [English](README.md) | 中文 -agent 修改自身运行时:检查已加载的插件与服务接口、挂载模型编写的插件并再次 dispose,外加受限 repository Plugin 运行时。设计居所:[工具集 Agent Note](../../.agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.md)。 +agent 修改自身运行时:检查已加载的插件与服务接口、挂载模型编写的插件并再次 dispose。该组是未来自我修改类包的落点。设计居所:[工具集 Agent Note](../../.agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.md)。 | 包(package) | 角色 | ctx 键 | |---|---|---| | [`tool-cordis/`](tool-cordis/README.md) | `cordis_inspect`/`cordis_mount`/`cordis_unmount` 工具:读取当前进程运行时,并在一个自有分组 fiber 下管理内存中的临时插件 | 注册到 `ctx.tools` | -| [`repository-plugin/`](repository-plugin/README.md) | 通过 DSH 自有子 Plugin 准备并挂载静态 repository skills 与通用 `.mcp.json` server | 注册一个 Loader builtin | diff --git a/packages/self-modification/repository-plugin/README.i18n.yaml b/packages/self-modification/repository-plugin/README.i18n.yaml deleted file mode 100644 index 6b0e958c2c..0000000000 --- a/packages/self-modification/repository-plugin/README.i18n.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each -# side as of the last confirmed-consistent state. Both languages carry equal authority; -# after editing either side, bring the other along and re-record with: -# pnpm run verify-translation-pairing --write packages/self-modification/repository-plugin/README.md -README.md: 666f00e02b9ab33bff348df6b4ff90e3f3bfecc7 -README.zh.md: b09f68bc17a4eb08df6ecbb3782e14bf26fb7d7f diff --git a/packages/self-modification/repository-plugin/README.md b/packages/self-modification/repository-plugin/README.md deleted file mode 100644 index 666f00e02b..0000000000 --- a/packages/self-modification/repository-plugin/README.md +++ /dev/null @@ -1,128 +0,0 @@ -# @deepseek-ai/dsh-repository-plugin - -English | [中文](README.zh.md) - -Trusted repository package format for DeepSeek Harness. A `.dsh-plugin` npm package may contribute a compiled Cordis/DSH Plugin entry, skill roots, and a common `.mcp.json`; its ordinary `prepack` lifecycle owns dependency installation and source compilation before the DSH prepare helper validates the outputs and emits the Loader wrapper. Static contributions compose [`dsh-skill-local`](../../skill/skill-local/README.md) and [`dsh-mcp-client`](../../mcp/mcp-client/README.md). Design rationale: [trusted repository package code](../../../.agents/notes/implemented/architecture/2026-08-08-trusted-repository-package-code.md) and the [static contribution subformat](../../../.agents/notes/implemented/architecture/2026-07-30-static-repository-plugin-format.md). - -## Authoring format - -Place an ordinary package in the repository's `.dsh-plugin` directory: - -```json -{ - "name": "humanize-dsh-plugin", - "version": "0.0.0", - "private": true, - "type": "module", - "scripts": { - "build": "tsc", - "prepack": "npm run build && dsh-plugin-prepare" - }, - "dsh": { - "entry": "./lib/plugin.js", - "skills": ["../skills"], - "mcpServers": "../.mcp.json" - }, - "dependencies": { - "@modelcontextprotocol/sdk": "1.29.0" - }, - "devDependencies": { - "@deepseek-ai/dsh-repository-plugin": "^0.0.1", - "typescript": "6.0.3" - } -} -``` - -`scripts.prepack` must be non-empty and invoke `dsh-plugin-prepare`; it may run arbitrary package-owned build steps first. The package declares `@deepseek-ai/dsh-repository-plugin` as an ordinary development dependency so its published executable is available to that lifecycle. DSH does not inject the helper: the repository package declares and runs its own compiler, runtime dependencies, preparation helper, and other npm lifecycle code. The selected package is installed from its own manifest instead of inheriting an enclosing pnpm workspace, so declare every dependency it needs and do not depend on workspace-only hoisting. DSH does not transpile TypeScript or infer a package entry. - -`dsh.entry` is an optional relative path to a compiled ESM Cordis Plugin inside `.dsh-plugin`. The module may use either namespace exports or a default export and owns its ordinary `name`, `inject`, `Config`, registrations, and effects. `dsh.skills` is an optional array of local skill roots, and `dsh.mcpServers` is an optional path to one `.mcp.json`; at least one of the three fields is required. Skill and MCP paths may reach adjacent repository assets but must remain beneath the directory containing `.dsh-plugin`; the compiled entry must remain inside the package selected and packed by the package manager. A repository containing several Plugins gives each one its own `.dsh-plugin` package under a different selectable subdirectory. - -The repository package and every dependency or lifecycle script it runs are trusted code, just like an npm package selected directly by the user. This format is not a sandbox: install only repositories whose code may access the host process, filesystem, network, and services declared through Cordis. Exact refs and the immutable cache provide identity and reproducibility, not isolation. - -## Standalone app configuration - -The shipped `dsh-base` bundle every profile starts from contains an empty `repository-plugins` row. A user enables exact GitHub generations by replacing that row's config in a user patch layer — `$DSH_HOME/profiles//cordis.patch.yml`, or the home-level `$DSH_HOME/cordis.patch.yml` shared by every profile; a `--patch` overlay patches the same row for one run: - -```yaml -- id: repository-plugins - name: '@deepseek-ai/dsh-repository-plugin' - config: - repositories: - - 'github:PolyArch/humanize#' - - 'github:owner/repository#&path:/plugins/one/.dsh-plugin' -``` - -Each source must use `github:owner/repository#`. Omitting `&path:` selects `/.dsh-plugin`; an explicit path is absolute within the repository and must end in `.dsh-plugin`. A commit ref gives the clearest immutable identity, while tags and branches remain accepted exact config values. `cacheDir` may override the default `$DSH_HOME/cache/repository-plugins` cache root. - -Git transport uses the host's ordinary Git authentication. Public repositories need no credentials; private sources require a read-only credential or SSH agent that can read the selected repository. DSH removes credential-shaped environment variables before package lifecycles, so configure Git itself, such as through a credential helper or job-scoped Git config, instead of expecting an exported token variable to cross that boundary. Repository lifecycle code is trusted and can invoke Git, so use the narrowest repository-scoped credential available. - -Long-lived surfaces watch both `cordis.patch.yml` layers through Cordis HMR. A valid source-list change installs and swaps the complete repository Plugin generation; a failed fetch, prepare, import, or Plugin application keeps the last good tree and broadcasts `hmr/config-update-failed(filename, error)`. One-shot runs read the layers only at startup, and a `--patch` overlay is never watched. An identical source string permanently reuses its prepared cache entry, so selecting changed code requires a ref, path, or other source-config change. App integration rationale: [config-only repository Plugins Agent Note](../../../.agents/notes/implemented/feature/2026-07-30-config-only-repository-plugins.md). - -## Preparation - -During exact Git installation, DSH's bundled pnpm installs the selected package from its own manifest. A transaction-owned `pnpm` wrapper reinvokes the same pinned pnpm with `--ignore-workspace`, so an enclosing workspace lockfile cannot suppress dependencies declared only by the selected `.dsh-plugin` package. The required `prepack` lifecycle runs after that dependency installation and before the selected subdirectory is packed; its ordinary `node_modules/.bin` lookup obtains `dsh-plugin-prepare` from the declared direct development dependency on `@deepseek-ai/dsh-repository-plugin`. That package marks its Cordis/DSH runtime peers optional so using the executable alone does not install the runtime graph. Package-owned commands may build TypeScript or other source before invoking the helper. The helper validates `package.json#dsh`, verifies that the compiled entry is an in-package file, validates skill and MCP sources, copies static assets under `dsh-plugin-assets`, and writes `dsh-plugin.mjs`. Before importing that wrapper, DSH revalidates that the installed package retained both the direct development dependency and a `prepack` declaration containing the helper command. Failure to resolve the published helper, install dependencies, build, or prepare fails before a cache generation is published. Rationale: [npm-backed Git source preparation Agent Note](../../../.agents/notes/implemented/bug-fix/2026-08-08-npm-backed-git-repository-plugin-preparation.md). - -## Runtime composition - -Loading this package registers one effect-scoped Loader builtin. Each generated wrapper delegates its prepared static manifest to that builtin, then imports and mounts `dsh.entry` when declared. The wrapper can statically gate only the `loader`, `skills`, and `tools` services implied by the prepared manifest; the entry's own `inject` is discovered when that child is mounted. The entry must reach `ACTIVE`, so a missing entry-only service or startup failure rejects the repository generation instead of committing an inert child, and all effects disappear on Loader removal or rollback. The runtime likewise validates every declared skill root as an existing in-package directory before mounting — a package whose generated outputs were dropped by `files`/`.npmignore` or damaged in cache fails instead of silently losing contributions. Repository skill roots mount as uniquely named `dsh-skill-local` providers with default project/user roots excluded and watching disabled; cached package generations are immutable. - -## Common MCP format - -The `.mcp.json` root is `{ "mcpServers": { ... } }`. A stdio entry accepts only `type: "stdio"` (optional), `command`, `args`, and `env`; an HTTP entry accepts only `type: "http"`, `url`, and `headers`. String values support exact `${NAME}` process-environment expansion at Plugin load, and a missing name fails that load. HTTP URLs become the existing MCP client's `streamable-http` transport; stdio entries use the prepared package directory as `cwd`. - -Unknown fields reject, including OAuth and `auth` objects. There is no `CLAUDE_PLUGIN_ROOT` expansion or compatibility layer. After translation, the existing `dsh-mcp-client` exclusively owns transport creation, connection diagnostics, tool synchronization, calls, and disconnect lifecycle. Repository-declared servers enable its strict startup mode: Plugin activation waits for the initial connection and tool synchronization, so the first model request observes a fully registered initial tool generation, while a network, child-process, discovery, or registration failure rejects the candidate repository generation instead of silently activating without its declared tools. - -## Export shape - -Namespace Plugin: named exports `name` / `inject` / `apply`, preparation constants, and `prepareDshPlugin`; no default export. The package also exposes the `dsh-plugin-prepare` executable and an invariant companion. - -## Model Experience - -### Repository skills - -#### What the model sees - -Indirectly through `dsh-tool-skill`: prepared, model-invocable skills join its logged catalog and selected instruction-body surface under their declared names and descriptions. The exact consumer schema is in the generated [`skill` tool catalog](../../../docs/tool-catalog.md#deepseek-aidsh-tool-skill). - -#### Token effect - -Conditional and data-dependent: each visible repository skill adds one capped catalog row; loading one adds its full current instruction body and resource-base guidance to retained tool history. - -#### KV Cache effect - -A stable prepared Plugin set is prefix-stable. Adding, removing, or replacing a repository Plugin can append the consumer's replacement catalog and affect later request prefixes. - -### Repository MCP tools - -#### What the model sees - -Indirectly through `dsh-mcp-client`: every connected server contributes its server-qualified tool schemas, and calls retain that client's canonical MCP results and rendering. - -#### Token effect - -Conditional on successful connection and the remote tool list; schemas recur on requests in the active tool view, while calls and results remain in history until compaction. - -#### KV Cache effect - -Stable connected tool lists are prefix-stable. Plugin lifecycle or MCP tool-list changes can change later tool-schema prefixes from the first affected definition. - -### Repository code - -#### What the model sees - -Data-dependent. The trusted Cordis entry may contribute any DSH behavior available through its declared services and events, including tools, prompt sections, policies, commands, and transformations. Every model-visible contribution remains subject to its owning DSH seam's logging and lifecycle contract. - -#### Token effect - -Defined by the services and registrations the entry contributes; the repository format itself adds no model content. - -#### KV Cache effect - -Stable registrations preserve the owning surface's normal prefix behavior. Loading, removing, or replacing the exact repository generation can change any prefixes affected by that Plugin. - -## Known Limitations and Deferred Work - -- **No code sandbox** — `dsh.entry`, npm dependencies, and package lifecycle scripts execute with the DSH host's authority; repository trust is mandatory. -- **Entry-only service dependencies are not pre-gated** — the generated wrapper cannot declare an entry module's `inject` before importing it. Any service beyond those implied by Skills or MCP must already exist when the wrapper mounts the entry, or that repository generation rejects. -- **No MCP authentication protocol** — static headers may use environment expansion, but OAuth-bearing definitions reject and private-server login flows are not implemented here. -- **Generated assets are immutable runtime input** — repository cache generations are not watched; source, ref, path, or configuration must select another prepared generation. diff --git a/packages/self-modification/repository-plugin/README.zh.md b/packages/self-modification/repository-plugin/README.zh.md deleted file mode 100644 index b09f68bc17..0000000000 --- a/packages/self-modification/repository-plugin/README.zh.md +++ /dev/null @@ -1,128 +0,0 @@ -# @deepseek-ai/dsh-repository-plugin - -[English](README.md) | 中文 - -这是 DeepSeek Harness 的受信任 repository 包格式。`.dsh-plugin` NPM 包可以贡献已编译的 Cordis/DSH 插件入口、skill(技能)根和通用 `.mcp.json`;其常规 `prepack` 生命周期负责安装依赖并编译源码,随后 DSH 准备辅助程序校验输出并生成 Loader 包装层。静态贡献由 [`dsh-skill-local`](../../skill/skill-local/README.md) 与 [`dsh-mcp-client`](../../mcp/mcp-client/README.md) 组合。设计依据见[受信任 repository 包代码](../../../.agents/notes/implemented/architecture/2026-08-08-trusted-repository-package-code.md)和[静态贡献子格式](../../../.agents/notes/implemented/architecture/2026-07-30-static-repository-plugin-format.md)。 - -## 创作格式 - -在仓库的 `.dsh-plugin` 目录中放置一个普通包: - -```json -{ - "name": "humanize-dsh-plugin", - "version": "0.0.0", - "private": true, - "type": "module", - "scripts": { - "build": "tsc", - "prepack": "npm run build && dsh-plugin-prepare" - }, - "dsh": { - "entry": "./lib/plugin.js", - "skills": ["../skills"], - "mcpServers": "../.mcp.json" - }, - "dependencies": { - "@modelcontextprotocol/sdk": "1.29.0" - }, - "devDependencies": { - "@deepseek-ai/dsh-repository-plugin": "^0.0.1", - "typescript": "6.0.3" - } -} -``` - -`scripts.prepack` 必须非空并调用 `dsh-plugin-prepare`;可以先运行任意包自有的构建步骤。包将 `@deepseek-ai/dsh-repository-plugin` 声明为普通开发依赖,使该生命周期可以使用其已发布的可执行文件。DSH 不会注入辅助程序:repository 包自行声明并运行编译器、运行时依赖、准备辅助程序及其他 NPM 生命周期代码。所选包按自身 manifest 独立安装,而不继承外层 pnpm workspace,因此必须声明所需的每项依赖,不能依赖仅由 workspace 提升而可见的包。DSH 不转译 TypeScript,也不推断包入口。 - -`dsh.entry` 是指向 `.dsh-plugin` 内已编译 ESM Cordis 插件的可选相对路径。该模块可以使用 namespace 导出或 default export,并自行拥有常规的 `name`、`inject`、`Config`、注册和 effect。`dsh.skills` 是可选的本地 skill 根数组,`dsh.mcpServers` 是指向一个 `.mcp.json` 的可选路径;三个字段中至少声明一个。skill 和 MCP 路径可以引用相邻的 repository 资源,但必须留在包含 `.dsh-plugin` 的目录下;已编译入口必须留在由包管理器选中并打包的包内。一个仓库可以在不同的可选择子目录下放置多个各自独立的 `.dsh-plugin` 包。 - -repository 包及其运行的每项依赖或生命周期脚本都是受信任代码,与用户直接选择的 NPM 包相同。本格式不是沙箱:只有在你信任仓库代码并愿意允许其访问宿主进程、文件系统、网络及其通过 Cordis 声明的服务时才应安装。精确 ref 和不可变缓存提供身份与可复现性,而非隔离。 - -## 独立应用配置 - -随附的 `dsh-base` 组合包是每个 profile 的起点,其中包含一个空 `repository-plugins` 配置项。用户可在用户 patch 层中替换该配置项的配置来启用精确指定的 GitHub generation:写入 `$DSH_HOME/profiles//cordis.patch.yml`,或写入各 profile 共享的 home 级 `$DSH_HOME/cordis.patch.yml`;`--patch` overlay 则只为单次运行 patch 同一配置项: - -```yaml -- id: repository-plugins - name: '@deepseek-ai/dsh-repository-plugin' - config: - repositories: - - 'github:PolyArch/humanize#' - - 'github:owner/repository#&path:/plugins/one/.dsh-plugin' -``` - -每个源都必须采用 `github:owner/repository#`。省略 `&path:` 时选择 `/.dsh-plugin`;显式路径是仓库内的绝对路径,并且必须以 `.dsh-plugin` 结尾。commit ref 提供最清晰的不可变身份;tag 和 branch 仍可作为精确配置值使用。`cacheDir` 可覆盖默认缓存根 `$DSH_HOME/cache/repository-plugins`。 - -Git 传输使用宿主的常规 Git 认证。公共仓库无需凭据;私有源需要可读取所选仓库的只读凭据或 SSH agent。DSH 会在包生命周期运行前移除名称符合凭据模式的环境变量,因此请配置 Git 本身,例如使用 Git 凭据辅助工具或作业作用域的 Git 配置,而不要指望已导出的 token 变量跨越该边界。仓库生命周期代码受信任且可以调用 Git,因此请使用作用域最窄且仅限所选仓库的凭据。 - -长期运行的 surface 通过 Cordis HMR(热模块替换)监视两个 `cordis.patch.yml` 层。有效的源列表变更会安装并替换整套 repository Plugin generation;拉取、准备、导入或插件应用失败时,最后一个可用树保持运行,并广播 `hmr/config-update-failed(filename, error)`。一次性运行只在启动时读取这些层,`--patch` overlay 则从不被监视。相同的源字符串会永久复用其已准备缓存条目,因此必须改变 ref、路径或其他源配置,才能选择发生变化的代码。应用集成依据见[仅凭配置接入 repository Plugin 的 Agent Note](../../../.agents/notes/implemented/feature/2026-07-30-config-only-repository-plugins.md)。 - -## 准备阶段 - -安装精确指定的 Git 源时,DSH 随附的 pnpm 会按所选包自身的 manifest 安装。由事务持有的 `pnpm` 包装脚本会以 `--ignore-workspace` 重新调用同一份锁定的 pnpm,因此外层 workspace lockfile 无法抑制仅由所选 `.dsh-plugin` 包声明的依赖。必需的 `prepack` 生命周期在该依赖安装完成后、选定子目录打包前运行;其常规 `node_modules/.bin` 查找会从直接声明的 `@deepseek-ai/dsh-repository-plugin` 开发依赖中取得 `dsh-plugin-prepare`。该包把 Cordis/DSH 运行时对等依赖(peer dependency)标为可选,因此单独使用该可执行文件不会安装运行时依赖图。包自有命令可以在调用辅助程序前构建 TypeScript 或其他源码。辅助程序会校验 `package.json#dsh`,确认已编译入口是包内文件,校验 skill 与 MCP 源,把静态资源复制到 `dsh-plugin-assets`,并写入 `dsh-plugin.mjs`。导入该包装层前,DSH 会重新校验已安装包是否仍同时保留该直接开发依赖,以及包含该辅助命令的 `prepack` 声明。无法解析已发布的辅助程序,或安装依赖、构建或准备失败时,流程会在发布缓存 generation 前失败。设计依据见[基于 NPM 的 Git 源准备 Agent Note](../../../.agents/notes/implemented/bug-fix/2026-08-08-npm-backed-git-repository-plugin-preparation.md)。 - -## 运行时组合 - -加载本包会注册一个 effect-scoped Loader builtin。每个生成的包装层都把已准备的静态 manifest(元数据清单)委托给该 builtin,再在声明了 `dsh.entry` 时导入并挂载该入口。包装层只能静态门控已准备 manifest 所隐含的 `loader`、`skills` 与 `tools` 服务;入口自身的 `inject` 要到挂载该子级时才会发现。入口必须进入 `ACTIVE`,因此缺少入口专用服务或启动失败时,会拒绝 repository generation,而不会提交未激活的子级;Loader 移除或回滚时,所有 effect 都会消失。运行时同样会在挂载前校验每个声明的 skill 根都是包内实际存在的目录——生成输出因 `files`/`.npmignore` 被丢弃或在缓存中损坏的包会加载失败,而不是静默丢失贡献。Repository skill 根以唯一命名的 `dsh-skill-local` 提供方挂载,排除默认项目/用户根并禁用监视;缓存包 generation 是不可变的。 - -## 通用 MCP 格式 - -`.mcp.json` 根对象是 `{ "mcpServers": { ... } }`。stdio 条目只接受可选的 `type: "stdio"`、`command`、`args` 和 `env`;HTTP 条目只接受 `type: "http"`、`url` 和 `headers`。字符串值在插件加载时支持严格的 `${NAME}` 进程环境变量展开;缺失变量会使该次加载失败。HTTP URL 映射到现有 MCP client 的 `streamable-http` transport;stdio 条目以已准备的包目录作为 `cwd`。 - -未知字段会被拒绝,包括 OAuth 字段与 `auth` 对象。不提供 `CLAUDE_PLUGIN_ROOT` 展开或兼容层。完成格式转换后,现有 `dsh-mcp-client` 独占 transport 创建、连接诊断、工具同步、调用和断开生命周期。Repository 声明的 server 会启用其严格启动模式:插件激活会等待初始连接与工具同步,因此首个模型请求会看到已完整注册的初始工具 generation;网络、子进程、发现或注册失败则会拒绝候选 repository generation,而不是在缺少已声明工具的情况下静默激活。 - -## 导出形状 - -Namespace 插件:具名导出 `name`/`inject`/`apply`、准备阶段常量和 `prepareDshPlugin`,不提供 default export。本包还提供 `dsh-plugin-prepare` 可执行文件和 invariant companion。 - -## 模型体验 - -### Repository skill - -#### 模型看到什么 - -通过 `dsh-tool-skill` 间接呈现:已准备且允许模型调用的 skill 会按其声明的名称和描述进入该消费方记录到日志的目录及所选指令正文表面。消费方的确切 schema 见生成的 [`skill` 工具目录](../../../docs/tool-catalog.md#deepseek-aidsh-tool-skill)。 - -#### Token 影响 - -有条件且随数据变化:每个可见的 repository skill 增加一行受限长度的目录项;加载一个 skill 会把其当前完整指令正文和资源基址指引加入保留的工具历史。 - -#### KV Cache 影响 - -稳定的已准备插件集合保持前缀稳定。添加、移除或替换 repository 插件可能使消费方追加替换目录,并影响后续请求前缀。 - -### Repository MCP 工具 - -#### 模型看到什么 - -通过 `dsh-mcp-client` 间接呈现:每个已连接 server 都贡献带 server 限定名的工具 schema;调用会保留该 client 的规范 MCP 结果和渲染。 - -#### Token 影响 - -取决于连接成功和远端工具列表;schema 会在当前工具视图中的请求上重复出现,而调用与结果会留在历史中直至压缩(compaction)。 - -#### KV Cache 影响 - -稳定的已连接工具列表保持前缀稳定。插件生命周期或 MCP 工具列表变化可能从首个受影响定义开始改变后续工具 schema 前缀。 - -### Repository 代码 - -#### 模型看到什么 - -取决于数据。受信任的 Cordis 入口可以通过其声明的服务和事件贡献任意可用的 DSH 行为,包括工具、提示词片段、策略、命令和转换。每项模型可见贡献仍受所属 DSH seam 的日志与生命周期约定约束。 - -#### Token 影响 - -由入口贡献的服务和注册决定;repository 格式本身不添加模型内容。 - -#### KV Cache 影响 - -稳定的注册会保留所属表面的正常前缀行为。加载、移除或替换精确的 repository generation,可能改变受该插件影响的任意前缀。 - -## 已知限制与暂缓事项 - -- **没有代码沙箱**:`dsh.entry`、NPM 依赖和包生命周期脚本以 DSH 宿主权限执行;必须信任该 repository。 -- **入口专用服务依赖不会预先门控**:生成的包装层无法在导入入口模块前声明其 `inject`。除 skill 或 MCP 隐含的服务外,其他任何服务在包装层挂载入口时都必须已经存在,否则该 repository generation 会被拒绝。 -- **没有 MCP 认证协议**:静态 header 可以使用环境变量展开,但带 OAuth 的定义会被拒绝,私有 server 登录流程不在此实现。 -- **生成资源是不可变运行时输入**:repository cache generation 不受监视;必须改变 source、ref、path 或配置才能选择另一份已准备 generation。 diff --git a/packages/self-modification/repository-plugin/package.json b/packages/self-modification/repository-plugin/package.json deleted file mode 100644 index f20ec986c2..0000000000 --- a/packages/self-modification/repository-plugin/package.json +++ /dev/null @@ -1,73 +0,0 @@ -{ - "name": "@deepseek-ai/dsh-repository-plugin", - "description": "Trusted repository package format and Cordis runtime for DeepSeek Harness", - "version": "0.0.1", - "private": true, - "type": "module", - "main": "lib/index.js", - "types": "lib/types/index.d.ts", - "bin": { - "dsh-plugin-prepare": "./lib/bin.js" - }, - "exports": { - ".": { - "types": "./lib/types/index.d.ts", - "default": "./lib/index.js" - }, - "./invariant": { - "types": "./lib/types/invariant.d.ts", - "default": "./lib/invariant.js" - }, - "./src/*": "./src/*", - "./package.json": "./package.json" - }, - "files": [ - "lib/index.js", - "lib/invariant.js", - "lib/bin.js", - "lib/types/**/*.d.ts" - ], - "license": "BSD-3-Clause", - "peerDependencies": { - "@cordisjs/plugin-loader": "^1.0.0-rc.5", - "@deepseek-ai/dsh-invariants": "^0.0.1", - "@deepseek-ai/dsh-mcp-client": "^0.0.1", - "@deepseek-ai/dsh-paths": "^0.0.1", - "@deepseek-ai/dsh-skill-local": "^0.0.1", - "cordis": "^4.0.0-rc.7" - }, - "peerDependenciesMeta": { - "@cordisjs/plugin-loader": { - "optional": true - }, - "@deepseek-ai/dsh-invariants": { - "optional": true - }, - "@deepseek-ai/dsh-mcp-client": { - "optional": true - }, - "@deepseek-ai/dsh-paths": { - "optional": true - }, - "@deepseek-ai/dsh-skill-local": { - "optional": true - }, - "cordis": { - "optional": true - } - }, - "dependencies": { - "zod": "^4.4.3" - }, - "devDependencies": { - "@cordisjs/plugin-loader": "workspace:^", - "@deepseek-ai/dsh-invariants": "workspace:^", - "@deepseek-ai/dsh-mcp-client": "workspace:^", - "@deepseek-ai/dsh-paths": "workspace:^", - "@deepseek-ai/dsh-skill": "workspace:^", - "@deepseek-ai/dsh-skill-local": "workspace:^", - "@deepseek-ai/dsh-system-prompt": "workspace:^", - "@deepseek-ai/dsh-tools": "workspace:^", - "cordis": "^4.0.0-rc.7" - } -} diff --git a/packages/self-modification/repository-plugin/src/bin.ts b/packages/self-modification/repository-plugin/src/bin.ts deleted file mode 100644 index a1787ff090..0000000000 --- a/packages/self-modification/repository-plugin/src/bin.ts +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env node - -/** Command-line entry that prepares the current `.dsh-plugin` package. @module */ - -import { prepareDshPlugin } from './format.ts' - -try { - await prepareDshPlugin() -} catch (error) { - process.stderr.write(`dsh-plugin-prepare: ${error instanceof Error ? error.message : String(error)}\n`) - process.exitCode = 1 -} diff --git a/packages/self-modification/repository-plugin/src/format.ts b/packages/self-modification/repository-plugin/src/format.ts deleted file mode 100644 index 7af948595d..0000000000 --- a/packages/self-modification/repository-plugin/src/format.ts +++ /dev/null @@ -1,249 +0,0 @@ -/** - * Trusted repository-package preparation and prepared-manifest validation. - * @module - */ - -import { cp, copyFile, mkdir, mkdtemp, readFile, realpath, rename, rm, stat, writeFile } from 'node:fs/promises' -import { dirname, isAbsolute, join, relative, resolve, sep } from 'node:path' -import { z } from 'zod' -import { parseMcpDocument } from './mcp.ts' - -/** Fixed module filename loaded from an installed prepared plugin package. */ -export const PREPARED_ENTRY_FILENAME = 'dsh-plugin.mjs' -/** Fixed directory containing copied static plugin assets. */ -export const PREPARED_ASSET_DIRECTORY = 'dsh-plugin-assets' -/** Loader builtin used by every generated repository wrapper. */ -export const REPOSITORY_PLUGIN_BUILTIN = 'dsh-repository-plugin' -/** Dependency-provided command that repository package `prepack` lifecycles must invoke. */ -export const REPOSITORY_PLUGIN_PREPARE_COMMAND = 'dsh-plugin-prepare' -/** Published package whose direct development dependency supplies the prepare command. */ -export const REPOSITORY_PLUGIN_PACKAGE_NAME = '@deepseek-ai/dsh-repository-plugin' - -/** - * Whether a package lifecycle declaration names the preparation dependency's helper. - * @param script - package-authored lifecycle command. - * @returns true when the required helper command is present. - */ -export function hasRepositoryPrepareCommand(script: string): boolean { - return script.includes(REPOSITORY_PLUGIN_PREPARE_COMMAND) -} - -const prepackSchema = z.string().min(1).refine( - hasRepositoryPrepareCommand, - { message: `must invoke ${REPOSITORY_PLUGIN_PREPARE_COMMAND}` }, -) - -const sourceMetadataSchema = z.object({ - skills: z.array(z.string().min(1)).default([]), - mcpServers: z.string().min(1).optional(), - entry: z.string().min(1).optional(), -}).strict().refine(value => value.skills.length > 0 || value.mcpServers !== undefined || value.entry !== undefined, { - message: 'declare at least one skill root, mcpServers file, or compiled entry', -}) -const sourcePackageSchema = z.looseObject({ - name: z.string().min(1), - devDependencies: z.looseObject({ - [REPOSITORY_PLUGIN_PACKAGE_NAME]: z.string().min(1), - }), - scripts: z.looseObject({ - prepack: prepackSchema, - }), - dsh: sourceMetadataSchema, -}) -const preparedManifestSchema = z.object({ - name: z.string().min(1), - skills: z.array(z.string().min(1)), - mcpServers: z.string().min(1).optional(), - entry: z.string().min(1).optional(), -}).strict() -const preparedConfigSchema = z.object({ - // Wrappers pass import.meta.url, which is always file: for an installed - // package; any other scheme would only fail later inside fileURLToPath with - // an uncontextualized TypeError, so reject it at this validation boundary. - baseUrl: z.url({ protocol: /^file$/ }), - manifest: preparedManifestSchema, -}).strict() - -/** Prepared manifest embedded in the generated wrapper. */ -export interface PreparedPluginManifest { - name: string - skills: string[] - mcpServers?: string - entry?: string -} - -/** Untrusted generated-wrapper config accepted by the DSH-owned runtime builtin. */ -export interface PreparedPluginConfig { - baseUrl: string - manifest: PreparedPluginManifest -} - -function formatZodError(label: string, error: z.ZodError): Error { - return new Error(`${label}:\n${z.prettifyError(error)}`) -} - -/** - * Validate the config passed by an installed prepared wrapper. - * @param value - wrapper-provided value crossing the file/module boundary. - * @returns a detached typed config. - */ -export function parsePreparedPluginConfig(value: unknown): PreparedPluginConfig { - const result = preparedConfigSchema.safeParse(value) - if (!result.success) throw formatZodError('invalid prepared DSH plugin', result.error) - return { - baseUrl: result.data.baseUrl, - manifest: { - name: result.data.manifest.name, - skills: result.data.manifest.skills, - ...result.data.manifest.mcpServers === undefined ? {} : { mcpServers: result.data.manifest.mcpServers }, - ...result.data.manifest.entry === undefined ? {} : { entry: result.data.manifest.entry }, - }, - } -} - -/** - * Whether `candidate` resolves outside `root` — the containment check shared - * by prepare-time asset copying and runtime prepared-path resolution. - * @param root - directory that must contain the candidate. - * @param candidate - absolute path to test. - * @returns true when the candidate escapes the root. - */ -export function isOutside(root: string, candidate: string): boolean { - const path = relative(root, candidate) - /* v8 ignore next -- Different-drive Windows relative paths cannot be produced on POSIX coverage hosts. */ - return path === '..' || path.startsWith(`..${sep}`) || isAbsolute(path) -} - -async function sourcePath(pluginDirectory: string, sourceRoot: string, configured: string, kind: 'directory' | 'file'): Promise { - if (isAbsolute(configured)) throw new Error(`DSH plugin asset path must be relative: ${JSON.stringify(configured)}`) - let path: string - try { - path = await realpath(resolve(pluginDirectory, configured)) - } catch (cause) { - throw new Error(`DSH plugin asset does not exist: ${JSON.stringify(configured)}`, { cause }) - } - if (isOutside(sourceRoot, path)) { - throw new Error(`DSH plugin asset escapes its plugin source root: ${JSON.stringify(configured)}`) - } - const info = await stat(path) - if (kind === 'directory' ? !info.isDirectory() : !info.isFile()) { - throw new Error(`DSH plugin asset is not a ${kind}: ${JSON.stringify(configured)}`) - } - return path -} - -function wrapperSource(manifest: PreparedPluginManifest): string { - // The manifest is static, so the wrapper's service dependencies are too: - // declaring them gates the wrapper fiber until the composition provides - // them, which means the runtime's SkillLocal/McpClient children activate - // within the wrapper's own load epoch and their failures (duplicate - // provider names, damaged packages) reject the wrapper's Loader - // transaction instead of leaving a silently PENDING or FAILED child. - const inject = [ - 'loader', - ...manifest.skills.length > 0 ? ['skills'] : [], - ...manifest.mcpServers === undefined ? [] : ['tools'], - ] - const entryHelpers = manifest.entry === undefined ? [] : [ - 'function unwrap(exports) {', - ' const value = exports?.default ?? exports', - ' return value?.__esModule ? (value.default ?? value) : value', - '}', - ] - const entryApply = manifest.entry === undefined ? [] : [ - ' const repositoryPlugin = unwrap(await import(manifest.entry))', - " await mount(ctx, repositoryPlugin, 'repository Plugin entry')", - ] - return [ - '// Generated by dsh-plugin-prepare. Do not edit.', - `const manifest = ${JSON.stringify(manifest)}`, - '// Value mirror: Cordis const enum FiberState.ACTIVE; keep aligned with dsh-repository-plugin source.ts.', - 'const FIBER_ACTIVE = 2', - `export const name = ${JSON.stringify(manifest.name)}`, - `export const inject = ${JSON.stringify(inject)}`, - ...entryHelpers, - 'async function mount(ctx, plugin, label, config) {', - ' const fiber = ctx.plugin(plugin, config)', - ' await fiber', - ' if (fiber.state !== FIBER_ACTIVE) {', - ' const missing = Object.keys(fiber.inject).filter(service => fiber.ctx.get(service) === undefined)', - " throw new Error(`${label} did not activate (waiting for services: ${missing.join(', ') || 'unknown'})`)", - ' }', - '}', - 'export async function apply(ctx) {', - ` const runtime = ctx.loader.builtins[${JSON.stringify(REPOSITORY_PLUGIN_BUILTIN)}]`, - ` if (runtime === undefined) throw new Error(${JSON.stringify(`missing Cordis builtin ${REPOSITORY_PLUGIN_BUILTIN}`)})`, - " await mount(ctx, runtime, 'repository Plugin runtime', { baseUrl: import.meta.url, manifest })", - ...entryApply, - '}', - '', - ].join('\n') -} - -/** - * Validate and package one `.dsh-plugin` directory into copied assets plus a generated wrapper. - * Outputs are staged and committed by rename, but the final publish (remove - * old outputs, rename assets, rename entry) is not one atomic step: a crash - * mid-publish can leave assets without an entry or neither. Rerunning prepare - * repairs the package; partial outputs are never importable as a plugin. - * @param directory - `.dsh-plugin` package directory; defaults to the prepare process cwd. - * @returns the generated prepared manifest. - */ -export async function prepareDshPlugin(directory: string = process.cwd()): Promise { - const pluginDirectory = await realpath(resolve(directory)) - let packageValue: unknown - try { - packageValue = JSON.parse(await readFile(join(pluginDirectory, 'package.json'), 'utf8')) as unknown - } catch (cause) { - throw new Error(`failed to read DSH plugin package metadata in ${pluginDirectory}`, { cause }) - } - const parsed = sourcePackageSchema.safeParse(packageValue) - if (!parsed.success) throw formatZodError('invalid DSH plugin package.json', parsed.error) - - const sourceRoot = await realpath(dirname(pluginDirectory)) - const skillSources: string[] = [] - for (const configured of parsed.data.dsh.skills) { - const source = await sourcePath(pluginDirectory, sourceRoot, configured, 'directory') - if (!isOutside(source, pluginDirectory)) { - throw new Error(`DSH skill root cannot contain the .dsh-plugin package: ${JSON.stringify(configured)}`) - } - skillSources.push(source) - } - let mcpSource: string | undefined - if (parsed.data.dsh.mcpServers !== undefined) { - mcpSource = await sourcePath(pluginDirectory, sourceRoot, parsed.data.dsh.mcpServers, 'file') - parseMcpDocument(await readFile(mcpSource, 'utf8')) - } - let entry: string | undefined - if (parsed.data.dsh.entry !== undefined) { - const entrySource = await sourcePath(pluginDirectory, pluginDirectory, parsed.data.dsh.entry, 'file') - entry = `./${relative(pluginDirectory, entrySource).split(sep).join('/')}` - } - - const manifest: PreparedPluginManifest = { - name: parsed.data.name, - skills: skillSources.map((_, index) => `${PREPARED_ASSET_DIRECTORY}/skills/${index}`), - ...mcpSource === undefined ? {} : { mcpServers: `${PREPARED_ASSET_DIRECTORY}/.mcp.json` }, - ...entry === undefined ? {} : { entry }, - } - const staging = await mkdtemp(join(pluginDirectory, '.dsh-plugin-prepare-')) - try { - const stagedAssets = join(staging, PREPARED_ASSET_DIRECTORY) - await mkdir(join(stagedAssets, 'skills'), { recursive: true }) - await Promise.all(skillSources.map((source, index) => cp(source, join(stagedAssets, 'skills', String(index)), { - recursive: true, - force: false, - errorOnExist: true, - }))) - if (mcpSource !== undefined) await copyFile(mcpSource, join(stagedAssets, '.mcp.json')) - await writeFile(join(staging, PREPARED_ENTRY_FILENAME), wrapperSource(manifest)) - - await rm(join(pluginDirectory, PREPARED_ASSET_DIRECTORY), { recursive: true, force: true }) - await rm(join(pluginDirectory, PREPARED_ENTRY_FILENAME), { force: true }) - await rename(stagedAssets, join(pluginDirectory, PREPARED_ASSET_DIRECTORY)) - await rename(join(staging, PREPARED_ENTRY_FILENAME), join(pluginDirectory, PREPARED_ENTRY_FILENAME)) - } finally { - await rm(staging, { recursive: true, force: true }) - } - return manifest -} diff --git a/packages/self-modification/repository-plugin/src/index.ts b/packages/self-modification/repository-plugin/src/index.ts deleted file mode 100644 index 46a020f40a..0000000000 --- a/packages/self-modification/repository-plugin/src/index.ts +++ /dev/null @@ -1,147 +0,0 @@ -/** - * Trusted repository-package runtime for code, skills, and common MCP definitions. - * @module @deepseek-ai/dsh-repository-plugin - */ - -import { readFile, stat } from 'node:fs/promises' -import { dirname, isAbsolute, resolve } from 'node:path' -import { fileURLToPath } from 'node:url' -import type { Context } from 'cordis' -import type {} from '@cordisjs/plugin-loader' -import { RepositoryCache } from '@cordisjs/plugin-loader/repository' -import * as SkillLocal from '@deepseek-ai/dsh-skill-local' -import * as McpClient from '@deepseek-ai/dsh-mcp-client' -import { z } from 'zod' -import { - REPOSITORY_PLUGIN_BUILTIN, - isOutside, - parsePreparedPluginConfig, - type PreparedPluginConfig, -} from './format.ts' -import { parseMcpDocument, resolveMcpServers } from './mcp.ts' -import { - loadPreparedRepository, - resolveRepositoryCacheDirectory, - resolveRepositorySpecifier, -} from './source.ts' - -export { - PREPARED_ASSET_DIRECTORY, - PREPARED_ENTRY_FILENAME, - REPOSITORY_PLUGIN_BUILTIN, - REPOSITORY_PLUGIN_PACKAGE_NAME, - REPOSITORY_PLUGIN_PREPARE_COMMAND, - prepareDshPlugin, - type PreparedPluginManifest, -} from './format.ts' - -/** Cordis plugin name used by Loader diagnostics. */ -export const name = 'repository-plugin' -/** Loader service required to register the fixed prepared-wrapper builtin. */ -export const inject = ['loader'] - -/** Repository Plugin runtime and source-list configuration. */ -export interface Config { - /** GitHub repository sources with explicit refs and optional `.dsh-plugin` subpaths. */ - repositories?: string[] - /** Persistent generation cache; defaults to `$DSH_HOME/cache/repository-plugins`. */ - cacheDir?: string -} - -export const Config = z.object({ - repositories: z.array(z.string().min(1)).default([]), - cacheDir: z.string().min(1).optional(), -}).strict().default({ repositories: [] }) - -function preparedPath(baseUrl: string, configured: string): string { - if (isAbsolute(configured)) throw new Error(`prepared DSH plugin path must be relative: ${JSON.stringify(configured)}`) - const directory = dirname(fileURLToPath(baseUrl)) - const path = resolve(directory, configured) - if (isOutside(directory, path)) { - throw new Error(`prepared DSH plugin path escapes its package: ${JSON.stringify(configured)}`) - } - return path -} - -async function preparedDirectory(baseUrl: string, configured: string): Promise { - const path = preparedPath(baseUrl, configured) - // A manifest-declared skill root missing from the installed package (files/ - // .npmignore dropping generated outputs, a damaged cache entry) must fail - // the plugin load: the skill provider treats an absent root as legitimately - // empty, which would silently mount a skill-less plugin. - let info - try { - info = await stat(path) - } catch (cause) { - throw new Error(`prepared DSH plugin skill root is missing from the installed package: ${JSON.stringify(configured)}`, { cause }) - } - if (!info.isDirectory()) { - throw new Error(`prepared DSH plugin skill root is not a directory: ${JSON.stringify(configured)}`) - } - return path -} - -async function applyPrepared(ctx: Context, value: PreparedPluginConfig): Promise { - const config = parsePreparedPluginConfig(value) - const directory = dirname(fileURLToPath(config.baseUrl)) - const skillDirectories = await Promise.all(config.manifest.skills.map(path => preparedDirectory(config.baseUrl, path))) - const mcpConfigs = config.manifest.mcpServers === undefined - ? [] - : resolveMcpServers( - parseMcpDocument(await readFile(preparedPath(config.baseUrl, config.manifest.mcpServers), 'utf8')), - process.env, - directory, - // Schemastery call signatures collapse the parameter to `never` under - // NodeNext; ResolvedMcpServer matches the Config union by design. - ).map(input => McpClient.Config(input as never)) - - await ctx.effect(async function* () { - if (skillDirectories.length > 0) { - const skills = ctx.plugin(SkillLocal, { - providerName: `repository:${config.manifest.name}`, - includeDefaultRoots: false, - customSkillDirs: skillDirectories, - watch: false, - }) - await skills - yield skills.dispose - } - for (const mcpConfig of mcpConfigs) { - const mcp = ctx.plugin(McpClient, mcpConfig) - await mcp - yield mcp.dispose - } - }, `repository-plugin(${config.manifest.name})`) -} - -const preparedRuntime = { - name: 'repository-plugin-runtime', - apply: applyPrepared, -} - -/** - * Register the DSH-owned runtime as the Loader builtin used by fixed prepared wrappers. - * @param ctx - plugin context carrying the Loader service. - */ -export async function apply(ctx: Context, config: Config = {}): Promise { - if (ctx.loader.builtins[REPOSITORY_PLUGIN_BUILTIN] !== undefined) { - throw new Error(`Loader builtin ${REPOSITORY_PLUGIN_BUILTIN} is already registered`) - } - const repositories = (config.repositories ?? []).map(resolveRepositorySpecifier) - if (new Set(repositories).size !== repositories.length) { - throw new Error('repository sources must resolve to unique exact specifiers') - } - const cache = new RepositoryCache(resolveRepositoryCacheDirectory(config.cacheDir)) - await ctx.effect(async function* () { - ctx.loader.builtins[REPOSITORY_PLUGIN_BUILTIN] = preparedRuntime - yield () => { - if (ctx.loader.builtins[REPOSITORY_PLUGIN_BUILTIN] === preparedRuntime) { - Reflect.deleteProperty(ctx.loader.builtins, REPOSITORY_PLUGIN_BUILTIN) - } - } - for (const repository of repositories) { - const plugin = await loadPreparedRepository(ctx, cache, repository) - yield plugin.dispose - } - }, 'repository-plugin runtime and sources') -} diff --git a/packages/self-modification/repository-plugin/src/invariant.ts b/packages/self-modification/repository-plugin/src/invariant.ts deleted file mode 100644 index 410e8bf69e..0000000000 --- a/packages/self-modification/repository-plugin/src/invariant.ts +++ /dev/null @@ -1,30 +0,0 @@ -/** - * Package-owned invariant companion for `@deepseek-ai/dsh-repository-plugin`. - * @module @deepseek-ai/dsh-repository-plugin/invariant - */ - -/* jscpd:ignore-start */ -import type { Context } from 'cordis' -import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' - -const PACKAGE_NAME = '@deepseek-ai/dsh-repository-plugin' - -/** Cordis companion plugin name. */ -export const name = 'repository-plugin-invariant' -/** Service required before the companion can reserve package ownership. */ -export const inject = ['invariants'] - -/** - * No runtime invariant: the package owns no service state; Loader fibers and the existing skill - * and MCP owners expose the authoritative lifecycle relationships for its composed children. - */ -const install: InvariantInstaller = () => {} - -/** - * Register this package's invariant companion. - * @param ctx - Cordis context carrying the invariant service. - * @returns the installed registration's disposer after setup succeeds. - */ -export const apply = (ctx: Context): Promise<() => void> => - Promise.resolve(ctx.invariants.register(PACKAGE_NAME, install)) -/* jscpd:ignore-end */ diff --git a/packages/self-modification/repository-plugin/src/mcp.ts b/packages/self-modification/repository-plugin/src/mcp.ts deleted file mode 100644 index d2294fb5c6..0000000000 --- a/packages/self-modification/repository-plugin/src/mcp.ts +++ /dev/null @@ -1,156 +0,0 @@ -/** - * Parser for the common `.mcp.json` file consumed by prepared repository plugins. - * @module - */ - -import { z } from 'zod' - -/** - * Restates dsh-mcp-client's `SERVER_NAME_PATTERN` rather than importing it: - * the prepare bin must stay a zod-only module graph (no tools service, no MCP - * SDK). Exported so `repository-plugin.spec.ts` pins equality with the - * client's exported pattern — prepare-time validation cannot drift from the - * registry that enforces uniqueness. - */ -export const SERVER_NAME_PATTERN = /^[A-Za-z0-9_-]{1,32}$/ -const ENVIRONMENT_NAME_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/ -const PLACEHOLDER_PATTERN = /\$\{([^}]*)\}/g - -const stringMap = z.record(z.string(), z.string()) -const stdioServerSchema = z.object({ - type: z.literal('stdio').optional(), - command: z.string().min(1), - args: z.array(z.string()).optional(), - env: stringMap.optional(), -}).strict() -const httpServerSchema = z.object({ - type: z.literal('http'), - url: z.string().min(1), - headers: stringMap.optional(), -}).strict() -const documentSchema = z.object({ - mcpServers: z.record(z.string(), z.union([stdioServerSchema, httpServerSchema])), -}).strict() - -/** One supported server entry from the common `.mcp.json` format. */ -export type McpServerDefinition = z.infer | z.infer - -/** Parsed common MCP document before process-environment expansion. */ -export interface McpDocument { - mcpServers: Record -} - -/** Resolved input handed to the existing `dsh-mcp-client` Config schema. */ -export type ResolvedMcpServer = - | { - transport: 'stdio' - serverName: string - command: string - args: string[] - env: Record - cwd: string - failOnStartupError: true - } - | { - transport: 'streamable-http' - serverName: string - url: string - headers: Record - failOnStartupError: true - } - -function assertTemplate(value: string, location: string): void { - for (const match of value.matchAll(PLACEHOLDER_PATTERN)) { - const name = match[1] as string - if (!ENVIRONMENT_NAME_PATTERN.test(name)) { - throw new Error(`${location} contains an unsupported environment placeholder ${JSON.stringify(match[0])}`) - } - } - if (value.replace(PLACEHOLDER_PATTERN, '').includes('${')) { - throw new Error(`${location} contains an unterminated environment placeholder`) - } -} - -function visitStrings(serverName: string, definition: McpServerDefinition, visit: (value: string, location: string) => void): void { - if ('command' in definition) { - visit(definition.command, `mcpServers.${serverName}.command`) - definition.args?.forEach((value, index) => { visit(value, `mcpServers.${serverName}.args[${index}]`) }) - Object.entries(definition.env ?? {}).forEach(([name, value]) => { visit(value, `mcpServers.${serverName}.env.${name}`) }) - return - } - visit(definition.url, `mcpServers.${serverName}.url`) - Object.entries(definition.headers ?? {}).forEach(([name, value]) => { visit(value, `mcpServers.${serverName}.headers.${name}`) }) -} - -/** - * Parse and validate one common `.mcp.json` document without resolving environment values. - * @param content - UTF-8 JSON document. - * @returns the supported stdio and Streamable HTTP server definitions. - */ -export function parseMcpDocument(content: string): McpDocument { - let value: unknown - try { - value = JSON.parse(content) as unknown - } catch (cause) { - throw new Error('invalid .mcp.json: expected JSON', { cause }) - } - const result = documentSchema.safeParse(value) - if (!result.success) throw new Error(`invalid .mcp.json:\n${z.prettifyError(result.error)}`) - for (const [serverName, definition] of Object.entries(result.data.mcpServers)) { - if (!SERVER_NAME_PATTERN.test(serverName)) { - throw new Error(`invalid .mcp.json: server name ${JSON.stringify(serverName)} must match ${SERVER_NAME_PATTERN.source}`) - } - visitStrings(serverName, definition, assertTemplate) - } - return result.data -} - -function expand(value: string, environment: NodeJS.ProcessEnv, location: string): string { - return value.replace(PLACEHOLDER_PATTERN, (_placeholder, name: string) => { - const replacement = environment[name] - if (replacement === undefined) throw new Error(`${location} requires missing environment variable ${name}`) - return replacement - }) -} - -function expandMap(values: Record | undefined, environment: NodeJS.ProcessEnv, location: string): Record { - return Object.fromEntries(Object.entries(values ?? {}).map(([name, value]) => [ - name, - expand(value, environment, `${location}.${name}`), - ])) -} - -/** - * Resolve supported MCP definitions to inputs for the existing MCP client. - * @param document - validated common MCP document. - * @param environment - process environment used for exact `${NAME}` expansion. - * @param cwd - prepared plugin directory used for stdio child processes. - * @returns one existing-client config input per declared server. - */ -export function resolveMcpServers(document: McpDocument, environment: NodeJS.ProcessEnv, cwd: string): ResolvedMcpServer[] { - return Object.entries(document.mcpServers).map(([serverName, definition]) => { - if ('command' in definition) { - return { - transport: 'stdio', - serverName, - command: expand(definition.command, environment, `mcpServers.${serverName}.command`), - args: (definition.args ?? []).map((value, index) => expand(value, environment, `mcpServers.${serverName}.args[${index}]`)), - env: expandMap(definition.env, environment, `mcpServers.${serverName}.env`), - cwd, - failOnStartupError: true, - } - } - const url = expand(definition.url, environment, `mcpServers.${serverName}.url`) - const protocol = new URL(url).protocol - if (protocol !== 'http:' && protocol !== 'https:') { - throw new Error(`mcpServers.${serverName}.url must use http or https`) - } - return { - transport: 'streamable-http', - serverName, - url, - headers: expandMap(definition.headers, environment, `mcpServers.${serverName}.headers`), - failOnStartupError: true, - } - }) -} diff --git a/packages/self-modification/repository-plugin/src/source.ts b/packages/self-modification/repository-plugin/src/source.ts deleted file mode 100644 index 536025d6d7..0000000000 --- a/packages/self-modification/repository-plugin/src/source.ts +++ /dev/null @@ -1,130 +0,0 @@ -/** - * GitHub repository source validation and prepared-wrapper loading. - * @module - */ - -import { readFile } from 'node:fs/promises' -import { join, resolve } from 'node:path' -import { pathToFileURL } from 'node:url' -import type { Context, Fiber, FiberState, Plugin } from 'cordis' -import type { RepositoryCache } from '@cordisjs/plugin-loader/repository' -import { resolveDshHome } from '@deepseek-ai/dsh-paths' -import { z } from 'zod' -import { - PREPARED_ENTRY_FILENAME, - REPOSITORY_PLUGIN_PACKAGE_NAME, - REPOSITORY_PLUGIN_PREPARE_COMMAND, - hasRepositoryPrepareCommand, -} from './format.ts' - -// Value mirror: Cordis's const enum has no runtime object to import. Keep -// aligned with `packages/self-modification/tool-cordis/src/fiber-state.ts`. -const FIBER_ACTIVE = 2 as FiberState.ACTIVE - -/** Directory under the Harness home containing immutable repository generations. */ -export const DEFAULT_REPOSITORY_CACHE_DIRECTORY = 'repository-plugins' - -// The ref segment excludes `#` so `github:o/r#a#b` fails here — at the config -// parser, with the syntax the error message promises — instead of inside the -// cache's pnpm install ('misconfiguration fails loud at the earliest -// resolvable point'). -const GITHUB_SOURCE_PATTERN = /^github:([^/\s#&]+)\/([^/\s#&]+)#([^\s#&]+)(?:&path:(\/[^\s&]+))?$/ -const installedPackageSchema = z.looseObject({ - devDependencies: z.looseObject({ - [REPOSITORY_PLUGIN_PACKAGE_NAME]: z.string().min(1), - }), - scripts: z.looseObject({ - prepack: z.string().min(1).refine( - hasRepositoryPrepareCommand, - { message: `must invoke ${REPOSITORY_PLUGIN_PREPARE_COMMAND}` }, - ), - }), -}) - -function validPluginPath(path: string): boolean { - const segments = path.split('/').slice(1) - return segments.length > 0 - && segments.at(-1) === '.dsh-plugin' - && segments.every(segment => segment.length > 0 && segment !== '.' && segment !== '..') -} - -/** - * Normalize one user-facing GitHub source to the exact pnpm dependency specifier. - * @param configured - `github:owner/repo#ref` with an optional `&path:/.../.dsh-plugin`. - * @returns the exact specifier, with the root `.dsh-plugin` subpath added when omitted. - * @throws when the GitHub owner, repository, explicit ref, or plugin subpath is invalid. - */ -export function resolveRepositorySpecifier(configured: string): string { - const match = GITHUB_SOURCE_PATTERN.exec(configured) - if (match === null) { - throw new Error(`repository source must use github:owner/repo# with an optional &path:/.../.dsh-plugin: ${JSON.stringify(configured)}`) - } - const path = match[4] - if (path !== undefined && !validPluginPath(path)) { - throw new Error(`repository source path must be an absolute repository subpath ending in .dsh-plugin without empty, . or .. segments: ${JSON.stringify(path)}`) - } - return path === undefined ? `${configured}&path:/.dsh-plugin` : configured -} - -/** - * Resolve the persistent repository cache root. - * @param configured - explicit cache directory, or undefined for `$DSH_HOME/cache/repository-plugins`. - * @returns an absolute cache directory. - */ -export function resolveRepositoryCacheDirectory(configured: string | undefined): string { - return resolve(configured ?? join(resolveDshHome(), 'cache', DEFAULT_REPOSITORY_CACHE_DIRECTORY)) -} - -async function assertInstalledPackageMetadata(directory: string): Promise { - let value: unknown - try { - value = JSON.parse(await readFile(join(directory, 'package.json'), 'utf8')) as unknown - } catch (cause) { - throw new Error(`failed to read installed DSH plugin package metadata in ${directory}`, { cause }) - } - const result = installedPackageSchema.safeParse(value) - if (!result.success) { - throw new Error([ - `installed DSH plugin package must declare a non-empty scripts.prepack that invokes ${JSON.stringify(REPOSITORY_PLUGIN_PREPARE_COMMAND)}, and declare ${JSON.stringify(REPOSITORY_PLUGIN_PACKAGE_NAME)} in devDependencies:`, - z.prettifyError(result.error), - 'Clear the matching repository cache generation before retrying the same source, or select a different exact source/ref/path after fixing the package.', - ].join('\n')) - } -} - -/** - * Load one exact repository generation's generated wrapper as a child Cordis fiber. - * @param ctx - repository runtime context that owns the child. - * @param cache - package-manager-native immutable repository cache. - * @param specifier - normalized exact pnpm dependency specifier. - * @returns the settled prepared-wrapper fiber. - * @throws when installation, wrapper import, manifest validation, or child registration fails. - */ -export async function loadPreparedRepository( - ctx: Context, - cache: Pick, - specifier: string, -): Promise { - const directory = await cache.resolve(specifier) - const filename = join(directory, PREPARED_ENTRY_FILENAME) - try { - await assertInstalledPackageMetadata(directory) - const plugin = await import(/* @vite-ignore */pathToFileURL(filename).href) as Plugin - const fiber = ctx.plugin(plugin) - await fiber - // Awaiting a service-gated fiber returns while it is still PENDING (the - // generated wrapper injects `skills`/`tools` per its manifest). This - // runtime commits the repository configuration transactionally, so a - // composition that never provides a required service must reject the - // transaction here — not settle ACTIVE with a silently pending child. - if (fiber.state !== FIBER_ACTIVE) { - const missing = Object.keys(fiber.inject).filter(service => fiber.ctx.get(service) === undefined) - /* v8 ignore next 2 -- the 'unknown' arm needs a service to appear after the state read; not deterministically stageable. */ - const detail = missing.join(', ') || 'unknown' - throw new Error(`prepared wrapper did not activate (waiting for services: ${detail})`) - } - return await fiber - } catch (cause) { - throw new Error(`failed to load prepared repository Plugin ${JSON.stringify(specifier)} from ${filename}`, { cause }) - } -} diff --git a/packages/self-modification/repository-plugin/tests/mcp-format.spec.ts b/packages/self-modification/repository-plugin/tests/mcp-format.spec.ts deleted file mode 100644 index 709c1a2c4b..0000000000 --- a/packages/self-modification/repository-plugin/tests/mcp-format.spec.ts +++ /dev/null @@ -1,121 +0,0 @@ -import { describe, expect, it } from 'vitest' -import { SERVER_NAME_PATTERN as CLIENT_SERVER_NAME_PATTERN } from '@deepseek-ai/dsh-mcp-client' -import { SERVER_NAME_PATTERN, parseMcpDocument, resolveMcpServers } from '../src/mcp.ts' - -describe('repository plugin common .mcp.json support', () => { - it('validates server names with exactly the pattern the MCP client registry enforces', () => { - // mcp.ts restates the pattern to keep the prepare bin's module graph - // zod-only; this pin is the drift guard. - expect(SERVER_NAME_PATTERN.source).toBe(CLIENT_SERVER_NAME_PATTERN.source) - expect(SERVER_NAME_PATTERN.flags).toBe(CLIENT_SERVER_NAME_PATTERN.flags) - }) - - it('maps Expo-style HTTP servers to the existing Streamable HTTP client config', () => { - const document = parseMcpDocument(JSON.stringify({ - mcpServers: { - expo: { type: 'http', url: 'https://mcp.expo.dev/mcp' }, - }, - })) - - expect(resolveMcpServers(document, {}, '/plugin')).toEqual([{ - transport: 'streamable-http', - serverName: 'expo', - url: 'https://mcp.expo.dev/mcp', - headers: {}, - failOnStartupError: true, - }]) - }) - - it('maps DataJunction-style stdio servers and expands exact environment placeholders', () => { - const document = parseMcpDocument(JSON.stringify({ - mcpServers: { - datajunction: { - command: 'dj-mcp', - args: ['--endpoint', '${DJ_API_URL}'], - env: { DJ_API_URL: '${DJ_API_URL}' }, - }, - }, - })) - - expect(resolveMcpServers(document, { DJ_API_URL: 'http://localhost:8000' }, '/plugin')).toEqual([{ - transport: 'stdio', - serverName: 'datajunction', - command: 'dj-mcp', - args: ['--endpoint', 'http://localhost:8000'], - env: { DJ_API_URL: 'http://localhost:8000' }, - cwd: '/plugin', - failOnStartupError: true, - }]) - }) - - it('fails loud when a declared environment value is absent', () => { - const document = parseMcpDocument(JSON.stringify({ - mcpServers: { datajunction: { command: 'dj-mcp', env: { DJ_API_URL: '${DJ_API_URL}' } } }, - })) - - expect(() => resolveMcpServers(document, {}, '/plugin')).toThrow('missing environment variable DJ_API_URL') - }) - - it('accepts explicit stdio defaults and expands HTTP URLs and headers', () => { - const document = parseMcpDocument(JSON.stringify({ - mcpServers: { - local: { type: 'stdio', command: 'local-mcp' }, - remote: { - type: 'http', - url: 'http://${MCP_HOST}/mcp', - headers: { Authorization: 'Bearer ${MCP_TOKEN}' }, - }, - }, - })) - - expect(resolveMcpServers(document, { MCP_HOST: 'localhost:3000', MCP_TOKEN: 'test-token' }, '/plugin')).toEqual([ - { - transport: 'stdio', - serverName: 'local', - command: 'local-mcp', - args: [], - env: {}, - cwd: '/plugin', - failOnStartupError: true, - }, - { - transport: 'streamable-http', - serverName: 'remote', - url: 'http://localhost:3000/mcp', - headers: { Authorization: 'Bearer test-token' }, - failOnStartupError: true, - }, - ]) - }) - - it('rejects malformed JSON, server names, placeholders, and non-HTTP URLs', () => { - expect(() => parseMcpDocument('{')).toThrow('expected JSON') - expect(() => parseMcpDocument(JSON.stringify({ - mcpServers: { 'bad name': { command: 'server' } }, - }))).toThrow('server name') - expect(() => parseMcpDocument(JSON.stringify({ - mcpServers: { bad: { command: '${BAD-NAME}' } }, - }))).toThrow('unsupported environment placeholder') - expect(() => parseMcpDocument(JSON.stringify({ - mcpServers: { bad: { command: '${UNFINISHED' } }, - }))).toThrow('unterminated environment placeholder') - const ftp = parseMcpDocument(JSON.stringify({ - mcpServers: { remote: { type: 'http', url: 'ftp://example.test/mcp' } }, - })) - expect(() => resolveMcpServers(ftp, {}, '/plugin')).toThrow('must use http or https') - }) - - it('rejects Work IQ OAuth fields instead of treating them as unauthenticated HTTP', () => { - expect(() => parseMcpDocument(JSON.stringify({ - mcpServers: { - workiq: { - type: 'http', - url: 'https://workiq.microsoft.com/mcp', - oauthClientId: 'client-id', - oauthPublicClient: true, - auth: { redirectPort: 3317 }, - }, - }, - }))).toThrow('invalid .mcp.json') - }) -}) diff --git a/packages/self-modification/repository-plugin/tests/repository-plugin.spec.ts b/packages/self-modification/repository-plugin/tests/repository-plugin.spec.ts deleted file mode 100644 index 086616f2f9..0000000000 --- a/packages/self-modification/repository-plugin/tests/repository-plugin.spec.ts +++ /dev/null @@ -1,676 +0,0 @@ -import { mkdir, mkdtemp, readFile, rm, writeFile } from 'node:fs/promises' -import { tmpdir } from 'node:os' -import { join, relative, resolve } from 'node:path' -import { pathToFileURL } from 'node:url' -import { afterEach, describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' -import Loader from '@cordisjs/plugin-loader' -import { RepositoryCache } from '@cordisjs/plugin-loader/repository' -import SkillService from '@deepseek-ai/dsh-skill' -import SystemPrompt from '@deepseek-ai/dsh-system-prompt' -import ToolRegistry from '@deepseek-ai/dsh-tools' -import InvariantService from '@deepseek-ai/dsh-invariants' -import * as RepositoryPlugin from '@deepseek-ai/dsh-repository-plugin' -import * as RepositoryPluginInvariant from '@deepseek-ai/dsh-repository-plugin/invariant' -import { parsePreparedPluginConfig } from '../src/format.ts' -import { - loadPreparedRepository, - resolveRepositoryCacheDirectory, - resolveRepositorySpecifier, -} from '../src/source.ts' - -const roots: string[] = [] - -async function temporaryDirectory(name: string): Promise { - const directory = await mkdtemp(join(tmpdir(), `dsh-repository-plugin-${name}-`)) - roots.push(directory) - return directory -} - -async function writePlugin( - root: string, - name: string, - dsh: Record, - prepack = RepositoryPlugin.REPOSITORY_PLUGIN_PREPARE_COMMAND, - devDependencies: Record = { - [RepositoryPlugin.REPOSITORY_PLUGIN_PACKAGE_NAME]: '0.0.1', - }, -): Promise { - const directory = join(root, '.dsh-plugin') - await mkdir(directory, { recursive: true }) - await writeFile(join(directory, 'package.json'), `${JSON.stringify({ - name, - version: '0.0.0', - devDependencies, - scripts: { prepack }, - dsh, - }, undefined, 2)}\n`) - return directory -} - -async function writeSkill(root: string, name: string): Promise { - const directory = join(root, name) - await mkdir(directory, { recursive: true }) - await writeFile(join(directory, 'SKILL.md'), `---\nname: ${name}\ndescription: Repository fixture skill.\n---\n\nStatic instructions.\n`) -} - -afterEach(async () => { - vi.restoreAllMocks() - vi.unstubAllEnvs() - await Promise.all(roots.splice(0).map(root => rm(root, { recursive: true, force: true }))) -}) - -describe('dsh-plugin-prepare', () => { - it('copies declared static assets and emits the fixed import-free wrapper', async () => { - const root = await temporaryDirectory('prepare') - await writeSkill(join(root, 'skills'), 'repository-fixture') - await writeFile(join(root, '.mcp.json'), JSON.stringify({ - mcpServers: { - expo: { type: 'http', url: 'https://mcp.expo.dev/mcp' }, - }, - })) - const directory = await writePlugin(root, 'fixture-plugin', { - skills: ['../skills'], - mcpServers: '../.mcp.json', - }) - - await expect(RepositoryPlugin.prepareDshPlugin(directory)).resolves.toEqual({ - name: 'fixture-plugin', - skills: ['dsh-plugin-assets/skills/0'], - mcpServers: 'dsh-plugin-assets/.mcp.json', - }) - const wrapper = await readFile(join(directory, RepositoryPlugin.PREPARED_ENTRY_FILENAME), 'utf8') - expect(wrapper).toContain(`ctx.loader.builtins["${RepositoryPlugin.REPOSITORY_PLUGIN_BUILTIN}"]`) - // Import-free means no static AND no dynamic imports; `import.meta.url` - // (no whitespace, no call parenthesis) is the one allowed appearance. - expect(wrapper).not.toMatch(/\b(?:import|from)\s|\bimport\s*\(/) - await expect(readFile(join(directory, 'dsh-plugin-assets/skills/0/repository-fixture/SKILL.md'), 'utf8')) - .resolves.toContain('Static instructions.') - await expect(readFile(join(directory, 'dsh-plugin-assets/.mcp.json'), 'utf8')) - .resolves.toContain('mcp.expo.dev') - }) - - it('preserves a compiled package entry and accepts a build before the package prepare command', async () => { - const root = await temporaryDirectory('compiled-entry') - const directory = await writePlugin(root, 'compiled-entry-fixture', { - entry: './lib/plugin.mjs', - }, 'npm run build && dsh-plugin-prepare') - await mkdir(join(directory, 'lib')) - await writeFile(join(directory, 'lib/plugin.mjs'), 'export default { name: "compiled-entry" }\n') - - await expect(RepositoryPlugin.prepareDshPlugin(directory)).resolves.toEqual({ - name: 'compiled-entry-fixture', - skills: [], - entry: './lib/plugin.mjs', - }) - const wrapper = await readFile(join(directory, RepositoryPlugin.PREPARED_ENTRY_FILENAME), 'utf8') - expect(wrapper).toContain('await import(manifest.entry)') - expect(wrapper).toContain('"entry":"./lib/plugin.mjs"') - }) - - it('rejects unsupported OAuth MCP metadata before publishing outputs', async () => { - const root = await temporaryDirectory('oauth') - await writeFile(join(root, '.mcp.json'), JSON.stringify({ - mcpServers: { - workiq: { - type: 'http', - url: 'https://workiq.microsoft.com/mcp', - oauthClientId: 'client-id', - oauthPublicClient: true, - auth: { redirectPort: 3317 }, - }, - }, - })) - const directory = await writePlugin(root, 'unsupported-oauth', { mcpServers: '../.mcp.json' }) - - await expect(RepositoryPlugin.prepareDshPlugin(directory)).rejects.toThrow('invalid .mcp.json') - await expect(readFile(join(directory, RepositoryPlugin.PREPARED_ENTRY_FILENAME), 'utf8')).rejects.toMatchObject({ code: 'ENOENT' }) - }) - - it('rejects invalid metadata, missing assets, wrong asset types, and escaped paths', async () => { - const malformedRoot = await temporaryDirectory('malformed-package') - const malformed = join(malformedRoot, '.dsh-plugin') - await mkdir(malformed) - await writeFile(join(malformed, 'package.json'), '{') - await expect(RepositoryPlugin.prepareDshPlugin(malformed)).rejects.toThrow('failed to read DSH plugin package metadata') - - const lifecycleRoot = await temporaryDirectory('wrong-lifecycle') - const lifecycle = join(lifecycleRoot, '.dsh-plugin') - await mkdir(lifecycle) - await writeFile(join(lifecycle, 'package.json'), JSON.stringify({ - name: 'wrong-lifecycle', - scripts: { prepare: 'dsh-plugin-prepare' }, - dsh: { skills: ['../skills'] }, - })) - await expect(RepositoryPlugin.prepareDshPlugin(lifecycle)).rejects.toThrow('prepack') - - const skippedPrepareRoot = await temporaryDirectory('skipped-prepare') - const skippedPrepare = await writePlugin( - skippedPrepareRoot, - 'skipped-prepare', - { skills: ['../skills'] }, - 'npm run build', - ) - await expect(RepositoryPlugin.prepareDshPlugin(skippedPrepare)).rejects.toThrow('must invoke dsh-plugin-prepare') - - const undeclaredPrepareRoot = await temporaryDirectory('undeclared-prepare-dependency') - const undeclaredPrepare = await writePlugin( - undeclaredPrepareRoot, - 'undeclared-prepare-dependency', - { skills: ['../skills'] }, - RepositoryPlugin.REPOSITORY_PLUGIN_PREPARE_COMMAND, - {}, - ) - await expect(RepositoryPlugin.prepareDshPlugin(undeclaredPrepare)) - .rejects.toThrow(RepositoryPlugin.REPOSITORY_PLUGIN_PACKAGE_NAME) - - const emptyRoot = await temporaryDirectory('empty-metadata') - const empty = await writePlugin(emptyRoot, 'empty', {}) - await expect(RepositoryPlugin.prepareDshPlugin(empty)).rejects.toThrow('declare at least one skill root, mcpServers file, or compiled entry') - - const missingRoot = await temporaryDirectory('missing-asset') - const missing = await writePlugin(missingRoot, 'missing', { skills: ['../missing'] }) - await expect(RepositoryPlugin.prepareDshPlugin(missing)).rejects.toThrow('asset does not exist') - - const absoluteRoot = await temporaryDirectory('absolute-asset') - const absolute = await writePlugin(absoluteRoot, 'absolute', { skills: [absoluteRoot] }) - await expect(RepositoryPlugin.prepareDshPlugin(absolute)).rejects.toThrow('asset path must be relative') - - const wrongTypeRoot = await temporaryDirectory('wrong-type') - await writeFile(join(wrongTypeRoot, 'not-a-directory'), 'text') - const wrongType = await writePlugin(wrongTypeRoot, 'wrong-type', { skills: ['../not-a-directory'] }) - await expect(RepositoryPlugin.prepareDshPlugin(wrongType)).rejects.toThrow('asset is not a directory') - - const wrongMcpRoot = await temporaryDirectory('wrong-mcp-type') - await mkdir(join(wrongMcpRoot, 'not-a-file')) - const wrongMcp = await writePlugin(wrongMcpRoot, 'wrong-mcp', { mcpServers: '../not-a-file' }) - await expect(RepositoryPlugin.prepareDshPlugin(wrongMcp)).rejects.toThrow('asset is not a file') - - const containingRoot = await temporaryDirectory('containing-root') - const containing = await writePlugin(containingRoot, 'containing', { skills: ['..'] }) - await expect(RepositoryPlugin.prepareDshPlugin(containing)).rejects.toThrow('cannot contain the .dsh-plugin package') - - const escapedRoot = await temporaryDirectory('escaped-root') - const outside = await temporaryDirectory('outside-root') - await writeSkill(outside, 'outside-skill') - const escaped = await writePlugin(escapedRoot, 'escaped', { skills: [relative(join(escapedRoot, '.dsh-plugin'), outside)] }) - await expect(RepositoryPlugin.prepareDshPlugin(escaped)).rejects.toThrow('escapes its plugin source root') - - const escapedEntryRoot = await temporaryDirectory('escaped-entry') - await writeFile(join(escapedEntryRoot, 'outside.mjs'), 'export default {}\n') - const escapedEntry = await writePlugin(escapedEntryRoot, 'escaped-entry', { entry: '../outside.mjs' }) - await expect(RepositoryPlugin.prepareDshPlugin(escapedEntry)).rejects.toThrow('escapes its plugin source root') - }) - - it('validates prepared wrapper configs with optional MCP assets and code entries', () => { - expect(() => parsePreparedPluginConfig({})).toThrow('invalid prepared DSH plugin') - expect(parsePreparedPluginConfig({ - baseUrl: 'file:///plugin/dsh-plugin.mjs', - manifest: { name: 'fixture', skills: [], mcpServers: 'dsh-plugin-assets/.mcp.json', entry: './lib/plugin.js' }, - })).toEqual({ - baseUrl: 'file:///plugin/dsh-plugin.mjs', - manifest: { name: 'fixture', skills: [], mcpServers: 'dsh-plugin-assets/.mcp.json', entry: './lib/plugin.js' }, - }) - }) -}) - -describe('prepared repository plugin Loader composition', () => { - it('mounts and removes copied skills through the real Loader and skill-local provider', async () => { - const root = await temporaryDirectory('loader') - await writeSkill(join(root, 'skills'), 'loaded-from-repository') - const directory = await writePlugin(root, 'loader-fixture', { skills: ['../skills'] }) - await RepositoryPlugin.prepareDshPlugin(directory) - - const ctx = new Context() - ctx.baseUrl = pathToFileURL(directory).href + '/' - await ctx.plugin(Loader) - await ctx.plugin(SkillService) - const registrar = ctx.plugin(RepositoryPlugin) - await registrar - expect(ctx.loader.builtins[RepositoryPlugin.REPOSITORY_PLUGIN_BUILTIN]).toBeDefined() - - const id = await ctx.loader.create({ - name: pathToFileURL(join(directory, RepositoryPlugin.PREPARED_ENTRY_FILENAME)).href, - }) - await ctx.loader.await() - await expect(ctx.skills.get('loaded-from-repository')).resolves.toMatchObject({ - name: 'loaded-from-repository', - provider: 'repository:loader-fixture', - content: 'Static instructions.', - }) - - await ctx.loader.remove(id) - await expect(ctx.skills.get('loaded-from-repository')).resolves.toBeUndefined() - await registrar.dispose() - expect(ctx.loader.builtins[RepositoryPlugin.REPOSITORY_PLUGIN_BUILTIN]).toBeUndefined() - await ctx.fiber.dispose() - }) - - it('mounts and removes the repository package code entry through the real Loader', async () => { - const root = await temporaryDirectory('code-loader') - const directory = await writePlugin(root, 'code-loader-fixture', { entry: './lib/plugin.mjs' }) - await mkdir(join(directory, 'lib')) - await writeFile(join(directory, 'lib/plugin.mjs'), [ - "export const name = 'repository-code-proof'", - 'export function apply(ctx) {', - " ctx.provide('repositoryCodeProof', { source: 'compiled-entry' })", - '}', - '', - ].join('\n')) - await RepositoryPlugin.prepareDshPlugin(directory) - - const ctx = new Context() - ctx.baseUrl = pathToFileURL(directory).href + '/' - await ctx.plugin(Loader) - await ctx.plugin(RepositoryPlugin) - const id = await ctx.loader.create({ - name: pathToFileURL(join(directory, RepositoryPlugin.PREPARED_ENTRY_FILENAME)).href, - }) - await ctx.loader.await() - const getService = (name: string): unknown => (ctx as unknown as { get(name: string): unknown }).get(name) - expect(getService('repositoryCodeProof')).toEqual({ source: 'compiled-entry' }) - - await ctx.loader.remove(id) - expect(getService('repositoryCodeProof')).toBeUndefined() - await ctx.fiber.dispose() - }) - - it('mounts and removes tools discovered from a repository MCP server', async () => { - const root = await temporaryDirectory('mcp-loader-success') - const server = join(root, 'mcp-server.mjs') - await writeFile(server, [ - "import { createInterface } from 'node:readline'", - 'const lines = createInterface({ input: process.stdin })', - 'for await (const line of lines) {', - ' const request = JSON.parse(line)', - " if (!('id' in request)) continue", - ' let result', - " if (request.method === 'initialize') {", - ' result = {', - ' protocolVersion: request.params.protocolVersion,', - ' capabilities: { tools: {} },', - " serverInfo: { name: 'repository-fixture', version: '0.0.0' },", - ' }', - " } else if (request.method === 'tools/list') {", - ' result = {', - ' tools: [{', - " name: 'proof',", - " description: 'Repository MCP proof.',", - " inputSchema: { type: 'object', properties: {} },", - ' }],', - ' }', - ' } else {', - ' result = {}', - ' }', - " process.stdout.write(`${JSON.stringify({ jsonrpc: '2.0', id: request.id, result })}\\n`)", - '}', - '', - ].join('\n')) - await writeFile(join(root, '.mcp.json'), JSON.stringify({ - mcpServers: { online: { command: process.execPath, args: [server] } }, - })) - const directory = await writePlugin(root, 'mcp-loader-success-fixture', { mcpServers: '../.mcp.json' }) - await RepositoryPlugin.prepareDshPlugin(directory) - - const ctx = new Context() - ctx.baseUrl = pathToFileURL(directory).href + '/' - await ctx.plugin(Loader) - await ctx.plugin(SystemPrompt) - await ctx.plugin(ToolRegistry) - await ctx.plugin(RepositoryPlugin) - const id = await ctx.loader.create({ - name: pathToFileURL(join(directory, RepositoryPlugin.PREPARED_ENTRY_FILENAME)).href, - }) - await ctx.loader.await() - expect(ctx.tools.get('mcp__online__proof')).toBeDefined() - - await ctx.loader.remove(id) - expect(ctx.tools.get('mcp__online__proof')).toBeUndefined() - await ctx.fiber.dispose() - }) - - it('fails an MCP repository plugin load when its declared server cannot connect', async () => { - const root = await temporaryDirectory('mcp-loader') - await writeFile(join(root, '.mcp.json'), JSON.stringify({ - mcpServers: { offline: { command: join(root, 'missing-mcp-command') } }, - })) - const directory = await writePlugin(root, 'mcp-loader-fixture', { mcpServers: '../.mcp.json' }) - await RepositoryPlugin.prepareDshPlugin(directory) - - const ctx = new Context() - ctx.baseUrl = pathToFileURL(directory).href + '/' - await ctx.plugin(Loader) - await ctx.plugin(SystemPrompt) - await ctx.plugin(ToolRegistry) - await ctx.plugin(RepositoryPlugin) - await expect(ctx.loader.create({ - name: pathToFileURL(join(directory, RepositoryPlugin.PREPARED_ENTRY_FILENAME)).href, - })).rejects.toThrow('initial connection or tool synchronization failed') - expect(ctx.tools.schemas().some(tool => tool.name.startsWith('mcp__offline__'))).toBe(false) - await ctx.fiber.dispose() - }) - - it('rejects hostile prepared paths before mounting children', async () => { - const root = await temporaryDirectory('prepared-paths') - const ctx = new Context() - ctx.baseUrl = pathToFileURL(root).href + '/' - await ctx.plugin(Loader) - await ctx.plugin(RepositoryPlugin) - - for (const [filename, skillPath] of [ - ['absolute.mjs', resolve(root)], - ['escaped.mjs', '../outside'], - ] as const) { - const wrapper = join(root, filename) - await writeFile(wrapper, [ - "export const inject = ['loader']", - 'export async function apply(ctx) {', - ` await ctx.plugin(ctx.loader.builtins['${RepositoryPlugin.REPOSITORY_PLUGIN_BUILTIN}'], {`, - ` baseUrl: import.meta.url, manifest: { name: 'hostile', skills: [${JSON.stringify(skillPath)}] },`, - ' })', - '}', - '', - ].join('\n')) - await expect(ctx.loader.create({ name: pathToFileURL(wrapper).href })).rejects.toThrow('prepared DSH plugin path') - } - await ctx.fiber.dispose() - }) - - it('fails the plugin load when a declared skill root is missing or not a directory', async () => { - const root = await temporaryDirectory('missing-skill-root') - await writeFile(join(root, 'not-a-directory'), 'text') - const ctx = new Context() - ctx.baseUrl = pathToFileURL(root).href + '/' - await ctx.plugin(Loader) - await ctx.plugin(SkillService) - await ctx.plugin(RepositoryPlugin) - - for (const [filename, skillPath, message] of [ - ['missing.mjs', 'dsh-plugin-assets/skills/0', 'skill root is missing from the installed package'], - ['file.mjs', 'not-a-directory', 'skill root is not a directory'], - ] as const) { - const wrapper = join(root, filename) - await writeFile(wrapper, [ - "export const inject = ['loader']", - 'export async function apply(ctx) {', - ` await ctx.plugin(ctx.loader.builtins['${RepositoryPlugin.REPOSITORY_PLUGIN_BUILTIN}'], {`, - ` baseUrl: import.meta.url, manifest: { name: 'damaged', skills: [${JSON.stringify(skillPath)}] },`, - ' })', - '}', - '', - ].join('\n')) - await expect(ctx.loader.create({ name: pathToFileURL(wrapper).href })).rejects.toThrow(message) - } - await ctx.fiber.dispose() - }) - - it('rejects duplicate builtin ownership and preserves a later replacement on teardown', async () => { - const ctx = new Context() - await ctx.plugin(Loader) - const registrar = ctx.plugin(RepositoryPlugin) - await registrar - await expect(RepositoryPlugin.apply(ctx)).rejects.toThrow('already registered') - - const replacement = { name: 'replacement', apply() {} } - ctx.loader.builtins[RepositoryPlugin.REPOSITORY_PLUGIN_BUILTIN] = replacement - await registrar.dispose() - expect(ctx.loader.builtins[RepositoryPlugin.REPOSITORY_PLUGIN_BUILTIN]).toBe(replacement) - await ctx.fiber.dispose() - }) -}) - -describe('configured GitHub repository sources', () => { - it('defaults an omitted source list and rejects unknown configuration fields', () => { - expect(RepositoryPlugin.Config.parse(undefined)).toEqual({ repositories: [] }) - expect(RepositoryPlugin.Config.safeParse({ repositories: [], unexpected: true }).success).toBe(false) - }) - - it('accepts an empty direct-apply config', async () => { - const ctx = new Context() - await ctx.plugin(Loader) - await RepositoryPlugin.apply(ctx, {}) - expect(ctx.loader.builtins[RepositoryPlugin.REPOSITORY_PLUGIN_BUILTIN]).toBeDefined() - await ctx.fiber.dispose() - }) - - it('adds the root plugin subpath and preserves an explicit nested plugin subpath', () => { - expect(resolveRepositorySpecifier('github:PolyArch/humanize#v1.0.0')) - .toBe('github:PolyArch/humanize#v1.0.0&path:/.dsh-plugin') - expect(resolveRepositorySpecifier('github:owner/repository#feature/ref&path:/plugins/one/.dsh-plugin')) - .toBe('github:owner/repository#feature/ref&path:/plugins/one/.dsh-plugin') - }) - - it('rejects absent refs and invalid plugin subpaths', () => { - for (const source of [ - 'github:owner/repository', - 'github:owner/repository#', - 'github:owner/repository#a#b', - 'https://github.com/owner/repository#ref', - 'github:owner/repository#ref&path:relative/.dsh-plugin', - ]) { - expect(() => resolveRepositorySpecifier(source)).toThrow('must use github:owner/repo#') - } - for (const path of [ - '/plugins//.dsh-plugin', - '/plugins/../.dsh-plugin', - '/plugins/./.dsh-plugin', - '/plugins/not-a-plugin', - ]) { - expect(() => resolveRepositorySpecifier(`github:owner/repository#ref&path:${path}`)) - .toThrow('path must be an absolute repository subpath') - } - }) - - it('resolves the default cache under DSH_HOME and an explicit cache absolutely', async () => { - const root = await temporaryDirectory('cache-root') - vi.stubEnv('DSH_HOME', root) - expect(resolveRepositoryCacheDirectory(undefined)).toBe(join(root, 'cache', 'repository-plugins')) - expect(resolveRepositoryCacheDirectory(join(root, 'explicit'))).toBe(join(root, 'explicit')) - }) - - it('loads a configured source through the immutable cache and removes its skill on teardown', async () => { - const root = await temporaryDirectory('configured-source') - await writeSkill(join(root, 'skills'), 'configured-repository-skill') - const directory = await writePlugin(root, 'configured-source-fixture', { skills: ['../skills'] }) - await RepositoryPlugin.prepareDshPlugin(directory) - const resolved: string[] = [] - const cacheDirectory = join(root, 'cache') - vi.spyOn(RepositoryCache.prototype, 'resolve').mockImplementation(async function (this: RepositoryCache, specifier) { - expect(this.directory).toBe(cacheDirectory) - resolved.push(specifier) - return directory - }) - - const ctx = new Context() - await ctx.plugin(Loader) - await ctx.plugin(SkillService) - const registrar = ctx.plugin(RepositoryPlugin, { - repositories: ['github:owner/repository#fixed-ref'], - cacheDir: cacheDirectory, - }) - await registrar - expect(resolved).toEqual(['github:owner/repository#fixed-ref&path:/.dsh-plugin']) - await expect(ctx.skills.get('configured-repository-skill')).resolves.toMatchObject({ - provider: 'repository:configured-source-fixture', - }) - - await registrar.dispose() - await expect(ctx.skills.get('configured-repository-skill')).resolves.toBeUndefined() - await ctx.fiber.dispose() - }) - - it('swaps generations on a live source-list update and rolls a failed candidate back', async () => { - // The headline flow: a personal-config edit reaches this plugin as a - // Loader entry.update, which restarts the row's fiber (old cleanup, then - // new apply — so the 'already registered' builtin guard must not fire). - const roots: Record = {} - for (const generation of ['one', 'two'] as const) { - const root = await temporaryDirectory(`live-${generation}`) - await writeSkill(join(root, 'skills'), `live-skill-${generation}`) - const directory = await writePlugin(root, `live-fixture-${generation}`, { skills: ['../skills'] }) - await RepositoryPlugin.prepareDshPlugin(directory) - roots[`github:owner/repository#${generation}&path:/.dsh-plugin`] = directory - } - vi.spyOn(RepositoryCache.prototype, 'resolve').mockImplementation(async (specifier) => { - const directory = roots[specifier] - if (directory === undefined) throw new Error(`unprepared generation ${specifier}`) - return directory - }) - - // Route the row through the Loader builtin table exactly as a config tree - // would; the module itself is the row's plugin. - const ctx2 = new Context() - await ctx2.plugin(Loader) - await ctx2.plugin(SkillService) - ctx2.loader.builtins['repository-plugins'] = RepositoryPlugin - const entryId = await ctx2.loader.create({ - name: 'cordis:repository-plugins', - config: { repositories: ['github:owner/repository#one'] }, - }) - await ctx2.loader.await() - await expect(ctx2.skills.get('live-skill-one')).resolves.toMatchObject({ provider: 'repository:live-fixture-one' }) - - const entry = ctx2.loader.resolve(entryId) - await entry.update({ config: { repositories: ['github:owner/repository#two'] } }) - await ctx2.loader.await() - await expect(ctx2.skills.get('live-skill-one')).resolves.toBeUndefined() - await expect(ctx2.skills.get('live-skill-two')).resolves.toMatchObject({ provider: 'repository:live-fixture-two' }) - - // A failed candidate (unprepared source) rejects the update and the - // transactional Loader restores the previous generation. - await expect(entry.update({ config: { repositories: ['github:owner/repository#missing'] } })) - .rejects.toThrow('unprepared generation') - await ctx2.loader.await() - await expect(ctx2.skills.get('live-skill-two')).resolves.toMatchObject({ provider: 'repository:live-fixture-two' }) - await ctx2.fiber.dispose() - }) - - it('rejects duplicate generations and cleans the builtin after cache preparation fails', async () => { - const ctx = new Context() - await ctx.plugin(Loader) - await expect(RepositoryPlugin.apply(ctx, { - repositories: [ - 'github:owner/repository#ref', - 'github:owner/repository#ref', - ], - })).rejects.toThrow('must resolve to unique exact specifiers') - - vi.spyOn(RepositoryCache.prototype, 'resolve').mockRejectedValue(new Error('prepare failed')) - await expect(RepositoryPlugin.apply(ctx, { - repositories: ['github:owner/repository#other'], - })).rejects.toThrow('prepare failed') - expect(ctx.loader.builtins[RepositoryPlugin.REPOSITORY_PLUGIN_BUILTIN]).toBeUndefined() - await ctx.fiber.dispose() - }) - - it('rejects a wrapper left pending by a composition without its required services', async () => { - // A skills-declaring generation mounted where no skills service exists: - // the wrapper fiber stays PENDING, and the transaction must fail loud - // instead of committing an ACTIVE row over a silently inert child. - const root = await temporaryDirectory('pending-services') - await writeSkill(join(root, 'skills'), 'pending-service-skill') - const directory = await writePlugin(root, 'pending-service-fixture', { skills: ['../skills'] }) - await RepositoryPlugin.prepareDshPlugin(directory) - - const ctx = new Context() - await ctx.plugin(Loader) - // Deliberately NO SkillService. - await expect(loadPreparedRepository(ctx, { resolve: async () => directory }, 'github:owner/repository#pending&path:/.dsh-plugin')) - .rejects.toMatchObject({ - message: expect.stringContaining('failed to load prepared repository Plugin') as string, - cause: expect.objectContaining({ - message: expect.stringContaining('waiting for services: skills') as string, - }) as Error, - }) - await ctx.fiber.dispose() - }) - - it('labels a missing prepared wrapper with its exact source and path', async () => { - const root = await temporaryDirectory('missing-wrapper') - const directory = await writePlugin(root, 'missing-wrapper', { skills: ['../skills'] }) - const ctx = new Context() - const specifier = 'github:owner/repository#missing&path:/.dsh-plugin' - await expect(loadPreparedRepository(ctx, { resolve: async () => directory }, specifier)) - .rejects.toThrow(`failed to load prepared repository Plugin ${JSON.stringify(specifier)}`) - await ctx.fiber.dispose() - }) - - it('rejects installed source with the obsolete prepare lifecycle', async () => { - const root = await temporaryDirectory('installed-lifecycle') - await writeFile(join(root, 'package.json'), JSON.stringify({ - name: 'installed-lifecycle', - devDependencies: { [RepositoryPlugin.REPOSITORY_PLUGIN_PACKAGE_NAME]: '0.0.1' }, - scripts: { prepare: 'dsh-plugin-prepare' }, - })) - const ctx = new Context() - await expect(loadPreparedRepository(ctx, { resolve: async () => root }, 'github:owner/repository#old&path:/.dsh-plugin')) - .rejects.toMatchObject({ - cause: expect.objectContaining({ - message: expect.stringContaining('must declare a non-empty scripts.prepack') as string, - }) as Error, - }) - await expect(loadPreparedRepository(ctx, { resolve: async () => root }, 'github:owner/repository#old&path:/.dsh-plugin')) - .rejects.toMatchObject({ - cause: expect.objectContaining({ - message: expect.stringContaining('Clear the matching repository cache generation') as string, - }) as Error, - }) - await ctx.fiber.dispose() - }) - - it('rejects an installed source whose prepack omits the package prepare command', async () => { - const root = await temporaryDirectory('installed-skipped-prepare') - await writeFile(join(root, 'package.json'), JSON.stringify({ - name: 'installed-skipped-prepare', - devDependencies: { [RepositoryPlugin.REPOSITORY_PLUGIN_PACKAGE_NAME]: '0.0.1' }, - scripts: { prepack: 'npm run build' }, - })) - const ctx = new Context() - await expect(loadPreparedRepository(ctx, { resolve: async () => root }, 'github:owner/repository#unprepared&path:/.dsh-plugin')) - .rejects.toMatchObject({ - cause: expect.objectContaining({ - message: expect.stringContaining('must invoke dsh-plugin-prepare') as string, - }) as Error, - }) - await ctx.fiber.dispose() - }) - - it('rejects installed source without the declared prepare dependency', async () => { - const root = await temporaryDirectory('installed-missing-prepare-dependency') - await writeFile(join(root, 'package.json'), JSON.stringify({ - name: 'installed-missing-prepare-dependency', - scripts: { prepack: 'dsh-plugin-prepare' }, - })) - const ctx = new Context() - await expect(loadPreparedRepository(ctx, { resolve: async () => root }, 'github:owner/repository#ambient-helper&path:/.dsh-plugin')) - .rejects.toMatchObject({ - cause: expect.objectContaining({ - message: expect.stringContaining(`${JSON.stringify(RepositoryPlugin.REPOSITORY_PLUGIN_PACKAGE_NAME)} in devDependencies`) as string, - }) as Error, - }) - await ctx.fiber.dispose() - }) - - it('labels missing installed package metadata with its source', async () => { - const root = await temporaryDirectory('missing-installed-metadata') - const ctx = new Context() - const specifier = 'github:owner/repository#damaged&path:/.dsh-plugin' - await expect(loadPreparedRepository(ctx, { resolve: async () => root }, specifier)) - .rejects.toMatchObject({ - message: expect.stringContaining(JSON.stringify(specifier)) as string, - cause: expect.objectContaining({ - message: expect.stringContaining('failed to read installed DSH plugin package metadata') as string, - }) as Error, - }) - await ctx.fiber.dispose() - }) -}) - -describe('repository plugin invariant companion', () => { - it('registers its explained empty invariant', async () => { - const ctx = new Context() - await ctx.plugin(InvariantService, { enabled: true }) - await expect(ctx.plugin(RepositoryPluginInvariant).await()).resolves.toBeDefined() - await ctx.fiber.dispose() - }) -}) diff --git a/packages/self-modification/repository-plugin/tsconfig.json b/packages/self-modification/repository-plugin/tsconfig.json deleted file mode 100644 index 67cb0dedf2..0000000000 --- a/packages/self-modification/repository-plugin/tsconfig.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "extends": "../../../tsconfig.base.json", - "compilerOptions": { - "rootDir": "src", - "outDir": "lib/types" - }, - "include": [ - "src" - ], - "references": [ - { - "path": "../../../vendor/cosmokit" - }, - { - "path": "../../../vendor/cordis" - }, - { - "path": "../../../vendor/loader" - }, - { - "path": "../../skill/skill-local" - }, - { - "path": "../../mcp/mcp-client" - }, - { - "path": "../../util/paths" - }, - { - "path": "../../support/invariants" - } - ] -} diff --git a/packages/self-modification/repository-plugin/tsdown.config.ts b/packages/self-modification/repository-plugin/tsdown.config.ts deleted file mode 100644 index ac8e9a5fe0..0000000000 --- a/packages/self-modification/repository-plugin/tsdown.config.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { defineConfig } from 'tsdown' - -/** Build the runtime, invariant, and prepare executable as self-contained entries. */ -export default defineConfig([ - { - entry: ['lib/types/index.js'], outDir: 'lib', format: ['esm'], platform: 'node', target: 'es2024', - fixedExtension: false, outputOptions: { codeSplitting: false }, dts: false, clean: false, - }, - { - entry: ['lib/types/invariant.js'], outDir: 'lib', format: ['esm'], platform: 'node', target: 'es2024', - fixedExtension: false, outputOptions: { codeSplitting: false }, dts: false, clean: false, - }, - { - entry: ['lib/types/bin.js'], outDir: 'lib', format: ['esm'], platform: 'node', target: 'es2024', - fixedExtension: false, outputOptions: { codeSplitting: false }, dts: false, clean: false, - }, -]) diff --git a/packages/self-modification/tool-cordis/README.i18n.yaml b/packages/self-modification/tool-cordis/README.i18n.yaml index ef1f441711..67d3737753 100644 --- a/packages/self-modification/tool-cordis/README.i18n.yaml +++ b/packages/self-modification/tool-cordis/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/self-modification/tool-cordis/README.md -README.md: f2a65043a1d2f74553e98caf59ed3d38b5a70b7c -README.zh.md: 66742094992d219ccfbd60b935dcd10e48cb12b8 +README.md: 4f856523cca4800cdbb98951183fbea1e3c96c87 +README.zh.md: 7bb21396452ddbe49cf3008cd89cd6044b3c4a51 diff --git a/packages/self-modification/tool-cordis/README.md b/packages/self-modification/tool-cordis/README.md index f2a65043a1..4f856523cc 100644 --- a/packages/self-modification/tool-cordis/README.md +++ b/packages/self-modification/tool-cordis/README.md @@ -14,7 +14,7 @@ Exact model-facing schemas: [the generated tool catalog](../../../docs/tool-cata Canonical successes are the inspection string, mount `{ id, pluginName, state, provides, waitingFor }`, and unmount `{ id, pluginName }`. Native rendering says whether the temporary Plugin is running or pending and that it remains available until unmounted or DSH restarts; unmount confirms that it was removed. -Temporary Plugins live only in the shared DSH process memory. They remain active across later turns and may affect other sessions in that process, but disappear after `cordis_unmount`, toolset unload, or DSH restart. They create no Plugin file, install no package, change no `cordis.yml` or personal/project configuration, do not survive restart, and cannot be promoted automatically. To keep an experiment, ask the Agent to implement a normal local, project, or repository Plugin through the regular development workflow. +Temporary Plugins live only in the shared DSH process memory. They remain active across later turns and may affect other sessions in that process, but disappear after `cordis_unmount`, toolset unload, or DSH restart. They create no Plugin file, install no package, change no `cordis.yml` or personal/project configuration, do not survive restart, and cannot be promoted automatically. To keep an experiment, ask the Agent to implement an SDK Plugin or installable profile bundle through the regular development workflow. ## Trust stance diff --git a/packages/self-modification/tool-cordis/README.zh.md b/packages/self-modification/tool-cordis/README.zh.md index 6674209499..7bb2139645 100644 --- a/packages/self-modification/tool-cordis/README.zh.md +++ b/packages/self-modification/tool-cordis/README.zh.md @@ -14,7 +14,7 @@ 规范成功结果分别为检查字符串、挂载 `{ id, pluginName, state, provides, waitingFor }`,以及卸载 `{ id, pluginName }`。原生渲染会说明临时插件正在运行还是等待中,并说明它可用至被卸载或 DSH 重启;卸载结果确认它已移除。 -临时插件只存在于共享 DSH 进程内存中。它可跨后续轮次保持活跃,也可能影响同一进程中的其他会话,但会在 `cordis_unmount`、工具集卸载或 DSH 重启后消失。它不会创建插件文件、安装任何包、修改 `cordis.yml` 或个人/项目配置、跨重启存续,也不能自动转为正式插件。若要保留实验结果,应让 agent(智能体)通过常规开发流程实现普通的本地、项目或仓库插件。 +临时插件只存在于共享 DSH 进程内存中。它可跨后续轮次保持活跃,也可能影响同一进程中的其他会话,但会在 `cordis_unmount`、工具集卸载或 DSH 重启后消失。它不会创建插件文件、安装任何包、修改 `cordis.yml` 或个人/项目配置、跨重启存续,也不能自动转为正式插件。若要保留实验结果,应让 agent(智能体)通过常规开发流程实现 SDK 插件或可安装的 profile 组合包。 ## 信任立场 diff --git a/packages/self-modification/tool-cordis/src/index.ts b/packages/self-modification/tool-cordis/src/index.ts index 6ba56ccfe4..46c51fa6ad 100644 --- a/packages/self-modification/tool-cordis/src/index.ts +++ b/packages/self-modification/tool-cordis/src/index.ts @@ -112,7 +112,7 @@ export function apply(ctx: Context, config: Config): void { + 'This creates an in-memory runtime Plugin, not an installed or configured Plugin. ' + 'It remains active across later turns until cordis_unmount, toolset unload, or DSH restart. ' + 'It does not create files, install a package, change cordis.yml or personal/project config, survive restart, or automatically become permanent. ' - + 'To keep it, ask the Agent to implement a normal local, project, or repository Plugin through the regular development workflow. ' + + 'To keep it, ask the Agent to implement an SDK Plugin or installable profile bundle through the regular development workflow. ' + 'It may affect other sessions in the same process; the sandbox is not a security boundary, and injected services reach the real runtime. ' + '`code` runs now as the body of an async JavaScript function ' + 'in an isolated sandbox and MUST `return` a plugin. Two forms: ' diff --git a/packages/skill/skill-local/README.i18n.yaml b/packages/skill/skill-local/README.i18n.yaml index ed7a501145..38d25a6d7c 100644 --- a/packages/skill/skill-local/README.i18n.yaml +++ b/packages/skill/skill-local/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/skill/skill-local/README.md -README.md: aa25278750b5a1577eb567e50344fb3af425d71a -README.zh.md: 59abd5623da189d0b5d739eec56e034b553690b9 +README.md: 877b784353998a191a2d1a377aaf5406e1a97965 +README.zh.md: e6f07b2f630ecd1e6261f32c6e58254c14bb450c diff --git a/packages/skill/skill-local/README.md b/packages/skill/skill-local/README.md index aa25278750..877b784353 100644 --- a/packages/skill/skill-local/README.md +++ b/packages/skill/skill-local/README.md @@ -38,7 +38,7 @@ Default roots are resolved in this provider's rank order: | 400 | `user-dsh` | `/skills` | | 500 | `user-agents` | `/skills` | -The project root is the nearest ancestor containing `.git`; without one, the current cwd is used. The user DSH root skips its `.system` child so system-owned directories are not treated as normal user skills. `includeDefaultRoots: false` omits the project and user rows and the `$DSH_BUNDLED_SKILL_DIR` environment default while retaining explicitly configured custom and bundled roots, allowing several uniquely named isolated providers such as immutable repository Plugins to see only their own roots. This provider supplies project and user skills; another provider may supply built-in system skills. +The project root is the nearest ancestor containing `.git`; without one, the current cwd is used. The user DSH root skips its `.system` child so system-owned directories are not treated as normal user skills. `includeDefaultRoots: false` omits the project and user rows and the `$DSH_BUNDLED_SKILL_DIR` environment default while retaining explicitly configured custom and bundled roots, allowing several uniquely named isolated providers to see only their own roots. This provider supplies project and user skills; another provider may supply built-in system skills. When `ctx.fs` is available, discovery lists roots through `ctx.fs.listDir`, reads skill files through `ctx.fs.readText`, and probes `.git` through the filesystem service. Full skill loads forward the lookup abort signal to filesystem metadata and content reads. Without a filesystem service, the provider falls back to abortable Node filesystem I/O so minimal local contexts can still load skills. Confirmed missing paths are valid empty state, malformed or non-text entries warn and skip, and unexpected discovery/read failures make the registry snapshot incomplete rather than replacing a last-good model catalog with a misleading deletion. diff --git a/packages/skill/skill-local/README.zh.md b/packages/skill/skill-local/README.zh.md index 59abd5623d..e6f07b2f63 100644 --- a/packages/skill/skill-local/README.zh.md +++ b/packages/skill/skill-local/README.zh.md @@ -38,7 +38,7 @@ | 400 | `user-dsh` | `/skills` | | 500 | `user-agents` | `/skills` | -项目根目录是包含 `.git` 的最近祖先目录;如果不存在,则使用当前 cwd。用户 DSH 根目录会跳过其 `.system` 子目录,因此归系统所有的目录不会被当作普通用户 skill。`includeDefaultRoots: false` 会省略项目根、用户根以及 `$DSH_BUNDLED_SKILL_DIR` 环境默认值,同时保留显式配置的自定义根与 bundled 根,因此可以挂载多个只看到自身根的唯一命名隔离提供方,例如不可变的仓库插件。该提供方提供项目和用户 skill;其他提供方可提供内置系统 skill。 +项目根目录是包含 `.git` 的最近祖先目录;如果不存在,则使用当前 cwd。用户 DSH 根目录会跳过其 `.system` 子目录,因此归系统所有的目录不会被当作普通用户 skill。`includeDefaultRoots: false` 会省略项目根、用户根以及 `$DSH_BUNDLED_SKILL_DIR` 环境默认值,同时保留显式配置的自定义根与 bundled 根,因此可以挂载多个只看到自身根的唯一命名隔离提供方。该提供方提供项目和用户 skill;其他提供方可提供内置系统 skill。 当 `ctx.fs` 可用时,发现通过 `ctx.fs.listDir` 列出根,通过 `ctx.fs.readText` 读取 skill 文件,并通过文件系统服务探测 `.git`。完整 skill 加载会将查找中止信号转发给文件系统元数据和内容读取。如果没有文件系统服务,提供方回退到可中止的 Node 文件系统 I/O,使最小本地上下文仍能加载 skill。已确认缺失的路径属于有效空状态;遇到格式错误或非文本条目时,提供方会发出警告并跳过;意外的发现或读取失败会使注册表快照不完整,系统不会因此用看似发生删除的结果替换上一份可用模型目录。 diff --git a/packages/skill/skill-local/src/index.ts b/packages/skill/skill-local/src/index.ts index 996a12329f..912feaa2ca 100644 --- a/packages/skill/skill-local/src/index.ts +++ b/packages/skill/skill-local/src/index.ts @@ -166,9 +166,8 @@ export class LocalSkillProvider implements SkillProvider { this.watchManager = new SkillWatchManager(ctx, control.invalidate, resolveWatchConfig(config)) control.signal.addEventListener('abort', () => { void this.dispose() }, { once: true }) // The environment bundled root is a default root: an isolated provider - // (includeDefaultRoots: false — repository plugins) must see only its - // explicit custom roots, or every such provider would re-discover the - // app's bundled skills and claim them under its own provider name. + // must see only its explicit roots, or every such provider would + // re-discover the app's bundled skills under its own provider name. const bundledSkillDir = config.bundledSkillDir ?? (this.includeDefaultRoots ? process.env.DSH_BUNDLED_SKILL_DIR : undefined) this.bundledSkillDir = bundledSkillDir === undefined ? undefined : resolve(bundledSkillDir) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f36be6b1b6..732e00e4ee 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -517,9 +517,6 @@ importers: '@deepseek-ai/dsh-repeat-tool-guard': specifier: workspace:* version: link:../packages/guard/repeat-tool-guard - '@deepseek-ai/dsh-repository-plugin': - specifier: workspace:* - version: link:../packages/self-modification/repository-plugin '@deepseek-ai/dsh-sandbox': specifier: workspace:* version: link:../packages/sandbox/sandbox @@ -1263,9 +1260,6 @@ importers: '@deepseek-ai/dsh-repeat-tool-guard': specifier: workspace:^ version: link:../../guard/repeat-tool-guard - '@deepseek-ai/dsh-repository-plugin': - specifier: workspace:^ - version: link:../../self-modification/repository-plugin '@deepseek-ai/dsh-sandbox-local': specifier: workspace:^ version: link:../../sandbox/sandbox-local @@ -5517,40 +5511,6 @@ importers: specifier: ^4.0.0-rc.7 version: link:../../../vendor/cordis - packages/self-modification/repository-plugin: - dependencies: - zod: - specifier: ^4.4.3 - version: 4.4.3 - devDependencies: - '@cordisjs/plugin-loader': - specifier: workspace:^ - version: link:../../../vendor/loader - '@deepseek-ai/dsh-invariants': - specifier: workspace:^ - version: link:../../support/invariants - '@deepseek-ai/dsh-mcp-client': - specifier: workspace:^ - version: link:../../mcp/mcp-client - '@deepseek-ai/dsh-paths': - specifier: workspace:^ - version: link:../../util/paths - '@deepseek-ai/dsh-skill': - specifier: workspace:^ - version: link:../../skill/skill - '@deepseek-ai/dsh-skill-local': - specifier: workspace:^ - version: link:../../skill/skill-local - '@deepseek-ai/dsh-system-prompt': - specifier: workspace:^ - version: link:../../core/system-prompt - '@deepseek-ai/dsh-tools': - specifier: workspace:^ - version: link:../../core/tools - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis - packages/self-modification/tool-cordis: dependencies: schemastery: @@ -7978,9 +7938,6 @@ importers: node-addon-require-builtin: specifier: ^0.1.4 version: 0.1.4 - pnpm: - specifier: 11.7.0 - version: 11.7.0 vendor/logger-console: dependencies: @@ -12638,11 +12595,6 @@ packages: engines: {node: '>=18'} hasBin: true - pnpm@11.7.0: - resolution: {integrity: sha512-GcyFLBIMcSV2DyRD7mvgyltA+fUFmN4aCaHxd1A+AQ5Xwjx3ZG4B52HeWb+HT7IqM5jDOrlpH8E+uUa28PTWIA==} - engines: {node: '>=22.13'} - hasBin: true - points-on-curve@0.2.0: resolution: {integrity: sha512-0mYKnYYe9ZcqMCWhUjItv/oHjvgEsfKvnUTg8sAtnHr3GVy7rGkXCb6d5cSyqrWqL4k81b9CPg3urd+T7aop3A==} @@ -18146,8 +18098,6 @@ snapshots: optionalDependencies: fsevents: 2.3.2 - pnpm@11.7.0: {} - points-on-curve@0.2.0: {} points-on-path@0.2.1: diff --git a/scripts/run-gates.spec.ts b/scripts/run-gates.spec.ts index 7c85d8ff48..6ef494b76b 100644 --- a/scripts/run-gates.spec.ts +++ b/scripts/run-gates.spec.ts @@ -227,7 +227,7 @@ describe('Node 24 lane ownership', () => { const subject = withPnpmEntrypoint(() => gatesForMode('ci-consumers')) expect(defaultConcurrency('ci-consumers', subject.length, 4)).toEqual({ - workers: 11, + workers: 10, source: 'ci-consumers gate count', }) expect(subject.map(item => item.id)).toEqual([ @@ -241,7 +241,6 @@ describe('Node 24 lane ownership', () => { 'doc-typecheck', 'node-next-types', 'built-bin-smoke', - 'github-repository-plugin-e2e', ]) expect(subject.find(item => item.id === 'publint')?.needs).toEqual(['build']) expect(subject.find(item => item.id === 'built-package-invariants')?.needs).toEqual(['publint']) @@ -252,7 +251,6 @@ describe('Node 24 lane ownership', () => { 'doc-typecheck', 'node-next-types', 'built-bin-smoke', - 'github-repository-plugin-e2e', ]) { expect(subject.find(item => item.id === id)?.needs).toEqual(['built-package-invariants']) } @@ -266,16 +264,6 @@ describe('Node 24 lane ownership', () => { 'packages/subagent/subagent-claude-code/tests/loader-composition.e2e.ts', ]), ) - const githubRepositoryPlugin = subject.find(item => item.id === 'github-repository-plugin-e2e') - expect(githubRepositoryPlugin).toMatchObject({ - label: 'GitHub repository Plugin dsh run', - env: { - DSH_REQUIRE_GITHUB_REPOSITORY_PLUGIN_E2E: '1', - }, - }) - expect(githubRepositoryPlugin?.args).toEqual( - expect.arrayContaining(['apps/cli/tests/github-repository-plugin.built.e2e.ts']), - ) expect(subject.find(item => item.id === 'web-snapshot')).toMatchObject({ displayCommand: 'DSH_SNAPSHOT=replay pnpm run test:web:built', env: { DSH_SNAPSHOT: 'replay' }, diff --git a/scripts/run-gates.ts b/scripts/run-gates.ts index 3b88da217f..b986b2e0f3 100644 --- a/scripts/run-gates.ts +++ b/scripts/run-gates.ts @@ -406,7 +406,6 @@ function ciConsumerGates(): Gate[] { needs: validatedBuild, }), builtBinSmokeGate(validatedBuild), - githubRepositoryPluginE2eGate(validatedBuild), ] } @@ -518,7 +517,7 @@ function coverageGates(): Gate[] { } // Example and package snapshots boot their bins in `lib` mode (built artifacts under plain Node, -// plugins via real exports); repository-script snapshots execute their real source entry path. +// plugins via real exports); script snapshots execute their real source entry path. // Callers wait either on `build` or on a validation gate that transitively owns that build. function snapshotGate(needs: string[] = ['build']): Gate { return pnpmScript('snapshot', 'test:snapshot', { @@ -639,20 +638,6 @@ function builtBinSmokeGate(needs: string[] = ['build']): Gate { }) } -function githubRepositoryPluginE2eGate(needs: string[]): Gate { - return pnpmExec('github-repository-plugin-e2e', [ - 'vitest', - 'run', - '--config', - 'vitest.e2e.config.ts', - 'apps/cli/tests/github-repository-plugin.built.e2e.ts', - ], { - label: 'GitHub repository Plugin dsh run', - needs, - env: { DSH_REQUIRE_GITHUB_REPOSITORY_PLUGIN_E2E: '1' }, - }) -} - /** * Reject a gate list whose graph cannot be executed unambiguously. * @param gates - complete aggregate to validate. diff --git a/tsconfig.host.json b/tsconfig.host.json index d9bf1c29e4..7b4616367e 100644 --- a/tsconfig.host.json +++ b/tsconfig.host.json @@ -253,7 +253,6 @@ { "path": "./packages/preset/persona" }, { "path": "./packages/guard/repeat-tool-guard" }, { "path": "./packages/self-modification/tool-cordis" }, - { "path": "./packages/self-modification/repository-plugin" }, { "path": "./packages/hooks/hook-protocol" }, { "path": "./packages/hooks/hooks-claude" }, { "path": "./packages/hooks/hooks-codex" }, diff --git a/vendor/README.md b/vendor/README.md index 75f93b2b88..87e5859212 100644 --- a/vendor/README.md +++ b/vendor/README.md @@ -39,12 +39,11 @@ Keep this log exhaustive — every divergence from upstream must be listed. 7. **`cordis/src/*.ts` JSDoc enrichment**: added `@param`/`@returns` tags and contract documentation (disposal semantics, waterfall veto, bail conditions, error cases) across the public plugin-author surface — `Context` (class, statics, and the `Context` interface properties incl. `root`), `EventsService`, `Fiber`, `RegistryService`, `ReflectService`, `Service`, `LoggerService` and their `declare module './context.ts'` overloads. Comment-only; no code changes. Motivation: the website API-reference generator renders these docs and hard-errors on undocumented members. Retire this entry when the enrichment is upstreamed to the fork. 8. **Transactional Loader/Include config reconciliation**: Loader imports a changed entry name before disposal, awaits lifecycle settlement, and restores the previous plugin or config when candidate application fails. Loader settlement rechecks service-gated fibers after current tasks drain, rejects failures, and leaves fibers with absent dependencies pending. Group updates start candidates concurrently, await every outcome, undo changes and additions on failure, await removal, preserve programmatic option identity, and persist direct or tree-level mutations only after success. Include reads and validates detached candidate content, applies patches to a clone, reconciles the tree, and only then commits its cached content/data; direct refresh failures propagate for the caller to contain. A non-array parse is invalid, patches re-apply on every file or Include-config update, an omitted patch list clears the overlay, and initial content falls back to `initial` only on `ENOENT`. Covered by `packages/boot/app-boot/tests/config-reload.spec.ts` and `packages/host/webserver/tests/webserver.spec.ts`. 9. **`hmr/src/index.ts` exact config watching**: `registerConfig()` watches one absolute config path outside module roots, including a path under missing parents, serializes and coalesces refreshes, and returns an async disposer that closes the watcher and drains active work. Module watches realpath their existing base directory, attach change listeners before declaring the service ready, and use that spelling for Node module-cache identity; exact config watches realpath the deepest existing watch ancestor and restore the missing suffix. Those native paths prevent Windows short-name aliases from colliding with long-form libuv event paths while exact-config callbacks keep the requested filename. Refresh failures are normalized to `Error`, logged, and broadcast through the parallel `hmr/config-update-failed` event; observer failures are contained. Config-file changes discovered by the ordinary HMR watcher use the same serialized path. Covered by `packages/boot/app-boot/tests/hmr-config.spec.ts`. -10. **`loader/src/repository.ts`, `loader/tsdown.config.ts`, and the `@cordisjs/plugin-loader/repository` export**: the Node-only `RepositoryCache` installs one exact dependency specifier through the bundled `pnpm@11.7.0`, single-flights callers, and atomically publishes only a prepared package plus marker under the specifier hash. The subpath stays out of the browser-reachable Loader entry. Identical specifiers permanently reuse that entry; callers change the ref/specifier for another generation. A transaction-owned `pnpm` wrapper and exported `PNPM_CONFIG_IGNORE_WORKSPACE` make pnpm's nested Git-package install reinvoke the same bundled entry outside an enclosing source workspace. The child retains `PNPM_HOME` for pnpm data while removing that directory from lifecycle `PATH`, and prioritizes `.CMD` in `PATHEXT` so a later inherited pnpm executable cannot outrank the wrapper on Windows. The temporary command directory is removed after the child settles. The isolated workspace permits dependency build scripts because a configured repository is executable code, while the child drops ambient credential-shaped variables. Covered by `packages/boot/app-boot/tests/repository-cache.spec.ts`, including a keyless local-Git `prepack` whose package is excluded from an enclosing pnpm lockfile, obtains both its build and prepare commands from declared dependencies, and rejects an inherited shadow pnpm. -11. **Vendored Node-compatible TypeScript**: marked erased imports explicitly across `cordis`, `loader`, `include`, `hmr`, and `schemastery` so Node's native TypeScript transform does not request types as runtime exports. Schemastery's source uses an ESM default export and its package declares `type: module`; its built ESM/CJS entries retain explicit `.mjs`/`.cjs` extensions. -12. **`include/src/index.ts` patch-semantics export**: extracted the private `applyPatches` body into the exported pure function `applyEntryPatches(data, patches, warn)` (the method delegates to it) and exported the `!!js` YAML dialect as `entryListSchema`, so `dsh --dump-config` composes and prints exactly what the include would mount without booting a tree. Behavior-preserving for mounting; the extraction exists because config tooling must never reimplement (and drift from) the patch algorithm. `applyEntryPatches` also indexes each `insert`ed entry as it is added, so a later patch in the same list can configure or disable a row an earlier patch inserted; upstream built the id index once before the patch loop, leaving inserted rows silently unpatchable. That matters because `dsh` composes an empty profile root with each bundle's patch layer, the profile's and the home-level `cordis.patch.yml`, and any `--patch` overlays as sibling patch lists at one include level — patches never cross an include boundary, so surface-only rows would otherwise be unreachable from user config. Covered by `packages/boot/app-boot/tests/config-reload.spec.ts`. -13. **`include/src/index.ts` serialized child-tree mutation and `hmr/src/index.ts` main-watcher initial-scan suppression**: every Include child-tree mutation (initial apply, refresh, `internal/update` patch re-application) runs through one per-Include queue, because the group's transactional `update` is not reentrant — two concurrent applies interleave create and rollback on the same entries and strand the Include fiber without ever settling. The HMR main watcher passes `ignoreInitial: true`: the initial scan re-announced files boot had just consumed, and its `add` for a config file refreshed an Include mid-initial-apply; once serialized, a failing initial apply's rollback disposed HMR, whose teardown drain waited on the queued refresh sitting behind that same apply — a deadlock that exited 13 with no diagnostic. `registerConfig()` keeps its own `ignoreInitial: false` watcher because a user patch layer present at registration must apply once. Covered by the patch-overlay boot-failure built-bin case in `apps/cli/tests/built-bin.e2e.ts`. -14. **`include/src/index.ts` `writeTask` type**: widened the optional `writeTask?: NodeJS.Timeout` property to `NodeJS.Timeout | undefined` — the debounced writer assigns `undefined` on flush, which `exactOptionalPropertyTypes` rejects on a plain optional. Type-only; no behavior change. -15. **`include/src/index.ts` durable debounced writes**: serialized and tracked config-file writes, retried transient `EACCES`/`EBUSY`/`EPERM` rename failures with a bounded backoff, observed asynchronous timer rejections, and drained the latest write during Include teardown. Windows can briefly retain a destination handle after a Loader child disposes; the upstream fire-and-forget rename escaped as an unhandled rejection and could lose the persisted `disabled` state. A terminal failure is logged by the asynchronous writer and remains on the queue so `Include.stop()` rethrows it instead of silently declaring persistence complete; Cordis's ordinary fiber teardown retains its separate error-containment contract. Covered by `packages/host/directory-picker-auto/tests/loader-composition.spec.ts` with injected transient and terminal rename failures. +10. **Vendored Node-compatible TypeScript**: marked erased imports explicitly across `cordis`, `loader`, `include`, `hmr`, and `schemastery` so Node's native TypeScript transform does not request types as runtime exports. Schemastery's source uses an ESM default export and its package declares `type: module`; its built ESM/CJS entries retain explicit `.mjs`/`.cjs` extensions. +11. **`include/src/index.ts` patch-semantics export**: extracted the private `applyPatches` body into the exported pure function `applyEntryPatches(data, patches, warn)` (the method delegates to it) and exported the `!!js` YAML dialect as `entryListSchema`, so `dsh --dump-config` composes and prints exactly what the include would mount without booting a tree. Behavior-preserving for mounting; the extraction exists because config tooling must never reimplement (and drift from) the patch algorithm. `applyEntryPatches` also indexes each `insert`ed entry as it is added, so a later patch in the same list can configure or disable a row an earlier patch inserted; upstream built the id index once before the patch loop, leaving inserted rows silently unpatchable. That matters because `dsh` composes an empty profile root with each bundle's patch layer, the profile's and the home-level `cordis.patch.yml`, and any `--patch` overlays as sibling patch lists at one include level — patches never cross an include boundary, so surface-only rows would otherwise be unreachable from user config. Covered by `packages/boot/app-boot/tests/config-reload.spec.ts`. +12. **`include/src/index.ts` serialized child-tree mutation and `hmr/src/index.ts` main-watcher initial-scan suppression**: every Include child-tree mutation (initial apply, refresh, `internal/update` patch re-application) runs through one per-Include queue, because the group's transactional `update` is not reentrant — two concurrent applies interleave create and rollback on the same entries and strand the Include fiber without ever settling. The HMR main watcher passes `ignoreInitial: true`: the initial scan re-announced files boot had just consumed, and its `add` for a config file refreshed an Include mid-initial-apply; once serialized, a failing initial apply's rollback disposed HMR, whose teardown drain waited on the queued refresh sitting behind that same apply — a deadlock that exited 13 with no diagnostic. `registerConfig()` keeps its own `ignoreInitial: false` watcher because a user patch layer present at registration must apply once. Covered by the patch-overlay boot-failure built-bin case in `apps/cli/tests/built-bin.e2e.ts`. +13. **`include/src/index.ts` `writeTask` type**: widened the optional `writeTask?: NodeJS.Timeout` property to `NodeJS.Timeout | undefined` — the debounced writer assigns `undefined` on flush, which `exactOptionalPropertyTypes` rejects on a plain optional. Type-only; no behavior change. +14. **`include/src/index.ts` durable debounced writes**: serialized and tracked config-file writes, retried transient `EACCES`/`EBUSY`/`EPERM` rename failures with a bounded backoff, observed asynchronous timer rejections, and drained the latest write during Include teardown. Windows can briefly retain a destination handle after a Loader child disposes; the upstream fire-and-forget rename escaped as an unhandled rejection and could lose the persisted `disabled` state. A terminal failure is logged by the asynchronous writer and remains on the queue so `Include.stop()` rethrows it instead of silently declaring persistence complete; Cordis's ordinary fiber teardown retains its separate error-containment contract. Covered by `packages/host/directory-picker-auto/tests/loader-composition.spec.ts` with injected transient and terminal rename failures. ## Sync procedure diff --git a/vendor/loader/package.json b/vendor/loader/package.json index 509c558ed3..1d4e757099 100644 --- a/vendor/loader/package.json +++ b/vendor/loader/package.json @@ -11,16 +11,11 @@ "types": "./lib/types/index.d.ts", "default": "./lib/index.js" }, - "./repository": { - "types": "./lib/types/repository.d.ts", - "default": "./lib/repository.js" - }, "./src/*": "./src/*", "./package.json": "./package.json" }, "files": [ "lib/index.js", - "lib/repository.js", "lib/types/**/*.d.ts", "lib/types/**/*.d.ts.map", "src" @@ -37,7 +32,6 @@ } }, "dependencies": { - "cosmokit": "^1.8.1", - "pnpm": "11.7.0" + "cosmokit": "^1.8.1" } } diff --git a/vendor/loader/src/repository.ts b/vendor/loader/src/repository.ts deleted file mode 100644 index c85b84ccfc..0000000000 --- a/vendor/loader/src/repository.ts +++ /dev/null @@ -1,258 +0,0 @@ -/** - * Exact-specifier repository packages installed through the Loader's bundled - * pnpm. The caller owns source validation and the cache root; this module owns - * isolated installation, single-flight reuse, and atomic cache publication. - */ - -import { spawn } from 'node:child_process' -import { createHash } from 'node:crypto' -import { mkdir, mkdtemp, readFile, rename, rm, stat, writeFile } from 'node:fs/promises' -import { createRequire } from 'node:module' -import { tmpdir } from 'node:os' -import { delimiter, dirname, join, resolve } from 'node:path' - -/** Exact pnpm release shipped with the Loader for repository installation. */ -export const BUNDLED_PNPM_VERSION = '11.7.0' - -const DEPENDENCY_NAME = 'repository' -const MARKER_NAME = '.repository-cache.json' -const MAX_ERROR_OUTPUT = 32 * 1024 -const SENSITIVE_ENV_PATTERN = /KEY|PASSWORD|SECRET|TOKEN/i - -/** Injectable isolated-install boundary used by {@link RepositoryCache}. */ -export type RepositoryInstall = (directory: string) => Promise - -/** Installation controls for {@link RepositoryCache}. */ -export interface RepositoryCacheOptions { - /** Override the isolated package installation boundary. */ - install?: RepositoryInstall -} - -interface CacheMarker { - specifier: string -} - -function scrubEnvironment(environment: NodeJS.ProcessEnv = process.env): NodeJS.ProcessEnv { - return Object.fromEntries(Object.entries(environment).filter(([name]) => !SENSITIVE_ENV_PATTERN.test(name))) -} - -function normalizedEnvironmentPath(value: string): string { - const unquoted = value.startsWith('"') && value.endsWith('"') ? value.slice(1, -1) : value - const normalized = resolve(unquoted) - return process.platform === 'win32' ? normalized.toUpperCase() : normalized -} - -function installEnvironment(commandDirectory: string): NodeJS.ProcessEnv { - const scrubbed = scrubEnvironment() - const path = Object.entries(scrubbed).find(([name]) => name.toUpperCase() === 'PATH')?.[1] - const pathExt = Object.entries(scrubbed).find(([name]) => name.toUpperCase() === 'PATHEXT')?.[1] - const pnpmHome = Object.entries(scrubbed).find(([name]) => name.toUpperCase() === 'PNPM_HOME')?.[1] - const normalizedPnpmHome = pnpmHome === undefined ? undefined : normalizedEnvironmentPath(pnpmHome) - const inheritedPath = path === undefined ? [] : path.split(delimiter).filter((entry) => { - return normalizedPnpmHome === undefined || normalizedEnvironmentPath(entry) !== normalizedPnpmHome - }) - const pathExtensions = pathExt?.split(';') - const prioritizedPathExt = pathExtensions === undefined ? undefined : [ - ...pathExtensions.filter(extension => extension.toUpperCase() === '.CMD'), - ...pathExtensions.filter(extension => extension.toUpperCase() !== '.CMD'), - ].join(';') - const withoutOverrides = Object.fromEntries(Object.entries(scrubbed).filter(([name]) => { - return !['PATH', 'PATHEXT', 'PNPM_CONFIG_IGNORE_WORKSPACE'].includes(name.toUpperCase()) - })) - return { - ...withoutOverrides, - PATH: [commandDirectory, ...inheritedPath].join(delimiter), - // cmd.exe tests PATHEXT before later PATH entries, so the transaction's - // pnpm.cmd must precede an inherited pnpm executable from PNPM_HOME. - ...(prioritizedPathExt === undefined ? {} : { PATHEXT: prioritizedPathExt }), - PNPM_CONFIG_IGNORE_WORKSPACE: 'true', - } -} - -function shellQuote(value: string): string { - return `'${value.replaceAll("'", "'\\''")}'` -} - -function batchQuote(value: string): string { - return `"${value.replaceAll('%', '%%')}"` -} - -function appendOutput(current: string, chunk: Uint8Array): string { - const combined = current + Buffer.from(chunk).toString('utf8') - return combined.length <= MAX_ERROR_OUTPUT ? combined : combined.slice(-MAX_ERROR_OUTPUT) -} - -async function installWithBundledPnpm(directory: string): Promise { - const require = createRequire(import.meta.url) - const pnpmManifest = require.resolve('pnpm') - const pnpmBin = join(dirname(pnpmManifest), 'bin', 'pnpm.mjs') - const commandDirectory = await mkdtemp(join(tmpdir(), 'cordis-repository-pnpm-')) - try { - await Promise.all([ - writeFile(join(commandDirectory, 'pnpm'), [ - '#!/bin/sh', - `exec ${shellQuote(process.execPath)} ${shellQuote(pnpmBin)} --ignore-workspace "$@"`, - '', - ].join('\n'), { mode: 0o700 }), - writeFile(join(commandDirectory, 'pnpm.cmd'), [ - '@echo off', - `${batchQuote(process.execPath)} ${batchQuote(pnpmBin)} --ignore-workspace %*`, - '', - ].join('\r\n'), { mode: 0o700 }), - ]) - let output = '' - const result = await new Promise<{ code: number | null; signal: NodeJS.Signals | null }>((resolve, reject) => { - const child = spawn(process.execPath, [ - pnpmBin, - 'install', - '--no-frozen-lockfile', - '--reporter=append-only', - ], { - cwd: directory, - env: installEnvironment(commandDirectory), - shell: false, - stdio: ['ignore', 'pipe', 'pipe'], - }) - child.stdout.on('data', (chunk: Uint8Array) => { output = appendOutput(output, chunk) }) - child.stderr.on('data', (chunk: Uint8Array) => { output = appendOutput(output, chunk) }) - child.once('error', reject) - child.once('close', (code, signal) => { resolve({ code, signal }) }) - }) - if (result.signal !== null) { - throw new Error(`bundled pnpm install was killed by ${result.signal}${output ? `\n${output.trimEnd()}` : ''}`) - } - if (result.code !== 0) { - throw new Error(`bundled pnpm install exited with code ${String(result.code)}${output ? `\n${output.trimEnd()}` : ''}`) - } - } finally { - await rm(commandDirectory, { recursive: true, force: true }) - } -} - -function cacheKey(specifier: string): string { - return createHash('sha256').update(specifier).digest('hex') -} - -async function readCached(directory: string, specifier: string): Promise { - let content: string - try { - content = await readFile(join(directory, MARKER_NAME), 'utf8') - } catch (error) { - if ((error as NodeJS.ErrnoException).code === 'ENOENT') return - throw error - } - let parsed: unknown - try { - parsed = JSON.parse(content) as unknown - } catch (error) { - throw new Error(`repository cache marker is invalid: ${join(directory, MARKER_NAME)}`, { cause: error }) - } - if (typeof parsed !== 'object' || parsed === null || typeof (parsed as Partial).specifier !== 'string') { - throw new Error(`repository cache marker is invalid: ${join(directory, MARKER_NAME)}`) - } - const marker = parsed as CacheMarker - if (marker.specifier !== specifier) { - throw new Error(`repository cache key collision for ${JSON.stringify(specifier)}`) - } - const packageDirectory = join(directory, 'node_modules', DEPENDENCY_NAME) - let packageStat - try { - packageStat = await stat(packageDirectory) - } catch (error) { - throw new Error(`repository cache entry is incomplete: ${directory}`, { cause: error }) - } - if (!packageStat.isDirectory()) throw new Error(`repository cache package is not a directory: ${packageDirectory}`) - return packageDirectory -} - -async function removeStaging(directory: string, cause: unknown): Promise { - try { - await rm(directory, { recursive: true, force: true }) - } catch (cleanupError) { - throw new AggregateError([cause, cleanupError], `failed to clean repository staging directory ${directory}`) - } - throw cause -} - -/** - * Persistent exact-specifier package cache backed by bundled pnpm. - * - * One isolated project contains one dependency named `repository`. A successful - * install is atomically renamed into its SHA-256 key, so failed installs never - * become cache hits. The exact specifier is immutable: callers change the - * specifier (normally its Git ref) to request another generation. - */ -export class RepositoryCache { - /** Absolute directory containing immutable repository cache entries. */ - readonly directory: string - - private readonly tasks = new Map>() - private readonly install: RepositoryInstall - - /** - * @param directory - caller-owned persistent cache root. - * @param options - isolated installer override. - */ - constructor(directory: string, options: RepositoryCacheOptions = {}) { - this.directory = resolve(directory) - this.install = options.install ?? installWithBundledPnpm - } - - /** - * Resolve one package-manager-native dependency specifier to its installed package directory. - * @param specifier - exact immutable dependency specifier used as the permanent cache identity. - * @returns the installed `repository` dependency directory. - * @throws when the specifier is empty/padded, installation fails, or a published cache entry is corrupt. - */ - resolve(specifier: string): Promise { - if (!specifier || specifier.trim() !== specifier) { - throw new TypeError('repository specifier must be a non-empty unpadded string') - } - const existing = this.tasks.get(specifier) - if (existing) return existing - const task = this.resolveUncached(specifier).finally(() => { - if (this.tasks.get(specifier) === task) this.tasks.delete(specifier) - }) - this.tasks.set(specifier, task) - return task - } - - private async resolveUncached(specifier: string): Promise { - const finalDirectory = join(this.directory, cacheKey(specifier)) - const cached = await readCached(finalDirectory, specifier) - if (cached) return cached - - await mkdir(this.directory, { recursive: true }) - const staging = await mkdtemp(join(this.directory, '.repository-')) - try { - await writeFile(join(staging, 'package.json'), `${JSON.stringify({ - name: 'cordis-repository-cache-entry', - private: true, - version: '0.0.0', - packageManager: `pnpm@${BUNDLED_PNPM_VERSION}`, - dependencies: { [DEPENDENCY_NAME]: specifier }, - }, undefined, 2)}\n`) - await writeFile(join(staging, 'pnpm-workspace.yaml'), [ - 'packages: []', - 'dangerouslyAllowAllBuilds: true', - '', - ].join('\n')) - await this.install(staging) - const packageDirectory = join(staging, 'node_modules', DEPENDENCY_NAME) - const packageStat = await stat(packageDirectory) - if (!packageStat.isDirectory()) throw new Error(`installed repository is not a directory: ${packageDirectory}`) - await writeFile(join(staging, MARKER_NAME), `${JSON.stringify({ specifier })}\n`) - try { - await rename(staging, finalDirectory) - } catch (error) { - const winner = await readCached(finalDirectory, specifier) - if (!winner) throw error - await rm(staging, { recursive: true, force: true }) - return winner - } - } catch (error) { - return removeStaging(staging, new Error(`failed to prepare repository ${JSON.stringify(specifier)}`, { cause: error })) - } - return (await readCached(finalDirectory, specifier))! - } -} diff --git a/vendor/loader/tsdown.config.ts b/vendor/loader/tsdown.config.ts index 75e627cdd2..b1e43952f2 100644 --- a/vendor/loader/tsdown.config.ts +++ b/vendor/loader/tsdown.config.ts @@ -1,6 +1,5 @@ import { defineConfig } from 'tsdown' -/** Keep the browser-reachable Loader entry separate from the Node-only repository cache. */ const shared = { outDir: 'lib', format: ['esm'], @@ -14,5 +13,4 @@ const shared = { export default defineConfig([ { ...shared, entry: ['lib/types/index.js'] }, - { ...shared, entry: ['lib/types/repository.js'] }, ]) From 541591d5f686eb3447b698b2b4a8dc6c4e1233c6 Mon Sep 17 00:00:00 2001 From: Turtle Date: Sun, 9 Aug 2026 16:53:54 +0800 Subject: [PATCH 09/15] fix: address repository removal review --- .../2026-08-09-remove-repository-plugin.i18n.yaml | 4 ++-- .../simplification/2026-08-09-remove-repository-plugin.md | 5 +++-- .../2026-08-09-remove-repository-plugin.zh.md | 5 +++-- packages/mcp/mcp-client/src/index.ts | 8 ++------ packages/skill/skill-local/tests/skill-local.spec.ts | 2 +- tsconfig.base.json | 1 - 6 files changed, 11 insertions(+), 14 deletions(-) diff --git a/.agents/notes/implemented/simplification/2026-08-09-remove-repository-plugin.i18n.yaml b/.agents/notes/implemented/simplification/2026-08-09-remove-repository-plugin.i18n.yaml index da5b77fbd0..5317c7911e 100644 --- a/.agents/notes/implemented/simplification/2026-08-09-remove-repository-plugin.i18n.yaml +++ b/.agents/notes/implemented/simplification/2026-08-09-remove-repository-plugin.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/simplification/2026-08-09-remove-repository-plugin.md -2026-08-09-remove-repository-plugin.md: 8dd2fe95ac97bc2d8ab50043eb6c516f53d3204c -2026-08-09-remove-repository-plugin.zh.md: 832a69ff206dd91dd312625bd9218e980d890ae2 +2026-08-09-remove-repository-plugin.md: 8ac6fd18b756e227f8dabc82eb4926a51702c5a1 +2026-08-09-remove-repository-plugin.zh.md: 6e504a151a88b87b8093a91a91ede1cb919a0b45 diff --git a/.agents/notes/implemented/simplification/2026-08-09-remove-repository-plugin.md b/.agents/notes/implemented/simplification/2026-08-09-remove-repository-plugin.md index 8dd2fe95ac..8ac6fd18b7 100644 --- a/.agents/notes/implemented/simplification/2026-08-09-remove-repository-plugin.md +++ b/.agents/notes/implemented/simplification/2026-08-09-remove-repository-plugin.md @@ -26,7 +26,7 @@ This note consolidates the removed repository cache, static format, config-only **Teach the repository wrapper to load a bundle patch.** Rejected because the repository cache and preparation protocol would still duplicate profile dependency installation. Bundle packages are already accepted from npm, Git, file, and link specifications through pnpm. -**Keep the generic Loader repository cache for possible future consumers.** Rejected because it has no current consumer after the package removal and carries a pinned package-manager runtime in a vendored browser-adjacent package. A future need can choose its cache contract from current consumers rather than preserving this one speculatively. +**Keep the generic Loader repository cache for possible future consumers.** Rejected because it has no current consumer after the package removal and carries a pinned package-manager runtime in a vendored browser-adjacent package. A dedicated cache is warranted again only if configuration-time activation without an explicit installation becomes a product requirement that profile dependencies cannot satisfy; that consumer can choose its cache contract then. **Disable repository Plugin but retain its on-disk format for migration.** Rejected under the pre-release stance. Retaining a parser or compatibility loader would keep the removed contract alive without an external compatibility obligation. @@ -34,10 +34,11 @@ This note consolidates the removed repository cache, static format, config-only - Third-party packages use one installation and composition model, with ordinary dependency declarations and full patch-level Plugin config. - Installing or updating an external bundle is an explicit `dsh plugin` package-manager operation rather than a watched source-list edit. User patch HMR still configures rows contributed by installed bundles. +- Profile installation requires `pnpm` on the host `PATH`. This is acceptable for an explicit package-management operation and avoids shipping the removed cache's pinned package-manager runtime solely for configuration-time activation. - `.dsh-plugin` packages and existing repository source-list patches stop working. Their cache files remain removable by the user but are not migrated or automatically deleted. - The dedicated pnpm runtime, preparation executable, wrapper generator, Git credential CI setup, repository cache, and repository-specific tests disappear. - Package-relative static assets need a bundle-owned path form so a declarative bundle can point `dsh-skill-local`, `dsh-mcp-client`, or another Plugin at files it ships without custom runtime glue. That capability is owned by the bundle format rather than a repository adapter. ## Testing -Static gates reject stale package, config, documentation, graph, and workspace references. The existing `dsh plugin` built-CLI acceptance covers profile initialization, package-manager installation, bundle discovery, and layer reconciliation. Bundle-specific tests own declarative asset-path resolution and real Skill/MCP composition. +Static gates reject stale package, config, documentation, graph, and workspace references. The existing `dsh plugin` built-CLI acceptance covers profile initialization, package-manager installation, bundle discovery, and layer reconciliation. Declarative package-relative Skill and MCP bundle resources remain a named coverage gap in this removal layer. diff --git a/.agents/notes/implemented/simplification/2026-08-09-remove-repository-plugin.zh.md b/.agents/notes/implemented/simplification/2026-08-09-remove-repository-plugin.zh.md index 832a69ff20..6e504a151a 100644 --- a/.agents/notes/implemented/simplification/2026-08-09-remove-repository-plugin.zh.md +++ b/.agents/notes/implemented/simplification/2026-08-09-remove-repository-plugin.zh.md @@ -26,7 +26,7 @@ DeepSeek Harness 只保留一种独立的外部插件分发路径:可安装的 **让 repository 包装层加载组合包 patch。** 不予采纳,因为 repository 缓存和准备协议仍会重复 profile 依赖安装。组合包已经可以通过 pnpm 接受 npm、Git、file 和 link 说明符。 -**为未来可能出现的消费方保留通用 Loader repository 缓存。** 不予采纳,因为在移除相关包后,它已无当前消费方,却仍让一个 vendor 中与浏览器相邻的包携带固定版本的包管理器运行时。未来若确有需要,可以根据届时的实际消费方选择缓存契约,无需推测性地保留现有契约。 +**为未来可能出现的消费方保留通用 Loader repository 缓存。** 不予采纳,因为在移除相关包后,它已无当前消费方,却仍让一个 vendor 中与浏览器相邻的包携带固定版本的包管理器运行时。只有当无需显式安装即可在配置阶段激活这一能力成为 profile 依赖无法满足的产品需求时,才有理由重新引入专用缓存;届时该消费方可以选择自己的缓存约定。 **禁用 repository 插件,但保留其磁盘格式以供迁移。** 根据预发布方针,不予采纳。保留解析器或兼容 loader 会在没有外部兼容义务的情况下,让已移除的契约继续存在。 @@ -34,10 +34,11 @@ DeepSeek Harness 只保留一种独立的外部插件分发路径:可安装的 - 第三方包统一使用一种安装与组合模型,采用普通依赖声明和完整的 patch 层插件配置。 - 安装或更新外部组合包时,必须显式通过 `dsh plugin` 执行包管理器操作,而不是编辑受监听的源列表。用户 patch 的 HMR(热模块替换)仍可配置已安装组合包所提供的配置项。 +- 安装 profile 时,宿主机的 `PATH` 中必须提供 `pnpm`。对于显式的包管理操作,这一要求可以接受,并且可避免仅为配置阶段激活而随产品交付已移除缓存所使用的固定版本包管理器运行时。 - `.dsh-plugin` 包和现有 repository 源列表 patch 停止工作。用户仍可自行删除其缓存文件,但系统不会迁移或自动删除这些文件。 - 专用 pnpm 运行时、准备工作可执行文件、包装层生成器、Git 凭据 CI 设置、repository 缓存和 repository 专用测试全部消失。 - 静态资源需要一种由组合包拥有、可相对于包解析的路径形式,使声明式组合包可以将 `dsh-skill-local`、`dsh-mcp-client` 或其他插件指向它随包交付的文件,而无需定制运行时代码。该能力归组合包格式所有,而不是 repository 适配器。 ## 测试 -静态门禁会拒绝残留的包、配置、文档、图和 workspace 引用。现有 `dsh plugin` 已构建 CLI(命令行界面)验收测试覆盖 profile 初始化、包管理器安装、组合包发现和层调和。组合包专用测试负责覆盖声明式资源路径解析,以及真实的 skill/MCP 组合。 +静态门禁会拒绝残留的包、配置、文档、图和 workspace 引用。现有 `dsh plugin` 已构建 CLI(命令行界面)验收测试覆盖 profile 初始化、包管理器安装、组合包发现和层调和。声明式、相对于包解析的 skill 与 MCP 组合包资源仍是本移除层中已明确记录的覆盖缺口。 diff --git a/packages/mcp/mcp-client/src/index.ts b/packages/mcp/mcp-client/src/index.ts index ece8c7857f..b55896544d 100644 --- a/packages/mcp/mcp-client/src/index.ts +++ b/packages/mcp/mcp-client/src/index.ts @@ -33,12 +33,8 @@ export const inject = ['tools'] /** Default timeout for individual MCP tool calls (ms). */ const DEFAULT_TOOL_CALL_TIMEOUT_MS = 60_000 -/** - * Valid `serverName`: 1–32 chars of `[A-Za-z0-9_-]`. Kept well under the - * 64-char public-name budget so typical raw tool names survive unhashed. - * Exported so config producers can reject the same names this registry would. - */ -export const SERVER_NAME_PATTERN = /^[A-Za-z0-9_-]{1,32}$/ +/** Valid `serverName`, kept below the public tool-name budget. */ +const SERVER_NAME_PATTERN = /^[A-Za-z0-9_-]{1,32}$/ /** * Live `serverName` reservations per app, keyed off `ctx.root` (multiple apps diff --git a/packages/skill/skill-local/tests/skill-local.spec.ts b/packages/skill/skill-local/tests/skill-local.spec.ts index 8bb08d2947..5bf1d24856 100644 --- a/packages/skill/skill-local/tests/skill-local.spec.ts +++ b/packages/skill/skill-local/tests/skill-local.spec.ts @@ -830,7 +830,7 @@ describe('LocalSkillProvider', () => { // Isolated providers see only their explicit roots: the environment // bundled root is a default root, so includeDefaultRoots: false must - // drop it — repository providers never re-claim the app's builtins. + // drop it — isolated providers never re-claim the app's builtins. const isolated = new Context() await isolated.plugin(SkillService) const customOnly = join(envHome, 'custom-only') diff --git a/tsconfig.base.json b/tsconfig.base.json index 0523b378d9..732e740ce7 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -32,7 +32,6 @@ "cosmokit": ["./vendor/cosmokit/src"], "schemastery": ["./vendor/schemastery/src"], "@cordisjs/plugin-loader": ["./vendor/loader/src"], - "@cordisjs/plugin-loader/repository": ["./vendor/loader/src/repository.ts"], "@cordisjs/plugin-include": ["./vendor/include/src"], "@cordisjs/plugin-group": ["./vendor/group/src"], "@cordisjs/plugin-timer": ["./vendor/timer/src"], From a33ee3d4f098ffbe9a2617c4eadb12a0282910c5 Mon Sep 17 00:00:00 2001 From: Turtle Date: Sun, 9 Aug 2026 17:01:03 +0800 Subject: [PATCH 10/15] docs: refresh MCP config catalog --- docs/config-catalog.i18n.yaml | 4 ++-- docs/config-catalog.md | 2 +- docs/config-catalog.zh.md | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/config-catalog.i18n.yaml b/docs/config-catalog.i18n.yaml index 889b2e24e7..a4cdb4a414 100644 --- a/docs/config-catalog.i18n.yaml +++ b/docs/config-catalog.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write docs/config-catalog.md -config-catalog.md: 471680f92dc44f3dd4e98ba9e946525ec79f25b0 -config-catalog.zh.md: bf78766799b02a1f6f21f935723abace108bc306 +config-catalog.md: 10078dea5221cfe76b1c028ef83216f5a4575940 +config-catalog.zh.md: 40153ab6a1a8a98fdaaebd0a42906557430b39d6 diff --git a/docs/config-catalog.md b/docs/config-catalog.md index 842b96d950..10078dea52 100644 --- a/docs/config-catalog.md +++ b/docs/config-catalog.md @@ -1109,7 +1109,7 @@ export interface StreamableHttpConfig { } ``` -Source: [`packages/mcp/mcp-client/src/index.ts:98`](../packages/mcp/mcp-client/src/index.ts) +Source: [`packages/mcp/mcp-client/src/index.ts:94`](../packages/mcp/mcp-client/src/index.ts) ## `@deepseek-ai/dsh-permission` diff --git a/docs/config-catalog.zh.md b/docs/config-catalog.zh.md index bf78766799..40153ab6a1 100644 --- a/docs/config-catalog.zh.md +++ b/docs/config-catalog.zh.md @@ -1111,7 +1111,7 @@ export interface StreamableHttpConfig { } ``` -来源:[`packages/mcp/mcp-client/src/index.ts:100`](../packages/mcp/mcp-client/src/index.ts) +来源:[`packages/mcp/mcp-client/src/index.ts:94`](../packages/mcp/mcp-client/src/index.ts) ## `@deepseek-ai/dsh-permission` From 820bb290357f2918a6d35fff0357ddf9b01dd7d3 Mon Sep 17 00:00:00 2001 From: Turtle Date: Mon, 10 Aug 2026 21:31:04 +0800 Subject: [PATCH 11/15] docs: sync repository removal translations --- docs/config-catalog.i18n.yaml | 2 +- docs/config-catalog.zh.md | 16 ---------------- docs/module-graph.i18n.yaml | 4 ++-- docs/module-graph.zh.md | 6 ------ docs/tool-catalog.i18n.yaml | 4 ++-- docs/tool-catalog.zh.md | 2 +- 6 files changed, 6 insertions(+), 28 deletions(-) diff --git a/docs/config-catalog.i18n.yaml b/docs/config-catalog.i18n.yaml index a4cdb4a414..02e95f011e 100644 --- a/docs/config-catalog.i18n.yaml +++ b/docs/config-catalog.i18n.yaml @@ -3,4 +3,4 @@ # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write docs/config-catalog.md config-catalog.md: 10078dea5221cfe76b1c028ef83216f5a4575940 -config-catalog.zh.md: 40153ab6a1a8a98fdaaebd0a42906557430b39d6 +config-catalog.zh.md: 38ed9f94bee9b0c11f5ea4dad4ba48532cce6450 diff --git a/docs/config-catalog.zh.md b/docs/config-catalog.zh.md index 40153ab6a1..38ed9f94be 100644 --- a/docs/config-catalog.zh.md +++ b/docs/config-catalog.zh.md @@ -1308,22 +1308,6 @@ export interface Config { 来源:[`packages/guard/repeat-tool-guard/src/index.ts:28`](../packages/guard/repeat-tool-guard/src/index.ts) -## `@deepseek-ai/dsh-repository-plugin` - -需要:`loader` - -```ts config-catalog -/** Repository Plugin runtime and source-list configuration. */ -export interface Config { - /** GitHub repository sources with explicit refs and optional `.dsh-plugin` subpaths. */ - repositories?: string[] - /** Persistent generation cache; defaults to `$DSH_HOME/cache/repository-plugins`. */ - cacheDir?: string -} -``` - -来源:[`packages/self-modification/repository-plugin/src/index.ts:44`](../packages/self-modification/repository-plugin/src/index.ts) - ## `@deepseek-ai/dsh-sandbox-local` ```ts config-catalog diff --git a/docs/module-graph.i18n.yaml b/docs/module-graph.i18n.yaml index 77fcfca867..8123225d51 100644 --- a/docs/module-graph.i18n.yaml +++ b/docs/module-graph.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write docs/module-graph.md -module-graph.md: b596cb564943e321ff42cd59855bd7dc10981319 -module-graph.zh.md: b64f30c2df1eedb1a1fa106b79710558b765fdde +module-graph.md: 9f2780c57aa78dabb6de5ff3d3d840b34c888ae0 +module-graph.zh.md: 8d67d9229a1498c2b39d80d32c84c4643086dd8f diff --git a/docs/module-graph.zh.md b/docs/module-graph.zh.md index b64f30c2df..8d67d9229a 100644 --- a/docs/module-graph.zh.md +++ b/docs/module-graph.zh.md @@ -255,7 +255,6 @@ flowchart TD pkg_telemetry["telemetry"] end subgraph group_self_modification["packages/self-modification"] - pkg_repository_plugin["repository-plugin"] pkg_tool_cordis["tool-cordis"] end subgraph group_session["packages/session"] @@ -1071,10 +1070,6 @@ flowchart TD pkg_sdk_protocol --> pkg_llm pkg_sdk_protocol --> pkg_session pkg_sdk_protocol --> pkg_subagent - pkg_repository_plugin --> pkg_invariants - pkg_repository_plugin --> pkg_mcp_client - pkg_repository_plugin --> pkg_paths - pkg_repository_plugin --> pkg_skill_local pkg_tool_ralph --> pkg_agent pkg_tool_ralph --> pkg_invariants pkg_tool_ralph --> pkg_llm @@ -1432,7 +1427,6 @@ flowchart TD | [`web-app`](../packages/bundle/web-app) | `bundle` | [`bash-env`](../packages/bash/bash-env), [`invariants`](../packages/support/invariants), [`system-prompt`](../packages/core/system-prompt) | | [`client-ui-conversation`](../packages/client/ui-conversation) | `client` | [`agent`](../packages/core/agent), [`attachment`](../packages/attachment/attachment), [`brand`](../packages/util/brand), [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-primitives`](../packages/client/ui-primitives), [`client-ui-slash`](../packages/client/ui-slash), [`client-ui-slots`](../packages/client/ui-slots), [`commands`](../packages/interaction/commands), [`compact`](../packages/compact/compact), [`invariants`](../packages/support/invariants), [`llm-retry`](../packages/llm/llm-retry), [`token-meter`](../packages/llm/token-meter), [`tools`](../packages/core/tools) | | [`sdk-protocol`](../packages/scaffold/protocol) | `scaffold` | [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`subagent`](../packages/subagent/subagent) | -| [`repository-plugin`](../packages/self-modification/repository-plugin) | `self-modification` | [`invariants`](../packages/support/invariants), [`mcp-client`](../packages/mcp/mcp-client), [`paths`](../packages/util/paths), [`skill-local`](../packages/skill/skill-local) | | [`tool-ralph`](../packages/workflow/tool-ralph) | `workflow` | [`agent`](../packages/core/agent), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`subagent`](../packages/subagent/subagent), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools), [`workflow`](../packages/workflow/workflow) | | [`workflow-workerthread`](../packages/workflow/workflow-workerthread) | `workflow` | [`agent`](../packages/core/agent), [`brand`](../packages/util/brand), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`subagent`](../packages/subagent/subagent), [`tools`](../packages/core/tools), [`workflow`](../packages/workflow/workflow) | | [`compact-basic`](../packages/compact/compact-basic) | `compact` | [`agent`](../packages/core/agent), [`commands`](../packages/interaction/commands), [`compact`](../packages/compact/compact), [`compact-tool-result-prune`](../packages/compact/compact-tool-result-prune), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`token-meter`](../packages/llm/token-meter) | diff --git a/docs/tool-catalog.i18n.yaml b/docs/tool-catalog.i18n.yaml index 567f95d408..b74b7fa8ea 100644 --- a/docs/tool-catalog.i18n.yaml +++ b/docs/tool-catalog.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write docs/tool-catalog.md -tool-catalog.md: dbab9ce2f389dbfe40e7d753ced995a8a384be17 -tool-catalog.zh.md: e99f8bc78923e616265427c1e0361c832cc0930f +tool-catalog.md: f61b6daeb7209d0fa81606bda7718fd42c7f22dc +tool-catalog.zh.md: cbecdba084fa64ec78913706221a1558d206cde8 diff --git a/docs/tool-catalog.zh.md b/docs/tool-catalog.zh.md index e99f8bc789..cbecdba084 100644 --- a/docs/tool-catalog.zh.md +++ b/docs/tool-catalog.zh.md @@ -286,7 +286,7 @@ pwsh 工具是 Windows 组合中 bash 执行器 seam 的 PowerShell 方言消费 ### `cordis_mount` -在当前 DSH 进程中挂载临时 Cordis Plugin。它创建的是内存中的运行时 Plugin,而不是已安装或已配置的 Plugin。该插件会在后续轮次中保持活动,直到执行 cordis_unmount、工具集卸载或 DSH 重启。它不会创建文件、安装包、修改 cordis.yml 或个人/项目配置、在重启后保留,也不会自动转为永久插件。若要保留,请让 Agent 通过常规开发工作流实现普通的本地、项目或仓库 Plugin。它可能影响同一进程中的其他会话;沙箱不是安全边界,注入的服务会访问真实运行时。`code` 会立即作为异步 JavaScript 函数的函数体在隔离沙箱中运行,并且**必须** `return` 一个插件。支持两种形式:函数形式 `return (ctx) => { … }`,它不声明 inject,因此可以注册工具、监听事件和提供服务,但访问**任何**服务(例如 ctx.bash)都会抛出异常;仅在不需要服务时使用。对象形式 `return { name?, inject: ['bash', 'llm', …], apply(ctx) { … } }`,它声明依赖,Cordis 只在服务存在后激活插件;**优先使用**这种形式。你只能访问 inject 中列出的服务:即使未声明的服务存在,访问它也会抛出异常,因为如果提供方被卸载,未声明的依赖将无法清理。代码调用服务**之前**,请读取 cordis_inspect 的 what:"api";它会列出方法签名以及参数/返回值的类型形状,不要猜测字段类型,例如 bash 运行的 stdout 是对象而非字符串。在 `apply` 内,请使用标准 Cordis API:通过 `ctx.on(event, listener)` 观察事件(见 cordis_inspect 的 what:"events"),或调用 `harness.registerTool(ctx, harness.defineTool({ name, description, parameters: { text: { type: 'string', required: true } }, output: { schema: { type: 'string' }, render(_args, value) { return [{ type: 'text', text: value }] } }, async execute(args) { return args.text } }))` 为自己提供新工具;该工具会在你的**下一步骤**可调用。工具参数:每个键**就是**一个属性,即 { type: 'string'|'number'|'integer'|'boolean'|'null'|'object'|'array'|'json', required?: true, description?, enum?, const?, items?, properties? };每个直接 DSL 对象都声明 additionalProperties: true|false,而 oneOf: [schema, schema, ...] 会取代 type,表示恰好匹配一个成员的联合。也接受原始 JSON Schema { type: 'object', properties, required?: […] } 包装层,其中对象默认开放。工具的 `execute` **必须**返回 `output.schema` 声明的无损 JSON 值;`output.render(args, value)` 单独返回 Native/模型内容块。临时 Plugin 可以**组合**:一个 Plugin 可以通过 `ctx.provide('name', value)` 提供服务,另一个则可声明 `inject: ['name']` 来消费它;消费方会在提供方出现前保持等待,提供方卸载后重新回到等待状态。在 `apply` 中注册的一切都会由 cordis_unmount 自动清理。沙箱全局对象:`console`(带 `[cordis:]` 标签,写入 harness 终端)、`harness.defineTool`、`harness.registerTool`、`btoa`、`atob`、`TextEncoder`、`TextDecoder`。Node API 已**禁用**:文件系统/网络/定时工作必须通过 Cordis 服务完成,绝不能使用 Node 内置能力;`require`、`setTimeout`/`setInterval` 和 `fetch` 会抛出重定向错误,`process` 和 `Buffer` 未定义。应改用 inject: ['fs'] + ctx.fs 处理文件、inject: ['web'] + ctx.web 处理 HTTP、inject: ['bash'] + ctx.bash 处理进程、inject: ['timer'] + ctx.setTimeout/ctx.setInterval 处理定时(这些是 fiber effect,卸载时自动清理);cordis_inspect 的 what:"api" 会展示**当前**运行时提供的能力。请编写**纯** JavaScript,不要使用 TypeScript(不得使用 `as` 或类型注解)。注意事项:(1) waterfall(瀑布式事件)事件(例如 tools/pre-execute)会向监听器传入最后一个 `next` 回调,该回调**必须**被调用;不调用 `next()` 就返回会**短路**此次调用。除非你有意拦截,否则请优先使用普通通知事件。(2) 切勿等待只能在当前轮次之后解析的内容;你的代码运行在该轮次的工具调用**内部**,否则会死锁。(3) 你的 `ctx` 是受限门面:可以注册工具、观察事件、提供/消费服务和使用定时器,但不会提供框架内部能力(ctx.root、ctx.fiber、ctx.extend、ctx.plugin 等)。不过,它并非安全边界:你注入的服务(例如 ctx.bash)会访问真实运行时。 +在当前 DSH 进程中挂载临时 Cordis Plugin。它创建的是内存中的运行时 Plugin,而不是已安装或已配置的 Plugin。该插件会在后续轮次中保持活动,直到执行 cordis_unmount、工具集卸载或 DSH 重启。它不会创建文件、安装包、修改 cordis.yml 或个人/项目配置、在重启后保留,也不会自动转为永久插件。若要保留,请让 Agent 通过常规开发工作流实现 SDK Plugin 或可安装的 profile bundle。它可能影响同一进程中的其他会话;沙箱不是安全边界,注入的服务会访问真实运行时。`code` 会立即作为异步 JavaScript 函数的函数体在隔离沙箱中运行,并且**必须** `return` 一个插件。支持两种形式:函数形式 `return (ctx) => { … }`,它不声明 inject,因此可以注册工具、监听事件和提供服务,但访问**任何**服务(例如 ctx.bash)都会抛出异常;仅在不需要服务时使用。对象形式 `return { name?, inject: ['bash', 'llm', …], apply(ctx) { … } }`,它声明依赖,Cordis 只在服务存在后激活插件;**优先使用**这种形式。你只能访问 inject 中列出的服务:即使未声明的服务存在,访问它也会抛出异常,因为如果提供方被卸载,未声明的依赖将无法清理。代码调用服务**之前**,请读取 cordis_inspect 的 what:"api";它会列出方法签名以及参数/返回值的类型形状,不要猜测字段类型,例如 bash 运行的 stdout 是对象而非字符串。在 `apply` 内,请使用标准 Cordis API:通过 `ctx.on(event, listener)` 观察事件(见 cordis_inspect 的 what:"events"),或调用 `harness.registerTool(ctx, harness.defineTool({ name, description, parameters: { text: { type: 'string', required: true } }, output: { schema: { type: 'string' }, render(_args, value) { return [{ type: 'text', text: value }] } }, async execute(args) { return args.text } }))` 为自己提供新工具;该工具会在你的**下一步骤**可调用。工具参数:每个键**就是**一个属性,即 { type: 'string'|'number'|'integer'|'boolean'|'null'|'object'|'array'|'json', required?: true, description?, enum?, const?, items?, properties? };每个直接 DSL 对象都声明 additionalProperties: true|false,而 oneOf: [schema, schema, ...] 会取代 type,表示恰好匹配一个成员的联合。也接受原始 JSON Schema { type: 'object', properties, required?: […] } 包装层,其中对象默认开放。工具的 `execute` **必须**返回 `output.schema` 声明的无损 JSON 值;`output.render(args, value)` 单独返回 Native/模型内容块。临时 Plugin 可以**组合**:一个 Plugin 可以通过 `ctx.provide('name', value)` 提供服务,另一个则可声明 `inject: ['name']` 来消费它;消费方会在提供方出现前保持等待,提供方卸载后重新回到等待状态。在 `apply` 中注册的一切都会由 cordis_unmount 自动清理。沙箱全局对象:`console`(带 `[cordis:]` 标签,写入 harness 终端)、`harness.defineTool`、`harness.registerTool`、`btoa`、`atob`、`TextEncoder`、`TextDecoder`。Node API 已**禁用**:文件系统/网络/定时工作必须通过 Cordis 服务完成,绝不能使用 Node 内置能力;`require`、`setTimeout`/`setInterval` 和 `fetch` 会抛出重定向错误,`process` 和 `Buffer` 未定义。应改用 inject: ['fs'] + ctx.fs 处理文件、inject: ['web'] + ctx.web 处理 HTTP、inject: ['bash'] + ctx.bash 处理进程、inject: ['timer'] + ctx.setTimeout/ctx.setInterval 处理定时(这些是 fiber effect,卸载时自动清理);cordis_inspect 的 what:"api" 会展示**当前**运行时提供的能力。请编写**纯** JavaScript,不要使用 TypeScript(不得使用 `as` 或类型注解)。注意事项:(1) waterfall(瀑布式事件)事件(例如 tools/pre-execute)会向监听器传入最后一个 `next` 回调,该回调**必须**被调用;不调用 `next()` 就返回会**短路**此次调用。除非你有意拦截,否则请优先使用普通通知事件。(2) 切勿等待只能在当前轮次之后解析的内容;你的代码运行在该轮次的工具调用**内部**,否则会死锁。(3) 你的 `ctx` 是受限门面:可以注册工具、观察事件、提供/消费服务和使用定时器,但不会提供框架内部能力(ctx.root、ctx.fiber、ctx.extend、ctx.plugin 等)。不过,它并非安全边界:你注入的服务(例如 ctx.bash)会访问真实运行时。 ```json { From ec810b02e8872ff14da7a058f10021e53585fe16 Mon Sep 17 00:00:00 2001 From: Hypatia May Date: Mon, 10 Aug 2026 22:00:58 +0800 Subject: [PATCH 12/15] test(subagent): dispose continuable inheritance fixtures --- .../subagent/subagent/tests/continuation-inheritance.spec.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/subagent/subagent/tests/continuation-inheritance.spec.ts b/packages/subagent/subagent/tests/continuation-inheritance.spec.ts index e30623c073..e119ffec13 100644 --- a/packages/subagent/subagent/tests/continuation-inheritance.spec.ts +++ b/packages/subagent/subagent/tests/continuation-inheritance.spec.ts @@ -28,13 +28,16 @@ import SubagentService from '../src/index.ts' type Script = ConstructorParameters[0] const roots: string[] = [] -afterEach(() => { +const contexts: Context[] = [] +afterEach(async () => { + for (const ctx of contexts.splice(0).reverse()) await ctx.fiber.dispose() for (const root of roots.splice(0)) rmSync(root, { recursive: true, force: true }) }) /** Boot the continuable stack plus both policy services the manager consumes opportunistically. */ async function setup(script: Script) { const ctx = new Context() + contexts.push(ctx) await mountAgentLoopTestDependencies(ctx) const root = mkdtempSync(join(tmpdir(), 'dsh-continuation-inherit-')) roots.push(root) From 194828e8b8ac7ad347e43f80d1d88ea022d47ae6 Mon Sep 17 00:00:00 2001 From: imccyu <276526105+imccyu@users.noreply.github.com> Date: Mon, 10 Aug 2026 10:50:09 +0800 Subject: [PATCH 13/15] build(vendor): add the @deepseek-ai rescope codemod, its mapping doc, and its Agent Note MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Every harness package declares cordis as a peer dependency, so publishing the harness publishes the vendored framework layer too; under the upstream names that publication would squat them on the registry. scripts/rescope-vendor.ts owns the rename: the nine-package mapping, a delimited-token rule that leaves cordis.yml, the Loader's cordis: builtins and vendor directory names alone, per-file exemptions where a name is a directory or an upstream runtime identifier, and the exact edits for sites a token rule cannot express — dot-notation lookups, unquoted manifest keys, a regex literal whose failure would make every Context-merge scan silently find nothing, the vendored-manifest table, and the contracts that told readers vendored packages keep their upstream names. Markdown follows the rename inside every fence, because a fence is code a reader copies or configuration they mount, and in `docs/` prose as well, where a sentence quoting a name teaches something this repository no longer resolves. Prose elsewhere records what was true when it was written, and the same spelling can mean something else: the Python SDK's `cordis` option, or the unvendored `@cordisjs/plugin-http`. `docs/rescope.md` states both names on purpose and is exempt. exactEditState() classifies every exact edit as pending, applied, or invalid. An insertion keeps its anchor and a deletion keeps its remainder, so each side counts the form that survives: a duplicated insertion, a half-applied replacement, and a deletion whose remainder moved are all invalid. The run classifies every edit before writing anything and aborts on the first invalid one, so a disagreement between the mapping and the tree cannot leave a half-rescoped checkout; each write re-reads its file, because two edits can target one. rescope-vendor.spec.ts pins those rejections, and --check asserts the whole post-state from the hygiene gate, so CI owns the invariant. --reverse restores the upstream names, verified as a round trip: reverse, then apply, reproduces this tree byte for byte. docs/rescope.md is the consumer-facing reference: the old-name/new-name table with each package's role, what the rename deliberately leaves alone, the sites callers must change, and the commands to apply, verify, and revert. The Agent Note carries the decision and its consequences. The rename itself lands in the next commit, produced by running the script. --- ...026-08-10-vendor-package-rescope.i18n.yaml | 6 + .../2026-08-10-vendor-package-rescope.md | 51 ++ .../2026-08-10-vendor-package-rescope.zh.md | 51 ++ docs/rescope.i18n.yaml | 6 + docs/rescope.md | 53 ++ docs/rescope.zh.md | 53 ++ package.json | 4 +- scripts/rescope-vendor.spec.ts | 41 + scripts/rescope-vendor.ts | 771 ++++++++++++++++++ scripts/run-gates.ts | 1 + 10 files changed, 1036 insertions(+), 1 deletion(-) create mode 100644 .agents/notes/implemented/process/2026-08-10-vendor-package-rescope.i18n.yaml create mode 100644 .agents/notes/implemented/process/2026-08-10-vendor-package-rescope.md create mode 100644 .agents/notes/implemented/process/2026-08-10-vendor-package-rescope.zh.md create mode 100644 docs/rescope.i18n.yaml create mode 100644 docs/rescope.md create mode 100644 docs/rescope.zh.md create mode 100644 scripts/rescope-vendor.spec.ts create mode 100644 scripts/rescope-vendor.ts diff --git a/.agents/notes/implemented/process/2026-08-10-vendor-package-rescope.i18n.yaml b/.agents/notes/implemented/process/2026-08-10-vendor-package-rescope.i18n.yaml new file mode 100644 index 0000000000..46715efdcb --- /dev/null +++ b/.agents/notes/implemented/process/2026-08-10-vendor-package-rescope.i18n.yaml @@ -0,0 +1,6 @@ +# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each +# side as of the last confirmed-consistent state. Both languages carry equal authority; +# after editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-08-10-vendor-package-rescope.md +2026-08-10-vendor-package-rescope.md: f2a142cec4e3c28fae54af8063cd730931fa738b +2026-08-10-vendor-package-rescope.zh.md: 994064fc869e1ccd95609ec67010eae794ed1c48 diff --git a/.agents/notes/implemented/process/2026-08-10-vendor-package-rescope.md b/.agents/notes/implemented/process/2026-08-10-vendor-package-rescope.md new file mode 100644 index 0000000000..f2a142cec4 --- /dev/null +++ b/.agents/notes/implemented/process/2026-08-10-vendor-package-rescope.md @@ -0,0 +1,51 @@ +# Agent Note: Rescope vendored Cordis into @deepseek-ai + +Status: implemented + +English | [中文](2026-08-10-vendor-package-rescope.zh.md) + +## Problem + +The nine packages under `vendor/` kept their upstream npm names (`cordis`, `cosmokit`, `schemastery`, `@cordisjs/plugin-*`). That premise does not survive publication: every harness package declares `cordis` as a peer dependency, so a consumer installing `@deepseek-ai/dsh-*` must resolve it from the registry, which means publishing the harness publishes this framework layer too. Publishing it under the upstream names squats them on the registry, and where that registry proxies npmjs, the same-name entries shadow the real upstream packages and install the wrong framework into unrelated projects. + +## Decision + +All nine packages move into the `@deepseek-ai` scope. Directory names, upstream version numbers, and dependency ranges stay untouched, so the `vendor/README.md` manifest still reads as an upstream snapshot. [docs/rescope.md](../../../../docs/rescope.md) restates this mapping for consumers. + +| Directory | npm name | Upstream name | +|---|---|---| +| `cordis/` | `@deepseek-ai/cordis` | `cordis` | +| `cosmokit/` | `@deepseek-ai/cosmokit` | `cosmokit` | +| `schemastery/` | `@deepseek-ai/schemastery` | `schemastery` | +| `loader/` | `@deepseek-ai/cordis-plugin-loader` | `@cordisjs/plugin-loader` | +| `include/` | `@deepseek-ai/cordis-plugin-include` | `@cordisjs/plugin-include` | +| `group/` | `@deepseek-ai/cordis-plugin-group` | `@cordisjs/plugin-group` | +| `timer/` | `@deepseek-ai/cordis-plugin-timer` | `@cordisjs/plugin-timer` | +| `hmr/` | `@deepseek-ai/cordis-plugin-hmr` | `@cordisjs/plugin-hmr` | +| `logger-console/` | `@deepseek-ai/cordis-plugin-logger-console` | `@cordisjs/plugin-logger-console` | + +The rewrite touches only **delimited, complete package-name tokens**: quoted or backticked specifiers (optionally with a `/subpath`), `package.json` names and dependency keys, `cordis.yml` `name:` values, and `tsconfig.base.json` `paths` keys. Identically spelled strings that are not package names therefore stayed as they were: the `cordis.yml` config-file family, the Loader's literal `cordis:` builtin prefix (`cordis:include`, `cordis:group` — see `vendor/loader/src/config/tree.ts`), kind strings like `cordis-config-entry`, `@deepseek-ai/dsh-tool-cordis`, Schemastery's upstream `Symbol.for('schemastery')` and `vendor:` metadata field, the `packages//` directory names in `GROUP_ORDER` (`scripts/gen-module-graph.ts`, `scripts/gen-doc-graphs.ts`), and the upstream install instructions in `vendor/*/README.md`. + +Two classes are invisible to a token rule and were renamed site by site. First, property access and unquoted object keys — `manifest.peerDependencies?.cordis`, and the manifest keys the scaffold generates in `npm-dependency-policy.ts` and `local-plugin-blueprint.ts` — where TypeScript cannot catch a stale `Record` key. Second, constants that carry the name as data: the vendored set in `check-workspace-constraints.ts`, the group/include names in `verify-cordis-config.ts`, the `declare module` target strings in `cordis-walk.ts`, `gen-scoped-events.ts`, and typert's `analyzer.ts`, and `alwaysBundle` in `app-boot/tsdown.config.ts`. + +Markdown splits along what a reader does with it. Every fence follows the rename regardless of its info string, because a fence is code they copy or configuration they mount — the `yaml` fences naming Loader plugins and the `ts ignore-check` fences beside compiled ones included. Prose follows it under `docs/`, where a tutorial sentence quoting a name teaches something this repository no longer resolves. Prose elsewhere — `vendor/*/README.md`, package READMEs, and `.agents/notes/` — keeps the names it was written with, both because it records what was true then and because the same spelling can mean something else: the Python SDK's `cordis` option, the unvendored `@cordisjs/plugin-http`, or an agent-preset id. + +## Consequences + +- No upstream name remains in the publication set. `publish-npm-baseline.ts` now requires every published package to be `@deepseek-ai/*` with no vendored exemption, so regressing the rename fails before packing. +- The `vendor/README.md` manifest table gains an upstream-name column; `gen-third-party-notices` parses six columns and renders that name into `THIRD_PARTY_NOTICES.md`, keeping MIT attribution pointed at each fork's origin rather than our scope. +- `pnpm-workspace.yaml` drops the `cordis` and `@cordisjs/plugin-loader` `minimumReleaseAgeExclude` entries, which can no longer be fetched from a registry, and `knip.json` drops the `@cordisjs/.+` ignore pattern that `@deepseek-ai/.+` already covers. +- Upstream sync follows the procedure in `vendor/README.md` with one added obligation in step 3: re-apply the rename over the copied sources with `pnpm run rescope-vendor --apply`, whose mapping and the table's two name columns must agree. +- **Returning to the official upstream packages** means applying that mapping in reverse — `pnpm run rescope-vendor --apply --reverse` — then restoring the two `minimumReleaseAgeExclude` entries and relaxing the publication-set assertion. It spans roughly 1300 files, so replay it with the script rather than by hand. + +`scripts/rescope-vendor.ts` owns the rename: the mapping, the delimited-token rule, the per-file exemptions where a name is a directory instead of a package, the exact edits above, and a `--check` mode asserting no residue, every exact edit landed, and idempotency, which the `hygiene` gate runs on every CI pass. A rebase replays it instead of resolving a 1300-file conflict, and an upstream change to one of the pinned sites fails the run loudly instead of being silently skipped. + +## Alternatives considered + +**Keep the upstream names and exclude `vendor/` from publication.** Rejected because every harness package declares `cordis` as a peer dependency, so an installed `@deepseek-ai/dsh-*` would have no resolvable framework. + +**Rename only at pack time.** Rejected because the published names would disagree with the source tree, every module specifier would have to be rewritten inside the publish path, and no local run could reproduce what was published. + +**Rename the `vendor/` directories and unify versions on the repository base version too.** Rejected because directory names are not publication identity — renaming them drags in project references, tsdown globs, and documentation paths for no gain — and a `0.0.1` version would no longer satisfy the preserved `^4.0.0-rc.7` ranges, so pnpm would look for a registry copy and `verify-vendored-links` would fail. + +**Rewrite prose outside `docs/` and historical Agent Notes as well.** Rejected because those record what was true when written, and a bare `cordis` there is as likely to be an SDK option name or a preset id as a package; `docs/rescope.md` carries the mapping for readers instead. diff --git a/.agents/notes/implemented/process/2026-08-10-vendor-package-rescope.zh.md b/.agents/notes/implemented/process/2026-08-10-vendor-package-rescope.zh.md new file mode 100644 index 0000000000..994064fc86 --- /dev/null +++ b/.agents/notes/implemented/process/2026-08-10-vendor-package-rescope.zh.md @@ -0,0 +1,51 @@ +# Agent Note: 把 vendored Cordis 重命名进 @deepseek-ai scope + +Status: implemented + +[English](2026-08-10-vendor-package-rescope.md) | 中文 + +## 问题 + +`vendor/` 下的九个包此前保留上游 npm 名(`cordis`、`cosmokit`、`schemastery`、`@cordisjs/plugin-*`)。这个前提在发布时不成立:每个 harness 包都把 `cordis` 声明成 peer dependency,装了 `@deepseek-ai/dsh-*` 的消费者必须能从 registry 解析到它,所以发布 harness 必然连带发布这一层框架。用上游名发布就是在 registry 上占用别人的名字;若该 registry 对 npmjs 做上游代理,本名条目还会遮蔽真正的上游包,把错误的框架装进无关项目。 + +## 决定 + +九个包统一改名进 `@deepseek-ai` scope。目录名、上游版本号、依赖 range 一律不动,所以 `vendor/README.md` 的清单仍然读作一份上游快照。面向使用者的映射表见 [docs/rescope.md](../../../../docs/rescope.md)。 + +| 目录 | npm 名 | 上游名 | +|---|---|---| +| `cordis/` | `@deepseek-ai/cordis` | `cordis` | +| `cosmokit/` | `@deepseek-ai/cosmokit` | `cosmokit` | +| `schemastery/` | `@deepseek-ai/schemastery` | `schemastery` | +| `loader/` | `@deepseek-ai/cordis-plugin-loader` | `@cordisjs/plugin-loader` | +| `include/` | `@deepseek-ai/cordis-plugin-include` | `@cordisjs/plugin-include` | +| `group/` | `@deepseek-ai/cordis-plugin-group` | `@cordisjs/plugin-group` | +| `timer/` | `@deepseek-ai/cordis-plugin-timer` | `@cordisjs/plugin-timer` | +| `hmr/` | `@deepseek-ai/cordis-plugin-hmr` | `@cordisjs/plugin-hmr` | +| `logger-console/` | `@deepseek-ai/cordis-plugin-logger-console` | `@cordisjs/plugin-logger-console` | + +改写只落在**带定界符的完整包名 token** 上:引号或反引号包裹的 specifier(可带 `/子路径`)、`package.json` 的 `name` 与依赖键、`cordis.yml` 的 `name:` 值、`tsconfig.base.json` 的 `paths` 键。因此以下同形串一律未改,它们不是包名:`cordis.yml` 及其家族文件名、Loader 的 `cordis:` 内建前缀(`cordis:include`、`cordis:group`,见 `vendor/loader/src/config/tree.ts`)、`cordis-config-entry` 这类 kind 串、`@deepseek-ai/dsh-tool-cordis`、Schemastery 上游的 `Symbol.for('schemastery')` 与 `vendor:` 元数据、`scripts/gen-module-graph.ts` 与 `gen-doc-graphs.ts` 里 `GROUP_ORDER` 的 `packages//` 目录名,以及 `vendor/*/README.md` 里的上游安装指引。 + +Token 规则看不见两类点位,它们按名字逐处改:一是属性访问与未加引号的对象键(`manifest.peerDependencies?.cordis`、脚手架 `npm-dependency-policy.ts` 与 `local-plugin-blueprint.ts` 生成的清单键)——TypeScript 抓不到过期的 `Record` 键;二是把名字当数据的常量(`check-workspace-constraints.ts` 的 vendored 集合、`verify-cordis-config.ts` 的 group/include 名、`cordis-walk.ts` 与 `gen-scoped-events.ts` 与 typert `analyzer.ts` 里识别 `declare module` 目标的字符串、`app-boot/tsdown.config.ts` 的 `alwaysBundle`)。 + +Markdown 按「读者拿它做什么」一分为二。围栏一律跟着改,不看 info string——围栏里是读者要照抄的代码或要挂载的配置,包括写着 Loader 插件名的 `yaml` 围栏和紧邻编译围栏的 `ts ignore-check` 围栏。散文只在 `docs/` 下跟着改:教程里引用某个名字的句子,教的是本仓已不解析的东西。`docs/` 之外的散文——`vendor/*/README.md`、各包 README、`.agents/notes/`——保留写作当时的名字:既因为它记录的是当时的事实,也因为同一个拼写可能指别的东西,比如 Python SDK 的 `cordis` 选项、我们没 vendor 的 `@cordisjs/plugin-http`,或某个 agent-preset 的 id。 + +## 影响 + +- 发布集里不再有任何上游名:`publish-npm-baseline.ts` 现在无条件要求每个待发包都是 `@deepseek-ai/*`,vendored 包不再豁免,改名一旦回退就会在打包前失败。 +- `vendor/README.md` 的清单表新增「上游名」列,`gen-third-party-notices` 随之解析六列并把上游名渲进 `THIRD_PARTY_NOTICES.md`;MIT 归属指向 fork 的来源,而不是我们的 scope。 +- `pnpm-workspace.yaml` 的 `minimumReleaseAgeExclude` 删去 `cordis` 与 `@cordisjs/plugin-loader` 两条:改名后这两个名字永远不从 registry 取。`knip.json` 的 `@cordisjs/.+` 忽略模式同理删除,已被 `@deepseek-ai/.+` 覆盖。 +- 上游 sync 照 `vendor/README.md` 的流程走,第 3 步多一项:对拷进来的源码重跑 `pnpm run rescope-vendor --apply`,脚本里的映射与清单表两列名字必须一致。 +- **要回到官方上游包**时反着跑这份映射——`pnpm run rescope-vendor --apply --reverse`——再补回 `minimumReleaseAgeExclude` 两条、放开发布集对 `@deepseek-ai/*` 的断言。改写量约 1300 个文件,用脚本重放而不是手改。 + +改名这件事由 `scripts/rescope-vendor.ts` 承载:映射、带定界符的 token 规则、名字其实是目录而非包时的逐文件豁免、上面那批精确改写,以及一个断言「零残留、每条精确改写都落上、幂等」的 `--check` 模式——它由 `hygiene` 门在每次 CI 上执行。rebase 时重放它,而不是去解一个 1300 文件的冲突;上游动了任一被钉住的点位,脚本会响亮失败而不是静默漏改。 + +## 考虑过的替代方案 + +**保留上游名,把 `vendor/` 排除在发布集之外。** 否决:每个 harness 包都声明 `cordis` 为 peer dependency,装好的 `@deepseek-ai/dsh-*` 会解析不到框架。 + +**只在打包时改名。** 否决:发出去的名字与源码树不一致,所有模块 specifier 得在发布路径里现改,本地也没有任何一次运行能复现发布出去的东西。 + +**目录名与版本号一并改。** 否决:目录名不是发布标识,改它会连带项目引用、tsdown glob 与文档路径,收益为零;版本号并入 `0.0.1` 后不再满足保留下来的 `^4.0.0-rc.7` range,pnpm 会转去 registry 找副本,`verify-vendored-links` 直接红。 + +**`docs/` 之外的散文与历史 Agent Note 一起改。** 否决:它们记录的是写作当时的事实,而且那里的裸 `cordis` 同样可能是 SDK 选项名或某个 preset id,未必是包;面向读者的映射由 `docs/rescope.md` 承载。 diff --git a/docs/rescope.i18n.yaml b/docs/rescope.i18n.yaml new file mode 100644 index 0000000000..2959c354da --- /dev/null +++ b/docs/rescope.i18n.yaml @@ -0,0 +1,6 @@ +# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each +# side as of the last confirmed-consistent state. Both languages carry equal authority; +# after editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write docs/rescope.md +rescope.md: 3dde39875021e7a4161e1ae66550e9dedf5eb4fa +rescope.zh.md: a7f355cf651fb063bf2d4c3cefe18babd4a57401 diff --git a/docs/rescope.md b/docs/rescope.md new file mode 100644 index 0000000000..3dde398750 --- /dev/null +++ b/docs/rescope.md @@ -0,0 +1,53 @@ +# Vendored package rescope + +English | [中文](rescope.zh.md) + +The Cordis framework and its foundation libraries are vendored under [`vendor/`](../vendor/README.md) and published under the `@deepseek-ai` scope, because every harness package declares the framework as a peer dependency: publishing the harness publishes this layer with it, and under the upstream names that publication would squat them on the registry. This page is the name mapping; the decision and its consequences live in the [rescope Agent Note](../.agents/notes/implemented/process/2026-08-10-vendor-package-rescope.md), and the upstream commits in [`vendor/README.md`](../vendor/README.md). + +## Name mapping + +| Directory | Upstream name | Published name | Version | Role | +|---|---|---|---|---| +| `vendor/cordis/` | `cordis` | `@deepseek-ai/cordis` | 4.0.0-rc.7 | Framework core: `Context`, `Service`, `Fiber`, events | +| `vendor/cosmokit/` | `cosmokit` | `@deepseek-ai/cosmokit` | 1.8.1 | Shared utilities the framework and Schemastery build on | +| `vendor/schemastery/` | `schemastery` | `@deepseek-ai/schemastery` | 3.18.0 | Config schemas (`Schema`) behind every plugin's `Config` | +| `vendor/loader/` | `@cordisjs/plugin-loader` | `@deepseek-ai/cordis-plugin-loader` | 1.0.0-rc.5 | `cordis.yml` loading, plugin resolution, repository cache | +| `vendor/include/` | `@cordisjs/plugin-include` | `@deepseek-ai/cordis-plugin-include` | 1.0.4 | Config includes and patch overlays | +| `vendor/group/` | `@cordisjs/plugin-group` | `@deepseek-ai/cordis-plugin-group` | 1.0.0 | Nested plugin groups | +| `vendor/timer/` | `@cordisjs/plugin-timer` | `@deepseek-ai/cordis-plugin-timer` | 1.1.2 | Disposal-aware timers on `ctx` | +| `vendor/hmr/` | `@cordisjs/plugin-hmr` | `@deepseek-ai/cordis-plugin-hmr` | 1.0.15 | Hot module replacement for plugins and config | +| `vendor/logger-console/` | `@cordisjs/plugin-logger-console` | `@deepseek-ai/cordis-plugin-logger-console` | 1.0.0 | Console logger exporter | + +Subpath exports keep their path: `@cordisjs/plugin-loader/repository` becomes `@deepseek-ai/cordis-plugin-loader/repository`. + +## What the rename does not touch + +- **Directory names and versions.** `vendor/hmr/` stays `vendor/hmr/`, and every package keeps the upstream version its manifest table row records, so the vendored tree still reads as an upstream snapshot. +- **Dependency ranges.** A dependency entry changes its key, never its range: `"cordis": "^4.0.0-rc.7"` becomes `"@deepseek-ai/cordis": "^4.0.0-rc.7"`. `linkWorkspacePackages` resolves those preserved ranges to the pinned workspaces. +- **The Loader's `cordis:` builtin prefix.** `cordis:include` and `cordis:group` are a protocol prefix, not a package name. +- **The `cordis.yml` configuration family**, including `*.cordis.yml`, `*.cordis.snapshot.yml`, and `cordis.patch.yml`. +- **Harness packages whose own names contain the word**, such as `@deepseek-ai/dsh-tool-cordis`. +- **Upstream runtime identifiers**, such as Schemastery's `Symbol.for('schemastery')` and its `vendor:` metadata field. +- **Prose outside `docs/`.** `vendor/*/README.md`, package READMEs, and Agent Notes keep the names they were written with; a bare `cordis` there can also be the Python SDK's option name or an agent-preset id. Inside `docs/`, prose and every Markdown fence follow the rename. + +## What your code has to change + +| Site | Before | After | +|---|---|---| +| Module import | `import { Context } from 'cordis'` | `import { Context } from '@deepseek-ai/cordis'` | +| Typed-event merge | `declare module 'cordis'` | `declare module '@deepseek-ai/cordis'` | +| `package.json` dependency key | `"@cordisjs/plugin-hmr": "^1.0.15"` | `"@deepseek-ai/cordis-plugin-hmr": "^1.0.15"` | +| `cordis.yml` plugin entry | `name: '@cordisjs/plugin-include'` | `name: '@deepseek-ai/cordis-plugin-include'` | + +## Applying, verifying, and reverting + +[`scripts/rescope-vendor.ts`](../scripts/rescope-vendor.ts) owns the mapping above and performs the rename, so no reference is renamed by hand: + +```sh +pnpm run rescope-vendor # report what would change +pnpm run rescope-vendor --apply # rewrite every reference +pnpm run rescope-vendor:check # assert the post-state; runs in the hygiene gate +pnpm run rescope-vendor --apply --reverse # return to the upstream names +``` + +Re-apply it after an upstream sync ([procedure](../vendor/README.md)), and follow it with the regeneration it prints: `pnpm install` for the lockfile, `pnpm run gen-third-party-notices`, and `pnpm run verify-translation-pairing --write` for the bilingual pairs it touched. diff --git a/docs/rescope.zh.md b/docs/rescope.zh.md new file mode 100644 index 0000000000..a7f355cf65 --- /dev/null +++ b/docs/rescope.zh.md @@ -0,0 +1,53 @@ +# Vendored 包改名 + +[English](rescope.md) | 中文 + +Cordis 框架及其基础库以源码形式 vendored 在 [`vendor/`](../vendor/README.md) 下,并以 `@deepseek-ai` scope 发布:每个 harness 包都把框架声明为 peer dependency,发布 harness 就会连带发布这一层,用上游名发布等于在 registry 上占用别人的名字。本页是名字映射表;决策与影响见 [改名 Agent Note](../.agents/notes/implemented/process/2026-08-10-vendor-package-rescope.md),上游 commit 见 [`vendor/README.md`](../vendor/README.md)。 + +## 名字映射 + +| 目录 | 上游名 | 发布名 | 版本 | 角色 | +|---|---|---|---|---| +| `vendor/cordis/` | `cordis` | `@deepseek-ai/cordis` | 4.0.0-rc.7 | 框架核心:`Context`、`Service`、`Fiber`、事件 | +| `vendor/cosmokit/` | `cosmokit` | `@deepseek-ai/cosmokit` | 1.8.1 | 框架与 Schemastery 共用的基础工具 | +| `vendor/schemastery/` | `schemastery` | `@deepseek-ai/schemastery` | 3.18.0 | 配置 schema(`Schema`),每个插件的 `Config` 都基于它 | +| `vendor/loader/` | `@cordisjs/plugin-loader` | `@deepseek-ai/cordis-plugin-loader` | 1.0.0-rc.5 | `cordis.yml` 装载、插件解析、repository 缓存 | +| `vendor/include/` | `@cordisjs/plugin-include` | `@deepseek-ai/cordis-plugin-include` | 1.0.4 | 配置包含与 patch 叠加 | +| `vendor/group/` | `@cordisjs/plugin-group` | `@deepseek-ai/cordis-plugin-group` | 1.0.0 | 嵌套插件分组 | +| `vendor/timer/` | `@cordisjs/plugin-timer` | `@deepseek-ai/cordis-plugin-timer` | 1.1.2 | `ctx` 上随 disposal 回收的定时器 | +| `vendor/hmr/` | `@cordisjs/plugin-hmr` | `@deepseek-ai/cordis-plugin-hmr` | 1.0.15 | 插件与配置的热替换 | +| `vendor/logger-console/` | `@cordisjs/plugin-logger-console` | `@deepseek-ai/cordis-plugin-logger-console` | 1.0.0 | 控制台日志导出 | + +子路径导出保持原路径:`@cordisjs/plugin-loader/repository` 变成 `@deepseek-ai/cordis-plugin-loader/repository`。 + +## 改名不碰什么 + +- **目录名与版本号。** `vendor/hmr/` 仍是 `vendor/hmr/`,每个包保留清单表那行记录的上游版本,所以 vendored 树依旧读作一份上游快照。 +- **依赖 range。** 依赖条目只换键、不换范围:`"cordis": "^4.0.0-rc.7"` 变成 `"@deepseek-ai/cordis": "^4.0.0-rc.7"`;`linkWorkspacePackages` 靠这些保留下来的范围把它们解析到固定的 workspace。 +- **Loader 的 `cordis:` 内建前缀。** `cordis:include`、`cordis:group` 是协议前缀,不是包名。 +- **`cordis.yml` 配置文件家族**,包括 `*.cordis.yml`、`*.cordis.snapshot.yml`、`cordis.patch.yml`。 +- **名字里带这个词的 harness 包**,例如 `@deepseek-ai/dsh-tool-cordis`。 +- **上游运行时标识符**,例如 Schemastery 的 `Symbol.for('schemastery')` 及其 `vendor:` 元数据字段。 +- **`docs/` 之外的散文。** `vendor/*/README.md`、各包 README 与 Agent Note 保留写作当时的名字;那里的裸 `cordis` 也可能是 Python SDK 的选项名或某个 agent-preset 的 id。`docs/` 之内,散文与所有 Markdown 围栏都跟着改。 + +## 你的代码要改什么 + +| 位置 | 改前 | 改后 | +|---|---|---| +| 模块 import | `import { Context } from 'cordis'` | `import { Context } from '@deepseek-ai/cordis'` | +| 类型事件声明合并 | `declare module 'cordis'` | `declare module '@deepseek-ai/cordis'` | +| `package.json` 依赖键 | `"@cordisjs/plugin-hmr": "^1.0.15"` | `"@deepseek-ai/cordis-plugin-hmr": "^1.0.15"` | +| `cordis.yml` 插件条目 | `name: '@cordisjs/plugin-include'` | `name: '@deepseek-ai/cordis-plugin-include'` | + +## 施加、核验与回退 + +上面这份映射由 [`scripts/rescope-vendor.ts`](../scripts/rescope-vendor.ts) 承载并执行改名,任何引用都不靠手改: + +```sh +pnpm run rescope-vendor # report what would change +pnpm run rescope-vendor --apply # rewrite every reference +pnpm run rescope-vendor:check # assert the post-state; runs in the hygiene gate +pnpm run rescope-vendor --apply --reverse # return to the upstream names +``` + +上游 sync 之后重跑它([流程](../vendor/README.md)),并接上它打印的重生成:`pnpm install` 重生成 lockfile、`pnpm run gen-third-party-notices`、以及对它触及的双语对跑 `pnpm run verify-translation-pairing --write`。 diff --git a/package.json b/package.json index 2830640c26..5b07ed60fa 100644 --- a/package.json +++ b/package.json @@ -95,6 +95,8 @@ "verify-runtime-closure": "tsx scripts/verify-runtime-closure.ts", "verify-vendored-links": "tsx scripts/verify-vendored-links.ts", "verify-cordis-config": "tsx scripts/verify-cordis-config.ts", + "rescope-vendor": "tsx scripts/rescope-vendor.ts", + "rescope-vendor:check": "tsx scripts/rescope-vendor.ts --check", "verify-client-domain-graph": "tsx scripts/verify-client-domain-graph.ts", "gen-cordis-catalog": "tsx scripts/gen-cordis-catalog.ts", "verify-cordis-catalog": "tsx scripts/gen-cordis-catalog.ts --check", @@ -117,7 +119,7 @@ "verify-module-graph": "tsx scripts/gen-module-graph.ts --check", "constraints": "tsx scripts/check-workspace-constraints.ts", "doc-sync": "tsx scripts/run-gates.ts doc-sync", - "hygiene": "pnpm run knip && pnpm run publint && pnpm run constraints && pnpm run verify-package-invariants && pnpm run verify-built-package-invariants && pnpm run verify-cordis-config && pnpm run verify-node-next-types && pnpm run verify-runtime-closure && pnpm run verify-vendored-links", + "hygiene": "pnpm run rescope-vendor:check && pnpm run knip && pnpm run publint && pnpm run constraints && pnpm run verify-package-invariants && pnpm run verify-built-package-invariants && pnpm run verify-cordis-config && pnpm run verify-node-next-types && pnpm run verify-runtime-closure && pnpm run verify-vendored-links", "publish:npm-baseline": "tsx scripts/publish-npm-baseline.ts", "dsh": "node --import tsx/esm apps/cli/src/bin.ts", "demo:headless": "node --import tsx/esm apps/cli/src/bin.ts run", diff --git a/scripts/rescope-vendor.spec.ts b/scripts/rescope-vendor.spec.ts new file mode 100644 index 0000000000..563be68dfa --- /dev/null +++ b/scripts/rescope-vendor.spec.ts @@ -0,0 +1,41 @@ +/** + * Acceptance-path coverage for the rescope codemod's exact-edit classifier: a + * duplicated insertion — what a non-idempotent apply produces — must be + * rejected rather than applied again. + */ + +import { describe, expect, it } from 'vitest' +import { exactEditState } from './rescope-vendor.ts' + +const ANCHOR = '\n## Sync procedure' +const INSERTED = `\n15. **rescope**: one log entry.\n${ANCHOR}` + +describe('exactEditState', () => { + it('classifies an insertion by its target form, so a duplicate is invalid', () => { + expect(exactEditState(`log\n${ANCHOR}\n`, ANCHOR, INSERTED, 1)).toBe('pending') + expect(exactEditState(`log${INSERTED}\n`, ANCHOR, INSERTED, 1)).toBe('applied') + // The anchor survives an insertion, so counting the source form would have + // called this pending and inserted the entry a second time. + expect(exactEditState(`log${INSERTED}${INSERTED}\n`, ANCHOR, INSERTED, 1)).toBe('invalid') + expect(exactEditState('log\n', ANCHOR, INSERTED, 1)).toBe('invalid') + }) + + it('classifies a deletion by its source form, and requires its remainder to survive', () => { + const remainder = 'exclude:\n' + const withEntries = 'exclude:\n - cordis@4\n' + expect(exactEditState(withEntries, withEntries, remainder, 1)).toBe('pending') + expect(exactEditState(remainder, withEntries, remainder, 1)).toBe('applied') + // Upstream dropped the whole field: the source form is gone, but so is the + // remainder, so this is a moved site rather than a completed deletion. + expect(exactEditState('unrelated:\n', withEntries, remainder, 1)).toBe('invalid') + }) + + it('requires a replacement to leave no source form and the exact target count', () => { + expect(exactEditState('a = 1\n', 'a = 1', 'b = 2', 1)).toBe('pending') + expect(exactEditState('b = 2\n', 'a = 1', 'b = 2', 1)).toBe('applied') + expect(exactEditState('b = 2\nb = 2\n', 'a = 1', 'b = 2', 1)).toBe('invalid') + // A moved or partially applied site: neither state is complete. + expect(exactEditState('a = 1\nb = 2\n', 'a = 1', 'b = 2', 1)).toBe('invalid') + expect(exactEditState('x\n', 'a = 1', 'b = 2', 1)).toBe('invalid') + }) +}) diff --git a/scripts/rescope-vendor.ts b/scripts/rescope-vendor.ts new file mode 100644 index 0000000000..e083d375e3 --- /dev/null +++ b/scripts/rescope-vendor.ts @@ -0,0 +1,771 @@ +/** + * Rescope the vendored Cordis packages into the `@deepseek-ai` scope, and undo + * that rescope with `--reverse`. Every harness package declares `cordis` as a + * peer dependency, so publication carries this framework layer too; publishing + * it under the upstream names would squat them on the registry + * ([rationale](../.agents/notes/implemented/process/2026-08-10-vendor-package-rescope.md), + * [name mapping](../docs/rescope.md)). + * + * The generic pass rewrites ONLY delimited, complete package-name tokens: + * `'old'` / `"old"` / `` `old` `` / `'old/subpath'`, plus a YAML `name: old` + * scalar. A match needs a quote (or `name: `) immediately left and the matching + * quote — optionally after a `/subpath` — immediately right, which excludes + * `cordis.yml`, the Loader's `cordis:` builtin prefix, `cordis-config-entry`, + * `@deepseek-ai/dsh-tool-cordis`, and `cordiverse/cordis`, and makes the + * rewrite idempotent because the scoped name's `cordis` is preceded by `/`. + * Markdown follows the rename inside every fence, and in `docs/` prose too: + * a tutorial that teaches an unresolvable name is wrong, while prose elsewhere + * records what was true when it was written. + * + * Sites the token rule cannot express (dot-notation access, unquoted object + * keys, regex literals, the vendored-manifest table) are listed in + * {@link EXACT_EDITS} with an exact hit count, so an upstream change to one of + * them fails loudly instead of being silently skipped. + * + * Usage: `pnpm run rescope-vendor [--apply|--check] [--reverse]`. Without a + * mode it reports what would change. `--check` asserts the post-state: no + * residue, every exact edit landed, every postcondition holds, and a second + * `--apply` would be a no-op. + */ + +import { execFileSync } from 'node:child_process' +import { existsSync, readFileSync, realpathSync, writeFileSync } from 'node:fs' +import { resolve } from 'node:path' +import { fileURLToPath } from 'node:url' + +const root = resolve(import.meta.dirname, '..') + +/** One vendored package's directory, upstream npm name, and rescoped name. */ +interface Rename { + readonly directory: string + readonly upstream: string + readonly scoped: string +} + +/** The mapping this codemod applies; `vendor/README.md` carries the same table. */ +const RENAMES: readonly Rename[] = [ + { directory: 'cordis', upstream: 'cordis', scoped: '@deepseek-ai/cordis' }, + { directory: 'cosmokit', upstream: 'cosmokit', scoped: '@deepseek-ai/cosmokit' }, + { directory: 'schemastery', upstream: 'schemastery', scoped: '@deepseek-ai/schemastery' }, + { directory: 'loader', upstream: '@cordisjs/plugin-loader', scoped: '@deepseek-ai/cordis-plugin-loader' }, + { directory: 'include', upstream: '@cordisjs/plugin-include', scoped: '@deepseek-ai/cordis-plugin-include' }, + { directory: 'group', upstream: '@cordisjs/plugin-group', scoped: '@deepseek-ai/cordis-plugin-group' }, + { directory: 'timer', upstream: '@cordisjs/plugin-timer', scoped: '@deepseek-ai/cordis-plugin-timer' }, + { directory: 'hmr', upstream: '@cordisjs/plugin-hmr', scoped: '@deepseek-ai/cordis-plugin-hmr' }, + { directory: 'logger-console', upstream: '@cordisjs/plugin-logger-console', scoped: '@deepseek-ai/cordis-plugin-logger-console' }, +] + +const EXTENSIONS = ['.ts', '.tsx', '.js', '.mjs', '.cjs', '.tpl', '.json', '.yml', '.yaml', '.md'] as const + +/** An exact-string edit the token rule cannot express, with its required hit count. */ +interface ExactEdit { + readonly id: string + readonly file: string + readonly find: string + readonly replace: string + readonly expect: number +} + +/** + * A file where an upstream name also appears as a vendor DIRECTORY name or an + * upstream runtime identifier: the generic pass is disabled for the listed + * names and {@link EXACT_EDITS} renames the real package-name occurrences. + */ +interface GenericSkip { + readonly file: string + readonly upstream: readonly string[] +} + +const GENERIC_SKIPS: readonly GenericSkip[] = [ + // `vendorPackages` lists vendor/ directory names, joined with 'vendor' below it. + { file: 'packages/examples/acp-demo/tests/built-bin.e2e.ts', upstream: ['cordis', 'cosmokit', 'schemastery'] }, + // Mixes join(root, 'vendor', 'cordis') paths with real manifest names. + { file: 'packages/scaffold/helper/tests/documents.spec.ts', upstream: ['cordis'] }, + // `Symbol.for('schemastery')` and the `vendor:` metadata field are upstream identifiers. + { file: 'vendor/schemastery/src/index.ts', upstream: ['schemastery'] }, + // Asserts the vendored-manifest table, which gains an upstream-name column. + { file: 'scripts/gen-third-party-notices.spec.ts', upstream: RENAMES.map(rename => rename.upstream) }, + // `cordis` is also an agent-preset id — the directory name under + // apps/cli/config/agent-presets/ — so in these files the bare name is + // product data, not a package reference. Renaming it changed which preset + // the creator flow stages and which id the roster reports. + { file: 'packages/client/ui-agent-preset/src/client/AgentPresetSection.tsx', upstream: ['cordis'] }, + { file: 'packages/client/ui-agent-preset/src/client/index.ts', upstream: ['cordis'] }, + { file: 'packages/client/ui-agent-preset/tests/apply.spec.ts', upstream: ['cordis'] }, + { file: 'packages/client/ui-agent-preset/tests/locales.spec.ts', upstream: ['cordis'] }, + { file: 'packages/client/ui-agent-preset/tests/section.spec.tsx', upstream: ['cordis'] }, + { file: 'apps/cli/tests/web-agent-presets.e2e.ts', upstream: ['cordis'] }, + { file: 'apps/web/tests/agent-preset-authoring.e2e.ts', upstream: ['cordis'] }, + { file: 'packages/preset/agent-presets/tests/session.spec.ts', upstream: ['cordis'] }, + // The preset's own composition: its header comment and its system prompt name + // the preset a model mounts, so the scoped name would send the model after an + // id no roster reports. + { file: 'apps/cli/config/agent-presets/cordis/agent.cordis.yml', upstream: ['cordis'] }, + // GROUP_ORDER holds `packages//` directory names, not package names. + { file: 'scripts/gen-module-graph.ts', upstream: ['cordis'] }, + { file: 'scripts/gen-doc-graphs.ts', upstream: ['cordis'] }, +] + +/** A string that must appear exactly `count` times once the rescope has run. */ +interface PostCondition { + readonly file: string + readonly text: string + readonly count: number +} + +const POSTCONDITIONS: readonly PostCondition[] = [ + { file: 'vendor/cordis/package.json', text: '"name": "@deepseek-ai/cordis"', count: 1 }, + { file: 'vendor/hmr/package.json', text: '"name": "@deepseek-ai/cordis-plugin-hmr"', count: 1 }, + { file: 'scripts/cordis-walk.ts', text: '@deepseek-ai\\/cordis', count: 1 }, + { file: 'scripts/cordis-walk.ts', text: '!== \'@deepseek-ai/cordis\'', count: 1 }, + { file: 'scripts/gen-scoped-events.ts', text: '=== \'@deepseek-ai/cordis\'', count: 1 }, + { file: 'packages/typert/generator/src/analyzer.ts', text: '!== \'@deepseek-ai/cordis\'', count: 2 }, + { file: 'scripts/check-workspace-constraints.ts', text: '?.[\'@deepseek-ai/cordis\']', count: 2 }, + { file: 'packages/scaffold/helper/src/project/npm-dependency-policy.ts', text: '\'@deepseek-ai/cordis\': \'^4.0.0-rc.7\'', count: 1 }, + { file: 'packages/scaffold/helper/src/plugins/local-plugin-blueprint.ts', text: '\'@deepseek-ai/cordis\': cordisSpec', count: 2 }, + { file: 'packages/boot/app-boot/tsdown.config.ts', text: '[\'@deepseek-ai/cordis-plugin-include\']', count: 1 }, + { file: 'tsconfig.base.json', text: '"@deepseek-ai/cordis-plugin-loader": ["./vendor/loader/src"]', count: 1 }, + // One insertion, once: a duplicated log entry is what a non-idempotent apply produced. + { file: 'vendor/README.md', text: '15. **`@deepseek-ai` rescope**', count: 1 }, + { file: 'knip.json', text: '@cordisjs', count: 0 }, + { file: 'pnpm-workspace.yaml', text: 'cordis@4.0.0-rc.7', count: 0 }, + // The preset ids in this table are product data, not package names. + { file: 'packages/client/ui-agent-preset/tests/locales.spec.ts', text: '[\'cordis\', \'presetCordisName\'', count: 1 }, + // The preset id the shipped composition documents to its own model. + { file: 'apps/cli/config/agent-presets/cordis/agent.cordis.yml', text: 'The `cordis` agent preset', count: 1 }, + { file: 'apps/cli/config/agent-presets/cordis/agent.cordis.yml', text: 'corrupting the `cordis` preset', count: 1 }, + // The vendor-directory paths in these fixtures must survive the rename. + { file: 'packages/scaffold/helper/tests/documents.spec.ts', text: 'join(root, \'vendor\', \'cordis\')', count: 2 }, + { file: 'packages/examples/acp-demo/tests/built-bin.e2e.ts', text: '\'cordis\', \'loader\', \'include\', \'timer\', \'hmr\', \'logger-console\',', count: 1 }, +] + +/** + * Every exact edit, in application order. Each `find` is written against the + * PRE-rename text because these run before the generic pass, so no `find` may + * quote a neighbouring line the generic pass would rewrite. + */ +const EXACT_EDITS: readonly ExactEdit[] = [ + { + id: 'cordis-walk-merge-head', + file: 'scripts/cordis-walk.ts', + find: 'const MERGE_HEAD = /declare module [\'"](?:cordis|\\.\\/context\\.ts)[\'"]/', + replace: 'const MERGE_HEAD = /declare module [\'"](?:@deepseek-ai\\/cordis|\\.\\/context\\.ts)[\'"]/', + expect: 1, + }, + { + id: 'constraints-manifest-lookup', + file: 'scripts/check-workspace-constraints.ts', + find: ` const peer = manifest.peerDependencies?.cordis + const dev = manifest.devDependencies?.cordis + + if (!peer) errors.push(\`\${label}: cordis must be a peerDependency\`) + if (!dev) errors.push(\`\${label}: cordis must also be a devDependency\`) + if (peer && dev && peer !== dev) { + errors.push(\`\${label}: cordis peer (\${peer}) and dev (\${dev}) ranges must match\`)`, + replace: ` const peer = manifest.peerDependencies?.['@deepseek-ai/cordis'] + const dev = manifest.devDependencies?.['@deepseek-ai/cordis'] + + if (!peer) errors.push(\`\${label}: @deepseek-ai/cordis must be a peerDependency\`) + if (!dev) errors.push(\`\${label}: @deepseek-ai/cordis must also be a devDependency\`) + if (peer && dev && peer !== dev) { + errors.push(\`\${label}: @deepseek-ai/cordis peer (\${peer}) and dev (\${dev}) ranges must match\`)`, + expect: 1, + }, + { + id: 'scaffold-dependency-policy', + file: 'packages/scaffold/helper/src/project/npm-dependency-policy.ts', + find: ' cordis: \'^4.0.0-rc.7\',', + replace: ' \'@deepseek-ai/cordis\': \'^4.0.0-rc.7\',', + expect: 1, + }, + { + id: 'scaffold-plugin-blueprint', + file: 'packages/scaffold/helper/src/plugins/local-plugin-blueprint.ts', + find: ` cordis: cordisSpec, + }, + devDependencies: { + cordis: cordisSpec, + },`, + replace: ` '@deepseek-ai/cordis': cordisSpec, + }, + devDependencies: { + '@deepseek-ai/cordis': cordisSpec, + },`, + expect: 1, + }, + { + id: 'scaffold-link-workspace-lookup', + file: 'packages/scaffold/create-sdk/tests/link-workspace.e2e.ts', + find: 'manifest.dependencies.cordis', + replace: 'manifest.dependencies[\'@deepseek-ai/cordis\']', + expect: 1, + }, + { + id: 'documents-spec-manifest-name', + file: 'packages/scaffold/helper/tests/documents.spec.ts', + find: 'JSON.stringify({ name: \'cordis\' })', + replace: 'JSON.stringify({ name: \'@deepseek-ai/cordis\' })', + expect: 1, + }, + { + id: 'documents-spec-peer-key', + file: 'packages/scaffold/helper/tests/documents.spec.ts', + find: 'peerDependencies: { cordis: \'^4\' },', + replace: 'peerDependencies: { \'@deepseek-ai/cordis\': \'^4\' },', + expect: 1, + }, + { + id: 'documents-spec-closure-order', + file: 'packages/scaffold/helper/tests/documents.spec.ts', + find: ' \'@deepseek-ai/dsh-helper\', \'@deepseek-ai/dsh-scripts\', \'cordis\',', + replace: ' \'@deepseek-ai/cordis\', \'@deepseek-ai/dsh-helper\', \'@deepseek-ai/dsh-scripts\',', + expect: 1, + }, + { + id: 'documents-spec-lookups', + file: 'packages/scaffold/helper/tests/documents.spec.ts', + find: ` expect(manifest.npmDependency('cordis')?.spec).toMatch(/^link:/) + expect(pnpmWorkspace.serialize()).toContain('autoInstallPeers: false') + expect(workspace.packageDirectory('cordis')).toBe(join(root, 'vendor', 'cordis')) + expect(await readFile(join(root, 'vendor', 'cordis', 'package.json'), 'utf8')).toContain('cordis')`, + replace: ` expect(manifest.npmDependency('@deepseek-ai/cordis')?.spec).toMatch(/^link:/) + expect(pnpmWorkspace.serialize()).toContain('autoInstallPeers: false') + expect(workspace.packageDirectory('@deepseek-ai/cordis')).toBe(join(root, 'vendor', 'cordis')) + expect(await readFile(join(root, 'vendor', 'cordis', 'package.json'), 'utf8')).toContain('@deepseek-ai/cordis')`, + expect: 1, + }, + { + id: 'documents-spec-policy-lookup', + file: 'packages/scaffold/helper/tests/documents.spec.ts', + find: ' expect(resolveNpmDependency(\'cordis\', \'devDependencies\', \'0.0.1\')).toEqual({', + replace: ' expect(resolveNpmDependency(\'@deepseek-ai/cordis\', \'devDependencies\', \'0.0.1\')).toEqual({', + expect: 1, + }, + { + // The rescoped name is already covered by the `@deepseek-ai/.+` pattern beside it. + id: 'knip-logger-console', + file: 'knip.json', + find: ` "ignoreDependencies": [ + "@cordisjs/plugin-logger-console", + "@deepseek-ai/.+" + ] + }, + "packages/util/home": {`, + replace: ` "ignoreDependencies": [ + "@deepseek-ai/.+" + ] + }, + "packages/util/home": {`, + expect: 1, + }, + { + id: 'knip-bundle-base', + file: 'knip.json', + find: ` "packages/bundle/base": { + "ignoreDependencies": [ + "@deepseek-ai/.+", + "@cordisjs/.+" + ]`, + replace: ` "packages/bundle/base": { + "ignoreDependencies": [ + "@deepseek-ai/.+" + ]`, + expect: 1, + }, + { + // Rescoped packages are never fetched from a registry, so the exclusion is dead config. + id: 'pnpm-release-age', + file: 'pnpm-workspace.yaml', + find: `minimumReleaseAgeExclude: + # Cordis release candidates are source-vendored and pinned in vendor/README.md + # during the same-day sync that updates package manifests and the lockfile. + - '@cordisjs/plugin-loader@1.0.0-rc.5' + - cordis@4.0.0-rc.7 +`, + replace: 'minimumReleaseAgeExclude:\n', + expect: 1, + }, + { + id: 'publication-set-scope-assertion', + file: 'scripts/publish-npm-baseline.ts', + find: ' if (!isVendored && !name.startsWith(\'@deepseek-ai/\')) {', + replace: ` // Vendored packages are rescoped too (vendor/README.md), so publication + // never carries an upstream name that would squat it on the registry. + if (!name.startsWith('@deepseek-ai/')) {`, + expect: 1, + }, + { + id: 'vendor-readme-preamble', + file: 'vendor/README.md', + find: 'All vendored packages keep their **original npm names** and are marked `private: true` — they are never published from this repo. `pnpm-workspace.yaml#linkWorkspacePackages` makes matching upstream semver ranges resolve these pinned workspaces, including imports from built `lib/`; disabling it substitutes npm copies behind the same names.', + replace: 'All vendored packages are **renamed into the `@deepseek-ai` scope** (`cordis` → `@deepseek-ai/cordis`, `@cordisjs/plugin-` → `@deepseek-ai/cordis-plugin-`): every harness package declares `cordis` as a peer dependency, so publishing the harness publishes this framework layer too, and a publication under the upstream names would squat them on the registry. Directory names and upstream version numbers are deliberately unchanged, so the manifest below still reads as an upstream snapshot. `pnpm-workspace.yaml#linkWorkspacePackages` makes those preserved semver ranges resolve these pinned workspaces, including imports from built `lib/`.', + expect: 1, + }, + { + id: 'vendor-readme-schemastery-note', + file: 'vendor/README.md', + find: 'whose lazy `require(\'cosmokit\')` can race', + replace: 'whose lazy `require(\'@deepseek-ai/cosmokit\')` can race', + expect: 1, + }, + { + id: 'vendor-readme-table-head', + file: 'vendor/README.md', + find: '| Directory | npm name | Version | Upstream repo | Commit |\n|---|---|---|---|---|', + replace: '| Directory | npm name | Upstream name | Version | Upstream repo | Commit |\n|---|---|---|---|---|---|', + expect: 1, + }, + { + id: 'vendor-readme-local-modification-log', + file: 'vendor/README.md', + find: '\n## Sync procedure', + replace: '15. **`@deepseek-ai` rescope**: every vendored manifest `name`, every internal dependency entry among the vendored set, and every module specifier that reaches them use the scoped names in the manifest table\'s `npm name` column. Directory names, version numbers, and dependency ranges are unchanged, and no upstream runtime identifier is renamed — `Symbol.for(\'schemastery\')` and Schemastery\'s `vendor:` metadata field keep their upstream values. Re-apply with `pnpm run rescope-vendor --apply` after a sync; the table\'s two name columns are the mapping, restated for consumers in [docs/rescope.md](../docs/rescope.md).\n\n## Sync procedure', + expect: 1, + }, + { + // A plain fence listing the bundle's mounted tree: a bare token, no quotes. + id: 'agent-spine-demo-mounted-tree', + file: 'packages/examples/agent-spine-demo/README.md', + find: '@cordisjs/plugin-timer timer service', + replace: '@deepseek-ai/cordis-plugin-timer timer service', + expect: 1, + }, + { + id: 'agent-spine-demo-mounted-tree-zh', + file: 'packages/examples/agent-spine-demo/README.zh.md', + find: '@cordisjs/plugin-timer timer service', + replace: '@deepseek-ai/cordis-plugin-timer timer service', + expect: 1, + }, + { + // The root contract claimed vendored packages keep their upstream names. + id: 'root-agents-vendored-name-contract', + file: 'AGENTS.md', + find: 'vendored packages keep upstream names and are `private: true`. `cordis` is a peerDependency (+ dev) of every harness package.', + replace: 'vendored packages are rescoped ([mapping](docs/rescope.md)) and `private: true`. `@deepseek-ai/cordis` is a peerDependency (+ dev) of every harness package.', + expect: 1, + }, + { + // The client purity gate reads `@deepseek-ai/` as "another plugin package". + // The rescope moves the vendored framework and its libraries into that + // namespace, where the gate would reject the library imports client + // bundles have always inlined, so it needs their names. + id: 'client-purity-vendored-libraries', + file: 'packages/client/tsdown.client.ts', + find: '/** Generated descriptor/codec contribution with no shared runtime identity. */', + replace: `/** + * Vendored framework libraries: rescoped into @deepseek-ai, so the gate below + * would read them as plugin packages. They carry no cross-plugin runtime + * identity to share — the framework itself is a platform module (external), + * while these are ordinary libraries a browser bundle inlines. + */ +const VENDORED_LIBRARY = /^@deepseek-ai\\/(cosmokit|schemastery)(\\/|$)/ + +/** Generated descriptor/codec contribution with no shared runtime identity. */`, + expect: 1, + }, + { + id: 'client-purity-vendored-libraries-predicate', + file: 'packages/client/tsdown.client.ts', + find: ' if (INLINE_SAFE.test(source) || GENERATED_REMOTE.test(source)) return null // wire contribution: inline is the point', + replace: ` if (VENDORED_LIBRARY.test(source)) return null // vendored library: inline, no shared identity + if (INLINE_SAFE.test(source) || GENERATED_REMOTE.test(source)) return null // wire contribution: inline is the point`, + expect: 1, + }, + { + // The step-1 file tree told the reader to keep the upstream name, one + // paragraph above the invariant that says to rescope it. + id: 'vendoring-cookbook-tree-comment', + file: 'docs/cookbook/adding-a-vendored-package.md', + find: ' package.json # from upstream; set "private": true, keep name/exports/type', + replace: ' package.json # from upstream; set "private": true, rescope the name, keep exports/type', + expect: 1, + }, + { + id: 'vendoring-cookbook-tree-comment-zh', + file: 'docs/cookbook/adding-a-vendored-package.zh.md', + find: ' package.json # from upstream; set "private": true, keep name/exports/type', + replace: ' package.json # from upstream; set "private": true, rescope the name, keep exports/type', + expect: 1, + }, + { + // The checklist told the next vendoring to keep upstream's name. + id: 'vendoring-cookbook-name-invariant', + file: 'docs/cookbook/adding-a-vendored-package.md', + find: "keep upstream's `name`/`version`/`exports`/`type`", + replace: "rescope the `name` ([mapping](../rescope.md)) while keeping upstream's `version`/`exports`/`type`", + expect: 1, + }, + { + id: 'vendoring-cookbook-name-invariant-zh', + file: 'docs/cookbook/adding-a-vendored-package.zh.md', + find: '保留上游的 `name`/`version`/`exports`/`type`', + replace: '改写 `name` 的 scope([映射](../rescope.md)),保留上游的 `version`/`exports`/`type`', + expect: 1, + }, + { + // The real package references in files whose other `cordis` strings are preset ids. + id: 'agent-preset-spec-framework-import', + file: 'packages/client/ui-agent-preset/tests/apply.spec.ts', + find: "import { Context } from 'cordis'", + replace: "import { Context } from '@deepseek-ai/cordis'", + expect: 1, + }, + { + id: 'web-agent-presets-e2e-framework-import', + file: 'apps/cli/tests/web-agent-presets.e2e.ts', + find: "import { Context } from 'cordis'", + replace: "import { Context } from '@deepseek-ai/cordis'", + expect: 1, + }, + { + id: 'notices-vendored-row-type', + file: 'scripts/gen-third-party-notices.ts', + find: `export interface VendoredRow { + npmName: string + upstream: string +}`, + replace: `export interface VendoredRow { + npmName: string + /** The name this package carries upstream; MIT attribution names the fork's origin, not our scope. */ + upstreamName: string + upstream: string +}`, + expect: 1, + }, + { + id: 'notices-vendored-row-parse', + file: 'scripts/gen-third-party-notices.ts', + find: ` const match = /^\\| \\x60\\S+\\/\\x60 \\| \\x60([^\\x60]+)\\x60 \\| \\S+ \\| (https:\\/\\/\\S+?)(?: \\([^)]*\\))? \\| \\x60[0-9a-f]+\\x60 \\|$/.exec(line) + if (match === null) continue + const [, npmName, upstream] = match + if (npmName === undefined || upstream === undefined) continue + rows.push({ npmName, upstream })`, + replace: ` const match = new RegExp(String.raw\`^\\| \\x60\\S+\\/\\x60 \\| \\x60([^\\x60]+)\\x60 \\| \\x60([^\\x60]+)\\x60 \\| \\S+ \\| \` + + String.raw\`(https:\\/\\/\\S+?)(?: \\([^)]*\\))? \\| \\x60[0-9a-f]+\\x60 \\|$\`).exec(line) + if (match === null) continue + const [, npmName, upstreamName, upstream] = match + if (npmName === undefined || upstreamName === undefined || upstream === undefined) continue + rows.push({ npmName, upstreamName, upstream })`, + expect: 1, + }, + { + id: 'notices-vendored-section', + file: 'scripts/gen-third-party-notices.ts', + find: 'The Cordis framework and its foundation libraries are source-vendored into this repository rather than consumed from npm. All are MIT-licensed', + replace: 'The Cordis framework and its foundation libraries are source-vendored into this repository rather than consumed from npm, and republished under the \\`@deepseek-ai\\` scope. All are MIT-licensed', + expect: 1, + }, + { + id: 'notices-vendored-table', + file: 'scripts/gen-third-party-notices.ts', + find: `| Package | Upstream | License | +| --- | --- | --- | +\${vendored.map(row => \`| \\\`\${row.npmName}\\\` | [\${row.upstream.replace('https://', '')}](\${row.upstream}) | MIT |\`).join('\\n')}`, + replace: `| Package | Upstream name | Upstream | License | +| --- | --- | --- | --- | +\${vendored.map(row => \`| \\\`\${row.npmName}\\\` | \\\`\${row.upstreamName}\\\` | [\${row.upstream.replace('https://', '')}](\${row.upstream}) | MIT |\`).join('\\n')}`, + expect: 1, + }, + { + id: 'notices-spec-row-fixture', + file: 'scripts/gen-third-party-notices.spec.ts', + find: ' expect(rows).toContainEqual({ npmName: \'cordis\', upstream: \'https://github.com/cordiverse/cordis\' })', + replace: ` expect(rows).toContainEqual({ + npmName: '@deepseek-ai/cordis', + upstreamName: 'cordis', + upstream: 'https://github.com/cordiverse/cordis', + })`, + expect: 1, + }, + { + id: 'notices-spec-shape-fixture', + file: 'scripts/gen-third-party-notices.spec.ts', + find: 'parseVendoredRows(\'| `cordis/` | cordis | 4.0.0 | https://example.com | `abc123` |\\n\')', + replace: 'parseVendoredRows(\'| `cordis/` | `@deepseek-ai/cordis` | cordis | 4.0.0 | https://example.com | `abc123` |\\n\')', + expect: 1, + }, + { + // The framework peer is no longer a registry name, so the rehearsal must install this + // repository's vendored copies; cosmokit comes along as cordis's own dependency. + id: 'packed-install-vendored-peer', + file: 'packages/sandbox/sandbox-local/tests/packed-install.e2e.ts', + find: ` 'packages/support/invariants', +]`, + replace: ` 'packages/support/invariants', + // The framework and the vendored packages the closure declares outright: + // rescoped into @deepseek-ai, so the consumer installs this repository's + // copies. Schemastery is a hard dependency of three members above, not a + // peer, so npm resolves it while installing them. + 'vendor/cordis', + 'vendor/cosmokit', + 'vendor/schemastery', +]`, + expect: 1, + }, + { + id: 'packed-install-registry-spec', + file: 'packages/sandbox/sandbox-local/tests/packed-install.e2e.ts', + find: ` // Peer ranges resolve to the tarballs; Cordis is pinned to their peer range. Do not omit optional + // dependencies because the launcher selects its OS/CPU package through one. + writeFileSync(join(consumerDir, 'package.json'), JSON.stringify({ name: 'dsh-packed-consumer', private: true, type: 'module' })) + const install = spawnSync('npm', ['install', '--no-audit', '--no-fund', ...tarballs, 'cordis@4.0.0-rc.7'], {`, + replace: ` // Peer ranges resolve to the tarballs, the framework peer included. Do not omit optional + // dependencies because the launcher selects its OS/CPU package through one. + writeFileSync(join(consumerDir, 'package.json'), JSON.stringify({ name: 'dsh-packed-consumer', private: true, type: 'module' })) + const install = spawnSync('npm', ['install', '--no-audit', '--no-fund', ...tarballs], {`, + expect: 1, + }, + { + id: 'packed-install-module-doc', + file: 'packages/sandbox/sandbox-local/tests/packed-install.e2e.ts', + find: ` * Keyless publish-path rehearsal. It packs the provider, its workspace peers, and the current + * repository's Landlock entry/platform packages, then installs those exact tarballs in an external + * plain-Node consumer. The host launcher comes from the exact local tarballs, so no registry copy, + * tsx, path mapping, or workspace resolution can hide missing files, dependency errors, or lost + * executable modes.`, + replace: ` * Keyless publish-path rehearsal. It packs the provider, its workspace peers, the vendored framework + * peer, and the current repository's Landlock entry/platform packages, then installs those exact + * tarballs in an external plain-Node consumer. The host launcher comes from the exact local tarballs, + * so no registry copy, tsx, path mapping, or workspace resolution can hide missing files, dependency + * errors, or lost executable modes.`, + expect: 1, + }, + // The manifest table's name column plus the new upstream-name column, one edit per row. + ...RENAMES.map(rename => ({ + id: `vendor-readme-row-${rename.directory}`, + file: 'vendor/README.md', + find: `| \`${rename.directory}/\` | \`${rename.upstream}\` | `, + replace: `| \`${rename.directory}/\` | \`${rename.scoped}\` | \`${rename.upstream}\` | `, + expect: 1, + })), +] + +/** Files the rescope must never rewrite. */ +function excluded(file: string): boolean { + if (file === 'scripts/rescope-vendor.ts') return true // the mapping itself + if (file.startsWith('.agents/notes/')) return true // notes record what was true when written + // Recorded model payloads quote documentation verbatim, so they must mirror the + // sources on disk — including the notes this rescope leaves alone. + if (file.startsWith('scripts/snapshots/')) return true + // The mapping documents state both names on purpose. + if (file === 'docs/rescope.md' || file === 'docs/rescope.zh.md') return true + if (file.endsWith('.i18n.yaml')) return true // blob-hash records, re-recorded by the pairing gate + if (file === 'pnpm-lock.yaml') return true // regenerated by pnpm install + if (/^vendor\/[^/]+\/(README\.md|LICENSE)$/.test(file)) return true // upstream files kept verbatim + return !EXTENSIONS.some(extension => file.endsWith(extension)) +} + +function escapeRegExp(value: string): string { + return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') +} + +/** One name's rewrite, precompiled for both delimited forms. */ +interface Pattern { + readonly upstream: string + readonly from: string + readonly to: string + readonly token: RegExp + readonly yamlName: RegExp +} + +function patterns(reverse: boolean): Pattern[] { + return RENAMES + .map(rename => ({ + upstream: rename.upstream, + from: reverse ? rename.scoped : rename.upstream, + to: reverse ? rename.upstream : rename.scoped, + })) + .sort((left, right) => right.from.length - left.from.length) + .map(rename => ({ + ...rename, + token: new RegExp(`(['"\`])${escapeRegExp(rename.from)}((?:/[^'"\`\\s]*)?)\\1`, 'g'), + yamlName: new RegExp(`^(\\s*(?:-\\s*)?name:[ \\t]+)${escapeRegExp(rename.from)}([ \\t]*(?:#.*)?)$`, 'gm'), + })) +} + +function skipped(file: string, pattern: Pattern): boolean { + return GENERIC_SKIPS.some(skip => skip.file === file && skip.upstream.includes(pattern.upstream)) +} + +function rewriteLine(line: string, file: string, all: readonly Pattern[]): string { + let out = line + for (const pattern of all) { + if (skipped(file, pattern)) continue + out = out.replace(pattern.token, (_match, quote: string, subpath: string) => `${quote}${pattern.to}${subpath}${quote}`) + out = out.replace(pattern.yamlName, (_match, prefix: string, suffix: string) => `${prefix}${pattern.to}${suffix}`) + } + return out +} + +/** + * Rewrite a file's eligible lines. + * + * Markdown splits in two. Every fence is code a reader copies or a + * configuration they mount, so every fence follows the rename regardless of its + * info string. Prose follows it only under `docs/`, where a sentence quoting + * `` `cordis` `` teaches a name this repository no longer resolves; elsewhere + * prose is a record of what was true when it was written, and the same spelling + * can mean something else entirely — the Python SDK's `cordis` option, or the + * unvendored `@cordisjs/plugin-http`. + */ +function rewrite(text: string, file: string, all: readonly Pattern[]): { text: string; lines: number } { + const markdown = file.endsWith('.md') + const prose = markdown && file.startsWith('docs/') + let insideFence = false + let lines = 0 + const out = text.split('\n').map((line) => { + if (markdown) { + if (/^\s*```/.test(line)) { + insideFence = !insideFence + return line + } + if (!insideFence && !prose) return line + } + const next = rewriteLine(line, file, all) + if (next !== line) lines += 1 + return next + }) + return { text: out.join('\n'), lines } +} + +function classify(file: string): string { + if (/^vendor\/[^/]+\/package\.json$/.test(file)) return 'vendor manifest name' + if (file.endsWith('package.json')) return 'package.json dependencies' + if (/\.(ts|tsx|js|mjs|cjs|tpl)$/.test(file)) return 'code specifiers' + if (/\.(yml|yaml)$/.test(file)) return 'YAML plugin names' + if (file.endsWith('.json')) return 'JSON configuration' + return 'Markdown fences and docs prose' +} + +/** + * One exact edit's state in the text it targets. `pending` means the source + * form is present and the target form absent; `applied` means the reverse; + * anything else — a partial application, a moved site, or a DUPLICATED + * insertion — is `invalid`, so it fails the run instead of being applied again. + */ +export type ExactEditState = 'pending' | 'applied' | 'invalid' + +/** + * Classify one exact edit against its target text. + * + * An insertion keeps its anchor (`replace` contains `find`) and a deletion + * keeps its remainder (`find` contains `replace`), so neither can be judged by + * the source form alone: the surviving side counts the target form instead. + * @param text - the complete current text of the edited file. + * @param find - the source form, already oriented for the running direction. + * @param replace - the target form, already oriented for the running direction. + * @param expect - how many occurrences one complete application produces. + * @returns Whether the edit is pending, already applied, or invalid. + */ +export function exactEditState(text: string, find: string, replace: string, expect: number): ExactEditState { + const hits = text.split(find).length - 1 + const landed = text.split(replace).length - 1 + if (replace.includes(find)) { + if (landed === expect) return 'applied' + return landed === 0 && hits === expect ? 'pending' : 'invalid' + } + if (find.includes(replace)) { + if (hits === 0) return landed === expect ? 'applied' : 'invalid' + return hits === expect ? 'pending' : 'invalid' + } + if (hits === 0 && landed === expect) return 'applied' + return hits === expect && landed === 0 ? 'pending' : 'invalid' +} + +function main(): void { + const args = process.argv.slice(2) + const mode = args.includes('--apply') ? 'apply' : args.includes('--check') ? 'check' : 'dry' + const reverse = args.includes('--reverse') + const all = patterns(reverse) + const files = execFileSync('git', ['ls-files', '-z'], { cwd: root, encoding: 'utf8' }) + .split('\0') + .filter(file => file !== '' && !excluded(file)) + + const counts = new Map() + const failures: string[] = [] + const outstanding: string[] = [] + + // Classify every exact edit before writing anything: a single invalid site + // means the mapping and the tree disagree, and a half-applied tree is worse + // than an untouched one. + const planned: { edit: ExactEdit; path: string; find: string; replace: string }[] = [] + for (const edit of EXACT_EDITS) { + const path = resolve(root, edit.file) + const before = readFileSync(path, 'utf8') + const find = reverse ? edit.replace : edit.find + const replace = reverse ? edit.find : edit.replace + const state = exactEditState(before, find, replace, edit.expect) + if (state === 'invalid') { + failures.push(`exact edit ${edit.id}: ${edit.file} is neither pending nor cleanly applied (duplicated, partial, or moved)`) + continue + } + if (mode === 'check') { + if (state !== 'applied') failures.push(`exact edit ${edit.id} did not land in ${edit.file}`) + continue + } + if (state === 'pending') planned.push({ edit, path, find, replace }) + } + if (failures.length > 0) { + for (const failure of failures) console.error(`rescope-vendor: ${failure}`) + console.error(`rescope-vendor: ${String(failures.length)} problem(s); nothing was written.`) + process.exitCode = 1 + return + } + if (mode === 'apply') { + // Re-read per edit: two edits can target one file, and a stale snapshot + // would let the second write discard the first. + for (const { path, find, replace } of planned) { + writeFileSync(path, readFileSync(path, 'utf8').split(find).join(replace)) + } + } + + for (const file of files) { + const path = resolve(root, file) + const before = readFileSync(path, 'utf8') + const { text: after, lines } = rewrite(before, file, all) + if (after === before) continue + outstanding.push(file) + const kind = classify(file) + const current = counts.get(kind) ?? { files: 0, lines: 0 } + counts.set(kind, { files: current.files + 1, lines: current.lines + lines }) + if (mode === 'apply') writeFileSync(path, after) + } + + console.log(`rescope-vendor: ${mode}${reverse ? ' --reverse' : ''} over ${String(files.length)} tracked files`) + for (const kind of [...counts.keys()].sort()) { + const { files: count, lines } = counts.get(kind) ?? { files: 0, lines: 0 } + console.log(` ${kind.padEnd(24)} ${String(count).padStart(4)} file(s), ${String(lines)} line(s)`) + } + + if (mode !== 'dry') { + for (const check of POSTCONDITIONS) { + if (reverse) break + const path = resolve(root, check.file) + const hits = existsSync(path) ? readFileSync(path, 'utf8').split(check.text).length - 1 : -1 + if (hits !== check.count) { + failures.push(`postcondition: ${check.file} has ${String(hits)} occurrence(s) of ${JSON.stringify(check.text)}, expected ${String(check.count)}`) + } + } + // The generic pass above already told us which files would still change, + // which in check mode is exactly the residue-and-idempotency signal. + if (mode === 'check') { + for (const file of outstanding) failures.push(`residue: ${file} still carries a pre-rescope name token`) + } + } + + if (failures.length > 0) { + for (const failure of failures) console.error(`rescope-vendor: ${failure}`) + console.error(`rescope-vendor: ${String(failures.length)} problem(s); the mapping or an upstream site moved.`) + process.exitCode = 1 + } else if (mode === 'check') { + console.log('rescope-vendor: post-state verified — no residue, every exact edit landed, idempotent.') + } else if (mode === 'apply') { + console.log('rescope-vendor: applied. Run `pnpm install`, `pnpm run gen-third-party-notices`, and re-record the touched bilingual pairs.') + } +} + +// Importing this module for its exported classifier must not run the codemod. +if (process.argv[1] !== undefined && realpathSync(process.argv[1]) === realpathSync(fileURLToPath(import.meta.url))) { + main() +} diff --git a/scripts/run-gates.ts b/scripts/run-gates.ts index b986b2e0f3..ad7b6842d9 100644 --- a/scripts/run-gates.ts +++ b/scripts/run-gates.ts @@ -553,6 +553,7 @@ function flagEnabled(envName: string): boolean { function hygieneLeafGates(options: { artifactNeeds?: string[] } = {}): Gate[] { const artifactOptions = options.artifactNeeds === undefined ? {} : { needs: options.artifactNeeds } return [ + pnpmScript('rescope-vendor', 'rescope-vendor:check', { label: 'vendor rescope' }), pnpmScript('knip', 'knip'), pnpmScript('publint', 'publint', artifactOptions), pnpmScript('constraints', 'constraints'), From 78e9b8bec5df739acac847103637b4c389746ae6 Mon Sep 17 00:00:00 2001 From: imccyu <276526105+imccyu@users.noreply.github.com> Date: Mon, 10 Aug 2026 11:26:59 +0800 Subject: [PATCH 14/15] fix(scaffold): resolve the framework peer from this repository, not a registry MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two sites reached a registry for the vendored framework, which the rescope turns from a silent second copy into a hard failure. Live-link mode relinked only the root manifest, so a generated workspace member — `plugins/*/package.json` — resolved its own dependencies from the registry and installed upstream cordis beside this repository's vendored copy. `LinkWorkspace.relinkNestedManifest()` relinks every nested generated manifest; `peerDependencies` keeps its range because package managers reject a link spec there. The sandbox publish-path rehearsal installs this repository's vendored cordis and cosmokit tarballs instead of naming a registry version. --- .../src/package-managers/link-workspace.ts | 33 +++++++++++++++++++ .../src/project/project-edit-session.ts | 14 +++++++- .../scaffold/helper/tests/documents.spec.ts | 21 ++++++++++++ .../scaffold/helper/tests/project.spec.ts | 12 ++++++- 4 files changed, 78 insertions(+), 2 deletions(-) diff --git a/packages/scaffold/helper/src/package-managers/link-workspace.ts b/packages/scaffold/helper/src/package-managers/link-workspace.ts index 1a6b518fa9..3fbc063451 100644 --- a/packages/scaffold/helper/src/package-managers/link-workspace.ts +++ b/packages/scaffold/helper/src/package-managers/link-workspace.ts @@ -134,4 +134,37 @@ export class LinkWorkspace { ? resolve(dirname(directory), directory.split(sep).at(-1) as string) : undefined } + + /** + * Rewrite one nested generated manifest's local dependencies to live-link specs. + * + * A generated workspace member resolves its own dependencies, so every local + * name it declares must point into this repository as well: none of them — + * the harness packages or the rescoped framework — exists on a public + * registry, so a semver spec there fails the install outright. + * `peerDependencies` keeps its range because a peer states what the consumer + * must supply, and package managers reject a link spec in that section. + * @param projectRoot - Absolute root of the generated project. + * @param manifestPath - The nested manifest's project-relative POSIX path. + * @param text - The nested manifest's complete current text. + * @param manager - Package manager whose link-spec form applies. + * @returns The manifest text with every resolved local dependency relinked. + */ + relinkNestedManifest(projectRoot: string, manifestPath: string, text: string, manager: PackageManager): string { + const manifest = JSON.parse(text) as Record + const manifestDirectory = resolve(canonicalPath(projectRoot), dirname(manifestPath)) + let changed = false + for (const section of ['dependencies', 'devDependencies', 'optionalDependencies']) { + const dependencies = manifest[section] + if (typeof dependencies !== 'object' || dependencies === null) continue + for (const [name] of Object.entries(dependencies as Record)) { + const pkg = this.packages.get(name) + if (!pkg) continue + const relativePath = posixPath(relative(manifestDirectory, realpathSync(pkg.directory))) + ;(dependencies as Record)[name] = manager.linkSpec(relativePath) + changed = true + } + } + return changed ? `${JSON.stringify(manifest, null, 2)}\n` : text + } } diff --git a/packages/scaffold/helper/src/project/project-edit-session.ts b/packages/scaffold/helper/src/project/project-edit-session.ts index 4c3d39c07c..3d86050017 100644 --- a/packages/scaffold/helper/src/project/project-edit-session.ts +++ b/packages/scaffold/helper/src/project/project-edit-session.ts @@ -17,7 +17,7 @@ import type { ProjectResource } from '../features/resources.ts' import { CordisYamlFile, type CordisConfigEntry } from '../documents/cordis-yaml-file.ts' import { EnvFile } from '../documents/env-file.ts' import { PackageJsonFile, type PackageManifest } from '../documents/package-json-file.ts' -import { ProjectFile } from '../documents/project-file.ts' +import { ProjectFile, TextProjectFile } from '../documents/project-file.ts' import { TsConfigFile } from '../documents/tsconfig-file.ts' import { featureId, type FeatureId, type ResourceKey } from '../ids.ts' import { LinkWorkspace } from '../package-managers/link-workspace.ts' @@ -288,6 +288,18 @@ export class ProjectEditSession implements FeatureProjectView { this.profile.packageManager, [...this.documents.values()], ) + // Generated workspace members resolve their own dependencies, so the root + // manifest's links are not enough: relink every nested manifest as well. + for (const [path, document] of this.documents) { + if (path === 'package.json' || !path.endsWith('/package.json')) continue + const relinked = workspace.relinkNestedManifest( + this.source.root, + path, + document.serialize(), + this.profile.packageManager, + ) + this.documents.set(path, new TextProjectFile(path, relinked, document.originalText)) + } } this.validateFinalState() const changes = this.changes() diff --git a/packages/scaffold/helper/tests/documents.spec.ts b/packages/scaffold/helper/tests/documents.spec.ts index e3ffe18b77..317a9ed3ab 100644 --- a/packages/scaffold/helper/tests/documents.spec.ts +++ b/packages/scaffold/helper/tests/documents.spec.ts @@ -371,6 +371,27 @@ describe('package manager strategies', () => { expect(workspace.packageDirectory('cordis')).toBe(join(root, 'vendor', 'cordis')) expect(await readFile(join(root, 'vendor', 'cordis', 'package.json'), 'utf8')).toContain('cordis') expect(workspace.packageDirectory('missing')).toBeUndefined() + // A generated workspace member resolves its own dependencies: every local name it + // declares relinks, while a peer keeps the range package managers require there. + const nested = workspace.relinkNestedManifest(join(root, 'consumer'), 'plugins/probe/package.json', `${JSON.stringify({ + name: 'probe', + dependencies: { '@deepseek-ai/dsh-helper': '^0.0.1', 'left-pad': '^1' }, + peerDependencies: { '@deepseek-ai/dsh-scripts': '^0.0.1' }, + devDependencies: { '@deepseek-ai/dsh-scripts': '^0.0.1' }, + }, null, 2)}\n`, new PnpmPackageManager('10.0.0')) + const nestedManifest = JSON.parse(nested) as { + dependencies: Record + peerDependencies: Record + devDependencies: Record + } + expect(nestedManifest.dependencies['@deepseek-ai/dsh-helper']).toMatch(/^link:\.\.\/\.\.\//) + expect(nestedManifest.dependencies['left-pad']).toBe('^1') + expect(nestedManifest.devDependencies['@deepseek-ai/dsh-scripts']).toMatch(/^link:\.\.\/\.\.\//) + expect(nestedManifest.peerDependencies['@deepseek-ai/dsh-scripts']).toBe('^0.0.1') + // Nothing local to relink, and a non-object section, leave the text byte-identical. + const untouched = `${JSON.stringify({ name: 'probe', dependencies: { 'left-pad': '^1' }, devDependencies: null }, null, 2)}\n` + expect(workspace.relinkNestedManifest(join(root, 'consumer'), 'plugins/probe/package.json', untouched, new PnpmPackageManager('10.0.0'))) + .toBe(untouched) const yarnManifest = PackageJsonFile.create('{"name":"consumer"}') yarnManifest.setNpmDependency('dependencies', '@deepseek-ai/dsh-scripts', '^0.0.1') workspace.apply(join(root, 'consumer-yarn'), yarnManifest, new YarnPackageManager('4.0.0'), []) diff --git a/packages/scaffold/helper/tests/project.spec.ts b/packages/scaffold/helper/tests/project.spec.ts index 41acf530ba..01918d7570 100644 --- a/packages/scaffold/helper/tests/project.spec.ts +++ b/packages/scaffold/helper/tests/project.spec.ts @@ -698,14 +698,24 @@ describe('SdkProject and ProjectEditSession', () => { it('does not mistake a linked NPM dependency closure for an installed feature', async () => { const root = await mkdtemp(join(tmpdir(), 'dsh-link-closure-inspection-')) temporary.push(root) - const base = request([selection('hooks', ['claude'])]) + const base = request([selection('hooks', ['claude'])], [new LocalPluginBlueprint('probe', 'plugin')]) const creation: ProjectCreationRequest = { ...base, linkWorkspaceRoot: repoRoot } const project = SdkProject.create(root, creation) const registry = createBuiltinRegistry(project.profile) const edit = project.edit(registry) for (const item of creation.features) edit.installFeature(registry.get(item.id), item) + for (const blueprint of creation.localPlugins) edit.addPlugin(blueprint) const committed = (await edit.commit()).project expect(committed.packageManifest().dependencies?.['@deepseek-ai/dsh-subagent']).toMatch(/^file:/) + // A generated workspace member resolves its own dependencies, so its manifest links too. + const plugin = JSON.parse(await readFile(join(root, 'plugins/probe/package.json'), 'utf8')) as { + devDependencies?: Record + peerDependencies?: Record + } + // Asserted by shape, not by the framework's name: what matters is that the + // resolved section links into this repository while the peer keeps its range. + expect(Object.values(plugin.devDependencies ?? {}).every(spec => spec.startsWith('file:'))).toBe(true) + expect(Object.values(plugin.peerDependencies ?? {}).some(spec => spec.startsWith('^'))).toBe(true) expect(createBuiltinRegistry(committed.profile).get(featureId('subagent')).inspect(committed).state).toBe('absent') }) From ec601ca13dbc8a8a912d6e1b2f4a7550d2be6c9a Mon Sep 17 00:00:00 2001 From: imccyu <276526105+imccyu@users.noreply.github.com> Date: Mon, 10 Aug 2026 22:04:06 +0800 Subject: [PATCH 15/15] build(vendor): rescope the vendored Cordis packages into @deepseek-ai MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Machine-produced by `pnpm run rescope-vendor --apply` plus the regeneration it prints: `pnpm install` for the lockfile, `pnpm run gen-third-party-notices`, `verify-translation-pairing --write` for the touched bilingual pairs, `gen-doc-graphs`, and one typert snapshot whose ids embed character offsets. `pnpm run rescope-vendor --check` verifies the result. Renames nine vendored packages (cordis, cosmokit, schemastery and the six @cordisjs plugins) and every reference that resolves them: manifest names and dependency keys, module specifiers including declare-module merges, cordis.yml plugin names, tsconfig paths, every Markdown fence, and `docs/` prose. Directory names, upstream versions, and dependency ranges are unchanged, so vendor/README.md still reads as an upstream snapshot; its manifest table gains an upstream-name column so THIRD_PARTY_NOTICES keeps MIT attribution pointed at each fork's origin. The tutorial tier follows the rename end to end: its yaml fences named plugins the Loader can no longer resolve, its `ts ignore-check` fences disagreed with the compiled fences beside them, and its prose quoted both. The contracts that told readers to keep upstream names — the root convention and the vendoring cookbook's tree comment and manifest invariant — now say to rescope instead. Two rules read `@deepseek-ai/` as "another workspace plugin": the client bundle purity gate now names the vendored libraries a browser bundle inlines, and the files where a bare `cordis` is an agent-preset id keep that product data. --- AGENTS.md | 2 +- THIRD_PARTY_NOTICES.md | 24 +- apps/cli/composition.md | 8 +- apps/cli/package.json | 10 +- apps/cli/src/profile-boot.ts | 8 +- apps/cli/src/web.ts | 4 +- apps/cli/src/windows-shell.ts | 2 +- apps/cli/tests/args.spec.ts | 4 +- apps/cli/tests/fixtures/dsh-badge/snapshot.ts | 2 +- apps/cli/tests/fixtures/never-dispose.mjs | 2 +- apps/cli/tests/memory-mcp-configs.spec.ts | 4 +- apps/cli/tests/web-agent-presets.e2e.ts | 4 +- apps/web/package.json | 2 +- apps/web/tests/hmr-live.e2e.ts | 4 +- apps/web/tests/scaffold.ts | 10 +- docs/api-gateway.i18n.yaml | 4 +- docs/api-gateway.md | 4 +- docs/api-gateway.zh.md | 4 +- docs/cookbook/adding-a-package.i18n.yaml | 4 +- docs/cookbook/adding-a-package.md | 2 +- docs/cookbook/adding-a-package.zh.md | 2 +- docs/cookbook/adding-a-tool.i18n.yaml | 4 +- docs/cookbook/adding-a-tool.md | 2 +- docs/cookbook/adding-a-tool.zh.md | 2 +- .../adding-a-vendored-package.i18n.yaml | 4 +- docs/cookbook/adding-a-vendored-package.md | 4 +- docs/cookbook/adding-a-vendored-package.zh.md | 4 +- docs/cookbook/extension-cookbook.i18n.yaml | 4 +- docs/cookbook/extension-cookbook.md | 6 +- docs/cookbook/extension-cookbook.zh.md | 6 +- docs/cordis-primer.i18n.yaml | 4 +- docs/cordis-primer.md | 2 +- docs/cordis-primer.zh.md | 2 +- .../cordis-tutorial/01-first-plugin.i18n.yaml | 4 +- docs/cordis-tutorial/01-first-plugin.md | 4 +- docs/cordis-tutorial/01-first-plugin.zh.md | 4 +- .../02-lifecycle-and-effects.i18n.yaml | 4 +- .../02-lifecycle-and-effects.md | 2 +- .../02-lifecycle-and-effects.zh.md | 2 +- docs/cordis-tutorial/03-services.i18n.yaml | 4 +- docs/cordis-tutorial/03-services.md | 8 +- docs/cordis-tutorial/03-services.zh.md | 8 +- docs/cordis-tutorial/04-events.i18n.yaml | 4 +- docs/cordis-tutorial/04-events.md | 10 +- docs/cordis-tutorial/04-events.zh.md | 10 +- docs/cordis-tutorial/05-config.i18n.yaml | 4 +- docs/cordis-tutorial/05-config.md | 4 +- docs/cordis-tutorial/05-config.zh.md | 4 +- .../06-composition-and-hmr.i18n.yaml | 4 +- .../cordis-tutorial/06-composition-and-hmr.md | 16 +- .../06-composition-and-hmr.zh.md | 16 +- .../07-into-the-harness.i18n.yaml | 4 +- docs/cordis-tutorial/07-into-the-harness.md | 4 +- .../cordis-tutorial/07-into-the-harness.zh.md | 4 +- docs/cordis-tutorial/index.i18n.yaml | 4 +- docs/cordis-tutorial/index.md | 4 +- docs/cordis-tutorial/index.zh.md | 4 +- docs/user/develop/basic/config.i18n.yaml | 4 +- docs/user/develop/basic/config.md | 8 +- docs/user/develop/basic/config.zh.md | 8 +- docs/user/develop/basic/index.i18n.yaml | 4 +- docs/user/develop/basic/index.md | 12 +- docs/user/develop/basic/index.zh.md | 12 +- docs/user/develop/basic/tool.i18n.yaml | 4 +- docs/user/develop/basic/tool.md | 2 +- docs/user/develop/basic/tool.zh.md | 2 +- docs/user/develop/framework/events.i18n.yaml | 4 +- docs/user/develop/framework/events.md | 6 +- docs/user/develop/framework/events.zh.md | 6 +- docs/user/develop/framework/index.i18n.yaml | 4 +- docs/user/develop/framework/index.md | 4 +- docs/user/develop/framework/index.zh.md | 4 +- docs/user/develop/framework/service.i18n.yaml | 4 +- docs/user/develop/framework/service.md | 10 +- docs/user/develop/framework/service.zh.md | 10 +- docs/user/develop/practice/index.i18n.yaml | 4 +- docs/user/develop/practice/index.md | 8 +- docs/user/develop/practice/index.zh.md | 8 +- .../develop/practice/llm-adapter.i18n.yaml | 4 +- docs/user/develop/practice/llm-adapter.md | 4 +- docs/user/develop/practice/llm-adapter.zh.md | 4 +- .../acp-agent/advanced.cordis.snapshot.yml | 2 +- examples/acp-agent/advanced.cordis.yml | 2 +- .../acp-agent/both-mode.cordis.snapshot.yml | 2 +- examples/acp-agent/both-mode.cordis.yml | 2 +- .../child-question.cordis.snapshot.yml | 2 +- examples/acp-agent/child-question.cordis.yml | 2 +- ...mode-workspace-context.cordis.snapshot.yml | 2 +- .../code-mode-workspace-context.cordis.yml | 2 +- .../acp-agent/code-mode.cordis.snapshot.yml | 2 +- examples/acp-agent/code-mode.cordis.yml | 2 +- examples/acp-agent/cordis-tools.cordis.yml | 2 +- examples/acp-agent/cordis.snapshot.yml | 2 +- .../acp-agent/depth-two.cordis.snapshot.yml | 2 +- examples/acp-agent/depth-two.cordis.yml | 2 +- examples/acp-agent/fs.cordis.snapshot.yml | 2 +- examples/acp-agent/fs.cordis.yml | 2 +- .../partial-landlock.cordis.snapshot.yml | 2 +- .../acp-agent/partial-landlock.cordis.yml | 2 +- examples/acp-agent/pty.cordis.snapshot.yml | 2 +- examples/acp-agent/pty.cordis.yml | 2 +- examples/acp-agent/retry.cordis.snapshot.yml | 2 +- examples/acp-agent/retry.cordis.yml | 2 +- .../session-query.cordis.snapshot.yml | 2 +- examples/acp-agent/session-query.cordis.yml | 2 +- .../session-sandbox-root.cordis.snapshot.yml | 2 +- .../acp-agent/session-sandbox-root.cordis.yml | 2 +- .../session-title.cordis.snapshot.yml | 2 +- examples/acp-agent/session-title.cordis.yml | 2 +- ...ent-durability-failure.cordis.snapshot.yml | 2 +- .../subagent-durability-failure.cordis.yml | 2 +- .../tests/fixtures/child-question-tripwire.ts | 2 +- .../fixtures/subagent-durability-failure.ts | 2 +- .../fixtures/subagent-settlement-marker.ts | 2 +- .../subagent-acp/mock-delegating-llm.ts | 2 +- .../subagent/subagent-codex/fixture.ts | 2 +- .../fixtures/workspace-context-compaction.ts | 2 +- .../tests/fs-diff-bound.cordis.snapshot.yml | 2 +- .../acp-agent/tests/fs-diff-bound.cordis.yml | 2 +- .../acp-agent/tests/lsp.cordis.snapshot.yml | 2 +- examples/acp-agent/tests/lsp.cordis.yml | 2 +- examples/acp-agent/web.cordis.snapshot.yml | 2 +- examples/acp-agent/web.cordis.yml | 2 +- .../workspace-context.cordis.snapshot.yml | 2 +- .../acp-agent/workspace-context.cordis.yml | 2 +- .../advanced.cordis.snapshot.yml | 2 +- examples/headless-agent/advanced.cordis.yml | 2 +- .../compaction.cordis.snapshot.yml | 2 +- .../credentials.cordis.snapshot.yml | 2 +- examples/headless-agent/e2b.cordis.yml | 2 +- .../headless-agent/goal.cordis.snapshot.yml | 2 +- examples/headless-agent/goal.cordis.yml | 2 +- .../headless-agent/pty.cordis.snapshot.yml | 2 +- .../headless-agent/ralph.cordis.snapshot.yml | 2 +- .../headless-agent/retry.cordis.snapshot.yml | 2 +- .../headless-agent/tests/code-mode.e2e.ts | 2 +- .../headless-agent/tests/coding-task.e2e.ts | 2 +- .../headless-agent/tests/compaction.e2e.ts | 2 +- .../tests/fixtures/cli-mock-llm.ts | 2 +- .../tests/fixtures/cli.cordis.yml | 2 +- .../fixtures/deepseek-defaults.cordis.yml | 2 +- .../tests/fixtures/goal-domain/seed-goal.ts | 2 +- .../tests/fixtures/headless-driver.ts | 2 +- .../tests/fixtures/retry-snapshot-backend.mjs | 2 +- .../fixtures/semantic-checkpoint-agent.ts | 2 +- .../fixtures/subagent-diagnostic-agent.ts | 2 +- .../fixtures/subagent-inheritance-agent.ts | 2 +- .../tests/fixtures/telemetry-otel.cordis.yml | 2 +- .../tests/fixtures/telemetry-redact-rule.ts | 2 +- .../tests/fixtures/time-context-mock-llm.ts | 2 +- .../workspace-context-resume-agent.ts | 2 +- .../headless-agent/tests/full-loop.e2e.ts | 2 +- examples/headless-agent/tests/harness.ts | 2 +- examples/headless-agent/tests/resume.e2e.ts | 2 +- .../tests/semantic-checkpoint.snapshot.ts | 2 +- .../tests/subagent-diagnostic.snapshot.ts | 2 +- .../tests/subagent-inheritance.snapshot.ts | 2 +- .../headless-agent/tests/todo-write.e2e.ts | 2 +- .../workspace-context-resume.snapshot.ts | 2 +- examples/jsonrpc-agent/cordis.snapshot.yml | 2 +- .../persistent-tools.snapshot.cordis.yml | 2 +- .../subagent-dsh-sdk/child-mock-llm.ts | 2 +- .../subagent-dsh-sdk/mock-delegating-llm.ts | 2 +- examples/package.json | 8 +- knip.json | 4 +- packages/acp/acp/package.json | 6 +- packages/acp/acp/src/index.ts | 4 +- packages/acp/acp/src/invariant.ts | 2 +- packages/acp/acp/tests/harness.ts | 2 +- packages/api/gateway/package.json | 4 +- packages/api/gateway/src/client/index.ts | 6 +- packages/api/gateway/src/index.ts | 2 +- packages/api/gateway/src/invariant.ts | 2 +- packages/api/gateway/src/types.ts | 2 +- packages/api/gateway/tests/client.spec.ts | 2 +- packages/api/gateway/tests/gateway.spec.ts | 2 +- packages/api/remotes/package.json | 4 +- packages/api/remotes/src/agent-lookup.ts | 2 +- packages/api/remotes/src/client/index.ts | 4 +- packages/api/remotes/src/invariant.ts | 2 +- .../api/remotes/tests/agent-lookup.spec.ts | 2 +- packages/api/remotes/tests/built-lib.e2e.ts | 4 +- .../attachment/attachment-local/package.json | 6 +- .../attachment/attachment-local/src/index.ts | 4 +- .../attachment-local/src/invariant.ts | 2 +- .../attachment-local/tests/index.spec.ts | 2 +- packages/attachment/attachment/package.json | 4 +- packages/attachment/attachment/src/index.ts | 4 +- .../attachment/attachment/src/invariant.ts | 2 +- packages/bash/bash-env/README.i18n.yaml | 4 +- packages/bash/bash-env/README.md | 2 +- packages/bash/bash-env/README.zh.md | 2 +- packages/bash/bash-env/package.json | 6 +- packages/bash/bash-env/src/index.ts | 6 +- packages/bash/bash-env/src/invariant.ts | 2 +- packages/bash/bash-env/tests/bash-env.spec.ts | 2 +- packages/bash/bash-local/package.json | 6 +- packages/bash/bash-local/src/index.ts | 4 +- packages/bash/bash-local/src/invariant.ts | 2 +- .../bash/bash-local/tests/executor.spec.ts | 2 +- packages/bash/bash-sandbox/package.json | 4 +- packages/bash/bash-sandbox/src/index.ts | 2 +- packages/bash/bash-sandbox/src/invariant.ts | 2 +- packages/bash/bash-sandbox/tests/bwrap.e2e.ts | 2 +- .../bash/bash-sandbox/tests/landlock.e2e.ts | 2 +- .../tests/partial-landlock.spec.ts | 2 +- .../bash/bash-sandbox/tests/sandbox.spec.ts | 2 +- .../bash/bash-sandbox/tests/seatbelt.e2e.ts | 2 +- packages/bash/bash/package.json | 4 +- packages/bash/bash/src/index.ts | 4 +- packages/bash/bash/src/invariant.ts | 2 +- packages/bash/bash/tests/service.spec.ts | 2 +- packages/bash/pwsh-local/package.json | 6 +- packages/bash/pwsh-local/src/index.ts | 4 +- packages/bash/pwsh-local/src/invariant.ts | 2 +- .../bash/pwsh-local/tests/executor.spec.ts | 2 +- packages/bash/pwsh-sandbox/package.json | 4 +- packages/bash/pwsh-sandbox/src/index.ts | 2 +- packages/bash/pwsh-sandbox/src/invariant.ts | 2 +- packages/bash/pwsh-sandbox/tests/acl.e2e.ts | 2 +- .../bash/pwsh-sandbox/tests/sandbox.spec.ts | 2 +- packages/bash/tool-bash/package.json | 6 +- packages/bash/tool-bash/src/index.ts | 4 +- packages/bash/tool-bash/src/invariant.ts | 2 +- .../bash/tool-bash/tests/integration.spec.ts | 2 +- packages/bash/tool-bash/tests/tools.spec.ts | 2 +- packages/bash/tool-pwsh/package.json | 6 +- packages/bash/tool-pwsh/src/index.ts | 4 +- packages/bash/tool-pwsh/src/invariant.ts | 2 +- .../bash/tool-pwsh/tests/integration.spec.ts | 2 +- packages/bash/tool-pwsh/tests/tools.spec.ts | 2 +- packages/boot/app-boot/package.json | 24 +- packages/boot/app-boot/src/index.ts | 18 +- packages/boot/app-boot/src/invariant.ts | 2 +- packages/boot/app-boot/src/profile.ts | 4 +- packages/boot/app-boot/tests/app-boot.spec.ts | 2 +- .../boot/app-boot/tests/config-dump.spec.ts | 2 +- .../boot/app-boot/tests/config-reload.spec.ts | 6 +- .../boot/app-boot/tests/hmr-config.spec.ts | 8 +- .../boot/app-boot/tests/user-patches.spec.ts | 8 +- packages/boot/app-boot/tsdown.config.ts | 2 +- packages/bundle/base/cordis.patch.yml | 4 +- packages/bundle/base/package.json | 8 +- packages/bundle/base/src/invariant.ts | 2 +- packages/bundle/base/tests/base.spec.ts | 2 +- packages/bundle/headless/package.json | 8 +- packages/bundle/headless/src/index.ts | 8 +- packages/bundle/headless/src/invariant.ts | 2 +- .../bundle/headless/tests/headless.spec.ts | 2 +- packages/bundle/web-app/package.json | 6 +- packages/bundle/web-app/src/index.ts | 6 +- packages/bundle/web-app/src/invariant.ts | 2 +- packages/bundle/web-app/tests/web-app.spec.ts | 2 +- packages/client/connection/package.json | 6 +- .../client/connection/src/client/index.ts | 2 +- packages/client/connection/src/index.ts | 4 +- packages/client/connection/src/invariant.ts | 2 +- packages/client/connection/src/rpc-host.ts | 4 +- .../connection/tests/client-apply.spec.ts | 2 +- .../client/connection/tests/node-half.spec.ts | 2 +- packages/client/hmr/package.json | 10 +- packages/client/hmr/src/client/index.ts | 4 +- packages/client/hmr/src/index.ts | 4 +- packages/client/hmr/src/invariant.ts | 2 +- packages/client/hmr/tests/node-half.spec.ts | 2 +- packages/client/locale/package.json | 6 +- packages/client/locale/src/client/index.ts | 4 +- packages/client/locale/src/index.ts | 2 +- packages/client/locale/src/invariant.ts | 2 +- packages/client/locale/src/locale-settings.ts | 2 +- packages/client/locale/tests/apply.spec.ts | 2 +- packages/client/locale/tests/host.spec.ts | 2 +- .../client/locale/tests/invariant.spec.ts | 2 +- packages/client/locale/tests/locale.spec.ts | 2 +- packages/client/modules/package.json | 6 +- packages/client/modules/src/client/index.ts | 2 +- .../client/modules/src/client/manifest.ts | 4 +- packages/client/modules/src/index.ts | 8 +- packages/client/modules/src/invariant.ts | 2 +- .../client/modules/tests/node-half.spec.ts | 2 +- packages/client/runtime/package.json | 6 +- .../client/runtime/src/client/agents/scope.ts | 4 +- .../runtime/src/client/contract/sessions.ts | 2 +- .../conversation/definition-registry.ts | 2 +- .../src/client/conversation/event-registry.ts | 2 +- .../src/client/conversation/view-registry.ts | 2 +- packages/client/runtime/src/client/index.ts | 4 +- .../src/client/session-history/service.ts | 2 +- .../runtime/src/client/sessions/service.ts | 2 +- .../runtime/src/client/sessions/session.ts | 2 +- .../runtime/src/client/settings-scope.ts | 2 +- packages/client/runtime/src/client/slots.ts | 4 +- .../runtime/src/client/workspaces/service.ts | 2 +- packages/client/runtime/src/invariant.ts | 2 +- .../client/runtime/tests/client-apply.spec.ts | 2 +- .../tests/conversation-registry.spec.ts | 2 +- .../client/runtime/tests/invariant.spec.ts | 2 +- packages/client/runtime/tests/scope.spec.ts | 4 +- .../runtime/tests/sessions-service.spec.ts | 2 +- .../runtime/tests/settings-scope.spec.ts | 4 +- .../runtime/tests/slots-service.spec.ts | 2 +- .../client/runtime/tests/wire-events.spec.ts | 2 +- .../runtime/tests/workspaces-service.spec.ts | 2 +- packages/client/schema-form/package.json | 6 +- packages/client/schema-form/src/invariant.ts | 2 +- packages/client/schema-form/src/model.ts | 2 +- .../schema-form/tests/invariant.spec.ts | 2 +- .../client/schema-form/tests/model.spec.ts | 2 +- packages/client/test-runtime/package.json | 4 +- packages/client/test-runtime/src/index.ts | 4 +- packages/client/test-runtime/src/invariant.ts | 2 +- packages/client/test-runtime/src/sessions.ts | 2 +- .../test-runtime/tests/invariant.spec.ts | 2 +- packages/client/tsdown.client.ts | 9 + packages/client/ui-agent-preset/package.json | 4 +- .../client/ui-agent-preset/src/invariant.ts | 2 +- .../ui-agent-preset/tests/apply.spec.ts | 2 +- .../ui-agent-preset/tests/invariant.spec.ts | 2 +- packages/client/ui-command/package.json | 4 +- .../client/ui-command/src/client/index.ts | 2 +- .../client/ui-command/src/client/service.ts | 4 +- packages/client/ui-command/src/invariant.ts | 2 +- .../ui-command/tests/browser-plugin.spec.ts | 2 +- .../client/ui-command/tests/service.spec.ts | 2 +- packages/client/ui-conversation/package.json | 6 +- .../ui-conversation/src/client/apply.ts | 2 +- .../client/chat/register-node-renderers.ts | 2 +- .../src/client/contract/slots.ts | 2 +- .../client/conversation-nodes/assistant.ts | 2 +- .../chat-snapshot-builder.ts | 2 +- .../src/client/conversation-nodes/command.ts | 2 +- .../client/conversation-nodes/compaction.ts | 2 +- .../src/client/conversation-nodes/fallback.ts | 2 +- .../src/client/conversation-nodes/inbox.ts | 2 +- .../src/client/conversation-nodes/message.ts | 2 +- .../src/client/conversation-nodes/register.ts | 2 +- .../src/client/conversation-nodes/retry.ts | 2 +- .../src/client/conversation-nodes/tool.ts | 2 +- .../client/conversation-nodes/turn-error.ts | 2 +- .../client/conversation-nodes/turn-tail.ts | 2 +- .../ui-conversation/src/client/index.ts | 2 +- .../src/client/queue/QueueDock.tsx | 2 +- .../ui-conversation/src/client/service.ts | 4 +- .../src/client/skeleton/TodoPanel.tsx | 2 +- packages/client/ui-conversation/src/index.ts | 2 +- .../client/ui-conversation/src/invariant.ts | 2 +- .../src/submission-settings.ts | 2 +- .../tests/coverage-tails.spec.tsx | 2 +- .../client/ui-conversation/tests/host.spec.ts | 2 +- .../tests/input-scenarios.spec.tsx | 2 +- .../tests/service-orchestration.spec.ts | 2 +- .../tests/views-type-chain.spec.tsx | 2 +- packages/client/ui-deliverables/package.json | 4 +- .../client/ui-deliverables/src/invariant.ts | 2 +- .../tests/produced-files.spec.tsx | 2 +- packages/client/ui-goal/package.json | 4 +- packages/client/ui-goal/src/invariant.ts | 2 +- .../ui-goal/tests/browser-plugin.spec.tsx | 2 +- packages/client/ui-layout/package.json | 4 +- packages/client/ui-layout/src/client/index.ts | 2 +- packages/client/ui-layout/src/invariant.ts | 2 +- packages/client/ui-layout/tests/apply.spec.ts | 2 +- packages/client/ui-model/package.json | 4 +- .../client/ui-model/src/client/service.ts | 6 +- packages/client/ui-model/src/invariant.ts | 2 +- .../ui-model/tests/browser-plugin.spec.ts | 2 +- packages/client/ui-models/package.json | 4 +- packages/client/ui-models/src/invariant.ts | 2 +- packages/client/ui-models/tests/apply.spec.ts | 2 +- .../ui-models/tests/components.spec.tsx | 2 +- .../client/ui-models/tests/invariant.spec.ts | 2 +- .../ui-models/tests/provider-form.spec.tsx | 2 +- packages/client/ui-permission/package.json | 4 +- .../client/ui-permission/src/invariant.ts | 2 +- .../tests/browser-plugin.spec.ts | 2 +- packages/client/ui-plan/package.json | 4 +- packages/client/ui-plan/src/invariant.ts | 2 +- .../ui-plan/tests/browser-plugin.spec.ts | 2 +- packages/client/ui-primitives/package.json | 4 +- .../client/ui-primitives/src/invariant.ts | 2 +- .../ui-primitives/tests/invariant.spec.ts | 2 +- packages/client/ui-question/package.json | 4 +- packages/client/ui-question/src/invariant.ts | 2 +- .../ui-question/tests/browser-plugin.spec.ts | 2 +- .../ui-question/tests/node-plugin.spec.ts | 2 +- .../client/ui-settings-general/package.json | 6 +- .../client/ui-settings-general/src/index.ts | 4 +- .../ui-settings-general/src/invariant.ts | 2 +- .../ui-settings-general/tests/apply.spec.ts | 2 +- .../ui-settings-general/tests/host.spec.ts | 2 +- .../tests/invariant.spec.ts | 2 +- packages/client/ui-settings/package.json | 4 +- packages/client/ui-settings/src/invariant.ts | 2 +- .../client/ui-settings/tests/apply.spec.ts | 2 +- .../ui-settings/tests/invariant.spec.ts | 2 +- packages/client/ui-sidebar/package.json | 4 +- packages/client/ui-sidebar/src/invariant.ts | 2 +- .../client/ui-sidebar/tests/apply.spec.tsx | 2 +- .../client/ui-sidebar/tests/invariant.spec.ts | 2 +- packages/client/ui-skill/package.json | 4 +- packages/client/ui-skill/src/invariant.ts | 2 +- .../ui-skill/tests/browser-plugin.spec.ts | 2 +- packages/client/ui-slash/package.json | 4 +- packages/client/ui-slash/src/client/index.ts | 2 +- .../client/ui-slash/src/client/service.ts | 4 +- packages/client/ui-slash/src/invariant.ts | 2 +- packages/client/ui-slash/src/types.ts | 2 +- packages/client/ui-slash/tests/apply.spec.ts | 2 +- .../client/ui-slash/tests/service.spec.ts | 2 +- packages/client/ui-slots/package.json | 4 +- packages/client/ui-slots/src/invariant.ts | 2 +- .../client/ui-slots/tests/invariant.spec.ts | 2 +- packages/client/ui-subagent/package.json | 4 +- packages/client/ui-subagent/src/invariant.ts | 2 +- .../ui-subagent/tests/browser-plugin.spec.ts | 2 +- packages/client/ui-theme/package.json | 6 +- packages/client/ui-theme/src/client/index.ts | 4 +- packages/client/ui-theme/src/index.ts | 2 +- packages/client/ui-theme/src/invariant.ts | 2 +- .../client/ui-theme/src/theme-settings.ts | 2 +- packages/client/ui-theme/tests/apply.spec.ts | 2 +- packages/client/ui-theme/tests/host.spec.ts | 2 +- .../client/ui-theme/tests/invariant.spec.ts | 2 +- packages/client/ui-theme/tests/theme.spec.ts | 2 +- packages/client/ui-tool/package.json | 4 +- .../tool/toolviews/ask-question-row.tsx | 2 +- .../src/client/tool/toolviews/bash-sample.tsx | 2 +- .../tool/toolviews/file-mutation-row.tsx | 2 +- .../src/client/tool/toolviews/read-row.tsx | 2 +- .../src/client/tool/toolviews/search-row.tsx | 2 +- .../src/client/tool/toolviews/todo-row.tsx | 2 +- .../src/client/tool/toolviews/web-row.tsx | 2 +- packages/client/ui-tool/src/invariant.ts | 2 +- .../ui-tool/tests/chat-code-subcalls.spec.tsx | 2 +- .../client/ui-tool/tests/read-card.spec.tsx | 2 +- .../client/ui-tool/tests/web-card.spec.tsx | 2 +- packages/client/ui-trajectory/package.json | 4 +- .../client/ui-trajectory/src/client/index.ts | 2 +- .../client/ui-trajectory/src/invariant.ts | 2 +- .../ui-trajectory/tests/client-bundle.spec.ts | 2 +- .../client/ui-trajectory/tests/views.spec.tsx | 2 +- packages/client/ui-workspace/package.json | 4 +- packages/client/ui-workspace/src/invariant.ts | 2 +- .../client/ui-workspace/tests/apply.spec.ts | 2 +- .../ui-workspace/tests/invariant.spec.ts | 2 +- packages/client/web-react/package.json | 4 +- packages/client/web-react/src/invariant.ts | 2 +- packages/client/web/package.json | 8 +- packages/client/web/src/app-shell.ts | 4 +- packages/client/web/src/app.tsx | 2 +- packages/client/web/src/boot.tsx | 4 +- packages/client/web/src/invariant.ts | 2 +- packages/client/web/src/loader-status.ts | 2 +- packages/client/web/src/platform.ts | 2 +- packages/client/web/src/seed.ts | 4 +- packages/client/web/tests/app-shell.spec.tsx | 2 +- packages/client/web/tests/app.spec.tsx | 2 +- .../code-runtime-worker/package.json | 6 +- .../code-runtime-worker/src/index.ts | 4 +- .../code-runtime-worker/src/invariant.ts | 2 +- .../tests/built-lib.e2e.ts | 2 +- .../code-runtime-worker/tests/runtime.spec.ts | 2 +- .../code-runtime/code-runtime/package.json | 4 +- .../code-runtime/code-runtime/src/index.ts | 4 +- .../code-runtime/src/invariant.ts | 2 +- .../code-runtime/tests/service.spec.ts | 2 +- packages/compact/command-compact/package.json | 8 +- packages/compact/command-compact/src/index.ts | 2 +- .../compact/command-compact/src/invariant.ts | 2 +- .../tests/command-compact.spec.ts | 4 +- .../tests/loader-composition.spec.ts | 6 +- .../compact/compact-basic/README.i18n.yaml | 4 +- packages/compact/compact-basic/README.md | 2 +- packages/compact/compact-basic/README.zh.md | 2 +- packages/compact/compact-basic/package.json | 10 +- packages/compact/compact-basic/src/index.ts | 4 +- .../compact/compact-basic/src/invariant.ts | 2 +- .../compact/compact-basic/src/summarizer.ts | 2 +- .../compact-basic/tests/compact-basic.spec.ts | 2 +- .../tests/compact-loop-repro.spec.ts | 2 +- .../tests/loader-composition.spec.ts | 6 +- .../tests/manual-compact.spec.ts | 2 +- .../README.i18n.yaml | 4 +- .../compact-tool-result-prune/README.md | 2 +- .../compact-tool-result-prune/README.zh.md | 2 +- .../compact-tool-result-prune/package.json | 10 +- .../compact-tool-result-prune/src/index.ts | 6 +- .../src/invariant.ts | 2 +- .../tests/loader-composition.spec.ts | 6 +- .../tests/tool-result-prune.spec.ts | 2 +- packages/compact/compact/package.json | 4 +- packages/compact/compact/src/index.ts | 4 +- packages/compact/compact/src/invariant.ts | 2 +- .../compact/compact/tests/compact.spec.ts | 2 +- .../compact/compact/tests/invariant.spec.ts | 2 +- .../context/session-reference/package.json | 6 +- .../context/session-reference/src/index.ts | 6 +- .../session-reference/src/invariant.ts | 2 +- .../tests/session-reference.spec.ts | 2 +- packages/context/time-context/package.json | 6 +- packages/context/time-context/src/index.ts | 4 +- .../context/time-context/src/invariant.ts | 2 +- .../time-context/tests/invariant.spec.ts | 2 +- .../time-context/tests/time-context.spec.ts | 4 +- packages/context/tmux-context/package.json | 6 +- packages/context/tmux-context/src/index.ts | 4 +- .../context/tmux-context/src/invariant.ts | 2 +- .../tmux-context/tests/tmux-context.spec.ts | 2 +- .../context/workspace-context/package.json | 8 +- .../context/workspace-context/src/config.ts | 2 +- .../context/workspace-context/src/index.ts | 2 +- .../workspace-context/src/invariant.ts | 2 +- .../tests/workspace-context.e2e.ts | 2 +- .../tests/workspace-context.spec.ts | 4 +- .../core/agent-default-model/package.json | 6 +- .../core/agent-default-model/src/index.ts | 6 +- .../core/agent-default-model/src/invariant.ts | 2 +- .../tests/agent-default-model.spec.ts | 2 +- packages/core/agent-loop/package.json | 6 +- packages/core/agent-loop/src/agent.ts | 2 +- packages/core/agent-loop/src/index.ts | 6 +- packages/core/agent-loop/src/invariant.ts | 2 +- .../core/agent-loop/src/runtime-context.ts | 2 +- packages/core/agent-loop/src/tool-calls.ts | 2 +- .../agent-loop/tests/agent-initiator.spec.ts | 2 +- packages/core/agent-loop/tests/agent.spec.ts | 2 +- packages/core/agent-loop/tests/cancel.spec.ts | 2 +- .../tests/config-session-id.spec.ts | 2 +- .../tests/contract-regressions.spec.ts | 2 +- .../agent-loop/tests/coverage-edges.spec.ts | 2 +- .../agent-loop/tests/interception.spec.ts | 2 +- .../core/agent-loop/tests/invariant.spec.ts | 2 +- packages/core/agent-loop/tests/loop.spec.ts | 2 +- .../core/agent-loop/tests/properties.spec.ts | 2 +- .../agent-loop/tests/request-cache.e2e.ts | 2 +- .../agent-loop/tests/request-error.spec.ts | 2 +- .../tests/request-reconstruction.spec.ts | 2 +- packages/core/agent-loop/tests/resume.spec.ts | 2 +- .../agent-loop/tests/runtime-context.spec.ts | 2 +- .../agent-loop/tests/scope-lifecycle.spec.ts | 2 +- .../core/agent-loop/tests/tool-calls.spec.ts | 2 +- .../core/agent-loop/tests/tool-order.spec.ts | 2 +- packages/core/agent-tool-mode/package.json | 6 +- packages/core/agent-tool-mode/src/index.ts | 4 +- .../core/agent-tool-mode/src/invariant.ts | 2 +- .../tests/agent-tool-mode.spec.ts | 2 +- packages/core/agent/package.json | 4 +- packages/core/agent/src/dispatch.ts | 2 +- packages/core/agent/src/index.ts | 6 +- packages/core/agent/src/invariant.ts | 2 +- packages/core/agent/src/model-selection.ts | 2 +- packages/core/agent/src/runtime-types.ts | 4 +- .../core/agent/tests/agent-initiator.spec.ts | 2 +- packages/core/agent/tests/agent.spec.ts | 2 +- packages/core/agent/tests/invariant.spec.ts | 2 +- .../core/agent/tests/model-selection.spec.ts | 2 +- .../agent/tests/verify-export-jsdoc.spec.ts | 2 +- packages/core/scope/package.json | 4 +- packages/core/scope/src/index.ts | 4 +- packages/core/scope/src/invariant.ts | 2 +- packages/core/scope/src/store.ts | 2 +- packages/core/scope/tests/invariant.spec.ts | 4 +- packages/core/scope/tests/scope.spec.ts | 4 +- packages/core/scope/tests/store.spec.ts | 2 +- packages/core/session/package.json | 4 +- packages/core/session/src/index.ts | 4 +- packages/core/session/src/invariant.ts | 2 +- packages/core/session/tests/fork.spec.ts | 2 +- packages/core/session/tests/invariant.spec.ts | 2 +- packages/core/session/tests/scoped.spec.ts | 2 +- packages/core/session/tests/session.spec.ts | 2 +- packages/core/session/tests/typert.spec.ts | 2 +- packages/core/system-prompt/package.json | 6 +- packages/core/system-prompt/src/index.ts | 6 +- packages/core/system-prompt/src/invariant.ts | 2 +- .../system-prompt/tests/invariant.spec.ts | 2 +- .../core/system-prompt/tests/scoped.spec.ts | 2 +- .../system-prompt/tests/system-prompt.spec.ts | 2 +- .../system-prompt/tests/tool-order.spec.ts | 2 +- packages/core/tools/README.i18n.yaml | 4 +- packages/core/tools/README.md | 2 +- packages/core/tools/README.zh.md | 2 +- packages/core/tools/package.json | 6 +- packages/core/tools/src/index.ts | 6 +- packages/core/tools/src/invariant.ts | 2 +- packages/core/tools/tests/code-mode.spec.ts | 2 +- .../core/tools/tests/execution-mode.spec.ts | 2 +- .../tests/execution-signal-types.spec.ts | 2 +- packages/core/tools/tests/invariant.spec.ts | 2 +- packages/core/tools/tests/scoped.spec.ts | 4 +- packages/core/tools/tests/tools.spec.ts | 2 +- .../credentials-local/package.json | 6 +- .../credentials-local/src/index.ts | 4 +- .../credentials-local/src/invariant.ts | 2 +- .../credentials-local/tests/drain.spec.ts | 2 +- .../credentials-local/tests/local.spec.ts | 2 +- .../tests/review-fixes.spec.ts | 2 +- .../credentials-local/tests/watcher.spec.ts | 2 +- .../credentials/credentials/README.i18n.yaml | 4 +- packages/credentials/credentials/README.md | 2 +- packages/credentials/credentials/README.zh.md | 2 +- packages/credentials/credentials/package.json | 4 +- packages/credentials/credentials/src/index.ts | 4 +- .../credentials/credentials/src/invariant.ts | 2 +- .../credentials/tests/credentials.spec.ts | 2 +- .../credentials/tests/invariant.spec.ts | 2 +- .../credentials/credentials/tests/memory.ts | 2 +- packages/e2b/e2b/package.json | 6 +- packages/e2b/e2b/src/index.ts | 6 +- packages/e2b/e2b/src/invariant.ts | 2 +- packages/e2b/e2b/tests/composition.e2e.ts | 2 +- packages/e2b/e2b/tests/e2b.spec.ts | 2 +- packages/e2b/fs-e2b/package.json | 4 +- packages/e2b/fs-e2b/src/invariant.ts | 2 +- packages/e2b/fs-e2b/tests/filesystem.spec.ts | 2 +- packages/e2b/subprocess-e2b/package.json | 6 +- packages/e2b/subprocess-e2b/src/index.ts | 4 +- packages/e2b/subprocess-e2b/src/invariant.ts | 2 +- .../subprocess-e2b/tests/subprocess.spec.ts | 2 +- .../e2b/subprocess-e2b/tests/terminal.spec.ts | 2 +- packages/examples/acp-demo/package.json | 16 +- packages/examples/acp-demo/src/index.ts | 4 +- packages/examples/acp-demo/src/invariant.ts | 2 +- .../examples/acp-demo/tests/acp-agent.spec.ts | 4 +- .../agent-spine-demo/README.i18n.yaml | 4 +- packages/examples/agent-spine-demo/README.md | 2 +- .../examples/agent-spine-demo/README.zh.md | 2 +- .../examples/agent-spine-demo/package.json | 10 +- .../examples/agent-spine-demo/src/index.ts | 6 +- .../agent-spine-demo/src/invariant.ts | 2 +- .../agent-spine-demo/tests/agent-core.spec.ts | 4 +- .../tests/gen-config-catalog.spec.ts | 70 +- .../tests/multi-project-sandbox.e2e.ts | 2 +- packages/examples/jsonrpc-demo/package.json | 4 +- .../examples/jsonrpc-demo/src/invariant.ts | 2 +- .../feedback/command-feedback/package.json | 8 +- .../feedback/command-feedback/src/index.ts | 2 +- .../command-feedback/src/invariant.ts | 2 +- .../tests/command-feedback.spec.ts | 4 +- .../tests/loader-composition.spec.ts | 6 +- packages/fs/fs-local/package.json | 6 +- packages/fs/fs-local/src/index.ts | 4 +- packages/fs/fs-local/src/invariant.ts | 2 +- packages/fs/fs-local/tests/filesystem.spec.ts | 2 +- packages/fs/fs-policy/README.i18n.yaml | 4 +- packages/fs/fs-policy/README.md | 2 +- packages/fs/fs-policy/README.zh.md | 2 +- packages/fs/fs-policy/package.json | 4 +- packages/fs/fs-policy/src/index.ts | 2 +- packages/fs/fs-policy/src/invariant.ts | 2 +- packages/fs/fs-policy/tests/policy.spec.ts | 2 +- packages/fs/fs-sandbox/package.json | 4 +- packages/fs/fs-sandbox/src/index.ts | 2 +- packages/fs/fs-sandbox/src/invariant.ts | 2 +- .../fs/fs-sandbox/tests/fs-sandbox.spec.ts | 2 +- packages/fs/fs/package.json | 4 +- packages/fs/fs/src/index.ts | 4 +- packages/fs/fs/src/invariant.ts | 2 +- packages/fs/fs/tests/invariant.spec.ts | 2 +- packages/fs/fs/tests/service.spec.ts | 2 +- packages/fs/tool-fs-search/package.json | 6 +- packages/fs/tool-fs-search/src/glob.ts | 2 +- packages/fs/tool-fs-search/src/grep.ts | 2 +- packages/fs/tool-fs-search/src/index.ts | 4 +- packages/fs/tool-fs-search/src/invariant.ts | 2 +- packages/fs/tool-fs-search/src/search-core.ts | 2 +- packages/fs/tool-fs-search/src/surface.ts | 2 +- .../tool-fs-search/tests/integration.spec.ts | 2 +- .../fs/tool-fs-search/tests/load-path.spec.ts | 4 +- .../fs/tool-fs-search/tests/rg-path.spec.ts | 2 +- .../fs/tool-fs-search/tests/tools.spec.ts | 2 +- packages/fs/tool-fs/package.json | 6 +- packages/fs/tool-fs/src/edit.ts | 2 +- packages/fs/tool-fs/src/index.ts | 4 +- packages/fs/tool-fs/src/invariant.ts | 2 +- packages/fs/tool-fs/src/read.ts | 2 +- packages/fs/tool-fs/src/sandbox.ts | 2 +- packages/fs/tool-fs/src/write.ts | 2 +- packages/fs/tool-fs/tests/fs-tools.e2e.ts | 2 +- packages/fs/tool-fs/tests/harness.ts | 2 +- packages/fs/tool-fs/tests/integration.spec.ts | 2 +- packages/fs/tool-fs/tests/tools.spec.ts | 2 +- .../fs/tool-str-replace-editor/package.json | 6 +- .../fs/tool-str-replace-editor/src/index.ts | 4 +- .../tool-str-replace-editor/src/invariant.ts | 2 +- .../tests/tools.spec.ts | 2 +- packages/goal/command-goal/package.json | 6 +- packages/goal/command-goal/src/index.ts | 2 +- packages/goal/command-goal/src/invariant.ts | 2 +- .../command-goal/tests/command-goal.spec.ts | 4 +- packages/goal/goal-session/package.json | 4 +- packages/goal/goal-session/src/index.ts | 4 +- packages/goal/goal-session/src/invariant.ts | 2 +- .../goal-session/tests/goal-session.spec.ts | 2 +- .../goal/goal-session/tests/invariant.spec.ts | 2 +- packages/goal/goal/package.json | 6 +- packages/goal/goal/src/domain.ts | 2 +- packages/goal/goal/src/index.ts | 6 +- packages/goal/goal/src/invariant.ts | 2 +- packages/goal/goal/tests/goal.spec.ts | 2 +- packages/goal/goal/tests/invariant.spec.ts | 2 +- packages/goal/goal/tests/projection.spec.ts | 2 +- packages/goal/tool-goal/package.json | 8 +- packages/goal/tool-goal/src/authority.ts | 2 +- packages/goal/tool-goal/src/index.ts | 4 +- packages/goal/tool-goal/src/invariant.ts | 2 +- .../goal/tool-goal/tests/tool-goal.spec.ts | 4 +- packages/guard/repeat-tool-guard/package.json | 6 +- packages/guard/repeat-tool-guard/src/index.ts | 4 +- .../guard/repeat-tool-guard/src/invariant.ts | 2 +- .../tests/repeat-tool-guard.spec.ts | 2 +- packages/guard/timeout-policy/package.json | 4 +- packages/guard/timeout-policy/src/index.ts | 2 +- .../guard/timeout-policy/src/invariant.ts | 2 +- .../tests/timeout-policy.spec.ts | 4 +- packages/hooks/hook-protocol/package.json | 4 +- packages/hooks/hook-protocol/src/invariant.ts | 2 +- .../hook-protocol/tests/invariant.spec.ts | 2 +- packages/hooks/hooks-claude/package.json | 6 +- packages/hooks/hooks-claude/src/index.ts | 4 +- packages/hooks/hooks-claude/src/invariant.ts | 2 +- .../hooks/hooks-claude/tests/bridge.spec.ts | 4 +- .../hooks-claude/tests/coverage-cases.ts | 2 +- packages/hooks/hooks-codex/package.json | 6 +- packages/hooks/hooks-codex/src/index.ts | 4 +- packages/hooks/hooks-codex/src/invariant.ts | 2 +- .../hooks/hooks-codex/tests/bridge.spec.ts | 4 +- .../hooks/hooks-codex/tests/coverage-cases.ts | 2 +- packages/host/apiproxy/package.json | 6 +- packages/host/apiproxy/src/api-proxy.ts | 2 +- packages/host/apiproxy/src/index.ts | 6 +- packages/host/apiproxy/src/invariant.ts | 2 +- .../tests/api-proxy-agent-preset.spec.ts | 2 +- .../apiproxy/tests/api-proxy-approval.spec.ts | 2 +- .../apiproxy/tests/api-proxy-blank.spec.ts | 2 +- .../apiproxy/tests/api-proxy-cold.spec.ts | 2 +- .../apiproxy/tests/api-proxy-commands.spec.ts | 2 +- .../apiproxy/tests/api-proxy-config.spec.ts | 4 +- .../apiproxy/tests/api-proxy-fork.spec.ts | 2 +- .../apiproxy/tests/api-proxy-models.spec.ts | 2 +- .../tests/api-proxy-projections.spec.ts | 2 +- .../apiproxy/tests/api-proxy-question.spec.ts | 2 +- .../apiproxy/tests/api-proxy-rename.spec.ts | 2 +- .../apiproxy/tests/api-proxy-search.spec.ts | 2 +- .../tests/api-proxy-subagents.spec.ts | 2 +- .../apiproxy/tests/api-proxy-view.spec.ts | 2 +- .../tests/api-proxy-workspace.spec.ts | 2 +- .../host/directory-picker-auto/package.json | 10 +- .../host/directory-picker-auto/src/index.ts | 4 +- .../directory-picker-auto/src/invariant.ts | 2 +- .../tests/loader-composition.spec.ts | 6 +- .../host/directory-picker-browse/package.json | 6 +- .../host/directory-picker-browse/src/index.ts | 4 +- .../directory-picker-browse/src/invariant.ts | 2 +- .../tests/client-flow.spec.tsx | 2 +- .../tests/service.spec.ts | 2 +- .../host/directory-picker-native/package.json | 4 +- .../directory-picker-native/src/invariant.ts | 2 +- .../tests/client-flow.spec.tsx | 2 +- .../tests/service.spec.ts | 2 +- packages/host/directory-picker/package.json | 4 +- packages/host/directory-picker/src/index.ts | 4 +- .../host/directory-picker/src/invariant.ts | 2 +- .../host/directory-picker/tests/seam.spec.ts | 2 +- packages/host/frontend-static/package.json | 8 +- packages/host/frontend-static/src/index.ts | 4 +- .../host/frontend-static/src/invariant.ts | 2 +- .../tests/frontend-static.spec.ts | 6 +- packages/host/webserver/package.json | 6 +- packages/host/webserver/src/index.ts | 6 +- packages/host/webserver/src/invariant.ts | 2 +- .../host/webserver/tests/webserver.spec.ts | 6 +- packages/interaction/commands/package.json | 4 +- packages/interaction/commands/src/index.ts | 4 +- .../interaction/commands/src/invariant.ts | 2 +- .../commands/tests/commands.spec.ts | 2 +- .../commands/tests/invariant.spec.ts | 2 +- packages/interaction/permission/package.json | 6 +- packages/interaction/permission/src/index.ts | 6 +- .../interaction/permission/src/invariant.ts | 2 +- .../permission/tests/invariant.spec.ts | 2 +- .../permission/tests/permission.spec.ts | 2 +- .../permission/tests/projection.spec.ts | 2 +- .../interaction/tool-ask-user/package.json | 4 +- .../interaction/tool-ask-user/src/index.ts | 2 +- .../tool-ask-user/src/invariant.ts | 2 +- .../tool-ask-user/tests/tool-ask-user.spec.ts | 2 +- .../interaction/user-approval/package.json | 6 +- .../interaction/user-approval/src/index.ts | 6 +- .../user-approval/src/invariant.ts | 2 +- .../user-approval/tests/approval.spec.ts | 2 +- .../user-approval/tests/invariant.spec.ts | 2 +- .../interaction/user-interaction/package.json | 4 +- .../interaction/user-interaction/src/index.ts | 4 +- .../user-interaction/src/invariant.ts | 2 +- .../tests/user-interaction.spec.ts | 2 +- packages/llm/llm-deepseek/package.json | 6 +- packages/llm/llm-deepseek/src/index.ts | 4 +- packages/llm/llm-deepseek/src/invariant.ts | 2 +- .../llm/llm-deepseek/tests/adapter.e2e.ts | 2 +- .../llm/llm-deepseek/tests/adapter.spec.ts | 2 +- packages/llm/llm-deepseek/tests/assemble.ts | 2 +- .../llm-deepseek/tests/dynamic-config.spec.ts | 2 +- .../tests/loader-composition.spec.ts | 6 +- packages/llm/llm-pi-ai/package.json | 6 +- packages/llm/llm-pi-ai/src/config.ts | 2 +- packages/llm/llm-pi-ai/src/index.ts | 2 +- packages/llm/llm-pi-ai/src/invariant.ts | 2 +- packages/llm/llm-pi-ai/tests/adapter.e2e.ts | 2 +- packages/llm/llm-pi-ai/tests/adapter.spec.ts | 2 +- packages/llm/llm-pi-ai/tests/assemble.ts | 2 +- packages/llm/llm-pi-ai/tests/catalog.spec.ts | 2 +- .../llm/llm-pi-ai/tests/discovery.spec.ts | 2 +- .../llm-pi-ai/tests/dynamic-config.spec.ts | 2 +- .../tests/loader-composition.spec.ts | 6 +- .../llm/llm-pi-ai/tests/provider-apis.e2e.ts | 2 +- packages/llm/llm-retry/package.json | 10 +- packages/llm/llm-retry/src/index.ts | 4 +- packages/llm/llm-retry/src/invariant.ts | 2 +- .../llm/llm-retry/tests/invariant.spec.ts | 2 +- .../tests/loader-composition.spec.ts | 6 +- .../llm/llm-retry/tests/persistence.spec.ts | 2 +- packages/llm/llm-retry/tests/retry.spec.ts | 4 +- .../tests/transport-recovery.spec.ts | 2 +- packages/llm/llm/package.json | 6 +- packages/llm/llm/src/index.ts | 4 +- packages/llm/llm/src/invariant.ts | 2 +- packages/llm/llm/src/retry-policy.ts | 2 +- packages/llm/llm/tests/invariant.spec.ts | 2 +- packages/llm/llm/tests/service.spec.ts | 2 +- packages/llm/llm/tests/topology.spec.ts | 2 +- packages/llm/token-meter/package.json | 6 +- packages/llm/token-meter/src/index.ts | 6 +- packages/llm/token-meter/src/invariant.ts | 2 +- .../context-breakdown-projection.spec.ts | 2 +- .../llm/token-meter/tests/token-meter.spec.ts | 2 +- .../tests/token-usage-projection.spec.ts | 2 +- packages/lsp/lsp-local/package.json | 6 +- packages/lsp/lsp-local/src/index.ts | 4 +- packages/lsp/lsp-local/src/invariant.ts | 2 +- packages/lsp/lsp-local/tests/built-lib.e2e.ts | 2 +- packages/lsp/lsp-local/tests/host.spec.ts | 2 +- packages/lsp/lsp-local/tests/instance.spec.ts | 2 +- .../lsp/lsp-local/tests/lifecycle.spec.ts | 2 +- packages/lsp/lsp-local/tests/provider.spec.ts | 2 +- .../lsp-local/tests/typescript-server.e2e.ts | 2 +- packages/lsp/lsp/package.json | 4 +- packages/lsp/lsp/src/index.ts | 4 +- packages/lsp/lsp/src/invariant.ts | 2 +- packages/lsp/lsp/tests/lsp.spec.ts | 2 +- packages/lsp/tool-lsp/package.json | 6 +- packages/lsp/tool-lsp/src/index.ts | 4 +- packages/lsp/tool-lsp/src/invariant.ts | 2 +- .../lsp/tool-lsp/tests/integration.spec.ts | 2 +- packages/lsp/tool-lsp/tests/load-path.spec.ts | 2 +- packages/lsp/tool-lsp/tests/tool-lsp.spec.ts | 2 +- packages/mcp/mcp-client/package.json | 6 +- packages/mcp/mcp-client/src/index.ts | 4 +- packages/mcp/mcp-client/src/invariant.ts | 2 +- packages/mcp/mcp-client/src/tools.ts | 2 +- packages/mcp/mcp-client/tests/apply.spec.ts | 2 +- .../mcp/mcp-client/tests/load-path.spec.ts | 2 +- .../mcp/mcp-client/tests/mcp-client.e2e.ts | 2 +- .../mcp/mcp-client/tests/mcp-client.spec.ts | 2 +- packages/plan/plan-mode/package.json | 4 +- packages/plan/plan-mode/src/index.ts | 4 +- packages/plan/plan-mode/src/invariant.ts | 2 +- .../plan/plan-mode/tests/integration.spec.ts | 2 +- .../plan/plan-mode/tests/invariant.spec.ts | 2 +- .../plan/plan-mode/tests/plan-mode.spec.ts | 2 +- .../plan/plan-mode/tests/projection.spec.ts | 2 +- packages/preset/agent-presets/package.json | 14 +- .../preset/agent-presets/src/discovery.ts | 2 +- packages/preset/agent-presets/src/index.ts | 6 +- .../preset/agent-presets/src/invariant.ts | 2 +- packages/preset/agent-presets/src/mount.ts | 6 +- .../agent-presets/tests/authoring.spec.ts | 6 +- .../agent-presets/tests/invariant.spec.ts | 6 +- .../preset/agent-presets/tests/mount.spec.ts | 8 +- .../agent-presets/tests/settings.spec.ts | 6 +- packages/preset/persona/package.json | 6 +- packages/preset/persona/src/index.ts | 4 +- packages/preset/persona/src/invariant.ts | 2 +- packages/preset/persona/tests/persona.spec.ts | 2 +- packages/pty/pty-local/package.json | 6 +- packages/pty/pty-local/src/config.ts | 2 +- packages/pty/pty-local/src/index.ts | 2 +- packages/pty/pty-local/src/invariant.ts | 2 +- packages/pty/pty-local/tests/index.spec.ts | 4 +- packages/pty/pty-local/tests/local.spec.ts | 2 +- packages/pty/pty/package.json | 4 +- packages/pty/pty/src/index.ts | 4 +- packages/pty/pty/src/invariant.ts | 2 +- packages/pty/pty/tests/service.spec.ts | 2 +- .../pty/tool-bash-persistent/package.json | 10 +- .../pty/tool-bash-persistent/src/index.ts | 4 +- .../pty/tool-bash-persistent/src/invariant.ts | 2 +- .../tests/loader-composition.spec.ts | 6 +- .../tool-bash-persistent/tests/tools.spec.ts | 2 +- packages/pty/tool-pty/package.json | 10 +- packages/pty/tool-pty/src/index.ts | 4 +- packages/pty/tool-pty/src/invariant.ts | 2 +- .../tool-pty/tests/loader-composition.spec.ts | 6 +- packages/pty/tool-pty/tests/tools.spec.ts | 2 +- packages/sandbox/sandbox-local/package.json | 6 +- packages/sandbox/sandbox-local/src/index.ts | 4 +- .../sandbox/sandbox-local/src/invariant.ts | 2 +- .../sandbox-local/tests/acl-grants.spec.ts | 2 +- .../sandbox/sandbox-local/tests/bwrap.e2e.ts | 2 +- .../sandbox-local/tests/landlock.e2e.ts | 2 +- .../sandbox/sandbox-local/tests/local.spec.ts | 2 +- .../sandbox-local/tests/packed-install.e2e.ts | 23 +- .../sandbox-local/tests/seatbelt.e2e.ts | 2 +- packages/sandbox/sandbox-policy/package.json | 6 +- packages/sandbox/sandbox-policy/src/index.ts | 6 +- .../sandbox/sandbox-policy/src/invariant.ts | 2 +- .../sandbox-policy/tests/invariant.spec.ts | 2 +- .../sandbox-policy/tests/policy.spec.ts | 2 +- .../sandbox/sandbox-windows-acl/package.json | 4 +- .../sandbox-windows-acl/src/invariant.ts | 2 +- .../tests/provider-chain.spec.ts | 2 +- packages/sandbox/sandbox/package.json | 4 +- packages/sandbox/sandbox/src/index.ts | 4 +- packages/sandbox/sandbox/src/invariant.ts | 2 +- packages/scaffold/client/package.json | 4 +- packages/scaffold/client/src/invariant.ts | 2 +- packages/scaffold/create-sdk/package.json | 4 +- packages/scaffold/create-sdk/src/invariant.ts | 2 +- .../create-sdk/tests/link-workspace.e2e.ts | 4 +- packages/scaffold/helper/package.json | 4 +- .../helper/src/features/builtin/index.ts | 2 +- .../helper/src/features/builtin/spine.ts | 2 +- packages/scaffold/helper/src/invariant.ts | 2 +- .../src/package-managers/link-workspace.ts | 2 +- .../src/plugins/local-plugin-blueprint.ts | 6 +- .../src/project/npm-dependency-policy.ts | 8 +- .../src/templates/assets/local-plugin.ts.tpl | 2 +- .../src/templates/assets/local-tool.ts.tpl | 2 +- .../scaffold/helper/tests/documents.spec.ts | 16 +- .../scaffold/helper/tests/project.spec.ts | 8 +- packages/scaffold/protocol/package.json | 4 +- packages/scaffold/protocol/src/invariant.ts | 2 +- packages/scaffold/scripts/package.json | 4 +- packages/scaffold/scripts/src/invariant.ts | 2 +- packages/scaffold/scripts/src/runtime.ts | 2 +- .../scaffold/scripts/tests/scripts.spec.ts | 2 +- packages/scaffold/server/package.json | 8 +- packages/scaffold/server/src/index.ts | 4 +- packages/scaffold/server/src/invariant.ts | 2 +- packages/scaffold/server/src/server.ts | 2 +- .../server/tests/plugin-apply.spec.ts | 2 +- .../server/tests/plugin-shape.spec.ts | 2 +- packages/scaffold/server/tests/server.spec.ts | 2 +- packages/scaffold/telemetry/package.json | 4 +- packages/scaffold/telemetry/src/invariant.ts | 2 +- .../tool-cordis/package.json | 10 +- .../tool-cordis/src/fiber-state.ts | 2 +- .../tool-cordis/src/guard.ts | 4 +- .../tool-cordis/src/index.ts | 4 +- .../tool-cordis/src/inspect.ts | 2 +- .../tool-cordis/src/invariant.ts | 2 +- .../tool-cordis/src/mount.ts | 2 +- .../tests/cordis-lifecycle.spec.ts | 2 +- .../tool-cordis/tests/helpers.ts | 4 +- .../tool-cordis/tests/inspect.spec.ts | 2 +- .../tool-cordis/tests/integration.spec.ts | 2 +- .../tool-cordis/tests/tool-cordis.spec.ts | 2 +- .../tool-cordis/tests/unmount-hmr.spec.ts | 2 +- .../session-query-sqlite/package.json | 8 +- .../session-query-sqlite/src/index.ts | 6 +- .../session-query-sqlite/src/invariant.ts | 2 +- .../tests/load-path.e2e.ts | 4 +- .../session-query-sqlite/tests/sqlite.spec.ts | 2 +- .../session-query/session-query/package.json | 4 +- .../session-query/session-query/src/corpus.ts | 2 +- .../session-query/session-query/src/index.ts | 4 +- .../session-query/src/invariant.ts | 2 +- .../tests/search-helpers.spec.ts | 2 +- .../session-query/tests/session-query.spec.ts | 2 +- .../session-query/tests/tracing.spec.ts | 2 +- .../tool-session-query/package.json | 6 +- .../tool-session-query/src/index.ts | 4 +- .../tool-session-query/src/invariant.ts | 2 +- .../tool-session-query/src/operations.ts | 2 +- .../src/service-boundary.ts | 2 +- .../src/workspace-access.ts | 2 +- .../tests/sqlite-integration.spec.ts | 2 +- .../tests/tool-session-query.spec.ts | 2 +- .../session-checkpoint-policy/package.json | 6 +- .../session-checkpoint-policy/src/index.ts | 2 +- .../src/invariant.ts | 2 +- .../tests/crash-recovery.e2e.ts | 2 +- .../tests/fixtures/crash-child.ts | 2 +- .../tests/session-checkpoint-policy.spec.ts | 4 +- .../session-persistence-jsonl/package.json | 6 +- .../session-persistence-jsonl/src/index.ts | 4 +- .../src/invariant.ts | 2 +- .../tests/jsonl.spec.ts | 2 +- .../tests/zstd.spec.ts | 2 +- .../session-persistence-sqlite/package.json | 6 +- .../session-persistence-sqlite/src/index.ts | 4 +- .../src/invariant.ts | 2 +- .../tests/sqlite.spec.ts | 2 +- .../session/session-persistence/package.json | 4 +- .../session-persistence/src/coordinator.ts | 2 +- .../session/session-persistence/src/index.ts | 4 +- .../session-persistence/src/invariant.ts | 2 +- .../tests/coordinator-contract.ts | 2 +- .../tests/persistence.spec.ts | 2 +- .../session-projection-cache/package.json | 6 +- .../session-projection-cache/src/index.ts | 6 +- .../session-projection-cache/src/invariant.ts | 2 +- .../tests/cache.spec.ts | 2 +- .../session/session-projection/package.json | 4 +- .../session/session-projection/src/index.ts | 4 +- .../session-projection/src/invariant.ts | 2 +- .../session-projection/tests/registry.spec.ts | 2 +- .../session-telemetry-otel/package.json | 8 +- .../session-telemetry-otel/src/index.ts | 4 +- .../session-telemetry-otel/src/invariant.ts | 2 +- .../session-telemetry-otel/tests/otel.spec.ts | 4 +- .../session/session-telemetry/package.json | 4 +- .../session-telemetry/src/coordinator.ts | 2 +- .../session/session-telemetry/src/index.ts | 4 +- .../session-telemetry/src/invariant.ts | 2 +- .../session-telemetry/tests/redact.spec.ts | 2 +- .../session-telemetry/tests/telemetry.spec.ts | 2 +- .../package.json | 6 +- .../src/index.ts | 4 +- .../src/invariant.ts | 2 +- .../tests/provider.spec.ts | 2 +- .../package.json | 10 +- .../src/index.ts | 4 +- .../src/invariant.ts | 2 +- .../tests/loader-composition.spec.ts | 6 +- .../tests/provider.e2e.ts | 2 +- .../tests/provider.spec.ts | 2 +- .../session/session-title-llm/package.json | 6 +- .../session/session-title-llm/src/index.ts | 4 +- .../session-title-llm/src/invariant.ts | 2 +- .../session-title-llm/tests/llm.spec.ts | 2 +- packages/session/session-title/package.json | 6 +- packages/session/session-title/src/index.ts | 6 +- .../session/session-title/src/invariant.ts | 2 +- .../session-title/tests/invariant.spec.ts | 2 +- .../session-title/tests/persistence.spec.ts | 2 +- .../session-title/tests/projection.spec.ts | 2 +- .../session-title/tests/provider.spec.ts | 2 +- .../session-title/tests/rename.spec.ts | 2 +- .../tests/service-contracts.spec.ts | 2 +- .../session-title/tests/session-title.spec.ts | 2 +- packages/session/user-id/package.json | 4 +- packages/session/user-id/src/invariant.ts | 2 +- .../session/user-id/tests/invariant.spec.ts | 2 +- packages/settings/settings-local/package.json | 6 +- packages/settings/settings-local/src/index.ts | 4 +- .../settings/settings-local/src/invariant.ts | 2 +- .../settings-local/tests/concurrency.spec.ts | 4 +- .../tests/loader-composition.spec.ts | 8 +- .../settings-local/tests/local.spec.ts | 4 +- .../settings-local/tests/lock-race.spec.ts | 4 +- .../settings-local/tests/watcher.spec.ts | 4 +- packages/settings/settings/package.json | 8 +- packages/settings/settings/src/index.ts | 6 +- packages/settings/settings/src/invariant.ts | 2 +- packages/settings/settings/src/redact.ts | 2 +- .../settings/settings/tests/invariant.spec.ts | 4 +- .../settings/settings/tests/redact.spec.ts | 4 +- .../settings/settings/tests/settings.spec.ts | 4 +- packages/skill/skill-badge/package.json | 4 +- packages/skill/skill-badge/src/index.ts | 2 +- packages/skill/skill-badge/src/invariant.ts | 2 +- .../skill-badge/tests/skill-badge.spec.ts | 2 +- packages/skill/skill-local/package.json | 6 +- packages/skill/skill-local/src/index.ts | 6 +- packages/skill/skill-local/src/invariant.ts | 2 +- .../tests/skill-local-watcher.spec.ts | 2 +- .../skill-local/tests/skill-local.spec.ts | 2 +- packages/skill/skill/package.json | 6 +- packages/skill/skill/src/index.ts | 8 +- packages/skill/skill/src/invariant.ts | 2 +- packages/skill/skill/tests/skill.spec.ts | 2 +- packages/skill/tool-skill/package.json | 6 +- packages/skill/tool-skill/src/index.ts | 4 +- packages/skill/tool-skill/src/invariant.ts | 2 +- .../skill/tool-skill/tests/tool-skill.spec.ts | 2 +- packages/spill/spill-local/package.json | 6 +- packages/spill/spill-local/src/index.ts | 4 +- packages/spill/spill-local/src/invariant.ts | 2 +- .../spill-local/tests/spill-local.spec.ts | 2 +- packages/spill/spill-policy/package.json | 6 +- packages/spill/spill-policy/src/index.ts | 4 +- packages/spill/spill-policy/src/invariant.ts | 2 +- .../spill-policy/tests/spill-policy.spec.ts | 4 +- packages/spill/spill/package.json | 4 +- packages/spill/spill/src/index.ts | 4 +- packages/spill/spill/src/invariant.ts | 2 +- packages/spill/spill/tests/service.spec.ts | 2 +- packages/storage/storage-domain/package.json | 6 +- packages/storage/storage-domain/src/domain.ts | 2 +- packages/storage/storage-domain/src/events.ts | 2 +- packages/storage/storage-domain/src/index.ts | 6 +- .../storage/storage-domain/src/invariant.ts | 2 +- .../storage-domain/tests/domain.spec.ts | 2 +- .../storage-domain/tests/invariant.spec.ts | 2 +- packages/storage/storage-json/package.json | 6 +- packages/storage/storage-json/src/index.ts | 4 +- .../storage/storage-json/src/invariant.ts | 2 +- .../storage-json/tests/json-backend.spec.ts | 2 +- packages/storage/storage-sqlite/package.json | 6 +- packages/storage/storage-sqlite/src/index.ts | 4 +- .../storage/storage-sqlite/src/invariant.ts | 2 +- .../storage-sqlite/tests/invariant.spec.ts | 2 +- .../tests/sqlite-backend.spec.ts | 2 +- packages/storage/storage/package.json | 4 +- packages/storage/storage/src/index.ts | 4 +- packages/storage/storage/src/invariant.ts | 2 +- .../storage/storage/tests/registry.spec.ts | 2 +- packages/subagent/subagent-acp/package.json | 8 +- packages/subagent/subagent-acp/src/index.ts | 4 +- .../subagent/subagent-acp/src/invariant.ts | 2 +- .../subagent-acp/tests/subagent-acp.e2e.ts | 2 +- .../subagent-acp/tests/subagent-acp.spec.ts | 4 +- .../subagent-claude-code/package.json | 6 +- .../subagent-claude-code/src/index.ts | 4 +- .../subagent-claude-code/src/invariant.ts | 2 +- .../tests/real-deepseek.e2e.ts | 2 +- .../tests/real-product.spec.ts | 2 +- .../tests/subagent-claude-code.spec.ts | 4 +- packages/subagent/subagent-codex/package.json | 8 +- packages/subagent/subagent-codex/src/index.ts | 4 +- .../subagent/subagent-codex/src/invariant.ts | 2 +- .../subagent-codex/tests/real-deepseek.e2e.ts | 2 +- .../subagent-codex/tests/real-product.spec.ts | 2 +- .../tests/subagent-codex.spec.ts | 4 +- .../subagent/subagent-dsh-sdk/package.json | 8 +- .../subagent/subagent-dsh-sdk/src/index.ts | 4 +- .../subagent-dsh-sdk/src/invariant.ts | 2 +- .../tests/subagent-dsh-sdk.spec.ts | 2 +- packages/subagent/subagent-fork/package.json | 8 +- packages/subagent/subagent-fork/src/index.ts | 4 +- .../subagent/subagent-fork/src/invariant.ts | 2 +- .../tests/multi-subagent.spec.ts | 2 +- .../subagent-fork/tests/subagent-fork.spec.ts | 4 +- .../subagent/subagent-inprocess/package.json | 8 +- .../subagent/subagent-inprocess/src/index.ts | 2 +- .../subagent-inprocess/src/invariant.ts | 2 +- .../subagent-inprocess/src/structured.ts | 2 +- .../tests/inheritance.spec.ts | 2 +- .../tests/preset-inheritance.spec.ts | 6 +- .../tests/structured.spec.ts | 2 +- .../tests/subagent-inprocess.spec.ts | 2 +- packages/subagent/subagent-spawn/package.json | 8 +- packages/subagent/subagent-spawn/src/index.ts | 4 +- .../subagent/subagent-spawn/src/invariant.ts | 2 +- .../subagent/subagent-spawn/tests/harness.ts | 2 +- .../subagent-spawn/tests/spawn.e2e.ts | 2 +- .../tests/subagent-spawn.spec.ts | 4 +- packages/subagent/subagent/package.json | 4 +- .../subagent/src/activation-setup-registry.ts | 2 +- packages/subagent/subagent/src/child-agent.ts | 2 +- .../subagent/subagent/src/continuation.ts | 2 +- packages/subagent/subagent/src/index.ts | 4 +- packages/subagent/subagent/src/invariant.ts | 2 +- packages/subagent/subagent/src/lifecycle.ts | 2 +- .../subagent/subagent/src/list-children.ts | 2 +- .../tests/activation-setup-registry.spec.ts | 2 +- .../subagent/tests/continuation.spec.ts | 2 +- .../subagent/subagent/tests/invariant.spec.ts | 2 +- .../subagent/tests/list-children.spec.ts | 2 +- .../subagent/subagent/tests/service.spec.ts | 2 +- .../subagent/tests/timing-projection.spec.ts | 2 +- .../tool-subagent-control/package.json | 4 +- .../tool-subagent-control/src/index.ts | 2 +- .../tool-subagent-control/src/invariant.ts | 2 +- .../tool-subagent-control/src/list-agents.ts | 2 +- .../tests/list-agents.spec.ts | 2 +- .../tests/tool-subagent-control.spec.ts | 2 +- .../tool-subagent-report/package.json | 6 +- .../tool-subagent-report/src/index.ts | 4 +- .../tool-subagent-report/src/invariant.ts | 2 +- .../tests/tool-subagent-report.spec.ts | 2 +- packages/subagent/tool-subagent/package.json | 8 +- packages/subagent/tool-subagent/src/index.ts | 4 +- .../subagent/tool-subagent/src/invariant.ts | 2 +- .../tests/scripted-provider.spec.ts | 2 +- .../tool-subagent/tests/scripted-provider.ts | 2 +- .../tool-subagent/tests/tool-subagent.spec.ts | 4 +- .../subprocess/subprocess-local/package.json | 4 +- .../subprocess/subprocess-local/src/index.ts | 2 +- .../subprocess-local/src/invariant.ts | 2 +- .../subprocess-local/tests/local.spec.ts | 2 +- .../subprocess-local/tests/spawn.spec.ts | 2 +- packages/subprocess/subprocess/package.json | 4 +- packages/subprocess/subprocess/src/index.ts | 4 +- .../subprocess/subprocess/src/invariant.ts | 2 +- .../subprocess/tests/service.spec.ts | 2 +- packages/support/acp-snapshot/package.json | 4 +- .../support/acp-snapshot/src/invariant.ts | 2 +- .../agent-loop-testkit/README.i18n.yaml | 4 +- packages/support/agent-loop-testkit/README.md | 2 +- .../support/agent-loop-testkit/README.zh.md | 2 +- .../support/agent-loop-testkit/package.json | 4 +- .../support/agent-loop-testkit/src/index.ts | 2 +- .../agent-loop-testkit/src/invariant.ts | 2 +- .../tests/agent-loop-testkit.spec.ts | 2 +- packages/support/invariants/README.i18n.yaml | 4 +- packages/support/invariants/README.md | 2 +- packages/support/invariants/README.zh.md | 2 +- packages/support/invariants/package.json | 6 +- packages/support/invariants/src/index.ts | 10 +- packages/support/invariants/src/invariant.ts | 2 +- .../support/invariants/tests/service.spec.ts | 4 +- packages/support/llm-mock-server/package.json | 4 +- .../support/llm-mock-server/src/invariant.ts | 2 +- .../llm-mock-server/tests/invariant.spec.ts | 2 +- packages/support/llm-replay/package.json | 4 +- packages/support/llm-replay/src/index.ts | 2 +- packages/support/llm-replay/src/invariant.ts | 2 +- .../llm-replay/tests/llm-replay.spec.ts | 2 +- packages/support/loader-smoke/package.json | 4 +- .../support/loader-smoke/src/agent-turn.ts | 2 +- .../support/loader-smoke/src/invariant.ts | 2 +- .../loader-smoke/tests/agent-turn.spec.ts | 2 +- packages/tasks/tasks-local/package.json | 4 +- packages/tasks/tasks-local/src/index.ts | 2 +- packages/tasks/tasks-local/src/invariant.ts | 2 +- .../tasks/tasks-local/tests/tasks.spec.ts | 2 +- packages/tasks/tasks/package.json | 4 +- packages/tasks/tasks/src/index.ts | 4 +- packages/tasks/tasks/src/invariant.ts | 2 +- packages/tasks/tasks/tests/invariant.spec.ts | 2 +- packages/tasks/tasks/tests/service.spec.ts | 2 +- packages/tasks/tool-tasks/package.json | 6 +- packages/tasks/tool-tasks/src/index.ts | 4 +- packages/tasks/tool-tasks/src/invariant.ts | 2 +- .../tasks/tool-tasks/tests/tool-tasks.spec.ts | 2 +- packages/todo/tool-todo/package.json | 10 +- packages/todo/tool-todo/src/index.ts | 4 +- packages/todo/tool-todo/src/invariant.ts | 2 +- .../todo/tool-todo/tests/integration.spec.ts | 2 +- .../todo/tool-todo/tests/invariant.spec.ts | 2 +- .../tests/loader-composition.spec.ts | 6 +- .../todo/tool-todo/tests/projection.spec.ts | 2 +- .../todo/tool-todo/tests/tool-todo.spec.ts | 4 +- packages/typert/generator/package.json | 4 +- packages/typert/generator/src/analyzer.ts | 4 +- packages/typert/generator/src/invariant.ts | 2 +- .../__snapshots__/type-model.spec.ts.snap | 88 +- .../tests/cordis-catalog-contract.spec.ts | 4 +- .../tests/fixtures/type-model/cordis.d.ts | 2 +- .../type-model/packages/client/src/index.ts | 4 +- .../type-model/packages/host/src/index.ts | 6 +- .../type-model/packages/write/src/index.ts | 4 +- .../fixtures/type-model/tsconfig.base.json | 2 +- .../generator/tests/tools-catalog.spec.ts | 2 +- .../typert/generator/tests/type-model.spec.ts | 10 +- packages/typert/loader/package.json | 10 +- packages/typert/loader/src/index.ts | 6 +- packages/typert/loader/src/invariant.ts | 2 +- packages/typert/loader/tests/loader.spec.ts | 4 +- packages/typert/registry/package.json | 4 +- packages/typert/registry/src/client/index.ts | 2 +- packages/typert/registry/src/invariant.ts | 2 +- packages/typert/registry/src/service.ts | 2 +- packages/typert/registry/tests/typert.spec.ts | 2 +- packages/typert/type-meta/package.json | 4 +- packages/typert/type-meta/src/index.ts | 2 +- packages/typert/type-meta/src/invariant.ts | 2 +- packages/typert/type-meta/src/types.ts | 4 +- .../type-meta/tests/fixtures/source-launch.ts | 2 +- .../typert/type-meta/tests/type-meta.spec.ts | 2 +- packages/util/atomic-write/package.json | 4 +- packages/util/atomic-write/src/invariant.ts | 2 +- .../util/atomic-write/tests/invariant.spec.ts | 2 +- packages/util/brand/package.json | 4 +- packages/util/brand/src/invariant.ts | 2 +- packages/util/environment/README.i18n.yaml | 4 +- packages/util/environment/README.md | 2 +- packages/util/environment/README.zh.md | 2 +- packages/util/environment/package.json | 4 +- packages/util/environment/src/index.ts | 4 +- packages/util/environment/src/invariant.ts | 2 +- .../environment/tests/environment.spec.ts | 2 +- packages/util/native-command/package.json | 4 +- packages/util/native-command/src/invariant.ts | 2 +- packages/util/paths/package.json | 4 +- packages/util/paths/src/invariant.ts | 2 +- packages/util/retention/package.json | 4 +- packages/util/retention/src/invariant.ts | 2 +- packages/util/timeout/package.json | 4 +- packages/util/timeout/src/invariant.ts | 2 +- packages/web/tool-web/package.json | 6 +- packages/web/tool-web/src/fetch.ts | 2 +- packages/web/tool-web/src/index.ts | 4 +- packages/web/tool-web/src/invariant.ts | 2 +- packages/web/tool-web/src/search.ts | 2 +- .../web/tool-web/tests/integration.spec.ts | 2 +- packages/web/tool-web/tests/load-path.spec.ts | 4 +- packages/web/tool-web/tests/spill.spec.ts | 2 +- packages/web/tool-web/tests/tool-web.spec.ts | 2 +- packages/web/web-fetch-local/package.json | 6 +- packages/web/web-fetch-local/src/index.ts | 4 +- packages/web/web-fetch-local/src/invariant.ts | 2 +- .../web-fetch-local/tests/fetch-local.spec.ts | 2 +- packages/web/web-search-deepseek/package.json | 6 +- packages/web/web-search-deepseek/src/index.ts | 4 +- .../web/web-search-deepseek/src/invariant.ts | 2 +- .../tests/deepseek.spec.ts | 4 +- packages/web/web-search-exa/package.json | 6 +- packages/web/web-search-exa/src/index.ts | 4 +- packages/web/web-search-exa/src/invariant.ts | 2 +- packages/web/web-search-exa/tests/exa.spec.ts | 2 +- .../web/web-search-perplexity/package.json | 6 +- .../web/web-search-perplexity/src/index.ts | 4 +- .../web-search-perplexity/src/invariant.ts | 2 +- .../tests/perplexity.spec.ts | 2 +- packages/web/web/package.json | 6 +- packages/web/web/src/index.ts | 6 +- packages/web/web/src/invariant.ts | 2 +- packages/web/web/tests/web.spec.ts | 2 +- packages/workflow/tool-ralph/package.json | 8 +- packages/workflow/tool-ralph/src/index.ts | 4 +- packages/workflow/tool-ralph/src/invariant.ts | 2 +- .../tool-ralph/tests/integration.spec.ts | 2 +- .../tool-ralph/tests/tool-ralph.spec.ts | 4 +- packages/workflow/tool-workflow/package.json | 6 +- packages/workflow/tool-workflow/src/index.ts | 4 +- .../workflow/tool-workflow/src/invariant.ts | 2 +- .../tool-workflow/tests/tool-workflow.spec.ts | 4 +- .../workflow-workerthread/package.json | 6 +- .../workflow-workerthread/src/host.ts | 2 +- .../workflow-workerthread/src/index.ts | 4 +- .../workflow-workerthread/src/invariant.ts | 2 +- .../tests/built-worker.e2e.ts | 2 +- .../tests/integration.spec.ts | 2 +- .../tests/source-worker.compat.spec.ts | 2 +- .../tests/workflow-workerthread.e2e.ts | 2 +- .../tests/workflow-workerthread.spec.ts | 4 +- packages/workflow/workflow/package.json | 4 +- packages/workflow/workflow/src/index.ts | 4 +- packages/workflow/workflow/src/invariant.ts | 2 +- .../workflow/workflow/tests/invariant.spec.ts | 2 +- .../workflow/workflow/tests/workflow.spec.ts | 2 +- packages/workspace/workspace/package.json | 4 +- packages/workspace/workspace/src/index.ts | 4 +- packages/workspace/workspace/src/invariant.ts | 2 +- .../workspace/tests/invariant.spec.ts | 2 +- .../workspace/tests/workspace.spec.ts | 2 +- pnpm-lock.yaml | 1738 ++++++++--------- pnpm-workspace.yaml | 4 - python/sdk-runtime/package.json | 12 +- scripts/check-workspace-constraints.ts | 28 +- scripts/cordis-walk.ts | 12 +- scripts/gen-cordis-catalog-partition.spec.ts | 10 +- scripts/gen-cordis-catalog.ts | 4 +- scripts/gen-scoped-events.ts | 4 +- scripts/gen-third-party-notices.spec.ts | 8 +- scripts/gen-third-party-notices.ts | 19 +- scripts/gen-tool-catalog.ts | 2 +- scripts/publish-npm-baseline.ts | 4 +- scripts/test-invariants.spec.ts | 8 +- scripts/test-invariants.ts | 4 +- scripts/verify-cordis-config.ts | 4 +- tsconfig.base.json | 18 +- vendor/README.md | 25 +- vendor/cordis/bin.js | 6 +- vendor/cordis/package.json | 12 +- vendor/cordis/src/context.ts | 2 +- vendor/cordis/src/events.ts | 4 +- vendor/cordis/src/fiber.ts | 4 +- vendor/cordis/src/logger.ts | 2 +- vendor/cordis/src/reflect.ts | 4 +- vendor/cordis/src/registry.ts | 4 +- vendor/cordis/src/service.ts | 2 +- vendor/cordis/src/utils.ts | 2 +- vendor/cosmokit/package.json | 2 +- vendor/group/package.json | 6 +- vendor/group/src/index.ts | 2 +- vendor/hmr/package.json | 12 +- vendor/hmr/src/error.ts | 2 +- vendor/hmr/src/index.ts | 14 +- vendor/include/package.json | 8 +- vendor/include/src/index.ts | 4 +- vendor/loader/package.json | 6 +- vendor/loader/src/config/entry.ts | 4 +- vendor/loader/src/config/group.ts | 2 +- vendor/loader/src/config/isolate.ts | 4 +- vendor/loader/src/config/tree.ts | 4 +- vendor/loader/src/config/utils.ts | 2 +- vendor/loader/src/index.ts | 6 +- vendor/loader/src/internal.ts | 2 +- vendor/logger-console/package.json | 8 +- vendor/logger-console/src/browser.ts | 2 +- vendor/logger-console/src/index.ts | 2 +- vendor/logger-console/src/shared.ts | 6 +- vendor/schemastery/package.json | 4 +- vendor/schemastery/src/index.ts | 2 +- vendor/timer/package.json | 6 +- vendor/timer/src/index.ts | 4 +- 1400 files changed, 3337 insertions(+), 3317 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 9daf45a832..adc14858d7 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -96,7 +96,7 @@ Real-API tests and demos read `DEEPSEEK_API_KEY`, optional `DEEPSEEK_BASE_URL`, ## Conventions -- Every npm package is `@deepseek-ai/dsh-`; vendored packages keep upstream names and are `private: true`. `cordis` is a peerDependency (+ dev) of every harness package. +- Every npm package is `@deepseek-ai/dsh-`; vendored packages are rescoped ([mapping](docs/rescope.md)) and `private: true`. `@deepseek-ai/cordis` is a peerDependency (+ dev) of every harness package. - ESM everywhere (`"type": "module"`). Use package names across packages and `.ts` in local relative imports. Config subprocesses run built `lib/` under plain Node; source regressions use their declared launcher ([testing policy](docs/testing.md#test-subprocess-launch-modes)). The `dsh` CLI source launch runs through tsx's ESM-only hook (`node --import tsx/esm`); modules it reaches must stay ESM (no CJS-only exports) — Node's native TypeScript modes are unavailable across the engines range ([source-launch contract](.agents/notes/implemented/architecture/2026-07-29-dsh-source-launch-tsx-esm.md)). Raw/Web `cordis.yml` bare plugins must appear in their resolver manifest's `dependencies`; `verify-cordis-config` enforces it. - **Registrations are effects**: every contribution goes through `ctx.effect()` / `ctx.on()`; a registry's `register()` returns the disposer. - **Runtime invariants assert owned relationships.** Check authoritative event streams or mutable data, not service or method presence, plugin metadata or effects, or fixed pure examples. Without a plausible relationship, an explained empty companion is correct ([package invariant rules](packages/AGENTS.md)). diff --git a/THIRD_PARTY_NOTICES.md b/THIRD_PARTY_NOTICES.md index fd10ebc2e0..b5b0fc5b29 100644 --- a/THIRD_PARTY_NOTICES.md +++ b/THIRD_PARTY_NOTICES.md @@ -11,19 +11,19 @@ The complete npm transitive closure, including the Landlock launcher workspace, ## Vendored source (`vendor/`) -The Cordis framework and its foundation libraries are source-vendored into this repository rather than consumed from npm. All are MIT-licensed; each directory preserves its upstream `LICENSE` file. Exact upstream commits and local modifications are recorded in [`vendor/README.md`](vendor/README.md). +The Cordis framework and its foundation libraries are source-vendored into this repository rather than consumed from npm, and republished under the `@deepseek-ai` scope. All are MIT-licensed; each directory preserves its upstream `LICENSE` file. Exact upstream commits and local modifications are recorded in [`vendor/README.md`](vendor/README.md). -| Package | Upstream | License | -| --- | --- | --- | -| `cosmokit` | [github.com/deepseek-harness/cosmokit](https://github.com/deepseek-harness/cosmokit) | MIT | -| `schemastery` | [github.com/deepseek-harness/schemastery](https://github.com/deepseek-harness/schemastery) | MIT | -| `cordis` | [github.com/cordiverse/cordis](https://github.com/cordiverse/cordis) | MIT | -| `@cordisjs/plugin-loader` | [github.com/cordiverse/cordis](https://github.com/cordiverse/cordis) | MIT | -| `@cordisjs/plugin-include` | [github.com/deepseek-harness/cordis](https://github.com/deepseek-harness/cordis) | MIT | -| `@cordisjs/plugin-group` | [github.com/deepseek-harness/cordis](https://github.com/deepseek-harness/cordis) | MIT | -| `@cordisjs/plugin-timer` | [github.com/deepseek-harness/cordis](https://github.com/deepseek-harness/cordis) | MIT | -| `@cordisjs/plugin-hmr` | [github.com/deepseek-harness/cordis](https://github.com/deepseek-harness/cordis) | MIT | -| `@cordisjs/plugin-logger-console` | [github.com/deepseek-harness/cordis](https://github.com/deepseek-harness/cordis) | MIT | +| Package | Upstream name | Upstream | License | +| --- | --- | --- | --- | +| `@deepseek-ai/cosmokit` | `cosmokit` | [github.com/deepseek-harness/cosmokit](https://github.com/deepseek-harness/cosmokit) | MIT | +| `@deepseek-ai/schemastery` | `schemastery` | [github.com/deepseek-harness/schemastery](https://github.com/deepseek-harness/schemastery) | MIT | +| `@deepseek-ai/cordis` | `cordis` | [github.com/cordiverse/cordis](https://github.com/cordiverse/cordis) | MIT | +| `@deepseek-ai/cordis-plugin-loader` | `@cordisjs/plugin-loader` | [github.com/cordiverse/cordis](https://github.com/cordiverse/cordis) | MIT | +| `@deepseek-ai/cordis-plugin-include` | `@cordisjs/plugin-include` | [github.com/deepseek-harness/cordis](https://github.com/deepseek-harness/cordis) | MIT | +| `@deepseek-ai/cordis-plugin-group` | `@cordisjs/plugin-group` | [github.com/deepseek-harness/cordis](https://github.com/deepseek-harness/cordis) | MIT | +| `@deepseek-ai/cordis-plugin-timer` | `@cordisjs/plugin-timer` | [github.com/deepseek-harness/cordis](https://github.com/deepseek-harness/cordis) | MIT | +| `@deepseek-ai/cordis-plugin-hmr` | `@cordisjs/plugin-hmr` | [github.com/deepseek-harness/cordis](https://github.com/deepseek-harness/cordis) | MIT | +| `@deepseek-ai/cordis-plugin-logger-console` | `@cordisjs/plugin-logger-console` | [github.com/deepseek-harness/cordis](https://github.com/deepseek-harness/cordis) | MIT | ## Runtime npm dependencies diff --git a/apps/cli/composition.md b/apps/cli/composition.md index 9ca8ab91bf..77d8143d53 100644 --- a/apps/cli/composition.md +++ b/apps/cli/composition.md @@ -8,9 +8,9 @@ The dsh-base bundle patch every profile applies first; mode bundles (dsh-web-app ```mermaid flowchart LR cfg["packages/bundle/base/cordis.patch.yml
cordis.yml"] - plugin_dsh_base_timer["timer
@cordisjs/plugin-timer"] + plugin_dsh_base_timer["timer
@deepseek-ai/cordis-plugin-timer"] cfg --> plugin_dsh_base_timer - plugin_dsh_base_hmr["hmr
@cordisjs/plugin-hmr"] + plugin_dsh_base_hmr["hmr
@deepseek-ai/cordis-plugin-hmr"] cfg --> plugin_dsh_base_hmr plugin_dsh_base_llm["llm
@deepseek-ai/dsh-llm"] cfg --> plugin_dsh_base_llm @@ -164,8 +164,8 @@ flowchart LR | Plugin id | Package / module | | --- | --- | -| `timer` | `@cordisjs/plugin-timer` | -| `hmr` | `@cordisjs/plugin-hmr` | +| `timer` | `@deepseek-ai/cordis-plugin-timer` | +| `hmr` | `@deepseek-ai/cordis-plugin-hmr` | | `llm` | `@deepseek-ai/dsh-llm` | | `session` | `@deepseek-ai/dsh-session` | | `typert` | `@deepseek-ai/dsh-typert-registry` | diff --git a/apps/cli/package.json b/apps/cli/package.json index 03bd4c3db9..a2695f59c9 100644 --- a/apps/cli/package.json +++ b/apps/cli/package.json @@ -13,10 +13,10 @@ ], "license": "BSD-3-Clause", "dependencies": { - "@cordisjs/plugin-hmr": "workspace:*", - "@cordisjs/plugin-include": "workspace:*", - "@cordisjs/plugin-loader": "workspace:*", - "@cordisjs/plugin-timer": "workspace:*", + "@deepseek-ai/cordis-plugin-hmr": "workspace:*", + "@deepseek-ai/cordis-plugin-include": "workspace:*", + "@deepseek-ai/cordis-plugin-loader": "workspace:*", + "@deepseek-ai/cordis-plugin-timer": "workspace:*", "@deepseek-ai/dsh-agent-tool-mode": "workspace:^", "@deepseek-ai/dsh-app-boot": "workspace:^", "@deepseek-ai/dsh-base": "workspace:^", @@ -63,7 +63,7 @@ "@deepseek-ai/dsh-workflow-workerthread": "workspace:^", "@deepseek-ai/dsh-workspace-context": "workspace:^", "commander": "^15.0.0", - "cordis": "^4.0.0-rc.7", + "@deepseek-ai/cordis": "^4.0.0-rc.7", "js-yaml": "^4.2.0", "node-addon-require-builtin": "^0.1.4" }, diff --git a/apps/cli/src/profile-boot.ts b/apps/cli/src/profile-boot.ts index e4a719379e..8c37af124a 100644 --- a/apps/cli/src/profile-boot.ts +++ b/apps/cli/src/profile-boot.ts @@ -10,8 +10,8 @@ import { writeFileSync } from 'node:fs' import { join, resolve } from 'node:path' import { fileURLToPath } from 'node:url' -import { FiberState, type Context } from 'cordis' -import type { PatchOptions } from '@cordisjs/plugin-include' +import { FiberState, type Context } from '@deepseek-ai/cordis' +import type { PatchOptions } from '@deepseek-ai/cordis-plugin-include' import { dshHomePath } from '@deepseek-ai/dsh-paths' import { boot, @@ -308,9 +308,9 @@ export async function runProfile(options: RunProfileOptions): Promise<{ ctx: Con // bare custom profile may not mount either. if (ctx.get('hmr') === undefined) { if (ctx.get('timer') === undefined) { - await ctx.loader.create({ name: '@cordisjs/plugin-timer' }) + await ctx.loader.create({ name: '@deepseek-ai/cordis-plugin-timer' }) } - await ctx.loader.create({ name: '@cordisjs/plugin-hmr', config: { root: [] } }) + await ctx.loader.create({ name: '@deepseek-ai/cordis-plugin-hmr', config: { root: [] } }) } await watchUserPatches(ctx, { binName: NAME, diff --git a/apps/cli/src/web.ts b/apps/cli/src/web.ts index e438c7da7c..8d056d100b 100644 --- a/apps/cli/src/web.ts +++ b/apps/cli/src/web.ts @@ -10,8 +10,8 @@ import { networkInterfaces } from 'node:os' import { fileURLToPath } from 'node:url' -import type { Context } from 'cordis' -import type { PatchOptions } from '@cordisjs/plugin-include' +import type { Context } from '@deepseek-ai/cordis' +import type { PatchOptions } from '@deepseek-ai/cordis-plugin-include' import { addHarnessSourceSection } from '@deepseek-ai/dsh-app-boot' import type { EnvironmentSnapshot } from '@deepseek-ai/dsh-environment' import { runProfile, type ProfileRows } from './profile-boot.ts' diff --git a/apps/cli/src/windows-shell.ts b/apps/cli/src/windows-shell.ts index fbb3d13194..1a9ca719f8 100644 --- a/apps/cli/src/windows-shell.ts +++ b/apps/cli/src/windows-shell.ts @@ -11,7 +11,7 @@ */ import { join } from 'node:path' -import type { PatchOptions } from '@cordisjs/plugin-include' +import type { PatchOptions } from '@deepseek-ai/cordis-plugin-include' import { loadOverlayPatches, type ProfileLayer } from '@deepseek-ai/dsh-app-boot' /** The base bundle whose package carries the Windows shell patch. */ diff --git a/apps/cli/tests/args.spec.ts b/apps/cli/tests/args.spec.ts index 603d8e2dd5..e30739214d 100644 --- a/apps/cli/tests/args.spec.ts +++ b/apps/cli/tests/args.spec.ts @@ -44,8 +44,8 @@ describe('parseDshArgs', () => { .toEqual({ mode: 'plugin', profile: 'tui', args: ['add', 'turtle-ui'] }) expect(parse(['plugin', '--profile', 'tui', 'remove', 'turtle-ui'])) .toEqual({ mode: 'plugin', profile: 'tui', args: ['remove', 'turtle-ui'] }) - expect(parse(['plugin', '--profile', 'tui', 'why', 'cordis'])) - .toEqual({ mode: 'plugin', profile: 'tui', args: ['why', 'cordis'] }) + expect(parse(['plugin', '--profile', 'tui', 'why', '@deepseek-ai/cordis'])) + .toEqual({ mode: 'plugin', profile: 'tui', args: ['why', '@deepseek-ai/cordis'] }) // Unknown pnpm flags forward verbatim. expect(parse(['plugin', '--profile', 'tui', 'add', '--save-dev', 'x'])) .toEqual({ mode: 'plugin', profile: 'tui', args: ['add', '--save-dev', 'x'] }) diff --git a/apps/cli/tests/fixtures/dsh-badge/snapshot.ts b/apps/cli/tests/fixtures/dsh-badge/snapshot.ts index 8d6019ab53..98f3fd7578 100644 --- a/apps/cli/tests/fixtures/dsh-badge/snapshot.ts +++ b/apps/cli/tests/fixtures/dsh-badge/snapshot.ts @@ -1,5 +1,5 @@ import { fileURLToPath } from 'node:url' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { agentEvents, Inbox, type Agent } from '@deepseek-ai/dsh-agent' import { CallId } from '@deepseek-ai/dsh-llm' import { boot, loadOverlayPatches } from '@deepseek-ai/dsh-app-boot' diff --git a/apps/cli/tests/fixtures/never-dispose.mjs b/apps/cli/tests/fixtures/never-dispose.mjs index 5dc8510550..9e81b32738 100644 --- a/apps/cli/tests/fixtures/never-dispose.mjs +++ b/apps/cli/tests/fixtures/never-dispose.mjs @@ -4,7 +4,7 @@ import { existsSync } from 'node:fs' /** * Register a disposer that keeps process shutdown pending until it is forced. - * @param {import('cordis').Context} ctx - loader-mounted test plugin context. + * @param {import('@deepseek-ai/cordis').Context} ctx - loader-mounted test plugin context. */ export function apply(ctx) { const keepAlive = setInterval(() => {}, 60_000) diff --git a/apps/cli/tests/memory-mcp-configs.spec.ts b/apps/cli/tests/memory-mcp-configs.spec.ts index 818b8f4561..ee8905c3b6 100644 --- a/apps/cli/tests/memory-mcp-configs.spec.ts +++ b/apps/cli/tests/memory-mcp-configs.spec.ts @@ -8,8 +8,8 @@ import { readFileSync } from 'node:fs' import { resolve } from 'node:path' import { afterEach, describe, expect, it } from 'vitest' -import type { Context } from 'cordis' -import type { PatchOptions } from '@cordisjs/plugin-include' +import type { Context } from '@deepseek-ai/cordis' +import type { PatchOptions } from '@deepseek-ai/cordis-plugin-include' import { boot, loadOverlayPatches } from '@deepseek-ai/dsh-app-boot' import SystemPrompt from '@deepseek-ai/dsh-system-prompt' import ToolRegistry from '@deepseek-ai/dsh-tools' diff --git a/apps/cli/tests/web-agent-presets.e2e.ts b/apps/cli/tests/web-agent-presets.e2e.ts index 004de203c8..27e88a1738 100644 --- a/apps/cli/tests/web-agent-presets.e2e.ts +++ b/apps/cli/tests/web-agent-presets.e2e.ts @@ -3,11 +3,11 @@ import { mkdir, mkdtemp, readFile, stat, writeFile } from 'node:fs/promises' import { tmpdir } from 'node:os' import { fileURLToPath } from 'node:url' import { dirname, join } from 'node:path' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { boot, healProfilesModuleFallback, loadOverlayPatches } from '@deepseek-ai/dsh-app-boot' import { SessionId } from '@deepseek-ai/dsh-session' import type { Agent } from '@deepseek-ai/dsh-agent' -import type { PatchOptions } from '@cordisjs/plugin-include' +import type { PatchOptions } from '@deepseek-ai/cordis-plugin-include' import { beforeAll, describe, expect, it } from 'vitest' import { settingsNamespace } from '@deepseek-ai/dsh-settings' import { resolveSessionPreset, SETTINGS_NAMESPACE } from '@deepseek-ai/dsh-agent-presets' diff --git a/apps/web/package.json b/apps/web/package.json index c58e5b9682..6f4bce8dc2 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -23,7 +23,7 @@ "react-dom": "^18.2.0" }, "devDependencies": { - "@cordisjs/plugin-group": "workspace:^", + "@deepseek-ai/cordis-plugin-group": "workspace:^", "@deepseek-ai/dsh-client-modules": "workspace:^", "@deepseek-ai/dsh-client-ui-primitives": "workspace:^", "@deepseek-ai/dsh-client-ui-slots": "workspace:^", diff --git a/apps/web/tests/hmr-live.e2e.ts b/apps/web/tests/hmr-live.e2e.ts index cafd0fb474..57a3867187 100644 --- a/apps/web/tests/hmr-live.e2e.ts +++ b/apps/web/tests/hmr-live.e2e.ts @@ -6,8 +6,8 @@ import { tmpdir } from 'node:os' import { join } from 'node:path' import { chromium } from 'playwright' import { expect, it } from 'vitest' -import { Context } from 'cordis' -import type { Fiber } from 'cordis' +import { Context } from '@deepseek-ai/cordis' +import type { Fiber } from '@deepseek-ai/cordis' import LocalSubprocessService from '@deepseek-ai/dsh-subprocess-local' import type { SubprocessHandle, SubprocessSpawnSpec } from '@deepseek-ai/dsh-subprocess' import { REPO_ROOT } from './support.ts' diff --git a/apps/web/tests/scaffold.ts b/apps/web/tests/scaffold.ts index 945775678f..0104a7bee7 100644 --- a/apps/web/tests/scaffold.ts +++ b/apps/web/tests/scaffold.ts @@ -29,10 +29,10 @@ import { join } from 'node:path' import { pathToFileURL } from 'node:url' import type { Page } from 'playwright' import { expect } from 'vitest' -import { Context } from 'cordis' -import Loader from '@cordisjs/plugin-loader' -import Include, { type PatchOptions } from '@cordisjs/plugin-include' -import Group from '@cordisjs/plugin-group' +import { Context } from '@deepseek-ai/cordis' +import Loader from '@deepseek-ai/cordis-plugin-loader' +import Include, { type PatchOptions } from '@deepseek-ai/cordis-plugin-include' +import Group from '@deepseek-ai/cordis-plugin-group' import { scrubRequestHeaders, stabilizeFixtureMessageIds } from '@deepseek-ai/dsh-acp-snapshot' import { addHarnessSourceSection, @@ -464,7 +464,7 @@ export async function launchWebScaffold(options: LaunchOptions = {}): Promise// Choose an existing group when one matches the package's role (`core`, `llm`, `bash`, `compact`, `subagent`, `todo`, `session-persistence`, `ui`, `util`, or `support`). A new group is allowed, but it is a pure container: no `package.json`, no source files, and packages still sit exactly one level below it. -package.json invariants (enforced by `pnpm run constraints` / `scripts/check-workspace-constraints.ts`): `private: true`, a `version` matching the root `package.json`, `type: module`, `main: "lib/index.js"`, `types: "lib/types/index.d.ts"`, `exports["."].types: "./lib/types/index.d.ts"`, `exports["."].default: "./lib/index.js"`, `cordis` in BOTH peerDependencies and devDependencies (same range). Mirror every dsh peer dependency in devDependencies. `schemastery` goes in `dependencies` (it is a runtime validator), matching agent-loop. The `files` list contains exactly `lib/index.js`, `lib/invariant.js`, `lib/types/**/*.d.ts`, and package-specific runtime artifacts recognized by the gate; a package whose runtime export points into the emitted tree also includes `lib/types/**/*.js`. Do not publish `src`, declaration maps, JS maps, or stale root declaration files. CLI app packages with a package `bin` include `lib/bin.js` immediately after `lib/index.js` in `files`. +package.json invariants (enforced by `pnpm run constraints` / `scripts/check-workspace-constraints.ts`): `private: true`, a `version` matching the root `package.json`, `type: module`, `main: "lib/index.js"`, `types: "lib/types/index.d.ts"`, `exports["."].types: "./lib/types/index.d.ts"`, `exports["."].default: "./lib/index.js"`, `@deepseek-ai/cordis` in BOTH peerDependencies and devDependencies (same range). Mirror every dsh peer dependency in devDependencies. `@deepseek-ai/schemastery` goes in `dependencies` (it is a runtime validator), matching agent-loop. The `files` list contains exactly `lib/index.js`, `lib/invariant.js`, `lib/types/**/*.d.ts`, and package-specific runtime artifacts recognized by the gate; a package whose runtime export points into the emitted tree also includes `lib/types/**/*.js`. Do not publish `src`, declaration maps, JS maps, or stale root declaration files. CLI app packages with a package `bin` include `lib/bin.js` immediately after `lib/index.js` in `files`. In-package relative imports use explicit `.ts` specifiers in source (for example, `export * from './types.ts'`). The compiler rewrites those to `.js` in emitted JS and leaves explicit `.ts` specifiers in declarations, which standard NodeNext/Node16 TypeScript consumers resolve to the sibling `.d.ts` files. diff --git a/docs/cookbook/adding-a-package.zh.md b/docs/cookbook/adding-a-package.zh.md index c8769197e0..97b4df150f 100644 --- a/docs/cookbook/adding-a-package.zh.md +++ b/docs/cookbook/adding-a-package.zh.md @@ -22,7 +22,7 @@ packages/// 当已有分组与包的角色匹配时,选择该分组(`core`、`llm`、`bash`、`compact`、`subagent`、`todo`、`session-persistence`、`ui`、`util` 或 `support`)。允许新建分组,但分组只是纯容器:没有 `package.json`,没有源文件,包仍然恰好位于其下一层。 -package.json 不变式(由 `pnpm run constraints` / `scripts/check-workspace-constraints.ts` 强制执行):`private: true`,`version` 与根 `package.json` 一致,`type: module`,`main: "lib/index.js"`,`types: "lib/types/index.d.ts"`,`exports["."].types: "./lib/types/index.d.ts"`,`exports["."].default: "./lib/index.js"`,`cordis` 同时出现在 peerDependencies 和 devDependencies 中(相同范围)。每个 dsh 对等依赖(peer dependency)都要在 devDependencies 中镜像。`schemastery` 放在 `dependencies` 中(它是运行时校验器),与 agent-loop 保持一致。`files` 列表精确包含 `lib/index.js`、`lib/invariant.js`、`lib/types/**/*.d.ts` 以及门禁认可的包专用运行时产物;如果包的运行时 export 指向输出树,还要包含 `lib/types/**/*.js`。不要发布 `src`、声明映射、JS map 或陈旧的根声明文件。带有 `bin` 的 CLI 应用包在 `files` 中将 `lib/bin.js` 紧跟在 `lib/index.js` 之后。 +package.json 不变式(由 `pnpm run constraints` / `scripts/check-workspace-constraints.ts` 强制执行):`private: true`,`version` 与根 `package.json` 一致,`type: module`,`main: "lib/index.js"`,`types: "lib/types/index.d.ts"`,`exports["."].types: "./lib/types/index.d.ts"`,`exports["."].default: "./lib/index.js"`,`@deepseek-ai/cordis` 同时出现在 peerDependencies 和 devDependencies 中(相同范围)。每个 dsh 对等依赖(peer dependency)都要在 devDependencies 中镜像。`@deepseek-ai/schemastery` 放在 `dependencies` 中(它是运行时校验器),与 agent-loop 保持一致。`files` 列表精确包含 `lib/index.js`、`lib/invariant.js`、`lib/types/**/*.d.ts` 以及门禁认可的包专用运行时产物;如果包的运行时 export 指向输出树,还要包含 `lib/types/**/*.js`。不要发布 `src`、声明映射、JS map 或陈旧的根声明文件。带有 `bin` 的 CLI 应用包在 `files` 中将 `lib/bin.js` 紧跟在 `lib/index.js` 之后。 包内的相对导入在源码中使用显式 `.ts` 后缀(例如 `export * from './types.ts'`)。编译器在输出的 JS 中将其重写为 `.js`,在声明文件中保留显式 `.ts` 后缀;标准的 NodeNext/Node16 TypeScript 消费方会将其解析到同目录的 `.d.ts` 文件。 diff --git a/docs/cookbook/adding-a-tool.i18n.yaml b/docs/cookbook/adding-a-tool.i18n.yaml index e232ad4302..5b47beab61 100644 --- a/docs/cookbook/adding-a-tool.i18n.yaml +++ b/docs/cookbook/adding-a-tool.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write docs/cookbook/adding-a-tool.md -adding-a-tool.md: b030d3c3a6b7dd66b6594779345a96af3a895bd8 -adding-a-tool.zh.md: 4272a7a4571782bc213ca29de1a57d51fbd24075 +adding-a-tool.md: fa39c4b97f3c0eb739ea34d1b43ef46d11285bbf +adding-a-tool.zh.md: ab32e90fac5539ee403a36b2dd52e60db3ad603c diff --git a/docs/cookbook/adding-a-tool.md b/docs/cookbook/adding-a-tool.md index b030d3c3a6..fa39c4b97f 100644 --- a/docs/cookbook/adding-a-tool.md +++ b/docs/cookbook/adding-a-tool.md @@ -8,7 +8,7 @@ Reference for the contracts a model-facing tool must satisfy. For an ordered fir ```ts import { readFile } from 'node:fs/promises' -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { defineTool } from '@deepseek-ai/dsh-tools' export const name = 'my-tool' diff --git a/docs/cookbook/adding-a-tool.zh.md b/docs/cookbook/adding-a-tool.zh.md index 4272a7a457..ab32e90fac 100644 --- a/docs/cookbook/adding-a-tool.zh.md +++ b/docs/cookbook/adding-a-tool.zh.md @@ -8,7 +8,7 @@ ```ts import { readFile } from 'node:fs/promises' -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { defineTool } from '@deepseek-ai/dsh-tools' export const name = 'my-tool' diff --git a/docs/cookbook/adding-a-vendored-package.i18n.yaml b/docs/cookbook/adding-a-vendored-package.i18n.yaml index 4f5b8c3c49..b17f3390cf 100644 --- a/docs/cookbook/adding-a-vendored-package.i18n.yaml +++ b/docs/cookbook/adding-a-vendored-package.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write docs/cookbook/adding-a-vendored-package.md -adding-a-vendored-package.md: 724d89c1c7cd728f7123a6975b5500cd40815851 -adding-a-vendored-package.zh.md: d16ec1056431a4ac1c02d50a5ef0f0a64b67ca6d +adding-a-vendored-package.md: 239ac27565204332559038014fabae83fc2d1057 +adding-a-vendored-package.zh.md: 2bf5c7eeaffec594dbc4d13e0aa33b12a9eccf4f diff --git a/docs/cookbook/adding-a-vendored-package.md b/docs/cookbook/adding-a-vendored-package.md index 724d89c1c7..239ac27565 100644 --- a/docs/cookbook/adding-a-vendored-package.md +++ b/docs/cookbook/adding-a-vendored-package.md @@ -8,7 +8,7 @@ When the harness needs another upstream Cordis package (e.g. `@cordisjs/plugin-h ``` vendor// - package.json # from upstream; set "private": true, keep name/exports/type + package.json # from upstream; set "private": true, rescope the name, keep exports/type tsconfig.json # extends ../../tsconfig.base.json (see configuration below) src/ # the upstream src/ verbatim README.md LICENSE # if upstream ships them @@ -29,7 +29,7 @@ vendor// } ``` -`package.json` invariants: `"private": true` (vendored packages are never published), keep upstream's `name`/`version`/`exports`/`type`, point declaration metadata at `lib/types`, publish `.d.ts` and `.d.ts.map` declaration outputs, and list its cordis deps in `peerDependencies` (matching the upstream manifest). Transitive upstream deps must themselves be vendored or already present — vendoring one package often means vendoring its dependency tree (e.g. `@cordisjs/plugin-http` pulls `@cordisjs/fetch-file`). +`package.json` invariants: `"private": true` (vendored packages are never published), rescope the `name` ([mapping](../rescope.md)) while keeping upstream's `version`/`exports`/`type`, point declaration metadata at `lib/types`, publish `.d.ts` and `.d.ts.map` declaration outputs, and list its cordis deps in `peerDependencies` (matching the upstream manifest). Transitive upstream deps must themselves be vendored or already present — vendoring one package often means vendoring its dependency tree (e.g. `@cordisjs/plugin-http` pulls `@cordisjs/fetch-file`). Local relative imports/exports in vendored TypeScript source use explicit `.ts` specifiers after copying. This is a repo-local build difference from upstream: `rewriteRelativeImportExtensions` emits `.js` runtime imports while declarations keep explicit `.ts` specifiers that NodeNext/Node16 TypeScript consumers can resolve. diff --git a/docs/cookbook/adding-a-vendored-package.zh.md b/docs/cookbook/adding-a-vendored-package.zh.md index d16ec10564..2bf5c7eeaf 100644 --- a/docs/cookbook/adding-a-vendored-package.zh.md +++ b/docs/cookbook/adding-a-vendored-package.zh.md @@ -8,7 +8,7 @@ ``` vendor// - package.json # from upstream; set "private": true, keep name/exports/type + package.json # from upstream; set "private": true, rescope the name, keep exports/type tsconfig.json # extends ../../tsconfig.base.json (see configuration below) src/ # the upstream src/ verbatim README.md LICENSE # if upstream ships them @@ -29,7 +29,7 @@ vendor// } ``` -`package.json` 的不变式:`"private": true`(vendored 包永不发布);保留上游的 `name`/`version`/`exports`/`type`;声明元数据指向 `lib/types`;发布 `.d.ts` 与 `.d.ts.map` 声明输出;在 `peerDependencies` 中列出其 Cordis 依赖(与上游 manifest(元数据清单)一致)。传递性上游依赖本身也必须被 vendor 或已存在于仓库中——vendor 一个包往往意味着 vendor 其整条依赖树(如 `@cordisjs/plugin-http` 会拉入 `@cordisjs/fetch-file`)。 +`package.json` 的不变式:`"private": true`(vendored 包永不发布);改写 `name` 的 scope([映射](../rescope.md)),保留上游的 `version`/`exports`/`type`;声明元数据指向 `lib/types`;发布 `.d.ts` 与 `.d.ts.map` 声明输出;在 `peerDependencies` 中列出其 Cordis 依赖(与上游 manifest(元数据清单)一致)。传递性上游依赖本身也必须被 vendor 或已存在于仓库中——vendor 一个包往往意味着 vendor 其整条依赖树(如 `@cordisjs/plugin-http` 会拉入 `@cordisjs/fetch-file`)。 vendored TypeScript 源码中的本地相对导入/导出在复制后使用显式 `.ts` 后缀。这是仓库本地构建与上游的差异:`rewriteRelativeImportExtensions` 输出 `.js` 运行时导入,而声明文件保留显式 `.ts` 后缀,使 NodeNext/Node16 的 TypeScript 消费方能够解析。 diff --git a/docs/cookbook/extension-cookbook.i18n.yaml b/docs/cookbook/extension-cookbook.i18n.yaml index ac600e8c6d..3a98437564 100644 --- a/docs/cookbook/extension-cookbook.i18n.yaml +++ b/docs/cookbook/extension-cookbook.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write docs/cookbook/extension-cookbook.md -extension-cookbook.md: 95ba269a5d62e14cfde487d5a3aaca5db493657e -extension-cookbook.zh.md: e3fbe09f1ec09568e3b259aee361d33ba3e62140 +extension-cookbook.md: f292075dfdad5016d81521318b38594e3d7ee8b4 +extension-cookbook.zh.md: 0623c49d9d7075b3823c1fd340b36a5fba21f31e diff --git a/docs/cookbook/extension-cookbook.md b/docs/cookbook/extension-cookbook.md index 95ba269a5d..f292075dfd 100644 --- a/docs/cookbook/extension-cookbook.md +++ b/docs/cookbook/extension-cookbook.md @@ -13,7 +13,7 @@ A tool registers on `ctx.tools`. The annotated `defineTool` example (typed `exec This permission gate is one example of a hook plugin. It returns a typed decision from the `tools/pre-execute` gate to allow or deny a call; sandbox, permission, and plan-mode plugins can use this extension point. Hook plugins can intercept other extension points and are not inherently permission gates. A "native hook" is an ordinary Cordis plugin on an interception point; it needs no external protocol. ```ts -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { PreToolDecision, ToolExecution } from '@deepseek-ai/dsh-tools' declare function isAllowed(exec: ToolExecution): Promise @@ -37,7 +37,7 @@ This waterfall is the reorderable policy layer. Use `ctx.tools.guard()` when an A UI plugin renders from the `session/event` feed (the assistant token stream as `assistant/chunk`, plus turn/step boundaries and tool activity), and drives input back in via `agent.followup()` / `agent.steer()`. A browser plugin contributing a business row to the built-in Web Client instead registers a `ConversationNodeDefinition` and keyed Chat renderer; follow the [Conversation Node guide](adding-a-conversation-node.md). ```ts -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { createUserMessage } from '@deepseek-ai/dsh-llm' import { SessionId } from '@deepseek-ai/dsh-session' @@ -67,7 +67,7 @@ A *protocol driver* adapts a wire peer to `ctx.agents`; it may serve a UI or an [`packages/acp/acp`](../../packages/acp/acp) is the automation-only worked example: it exposes fresh text sessions over Agent Client Protocol JSON-RPC stdio, emits committed assistant text, and registers a one-shot machine permission answerer for agents it owns. Its [README](../../packages/acp/acp/README.md) defines the exact methods, event order, and lifecycle contract. ```ts -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' export const name = 'my-protocol-bridge' export const inject = ['agents', 'sessions', 'sessionPersistence'] diff --git a/docs/cookbook/extension-cookbook.zh.md b/docs/cookbook/extension-cookbook.zh.md index e3fbe09f1e..0623c49d9d 100644 --- a/docs/cookbook/extension-cookbook.zh.md +++ b/docs/cookbook/extension-cookbook.zh.md @@ -13,7 +13,7 @@ harness 扩展的参考模式。代码片段省略了 import 和辅助实现, 这个权限门禁是钩子插件的一个示例。它从 `tools/pre-execute` 门禁返回一个类型化的决策,用于允许或拒绝一次调用;沙箱、权限和 plan-mode 插件都可以使用该扩展点。钩子插件也可以拦截其他扩展点,本身并不等同于权限门禁。「原生钩子」是在拦截点上运行的普通 Cordis 插件,不需要外部协议。 ```ts -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { PreToolDecision, ToolExecution } from '@deepseek-ai/dsh-tools' declare function isAllowed(exec: ToolExecution): Promise @@ -37,7 +37,7 @@ export function apply(ctx: Context) { UI 插件从 `session/event` 事件流渲染(助手 token 流以 `assistant/chunk` 形式到达,加上轮次/步骤边界与工具活动),并通过 `agent.followup()` / `agent.steer()` 将输入驱动回去。如果浏览器插件要向内建 Web Client 贡献业务行,则应注册 `ConversationNodeDefinition` 与 keyed Chat renderer;具体步骤见 [Conversation Node 指南](adding-a-conversation-node.md)。 ```ts -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { createUserMessage } from '@deepseek-ai/dsh-llm' import { SessionId } from '@deepseek-ai/dsh-session' @@ -67,7 +67,7 @@ export function apply(ctx: Context) { [`packages/acp/acp`](../../packages/acp/acp) 是仅面向自动化的完整示例:它通过 ACP(Agent Client Protocol)JSON-RPC stdio 提供全新文本会话,发出已提交的助手文本,并为其拥有的 agent 注册一次性机器权限应答器。其 [README](../../packages/acp/acp/README.md) 定义确切的方法、事件顺序和生命周期约定。 ```ts -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' export const name = 'my-protocol-bridge' export const inject = ['agents', 'sessions', 'sessionPersistence'] diff --git a/docs/cordis-primer.i18n.yaml b/docs/cordis-primer.i18n.yaml index 12177e3d35..ad9cfe716e 100644 --- a/docs/cordis-primer.i18n.yaml +++ b/docs/cordis-primer.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write docs/cordis-primer.md -cordis-primer.md: c95909a4a1deab9407efedbb990ef13be6e43a16 -cordis-primer.zh.md: a18b8b37af19a610b71babbe5e67f96bb09e81b1 +cordis-primer.md: 93725949a9490f757edebcf3e8391db9e73321b1 +cordis-primer.zh.md: fd2a327b526b210986bc1574013fca2c0cec5dda diff --git a/docs/cordis-primer.md b/docs/cordis-primer.md index c95909a4a1..93725949a9 100644 --- a/docs/cordis-primer.md +++ b/docs/cordis-primer.md @@ -35,7 +35,7 @@ For single-decision events, short-circuiting is the design. A policy listener ca ## Loader Configuration -`@cordisjs/plugin-include` parses `!!js` into expression nodes, but the Loader interpolates only an entry's `config` before mounting the plugin. Entry metadata (`id`, `name`, `group`, `disabled`, `inject`, `intercept`, and `isolate`) remains literal; `disabled: !!js ...` is therefore a truthy object that always disables the entry. Use explicit config overlays when environment selection changes which plugins are mounted. +`@deepseek-ai/cordis-plugin-include` parses `!!js` into expression nodes, but the Loader interpolates only an entry's `config` before mounting the plugin. Entry metadata (`id`, `name`, `group`, `disabled`, `inject`, `intercept`, and `isolate`) remains literal; `disabled: !!js ...` is therefore a truthy object that always disables the entry. Use explicit config overlays when environment selection changes which plugins are mounted. ## Practical Rules diff --git a/docs/cordis-primer.zh.md b/docs/cordis-primer.zh.md index a18b8b37af..fd2a327b52 100644 --- a/docs/cordis-primer.zh.md +++ b/docs/cordis-primer.zh.md @@ -39,7 +39,7 @@ Cordis 是 DeepSeek Harness SDK 底层以 vendor 方式引入的插件框架。 ## Loader 配置 -`@cordisjs/plugin-include` 将 `!!js` 解析为表达式节点,但 Loader 仅在挂载插件前对条目的 `config` 做插值。条目元数据(`id`、`name`、`group`、`disabled`、`inject`、`intercept` 和 `isolate`)保持字面值;因此 `disabled: !!js ...` 是一个 truthy 对象,会始终禁用该条目。需要根据环境选择挂载哪些插件时,请使用显式的配置覆盖层。 +`@deepseek-ai/cordis-plugin-include` 将 `!!js` 解析为表达式节点,但 Loader 仅在挂载插件前对条目的 `config` 做插值。条目元数据(`id`、`name`、`group`、`disabled`、`inject`、`intercept` 和 `isolate`)保持字面值;因此 `disabled: !!js ...` 是一个 truthy 对象,会始终禁用该条目。需要根据环境选择挂载哪些插件时,请使用显式的配置覆盖层。 ## 实践规则 diff --git a/docs/cordis-tutorial/01-first-plugin.i18n.yaml b/docs/cordis-tutorial/01-first-plugin.i18n.yaml index 9bf649ab29..2ac502e501 100644 --- a/docs/cordis-tutorial/01-first-plugin.i18n.yaml +++ b/docs/cordis-tutorial/01-first-plugin.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write docs/cordis-tutorial/01-first-plugin.md -01-first-plugin.md: 260026329443f9a5b8860d11a6527dbd687eb44c -01-first-plugin.zh.md: 69dedb898c7ea29f99233f07126cd413fa0ddbe2 +01-first-plugin.md: 448034b54107d5620673052ad388feecc22fe1e1 +01-first-plugin.zh.md: a1838be61f8099831d59afa266fe40ce6bd165bf diff --git a/docs/cordis-tutorial/01-first-plugin.md b/docs/cordis-tutorial/01-first-plugin.md index 2600263294..448034b541 100644 --- a/docs/cordis-tutorial/01-first-plugin.md +++ b/docs/cordis-tutorial/01-first-plugin.md @@ -9,7 +9,7 @@ In the loader configuration used here, a Cordis plugin module named-exports an ` In your `tmp/cordis-tutorial` directory (see [setup](index.md#setup)), create `hello.ts`: ```ts -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' export const name = 'hello' @@ -55,7 +55,7 @@ There is no framework bootstrap code in your file: a plugin describes what it co A function is the most common form, but Cordis accepts three: ```ts -import { Service, type Context } from 'cordis' +import { Service, type Context } from '@deepseek-ai/cordis' // 1. Function plugin (what you just wrote). export function apply(ctx: Context) {} diff --git a/docs/cordis-tutorial/01-first-plugin.zh.md b/docs/cordis-tutorial/01-first-plugin.zh.md index 69dedb898c..a1838be61f 100644 --- a/docs/cordis-tutorial/01-first-plugin.zh.md +++ b/docs/cordis-tutorial/01-first-plugin.zh.md @@ -9,7 +9,7 @@ 在 `tmp/cordis-tutorial` 目录中(参见[环境设置](index.md#setup))创建 `hello.ts`: ```ts -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' export const name = 'hello' @@ -55,7 +55,7 @@ hello from my first plugin 函数是最常见的形式,但 Cordis 接受三种形式: ```ts -import { Service, type Context } from 'cordis' +import { Service, type Context } from '@deepseek-ai/cordis' // 1. Function plugin (what you just wrote). export function apply(ctx: Context) {} diff --git a/docs/cordis-tutorial/02-lifecycle-and-effects.i18n.yaml b/docs/cordis-tutorial/02-lifecycle-and-effects.i18n.yaml index 12793267e2..f97516c457 100644 --- a/docs/cordis-tutorial/02-lifecycle-and-effects.i18n.yaml +++ b/docs/cordis-tutorial/02-lifecycle-and-effects.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write docs/cordis-tutorial/02-lifecycle-and-effects.md -02-lifecycle-and-effects.md: 7b195b63a1e8730f27b9dd9af8af6a68a588cee9 -02-lifecycle-and-effects.zh.md: 4a3f83dedd5c95c7fcb5c1aebbbb8cb2e849b9cf +02-lifecycle-and-effects.md: 3e88c6f1e1fb1bc825fb74434520993c855010c3 +02-lifecycle-and-effects.zh.md: 3cceecfb8334f2ed2ec9942fa876a0e51e1b315f diff --git a/docs/cordis-tutorial/02-lifecycle-and-effects.md b/docs/cordis-tutorial/02-lifecycle-and-effects.md index 7b195b63a1..3e88c6f1e1 100644 --- a/docs/cordis-tutorial/02-lifecycle-and-effects.md +++ b/docs/cordis-tutorial/02-lifecycle-and-effects.md @@ -11,7 +11,7 @@ For a resource Cordis does not already manage — a timer, a connection, a watch Create `lifecycle.ts` in `tmp/cordis-tutorial`: ```ts -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' export const name = 'lifecycle-demo' diff --git a/docs/cordis-tutorial/02-lifecycle-and-effects.zh.md b/docs/cordis-tutorial/02-lifecycle-and-effects.zh.md index 4a3f83dedd..3cceecfb83 100644 --- a/docs/cordis-tutorial/02-lifecycle-and-effects.zh.md +++ b/docs/cordis-tutorial/02-lifecycle-and-effects.zh.md @@ -11,7 +11,7 @@ Cordis 插件可能因修改配置、热重载、显式资源释放或所需服 创建 `lifecycle.ts`,将它放在 `tmp/cordis-tutorial` 中: ```ts -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' export const name = 'lifecycle-demo' diff --git a/docs/cordis-tutorial/03-services.i18n.yaml b/docs/cordis-tutorial/03-services.i18n.yaml index bdb7e19387..0d5f9dfccb 100644 --- a/docs/cordis-tutorial/03-services.i18n.yaml +++ b/docs/cordis-tutorial/03-services.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write docs/cordis-tutorial/03-services.md -03-services.md: 82b08b7b8a2ec8a6b340dd1fdc7fa3de98cedff9 -03-services.zh.md: ba4152454eb79a21b183b867c0ba2ef32cd43923 +03-services.md: 3f2273ba4061912640e409d7b4deb4cd1b45684f +03-services.zh.md: 657271aba6c0b2e824c79fa822e29c8a6dcf4275 diff --git a/docs/cordis-tutorial/03-services.md b/docs/cordis-tutorial/03-services.md index 82b08b7b8a..3f2273ba40 100644 --- a/docs/cordis-tutorial/03-services.md +++ b/docs/cordis-tutorial/03-services.md @@ -9,9 +9,9 @@ A **service** is a named capability one plugin provides and other plugins consum Create `greeter.ts` in `tmp/cordis-tutorial`: ```ts -import { Service, type Context } from 'cordis' +import { Service, type Context } from '@deepseek-ai/cordis' -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { greeter: GreeterService } @@ -37,7 +37,7 @@ export function apply(ctx: Context) { Two pieces work together: - **Runtime**: `super(ctx, 'greeter')` registers the instance under the name `greeter`. From then on, any plugin can reach it as `ctx.greeter`. The registration is an effect — unloading the provider removes the service. -- **Compile time**: the `declare module 'cordis'` block is TypeScript declaration merging. It adds `greeter` to the `Context` interface so `ctx.greeter` typechecks everywhere. It generates no code; without it the service still works at runtime, but consumers lose type safety. +- **Compile time**: the `declare module '@deepseek-ai/cordis'` block is TypeScript declaration merging. It adds `greeter` to the `Context` interface so `ctx.greeter` typechecks everywhere. It generates no code; without it the service still works at runtime, but consumers lose type safety. A `Service` subclass is itself a plugin (the class form from chapter 1), so `ctx.plugin(GreeterService)` mounts it like any other. @@ -46,7 +46,7 @@ A `Service` subclass is itself a plugin (the class form from chapter 1), so `ctx Create `consumer.ts`: ```ts -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' export const name = 'consumer' export const inject = ['greeter'] diff --git a/docs/cordis-tutorial/03-services.zh.md b/docs/cordis-tutorial/03-services.zh.md index ba4152454e..657271aba6 100644 --- a/docs/cordis-tutorial/03-services.zh.md +++ b/docs/cordis-tutorial/03-services.zh.md @@ -9,9 +9,9 @@ 创建 `greeter.ts`,将它放在 `tmp/cordis-tutorial` 中: ```ts -import { Service, type Context } from 'cordis' +import { Service, type Context } from '@deepseek-ai/cordis' -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { greeter: GreeterService } @@ -37,7 +37,7 @@ export function apply(ctx: Context) { 两部分协同工作: - **运行时**:`super(ctx, 'greeter')` 以名称 `greeter` 注册该实例。此后,任何插件都可以通过 `ctx.greeter` 访问它。注册属于 effect,卸载提供方时会移除该服务。 -- **编译时**:`declare module 'cordis'` 块使用 TypeScript 声明合并,把 `greeter` 加入 `Context` 接口,使 `ctx.greeter` 在各处都能通过类型检查。它不会生成代码;没有该声明时,服务在运行时仍能工作,但消费方会失去类型安全。 +- **编译时**:`declare module '@deepseek-ai/cordis'` 块使用 TypeScript 声明合并,把 `greeter` 加入 `Context` 接口,使 `ctx.greeter` 在各处都能通过类型检查。它不会生成代码;没有该声明时,服务在运行时仍能工作,但消费方会失去类型安全。 `Service` 子类本身就是插件(第 1 章介绍的类形态),因此 `ctx.plugin(GreeterService)` 会像挂载其他插件一样挂载它。 @@ -46,7 +46,7 @@ export function apply(ctx: Context) { 创建 `consumer.ts`: ```ts -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' export const name = 'consumer' export const inject = ['greeter'] diff --git a/docs/cordis-tutorial/04-events.i18n.yaml b/docs/cordis-tutorial/04-events.i18n.yaml index b453ffb1f6..0f86242ecd 100644 --- a/docs/cordis-tutorial/04-events.i18n.yaml +++ b/docs/cordis-tutorial/04-events.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write docs/cordis-tutorial/04-events.md -04-events.md: e77641dffcb82fcb50a24ca2e3e764d152218094 -04-events.zh.md: 00cce854e9a54fddb594ffa8e306f60a725ac012 +04-events.md: 0302adf7c81b802b406f5f6737539ccf3eb970f9 +04-events.zh.md: ae41e757c06a46ef70c250c94a124546769e0112 diff --git a/docs/cordis-tutorial/04-events.md b/docs/cordis-tutorial/04-events.md index e77641dffc..0302adf7c8 100644 --- a/docs/cordis-tutorial/04-events.md +++ b/docs/cordis-tutorial/04-events.md @@ -9,9 +9,9 @@ Services support direct calls; **events** let a plugin announce something withou Create `stats.ts` in `tmp/cordis-tutorial` — a service that counts things and announces each change: ```ts -import { Service, type Context } from 'cordis' +import { Service, type Context } from '@deepseek-ai/cordis' -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { stats: StatsService } @@ -46,7 +46,7 @@ The `interface Events` merge is the event-system twin of the `interface Context` Create `reporter.ts`: ```ts ignore-check -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type {} from './stats.ts' export const name = 'reporter' @@ -96,9 +96,9 @@ Every harness event documents its mode in the generated reference on its owning Waterfall is the mode that powers interception. Each listener receives the arguments plus a `next()` continuation; it can transform what `next()` returns, or return without calling `next()` and short-circuit the rest of the chain — what the Cordis docs call the veto. Create `waterfall-demo.ts`: ```ts -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Events { 'demo/transform'(input: string, next: () => Promise): Promise } diff --git a/docs/cordis-tutorial/04-events.zh.md b/docs/cordis-tutorial/04-events.zh.md index 00cce854e9..ae41e757c0 100644 --- a/docs/cordis-tutorial/04-events.zh.md +++ b/docs/cordis-tutorial/04-events.zh.md @@ -9,9 +9,9 @@ 创建 `stats.ts`,将它放在 `tmp/cordis-tutorial` 中。它是一项负责计数并在每次变化时发出通知的服务: ```ts -import { Service, type Context } from 'cordis' +import { Service, type Context } from '@deepseek-ai/cordis' -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { stats: StatsService } @@ -46,7 +46,7 @@ export function apply(ctx: Context) { 创建 `reporter.ts`: ```ts ignore-check -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type {} from './stats.ts' export const name = 'reporter' @@ -96,9 +96,9 @@ export function apply(ctx: Context) { waterfall 是实现拦截的模式。每个监听器都会收到参数和一个 `next()` continuation;它可以转换 `next()` 的返回值,也可以不调用 `next()` 就直接返回,从而短路链条的其余部分。Cordis 文档把后一种行为称为否决。创建 `waterfall-demo.ts`: ```ts -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Events { 'demo/transform'(input: string, next: () => Promise): Promise } diff --git a/docs/cordis-tutorial/05-config.i18n.yaml b/docs/cordis-tutorial/05-config.i18n.yaml index 7db45165c4..08493c67af 100644 --- a/docs/cordis-tutorial/05-config.i18n.yaml +++ b/docs/cordis-tutorial/05-config.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write docs/cordis-tutorial/05-config.md -05-config.md: 834bb140cc1ff976acc8f21c8f54a7fb02636eac -05-config.zh.md: f5cc6ac1ca4fa02eba6a1b015b9f6ae3b1a925fc +05-config.md: ad73a732242e4015b2976e6fb193ff464e148dfa +05-config.zh.md: edb3c4113288dfa80e899fb2e5eb21a67d929ca6 diff --git a/docs/cordis-tutorial/05-config.md b/docs/cordis-tutorial/05-config.md index 834bb140cc..ad73a73224 100644 --- a/docs/cordis-tutorial/05-config.md +++ b/docs/cordis-tutorial/05-config.md @@ -9,8 +9,8 @@ Each `cordis.yml` entry can carry a `config` block, and the plugin declares a sc Create `config-demo.ts` in `tmp/cordis-tutorial`: ```ts -import type { Context } from 'cordis' -import Schema from 'schemastery' +import type { Context } from '@deepseek-ai/cordis' +import Schema from '@deepseek-ai/schemastery' export const name = 'config-demo' diff --git a/docs/cordis-tutorial/05-config.zh.md b/docs/cordis-tutorial/05-config.zh.md index f5cc6ac1ca..edb3c41132 100644 --- a/docs/cordis-tutorial/05-config.zh.md +++ b/docs/cordis-tutorial/05-config.zh.md @@ -9,8 +9,8 @@ 创建 `config-demo.ts`,并将其放在 `tmp/cordis-tutorial` 中: ```ts -import type { Context } from 'cordis' -import Schema from 'schemastery' +import type { Context } from '@deepseek-ai/cordis' +import Schema from '@deepseek-ai/schemastery' export const name = 'config-demo' diff --git a/docs/cordis-tutorial/06-composition-and-hmr.i18n.yaml b/docs/cordis-tutorial/06-composition-and-hmr.i18n.yaml index 3732651e58..a75d53e7dd 100644 --- a/docs/cordis-tutorial/06-composition-and-hmr.i18n.yaml +++ b/docs/cordis-tutorial/06-composition-and-hmr.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write docs/cordis-tutorial/06-composition-and-hmr.md -06-composition-and-hmr.md: a169d7a164be63c939e352e4e5b0bf9bce43da29 -06-composition-and-hmr.zh.md: 07ae46555c390d625a4397933e2ec5ac059bd270 +06-composition-and-hmr.md: 490e3de3a98dd823190deefd47e1b6f2f8ba71b5 +06-composition-and-hmr.zh.md: 4aefb5ecd036929590ab373a2883d90779997b4b diff --git a/docs/cordis-tutorial/06-composition-and-hmr.md b/docs/cordis-tutorial/06-composition-and-hmr.md index a169d7a164..490e3de3a9 100644 --- a/docs/cordis-tutorial/06-composition-and-hmr.md +++ b/docs/cordis-tutorial/06-composition-and-hmr.md @@ -22,24 +22,24 @@ Groups nest a sub-list of entries that load and unload as one unit, and `isolate ## Hot module replacement -Because unloading releases effects ([chapter 2](02-lifecycle-and-effects.md)) and loading follows dependencies ([chapter 3](03-services.md)), HMR can replace a running plugin by unloading and loading it. The `@cordisjs/plugin-hmr` plugin watches your files and does exactly that on save. +Because unloading releases effects ([chapter 2](02-lifecycle-and-effects.md)) and loading follows dependencies ([chapter 3](03-services.md)), HMR can replace a running plugin by unloading and loading it. The `@deepseek-ai/cordis-plugin-hmr` plugin watches your files and does exactly that on save. In `tmp/cordis-tutorial`, write `cordis.yml`: ```yaml - id: logger - name: '@cordisjs/plugin-logger-console' + name: '@deepseek-ai/cordis-plugin-logger-console' - id: timer - name: '@cordisjs/plugin-timer' + name: '@deepseek-ai/cordis-plugin-timer' - id: hmr - name: '@cordisjs/plugin-hmr' + name: '@deepseek-ai/cordis-plugin-hmr' config: root: ['.'] - id: hello name: './hello.ts' ``` -Two support plugins joined the list: HMR logs through the Cordis logger service, so without a console exporter you would not see its messages, and it `inject`s the `timer` service for debouncing — without `@cordisjs/plugin-timer` it sits in PENDING forever, silently. That silence is the subject of the next section. +Two support plugins joined the list: HMR logs through the Cordis logger service, so without a console exporter you would not see its messages, and it `inject`s the `timer` service for debouncing — without `@deepseek-ai/cordis-plugin-timer` it sits in PENDING forever, silently. That silence is the subject of the next section. HMR reads Node's loader internals through the Loader's native helper. Run Cordis under tsx: @@ -65,7 +65,7 @@ The flip side of dependency-driven loading: a plugin whose `inject` names a serv You can see the states directly. Every context can enumerate the plugin registry; create `diagnose.ts`: ```ts -import { FiberState, type Context } from 'cordis' +import { FiberState, type Context } from '@deepseek-ai/cordis' export const name = 'diagnose' @@ -85,7 +85,7 @@ export function apply(ctx: Context) { And a plugin with an unsatisfiable dependency, `needs-timer.ts`: ```ts -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' export const name = 'needs-timer' export const inject = ['timer'] @@ -106,7 +106,7 @@ Run it (plain `node --import tsx ../../vendor/cordis/bin.js`; stop with Ctrl-C): needs-timer is PENDING — a required service is missing ``` -`inject: ['timer']` has no provider. Add `- name: '@cordisjs/plugin-timer'` to the list and the plugin loads. When a plugin does nothing and reports nothing, inspect its fiber state. Iterating without the PENDING filter also shows the loader's own plugins (Loader, Include) as ACTIVE fibers because plugins mount the config file itself. +`inject: ['timer']` has no provider. Add `- name: '@deepseek-ai/cordis-plugin-timer'` to the list and the plugin loads. When a plugin does nothing and reports nothing, inspect its fiber state. Iterating without the PENDING filter also shows the loader's own plugins (Loader, Include) as ACTIVE fibers because plugins mount the config file itself. Next: [Into the harness](07-into-the-harness.md) — the same patterns against real harness services. diff --git a/docs/cordis-tutorial/06-composition-and-hmr.zh.md b/docs/cordis-tutorial/06-composition-and-hmr.zh.md index 07ae46555c..4aefb5ecd0 100644 --- a/docs/cordis-tutorial/06-composition-and-hmr.zh.md +++ b/docs/cordis-tutorial/06-composition-and-hmr.zh.md @@ -22,24 +22,24 @@ Cordis 配置项除了 `name` 和 `config`,还接受其他元数据: ## 热模块替换 -卸载会释放 effect([第 2 章](02-lifecycle-and-effects.md)),加载则遵循依赖关系([第 3 章](03-services.md)),因此 HMR 可以先卸载、再加载,以替换正在运行的插件。`@cordisjs/plugin-hmr` 插件会监视文件,并在保存时执行这一过程。 +卸载会释放 effect([第 2 章](02-lifecycle-and-effects.md)),加载则遵循依赖关系([第 3 章](03-services.md)),因此 HMR 可以先卸载、再加载,以替换正在运行的插件。`@deepseek-ai/cordis-plugin-hmr` 插件会监视文件,并在保存时执行这一过程。 在 `tmp/cordis-tutorial` 中编写 `cordis.yml`: ```yaml - id: logger - name: '@cordisjs/plugin-logger-console' + name: '@deepseek-ai/cordis-plugin-logger-console' - id: timer - name: '@cordisjs/plugin-timer' + name: '@deepseek-ai/cordis-plugin-timer' - id: hmr - name: '@cordisjs/plugin-hmr' + name: '@deepseek-ai/cordis-plugin-hmr' config: root: ['.'] - id: hello name: './hello.ts' ``` -列表中增加了两个辅助插件:HMR 通过 Cordis logger 服务记录日志,因此没有控制台导出器时看不到其消息;它还会 `inject` `timer` 服务来实现去抖,如果没有 `@cordisjs/plugin-timer`,它就会永远停在 PENDING,而且不发出任何提示。下一节就讨论这种静默状态。 +列表中增加了两个辅助插件:HMR 通过 Cordis logger 服务记录日志,因此没有控制台导出器时看不到其消息;它还会 `inject` `timer` 服务来实现去抖,如果没有 `@deepseek-ai/cordis-plugin-timer`,它就会永远停在 PENDING,而且不发出任何提示。下一节就讨论这种静默状态。 HMR 通过 Loader 的原生辅助工具读取 Node 的 loader 内部结构。请在 tsx 下运行 Cordis: @@ -65,7 +65,7 @@ hello from my EDITED plugin 你可以直接查看这些状态。每个上下文都能枚举插件注册表;创建 `diagnose.ts`: ```ts -import { FiberState, type Context } from 'cordis' +import { FiberState, type Context } from '@deepseek-ai/cordis' export const name = 'diagnose' @@ -85,7 +85,7 @@ export function apply(ctx: Context) { 再创建一个依赖无法满足的插件 `needs-timer.ts`: ```ts -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' export const name = 'needs-timer' export const inject = ['timer'] @@ -106,7 +106,7 @@ export function apply(ctx: Context) { needs-timer is PENDING — a required service is missing ``` -`inject: ['timer']` 没有提供方。向列表添加 `- name: '@cordisjs/plugin-timer'` 后,插件就会加载。如果插件既不执行任何操作,也不报告任何内容,请检查其 fiber 状态。不加 PENDING 过滤条件进行迭代时,还会看到 loader 自身的插件(Loader、Include)处于 ACTIVE,因为配置文件本身也是通过插件挂载的。 +`inject: ['timer']` 没有提供方。向列表添加 `- name: '@deepseek-ai/cordis-plugin-timer'` 后,插件就会加载。如果插件既不执行任何操作,也不报告任何内容,请检查其 fiber 状态。不加 PENDING 过滤条件进行迭代时,还会看到 loader 自身的插件(Loader、Include)处于 ACTIVE,因为配置文件本身也是通过插件挂载的。 下一章:[进入 harness](07-into-the-harness.md):把相同模式用于真实的 harness 服务。 diff --git a/docs/cordis-tutorial/07-into-the-harness.i18n.yaml b/docs/cordis-tutorial/07-into-the-harness.i18n.yaml index 8fb1893fca..cc42357525 100644 --- a/docs/cordis-tutorial/07-into-the-harness.i18n.yaml +++ b/docs/cordis-tutorial/07-into-the-harness.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write docs/cordis-tutorial/07-into-the-harness.md -07-into-the-harness.md: 69133786f58541b015aed080f4ac8fb2a7e488c0 -07-into-the-harness.zh.md: bc9c61da984e3eb691eb6bfbe59ae556823e82de +07-into-the-harness.md: 41a30f032ac02d8e9e3b17ac8d9cd13e9973e36a +07-into-the-harness.zh.md: 159cede00d453796f6a2cacae184229d71e17f87 diff --git a/docs/cordis-tutorial/07-into-the-harness.md b/docs/cordis-tutorial/07-into-the-harness.md index 69133786f5..41a30f032a 100644 --- a/docs/cordis-tutorial/07-into-the-harness.md +++ b/docs/cordis-tutorial/07-into-the-harness.md @@ -9,7 +9,7 @@ This chapter registers a model-callable tool with the harness's `tools` service, Create `greet-tool.ts` in `tmp/cordis-tutorial`: ```ts -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { defineTool } from '@deepseek-ai/dsh-tools' import { CallId } from '@deepseek-ai/dsh-llm' @@ -53,7 +53,7 @@ Every pattern here is from the earlier chapters: `inject: ['tools']` ([chapter 3 Create `tool-logger.ts` — a separate plugin that watches every tool call in the app through the harness's `tools/result` event: ```ts -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type {} from '@deepseek-ai/dsh-tools' export const name = 'tool-logger' diff --git a/docs/cordis-tutorial/07-into-the-harness.zh.md b/docs/cordis-tutorial/07-into-the-harness.zh.md index bc9c61da98..159cede00d 100644 --- a/docs/cordis-tutorial/07-into-the-harness.zh.md +++ b/docs/cordis-tutorial/07-into-the-harness.zh.md @@ -9,7 +9,7 @@ 创建 `greet-tool.ts`,将它放在 `tmp/cordis-tutorial` 中: ```ts -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { defineTool } from '@deepseek-ai/dsh-tools' import { CallId } from '@deepseek-ai/dsh-llm' @@ -53,7 +53,7 @@ export function apply(ctx: Context) { 创建 `tool-logger.ts`。这是一个独立插件,通过 harness 的 `tools/result` 事件观察应用中的每次工具调用: ```ts -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type {} from '@deepseek-ai/dsh-tools' export const name = 'tool-logger' diff --git a/docs/cordis-tutorial/index.i18n.yaml b/docs/cordis-tutorial/index.i18n.yaml index 719e949ffe..234d911a10 100644 --- a/docs/cordis-tutorial/index.i18n.yaml +++ b/docs/cordis-tutorial/index.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write docs/cordis-tutorial/index.md -index.md: 307c12854b3075cfd4dd5ea8a19806c58b4e998d -index.zh.md: a0107b7d15272e6ef8d526b9c0e03a99275644d6 +index.md: cf61fec07acd2022591cd858ba4146b6a4ae1a3d +index.zh.md: 775bf2fce2138b9edd91f5ee46b93b8c4eb4559e diff --git a/docs/cordis-tutorial/index.md b/docs/cordis-tutorial/index.md index 307c12854b..cf61fec07a 100644 --- a/docs/cordis-tutorial/index.md +++ b/docs/cordis-tutorial/index.md @@ -50,8 +50,8 @@ That one-file launcher (see [vendor/cordis/bin.js](../../vendor/cordis/bin.js)) The examples use three TypeScript features beyond ordinary modern JavaScript: - **Type annotations** describe values without changing runtime behavior: `ctx: Context` says that `ctx` has the Cordis context API, `who: string` accepts text, and `string[]` means an array of strings. -- **`import type { Context } from 'cordis'`** imports only type information. It vanishes at runtime, so a plugin file that needs `Context` solely for annotations adds no runtime dependency. -- **Declaration merging** (`declare module 'cordis' { ... }`) adds your entries to interfaces that Cordis already declares — for example the type of a new `ctx.greeter` property or event name. It generates no runtime wiring; the plugin separately provides the service or emits the event. Chapter 3 shows the pattern in full. +- **`import type { Context } from '@deepseek-ai/cordis'`** imports only type information. It vanishes at runtime, so a plugin file that needs `Context` solely for annotations adds no runtime dependency. +- **Declaration merging** (`declare module '@deepseek-ai/cordis' { ... }`) adds your entries to interfaces that Cordis already declares — for example the type of a new `ctx.greeter` property or event name. It generates no runtime wiring; the plugin separately provides the service or emits the event. Chapter 3 shows the pattern in full. Chapter 5 also uses an `interface` to describe a configuration object's fields and a generic type such as `Schema` to say which object fields a schema validates. You can copy those declarations as shown; the surrounding text explains what each one connects. diff --git a/docs/cordis-tutorial/index.zh.md b/docs/cordis-tutorial/index.zh.md index a0107b7d15..775bf2fce2 100644 --- a/docs/cordis-tutorial/index.zh.md +++ b/docs/cordis-tutorial/index.zh.md @@ -50,8 +50,8 @@ node --import tsx ../../vendor/cordis/bin.js 这些示例使用了普通现代 JavaScript 之外的三项 TypeScript 功能: - **类型注解** 描述值,但不会改变运行时行为:`ctx: Context` 表示 `ctx` 具备 Cordis 上下文 API,`who: string` 接受文本,而 `string[]` 表示字符串数组。 -- **`import type { Context } from 'cordis'`** 只导入类型信息。它在运行时会消失,因此仅为类型注解使用 `Context` 的插件文件不会增加运行时依赖。 -- **声明合并**(`declare module 'cordis' { ... }`)会为 Cordis 已经声明的接口添加你的条目,例如新 `ctx.greeter` 属性的类型或事件名称。它不会生成任何运行时接线;插件必须另行提供服务或发出事件。第 3 章会完整展示该模式。 +- **`import type { Context } from '@deepseek-ai/cordis'`** 只导入类型信息。它在运行时会消失,因此仅为类型注解使用 `Context` 的插件文件不会增加运行时依赖。 +- **声明合并**(`declare module '@deepseek-ai/cordis' { ... }`)会为 Cordis 已经声明的接口添加你的条目,例如新 `ctx.greeter` 属性的类型或事件名称。它不会生成任何运行时接线;插件必须另行提供服务或发出事件。第 3 章会完整展示该模式。 第 5 章还会使用 `interface` 描述配置对象的字段,并使用 `Schema` 这类泛型表示 schema 校验哪些对象字段。你可以直接照写这些声明;周围的正文会解释每项声明连接了什么。 diff --git a/docs/user/develop/basic/config.i18n.yaml b/docs/user/develop/basic/config.i18n.yaml index 2887d77209..b367fbb82e 100644 --- a/docs/user/develop/basic/config.i18n.yaml +++ b/docs/user/develop/basic/config.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write docs/user/develop/basic/config.md -config.md: 02998c32415b5ba7acf82700034cabc1f7314f33 -config.zh.md: 161af5d6703b4cc77d63443a5a80846593d1c7fd +config.md: 21ba39fd7de1795e9139aff3e2b11743eedd4833 +config.zh.md: a882c4d59b0ac8e8ec27a5b32da5376b534a7f62 diff --git a/docs/user/develop/basic/config.md b/docs/user/develop/basic/config.md index 02998c3241..21ba39fd7d 100644 --- a/docs/user/develop/basic/config.md +++ b/docs/user/develop/basic/config.md @@ -9,8 +9,8 @@ Accept configuration supplied through `cordis.yml`. Export a `Config` type and a same-named Schemastery schema. Put defaults directly on the schema fields: ```ts -import type { Context } from 'cordis' -import Schema from 'schemastery' +import type { Context } from '@deepseek-ai/cordis' +import Schema from '@deepseek-ai/schemastery' export const name = 'my-plugin' @@ -49,8 +49,8 @@ When loading the plugin, Cordis uses the exported schema to validate configurati Use Schemastery to express stricter validation: ```ts -import type { Context } from 'cordis' -import Schema from 'schemastery' +import type { Context } from '@deepseek-ai/cordis' +import Schema from '@deepseek-ai/schemastery' export const name = 'validated-plugin' diff --git a/docs/user/develop/basic/config.zh.md b/docs/user/develop/basic/config.zh.md index 161af5d670..a882c4d59b 100644 --- a/docs/user/develop/basic/config.zh.md +++ b/docs/user/develop/basic/config.zh.md @@ -9,8 +9,8 @@ 在插件中导出一个 `Config` 类型和同名的 Schemastery schema;默认值直接写在 schema 中: ```ts -import type { Context } from 'cordis' -import Schema from 'schemastery' +import type { Context } from '@deepseek-ai/cordis' +import Schema from '@deepseek-ai/schemastery' export const name = 'my-plugin' @@ -49,8 +49,8 @@ export function apply(ctx: Context, config: Config) { 对于需要严格校验的场景,使用 Schemastery 定义 schema: ```ts -import type { Context } from 'cordis' -import Schema from 'schemastery' +import type { Context } from '@deepseek-ai/cordis' +import Schema from '@deepseek-ai/schemastery' export const name = 'validated-plugin' diff --git a/docs/user/develop/basic/index.i18n.yaml b/docs/user/develop/basic/index.i18n.yaml index 0d89e9622e..bb4870f624 100644 --- a/docs/user/develop/basic/index.i18n.yaml +++ b/docs/user/develop/basic/index.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write docs/user/develop/basic/index.md -index.md: 7fe66bb19ddb978a4b5a96768b62151b97bca0ec -index.zh.md: 59f4e5b58b6cf1fbc15de8fafb5f4b0db2e220d6 +index.md: fe525018011809abe4dd18ac5739c54cd330c8f6 +index.zh.md: 0dbb7275be3c7147395041fb18d49a7f6ea69cdd diff --git a/docs/user/develop/basic/index.md b/docs/user/develop/basic/index.md index 7fe66bb19d..fe52501801 100644 --- a/docs/user/develop/basic/index.md +++ b/docs/user/develop/basic/index.md @@ -17,7 +17,7 @@ mkdir -p scratch-plugin/src In Harness, a plugin is a TypeScript module that exports an `apply` function. The framework calls `apply` when loading the plugin and passes a `ctx` context object through which the plugin registers capabilities: ```ts -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' export const name = 'my-plugin' @@ -33,7 +33,7 @@ That is the complete configuration. Create `scratch-plugin/src/my-plugin.ts`: ```ts -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' export const name = 'hello-plugin' @@ -68,7 +68,7 @@ Anything registered through `ctx`—event listeners, tools, or timers—is clean For a resource that needs explicit cleanup, such as a network connection, use `ctx.effect()` to provide its disposer: ```ts -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' export function apply(ctx: Context) { ctx.effect(() => { @@ -87,7 +87,7 @@ export function apply(ctx: Context) { If the plugin consumes another service such as `tools` or `llm`, declare it in `inject`: ```ts ignore-check -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' export const name = 'my-tool-plugin' export const inject = ['tools'] @@ -107,7 +107,7 @@ In addition to a function module, a plugin can use object or class form. ### Object form ```ts -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' export default { name: 'my-plugin', @@ -121,7 +121,7 @@ export default { ### Class form ```ts -import { Service, type Context } from 'cordis' +import { Service, type Context } from '@deepseek-ai/cordis' export default class MyService extends Service { static inject = ['tools'] diff --git a/docs/user/develop/basic/index.zh.md b/docs/user/develop/basic/index.zh.md index 59f4e5b58b..0dbb7275be 100644 --- a/docs/user/develop/basic/index.zh.md +++ b/docs/user/develop/basic/index.zh.md @@ -17,7 +17,7 @@ mkdir -p scratch-plugin/src 在 Harness 中,插件是一个导出 `apply` 函数的 TypeScript 模块。框架在加载时调用 `apply`,传入一个 `ctx`(上下文对象),你通过 `ctx` 注册能力: ```ts -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' export const name = 'my-plugin' @@ -33,7 +33,7 @@ export function apply(ctx: Context) { 创建 `scratch-plugin/src/my-plugin.ts`: ```ts -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' export const name = 'hello-plugin' @@ -68,7 +68,7 @@ pnpm run dsh web --patch ./scratch-plugin/cordis.yml 如果你有需要手动清理的资源(比如一个网络连接),用 `ctx.effect()` 告诉框架怎么清理: ```ts -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' export function apply(ctx: Context) { ctx.effect(() => { @@ -87,7 +87,7 @@ export function apply(ctx: Context) { 如果你的插件需要使用其他服务(如 `tools`、`llm`),需要声明 `inject`: ```ts ignore-check -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' export const name = 'my-tool-plugin' export const inject = ['tools'] @@ -107,7 +107,7 @@ export function apply(ctx: Context) { ### 对象形式 ```ts -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' export default { name: 'my-plugin', @@ -121,7 +121,7 @@ export default { ### 类形式 ```ts -import { Service, type Context } from 'cordis' +import { Service, type Context } from '@deepseek-ai/cordis' export default class MyService extends Service { static inject = ['tools'] diff --git a/docs/user/develop/basic/tool.i18n.yaml b/docs/user/develop/basic/tool.i18n.yaml index 594e2c2872..3ddc760f7d 100644 --- a/docs/user/develop/basic/tool.i18n.yaml +++ b/docs/user/develop/basic/tool.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write docs/user/develop/basic/tool.md -tool.md: ba2f3b1302ba31735d67be264f498a0395394d06 -tool.zh.md: 676f8fc996d752a05d94b55d4522e61e3b3e2161 +tool.md: f110bd2c10caf21ea8c87bc32fd43b01b209a9d1 +tool.zh.md: a237b6015de0ea6141a94c56aaa6f68c73fa3feb diff --git a/docs/user/develop/basic/tool.md b/docs/user/develop/basic/tool.md index ba2f3b1302..f110bd2c10 100644 --- a/docs/user/develop/basic/tool.md +++ b/docs/user/develop/basic/tool.md @@ -9,7 +9,7 @@ This tutorial adds a `greet` tool to the Web UI. Complete [Your first plugin](./ Replace `scratch-plugin/src/my-plugin.ts` with: ```ts -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { defineTool } from '@deepseek-ai/dsh-tools' export const name = 'greet-tool' diff --git a/docs/user/develop/basic/tool.zh.md b/docs/user/develop/basic/tool.zh.md index 676f8fc996..a237b6015d 100644 --- a/docs/user/develop/basic/tool.zh.md +++ b/docs/user/develop/basic/tool.zh.md @@ -9,7 +9,7 @@ 将 `scratch-plugin/src/my-plugin.ts` 替换为: ```ts -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { defineTool } from '@deepseek-ai/dsh-tools' export const name = 'greet-tool' diff --git a/docs/user/develop/framework/events.i18n.yaml b/docs/user/develop/framework/events.i18n.yaml index f39b04145d..ebc4dc7833 100644 --- a/docs/user/develop/framework/events.i18n.yaml +++ b/docs/user/develop/framework/events.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write docs/user/develop/framework/events.md -events.md: 8a8c076d9c7b40d73182db074c4f494fded8c6dd -events.zh.md: 9649d89d575a1b05fa524bd460043da71dc9ae43 +events.md: 4b5f9ee215186398ee5aee7a438f792f9b5a3639 +events.zh.md: b48c8020803239d3c9636f81052d3b70afa315f2 diff --git a/docs/user/develop/framework/events.md b/docs/user/develop/framework/events.md index 8a8c076d9c..4b5f9ee215 100644 --- a/docs/user/develop/framework/events.md +++ b/docs/user/develop/framework/events.md @@ -85,9 +85,9 @@ A waterfall listener **must call `next()`**. Omitting it short-circuits the pipe Harness uses TypeScript declaration merging for type-safe events: ```ts -import 'cordis' +import '@deepseek-ai/cordis' -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Events { 'my-plugin/ready': (payload: { id: string }) => void 'my-plugin/check': (input: string) => boolean | undefined @@ -121,7 +121,7 @@ export function apply(ctx: Context) { This plugin logs tool calls and results: ```ts -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import '@deepseek-ai/dsh-tools' export const name = 'tool-logger' diff --git a/docs/user/develop/framework/events.zh.md b/docs/user/develop/framework/events.zh.md index 9649d89d57..b48c802080 100644 --- a/docs/user/develop/framework/events.zh.md +++ b/docs/user/develop/framework/events.zh.md @@ -85,9 +85,9 @@ waterfall 监听器**必须调用 `next()`**。不调用 `next` 会短路整个 Harness 使用 TypeScript 声明合并来为事件提供类型安全: ```ts -import 'cordis' +import '@deepseek-ai/cordis' -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Events { 'my-plugin/ready': (payload: { id: string }) => void 'my-plugin/check': (input: string) => boolean | undefined @@ -121,7 +121,7 @@ export function apply(ctx: Context) { 这个插件记录工具调用和工具结果: ```ts -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import '@deepseek-ai/dsh-tools' export const name = 'tool-logger' diff --git a/docs/user/develop/framework/index.i18n.yaml b/docs/user/develop/framework/index.i18n.yaml index d06be13bdd..1c8dc3dae4 100644 --- a/docs/user/develop/framework/index.i18n.yaml +++ b/docs/user/develop/framework/index.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write docs/user/develop/framework/index.md -index.md: 79e925b54509da41535735527e283850384257ec -index.zh.md: 962677dc468c9cc233a51d50758247e028d9c3ed +index.md: 85701ce281d92da0c805b39291179df73eb65f51 +index.zh.md: 871aa55ef81a7dcbfe3cbde5986244220ee32f98 diff --git a/docs/user/develop/framework/index.md b/docs/user/develop/framework/index.md index 79e925b545..85701ce281 100644 --- a/docs/user/develop/framework/index.md +++ b/docs/user/develop/framework/index.md @@ -80,7 +80,7 @@ export function apply(ctx: Context) { To stop a plugin instance early: ```ts -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' declare const ctx: Context declare function myPlugin(ctx: Context): void @@ -98,7 +98,7 @@ await fiber.dispose() ## Hot replacement (HMR) -With `@cordisjs/plugin-hmr` loaded from `cordis.yml`, editing a plugin source file triggers: +With `@deepseek-ai/cordis-plugin-hmr` loaded from `cordis.yml`, editing a plugin source file triggers: 1. Unload the old plugin and clean up its registrations. 2. Load the new code. diff --git a/docs/user/develop/framework/index.zh.md b/docs/user/develop/framework/index.zh.md index 962677dc46..871aa55ef8 100644 --- a/docs/user/develop/framework/index.zh.md +++ b/docs/user/develop/framework/index.zh.md @@ -80,7 +80,7 @@ export function apply(ctx: Context) { 当你需要提前终止一个插件实例: ```ts -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' declare const ctx: Context declare function myPlugin(ctx: Context): void @@ -98,7 +98,7 @@ await fiber.dispose() ## HMR(热模块替换) -通过 `cordis.yml` 加载 `@cordisjs/plugin-hmr` 后,修改插件源文件会触发: +通过 `cordis.yml` 加载 `@deepseek-ai/cordis-plugin-hmr` 后,修改插件源文件会触发: 1. 卸载旧插件(清理所有注册) 2. 重新加载新代码 diff --git a/docs/user/develop/framework/service.i18n.yaml b/docs/user/develop/framework/service.i18n.yaml index 7cb2f4ff88..29151de351 100644 --- a/docs/user/develop/framework/service.i18n.yaml +++ b/docs/user/develop/framework/service.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write docs/user/develop/framework/service.md -service.md: 040b1388cc431c30045e05f7d372ab5885bb3f9d -service.zh.md: 0786b684c1688440a24cc729288835ad636f8ff7 +service.md: 3358f82ca5391741a7f531b7504de7335959ad03 +service.zh.md: 8fb4beeac43051c0f08483fe61e22c588127c360 diff --git a/docs/user/develop/framework/service.md b/docs/user/develop/framework/service.md index 040b1388cc..3358f82ca5 100644 --- a/docs/user/develop/framework/service.md +++ b/docs/user/develop/framework/service.md @@ -36,7 +36,7 @@ When `apply` runs, every service declared by `inject` is ready. If a service is ### Extend Service ```ts -import { Service, type Context } from 'cordis' +import { Service, type Context } from '@deepseek-ai/cordis' export default class MetricsService extends Service { static inject = ['llm'] // A service may depend on other services. @@ -67,9 +67,9 @@ export function apply(ctx: Context) { Use TypeScript declaration merging to type `ctx.metrics`: ```ts -import { Service, type Context } from 'cordis' +import { Service, type Context } from '@deepseek-ai/cordis' -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { metrics: MetricsService } @@ -114,7 +114,7 @@ This prevents a plugin from calling a service that no longer exists. ```yaml - id: group-a - name: '@cordisjs/plugin-group' + name: '@deepseek-ai/cordis-plugin-group' group: true isolate: bash: true @@ -125,7 +125,7 @@ This prevents a plugin from calling a service that no longer exists. - name: './src/plugin-a.ts' - id: group-b - name: '@cordisjs/plugin-group' + name: '@deepseek-ai/cordis-plugin-group' group: true isolate: bash: true diff --git a/docs/user/develop/framework/service.zh.md b/docs/user/develop/framework/service.zh.md index 0786b684c1..8fb4beeac4 100644 --- a/docs/user/develop/framework/service.zh.md +++ b/docs/user/develop/framework/service.zh.md @@ -36,7 +36,7 @@ export function apply(ctx: Context) { ### 使用 Service 基类 ```ts -import { Service, type Context } from 'cordis' +import { Service, type Context } from '@deepseek-ai/cordis' export default class MetricsService extends Service { static inject = ['llm'] // A service may depend on other services. @@ -67,9 +67,9 @@ export function apply(ctx: Context) { 使用 TypeScript 声明合并让 `ctx.metrics` 有正确类型: ```ts -import { Service, type Context } from 'cordis' +import { Service, type Context } from '@deepseek-ai/cordis' -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { metrics: MetricsService } @@ -114,7 +114,7 @@ export function apply(ctx: Context) { ```yaml - id: group-a - name: '@cordisjs/plugin-group' + name: '@deepseek-ai/cordis-plugin-group' group: true isolate: bash: true @@ -125,7 +125,7 @@ export function apply(ctx: Context) { - name: './src/plugin-a.ts' - id: group-b - name: '@cordisjs/plugin-group' + name: '@deepseek-ai/cordis-plugin-group' group: true isolate: bash: true diff --git a/docs/user/develop/practice/index.i18n.yaml b/docs/user/develop/practice/index.i18n.yaml index fc15dfeb2f..1bb86a5cbb 100644 --- a/docs/user/develop/practice/index.i18n.yaml +++ b/docs/user/develop/practice/index.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write docs/user/develop/practice/index.md -index.md: 1eb33e17ab6c5d0a2b37ff97d5948dfbcba497ca -index.zh.md: 31afa80407f81f571615b5ed68a9370775f5188f +index.md: 7ca9f0b1abe472dc90c6d4e56543e43b6d2ec727 +index.zh.md: 216b1cb01b355e411bf1949c59fd3720ae47139e diff --git a/docs/user/develop/practice/index.md b/docs/user/develop/practice/index.md index 1eb33e17ab..7ca9f0b1ab 100644 --- a/docs/user/develop/practice/index.md +++ b/docs/user/develop/practice/index.md @@ -61,9 +61,9 @@ The [capability-seam reference](../../../capability-seams.md) owns the current b ```ts ignore-check // packages/my-cap/my-cap/src/index.ts -import { Service, type Context } from 'cordis' +import { Service, type Context } from '@deepseek-ai/cordis' -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { myCap: MyCapService } @@ -91,7 +91,7 @@ export interface MyCapResult { ```ts ignore-check // packages/my-cap/my-cap-local/src/index.ts -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { MyCapService, type MyCapRequest, type MyCapResult } from '@deepseek-ai/dsh-my-cap' class MyCapLocal extends MyCapService { @@ -112,7 +112,7 @@ export function apply(ctx: Context) { ```ts ignore-check // packages/my-cap/tool-my-cap/src/index.ts -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { defineTool } from '@deepseek-ai/dsh-tools' export const name = 'tool-my-cap' diff --git a/docs/user/develop/practice/index.zh.md b/docs/user/develop/practice/index.zh.md index 31afa80407..216b1cb01b 100644 --- a/docs/user/develop/practice/index.zh.md +++ b/docs/user/develop/practice/index.zh.md @@ -61,9 +61,9 @@ ```ts ignore-check // packages/my-cap/my-cap/src/index.ts -import { Service, type Context } from 'cordis' +import { Service, type Context } from '@deepseek-ai/cordis' -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { myCap: MyCapService } @@ -91,7 +91,7 @@ export interface MyCapResult { ```ts ignore-check // packages/my-cap/my-cap-local/src/index.ts -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { MyCapService, type MyCapRequest, type MyCapResult } from '@deepseek-ai/dsh-my-cap' class MyCapLocal extends MyCapService { @@ -112,7 +112,7 @@ export function apply(ctx: Context) { ```ts ignore-check // packages/my-cap/tool-my-cap/src/index.ts -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { defineTool } from '@deepseek-ai/dsh-tools' export const name = 'tool-my-cap' diff --git a/docs/user/develop/practice/llm-adapter.i18n.yaml b/docs/user/develop/practice/llm-adapter.i18n.yaml index a7a745faaf..c8487899ec 100644 --- a/docs/user/develop/practice/llm-adapter.i18n.yaml +++ b/docs/user/develop/practice/llm-adapter.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write docs/user/develop/practice/llm-adapter.md -llm-adapter.md: 7445688530c1ba61e5c065f9f5e49db6498da5b1 -llm-adapter.zh.md: c726735ff2679584d1c061ef8acddc8981dadd26 +llm-adapter.md: aba4a6d0c8ee42e78ca5a804d9a0dd9b31c1e240 +llm-adapter.zh.md: dff9eef464599823d6cd99e83d668485109b2ec0 diff --git a/docs/user/develop/practice/llm-adapter.md b/docs/user/develop/practice/llm-adapter.md index 7445688530..aba4a6d0c8 100644 --- a/docs/user/develop/practice/llm-adapter.md +++ b/docs/user/develop/practice/llm-adapter.md @@ -11,8 +11,8 @@ An LLM adapter extends `LlmAdapter` and implements `stream()`, translating Harne ## Minimal implementation ```ts -import type { Context } from 'cordis' -import Schema from 'schemastery' +import type { Context } from '@deepseek-ai/cordis' +import Schema from '@deepseek-ai/schemastery' import { LlmAdapter, type GenerateOptions, type StreamChunk } from '@deepseek-ai/dsh-llm' class MyAdapter extends LlmAdapter { diff --git a/docs/user/develop/practice/llm-adapter.zh.md b/docs/user/develop/practice/llm-adapter.zh.md index c726735ff2..dff9eef464 100644 --- a/docs/user/develop/practice/llm-adapter.zh.md +++ b/docs/user/develop/practice/llm-adapter.zh.md @@ -11,8 +11,8 @@ LLM 适配器是一个继承 `LlmAdapter` 并实现 `stream()` 方法的类, ## 最小实现 ```ts -import type { Context } from 'cordis' -import Schema from 'schemastery' +import type { Context } from '@deepseek-ai/cordis' +import Schema from '@deepseek-ai/schemastery' import { LlmAdapter, type GenerateOptions, type StreamChunk } from '@deepseek-ai/dsh-llm' class MyAdapter extends LlmAdapter { diff --git a/examples/acp-agent/advanced.cordis.snapshot.yml b/examples/acp-agent/advanced.cordis.snapshot.yml index c89fdaf2a6..19d4a79fca 100644 --- a/examples/acp-agent/advanced.cordis.snapshot.yml +++ b/examples/acp-agent/advanced.cordis.snapshot.yml @@ -1,6 +1,6 @@ # Replay counterpart to advanced.cordis.yml; only the live model is replaced. - id: base - name: '@cordisjs/plugin-include' + name: '@deepseek-ai/cordis-plugin-include' config: path: ./cordis.yml patches: diff --git a/examples/acp-agent/advanced.cordis.yml b/examples/acp-agent/advanced.cordis.yml index aa20e1558d..1273d4f059 100644 --- a/examples/acp-agent/advanced.cordis.yml +++ b/examples/acp-agent/advanced.cordis.yml @@ -1,7 +1,7 @@ # Add Code Mode and Cordis tools to the base spawn/workflow stack, exercising # all four boundaries in one ACP snapshot. - id: base - name: '@cordisjs/plugin-include' + name: '@deepseek-ai/cordis-plugin-include' config: path: ./cordis.yml patches: diff --git a/examples/acp-agent/both-mode.cordis.snapshot.yml b/examples/acp-agent/both-mode.cordis.snapshot.yml index 84a286649a..8f2c92d62e 100644 --- a/examples/acp-agent/both-mode.cordis.snapshot.yml +++ b/examples/acp-agent/both-mode.cordis.snapshot.yml @@ -2,7 +2,7 @@ # swap. Include patches cannot target entries behind a nested include, so this file # applies both overlays directly to `cordis.yml`. - id: base - name: '@cordisjs/plugin-include' + name: '@deepseek-ai/cordis-plugin-include' config: path: ./cordis.yml patches: diff --git a/examples/acp-agent/both-mode.cordis.yml b/examples/acp-agent/both-mode.cordis.yml index d793e616f9..58e465176c 100644 --- a/examples/acp-agent/both-mode.cordis.yml +++ b/examples/acp-agent/both-mode.cordis.yml @@ -3,7 +3,7 @@ # this overlay for snapshot recording and the sibling overlay for replay. A config # patch replaces the whole app config, so unchanged base fields are restated below. - id: base - name: '@cordisjs/plugin-include' + name: '@deepseek-ai/cordis-plugin-include' config: path: ./cordis.yml patches: diff --git a/examples/acp-agent/child-question.cordis.snapshot.yml b/examples/acp-agent/child-question.cordis.snapshot.yml index 4eb0c5bfb4..d9d87e8db9 100644 --- a/examples/acp-agent/child-question.cordis.snapshot.yml +++ b/examples/acp-agent/child-question.cordis.snapshot.yml @@ -2,7 +2,7 @@ # seam, model-facing tool, and tripwire provider while replacing DeepSeek with # per-session replay. - id: base - name: '@cordisjs/plugin-include' + name: '@deepseek-ai/cordis-plugin-include' config: path: ./cordis.yml patches: diff --git a/examples/acp-agent/child-question.cordis.yml b/examples/acp-agent/child-question.cordis.yml index 803d21c35d..8de7fe135b 100644 --- a/examples/acp-agent/child-question.cordis.yml +++ b/examples/acp-agent/child-question.cordis.yml @@ -1,7 +1,7 @@ # Snapshot-only human-interaction composition. The provider is a tripwire: the # runtime-owned child must be rejected by the seam before any UI wait begins. - id: base - name: '@cordisjs/plugin-include' + name: '@deepseek-ai/cordis-plugin-include' config: path: ./cordis.yml patches: diff --git a/examples/acp-agent/code-mode-workspace-context.cordis.snapshot.yml b/examples/acp-agent/code-mode-workspace-context.cordis.snapshot.yml index 684ac2b27d..650d950e69 100644 --- a/examples/acp-agent/code-mode-workspace-context.cordis.snapshot.yml +++ b/examples/acp-agent/code-mode-workspace-context.cordis.snapshot.yml @@ -1,7 +1,7 @@ # Keyless replay counterpart of code-mode-workspace-context.cordis.yml. It adds # Code Mode to the default filesystem suite and swaps in replay. - id: base - name: '@cordisjs/plugin-include' + name: '@deepseek-ai/cordis-plugin-include' config: path: ./cordis.yml patches: diff --git a/examples/acp-agent/code-mode-workspace-context.cordis.yml b/examples/acp-agent/code-mode-workspace-context.cordis.yml index a724a86961..02ca7d40de 100644 --- a/examples/acp-agent/code-mode-workspace-context.cordis.yml +++ b/examples/acp-agent/code-mode-workspace-context.cordis.yml @@ -1,7 +1,7 @@ # Code Mode workspace-context snapshot recording overlay. The default filesystem # tools trigger nested instruction discovery after a read. - id: base - name: '@cordisjs/plugin-include' + name: '@deepseek-ai/cordis-plugin-include' config: path: ./cordis.yml patches: diff --git a/examples/acp-agent/code-mode.cordis.snapshot.yml b/examples/acp-agent/code-mode.cordis.snapshot.yml index 992a442343..7c114d81f3 100644 --- a/examples/acp-agent/code-mode.cordis.snapshot.yml +++ b/examples/acp-agent/code-mode.cordis.snapshot.yml @@ -2,7 +2,7 @@ # swap. Include patches cannot target entries behind a nested include, so this file # applies both overlays directly to `cordis.yml`. - id: base - name: '@cordisjs/plugin-include' + name: '@deepseek-ai/cordis-plugin-include' config: path: ./cordis.yml patches: diff --git a/examples/acp-agent/code-mode.cordis.yml b/examples/acp-agent/code-mode.cordis.yml index ec31a1fc87..8ad70610b9 100644 --- a/examples/acp-agent/code-mode.cordis.yml +++ b/examples/acp-agent/code-mode.cordis.yml @@ -4,7 +4,7 @@ # replay overlay for `DSH_SNAPSHOT=replay`. A config patch replaces the whole app # config, so unchanged base fields are restated below. - id: base - name: '@cordisjs/plugin-include' + name: '@deepseek-ai/cordis-plugin-include' config: path: ./cordis.yml patches: diff --git a/examples/acp-agent/cordis-tools.cordis.yml b/examples/acp-agent/cordis-tools.cordis.yml index c6e3e84457..87ba11858e 100644 --- a/examples/acp-agent/cordis-tools.cordis.yml +++ b/examples/acp-agent/cordis-tools.cordis.yml @@ -1,7 +1,7 @@ # Add the self-referential Cordis tools without changing the base ACP tool # presentation mode. - id: base - name: '@cordisjs/plugin-include' + name: '@deepseek-ai/cordis-plugin-include' config: path: ./cordis.yml patches: diff --git a/examples/acp-agent/cordis.snapshot.yml b/examples/acp-agent/cordis.snapshot.yml index 5bc771a0fc..46eff1e869 100644 --- a/examples/acp-agent/cordis.snapshot.yml +++ b/examples/acp-agent/cordis.snapshot.yml @@ -9,7 +9,7 @@ # `DSH_SNAPSHOT_OVERRIDE` from the harness. The one-shot patch applies at include # load time, and stdout remains reserved for ACP JSON-RPC. - id: base - name: '@cordisjs/plugin-include' + name: '@deepseek-ai/cordis-plugin-include' config: path: ./cordis.yml patches: diff --git a/examples/acp-agent/depth-two.cordis.snapshot.yml b/examples/acp-agent/depth-two.cordis.snapshot.yml index 3e292699d1..e988f9be60 100644 --- a/examples/acp-agent/depth-two.cordis.snapshot.yml +++ b/examples/acp-agent/depth-two.cordis.snapshot.yml @@ -1,7 +1,7 @@ # Keyless counterpart to depth-two.cordis.yml: apply the depth patch and replace # the live adapter with per-session replay. - id: base - name: '@cordisjs/plugin-include' + name: '@deepseek-ai/cordis-plugin-include' config: path: ./cordis.yml patches: diff --git a/examples/acp-agent/depth-two.cordis.yml b/examples/acp-agent/depth-two.cordis.yml index 1af96e9283..73e02d7ffc 100644 --- a/examples/acp-agent/depth-two.cordis.yml +++ b/examples/acp-agent/depth-two.cordis.yml @@ -1,7 +1,7 @@ # Depth-limit snapshot overlay: keep the default composition and allow two # generations of spawn children before runtime enforcement rejects another. - id: base - name: '@cordisjs/plugin-include' + name: '@deepseek-ai/cordis-plugin-include' config: path: ./cordis.yml patches: diff --git a/examples/acp-agent/fs.cordis.snapshot.yml b/examples/acp-agent/fs.cordis.snapshot.yml index 0cab77bb36..ee922dba07 100644 --- a/examples/acp-agent/fs.cordis.snapshot.yml +++ b/examples/acp-agent/fs.cordis.snapshot.yml @@ -5,7 +5,7 @@ # `deepseek-v4-pro`, but the recorded corpus was captured on flash, and a config # patch replaces the whole app config, so the base fields are restated verbatim. - id: base - name: '@cordisjs/plugin-include' + name: '@deepseek-ai/cordis-plugin-include' config: path: ./cordis.yml patches: diff --git a/examples/acp-agent/fs.cordis.yml b/examples/acp-agent/fs.cordis.yml index 0d667255c8..c68e361302 100644 --- a/examples/acp-agent/fs.cordis.yml +++ b/examples/acp-agent/fs.cordis.yml @@ -2,7 +2,7 @@ # the base cordis.yml, so this overlay adds only the local tool-result spill # storage those scenarios exercise. - id: base - name: '@cordisjs/plugin-include' + name: '@deepseek-ai/cordis-plugin-include' config: path: ./cordis.yml patches: diff --git a/examples/acp-agent/partial-landlock.cordis.snapshot.yml b/examples/acp-agent/partial-landlock.cordis.snapshot.yml index af834b885d..ce48d20ac7 100644 --- a/examples/acp-agent/partial-landlock.cordis.snapshot.yml +++ b/examples/acp-agent/partial-landlock.cordis.snapshot.yml @@ -1,7 +1,7 @@ # Keyless runner-classification composition: replay authored model turns and # replace the shipping provider with a deterministic process-launch stand-in. - id: base - name: '@cordisjs/plugin-include' + name: '@deepseek-ai/cordis-plugin-include' config: path: ./cordis.yml patches: diff --git a/examples/acp-agent/partial-landlock.cordis.yml b/examples/acp-agent/partial-landlock.cordis.yml index 7a958bb6de..2272c657d1 100644 --- a/examples/acp-agent/partial-landlock.cordis.yml +++ b/examples/acp-agent/partial-landlock.cordis.yml @@ -1,7 +1,7 @@ # Live counterpart for the runner-classification snapshot overlay. It replaces # only the sandbox provider; authored scenarios are skipped in record mode. - id: base - name: '@cordisjs/plugin-include' + name: '@deepseek-ai/cordis-plugin-include' config: path: ./cordis.yml patches: diff --git a/examples/acp-agent/pty.cordis.snapshot.yml b/examples/acp-agent/pty.cordis.snapshot.yml index c918f74c56..75e9f313b6 100644 --- a/examples/acp-agent/pty.cordis.snapshot.yml +++ b/examples/acp-agent/pty.cordis.snapshot.yml @@ -1,6 +1,6 @@ # Keyless replay counterpart to pty.cordis.yml. - id: base - name: '@cordisjs/plugin-include' + name: '@deepseek-ai/cordis-plugin-include' config: path: ./cordis.yml patches: diff --git a/examples/acp-agent/pty.cordis.yml b/examples/acp-agent/pty.cordis.yml index 5e911b29d0..0ff9c1d4b5 100644 --- a/examples/acp-agent/pty.cordis.yml +++ b/examples/acp-agent/pty.cordis.yml @@ -1,7 +1,7 @@ # Opt-in persistent PTY composition for the PTY snapshot scenario. The base # deployment already owns the shared sandbox provider and policy. - id: base - name: '@cordisjs/plugin-include' + name: '@deepseek-ai/cordis-plugin-include' config: path: ./cordis.yml patches: diff --git a/examples/acp-agent/retry.cordis.snapshot.yml b/examples/acp-agent/retry.cordis.snapshot.yml index 72370f1a70..c69b08fe64 100644 --- a/examples/acp-agent/retry.cordis.snapshot.yml +++ b/examples/acp-agent/retry.cordis.snapshot.yml @@ -3,7 +3,7 @@ # 1 ms zero-jitter retry policy as the live sibling. The app patch still # restates its whole config for raw JSONL persistence and the recorded model. - id: base - name: '@cordisjs/plugin-include' + name: '@deepseek-ai/cordis-plugin-include' config: path: ./cordis.yml patches: diff --git a/examples/acp-agent/retry.cordis.yml b/examples/acp-agent/retry.cordis.yml index 087faa271d..2da66a3e44 100644 --- a/examples/acp-agent/retry.cordis.yml +++ b/examples/acp-agent/retry.cordis.yml @@ -6,7 +6,7 @@ # adapter fields around `retryPolicy`, while the app patch re-pins the recorded # flash model and restates its base fields. - id: base - name: '@cordisjs/plugin-include' + name: '@deepseek-ai/cordis-plugin-include' config: path: ./cordis.yml patches: diff --git a/examples/acp-agent/session-query.cordis.snapshot.yml b/examples/acp-agent/session-query.cordis.snapshot.yml index 1edadf8374..33029a9c7a 100644 --- a/examples/acp-agent/session-query.cordis.snapshot.yml +++ b/examples/acp-agent/session-query.cordis.snapshot.yml @@ -1,7 +1,7 @@ # Keyless counterpart to session-query.cordis.yml: the nested snapshot overlay # supplies replay plus deterministic private spill storage and its byte limit. - id: base - name: '@cordisjs/plugin-include' + name: '@deepseek-ai/cordis-plugin-include' config: path: ./fs.cordis.snapshot.yml patches: diff --git a/examples/acp-agent/session-query.cordis.yml b/examples/acp-agent/session-query.cordis.yml index e5e45025df..03ed085fa2 100644 --- a/examples/acp-agent/session-query.cordis.yml +++ b/examples/acp-agent/session-query.cordis.yml @@ -1,7 +1,7 @@ # Explicit session-query tool opt-in for the dedicated spill scenario. The # nested filesystem overlay supplies private spill storage and its byte limit. - id: base - name: '@cordisjs/plugin-include' + name: '@deepseek-ai/cordis-plugin-include' config: path: ./fs.cordis.yml patches: diff --git a/examples/acp-agent/session-sandbox-root.cordis.snapshot.yml b/examples/acp-agent/session-sandbox-root.cordis.snapshot.yml index 02b1d303d4..55627c17fa 100644 --- a/examples/acp-agent/session-sandbox-root.cordis.snapshot.yml +++ b/examples/acp-agent/session-sandbox-root.cordis.snapshot.yml @@ -3,7 +3,7 @@ # and the deliberately distinct sandbox fallback are applied together to the # live tree. - id: base - name: '@cordisjs/plugin-include' + name: '@deepseek-ai/cordis-plugin-include' config: path: ./cordis.yml patches: diff --git a/examples/acp-agent/session-sandbox-root.cordis.yml b/examples/acp-agent/session-sandbox-root.cordis.yml index f27732fd68..fd2d712882 100644 --- a/examples/acp-agent/session-sandbox-root.cordis.yml +++ b/examples/acp-agent/session-sandbox-root.cordis.yml @@ -3,7 +3,7 @@ # /tmp. A workspace-write mutation can therefore succeed only when the calling # session's cwd replaces the process-level fallback root. - id: base - name: '@cordisjs/plugin-include' + name: '@deepseek-ai/cordis-plugin-include' config: path: ./cordis.yml patches: diff --git a/examples/acp-agent/session-title.cordis.snapshot.yml b/examples/acp-agent/session-title.cordis.snapshot.yml index b10e82cfcc..4debc76a02 100644 --- a/examples/acp-agent/session-title.cordis.snapshot.yml +++ b/examples/acp-agent/session-title.cordis.snapshot.yml @@ -2,7 +2,7 @@ # the auxiliary route consumes replay.override.json with pacing so its accepted # title commits only after the main turn has closed. - id: base - name: '@cordisjs/plugin-include' + name: '@deepseek-ai/cordis-plugin-include' config: path: ./cordis.yml patches: diff --git a/examples/acp-agent/session-title.cordis.yml b/examples/acp-agent/session-title.cordis.yml index 0819b79d98..e18a6eeafd 100644 --- a/examples/acp-agent/session-title.cordis.yml +++ b/examples/acp-agent/session-title.cordis.yml @@ -2,7 +2,7 @@ # the ordinary DeepSeek route while the ACP app and every other capability stay # identical to the base example. - id: base - name: '@cordisjs/plugin-include' + name: '@deepseek-ai/cordis-plugin-include' config: path: ./cordis.yml patches: diff --git a/examples/acp-agent/subagent-durability-failure.cordis.snapshot.yml b/examples/acp-agent/subagent-durability-failure.cordis.snapshot.yml index 7ce0733e53..2fc7c8a369 100644 --- a/examples/acp-agent/subagent-durability-failure.cordis.snapshot.yml +++ b/examples/acp-agent/subagent-durability-failure.cordis.snapshot.yml @@ -1,7 +1,7 @@ # Keyless counterpart to subagent-durability-failure.cordis.yml: replace the # live adapter with replay and fail the provider-owned final child checkpoint. - id: base - name: '@cordisjs/plugin-include' + name: '@deepseek-ai/cordis-plugin-include' config: path: ./cordis.yml patches: diff --git a/examples/acp-agent/subagent-durability-failure.cordis.yml b/examples/acp-agent/subagent-durability-failure.cordis.yml index c033c323dc..ff5603093e 100644 --- a/examples/acp-agent/subagent-durability-failure.cordis.yml +++ b/examples/acp-agent/subagent-durability-failure.cordis.yml @@ -1,7 +1,7 @@ # Snapshot-only durability-failure overlay. The child turn's ordinary flush # succeeds; the provider-owned final confirmation fails deterministically. - id: base - name: '@cordisjs/plugin-include' + name: '@deepseek-ai/cordis-plugin-include' config: path: ./cordis.yml patches: diff --git a/examples/acp-agent/tests/fixtures/child-question-tripwire.ts b/examples/acp-agent/tests/fixtures/child-question-tripwire.ts index 7eb15ac551..7495e68819 100644 --- a/examples/acp-agent/tests/fixtures/child-question-tripwire.ts +++ b/examples/acp-agent/tests/fixtures/child-question-tripwire.ts @@ -1,4 +1,4 @@ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import '@deepseek-ai/dsh-user-interaction' /** Snapshot-only provider whose invocation means the child guard failed. */ diff --git a/examples/acp-agent/tests/fixtures/subagent-durability-failure.ts b/examples/acp-agent/tests/fixtures/subagent-durability-failure.ts index d3ffa4e8a7..8f5185026e 100644 --- a/examples/acp-agent/tests/fixtures/subagent-durability-failure.ts +++ b/examples/acp-agent/tests/fixtures/subagent-durability-failure.ts @@ -1,4 +1,4 @@ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { SessionId } from '@deepseek-ai/dsh-session' export const name = 'subagent-durability-failure' diff --git a/examples/acp-agent/tests/fixtures/subagent-settlement-marker.ts b/examples/acp-agent/tests/fixtures/subagent-settlement-marker.ts index e81bde95c4..8e4ad0a0e9 100644 --- a/examples/acp-agent/tests/fixtures/subagent-settlement-marker.ts +++ b/examples/acp-agent/tests/fixtures/subagent-settlement-marker.ts @@ -1,6 +1,6 @@ import { writeFileSync } from 'node:fs' import { join } from 'node:path' -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type {} from '@deepseek-ai/dsh-subagent' export const name = 'subagent-settlement-marker' diff --git a/examples/acp-agent/tests/fixtures/subagent/subagent-acp/mock-delegating-llm.ts b/examples/acp-agent/tests/fixtures/subagent/subagent-acp/mock-delegating-llm.ts index 9d3857ffc8..f98c007125 100644 --- a/examples/acp-agent/tests/fixtures/subagent/subagent-acp/mock-delegating-llm.ts +++ b/examples/acp-agent/tests/fixtures/subagent/subagent-acp/mock-delegating-llm.ts @@ -1,4 +1,4 @@ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { GenerateOptions, StreamChunk } from '@deepseek-ai/dsh-llm' import { CallId, LlmAdapter } from '@deepseek-ai/dsh-llm' diff --git a/examples/acp-agent/tests/fixtures/subagent/subagent-codex/fixture.ts b/examples/acp-agent/tests/fixtures/subagent/subagent-codex/fixture.ts index e2dc946dfe..781138d9ff 100644 --- a/examples/acp-agent/tests/fixtures/subagent/subagent-codex/fixture.ts +++ b/examples/acp-agent/tests/fixtures/subagent/subagent-codex/fixture.ts @@ -1,6 +1,6 @@ /** Parent adapter that fails if the composition-only Loader test starts a turn. */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { GenerateOptions, StreamChunk } from '@deepseek-ai/dsh-llm' import { LlmAdapter } from '@deepseek-ai/dsh-llm' diff --git a/examples/acp-agent/tests/fixtures/workspace-context-compaction.ts b/examples/acp-agent/tests/fixtures/workspace-context-compaction.ts index 6c1cd46fbf..e1819e430f 100644 --- a/examples/acp-agent/tests/fixtures/workspace-context-compaction.ts +++ b/examples/acp-agent/tests/fixtures/workspace-context-compaction.ts @@ -1,4 +1,4 @@ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type {} from '@deepseek-ai/dsh-agent' import { CompactionId, compactCheckpointSource } from '@deepseek-ai/dsh-compact' import { createUserMessage } from '@deepseek-ai/dsh-llm' diff --git a/examples/acp-agent/tests/fs-diff-bound.cordis.snapshot.yml b/examples/acp-agent/tests/fs-diff-bound.cordis.snapshot.yml index a216a34cfd..4cc6ba1f3e 100644 --- a/examples/acp-agent/tests/fs-diff-bound.cordis.snapshot.yml +++ b/examples/acp-agent/tests/fs-diff-bound.cordis.snapshot.yml @@ -3,7 +3,7 @@ # entries behind a nested include; the acp-agent restatement keeps the recorded # deepseek-v4-flash model and raw JSONL persistence for the harness's harvest. - id: base - name: '@cordisjs/plugin-include' + name: '@deepseek-ai/cordis-plugin-include' config: path: ../cordis.yml patches: diff --git a/examples/acp-agent/tests/fs-diff-bound.cordis.yml b/examples/acp-agent/tests/fs-diff-bound.cordis.yml index 9be25cdb25..c82a7ce63a 100644 --- a/examples/acp-agent/tests/fs-diff-bound.cordis.yml +++ b/examples/acp-agent/tests/fs-diff-bound.cordis.yml @@ -5,7 +5,7 @@ # verbatim, and the acp-agent restatement re-pins `deepseek-v4-flash` to match # the recorded corpus and its pinned request headers. - id: base - name: '@cordisjs/plugin-include' + name: '@deepseek-ai/cordis-plugin-include' config: path: ../cordis.yml patches: diff --git a/examples/acp-agent/tests/lsp.cordis.snapshot.yml b/examples/acp-agent/tests/lsp.cordis.snapshot.yml index dc672376b5..574d8f646f 100644 --- a/examples/acp-agent/tests/lsp.cordis.snapshot.yml +++ b/examples/acp-agent/tests/lsp.cordis.snapshot.yml @@ -1,6 +1,6 @@ # Keyless replay keeps the LSP composition intact and replaces only the model adapter. - id: base - name: '@cordisjs/plugin-include' + name: '@deepseek-ai/cordis-plugin-include' config: path: ../cordis.yml patches: diff --git a/examples/acp-agent/tests/lsp.cordis.yml b/examples/acp-agent/tests/lsp.cordis.yml index 49c9099d65..b9600d5d09 100644 --- a/examples/acp-agent/tests/lsp.cordis.yml +++ b/examples/acp-agent/tests/lsp.cordis.yml @@ -1,7 +1,7 @@ # Exercise the model-facing LSP tool through the shipped ACP app and Loader entry path. # The scenario workspace supplies the deterministic stdio server used by this test composition. - id: base - name: '@cordisjs/plugin-include' + name: '@deepseek-ai/cordis-plugin-include' config: path: ../cordis.yml patches: diff --git a/examples/acp-agent/web.cordis.snapshot.yml b/examples/acp-agent/web.cordis.snapshot.yml index f0da7617b0..facd66f76c 100644 --- a/examples/acp-agent/web.cordis.snapshot.yml +++ b/examples/acp-agent/web.cordis.snapshot.yml @@ -2,7 +2,7 @@ # fixture server stay real (the tool call re-executes the actual HTTP fetch and # markdown rendering); only the model adapter is replaced by replay. - id: base - name: '@cordisjs/plugin-include' + name: '@deepseek-ai/cordis-plugin-include' config: path: ./cordis.yml patches: diff --git a/examples/acp-agent/web.cordis.yml b/examples/acp-agent/web.cordis.yml index 1ed0b3efba..63ce043340 100644 --- a/examples/acp-agent/web.cordis.yml +++ b/examples/acp-agent/web.cordis.yml @@ -4,7 +4,7 @@ # fixture server the scenario prompt fetches — deterministic content, no # external network, in recording and replay alike. - id: base - name: '@cordisjs/plugin-include' + name: '@deepseek-ai/cordis-plugin-include' config: path: ./cordis.yml patches: diff --git a/examples/acp-agent/workspace-context.cordis.snapshot.yml b/examples/acp-agent/workspace-context.cordis.snapshot.yml index 6abaaa3f13..0215128de1 100644 --- a/examples/acp-agent/workspace-context.cordis.snapshot.yml +++ b/examples/acp-agent/workspace-context.cordis.snapshot.yml @@ -2,7 +2,7 @@ # compose across includes, so this applies the scenario config and model swap # directly to the live tree. - id: base - name: '@cordisjs/plugin-include' + name: '@deepseek-ai/cordis-plugin-include' config: path: ./cordis.yml patches: diff --git a/examples/acp-agent/workspace-context.cordis.yml b/examples/acp-agent/workspace-context.cordis.yml index 34562e7324..db9fb85353 100644 --- a/examples/acp-agent/workspace-context.cordis.yml +++ b/examples/acp-agent/workspace-context.cordis.yml @@ -2,7 +2,7 @@ # discovery inside the scenario's temporary cwd. The app config patch replaces # the whole base config, so the base fields are restated verbatim. - id: base - name: '@cordisjs/plugin-include' + name: '@deepseek-ai/cordis-plugin-include' config: path: ./cordis.yml patches: diff --git a/examples/headless-agent/advanced.cordis.snapshot.yml b/examples/headless-agent/advanced.cordis.snapshot.yml index 881a976e33..6ce18953cc 100644 --- a/examples/headless-agent/advanced.cordis.snapshot.yml +++ b/examples/headless-agent/advanced.cordis.snapshot.yml @@ -8,7 +8,7 @@ # disables the key-requiring DeepSeek adapter and inserts `llm-replay` to serve # recorded JSONL without a key or network. - id: base - name: '@cordisjs/plugin-include' + name: '@deepseek-ai/cordis-plugin-include' config: path: ./cordis.yml patches: diff --git a/examples/headless-agent/advanced.cordis.yml b/examples/headless-agent/advanced.cordis.yml index 09ecec6ea2..ab0bd18d6d 100644 --- a/examples/headless-agent/advanced.cordis.yml +++ b/examples/headless-agent/advanced.cordis.yml @@ -1,6 +1,6 @@ # Add Code Mode and Cordis tools to the headless spawn/workflow stack. - id: base - name: '@cordisjs/plugin-include' + name: '@deepseek-ai/cordis-plugin-include' config: path: ./cordis.yml patches: diff --git a/examples/headless-agent/compaction.cordis.snapshot.yml b/examples/headless-agent/compaction.cordis.snapshot.yml index 13515cf5cc..56431c6e37 100644 --- a/examples/headless-agent/compaction.cordis.snapshot.yml +++ b/examples/headless-agent/compaction.cordis.snapshot.yml @@ -1,6 +1,6 @@ # Keyless context-overflow composition for the assembled compaction snapshot. - id: base - name: '@cordisjs/plugin-include' + name: '@deepseek-ai/cordis-plugin-include' config: path: ./cordis.yml patches: diff --git a/examples/headless-agent/credentials.cordis.snapshot.yml b/examples/headless-agent/credentials.cordis.snapshot.yml index 3a8638089a..7f1cb2b1f2 100644 --- a/examples/headless-agent/credentials.cordis.snapshot.yml +++ b/examples/headless-agent/credentials.cordis.snapshot.yml @@ -3,7 +3,7 @@ # the deepseek-official route still registers — so the prompt fails with the actionable # MISSING_CREDENTIAL guidance this snapshot pins as first-run UX. - id: base - name: '@cordisjs/plugin-include' + name: '@deepseek-ai/cordis-plugin-include' config: path: ./cordis.yml patches: diff --git a/examples/headless-agent/e2b.cordis.yml b/examples/headless-agent/e2b.cordis.yml index 61bdbc8aa7..3c48a397ad 100644 --- a/examples/headless-agent/e2b.cordis.yml +++ b/examples/headless-agent/e2b.cordis.yml @@ -8,7 +8,7 @@ # falls back to /home/user/workspace while Bash and PTY keep targeting the # host path, so every tool call fails with a remote spawn error. - id: base - name: '@cordisjs/plugin-include' + name: '@deepseek-ai/cordis-plugin-include' config: path: ./advanced.cordis.yml patches: diff --git a/examples/headless-agent/goal.cordis.snapshot.yml b/examples/headless-agent/goal.cordis.snapshot.yml index f6eeeb05ec..00c34e272e 100644 --- a/examples/headless-agent/goal.cordis.snapshot.yml +++ b/examples/headless-agent/goal.cordis.snapshot.yml @@ -2,7 +2,7 @@ # a config patch cannot target an entry behind a nested include, then restates # the goal overlay while replacing the live model with keyless replay. - id: base - name: '@cordisjs/plugin-include' + name: '@deepseek-ai/cordis-plugin-include' config: path: ./cordis.yml patches: diff --git a/examples/headless-agent/goal.cordis.yml b/examples/headless-agent/goal.cordis.yml index 8f8cdf9e0b..fe84de7bf5 100644 --- a/examples/headless-agent/goal.cordis.yml +++ b/examples/headless-agent/goal.cordis.yml @@ -1,6 +1,6 @@ # Add the persisted goal domain and its model-facing tools to the real one-shot app. - id: base - name: '@cordisjs/plugin-include' + name: '@deepseek-ai/cordis-plugin-include' config: path: ./cordis.yml patches: diff --git a/examples/headless-agent/pty.cordis.snapshot.yml b/examples/headless-agent/pty.cordis.snapshot.yml index 49f3a95afb..3fb20ff468 100644 --- a/examples/headless-agent/pty.cordis.snapshot.yml +++ b/examples/headless-agent/pty.cordis.snapshot.yml @@ -1,6 +1,6 @@ # Keyless opt-in PTY composition for the headless stream-json snapshot. - id: base - name: '@cordisjs/plugin-include' + name: '@deepseek-ai/cordis-plugin-include' config: path: ./cordis.yml patches: diff --git a/examples/headless-agent/ralph.cordis.snapshot.yml b/examples/headless-agent/ralph.cordis.snapshot.yml index e84bdfed31..87e5619cde 100644 --- a/examples/headless-agent/ralph.cordis.snapshot.yml +++ b/examples/headless-agent/ralph.cordis.snapshot.yml @@ -1,6 +1,6 @@ # Replay counterpart to cordis.yml for the shipped Ralph-loop snapshot. - id: base - name: '@cordisjs/plugin-include' + name: '@deepseek-ai/cordis-plugin-include' config: path: ./cordis.yml patches: diff --git a/examples/headless-agent/retry.cordis.snapshot.yml b/examples/headless-agent/retry.cordis.snapshot.yml index b8fc79d17f..30a67f45f6 100644 --- a/examples/headless-agent/retry.cordis.snapshot.yml +++ b/examples/headless-agent/retry.cordis.snapshot.yml @@ -1,6 +1,6 @@ # Keyless provider-retry composition for the headless stream-json snapshot. - id: base - name: '@cordisjs/plugin-include' + name: '@deepseek-ai/cordis-plugin-include' config: path: ./cordis.yml patches: diff --git a/examples/headless-agent/tests/code-mode.e2e.ts b/examples/headless-agent/tests/code-mode.e2e.ts index ad049ab308..d360f7083d 100644 --- a/examples/headless-agent/tests/code-mode.e2e.ts +++ b/examples/headless-agent/tests/code-mode.e2e.ts @@ -2,7 +2,7 @@ import { mkdtemp, mkdir, readFile, rm, writeFile } from 'node:fs/promises' import { tmpdir } from 'node:os' import { join } from 'node:path' import { afterEach, describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import LlmService, { createUserMessage, CallId, HarnessError } from '@deepseek-ai/dsh-llm' import SessionStore, { SessionId } from '@deepseek-ai/dsh-session' import type { SessionEvent } from '@deepseek-ai/dsh-session' diff --git a/examples/headless-agent/tests/coding-task.e2e.ts b/examples/headless-agent/tests/coding-task.e2e.ts index 75b10ee2bc..42b87eff8a 100644 --- a/examples/headless-agent/tests/coding-task.e2e.ts +++ b/examples/headless-agent/tests/coding-task.e2e.ts @@ -4,7 +4,7 @@ import { mkdtemp, readFile, rm, writeFile } from 'node:fs/promises' import { tmpdir } from 'node:os' import { join } from 'node:path' import { afterEach, describe, expect, it } from 'vitest' -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { codingHarness, finalText, SYSTEM_PROMPT, waitForIdle } from './harness.ts' import { SessionId } from '@deepseek-ai/dsh-session' diff --git a/examples/headless-agent/tests/compaction.e2e.ts b/examples/headless-agent/tests/compaction.e2e.ts index 35a9a1627e..94dd510b84 100644 --- a/examples/headless-agent/tests/compaction.e2e.ts +++ b/examples/headless-agent/tests/compaction.e2e.ts @@ -3,7 +3,7 @@ import { mkdtemp, rm, writeFile } from 'node:fs/promises' import { tmpdir } from 'node:os' import { join } from 'node:path' import { afterEach, describe, expect, it } from 'vitest' -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { codingHarness, finalText, SYSTEM_PROMPT, waitForIdle } from './harness.ts' import { SessionId } from '@deepseek-ai/dsh-session' diff --git a/examples/headless-agent/tests/fixtures/cli-mock-llm.ts b/examples/headless-agent/tests/fixtures/cli-mock-llm.ts index b0b120ecb2..57cb384138 100644 --- a/examples/headless-agent/tests/fixtures/cli-mock-llm.ts +++ b/examples/headless-agent/tests/fixtures/cli-mock-llm.ts @@ -1,4 +1,4 @@ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { CallId, LlmAdapter, diff --git a/examples/headless-agent/tests/fixtures/cli.cordis.yml b/examples/headless-agent/tests/fixtures/cli.cordis.yml index b9df4d29f7..3106467857 100644 --- a/examples/headless-agent/tests/fixtures/cli.cordis.yml +++ b/examples/headless-agent/tests/fixtures/cli.cordis.yml @@ -2,7 +2,7 @@ name: './cli-mock-llm.ts' - id: base - name: '@cordisjs/plugin-include' + name: '@deepseek-ai/cordis-plugin-include' config: path: ../../cordis.yml patches: diff --git a/examples/headless-agent/tests/fixtures/deepseek-defaults.cordis.yml b/examples/headless-agent/tests/fixtures/deepseek-defaults.cordis.yml index 930363cf37..fab8ae1b7b 100644 --- a/examples/headless-agent/tests/fixtures/deepseek-defaults.cordis.yml +++ b/examples/headless-agent/tests/fixtures/deepseek-defaults.cordis.yml @@ -1,5 +1,5 @@ - id: base - name: '@cordisjs/plugin-include' + name: '@deepseek-ai/cordis-plugin-include' config: path: ../../cordis.yml patches: diff --git a/examples/headless-agent/tests/fixtures/goal-domain/seed-goal.ts b/examples/headless-agent/tests/fixtures/goal-domain/seed-goal.ts index d8dc2c2465..9776438079 100644 --- a/examples/headless-agent/tests/fixtures/goal-domain/seed-goal.ts +++ b/examples/headless-agent/tests/fixtures/goal-domain/seed-goal.ts @@ -1,6 +1,6 @@ /** Test-only Loader plugin that creates a goal at the first real step edge. */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type {} from '@deepseek-ai/dsh-goal' export const name = 'seed-goal' diff --git a/examples/headless-agent/tests/fixtures/headless-driver.ts b/examples/headless-agent/tests/fixtures/headless-driver.ts index 88d7d73b67..8020129bfb 100644 --- a/examples/headless-agent/tests/fixtures/headless-driver.ts +++ b/examples/headless-agent/tests/fixtures/headless-driver.ts @@ -1,7 +1,7 @@ #!/usr/bin/env node /** Snapshot-only Loader driver: stream one fixture turn as canonical JSONL. */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { boot, installFailLoud, loadEnv, resolveConfigPath } from '@deepseek-ai/dsh-app-boot' import { runFixtureTurn } from '@deepseek-ai/dsh-loader-smoke' import type { SessionEvent } from '@deepseek-ai/dsh-session' diff --git a/examples/headless-agent/tests/fixtures/retry-snapshot-backend.mjs b/examples/headless-agent/tests/fixtures/retry-snapshot-backend.mjs index 5a2fc5d128..76981fe79c 100644 --- a/examples/headless-agent/tests/fixtures/retry-snapshot-backend.mjs +++ b/examples/headless-agent/tests/fixtures/retry-snapshot-backend.mjs @@ -46,7 +46,7 @@ export const inject = ['llm'] /** * Register the deterministic provider adapter. - * @param {import('cordis').Context} ctx - plugin context carrying the LLM service. + * @param {import('@deepseek-ai/cordis').Context} ctx - plugin context carrying the LLM service. */ export function apply(ctx) { ctx.llm.registerAdapter(['deepseek-official'], new RetrySnapshotAdapter()) diff --git a/examples/headless-agent/tests/fixtures/semantic-checkpoint-agent.ts b/examples/headless-agent/tests/fixtures/semantic-checkpoint-agent.ts index ef7cf4bafe..f8832da8b3 100644 --- a/examples/headless-agent/tests/fixtures/semantic-checkpoint-agent.ts +++ b/examples/headless-agent/tests/fixtures/semantic-checkpoint-agent.ts @@ -3,7 +3,7 @@ * @module semantic-checkpoint-agent */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { SessionId } from '@deepseek-ai/dsh-session' /** Fixture plugin name. */ diff --git a/examples/headless-agent/tests/fixtures/subagent-diagnostic-agent.ts b/examples/headless-agent/tests/fixtures/subagent-diagnostic-agent.ts index f77afe7e0a..a869ab6c9f 100644 --- a/examples/headless-agent/tests/fixtures/subagent-diagnostic-agent.ts +++ b/examples/headless-agent/tests/fixtures/subagent-diagnostic-agent.ts @@ -4,7 +4,7 @@ * @module subagent-diagnostic-agent */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { SessionId } from '@deepseek-ai/dsh-session' /** Fixture plugin name. */ diff --git a/examples/headless-agent/tests/fixtures/subagent-inheritance-agent.ts b/examples/headless-agent/tests/fixtures/subagent-inheritance-agent.ts index 9cd3e6235f..681793a85b 100644 --- a/examples/headless-agent/tests/fixtures/subagent-inheritance-agent.ts +++ b/examples/headless-agent/tests/fixtures/subagent-inheritance-agent.ts @@ -3,7 +3,7 @@ * @module subagent-inheritance-agent */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { SessionId } from '@deepseek-ai/dsh-session' /** Fixture plugin name. */ diff --git a/examples/headless-agent/tests/fixtures/telemetry-otel.cordis.yml b/examples/headless-agent/tests/fixtures/telemetry-otel.cordis.yml index 27172b40d8..d7be47fbbe 100644 --- a/examples/headless-agent/tests/fixtures/telemetry-otel.cordis.yml +++ b/examples/headless-agent/tests/fixtures/telemetry-otel.cordis.yml @@ -3,7 +3,7 @@ # The redact-rule entry models a deployment mounting its own scrub rule on the # telemetry/record waterfall — the seam itself ships no rules. - id: logger-console - name: '@cordisjs/plugin-logger-console' + name: '@deepseek-ai/cordis-plugin-logger-console' config: colors: false levels: diff --git a/examples/headless-agent/tests/fixtures/telemetry-redact-rule.ts b/examples/headless-agent/tests/fixtures/telemetry-redact-rule.ts index 7a2aa7958a..5f205f606e 100644 --- a/examples/headless-agent/tests/fixtures/telemetry-redact-rule.ts +++ b/examples/headless-agent/tests/fixtures/telemetry-redact-rule.ts @@ -1,4 +1,4 @@ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' /** * Deployment-style redaction rule for the telemetry e2e: scrubs the fixture diff --git a/examples/headless-agent/tests/fixtures/time-context-mock-llm.ts b/examples/headless-agent/tests/fixtures/time-context-mock-llm.ts index 8cd3155ca7..9689dafbcf 100644 --- a/examples/headless-agent/tests/fixtures/time-context-mock-llm.ts +++ b/examples/headless-agent/tests/fixtures/time-context-mock-llm.ts @@ -1,4 +1,4 @@ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { LlmAdapter, type StreamChunk } from '@deepseek-ai/dsh-llm' /** Deterministic one-step adapter for the time-context Loader fixture. */ diff --git a/examples/headless-agent/tests/fixtures/workspace-context-resume-agent.ts b/examples/headless-agent/tests/fixtures/workspace-context-resume-agent.ts index 4cdf7d157a..ca1499d897 100644 --- a/examples/headless-agent/tests/fixtures/workspace-context-resume-agent.ts +++ b/examples/headless-agent/tests/fixtures/workspace-context-resume-agent.ts @@ -3,7 +3,7 @@ * @module workspace-context-resume-agent */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { SessionId } from '@deepseek-ai/dsh-session' /** Fixture plugin name. */ diff --git a/examples/headless-agent/tests/full-loop.e2e.ts b/examples/headless-agent/tests/full-loop.e2e.ts index f4bb8695c9..a8825cc84d 100644 --- a/examples/headless-agent/tests/full-loop.e2e.ts +++ b/examples/headless-agent/tests/full-loop.e2e.ts @@ -3,7 +3,7 @@ import { mkdtemp, rm } from 'node:fs/promises' import { tmpdir } from 'node:os' import { join } from 'node:path' import { afterEach, describe, expect, it } from 'vitest' -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { codingHarness, finalText, SYSTEM_PROMPT, waitForIdle } from './harness.ts' import { SessionId } from '@deepseek-ai/dsh-session' diff --git a/examples/headless-agent/tests/harness.ts b/examples/headless-agent/tests/harness.ts index 9b953256b7..7cf28a0dc0 100644 --- a/examples/headless-agent/tests/harness.ts +++ b/examples/headless-agent/tests/harness.ts @@ -1,4 +1,4 @@ -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import type { SessionEvent } from '@deepseek-ai/dsh-session' import type { Agent } from '@deepseek-ai/dsh-agent' import AgentLoop from '@deepseek-ai/dsh-agent-loop' diff --git a/examples/headless-agent/tests/resume.e2e.ts b/examples/headless-agent/tests/resume.e2e.ts index 3875a157d8..6767357b4e 100644 --- a/examples/headless-agent/tests/resume.e2e.ts +++ b/examples/headless-agent/tests/resume.e2e.ts @@ -3,7 +3,7 @@ import { mkdtemp, rm } from 'node:fs/promises' import { tmpdir } from 'node:os' import { join } from 'node:path' import { afterEach, describe, expect, it } from 'vitest' -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { SessionId } from '@deepseek-ai/dsh-session' import { codingHarness, finalText, SYSTEM_PROMPT, waitForIdle } from './harness.ts' diff --git a/examples/headless-agent/tests/semantic-checkpoint.snapshot.ts b/examples/headless-agent/tests/semantic-checkpoint.snapshot.ts index a8b8f02b9a..474422b4d2 100644 --- a/examples/headless-agent/tests/semantic-checkpoint.snapshot.ts +++ b/examples/headless-agent/tests/semantic-checkpoint.snapshot.ts @@ -1,7 +1,7 @@ import { readFile, writeFile } from 'node:fs/promises' import { dirname, join } from 'node:path' import { fileURLToPath } from 'node:url' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { normalizeSessionLog, scrubRequestHeaders, type NormalizeContext } from '@deepseek-ai/dsh-acp-snapshot' import { LOADER_SMOKE_TEST_TIMEOUT_MS, runLoaderSmoke } from '@deepseek-ai/dsh-loader-smoke' import { createUserMessage, CallId , createMessage } from '@deepseek-ai/dsh-llm' diff --git a/examples/headless-agent/tests/subagent-diagnostic.snapshot.ts b/examples/headless-agent/tests/subagent-diagnostic.snapshot.ts index 998c9129a5..22a3071d9c 100644 --- a/examples/headless-agent/tests/subagent-diagnostic.snapshot.ts +++ b/examples/headless-agent/tests/subagent-diagnostic.snapshot.ts @@ -7,7 +7,7 @@ import { readFile, readdir, writeFile } from 'node:fs/promises' import { join } from 'node:path' import { fileURLToPath } from 'node:url' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { normalizeSessionLog, scrubRequestHeaders, type NormalizeContext } from '@deepseek-ai/dsh-acp-snapshot' import { LOADER_SMOKE_TEST_TIMEOUT_MS, runLoaderSmoke } from '@deepseek-ai/dsh-loader-smoke' import { createUserMessage } from '@deepseek-ai/dsh-llm' diff --git a/examples/headless-agent/tests/subagent-inheritance.snapshot.ts b/examples/headless-agent/tests/subagent-inheritance.snapshot.ts index be5be2b357..76fe7b41e6 100644 --- a/examples/headless-agent/tests/subagent-inheritance.snapshot.ts +++ b/examples/headless-agent/tests/subagent-inheritance.snapshot.ts @@ -6,7 +6,7 @@ import { readFile, readdir, writeFile } from 'node:fs/promises' import { join } from 'node:path' import { fileURLToPath } from 'node:url' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { normalizeSessionLog, scrubRequestHeaders, type NormalizeContext } from '@deepseek-ai/dsh-acp-snapshot' import { LOADER_SMOKE_TEST_TIMEOUT_MS, runLoaderSmoke } from '@deepseek-ai/dsh-loader-smoke' import { createUserMessage } from '@deepseek-ai/dsh-llm' diff --git a/examples/headless-agent/tests/todo-write.e2e.ts b/examples/headless-agent/tests/todo-write.e2e.ts index 8b1aa9691e..014f1e3e69 100644 --- a/examples/headless-agent/tests/todo-write.e2e.ts +++ b/examples/headless-agent/tests/todo-write.e2e.ts @@ -3,7 +3,7 @@ import { mkdtemp, rm } from 'node:fs/promises' import { tmpdir } from 'node:os' import { join } from 'node:path' import { afterEach, describe, expect, it } from 'vitest' -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { codingHarness, TODO_SYSTEM_PROMPT, waitForIdle } from './harness.ts' import { SessionId } from '@deepseek-ai/dsh-session' diff --git a/examples/headless-agent/tests/workspace-context-resume.snapshot.ts b/examples/headless-agent/tests/workspace-context-resume.snapshot.ts index afe2ba325a..13d80e9fcc 100644 --- a/examples/headless-agent/tests/workspace-context-resume.snapshot.ts +++ b/examples/headless-agent/tests/workspace-context-resume.snapshot.ts @@ -7,7 +7,7 @@ import { createHash } from 'node:crypto' import { mkdir, readFile, readdir, writeFile } from 'node:fs/promises' import { dirname, join } from 'node:path' import { fileURLToPath } from 'node:url' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { normalizeSessionLog, scrubRequestHeaders, type NormalizeContext } from '@deepseek-ai/dsh-acp-snapshot' import { LOADER_SMOKE_TEST_TIMEOUT_MS, runLoaderSmoke } from '@deepseek-ai/dsh-loader-smoke' import { createUserMessage } from '@deepseek-ai/dsh-llm' diff --git a/examples/jsonrpc-agent/cordis.snapshot.yml b/examples/jsonrpc-agent/cordis.snapshot.yml index 6c3a6f99e7..23bc8c5402 100644 --- a/examples/jsonrpc-agent/cordis.snapshot.yml +++ b/examples/jsonrpc-agent/cordis.snapshot.yml @@ -8,7 +8,7 @@ # `llm-replay` reads `DSH_SNAPSHOT_FILE` / `DSH_SNAPSHOT_CHILD_FILES` from the # harness. Stdout remains reserved for JSON-RPC frames. - id: base - name: '@cordisjs/plugin-include' + name: '@deepseek-ai/cordis-plugin-include' config: path: ./cordis.yml patches: diff --git a/examples/jsonrpc-agent/persistent-tools.snapshot.cordis.yml b/examples/jsonrpc-agent/persistent-tools.snapshot.cordis.yml index 498d5467f2..2b6049382f 100644 --- a/examples/jsonrpc-agent/persistent-tools.snapshot.cordis.yml +++ b/examples/jsonrpc-agent/persistent-tools.snapshot.cordis.yml @@ -4,7 +4,7 @@ # unowned route makes the SDK server mount the real adapter, which then demands # a key this keyless lane has no way to supply. - id: base - name: '@cordisjs/plugin-include' + name: '@deepseek-ai/cordis-plugin-include' config: path: ./persistent-tools.cordis.yml patches: diff --git a/examples/jsonrpc-agent/tests/fixtures/subagent/subagent-dsh-sdk/child-mock-llm.ts b/examples/jsonrpc-agent/tests/fixtures/subagent/subagent-dsh-sdk/child-mock-llm.ts index 30f480064e..b693787968 100644 --- a/examples/jsonrpc-agent/tests/fixtures/subagent/subagent-dsh-sdk/child-mock-llm.ts +++ b/examples/jsonrpc-agent/tests/fixtures/subagent/subagent-dsh-sdk/child-mock-llm.ts @@ -1,4 +1,4 @@ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { GenerateOptions, StreamChunk } from '@deepseek-ai/dsh-llm' import { LlmAdapter } from '@deepseek-ai/dsh-llm' diff --git a/examples/jsonrpc-agent/tests/fixtures/subagent/subagent-dsh-sdk/mock-delegating-llm.ts b/examples/jsonrpc-agent/tests/fixtures/subagent/subagent-dsh-sdk/mock-delegating-llm.ts index e5ce753fd8..e0a3664487 100644 --- a/examples/jsonrpc-agent/tests/fixtures/subagent/subagent-dsh-sdk/mock-delegating-llm.ts +++ b/examples/jsonrpc-agent/tests/fixtures/subagent/subagent-dsh-sdk/mock-delegating-llm.ts @@ -1,4 +1,4 @@ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { GenerateOptions, StreamChunk } from '@deepseek-ai/dsh-llm' import { CallId, LlmAdapter } from '@deepseek-ai/dsh-llm' diff --git a/examples/package.json b/examples/package.json index 4e684d9d80..64b1ffdf3d 100644 --- a/examples/package.json +++ b/examples/package.json @@ -5,10 +5,10 @@ "type": "module", "description": "Workspace umbrella for runnable demos and example-owned test compositions: declares their cordis.yml packages so plain Node resolves real exports→lib. Not a build target.", "dependencies": { - "@cordisjs/plugin-hmr": "workspace:*", - "@cordisjs/plugin-include": "workspace:*", - "@cordisjs/plugin-logger-console": "workspace:*", - "@cordisjs/plugin-timer": "workspace:*", + "@deepseek-ai/cordis-plugin-hmr": "workspace:*", + "@deepseek-ai/cordis-plugin-include": "workspace:*", + "@deepseek-ai/cordis-plugin-logger-console": "workspace:*", + "@deepseek-ai/cordis-plugin-timer": "workspace:*", "@deepseek-ai/dsh-acp-demo": "workspace:*", "@deepseek-ai/dsh-agent": "workspace:*", "@deepseek-ai/dsh-agent-loop": "workspace:*", diff --git a/knip.json b/knip.json index 512ec350e4..930504f478 100644 --- a/knip.json +++ b/knip.json @@ -67,7 +67,6 @@ "**/*.ts" ], "ignoreDependencies": [ - "@cordisjs/plugin-logger-console", "@deepseek-ai/.+" ] }, @@ -747,8 +746,7 @@ }, "packages/bundle/base": { "ignoreDependencies": [ - "@deepseek-ai/.+", - "@cordisjs/.+" + "@deepseek-ai/.+" ] }, "packages/bundle/headless": { diff --git a/packages/acp/acp/package.json b/packages/acp/acp/package.json index 7aa9f8c4ef..0d83ca8c24 100644 --- a/packages/acp/acp/package.json +++ b/packages/acp/acp/package.json @@ -26,14 +26,14 @@ "license": "BSD-3-Clause", "dependencies": { "@agentclientprotocol/sdk": "0.25.1", - "schemastery": "^3.17.0" + "@deepseek-ai/schemastery": "^3.17.0" }, "peerDependencies": { "@deepseek-ai/dsh-agent": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-session": "^0.0.1", "@deepseek-ai/dsh-user-approval": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-agent": "workspace:^", @@ -44,6 +44,6 @@ "@deepseek-ai/dsh-session": "workspace:^", "@deepseek-ai/dsh-tools": "workspace:^", "@deepseek-ai/dsh-user-approval": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/acp/acp/src/index.ts b/packages/acp/acp/src/index.ts index ce00fb105a..13b24feb42 100644 --- a/packages/acp/acp/src/index.ts +++ b/packages/acp/acp/src/index.ts @@ -9,11 +9,11 @@ * @module @deepseek-ai/dsh-acp */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { randomUUID } from 'node:crypto' import { isAbsolute } from 'node:path' import { Readable, Writable } from 'node:stream' -import Schema from 'schemastery' +import Schema from '@deepseek-ai/schemastery' import { createUserMessage, errorChain } from '@deepseek-ai/dsh-llm' import { AgentSideConnection, diff --git a/packages/acp/acp/src/invariant.ts b/packages/acp/acp/src/invariant.ts index 9d5b769872..d4db1c964c 100644 --- a/packages/acp/acp/src/invariant.ts +++ b/packages/acp/acp/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-acp' diff --git a/packages/acp/acp/tests/harness.ts b/packages/acp/acp/tests/harness.ts index aa3564ea8a..c5b03c39a2 100644 --- a/packages/acp/acp/tests/harness.ts +++ b/packages/acp/acp/tests/harness.ts @@ -1,6 +1,6 @@ /** In-memory ACP transport fixture over the real agent factory and loop. */ -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { ClientSideConnection, ndJsonStream, diff --git a/packages/api/gateway/package.json b/packages/api/gateway/package.json index 0b76b607cd..9720c8530a 100644 --- a/packages/api/gateway/package.json +++ b/packages/api/gateway/package.json @@ -55,14 +55,14 @@ "@deepseek-ai/dsh-client-connection": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-typert-registry": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-client-connection": "workspace:^", "@deepseek-ai/dsh-host-webserver": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-typert-registry": "workspace:^", - "cordis": "^4.0.0-rc.7", + "@deepseek-ai/cordis": "^4.0.0-rc.7", "zod": "^4.4.3" } } diff --git a/packages/api/gateway/src/client/index.ts b/packages/api/gateway/src/client/index.ts index e49e9e5822..847998f173 100644 --- a/packages/api/gateway/src/client/index.ts +++ b/packages/api/gateway/src/client/index.ts @@ -4,8 +4,8 @@ * participates in method lookup, invocation, or type exposure. */ -import { Service } from 'cordis' -import type { Context } from 'cordis' +import { Service } from '@deepseek-ai/cordis' +import type { Context } from '@deepseek-ai/cordis' import type { ConnectionHandle, RpcError } from '@deepseek-ai/dsh-client-connection/client' import type { InvocationDescriptor, @@ -53,7 +53,7 @@ interface RemoteNamespaceHandle { /** Typed Remote service augmented by generated direct namespaces. */ export type ClientRemote = TypeRTClientRemote -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { /** Generated Remote namespaces selected by the Client assembly. */ remote: ClientRemote diff --git a/packages/api/gateway/src/index.ts b/packages/api/gateway/src/index.ts index 5899f5d560..ee4b063622 100644 --- a/packages/api/gateway/src/index.ts +++ b/packages/api/gateway/src/index.ts @@ -4,7 +4,7 @@ * @module @deepseek-ai/dsh-api-gateway */ -import { Context, Service, symbols } from 'cordis' +import { Context, Service, symbols } from '@deepseek-ai/cordis' import type { ConnectionRpcHandler } from '@deepseek-ai/dsh-client-connection' import { remoteMethods, diff --git a/packages/api/gateway/src/invariant.ts b/packages/api/gateway/src/invariant.ts index 711c4edab5..a09d2fa776 100644 --- a/packages/api/gateway/src/invariant.ts +++ b/packages/api/gateway/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-api-gateway' diff --git a/packages/api/gateway/src/types.ts b/packages/api/gateway/src/types.ts index 0917ba2ca6..7a63c8c45a 100644 --- a/packages/api/gateway/src/types.ts +++ b/packages/api/gateway/src/types.ts @@ -46,7 +46,7 @@ export interface TypertGateway { invoke(request: InvokeRemoteRequest): Promise } -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { /** Host dispatcher for TypeRT Remote calls. */ typertGateway: TypertGateway diff --git a/packages/api/gateway/tests/client.spec.ts b/packages/api/gateway/tests/client.spec.ts index 641ea81ebc..b253547c7d 100644 --- a/packages/api/gateway/tests/client.spec.ts +++ b/packages/api/gateway/tests/client.spec.ts @@ -1,4 +1,4 @@ -import { Context, Service } from 'cordis' +import { Context, Service } from '@deepseek-ai/cordis' import { describe, expect, it, vi } from 'vitest' import { z } from 'zod' import type { ConnectionHandle } from '@deepseek-ai/dsh-client-connection/client' diff --git a/packages/api/gateway/tests/gateway.spec.ts b/packages/api/gateway/tests/gateway.spec.ts index 4fa0ea80ad..38be5c822d 100644 --- a/packages/api/gateway/tests/gateway.spec.ts +++ b/packages/api/gateway/tests/gateway.spec.ts @@ -1,7 +1,7 @@ import { createServer } from 'node:http' import type { AddressInfo } from 'node:net' import { describe, expect, it } from 'vitest' -import { Context, Service, symbols } from 'cordis' +import { Context, Service, symbols } from '@deepseek-ai/cordis' import { z } from 'zod' import { apply as applyConnection, inject as connectionInject } from '@deepseek-ai/dsh-client-connection' import type { HttpServerService, WebRoute } from '@deepseek-ai/dsh-host-webserver' diff --git a/packages/api/remotes/package.json b/packages/api/remotes/package.json index 3112a1e7c6..2a1d92b82a 100644 --- a/packages/api/remotes/package.json +++ b/packages/api/remotes/package.json @@ -52,7 +52,7 @@ "@deepseek-ai/dsh-session": "^0.0.1", "@deepseek-ai/dsh-session-persistence": "^0.0.1", "@deepseek-ai/dsh-typert-registry": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-agent": "workspace:^", @@ -61,6 +61,6 @@ "@deepseek-ai/dsh-session": "workspace:^", "@deepseek-ai/dsh-session-persistence": "workspace:^", "@deepseek-ai/dsh-typert-registry": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/api/remotes/src/agent-lookup.ts b/packages/api/remotes/src/agent-lookup.ts index db765f3dde..c7b4018546 100644 --- a/packages/api/remotes/src/agent-lookup.ts +++ b/packages/api/remotes/src/agent-lookup.ts @@ -1,6 +1,6 @@ /** Host BFF policy for resolving Remote Agent and Session identities. */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { Agent, AgentOptions, AgentSetup } from '@deepseek-ai/dsh-agent' import type { Session, SessionEvent, SessionHeader, SessionId } from '@deepseek-ai/dsh-session' import type {} from '@deepseek-ai/dsh-session-persistence' diff --git a/packages/api/remotes/src/client/index.ts b/packages/api/remotes/src/client/index.ts index be92b02d77..ce67fb05d7 100644 --- a/packages/api/remotes/src/client/index.ts +++ b/packages/api/remotes/src/client/index.ts @@ -1,13 +1,13 @@ /** Platform-neutral assembly of generated Host Remote contributions. */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import goalsRemote from '@deepseek-ai/dsh-goal/remote' import type { TypeRTClientRemote } from '@deepseek-ai/dsh-type-meta' export type { TypeRTClientRemote as ClientRemote } from '@deepseek-ai/dsh-type-meta' export type {} from '@deepseek-ai/dsh-goal/remote' -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { /** Generated Remote namespaces selected by this Client assembly. */ remote: TypeRTClientRemote diff --git a/packages/api/remotes/src/invariant.ts b/packages/api/remotes/src/invariant.ts index 3310bed11f..f93b63e98b 100644 --- a/packages/api/remotes/src/invariant.ts +++ b/packages/api/remotes/src/invariant.ts @@ -1,7 +1,7 @@ /** Package-owned invariant companion for `@deepseek-ai/dsh-api-remotes`. */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-api-remotes' diff --git a/packages/api/remotes/tests/agent-lookup.spec.ts b/packages/api/remotes/tests/agent-lookup.spec.ts index 7179f5b2b2..ed403f7f4d 100644 --- a/packages/api/remotes/tests/agent-lookup.spec.ts +++ b/packages/api/remotes/tests/agent-lookup.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import AgentRegistry from '@deepseek-ai/dsh-agent' import type { Agent } from '@deepseek-ai/dsh-agent' import SessionStore from '@deepseek-ai/dsh-session' diff --git a/packages/api/remotes/tests/built-lib.e2e.ts b/packages/api/remotes/tests/built-lib.e2e.ts index af584cba7f..be76cd148c 100644 --- a/packages/api/remotes/tests/built-lib.e2e.ts +++ b/packages/api/remotes/tests/built-lib.e2e.ts @@ -45,7 +45,7 @@ describe.skipIf(!requiredArtifacts)('Goal Remote built LIB chain', () => { }).map(([key, path]) => [key, artifactUrl(path)])) const script = ` import { createServer } from 'node:http' - import * as cordis from 'cordis' + import * as cordis from '@deepseek-ai/cordis' const urls = ${JSON.stringify(urls)} const { Context } = cordis @@ -123,7 +123,7 @@ describe.skipIf(!requiredArtifacts)('Goal Remote built LIB chain', () => { const handoff = handoffs.get(id) if (handoff === undefined) throw new Error('missing Client bundle handoff ' + id) return handoff.factory(specifier => { - if (specifier === 'cordis') return cordis + if (specifier === '@deepseek-ai/cordis') return cordis throw new Error('unexpected Client external ' + specifier) }) } diff --git a/packages/attachment/attachment-local/package.json b/packages/attachment/attachment-local/package.json index 1834ef2d90..b11180f133 100644 --- a/packages/attachment/attachment-local/package.json +++ b/packages/attachment/attachment-local/package.json @@ -18,16 +18,16 @@ "@deepseek-ai/dsh-attachment": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-paths": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { - "schemastery": "^3.18.0", + "@deepseek-ai/schemastery": "^3.18.0", "sharp": "^0.35.3" }, "devDependencies": { "@deepseek-ai/dsh-attachment": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-paths": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/attachment/attachment-local/src/index.ts b/packages/attachment/attachment-local/src/index.ts index 7ed4824ef2..3d67041ea4 100644 --- a/packages/attachment/attachment-local/src/index.ts +++ b/packages/attachment/attachment-local/src/index.ts @@ -1,8 +1,8 @@ /** Local durable attachment backend rooted below `DSH_HOME`. @module @deepseek-ai/dsh-attachment-local */ import { join, resolve } from 'node:path' -import { Context } from 'cordis' -import z from 'schemastery' +import { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import { AttachmentStore } from '@deepseek-ai/dsh-attachment' import type { ImageAttachmentLimits, ImageAttachmentRef, SaveImageAttachment, StoredImageAttachment } from '@deepseek-ai/dsh-attachment' import { resolveDshHome } from '@deepseek-ai/dsh-paths' diff --git a/packages/attachment/attachment-local/src/invariant.ts b/packages/attachment/attachment-local/src/invariant.ts index eb14a84af6..2e37667801 100644 --- a/packages/attachment/attachment-local/src/invariant.ts +++ b/packages/attachment/attachment-local/src/invariant.ts @@ -1,7 +1,7 @@ /** Package-owned invariant companion for `@deepseek-ai/dsh-attachment-local`. @module @deepseek-ai/dsh-attachment-local/invariant */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-attachment-local' diff --git a/packages/attachment/attachment-local/tests/index.spec.ts b/packages/attachment/attachment-local/tests/index.spec.ts index 8aad68d2ff..e196966fa4 100644 --- a/packages/attachment/attachment-local/tests/index.spec.ts +++ b/packages/attachment/attachment-local/tests/index.spec.ts @@ -1,4 +1,4 @@ -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { existsSync } from 'node:fs' import { mkdtemp, rm } from 'node:fs/promises' import { tmpdir } from 'node:os' diff --git a/packages/attachment/attachment/package.json b/packages/attachment/attachment/package.json index 66cecc1894..4ec0fee955 100644 --- a/packages/attachment/attachment/package.json +++ b/packages/attachment/attachment/package.json @@ -17,11 +17,11 @@ "peerDependencies": { "@deepseek-ai/dsh-brand": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-brand": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/attachment/attachment/src/index.ts b/packages/attachment/attachment/src/index.ts index 9b3b8dd92b..d2dc2dbd86 100644 --- a/packages/attachment/attachment/src/index.ts +++ b/packages/attachment/attachment/src/index.ts @@ -1,6 +1,6 @@ /** Durable attachment storage seam (`ctx.attachments`). @module @deepseek-ai/dsh-attachment */ -import { Context, Service } from 'cordis' +import { Context, Service } from '@deepseek-ai/cordis' import type { ImageAttachmentLimits, ImageAttachmentRef, @@ -19,7 +19,7 @@ export type { StoredImageAttachment, } from './types.ts' -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { attachments: AttachmentStore } diff --git a/packages/attachment/attachment/src/invariant.ts b/packages/attachment/attachment/src/invariant.ts index 2c00d56ece..a44607b093 100644 --- a/packages/attachment/attachment/src/invariant.ts +++ b/packages/attachment/attachment/src/invariant.ts @@ -1,7 +1,7 @@ /** Package-owned invariant companion for `@deepseek-ai/dsh-attachment`. @module @deepseek-ai/dsh-attachment/invariant */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-attachment' diff --git a/packages/bash/bash-env/README.i18n.yaml b/packages/bash/bash-env/README.i18n.yaml index e09b4b1405..2845459293 100644 --- a/packages/bash/bash-env/README.i18n.yaml +++ b/packages/bash/bash-env/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/bash/bash-env/README.md -README.md: 7b939326d4effd14fc83ef0ad4e133f019f1011f -README.zh.md: 4d80d9d34f2be18e07d57d2427eb841f61f1ccfc +README.md: 54758a91773aad723c6fbbebe2ffe25aedb38599 +README.zh.md: e0663b003e94942c76cde4fb7867ed0ce74c2aa2 diff --git a/packages/bash/bash-env/README.md b/packages/bash/bash-env/README.md index 7b939326d4..54758a9177 100644 --- a/packages/bash/bash-env/README.md +++ b/packages/bash/bash-env/README.md @@ -22,7 +22,7 @@ Every foreground and background model shell call receives a newly collected trus `ctx.bashEnv` owns collection. Other plugins can register an effect-scoped contributor with a stable name, declared keys/descriptions, and `resolve(execution: ToolExecution)`; duplicate ownership and undeclared runtime keys fail loudly, while `list()` enumerates declarations without executing providers. Harness built-ins reserve `DSH_HOME`, `DSH_SHELL`, and `DSH_SESSION_ID`; this plugin's persistence translator owns `DSH_SESSION_JSONL` by reading the backend-neutral `sessionPersistence.locate()` seam. ```ts -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type {} from '@deepseek-ai/dsh-bash-env' export const inject = ['bashEnv'] diff --git a/packages/bash/bash-env/README.zh.md b/packages/bash/bash-env/README.zh.md index 4d80d9d34f..e0663b003e 100644 --- a/packages/bash/bash-env/README.zh.md +++ b/packages/bash/bash-env/README.zh.md @@ -22,7 +22,7 @@ `ctx.bashEnv` 负责收集。其他插件可以注册一个受 effect 作用域约束的 contributor,带有稳定名称、已声明的键/描述以及 `resolve(execution: ToolExecution)`;重复所有权与未声明的运行时键会响亮失败,而 `list()` 只枚举声明、不执行 provider。Harness 内置键保留 `DSH_HOME`、`DSH_SHELL` 与 `DSH_SESSION_ID`;本插件的持久化翻译器通过读取与后端无关的 `sessionPersistence.locate()` seam 拥有 `DSH_SESSION_JSONL`。 ```ts -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type {} from '@deepseek-ai/dsh-bash-env' export const inject = ['bashEnv'] diff --git a/packages/bash/bash-env/package.json b/packages/bash/bash-env/package.json index 33243ab344..b2de167a64 100644 --- a/packages/bash/bash-env/package.json +++ b/packages/bash/bash-env/package.json @@ -30,10 +30,10 @@ "@deepseek-ai/dsh-paths": "^0.0.1", "@deepseek-ai/dsh-session-persistence": "^0.0.1", "@deepseek-ai/dsh-tools": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { "@deepseek-ai/dsh-agent": "workspace:^", @@ -43,6 +43,6 @@ "@deepseek-ai/dsh-paths": "workspace:^", "@deepseek-ai/dsh-session-persistence": "workspace:^", "@deepseek-ai/dsh-tools": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/bash/bash-env/src/index.ts b/packages/bash/bash-env/src/index.ts index c7caa89f08..6bdbbc2623 100644 --- a/packages/bash/bash-env/src/index.ts +++ b/packages/bash/bash-env/src/index.ts @@ -8,15 +8,15 @@ * @module @deepseek-ai/dsh-bash-env */ -import { Service, type Context } from 'cordis' -import z from 'schemastery' +import { Service, type Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import { DSH_ENV_PREFIX } from '@deepseek-ai/dsh-bash' import type { DshEnvironment, DshEnvironmentKey } from '@deepseek-ai/dsh-bash' import { DSH_HOME_ENV, resolveDshHome } from '@deepseek-ai/dsh-paths' import type { ToolExecution } from '@deepseek-ai/dsh-tools' import type {} from '@deepseek-ai/dsh-session-persistence' -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { bashEnv: BashEnvRegistry } diff --git a/packages/bash/bash-env/src/invariant.ts b/packages/bash/bash-env/src/invariant.ts index 31f842c56d..fff86f91c1 100644 --- a/packages/bash/bash-env/src/invariant.ts +++ b/packages/bash/bash-env/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-bash-env' diff --git a/packages/bash/bash-env/tests/bash-env.spec.ts b/packages/bash/bash-env/tests/bash-env.spec.ts index eb482fd9d3..ab7905fa13 100644 --- a/packages/bash/bash-env/tests/bash-env.spec.ts +++ b/packages/bash/bash-env/tests/bash-env.spec.ts @@ -7,7 +7,7 @@ import { homedir } from 'node:os' import { join, resolve } from 'node:path' import { afterEach, describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { CallId } from '@deepseek-ai/dsh-llm' import type { Agent } from '@deepseek-ai/dsh-agent' import type { ToolExecution } from '@deepseek-ai/dsh-tools' diff --git a/packages/bash/bash-local/package.json b/packages/bash/bash-local/package.json index c3c3a5c3e6..2a19e4da5d 100644 --- a/packages/bash/bash-local/package.json +++ b/packages/bash/bash-local/package.json @@ -29,10 +29,10 @@ "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-subprocess": "^0.0.1", "@deepseek-ai/dsh-timeout": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { "@deepseek-ai/dsh-bash": "workspace:^", @@ -40,6 +40,6 @@ "@deepseek-ai/dsh-subprocess": "workspace:^", "@deepseek-ai/dsh-subprocess-local": "workspace:^", "@deepseek-ai/dsh-timeout": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/bash/bash-local/src/index.ts b/packages/bash/bash-local/src/index.ts index 3d3ca833bc..2c8e200fc3 100644 --- a/packages/bash/bash-local/src/index.ts +++ b/packages/bash/bash-local/src/index.ts @@ -9,8 +9,8 @@ * @module @deepseek-ai/dsh-bash-local */ -import { Context } from 'cordis' -import z from 'schemastery' +import { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import { BashExecutor } from '@deepseek-ai/dsh-bash' import type { BashExecRequest, BashExecSpec, BashProcess, BashProcessRead, BashRunResult, CollectedOutput } from '@deepseek-ai/dsh-bash' import type { SubprocessCollect, SubprocessHandle, SubprocessOutputReader, SubprocessSpawnSpec } from '@deepseek-ai/dsh-subprocess' diff --git a/packages/bash/bash-local/src/invariant.ts b/packages/bash/bash-local/src/invariant.ts index 3cc7bd62e2..55905cbf5e 100644 --- a/packages/bash/bash-local/src/invariant.ts +++ b/packages/bash/bash-local/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-bash-local' diff --git a/packages/bash/bash-local/tests/executor.spec.ts b/packages/bash/bash-local/tests/executor.spec.ts index af5566086f..607eb48dd1 100644 --- a/packages/bash/bash-local/tests/executor.spec.ts +++ b/packages/bash/bash-local/tests/executor.spec.ts @@ -2,7 +2,7 @@ import { mkdtempSync } from 'node:fs' import { tmpdir } from 'node:os' import { join } from 'node:path' import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { LocalBashExecutor } from '@deepseek-ai/dsh-bash-local' import LocalSubprocessService from '@deepseek-ai/dsh-subprocess-local' import { MAX_TIMER_DELAY_MS } from '@deepseek-ai/dsh-timeout' diff --git a/packages/bash/bash-sandbox/package.json b/packages/bash/bash-sandbox/package.json index a771acb1d3..b37f9dc48e 100644 --- a/packages/bash/bash-sandbox/package.json +++ b/packages/bash/bash-sandbox/package.json @@ -30,7 +30,7 @@ "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-sandbox": "^0.0.1", "@deepseek-ai/dsh-sandbox-policy": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-bash": "workspace:^", @@ -40,7 +40,7 @@ "@deepseek-ai/dsh-sandbox": "workspace:^", "@deepseek-ai/dsh-sandbox-local": "workspace:^", "@deepseek-ai/dsh-sandbox-policy": "workspace:^", - "cordis": "^4.0.0-rc.7", + "@deepseek-ai/cordis": "^4.0.0-rc.7", "@deepseek-ai/node-addon-landlock-run": "workspace:*" } } diff --git a/packages/bash/bash-sandbox/src/index.ts b/packages/bash/bash-sandbox/src/index.ts index dc299f49c3..95e8807e1e 100644 --- a/packages/bash/bash-sandbox/src/index.ts +++ b/packages/bash/bash-sandbox/src/index.ts @@ -8,7 +8,7 @@ * @module @deepseek-ai/dsh-bash-sandbox */ -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import type { BashExecRequest, BashExecSpec, BashProcess, BashRunResult } from '@deepseek-ai/dsh-bash' import { SandboxUnavailableError } from '@deepseek-ai/dsh-sandbox' import type { diff --git a/packages/bash/bash-sandbox/src/invariant.ts b/packages/bash/bash-sandbox/src/invariant.ts index b79b626033..4592d633af 100644 --- a/packages/bash/bash-sandbox/src/invariant.ts +++ b/packages/bash/bash-sandbox/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-bash-sandbox' diff --git a/packages/bash/bash-sandbox/tests/bwrap.e2e.ts b/packages/bash/bash-sandbox/tests/bwrap.e2e.ts index 437078440c..2e6567b8d8 100644 --- a/packages/bash/bash-sandbox/tests/bwrap.e2e.ts +++ b/packages/bash/bash-sandbox/tests/bwrap.e2e.ts @@ -4,7 +4,7 @@ import { mkdtemp, rm } from 'node:fs/promises' import { homedir } from 'node:os' import { join } from 'node:path' import { afterEach, describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { LocalSandboxProvider } from '@deepseek-ai/dsh-sandbox-local' import { SandboxPolicyService } from '@deepseek-ai/dsh-sandbox-policy' import { bwrapProfileArgs } from '@deepseek-ai/dsh-sandbox-local/src/profiles.ts' diff --git a/packages/bash/bash-sandbox/tests/landlock.e2e.ts b/packages/bash/bash-sandbox/tests/landlock.e2e.ts index 7255ee43c9..e9c25b13e5 100644 --- a/packages/bash/bash-sandbox/tests/landlock.e2e.ts +++ b/packages/bash/bash-sandbox/tests/landlock.e2e.ts @@ -4,7 +4,7 @@ import { mkdtemp, rm } from 'node:fs/promises' import { homedir, tmpdir } from 'node:os' import { join } from 'node:path' import { afterEach, describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { launcherPath } from '@deepseek-ai/node-addon-landlock-run' import { LocalSandboxProvider } from '@deepseek-ai/dsh-sandbox-local' import { SandboxPolicyService } from '@deepseek-ai/dsh-sandbox-policy' diff --git a/packages/bash/bash-sandbox/tests/partial-landlock.spec.ts b/packages/bash/bash-sandbox/tests/partial-landlock.spec.ts index 9176ac320b..7bb63eeb57 100644 --- a/packages/bash/bash-sandbox/tests/partial-landlock.spec.ts +++ b/packages/bash/bash-sandbox/tests/partial-landlock.spec.ts @@ -8,7 +8,7 @@ import { mkdtemp, rm, writeFile } from 'node:fs/promises' import { tmpdir } from 'node:os' import { join } from 'node:path' import { afterEach, describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { LAUNCHER_FAILURE_EXIT } from '@deepseek-ai/node-addon-landlock-run' import { SANDBOX_UNAVAILABLE, SandboxUnavailableError } from '@deepseek-ai/dsh-sandbox' import { LocalSandboxProvider } from '@deepseek-ai/dsh-sandbox-local' diff --git a/packages/bash/bash-sandbox/tests/sandbox.spec.ts b/packages/bash/bash-sandbox/tests/sandbox.spec.ts index 9c3eceda1e..a0dbec3645 100644 --- a/packages/bash/bash-sandbox/tests/sandbox.spec.ts +++ b/packages/bash/bash-sandbox/tests/sandbox.spec.ts @@ -9,7 +9,7 @@ import { chmodSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync import { tmpdir } from 'node:os' import { join, resolve } from 'node:path' import { describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import type { BashRunResult, CollectedOutput } from '@deepseek-ai/dsh-bash' import { SANDBOX_UNAVAILABLE, SandboxProvider, SandboxUnavailableError } from '@deepseek-ai/dsh-sandbox' import type { ConfinedArgv, SandboxExecutionPolicy, SandboxMode, SandboxPolicy } from '@deepseek-ai/dsh-sandbox' diff --git a/packages/bash/bash-sandbox/tests/seatbelt.e2e.ts b/packages/bash/bash-sandbox/tests/seatbelt.e2e.ts index c03e407986..e3d91fb33a 100644 --- a/packages/bash/bash-sandbox/tests/seatbelt.e2e.ts +++ b/packages/bash/bash-sandbox/tests/seatbelt.e2e.ts @@ -4,7 +4,7 @@ import { mkdtemp, rm, writeFile } from 'node:fs/promises' import { homedir } from 'node:os' import { join } from 'node:path' import { afterEach, describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { LocalSandboxProvider } from '@deepseek-ai/dsh-sandbox-local' import { SandboxPolicyService } from '@deepseek-ai/dsh-sandbox-policy' import { seatbeltProfileArgs } from '@deepseek-ai/dsh-sandbox-local/src/profiles.ts' diff --git a/packages/bash/bash/package.json b/packages/bash/bash/package.json index 71e9ed8d9f..d184a18d7b 100644 --- a/packages/bash/bash/package.json +++ b/packages/bash/bash/package.json @@ -28,12 +28,12 @@ "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-subprocess": "^0.0.1", "@deepseek-ai/dsh-sandbox": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-subprocess": "workspace:^", "@deepseek-ai/dsh-sandbox": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/bash/bash/src/index.ts b/packages/bash/bash/src/index.ts index 73f3d7b519..30d5840052 100644 --- a/packages/bash/bash/src/index.ts +++ b/packages/bash/bash/src/index.ts @@ -5,7 +5,7 @@ * @module @deepseek-ai/dsh-bash */ -import { Context, Service } from 'cordis' +import { Context, Service } from '@deepseek-ai/cordis' import type { SandboxMode } from '@deepseek-ai/dsh-sandbox' import type { BashExecRequest, BashExecSpec, BashProcess, BashRunResult } from './types.ts' @@ -25,7 +25,7 @@ export type { export { parseExitStatus } from './render.ts' export type { ParsedExitStatus } from './render.ts' -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { bash: BashExecutor } diff --git a/packages/bash/bash/src/invariant.ts b/packages/bash/bash/src/invariant.ts index acf00f48a4..35f0382061 100644 --- a/packages/bash/bash/src/invariant.ts +++ b/packages/bash/bash/src/invariant.ts @@ -1,6 +1,6 @@ /** Package-owned invariant companion for the bash seam. @module @deepseek-ai/dsh-bash/invariant */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-bash' diff --git a/packages/bash/bash/tests/service.spec.ts b/packages/bash/bash/tests/service.spec.ts index cacfe85eca..2306c0293d 100644 --- a/packages/bash/bash/tests/service.spec.ts +++ b/packages/bash/bash/tests/service.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { BashExecutor } from '@deepseek-ai/dsh-bash' import type { BashExecRequest, BashExecSpec, BashProcess, BashProcessRead, BashRunResult } from '@deepseek-ai/dsh-bash' diff --git a/packages/bash/pwsh-local/package.json b/packages/bash/pwsh-local/package.json index f65d524904..ecfa7f11da 100644 --- a/packages/bash/pwsh-local/package.json +++ b/packages/bash/pwsh-local/package.json @@ -29,10 +29,10 @@ "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-subprocess": "^0.0.1", "@deepseek-ai/dsh-timeout": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { "@deepseek-ai/dsh-bash": "workspace:^", @@ -40,6 +40,6 @@ "@deepseek-ai/dsh-subprocess": "workspace:^", "@deepseek-ai/dsh-subprocess-local": "workspace:^", "@deepseek-ai/dsh-timeout": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/bash/pwsh-local/src/index.ts b/packages/bash/pwsh-local/src/index.ts index 5983500772..16f5c4479f 100644 --- a/packages/bash/pwsh-local/src/index.ts +++ b/packages/bash/pwsh-local/src/index.ts @@ -13,8 +13,8 @@ * @module @deepseek-ai/dsh-pwsh-local */ -import { Context } from 'cordis' -import z from 'schemastery' +import { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import { BashExecutor } from '@deepseek-ai/dsh-bash' import type { BashExecRequest, BashExecSpec, BashProcess, BashProcessRead, BashRunResult, CollectedOutput } from '@deepseek-ai/dsh-bash' import type { SubprocessCollect, SubprocessHandle, SubprocessOutputReader, SubprocessSpawnSpec } from '@deepseek-ai/dsh-subprocess' diff --git a/packages/bash/pwsh-local/src/invariant.ts b/packages/bash/pwsh-local/src/invariant.ts index 4bb1c1ea30..9b6db9426b 100644 --- a/packages/bash/pwsh-local/src/invariant.ts +++ b/packages/bash/pwsh-local/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-pwsh-local' diff --git a/packages/bash/pwsh-local/tests/executor.spec.ts b/packages/bash/pwsh-local/tests/executor.spec.ts index ef5e972fc0..6f38af8153 100644 --- a/packages/bash/pwsh-local/tests/executor.spec.ts +++ b/packages/bash/pwsh-local/tests/executor.spec.ts @@ -14,7 +14,7 @@ import { tmpdir } from 'node:os' import { join } from 'node:path' import { spawnSync } from 'node:child_process' import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { PwshLocalExecutor, ENCODING_PREAMBLE, candidatePwshPaths, resolvePwshPath } from '@deepseek-ai/dsh-pwsh-local' import LocalSubprocessService from '@deepseek-ai/dsh-subprocess-local' import SubprocessService from '@deepseek-ai/dsh-subprocess' diff --git a/packages/bash/pwsh-sandbox/package.json b/packages/bash/pwsh-sandbox/package.json index 6f2a87fc58..fbc5227912 100644 --- a/packages/bash/pwsh-sandbox/package.json +++ b/packages/bash/pwsh-sandbox/package.json @@ -30,7 +30,7 @@ "@deepseek-ai/dsh-pwsh-local": "^0.0.1", "@deepseek-ai/dsh-sandbox": "^0.0.1", "@deepseek-ai/dsh-sandbox-policy": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-bash": "workspace:^", @@ -40,6 +40,6 @@ "@deepseek-ai/dsh-sandbox-local": "workspace:^", "@deepseek-ai/dsh-sandbox-policy": "workspace:^", "@deepseek-ai/dsh-subprocess-local": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/bash/pwsh-sandbox/src/index.ts b/packages/bash/pwsh-sandbox/src/index.ts index 7a930b7f0e..ec45571b76 100644 --- a/packages/bash/pwsh-sandbox/src/index.ts +++ b/packages/bash/pwsh-sandbox/src/index.ts @@ -12,7 +12,7 @@ * @module @deepseek-ai/dsh-pwsh-sandbox */ -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import type { BashExecRequest, BashExecSpec, BashProcess, BashRunResult } from '@deepseek-ai/dsh-bash' import { SandboxUnavailableError } from '@deepseek-ai/dsh-sandbox' import type { diff --git a/packages/bash/pwsh-sandbox/src/invariant.ts b/packages/bash/pwsh-sandbox/src/invariant.ts index 6afda519ff..9d229d1f0d 100644 --- a/packages/bash/pwsh-sandbox/src/invariant.ts +++ b/packages/bash/pwsh-sandbox/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-pwsh-sandbox' diff --git a/packages/bash/pwsh-sandbox/tests/acl.e2e.ts b/packages/bash/pwsh-sandbox/tests/acl.e2e.ts index bb6f4f25e4..516895c6fa 100644 --- a/packages/bash/pwsh-sandbox/tests/acl.e2e.ts +++ b/packages/bash/pwsh-sandbox/tests/acl.e2e.ts @@ -12,7 +12,7 @@ import { existsSync, mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node: import { homedir, tmpdir } from 'node:os' import { join } from 'node:path' import { afterAll, beforeAll, describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import type { SandboxExecutionPolicy } from '@deepseek-ai/dsh-sandbox' import { resolvePwshPath } from '@deepseek-ai/dsh-pwsh-local' import { LocalSandboxProvider } from '@deepseek-ai/dsh-sandbox-local' diff --git a/packages/bash/pwsh-sandbox/tests/sandbox.spec.ts b/packages/bash/pwsh-sandbox/tests/sandbox.spec.ts index d710801004..fc4cd295a7 100644 --- a/packages/bash/pwsh-sandbox/tests/sandbox.spec.ts +++ b/packages/bash/pwsh-sandbox/tests/sandbox.spec.ts @@ -11,7 +11,7 @@ import { chmodSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs' import { tmpdir } from 'node:os' import { join } from 'node:path' import { afterAll, describe, expect, it } from 'vitest' -import { Context, Service } from 'cordis' +import { Context, Service } from '@deepseek-ai/cordis' import { SandboxProvider, SandboxUnavailableError } from '@deepseek-ai/dsh-sandbox' import type { ConfinedArgv, RunnerFailureRule, SandboxExecutionPolicy, SandboxPolicy } from '@deepseek-ai/dsh-sandbox' import { resolvePwshPath } from '@deepseek-ai/dsh-pwsh-local' diff --git a/packages/bash/tool-bash/package.json b/packages/bash/tool-bash/package.json index 2e304ae913..bd467f103e 100644 --- a/packages/bash/tool-bash/package.json +++ b/packages/bash/tool-bash/package.json @@ -36,10 +36,10 @@ "@deepseek-ai/dsh-tasks": "^0.0.1", "@deepseek-ai/dsh-tools": "^0.0.1", "@deepseek-ai/dsh-user-approval": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { "@deepseek-ai/dsh-agent": "workspace:^", @@ -61,6 +61,6 @@ "@deepseek-ai/dsh-tool-tasks": "workspace:^", "@deepseek-ai/dsh-tools": "workspace:^", "@deepseek-ai/dsh-user-approval": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/bash/tool-bash/src/index.ts b/packages/bash/tool-bash/src/index.ts index 69dae2915a..378b286ac7 100644 --- a/packages/bash/tool-bash/src/index.ts +++ b/packages/bash/tool-bash/src/index.ts @@ -8,8 +8,8 @@ * @module @deepseek-ai/dsh-tool-bash */ -import type { Context } from 'cordis' -import z from 'schemastery' +import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import { isAbsolute, resolve as resolvePath } from 'node:path' import { defineTool, TOOL_ABORTED } from '@deepseek-ai/dsh-tools' import type { GenericCallView, TerminalCallView, ToolExecution, ToolResult, ToolResultView } from '@deepseek-ai/dsh-tools' diff --git a/packages/bash/tool-bash/src/invariant.ts b/packages/bash/tool-bash/src/invariant.ts index 0620f0cfa9..a4ce0c34eb 100644 --- a/packages/bash/tool-bash/src/invariant.ts +++ b/packages/bash/tool-bash/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-tool-bash' diff --git a/packages/bash/tool-bash/tests/integration.spec.ts b/packages/bash/tool-bash/tests/integration.spec.ts index 99510dc6e5..425fa0644f 100644 --- a/packages/bash/tool-bash/tests/integration.spec.ts +++ b/packages/bash/tool-bash/tests/integration.spec.ts @@ -1,6 +1,6 @@ import { createUserMessage } from '@deepseek-ai/dsh-llm' import { afterEach, describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { existsSync, mkdtempSync, readFileSync, rmSync } from 'node:fs' import { tmpdir } from 'node:os' import { join } from 'node:path' diff --git a/packages/bash/tool-bash/tests/tools.spec.ts b/packages/bash/tool-bash/tests/tools.spec.ts index 9a1698ac1d..f03de1ca93 100644 --- a/packages/bash/tool-bash/tests/tools.spec.ts +++ b/packages/bash/tool-bash/tests/tools.spec.ts @@ -2,7 +2,7 @@ import { mkdtempSync } from 'node:fs' import { tmpdir } from 'node:os' import { join } from 'node:path' import { describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { CallId } from '@deepseek-ai/dsh-llm' import { BashExecutor } from '@deepseek-ai/dsh-bash' import type { BashExecRequest, BashExecSpec, BashProcess, BashProcessRead, BashRunResult } from '@deepseek-ai/dsh-bash' diff --git a/packages/bash/tool-pwsh/package.json b/packages/bash/tool-pwsh/package.json index 042166b493..7f18585332 100644 --- a/packages/bash/tool-pwsh/package.json +++ b/packages/bash/tool-pwsh/package.json @@ -36,10 +36,10 @@ "@deepseek-ai/dsh-tasks": "^0.0.1", "@deepseek-ai/dsh-tools": "^0.0.1", "@deepseek-ai/dsh-user-approval": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { "@deepseek-ai/dsh-agent": "workspace:^", @@ -58,6 +58,6 @@ "@deepseek-ai/dsh-tool-tasks": "workspace:^", "@deepseek-ai/dsh-tools": "workspace:^", "@deepseek-ai/dsh-user-approval": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/bash/tool-pwsh/src/index.ts b/packages/bash/tool-pwsh/src/index.ts index 9ef6650748..6f1cc14a37 100644 --- a/packages/bash/tool-pwsh/src/index.ts +++ b/packages/bash/tool-pwsh/src/index.ts @@ -20,8 +20,8 @@ */ import { isAbsolute, resolve as resolvePath } from 'node:path' -import type { Context } from 'cordis' -import z from 'schemastery' +import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import { defineTool, TOOL_ABORTED } from '@deepseek-ai/dsh-tools' import type { GenericCallView, TerminalCallView, ToolExecution, ToolResult, ToolResultView } from '@deepseek-ai/dsh-tools' import { HarnessError } from '@deepseek-ai/dsh-llm' diff --git a/packages/bash/tool-pwsh/src/invariant.ts b/packages/bash/tool-pwsh/src/invariant.ts index dd6370b490..aa53743ba7 100644 --- a/packages/bash/tool-pwsh/src/invariant.ts +++ b/packages/bash/tool-pwsh/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-tool-pwsh' diff --git a/packages/bash/tool-pwsh/tests/integration.spec.ts b/packages/bash/tool-pwsh/tests/integration.spec.ts index c347866f50..d2a89468ff 100644 --- a/packages/bash/tool-pwsh/tests/integration.spec.ts +++ b/packages/bash/tool-pwsh/tests/integration.spec.ts @@ -14,7 +14,7 @@ import { mkdtemp, rm, writeFile } from 'node:fs/promises' import { tmpdir } from 'node:os' import { join } from 'node:path' import { spawnSync } from 'node:child_process' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { CallId } from '@deepseek-ai/dsh-llm' import SystemPrompt from '@deepseek-ai/dsh-system-prompt' import ToolRegistry, { TOOL_ABORTED } from '@deepseek-ai/dsh-tools' diff --git a/packages/bash/tool-pwsh/tests/tools.spec.ts b/packages/bash/tool-pwsh/tests/tools.spec.ts index 7ecdbcd5f2..e6480652f9 100644 --- a/packages/bash/tool-pwsh/tests/tools.spec.ts +++ b/packages/bash/tool-pwsh/tests/tools.spec.ts @@ -11,7 +11,7 @@ */ import { describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { mkdtempSync, realpathSync } from 'node:fs' import { tmpdir } from 'node:os' import { join, resolve as resolvePath } from 'node:path' diff --git a/packages/boot/app-boot/package.json b/packages/boot/app-boot/package.json index c33dc878b8..0295742268 100644 --- a/packages/boot/app-boot/package.json +++ b/packages/boot/app-boot/package.json @@ -28,32 +28,32 @@ "js-yaml": "^4.2.0" }, "peerDependencies": { - "@cordisjs/plugin-group": "^1.0.0", - "@cordisjs/plugin-hmr": "^1.0.15", - "@cordisjs/plugin-include": "^1.0.4", - "@cordisjs/plugin-loader": "^1.0.0-rc.5", + "@deepseek-ai/cordis-plugin-group": "^1.0.0", + "@deepseek-ai/cordis-plugin-hmr": "^1.0.15", + "@deepseek-ai/cordis-plugin-include": "^1.0.4", + "@deepseek-ai/cordis-plugin-loader": "^1.0.0-rc.5", "@deepseek-ai/dsh-environment": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-paths": "^0.0.1", "@deepseek-ai/dsh-system-prompt": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "peerDependenciesMeta": { - "@cordisjs/plugin-hmr": { + "@deepseek-ai/cordis-plugin-hmr": { "optional": true } }, "devDependencies": { - "@cordisjs/plugin-group": "workspace:^", - "@cordisjs/plugin-hmr": "workspace:^", - "@cordisjs/plugin-include": "workspace:^", - "@cordisjs/plugin-loader": "workspace:^", - "@cordisjs/plugin-timer": "workspace:^", + "@deepseek-ai/cordis-plugin-group": "workspace:^", + "@deepseek-ai/cordis-plugin-hmr": "workspace:^", + "@deepseek-ai/cordis-plugin-include": "workspace:^", + "@deepseek-ai/cordis-plugin-loader": "workspace:^", + "@deepseek-ai/cordis-plugin-timer": "workspace:^", "@deepseek-ai/dsh-environment": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-paths": "workspace:^", "@deepseek-ai/dsh-system-prompt": "workspace:^", "@types/js-yaml": "^4.0.9", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/boot/app-boot/src/index.ts b/packages/boot/app-boot/src/index.ts index fa23e6f8da..9de8c7765d 100644 --- a/packages/boot/app-boot/src/index.ts +++ b/packages/boot/app-boot/src/index.ts @@ -11,17 +11,17 @@ import { readFileSync } from 'node:fs' import { parseEnv } from 'node:util' import { basename, dirname, resolve } from 'node:path' import * as yaml from 'js-yaml' -import { Context, type FiberState } from 'cordis' -import Loader, { type Entry, type EntryOptions } from '@cordisjs/plugin-loader' -import Include, { applyEntryPatches, entryListSchema, type PatchOptions } from '@cordisjs/plugin-include' -import Group from '@cordisjs/plugin-group' +import { Context, type FiberState } from '@deepseek-ai/cordis' +import Loader, { type Entry, type EntryOptions } from '@deepseek-ai/cordis-plugin-loader' +import Include, { applyEntryPatches, entryListSchema, type PatchOptions } from '@deepseek-ai/cordis-plugin-include' +import Group from '@deepseek-ai/cordis-plugin-group' import { dshHomePath, resolveDshHome } from '@deepseek-ai/dsh-paths' import { createEnvironmentSnapshot, type EnvironmentSnapshot } from '@deepseek-ai/dsh-environment' -import type {} from '@cordisjs/plugin-hmr' +import type {} from '@deepseek-ai/cordis-plugin-hmr' // Side-effect type import: resolves `ctx.get('systemPrompt')` to the service. import type {} from '@deepseek-ai/dsh-system-prompt' -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { /** Harness-home path resolver available to Loader `!!js` config expressions. */ dshHomePath?: typeof dshHomePath @@ -265,7 +265,7 @@ export async function watchUserPatches( /** * Load an optional patch-list file: a top-level YAML array of loader patch - * entries (`@cordisjs/plugin-include`'s `PatchOptions`): id-targeted config + * entries (`@deepseek-ai/cordis-plugin-include`'s `PatchOptions`): id-targeted config * overrides and `insert` lists, with `!!js` expressions allowed. A missing * file means "no layer"; an unreadable, unparsable, or non-array file throws — * a present patch file that cannot apply is a misconfiguration and must fail @@ -305,7 +305,7 @@ export function loadOverlayPatches(binName: string, file: string): PatchOptions[ } /** * Parse one loader patch list: a top-level YAML array of - * `@cordisjs/plugin-include` `PatchOptions` (id-targeted config overrides and + * `@deepseek-ai/cordis-plugin-include` `PatchOptions` (id-targeted config overrides and * `insert` lists, `!!js` expressions allowed). Every invalid field or value throws, * because a patch file that cannot be applied at all is a misconfiguration; a * single patch whose target row is absent stays a per-entry Loader warning, so @@ -488,7 +488,7 @@ export async function mountRootInclude( ctx.loader.builtins.include = Include // `cordis:group` alongside it: a group row is how a composition gives one // `isolate` realm to a provider and its consumers together, and an agent - // preset living outside this workspace cannot resolve `@cordisjs/plugin-group` + // preset living outside this workspace cannot resolve `@deepseek-ai/cordis-plugin-group` // by name. Both builtins load through the ambient module pipeline, so neither // depends on the included tree's own specifier resolution. ctx.loader.builtins.group = Group diff --git a/packages/boot/app-boot/src/invariant.ts b/packages/boot/app-boot/src/invariant.ts index 0dacba6e40..8195ecb553 100644 --- a/packages/boot/app-boot/src/invariant.ts +++ b/packages/boot/app-boot/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-app-boot' diff --git a/packages/boot/app-boot/src/profile.ts b/packages/boot/app-boot/src/profile.ts index 486d414749..e19bb13c41 100644 --- a/packages/boot/app-boot/src/profile.ts +++ b/packages/boot/app-boot/src/profile.ts @@ -27,8 +27,8 @@ import { existsSync, lstatSync, mkdirSync, readFileSync, readlinkSync, rmSync, symlinkSync, writeFileSync, } from 'node:fs' import { basename, dirname, join } from 'node:path' -import type { EntryOptions } from '@cordisjs/plugin-loader' -import { applyEntryPatches, type PatchOptions } from '@cordisjs/plugin-include' +import type { EntryOptions } from '@deepseek-ai/cordis-plugin-loader' +import { applyEntryPatches, type PatchOptions } from '@deepseek-ai/cordis-plugin-include' import { resolveDshHome } from '@deepseek-ai/dsh-paths' import { loadOverlayPatches } from './index.ts' diff --git a/packages/boot/app-boot/tests/app-boot.spec.ts b/packages/boot/app-boot/tests/app-boot.spec.ts index baeb98fe77..301a42cdc1 100644 --- a/packages/boot/app-boot/tests/app-boot.spec.ts +++ b/packages/boot/app-boot/tests/app-boot.spec.ts @@ -2,7 +2,7 @@ import { mkdtempSync, mkdirSync, writeFileSync } from 'node:fs' import { tmpdir } from 'node:os' import { join, resolve, sep } from 'node:path' import { describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import SystemPrompt, { renderPrompt } from '@deepseek-ai/dsh-system-prompt' import { addHarnessSourceSection, assertEntriesActivated, assertEntriesLoaded, boot, diff --git a/packages/boot/app-boot/tests/config-dump.spec.ts b/packages/boot/app-boot/tests/config-dump.spec.ts index 3876ec2421..ed0117b0dc 100644 --- a/packages/boot/app-boot/tests/config-dump.spec.ts +++ b/packages/boot/app-boot/tests/config-dump.spec.ts @@ -12,7 +12,7 @@ import { tmpdir } from 'node:os' import { join } from 'node:path' import { describe, expect, it, vi } from 'vitest' import * as yaml from 'js-yaml' -import { entryListSchema } from '@cordisjs/plugin-include' +import { entryListSchema } from '@deepseek-ai/cordis-plugin-include' import { loadOverlayPatches, renderConfigDump } from '../src/index.ts' const NAME = 'dsh-test-bin' diff --git a/packages/boot/app-boot/tests/config-reload.spec.ts b/packages/boot/app-boot/tests/config-reload.spec.ts index 9cbe3d1a58..ca718a65b3 100644 --- a/packages/boot/app-boot/tests/config-reload.spec.ts +++ b/packages/boot/app-boot/tests/config-reload.spec.ts @@ -8,8 +8,8 @@ import { mkdtempSync, writeFileSync } from 'node:fs' import { tmpdir } from 'node:os' import { join } from 'node:path' import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' -import type { Include } from '@cordisjs/plugin-include' +import { Context } from '@deepseek-ai/cordis' +import type { Include } from '@deepseek-ai/cordis-plugin-include' import { boot } from '../src/index.ts' const NAME = 'dsh-test-bin' @@ -391,7 +391,7 @@ describe('shipped builtins', () => { it('lets a booted composition share one isolate realm across a group of rows', async () => { // The reason `boot()` registers `cordis:group`: a composition — notably an // agent preset living outside this workspace, which cannot resolve - // `@cordisjs/plugin-group` by name — gives a provider and its consumer one + // `@deepseek-ai/cordis-plugin-group` by name — gives a provider and its consumer one // named realm so the service stays out of the root realm while remaining // visible to the rows that need it. const { ctx } = await bootTree([ diff --git a/packages/boot/app-boot/tests/hmr-config.spec.ts b/packages/boot/app-boot/tests/hmr-config.spec.ts index 82cbd71c28..c248643130 100644 --- a/packages/boot/app-boot/tests/hmr-config.spec.ts +++ b/packages/boot/app-boot/tests/hmr-config.spec.ts @@ -3,10 +3,10 @@ import { realpath } from 'node:fs/promises' import { tmpdir } from 'node:os' import { join } from 'node:path' import { pathToFileURL } from 'node:url' -import { Context } from 'cordis' -import Hmr from '@cordisjs/plugin-hmr' -import Loader from '@cordisjs/plugin-loader' -import Timer from '@cordisjs/plugin-timer' +import { Context } from '@deepseek-ai/cordis' +import Hmr from '@deepseek-ai/cordis-plugin-hmr' +import Loader from '@deepseek-ai/cordis-plugin-loader' +import Timer from '@deepseek-ai/cordis-plugin-timer' import { describe, expect, it, vi } from 'vitest' async function bootHmr(dir: string, root: string[] = [], usePolling?: boolean): Promise { diff --git a/packages/boot/app-boot/tests/user-patches.spec.ts b/packages/boot/app-boot/tests/user-patches.spec.ts index 333385ee50..2e67bd08f8 100644 --- a/packages/boot/app-boot/tests/user-patches.spec.ts +++ b/packages/boot/app-boot/tests/user-patches.spec.ts @@ -9,10 +9,10 @@ import { tmpdir } from 'node:os' import { join } from 'node:path' import { pathToFileURL } from 'node:url' import { afterEach, describe, expect, it } from 'vitest' -import { Context } from 'cordis' -import Hmr from '@cordisjs/plugin-hmr' -import Loader from '@cordisjs/plugin-loader' -import Timer from '@cordisjs/plugin-timer' +import { Context } from '@deepseek-ai/cordis' +import Hmr from '@deepseek-ai/cordis-plugin-hmr' +import Loader from '@deepseek-ai/cordis-plugin-loader' +import Timer from '@deepseek-ai/cordis-plugin-timer' import { boot, loadOptionalPatches, diff --git a/packages/boot/app-boot/tsdown.config.ts b/packages/boot/app-boot/tsdown.config.ts index 88492d7c26..6693770892 100644 --- a/packages/boot/app-boot/tsdown.config.ts +++ b/packages/boot/app-boot/tsdown.config.ts @@ -14,6 +14,6 @@ export default defineConfig({ dts: false, clean: false, deps: { - alwaysBundle: ['@cordisjs/plugin-include'], + alwaysBundle: ['@deepseek-ai/cordis-plugin-include'], }, }) diff --git a/packages/bundle/base/cordis.patch.yml b/packages/bundle/base/cordis.patch.yml index 66612f70fd..e5ab0d9463 100644 --- a/packages/bundle/base/cordis.patch.yml +++ b/packages/bundle/base/cordis.patch.yml @@ -14,10 +14,10 @@ - insert: - id: timer - name: '@cordisjs/plugin-timer' + name: '@deepseek-ai/cordis-plugin-timer' - id: hmr - name: '@cordisjs/plugin-hmr' + name: '@deepseek-ai/cordis-plugin-hmr' config: root: ['.'] diff --git a/packages/bundle/base/package.json b/packages/bundle/base/package.json index def597150e..272a403872 100644 --- a/packages/bundle/base/package.json +++ b/packages/bundle/base/package.json @@ -34,8 +34,8 @@ } }, "dependencies": { - "@cordisjs/plugin-hmr": "workspace:*", - "@cordisjs/plugin-timer": "workspace:*", + "@deepseek-ai/cordis-plugin-hmr": "workspace:*", + "@deepseek-ai/cordis-plugin-timer": "workspace:*", "@deepseek-ai/dsh-agent": "workspace:^", "@deepseek-ai/dsh-agent-default-model": "workspace:^", "@deepseek-ai/dsh-agent-loop": "workspace:^", @@ -114,10 +114,10 @@ }, "peerDependencies": { "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-invariants": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/bundle/base/src/invariant.ts b/packages/bundle/base/src/invariant.ts index 65365fb193..a3f9b51de0 100644 --- a/packages/bundle/base/src/invariant.ts +++ b/packages/bundle/base/src/invariant.ts @@ -3,7 +3,7 @@ * @module @deepseek-ai/dsh-base/invariant */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-base' diff --git a/packages/bundle/base/tests/base.spec.ts b/packages/bundle/base/tests/base.spec.ts index 2da84a0931..4db8f9bdb9 100644 --- a/packages/bundle/base/tests/base.spec.ts +++ b/packages/bundle/base/tests/base.spec.ts @@ -8,7 +8,7 @@ import { fileURLToPath } from 'node:url' import { resolve } from 'node:path' import { describe, expect, it } from 'vitest' import * as yaml from 'js-yaml' -import { entryListSchema } from '@cordisjs/plugin-include' +import { entryListSchema } from '@deepseek-ai/cordis-plugin-include' describe('dsh-base bundle', () => { it('declares a parseable patch list through the dsh.bundle.patch manifest field', () => { diff --git a/packages/bundle/headless/package.json b/packages/bundle/headless/package.json index bc461e4c72..c5090d4b93 100644 --- a/packages/bundle/headless/package.json +++ b/packages/bundle/headless/package.json @@ -33,7 +33,7 @@ }, "dependencies": { "@deepseek-ai/dsh-code-runtime-worker": "workspace:^", - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "peerDependencies": { "@deepseek-ai/dsh-agent": "^0.0.1", @@ -41,15 +41,15 @@ "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-llm": "^0.0.1", "@deepseek-ai/dsh-session": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { - "@cordisjs/plugin-loader": "workspace:^", + "@deepseek-ai/cordis-plugin-loader": "workspace:^", "@deepseek-ai/dsh-agent": "workspace:^", "@deepseek-ai/dsh-agent-default-model": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-llm": "workspace:^", "@deepseek-ai/dsh-session": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/bundle/headless/src/index.ts b/packages/bundle/headless/src/index.ts index 2ea68c441b..4b1403ca59 100644 --- a/packages/bundle/headless/src/index.ts +++ b/packages/bundle/headless/src/index.ts @@ -8,8 +8,8 @@ */ import { randomUUID } from 'node:crypto' -import type { Context } from 'cordis' -import z from 'schemastery' +import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import { installModelSelection } from '@deepseek-ai/dsh-agent' import type { ModelSelectionRef } from '@deepseek-ai/dsh-agent' import type {} from '@deepseek-ai/dsh-agent-default-model' @@ -17,7 +17,7 @@ import { createUserMessage } from '@deepseek-ai/dsh-llm' import { SessionId } from '@deepseek-ai/dsh-session' import type { SessionEvent } from '@deepseek-ai/dsh-session' // Empty type import carries the loader Context merge for the settlement await. -import type {} from '@cordisjs/plugin-loader' +import type {} from '@deepseek-ai/cordis-plugin-loader' /** Stable Cordis plugin name. */ export const name = 'headless-runner' @@ -52,7 +52,7 @@ export interface HeadlessIo { exit(code: number): void } -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { /** Process-facing effects provided before the headless tree mounts. */ headlessIo?: HeadlessIo diff --git a/packages/bundle/headless/src/invariant.ts b/packages/bundle/headless/src/invariant.ts index 91e4925aa1..cd435b5fcc 100644 --- a/packages/bundle/headless/src/invariant.ts +++ b/packages/bundle/headless/src/invariant.ts @@ -3,7 +3,7 @@ * @module @deepseek-ai/dsh-headless/invariant */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-headless' diff --git a/packages/bundle/headless/tests/headless.spec.ts b/packages/bundle/headless/tests/headless.spec.ts index bd24a9300a..788e0a5a10 100644 --- a/packages/bundle/headless/tests/headless.spec.ts +++ b/packages/bundle/headless/tests/headless.spec.ts @@ -1,7 +1,7 @@ /** Direct one-shot Agent driving, durable aggregation, flushing, and exit mapping. */ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import AgentRegistry, { Inbox } from '@deepseek-ai/dsh-agent' import type { Agent, AgentHandle, CreateAgentOptions } from '@deepseek-ai/dsh-agent' import AgentDefaultModelService from '@deepseek-ai/dsh-agent-default-model' diff --git a/packages/bundle/web-app/package.json b/packages/bundle/web-app/package.json index 4f8b8d4318..f8cd162a11 100644 --- a/packages/bundle/web-app/package.json +++ b/packages/bundle/web-app/package.json @@ -74,18 +74,18 @@ "@deepseek-ai/dsh-storage-domain": "workspace:^", "@deepseek-ai/dsh-storage-json": "workspace:^", "@deepseek-ai/dsh-workspace": "workspace:^", - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "peerDependencies": { "@deepseek-ai/dsh-bash-env": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-system-prompt": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-bash-env": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-system-prompt": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/bundle/web-app/src/index.ts b/packages/bundle/web-app/src/index.ts index b14635a868..286a006f28 100644 --- a/packages/bundle/web-app/src/index.ts +++ b/packages/bundle/web-app/src/index.ts @@ -11,10 +11,10 @@ */ import { createRequire } from 'node:module' -import type { Context } from 'cordis' -import z from 'schemastery' +import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import * as FrontendStatic from '@deepseek-ai/dsh-frontend-static' -import type {} from '@cordisjs/plugin-loader' +import type {} from '@deepseek-ai/cordis-plugin-loader' import type {} from '@deepseek-ai/dsh-host-webserver' import type {} from '@deepseek-ai/dsh-system-prompt' import type {} from '@deepseek-ai/dsh-bash-env' diff --git a/packages/bundle/web-app/src/invariant.ts b/packages/bundle/web-app/src/invariant.ts index a91d7cf7d1..13df7f956c 100644 --- a/packages/bundle/web-app/src/invariant.ts +++ b/packages/bundle/web-app/src/invariant.ts @@ -3,7 +3,7 @@ * @module @deepseek-ai/dsh-web-app/invariant */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-web-app' diff --git a/packages/bundle/web-app/tests/web-app.spec.ts b/packages/bundle/web-app/tests/web-app.spec.ts index c73f9817db..eeb2aefc07 100644 --- a/packages/bundle/web-app/tests/web-app.spec.ts +++ b/packages/bundle/web-app/tests/web-app.spec.ts @@ -9,7 +9,7 @@ import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs' import { tmpdir } from 'node:os' import { join } from 'node:path' import { afterEach, describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import SystemPrompt from '@deepseek-ai/dsh-system-prompt' import type { HttpServerService } from '@deepseek-ai/dsh-host-webserver' import { apply, Config, internals } from '../src/index.ts' diff --git a/packages/client/connection/package.json b/packages/client/connection/package.json index 1433c59655..8f7b485c09 100644 --- a/packages/client/connection/package.json +++ b/packages/client/connection/package.json @@ -37,7 +37,7 @@ "@deepseek-ai/dsh-llm": "workspace:^", "@deepseek-ai/dsh-session": "workspace:^", "@deepseek-ai/dsh-tools": "workspace:^", - "schemastery": "^3.18.0", + "@deepseek-ai/schemastery": "^3.18.0", "ws": "^8.21.0" }, "files": [ @@ -49,12 +49,12 @@ "peerDependencies": { "@deepseek-ai/dsh-host-webserver": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-host-webserver": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", "@types/ws": "^8.18.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/client/connection/src/client/index.ts b/packages/client/connection/src/client/index.ts index 0788e4508e..99f49ff13a 100644 --- a/packages/client/connection/src/client/index.ts +++ b/packages/client/connection/src/client/index.ts @@ -3,7 +3,7 @@ * the shared API client, and lets the runtime object layer start the stream * controller with its sinks. */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { IApiClient } from './api.ts' import { ConnectionController, type ConnectionConfig, type ConnectionSinks, type ConnectionState } from './connection.ts' import { FixtureApiClient } from './fixture.ts' diff --git a/packages/client/connection/src/index.ts b/packages/client/connection/src/index.ts index b2189501cb..11d9a2fd87 100644 --- a/packages/client/connection/src/index.ts +++ b/packages/client/connection/src/index.ts @@ -1,6 +1,6 @@ /** Host HTTP bridge for browser-client RPC. */ -import type { Context } from 'cordis' -import z from 'schemastery' +import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import type {} from '@deepseek-ai/dsh-attachment' // Activates the httpServer Context merge used below. import type { WebRoute, WebUpgradeRoute } from '@deepseek-ai/dsh-host-webserver' diff --git a/packages/client/connection/src/invariant.ts b/packages/client/connection/src/invariant.ts index 1112a4e638..78394263cf 100644 --- a/packages/client/connection/src/invariant.ts +++ b/packages/client/connection/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-client-connection' diff --git a/packages/client/connection/src/rpc-host.ts b/packages/client/connection/src/rpc-host.ts index 7d3e5ff6f5..ec37719768 100644 --- a/packages/client/connection/src/rpc-host.ts +++ b/packages/client/connection/src/rpc-host.ts @@ -1,6 +1,6 @@ /** Host registry and HTTP adapter for generic Connection RPC channels. */ -import { Context, Service } from 'cordis' +import { Context, Service } from '@deepseek-ai/cordis' import type { WebRoute } from '@deepseek-ai/dsh-host-webserver' import { clientRequestSchema, @@ -32,7 +32,7 @@ interface ConnectionRpcInterceptor { readonly options: ConnectionRpcHandlerOptions } -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { /** Host Connection transport and RPC registrations. */ connection: HostConnectionHandle diff --git a/packages/client/connection/tests/client-apply.spec.ts b/packages/client/connection/tests/client-apply.spec.ts index 9d9bbd2f26..9c72e862e2 100644 --- a/packages/client/connection/tests/client-apply.spec.ts +++ b/packages/client/connection/tests/client-apply.spec.ts @@ -2,7 +2,7 @@ * Connection plugin browser-half apply: ctx.connection handle mounting, mode * selection off the page URL, and the single-consumer stream-loop ownership. */ -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { afterEach, describe, expect, it, vi } from 'vitest' import { apply, type ConnectionHandle } from '../src/client/index.ts' import type { RpcMessage } from '../src/client/api.ts' diff --git a/packages/client/connection/tests/node-half.spec.ts b/packages/client/connection/tests/node-half.spec.ts index fc69e4d7a1..54a2ab7e5c 100644 --- a/packages/client/connection/tests/node-half.spec.ts +++ b/packages/client/connection/tests/node-half.spec.ts @@ -2,7 +2,7 @@ import { EventEmitter, once } from 'node:events' import { createServer, request as httpRequest } from 'node:http' import { PassThrough, Readable } from 'node:stream' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { describe, expect, it } from 'vitest' import type { AddressInfo } from 'node:net' import type { IncomingMessage, ServerResponse } from 'node:http' diff --git a/packages/client/hmr/package.json b/packages/client/hmr/package.json index 04e94c24bd..79e2789d33 100644 --- a/packages/client/hmr/package.json +++ b/packages/client/hmr/package.json @@ -31,21 +31,21 @@ }, "license": "BSD-3-Clause", "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "peerDependencies": { - "@cordisjs/plugin-loader": "^1.0.0-rc.5", + "@deepseek-ai/cordis-plugin-loader": "^1.0.0-rc.5", "@deepseek-ai/dsh-client-modules": "^0.0.1", "@deepseek-ai/dsh-host-webserver": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { - "@cordisjs/plugin-loader": "workspace:^", + "@deepseek-ai/cordis-plugin-loader": "workspace:^", "@deepseek-ai/dsh-client-modules": "workspace:^", "@deepseek-ai/dsh-host-webserver": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "files": [ "lib/index.js", diff --git a/packages/client/hmr/src/client/index.ts b/packages/client/hmr/src/client/index.ts index d0558bcecc..8e440ac0de 100644 --- a/packages/client/hmr/src/client/index.ts +++ b/packages/client/hmr/src/client/index.ts @@ -61,8 +61,8 @@ * fiberless (the next rebuilt frame retries from scratch); an apply failure * leaves a FAILED fiber for the shell's status projection. Both log loudly. */ -import type { Context } from 'cordis' -import type { Entry, Loader } from '@cordisjs/plugin-loader' +import type { Context } from '@deepseek-ai/cordis' +import type { Entry, Loader } from '@deepseek-ai/cordis-plugin-loader' import type { PluginsEventFrame } from '../events.ts' import { EVENTS_ENDPOINT } from '../events.ts' diff --git a/packages/client/hmr/src/index.ts b/packages/client/hmr/src/index.ts index 848b546b13..17604133eb 100644 --- a/packages/client/hmr/src/index.ts +++ b/packages/client/hmr/src/index.ts @@ -8,8 +8,8 @@ */ import { statSync } from 'node:fs' import type { ServerResponse } from 'node:http' -import type { Context } from 'cordis' -import z from 'schemastery' +import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' // Empty type imports carry the clientModuleHost/httpServer Context merges. import type {} from '@deepseek-ai/dsh-client-modules' import type {} from '@deepseek-ai/dsh-host-webserver' diff --git a/packages/client/hmr/src/invariant.ts b/packages/client/hmr/src/invariant.ts index cc875f3e13..1054d91430 100644 --- a/packages/client/hmr/src/invariant.ts +++ b/packages/client/hmr/src/invariant.ts @@ -3,7 +3,7 @@ * @module @deepseek-ai/dsh-client-hmr/invariant */ -import type { Context, Fiber } from 'cordis' +import type { Context, Fiber } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-client-hmr' diff --git a/packages/client/hmr/tests/node-half.spec.ts b/packages/client/hmr/tests/node-half.spec.ts index 5224061e61..7f0e1ded83 100644 --- a/packages/client/hmr/tests/node-half.spec.ts +++ b/packages/client/hmr/tests/node-half.spec.ts @@ -5,7 +5,7 @@ import { mkdtempSync, rmSync, statSync, unlinkSync, utimesSync, writeFileSync } from 'node:fs' import { tmpdir } from 'node:os' import { join } from 'node:path' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' import type { WebBootGraph, ClientModuleHostService } from '@deepseek-ai/dsh-client-modules' import type { WebRoute, HttpServerService } from '@deepseek-ai/dsh-host-webserver' diff --git a/packages/client/locale/package.json b/packages/client/locale/package.json index 0814c86b8d..dc90483e1b 100644 --- a/packages/client/locale/package.json +++ b/packages/client/locale/package.json @@ -39,7 +39,7 @@ "@deepseek-ai/dsh-client-ui-primitives": "^0.0.1", "@deepseek-ai/dsh-client-ui-slots": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.7", + "@deepseek-ai/cordis": "^4.0.0-rc.7", "react": "^18.2.0" }, "devDependencies": { @@ -48,12 +48,12 @@ "@deepseek-ai/dsh-client-ui-slots": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", "@types/react": "~18.3.1", - "cordis": "^4.0.0-rc.7", + "@deepseek-ai/cordis": "^4.0.0-rc.7", "react": "^18.2.0" }, "dependencies": { "@deepseek-ai/dsh-settings": "workspace:^", - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "files": [ "lib/index.js", diff --git a/packages/client/locale/src/client/index.ts b/packages/client/locale/src/client/index.ts index b8c06872db..3eea9eede6 100644 --- a/packages/client/locale/src/client/index.ts +++ b/packages/client/locale/src/client/index.ts @@ -9,7 +9,7 @@ * ui-slots): in THIS unit the map holds only this package's own merges, but * consumers merge more namespaces in and the intersection keeps them * string-typed. The rule fires on the narrow-map view, not real redundancy. */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { type BoundActions, type LocaleDictOf, type LocaleNamespaceMap, type Translate, type TranslateNS, } from '@deepseek-ai/dsh-client-ui-slots' @@ -68,7 +68,7 @@ export interface LocaleSnapshot { revision: number } -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { locale: LocaleService } diff --git a/packages/client/locale/src/index.ts b/packages/client/locale/src/index.ts index c8d7ed9f95..af1c9a3057 100644 --- a/packages/client/locale/src/index.ts +++ b/packages/client/locale/src/index.ts @@ -1,6 +1,6 @@ /** Host registration for the browser locale preference. */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { settingsNamespace } from '@deepseek-ai/dsh-settings' import { LOCALE_SETTINGS_NAMESPACE, LocaleSettingsSchema } from './locale-settings.ts' diff --git a/packages/client/locale/src/invariant.ts b/packages/client/locale/src/invariant.ts index 96c94018f0..6c28c2353e 100644 --- a/packages/client/locale/src/invariant.ts +++ b/packages/client/locale/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-client-locale' diff --git a/packages/client/locale/src/locale-settings.ts b/packages/client/locale/src/locale-settings.ts index c5d0399f86..9733714502 100644 --- a/packages/client/locale/src/locale-settings.ts +++ b/packages/client/locale/src/locale-settings.ts @@ -1,6 +1,6 @@ /** Locale preference stored in the Host user-settings document. */ -import z from 'schemastery' +import z from '@deepseek-ai/schemastery' /** Settings namespace owned by the locale plugin. */ export const LOCALE_SETTINGS_NAMESPACE = 'locale' diff --git a/packages/client/locale/tests/apply.spec.ts b/packages/client/locale/tests/apply.spec.ts index 84f4299ef2..c82e7c7cb3 100644 --- a/packages/client/locale/tests/apply.spec.ts +++ b/packages/client/locale/tests/apply.spec.ts @@ -1,7 +1,7 @@ /** locale apply wiring: service + dictionaries provision, declaration-aware * Language row registration, snapshot projection into the row store, and * recovery after an HMR collapse of the declaring entry. */ -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' import { SlotsService } from '@deepseek-ai/dsh-client-runtime/client' import { diff --git a/packages/client/locale/tests/host.spec.ts b/packages/client/locale/tests/host.spec.ts index 8fa339e660..809ed5bc9e 100644 --- a/packages/client/locale/tests/host.spec.ts +++ b/packages/client/locale/tests/host.spec.ts @@ -1,4 +1,4 @@ -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { describe, expect, it } from 'vitest' import { Settings, settingsNamespace, type SettingsNamespace } from '@deepseek-ai/dsh-settings' import { diff --git a/packages/client/locale/tests/invariant.spec.ts b/packages/client/locale/tests/invariant.spec.ts index 2b362cb115..c55efa9a12 100644 --- a/packages/client/locale/tests/invariant.spec.ts +++ b/packages/client/locale/tests/invariant.spec.ts @@ -1,6 +1,6 @@ // @vitest-environment jsdom import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { apply as nodeApply } from '@deepseek-ai/dsh-client-locale' import { apply as clientApply, COMMON_NS, LocaleService, inject } from '@deepseek-ai/dsh-client-locale/client' import * as LocaleInvariant from '@deepseek-ai/dsh-client-locale/invariant' diff --git a/packages/client/locale/tests/locale.spec.ts b/packages/client/locale/tests/locale.spec.ts index 2b696f6fc5..fb751cb301 100644 --- a/packages/client/locale/tests/locale.spec.ts +++ b/packages/client/locale/tests/locale.spec.ts @@ -1,6 +1,6 @@ // @vitest-environment jsdom import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { stubSettingsScope, type StubSettingsScope } from '@deepseek-ai/dsh-client-test-runtime' import type { LocaleSettings, LocaleSnapshot } from '@deepseek-ai/dsh-client-locale/client' import { LocaleService } from '@deepseek-ai/dsh-client-locale/client' diff --git a/packages/client/modules/package.json b/packages/client/modules/package.json index 906ef783ed..a9d9d1de2d 100644 --- a/packages/client/modules/package.json +++ b/packages/client/modules/package.json @@ -35,10 +35,10 @@ }, "license": "BSD-3-Clause", "devDependencies": { - "@cordisjs/plugin-loader": "workspace:^", + "@deepseek-ai/cordis-plugin-loader": "workspace:^", "@deepseek-ai/dsh-host-webserver": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "files": [ "lib/index.js", @@ -48,6 +48,6 @@ ], "peerDependencies": { "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/client/modules/src/client/index.ts b/packages/client/modules/src/client/index.ts index a516d6cef9..c7efe7df9f 100644 --- a/packages/client/modules/src/client/index.ts +++ b/packages/client/modules/src/client/index.ts @@ -9,7 +9,7 @@ * a no-op against the already-registered entry. * @module @deepseek-ai/dsh-client-modules/client */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { DshWindow } from './manifest.ts' export { ClientModuleSystem } from './system.ts' diff --git a/packages/client/modules/src/client/manifest.ts b/packages/client/modules/src/client/manifest.ts index 50b2f8d985..a780525a9c 100644 --- a/packages/client/modules/src/client/manifest.ts +++ b/packages/client/modules/src/client/manifest.ts @@ -30,10 +30,10 @@ * composes the wire. */ -import type {} from 'cordis' +import type {} from '@deepseek-ai/cordis' import type { ClientModuleSystem } from './system.ts' -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { /** The client module system the web shell builds at boot (provided by the `./client` wrapper plugin). */ modules: ClientModuleLoader diff --git a/packages/client/modules/src/index.ts b/packages/client/modules/src/index.ts index a0f932fa84..919c139283 100644 --- a/packages/client/modules/src/index.ts +++ b/packages/client/modules/src/index.ts @@ -26,9 +26,9 @@ import { readFile } from 'node:fs/promises' import type { IncomingMessage, ServerResponse } from 'node:http' import { createRequire } from 'node:module' import { dirname, join } from 'node:path' -import { Service } from 'cordis' -import type { Context } from 'cordis' -import type {} from '@cordisjs/plugin-loader' +import { Service } from '@deepseek-ai/cordis' +import type { Context } from '@deepseek-ai/cordis' +import type {} from '@deepseek-ai/cordis-plugin-loader' import type {} from '@deepseek-ai/dsh-host-webserver' import type { WebBootEntry, WebBootGraph } from './client/manifest.ts' @@ -36,7 +36,7 @@ export type { BootManifest, BootModuleRow, BootPluginRow, WebBootEntry, WebBootGraph, } from './client/manifest.ts' -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { /** The web plugin table (provided by the client-modules node half). */ clientModuleHost: ClientModuleHostService diff --git a/packages/client/modules/src/invariant.ts b/packages/client/modules/src/invariant.ts index ad9605f5dd..13b48be9a8 100644 --- a/packages/client/modules/src/invariant.ts +++ b/packages/client/modules/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-client-modules' diff --git a/packages/client/modules/tests/node-half.spec.ts b/packages/client/modules/tests/node-half.spec.ts index c2c865fd12..7a95281591 100644 --- a/packages/client/modules/tests/node-half.spec.ts +++ b/packages/client/modules/tests/node-half.spec.ts @@ -5,7 +5,7 @@ import type { IncomingMessage, ServerResponse } from 'node:http' import { tmpdir } from 'node:os' import { dirname, join } from 'node:path' import { pathToFileURL } from 'node:url' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { afterEach, describe, expect, it } from 'vitest' import type { HttpServerService, WebRoute } from '@deepseek-ai/dsh-host-webserver' import { ClientModuleHostService } from '../src/index.ts' diff --git a/packages/client/runtime/package.json b/packages/client/runtime/package.json index 9f922ed956..6250a97ff5 100644 --- a/packages/client/runtime/package.json +++ b/packages/client/runtime/package.json @@ -56,7 +56,7 @@ "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-type-meta": "^0.0.1", "@deepseek-ai/dsh-typert-registry": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-invariants": "workspace:^", @@ -64,8 +64,8 @@ "@deepseek-ai/dsh-type-meta": "workspace:^", "@deepseek-ai/dsh-typert-registry": "workspace:^", "@types/react": "~18.3.1", - "cordis": "^4.0.0-rc.7", - "schemastery": "^3.18.0" + "@deepseek-ai/cordis": "^4.0.0-rc.7", + "@deepseek-ai/schemastery": "^3.18.0" }, "files": [ "lib/index.js", diff --git a/packages/client/runtime/src/client/agents/scope.ts b/packages/client/runtime/src/client/agents/scope.ts index 25644d24ba..b32840daa0 100644 --- a/packages/client/runtime/src/client/agents/scope.ts +++ b/packages/client/runtime/src/client/agents/scope.ts @@ -15,8 +15,8 @@ * — a cold session's host Agent is already disposed while its client actx * stays alive for history viewing. */ -import { Context as CordisContext } from 'cordis' -import type { Context, Fiber } from 'cordis' +import { Context as CordisContext } from '@deepseek-ai/cordis' +import type { Context, Fiber } from '@deepseek-ai/cordis' import type { SessionId } from '@deepseek-ai/dsh-client-connection/client' import type { TypeRTClientRemote, TypeRTRemoteScopeApi } from '@deepseek-ai/dsh-type-meta' diff --git a/packages/client/runtime/src/client/contract/sessions.ts b/packages/client/runtime/src/client/contract/sessions.ts index 1560f131d2..960d2038de 100644 --- a/packages/client/runtime/src/client/contract/sessions.ts +++ b/packages/client/runtime/src/client/contract/sessions.ts @@ -7,7 +7,7 @@ * [SessionsPort](./sessions-port.ts). Widening this interface is the * explicit act of widening what features may do to the sessions domain. */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { RpcResult, SessionId, SubagentAddress, } from '@deepseek-ai/dsh-client-connection/client' diff --git a/packages/client/runtime/src/client/conversation/definition-registry.ts b/packages/client/runtime/src/client/conversation/definition-registry.ts index d43f494e1a..425f426512 100644 --- a/packages/client/runtime/src/client/conversation/definition-registry.ts +++ b/packages/client/runtime/src/client/conversation/definition-registry.ts @@ -1,4 +1,4 @@ -import { Service } from 'cordis' +import { Service } from '@deepseek-ai/cordis' /** Shared lifecycle and stable-entry storage for one Conversation Definition registry. */ export abstract class ConversationDefinitionRegistry extends Service { diff --git a/packages/client/runtime/src/client/conversation/event-registry.ts b/packages/client/runtime/src/client/conversation/event-registry.ts index 6935ed1741..381fff81b5 100644 --- a/packages/client/runtime/src/client/conversation/event-registry.ts +++ b/packages/client/runtime/src/client/conversation/event-registry.ts @@ -1,4 +1,4 @@ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { ConversationNodeDefinition } from '../contract/conversation.ts' import { ConversationDefinitionRegistry } from './definition-registry.ts' diff --git a/packages/client/runtime/src/client/conversation/view-registry.ts b/packages/client/runtime/src/client/conversation/view-registry.ts index 1e2e53e141..5372b4a4db 100644 --- a/packages/client/runtime/src/client/conversation/view-registry.ts +++ b/packages/client/runtime/src/client/conversation/view-registry.ts @@ -1,4 +1,4 @@ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { ConversationViewDefinition } from '../contract/conversation.ts' import { ConversationDefinitionRegistry } from './definition-registry.ts' diff --git a/packages/client/runtime/src/client/index.ts b/packages/client/runtime/src/client/index.ts index 0bc673b542..7dc604ff72 100644 --- a/packages/client/runtime/src/client/index.ts +++ b/packages/client/runtime/src/client/index.ts @@ -1,5 +1,5 @@ /** Browser runtime services for slots, sessions, workspaces, and connection-stream delivery. */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { ConnectionHandle, SessionId } from '@deepseek-ai/dsh-client-connection/client' import type { TypeRTContext } from '@deepseek-ai/dsh-type-meta' import type { MaybeSnapshotSelectorHook, SnapshotSelectorHook } from '@deepseek-ai/dsh-client-ui-slots' @@ -146,7 +146,7 @@ declare module '@deepseek-ai/dsh-client-ui-slots' { } } -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Events { /** * A slot's definition or registration set changed. diff --git a/packages/client/runtime/src/client/session-history/service.ts b/packages/client/runtime/src/client/session-history/service.ts index b5aba32bce..4705b6566d 100644 --- a/packages/client/runtime/src/client/session-history/service.ts +++ b/packages/client/runtime/src/client/session-history/service.ts @@ -1,4 +1,4 @@ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { HostFrame, IApiClient, MuxFrame, RpcRequest, SessionId, } from '@deepseek-ai/dsh-client-connection/client' diff --git a/packages/client/runtime/src/client/sessions/service.ts b/packages/client/runtime/src/client/sessions/service.ts index 72edcea1c3..0f0f68827d 100644 --- a/packages/client/runtime/src/client/sessions/service.ts +++ b/packages/client/runtime/src/client/sessions/service.ts @@ -14,7 +14,7 @@ * tears its scope down immediately unless it is the staged one, whose scope * survives frozen (read-only view) until the stage moves on. */ -import type { Context, Fiber } from 'cordis' +import type { Context, Fiber } from '@deepseek-ai/cordis' import type { IApiClient, RpcError, RpcResult, SessionId, SubagentAddress, WorkspaceId, } from '@deepseek-ai/dsh-client-connection/client' diff --git a/packages/client/runtime/src/client/sessions/session.ts b/packages/client/runtime/src/client/sessions/session.ts index b073bc7ef0..9c1d86987c 100644 --- a/packages/client/runtime/src/client/sessions/session.ts +++ b/packages/client/runtime/src/client/sessions/session.ts @@ -1,6 +1,6 @@ // Sessions remain resident after creation so they continue consuming mux frames off-screen. -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { AttachmentIdType, ImageAttachmentRef } from '@deepseek-ai/dsh-attachment' import type { SessionEvent } from '@deepseek-ai/dsh-session/types' import type { diff --git a/packages/client/runtime/src/client/settings-scope.ts b/packages/client/runtime/src/client/settings-scope.ts index 91b6c7ec3a..cb7e933406 100644 --- a/packages/client/runtime/src/client/settings-scope.ts +++ b/packages/client/runtime/src/client/settings-scope.ts @@ -1,6 +1,6 @@ /** Host-backed settings-namespace synchronization for browser plugins. */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { ConnectionHandle, IApiClient, SettingsNamespaceView, } from '@deepseek-ai/dsh-client-connection/client' diff --git a/packages/client/runtime/src/client/slots.ts b/packages/client/runtime/src/client/slots.ts index e3ad848e05..e9b587bdc2 100644 --- a/packages/client/runtime/src/client/slots.ts +++ b/packages/client/runtime/src/client/slots.ts @@ -14,8 +14,8 @@ * holds this package's 'root' row in this compilation unit, but consumers * merge keys in; the rule fires on the narrow-map view, not on real * redundancy. */ -import { Service } from 'cordis' -import type { Context } from 'cordis' +import { Service } from '@deepseek-ai/cordis' +import type { Context } from '@deepseek-ai/cordis' import { SlotCore } from '@deepseek-ai/dsh-client-ui-slots' import type { LocaleFace, OwnerOf, SlotEntryDef, SlotMap, SlotRenderer, SlotRendererHost, diff --git a/packages/client/runtime/src/client/workspaces/service.ts b/packages/client/runtime/src/client/workspaces/service.ts index c0f71b92db..468ae95a19 100644 --- a/packages/client/runtime/src/client/workspaces/service.ts +++ b/packages/client/runtime/src/client/workspaces/service.ts @@ -1,6 +1,6 @@ /** WorkspacesService projects the Workspace object manager for UI consumers. */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { DirectoryListing, IApiClient, RpcError, SessionId, WorkspaceId, WorkspaceView, diff --git a/packages/client/runtime/src/invariant.ts b/packages/client/runtime/src/invariant.ts index 2b055ede0b..c11a014cd9 100644 --- a/packages/client/runtime/src/invariant.ts +++ b/packages/client/runtime/src/invariant.ts @@ -8,7 +8,7 @@ * `keyof SlotMap & string` is the declare-merge key pattern: SlotMap is empty * in this compilation unit (intersection reads `never`) but consumers merge * keys in; the rule fires on the empty-map view, not on real redundancy. */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { SlotMap } from '@deepseek-ai/dsh-client-ui-slots' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' diff --git a/packages/client/runtime/tests/client-apply.spec.ts b/packages/client/runtime/tests/client-apply.spec.ts index 58d48affce..7c8a40e06b 100644 --- a/packages/client/runtime/tests/client-apply.spec.ts +++ b/packages/client/runtime/tests/client-apply.spec.ts @@ -3,7 +3,7 @@ * connection handle, stream-loop sink wiring into the object layer, and the * fiber-scoped loop teardown. */ -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { describe, expect, it, vi } from 'vitest' import type { ConnectionHandle } from '@deepseek-ai/dsh-client-connection/client' import type { ConnectionSinks } from '@deepseek-ai/dsh-client-connection/client' diff --git a/packages/client/runtime/tests/conversation-registry.spec.ts b/packages/client/runtime/tests/conversation-registry.spec.ts index 19cbdf17f9..9f45b36c6a 100644 --- a/packages/client/runtime/tests/conversation-registry.spec.ts +++ b/packages/client/runtime/tests/conversation-registry.spec.ts @@ -1,4 +1,4 @@ -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { describe, expect, it, vi } from 'vitest' import type { SessionId } from '@deepseek-ai/dsh-client-connection/client' import { ConversationEventRegistry } from '../src/client/conversation/event-registry.ts' diff --git a/packages/client/runtime/tests/invariant.spec.ts b/packages/client/runtime/tests/invariant.spec.ts index 708b714b2f..9e869baa44 100644 --- a/packages/client/runtime/tests/invariant.spec.ts +++ b/packages/client/runtime/tests/invariant.spec.ts @@ -3,7 +3,7 @@ * a fired key must already carry a bumped version (emission follows the * applied mutation), bogus payloads fail loud, foreign events pass. */ -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { describe, expect, it } from 'vitest' import InvariantService from '@deepseek-ai/dsh-invariants' import * as RuntimeInvariant from '../src/invariant.ts' diff --git a/packages/client/runtime/tests/scope.spec.ts b/packages/client/runtime/tests/scope.spec.ts index f1c3847ce2..4c69b46edc 100644 --- a/packages/client/runtime/tests/scope.spec.ts +++ b/packages/client/runtime/tests/scope.spec.ts @@ -6,14 +6,14 @@ * and a subject-less root dispatch stays unfiltered. Scope-owned listeners * dispose with the fiber. */ -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { describe, expect, it } from 'vitest' import type { SessionId } from '@deepseek-ai/dsh-client-connection/client' import { createScope, scopeOf } from '../src/client/agents/scope.ts' const sid = (k: string): SessionId => k as SessionId -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Events { /** * Test-only routed probe event. diff --git a/packages/client/runtime/tests/sessions-service.spec.ts b/packages/client/runtime/tests/sessions-service.spec.ts index 3b25ff849c..c80e7e78c1 100644 --- a/packages/client/runtime/tests/sessions-service.spec.ts +++ b/packages/client/runtime/tests/sessions-service.spec.ts @@ -6,7 +6,7 @@ * deferral — the stage follows list.current), binding identity, breadcrumb * projection, create. */ -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { afterEach, describe, expect, it, vi } from 'vitest' import type { SessionId } from '@deepseek-ai/dsh-client-connection/client' import { SessionCreateError, SessionsService, scopeOf } from '../src/client/sessions/service.ts' diff --git a/packages/client/runtime/tests/settings-scope.spec.ts b/packages/client/runtime/tests/settings-scope.spec.ts index db980bf6d1..ae3c1db73c 100644 --- a/packages/client/runtime/tests/settings-scope.spec.ts +++ b/packages/client/runtime/tests/settings-scope.spec.ts @@ -1,5 +1,5 @@ -import { Context } from 'cordis' -import z from 'schemastery' +import { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import { describe, expect, it, vi } from 'vitest' import type { RpcResponse, SettingsNamespaceView } from '@deepseek-ai/dsh-client-connection/client' import { diff --git a/packages/client/runtime/tests/slots-service.spec.ts b/packages/client/runtime/tests/slots-service.spec.ts index a796d324ee..7869500f7e 100644 --- a/packages/client/runtime/tests/slots-service.spec.ts +++ b/packages/client/runtime/tests/slots-service.spec.ts @@ -5,7 +5,7 @@ * contract (double install / not installed / non-root key), store instance * resolution and lifecycle on the ledger axis, and the entry-unload cascade. */ -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { describe, expect, it, vi } from 'vitest' import type { FC } from 'react' import type { SlotRendererHost } from '@deepseek-ai/dsh-client-ui-slots' diff --git a/packages/client/runtime/tests/wire-events.spec.ts b/packages/client/runtime/tests/wire-events.spec.ts index e82c4cae3b..cc1f6c374c 100644 --- a/packages/client/runtime/tests/wire-events.spec.ts +++ b/packages/client/runtime/tests/wire-events.spec.ts @@ -4,7 +4,7 @@ * ctx 'session/preset-changed'; each established connection generation → * ctx 'connection/reset' (the forced cache-invalidation broadcast). */ -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { describe, expect, it } from 'vitest' import type { ConnectionHandle, ConnectionSinks } from '@deepseek-ai/dsh-client-connection/client' import TypertRegistry from '@deepseek-ai/dsh-typert-registry' diff --git a/packages/client/runtime/tests/workspaces-service.spec.ts b/packages/client/runtime/tests/workspaces-service.spec.ts index dd38a3119c..aa0f404da6 100644 --- a/packages/client/runtime/tests/workspaces-service.spec.ts +++ b/packages/client/runtime/tests/workspaces-service.spec.ts @@ -1,4 +1,4 @@ -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { describe, expect, it } from 'vitest' import type { SessionId, WorkspaceId, WorkspaceView } from '@deepseek-ai/dsh-client-connection/client' import { SessionsService } from '../src/client/sessions/service.ts' diff --git a/packages/client/schema-form/package.json b/packages/client/schema-form/package.json index c1cd5e8018..ee6529025c 100644 --- a/packages/client/schema-form/package.json +++ b/packages/client/schema-form/package.json @@ -20,15 +20,15 @@ }, "license": "BSD-3-Clause", "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "peerDependencies": { "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-invariants": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "files": [ "lib/index.js", diff --git a/packages/client/schema-form/src/invariant.ts b/packages/client/schema-form/src/invariant.ts index f60f951fb5..90636e5d67 100644 --- a/packages/client/schema-form/src/invariant.ts +++ b/packages/client/schema-form/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-client-schema-form' diff --git a/packages/client/schema-form/src/model.ts b/packages/client/schema-form/src/model.ts index 5377012141..5cfb624eb4 100644 --- a/packages/client/schema-form/src/model.ts +++ b/packages/client/schema-form/src/model.ts @@ -6,7 +6,7 @@ * @module @deepseek-ai/dsh-client-schema-form/model */ -import Schema from 'schemastery' +import Schema from '@deepseek-ai/schemastery' /** Live schemastery node; the renderer reads only its structural relations. */ export type SchemaNode = Schema diff --git a/packages/client/schema-form/tests/invariant.spec.ts b/packages/client/schema-form/tests/invariant.spec.ts index 7f7ba10dd8..5507c23e66 100644 --- a/packages/client/schema-form/tests/invariant.spec.ts +++ b/packages/client/schema-form/tests/invariant.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import * as SchemaFormInvariant from '@deepseek-ai/dsh-client-schema-form/invariant' import InvariantService from '@deepseek-ai/dsh-invariants' diff --git a/packages/client/schema-form/tests/model.spec.ts b/packages/client/schema-form/tests/model.spec.ts index 81e81e1992..1a95e88903 100644 --- a/packages/client/schema-form/tests/model.spec.ts +++ b/packages/client/schema-form/tests/model.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import Schema from 'schemastery' +import Schema from '@deepseek-ai/schemastery' import { deletePath, getPath, hasPath, nodeAtPath, rehydrateSchema, setPath, validateDraft, } from '../src/model.ts' diff --git a/packages/client/test-runtime/package.json b/packages/client/test-runtime/package.json index c93a302124..0891660b79 100644 --- a/packages/client/test-runtime/package.json +++ b/packages/client/test-runtime/package.json @@ -30,7 +30,7 @@ "@deepseek-ai/dsh-client-web-react": "^0.0.1", "@deepseek-ai/dsh-host-apiproxy": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.7", + "@deepseek-ai/cordis": "^4.0.0-rc.7", "react": "^18.2.0", "react-dom": "^18.2.0" }, @@ -42,7 +42,7 @@ "@deepseek-ai/dsh-invariants": "workspace:^", "@types/react": "~18.3.1", "@types/react-dom": "~18.3.0", - "cordis": "^4.0.0-rc.7", + "@deepseek-ai/cordis": "^4.0.0-rc.7", "react": "^18.2.0", "react-dom": "^18.2.0" }, diff --git a/packages/client/test-runtime/src/index.ts b/packages/client/test-runtime/src/index.ts index 5dea393047..e94030a1f1 100644 --- a/packages/client/test-runtime/src/index.ts +++ b/packages/client/test-runtime/src/index.ts @@ -14,8 +14,8 @@ * `keyof SlotMap & string` is the declare-merge key pattern (see ui-slots): * this compilation unit sees only the runtime's 'root' row, but consumer * programs merge their own keys in; the rule fires on the narrow-map view. */ -import { Context, Inject } from 'cordis' -import type { Fiber, Plugin } from 'cordis' +import { Context, Inject } from '@deepseek-ai/cordis' +import type { Fiber, Plugin } from '@deepseek-ai/cordis' import { createElement, Fragment, useSyncExternalStore } from 'react' import type { ReactNode } from 'react' import { act, render, within } from '@testing-library/react' diff --git a/packages/client/test-runtime/src/invariant.ts b/packages/client/test-runtime/src/invariant.ts index 09ef3da6ce..bb4ea6f6f1 100644 --- a/packages/client/test-runtime/src/invariant.ts +++ b/packages/client/test-runtime/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-client-test-runtime' diff --git a/packages/client/test-runtime/src/sessions.ts b/packages/client/test-runtime/src/sessions.ts index 059cf22ebc..315efd8f13 100644 --- a/packages/client/test-runtime/src/sessions.ts +++ b/packages/client/test-runtime/src/sessions.ts @@ -1,5 +1,5 @@ /** Test-owned sessions face: the SlotsService host contract over declarative fixtures. */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { AttachmentIdType } from '@deepseek-ai/dsh-attachment' import { createScope, scopeOf, SessionProvideChannel } from '@deepseek-ai/dsh-client-runtime/client' import { createSnapshotStore } from '@deepseek-ai/dsh-client-runtime/client' diff --git a/packages/client/test-runtime/tests/invariant.spec.ts b/packages/client/test-runtime/tests/invariant.spec.ts index 837559ec81..08b7e5725c 100644 --- a/packages/client/test-runtime/tests/invariant.spec.ts +++ b/packages/client/test-runtime/tests/invariant.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import * as TestRuntimeInvariant from '@deepseek-ai/dsh-client-test-runtime/invariant' import InvariantService from '@deepseek-ai/dsh-invariants' diff --git a/packages/client/tsdown.client.ts b/packages/client/tsdown.client.ts index d7252cd195..1b4ea86eea 100644 --- a/packages/client/tsdown.client.ts +++ b/packages/client/tsdown.client.ts @@ -32,6 +32,14 @@ const CSS_VIRTUAL_SUFFIX = '.mjs' */ export const INLINE_SAFE = /^@deepseek-ai\/dsh-(host-apiproxy|session|llm|tools|brand)(\/|$)/ +/** + * Vendored framework libraries: rescoped into @deepseek-ai, so the gate below + * would read them as plugin packages. They carry no cross-plugin runtime + * identity to share — the framework itself is a platform module (external), + * while these are ordinary libraries a browser bundle inlines. + */ +const VENDORED_LIBRARY = /^@deepseek-ai\/(cosmokit|schemastery)(\/|$)/ + /** Generated descriptor/codec contribution with no shared runtime identity. */ const GENERATED_REMOTE = /^@deepseek-ai\/dsh-[a-z0-9]+(?:-[a-z0-9]+)*\/remote$/ @@ -208,6 +216,7 @@ function clientConfig(id: string, entry: string): UserConfig { resolveId(source: string) { if (!source.startsWith('@deepseek-ai/')) return null if (CLIENT_EXTERNALS.includes(source)) return null // platform module: external wins + if (VENDORED_LIBRARY.test(source)) return null // vendored library: inline, no shared identity if (INLINE_SAFE.test(source) || GENERATED_REMOTE.test(source)) return null // wire contribution: inline is the point throw new Error( `client bundle purity: "${source}" is not a platform module (CLIENT_EXTERNALS), an inline-safe wire layer, or a generated /remote contribution — ` diff --git a/packages/client/ui-agent-preset/package.json b/packages/client/ui-agent-preset/package.json index 2f682d3de5..93facc56eb 100644 --- a/packages/client/ui-agent-preset/package.json +++ b/packages/client/ui-agent-preset/package.json @@ -49,7 +49,7 @@ "@deepseek-ai/dsh-client-ui-slots": "^0.0.1", "@deepseek-ai/dsh-client-web-react": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.7", + "@deepseek-ai/cordis": "^4.0.0-rc.7", "react": "^18.2.0" }, "devDependencies": { @@ -64,7 +64,7 @@ "@deepseek-ai/dsh-client-web-react": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", "@types/react": "~18.3.1", - "cordis": "^4.0.0-rc.7", + "@deepseek-ai/cordis": "^4.0.0-rc.7", "react": "^18.2.0" }, "files": [ diff --git a/packages/client/ui-agent-preset/src/invariant.ts b/packages/client/ui-agent-preset/src/invariant.ts index 1794763066..8420348123 100644 --- a/packages/client/ui-agent-preset/src/invariant.ts +++ b/packages/client/ui-agent-preset/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-client-ui-agent-preset' diff --git a/packages/client/ui-agent-preset/tests/apply.spec.ts b/packages/client/ui-agent-preset/tests/apply.spec.ts index 23e1944948..3bd834d5e1 100644 --- a/packages/client/ui-agent-preset/tests/apply.spec.ts +++ b/packages/client/ui-agent-preset/tests/apply.spec.ts @@ -5,7 +5,7 @@ * that are already showing, so a default set from one converges the other. */ -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { describe, expect, it, vi } from 'vitest' import { resolveSlotLabel } from '@deepseek-ai/dsh-client-ui-slots' import { SlotsService } from '@deepseek-ai/dsh-client-runtime/client' diff --git a/packages/client/ui-agent-preset/tests/invariant.spec.ts b/packages/client/ui-agent-preset/tests/invariant.spec.ts index 300e561856..b6206763e1 100644 --- a/packages/client/ui-agent-preset/tests/invariant.spec.ts +++ b/packages/client/ui-agent-preset/tests/invariant.spec.ts @@ -1,7 +1,7 @@ /** The package's node half: an empty host body and an explained empty invariant companion. */ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import InvariantService from '@deepseek-ai/dsh-invariants' import * as AgentPresetInvariant from '@deepseek-ai/dsh-client-ui-agent-preset/invariant' diff --git a/packages/client/ui-command/package.json b/packages/client/ui-command/package.json index df3c88a678..5ff21d89b9 100644 --- a/packages/client/ui-command/package.json +++ b/packages/client/ui-command/package.json @@ -50,7 +50,7 @@ "@deepseek-ai/dsh-client-ui-slash": "^0.0.1", "@deepseek-ai/dsh-client-ui-slots": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.7", + "@deepseek-ai/cordis": "^4.0.0-rc.7", "react": "^18.2.0" }, "devDependencies": { @@ -64,7 +64,7 @@ "@deepseek-ai/dsh-client-ui-slots": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", "@types/react": "~18.3.1", - "cordis": "^4.0.0-rc.7", + "@deepseek-ai/cordis": "^4.0.0-rc.7", "react": "^18.2.0" }, "files": [ diff --git a/packages/client/ui-command/src/client/index.ts b/packages/client/ui-command/src/client/index.ts index d65ab0f78e..f8de391fad 100644 --- a/packages/client/ui-command/src/client/index.ts +++ b/packages/client/ui-command/src/client/index.ts @@ -28,7 +28,7 @@ export type { } from './contract.ts' export type { CommandKey } from './locales.ts' -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { command: CommandService } diff --git a/packages/client/ui-command/src/client/service.ts b/packages/client/ui-command/src/client/service.ts index 866ff89c9d..00515c1e41 100644 --- a/packages/client/ui-command/src/client/service.ts +++ b/packages/client/ui-command/src/client/service.ts @@ -7,8 +7,8 @@ * addresses the session's agent by sessionId — sessions are always * agent-backed. */ -import { Service } from 'cordis' -import type { Context } from 'cordis' +import { Service } from '@deepseek-ai/cordis' +import type { Context } from '@deepseek-ai/cordis' import type { ConnectionHandle, SessionId } from '@deepseek-ai/dsh-client-connection/client' import type { ClientContext, ISessions } from '@deepseek-ai/dsh-client-runtime/client' import type { diff --git a/packages/client/ui-command/src/invariant.ts b/packages/client/ui-command/src/invariant.ts index 2d38b762a9..734fef9466 100644 --- a/packages/client/ui-command/src/invariant.ts +++ b/packages/client/ui-command/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-client-ui-command' diff --git a/packages/client/ui-command/tests/browser-plugin.spec.ts b/packages/client/ui-command/tests/browser-plugin.spec.ts index f093548f3e..ae2afff1f5 100644 --- a/packages/client/ui-command/tests/browser-plugin.spec.ts +++ b/packages/client/ui-command/tests/browser-plugin.spec.ts @@ -6,7 +6,7 @@ * scope → popupFor; unknown id fails loud), both fold up on fiber disposal * (HMR safety), and the service satisfies the frozen CommandServiceContract. */ -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { describe, expect, it } from 'vitest' import { createScope, scopeOf, SlotsService } from '@deepseek-ai/dsh-client-runtime/client' import type { SessionId } from '@deepseek-ai/dsh-client-runtime/client' diff --git a/packages/client/ui-command/tests/service.spec.ts b/packages/client/ui-command/tests/service.spec.ts index f7ee172b8e..b5029761fa 100644 --- a/packages/client/ui-command/tests/service.spec.ts +++ b/packages/client/ui-command/tests/service.spec.ts @@ -7,7 +7,7 @@ * payload, the scoped consume-token dispatch, per-session popupFor * lifecycle, and the directory invalidation event subscriptions. */ -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { describe, expect, it, vi } from 'vitest' import { createScope, scopeOf } from '@deepseek-ai/dsh-client-runtime/client' import type { SessionId } from '@deepseek-ai/dsh-client-runtime/client' diff --git a/packages/client/ui-conversation/package.json b/packages/client/ui-conversation/package.json index 5dda7ef637..a21fad9168 100644 --- a/packages/client/ui-conversation/package.json +++ b/packages/client/ui-conversation/package.json @@ -41,7 +41,7 @@ "dependencies": { "@deepseek-ai/dsh-settings": "workspace:^", "clsx": "^2.0.0", - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "peerDependencies": { "@deepseek-ai/dsh-agent": "^0.0.1", @@ -59,7 +59,7 @@ "@deepseek-ai/dsh-llm-retry": "^0.0.1", "@deepseek-ai/dsh-token-meter": "^0.0.1", "@deepseek-ai/dsh-tools": "^0.0.1", - "cordis": "^4.0.0-rc.7", + "@deepseek-ai/cordis": "^4.0.0-rc.7", "react": "^18.2.0" }, "devDependencies": { @@ -86,7 +86,7 @@ "@deepseek-ai/dsh-tools": "workspace:^", "@deepseek-ai/dsh-tool-todo": "workspace:^", "@types/react": "~18.3.1", - "cordis": "^4.0.0-rc.7", + "@deepseek-ai/cordis": "^4.0.0-rc.7", "react": "^18.2.0" }, "files": [ diff --git a/packages/client/ui-conversation/src/client/apply.ts b/packages/client/ui-conversation/src/client/apply.ts index cad25cc84e..5449295055 100644 --- a/packages/client/ui-conversation/src/client/apply.ts +++ b/packages/client/ui-conversation/src/client/apply.ts @@ -1,5 +1,5 @@ /** Registers the conversation components, shared store, and service callbacks. */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { resolveSlotLabel, type BoundActions } from '@deepseek-ai/dsh-client-ui-slots' import { bindSettingsScope, resolveWorkspacePath, type ISessions, type SessionId, diff --git a/packages/client/ui-conversation/src/client/chat/register-node-renderers.ts b/packages/client/ui-conversation/src/client/chat/register-node-renderers.ts index 8926fc2a8e..78aa36d136 100644 --- a/packages/client/ui-conversation/src/client/chat/register-node-renderers.ts +++ b/packages/client/ui-conversation/src/client/chat/register-node-renderers.ts @@ -1,4 +1,4 @@ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { NS } from '../locales.ts' import { AssistantNodeView } from './AssistantNodeView.tsx' import { CommandNodeView, ManualCompactionNodeView } from './CommandNodeView.tsx' diff --git a/packages/client/ui-conversation/src/client/contract/slots.ts b/packages/client/ui-conversation/src/client/contract/slots.ts index bbca9254bc..36b517f5c4 100644 --- a/packages/client/ui-conversation/src/client/contract/slots.ts +++ b/packages/client/ui-conversation/src/client/contract/slots.ts @@ -228,7 +228,7 @@ export interface ChatFileMentions { forClosing(owner: TurnTailOwnerProps): MarkdownFileMentions | undefined } -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { /** Prose file-mention provider (ui-deliverables); reach via ctx.get — optional. */ chatFileMentions: ChatFileMentions diff --git a/packages/client/ui-conversation/src/client/conversation-nodes/assistant.ts b/packages/client/ui-conversation/src/client/conversation-nodes/assistant.ts index 83df1e0df6..5baad5c37b 100644 --- a/packages/client/ui-conversation/src/client/conversation-nodes/assistant.ts +++ b/packages/client/ui-conversation/src/client/conversation-nodes/assistant.ts @@ -1,4 +1,4 @@ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { AssistantBlock, AssistantMessageNode, ConversationLocation, ConversationMatch, ConversationNodeContext, ConversationNodeDefinition, diff --git a/packages/client/ui-conversation/src/client/conversation-nodes/chat-snapshot-builder.ts b/packages/client/ui-conversation/src/client/conversation-nodes/chat-snapshot-builder.ts index f417c33b75..8b5a506030 100644 --- a/packages/client/ui-conversation/src/client/conversation-nodes/chat-snapshot-builder.ts +++ b/packages/client/ui-conversation/src/client/conversation-nodes/chat-snapshot-builder.ts @@ -1,4 +1,4 @@ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { ChatConversationViewNode, ChatLocationNodeIndex, ChatNodeStore, ChatSnapshot, ConversationLocation, ConversationNode, ConversationTimelineSnapshot, diff --git a/packages/client/ui-conversation/src/client/conversation-nodes/command.ts b/packages/client/ui-conversation/src/client/conversation-nodes/command.ts index 752d7e3dd2..1517fbe718 100644 --- a/packages/client/ui-conversation/src/client/conversation-nodes/command.ts +++ b/packages/client/ui-conversation/src/client/conversation-nodes/command.ts @@ -1,4 +1,4 @@ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { CommandNode, CompactionSummaryNode, ConversationMatch, ConversationNodeContext, ConversationNodeDefinition, diff --git a/packages/client/ui-conversation/src/client/conversation-nodes/compaction.ts b/packages/client/ui-conversation/src/client/conversation-nodes/compaction.ts index d21b4aa4b4..2852019c3f 100644 --- a/packages/client/ui-conversation/src/client/conversation-nodes/compaction.ts +++ b/packages/client/ui-conversation/src/client/conversation-nodes/compaction.ts @@ -1,4 +1,4 @@ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { CompactionSummaryNode, ConversationMatch, ConversationNodeContext, ConversationNodeDefinition, } from '@deepseek-ai/dsh-client-runtime/client' diff --git a/packages/client/ui-conversation/src/client/conversation-nodes/fallback.ts b/packages/client/ui-conversation/src/client/conversation-nodes/fallback.ts index a93fc8fdd4..6309c35b94 100644 --- a/packages/client/ui-conversation/src/client/conversation-nodes/fallback.ts +++ b/packages/client/ui-conversation/src/client/conversation-nodes/fallback.ts @@ -1,4 +1,4 @@ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { ConversationNodeDefinition, UnknownSurfaceNode, } from '@deepseek-ai/dsh-client-runtime/client' diff --git a/packages/client/ui-conversation/src/client/conversation-nodes/inbox.ts b/packages/client/ui-conversation/src/client/conversation-nodes/inbox.ts index e3cfae47f4..92e611f77c 100644 --- a/packages/client/ui-conversation/src/client/conversation-nodes/inbox.ts +++ b/packages/client/ui-conversation/src/client/conversation-nodes/inbox.ts @@ -1,4 +1,4 @@ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { ConversationNodeDefinition, ConversationPreviousContext, } from '@deepseek-ai/dsh-client-runtime/client' diff --git a/packages/client/ui-conversation/src/client/conversation-nodes/message.ts b/packages/client/ui-conversation/src/client/conversation-nodes/message.ts index 91300944d7..d57a6d9d96 100644 --- a/packages/client/ui-conversation/src/client/conversation-nodes/message.ts +++ b/packages/client/ui-conversation/src/client/conversation-nodes/message.ts @@ -1,4 +1,4 @@ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { ContextMessageNode, ConversationNodeDefinition, SteeringMessageNode, UserMessageNode, } from '@deepseek-ai/dsh-client-runtime/client' diff --git a/packages/client/ui-conversation/src/client/conversation-nodes/register.ts b/packages/client/ui-conversation/src/client/conversation-nodes/register.ts index 9102b1f2f4..bc911ad5db 100644 --- a/packages/client/ui-conversation/src/client/conversation-nodes/register.ts +++ b/packages/client/ui-conversation/src/client/conversation-nodes/register.ts @@ -1,4 +1,4 @@ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { registerAssistantConversationNode } from './assistant.ts' import { registerChatConversationView } from './chat-snapshot-builder.ts' import { registerCommandConversationNode } from './command.ts' diff --git a/packages/client/ui-conversation/src/client/conversation-nodes/retry.ts b/packages/client/ui-conversation/src/client/conversation-nodes/retry.ts index d504f32928..31b80075a8 100644 --- a/packages/client/ui-conversation/src/client/conversation-nodes/retry.ts +++ b/packages/client/ui-conversation/src/client/conversation-nodes/retry.ts @@ -1,4 +1,4 @@ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { ConversationLocation, ConversationNodeDefinition, ModelRetryNode, } from '@deepseek-ai/dsh-client-runtime/client' diff --git a/packages/client/ui-conversation/src/client/conversation-nodes/tool.ts b/packages/client/ui-conversation/src/client/conversation-nodes/tool.ts index c1b8022e41..46c838e980 100644 --- a/packages/client/ui-conversation/src/client/conversation-nodes/tool.ts +++ b/packages/client/ui-conversation/src/client/conversation-nodes/tool.ts @@ -1,4 +1,4 @@ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { ConversationMatch, ConversationNodeContext, ConversationNodeDefinition, RunningToolCall, ToolCallBlock, ToolResultNode, diff --git a/packages/client/ui-conversation/src/client/conversation-nodes/turn-error.ts b/packages/client/ui-conversation/src/client/conversation-nodes/turn-error.ts index 60b2fca087..1f5a87add8 100644 --- a/packages/client/ui-conversation/src/client/conversation-nodes/turn-error.ts +++ b/packages/client/ui-conversation/src/client/conversation-nodes/turn-error.ts @@ -1,4 +1,4 @@ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { ConversationMatch, ConversationNodeContext, ConversationNodeDefinition, TurnErrorNode, } from '@deepseek-ai/dsh-client-runtime/client' diff --git a/packages/client/ui-conversation/src/client/conversation-nodes/turn-tail.ts b/packages/client/ui-conversation/src/client/conversation-nodes/turn-tail.ts index 2a1b4d2b13..01bee27f3f 100644 --- a/packages/client/ui-conversation/src/client/conversation-nodes/turn-tail.ts +++ b/packages/client/ui-conversation/src/client/conversation-nodes/turn-tail.ts @@ -1,4 +1,4 @@ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { ConversationMatch, ConversationNodeContext, ConversationNodeDefinition, TurnLocation, } from '@deepseek-ai/dsh-client-runtime/client' diff --git a/packages/client/ui-conversation/src/client/index.ts b/packages/client/ui-conversation/src/client/index.ts index afd2f3ba19..5f120157ca 100644 --- a/packages/client/ui-conversation/src/client/index.ts +++ b/packages/client/ui-conversation/src/client/index.ts @@ -36,7 +36,7 @@ export type { } from './contract/slots.ts' // Export discipline: packages/client/AGENTS.md. -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { /** The outward face only; the concrete service stays inside this plugin. */ conversation: import('./service.ts').IConversation diff --git a/packages/client/ui-conversation/src/client/queue/QueueDock.tsx b/packages/client/ui-conversation/src/client/queue/QueueDock.tsx index 35dac88ffd..19cc9c62c8 100644 --- a/packages/client/ui-conversation/src/client/queue/QueueDock.tsx +++ b/packages/client/ui-conversation/src/client/queue/QueueDock.tsx @@ -3,7 +3,7 @@ // // The 'conversation.input.dock' SlotMap declaration lives in // ../contract/slots.ts beside the other input-region slots. -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { useEffect, useId, useMemo, useState } from 'react' import type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots' import type { SessionId } from '@deepseek-ai/dsh-client-runtime/client' diff --git a/packages/client/ui-conversation/src/client/service.ts b/packages/client/ui-conversation/src/client/service.ts index f8d7095491..b70f58c6d9 100644 --- a/packages/client/ui-conversation/src/client/service.ts +++ b/packages/client/ui-conversation/src/client/service.ts @@ -7,8 +7,8 @@ * through one property read; assignment through the tracker proxy and `#` * private fields bypass that rebinding. */ -import { Service } from 'cordis' -import type { Context } from 'cordis' +import { Service } from '@deepseek-ai/cordis' +import type { Context } from '@deepseek-ai/cordis' // Type-only imports: a plugin-to-plugin value import is a bundle purity // error, so scope resolution goes through the sessions service (scopeOf // method) instead of the standalone helper. diff --git a/packages/client/ui-conversation/src/client/skeleton/TodoPanel.tsx b/packages/client/ui-conversation/src/client/skeleton/TodoPanel.tsx index da6faa5794..ad627e7cad 100644 --- a/packages/client/ui-conversation/src/client/skeleton/TodoPanel.tsx +++ b/packages/client/ui-conversation/src/client/skeleton/TodoPanel.tsx @@ -6,7 +6,7 @@ // framework-free. Visual: figma 772:51905 / 772:52972 / 772:53419. import { useId, useState } from 'react' -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots' // The domain's client-namespace pure-type outlet: one import edge delivers // the `todos` projection-key merge (single source, no consumer-side restated diff --git a/packages/client/ui-conversation/src/index.ts b/packages/client/ui-conversation/src/index.ts index b49d7dcf0d..31754ae7e1 100644 --- a/packages/client/ui-conversation/src/index.ts +++ b/packages/client/ui-conversation/src/index.ts @@ -1,6 +1,6 @@ /** Host registration for browser conversation preferences. */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { settingsNamespace } from '@deepseek-ai/dsh-settings' import { CONVERSATION_SETTINGS_NAMESPACE, ConversationSettingsSchema } from './submission-settings.ts' diff --git a/packages/client/ui-conversation/src/invariant.ts b/packages/client/ui-conversation/src/invariant.ts index 66c54081ab..7e0b5b9a9b 100644 --- a/packages/client/ui-conversation/src/invariant.ts +++ b/packages/client/ui-conversation/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-client-ui-conversation' diff --git a/packages/client/ui-conversation/src/submission-settings.ts b/packages/client/ui-conversation/src/submission-settings.ts index 0bd42d33cf..1aa4d0363a 100644 --- a/packages/client/ui-conversation/src/submission-settings.ts +++ b/packages/client/ui-conversation/src/submission-settings.ts @@ -1,6 +1,6 @@ /** Busy-Enter preference stored in the Host user-settings document. */ -import z from 'schemastery' +import z from '@deepseek-ai/schemastery' /** Settings namespace owned by the conversation plugin. */ export const CONVERSATION_SETTINGS_NAMESPACE = 'ui-conversation' diff --git a/packages/client/ui-conversation/tests/coverage-tails.spec.tsx b/packages/client/ui-conversation/tests/coverage-tails.spec.tsx index ad644d940b..b0ce994f44 100644 --- a/packages/client/ui-conversation/tests/coverage-tails.spec.tsx +++ b/packages/client/ui-conversation/tests/coverage-tails.spec.tsx @@ -3,7 +3,7 @@ // without a settings service and AssistantMarkdown reasoning/unknown block arms. import { afterEach, describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { cleanup, render } from '@testing-library/react' import { makeTranslate } from '@deepseek-ai/dsh-client-test-runtime' import { zh as commonZh } from '@deepseek-ai/dsh-client-locale/src/locales/zh.ts' diff --git a/packages/client/ui-conversation/tests/host.spec.ts b/packages/client/ui-conversation/tests/host.spec.ts index 0d16a23da2..0b470e8d47 100644 --- a/packages/client/ui-conversation/tests/host.spec.ts +++ b/packages/client/ui-conversation/tests/host.spec.ts @@ -1,4 +1,4 @@ -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { describe, expect, it } from 'vitest' import { Settings, settingsNamespace, type SettingsNamespace } from '@deepseek-ai/dsh-settings' import { diff --git a/packages/client/ui-conversation/tests/input-scenarios.spec.tsx b/packages/client/ui-conversation/tests/input-scenarios.spec.tsx index ad268611e2..416d2fe620 100644 --- a/packages/client/ui-conversation/tests/input-scenarios.spec.tsx +++ b/packages/client/ui-conversation/tests/input-scenarios.spec.tsx @@ -8,7 +8,7 @@ * itself is not a dependency of this package; the source below is the * decision-table contract at the `SlashSource` boundary. */ -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { afterEach, describe, expect, it, vi } from 'vitest' import { act, cleanup, fireEvent, render } from '@testing-library/react' import { EMPTY_CHAT_SNAPSHOT, SessionsService } from '@deepseek-ai/dsh-client-runtime/client' diff --git a/packages/client/ui-conversation/tests/service-orchestration.spec.ts b/packages/client/ui-conversation/tests/service-orchestration.spec.ts index 8454aa35c8..65b07203f9 100644 --- a/packages/client/ui-conversation/tests/service-orchestration.spec.ts +++ b/packages/client/ui-conversation/tests/service-orchestration.spec.ts @@ -3,7 +3,7 @@ // TestSessions mints tagged scopes through the production createScope, so the // service's scopeOf/binding path runs against production resolution (no local // tag probe). -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { describe, expect, it, vi } from 'vitest' import { AttachmentId } from '@deepseek-ai/dsh-attachment' import { makeTranslate, SlotTestRuntime } from '@deepseek-ai/dsh-client-test-runtime' diff --git a/packages/client/ui-conversation/tests/views-type-chain.spec.tsx b/packages/client/ui-conversation/tests/views-type-chain.spec.tsx index b055c51560..c8d384163d 100644 --- a/packages/client/ui-conversation/tests/views-type-chain.spec.tsx +++ b/packages/client/ui-conversation/tests/views-type-chain.spec.tsx @@ -1,7 +1,7 @@ // View-ring type-chain samples. This spec pins the conversation-owned SlotMap // row, list-kind registration shape, composed view props, and the runtime // ledger projection consumed by ConversationRoot. -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { describe, expect, it } from 'vitest' import type { ReactNode } from 'react' import { SlotsService } from '@deepseek-ai/dsh-client-runtime/client' diff --git a/packages/client/ui-deliverables/package.json b/packages/client/ui-deliverables/package.json index 07e8a1bc28..4b7b8daa56 100644 --- a/packages/client/ui-deliverables/package.json +++ b/packages/client/ui-deliverables/package.json @@ -46,7 +46,7 @@ "@deepseek-ai/dsh-client-ui-conversation": "^0.0.1", "@deepseek-ai/dsh-client-ui-slots": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-client-locale": "workspace:^", @@ -56,7 +56,7 @@ "@deepseek-ai/dsh-client-ui-slots": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", "@types/react": "~18.3.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "files": [ "lib/index.js", diff --git a/packages/client/ui-deliverables/src/invariant.ts b/packages/client/ui-deliverables/src/invariant.ts index 39c39591cf..d14e474ca3 100644 --- a/packages/client/ui-deliverables/src/invariant.ts +++ b/packages/client/ui-deliverables/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-client-ui-deliverables' diff --git a/packages/client/ui-deliverables/tests/produced-files.spec.tsx b/packages/client/ui-deliverables/tests/produced-files.spec.tsx index 75f422787a..f38faf8dd5 100644 --- a/packages/client/ui-deliverables/tests/produced-files.spec.tsx +++ b/packages/client/ui-deliverables/tests/produced-files.spec.tsx @@ -5,7 +5,7 @@ * and opener wiring, and the plugin registrations' fiber-teardown removal * (HMR safety) against the real SlotsService. */ -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { cleanup, fireEvent, render } from '@testing-library/react' import { afterEach, describe, expect, it, vi } from 'vitest' import { diff --git a/packages/client/ui-goal/package.json b/packages/client/ui-goal/package.json index 9e8b6865f9..2e5816437e 100644 --- a/packages/client/ui-goal/package.json +++ b/packages/client/ui-goal/package.json @@ -47,7 +47,7 @@ "@deepseek-ai/dsh-client-ui-slots": "^0.0.1", "@deepseek-ai/dsh-goal": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.7", + "@deepseek-ai/cordis": "^4.0.0-rc.7", "react": "^18.2.0" }, "devDependencies": { @@ -62,7 +62,7 @@ "@deepseek-ai/dsh-invariants": "workspace:^", "@testing-library/react": "^16.1.0", "@types/react": "~18.3.1", - "cordis": "^4.0.0-rc.7", + "@deepseek-ai/cordis": "^4.0.0-rc.7", "react": "^18.2.0", "react-dom": "^18.2.0" }, diff --git a/packages/client/ui-goal/src/invariant.ts b/packages/client/ui-goal/src/invariant.ts index 2120600664..93d0602d25 100644 --- a/packages/client/ui-goal/src/invariant.ts +++ b/packages/client/ui-goal/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-client-ui-goal' diff --git a/packages/client/ui-goal/tests/browser-plugin.spec.tsx b/packages/client/ui-goal/tests/browser-plugin.spec.tsx index 756968136e..9ead151b65 100644 --- a/packages/client/ui-goal/tests/browser-plugin.spec.tsx +++ b/packages/client/ui-goal/tests/browser-plugin.spec.tsx @@ -10,7 +10,7 @@ * plugin fiber (HMR safety). The node half and the invariant companion are * exercised over the same Context. */ -import { Context, Service } from 'cordis' +import { Context, Service } from '@deepseek-ai/cordis' import { describe, expect, it, vi } from 'vitest' import { cleanup, render } from '@testing-library/react' import { afterEach } from 'vitest' diff --git a/packages/client/ui-layout/package.json b/packages/client/ui-layout/package.json index ba41bc9dcb..5fc53a5fa8 100644 --- a/packages/client/ui-layout/package.json +++ b/packages/client/ui-layout/package.json @@ -41,7 +41,7 @@ "@deepseek-ai/dsh-client-ui-slots": "^0.0.1", "@deepseek-ai/dsh-client-ui-theme": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.7", + "@deepseek-ai/cordis": "^4.0.0-rc.7", "react": "^18.2.0" }, "devDependencies": { @@ -51,7 +51,7 @@ "@deepseek-ai/dsh-client-ui-theme": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", "@types/react": "~18.3.1", - "cordis": "^4.0.0-rc.7", + "@deepseek-ai/cordis": "^4.0.0-rc.7", "react": "^18.2.0" }, "files": [ diff --git a/packages/client/ui-layout/src/client/index.ts b/packages/client/ui-layout/src/client/index.ts index 8050cb0916..f2269500b4 100644 --- a/packages/client/ui-layout/src/client/index.ts +++ b/packages/client/ui-layout/src/client/index.ts @@ -23,7 +23,7 @@ import { ThemePresenter } from './theme-presenter.ts' export { LayoutService } from './service.ts' export type { ILayout } from './service.ts' -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { /** The outward face only; the concrete service stays inside this plugin. */ layout: import('./service.ts').ILayout diff --git a/packages/client/ui-layout/src/invariant.ts b/packages/client/ui-layout/src/invariant.ts index dd572e679d..266b9e5b0f 100644 --- a/packages/client/ui-layout/src/invariant.ts +++ b/packages/client/ui-layout/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-client-ui-layout' diff --git a/packages/client/ui-layout/tests/apply.spec.ts b/packages/client/ui-layout/tests/apply.spec.ts index 024382fa79..1aae24bc11 100644 --- a/packages/client/ui-layout/tests/apply.spec.ts +++ b/packages/client/ui-layout/tests/apply.spec.ts @@ -6,7 +6,7 @@ // and the invariant companion ride along — one-line surfaces the aggregate // coverage gate still requires exercised. -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { beforeEach, describe, expect, it, vi } from 'vitest' import { SlotsService } from '@deepseek-ai/dsh-client-runtime/client' import { LocaleService } from '@deepseek-ai/dsh-client-locale/client' diff --git a/packages/client/ui-model/package.json b/packages/client/ui-model/package.json index 6b6ed328fc..dcd139dad5 100644 --- a/packages/client/ui-model/package.json +++ b/packages/client/ui-model/package.json @@ -48,7 +48,7 @@ "@deepseek-ai/dsh-client-ui-slots": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", "clsx": "^2.1.1", - "cordis": "^4.0.0-rc.7", + "@deepseek-ai/cordis": "^4.0.0-rc.7", "react": "^18.2.0" }, "devDependencies": { @@ -63,7 +63,7 @@ "@deepseek-ai/dsh-invariants": "workspace:^", "@types/react": "~18.3.1", "clsx": "^2.1.1", - "cordis": "^4.0.0-rc.7", + "@deepseek-ai/cordis": "^4.0.0-rc.7", "react": "^18.2.0" }, "files": [ diff --git a/packages/client/ui-model/src/client/service.ts b/packages/client/ui-model/src/client/service.ts index 5bf2c744a3..5a35ce0039 100644 --- a/packages/client/ui-model/src/client/service.ts +++ b/packages/client/ui-model/src/client/service.ts @@ -12,13 +12,13 @@ * strings, and it models global+shadow named registries — this is a * per-session singleton with no global layer to merge. */ -import { Service } from 'cordis' -import type { Context } from 'cordis' +import { Service } from '@deepseek-ai/cordis' +import type { Context } from '@deepseek-ai/cordis' import type { ConnectionHandle, SessionId } from '@deepseek-ai/dsh-client-connection/client' import type { SessionsService } from '@deepseek-ai/dsh-client-runtime/client' import { ModelDirectory } from './directory.ts' -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { models: ModelService } diff --git a/packages/client/ui-model/src/invariant.ts b/packages/client/ui-model/src/invariant.ts index baac6dcc70..9b24e5c3c9 100644 --- a/packages/client/ui-model/src/invariant.ts +++ b/packages/client/ui-model/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-client-ui-model' diff --git a/packages/client/ui-model/tests/browser-plugin.spec.ts b/packages/client/ui-model/tests/browser-plugin.spec.ts index 422ada56b3..4c7a1430b1 100644 --- a/packages/client/ui-model/tests/browser-plugin.spec.ts +++ b/packages/client/ui-model/tests/browser-plugin.spec.ts @@ -8,7 +8,7 @@ * (and the reverse), the one-shared-state contract of the dual entry. * Scope disposal drops the directory (HMR safety). */ -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { describe, expect, it } from 'vitest' import { createScope } from '@deepseek-ai/dsh-client-runtime/client' import type { SessionId } from '@deepseek-ai/dsh-client-runtime/client' diff --git a/packages/client/ui-models/package.json b/packages/client/ui-models/package.json index dc02a09aa6..fb0ff5a0c3 100644 --- a/packages/client/ui-models/package.json +++ b/packages/client/ui-models/package.json @@ -45,7 +45,7 @@ "@deepseek-ai/dsh-client-ui-slots": "^0.0.1", "@deepseek-ai/dsh-client-web-react": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.7", + "@deepseek-ai/cordis": "^4.0.0-rc.7", "react": "^18.2.0" }, "devDependencies": { @@ -60,7 +60,7 @@ "@deepseek-ai/dsh-client-web-react": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", "@types/react": "~18.3.1", - "cordis": "^4.0.0-rc.7", + "@deepseek-ai/cordis": "^4.0.0-rc.7", "react": "^18.2.0" }, "files": [ diff --git a/packages/client/ui-models/src/invariant.ts b/packages/client/ui-models/src/invariant.ts index c7c4996748..8b37c0774f 100644 --- a/packages/client/ui-models/src/invariant.ts +++ b/packages/client/ui-models/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-client-ui-models' diff --git a/packages/client/ui-models/tests/apply.spec.ts b/packages/client/ui-models/tests/apply.spec.ts index 2842b94554..dc648e939b 100644 --- a/packages/client/ui-models/tests/apply.spec.ts +++ b/packages/client/ui-models/tests/apply.spec.ts @@ -1,5 +1,5 @@ /** Models section registration: slot declaration injection, the locale-following label thunk, and HMR recovery. */ -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { describe, expect, it, vi } from 'vitest' import { resolveSlotLabel } from '@deepseek-ai/dsh-client-ui-slots' import { SlotsService } from '@deepseek-ai/dsh-client-runtime/client' diff --git a/packages/client/ui-models/tests/components.spec.tsx b/packages/client/ui-models/tests/components.spec.tsx index 09167b55cb..4d7086bd99 100644 --- a/packages/client/ui-models/tests/components.spec.tsx +++ b/packages/client/ui-models/tests/components.spec.tsx @@ -2,7 +2,7 @@ /** Section, setup-card, and hand-written editor behavior over a scripted wire face. */ import { act, cleanup, fireEvent, render, screen, waitFor, within } from '@testing-library/react' import { afterEach, describe, expect, it, vi } from 'vitest' -import Schema from 'schemastery' +import Schema from '@deepseek-ai/schemastery' import { bindSnapshotSelector } from '@deepseek-ai/dsh-client-web-react' import type { RpcResponse, SettingsNamespaceView } from '@deepseek-ai/dsh-client-connection/client' import { diff --git a/packages/client/ui-models/tests/invariant.spec.ts b/packages/client/ui-models/tests/invariant.spec.ts index 8f9622b599..05362ba8ea 100644 --- a/packages/client/ui-models/tests/invariant.spec.ts +++ b/packages/client/ui-models/tests/invariant.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import * as ModelsInvariant from '@deepseek-ai/dsh-client-ui-models/invariant' import InvariantService from '@deepseek-ai/dsh-invariants' import { ModelsSection } from '../src/client/ModelsSection.tsx' diff --git a/packages/client/ui-models/tests/provider-form.spec.tsx b/packages/client/ui-models/tests/provider-form.spec.tsx index 9ff96cdebc..a1953e3a5c 100644 --- a/packages/client/ui-models/tests/provider-form.spec.tsx +++ b/packages/client/ui-models/tests/provider-form.spec.tsx @@ -2,7 +2,7 @@ /** Model-list editing, endpoint interrogation, and hand-declared provider creation. */ import { cleanup, fireEvent, render, screen, waitFor } from '@testing-library/react' import { afterEach, describe, expect, it, vi } from 'vitest' -import Schema from 'schemastery' +import Schema from '@deepseek-ai/schemastery' import { bindSnapshotSelector } from '@deepseek-ai/dsh-client-web-react' import type { RpcResponse, SettingsNamespaceView } from '@deepseek-ai/dsh-client-connection/client' import { ModelsSection } from '../src/client/ModelsSection.tsx' diff --git a/packages/client/ui-permission/package.json b/packages/client/ui-permission/package.json index 4c90851cf7..457511c928 100644 --- a/packages/client/ui-permission/package.json +++ b/packages/client/ui-permission/package.json @@ -49,7 +49,7 @@ "@deepseek-ai/dsh-client-ui-slots": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-permission": "^0.0.1", - "cordis": "^4.0.0-rc.7", + "@deepseek-ai/cordis": "^4.0.0-rc.7", "react": "^18.2.0" }, "devDependencies": { @@ -65,7 +65,7 @@ "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-permission": "workspace:^", "@types/react": "~18.3.1", - "cordis": "^4.0.0-rc.7", + "@deepseek-ai/cordis": "^4.0.0-rc.7", "react": "^18.2.0" }, "files": [ diff --git a/packages/client/ui-permission/src/invariant.ts b/packages/client/ui-permission/src/invariant.ts index 1c3f7d6500..2e531fe55f 100644 --- a/packages/client/ui-permission/src/invariant.ts +++ b/packages/client/ui-permission/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-client-ui-permission' diff --git a/packages/client/ui-permission/tests/browser-plugin.spec.ts b/packages/client/ui-permission/tests/browser-plugin.spec.ts index 309298a64a..4575941b4a 100644 --- a/packages/client/ui-permission/tests/browser-plugin.spec.ts +++ b/packages/client/ui-permission/tests/browser-plugin.spec.ts @@ -8,7 +8,7 @@ * disposal removes the contribution (HMR safety). The same plugin registers * its Settings row and invalidates that row on host settings changes. */ -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { describe, expect, it } from 'vitest' import { SlotsService, type SessionId } from '@deepseek-ai/dsh-client-runtime/client' import { LocaleService } from '@deepseek-ai/dsh-client-locale/client' diff --git a/packages/client/ui-plan/package.json b/packages/client/ui-plan/package.json index c9aa3fd0f1..888cc74005 100644 --- a/packages/client/ui-plan/package.json +++ b/packages/client/ui-plan/package.json @@ -46,7 +46,7 @@ "@deepseek-ai/dsh-client-ui-slots": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-plan-mode": "^0.0.1", - "cordis": "^4.0.0-rc.7", + "@deepseek-ai/cordis": "^4.0.0-rc.7", "react": "^18.2.0" }, "devDependencies": { @@ -61,7 +61,7 @@ "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-plan-mode": "workspace:^", "@types/react": "~18.3.1", - "cordis": "^4.0.0-rc.7", + "@deepseek-ai/cordis": "^4.0.0-rc.7", "react": "^18.2.0" }, "files": [ diff --git a/packages/client/ui-plan/src/invariant.ts b/packages/client/ui-plan/src/invariant.ts index 82c9fc9376..acea37ddeb 100644 --- a/packages/client/ui-plan/src/invariant.ts +++ b/packages/client/ui-plan/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-client-ui-plan' diff --git a/packages/client/ui-plan/tests/browser-plugin.spec.ts b/packages/client/ui-plan/tests/browser-plugin.spec.ts index e384ba5356..79d2903e93 100644 --- a/packages/client/ui-plan/tests/browser-plugin.spec.ts +++ b/packages/client/ui-plan/tests/browser-plugin.spec.ts @@ -5,7 +5,7 @@ * outcomes into null (admitted) or a user-visible failure line; teardown * empties the seat (HMR safety). */ -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { describe, expect, it, vi } from 'vitest' import { SlotsService } from '@deepseek-ai/dsh-client-runtime/client' import type { SessionId } from '@deepseek-ai/dsh-client-runtime/client' diff --git a/packages/client/ui-primitives/package.json b/packages/client/ui-primitives/package.json index bb788f7069..91d8647a55 100644 --- a/packages/client/ui-primitives/package.json +++ b/packages/client/ui-primitives/package.json @@ -45,7 +45,7 @@ "@deepseek-ai/dsh-invariants": "workspace:^", "@types/react": "~18.3.1", "@types/react-dom": "~18.3.0", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "files": [ "lib/index.js", @@ -54,6 +54,6 @@ ], "peerDependencies": { "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/client/ui-primitives/src/invariant.ts b/packages/client/ui-primitives/src/invariant.ts index 5ce3411aff..a92fe97731 100644 --- a/packages/client/ui-primitives/src/invariant.ts +++ b/packages/client/ui-primitives/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-client-ui-primitives' diff --git a/packages/client/ui-primitives/tests/invariant.spec.ts b/packages/client/ui-primitives/tests/invariant.spec.ts index 72e5cb2f7c..122524380a 100644 --- a/packages/client/ui-primitives/tests/invariant.spec.ts +++ b/packages/client/ui-primitives/tests/invariant.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import * as PrimitivesInvariant from '@deepseek-ai/dsh-client-ui-primitives/invariant' import InvariantService from '@deepseek-ai/dsh-invariants' diff --git a/packages/client/ui-question/package.json b/packages/client/ui-question/package.json index 874a634f7c..80f18e3a2a 100644 --- a/packages/client/ui-question/package.json +++ b/packages/client/ui-question/package.json @@ -48,7 +48,7 @@ "peerDependencies": { "@deepseek-ai/dsh-client-locale": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-agent": "workspace:^", @@ -58,7 +58,7 @@ "@deepseek-ai/dsh-tools": "workspace:^", "@deepseek-ai/dsh-user-interaction": "workspace:^", "@types/react": "~18.3.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "files": [ "lib/index.js", diff --git a/packages/client/ui-question/src/invariant.ts b/packages/client/ui-question/src/invariant.ts index 6a6e7ebb90..4da42322c3 100644 --- a/packages/client/ui-question/src/invariant.ts +++ b/packages/client/ui-question/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-client-ui-question' diff --git a/packages/client/ui-question/tests/browser-plugin.spec.ts b/packages/client/ui-question/tests/browser-plugin.spec.ts index 01b077a29a..43e7673da9 100644 --- a/packages/client/ui-question/tests/browser-plugin.spec.ts +++ b/packages/client/ui-question/tests/browser-plugin.spec.ts @@ -6,7 +6,7 @@ * domain-face behavior is covered props-direct in question-composer.spec.tsx; * no renderer machinery here. */ -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { describe, expect, it } from 'vitest' import { SlotsService } from '@deepseek-ai/dsh-client-runtime/client' import { LocaleService } from '@deepseek-ai/dsh-client-locale/client' diff --git a/packages/client/ui-question/tests/node-plugin.spec.ts b/packages/client/ui-question/tests/node-plugin.spec.ts index 4602ef0bed..29f137ebfe 100644 --- a/packages/client/ui-question/tests/node-plugin.spec.ts +++ b/packages/client/ui-question/tests/node-plugin.spec.ts @@ -1,4 +1,4 @@ -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { afterEach, describe, expect, it } from 'vitest' import ToolRegistry from '@deepseek-ai/dsh-tools' import SystemPrompt from '@deepseek-ai/dsh-system-prompt' diff --git a/packages/client/ui-settings-general/package.json b/packages/client/ui-settings-general/package.json index 95166e6d66..a66cb41153 100644 --- a/packages/client/ui-settings-general/package.json +++ b/packages/client/ui-settings-general/package.json @@ -40,7 +40,7 @@ "license": "BSD-3-Clause", "dependencies": { "@deepseek-ai/dsh-settings": "workspace:^", - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "peerDependencies": { "@deepseek-ai/dsh-client-connection": "^0.0.1", @@ -51,7 +51,7 @@ "@deepseek-ai/dsh-client-ui-slots": "^0.0.1", "@deepseek-ai/dsh-client-web-react": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.7", + "@deepseek-ai/cordis": "^4.0.0-rc.7", "react": "^18.2.0" }, "devDependencies": { @@ -65,7 +65,7 @@ "@deepseek-ai/dsh-client-web-react": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", "@types/react": "~18.3.1", - "cordis": "^4.0.0-rc.7", + "@deepseek-ai/cordis": "^4.0.0-rc.7", "react": "^18.2.0" }, "files": [ diff --git a/packages/client/ui-settings-general/src/index.ts b/packages/client/ui-settings-general/src/index.ts index 18518c2835..0cea245db5 100644 --- a/packages/client/ui-settings-general/src/index.ts +++ b/packages/client/ui-settings-general/src/index.ts @@ -1,7 +1,7 @@ /** Host loader entry for the browser implementation exported from `./client`. */ -import type { Context } from 'cordis' -import z from 'schemastery' +import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import { settingsNamespace } from '@deepseek-ai/dsh-settings' import { WELCOME_NOTICE_ACK_FIELD, WELCOME_NOTICE_SETTINGS_NAMESPACE, diff --git a/packages/client/ui-settings-general/src/invariant.ts b/packages/client/ui-settings-general/src/invariant.ts index c5917bd83b..adfd582ca6 100644 --- a/packages/client/ui-settings-general/src/invariant.ts +++ b/packages/client/ui-settings-general/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-client-ui-settings-general' diff --git a/packages/client/ui-settings-general/tests/apply.spec.ts b/packages/client/ui-settings-general/tests/apply.spec.ts index ae06c22c03..4d7301faa1 100644 --- a/packages/client/ui-settings-general/tests/apply.spec.ts +++ b/packages/client/ui-settings-general/tests/apply.spec.ts @@ -1,5 +1,5 @@ /** Ownerless-copy registrations: the six seats, dictionaries, thunked labels, and HMR recovery. */ -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { describe, expect, it, vi } from 'vitest' import { resolveSlotLabel } from '@deepseek-ai/dsh-client-ui-slots' import { SlotsService } from '@deepseek-ai/dsh-client-runtime/client' diff --git a/packages/client/ui-settings-general/tests/host.spec.ts b/packages/client/ui-settings-general/tests/host.spec.ts index 6434bc833a..e78d0e006a 100644 --- a/packages/client/ui-settings-general/tests/host.spec.ts +++ b/packages/client/ui-settings-general/tests/host.spec.ts @@ -1,4 +1,4 @@ -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { describe, expect, it } from 'vitest' import { Settings, settingsNamespace, type SettingsNamespace } from '@deepseek-ai/dsh-settings' import { apply } from '../src/index.ts' diff --git a/packages/client/ui-settings-general/tests/invariant.spec.ts b/packages/client/ui-settings-general/tests/invariant.spec.ts index 59863a5794..343b09b547 100644 --- a/packages/client/ui-settings-general/tests/invariant.spec.ts +++ b/packages/client/ui-settings-general/tests/invariant.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import * as GeneralInvariant from '@deepseek-ai/dsh-client-ui-settings-general/invariant' import InvariantService from '@deepseek-ai/dsh-invariants' diff --git a/packages/client/ui-settings/package.json b/packages/client/ui-settings/package.json index 9383ca0205..138b4e3c88 100644 --- a/packages/client/ui-settings/package.json +++ b/packages/client/ui-settings/package.json @@ -44,7 +44,7 @@ "@deepseek-ai/dsh-client-ui-primitives": "^0.0.1", "@deepseek-ai/dsh-client-ui-slots": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.7", + "@deepseek-ai/cordis": "^4.0.0-rc.7", "react": "^18.2.0", "react-dom": "^18.2.0" }, @@ -57,7 +57,7 @@ "@deepseek-ai/dsh-invariants": "workspace:^", "@types/react-dom": "~18.3.0", "@types/react": "~18.3.1", - "cordis": "^4.0.0-rc.7", + "@deepseek-ai/cordis": "^4.0.0-rc.7", "react": "^18.2.0", "react-dom": "^18.2.0" }, diff --git a/packages/client/ui-settings/src/invariant.ts b/packages/client/ui-settings/src/invariant.ts index 53d7fb066a..f78b25e91c 100644 --- a/packages/client/ui-settings/src/invariant.ts +++ b/packages/client/ui-settings/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-client-ui-settings' diff --git a/packages/client/ui-settings/tests/apply.spec.ts b/packages/client/ui-settings/tests/apply.spec.ts index 3133ad4d76..2e8243fa26 100644 --- a/packages/client/ui-settings/tests/apply.spec.ts +++ b/packages/client/ui-settings/tests/apply.spec.ts @@ -1,5 +1,5 @@ /** Settings shell registration: slot declaration injection, the ledger projections, and HMR recovery. */ -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { describe, expect, it, vi } from 'vitest' import { SlotsService } from '@deepseek-ai/dsh-client-runtime/client' import { apply, inject } from '@deepseek-ai/dsh-client-ui-settings/client' diff --git a/packages/client/ui-settings/tests/invariant.spec.ts b/packages/client/ui-settings/tests/invariant.spec.ts index c3474d5bdd..f9824921a6 100644 --- a/packages/client/ui-settings/tests/invariant.spec.ts +++ b/packages/client/ui-settings/tests/invariant.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import * as SettingsInvariant from '@deepseek-ai/dsh-client-ui-settings/invariant' import InvariantService from '@deepseek-ai/dsh-invariants' diff --git a/packages/client/ui-sidebar/package.json b/packages/client/ui-sidebar/package.json index d40bcabcdb..7a135c1bcc 100644 --- a/packages/client/ui-sidebar/package.json +++ b/packages/client/ui-sidebar/package.json @@ -46,7 +46,7 @@ "@deepseek-ai/dsh-client-ui-primitives": "^0.0.1", "@deepseek-ai/dsh-client-ui-slots": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.7", + "@deepseek-ai/cordis": "^4.0.0-rc.7", "react": "^18.2.0" }, "devDependencies": { @@ -58,7 +58,7 @@ "@deepseek-ai/dsh-client-ui-slots": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", "@types/react": "~18.3.1", - "cordis": "^4.0.0-rc.7", + "@deepseek-ai/cordis": "^4.0.0-rc.7", "react": "^18.2.0" }, "files": [ diff --git a/packages/client/ui-sidebar/src/invariant.ts b/packages/client/ui-sidebar/src/invariant.ts index 52d69c5ce2..94e26021a8 100644 --- a/packages/client/ui-sidebar/src/invariant.ts +++ b/packages/client/ui-sidebar/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-client-ui-sidebar' diff --git a/packages/client/ui-sidebar/tests/apply.spec.tsx b/packages/client/ui-sidebar/tests/apply.spec.tsx index ccd997be76..31fcddfe9f 100644 --- a/packages/client/ui-sidebar/tests/apply.spec.tsx +++ b/packages/client/ui-sidebar/tests/apply.spec.tsx @@ -1,5 +1,5 @@ /** Sidebar shell slot registration and its plain runtime/layout callbacks. */ -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { describe, expect, it, vi } from 'vitest' import { SlotsService } from '@deepseek-ai/dsh-client-runtime/client' import { LocaleService } from '@deepseek-ai/dsh-client-locale/client' diff --git a/packages/client/ui-sidebar/tests/invariant.spec.ts b/packages/client/ui-sidebar/tests/invariant.spec.ts index c524606dd5..11a8d66a08 100644 --- a/packages/client/ui-sidebar/tests/invariant.spec.ts +++ b/packages/client/ui-sidebar/tests/invariant.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import * as SidebarInvariant from '@deepseek-ai/dsh-client-ui-sidebar/invariant' import InvariantService from '@deepseek-ai/dsh-invariants' diff --git a/packages/client/ui-skill/package.json b/packages/client/ui-skill/package.json index 68a2dc2667..0490958e7d 100644 --- a/packages/client/ui-skill/package.json +++ b/packages/client/ui-skill/package.json @@ -47,7 +47,7 @@ "@deepseek-ai/dsh-client-ui-slash": "^0.0.1", "@deepseek-ai/dsh-client-ui-slots": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.7", + "@deepseek-ai/cordis": "^4.0.0-rc.7", "react": "^18.2.0" }, "devDependencies": { @@ -62,7 +62,7 @@ "@deepseek-ai/dsh-invariants": "workspace:^", "@testing-library/react": "^16.1.0", "@types/react": "~18.3.1", - "cordis": "^4.0.0-rc.7", + "@deepseek-ai/cordis": "^4.0.0-rc.7", "react": "^18.2.0", "react-dom": "^18.2.0" }, diff --git a/packages/client/ui-skill/src/invariant.ts b/packages/client/ui-skill/src/invariant.ts index 9246466cd1..718a9586a1 100644 --- a/packages/client/ui-skill/src/invariant.ts +++ b/packages/client/ui-skill/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-client-ui-skill' diff --git a/packages/client/ui-skill/tests/browser-plugin.spec.ts b/packages/client/ui-skill/tests/browser-plugin.spec.ts index 5e143c0b96..844333dd81 100644 --- a/packages/client/ui-skill/tests/browser-plugin.spec.ts +++ b/packages/client/ui-skill/tests/browser-plugin.spec.ts @@ -13,7 +13,7 @@ * projections. Direct driving is deliberate: this spec owns only the * source's own contract. */ -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { describe, expect, it, vi } from 'vitest' import type { SessionId } from '@deepseek-ai/dsh-client-runtime/client' import { SlotsService } from '@deepseek-ai/dsh-client-runtime/client' diff --git a/packages/client/ui-slash/package.json b/packages/client/ui-slash/package.json index 01e48dcdf6..7e99d22875 100644 --- a/packages/client/ui-slash/package.json +++ b/packages/client/ui-slash/package.json @@ -45,7 +45,7 @@ "@deepseek-ai/dsh-client-ui-primitives": "^0.0.1", "@deepseek-ai/dsh-client-ui-slots": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.7", + "@deepseek-ai/cordis": "^4.0.0-rc.7", "react": "^18.2.0" }, "devDependencies": { @@ -56,7 +56,7 @@ "@deepseek-ai/dsh-client-ui-slots": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", "@types/react": "~18.3.1", - "cordis": "^4.0.0-rc.7", + "@deepseek-ai/cordis": "^4.0.0-rc.7", "react": "^18.2.0" }, "files": [ diff --git a/packages/client/ui-slash/src/client/index.ts b/packages/client/ui-slash/src/client/index.ts index bcc20a8679..54f7a96dda 100644 --- a/packages/client/ui-slash/src/client/index.ts +++ b/packages/client/ui-slash/src/client/index.ts @@ -27,7 +27,7 @@ export type { export type { DetectTrigger, ExactMatch, MenuEvent, MenuReduce, MenuState, TriggerHit } from '../core/contract.ts' export type { SlashServiceContract } from './contract.ts' -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { /** The outward face only; the concrete service stays inside this plugin. */ slash: import('./contract.ts').SlashServiceContract diff --git a/packages/client/ui-slash/src/client/service.ts b/packages/client/ui-slash/src/client/service.ts index d9af10e887..35e6153a9b 100644 --- a/packages/client/ui-slash/src/client/service.ts +++ b/packages/client/ui-slash/src/client/service.ts @@ -5,8 +5,8 @@ * {@link SlashController}; the service only registers sources, resolves * controllers by session scope, and relays roster changes. */ -import { Service } from 'cordis' -import type { Context } from 'cordis' +import { Service } from '@deepseek-ai/cordis' +import type { Context } from '@deepseek-ai/cordis' import type { ClientContext, ISessions, SessionId } from '@deepseek-ai/dsh-client-runtime/client' import type { SlashSource } from '../types.ts' import { SlashController } from './controller.ts' diff --git a/packages/client/ui-slash/src/invariant.ts b/packages/client/ui-slash/src/invariant.ts index a83b4841a1..fb9102be3f 100644 --- a/packages/client/ui-slash/src/invariant.ts +++ b/packages/client/ui-slash/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-client-ui-slash' diff --git a/packages/client/ui-slash/src/types.ts b/packages/client/ui-slash/src/types.ts index c62ca520d7..1266bc15da 100644 --- a/packages/client/ui-slash/src/types.ts +++ b/packages/client/ui-slash/src/types.ts @@ -220,7 +220,7 @@ export interface InsertTextRequest { readonly span: TokenSpan } -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Events { /** * Applies one command claim to the scoped Input. Dispatched with the diff --git a/packages/client/ui-slash/tests/apply.spec.ts b/packages/client/ui-slash/tests/apply.spec.ts index c8d65f10c8..b447cd12d0 100644 --- a/packages/client/ui-slash/tests/apply.spec.ts +++ b/packages/client/ui-slash/tests/apply.spec.ts @@ -4,7 +4,7 @@ * registration follows the slot declaration, resolves the per-session controller from the slot's * sessionId, and unregisters on fiber teardown. */ -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { describe, expect, it } from 'vitest' import { LocaleService } from '@deepseek-ai/dsh-client-locale/client' import { usePinnedBrowserLanguages } from '@deepseek-ai/dsh-client-test-runtime' diff --git a/packages/client/ui-slash/tests/service.spec.ts b/packages/client/ui-slash/tests/service.spec.ts index 143f6e6ddf..c642ec8001 100644 --- a/packages/client/ui-slash/tests/service.spec.ts +++ b/packages/client/ui-slash/tests/service.spec.ts @@ -7,7 +7,7 @@ * scope-birth roster warm — is SlashController behavior, tested on a real * session scope (createScope). */ -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { describe, expect, it, vi } from 'vitest' import { createScope, scopeOf } from '@deepseek-ai/dsh-client-runtime/client' import type { SessionId } from '@deepseek-ai/dsh-client-runtime/client' diff --git a/packages/client/ui-slots/package.json b/packages/client/ui-slots/package.json index 9c459fd0f8..ef809470b5 100644 --- a/packages/client/ui-slots/package.json +++ b/packages/client/ui-slots/package.json @@ -22,7 +22,7 @@ "devDependencies": { "@deepseek-ai/dsh-invariants": "workspace:^", "@types/react": "~18.3.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "files": [ "lib/index.js", @@ -31,6 +31,6 @@ ], "peerDependencies": { "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/client/ui-slots/src/invariant.ts b/packages/client/ui-slots/src/invariant.ts index de9ea2c511..d3cd66c5ed 100644 --- a/packages/client/ui-slots/src/invariant.ts +++ b/packages/client/ui-slots/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-client-ui-slots' diff --git a/packages/client/ui-slots/tests/invariant.spec.ts b/packages/client/ui-slots/tests/invariant.spec.ts index 3b5740924f..72d2f32fc8 100644 --- a/packages/client/ui-slots/tests/invariant.spec.ts +++ b/packages/client/ui-slots/tests/invariant.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import * as SlotsInvariant from '@deepseek-ai/dsh-client-ui-slots/invariant' import InvariantService from '@deepseek-ai/dsh-invariants' diff --git a/packages/client/ui-subagent/package.json b/packages/client/ui-subagent/package.json index 43a9c35a42..6c9a178d31 100644 --- a/packages/client/ui-subagent/package.json +++ b/packages/client/ui-subagent/package.json @@ -52,7 +52,7 @@ "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-subagent": "^0.0.1", "@deepseek-ai/dsh-token-meter": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-client-locale": "workspace:^", @@ -66,7 +66,7 @@ "@deepseek-ai/dsh-subagent": "workspace:^", "@deepseek-ai/dsh-token-meter": "workspace:^", "@types/react": "~18.3.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "files": [ "lib/index.js", diff --git a/packages/client/ui-subagent/src/invariant.ts b/packages/client/ui-subagent/src/invariant.ts index 645f88c9b6..b96fefa21c 100644 --- a/packages/client/ui-subagent/src/invariant.ts +++ b/packages/client/ui-subagent/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-client-ui-subagent' diff --git a/packages/client/ui-subagent/tests/browser-plugin.spec.ts b/packages/client/ui-subagent/tests/browser-plugin.spec.ts index 78d04489ab..426dadaa60 100644 --- a/packages/client/ui-subagent/tests/browser-plugin.spec.ts +++ b/packages/client/ui-subagent/tests/browser-plugin.spec.ts @@ -11,7 +11,7 @@ * projections. Direct driving is deliberate: this spec owns only the * source's own contract. */ -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { describe, expect, it } from 'vitest' import { SlotsService, type ConversationSnapshot, type SessionId, type SessionListState, diff --git a/packages/client/ui-theme/package.json b/packages/client/ui-theme/package.json index dbc65c11e9..27f1799c56 100644 --- a/packages/client/ui-theme/package.json +++ b/packages/client/ui-theme/package.json @@ -42,7 +42,7 @@ "@deepseek-ai/dsh-client-ui-primitives": "^0.0.1", "@deepseek-ai/dsh-client-ui-slots": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.7", + "@deepseek-ai/cordis": "^4.0.0-rc.7", "react": "^18.2.0" }, "devDependencies": { @@ -53,7 +53,7 @@ "@deepseek-ai/dsh-client-ui-slots": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", "@types/react": "~18.3.1", - "cordis": "^4.0.0-rc.7", + "@deepseek-ai/cordis": "^4.0.0-rc.7", "react": "^18.2.0" }, "files": [ @@ -70,6 +70,6 @@ "dependencies": { "@deepseek-ai/dsh-settings": "workspace:^", "clsx": "^2.0.0", - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" } } diff --git a/packages/client/ui-theme/src/client/index.ts b/packages/client/ui-theme/src/client/index.ts index 8ef7f3fee7..aaa37ecca8 100644 --- a/packages/client/ui-theme/src/client/index.ts +++ b/packages/client/ui-theme/src/client/index.ts @@ -7,7 +7,7 @@ * document. The plugin also registers the Appearance preference row into the * settings General section — the theme feature owns its own settings surface. */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { BoundActions } from '@deepseek-ai/dsh-client-ui-slots' import { bindSettingsScope, type ClientContext, type SettingsScope, @@ -66,7 +66,7 @@ export interface ThemeSnapshot { revision: number } -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { theme: ThemeService } diff --git a/packages/client/ui-theme/src/index.ts b/packages/client/ui-theme/src/index.ts index 576028d37d..8b8e0c6d30 100644 --- a/packages/client/ui-theme/src/index.ts +++ b/packages/client/ui-theme/src/index.ts @@ -1,6 +1,6 @@ /** Host registration for the browser theme preference. */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { settingsNamespace } from '@deepseek-ai/dsh-settings' import { THEME_SETTINGS_NAMESPACE, ThemeSettingsSchema } from './theme-settings.ts' diff --git a/packages/client/ui-theme/src/invariant.ts b/packages/client/ui-theme/src/invariant.ts index 51667dc5a9..6463b72f5f 100644 --- a/packages/client/ui-theme/src/invariant.ts +++ b/packages/client/ui-theme/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-client-ui-theme' diff --git a/packages/client/ui-theme/src/theme-settings.ts b/packages/client/ui-theme/src/theme-settings.ts index d7fc966031..c2c268e21f 100644 --- a/packages/client/ui-theme/src/theme-settings.ts +++ b/packages/client/ui-theme/src/theme-settings.ts @@ -1,6 +1,6 @@ /** Theme preferences stored in the Host user-settings document. */ -import z from 'schemastery' +import z from '@deepseek-ai/schemastery' /** Built-in preferences accepted at the registry and settings boundaries. */ export const THEME_PREFERENCES = ['light', 'dark', 'system'] as const diff --git a/packages/client/ui-theme/tests/apply.spec.ts b/packages/client/ui-theme/tests/apply.spec.ts index 25c2ac14df..006d64d621 100644 --- a/packages/client/ui-theme/tests/apply.spec.ts +++ b/packages/client/ui-theme/tests/apply.spec.ts @@ -1,7 +1,7 @@ /** ui-theme apply wiring: service provision, settings dictionaries riding the * locale service, declaration-aware Appearance row registration, snapshot * projection into the row store, and HMR collapse recovery. */ -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { describe, expect, it, vi } from 'vitest' import { SlotsService } from '@deepseek-ai/dsh-client-runtime/client' import { LocaleService } from '@deepseek-ai/dsh-client-locale/client' diff --git a/packages/client/ui-theme/tests/host.spec.ts b/packages/client/ui-theme/tests/host.spec.ts index 6cbbd91c27..0e99445892 100644 --- a/packages/client/ui-theme/tests/host.spec.ts +++ b/packages/client/ui-theme/tests/host.spec.ts @@ -1,4 +1,4 @@ -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { describe, expect, it } from 'vitest' import { Settings, settingsNamespace, type SettingsNamespace } from '@deepseek-ai/dsh-settings' import { diff --git a/packages/client/ui-theme/tests/invariant.spec.ts b/packages/client/ui-theme/tests/invariant.spec.ts index c5eedc9dd7..1e7e4a75ba 100644 --- a/packages/client/ui-theme/tests/invariant.spec.ts +++ b/packages/client/ui-theme/tests/invariant.spec.ts @@ -1,6 +1,6 @@ // @vitest-environment jsdom import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { apply as nodeApply } from '@deepseek-ai/dsh-client-ui-theme' import { apply as clientApply, inject, ThemeService } from '@deepseek-ai/dsh-client-ui-theme/client' import * as ThemeInvariant from '@deepseek-ai/dsh-client-ui-theme/invariant' diff --git a/packages/client/ui-theme/tests/theme.spec.ts b/packages/client/ui-theme/tests/theme.spec.ts index b7fc3bd17a..774b7dd10a 100644 --- a/packages/client/ui-theme/tests/theme.spec.ts +++ b/packages/client/ui-theme/tests/theme.spec.ts @@ -1,6 +1,6 @@ // @vitest-environment jsdom import { afterEach, describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { stubSettingsScope, type StubSettingsScope } from '@deepseek-ai/dsh-client-test-runtime' import type { ThemeSettings, ThemeSnapshot } from '@deepseek-ai/dsh-client-ui-theme/client' import { ThemeService } from '@deepseek-ai/dsh-client-ui-theme/client' diff --git a/packages/client/ui-tool/package.json b/packages/client/ui-tool/package.json index c40b09abdb..2db30e5d48 100644 --- a/packages/client/ui-tool/package.json +++ b/packages/client/ui-tool/package.json @@ -47,7 +47,7 @@ "@deepseek-ai/dsh-client-ui-primitives": "^0.0.1", "@deepseek-ai/dsh-client-ui-slots": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.7", + "@deepseek-ai/cordis": "^4.0.0-rc.7", "react": "^18.2.0" }, "devDependencies": { @@ -62,7 +62,7 @@ "@deepseek-ai/dsh-invariants": "workspace:^", "@testing-library/react": "^16.1.0", "@types/react": "~18.3.1", - "cordis": "^4.0.0-rc.7", + "@deepseek-ai/cordis": "^4.0.0-rc.7", "react": "^18.2.0", "react-dom": "^18.2.0" }, diff --git a/packages/client/ui-tool/src/client/tool/toolviews/ask-question-row.tsx b/packages/client/ui-tool/src/client/tool/toolviews/ask-question-row.tsx index 880938567f..a8a7a6497b 100644 --- a/packages/client/ui-tool/src/client/tool/toolviews/ask-question-row.tsx +++ b/packages/client/ui-tool/src/client/tool/toolviews/ask-question-row.tsx @@ -7,7 +7,7 @@ // render in the composer takeover. import { IconQuestionOutline14 } from '@deepseek-ai/dsh-client-ui-primitives' -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots' import type { ToolCallViewProps } from '../../contract/slots.ts' import { toolRowModel } from '../models/tool-call-model.ts' diff --git a/packages/client/ui-tool/src/client/tool/toolviews/bash-sample.tsx b/packages/client/ui-tool/src/client/tool/toolviews/bash-sample.tsx index 71a8503e69..dc9a02a901 100644 --- a/packages/client/ui-tool/src/client/tool/toolviews/bash-sample.tsx +++ b/packages/client/ui-tool/src/client/tool/toolviews/bash-sample.tsx @@ -14,7 +14,7 @@ // collapsed summary is the failure's first line in the error color. import { useState, type KeyboardEvent } from 'react' -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import clsx from 'clsx' import { IconApiOutline14, IconChevronDownOutline14, IconInspectOutline12, StateDot, TerminalBlock, diff --git a/packages/client/ui-tool/src/client/tool/toolviews/file-mutation-row.tsx b/packages/client/ui-tool/src/client/tool/toolviews/file-mutation-row.tsx index 8dd7a37306..9616dab7cd 100644 --- a/packages/client/ui-tool/src/client/tool/toolviews/file-mutation-row.tsx +++ b/packages/client/ui-tool/src/client/tool/toolviews/file-mutation-row.tsx @@ -8,7 +8,7 @@ // `result.isError`) keeps the model-facing error text on ToolRow's Output // section, its first line in the collapsed summary. -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { IconEditOutline16 } from '@deepseek-ai/dsh-client-ui-primitives' import type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots' import type { ToolCallViewProps } from '../../contract/slots.ts' diff --git a/packages/client/ui-tool/src/client/tool/toolviews/read-row.tsx b/packages/client/ui-tool/src/client/tool/toolviews/read-row.tsx index c404f535e5..c066b6667a 100644 --- a/packages/client/ui-tool/src/client/tool/toolviews/read-row.tsx +++ b/packages/client/ui-tool/src/client/tool/toolviews/read-row.tsx @@ -7,7 +7,7 @@ // yet) and a non-read result render the summary row alone: the read intent is // result-side only, so there is no running-state read card to draw. -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { IconBrowseOutline16 } from '@deepseek-ai/dsh-client-ui-primitives' import type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots' import type { ToolCallViewProps } from '../../contract/slots.ts' diff --git a/packages/client/ui-tool/src/client/tool/toolviews/search-row.tsx b/packages/client/ui-tool/src/client/tool/toolviews/search-row.tsx index 10fea1b8c8..47b17b6fa8 100644 --- a/packages/client/ui-tool/src/client/tool/toolviews/search-row.tsx +++ b/packages/client/ui-tool/src/client/tool/toolviews/search-row.tsx @@ -11,7 +11,7 @@ // nested run_code sub-dispatch, a legacy generic result) surfaces its // model-facing text through ToolRow's Output section instead. -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { IconSearchOutline16 } from '@deepseek-ai/dsh-client-ui-primitives' import type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots' import type { ToolCallViewProps } from '../../contract/slots.ts' diff --git a/packages/client/ui-tool/src/client/tool/toolviews/todo-row.tsx b/packages/client/ui-tool/src/client/tool/toolviews/todo-row.tsx index 111189aede..143a43ee29 100644 --- a/packages/client/ui-tool/src/client/tool/toolviews/todo-row.tsx +++ b/packages/client/ui-tool/src/client/tool/toolviews/todo-row.tsx @@ -8,7 +8,7 @@ // above the composer, so the row stays one line until expanded. import { IconChecklistOutline14 } from '@deepseek-ai/dsh-client-ui-primitives' -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots' import type { ToolCallViewProps } from '../../contract/slots.ts' import { toolRowModel } from '../models/tool-call-model.ts' diff --git a/packages/client/ui-tool/src/client/tool/toolviews/web-row.tsx b/packages/client/ui-tool/src/client/tool/toolviews/web-row.tsx index 80489c478f..c0e546f071 100644 --- a/packages/client/ui-tool/src/client/tool/toolviews/web-row.tsx +++ b/packages/client/ui-tool/src/client/tool/toolviews/web-row.tsx @@ -9,7 +9,7 @@ // no web card (the tools keep a generic pending view), so a running row is the // summary line alone. -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { IconBrowseOutline16, IconSearchOutline16 } from '@deepseek-ai/dsh-client-ui-primitives' import type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots' import type { ToolCallViewProps } from '../../contract/slots.ts' diff --git a/packages/client/ui-tool/src/invariant.ts b/packages/client/ui-tool/src/invariant.ts index bfee949195..e00671b0d7 100644 --- a/packages/client/ui-tool/src/invariant.ts +++ b/packages/client/ui-tool/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-client-ui-tool' diff --git a/packages/client/ui-tool/tests/chat-code-subcalls.spec.tsx b/packages/client/ui-tool/tests/chat-code-subcalls.spec.tsx index df5dcf6718..1a7dd2d892 100644 --- a/packages/client/ui-tool/tests/chat-code-subcalls.spec.tsx +++ b/packages/client/ui-tool/tests/chat-code-subcalls.spec.tsx @@ -8,7 +8,7 @@ // and a file sub-row click opens the host path. Running parents // (runningCalls) nest their so-far dispatches the same way. -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' import { cleanup, fireEvent, render } from '@testing-library/react' import { diff --git a/packages/client/ui-tool/tests/read-card.spec.tsx b/packages/client/ui-tool/tests/read-card.spec.tsx index 012ae754b2..ef00460103 100644 --- a/packages/client/ui-tool/tests/read-card.spec.tsx +++ b/packages/client/ui-tool/tests/read-card.spec.tsx @@ -8,7 +8,7 @@ import { afterEach, describe, expect, it, vi } from 'vitest' import { cleanup, fireEvent, render } from '@testing-library/react' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { bindSnapshotSelector } from '@deepseek-ai/dsh-client-web-react' import { createSnapshotStore } from '@deepseek-ai/dsh-client-runtime/client' import { makeTranslate } from '@deepseek-ai/dsh-client-test-runtime' diff --git a/packages/client/ui-tool/tests/web-card.spec.tsx b/packages/client/ui-tool/tests/web-card.spec.tsx index 927b760b82..44f63147a0 100644 --- a/packages/client/ui-tool/tests/web-card.spec.tsx +++ b/packages/client/ui-tool/tests/web-card.spec.tsx @@ -294,7 +294,7 @@ describe('web toolview registration', () => { return () => {} }, }, - } as unknown as import('cordis').Context + } as unknown as import('@deepseek-ai/cordis').Context webToolview.apply(ctx) expect(registered.map(r => r.key)).toEqual(['web_search', 'web_fetch']) // Both keys claim the conversation locale seat ToolRow's body copy needs. diff --git a/packages/client/ui-trajectory/package.json b/packages/client/ui-trajectory/package.json index 9ed4b550c1..6f85a51c8a 100644 --- a/packages/client/ui-trajectory/package.json +++ b/packages/client/ui-trajectory/package.json @@ -44,7 +44,7 @@ "@deepseek-ai/dsh-client-runtime": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-client-ui-primitives": "^0.0.1", - "cordis": "^4.0.0-rc.7", + "@deepseek-ai/cordis": "^4.0.0-rc.7", "react": "^18.2.0", "react-dom": "^18.2.0" }, @@ -56,7 +56,7 @@ "@deepseek-ai/dsh-invariants": "workspace:^", "@types/react": "~18.3.1", "@types/react-dom": "~18.3.0", - "cordis": "^4.0.0-rc.7", + "@deepseek-ai/cordis": "^4.0.0-rc.7", "react": "^18.2.0", "react-dom": "^18.2.0" }, diff --git a/packages/client/ui-trajectory/src/client/index.ts b/packages/client/ui-trajectory/src/client/index.ts index a6b5a4282d..e1d3a5cc17 100644 --- a/packages/client/ui-trajectory/src/client/index.ts +++ b/packages/client/ui-trajectory/src/client/index.ts @@ -2,7 +2,7 @@ * Browser trajectory plugin contributing one entry to the conversation view * slot without defining a service. */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { SessionId } from '@deepseek-ai/dsh-client-runtime/client' // Type-only: the 'conversation.view' SlotMap row (declared by the slot's // owning package) must be in the program for the register calls to type. diff --git a/packages/client/ui-trajectory/src/invariant.ts b/packages/client/ui-trajectory/src/invariant.ts index 11e56bb058..7a43d872cc 100644 --- a/packages/client/ui-trajectory/src/invariant.ts +++ b/packages/client/ui-trajectory/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-client-ui-trajectory' diff --git a/packages/client/ui-trajectory/tests/client-bundle.spec.ts b/packages/client/ui-trajectory/tests/client-bundle.spec.ts index 579a97337a..511cf03b5c 100644 --- a/packages/client/ui-trajectory/tests/client-bundle.spec.ts +++ b/packages/client/ui-trajectory/tests/client-bundle.spec.ts @@ -8,7 +8,7 @@ */ import { readFileSync } from 'node:fs' import { resolve } from 'node:path' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { afterEach, describe, expect, it } from 'vitest' import { SlotsService } from '@deepseek-ai/dsh-client-runtime/client' diff --git a/packages/client/ui-trajectory/tests/views.spec.tsx b/packages/client/ui-trajectory/tests/views.spec.tsx index c9952be580..26adf85ba8 100644 --- a/packages/client/ui-trajectory/tests/views.spec.tsx +++ b/packages/client/ui-trajectory/tests/views.spec.tsx @@ -7,7 +7,7 @@ * event ledger with its timing overview, and fiber disposal removes the tab. * Timeline projection and inclusive focus edge cases ride along. */ -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' import { act, cleanup, fireEvent, render, screen } from '@testing-library/react' import { createElement, type ComponentProps, type FC, type ReactNode } from 'react' diff --git a/packages/client/ui-workspace/package.json b/packages/client/ui-workspace/package.json index 197369cd48..5607c8cc40 100644 --- a/packages/client/ui-workspace/package.json +++ b/packages/client/ui-workspace/package.json @@ -47,7 +47,7 @@ "@deepseek-ai/dsh-client-ui-primitives": "^0.0.1", "@deepseek-ai/dsh-client-ui-slots": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.7", + "@deepseek-ai/cordis": "^4.0.0-rc.7", "react": "^18.2.0" }, "devDependencies": { @@ -60,7 +60,7 @@ "@deepseek-ai/dsh-client-ui-slots": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", "@types/react": "~18.3.1", - "cordis": "^4.0.0-rc.7", + "@deepseek-ai/cordis": "^4.0.0-rc.7", "react": "^18.2.0" }, "files": [ diff --git a/packages/client/ui-workspace/src/invariant.ts b/packages/client/ui-workspace/src/invariant.ts index d3f0df2cdc..4a15d37998 100644 --- a/packages/client/ui-workspace/src/invariant.ts +++ b/packages/client/ui-workspace/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-client-ui-workspace' diff --git a/packages/client/ui-workspace/tests/apply.spec.ts b/packages/client/ui-workspace/tests/apply.spec.ts index d6dfe8d185..44645a9ee3 100644 --- a/packages/client/ui-workspace/tests/apply.spec.ts +++ b/packages/client/ui-workspace/tests/apply.spec.ts @@ -1,4 +1,4 @@ -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { describe, expect, it, vi } from 'vitest' import { SlotsService } from '@deepseek-ai/dsh-client-runtime/client' import { LocaleService } from '@deepseek-ai/dsh-client-locale/client' diff --git a/packages/client/ui-workspace/tests/invariant.spec.ts b/packages/client/ui-workspace/tests/invariant.spec.ts index 0606c94e09..8773f754df 100644 --- a/packages/client/ui-workspace/tests/invariant.spec.ts +++ b/packages/client/ui-workspace/tests/invariant.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import * as WorkspaceInvariant from '@deepseek-ai/dsh-client-ui-workspace/invariant' import InvariantService from '@deepseek-ai/dsh-invariants' diff --git a/packages/client/web-react/package.json b/packages/client/web-react/package.json index b5e242a00e..5aeae6f06f 100644 --- a/packages/client/web-react/package.json +++ b/packages/client/web-react/package.json @@ -26,12 +26,12 @@ }, "peerDependencies": { "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-invariants": "workspace:^", "@types/react": "~18.3.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "files": [ "lib/index.js", diff --git a/packages/client/web-react/src/invariant.ts b/packages/client/web-react/src/invariant.ts index aff9c09cd3..6d4fec6566 100644 --- a/packages/client/web-react/src/invariant.ts +++ b/packages/client/web-react/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-client-web-react' diff --git a/packages/client/web/package.json b/packages/client/web/package.json index 847d126386..348f1ce1cb 100644 --- a/packages/client/web/package.json +++ b/packages/client/web/package.json @@ -30,19 +30,19 @@ "react-dom": "^18.2.0" }, "devDependencies": { - "@cordisjs/plugin-loader": "workspace:^", + "@deepseek-ai/cordis-plugin-loader": "workspace:^", "@deepseek-ai/dsh-client-runtime": "workspace:^", "@deepseek-ai/dsh-client-test-runtime": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", "@types/react": "~18.3.1", "@types/react-dom": "~18.3.0", - "cordis": "^4.0.0-rc.7", + "@deepseek-ai/cordis": "^4.0.0-rc.7", "typescript": "^6.0.3" }, "peerDependencies": { - "@cordisjs/plugin-loader": "^1.0.0-rc.5", + "@deepseek-ai/cordis-plugin-loader": "^1.0.0-rc.5", "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "files": [ "lib/index.js", diff --git a/packages/client/web/src/app-shell.ts b/packages/client/web/src/app-shell.ts index 140fd49c60..3ab76c54ba 100644 --- a/packages/client/web/src/app-shell.ts +++ b/packages/client/web/src/app-shell.ts @@ -3,7 +3,7 @@ * graph and shell registry; there is no npm package behind it. */ import type { ReactNode } from 'react' -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { createSlotRenderer } from '@deepseek-ai/dsh-client-web-react' import { buildRenderApp } from './app.tsx' @@ -16,7 +16,7 @@ export interface AppShellService { renderApp: () => ReactNode } -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { /** The shell assembly face, provided by the app-shell entry once its inject set is active. */ appShell: AppShellService diff --git a/packages/client/web/src/app.tsx b/packages/client/web/src/app.tsx index 5e0010301c..646dcec3dc 100644 --- a/packages/client/web/src/app.tsx +++ b/packages/client/web/src/app.tsx @@ -6,7 +6,7 @@ * the program. */ import type { ReactNode } from 'react' -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { bindSnapshotSelector } from '@deepseek-ai/dsh-client-web-react' import { DocumentTitle } from './DocumentTitle.tsx' // Type-only: pulls the runtime's SlotMap declaration merge (the 'root' key) into this program. diff --git a/packages/client/web/src/boot.tsx b/packages/client/web/src/boot.tsx index c1203929f9..7afc298767 100644 --- a/packages/client/web/src/boot.tsx +++ b/packages/client/web/src/boot.tsx @@ -32,8 +32,8 @@ * decisions (the app-shell assembly is itself a graph entry, the only * shell-own module registered with the module system). */ -import { Context } from 'cordis' -import Loader from '@cordisjs/plugin-loader' +import { Context } from '@deepseek-ai/cordis' +import Loader from '@deepseek-ai/cordis-plugin-loader' import { createRoot, type Root } from 'react-dom/client' import * as ModulesClient from '@deepseek-ai/dsh-client-modules/client' import { diff --git a/packages/client/web/src/invariant.ts b/packages/client/web/src/invariant.ts index 7b9fa6292c..8964082cc8 100644 --- a/packages/client/web/src/invariant.ts +++ b/packages/client/web/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-client-web' diff --git a/packages/client/web/src/loader-status.ts b/packages/client/web/src/loader-status.ts index 03ac761afe..8f8d250ef0 100644 --- a/packages/client/web/src/loader-status.ts +++ b/packages/client/web/src/loader-status.ts @@ -10,7 +10,7 @@ * the loading page has to work while (and especially when) plugins fail. * @module @deepseek-ai/dsh-client-web/src/loader-status */ -import type { FiberState } from 'cordis' +import type { FiberState } from '@deepseek-ai/cordis' /** * Value mirror of cordis's `FiberState` const enum: a const enum has no diff --git a/packages/client/web/src/platform.ts b/packages/client/web/src/platform.ts index dc6b9e58ed..e7997cf728 100644 --- a/packages/client/web/src/platform.ts +++ b/packages/client/web/src/platform.ts @@ -6,7 +6,7 @@ /** The module specifiers the shell shares into the frozen module table. */ export const PLATFORM_MODULES = [ - 'react', 'react/jsx-runtime', 'react-dom', 'react-dom/client', 'cordis', + 'react', 'react/jsx-runtime', 'react-dom', 'react-dom/client', '@deepseek-ai/cordis', '@deepseek-ai/dsh-client-ui-slots', '@deepseek-ai/dsh-client-web-react', '@deepseek-ai/dsh-client-ui-primitives', diff --git a/packages/client/web/src/seed.ts b/packages/client/web/src/seed.ts index fd5360f0f7..868b0fa058 100644 --- a/packages/client/web/src/seed.ts +++ b/packages/client/web/src/seed.ts @@ -10,7 +10,7 @@ import * as React from 'react' import * as ReactJsxRuntime from 'react/jsx-runtime' import * as ReactDom from 'react-dom' import * as ReactDomClient from 'react-dom/client' -import * as Cordis from 'cordis' +import * as Cordis from '@deepseek-ai/cordis' import * as UiSlots from '@deepseek-ai/dsh-client-ui-slots' import * as WebReact from '@deepseek-ai/dsh-client-web-react' import * as UiPrimitives from '@deepseek-ai/dsh-client-ui-primitives' @@ -30,7 +30,7 @@ export function getStaticModules(): Record { 'react/jsx-runtime': ReactJsxRuntime, 'react-dom': ReactDom, 'react-dom/client': ReactDomClient, - 'cordis': Cordis, + '@deepseek-ai/cordis': Cordis, '@deepseek-ai/dsh-client-ui-slots': UiSlots, '@deepseek-ai/dsh-client-web-react': WebReact, '@deepseek-ai/dsh-client-ui-primitives': UiPrimitives, diff --git a/packages/client/web/tests/app-shell.spec.tsx b/packages/client/web/tests/app-shell.spec.tsx index 10acab85d8..445ba787f8 100644 --- a/packages/client/web/tests/app-shell.spec.tsx +++ b/packages/client/web/tests/app-shell.spec.tsx @@ -8,7 +8,7 @@ */ import { afterEach, describe, expect, it, vi } from 'vitest' import { act, cleanup, render } from '@testing-library/react' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { SlotsService } from '@deepseek-ai/dsh-client-runtime/client' import { TestSessions, TestWorkspaces } from '@deepseek-ai/dsh-client-test-runtime' import type { Stabilizer } from '@deepseek-ai/dsh-client-test-runtime' diff --git a/packages/client/web/tests/app.spec.tsx b/packages/client/web/tests/app.spec.tsx index b8f5cb2fde..70bdf38611 100644 --- a/packages/client/web/tests/app.spec.tsx +++ b/packages/client/web/tests/app.spec.tsx @@ -6,7 +6,7 @@ */ import { afterEach, describe, expect, it } from 'vitest' import { cleanup, render } from '@testing-library/react' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { SlotTestRuntime } from '@deepseek-ai/dsh-client-test-runtime' import type { SessionId } from '@deepseek-ai/dsh-client-runtime/client' import { buildRenderApp } from '@deepseek-ai/dsh-client-web/src/app.tsx' diff --git a/packages/code-runtime/code-runtime-worker/package.json b/packages/code-runtime/code-runtime-worker/package.json index cc72bf1b12..565541abc8 100644 --- a/packages/code-runtime/code-runtime-worker/package.json +++ b/packages/code-runtime/code-runtime-worker/package.json @@ -33,16 +33,16 @@ "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-session": "^0.0.1", "@deepseek-ai/dsh-timeout": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { "@deepseek-ai/dsh-code-runtime": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-session": "workspace:^", "@deepseek-ai/dsh-timeout": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/code-runtime/code-runtime-worker/src/index.ts b/packages/code-runtime/code-runtime-worker/src/index.ts index 8193cb587e..df3c3ff98f 100644 --- a/packages/code-runtime/code-runtime-worker/src/index.ts +++ b/packages/code-runtime/code-runtime-worker/src/index.ts @@ -10,8 +10,8 @@ import { Worker } from 'node:worker_threads' import { stripTypeScriptTypes } from 'node:module' import type { Readable } from 'node:stream' import { fileURLToPath } from 'node:url' -import { Context } from 'cordis' -import z from 'schemastery' +import { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import { MAX_TIMER_DELAY_MS } from '@deepseek-ai/dsh-timeout' import { CodeRuntime, DUNDER_MEMBER, PORTABLE_RESERVED_WORDS, RESERVED_BINDING_GLOBALS, RESERVED_ERROR_MEMBERS } from '@deepseek-ai/dsh-code-runtime' import type { CodeBindingNamespace, CodeJsonValue, CodeRunFailure, CodeRunRequest, CodeRunResult } from '@deepseek-ai/dsh-code-runtime' diff --git a/packages/code-runtime/code-runtime-worker/src/invariant.ts b/packages/code-runtime/code-runtime-worker/src/invariant.ts index 3455104441..4569372efb 100644 --- a/packages/code-runtime/code-runtime-worker/src/invariant.ts +++ b/packages/code-runtime/code-runtime-worker/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-code-runtime-worker' diff --git a/packages/code-runtime/code-runtime-worker/tests/built-lib.e2e.ts b/packages/code-runtime/code-runtime-worker/tests/built-lib.e2e.ts index 5a09dd69f2..f0903002f1 100644 --- a/packages/code-runtime/code-runtime-worker/tests/built-lib.e2e.ts +++ b/packages/code-runtime/code-runtime-worker/tests/built-lib.e2e.ts @@ -18,7 +18,7 @@ const built = ['lib/index.js', 'lib/worker.cjs'].every(file => existsSync(join(p describe.skipIf(!built)('built lib real load path (plain node)', () => { it('runs a TypeScript program with a binding through lib/index.js and its lib/worker.cjs entry', async () => { const script = ` - const { Context } = await import('cordis') + const { Context } = await import('@deepseek-ai/cordis') const { WorkerCodeRuntime } = await import('@deepseek-ai/dsh-code-runtime-worker') const ctx = new Context() await ctx.plugin(WorkerCodeRuntime, {}) diff --git a/packages/code-runtime/code-runtime-worker/tests/runtime.spec.ts b/packages/code-runtime/code-runtime-worker/tests/runtime.spec.ts index 54f58eb414..d15bd9f8bd 100644 --- a/packages/code-runtime/code-runtime-worker/tests/runtime.spec.ts +++ b/packages/code-runtime/code-runtime-worker/tests/runtime.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { WorkerCodeRuntime } from '@deepseek-ai/dsh-code-runtime-worker' import type { Config } from '@deepseek-ai/dsh-code-runtime-worker' import type { CodeBindingFunction, CodeBindingNamespace, CodeRunResult } from '@deepseek-ai/dsh-code-runtime' diff --git a/packages/code-runtime/code-runtime/package.json b/packages/code-runtime/code-runtime/package.json index f6e3a08ce1..053e56b54a 100644 --- a/packages/code-runtime/code-runtime/package.json +++ b/packages/code-runtime/code-runtime/package.json @@ -26,10 +26,10 @@ "license": "BSD-3-Clause", "peerDependencies": { "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-invariants": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/code-runtime/code-runtime/src/index.ts b/packages/code-runtime/code-runtime/src/index.ts index 9a7716aea0..c23143f821 100644 --- a/packages/code-runtime/code-runtime/src/index.ts +++ b/packages/code-runtime/code-runtime/src/index.ts @@ -4,7 +4,7 @@ * @module @deepseek-ai/dsh-code-runtime */ -import { Context, Service } from 'cordis' +import { Context, Service } from '@deepseek-ai/cordis' import type { CodeRunRequest, CodeRunResult } from './types.ts' export type { @@ -86,7 +86,7 @@ export const PORTABLE_RESERVED_WORDS: ReadonlySet = new Set([ 'global', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'match', 'type', '_', ]) -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { codeRuntime: CodeRuntime } diff --git a/packages/code-runtime/code-runtime/src/invariant.ts b/packages/code-runtime/code-runtime/src/invariant.ts index 9c4019699b..5f234691e0 100644 --- a/packages/code-runtime/code-runtime/src/invariant.ts +++ b/packages/code-runtime/code-runtime/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-code-runtime' diff --git a/packages/code-runtime/code-runtime/tests/service.spec.ts b/packages/code-runtime/code-runtime/tests/service.spec.ts index 7ea3a30b31..44e356329a 100644 --- a/packages/code-runtime/code-runtime/tests/service.spec.ts +++ b/packages/code-runtime/code-runtime/tests/service.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { CodeRuntime } from '@deepseek-ai/dsh-code-runtime' import type { CodeRunRequest, CodeRunResult } from '@deepseek-ai/dsh-code-runtime' diff --git a/packages/compact/command-compact/package.json b/packages/compact/command-compact/package.json index 324051b188..ec043adca7 100644 --- a/packages/compact/command-compact/package.json +++ b/packages/compact/command-compact/package.json @@ -28,17 +28,17 @@ "@deepseek-ai/dsh-commands": "^0.0.1", "@deepseek-ai/dsh-compact": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { - "@cordisjs/plugin-include": "workspace:^", - "@cordisjs/plugin-loader": "workspace:^", + "@deepseek-ai/cordis-plugin-include": "workspace:^", + "@deepseek-ai/cordis-plugin-loader": "workspace:^", "@deepseek-ai/dsh-agent": "workspace:^", "@deepseek-ai/dsh-commands": "workspace:^", "@deepseek-ai/dsh-compact": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-llm": "workspace:^", "@deepseek-ai/dsh-session": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/compact/command-compact/src/index.ts b/packages/compact/command-compact/src/index.ts index b3f80d87fd..01639a780a 100644 --- a/packages/compact/command-compact/src/index.ts +++ b/packages/compact/command-compact/src/index.ts @@ -3,7 +3,7 @@ * @module @deepseek-ai/dsh-command-compact */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { ManualCompactionError } from '@deepseek-ai/dsh-compact' import type { CommandInvocation, CommandResult } from '@deepseek-ai/dsh-commands' diff --git a/packages/compact/command-compact/src/invariant.ts b/packages/compact/command-compact/src/invariant.ts index 09b3c04d8d..903c9d4375 100644 --- a/packages/compact/command-compact/src/invariant.ts +++ b/packages/compact/command-compact/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-command-compact' diff --git a/packages/compact/command-compact/tests/command-compact.spec.ts b/packages/compact/command-compact/tests/command-compact.spec.ts index 0c419d6799..ba09e5c42a 100644 --- a/packages/compact/command-compact/tests/command-compact.spec.ts +++ b/packages/compact/command-compact/tests/command-compact.spec.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' -import Loader from '@cordisjs/plugin-loader' +import { Context } from '@deepseek-ai/cordis' +import Loader from '@deepseek-ai/cordis-plugin-loader' import type { Agent } from '@deepseek-ai/dsh-agent' import CommandService, { type CommandResult } from '@deepseek-ai/dsh-commands' import { diff --git a/packages/compact/command-compact/tests/loader-composition.spec.ts b/packages/compact/command-compact/tests/loader-composition.spec.ts index 5f7fd0b346..10033d27af 100644 --- a/packages/compact/command-compact/tests/loader-composition.spec.ts +++ b/packages/compact/command-compact/tests/loader-composition.spec.ts @@ -3,9 +3,9 @@ import { tmpdir } from 'node:os' import { join } from 'node:path' import { pathToFileURL } from 'node:url' import { afterEach, describe, expect, it } from 'vitest' -import { Context } from 'cordis' -import Loader from '@cordisjs/plugin-loader' -import Include from '@cordisjs/plugin-include' +import { Context } from '@deepseek-ai/cordis' +import Loader from '@deepseek-ai/cordis-plugin-loader' +import Include from '@deepseek-ai/cordis-plugin-include' import type { Agent } from '@deepseek-ai/dsh-agent' import CommandService from '@deepseek-ai/dsh-commands' import { diff --git a/packages/compact/compact-basic/README.i18n.yaml b/packages/compact/compact-basic/README.i18n.yaml index 75e9e7be19..146170b779 100644 --- a/packages/compact/compact-basic/README.i18n.yaml +++ b/packages/compact/compact-basic/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/compact/compact-basic/README.md -README.md: 97c71cafe1eba7dd29c903535b378439586e807e -README.zh.md: 55a0080fe3c08e5559d737d46f57e23645a52cad +README.md: 4812f858b4773d8cc5ea6a1543430c08f858374f +README.zh.md: 189c5cad5e98533d2dad217404c8c2bcaf41b94b diff --git a/packages/compact/compact-basic/README.md b/packages/compact/compact-basic/README.md index 97c71cafe1..4812f858b4 100644 --- a/packages/compact/compact-basic/README.md +++ b/packages/compact/compact-basic/README.md @@ -49,7 +49,7 @@ An adapter may return no capacity for a valid dynamic route, and resolved capaci `BasicCompactService` requires `ctx.llm`, `ctx.tokenMeter`, and `ctx.sessions`. The composition below receives `ctx.llm` from its host and installs the other two services: ```ts -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { BasicCompactService } from '@deepseek-ai/dsh-compact-basic' import SessionStore from '@deepseek-ai/dsh-session' import TokenMeterService from '@deepseek-ai/dsh-token-meter' diff --git a/packages/compact/compact-basic/README.zh.md b/packages/compact/compact-basic/README.zh.md index 55a0080fe3..189c5cad5e 100644 --- a/packages/compact/compact-basic/README.zh.md +++ b/packages/compact/compact-basic/README.zh.md @@ -49,7 +49,7 @@ `BasicCompactService` 需要 `ctx.llm`、`ctx.tokenMeter` 和 `ctx.sessions`。以下组合从其宿主接收 `ctx.llm`,并安装另外两项服务: ```ts -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { BasicCompactService } from '@deepseek-ai/dsh-compact-basic' import SessionStore from '@deepseek-ai/dsh-session' import TokenMeterService from '@deepseek-ai/dsh-token-meter' diff --git a/packages/compact/compact-basic/package.json b/packages/compact/compact-basic/package.json index 3fffee14a7..f407d15188 100644 --- a/packages/compact/compact-basic/package.json +++ b/packages/compact/compact-basic/package.json @@ -33,7 +33,7 @@ "@deepseek-ai/dsh-session": "^0.0.1", "@deepseek-ai/dsh-token-meter": "^0.0.1", "@deepseek-ai/dsh-compact-tool-result-prune": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "peerDependenciesMeta": { "@deepseek-ai/dsh-compact-tool-result-prune": { @@ -41,11 +41,11 @@ } }, "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { - "@cordisjs/plugin-include": "workspace:^", - "@cordisjs/plugin-loader": "workspace:^", + "@deepseek-ai/cordis-plugin-include": "workspace:^", + "@deepseek-ai/cordis-plugin-loader": "workspace:^", "@deepseek-ai/dsh-agent": "workspace:^", "@deepseek-ai/dsh-agent-loop": "workspace:^", "@deepseek-ai/dsh-agent-loop-testkit": "workspace:^", @@ -58,6 +58,6 @@ "@deepseek-ai/dsh-token-meter": "workspace:^", "@deepseek-ai/dsh-compact-tool-result-prune": "workspace:^", "@deepseek-ai/dsh-tools": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/compact/compact-basic/src/index.ts b/packages/compact/compact-basic/src/index.ts index d3c710bef3..773f31d976 100644 --- a/packages/compact/compact-basic/src/index.ts +++ b/packages/compact/compact-basic/src/index.ts @@ -4,8 +4,8 @@ * @module @deepseek-ai/dsh-compact-basic */ -import { Context } from 'cordis' -import z from 'schemastery' +import { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import { CompactService, ManualCompactionError } from '@deepseek-ai/dsh-compact' import type { CompactionResult, CompactionTrigger } from '@deepseek-ai/dsh-compact' import type { TokenMeterService } from '@deepseek-ai/dsh-token-meter' diff --git a/packages/compact/compact-basic/src/invariant.ts b/packages/compact/compact-basic/src/invariant.ts index 172790d233..4818d6b5a6 100644 --- a/packages/compact/compact-basic/src/invariant.ts +++ b/packages/compact/compact-basic/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-compact-basic' diff --git a/packages/compact/compact-basic/src/summarizer.ts b/packages/compact/compact-basic/src/summarizer.ts index 681919905e..99e164ce12 100644 --- a/packages/compact/compact-basic/src/summarizer.ts +++ b/packages/compact/compact-basic/src/summarizer.ts @@ -4,7 +4,7 @@ * @module @deepseek-ai/dsh-compact-basic/summarizer */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { contentHasImage, createUserMessage, BlockAssembler, LlmError } from '@deepseek-ai/dsh-llm' import type { ContentBlock, FinishReason, GenerateOptions, Message, TokenUsage, ToolSchema, diff --git a/packages/compact/compact-basic/tests/compact-basic.spec.ts b/packages/compact/compact-basic/tests/compact-basic.spec.ts index b3e088c82a..4d1973326a 100644 --- a/packages/compact/compact-basic/tests/compact-basic.spec.ts +++ b/packages/compact/compact-basic/tests/compact-basic.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, expectTypeOf, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { AttachmentId } from '@deepseek-ai/dsh-attachment' import BasicCompactService from '@deepseek-ai/dsh-compact-basic' import type { BasicCompactConfig } from '@deepseek-ai/dsh-compact-basic' diff --git a/packages/compact/compact-basic/tests/compact-loop-repro.spec.ts b/packages/compact/compact-basic/tests/compact-loop-repro.spec.ts index 471207aa97..536ef9d543 100644 --- a/packages/compact/compact-basic/tests/compact-loop-repro.spec.ts +++ b/packages/compact/compact-basic/tests/compact-loop-repro.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { toolPairingBalancedAfter, toolPairingBalancedBefore } from '@deepseek-ai/dsh-compact' import { createUserMessage, CONTEXT_WINDOW_EXCEEDED_CODE, LlmError, resolveRetryPolicy , createMessage } from '@deepseek-ai/dsh-llm' import type { ContentBlock, GenerateOptions, LlmResolvedModelInfo, ResolvedRetryPolicy, StreamChunk } from '@deepseek-ai/dsh-llm' diff --git a/packages/compact/compact-basic/tests/loader-composition.spec.ts b/packages/compact/compact-basic/tests/loader-composition.spec.ts index 162c44efd4..2284d54cf9 100644 --- a/packages/compact/compact-basic/tests/loader-composition.spec.ts +++ b/packages/compact/compact-basic/tests/loader-composition.spec.ts @@ -3,9 +3,9 @@ import { tmpdir } from 'node:os' import { join } from 'node:path' import { pathToFileURL } from 'node:url' import { afterEach, describe, expect, it } from 'vitest' -import { Context } from 'cordis' -import Loader from '@cordisjs/plugin-loader' -import Include from '@cordisjs/plugin-include' +import { Context } from '@deepseek-ai/cordis' +import Loader from '@deepseek-ai/cordis-plugin-loader' +import Include from '@deepseek-ai/cordis-plugin-include' import LlmService from '@deepseek-ai/dsh-llm' import SessionStore from '@deepseek-ai/dsh-session' import TokenMeterService from '@deepseek-ai/dsh-token-meter' diff --git a/packages/compact/compact-basic/tests/manual-compact.spec.ts b/packages/compact/compact-basic/tests/manual-compact.spec.ts index 0599d3f364..16cf680e1d 100644 --- a/packages/compact/compact-basic/tests/manual-compact.spec.ts +++ b/packages/compact/compact-basic/tests/manual-compact.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import AgentLoop from '@deepseek-ai/dsh-agent-loop' import { mountAgentLoopTestDependencies } from '@deepseek-ai/dsh-agent-loop-testkit' import InvariantService from '@deepseek-ai/dsh-invariants' diff --git a/packages/compact/compact-tool-result-prune/README.i18n.yaml b/packages/compact/compact-tool-result-prune/README.i18n.yaml index 78eb863c26..ebe54ccf58 100644 --- a/packages/compact/compact-tool-result-prune/README.i18n.yaml +++ b/packages/compact/compact-tool-result-prune/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/compact/compact-tool-result-prune/README.md -README.md: edeba52b189b3cee5530faf7efc04043a326917f -README.zh.md: abc19afa784ec1121430b57a9d90d22d12b89810 +README.md: 8ebc422f37db1f86adedcb207f03eefc75b8d242 +README.zh.md: 8f8920bbc2b6014f98a3d82a4501ae33e367f39c diff --git a/packages/compact/compact-tool-result-prune/README.md b/packages/compact/compact-tool-result-prune/README.md index edeba52b18..8ebc422f37 100644 --- a/packages/compact/compact-tool-result-prune/README.md +++ b/packages/compact/compact-tool-result-prune/README.md @@ -31,7 +31,7 @@ All values are integers; the threshold is positive and head/tail are non-negativ ## Usage ```ts -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import ToolResultPruneService from '@deepseek-ai/dsh-compact-tool-result-prune' export function apply(ctx: Context): void { diff --git a/packages/compact/compact-tool-result-prune/README.zh.md b/packages/compact/compact-tool-result-prune/README.zh.md index abc19afa78..8f8920bbc2 100644 --- a/packages/compact/compact-tool-result-prune/README.zh.md +++ b/packages/compact/compact-tool-result-prune/README.zh.md @@ -31,7 +31,7 @@ ## 用法 ```ts -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import ToolResultPruneService from '@deepseek-ai/dsh-compact-tool-result-prune' export function apply(ctx: Context): void { diff --git a/packages/compact/compact-tool-result-prune/package.json b/packages/compact/compact-tool-result-prune/package.json index bc38eccdb0..5a30f7fc97 100644 --- a/packages/compact/compact-tool-result-prune/package.json +++ b/packages/compact/compact-tool-result-prune/package.json @@ -30,19 +30,19 @@ "@deepseek-ai/dsh-llm": "^0.0.1", "@deepseek-ai/dsh-session": "^0.0.1", "@deepseek-ai/dsh-token-meter": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { - "@cordisjs/plugin-include": "workspace:^", - "@cordisjs/plugin-loader": "workspace:^", + "@deepseek-ai/cordis-plugin-include": "workspace:^", + "@deepseek-ai/cordis-plugin-loader": "workspace:^", "@deepseek-ai/dsh-compact": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-llm": "workspace:^", "@deepseek-ai/dsh-session": "workspace:^", "@deepseek-ai/dsh-token-meter": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/compact/compact-tool-result-prune/src/index.ts b/packages/compact/compact-tool-result-prune/src/index.ts index 48e3ee308b..89e27108e9 100644 --- a/packages/compact/compact-tool-result-prune/src/index.ts +++ b/packages/compact/compact-tool-result-prune/src/index.ts @@ -4,8 +4,8 @@ * @module @deepseek-ai/dsh-compact-tool-result-prune */ -import { Context, Service } from 'cordis' -import z from 'schemastery' +import { Context, Service } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import { freezeMessage } from '@deepseek-ai/dsh-llm' import type { ContentBlock } from '@deepseek-ai/dsh-llm' import type { Session, SessionEvent, ToolResultMessage } from '@deepseek-ai/dsh-session' @@ -29,7 +29,7 @@ export type { ToolResultPruneConfig, } from './types.ts' -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { toolResultPrune: ToolResultPruneService } diff --git a/packages/compact/compact-tool-result-prune/src/invariant.ts b/packages/compact/compact-tool-result-prune/src/invariant.ts index 8c2b0a1133..199a4c9073 100644 --- a/packages/compact/compact-tool-result-prune/src/invariant.ts +++ b/packages/compact/compact-tool-result-prune/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-compact-tool-result-prune' diff --git a/packages/compact/compact-tool-result-prune/tests/loader-composition.spec.ts b/packages/compact/compact-tool-result-prune/tests/loader-composition.spec.ts index fbc4b840c9..9db0f0e976 100644 --- a/packages/compact/compact-tool-result-prune/tests/loader-composition.spec.ts +++ b/packages/compact/compact-tool-result-prune/tests/loader-composition.spec.ts @@ -3,9 +3,9 @@ import { tmpdir } from 'node:os' import { join } from 'node:path' import { pathToFileURL } from 'node:url' import { afterEach, describe, expect, it } from 'vitest' -import { Context } from 'cordis' -import Loader from '@cordisjs/plugin-loader' -import Include from '@cordisjs/plugin-include' +import { Context } from '@deepseek-ai/cordis' +import Loader from '@deepseek-ai/cordis-plugin-loader' +import Include from '@deepseek-ai/cordis-plugin-include' import TokenMeterService from '@deepseek-ai/dsh-token-meter' import ToolResultPruneService from '@deepseek-ai/dsh-compact-tool-result-prune' diff --git a/packages/compact/compact-tool-result-prune/tests/tool-result-prune.spec.ts b/packages/compact/compact-tool-result-prune/tests/tool-result-prune.spec.ts index 69a28eb123..672abf1286 100644 --- a/packages/compact/compact-tool-result-prune/tests/tool-result-prune.spec.ts +++ b/packages/compact/compact-tool-result-prune/tests/tool-result-prune.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { CallId , createMessage, createToolResultMessage } from '@deepseek-ai/dsh-llm' import type { ContentBlock } from '@deepseek-ai/dsh-llm' import SessionStore, { diff --git a/packages/compact/compact/package.json b/packages/compact/compact/package.json index 860145e542..2a4c3c9518 100644 --- a/packages/compact/compact/package.json +++ b/packages/compact/compact/package.json @@ -39,7 +39,7 @@ "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-llm": "^0.0.1", "@deepseek-ai/dsh-session": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-brand": "workspace:^", @@ -47,6 +47,6 @@ "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-llm": "workspace:^", "@deepseek-ai/dsh-session": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/compact/compact/src/index.ts b/packages/compact/compact/src/index.ts index 6fb9706c04..d3be6f5750 100644 --- a/packages/compact/compact/src/index.ts +++ b/packages/compact/compact/src/index.ts @@ -7,7 +7,7 @@ * @module @deepseek-ai/dsh-compact */ -import { Context, Service } from 'cordis' +import { Context, Service } from '@deepseek-ai/cordis' import type { Session } from '@deepseek-ai/dsh-session' import type { CommandId } from '@deepseek-ai/dsh-commands/brand' import type { CompactionResult } from './types.ts' @@ -78,7 +78,7 @@ export interface ManualCompactAgentContext extends CompactAgentContext { runMaintenance(task: (signal: AbortSignal) => Promise): Promise } -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { compact: CompactService } diff --git a/packages/compact/compact/src/invariant.ts b/packages/compact/compact/src/invariant.ts index adac557db5..1942bc8510 100644 --- a/packages/compact/compact/src/invariant.ts +++ b/packages/compact/compact/src/invariant.ts @@ -1,6 +1,6 @@ /** Package-owned compaction log-stream invariants. @module @deepseek-ai/dsh-compact/invariant */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { isReplacementSurfaceEvent } from '@deepseek-ai/dsh-session' import type { Session, SessionEvent } from '@deepseek-ai/dsh-session' import type { InvariantFailure, InvariantInstaller } from '@deepseek-ai/dsh-invariants' diff --git a/packages/compact/compact/tests/compact.spec.ts b/packages/compact/compact/tests/compact.spec.ts index 74e2bd0270..c9af4ed2e0 100644 --- a/packages/compact/compact/tests/compact.spec.ts +++ b/packages/compact/compact/tests/compact.spec.ts @@ -1,6 +1,6 @@ import { createUserMessage } from '@deepseek-ai/dsh-llm' import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { CompactionId, CompactService, diff --git a/packages/compact/compact/tests/invariant.spec.ts b/packages/compact/compact/tests/invariant.spec.ts index 1637c16179..e49fe8ec3e 100644 --- a/packages/compact/compact/tests/invariant.spec.ts +++ b/packages/compact/compact/tests/invariant.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import SessionStore, { Session, SessionId } from '@deepseek-ai/dsh-session' import { createUserMessage } from '@deepseek-ai/dsh-llm' import { CompactionId, compactCheckpointSource } from '@deepseek-ai/dsh-compact' diff --git a/packages/context/session-reference/package.json b/packages/context/session-reference/package.json index 48111ca09b..259c7a9a63 100644 --- a/packages/context/session-reference/package.json +++ b/packages/context/session-reference/package.json @@ -25,7 +25,7 @@ ], "license": "BSD-3-Clause", "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "peerDependencies": { "@deepseek-ai/dsh-agent": "^0.0.1", @@ -35,7 +35,7 @@ "@deepseek-ai/dsh-retention": "^0.0.1", "@deepseek-ai/dsh-session": "^0.0.1", "@deepseek-ai/dsh-session-query": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-agent": "workspace:^", @@ -45,6 +45,6 @@ "@deepseek-ai/dsh-retention": "workspace:^", "@deepseek-ai/dsh-session": "workspace:^", "@deepseek-ai/dsh-session-query": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/context/session-reference/src/index.ts b/packages/context/session-reference/src/index.ts index 01a6965027..792f0abd20 100644 --- a/packages/context/session-reference/src/index.ts +++ b/packages/context/session-reference/src/index.ts @@ -5,8 +5,8 @@ * @module @deepseek-ai/dsh-session-reference */ -import { Context, Service } from 'cordis' -import z from 'schemastery' +import { Context, Service } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import type { Agent } from '@deepseek-ai/dsh-agent' import { createUserMessage } from '@deepseek-ai/dsh-llm' import type { ContentBlock, UserMessage } from '@deepseek-ai/dsh-llm' @@ -50,7 +50,7 @@ user explicitly repeats them. ` const PROMPT_SUFFIX = '\n' -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { sessionReferences: SessionReferenceService } diff --git a/packages/context/session-reference/src/invariant.ts b/packages/context/session-reference/src/invariant.ts index c8a5b0b5c3..9a277e7614 100644 --- a/packages/context/session-reference/src/invariant.ts +++ b/packages/context/session-reference/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-session-reference' diff --git a/packages/context/session-reference/tests/session-reference.spec.ts b/packages/context/session-reference/tests/session-reference.spec.ts index ce964af16a..9f9dee8bb8 100644 --- a/packages/context/session-reference/tests/session-reference.spec.ts +++ b/packages/context/session-reference/tests/session-reference.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import type { Agent } from '@deepseek-ai/dsh-agent' import { CompactionId, compactCheckpointSource } from '@deepseek-ai/dsh-compact' import { createUserMessage, CallId , createMessage, createToolResultMessage } from '@deepseek-ai/dsh-llm' diff --git a/packages/context/time-context/package.json b/packages/context/time-context/package.json index 8e8421fd01..d2bf0a1dbe 100644 --- a/packages/context/time-context/package.json +++ b/packages/context/time-context/package.json @@ -25,13 +25,13 @@ ], "license": "BSD-3-Clause", "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "peerDependencies": { "@deepseek-ai/dsh-agent": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-session": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-agent": "workspace:^", @@ -43,6 +43,6 @@ "@deepseek-ai/dsh-session": "workspace:^", "@deepseek-ai/dsh-system-prompt": "workspace:^", "@deepseek-ai/dsh-tools": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/context/time-context/src/index.ts b/packages/context/time-context/src/index.ts index 5e95beb2b2..977d73cd35 100644 --- a/packages/context/time-context/src/index.ts +++ b/packages/context/time-context/src/index.ts @@ -5,8 +5,8 @@ * @module @deepseek-ai/dsh-time-context */ -import type { Context } from 'cordis' -import z from 'schemastery' +import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import type { Agent, PreStepDecision } from '@deepseek-ai/dsh-agent' import { createUserMessage } from '@deepseek-ai/dsh-llm' diff --git a/packages/context/time-context/src/invariant.ts b/packages/context/time-context/src/invariant.ts index ffd3fd22a8..8a1a888e4c 100644 --- a/packages/context/time-context/src/invariant.ts +++ b/packages/context/time-context/src/invariant.ts @@ -1,6 +1,6 @@ /** Package-owned durable clock-context invariants. @module @deepseek-ai/dsh-time-context/invariant */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { Session, SessionEvent } from '@deepseek-ai/dsh-session' import type { InvariantFailure, InvariantInstaller } from '@deepseek-ai/dsh-invariants' diff --git a/packages/context/time-context/tests/invariant.spec.ts b/packages/context/time-context/tests/invariant.spec.ts index b5f0385b3f..02a04eb863 100644 --- a/packages/context/time-context/tests/invariant.spec.ts +++ b/packages/context/time-context/tests/invariant.spec.ts @@ -1,6 +1,6 @@ import { createUserMessage } from '@deepseek-ai/dsh-llm' import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import type { ContentBlock } from '@deepseek-ai/dsh-llm' import SessionStore, { Session, SessionId, type SessionEvent } from '@deepseek-ai/dsh-session' import * as TimeInvariant from '@deepseek-ai/dsh-time-context/invariant' diff --git a/packages/context/time-context/tests/time-context.spec.ts b/packages/context/time-context/tests/time-context.spec.ts index a0ffb9e619..5e50b38136 100644 --- a/packages/context/time-context/tests/time-context.spec.ts +++ b/packages/context/time-context/tests/time-context.spec.ts @@ -1,6 +1,6 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' -import Loader from '@cordisjs/plugin-loader' +import { Context } from '@deepseek-ai/cordis' +import Loader from '@deepseek-ai/cordis-plugin-loader' import { createUserMessage, CallId, LlmAdapter } from '@deepseek-ai/dsh-llm' import type { GenerateOptions, StreamChunk } from '@deepseek-ai/dsh-llm' import { Session, SessionId, type SessionEvent } from '@deepseek-ai/dsh-session' diff --git a/packages/context/tmux-context/package.json b/packages/context/tmux-context/package.json index 524036a667..99959c18f3 100644 --- a/packages/context/tmux-context/package.json +++ b/packages/context/tmux-context/package.json @@ -25,14 +25,14 @@ ], "license": "BSD-3-Clause", "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "peerDependencies": { "@deepseek-ai/dsh-agent": "^0.0.1", "@deepseek-ai/dsh-bash": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-session": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-agent": "workspace:^", @@ -41,6 +41,6 @@ "@deepseek-ai/dsh-llm": "workspace:^", "@deepseek-ai/dsh-session": "workspace:^", "@deepseek-ai/dsh-system-prompt": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/context/tmux-context/src/index.ts b/packages/context/tmux-context/src/index.ts index c489ec0970..8eac866637 100644 --- a/packages/context/tmux-context/src/index.ts +++ b/packages/context/tmux-context/src/index.ts @@ -18,8 +18,8 @@ * @module @deepseek-ai/dsh-tmux-context */ -import type { Context, LoggerService } from 'cordis' -import z from 'schemastery' +import type { Context, LoggerService } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import type { Agent, PreStepDecision } from '@deepseek-ai/dsh-agent' import type { BashExecutor, BashRunResult } from '@deepseek-ai/dsh-bash' import { createUserMessage } from '@deepseek-ai/dsh-llm' diff --git a/packages/context/tmux-context/src/invariant.ts b/packages/context/tmux-context/src/invariant.ts index 181f1a2289..901f7c4043 100644 --- a/packages/context/tmux-context/src/invariant.ts +++ b/packages/context/tmux-context/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-tmux-context' diff --git a/packages/context/tmux-context/tests/tmux-context.spec.ts b/packages/context/tmux-context/tests/tmux-context.spec.ts index 12bc37b9ce..0b28486019 100644 --- a/packages/context/tmux-context/tests/tmux-context.spec.ts +++ b/packages/context/tmux-context/tests/tmux-context.spec.ts @@ -1,5 +1,5 @@ import { afterEach, describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { Session, SessionId } from '@deepseek-ai/dsh-session' import AgentRegistry, { agentEvents, Inbox, type Agent } from '@deepseek-ai/dsh-agent' import { createUserMessage } from '@deepseek-ai/dsh-llm' diff --git a/packages/context/workspace-context/package.json b/packages/context/workspace-context/package.json index 6548fb49a8..4972796a44 100644 --- a/packages/context/workspace-context/package.json +++ b/packages/context/workspace-context/package.json @@ -32,13 +32,13 @@ "@deepseek-ai/dsh-paths": "^0.0.1", "@deepseek-ai/dsh-session": "^0.0.1", "@deepseek-ai/dsh-tools": "^0.0.1", - "cordis": "^4.0.0-rc.6" + "@deepseek-ai/cordis": "^4.0.0-rc.6" }, "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { - "@cordisjs/plugin-loader": "workspace:^", + "@deepseek-ai/cordis-plugin-loader": "workspace:^", "@deepseek-ai/dsh-agent": "workspace:^", "@deepseek-ai/dsh-agent-loop": "workspace:^", "@deepseek-ai/dsh-fs": "workspace:^", @@ -51,6 +51,6 @@ "@deepseek-ai/dsh-system-prompt": "workspace:^", "@deepseek-ai/dsh-tool-fs": "workspace:^", "@deepseek-ai/dsh-tools": "workspace:^", - "cordis": "^4.0.0-rc.6" + "@deepseek-ai/cordis": "^4.0.0-rc.6" } } diff --git a/packages/context/workspace-context/src/config.ts b/packages/context/workspace-context/src/config.ts index c1a1fad1e6..cc3d9d7bbf 100644 --- a/packages/context/workspace-context/src/config.ts +++ b/packages/context/workspace-context/src/config.ts @@ -5,7 +5,7 @@ */ import { relative } from 'node:path' -import z from 'schemastery' +import z from '@deepseek-ai/schemastery' import { resolveDshHome } from '@deepseek-ai/dsh-paths' const DEFAULT_PROJECT_ROOT_MARKERS = ['.git'] as const diff --git a/packages/context/workspace-context/src/index.ts b/packages/context/workspace-context/src/index.ts index fee08f2c08..22611d2658 100644 --- a/packages/context/workspace-context/src/index.ts +++ b/packages/context/workspace-context/src/index.ts @@ -9,7 +9,7 @@ * @module @deepseek-ai/dsh-workspace-context */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { isDeepStrictEqual } from 'node:util' import type { Agent, PreStepDecision } from '@deepseek-ai/dsh-agent' import { createUserMessage } from '@deepseek-ai/dsh-llm' diff --git a/packages/context/workspace-context/src/invariant.ts b/packages/context/workspace-context/src/invariant.ts index f6c99ea10e..a3860cb122 100644 --- a/packages/context/workspace-context/src/invariant.ts +++ b/packages/context/workspace-context/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-workspace-context' diff --git a/packages/context/workspace-context/tests/workspace-context.e2e.ts b/packages/context/workspace-context/tests/workspace-context.e2e.ts index c1151428e2..0ed6d812ac 100644 --- a/packages/context/workspace-context/tests/workspace-context.e2e.ts +++ b/packages/context/workspace-context/tests/workspace-context.e2e.ts @@ -3,7 +3,7 @@ import { mkdtemp, mkdir, rm, writeFile } from 'node:fs/promises' import { tmpdir } from 'node:os' import { join } from 'node:path' import { afterEach, describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import LlmService from '@deepseek-ai/dsh-llm' import SessionStore, { SessionId } from '@deepseek-ai/dsh-session' import SystemPrompt from '@deepseek-ai/dsh-system-prompt' diff --git a/packages/context/workspace-context/tests/workspace-context.spec.ts b/packages/context/workspace-context/tests/workspace-context.spec.ts index a40d3aec9a..0f177a1d49 100644 --- a/packages/context/workspace-context/tests/workspace-context.spec.ts +++ b/packages/context/workspace-context/tests/workspace-context.spec.ts @@ -2,8 +2,8 @@ import { chmod, mkdtemp, mkdir, rm, stat, symlink, utimes, writeFile } from 'nod import { dirname, join, resolve } from 'node:path' import { tmpdir } from 'node:os' import { describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' -import Loader from '@cordisjs/plugin-loader' +import { Context } from '@deepseek-ai/cordis' +import Loader from '@deepseek-ai/cordis-plugin-loader' import * as workspaceContext from '@deepseek-ai/dsh-workspace-context' import LlmService, { createUserMessage, CallId, type Message, type StreamChunk } from '@deepseek-ai/dsh-llm' import SessionStore, { Session, SessionId, SESSION_FORMAT_VERSION, type SessionEvent, type UserMessage } from '@deepseek-ai/dsh-session' diff --git a/packages/core/agent-default-model/package.json b/packages/core/agent-default-model/package.json index 0035b0b617..e57709585b 100644 --- a/packages/core/agent-default-model/package.json +++ b/packages/core/agent-default-model/package.json @@ -25,20 +25,20 @@ ], "license": "BSD-3-Clause", "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "peerDependencies": { "@deepseek-ai/dsh-agent": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-llm": "^0.0.1", "@deepseek-ai/dsh-settings": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-agent": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-llm": "workspace:^", "@deepseek-ai/dsh-settings": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/core/agent-default-model/src/index.ts b/packages/core/agent-default-model/src/index.ts index 4d09b86eb3..5d9e92fc51 100644 --- a/packages/core/agent-default-model/src/index.ts +++ b/packages/core/agent-default-model/src/index.ts @@ -4,13 +4,13 @@ * @module @deepseek-ai/dsh-agent-default-model */ -import { Context, Service } from 'cordis' -import z from 'schemastery' +import { Context, Service } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import type { ModelSelection } from '@deepseek-ai/dsh-agent' import { ReasoningEffortId } from '@deepseek-ai/dsh-llm' import { installSettingsSection, settingsNamespace } from '@deepseek-ai/dsh-settings' -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { /** Default model selection for Agents created without an explicit model. */ agentDefaultModel: AgentDefaultModelService diff --git a/packages/core/agent-default-model/src/invariant.ts b/packages/core/agent-default-model/src/invariant.ts index 8366018661..48253ae159 100644 --- a/packages/core/agent-default-model/src/invariant.ts +++ b/packages/core/agent-default-model/src/invariant.ts @@ -8,7 +8,7 @@ * @module @deepseek-ai/dsh-agent-default-model/invariant */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-agent-default-model' diff --git a/packages/core/agent-default-model/tests/agent-default-model.spec.ts b/packages/core/agent-default-model/tests/agent-default-model.spec.ts index ef479b4a96..61324d7d71 100644 --- a/packages/core/agent-default-model/tests/agent-default-model.spec.ts +++ b/packages/core/agent-default-model/tests/agent-default-model.spec.ts @@ -1,7 +1,7 @@ /** Default Agent model settings layered over a real settings provider. */ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import AgentDefaultModelService, { AGENT_DEFAULT_MODEL_SETTINGS_NAMESPACE } from '../src/index.ts' import { Settings } from '@deepseek-ai/dsh-settings' import type { SettingsNamespace } from '@deepseek-ai/dsh-settings' diff --git a/packages/core/agent-loop/package.json b/packages/core/agent-loop/package.json index 68c30d9e55..fe37f8ca1c 100644 --- a/packages/core/agent-loop/package.json +++ b/packages/core/agent-loop/package.json @@ -32,10 +32,10 @@ "@deepseek-ai/dsh-session-persistence": "^0.0.1", "@deepseek-ai/dsh-system-prompt": "^0.0.1", "@deepseek-ai/dsh-tools": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { "@deepseek-ai/dsh-agent": "workspace:^", @@ -47,6 +47,6 @@ "@deepseek-ai/dsh-session-persistence-jsonl": "workspace:^", "@deepseek-ai/dsh-system-prompt": "workspace:^", "@deepseek-ai/dsh-tools": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/core/agent-loop/src/agent.ts b/packages/core/agent-loop/src/agent.ts index 6ef965e59e..a2e854f6d4 100644 --- a/packages/core/agent-loop/src/agent.ts +++ b/packages/core/agent-loop/src/agent.ts @@ -31,7 +31,7 @@ import type { EpochHeader, RequestContext, Session, SessionId, TurnEndReason, Us import { canonicalHeader, headerEquals } from '@deepseek-ai/dsh-session' import { joinContextSections, renderContextSections, renderPrompt } from '@deepseek-ai/dsh-system-prompt' import type { PromptAssembly } from '@deepseek-ai/dsh-system-prompt' -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { RuntimeContextProjection } from './runtime-context.ts' import { executeToolCalls } from './tool-calls.ts' diff --git a/packages/core/agent-loop/src/index.ts b/packages/core/agent-loop/src/index.ts index e7c840e296..e492a21073 100644 --- a/packages/core/agent-loop/src/index.ts +++ b/packages/core/agent-loop/src/index.ts @@ -5,9 +5,9 @@ * @module @deepseek-ai/dsh-agent-loop */ -import { Context, FiberState, Service } from 'cordis' +import { Context, FiberState, Service } from '@deepseek-ai/cordis' import { randomUUID } from 'node:crypto' -import z from 'schemastery' +import z from '@deepseek-ai/schemastery' import { emitAgentEvent } from '@deepseek-ai/dsh-agent' import type { Agent, @@ -156,7 +156,7 @@ interface PreparedAgent { dispose(): Promise } -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { agentLoop: AgentLoop /** diff --git a/packages/core/agent-loop/src/invariant.ts b/packages/core/agent-loop/src/invariant.ts index d87655d1fc..80fdfba8f9 100644 --- a/packages/core/agent-loop/src/invariant.ts +++ b/packages/core/agent-loop/src/invariant.ts @@ -3,7 +3,7 @@ * @module @deepseek-ai/dsh-agent-loop/invariant */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { isAgentLoopRequest, type GenerateOptions } from '@deepseek-ai/dsh-llm' import type { InvariantFailure, InvariantInstaller } from '@deepseek-ai/dsh-invariants' import { foldRequestHeader } from '@deepseek-ai/dsh-session' diff --git a/packages/core/agent-loop/src/runtime-context.ts b/packages/core/agent-loop/src/runtime-context.ts index 8cf4a41403..63b353ebae 100644 --- a/packages/core/agent-loop/src/runtime-context.ts +++ b/packages/core/agent-loop/src/runtime-context.ts @@ -7,7 +7,7 @@ import { createUserMessage } from '@deepseek-ai/dsh-llm' import type { ContextSnapshotSection } from '@deepseek-ai/dsh-llm' import type { Session, UserMessage } from '@deepseek-ai/dsh-session' import { isReplacementSurfaceEvent } from '@deepseek-ai/dsh-session' -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' const SOURCE = '@deepseek-ai/dsh-system-prompt' const CLEARED = 'Current runtime context: none. Earlier runtime-context snapshots no longer apply.' diff --git a/packages/core/agent-loop/src/tool-calls.ts b/packages/core/agent-loop/src/tool-calls.ts index 693ff7bd91..cb34f3dc86 100644 --- a/packages/core/agent-loop/src/tool-calls.ts +++ b/packages/core/agent-loop/src/tool-calls.ts @@ -11,7 +11,7 @@ * @module dsh-agent-loop/tool-calls */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { assertNever, createToolResultMessage, type ToolCallBlock } from '@deepseek-ai/dsh-llm' import type { Session, UserMessage } from '@deepseek-ai/dsh-session' import { TOOL_ABORTED_BEFORE_DISPATCH, TOOL_REGISTRY_SCHEDULER, type ToolExecutionInput, type ToolExecutionMode, type ToolExecutionResult, type ToolRunContext } from '@deepseek-ai/dsh-tools' diff --git a/packages/core/agent-loop/tests/agent-initiator.spec.ts b/packages/core/agent-loop/tests/agent-initiator.spec.ts index 5af6e70fe0..8195ea1df9 100644 --- a/packages/core/agent-loop/tests/agent-initiator.spec.ts +++ b/packages/core/agent-loop/tests/agent-initiator.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context, type Fiber } from 'cordis' +import { Context, type Fiber } from '@deepseek-ai/cordis' import AgentRegistry, { type Agent } from '@deepseek-ai/dsh-agent' import AgentLoop from '@deepseek-ai/dsh-agent-loop' import LlmService, { createUserMessage, CallId, LlmAdapter } from '@deepseek-ai/dsh-llm' diff --git a/packages/core/agent-loop/tests/agent.spec.ts b/packages/core/agent-loop/tests/agent.spec.ts index 7ac8a0dd64..e02925ca75 100644 --- a/packages/core/agent-loop/tests/agent.spec.ts +++ b/packages/core/agent-loop/tests/agent.spec.ts @@ -1,6 +1,6 @@ import { createUserMessage } from '@deepseek-ai/dsh-llm' import { describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import AgentRegistry, { type Agent } from '@deepseek-ai/dsh-agent' import AgentLoop from '@deepseek-ai/dsh-agent-loop' import LlmService from '@deepseek-ai/dsh-llm' diff --git a/packages/core/agent-loop/tests/cancel.spec.ts b/packages/core/agent-loop/tests/cancel.spec.ts index 6fb77d141c..9e53d8067e 100644 --- a/packages/core/agent-loop/tests/cancel.spec.ts +++ b/packages/core/agent-loop/tests/cancel.spec.ts @@ -8,7 +8,7 @@ import { createUserMessage } from '@deepseek-ai/dsh-llm' */ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import LlmService from '@deepseek-ai/dsh-llm' import SessionStore, { SessionId, TurnEndReason } from '@deepseek-ai/dsh-session' import SystemPrompt from '@deepseek-ai/dsh-system-prompt' diff --git a/packages/core/agent-loop/tests/config-session-id.spec.ts b/packages/core/agent-loop/tests/config-session-id.spec.ts index 74608e5f1a..40b226f165 100644 --- a/packages/core/agent-loop/tests/config-session-id.spec.ts +++ b/packages/core/agent-loop/tests/config-session-id.spec.ts @@ -1,6 +1,6 @@ import { createUserMessage } from '@deepseek-ai/dsh-llm' import { afterEach, describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { mkdtemp, rm } from 'node:fs/promises' import { tmpdir } from 'node:os' import { join } from 'node:path' diff --git a/packages/core/agent-loop/tests/contract-regressions.spec.ts b/packages/core/agent-loop/tests/contract-regressions.spec.ts index 7dfbaddc41..50f6257f45 100644 --- a/packages/core/agent-loop/tests/contract-regressions.spec.ts +++ b/packages/core/agent-loop/tests/contract-regressions.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import LlmService, { createUserMessage, CallId, LlmError, MessageSource, ProviderRequestId, StreamChunk } from '@deepseek-ai/dsh-llm' import SessionStore, { Session, SessionEvent, SessionId, TurnEndReason, type UserMessage } from '@deepseek-ai/dsh-session' import SystemPrompt from '@deepseek-ai/dsh-system-prompt' diff --git a/packages/core/agent-loop/tests/coverage-edges.spec.ts b/packages/core/agent-loop/tests/coverage-edges.spec.ts index 617c305071..2ebe1c0884 100644 --- a/packages/core/agent-loop/tests/coverage-edges.spec.ts +++ b/packages/core/agent-loop/tests/coverage-edges.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import LlmService, { createUserMessage, CallId, LlmError, StreamChunk, errorChain } from '@deepseek-ai/dsh-llm' import SessionStore, { SessionId, TurnEndReason } from '@deepseek-ai/dsh-session' import type { SessionEvent } from '@deepseek-ai/dsh-session' diff --git a/packages/core/agent-loop/tests/interception.spec.ts b/packages/core/agent-loop/tests/interception.spec.ts index 646c6d41fa..01cf57237b 100644 --- a/packages/core/agent-loop/tests/interception.spec.ts +++ b/packages/core/agent-loop/tests/interception.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import LlmService, { createUserMessage, CallId } from '@deepseek-ai/dsh-llm' import SessionStore, { SessionId, diff --git a/packages/core/agent-loop/tests/invariant.spec.ts b/packages/core/agent-loop/tests/invariant.spec.ts index d77ad3a7d6..4295eac226 100644 --- a/packages/core/agent-loop/tests/invariant.spec.ts +++ b/packages/core/agent-loop/tests/invariant.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import SessionStore, { SessionId } from '@deepseek-ai/dsh-session' import InvariantService from '@deepseek-ai/dsh-invariants' import * as AgentLoopInvariant from '@deepseek-ai/dsh-agent-loop/invariant' diff --git a/packages/core/agent-loop/tests/loop.spec.ts b/packages/core/agent-loop/tests/loop.spec.ts index c42331de58..d87fb56486 100644 --- a/packages/core/agent-loop/tests/loop.spec.ts +++ b/packages/core/agent-loop/tests/loop.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import LlmService, { createUserMessage, CallId, LlmError, StreamChunk } from '@deepseek-ai/dsh-llm' import SessionStore, { SessionId, TurnEndReason } from '@deepseek-ai/dsh-session' import SystemPrompt from '@deepseek-ai/dsh-system-prompt' diff --git a/packages/core/agent-loop/tests/properties.spec.ts b/packages/core/agent-loop/tests/properties.spec.ts index 0add31bd1f..7fcba03ebf 100644 --- a/packages/core/agent-loop/tests/properties.spec.ts +++ b/packages/core/agent-loop/tests/properties.spec.ts @@ -10,7 +10,7 @@ */ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import LlmService from '@deepseek-ai/dsh-llm' import { createUserMessage, LlmAdapter } from '@deepseek-ai/dsh-llm' import type { GenerateOptions, StreamChunk } from '@deepseek-ai/dsh-llm' diff --git a/packages/core/agent-loop/tests/request-cache.e2e.ts b/packages/core/agent-loop/tests/request-cache.e2e.ts index 0c7c65e483..0e0da3cb81 100644 --- a/packages/core/agent-loop/tests/request-cache.e2e.ts +++ b/packages/core/agent-loop/tests/request-cache.e2e.ts @@ -1,6 +1,6 @@ import { createUserMessage } from '@deepseek-ai/dsh-llm' import { afterEach, describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import LlmService from '@deepseek-ai/dsh-llm' import SessionStore, { SessionId } from '@deepseek-ai/dsh-session' import SystemPrompt from '@deepseek-ai/dsh-system-prompt' diff --git a/packages/core/agent-loop/tests/request-error.spec.ts b/packages/core/agent-loop/tests/request-error.spec.ts index d143bd79ae..eae579a8cb 100644 --- a/packages/core/agent-loop/tests/request-error.spec.ts +++ b/packages/core/agent-loop/tests/request-error.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import AgentRegistry from '@deepseek-ai/dsh-agent' import AgentLoop from '@deepseek-ai/dsh-agent-loop' import LlmService, { createUserMessage, LlmError } from '@deepseek-ai/dsh-llm' diff --git a/packages/core/agent-loop/tests/request-reconstruction.spec.ts b/packages/core/agent-loop/tests/request-reconstruction.spec.ts index 62a7ae5e71..dc69e1b835 100644 --- a/packages/core/agent-loop/tests/request-reconstruction.spec.ts +++ b/packages/core/agent-loop/tests/request-reconstruction.spec.ts @@ -6,7 +6,7 @@ */ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import LlmService, { createUserMessage, LlmError, ReasoningEffortId } from '@deepseek-ai/dsh-llm' import type { GenerateOptions, LlmModelReasoningInfo, LlmResolvedModelInfo, StreamChunk } from '@deepseek-ai/dsh-llm' import SessionStore, { Session, SessionId, foldRequestHeader } from '@deepseek-ai/dsh-session' diff --git a/packages/core/agent-loop/tests/resume.spec.ts b/packages/core/agent-loop/tests/resume.spec.ts index 964ef82aa6..e32db7c846 100644 --- a/packages/core/agent-loop/tests/resume.spec.ts +++ b/packages/core/agent-loop/tests/resume.spec.ts @@ -1,6 +1,6 @@ import { createUserMessage } from '@deepseek-ai/dsh-llm' import { afterEach, describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { mkdtemp, rm } from 'node:fs/promises' import { tmpdir } from 'node:os' import { join } from 'node:path' diff --git a/packages/core/agent-loop/tests/runtime-context.spec.ts b/packages/core/agent-loop/tests/runtime-context.spec.ts index 463515a61b..9cf76e79ba 100644 --- a/packages/core/agent-loop/tests/runtime-context.spec.ts +++ b/packages/core/agent-loop/tests/runtime-context.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { createUserMessage } from '@deepseek-ai/dsh-llm' import SessionStore, { SessionId } from '@deepseek-ai/dsh-session' import { RuntimeContextProjection } from '../src/runtime-context.ts' diff --git a/packages/core/agent-loop/tests/scope-lifecycle.spec.ts b/packages/core/agent-loop/tests/scope-lifecycle.spec.ts index 3f3e0a43d8..898604ff1b 100644 --- a/packages/core/agent-loop/tests/scope-lifecycle.spec.ts +++ b/packages/core/agent-loop/tests/scope-lifecycle.spec.ts @@ -1,6 +1,6 @@ import { createUserMessage } from '@deepseek-ai/dsh-llm' import { describe, expect, it } from 'vitest' -import { Context, symbols, type EffectMeta, type Fiber } from 'cordis' +import { Context, symbols, type EffectMeta, type Fiber } from '@deepseek-ai/cordis' import LlmService from '@deepseek-ai/dsh-llm' import SessionStore, { SessionId, type SessionEvent } from '@deepseek-ai/dsh-session' import SystemPrompt from '@deepseek-ai/dsh-system-prompt' diff --git a/packages/core/agent-loop/tests/tool-calls.spec.ts b/packages/core/agent-loop/tests/tool-calls.spec.ts index 89b2e300bd..972c321138 100644 --- a/packages/core/agent-loop/tests/tool-calls.spec.ts +++ b/packages/core/agent-loop/tests/tool-calls.spec.ts @@ -4,7 +4,7 @@ */ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { createUserMessage, CallId, StreamChunk } from '@deepseek-ai/dsh-llm' import SessionStore, { SessionEvent, SessionId } from '@deepseek-ai/dsh-session' import SystemPrompt from '@deepseek-ai/dsh-system-prompt' diff --git a/packages/core/agent-loop/tests/tool-order.spec.ts b/packages/core/agent-loop/tests/tool-order.spec.ts index 9fa321697a..195b1ad76a 100644 --- a/packages/core/agent-loop/tests/tool-order.spec.ts +++ b/packages/core/agent-loop/tests/tool-order.spec.ts @@ -8,7 +8,7 @@ import { createUserMessage } from '@deepseek-ai/dsh-llm' */ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import LlmService from '@deepseek-ai/dsh-llm' import SessionStore, { SessionId, foldRequestHeader } from '@deepseek-ai/dsh-session' import SystemPrompt, { TOOL_ORDER_REST } from '@deepseek-ai/dsh-system-prompt' diff --git a/packages/core/agent-tool-mode/package.json b/packages/core/agent-tool-mode/package.json index 236c9e5891..8427822784 100644 --- a/packages/core/agent-tool-mode/package.json +++ b/packages/core/agent-tool-mode/package.json @@ -25,12 +25,12 @@ ], "license": "BSD-3-Clause", "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "peerDependencies": { "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-tools": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-agent": "workspace:^", @@ -40,6 +40,6 @@ "@deepseek-ai/dsh-session": "workspace:^", "@deepseek-ai/dsh-system-prompt": "workspace:^", "@deepseek-ai/dsh-tools": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/core/agent-tool-mode/src/index.ts b/packages/core/agent-tool-mode/src/index.ts index d2f1e8fd49..7e4ee9e0c0 100644 --- a/packages/core/agent-tool-mode/src/index.ts +++ b/packages/core/agent-tool-mode/src/index.ts @@ -16,8 +16,8 @@ * @module @deepseek-ai/dsh-agent-tool-mode */ -import type { Context } from 'cordis' -import z from 'schemastery' +import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import type { ToolPresentationMode } from '@deepseek-ai/dsh-tools' // Type-only: brings the `ctx.tools` Context merge into this program. import type {} from '@deepseek-ai/dsh-tools' diff --git a/packages/core/agent-tool-mode/src/invariant.ts b/packages/core/agent-tool-mode/src/invariant.ts index bd576cb943..a7fbd8b923 100644 --- a/packages/core/agent-tool-mode/src/invariant.ts +++ b/packages/core/agent-tool-mode/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-agent-tool-mode' diff --git a/packages/core/agent-tool-mode/tests/agent-tool-mode.spec.ts b/packages/core/agent-tool-mode/tests/agent-tool-mode.spec.ts index ba9b9972ff..b626025dfd 100644 --- a/packages/core/agent-tool-mode/tests/agent-tool-mode.spec.ts +++ b/packages/core/agent-tool-mode/tests/agent-tool-mode.spec.ts @@ -7,7 +7,7 @@ */ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { createScope } from '@deepseek-ai/dsh-scope' import SystemPrompt from '@deepseek-ai/dsh-system-prompt' import { CodeRuntime } from '@deepseek-ai/dsh-code-runtime' diff --git a/packages/core/agent/package.json b/packages/core/agent/package.json index 9f64d33e75..5669858fd9 100644 --- a/packages/core/agent/package.json +++ b/packages/core/agent/package.json @@ -36,7 +36,7 @@ "@deepseek-ai/dsh-session": "^0.0.1", "@deepseek-ai/dsh-system-prompt": "^0.0.1", "@deepseek-ai/dsh-type-meta": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-invariants": "workspace:^", @@ -46,6 +46,6 @@ "@deepseek-ai/dsh-system-prompt": "workspace:^", "@deepseek-ai/dsh-type-meta": "workspace:^", "@deepseek-ai/dsh-typert-registry": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/core/agent/src/dispatch.ts b/packages/core/agent/src/dispatch.ts index 7eff09b01d..f95582851d 100644 --- a/packages/core/agent/src/dispatch.ts +++ b/packages/core/agent/src/dispatch.ts @@ -6,7 +6,7 @@ * @module @deepseek-ai/dsh-agent/dispatch */ -import type { Context, Events } from 'cordis' +import type { Context, Events } from '@deepseek-ai/cordis' import { scopeTarget } from '@deepseek-ai/dsh-scope' import type { Scoped } from '@deepseek-ai/dsh-scope' import type { AssembleContext } from '@deepseek-ai/dsh-system-prompt' diff --git a/packages/core/agent/src/index.ts b/packages/core/agent/src/index.ts index 0f2fcabf3a..dffc1f01b3 100644 --- a/packages/core/agent/src/index.ts +++ b/packages/core/agent/src/index.ts @@ -5,8 +5,8 @@ * @module @deepseek-ai/dsh-agent */ -import { Context, FiberState, getTraceable, Service, symbols } from 'cordis' -import type { Fiber } from 'cordis' +import { Context, FiberState, getTraceable, Service, symbols } from '@deepseek-ai/cordis' +import type { Fiber } from '@deepseek-ai/cordis' import { AsyncLocalStorage } from 'node:async_hooks' import { isPromise } from 'node:util/types' import { scopeTarget } from '@deepseek-ai/dsh-scope' @@ -32,7 +32,7 @@ declare module '@deepseek-ai/dsh-type-meta' { } } -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { agents: AgentRegistry /** diff --git a/packages/core/agent/src/invariant.ts b/packages/core/agent/src/invariant.ts index a561e862cb..fc3ebb2599 100644 --- a/packages/core/agent/src/invariant.ts +++ b/packages/core/agent/src/invariant.ts @@ -1,6 +1,6 @@ /** Package-owned agent lifecycle invariants. @module @deepseek-ai/dsh-agent/invariant */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' import type { Agent, AgentStatus } from '@deepseek-ai/dsh-agent' diff --git a/packages/core/agent/src/model-selection.ts b/packages/core/agent/src/model-selection.ts index a49e2f5979..2cb7e4468f 100644 --- a/packages/core/agent/src/model-selection.ts +++ b/packages/core/agent/src/model-selection.ts @@ -3,7 +3,7 @@ * @module @deepseek-ai/dsh-agent/model-selection */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { LlmCallConfig, ReasoningEffortId } from '@deepseek-ai/dsh-llm' /** Complete provider, model, and optional reasoning effort selected for one live Agent. */ diff --git a/packages/core/agent/src/runtime-types.ts b/packages/core/agent/src/runtime-types.ts index 3698c05018..7d713f8c77 100644 --- a/packages/core/agent/src/runtime-types.ts +++ b/packages/core/agent/src/runtime-types.ts @@ -5,7 +5,7 @@ * @module @deepseek-ai/dsh-agent */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { Scoped } from '@deepseek-ai/dsh-scope' import type { LlmCallConfig, LlmFailure, ResolvedRetryPolicy } from '@deepseek-ai/dsh-llm' import type { AgentCancelCause, Session, SessionId, UserMessage } from '@deepseek-ai/dsh-session' @@ -143,7 +143,7 @@ export interface Agent { inject(message: UserMessage): void } -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Events { // ---- lifecycle (emit) ---- /** diff --git a/packages/core/agent/tests/agent-initiator.spec.ts b/packages/core/agent/tests/agent-initiator.spec.ts index 7e0b70d13c..c86e0edfcf 100644 --- a/packages/core/agent/tests/agent-initiator.spec.ts +++ b/packages/core/agent/tests/agent-initiator.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { runInNewContext } from 'node:vm' import AgentRegistry from '@deepseek-ai/dsh-agent' import type { Agent } from '@deepseek-ai/dsh-agent' diff --git a/packages/core/agent/tests/agent.spec.ts b/packages/core/agent/tests/agent.spec.ts index 643a3a49a6..d5c345593c 100644 --- a/packages/core/agent/tests/agent.spec.ts +++ b/packages/core/agent/tests/agent.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, expectTypeOf, it } from 'vitest' -import { Context, Service, symbols } from 'cordis' +import { Context, Service, symbols } from '@deepseek-ai/cordis' import { createUserMessage, freezeMessage } from '@deepseek-ai/dsh-llm' import { Session, SessionId, type UserMessage } from '@deepseek-ai/dsh-session' import AgentRegistry, { diff --git a/packages/core/agent/tests/invariant.spec.ts b/packages/core/agent/tests/invariant.spec.ts index 458a10714d..26bc486b2e 100644 --- a/packages/core/agent/tests/invariant.spec.ts +++ b/packages/core/agent/tests/invariant.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import type { Agent } from '@deepseek-ai/dsh-agent' import * as AgentInvariant from '@deepseek-ai/dsh-agent/invariant' import { scopeTarget } from '@deepseek-ai/dsh-scope' diff --git a/packages/core/agent/tests/model-selection.spec.ts b/packages/core/agent/tests/model-selection.spec.ts index 2d7a1a7336..3e61060cd6 100644 --- a/packages/core/agent/tests/model-selection.spec.ts +++ b/packages/core/agent/tests/model-selection.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import SystemPrompt from '@deepseek-ai/dsh-system-prompt' import { agentEvents, diff --git a/packages/core/agent/tests/verify-export-jsdoc.spec.ts b/packages/core/agent/tests/verify-export-jsdoc.spec.ts index cc361a956e..cffa4e8564 100644 --- a/packages/core/agent/tests/verify-export-jsdoc.spec.ts +++ b/packages/core/agent/tests/verify-export-jsdoc.spec.ts @@ -154,7 +154,7 @@ describe('verify-export-jsdoc type-level exports', () => { it('skips `declare module` augmentation bodies (the cordis gate owns them)', () => { expect(collectExportJsdocViolations(make( - "declare module 'cordis' {\n interface Events {\n 'fix/x'(): void\n }\n}\nexport {}\n", + "declare module '@deepseek-ai/cordis' {\n interface Events {\n 'fix/x'(): void\n }\n}\nexport {}\n", ))).toEqual([]) }) }) diff --git a/packages/core/scope/package.json b/packages/core/scope/package.json index a752ee4c77..792a6716e6 100644 --- a/packages/core/scope/package.json +++ b/packages/core/scope/package.json @@ -26,10 +26,10 @@ "license": "BSD-3-Clause", "peerDependencies": { "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-invariants": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/core/scope/src/index.ts b/packages/core/scope/src/index.ts index b5f58dbdf0..84df79510e 100644 --- a/packages/core/scope/src/index.ts +++ b/packages/core/scope/src/index.ts @@ -5,8 +5,8 @@ * @module @deepseek-ai/dsh-scope */ -import type { Context, Fiber } from 'cordis' -import { Context as CordisContext } from 'cordis' +import type { Context, Fiber } from '@deepseek-ai/cordis' +import { Context as CordisContext } from '@deepseek-ai/cordis' export { AnonymousEntries, NamedEntries, ScopedLayers } from './store.ts' export type { ScopeLayer } from './store.ts' diff --git a/packages/core/scope/src/invariant.ts b/packages/core/scope/src/invariant.ts index a5bd59f263..b478b9417d 100644 --- a/packages/core/scope/src/invariant.ts +++ b/packages/core/scope/src/invariant.ts @@ -1,6 +1,6 @@ /** Package-owned scoped-dispatch invariants. @module @deepseek-ai/dsh-scope/invariant */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' import { carrierKeyOf, isScopeCarrier } from '@deepseek-ai/dsh-scope' import { scopedSubjectResolverFor } from './scoped-events.generated.ts' diff --git a/packages/core/scope/src/store.ts b/packages/core/scope/src/store.ts index a9e1468ccd..3b40693c82 100644 --- a/packages/core/scope/src/store.ts +++ b/packages/core/scope/src/store.ts @@ -4,7 +4,7 @@ * @module @deepseek-ai/dsh-scope */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { scopeChainOf, scopeOf } from './index.ts' import type { ScopeKey } from './index.ts' diff --git a/packages/core/scope/tests/invariant.spec.ts b/packages/core/scope/tests/invariant.spec.ts index 8744bb9aa7..5e8ba13a3e 100644 --- a/packages/core/scope/tests/invariant.spec.ts +++ b/packages/core/scope/tests/invariant.spec.ts @@ -1,7 +1,7 @@ import { freezeMessage, MessageId } from '@deepseek-ai/dsh-llm' import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' -import type { Events } from 'cordis' +import { Context } from '@deepseek-ai/cordis' +import type { Events } from '@deepseek-ai/cordis' import type { Agent } from '@deepseek-ai/dsh-agent' import { scopeTarget } from '@deepseek-ai/dsh-scope' import * as ScopeInvariant from '@deepseek-ai/dsh-scope/invariant' diff --git a/packages/core/scope/tests/scope.spec.ts b/packages/core/scope/tests/scope.spec.ts index 7007624d53..bb0361fbf2 100644 --- a/packages/core/scope/tests/scope.spec.ts +++ b/packages/core/scope/tests/scope.spec.ts @@ -1,9 +1,9 @@ import { describe, expect, expectTypeOf, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { bindScopeParent, carrierKeyOf, createScope, isScopeCarrier, scopeChainOf, scopeOf, scopeParentOf, scopeTarget } from '@deepseek-ai/dsh-scope' import type { Scope, Scoped } from '@deepseek-ai/dsh-scope' -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Events { /** * Test-only event for scope-filtered dispatch. diff --git a/packages/core/scope/tests/store.spec.ts b/packages/core/scope/tests/store.spec.ts index 622dbeb541..025f0f7181 100644 --- a/packages/core/scope/tests/store.spec.ts +++ b/packages/core/scope/tests/store.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { AnonymousEntries, createScope, diff --git a/packages/core/session/package.json b/packages/core/session/package.json index 04aa221573..ada5c170d1 100644 --- a/packages/core/session/package.json +++ b/packages/core/session/package.json @@ -39,7 +39,7 @@ "@deepseek-ai/dsh-llm": "^0.0.1", "@deepseek-ai/dsh-scope": "^0.0.1", "@deepseek-ai/dsh-type-meta": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-brand": "workspace:^", @@ -48,6 +48,6 @@ "@deepseek-ai/dsh-scope": "workspace:^", "@deepseek-ai/dsh-type-meta": "workspace:^", "@deepseek-ai/dsh-typert-registry": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/core/session/src/index.ts b/packages/core/session/src/index.ts index f27b2f4622..dd1f7b9175 100644 --- a/packages/core/session/src/index.ts +++ b/packages/core/session/src/index.ts @@ -6,7 +6,7 @@ * @module @deepseek-ai/dsh-session */ -import { Context, Service } from 'cordis' +import { Context, Service } from '@deepseek-ai/cordis' import { isAbsolute } from 'node:path' import { deepFreeze } from '@deepseek-ai/dsh-llm' import { scopeOf, scopeTarget } from '@deepseek-ai/dsh-scope' @@ -54,7 +54,7 @@ export function findLastMessageTurnEnd( return latest } -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { sessions: SessionStore } diff --git a/packages/core/session/src/invariant.ts b/packages/core/session/src/invariant.ts index 77d2b22ac2..da7cd55964 100644 --- a/packages/core/session/src/invariant.ts +++ b/packages/core/session/src/invariant.ts @@ -5,7 +5,7 @@ * @module @deepseek-ai/dsh-session/invariant */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { assertNever } from '@deepseek-ai/dsh-llm' import type { CallId } from '@deepseek-ai/dsh-llm' import type { InvariantFailure, InvariantInstaller } from '@deepseek-ai/dsh-invariants' diff --git a/packages/core/session/tests/fork.spec.ts b/packages/core/session/tests/fork.spec.ts index 58985cfb34..35b0cf3a54 100644 --- a/packages/core/session/tests/fork.spec.ts +++ b/packages/core/session/tests/fork.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { createUserMessage, CallId , createMessage } from '@deepseek-ai/dsh-llm' import SessionStore, { Session, SessionForkError, SessionId } from '@deepseek-ai/dsh-session' import type { SessionEvent, TurnEndReason } from '@deepseek-ai/dsh-session' diff --git a/packages/core/session/tests/invariant.spec.ts b/packages/core/session/tests/invariant.spec.ts index cc5e21f57a..5d6fff4cef 100644 --- a/packages/core/session/tests/invariant.spec.ts +++ b/packages/core/session/tests/invariant.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { createScope, scopeTarget } from '@deepseek-ai/dsh-scope' import { createUserMessage, CallId, createMessage, createToolResultMessage, freezeMessage } from '@deepseek-ai/dsh-llm' import SessionStore, { SessionId, TOOL_NOT_STARTED } from '@deepseek-ai/dsh-session' diff --git a/packages/core/session/tests/scoped.spec.ts b/packages/core/session/tests/scoped.spec.ts index 441d2d8029..7d75302248 100644 --- a/packages/core/session/tests/scoped.spec.ts +++ b/packages/core/session/tests/scoped.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { createScope, scopeOf } from '@deepseek-ai/dsh-scope' import type { Scope, ScopeKey } from '@deepseek-ai/dsh-scope' import SessionStore from '@deepseek-ai/dsh-session' diff --git a/packages/core/session/tests/session.spec.ts b/packages/core/session/tests/session.spec.ts index b0302b9d4d..779a24e748 100644 --- a/packages/core/session/tests/session.spec.ts +++ b/packages/core/session/tests/session.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, expectTypeOf, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { createUserMessage, CallId, createMessage, createToolResultMessage, MessageId, ReasoningEffortId } from '@deepseek-ai/dsh-llm' import SessionStore, { adoptSessionEvent, diff --git a/packages/core/session/tests/typert.spec.ts b/packages/core/session/tests/typert.spec.ts index e1e2b32d68..2ea8e4572e 100644 --- a/packages/core/session/tests/typert.spec.ts +++ b/packages/core/session/tests/typert.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import SessionStore, { SessionId } from '@deepseek-ai/dsh-session' import TypertRegistry from '@deepseek-ai/dsh-typert-registry' diff --git a/packages/core/system-prompt/package.json b/packages/core/system-prompt/package.json index d601365df7..35a270cf9d 100644 --- a/packages/core/system-prompt/package.json +++ b/packages/core/system-prompt/package.json @@ -28,15 +28,15 @@ "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-llm": "^0.0.1", "@deepseek-ai/dsh-scope": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-llm": "workspace:^", "@deepseek-ai/dsh-scope": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/core/system-prompt/src/index.ts b/packages/core/system-prompt/src/index.ts index 23b5936e08..d4f5c52db0 100644 --- a/packages/core/system-prompt/src/index.ts +++ b/packages/core/system-prompt/src/index.ts @@ -4,13 +4,13 @@ * @module @deepseek-ai/dsh-system-prompt */ -import { Context, Service } from 'cordis' -import z from 'schemastery' +import { Context, Service } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import { AnonymousEntries, NamedEntries, ScopedLayers, scopeTarget } from '@deepseek-ai/dsh-scope' import type { ScopeKey, ScopeLayer, Scoped } from '@deepseek-ai/dsh-scope' import type { ContextSnapshotSection, ToolSchema } from '@deepseek-ai/dsh-llm' -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { systemPrompt: SystemPrompt } diff --git a/packages/core/system-prompt/src/invariant.ts b/packages/core/system-prompt/src/invariant.ts index 04dc65e7ad..bbe587516f 100644 --- a/packages/core/system-prompt/src/invariant.ts +++ b/packages/core/system-prompt/src/invariant.ts @@ -1,6 +1,6 @@ /** Package-owned prompt-assembly invariants. @module @deepseek-ai/dsh-system-prompt/invariant */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantFailure, InvariantInstaller } from '@deepseek-ai/dsh-invariants' import type { PromptAssembly } from './index.ts' diff --git a/packages/core/system-prompt/tests/invariant.spec.ts b/packages/core/system-prompt/tests/invariant.spec.ts index ace65d2bc9..74c3648494 100644 --- a/packages/core/system-prompt/tests/invariant.spec.ts +++ b/packages/core/system-prompt/tests/invariant.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import type { PromptAssembly } from '@deepseek-ai/dsh-system-prompt' import * as SystemPromptInvariant from '@deepseek-ai/dsh-system-prompt/invariant' import InvariantService from '@deepseek-ai/dsh-invariants' diff --git a/packages/core/system-prompt/tests/scoped.spec.ts b/packages/core/system-prompt/tests/scoped.spec.ts index 704a3e769c..1498966cc6 100644 --- a/packages/core/system-prompt/tests/scoped.spec.ts +++ b/packages/core/system-prompt/tests/scoped.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { createScope, scopeOf } from '@deepseek-ai/dsh-scope' import type { Scope, ScopeKey } from '@deepseek-ai/dsh-scope' import SystemPrompt, { TOOL_ORDER_REST, renderContextSnapshot, renderPrompt } from '@deepseek-ai/dsh-system-prompt' diff --git a/packages/core/system-prompt/tests/system-prompt.spec.ts b/packages/core/system-prompt/tests/system-prompt.spec.ts index 834c17c341..96592565ce 100644 --- a/packages/core/system-prompt/tests/system-prompt.spec.ts +++ b/packages/core/system-prompt/tests/system-prompt.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import SystemPrompt, { AssembleContext, PromptAssembly, renderContextSnapshot, renderPrompt } from '@deepseek-ai/dsh-system-prompt' /** diff --git a/packages/core/system-prompt/tests/tool-order.spec.ts b/packages/core/system-prompt/tests/tool-order.spec.ts index 16eff6e354..6085276900 100644 --- a/packages/core/system-prompt/tests/tool-order.spec.ts +++ b/packages/core/system-prompt/tests/tool-order.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import SystemPrompt, { PromptAssembly, TOOL_ORDER_REST } from '@deepseek-ai/dsh-system-prompt' import type { ToolSchema } from '@deepseek-ai/dsh-llm' diff --git a/packages/core/tools/README.i18n.yaml b/packages/core/tools/README.i18n.yaml index e3a9b36a95..317f583994 100644 --- a/packages/core/tools/README.i18n.yaml +++ b/packages/core/tools/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/core/tools/README.md -README.md: 21851ca887147364c76612bae2e6a00ebdccec39 -README.zh.md: aec3b434e52f473001505bbea5212d5e247eb46f +README.md: cc7b323ae1de917e93e243e97bd5cf5937ecdca4 +README.zh.md: 8d4ae42596483f77aa82b23a0b41168465e2b165 diff --git a/packages/core/tools/README.md b/packages/core/tools/README.md index 21851ca887..cc7b323ae1 100644 --- a/packages/core/tools/README.md +++ b/packages/core/tools/README.md @@ -66,7 +66,7 @@ First-party plugin authors can use the `defineTool()` helper (exported from this ```ts import { readFile } from 'node:fs/promises' -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { defineTool } from '@deepseek-ai/dsh-tools' declare const ctx: Context diff --git a/packages/core/tools/README.zh.md b/packages/core/tools/README.zh.md index aec3b434e5..8d4ae42596 100644 --- a/packages/core/tools/README.zh.md +++ b/packages/core/tools/README.zh.md @@ -66,7 +66,7 @@ tools: ```ts import { readFile } from 'node:fs/promises' -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { defineTool } from '@deepseek-ai/dsh-tools' declare const ctx: Context diff --git a/packages/core/tools/package.json b/packages/core/tools/package.json index 0fcc66b497..7070431132 100644 --- a/packages/core/tools/package.json +++ b/packages/core/tools/package.json @@ -42,10 +42,10 @@ "@deepseek-ai/dsh-session": "^0.0.1", "@deepseek-ai/dsh-system-prompt": "^0.0.1", "@deepseek-ai/dsh-user-approval": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { "@deepseek-ai/dsh-agent": "workspace:^", @@ -56,6 +56,6 @@ "@deepseek-ai/dsh-session": "workspace:^", "@deepseek-ai/dsh-system-prompt": "workspace:^", "@deepseek-ai/dsh-user-approval": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/core/tools/src/index.ts b/packages/core/tools/src/index.ts index 86c69d9307..4073b6c705 100644 --- a/packages/core/tools/src/index.ts +++ b/packages/core/tools/src/index.ts @@ -4,8 +4,8 @@ * @module @deepseek-ai/dsh-tools */ -import { Context, Service } from 'cordis' -import z from 'schemastery' +import { Context, Service } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import { AnonymousEntries, NamedEntries, ScopedLayers, scopeOf, scopeTarget } from '@deepseek-ai/dsh-scope' import type { ScopeKey, ScopeLayer, Scoped } from '@deepseek-ai/dsh-scope' import type { CallId, ContentBlock, ToolSchema } from '@deepseek-ai/dsh-llm' @@ -120,7 +120,7 @@ export type { WebSource, } from './presentation.ts' -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { tools: ToolRegistry } diff --git a/packages/core/tools/src/invariant.ts b/packages/core/tools/src/invariant.ts index a0d9487857..5489f61d80 100644 --- a/packages/core/tools/src/invariant.ts +++ b/packages/core/tools/src/invariant.ts @@ -1,6 +1,6 @@ /** Package-owned tool-pipeline invariants. @module @deepseek-ai/dsh-tools/invariant */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { Session, SessionEvent } from '@deepseek-ai/dsh-session' import type { InvariantFailure, InvariantInstaller } from '@deepseek-ai/dsh-invariants' import type { ToolExecution, ToolExecutionResult } from './index.ts' diff --git a/packages/core/tools/tests/code-mode.spec.ts b/packages/core/tools/tests/code-mode.spec.ts index 1794e7e36e..c1d49808d8 100644 --- a/packages/core/tools/tests/code-mode.spec.ts +++ b/packages/core/tools/tests/code-mode.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { createUserMessage, CallId } from '@deepseek-ai/dsh-llm' import { createScope } from '@deepseek-ai/dsh-scope' import type { Scope } from '@deepseek-ai/dsh-scope' diff --git a/packages/core/tools/tests/execution-mode.spec.ts b/packages/core/tools/tests/execution-mode.spec.ts index 54c4687c60..cbac6fcecc 100644 --- a/packages/core/tools/tests/execution-mode.spec.ts +++ b/packages/core/tools/tests/execution-mode.spec.ts @@ -1,7 +1,7 @@ /** Covers fail-closed per-call classification and model-schema isolation. */ import { describe, expect, expectTypeOf, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { CallId } from '@deepseek-ai/dsh-llm' import SystemPrompt from '@deepseek-ai/dsh-system-prompt' import ToolRegistry, { diff --git a/packages/core/tools/tests/execution-signal-types.spec.ts b/packages/core/tools/tests/execution-signal-types.spec.ts index dd878d648e..0ac4ac85c0 100644 --- a/packages/core/tools/tests/execution-signal-types.spec.ts +++ b/packages/core/tools/tests/execution-signal-types.spec.ts @@ -1,5 +1,5 @@ import { describe, expectTypeOf, it } from 'vitest' -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { CallId } from '@deepseek-ai/dsh-llm' import { defineTool } from '@deepseek-ai/dsh-tools' import type { diff --git a/packages/core/tools/tests/invariant.spec.ts b/packages/core/tools/tests/invariant.spec.ts index 8a60c41331..28badfbc58 100644 --- a/packages/core/tools/tests/invariant.spec.ts +++ b/packages/core/tools/tests/invariant.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { scopeTarget } from '@deepseek-ai/dsh-scope' import { CallId } from '@deepseek-ai/dsh-llm' import SessionStore, { Session, SessionId } from '@deepseek-ai/dsh-session' diff --git a/packages/core/tools/tests/scoped.spec.ts b/packages/core/tools/tests/scoped.spec.ts index 8f7be45b19..6f03e0aef4 100644 --- a/packages/core/tools/tests/scoped.spec.ts +++ b/packages/core/tools/tests/scoped.spec.ts @@ -1,6 +1,6 @@ import { describe, expect, expectTypeOf, it, vi } from 'vitest' -import { Context } from 'cordis' -import type { Events } from 'cordis' +import { Context } from '@deepseek-ai/cordis' +import type { Events } from '@deepseek-ai/cordis' import { bindScopeParent, createScope } from '@deepseek-ai/dsh-scope' import type { Scope } from '@deepseek-ai/dsh-scope' import SystemPrompt from '@deepseek-ai/dsh-system-prompt' diff --git a/packages/core/tools/tests/tools.spec.ts b/packages/core/tools/tests/tools.spec.ts index cfb1f6db05..217875898d 100644 --- a/packages/core/tools/tests/tools.spec.ts +++ b/packages/core/tools/tests/tools.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, expectTypeOf, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { createUserMessage, CallId, HarnessError, type ContentBlock } from '@deepseek-ai/dsh-llm' import SystemPrompt from '@deepseek-ai/dsh-system-prompt' import type { Agent } from '@deepseek-ai/dsh-agent' diff --git a/packages/credentials/credentials-local/package.json b/packages/credentials/credentials-local/package.json index f4fbb3a9fe..483fc3d5d0 100644 --- a/packages/credentials/credentials-local/package.json +++ b/packages/credentials/credentials-local/package.json @@ -30,11 +30,11 @@ "@deepseek-ai/dsh-environment": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-paths": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { "chokidar": "^4.0.3", - "schemastery": "^3.18.0", + "@deepseek-ai/schemastery": "^3.18.0", "yaml": "^2.9.0" }, "devDependencies": { @@ -43,6 +43,6 @@ "@deepseek-ai/dsh-environment": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-paths": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/credentials/credentials-local/src/index.ts b/packages/credentials/credentials-local/src/index.ts index e7800253f3..c61a7521e9 100644 --- a/packages/credentials/credentials-local/src/index.ts +++ b/packages/credentials/credentials-local/src/index.ts @@ -35,8 +35,8 @@ * @module @deepseek-ai/dsh-credentials-local */ -import { Context, Service } from 'cordis' -import z from 'schemastery' +import { Context, Service } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import { watch as chokidarWatch } from 'chokidar' import { mkdir, readFile, stat } from 'node:fs/promises' import { dirname, join, resolve } from 'node:path' diff --git a/packages/credentials/credentials-local/src/invariant.ts b/packages/credentials/credentials-local/src/invariant.ts index 454f2b808e..0ea27d0071 100644 --- a/packages/credentials/credentials-local/src/invariant.ts +++ b/packages/credentials/credentials-local/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-credentials-local' diff --git a/packages/credentials/credentials-local/tests/drain.spec.ts b/packages/credentials/credentials-local/tests/drain.spec.ts index 9cf4e600fb..bbd2feec26 100644 --- a/packages/credentials/credentials-local/tests/drain.spec.ts +++ b/packages/credentials/credentials-local/tests/drain.spec.ts @@ -1,5 +1,5 @@ import { afterEach, describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { mkdtemp, rm } from 'node:fs/promises' import { tmpdir } from 'node:os' import { join } from 'node:path' diff --git a/packages/credentials/credentials-local/tests/local.spec.ts b/packages/credentials/credentials-local/tests/local.spec.ts index e9f65356bd..d66aa83047 100644 --- a/packages/credentials/credentials-local/tests/local.spec.ts +++ b/packages/credentials/credentials-local/tests/local.spec.ts @@ -1,5 +1,5 @@ import { afterEach, describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { mkdir, mkdtemp, readFile, rm, stat, writeFile } from 'node:fs/promises' import { tmpdir } from 'node:os' import { join, resolve } from 'node:path' diff --git a/packages/credentials/credentials-local/tests/review-fixes.spec.ts b/packages/credentials/credentials-local/tests/review-fixes.spec.ts index b7839cf538..6a9aad7ea4 100644 --- a/packages/credentials/credentials-local/tests/review-fixes.spec.ts +++ b/packages/credentials/credentials-local/tests/review-fixes.spec.ts @@ -3,7 +3,7 @@ // broken observer never fails a committed write), and the YAML document // editor's isolation between entries. import { afterEach, describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { mkdtemp, readFile, rm, stat, writeFile } from 'node:fs/promises' import { tmpdir } from 'node:os' import { join } from 'node:path' diff --git a/packages/credentials/credentials-local/tests/watcher.spec.ts b/packages/credentials/credentials-local/tests/watcher.spec.ts index e49f1421b4..11307cde0d 100644 --- a/packages/credentials/credentials-local/tests/watcher.spec.ts +++ b/packages/credentials/credentials-local/tests/watcher.spec.ts @@ -1,5 +1,5 @@ import { afterEach, describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { chmod, mkdtemp, rm, writeFile } from 'node:fs/promises' import { tmpdir } from 'node:os' import { join } from 'node:path' diff --git a/packages/credentials/credentials/README.i18n.yaml b/packages/credentials/credentials/README.i18n.yaml index 053af47617..756ba1ba04 100644 --- a/packages/credentials/credentials/README.i18n.yaml +++ b/packages/credentials/credentials/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/credentials/credentials/README.md -README.md: fc4fb16991a3396f106bed65b468d0ae538bbab8 -README.zh.md: 6007618e5dc917ebc38fd322b34427cb5281e70c +README.md: 5cfeb8e6656fabd638ea2126e56bc66391f0ca01 +README.zh.md: 28a029f0e4909fb14a1208458dcd1d22afe4abb9 diff --git a/packages/credentials/credentials/README.md b/packages/credentials/credentials/README.md index fc4fb16991..5cfeb8e665 100644 --- a/packages/credentials/credentials/README.md +++ b/packages/credentials/credentials/README.md @@ -13,7 +13,7 @@ Credential Service Definition (`ctx.credentials`). One doctrine, three consequen ## Surface ```ts -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { credentialRef } from '@deepseek-ai/dsh-credentials' declare const ctx: Context diff --git a/packages/credentials/credentials/README.zh.md b/packages/credentials/credentials/README.zh.md index 6007618e5d..28a029f0e4 100644 --- a/packages/credentials/credentials/README.zh.md +++ b/packages/credentials/credentials/README.zh.md @@ -13,7 +13,7 @@ ## 接口 ```ts -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { credentialRef } from '@deepseek-ai/dsh-credentials' declare const ctx: Context diff --git a/packages/credentials/credentials/package.json b/packages/credentials/credentials/package.json index 42dd183fc4..2b356c197c 100644 --- a/packages/credentials/credentials/package.json +++ b/packages/credentials/credentials/package.json @@ -27,11 +27,11 @@ "peerDependencies": { "@deepseek-ai/dsh-brand": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-brand": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/credentials/credentials/src/index.ts b/packages/credentials/credentials/src/index.ts index 5f1efb010c..b4fb1569f1 100644 --- a/packages/credentials/credentials/src/index.ts +++ b/packages/credentials/credentials/src/index.ts @@ -8,7 +8,7 @@ * @module @deepseek-ai/dsh-credentials */ -import { Context, Service } from 'cordis' +import { Context, Service } from '@deepseek-ai/cordis' import type { Branded } from '@deepseek-ai/dsh-brand' /** Nominal reference to one credential: a POSIX-style environment-variable name. */ @@ -46,7 +46,7 @@ export interface CredentialInfo { writable: boolean } -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { credentials: Credentials } diff --git a/packages/credentials/credentials/src/invariant.ts b/packages/credentials/credentials/src/invariant.ts index 23c2dda45b..790388ffae 100644 --- a/packages/credentials/credentials/src/invariant.ts +++ b/packages/credentials/credentials/src/invariant.ts @@ -3,7 +3,7 @@ * @module @deepseek-ai/dsh-credentials/invariant */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantFailure, InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-credentials' diff --git a/packages/credentials/credentials/tests/credentials.spec.ts b/packages/credentials/credentials/tests/credentials.spec.ts index 9b4cf7b1e8..a4676a2ea8 100644 --- a/packages/credentials/credentials/tests/credentials.spec.ts +++ b/packages/credentials/credentials/tests/credentials.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { credentialRef } from '../src/index.ts' import type { CredentialRef } from '../src/index.ts' import { MemoryCredentials } from './memory.ts' diff --git a/packages/credentials/credentials/tests/invariant.spec.ts b/packages/credentials/credentials/tests/invariant.spec.ts index dccde4843f..f1af9d28b8 100644 --- a/packages/credentials/credentials/tests/invariant.spec.ts +++ b/packages/credentials/credentials/tests/invariant.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import InvariantService from '@deepseek-ai/dsh-invariants' import { credentialRef } from '../src/index.ts' import * as CredentialsInvariant from '../src/invariant.ts' diff --git a/packages/credentials/credentials/tests/memory.ts b/packages/credentials/credentials/tests/memory.ts index dc1ed77a06..5b8ab32262 100644 --- a/packages/credentials/credentials/tests/memory.ts +++ b/packages/credentials/credentials/tests/memory.ts @@ -1,4 +1,4 @@ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { Credentials } from '../src/index.ts' import type { CredentialInfo, CredentialRef, ResolvedCredential } from '../src/index.ts' diff --git a/packages/e2b/e2b/package.json b/packages/e2b/e2b/package.json index 5abacb278a..edb7077d63 100644 --- a/packages/e2b/e2b/package.json +++ b/packages/e2b/e2b/package.json @@ -26,16 +26,16 @@ "license": "BSD-3-Clause", "peerDependencies": { "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { "e2b": "2.29.1", - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-loader-smoke": "workspace:^", "@deepseek-ai/dsh-sandbox-policy": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/e2b/e2b/src/index.ts b/packages/e2b/e2b/src/index.ts index 906941d421..b428f45cf3 100644 --- a/packages/e2b/e2b/src/index.ts +++ b/packages/e2b/e2b/src/index.ts @@ -6,8 +6,8 @@ import { randomUUID } from 'node:crypto' import { posix } from 'node:path' -import { Context, Service } from 'cordis' -import z from 'schemastery' +import { Context, Service } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import { FileType, Sandbox, SandboxNotFoundError } from 'e2b' export { @@ -60,7 +60,7 @@ interface SchemaResolvedConfig extends Config { timeoutMs: number } -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { e2b: E2BSandboxService } diff --git a/packages/e2b/e2b/src/invariant.ts b/packages/e2b/e2b/src/invariant.ts index 891cabb2db..63bf988e50 100644 --- a/packages/e2b/e2b/src/invariant.ts +++ b/packages/e2b/e2b/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-e2b' diff --git a/packages/e2b/e2b/tests/composition.e2e.ts b/packages/e2b/e2b/tests/composition.e2e.ts index 6da102a827..76f54ba7fd 100644 --- a/packages/e2b/e2b/tests/composition.e2e.ts +++ b/packages/e2b/e2b/tests/composition.e2e.ts @@ -1,7 +1,7 @@ import { access } from 'node:fs/promises' import { join, posix } from 'node:path' import { fileURLToPath } from 'node:url' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { describe, expect, it } from 'vitest' import { Inbox } from '@deepseek-ai/dsh-agent' import type { Agent } from '@deepseek-ai/dsh-agent' diff --git a/packages/e2b/e2b/tests/e2b.spec.ts b/packages/e2b/e2b/tests/e2b.spec.ts index b108bc68b0..9b9e4b0b9d 100644 --- a/packages/e2b/e2b/tests/e2b.spec.ts +++ b/packages/e2b/e2b/tests/e2b.spec.ts @@ -1,6 +1,6 @@ import { beforeEach, describe, expect, it, vi } from 'vitest' import type { Mock } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import type { Sandbox as SandboxType } from 'e2b' import E2BSandboxService, { e2bControlEnvs, diff --git a/packages/e2b/fs-e2b/package.json b/packages/e2b/fs-e2b/package.json index 02925ee7c4..7b7faf9c03 100644 --- a/packages/e2b/fs-e2b/package.json +++ b/packages/e2b/fs-e2b/package.json @@ -28,12 +28,12 @@ "@deepseek-ai/dsh-e2b": "^0.0.1", "@deepseek-ai/dsh-fs": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-e2b": "workspace:^", "@deepseek-ai/dsh-fs": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/e2b/fs-e2b/src/invariant.ts b/packages/e2b/fs-e2b/src/invariant.ts index 9f14bb37a6..891b157aec 100644 --- a/packages/e2b/fs-e2b/src/invariant.ts +++ b/packages/e2b/fs-e2b/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-fs-e2b' diff --git a/packages/e2b/fs-e2b/tests/filesystem.spec.ts b/packages/e2b/fs-e2b/tests/filesystem.spec.ts index 6ee3df6543..5eed6007c4 100644 --- a/packages/e2b/fs-e2b/tests/filesystem.spec.ts +++ b/packages/e2b/fs-e2b/tests/filesystem.spec.ts @@ -1,6 +1,6 @@ import { Buffer } from 'node:buffer' import { dirname, posix } from 'node:path' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { CommandExitError, FileNotFoundError, diff --git a/packages/e2b/subprocess-e2b/package.json b/packages/e2b/subprocess-e2b/package.json index 007b88f1c9..182c41b8f5 100644 --- a/packages/e2b/subprocess-e2b/package.json +++ b/packages/e2b/subprocess-e2b/package.json @@ -29,16 +29,16 @@ "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-subprocess": "^0.0.1", "@deepseek-ai/dsh-timeout": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { "@deepseek-ai/dsh-e2b": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-subprocess": "workspace:^", "@deepseek-ai/dsh-timeout": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/e2b/subprocess-e2b/src/index.ts b/packages/e2b/subprocess-e2b/src/index.ts index 3c0063c457..bd3978f818 100644 --- a/packages/e2b/subprocess-e2b/src/index.ts +++ b/packages/e2b/subprocess-e2b/src/index.ts @@ -6,8 +6,8 @@ import { randomUUID } from 'node:crypto' import { posix } from 'node:path' -import { Context } from 'cordis' -import z from 'schemastery' +import { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import { SubprocessService } from '@deepseek-ai/dsh-subprocess' import { MAX_TIMER_DELAY_MS } from '@deepseek-ai/dsh-timeout' import type { diff --git a/packages/e2b/subprocess-e2b/src/invariant.ts b/packages/e2b/subprocess-e2b/src/invariant.ts index 9f8b8fb739..733310245a 100644 --- a/packages/e2b/subprocess-e2b/src/invariant.ts +++ b/packages/e2b/subprocess-e2b/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-subprocess-e2b' diff --git a/packages/e2b/subprocess-e2b/tests/subprocess.spec.ts b/packages/e2b/subprocess-e2b/tests/subprocess.spec.ts index 153b144ccd..6272320e0c 100644 --- a/packages/e2b/subprocess-e2b/tests/subprocess.spec.ts +++ b/packages/e2b/subprocess-e2b/tests/subprocess.spec.ts @@ -1,5 +1,5 @@ import { once } from 'node:events' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { CommandExitError, FileNotFoundError, diff --git a/packages/e2b/subprocess-e2b/tests/terminal.spec.ts b/packages/e2b/subprocess-e2b/tests/terminal.spec.ts index a142817870..1e3e296a7f 100644 --- a/packages/e2b/subprocess-e2b/tests/terminal.spec.ts +++ b/packages/e2b/subprocess-e2b/tests/terminal.spec.ts @@ -1,6 +1,6 @@ import { Buffer } from 'node:buffer' import { once } from 'node:events' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { describe, expect, it, vi } from 'vitest' import { CommandExitError, diff --git a/packages/examples/acp-demo/package.json b/packages/examples/acp-demo/package.json index ce4b65466a..0e110ec3d4 100644 --- a/packages/examples/acp-demo/package.json +++ b/packages/examples/acp-demo/package.json @@ -33,8 +33,8 @@ ], "license": "BSD-3-Clause", "peerDependencies": { - "@cordisjs/plugin-include": "^1.0.4", - "@cordisjs/plugin-loader": "^1.0.0-rc.5", + "@deepseek-ai/cordis-plugin-include": "^1.0.4", + "@deepseek-ai/cordis-plugin-loader": "^1.0.0-rc.5", "@deepseek-ai/dsh-acp": "^0.0.1", "@deepseek-ai/dsh-agent-spine-demo": "^0.0.1", "@deepseek-ai/dsh-app-boot": "^0.0.1", @@ -45,12 +45,12 @@ "@deepseek-ai/dsh-session-query-sqlite": "^0.0.1", "@deepseek-ai/dsh-tools": "^0.0.1", "@deepseek-ai/dsh-workspace-context": "^0.0.1", - "cordis": "^4.0.0-rc.7", - "schemastery": "^3.17.0" + "@deepseek-ai/cordis": "^4.0.0-rc.7", + "@deepseek-ai/schemastery": "^3.17.0" }, "devDependencies": { - "@cordisjs/plugin-include": "workspace:^", - "@cordisjs/plugin-loader": "workspace:^", + "@deepseek-ai/cordis-plugin-include": "workspace:^", + "@deepseek-ai/cordis-plugin-loader": "workspace:^", "@deepseek-ai/dsh-acp": "workspace:^", "@deepseek-ai/dsh-agent": "workspace:^", "@deepseek-ai/dsh-agent-spine-demo": "workspace:^", @@ -63,7 +63,7 @@ "@deepseek-ai/dsh-system-prompt": "workspace:^", "@deepseek-ai/dsh-tools": "workspace:^", "@deepseek-ai/dsh-workspace-context": "workspace:^", - "cordis": "^4.0.0-rc.7", - "schemastery": "^3.17.0" + "@deepseek-ai/cordis": "^4.0.0-rc.7", + "@deepseek-ai/schemastery": "^3.17.0" } } diff --git a/packages/examples/acp-demo/src/index.ts b/packages/examples/acp-demo/src/index.ts index 8a900dd3cd..1bd0c44459 100644 --- a/packages/examples/acp-demo/src/index.ts +++ b/packages/examples/acp-demo/src/index.ts @@ -11,9 +11,9 @@ * @module @deepseek-ai/dsh-acp-demo */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { join } from 'node:path' -import z from 'schemastery' +import z from '@deepseek-ai/schemastery' import * as acp from '@deepseek-ai/dsh-acp' import * as agentCore from '@deepseek-ai/dsh-agent-spine-demo' import * as workspaceContext from '@deepseek-ai/dsh-workspace-context' diff --git a/packages/examples/acp-demo/src/invariant.ts b/packages/examples/acp-demo/src/invariant.ts index 95b57b57e1..106ba974d5 100644 --- a/packages/examples/acp-demo/src/invariant.ts +++ b/packages/examples/acp-demo/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-acp-demo' diff --git a/packages/examples/acp-demo/tests/acp-agent.spec.ts b/packages/examples/acp-demo/tests/acp-agent.spec.ts index 9c60bee081..af467660da 100644 --- a/packages/examples/acp-demo/tests/acp-agent.spec.ts +++ b/packages/examples/acp-demo/tests/acp-agent.spec.ts @@ -3,8 +3,8 @@ import { randomUUID } from 'node:crypto' import { mkdtemp } from 'node:fs/promises' import { join } from 'node:path' import { tmpdir } from 'node:os' -import { Context } from 'cordis' -import Loader from '@cordisjs/plugin-loader' +import { Context } from '@deepseek-ai/cordis' +import Loader from '@deepseek-ai/cordis-plugin-loader' import { agentEvents } from '@deepseek-ai/dsh-agent' import { TOOL_ORDER_REST } from '@deepseek-ai/dsh-system-prompt' import type { Message } from '@deepseek-ai/dsh-llm' diff --git a/packages/examples/agent-spine-demo/README.i18n.yaml b/packages/examples/agent-spine-demo/README.i18n.yaml index 44de45d88f..87c1dc1562 100644 --- a/packages/examples/agent-spine-demo/README.i18n.yaml +++ b/packages/examples/agent-spine-demo/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/examples/agent-spine-demo/README.md -README.md: cf0dc2ecd6e51eb872be75dfe6d80a5338605195 -README.zh.md: e5a8672d494e0c456aa820641e685d00be624445 +README.md: 5957d9a8e9218e18d5d7d0f620b6be811f2c230f +README.zh.md: 78372240764ff3c779ea0805aedd26a00baf1768 diff --git a/packages/examples/agent-spine-demo/README.md b/packages/examples/agent-spine-demo/README.md index cf0dc2ecd6..5957d9a8e9 100644 --- a/packages/examples/agent-spine-demo/README.md +++ b/packages/examples/agent-spine-demo/README.md @@ -11,7 +11,7 @@ Read this package for the whole plugin tree and its composition order. `apply(ctx, config)` mounts each of these as a child of the bundle fiber: ``` -@cordisjs/plugin-timer timer service (writes nothing to stdout) +@deepseek-ai/cordis-plugin-timer timer service (writes nothing to stdout) @deepseek-ai/dsh-llm abstract LLM service + content-block vocabulary @deepseek-ai/dsh-session event-sourced session log + store @deepseek-ai/dsh-session-title log-backed title service + deterministic fallback diff --git a/packages/examples/agent-spine-demo/README.zh.md b/packages/examples/agent-spine-demo/README.zh.md index e5a8672d49..7837224076 100644 --- a/packages/examples/agent-spine-demo/README.zh.md +++ b/packages/examples/agent-spine-demo/README.zh.md @@ -11,7 +11,7 @@ `apply(ctx, config)` 将以下每个插件挂载为组合包 fiber 的子节点: ``` -@cordisjs/plugin-timer timer service (writes nothing to stdout) +@deepseek-ai/cordis-plugin-timer timer service (writes nothing to stdout) @deepseek-ai/dsh-llm abstract LLM service + content-block vocabulary @deepseek-ai/dsh-session event-sourced session log + store @deepseek-ai/dsh-session-title log-backed title service + deterministic fallback diff --git a/packages/examples/agent-spine-demo/package.json b/packages/examples/agent-spine-demo/package.json index e6c6ce351d..73520f5645 100644 --- a/packages/examples/agent-spine-demo/package.json +++ b/packages/examples/agent-spine-demo/package.json @@ -25,7 +25,7 @@ ], "license": "BSD-3-Clause", "peerDependencies": { - "@cordisjs/plugin-timer": "^1.1.2", + "@deepseek-ai/cordis-plugin-timer": "^1.1.2", "@deepseek-ai/dsh-agent": "^0.0.1", "@deepseek-ai/dsh-agent-loop": "^0.0.1", "@deepseek-ai/dsh-goal": "^0.0.1", @@ -48,10 +48,10 @@ "@deepseek-ai/dsh-tool-tasks": "^0.0.1", "@deepseek-ai/dsh-tools": "^0.0.1", "@deepseek-ai/dsh-workspace-context": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { - "@cordisjs/plugin-timer": "workspace:^", + "@deepseek-ai/cordis-plugin-timer": "workspace:^", "@deepseek-ai/dsh-agent": "workspace:^", "@deepseek-ai/dsh-agent-loop": "workspace:^", "@deepseek-ai/dsh-bash-env": "workspace:^", @@ -85,9 +85,9 @@ "@deepseek-ai/dsh-tools": "workspace:^", "@deepseek-ai/dsh-workspace-context": "workspace:^", "@deepseek-ai/node-addon-landlock-run": "workspace:*", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" } } diff --git a/packages/examples/agent-spine-demo/src/index.ts b/packages/examples/agent-spine-demo/src/index.ts index 7d9e99a908..383fc8c212 100644 --- a/packages/examples/agent-spine-demo/src/index.ts +++ b/packages/examples/agent-spine-demo/src/index.ts @@ -8,9 +8,9 @@ * @module @deepseek-ai/dsh-agent-spine-demo */ -import type { Context } from 'cordis' -import Timer from '@cordisjs/plugin-timer' -import z from 'schemastery' +import type { Context } from '@deepseek-ai/cordis' +import Timer from '@deepseek-ai/cordis-plugin-timer' +import z from '@deepseek-ai/schemastery' import LlmService from '@deepseek-ai/dsh-llm' import SessionStore from '@deepseek-ai/dsh-session' import SessionTitleService, { type Config as SessionTitleConfig } from '@deepseek-ai/dsh-session-title' diff --git a/packages/examples/agent-spine-demo/src/invariant.ts b/packages/examples/agent-spine-demo/src/invariant.ts index fada985329..9735d8e74d 100644 --- a/packages/examples/agent-spine-demo/src/invariant.ts +++ b/packages/examples/agent-spine-demo/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-agent-spine-demo' diff --git a/packages/examples/agent-spine-demo/tests/agent-core.spec.ts b/packages/examples/agent-spine-demo/tests/agent-core.spec.ts index 8de047a79a..dd059793d5 100644 --- a/packages/examples/agent-spine-demo/tests/agent-core.spec.ts +++ b/packages/examples/agent-spine-demo/tests/agent-core.spec.ts @@ -2,8 +2,8 @@ import { describe, expect, it, vi } from 'vitest' import { mkdir, mkdtemp, rm, writeFile } from 'node:fs/promises' import { join, sep } from 'node:path' import { tmpdir } from 'node:os' -import { Context } from 'cordis' -import Loader from '@cordisjs/plugin-loader' +import { Context } from '@deepseek-ai/cordis' +import Loader from '@deepseek-ai/cordis-plugin-loader' import { renderPrompt, TOOL_ORDER_REST } from '@deepseek-ai/dsh-system-prompt' import * as agentCore from '../src/index.ts' import { agentEvents, type Agent } from '@deepseek-ai/dsh-agent' diff --git a/packages/examples/agent-spine-demo/tests/gen-config-catalog.spec.ts b/packages/examples/agent-spine-demo/tests/gen-config-catalog.spec.ts index ae4966fd12..dfd3ff407f 100644 --- a/packages/examples/agent-spine-demo/tests/gen-config-catalog.spec.ts +++ b/packages/examples/agent-spine-demo/tests/gen-config-catalog.spec.ts @@ -43,7 +43,7 @@ export interface Config { describe('gen-config-catalog classification', () => { it('classifies an apply plugin with a config parameter and extracts the paste', () => { const entries = collectConfigCatalog(make({ - 'src/index.ts': `import type { Context } from 'cordis' + 'src/index.ts': `import type { Context } from '@deepseek-ai/cordis' export const inject = ['tools'] ${DOCUMENTED_CONFIG} /** Load. */ @@ -57,8 +57,8 @@ export function apply(ctx: Context, config: Config): void {} it('classifies a default service class, reading its constructor and static inject', () => { const entries = collectConfigCatalog(make({ - 'src/index.ts': `import type { Context } from 'cordis' -import z from 'schemastery' + 'src/index.ts': `import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' ${DOCUMENTED_CONFIG} /** Fixture service. */ export default class Fix { @@ -110,7 +110,7 @@ export default class Fix { describe('gen-config-catalog config extraction guards', () => { it('hard-errors on a config field with no JSDoc prose', () => { expect(() => collectConfigCatalog(make({ - 'src/index.ts': `import type { Context } from 'cordis' + 'src/index.ts': `import type { Context } from '@deepseek-ai/cordis' export interface Config { knob?: string } @@ -122,7 +122,7 @@ export function apply(ctx: Context, config: Config): void {} it('hard-errors on an undocumented field nested in a type literal', () => { expect(() => collectConfigCatalog(make({ - 'src/index.ts': `import type { Context } from 'cordis' + 'src/index.ts': `import type { Context } from '@deepseek-ai/cordis' /** Fixture config. */ export interface Config { /** Entries. */ @@ -138,7 +138,7 @@ export function apply(ctx: Context, config: Config): void {} it('pastes a package-local type transitively and records external refs', () => { const entries = collectConfigCatalog(make({ - 'src/index.ts': `import type { Context } from 'cordis' + 'src/index.ts': `import type { Context } from '@deepseek-ai/cordis' import type { Mode } from './types.ts' import type { Remote } from '@fix/dep' /** Fixture config. */ @@ -162,7 +162,7 @@ export function apply(ctx: Context, config: Config): void {} it('pastes an enum referenced by the config type', () => { const entries = collectConfigCatalog(make({ - 'src/index.ts': `import type { Context } from 'cordis' + 'src/index.ts': `import type { Context } from '@deepseek-ai/cordis' /** Fixture mode. */ export enum Mode { A = 'a', @@ -185,7 +185,7 @@ export function apply(ctx: Context, config: Config): void {} it('hard-errors on a referenced type name that resolves nowhere', () => { expect(() => collectConfigCatalog(make({ - 'src/index.ts': `import type { Context } from 'cordis' + 'src/index.ts': `import type { Context } from '@deepseek-ai/cordis' /** Fixture config. */ export interface Config { /** The ghost. */ @@ -199,7 +199,7 @@ export function apply(ctx: Context, config: Config): void {} it('hard-errors on a config type imported from another package', () => { expect(() => collectConfigCatalog(make({ - 'src/index.ts': `import type { Context } from 'cordis' + 'src/index.ts': `import type { Context } from '@deepseek-ai/cordis' import type { Config } from '@fix/dep' /** Load. */ export function apply(ctx: Context, config: Config): void {} @@ -209,7 +209,7 @@ export function apply(ctx: Context, config: Config): void {} it('hard-errors when one name resolves to two different declarations across the closure', () => { expect(() => collectConfigCatalog(make({ - 'src/index.ts': `import type { Context } from 'cordis' + 'src/index.ts': `import type { Context } from '@deepseek-ai/cordis' import type { A } from './a.ts' import type { B } from './b.ts' /** Fixture config. */ @@ -231,8 +231,8 @@ export function apply(ctx: Context, config: Config): void {} describe('gen-config-catalog schema cross-check', () => { it('accepts a chained schema whose keys all appear on the config type', () => { const entries = collectConfigCatalog(make({ - 'src/index.ts': `import type { Context } from 'cordis' -import z from 'schemastery' + 'src/index.ts': `import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' ${DOCUMENTED_CONFIG} export const Config: z = z.object({ knob: z.string() }).default({}) /** Load. */ @@ -244,8 +244,8 @@ export function apply(ctx: Context, config: Config): void {} it('hard-errors on a schema key the config type does not declare', () => { expect(() => collectConfigCatalog(make({ - 'src/index.ts': `import type { Context } from 'cordis' -import z from 'schemastery' + 'src/index.ts': `import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' ${DOCUMENTED_CONFIG} export const Config: z = z.object({ knob: z.string(), hidden: z.number() }) /** Load. */ @@ -256,8 +256,8 @@ export function apply(ctx: Context, config: Config): void {} it('hard-errors on a NESTED schema key the config type does not declare', () => { expect(() => collectConfigCatalog(make({ - 'src/index.ts': `import type { Context } from 'cordis' -import z from 'schemastery' + 'src/index.ts': `import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' /** Fixture config. */ export interface Config { /** Entries. */ @@ -280,8 +280,8 @@ export function apply(ctx: Context, config: Config): void {} 'src/types.ts': '/** Shared options. */\nexport interface Opts {\n /** Model. */\n model?: string\n}\n', }) writePkg(root, 'group/one', '@fix/one', { - 'src/index.ts': `import type { Context } from 'cordis' -import z from 'schemastery' + 'src/index.ts': `import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import type { Opts } from '@fix/dep' /** Fixture config. */ export interface Config { @@ -301,8 +301,8 @@ export function apply(ctx: Context, config: Config): void {} it('resolves nested keys through a Partial<> wrapper', () => { expect(() => collectConfigCatalog(make({ - 'src/index.ts': `import type { Context } from 'cordis' -import z from 'schemastery' + 'src/index.ts': `import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' /** Caps. */ export interface Caps { /** X. */ @@ -322,8 +322,8 @@ export function apply(ctx: Context, config: Config): void {} it('leaves a nested key under an external (unresolvable) type unreported', () => { expect(() => collectConfigCatalog(make({ - 'src/index.ts': `import type { Context } from 'cordis' -import z from 'schemastery' + 'src/index.ts': `import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import type { External } from 'some-external-pkg' /** Fixture config. */ export interface Config { @@ -340,8 +340,8 @@ export function apply(ctx: Context, config: Config): void {} it('folds an intersected workspace schema into the subset check', () => { const root = makeRoot() writePkg(root, 'group/leaf', '@fix/leaf', { - 'src/index.ts': `import type { Context } from 'cordis' -import z from 'schemastery' + 'src/index.ts': `import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' /** Leaf config. */ export interface Config { /** Leaf knob. */ @@ -355,8 +355,8 @@ export default class Leaf { `, }) writePkg(root, 'group/bundle', '@fix/bundle', { - 'src/index.ts': `import type { Context } from 'cordis' -import z from 'schemastery' + 'src/index.ts': `import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import Leaf from '@fix/leaf' /** Bundle config. */ export interface Config { @@ -375,8 +375,8 @@ export function apply(ctx: Context, config: Config): void {} it('resolves composed nested keys through an indexed-access forwarder', () => { const root = makeRoot() writePkg(root, 'group/leaf', '@fix/leaf', { - 'src/index.ts': `import type { Context } from 'cordis' -import z from 'schemastery' + 'src/index.ts': `import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' /** Leaf config. */ export interface Config { /** Agents. */ @@ -393,8 +393,8 @@ export default class Leaf { `, }) writePkg(root, 'group/bundle', '@fix/bundle', { - 'src/index.ts': `import type { Context } from 'cordis' -import z from 'schemastery' + 'src/index.ts': `import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import Leaf, { type Config as LeafConfig } from '@fix/leaf' /** Bundle config forwarding the leaf's agents list. */ export interface Config { @@ -412,8 +412,8 @@ export function apply(ctx: Context, config: Config): void {} it('hard-errors when an intersected schema key is missing from the bundle config type', () => { const root = makeRoot() writePkg(root, 'group/leaf', '@fix/leaf', { - 'src/index.ts': `import type { Context } from 'cordis' -import z from 'schemastery' + 'src/index.ts': `import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' /** Leaf config. */ export interface Config { /** Leaf knob. */ @@ -427,8 +427,8 @@ export default class Leaf { `, }) writePkg(root, 'group/bundle', '@fix/bundle', { - 'src/index.ts': `import type { Context } from 'cordis' -import z from 'schemastery' + 'src/index.ts': `import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import Leaf from '@fix/leaf' /** Bundle config that forgot to declare the forwarded field. */ export interface Config { @@ -448,7 +448,7 @@ describe('gen-config-catalog render', () => { it('renders sections, fences, and the terse classification lists', () => { const root = makeRoot() writePkg(root, 'group/one', '@fix/one', { - 'src/index.ts': `import type { Context } from 'cordis' + 'src/index.ts': `import type { Context } from '@deepseek-ai/cordis' ${DOCUMENTED_CONFIG} /** Load. */ export function apply(ctx: Context, config: Config): void {} diff --git a/packages/examples/agent-spine-demo/tests/multi-project-sandbox.e2e.ts b/packages/examples/agent-spine-demo/tests/multi-project-sandbox.e2e.ts index 53722aa7e5..8769d91e1b 100644 --- a/packages/examples/agent-spine-demo/tests/multi-project-sandbox.e2e.ts +++ b/packages/examples/agent-spine-demo/tests/multi-project-sandbox.e2e.ts @@ -3,7 +3,7 @@ import { mkdir, mkdtemp, readFile, rm, symlink, writeFile } from 'node:fs/promis import { homedir } from 'node:os' import { basename, join } from 'node:path' import { afterEach, beforeEach, describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { SandboxBashExecutor } from '@deepseek-ai/dsh-bash-sandbox' import LocalSubprocessService from '@deepseek-ai/dsh-subprocess-local' import * as FsPolicy from '@deepseek-ai/dsh-fs-policy' diff --git a/packages/examples/jsonrpc-demo/package.json b/packages/examples/jsonrpc-demo/package.json index 155660d190..774028c914 100644 --- a/packages/examples/jsonrpc-demo/package.json +++ b/packages/examples/jsonrpc-demo/package.json @@ -37,10 +37,10 @@ }, "peerDependencies": { "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-invariants": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/examples/jsonrpc-demo/src/invariant.ts b/packages/examples/jsonrpc-demo/src/invariant.ts index dd093a5418..9eb3eeb53a 100644 --- a/packages/examples/jsonrpc-demo/src/invariant.ts +++ b/packages/examples/jsonrpc-demo/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-jsonrpc-demo' diff --git a/packages/feedback/command-feedback/package.json b/packages/feedback/command-feedback/package.json index 433087eff3..ac901d6a99 100644 --- a/packages/feedback/command-feedback/package.json +++ b/packages/feedback/command-feedback/package.json @@ -29,17 +29,17 @@ "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-session": "^0.0.1", "@deepseek-ai/dsh-user-id": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { - "@cordisjs/plugin-include": "workspace:^", - "@cordisjs/plugin-loader": "workspace:^", + "@deepseek-ai/cordis-plugin-include": "workspace:^", + "@deepseek-ai/cordis-plugin-loader": "workspace:^", "@deepseek-ai/dsh-agent": "workspace:^", "@deepseek-ai/dsh-commands": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-llm": "workspace:^", "@deepseek-ai/dsh-session": "workspace:^", "@deepseek-ai/dsh-user-id": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/feedback/command-feedback/src/index.ts b/packages/feedback/command-feedback/src/index.ts index 7f0bb3a59f..37205b76e2 100644 --- a/packages/feedback/command-feedback/src/index.ts +++ b/packages/feedback/command-feedback/src/index.ts @@ -6,7 +6,7 @@ * @module @deepseek-ai/dsh-command-feedback */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { CommandInvocation, CommandResult } from '@deepseek-ai/dsh-commands' import type { Session } from '@deepseek-ai/dsh-session' import { getOrCreateAnonymousUserId } from '@deepseek-ai/dsh-user-id' diff --git a/packages/feedback/command-feedback/src/invariant.ts b/packages/feedback/command-feedback/src/invariant.ts index 9c825a6e87..6f4c420ec6 100644 --- a/packages/feedback/command-feedback/src/invariant.ts +++ b/packages/feedback/command-feedback/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-command-feedback' diff --git a/packages/feedback/command-feedback/tests/command-feedback.spec.ts b/packages/feedback/command-feedback/tests/command-feedback.spec.ts index 6f93ff854e..453d9c17fc 100644 --- a/packages/feedback/command-feedback/tests/command-feedback.spec.ts +++ b/packages/feedback/command-feedback/tests/command-feedback.spec.ts @@ -1,6 +1,6 @@ import { beforeEach, describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' -import Loader from '@cordisjs/plugin-loader' +import { Context } from '@deepseek-ai/cordis' +import Loader from '@deepseek-ai/cordis-plugin-loader' import AgentRegistry, { Inbox } from '@deepseek-ai/dsh-agent' import type { Agent, AgentStatus } from '@deepseek-ai/dsh-agent' import CommandService from '@deepseek-ai/dsh-commands' diff --git a/packages/feedback/command-feedback/tests/loader-composition.spec.ts b/packages/feedback/command-feedback/tests/loader-composition.spec.ts index 958b23736f..2060fe2207 100644 --- a/packages/feedback/command-feedback/tests/loader-composition.spec.ts +++ b/packages/feedback/command-feedback/tests/loader-composition.spec.ts @@ -3,9 +3,9 @@ import { tmpdir } from 'node:os' import { join } from 'node:path' import { pathToFileURL } from 'node:url' import { afterEach, describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' -import Loader from '@cordisjs/plugin-loader' -import Include from '@cordisjs/plugin-include' +import { Context } from '@deepseek-ai/cordis' +import Loader from '@deepseek-ai/cordis-plugin-loader' +import Include from '@deepseek-ai/cordis-plugin-include' import AgentRegistry, { Inbox } from '@deepseek-ai/dsh-agent' import type { Agent, AgentStatus } from '@deepseek-ai/dsh-agent' import CommandService from '@deepseek-ai/dsh-commands' diff --git a/packages/fs/fs-local/package.json b/packages/fs/fs-local/package.json index 50135f0f50..1401a25597 100644 --- a/packages/fs/fs-local/package.json +++ b/packages/fs/fs-local/package.json @@ -27,16 +27,16 @@ "peerDependencies": { "@deepseek-ai/dsh-fs": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { "koffi": "^3.1.0", - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { "@deepseek-ai/dsh-fs": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-llm": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/fs/fs-local/src/index.ts b/packages/fs/fs-local/src/index.ts index 5d1f6b2865..5be06c3d1c 100644 --- a/packages/fs/fs-local/src/index.ts +++ b/packages/fs/fs-local/src/index.ts @@ -4,11 +4,11 @@ * @module @deepseek-ai/dsh-fs-local */ -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { constants as bufferConstants } from 'node:buffer' import { isAbsolute, relative, resolve, sep } from 'node:path' import { pathToFileURL } from 'node:url' -import z from 'schemastery' +import z from '@deepseek-ai/schemastery' import { FileSystem, FsError, FsVersion } from '@deepseek-ai/dsh-fs' import type { FsDirEntry, diff --git a/packages/fs/fs-local/src/invariant.ts b/packages/fs/fs-local/src/invariant.ts index 3e38550065..07a8a62246 100644 --- a/packages/fs/fs-local/src/invariant.ts +++ b/packages/fs/fs-local/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-fs-local' diff --git a/packages/fs/fs-local/tests/filesystem.spec.ts b/packages/fs/fs-local/tests/filesystem.spec.ts index d70581f28e..03bad054ec 100644 --- a/packages/fs/fs-local/tests/filesystem.spec.ts +++ b/packages/fs/fs-local/tests/filesystem.spec.ts @@ -12,7 +12,7 @@ import { mkdir, mkdtemp, readFile, realpath, rm, stat, symlink, unlink, utimes, import { tmpdir } from 'node:os' import { join } from 'node:path' import { pathToFileURL } from 'node:url' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { LocalFileSystem } from '@deepseek-ai/dsh-fs-local' import { FsVersion } from '@deepseek-ai/dsh-fs' import type { FsTarget } from '@deepseek-ai/dsh-fs' diff --git a/packages/fs/fs-policy/README.i18n.yaml b/packages/fs/fs-policy/README.i18n.yaml index 65239a6f00..d889e039de 100644 --- a/packages/fs/fs-policy/README.i18n.yaml +++ b/packages/fs/fs-policy/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/fs/fs-policy/README.md -README.md: 395a36e89e113dc3846a8dff62ce90601013addd -README.zh.md: 5b3b1f64de2d51f6b729392da2d4b459a9f0ca3b +README.md: 59865d063095d666244c2ec86b8604f006f70554 +README.zh.md: af84614194db2afef3865a62e1030a2849e48947 diff --git a/packages/fs/fs-policy/README.md b/packages/fs/fs-policy/README.md index 395a36e89e..59865d0630 100644 --- a/packages/fs/fs-policy/README.md +++ b/packages/fs/fs-policy/README.md @@ -5,7 +5,7 @@ English | [中文](README.zh.md) The **fs-policy plugin**: it records observed presence or absence and adds read-before-edit plus guarded write/edit on top of the `ctx.fs` provider contract ([`@deepseek-ai/dsh-fs`](../fs)) — through the `fs/*` event gate, **NOT** through a method service. This plugin registers **no** `ctx.fsPolicy` service and has no public `read`/`write`/`edit`/`resolve` methods. It is the policy third of the filesystem stack: not a swappable seam, but the policy that does not belong on the `FileSystem` provider base class. ```ts -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import * as FsPolicy from '@deepseek-ai/dsh-fs-policy' declare const ctx: Context diff --git a/packages/fs/fs-policy/README.zh.md b/packages/fs/fs-policy/README.zh.md index 5b3b1f64de..af84614194 100644 --- a/packages/fs/fs-policy/README.zh.md +++ b/packages/fs/fs-policy/README.zh.md @@ -5,7 +5,7 @@ **fs-policy 插件**:它记录观测到的存在或缺失状态,并在 `ctx.fs` 提供方约定([`@deepseek-ai/dsh-fs`](../fs))之上增加编辑前读取和带防护的写入/编辑;它通过 `fs/*` 事件门禁参与,**不是**通过方法服务。该插件**不**注册 `ctx.fsPolicy` 服务,也没有公开的 `read`/`write`/`edit`/`resolve` 方法。它是文件系统栈的政策层:不是可替换 seam,而是不应位于 `FileSystem` 提供方基类上的政策。 ```ts -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import * as FsPolicy from '@deepseek-ai/dsh-fs-policy' declare const ctx: Context diff --git a/packages/fs/fs-policy/package.json b/packages/fs/fs-policy/package.json index 634fb114f5..007ef3d529 100644 --- a/packages/fs/fs-policy/package.json +++ b/packages/fs/fs-policy/package.json @@ -27,12 +27,12 @@ "peerDependencies": { "@deepseek-ai/dsh-fs": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-fs": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-llm": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/fs/fs-policy/src/index.ts b/packages/fs/fs-policy/src/index.ts index c7feb8c484..91a9b4ec95 100644 --- a/packages/fs/fs-policy/src/index.ts +++ b/packages/fs/fs-policy/src/index.ts @@ -7,7 +7,7 @@ * @module @deepseek-ai/dsh-fs-policy */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { FsError } from '@deepseek-ai/dsh-fs' import type { FsObservation, FsTarget, FsVersion, FsWriteIntent } from '@deepseek-ai/dsh-fs' import type { FsPolicyExec } from './types.ts' diff --git a/packages/fs/fs-policy/src/invariant.ts b/packages/fs/fs-policy/src/invariant.ts index 369fa5ea84..cd0ff6d2a4 100644 --- a/packages/fs/fs-policy/src/invariant.ts +++ b/packages/fs/fs-policy/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-fs-policy' diff --git a/packages/fs/fs-policy/tests/policy.spec.ts b/packages/fs/fs-policy/tests/policy.spec.ts index 2c977cc3be..27dad3b5fc 100644 --- a/packages/fs/fs-policy/tests/policy.spec.ts +++ b/packages/fs/fs-policy/tests/policy.spec.ts @@ -1,7 +1,7 @@ /** Event-level policy tests; no filesystem provider is needed because the plugin performs no I/O. */ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { FsTargetKey, FsVersion } from '@deepseek-ai/dsh-fs' import type { FsObservation, FsTarget, FsWriteIntent } from '@deepseek-ai/dsh-fs' import * as FsPolicy from '@deepseek-ai/dsh-fs-policy' diff --git a/packages/fs/fs-sandbox/package.json b/packages/fs/fs-sandbox/package.json index 08d63895d0..015a572c19 100644 --- a/packages/fs/fs-sandbox/package.json +++ b/packages/fs/fs-sandbox/package.json @@ -30,7 +30,7 @@ "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-sandbox": "^0.0.1", "@deepseek-ai/dsh-sandbox-policy": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-fs": "workspace:^", @@ -38,6 +38,6 @@ "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-sandbox": "workspace:^", "@deepseek-ai/dsh-sandbox-policy": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/fs/fs-sandbox/src/index.ts b/packages/fs/fs-sandbox/src/index.ts index 8fa3654d62..9a0fa3104e 100644 --- a/packages/fs/fs-sandbox/src/index.ts +++ b/packages/fs/fs-sandbox/src/index.ts @@ -30,7 +30,7 @@ * @module @deepseek-ai/dsh-fs-sandbox */ -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { LocalFileSystem } from '@deepseek-ai/dsh-fs-local' import type { Config as LocalConfig } from '@deepseek-ai/dsh-fs-local' import { FsError } from '@deepseek-ai/dsh-fs' diff --git a/packages/fs/fs-sandbox/src/invariant.ts b/packages/fs/fs-sandbox/src/invariant.ts index 93806bd519..8a42c86c90 100644 --- a/packages/fs/fs-sandbox/src/invariant.ts +++ b/packages/fs/fs-sandbox/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-fs-sandbox' diff --git a/packages/fs/fs-sandbox/tests/fs-sandbox.spec.ts b/packages/fs/fs-sandbox/tests/fs-sandbox.spec.ts index 62648e1362..f6aaa0dd81 100644 --- a/packages/fs/fs-sandbox/tests/fs-sandbox.spec.ts +++ b/packages/fs/fs-sandbox/tests/fs-sandbox.spec.ts @@ -13,7 +13,7 @@ import { mkdir, mkdtemp, readFile, rm, symlink, writeFile } from 'node:fs/promis import { existsSync } from 'node:fs' import { homedir, tmpdir } from 'node:os' import { join, parse } from 'node:path' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { FsError, FsTargetKey } from '@deepseek-ai/dsh-fs' import type { FsTarget } from '@deepseek-ai/dsh-fs' import SandboxPolicyService from '@deepseek-ai/dsh-sandbox-policy' diff --git a/packages/fs/fs/package.json b/packages/fs/fs/package.json index 14989c2f77..c8445419e1 100644 --- a/packages/fs/fs/package.json +++ b/packages/fs/fs/package.json @@ -29,13 +29,13 @@ "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-llm": "^0.0.1", "@deepseek-ai/dsh-sandbox": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-brand": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-llm": "workspace:^", "@deepseek-ai/dsh-sandbox": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/fs/fs/src/index.ts b/packages/fs/fs/src/index.ts index 0be94dccc4..569342ab7e 100644 --- a/packages/fs/fs/src/index.ts +++ b/packages/fs/fs/src/index.ts @@ -8,7 +8,7 @@ * @module @deepseek-ai/dsh-fs */ -import { Context, Service } from 'cordis' +import { Context, Service } from '@deepseek-ai/cordis' import type { SandboxExecutionPolicy, SandboxMode } from '@deepseek-ai/dsh-sandbox' import type { FsDirEntry, @@ -41,7 +41,7 @@ export type { FsWriteOutcome, } from './types.ts' -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { fs: FileSystem } diff --git a/packages/fs/fs/src/invariant.ts b/packages/fs/fs/src/invariant.ts index 62fec9a53c..ec5a22e021 100644 --- a/packages/fs/fs/src/invariant.ts +++ b/packages/fs/fs/src/invariant.ts @@ -1,6 +1,6 @@ /** Package-owned filesystem event-data invariants. @module @deepseek-ai/dsh-fs/invariant */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' import type { FsObservation, FsTarget } from './types.ts' diff --git a/packages/fs/fs/tests/invariant.spec.ts b/packages/fs/fs/tests/invariant.spec.ts index eecdea8766..a63606781a 100644 --- a/packages/fs/fs/tests/invariant.spec.ts +++ b/packages/fs/fs/tests/invariant.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { FsTargetKey, FsVersion } from '@deepseek-ai/dsh-fs' import type { FsTarget } from '@deepseek-ai/dsh-fs' import * as FsInvariant from '@deepseek-ai/dsh-fs/invariant' diff --git a/packages/fs/fs/tests/service.spec.ts b/packages/fs/fs/tests/service.spec.ts index 2340871304..7260af2955 100644 --- a/packages/fs/fs/tests/service.spec.ts +++ b/packages/fs/fs/tests/service.spec.ts @@ -6,7 +6,7 @@ */ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { FileSystem, FsError, FsTargetKey, FsVersion } from '@deepseek-ai/dsh-fs' import type { FsDirEntry, diff --git a/packages/fs/tool-fs-search/package.json b/packages/fs/tool-fs-search/package.json index c0fb5d49d3..ab8a988ef6 100644 --- a/packages/fs/tool-fs-search/package.json +++ b/packages/fs/tool-fs-search/package.json @@ -26,7 +26,7 @@ "license": "BSD-3-Clause", "dependencies": { "@vscode/ripgrep": "^1.18.0", - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "peerDependencies": { "@deepseek-ai/dsh-invariants": "^0.0.1", @@ -38,7 +38,7 @@ "@deepseek-ai/dsh-system-prompt": "^0.0.1", "@deepseek-ai/dsh-timeout": "^0.0.1", "@deepseek-ai/dsh-tools": "^0.0.1", - "cordis": "^4.0.0-rc.6" + "@deepseek-ai/cordis": "^4.0.0-rc.6" }, "devDependencies": { "@deepseek-ai/dsh-agent": "workspace:^", @@ -52,6 +52,6 @@ "@deepseek-ai/dsh-system-prompt": "workspace:^", "@deepseek-ai/dsh-timeout": "workspace:^", "@deepseek-ai/dsh-tools": "workspace:^", - "cordis": "^4.0.0-rc.6" + "@deepseek-ai/cordis": "^4.0.0-rc.6" } } diff --git a/packages/fs/tool-fs-search/src/glob.ts b/packages/fs/tool-fs-search/src/glob.ts index 3eeea9c75c..50a432b0bb 100644 --- a/packages/fs/tool-fs-search/src/glob.ts +++ b/packages/fs/tool-fs-search/src/glob.ts @@ -9,7 +9,7 @@ * @module @deepseek-ai/dsh-tool-fs-search/glob */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { sep } from 'node:path' import { defineTool } from '@deepseek-ai/dsh-tools' import type { GenericCallView, SearchResultView, ToolResult } from '@deepseek-ai/dsh-tools' diff --git a/packages/fs/tool-fs-search/src/grep.ts b/packages/fs/tool-fs-search/src/grep.ts index c7e8ec7ee4..81f76dfa09 100644 --- a/packages/fs/tool-fs-search/src/grep.ts +++ b/packages/fs/tool-fs-search/src/grep.ts @@ -11,7 +11,7 @@ * @module @deepseek-ai/dsh-tool-fs-search/grep */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { defineTool } from '@deepseek-ai/dsh-tools' import type { GenericCallView, SearchResultView, ToolResult } from '@deepseek-ai/dsh-tools' import type { RetainedItems } from '@deepseek-ai/dsh-retention' diff --git a/packages/fs/tool-fs-search/src/index.ts b/packages/fs/tool-fs-search/src/index.ts index cf0a8db066..1f1d86556b 100644 --- a/packages/fs/tool-fs-search/src/index.ts +++ b/packages/fs/tool-fs-search/src/index.ts @@ -26,8 +26,8 @@ * @module @deepseek-ai/dsh-tool-fs-search */ -import type { Context } from 'cordis' -import z from 'schemastery' +import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import { MAX_TIMER_DELAY_MS } from '@deepseek-ai/dsh-timeout' import { GLOB_MAX_RESULTS, applyGlobTool } from './glob.ts' import { GREP_MAX_LINE_BYTES, GREP_MAX_MATCHES, applyGrepTool } from './grep.ts' diff --git a/packages/fs/tool-fs-search/src/invariant.ts b/packages/fs/tool-fs-search/src/invariant.ts index f7f206896d..26d14775ba 100644 --- a/packages/fs/tool-fs-search/src/invariant.ts +++ b/packages/fs/tool-fs-search/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-tool-fs-search' diff --git a/packages/fs/tool-fs-search/src/search-core.ts b/packages/fs/tool-fs-search/src/search-core.ts index 854c593190..ad8693a67c 100644 --- a/packages/fs/tool-fs-search/src/search-core.ts +++ b/packages/fs/tool-fs-search/src/search-core.ts @@ -20,7 +20,7 @@ */ import { isAbsolute, relative, sep } from 'node:path' -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { HarnessError } from '@deepseek-ai/dsh-llm' import { ItemRetainer, TextRetainer } from '@deepseek-ai/dsh-retention' import type { RetainedItems } from '@deepseek-ai/dsh-retention' diff --git a/packages/fs/tool-fs-search/src/surface.ts b/packages/fs/tool-fs-search/src/surface.ts index 78bdd6cc42..0db8887c0c 100644 --- a/packages/fs/tool-fs-search/src/surface.ts +++ b/packages/fs/tool-fs-search/src/surface.ts @@ -1,6 +1,6 @@ /** Shared surface-only post-policy selection for search result spill. @module dsh-tool-fs-search/surface */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { JsonValue, PostToolDecision, ToolDefinition, ToolExecution, ToolExecutionResult } from '@deepseek-ai/dsh-tools' /** diff --git a/packages/fs/tool-fs-search/tests/integration.spec.ts b/packages/fs/tool-fs-search/tests/integration.spec.ts index dc7a88b30f..5087fc96f0 100644 --- a/packages/fs/tool-fs-search/tests/integration.spec.ts +++ b/packages/fs/tool-fs-search/tests/integration.spec.ts @@ -14,7 +14,7 @@ import { existsSync } from 'node:fs' import { mkdir, mkdtemp, rm, utimes, writeFile } from 'node:fs/promises' import { tmpdir } from 'node:os' import { join } from 'node:path' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { CallId } from '@deepseek-ai/dsh-llm' import SystemPrompt from '@deepseek-ai/dsh-system-prompt' import ToolRegistry, { TOOL_ABORTED_BEFORE_DISPATCH } from '@deepseek-ai/dsh-tools' diff --git a/packages/fs/tool-fs-search/tests/load-path.spec.ts b/packages/fs/tool-fs-search/tests/load-path.spec.ts index 1d1e348c09..7dcd1aea6b 100644 --- a/packages/fs/tool-fs-search/tests/load-path.spec.ts +++ b/packages/fs/tool-fs-search/tests/load-path.spec.ts @@ -15,8 +15,8 @@ */ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' -import Loader from '@cordisjs/plugin-loader' +import { Context } from '@deepseek-ai/cordis' +import Loader from '@deepseek-ai/cordis-plugin-loader' import SystemPrompt from '@deepseek-ai/dsh-system-prompt' import ToolRegistry from '@deepseek-ai/dsh-tools' import LocalSubprocessService from '@deepseek-ai/dsh-subprocess-local' diff --git a/packages/fs/tool-fs-search/tests/rg-path.spec.ts b/packages/fs/tool-fs-search/tests/rg-path.spec.ts index 52888a3453..3ad75edaaf 100644 --- a/packages/fs/tool-fs-search/tests/rg-path.spec.ts +++ b/packages/fs/tool-fs-search/tests/rg-path.spec.ts @@ -7,7 +7,7 @@ */ import { describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { CallId } from '@deepseek-ai/dsh-llm' import type { ToolExecution } from '@deepseek-ai/dsh-tools' import { resolveRgPath, runRipgrep } from '@deepseek-ai/dsh-tool-fs-search' diff --git a/packages/fs/tool-fs-search/tests/tools.spec.ts b/packages/fs/tool-fs-search/tests/tools.spec.ts index c02e4f93db..c4ea89345f 100644 --- a/packages/fs/tool-fs-search/tests/tools.spec.ts +++ b/packages/fs/tool-fs-search/tests/tools.spec.ts @@ -11,7 +11,7 @@ */ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { join, sep } from 'node:path' import { createUserMessage, CallId } from '@deepseek-ai/dsh-llm' import SystemPrompt, { renderPrompt } from '@deepseek-ai/dsh-system-prompt' diff --git a/packages/fs/tool-fs/package.json b/packages/fs/tool-fs/package.json index 8af8bc77ba..b2070827cb 100644 --- a/packages/fs/tool-fs/package.json +++ b/packages/fs/tool-fs/package.json @@ -26,7 +26,7 @@ "license": "BSD-3-Clause", "dependencies": { "diff": "^9.0.0", - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "peerDependencies": { "@deepseek-ai/dsh-fs": "^0.0.1", @@ -38,7 +38,7 @@ "@deepseek-ai/dsh-system-prompt": "^0.0.1", "@deepseek-ai/dsh-tools": "^0.0.1", "@deepseek-ai/dsh-user-approval": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-agent": "workspace:^", @@ -56,6 +56,6 @@ "@deepseek-ai/dsh-system-prompt": "workspace:^", "@deepseek-ai/dsh-tools": "workspace:^", "@deepseek-ai/dsh-user-approval": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/fs/tool-fs/src/edit.ts b/packages/fs/tool-fs/src/edit.ts index a7b82bdd06..e74f507f3d 100644 --- a/packages/fs/tool-fs/src/edit.ts +++ b/packages/fs/tool-fs/src/edit.ts @@ -5,7 +5,7 @@ * @module @deepseek-ai/dsh-tool-fs/src/edit */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { defineTool } from '@deepseek-ai/dsh-tools' import type { DiffCallView, DiffResultView, ToolResult } from '@deepseek-ai/dsh-tools' import type {} from '@deepseek-ai/dsh-fs' diff --git a/packages/fs/tool-fs/src/index.ts b/packages/fs/tool-fs/src/index.ts index a4c96d606b..c6a311f686 100644 --- a/packages/fs/tool-fs/src/index.ts +++ b/packages/fs/tool-fs/src/index.ts @@ -5,8 +5,8 @@ * @module @deepseek-ai/dsh-tool-fs */ -import type { Context } from 'cordis' -import z from 'schemastery' +import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import type {} from '@deepseek-ai/dsh-user-approval' import { applyReadTool, READ_LIMIT, STREAM_MIN_SIZE } from './read.ts' import { applyWriteTool } from './write.ts' diff --git a/packages/fs/tool-fs/src/invariant.ts b/packages/fs/tool-fs/src/invariant.ts index eaa2485c06..8cbbe4f423 100644 --- a/packages/fs/tool-fs/src/invariant.ts +++ b/packages/fs/tool-fs/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-tool-fs' diff --git a/packages/fs/tool-fs/src/read.ts b/packages/fs/tool-fs/src/read.ts index dc4f07e8fe..0c062c129e 100644 --- a/packages/fs/tool-fs/src/read.ts +++ b/packages/fs/tool-fs/src/read.ts @@ -4,7 +4,7 @@ * @module @deepseek-ai/dsh-tool-fs/src/read */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { defineTool } from '@deepseek-ai/dsh-tools' import type { GenericCallView, ReadResultView, ToolResult } from '@deepseek-ai/dsh-tools' import { FsError } from '@deepseek-ai/dsh-fs' diff --git a/packages/fs/tool-fs/src/sandbox.ts b/packages/fs/tool-fs/src/sandbox.ts index ca824ceea5..79a2381441 100644 --- a/packages/fs/tool-fs/src/sandbox.ts +++ b/packages/fs/tool-fs/src/sandbox.ts @@ -10,7 +10,7 @@ * @module @deepseek-ai/dsh-tool-fs/sandbox */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { ToolExecution } from '@deepseek-ai/dsh-tools' import type { SandboxExecutionPolicy, SandboxMode } from '@deepseek-ai/dsh-sandbox' import { ESCALATION_TARGETS, approveEscalation, escalationHintMarker, sandboxDenialMarker, validateEscalationArgs } from '@deepseek-ai/dsh-sandbox' diff --git a/packages/fs/tool-fs/src/write.ts b/packages/fs/tool-fs/src/write.ts index ba96e32cd1..12f0ef2652 100644 --- a/packages/fs/tool-fs/src/write.ts +++ b/packages/fs/tool-fs/src/write.ts @@ -5,7 +5,7 @@ * @module @deepseek-ai/dsh-tool-fs/src/write */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { defineTool } from '@deepseek-ai/dsh-tools' import type { DiffCallView, DiffResultView, ToolResult } from '@deepseek-ai/dsh-tools' import type { FsWriteOutcome } from '@deepseek-ai/dsh-fs' diff --git a/packages/fs/tool-fs/tests/fs-tools.e2e.ts b/packages/fs/tool-fs/tests/fs-tools.e2e.ts index 290d7125a7..387fc2410c 100644 --- a/packages/fs/tool-fs/tests/fs-tools.e2e.ts +++ b/packages/fs/tool-fs/tests/fs-tools.e2e.ts @@ -3,7 +3,7 @@ import { mkdtemp, readFile, rm } from 'node:fs/promises' import { tmpdir } from 'node:os' import { join } from 'node:path' import { afterEach, describe, expect, it } from 'vitest' -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { SessionId } from '@deepseek-ai/dsh-session' import { fsHarness, waitForIdle } from './harness.ts' diff --git a/packages/fs/tool-fs/tests/harness.ts b/packages/fs/tool-fs/tests/harness.ts index 0d700e61b6..24a8b4d606 100644 --- a/packages/fs/tool-fs/tests/harness.ts +++ b/packages/fs/tool-fs/tests/harness.ts @@ -1,4 +1,4 @@ -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import type { Agent } from '@deepseek-ai/dsh-agent' import AgentLoop from '@deepseek-ai/dsh-agent-loop' import { mountAgentLoopTestDependencies } from '@deepseek-ai/dsh-agent-loop-testkit' diff --git a/packages/fs/tool-fs/tests/integration.spec.ts b/packages/fs/tool-fs/tests/integration.spec.ts index d2a63e0a38..c3845f76c2 100644 --- a/packages/fs/tool-fs/tests/integration.spec.ts +++ b/packages/fs/tool-fs/tests/integration.spec.ts @@ -9,7 +9,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' import { mkdtemp, readFile, rm, writeFile } from 'node:fs/promises' import { tmpdir } from 'node:os' import { join } from 'node:path' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { CallId } from '@deepseek-ai/dsh-llm' import SystemPrompt from '@deepseek-ai/dsh-system-prompt' import ToolRegistry, { TOOL_ABORTED_BEFORE_DISPATCH } from '@deepseek-ai/dsh-tools' diff --git a/packages/fs/tool-fs/tests/tools.spec.ts b/packages/fs/tool-fs/tests/tools.spec.ts index b217260972..73be4131e1 100644 --- a/packages/fs/tool-fs/tests/tools.spec.ts +++ b/packages/fs/tool-fs/tests/tools.spec.ts @@ -4,7 +4,7 @@ */ import { describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { mkdirSync, mkdtempSync, realpathSync, rmSync, symlinkSync } from 'node:fs' import { tmpdir } from 'node:os' import { join, resolve, sep } from 'node:path' diff --git a/packages/fs/tool-str-replace-editor/package.json b/packages/fs/tool-str-replace-editor/package.json index b9404e20d6..04ad220a3a 100644 --- a/packages/fs/tool-str-replace-editor/package.json +++ b/packages/fs/tool-str-replace-editor/package.json @@ -29,10 +29,10 @@ "@deepseek-ai/dsh-sandbox": "^0.0.1", "@deepseek-ai/dsh-sandbox-policy": "^0.0.1", "@deepseek-ai/dsh-tools": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { "@deepseek-ai/dsh-agent": "workspace:^", @@ -47,6 +47,6 @@ "@deepseek-ai/dsh-session": "workspace:^", "@deepseek-ai/dsh-system-prompt": "workspace:^", "@deepseek-ai/dsh-tools": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/fs/tool-str-replace-editor/src/index.ts b/packages/fs/tool-str-replace-editor/src/index.ts index 4b93c6d82c..c8afd16064 100644 --- a/packages/fs/tool-str-replace-editor/src/index.ts +++ b/packages/fs/tool-str-replace-editor/src/index.ts @@ -4,8 +4,8 @@ */ import { isAbsolute } from 'node:path' -import type { Context } from 'cordis' -import z from 'schemastery' +import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import { FsError } from '@deepseek-ai/dsh-fs' import type { FsInfo, FsTarget, FsWriteIntent } from '@deepseek-ai/dsh-fs' import { sandboxDenialMarker } from '@deepseek-ai/dsh-sandbox' diff --git a/packages/fs/tool-str-replace-editor/src/invariant.ts b/packages/fs/tool-str-replace-editor/src/invariant.ts index 99547c02ee..c2b6d8f149 100644 --- a/packages/fs/tool-str-replace-editor/src/invariant.ts +++ b/packages/fs/tool-str-replace-editor/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-tool-str-replace-editor' diff --git a/packages/fs/tool-str-replace-editor/tests/tools.spec.ts b/packages/fs/tool-str-replace-editor/tests/tools.spec.ts index db0fe8dc35..987f78b69b 100644 --- a/packages/fs/tool-str-replace-editor/tests/tools.spec.ts +++ b/packages/fs/tool-str-replace-editor/tests/tools.spec.ts @@ -2,7 +2,7 @@ import { mkdtemp, mkdir, readFile, rm, writeFile } from 'node:fs/promises' import { tmpdir } from 'node:os' import { join } from 'node:path' import { afterEach, describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { FsVersion } from '@deepseek-ai/dsh-fs' import { CallId } from '@deepseek-ai/dsh-llm' import { Session, SessionId } from '@deepseek-ai/dsh-session' diff --git a/packages/goal/command-goal/package.json b/packages/goal/command-goal/package.json index 7313daa4af..daf1ebf924 100644 --- a/packages/goal/command-goal/package.json +++ b/packages/goal/command-goal/package.json @@ -28,16 +28,16 @@ "@deepseek-ai/dsh-commands": "^0.0.1", "@deepseek-ai/dsh-goal": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { - "@cordisjs/plugin-loader": "workspace:^", + "@deepseek-ai/cordis-plugin-loader": "workspace:^", "@deepseek-ai/dsh-agent": "workspace:^", "@deepseek-ai/dsh-commands": "workspace:^", "@deepseek-ai/dsh-goal": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-llm": "workspace:^", "@deepseek-ai/dsh-session": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/goal/command-goal/src/index.ts b/packages/goal/command-goal/src/index.ts index 93ed7923b8..38d18e2529 100644 --- a/packages/goal/command-goal/src/index.ts +++ b/packages/goal/command-goal/src/index.ts @@ -3,7 +3,7 @@ * @module @deepseek-ai/dsh-command-goal */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { CommandInvocation, CommandResult } from '@deepseek-ai/dsh-commands' import { GoalError } from '@deepseek-ai/dsh-goal' import type { GoalPhase, GoalRef, GoalView } from '@deepseek-ai/dsh-goal' diff --git a/packages/goal/command-goal/src/invariant.ts b/packages/goal/command-goal/src/invariant.ts index 795294b4e8..673d6a27ef 100644 --- a/packages/goal/command-goal/src/invariant.ts +++ b/packages/goal/command-goal/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-command-goal' diff --git a/packages/goal/command-goal/tests/command-goal.spec.ts b/packages/goal/command-goal/tests/command-goal.spec.ts index 03bf965fd6..9479859e7d 100644 --- a/packages/goal/command-goal/tests/command-goal.spec.ts +++ b/packages/goal/command-goal/tests/command-goal.spec.ts @@ -1,6 +1,6 @@ import { describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' -import Loader from '@cordisjs/plugin-loader' +import { Context } from '@deepseek-ai/cordis' +import Loader from '@deepseek-ai/cordis-plugin-loader' import AgentRegistry, { Inbox } from '@deepseek-ai/dsh-agent' import type { Agent, AgentStatus } from '@deepseek-ai/dsh-agent' import CommandService from '@deepseek-ai/dsh-commands' diff --git a/packages/goal/goal-session/package.json b/packages/goal/goal-session/package.json index 86b58f3cda..bd315cb2c1 100644 --- a/packages/goal/goal-session/package.json +++ b/packages/goal/goal-session/package.json @@ -30,7 +30,7 @@ "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-llm": "^0.0.1", "@deepseek-ai/dsh-session": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-agent": "workspace:^", @@ -42,6 +42,6 @@ "@deepseek-ai/dsh-session": "workspace:^", "@deepseek-ai/dsh-system-prompt": "workspace:^", "@deepseek-ai/dsh-tools": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/goal/goal-session/src/index.ts b/packages/goal/goal-session/src/index.ts index 64c90e0c35..1d78dc5a50 100644 --- a/packages/goal/goal-session/src/index.ts +++ b/packages/goal/goal-session/src/index.ts @@ -4,8 +4,8 @@ */ import { isDeepStrictEqual } from 'node:util' -import { FiberState } from 'cordis' -import type { Context } from 'cordis' +import { FiberState } from '@deepseek-ai/cordis' +import type { Context } from '@deepseek-ai/cordis' import type { Agent, PreStepDecision } from '@deepseek-ai/dsh-agent' import type { GoalMessageSource, GoalRef, GoalView } from '@deepseek-ai/dsh-goal' import { createUserMessage } from '@deepseek-ai/dsh-llm' diff --git a/packages/goal/goal-session/src/invariant.ts b/packages/goal/goal-session/src/invariant.ts index 53cdd9b20b..121343dfff 100644 --- a/packages/goal/goal-session/src/invariant.ts +++ b/packages/goal/goal-session/src/invariant.ts @@ -1,7 +1,7 @@ /** Package-owned goal-round prompt invariants. @module @deepseek-ai/dsh-goal-session/invariant */ import { isDeepStrictEqual } from 'node:util' -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { foldGoal, type FoldedGoal, type GoalMessageSource, type GoalView } from '@deepseek-ai/dsh-goal' import type { InvariantFailure, InvariantInstaller } from '@deepseek-ai/dsh-invariants' import type { Session, SessionEvent } from '@deepseek-ai/dsh-session' diff --git a/packages/goal/goal-session/tests/goal-session.spec.ts b/packages/goal/goal-session/tests/goal-session.spec.ts index 2d14abf158..1231e659c2 100644 --- a/packages/goal/goal-session/tests/goal-session.spec.ts +++ b/packages/goal/goal-session/tests/goal-session.spec.ts @@ -1,5 +1,5 @@ import { afterEach, describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import type { Agent, PreStepDecision } from '@deepseek-ai/dsh-agent' import { agentEvents } from '@deepseek-ai/dsh-agent' import AgentLoop from '@deepseek-ai/dsh-agent-loop' diff --git a/packages/goal/goal-session/tests/invariant.spec.ts b/packages/goal/goal-session/tests/invariant.spec.ts index 6baaa724da..76830591e3 100644 --- a/packages/goal/goal-session/tests/invariant.spec.ts +++ b/packages/goal/goal-session/tests/invariant.spec.ts @@ -1,6 +1,6 @@ import { createUserMessage } from '@deepseek-ai/dsh-llm' import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { GoalId, type GoalSnapshotChangeMeta, diff --git a/packages/goal/goal/package.json b/packages/goal/goal/package.json index fccf7de3be..32ca4d00d9 100644 --- a/packages/goal/goal/package.json +++ b/packages/goal/goal/package.json @@ -56,10 +56,10 @@ "@deepseek-ai/dsh-scope": "^0.0.1", "@deepseek-ai/dsh-session": "^0.0.1", "@deepseek-ai/dsh-type-meta": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { - "schemastery": "^3.17.2", + "@deepseek-ai/schemastery": "^3.17.2", "zod": "^4.4.3" }, "devDependencies": { @@ -72,6 +72,6 @@ "@deepseek-ai/dsh-scope": "workspace:^", "@deepseek-ai/dsh-session": "workspace:^", "@deepseek-ai/dsh-type-meta": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/goal/goal/src/domain.ts b/packages/goal/goal/src/domain.ts index 3dc5672f0b..63f1573dc7 100644 --- a/packages/goal/goal/src/domain.ts +++ b/packages/goal/goal/src/domain.ts @@ -101,7 +101,7 @@ export type GoalErrorCode = | 'GOAL_INVALID_EDIT' | 'GOAL_INVALID_TRANSITION' -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Events { /** * Goal mutation accepted by one live agent. The matching `goal/change` diff --git a/packages/goal/goal/src/index.ts b/packages/goal/goal/src/index.ts index 6667463d86..c4f5d70ee8 100644 --- a/packages/goal/goal/src/index.ts +++ b/packages/goal/goal/src/index.ts @@ -5,8 +5,8 @@ */ import { randomUUID } from 'node:crypto' -import { Context } from 'cordis' -import z from 'schemastery' +import { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import { z as zod } from 'zod' import type { ZodType } from 'zod' import { agentEvents } from '@deepseek-ai/dsh-agent' @@ -56,7 +56,7 @@ export type * from './domain.ts' export { GOAL_CHANGE_VERSION, GoalError, GoalId } from './runtime.ts' export { decodeGoalChange, foldGoal, goalChangeRef } from './fold.ts' -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { goals: GoalService } diff --git a/packages/goal/goal/src/invariant.ts b/packages/goal/goal/src/invariant.ts index 42c83c65f0..31ac8e2f67 100644 --- a/packages/goal/goal/src/invariant.ts +++ b/packages/goal/goal/src/invariant.ts @@ -1,6 +1,6 @@ /** Package-owned durable goal-stream invariants. @module @deepseek-ai/dsh-goal/invariant */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantFailure, InvariantInstaller } from '@deepseek-ai/dsh-invariants' import type { Session, SessionEvent } from '@deepseek-ai/dsh-session' import { applyGoalEvent, emptyGoalFoldState } from './fold.ts' diff --git a/packages/goal/goal/tests/goal.spec.ts b/packages/goal/goal/tests/goal.spec.ts index 0c0a8e8373..e94e0754a0 100644 --- a/packages/goal/goal/tests/goal.spec.ts +++ b/packages/goal/goal/tests/goal.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import AgentRegistry, { agentEvents, Inbox } from '@deepseek-ai/dsh-agent' import type { Agent } from '@deepseek-ai/dsh-agent' import { createUserMessage, HarnessError } from '@deepseek-ai/dsh-llm' diff --git a/packages/goal/goal/tests/invariant.spec.ts b/packages/goal/goal/tests/invariant.spec.ts index b342036f83..79d7f10704 100644 --- a/packages/goal/goal/tests/invariant.spec.ts +++ b/packages/goal/goal/tests/invariant.spec.ts @@ -1,6 +1,6 @@ import { createUserMessage } from '@deepseek-ai/dsh-llm' import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { GoalId, type GoalSnapshotChangeMeta, diff --git a/packages/goal/goal/tests/projection.spec.ts b/packages/goal/goal/tests/projection.spec.ts index 7dcab0dc40..6282a6f739 100644 --- a/packages/goal/goal/tests/projection.spec.ts +++ b/packages/goal/goal/tests/projection.spec.ts @@ -9,7 +9,7 @@ */ import { describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import AgentRegistry, { Inbox } from '@deepseek-ai/dsh-agent' import type { Agent, AgentStatus } from '@deepseek-ai/dsh-agent' import { createUserMessage } from '@deepseek-ai/dsh-llm' diff --git a/packages/goal/tool-goal/package.json b/packages/goal/tool-goal/package.json index c7c87e44db..0b03bb02b6 100644 --- a/packages/goal/tool-goal/package.json +++ b/packages/goal/tool-goal/package.json @@ -32,13 +32,13 @@ "@deepseek-ai/dsh-session": "^0.0.1", "@deepseek-ai/dsh-system-prompt": "^0.0.1", "@deepseek-ai/dsh-tools": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { - "@cordisjs/plugin-loader": "workspace:^", + "@deepseek-ai/cordis-plugin-loader": "workspace:^", "@deepseek-ai/dsh-agent": "workspace:^", "@deepseek-ai/dsh-goal": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", @@ -46,6 +46,6 @@ "@deepseek-ai/dsh-session": "workspace:^", "@deepseek-ai/dsh-system-prompt": "workspace:^", "@deepseek-ai/dsh-tools": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/goal/tool-goal/src/authority.ts b/packages/goal/tool-goal/src/authority.ts index ad0fe9affd..1fdfbc740a 100644 --- a/packages/goal/tool-goal/src/authority.ts +++ b/packages/goal/tool-goal/src/authority.ts @@ -1,6 +1,6 @@ /** Execution-time authority checks for the model-facing goal tools. */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { Agent } from '@deepseek-ai/dsh-agent' import type { GoalView } from '@deepseek-ai/dsh-goal' import { HarnessError } from '@deepseek-ai/dsh-llm' diff --git a/packages/goal/tool-goal/src/index.ts b/packages/goal/tool-goal/src/index.ts index d22ff26dc2..903190de4d 100644 --- a/packages/goal/tool-goal/src/index.ts +++ b/packages/goal/tool-goal/src/index.ts @@ -4,8 +4,8 @@ * @module @deepseek-ai/dsh-tool-goal */ -import type { Context } from 'cordis' -import z from 'schemastery' +import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import { GoalId } from '@deepseek-ai/dsh-goal' import type { GoalRef, GoalView } from '@deepseek-ai/dsh-goal' import { boundContextSummary, createUserMessage, HarnessError } from '@deepseek-ai/dsh-llm' diff --git a/packages/goal/tool-goal/src/invariant.ts b/packages/goal/tool-goal/src/invariant.ts index d3ea60f049..28b9637772 100644 --- a/packages/goal/tool-goal/src/invariant.ts +++ b/packages/goal/tool-goal/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-tool-goal' diff --git a/packages/goal/tool-goal/tests/tool-goal.spec.ts b/packages/goal/tool-goal/tests/tool-goal.spec.ts index d8bc950019..71469bc5c6 100644 --- a/packages/goal/tool-goal/tests/tool-goal.spec.ts +++ b/packages/goal/tool-goal/tests/tool-goal.spec.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' -import Loader from '@cordisjs/plugin-loader' +import { Context } from '@deepseek-ai/cordis' +import Loader from '@deepseek-ai/cordis-plugin-loader' import AgentRegistry, { agentEvents, Inbox } from '@deepseek-ai/dsh-agent' import type { Agent, AgentStatus } from '@deepseek-ai/dsh-agent' import GoalService, { GoalId } from '@deepseek-ai/dsh-goal' diff --git a/packages/guard/repeat-tool-guard/package.json b/packages/guard/repeat-tool-guard/package.json index 9978865a5d..9bc4fd493f 100644 --- a/packages/guard/repeat-tool-guard/package.json +++ b/packages/guard/repeat-tool-guard/package.json @@ -25,13 +25,13 @@ ], "license": "BSD-3-Clause", "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "peerDependencies": { "@deepseek-ai/dsh-agent": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-tools": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-agent": "workspace:^", @@ -41,6 +41,6 @@ "@deepseek-ai/dsh-llm": "workspace:^", "@deepseek-ai/dsh-session": "workspace:^", "@deepseek-ai/dsh-tools": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/guard/repeat-tool-guard/src/index.ts b/packages/guard/repeat-tool-guard/src/index.ts index 464dd318da..efc3914592 100644 --- a/packages/guard/repeat-tool-guard/src/index.ts +++ b/packages/guard/repeat-tool-guard/src/index.ts @@ -6,8 +6,8 @@ * @module @deepseek-ai/dsh-repeat-tool-guard */ -import type { Context } from 'cordis' -import z from 'schemastery' +import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import type { Agent, PreStepDecision } from '@deepseek-ai/dsh-agent' import { createUserMessage } from '@deepseek-ai/dsh-llm' import type { MessageSource } from '@deepseek-ai/dsh-llm' diff --git a/packages/guard/repeat-tool-guard/src/invariant.ts b/packages/guard/repeat-tool-guard/src/invariant.ts index 5d8544b9aa..29363695a2 100644 --- a/packages/guard/repeat-tool-guard/src/invariant.ts +++ b/packages/guard/repeat-tool-guard/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-repeat-tool-guard' diff --git a/packages/guard/repeat-tool-guard/tests/repeat-tool-guard.spec.ts b/packages/guard/repeat-tool-guard/tests/repeat-tool-guard.spec.ts index 20cd9a0104..a8eda4cf4c 100644 --- a/packages/guard/repeat-tool-guard/tests/repeat-tool-guard.spec.ts +++ b/packages/guard/repeat-tool-guard/tests/repeat-tool-guard.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { createUserMessage, CallId } from '@deepseek-ai/dsh-llm' import { SessionId, type SessionEvent } from '@deepseek-ai/dsh-session' import { defineContentToolFixture } from '@deepseek-ai/dsh-tools' diff --git a/packages/guard/timeout-policy/package.json b/packages/guard/timeout-policy/package.json index b77bd23716..3f56d8e59e 100644 --- a/packages/guard/timeout-policy/package.json +++ b/packages/guard/timeout-policy/package.json @@ -29,13 +29,13 @@ "@deepseek-ai/dsh-llm": "^0.0.1", "@deepseek-ai/dsh-timeout": "^0.0.1", "@deepseek-ai/dsh-tools": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-llm": "workspace:^", "@deepseek-ai/dsh-timeout": "workspace:^", "@deepseek-ai/dsh-tools": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/guard/timeout-policy/src/index.ts b/packages/guard/timeout-policy/src/index.ts index 1ff88b46a9..11c8f986d7 100644 --- a/packages/guard/timeout-policy/src/index.ts +++ b/packages/guard/timeout-policy/src/index.ts @@ -11,7 +11,7 @@ * @module @deepseek-ai/dsh-timeout-policy */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { deadline, timeoutOf } from '@deepseek-ai/dsh-timeout' import type { ToolExecutionResult } from '@deepseek-ai/dsh-tools' diff --git a/packages/guard/timeout-policy/src/invariant.ts b/packages/guard/timeout-policy/src/invariant.ts index ddc3b3966e..ef2a25e6ae 100644 --- a/packages/guard/timeout-policy/src/invariant.ts +++ b/packages/guard/timeout-policy/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-timeout-policy' diff --git a/packages/guard/timeout-policy/tests/timeout-policy.spec.ts b/packages/guard/timeout-policy/tests/timeout-policy.spec.ts index c2d55d044c..cd8085785b 100644 --- a/packages/guard/timeout-policy/tests/timeout-policy.spec.ts +++ b/packages/guard/timeout-policy/tests/timeout-policy.spec.ts @@ -7,8 +7,8 @@ */ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' -import Loader from '@cordisjs/plugin-loader' +import { Context } from '@deepseek-ai/cordis' +import Loader from '@deepseek-ai/cordis-plugin-loader' import { CallId, HarnessError } from '@deepseek-ai/dsh-llm' import SystemPrompt from '@deepseek-ai/dsh-system-prompt' import ToolRegistry, { defineContentToolFixture, TOOL_ABORTED, type ToolExecutionInput, type PostToolDecision } from '@deepseek-ai/dsh-tools' diff --git a/packages/hooks/hook-protocol/package.json b/packages/hooks/hook-protocol/package.json index 0e35d83513..670cd4df5d 100644 --- a/packages/hooks/hook-protocol/package.json +++ b/packages/hooks/hook-protocol/package.json @@ -28,12 +28,12 @@ "@deepseek-ai/dsh-bash": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-session": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-bash": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-session": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/hooks/hook-protocol/src/invariant.ts b/packages/hooks/hook-protocol/src/invariant.ts index 8a7c7338c3..d4a36dc9f1 100644 --- a/packages/hooks/hook-protocol/src/invariant.ts +++ b/packages/hooks/hook-protocol/src/invariant.ts @@ -1,6 +1,6 @@ /** Package-owned hook invocation/result stream invariants. @module @deepseek-ai/dsh-hook-protocol/invariant */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { Session, SessionEvent } from '@deepseek-ai/dsh-session' import type { InvariantFailure, InvariantInstaller } from '@deepseek-ai/dsh-invariants' import type {} from './types.ts' diff --git a/packages/hooks/hook-protocol/tests/invariant.spec.ts b/packages/hooks/hook-protocol/tests/invariant.spec.ts index 94e5b57847..9ec212e5de 100644 --- a/packages/hooks/hook-protocol/tests/invariant.spec.ts +++ b/packages/hooks/hook-protocol/tests/invariant.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import SessionStore, { Session, SessionId } from '@deepseek-ai/dsh-session' import * as HookInvariant from '@deepseek-ai/dsh-hook-protocol/invariant' import InvariantService from '@deepseek-ai/dsh-invariants' diff --git a/packages/hooks/hooks-claude/package.json b/packages/hooks/hooks-claude/package.json index cce1d3edb9..2af6a96466 100644 --- a/packages/hooks/hooks-claude/package.json +++ b/packages/hooks/hooks-claude/package.json @@ -25,7 +25,7 @@ ], "license": "BSD-3-Clause", "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "peerDependencies": { "@deepseek-ai/dsh-agent": "^0.0.1", @@ -36,7 +36,7 @@ "@deepseek-ai/dsh-session-persistence": "^0.0.1", "@deepseek-ai/dsh-subagent": "^0.0.1", "@deepseek-ai/dsh-tools": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-agent": "workspace:^", @@ -53,6 +53,6 @@ "@deepseek-ai/dsh-session-persistence-jsonl": "workspace:^", "@deepseek-ai/dsh-subagent": "workspace:^", "@deepseek-ai/dsh-tools": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/hooks/hooks-claude/src/index.ts b/packages/hooks/hooks-claude/src/index.ts index cb86d86c92..ae28cf00a0 100644 --- a/packages/hooks/hooks-claude/src/index.ts +++ b/packages/hooks/hooks-claude/src/index.ts @@ -10,8 +10,8 @@ */ import { readFileSync } from 'node:fs' -import type { Context } from 'cordis' -import z from 'schemastery' +import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import type { Agent, PreStepDecision } from '@deepseek-ai/dsh-agent' import { createUserMessage } from '@deepseek-ai/dsh-llm' import type { ContentBlock, MessageSource } from '@deepseek-ai/dsh-llm' diff --git a/packages/hooks/hooks-claude/src/invariant.ts b/packages/hooks/hooks-claude/src/invariant.ts index d7908419d4..cdf3fb3ec3 100644 --- a/packages/hooks/hooks-claude/src/invariant.ts +++ b/packages/hooks/hooks-claude/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-hooks-claude' diff --git a/packages/hooks/hooks-claude/tests/bridge.spec.ts b/packages/hooks/hooks-claude/tests/bridge.spec.ts index 244abae423..86b2692493 100644 --- a/packages/hooks/hooks-claude/tests/bridge.spec.ts +++ b/packages/hooks/hooks-claude/tests/bridge.spec.ts @@ -3,8 +3,8 @@ import { afterEach, describe, expect, it, vi } from 'vitest' import { chmodSync, existsSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs' import { tmpdir } from 'node:os' import { join } from 'node:path' -import { Context, type Fiber } from 'cordis' -import Loader from '@cordisjs/plugin-loader' +import { Context, type Fiber } from '@deepseek-ai/cordis' +import Loader from '@deepseek-ai/cordis-plugin-loader' import { SessionId, type SessionEvent } from '@deepseek-ai/dsh-session' import { defineContentToolFixture } from '@deepseek-ai/dsh-tools' import type { Agent } from '@deepseek-ai/dsh-agent' diff --git a/packages/hooks/hooks-claude/tests/coverage-cases.ts b/packages/hooks/hooks-claude/tests/coverage-cases.ts index c82f0320f3..9411248d22 100644 --- a/packages/hooks/hooks-claude/tests/coverage-cases.ts +++ b/packages/hooks/hooks-claude/tests/coverage-cases.ts @@ -3,7 +3,7 @@ import { afterEach, describe, expect, it, vi } from 'vitest' import { mkdtempSync, rmSync, writeFileSync, chmodSync, existsSync, readFileSync } from 'node:fs' import { tmpdir } from 'node:os' import { join } from 'node:path' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { SessionId, type SessionEvent } from '@deepseek-ai/dsh-session' import SessionPersistenceJsonl from '@deepseek-ai/dsh-session-persistence-jsonl' import { defineContentToolFixture } from '@deepseek-ai/dsh-tools' diff --git a/packages/hooks/hooks-codex/package.json b/packages/hooks/hooks-codex/package.json index 078b58fb08..37ac4d7bed 100644 --- a/packages/hooks/hooks-codex/package.json +++ b/packages/hooks/hooks-codex/package.json @@ -25,7 +25,7 @@ ], "license": "BSD-3-Clause", "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "peerDependencies": { "@deepseek-ai/dsh-agent": "^0.0.1", @@ -35,7 +35,7 @@ "@deepseek-ai/dsh-session": "^0.0.1", "@deepseek-ai/dsh-session-persistence": "^0.0.1", "@deepseek-ai/dsh-tools": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-agent": "workspace:^", @@ -51,6 +51,6 @@ "@deepseek-ai/dsh-session-persistence": "workspace:^", "@deepseek-ai/dsh-session-persistence-jsonl": "workspace:^", "@deepseek-ai/dsh-tools": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/hooks/hooks-codex/src/index.ts b/packages/hooks/hooks-codex/src/index.ts index d31d9f8c48..3b7d0d7a40 100644 --- a/packages/hooks/hooks-codex/src/index.ts +++ b/packages/hooks/hooks-codex/src/index.ts @@ -13,8 +13,8 @@ // point; a cross-package facade for imports alone would add indirection. /* jscpd:ignore-start */ import { readFileSync } from 'node:fs' -import type { Context } from 'cordis' -import z from 'schemastery' +import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import type { Agent, PreStepDecision } from '@deepseek-ai/dsh-agent' import { createUserMessage } from '@deepseek-ai/dsh-llm' import type { ContentBlock, MessageSource } from '@deepseek-ai/dsh-llm' diff --git a/packages/hooks/hooks-codex/src/invariant.ts b/packages/hooks/hooks-codex/src/invariant.ts index c3eacb7ab0..5d19efb7b0 100644 --- a/packages/hooks/hooks-codex/src/invariant.ts +++ b/packages/hooks/hooks-codex/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-hooks-codex' diff --git a/packages/hooks/hooks-codex/tests/bridge.spec.ts b/packages/hooks/hooks-codex/tests/bridge.spec.ts index 0878397edd..cdfbe2c594 100644 --- a/packages/hooks/hooks-codex/tests/bridge.spec.ts +++ b/packages/hooks/hooks-codex/tests/bridge.spec.ts @@ -3,8 +3,8 @@ import { afterEach, describe, expect, it, vi } from 'vitest' import { chmodSync, existsSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs' import { tmpdir } from 'node:os' import { join } from 'node:path' -import { Context } from 'cordis' -import Loader from '@cordisjs/plugin-loader' +import { Context } from '@deepseek-ai/cordis' +import Loader from '@deepseek-ai/cordis-plugin-loader' import { SessionId, type SessionEvent } from '@deepseek-ai/dsh-session' import { defineContentToolFixture } from '@deepseek-ai/dsh-tools' import type { Agent } from '@deepseek-ai/dsh-agent' diff --git a/packages/hooks/hooks-codex/tests/coverage-cases.ts b/packages/hooks/hooks-codex/tests/coverage-cases.ts index d92ea597bd..8690af565e 100644 --- a/packages/hooks/hooks-codex/tests/coverage-cases.ts +++ b/packages/hooks/hooks-codex/tests/coverage-cases.ts @@ -3,7 +3,7 @@ import { afterEach, describe, expect, it, vi } from 'vitest' import { mkdtempSync, rmSync, writeFileSync, chmodSync, existsSync, readFileSync } from 'node:fs' import { tmpdir } from 'node:os' import { join } from 'node:path' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { SessionId, type SessionEvent } from '@deepseek-ai/dsh-session' import SessionPersistenceJsonl from '@deepseek-ai/dsh-session-persistence-jsonl' import { defineContentToolFixture } from '@deepseek-ai/dsh-tools' diff --git a/packages/host/apiproxy/package.json b/packages/host/apiproxy/package.json index 42f69c6211..5ce28e9d05 100644 --- a/packages/host/apiproxy/package.json +++ b/packages/host/apiproxy/package.json @@ -62,13 +62,13 @@ "@deepseek-ai/dsh-user-approval": "workspace:^", "@deepseek-ai/dsh-user-interaction": "workspace:^", "@deepseek-ai/dsh-workspace": "workspace:^", - "schemastery": "^3.18.0", + "@deepseek-ai/schemastery": "^3.18.0", "zod": "^4.4.3" }, "peerDependencies": { "@deepseek-ai/dsh-agent-presets": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-agent-presets": "workspace:^", @@ -77,6 +77,6 @@ "@deepseek-ai/dsh-storage-domain": "workspace:^", "@deepseek-ai/dsh-type-meta": "workspace:^", "@deepseek-ai/dsh-typert-registry": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/host/apiproxy/src/api-proxy.ts b/packages/host/apiproxy/src/api-proxy.ts index 3626ef9960..ea41122cc9 100644 --- a/packages/host/apiproxy/src/api-proxy.ts +++ b/packages/host/apiproxy/src/api-proxy.ts @@ -6,7 +6,7 @@ import { randomUUID } from 'node:crypto' import { mkdir, stat } from 'node:fs/promises' import { dirname } from 'node:path' -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { installModelSelection } from '@deepseek-ai/dsh-agent' import type { Agent, ModelSelection, ModelSelectionRef, AgentOptions, AgentStatus } from '@deepseek-ai/dsh-agent' import { AGENT_DEFAULT_MODEL_SETTINGS_NAMESPACE } from '@deepseek-ai/dsh-agent-default-model' diff --git a/packages/host/apiproxy/src/index.ts b/packages/host/apiproxy/src/index.ts index 43ce9e2df4..9290005a52 100644 --- a/packages/host/apiproxy/src/index.ts +++ b/packages/host/apiproxy/src/index.ts @@ -12,8 +12,8 @@ * service; sessions that have already logged a selection remain unchanged. */ -import { Context, Service } from 'cordis' -import z from 'schemastery' +import { Context, Service } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import type {} from '@deepseek-ai/dsh-agent-default-model' import type { ApiProxy } from './api/index.ts' import { createApiProxy } from './api-proxy.ts' @@ -26,7 +26,7 @@ export type { IApiClient } from './fetch/client.ts' export { createApiProxy } from './api-proxy.ts' export type { ApiProxyDefaults } from './api-proxy.ts' -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { /** The host-side ApiProxy implementation (the transport-agnostic gateway face). */ apiProxy: ApiProxy diff --git a/packages/host/apiproxy/src/invariant.ts b/packages/host/apiproxy/src/invariant.ts index a96b5d081d..ac21250e90 100644 --- a/packages/host/apiproxy/src/invariant.ts +++ b/packages/host/apiproxy/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-host-apiproxy' diff --git a/packages/host/apiproxy/tests/api-proxy-agent-preset.spec.ts b/packages/host/apiproxy/tests/api-proxy-agent-preset.spec.ts index 106cb213da..d1bfaba00d 100644 --- a/packages/host/apiproxy/tests/api-proxy-agent-preset.spec.ts +++ b/packages/host/apiproxy/tests/api-proxy-agent-preset.spec.ts @@ -8,7 +8,7 @@ import { mkdtempSync, realpathSync } from 'node:fs' import { tmpdir } from 'node:os' import { join } from 'node:path' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import AgentRegistry, { type AgentFactory } from '@deepseek-ai/dsh-agent' import type { Agent } from '@deepseek-ai/dsh-agent' import SessionStore, { SessionId, type Session } from '@deepseek-ai/dsh-session' diff --git a/packages/host/apiproxy/tests/api-proxy-approval.spec.ts b/packages/host/apiproxy/tests/api-proxy-approval.spec.ts index 1cee4cd4e0..8aaa44564b 100644 --- a/packages/host/apiproxy/tests/api-proxy-approval.spec.ts +++ b/packages/host/apiproxy/tests/api-proxy-approval.spec.ts @@ -7,7 +7,7 @@ */ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import AgentRegistry from '@deepseek-ai/dsh-agent' import type { Agent } from '@deepseek-ai/dsh-agent' import SessionStore from '@deepseek-ai/dsh-session' diff --git a/packages/host/apiproxy/tests/api-proxy-blank.spec.ts b/packages/host/apiproxy/tests/api-proxy-blank.spec.ts index e01282043b..066c47f376 100644 --- a/packages/host/apiproxy/tests/api-proxy-blank.spec.ts +++ b/packages/host/apiproxy/tests/api-proxy-blank.spec.ts @@ -8,7 +8,7 @@ */ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import AgentRegistry from '@deepseek-ai/dsh-agent' import type { Agent } from '@deepseek-ai/dsh-agent' import SessionStore from '@deepseek-ai/dsh-session' diff --git a/packages/host/apiproxy/tests/api-proxy-cold.spec.ts b/packages/host/apiproxy/tests/api-proxy-cold.spec.ts index 78c748861a..126ce506b8 100644 --- a/packages/host/apiproxy/tests/api-proxy-cold.spec.ts +++ b/packages/host/apiproxy/tests/api-proxy-cold.spec.ts @@ -8,7 +8,7 @@ import { mkdtempSync, writeFileSync, utimesSync } from 'node:fs' import { tmpdir } from 'node:os' import { join } from 'node:path' import { describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import SessionStore from '@deepseek-ai/dsh-session' import AgentRegistry from '@deepseek-ai/dsh-agent' import { TypeRTLookupFailure } from '@deepseek-ai/dsh-type-meta' diff --git a/packages/host/apiproxy/tests/api-proxy-commands.spec.ts b/packages/host/apiproxy/tests/api-proxy-commands.spec.ts index 5f0af7cc5c..038c1050f7 100644 --- a/packages/host/apiproxy/tests/api-proxy-commands.spec.ts +++ b/packages/host/apiproxy/tests/api-proxy-commands.spec.ts @@ -10,7 +10,7 @@ import { MessageId, freezeMessage } from '@deepseek-ai/dsh-llm' */ import { describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import AgentRegistry, { Inbox } from '@deepseek-ai/dsh-agent' import type { Agent } from '@deepseek-ai/dsh-agent' import SessionStore from '@deepseek-ai/dsh-session' diff --git a/packages/host/apiproxy/tests/api-proxy-config.spec.ts b/packages/host/apiproxy/tests/api-proxy-config.spec.ts index b8b067cae3..286a6d3f4f 100644 --- a/packages/host/apiproxy/tests/api-proxy-config.spec.ts +++ b/packages/host/apiproxy/tests/api-proxy-config.spec.ts @@ -6,8 +6,8 @@ */ import { describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' -import z from 'schemastery' +import { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import AgentRegistry from '@deepseek-ai/dsh-agent' import SessionStore from '@deepseek-ai/dsh-session' import SystemPrompt from '@deepseek-ai/dsh-system-prompt' diff --git a/packages/host/apiproxy/tests/api-proxy-fork.spec.ts b/packages/host/apiproxy/tests/api-proxy-fork.spec.ts index d1bf611fbb..e1d4dc5aa4 100644 --- a/packages/host/apiproxy/tests/api-proxy-fork.spec.ts +++ b/packages/host/apiproxy/tests/api-proxy-fork.spec.ts @@ -1,7 +1,7 @@ /** Session-fork boundaries, lineage, and inherited model routing. */ import { describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import AgentRegistry, { agentEvents } from '@deepseek-ai/dsh-agent' import type { Agent, AgentHandle, CreateAgentOptions } from '@deepseek-ai/dsh-agent' import { createUserMessage, ReasoningEffortId } from '@deepseek-ai/dsh-llm' diff --git a/packages/host/apiproxy/tests/api-proxy-models.spec.ts b/packages/host/apiproxy/tests/api-proxy-models.spec.ts index bdd21128b4..335b8b795f 100644 --- a/packages/host/apiproxy/tests/api-proxy-models.spec.ts +++ b/packages/host/apiproxy/tests/api-proxy-models.spec.ts @@ -6,7 +6,7 @@ */ import { describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import AgentRegistry, { agentEvents } from '@deepseek-ai/dsh-agent' import type { Agent } from '@deepseek-ai/dsh-agent' import LlmService, { LlmAdapter, ReasoningEffortId } from '@deepseek-ai/dsh-llm' diff --git a/packages/host/apiproxy/tests/api-proxy-projections.spec.ts b/packages/host/apiproxy/tests/api-proxy-projections.spec.ts index 45335e131b..a3a8867291 100644 --- a/packages/host/apiproxy/tests/api-proxy-projections.spec.ts +++ b/packages/host/apiproxy/tests/api-proxy-projections.spec.ts @@ -8,7 +8,7 @@ */ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { z } from 'zod' import AgentRegistry, { Inbox } from '@deepseek-ai/dsh-agent' import type { Agent } from '@deepseek-ai/dsh-agent' diff --git a/packages/host/apiproxy/tests/api-proxy-question.spec.ts b/packages/host/apiproxy/tests/api-proxy-question.spec.ts index 2ca7a31d12..fed6a5435e 100644 --- a/packages/host/apiproxy/tests/api-proxy-question.spec.ts +++ b/packages/host/apiproxy/tests/api-proxy-question.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import AgentRegistry, { type Agent } from '@deepseek-ai/dsh-agent' import SessionStore from '@deepseek-ai/dsh-session' import UserInteractionService from '@deepseek-ai/dsh-user-interaction' diff --git a/packages/host/apiproxy/tests/api-proxy-rename.spec.ts b/packages/host/apiproxy/tests/api-proxy-rename.spec.ts index 346ed9f313..bf2a7e3ba0 100644 --- a/packages/host/apiproxy/tests/api-proxy-rename.spec.ts +++ b/packages/host/apiproxy/tests/api-proxy-rename.spec.ts @@ -8,7 +8,7 @@ */ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import SessionStore from '@deepseek-ai/dsh-session' import AgentRegistry from '@deepseek-ai/dsh-agent' import type { Agent, AgentHandle, CreateAgentOptions } from '@deepseek-ai/dsh-agent' diff --git a/packages/host/apiproxy/tests/api-proxy-search.spec.ts b/packages/host/apiproxy/tests/api-proxy-search.spec.ts index 7637399f50..c945020eb1 100644 --- a/packages/host/apiproxy/tests/api-proxy-search.spec.ts +++ b/packages/host/apiproxy/tests/api-proxy-search.spec.ts @@ -5,7 +5,7 @@ */ import { describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { stat } from 'node:fs/promises' import AgentRegistry from '@deepseek-ai/dsh-agent' import { createUserMessage } from '@deepseek-ai/dsh-llm' diff --git a/packages/host/apiproxy/tests/api-proxy-subagents.spec.ts b/packages/host/apiproxy/tests/api-proxy-subagents.spec.ts index eb39bb6791..02f194eede 100644 --- a/packages/host/apiproxy/tests/api-proxy-subagents.spec.ts +++ b/packages/host/apiproxy/tests/api-proxy-subagents.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import type { SessionEvent, SessionHeader, SessionId } from '@deepseek-ai/dsh-session' import { SubagentError } from '@deepseek-ai/dsh-subagent' import { RpcId } from '../src/api/rpc.ts' diff --git a/packages/host/apiproxy/tests/api-proxy-view.spec.ts b/packages/host/apiproxy/tests/api-proxy-view.spec.ts index 86fb593f4b..eabac2056b 100644 --- a/packages/host/apiproxy/tests/api-proxy-view.spec.ts +++ b/packages/host/apiproxy/tests/api-proxy-view.spec.ts @@ -8,7 +8,7 @@ */ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import AgentRegistry from '@deepseek-ai/dsh-agent' import type { Agent } from '@deepseek-ai/dsh-agent' import SessionStore from '@deepseek-ai/dsh-session' diff --git a/packages/host/apiproxy/tests/api-proxy-workspace.spec.ts b/packages/host/apiproxy/tests/api-proxy-workspace.spec.ts index ddb53cf02f..a8f12641da 100644 --- a/packages/host/apiproxy/tests/api-proxy-workspace.spec.ts +++ b/packages/host/apiproxy/tests/api-proxy-workspace.spec.ts @@ -2,7 +2,7 @@ import { existsSync, mkdirSync, mkdtempSync, realpathSync } from 'node:fs' import { tmpdir } from 'node:os' import { join } from 'node:path' import { describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import AgentRegistry, { Inbox } from '@deepseek-ai/dsh-agent' import type { Agent, AgentFactory } from '@deepseek-ai/dsh-agent' import SessionStore, { SessionId } from '@deepseek-ai/dsh-session' diff --git a/packages/host/directory-picker-auto/package.json b/packages/host/directory-picker-auto/package.json index 753f83845a..b5e5164500 100644 --- a/packages/host/directory-picker-auto/package.json +++ b/packages/host/directory-picker-auto/package.json @@ -25,21 +25,21 @@ ], "license": "BSD-3-Clause", "peerDependencies": { - "@cordisjs/plugin-loader": "^1.0.0-rc.5", + "@deepseek-ai/cordis-plugin-loader": "^1.0.0-rc.5", "@deepseek-ai/dsh-host-directory-picker-browse": "^0.0.1", "@deepseek-ai/dsh-host-directory-picker-native": "^0.0.1", "@deepseek-ai/dsh-host-webserver": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { - "@cordisjs/plugin-include": "workspace:^", - "@cordisjs/plugin-loader": "workspace:^", + "@deepseek-ai/cordis-plugin-include": "workspace:^", + "@deepseek-ai/cordis-plugin-loader": "workspace:^", "@deepseek-ai/dsh-host-directory-picker": "workspace:^", "@deepseek-ai/dsh-host-directory-picker-browse": "workspace:^", "@deepseek-ai/dsh-host-directory-picker-native": "workspace:^", "@deepseek-ai/dsh-host-webserver": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/host/directory-picker-auto/src/index.ts b/packages/host/directory-picker-auto/src/index.ts index 3cf75b20dc..91343463fd 100644 --- a/packages/host/directory-picker-auto/src/index.ts +++ b/packages/host/directory-picker-auto/src/index.ts @@ -10,9 +10,9 @@ * @module @deepseek-ai/dsh-host-directory-picker-auto */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' // Empty type imports carry the `loader` and `httpServer` Context merges for the reads below. -import type {} from '@cordisjs/plugin-loader' +import type {} from '@deepseek-ai/cordis-plugin-loader' import type {} from '@deepseek-ai/dsh-host-webserver' import { canExecute, hasLinuxChooserBinary } from './probe.ts' import type { DirectoryPickerBackendKind } from './resolve.ts' diff --git a/packages/host/directory-picker-auto/src/invariant.ts b/packages/host/directory-picker-auto/src/invariant.ts index 8b3f251447..c31102a752 100644 --- a/packages/host/directory-picker-auto/src/invariant.ts +++ b/packages/host/directory-picker-auto/src/invariant.ts @@ -3,7 +3,7 @@ * @module @deepseek-ai/dsh-host-directory-picker-auto/invariant */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-host-directory-picker-auto' diff --git a/packages/host/directory-picker-auto/tests/loader-composition.spec.ts b/packages/host/directory-picker-auto/tests/loader-composition.spec.ts index 2ab50d6e80..ed9bfd1e44 100644 --- a/packages/host/directory-picker-auto/tests/loader-composition.spec.ts +++ b/packages/host/directory-picker-auto/tests/loader-composition.spec.ts @@ -13,9 +13,9 @@ import { tmpdir } from 'node:os' import { join } from 'node:path' import { pathToFileURL } from 'node:url' import { afterEach, describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' -import Loader from '@cordisjs/plugin-loader' -import Include from '@cordisjs/plugin-include' +import { Context } from '@deepseek-ai/cordis' +import Loader from '@deepseek-ai/cordis-plugin-loader' +import Include from '@deepseek-ai/cordis-plugin-include' import HttpServer from '@deepseek-ai/dsh-host-webserver' import type { DirectoryPicker } from '@deepseek-ai/dsh-host-directory-picker' import BrowseDirectoryPicker from '@deepseek-ai/dsh-host-directory-picker-browse' diff --git a/packages/host/directory-picker-browse/package.json b/packages/host/directory-picker-browse/package.json index 85256ef7dc..04078b9ea7 100644 --- a/packages/host/directory-picker-browse/package.json +++ b/packages/host/directory-picker-browse/package.json @@ -32,7 +32,7 @@ "dependencies": { "@deepseek-ai/dsh-host-directory-picker": "workspace:^", "clsx": "^2.0.0", - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "peerDependencies": { "@deepseek-ai/dsh-client-locale": "^0.0.1", @@ -41,7 +41,7 @@ "@deepseek-ai/dsh-client-ui-slots": "^0.0.1", "@deepseek-ai/dsh-client-ui-workspace": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.7", + "@deepseek-ai/cordis": "^4.0.0-rc.7", "react": "^18.2.0" }, "devDependencies": { @@ -53,7 +53,7 @@ "@deepseek-ai/dsh-client-ui-workspace": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", "@types/react": "~18.3.1", - "cordis": "^4.0.0-rc.7", + "@deepseek-ai/cordis": "^4.0.0-rc.7", "react": "^18.2.0" }, "dsh": { diff --git a/packages/host/directory-picker-browse/src/index.ts b/packages/host/directory-picker-browse/src/index.ts index e84f51b26a..adbe6d09ad 100644 --- a/packages/host/directory-picker-browse/src/index.ts +++ b/packages/host/directory-picker-browse/src/index.ts @@ -12,8 +12,8 @@ import { mkdir, opendir, stat } from 'node:fs/promises' import { homedir } from 'node:os' import { basename, dirname, join, posix, resolve, win32 } from 'node:path' -import type { Context } from 'cordis' -import z from 'schemastery' +import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import { DirectoryPicker, DirectoryPickerError, } from '@deepseek-ai/dsh-host-directory-picker' diff --git a/packages/host/directory-picker-browse/src/invariant.ts b/packages/host/directory-picker-browse/src/invariant.ts index ba4bfe7b13..7170de7809 100644 --- a/packages/host/directory-picker-browse/src/invariant.ts +++ b/packages/host/directory-picker-browse/src/invariant.ts @@ -3,7 +3,7 @@ * @module @deepseek-ai/dsh-host-directory-picker-browse/invariant */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-host-directory-picker-browse' diff --git a/packages/host/directory-picker-browse/tests/client-flow.spec.tsx b/packages/host/directory-picker-browse/tests/client-flow.spec.tsx index e7a07fb63a..69ea819564 100644 --- a/packages/host/directory-picker-browse/tests/client-flow.spec.tsx +++ b/packages/host/directory-picker-browse/tests/client-flow.spec.tsx @@ -1,5 +1,5 @@ // @vitest-environment jsdom -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { afterEach, describe, expect, it, vi } from 'vitest' import { cleanup, fireEvent, render, screen, waitFor } from '@testing-library/react' import { SlotsService } from '@deepseek-ai/dsh-client-runtime/client' diff --git a/packages/host/directory-picker-browse/tests/service.spec.ts b/packages/host/directory-picker-browse/tests/service.spec.ts index 002d42e516..a969845636 100644 --- a/packages/host/directory-picker-browse/tests/service.spec.ts +++ b/packages/host/directory-picker-browse/tests/service.spec.ts @@ -4,7 +4,7 @@ import { mkdir, mkdtemp, rm, symlink, writeFile } from 'node:fs/promises' import { homedir, tmpdir } from 'node:os' import { basename, join } from 'node:path' import { afterAll, beforeAll, describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { DirectoryPickerError } from '@deepseek-ai/dsh-host-directory-picker' import type { DirectoryPickerBrowseCapability } from '@deepseek-ai/dsh-host-directory-picker' import BrowseDirectoryPicker, { boundedInsert, fullyQualified, raceAbort } from '../src/index.ts' diff --git a/packages/host/directory-picker-native/package.json b/packages/host/directory-picker-native/package.json index c8e4e4003b..b725cd1001 100644 --- a/packages/host/directory-picker-native/package.json +++ b/packages/host/directory-picker-native/package.json @@ -44,7 +44,7 @@ "@deepseek-ai/dsh-client-ui-slots": "^0.0.1", "@deepseek-ai/dsh-client-ui-workspace": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.7", + "@deepseek-ai/cordis": "^4.0.0-rc.7", "react": "^18.2.0" }, "devDependencies": { @@ -53,7 +53,7 @@ "@deepseek-ai/dsh-client-ui-workspace": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", "@types/react": "~18.3.1", - "cordis": "^4.0.0-rc.7", + "@deepseek-ai/cordis": "^4.0.0-rc.7", "react": "^18.2.0", "tsx": "^4.19.2" }, diff --git a/packages/host/directory-picker-native/src/invariant.ts b/packages/host/directory-picker-native/src/invariant.ts index 777acd57dd..41b77ddb1c 100644 --- a/packages/host/directory-picker-native/src/invariant.ts +++ b/packages/host/directory-picker-native/src/invariant.ts @@ -3,7 +3,7 @@ * @module @deepseek-ai/dsh-host-directory-picker-native/invariant */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-host-directory-picker-native' diff --git a/packages/host/directory-picker-native/tests/client-flow.spec.tsx b/packages/host/directory-picker-native/tests/client-flow.spec.tsx index 34eb5e40b4..d501fdfce2 100644 --- a/packages/host/directory-picker-native/tests/client-flow.spec.tsx +++ b/packages/host/directory-picker-native/tests/client-flow.spec.tsx @@ -1,5 +1,5 @@ // @vitest-environment jsdom -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { describe, expect, it, vi } from 'vitest' import { act, cleanup, render } from '@testing-library/react' import { afterEach } from 'vitest' diff --git a/packages/host/directory-picker-native/tests/service.spec.ts b/packages/host/directory-picker-native/tests/service.spec.ts index 61b5adddaf..a05100f5cb 100644 --- a/packages/host/directory-picker-native/tests/service.spec.ts +++ b/packages/host/directory-picker-native/tests/service.spec.ts @@ -1,7 +1,7 @@ /** Registration/capability behavior of the native backend (the seam's cordis half). */ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import NativeDirectoryPicker from '../src/index.ts' describe('NativeDirectoryPicker', () => { diff --git a/packages/host/directory-picker/package.json b/packages/host/directory-picker/package.json index c37b67a4d7..c348021815 100644 --- a/packages/host/directory-picker/package.json +++ b/packages/host/directory-picker/package.json @@ -26,10 +26,10 @@ "license": "BSD-3-Clause", "peerDependencies": { "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-invariants": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/host/directory-picker/src/index.ts b/packages/host/directory-picker/src/index.ts index 4a0a831247..5e8eb64f87 100644 --- a/packages/host/directory-picker/src/index.ts +++ b/packages/host/directory-picker/src/index.ts @@ -11,7 +11,7 @@ * @module @deepseek-ai/dsh-host-directory-picker */ -import { Context, Service } from 'cordis' +import { Context, Service } from '@deepseek-ai/cordis' /** The native interaction: one OS directory chooser on the host display. */ export interface DirectoryPickerNativeCapability { @@ -115,7 +115,7 @@ export class DirectoryPickerError extends Error { } } -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { directoryPicker: DirectoryPicker } diff --git a/packages/host/directory-picker/src/invariant.ts b/packages/host/directory-picker/src/invariant.ts index 05638bd0cf..abf29856fc 100644 --- a/packages/host/directory-picker/src/invariant.ts +++ b/packages/host/directory-picker/src/invariant.ts @@ -1,6 +1,6 @@ /** Package-owned invariant companion for the directory-picker seam. @module @deepseek-ai/dsh-host-directory-picker/invariant */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-host-directory-picker' diff --git a/packages/host/directory-picker/tests/seam.spec.ts b/packages/host/directory-picker/tests/seam.spec.ts index 52722b9b0d..6fd6b48fa9 100644 --- a/packages/host/directory-picker/tests/seam.spec.ts +++ b/packages/host/directory-picker/tests/seam.spec.ts @@ -1,7 +1,7 @@ /** Contract behavior the seam itself owns: registration identity and typed failures. */ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { DirectoryPicker, DirectoryPickerError } from '../src/index.ts' import type { DirectoryPickerCapability } from '../src/index.ts' diff --git a/packages/host/frontend-static/package.json b/packages/host/frontend-static/package.json index ac690cee24..73414a5422 100644 --- a/packages/host/frontend-static/package.json +++ b/packages/host/frontend-static/package.json @@ -27,15 +27,15 @@ "peerDependencies": { "@deepseek-ai/dsh-host-webserver": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { - "@cordisjs/plugin-loader": "workspace:^", + "@deepseek-ai/cordis-plugin-loader": "workspace:^", "@deepseek-ai/dsh-host-webserver": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/host/frontend-static/src/index.ts b/packages/host/frontend-static/src/index.ts index 8bd5b829c1..d42cf59301 100644 --- a/packages/host/frontend-static/src/index.ts +++ b/packages/host/frontend-static/src/index.ts @@ -14,8 +14,8 @@ import type { ServerResponse } from 'node:http' import { readFile } from 'node:fs/promises' import { dirname, extname, join, normalize, resolve, sep } from 'node:path' -import type { Context } from 'cordis' -import z from 'schemastery' +import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import type {} from '@deepseek-ai/dsh-host-webserver' /** Stable Cordis plugin name. */ diff --git a/packages/host/frontend-static/src/invariant.ts b/packages/host/frontend-static/src/invariant.ts index 551daccbc8..567ff852ec 100644 --- a/packages/host/frontend-static/src/invariant.ts +++ b/packages/host/frontend-static/src/invariant.ts @@ -3,7 +3,7 @@ * @module @deepseek-ai/dsh-frontend-static/invariant */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-frontend-static' diff --git a/packages/host/frontend-static/tests/frontend-static.spec.ts b/packages/host/frontend-static/tests/frontend-static.spec.ts index 4f5fa0d2c7..16d75f88cd 100644 --- a/packages/host/frontend-static/tests/frontend-static.spec.ts +++ b/packages/host/frontend-static/tests/frontend-static.spec.ts @@ -11,9 +11,9 @@ import { tmpdir } from 'node:os' import { join } from 'node:path' import { pathToFileURL } from 'node:url' import { afterEach, describe, expect, it } from 'vitest' -import { Context } from 'cordis' -import Loader from '@cordisjs/plugin-loader' -import Include from '@cordisjs/plugin-include' +import { Context } from '@deepseek-ai/cordis' +import Loader from '@deepseek-ai/cordis-plugin-loader' +import Include from '@deepseek-ai/cordis-plugin-include' import HttpServer from '@deepseek-ai/dsh-host-webserver' import * as FrontendStatic from '../src/index.ts' diff --git a/packages/host/webserver/package.json b/packages/host/webserver/package.json index 4db9433935..e7a4b4cbf9 100644 --- a/packages/host/webserver/package.json +++ b/packages/host/webserver/package.json @@ -25,14 +25,14 @@ ], "license": "BSD-3-Clause", "peerDependencies": { - "cordis": "^4.0.0-rc.7", + "@deepseek-ai/cordis": "^4.0.0-rc.7", "@deepseek-ai/dsh-invariants": "^0.0.1" }, "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { - "cordis": "^4.0.0-rc.7", + "@deepseek-ai/cordis": "^4.0.0-rc.7", "@deepseek-ai/dsh-invariants": "workspace:^" } } diff --git a/packages/host/webserver/src/index.ts b/packages/host/webserver/src/index.ts index 2ff04379e3..e370d12224 100644 --- a/packages/host/webserver/src/index.ts +++ b/packages/host/webserver/src/index.ts @@ -12,10 +12,10 @@ import { createServer } from 'node:http' import type { IncomingMessage, ServerResponse, Server } from 'node:http' import type { AddressInfo } from 'node:net' import type { Duplex } from 'node:stream' -import { Context, Service } from 'cordis' -import z from 'schemastery' +import { Context, Service } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { httpServer: HttpServerService } diff --git a/packages/host/webserver/src/invariant.ts b/packages/host/webserver/src/invariant.ts index 7becf3543b..036fa03932 100644 --- a/packages/host/webserver/src/invariant.ts +++ b/packages/host/webserver/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-host-webserver' diff --git a/packages/host/webserver/tests/webserver.spec.ts b/packages/host/webserver/tests/webserver.spec.ts index d91284c87b..1a592cd432 100644 --- a/packages/host/webserver/tests/webserver.spec.ts +++ b/packages/host/webserver/tests/webserver.spec.ts @@ -12,9 +12,9 @@ import { tmpdir } from 'node:os' import { join } from 'node:path' import { pathToFileURL } from 'node:url' import { afterEach, describe, expect, it } from 'vitest' -import { Context } from 'cordis' -import Loader from '@cordisjs/plugin-loader' -import Include from '@cordisjs/plugin-include' +import { Context } from '@deepseek-ai/cordis' +import Loader from '@deepseek-ai/cordis-plugin-loader' +import Include from '@deepseek-ai/cordis-plugin-include' import HttpServer from '../src/index.ts' let root: string | undefined diff --git a/packages/interaction/commands/package.json b/packages/interaction/commands/package.json index cd62942a5f..96fd3e6740 100644 --- a/packages/interaction/commands/package.json +++ b/packages/interaction/commands/package.json @@ -39,7 +39,7 @@ "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-scope": "^0.0.1", "@deepseek-ai/dsh-session": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-agent": "workspace:^", @@ -47,6 +47,6 @@ "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-scope": "workspace:^", "@deepseek-ai/dsh-session": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/interaction/commands/src/index.ts b/packages/interaction/commands/src/index.ts index 9f4110568e..6b13ec549a 100644 --- a/packages/interaction/commands/src/index.ts +++ b/packages/interaction/commands/src/index.ts @@ -3,7 +3,7 @@ * @module @deepseek-ai/dsh-commands */ -import { Context, Service } from 'cordis' +import { Context, Service } from '@deepseek-ai/cordis' import type { Agent } from '@deepseek-ai/dsh-agent' import { NamedEntries, ScopedLayers } from '@deepseek-ai/dsh-scope' import type { ScopeKey, ScopeLayer } from '@deepseek-ai/dsh-scope' @@ -119,7 +119,7 @@ class CommandLayer implements ScopeLayer { } } -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { commands: CommandService } diff --git a/packages/interaction/commands/src/invariant.ts b/packages/interaction/commands/src/invariant.ts index 792733c199..ff5d60a7cb 100644 --- a/packages/interaction/commands/src/invariant.ts +++ b/packages/interaction/commands/src/invariant.ts @@ -4,7 +4,7 @@ * @module @deepseek-ai/dsh-commands/invariant */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { Session, SessionEvent } from '@deepseek-ai/dsh-session' import type { InvariantFailure, InvariantInstaller } from '@deepseek-ai/dsh-invariants' diff --git a/packages/interaction/commands/tests/commands.spec.ts b/packages/interaction/commands/tests/commands.spec.ts index 54b4227d19..7b39db932a 100644 --- a/packages/interaction/commands/tests/commands.spec.ts +++ b/packages/interaction/commands/tests/commands.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { createScope } from '@deepseek-ai/dsh-scope' import type { Scope } from '@deepseek-ai/dsh-scope' import type { Agent } from '@deepseek-ai/dsh-agent' diff --git a/packages/interaction/commands/tests/invariant.spec.ts b/packages/interaction/commands/tests/invariant.spec.ts index 556be701e8..60bbe20696 100644 --- a/packages/interaction/commands/tests/invariant.spec.ts +++ b/packages/interaction/commands/tests/invariant.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import * as CommandInvariant from '@deepseek-ai/dsh-commands/invariant' import InvariantService, { InvariantError } from '@deepseek-ai/dsh-invariants' import SessionStore, { SessionId, type Session } from '@deepseek-ai/dsh-session' diff --git a/packages/interaction/permission/package.json b/packages/interaction/permission/package.json index 0ae48d6e2f..5fad3f9d25 100644 --- a/packages/interaction/permission/package.json +++ b/packages/interaction/permission/package.json @@ -43,10 +43,10 @@ "@deepseek-ai/dsh-session-projection": "^0.0.1", "@deepseek-ai/dsh-settings": "^0.0.1", "@deepseek-ai/dsh-user-approval": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { - "schemastery": "^3.18.0", + "@deepseek-ai/schemastery": "^3.18.0", "zod": "^4.4.3" }, "devDependencies": { @@ -59,6 +59,6 @@ "@deepseek-ai/dsh-session-projection": "workspace:^", "@deepseek-ai/dsh-settings": "workspace:^", "@deepseek-ai/dsh-user-approval": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/interaction/permission/src/index.ts b/packages/interaction/permission/src/index.ts index 35b762b2aa..a68431aeb5 100644 --- a/packages/interaction/permission/src/index.ts +++ b/packages/interaction/permission/src/index.ts @@ -10,8 +10,8 @@ * @module dsh-permission */ -import { Context, Service } from 'cordis' -import z from 'schemastery' +import { Context, Service } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import { z as zod } from 'zod' import type { Session, SessionEvent } from '@deepseek-ai/dsh-session' import type { SandboxMode } from '@deepseek-ai/dsh-sandbox' @@ -33,7 +33,7 @@ import type { PermissionSelect, PresetOption } from './types.ts' // consuming the declarations still receive the SessionProjectionMap merge. export type * from './types.ts' -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { permission: PermissionService } diff --git a/packages/interaction/permission/src/invariant.ts b/packages/interaction/permission/src/invariant.ts index 3bd102645f..b403c9e576 100644 --- a/packages/interaction/permission/src/invariant.ts +++ b/packages/interaction/permission/src/invariant.ts @@ -1,6 +1,6 @@ /** Package-owned permission-preset event invariants. @module @deepseek-ai/dsh-permission/invariant */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { Session, SessionEvent } from '@deepseek-ai/dsh-session' import type { InvariantFailure, InvariantInstaller } from '@deepseek-ai/dsh-invariants' diff --git a/packages/interaction/permission/tests/invariant.spec.ts b/packages/interaction/permission/tests/invariant.spec.ts index 9b903dc6a5..7c916f5b58 100644 --- a/packages/interaction/permission/tests/invariant.spec.ts +++ b/packages/interaction/permission/tests/invariant.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context, Service } from 'cordis' +import { Context, Service } from '@deepseek-ai/cordis' import SessionStore, { type Session, type SessionEvent } from '@deepseek-ai/dsh-session' import * as PermissionInvariant from '@deepseek-ai/dsh-permission/invariant' import InvariantService from '@deepseek-ai/dsh-invariants' diff --git a/packages/interaction/permission/tests/permission.spec.ts b/packages/interaction/permission/tests/permission.spec.ts index 4940e3b155..d20f513b04 100644 --- a/packages/interaction/permission/tests/permission.spec.ts +++ b/packages/interaction/permission/tests/permission.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import SessionStore, { Session, SessionId } from '@deepseek-ai/dsh-session' import type { SandboxMode } from '@deepseek-ai/dsh-sandbox' import type { ApprovalPolicy } from '@deepseek-ai/dsh-user-approval' diff --git a/packages/interaction/permission/tests/projection.spec.ts b/packages/interaction/permission/tests/projection.spec.ts index 3a0e2091c9..e9bb098967 100644 --- a/packages/interaction/permission/tests/projection.spec.ts +++ b/packages/interaction/permission/tests/projection.spec.ts @@ -10,7 +10,7 @@ */ import { describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import SessionStore, { SessionId } from '@deepseek-ai/dsh-session' import type { Session } from '@deepseek-ai/dsh-session' import type { Agent } from '@deepseek-ai/dsh-agent' diff --git a/packages/interaction/tool-ask-user/package.json b/packages/interaction/tool-ask-user/package.json index 7418c7ba2c..b7291d4ccc 100644 --- a/packages/interaction/tool-ask-user/package.json +++ b/packages/interaction/tool-ask-user/package.json @@ -29,7 +29,7 @@ "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-tools": "^0.0.1", "@deepseek-ai/dsh-user-interaction": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-agent": "workspace:^", @@ -38,6 +38,6 @@ "@deepseek-ai/dsh-system-prompt": "workspace:^", "@deepseek-ai/dsh-tools": "workspace:^", "@deepseek-ai/dsh-user-interaction": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/interaction/tool-ask-user/src/index.ts b/packages/interaction/tool-ask-user/src/index.ts index ccfdefe6d3..f223053171 100644 --- a/packages/interaction/tool-ask-user/src/index.ts +++ b/packages/interaction/tool-ask-user/src/index.ts @@ -6,7 +6,7 @@ * @module @deepseek-ai/dsh-tool-ask-user */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { defineTool } from '@deepseek-ai/dsh-tools' import '@deepseek-ai/dsh-user-interaction' diff --git a/packages/interaction/tool-ask-user/src/invariant.ts b/packages/interaction/tool-ask-user/src/invariant.ts index 140bbd79c5..d723a4bc31 100644 --- a/packages/interaction/tool-ask-user/src/invariant.ts +++ b/packages/interaction/tool-ask-user/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-tool-ask-user' diff --git a/packages/interaction/tool-ask-user/tests/tool-ask-user.spec.ts b/packages/interaction/tool-ask-user/tests/tool-ask-user.spec.ts index 14e71ae15b..2795ffa3ff 100644 --- a/packages/interaction/tool-ask-user/tests/tool-ask-user.spec.ts +++ b/packages/interaction/tool-ask-user/tests/tool-ask-user.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { CallId } from '@deepseek-ai/dsh-llm' import AgentRegistry, { type Agent } from '@deepseek-ai/dsh-agent' import SystemPrompt from '@deepseek-ai/dsh-system-prompt' diff --git a/packages/interaction/user-approval/package.json b/packages/interaction/user-approval/package.json index 5b5c43cb42..854e316df9 100644 --- a/packages/interaction/user-approval/package.json +++ b/packages/interaction/user-approval/package.json @@ -37,10 +37,10 @@ "@deepseek-ai/dsh-scope": "^0.0.1", "@deepseek-ai/dsh-session": "^0.0.1", "@deepseek-ai/dsh-system-prompt": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { "@deepseek-ai/dsh-agent": "workspace:^", @@ -50,6 +50,6 @@ "@deepseek-ai/dsh-scope": "workspace:^", "@deepseek-ai/dsh-session": "workspace:^", "@deepseek-ai/dsh-system-prompt": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/interaction/user-approval/src/index.ts b/packages/interaction/user-approval/src/index.ts index f0b63080ed..b0618f6b3d 100644 --- a/packages/interaction/user-approval/src/index.ts +++ b/packages/interaction/user-approval/src/index.ts @@ -5,8 +5,8 @@ */ import { randomUUID } from 'node:crypto' -import { Context, Service } from 'cordis' -import z from 'schemastery' +import { Context, Service } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import type { Agent } from '@deepseek-ai/dsh-agent' import { createUserMessage, type CallId } from '@deepseek-ai/dsh-llm' import { scopeTarget } from '@deepseek-ai/dsh-scope' @@ -14,7 +14,7 @@ import type { Scoped } from '@deepseek-ai/dsh-scope' import type { Session, SessionEvent } from '@deepseek-ai/dsh-session' import type {} from '@deepseek-ai/dsh-system-prompt' -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { approval: ApprovalService } diff --git a/packages/interaction/user-approval/src/invariant.ts b/packages/interaction/user-approval/src/invariant.ts index 6eca2571ff..bf3ca8d18d 100644 --- a/packages/interaction/user-approval/src/invariant.ts +++ b/packages/interaction/user-approval/src/invariant.ts @@ -1,6 +1,6 @@ /** Package-owned approval audit-stream invariants. @module @deepseek-ai/dsh-user-approval/invariant */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { Session, SessionEvent } from '@deepseek-ai/dsh-session' import type { InvariantFailure, InvariantInstaller } from '@deepseek-ai/dsh-invariants' import type { ApprovalRequestId } from './index.ts' diff --git a/packages/interaction/user-approval/tests/approval.spec.ts b/packages/interaction/user-approval/tests/approval.spec.ts index 2bb66caa9d..3271ecc7a5 100644 --- a/packages/interaction/user-approval/tests/approval.spec.ts +++ b/packages/interaction/user-approval/tests/approval.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import type { Agent } from '@deepseek-ai/dsh-agent' import { CallId } from '@deepseek-ai/dsh-llm' import { carrierKeyOf, createScope } from '@deepseek-ai/dsh-scope' diff --git a/packages/interaction/user-approval/tests/invariant.spec.ts b/packages/interaction/user-approval/tests/invariant.spec.ts index bf23b4106d..42665b81f2 100644 --- a/packages/interaction/user-approval/tests/invariant.spec.ts +++ b/packages/interaction/user-approval/tests/invariant.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import SessionStore, { Session, SessionId } from '@deepseek-ai/dsh-session' import { ApprovalRequestId } from '@deepseek-ai/dsh-user-approval' import * as ApprovalInvariant from '@deepseek-ai/dsh-user-approval/invariant' diff --git a/packages/interaction/user-interaction/package.json b/packages/interaction/user-interaction/package.json index 5bed79e075..c72e3f1298 100644 --- a/packages/interaction/user-interaction/package.json +++ b/packages/interaction/user-interaction/package.json @@ -33,12 +33,12 @@ "@deepseek-ai/dsh-agent": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-llm": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-agent": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-llm": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/interaction/user-interaction/src/index.ts b/packages/interaction/user-interaction/src/index.ts index 82ab06e25b..79c22b8479 100644 --- a/packages/interaction/user-interaction/src/index.ts +++ b/packages/interaction/user-interaction/src/index.ts @@ -7,11 +7,11 @@ * @module @deepseek-ai/dsh-user-interaction */ -import { Context, Service } from 'cordis' +import { Context, Service } from '@deepseek-ai/cordis' import type { Agent } from '@deepseek-ai/dsh-agent' import { HarnessError } from '@deepseek-ai/dsh-llm' -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { userInteraction: UserInteractionService } diff --git a/packages/interaction/user-interaction/src/invariant.ts b/packages/interaction/user-interaction/src/invariant.ts index f4f2f2f31e..3e82a2f73e 100644 --- a/packages/interaction/user-interaction/src/invariant.ts +++ b/packages/interaction/user-interaction/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-user-interaction' diff --git a/packages/interaction/user-interaction/tests/user-interaction.spec.ts b/packages/interaction/user-interaction/tests/user-interaction.spec.ts index 8270b81bfd..44fc075233 100644 --- a/packages/interaction/user-interaction/tests/user-interaction.spec.ts +++ b/packages/interaction/user-interaction/tests/user-interaction.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import AgentRegistry, { type Agent } from '@deepseek-ai/dsh-agent' import UserInteractionService, { UserInteractionError, diff --git a/packages/llm/llm-deepseek/package.json b/packages/llm/llm-deepseek/package.json index e745fa1169..d2573696be 100644 --- a/packages/llm/llm-deepseek/package.json +++ b/packages/llm/llm-deepseek/package.json @@ -31,11 +31,11 @@ "@deepseek-ai/dsh-llm": "^0.0.1", "@deepseek-ai/dsh-settings": "^0.0.1", "@deepseek-ai/dsh-timeout": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { "eventsource-parser": "^3.1.0", - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { "@deepseek-ai/dsh-credentials": "workspace:^", @@ -44,6 +44,6 @@ "@deepseek-ai/dsh-llm": "workspace:^", "@deepseek-ai/dsh-settings": "workspace:^", "@deepseek-ai/dsh-timeout": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/llm/llm-deepseek/src/index.ts b/packages/llm/llm-deepseek/src/index.ts index 6d052edc45..f77b36a9cc 100644 --- a/packages/llm/llm-deepseek/src/index.ts +++ b/packages/llm/llm-deepseek/src/index.ts @@ -11,8 +11,8 @@ * @module @deepseek-ai/dsh-llm-deepseek */ -import type { Context } from 'cordis' -import z from 'schemastery' +import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import { assertUsableApiKey, LlmError, resolveRetryPolicy, RetryPolicySchema } from '@deepseek-ai/dsh-llm' import type { RetryPolicyConfig } from '@deepseek-ai/dsh-llm' import { credentialRef } from '@deepseek-ai/dsh-credentials' diff --git a/packages/llm/llm-deepseek/src/invariant.ts b/packages/llm/llm-deepseek/src/invariant.ts index dd2df6e99c..921e02a252 100644 --- a/packages/llm/llm-deepseek/src/invariant.ts +++ b/packages/llm/llm-deepseek/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-llm-deepseek' diff --git a/packages/llm/llm-deepseek/tests/adapter.e2e.ts b/packages/llm/llm-deepseek/tests/adapter.e2e.ts index 97ae629001..e8eeb7b403 100644 --- a/packages/llm/llm-deepseek/tests/adapter.e2e.ts +++ b/packages/llm/llm-deepseek/tests/adapter.e2e.ts @@ -2,7 +2,7 @@ import { mkdtemp, rm, writeFile } from 'node:fs/promises' import { tmpdir } from 'node:os' import { join } from 'node:path' import { afterEach, describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import LlmService, { createUserMessage, CallId, ReasoningEffortId , createMessage } from '@deepseek-ai/dsh-llm' import type { Message, ToolSchema } from '@deepseek-ai/dsh-llm' import { CredentialsLocal } from '@deepseek-ai/dsh-credentials-local' diff --git a/packages/llm/llm-deepseek/tests/adapter.spec.ts b/packages/llm/llm-deepseek/tests/adapter.spec.ts index 64e2bb1e7d..32a19776b2 100644 --- a/packages/llm/llm-deepseek/tests/adapter.spec.ts +++ b/packages/llm/llm-deepseek/tests/adapter.spec.ts @@ -1,5 +1,5 @@ import { afterEach, describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { createEnvironmentSnapshot } from '@deepseek-ai/dsh-environment' import LlmService, { createUserMessage, CONTEXT_WINDOW_EXCEEDED_CODE, diff --git a/packages/llm/llm-deepseek/tests/assemble.ts b/packages/llm/llm-deepseek/tests/assemble.ts index 490b4e87cf..2ed51d0f3d 100644 --- a/packages/llm/llm-deepseek/tests/assemble.ts +++ b/packages/llm/llm-deepseek/tests/assemble.ts @@ -6,7 +6,7 @@ */ import { BlockAssembler } from '@deepseek-ai/dsh-llm' -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { FinishReason, GenerateOptions, Message, TokenUsage } from '@deepseek-ai/dsh-llm' export interface AssembledResult { diff --git a/packages/llm/llm-deepseek/tests/dynamic-config.spec.ts b/packages/llm/llm-deepseek/tests/dynamic-config.spec.ts index 769264b11b..ec6da80b17 100644 --- a/packages/llm/llm-deepseek/tests/dynamic-config.spec.ts +++ b/packages/llm/llm-deepseek/tests/dynamic-config.spec.ts @@ -1,5 +1,5 @@ import { afterEach, describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { mkdtemp, rm, writeFile } from 'node:fs/promises' import { tmpdir } from 'node:os' import { join } from 'node:path' diff --git a/packages/llm/llm-deepseek/tests/loader-composition.spec.ts b/packages/llm/llm-deepseek/tests/loader-composition.spec.ts index 340bed3ee9..d87c6bfe6c 100644 --- a/packages/llm/llm-deepseek/tests/loader-composition.spec.ts +++ b/packages/llm/llm-deepseek/tests/loader-composition.spec.ts @@ -13,9 +13,9 @@ import { tmpdir } from 'node:os' import { join } from 'node:path' import { pathToFileURL } from 'node:url' import { afterEach, describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' -import Loader from '@cordisjs/plugin-loader' -import Include from '@cordisjs/plugin-include' +import { Context } from '@deepseek-ai/cordis' +import Loader from '@deepseek-ai/cordis-plugin-loader' +import Include from '@deepseek-ai/cordis-plugin-include' import LlmService from '@deepseek-ai/dsh-llm' import { credentialRef } from '@deepseek-ai/dsh-credentials' import CredentialsLocal from '@deepseek-ai/dsh-credentials-local' diff --git a/packages/llm/llm-pi-ai/package.json b/packages/llm/llm-pi-ai/package.json index 9804a35a0f..f7a931d902 100644 --- a/packages/llm/llm-pi-ai/package.json +++ b/packages/llm/llm-pi-ai/package.json @@ -32,11 +32,11 @@ "@deepseek-ai/dsh-llm": "^0.0.1", "@deepseek-ai/dsh-settings": "^0.0.1", "@deepseek-ai/dsh-timeout": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { "@earendil-works/pi-ai": "^0.82.1", - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { "@deepseek-ai/dsh-attachment": "workspace:^", @@ -47,6 +47,6 @@ "@deepseek-ai/dsh-llm-deepseek": "workspace:^", "@deepseek-ai/dsh-settings": "workspace:^", "@deepseek-ai/dsh-timeout": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/llm/llm-pi-ai/src/config.ts b/packages/llm/llm-pi-ai/src/config.ts index a2074302e8..e6d2c0849b 100644 --- a/packages/llm/llm-pi-ai/src/config.ts +++ b/packages/llm/llm-pi-ai/src/config.ts @@ -15,7 +15,7 @@ */ import type { CacheRetention, ModelThinkingLevel, Provider, ThinkingBudgets, Transport } from '@earendil-works/pi-ai' -import z from 'schemastery' +import z from '@deepseek-ai/schemastery' import { credentialRef } from '@deepseek-ai/dsh-credentials' import type { CredentialRef } from '@deepseek-ai/dsh-credentials' import { MAX_TIMER_DELAY_MS } from '@deepseek-ai/dsh-timeout' diff --git a/packages/llm/llm-pi-ai/src/index.ts b/packages/llm/llm-pi-ai/src/index.ts index 9deea3e1a8..199c98bff3 100644 --- a/packages/llm/llm-pi-ai/src/index.ts +++ b/packages/llm/llm-pi-ai/src/index.ts @@ -55,7 +55,7 @@ * @module @deepseek-ai/dsh-llm-pi-ai */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { environmentOf } from '@deepseek-ai/dsh-environment' import { assertUsableApiKey, LlmError } from '@deepseek-ai/dsh-llm' import type { AdapterRegistrationHandle, DirectoryRegistrationHandle, LlmConfigurableProvider } from '@deepseek-ai/dsh-llm' diff --git a/packages/llm/llm-pi-ai/src/invariant.ts b/packages/llm/llm-pi-ai/src/invariant.ts index a096804fd2..6fdf5b3126 100644 --- a/packages/llm/llm-pi-ai/src/invariant.ts +++ b/packages/llm/llm-pi-ai/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-llm-pi-ai' diff --git a/packages/llm/llm-pi-ai/tests/adapter.e2e.ts b/packages/llm/llm-pi-ai/tests/adapter.e2e.ts index 4637a75298..1232ca3484 100644 --- a/packages/llm/llm-pi-ai/tests/adapter.e2e.ts +++ b/packages/llm/llm-pi-ai/tests/adapter.e2e.ts @@ -1,5 +1,5 @@ import { afterEach, describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import LlmService, { createUserMessage, CallId, ReasoningEffortId } from '@deepseek-ai/dsh-llm' import type { Message, ToolSchema } from '@deepseek-ai/dsh-llm' import * as LlmPiAi from '@deepseek-ai/dsh-llm-pi-ai' diff --git a/packages/llm/llm-pi-ai/tests/adapter.spec.ts b/packages/llm/llm-pi-ai/tests/adapter.spec.ts index e0b54cecd0..1bc370f126 100644 --- a/packages/llm/llm-pi-ai/tests/adapter.spec.ts +++ b/packages/llm/llm-pi-ai/tests/adapter.spec.ts @@ -1,5 +1,5 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { AttachmentId, AttachmentStore } from '@deepseek-ai/dsh-attachment' import type { ImageAttachmentLimits, diff --git a/packages/llm/llm-pi-ai/tests/assemble.ts b/packages/llm/llm-pi-ai/tests/assemble.ts index 61726fd1d4..8d415941c7 100644 --- a/packages/llm/llm-pi-ai/tests/assemble.ts +++ b/packages/llm/llm-pi-ai/tests/assemble.ts @@ -6,7 +6,7 @@ */ import { BlockAssembler } from '@deepseek-ai/dsh-llm' -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { FinishReason, GenerateOptions, Message, TokenUsage } from '@deepseek-ai/dsh-llm' export interface AssembledResult { diff --git a/packages/llm/llm-pi-ai/tests/catalog.spec.ts b/packages/llm/llm-pi-ai/tests/catalog.spec.ts index e304dddade..38c4184e0a 100644 --- a/packages/llm/llm-pi-ai/tests/catalog.spec.ts +++ b/packages/llm/llm-pi-ai/tests/catalog.spec.ts @@ -2,7 +2,7 @@ import { mkdtemp, rm, writeFile } from 'node:fs/promises' import { tmpdir } from 'node:os' import { join } from 'node:path' import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import LlmService, { createUserMessage } from '@deepseek-ai/dsh-llm' import type { StreamChunk } from '@deepseek-ai/dsh-llm' import SettingsLocal from '@deepseek-ai/dsh-settings-local' diff --git a/packages/llm/llm-pi-ai/tests/discovery.spec.ts b/packages/llm/llm-pi-ai/tests/discovery.spec.ts index 02b859d5f2..d4efce4109 100644 --- a/packages/llm/llm-pi-ai/tests/discovery.spec.ts +++ b/packages/llm/llm-pi-ai/tests/discovery.spec.ts @@ -1,7 +1,7 @@ import { createServer } from 'node:http' import type { IncomingMessage, Server, ServerResponse } from 'node:http' import { afterEach, describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import LlmService, { userAgent } from '@deepseek-ai/dsh-llm' import * as LlmPiAi from '@deepseek-ai/dsh-llm-pi-ai' import { getBuiltinModels } from '@earendil-works/pi-ai/providers/all' diff --git a/packages/llm/llm-pi-ai/tests/dynamic-config.spec.ts b/packages/llm/llm-pi-ai/tests/dynamic-config.spec.ts index d30cf18cf9..85987088a3 100644 --- a/packages/llm/llm-pi-ai/tests/dynamic-config.spec.ts +++ b/packages/llm/llm-pi-ai/tests/dynamic-config.spec.ts @@ -1,5 +1,5 @@ import { afterEach, describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { mkdtemp, rm, writeFile } from 'node:fs/promises' import { tmpdir } from 'node:os' import { join } from 'node:path' diff --git a/packages/llm/llm-pi-ai/tests/loader-composition.spec.ts b/packages/llm/llm-pi-ai/tests/loader-composition.spec.ts index d5eed60e5e..e0800ed88d 100644 --- a/packages/llm/llm-pi-ai/tests/loader-composition.spec.ts +++ b/packages/llm/llm-pi-ai/tests/loader-composition.spec.ts @@ -13,9 +13,9 @@ import { tmpdir } from 'node:os' import { join } from 'node:path' import { pathToFileURL } from 'node:url' import { afterEach, describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' -import Loader from '@cordisjs/plugin-loader' -import Include from '@cordisjs/plugin-include' +import { Context } from '@deepseek-ai/cordis' +import Loader from '@deepseek-ai/cordis-plugin-loader' +import Include from '@deepseek-ai/cordis-plugin-include' import LlmService from '@deepseek-ai/dsh-llm' import CredentialsLocal from '@deepseek-ai/dsh-credentials-local' import SettingsLocal from '@deepseek-ai/dsh-settings-local' diff --git a/packages/llm/llm-pi-ai/tests/provider-apis.e2e.ts b/packages/llm/llm-pi-ai/tests/provider-apis.e2e.ts index 002de2b829..e64fb12377 100644 --- a/packages/llm/llm-pi-ai/tests/provider-apis.e2e.ts +++ b/packages/llm/llm-pi-ai/tests/provider-apis.e2e.ts @@ -1,6 +1,6 @@ import { readFile } from 'node:fs/promises' import { afterEach, describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { AttachmentId, AttachmentStore } from '@deepseek-ai/dsh-attachment' import type { ImageAttachmentLimits, diff --git a/packages/llm/llm-retry/package.json b/packages/llm/llm-retry/package.json index 809b5d14e5..5f69487147 100644 --- a/packages/llm/llm-retry/package.json +++ b/packages/llm/llm-retry/package.json @@ -35,15 +35,15 @@ "@deepseek-ai/dsh-llm": "^0.0.1", "@deepseek-ai/dsh-session": "^0.0.1", "@deepseek-ai/dsh-timeout": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { "@deepseek-ai/dsh-brand": "workspace:^", - "@cordisjs/plugin-include": "workspace:^", - "@cordisjs/plugin-loader": "workspace:^", + "@deepseek-ai/cordis-plugin-include": "workspace:^", + "@deepseek-ai/cordis-plugin-loader": "workspace:^", "@deepseek-ai/dsh-agent": "workspace:^", "@deepseek-ai/dsh-agent-loop": "workspace:^", "@deepseek-ai/dsh-agent-loop-testkit": "workspace:^", @@ -57,6 +57,6 @@ "@deepseek-ai/dsh-system-prompt": "workspace:^", "@deepseek-ai/dsh-timeout": "workspace:^", "@deepseek-ai/dsh-tools": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/llm/llm-retry/src/index.ts b/packages/llm/llm-retry/src/index.ts index 2ebeb79260..45db304059 100644 --- a/packages/llm/llm-retry/src/index.ts +++ b/packages/llm/llm-retry/src/index.ts @@ -6,8 +6,8 @@ */ import { randomUUID } from 'node:crypto' -import type { Context, Events } from 'cordis' -import z from 'schemastery' +import type { Context, Events } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import type { Agent, RequestErrorAction } from '@deepseek-ai/dsh-agent' import type { LlmFailure, ResolvedRetryPolicy } from '@deepseek-ai/dsh-llm' import type { SessionEvent } from '@deepseek-ai/dsh-session' diff --git a/packages/llm/llm-retry/src/invariant.ts b/packages/llm/llm-retry/src/invariant.ts index 1680873c0c..7b454bcc4e 100644 --- a/packages/llm/llm-retry/src/invariant.ts +++ b/packages/llm/llm-retry/src/invariant.ts @@ -1,6 +1,6 @@ /** Package-owned durable retry-event invariants. @module @deepseek-ai/dsh-llm-retry/invariant */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { Session, SessionEvent } from '@deepseek-ai/dsh-session' import type { LlmFailure } from '@deepseek-ai/dsh-llm' import { MAX_TIMER_DELAY_MS } from '@deepseek-ai/dsh-timeout' diff --git a/packages/llm/llm-retry/tests/invariant.spec.ts b/packages/llm/llm-retry/tests/invariant.spec.ts index dd22e11369..eccaeef4d8 100644 --- a/packages/llm/llm-retry/tests/invariant.spec.ts +++ b/packages/llm/llm-retry/tests/invariant.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import SessionStore, { SessionId, type Session } from '@deepseek-ai/dsh-session' import { createUserMessage, ProviderRequestId } from '@deepseek-ai/dsh-llm' import { MAX_TIMER_DELAY_MS } from '@deepseek-ai/dsh-timeout' diff --git a/packages/llm/llm-retry/tests/loader-composition.spec.ts b/packages/llm/llm-retry/tests/loader-composition.spec.ts index 16fb8581b9..c560720c76 100644 --- a/packages/llm/llm-retry/tests/loader-composition.spec.ts +++ b/packages/llm/llm-retry/tests/loader-composition.spec.ts @@ -3,9 +3,9 @@ import { tmpdir } from 'node:os' import { join } from 'node:path' import { pathToFileURL } from 'node:url' import { afterEach, describe, expect, it } from 'vitest' -import { Context } from 'cordis' -import Loader from '@cordisjs/plugin-loader' -import Include from '@cordisjs/plugin-include' +import { Context } from '@deepseek-ai/cordis' +import Loader from '@deepseek-ai/cordis-plugin-loader' +import Include from '@deepseek-ai/cordis-plugin-include' import AgentRegistry from '@deepseek-ai/dsh-agent' import AgentLoop from '@deepseek-ai/dsh-agent-loop' import LlmService, { createUserMessage, LlmAdapter, LlmError, resolveRetryPolicy } from '@deepseek-ai/dsh-llm' diff --git a/packages/llm/llm-retry/tests/persistence.spec.ts b/packages/llm/llm-retry/tests/persistence.spec.ts index 8affb9e059..de20b69698 100644 --- a/packages/llm/llm-retry/tests/persistence.spec.ts +++ b/packages/llm/llm-retry/tests/persistence.spec.ts @@ -2,7 +2,7 @@ import { mkdtemp, rm } from 'node:fs/promises' import { tmpdir } from 'node:os' import { join } from 'node:path' import { afterEach, describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import SessionStore, { SessionId } from '@deepseek-ai/dsh-session' import SessionPersistenceJsonl from '@deepseek-ai/dsh-session-persistence-jsonl' import SessionPersistenceSqlite from '@deepseek-ai/dsh-session-persistence-sqlite' diff --git a/packages/llm/llm-retry/tests/retry.spec.ts b/packages/llm/llm-retry/tests/retry.spec.ts index 7268c19ec6..62423ecfda 100644 --- a/packages/llm/llm-retry/tests/retry.spec.ts +++ b/packages/llm/llm-retry/tests/retry.spec.ts @@ -1,6 +1,6 @@ import { afterEach, describe, expect, expectTypeOf, it, vi } from 'vitest' -import { Context } from 'cordis' -import type { Fiber } from 'cordis' +import { Context } from '@deepseek-ai/cordis' +import type { Fiber } from '@deepseek-ai/cordis' import LlmService, { createUserMessage, CallId, EMPTY_RESPONSE_CODE, LlmAdapter, LlmError, resolveRetryPolicy } from '@deepseek-ai/dsh-llm' import type { AlwaysRetryPolicyConfig, diff --git a/packages/llm/llm-retry/tests/transport-recovery.spec.ts b/packages/llm/llm-retry/tests/transport-recovery.spec.ts index 3acb8605fc..fb830f9868 100644 --- a/packages/llm/llm-retry/tests/transport-recovery.spec.ts +++ b/packages/llm/llm-retry/tests/transport-recovery.spec.ts @@ -2,7 +2,7 @@ import { createUserMessage } from '@deepseek-ai/dsh-llm' import { createServer } from 'node:http' import type { AddressInfo } from 'node:net' import { afterEach, describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import type { Agent } from '@deepseek-ai/dsh-agent' import AgentLoop from '@deepseek-ai/dsh-agent-loop' import { mountAgentLoopTestDependencies } from '@deepseek-ai/dsh-agent-loop-testkit' diff --git a/packages/llm/llm/package.json b/packages/llm/llm/package.json index c802ce5c43..1a11622738 100644 --- a/packages/llm/llm/package.json +++ b/packages/llm/llm/package.json @@ -42,16 +42,16 @@ "@deepseek-ai/dsh-brand": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-timeout": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { "@deepseek-ai/dsh-attachment": "workspace:^", "@deepseek-ai/dsh-brand": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-timeout": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/llm/llm/src/index.ts b/packages/llm/llm/src/index.ts index 75d8d6f364..9938d687ac 100644 --- a/packages/llm/llm/src/index.ts +++ b/packages/llm/llm/src/index.ts @@ -6,7 +6,7 @@ * @module @deepseek-ai/dsh-llm */ -import { Context, Service } from 'cordis' +import { Context, Service } from '@deepseek-ai/cordis' import type { GenerateOptions, LlmConfigurableProvider, @@ -43,7 +43,7 @@ export { BlockAssembler } from './assembler.ts' export { callConfigEquals, deepFreeze, isAgentLoopRequest, markAgentLoopRequest } from './call-config.ts' export type { LlmCallConfig, LlmCallConfigAdapterDefaults } from './call-config.ts' -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { llm: LlmService } diff --git a/packages/llm/llm/src/invariant.ts b/packages/llm/llm/src/invariant.ts index 2f1afb5155..2106ca354d 100644 --- a/packages/llm/llm/src/invariant.ts +++ b/packages/llm/llm/src/invariant.ts @@ -1,6 +1,6 @@ /** Package-owned LLM stream-protocol invariants. @module @deepseek-ai/dsh-llm/invariant */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantFailure, InvariantInstaller } from '@deepseek-ai/dsh-invariants' import type { ContentBlockType, StreamChunk } from './types.ts' diff --git a/packages/llm/llm/src/retry-policy.ts b/packages/llm/llm/src/retry-policy.ts index 6f5548a111..ad9c7af65c 100644 --- a/packages/llm/llm/src/retry-policy.ts +++ b/packages/llm/llm/src/retry-policy.ts @@ -7,7 +7,7 @@ * @module @deepseek-ai/dsh-llm/retry-policy */ -import z from 'schemastery' +import z from '@deepseek-ai/schemastery' import { MAX_TIMER_DELAY_MS } from '@deepseek-ai/dsh-timeout' import { EMPTY_RESPONSE_CODE } from './error.ts' diff --git a/packages/llm/llm/tests/invariant.spec.ts b/packages/llm/llm/tests/invariant.spec.ts index 8aebb556c2..cfc51c67ee 100644 --- a/packages/llm/llm/tests/invariant.spec.ts +++ b/packages/llm/llm/tests/invariant.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import LlmService, { CallId, LlmAdapter } from '@deepseek-ai/dsh-llm' import type { GenerateOptions, StreamChunk } from '@deepseek-ai/dsh-llm' import * as LlmInvariant from '@deepseek-ai/dsh-llm/invariant' diff --git a/packages/llm/llm/tests/service.spec.ts b/packages/llm/llm/tests/service.spec.ts index a758fab415..8873d19859 100644 --- a/packages/llm/llm/tests/service.spec.ts +++ b/packages/llm/llm/tests/service.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import LlmService, { errorChain, GenerateOptions, diff --git a/packages/llm/llm/tests/topology.spec.ts b/packages/llm/llm/tests/topology.spec.ts index 8577e14b7c..c31948f61a 100644 --- a/packages/llm/llm/tests/topology.spec.ts +++ b/packages/llm/llm/tests/topology.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import LlmService, { LlmAdapter, LlmError } from '@deepseek-ai/dsh-llm' import type { GenerateOptions, LlmConfigurableProvider, StreamChunk } from '@deepseek-ai/dsh-llm' diff --git a/packages/llm/token-meter/package.json b/packages/llm/token-meter/package.json index 5670fe97cd..61cd66617f 100644 --- a/packages/llm/token-meter/package.json +++ b/packages/llm/token-meter/package.json @@ -35,10 +35,10 @@ "@deepseek-ai/dsh-llm": "^0.0.1", "@deepseek-ai/dsh-session": "^0.0.1", "@deepseek-ai/dsh-session-projection": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { - "schemastery": "^3.18.0", + "@deepseek-ai/schemastery": "^3.18.0", "zod": "^4.4.3" }, "devDependencies": { @@ -47,6 +47,6 @@ "@deepseek-ai/dsh-llm": "workspace:^", "@deepseek-ai/dsh-session": "workspace:^", "@deepseek-ai/dsh-session-projection": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/llm/token-meter/src/index.ts b/packages/llm/token-meter/src/index.ts index a5ac463fb2..6d7d7ffe49 100644 --- a/packages/llm/token-meter/src/index.ts +++ b/packages/llm/token-meter/src/index.ts @@ -4,8 +4,8 @@ * @module @deepseek-ai/dsh-token-meter */ -import { Context, Service } from 'cordis' -import z from 'schemastery' +import { Context, Service } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import { BlockAssembler, deepFreeze } from '@deepseek-ai/dsh-llm' import type { Message, TokenUsage } from '@deepseek-ai/dsh-llm' import type { EpochHeader, Session, SessionEvent } from '@deepseek-ai/dsh-session' @@ -64,7 +64,7 @@ function validateConfigKeys(config: TokenMeterConfig): void { } } -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { tokenMeter: TokenMeterService } diff --git a/packages/llm/token-meter/src/invariant.ts b/packages/llm/token-meter/src/invariant.ts index 53ae13c466..c65f4f27b8 100644 --- a/packages/llm/token-meter/src/invariant.ts +++ b/packages/llm/token-meter/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-token-meter' diff --git a/packages/llm/token-meter/tests/context-breakdown-projection.spec.ts b/packages/llm/token-meter/tests/context-breakdown-projection.spec.ts index 9bdd1222f0..460b1a54f9 100644 --- a/packages/llm/token-meter/tests/context-breakdown-projection.spec.ts +++ b/packages/llm/token-meter/tests/context-breakdown-projection.spec.ts @@ -2,7 +2,7 @@ // plus the shared estimator's pricing branches. import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { createMessage, createUserMessage } from '@deepseek-ai/dsh-llm' import type { ContentBlock, ToolSchema } from '@deepseek-ai/dsh-llm' import SessionStore from '@deepseek-ai/dsh-session' diff --git a/packages/llm/token-meter/tests/token-meter.spec.ts b/packages/llm/token-meter/tests/token-meter.spec.ts index e0bf348019..2ca24cf88d 100644 --- a/packages/llm/token-meter/tests/token-meter.spec.ts +++ b/packages/llm/token-meter/tests/token-meter.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, expectTypeOf, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { createUserMessage, CallId, createMessage } from '@deepseek-ai/dsh-llm' import type { ContentBlock, Message, TokenUsage } from '@deepseek-ai/dsh-llm' import SessionStore, { Session, SessionId, canonicalHeader } from '@deepseek-ai/dsh-session' diff --git a/packages/llm/token-meter/tests/token-usage-projection.spec.ts b/packages/llm/token-meter/tests/token-usage-projection.spec.ts index 9ccc2d7e9b..173bb8056b 100644 --- a/packages/llm/token-meter/tests/token-usage-projection.spec.ts +++ b/packages/llm/token-meter/tests/token-usage-projection.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { createMessage, createUserMessage } from '@deepseek-ai/dsh-llm' import type { TokenUsage } from '@deepseek-ai/dsh-llm' import SessionStore from '@deepseek-ai/dsh-session' diff --git a/packages/lsp/lsp-local/package.json b/packages/lsp/lsp-local/package.json index a5411bab55..02fcddd558 100644 --- a/packages/lsp/lsp-local/package.json +++ b/packages/lsp/lsp-local/package.json @@ -32,10 +32,10 @@ "@deepseek-ai/dsh-lsp": "^0.0.1", "@deepseek-ai/dsh-subprocess": "^0.0.1", "@deepseek-ai/dsh-timeout": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { "@deepseek-ai/dsh-brand": "workspace:^", @@ -47,7 +47,7 @@ "@deepseek-ai/dsh-subprocess": "workspace:^", "@deepseek-ai/dsh-subprocess-local": "workspace:^", "@deepseek-ai/dsh-timeout": "workspace:^", - "cordis": "^4.0.0-rc.7", + "@deepseek-ai/cordis": "^4.0.0-rc.7", "typescript": "^6.0.3", "typescript-language-server": "^5.0.0" } diff --git a/packages/lsp/lsp-local/src/index.ts b/packages/lsp/lsp-local/src/index.ts index fc7e50787f..13d032c5fd 100644 --- a/packages/lsp/lsp-local/src/index.ts +++ b/packages/lsp/lsp-local/src/index.ts @@ -11,8 +11,8 @@ * @module @deepseek-ai/dsh-lsp-local */ -import type { Context } from 'cordis' -import z from 'schemastery' +import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import { LspError, LspProviderId } from '@deepseek-ai/dsh-lsp' import type { LspProvider, diff --git a/packages/lsp/lsp-local/src/invariant.ts b/packages/lsp/lsp-local/src/invariant.ts index 52ebd16dc0..505d077eeb 100644 --- a/packages/lsp/lsp-local/src/invariant.ts +++ b/packages/lsp/lsp-local/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-lsp-local' diff --git a/packages/lsp/lsp-local/tests/built-lib.e2e.ts b/packages/lsp/lsp-local/tests/built-lib.e2e.ts index 75f9f227c3..707f389a2f 100644 --- a/packages/lsp/lsp-local/tests/built-lib.e2e.ts +++ b/packages/lsp/lsp-local/tests/built-lib.e2e.ts @@ -40,7 +40,7 @@ describe.skipIf(!built)('built lib real load path (plain node)', () => { it('runs a query through lib/index.js and disposes cleanly, framing over the base protocol', async () => { const location = JSON.stringify({ uri: pathToFileURL(join(ws, 'a.ts')).href, range: { start: { line: 0, character: 0 }, end: { line: 0, character: 3 } } }) const script = ` - const { Context } = await import('cordis') + const { Context } = await import('@deepseek-ai/cordis') const { default: Lsp } = await import('@deepseek-ai/dsh-lsp') const LspLocal = await import('@deepseek-ai/dsh-lsp-local') const { default: LocalFileSystem } = await import('@deepseek-ai/dsh-fs-local') diff --git a/packages/lsp/lsp-local/tests/host.spec.ts b/packages/lsp/lsp-local/tests/host.spec.ts index c06b6d9df8..8c7a9079d3 100644 --- a/packages/lsp/lsp-local/tests/host.spec.ts +++ b/packages/lsp/lsp-local/tests/host.spec.ts @@ -6,7 +6,7 @@ import { realpath } from 'node:fs/promises' import { execFile } from 'node:child_process' import { pathToFileURL } from 'node:url' import { promisify } from 'node:util' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import LocalFileSystem from '@deepseek-ai/dsh-fs-local' import { deadline } from '@deepseek-ai/dsh-timeout' import { canonicalizeWorkspace, readHostSource } from '@deepseek-ai/dsh-lsp-local' diff --git a/packages/lsp/lsp-local/tests/instance.spec.ts b/packages/lsp/lsp-local/tests/instance.spec.ts index 08bad67ae2..0a928fba50 100644 --- a/packages/lsp/lsp-local/tests/instance.spec.ts +++ b/packages/lsp/lsp-local/tests/instance.spec.ts @@ -4,7 +4,7 @@ import { mkdtemp, mkdir, readFile, rm, writeFile, realpath } from 'node:fs/promi import { tmpdir } from 'node:os' import { join } from 'node:path' import { pathToFileURL, fileURLToPath } from 'node:url' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import LocalFileSystem from '@deepseek-ai/dsh-fs-local' import { LspInstance, readHostSource } from '@deepseek-ai/dsh-lsp-local' import { encodeMessage } from '@deepseek-ai/dsh-lsp-local' diff --git a/packages/lsp/lsp-local/tests/lifecycle.spec.ts b/packages/lsp/lsp-local/tests/lifecycle.spec.ts index 20c4bc7bf0..bda3963d7d 100644 --- a/packages/lsp/lsp-local/tests/lifecycle.spec.ts +++ b/packages/lsp/lsp-local/tests/lifecycle.spec.ts @@ -4,7 +4,7 @@ import { realpath } from 'node:fs/promises' import { tmpdir } from 'node:os' import { join } from 'node:path' import { pathToFileURL, fileURLToPath } from 'node:url' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import Lsp, { type LspProvider, type LspQueryRequest, type LspQueryResult } from '@deepseek-ai/dsh-lsp' import { deadline } from '@deepseek-ai/dsh-timeout' import LocalSubprocessService from '@deepseek-ai/dsh-subprocess-local' diff --git a/packages/lsp/lsp-local/tests/provider.spec.ts b/packages/lsp/lsp-local/tests/provider.spec.ts index 24edca4795..94486e1ea7 100644 --- a/packages/lsp/lsp-local/tests/provider.spec.ts +++ b/packages/lsp/lsp-local/tests/provider.spec.ts @@ -2,7 +2,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' import { chmod, mkdtemp, mkdir, rm, writeFile, realpath } from 'node:fs/promises' import { tmpdir } from 'node:os' import { delimiter, join } from 'node:path' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import LocalSubprocessService from '@deepseek-ai/dsh-subprocess-local' import LocalFileSystem from '@deepseek-ai/dsh-fs-local' import Lsp, { type LspQueryRequest } from '@deepseek-ai/dsh-lsp' diff --git a/packages/lsp/lsp-local/tests/typescript-server.e2e.ts b/packages/lsp/lsp-local/tests/typescript-server.e2e.ts index 9bdb7d1fd4..5879ed3b2f 100644 --- a/packages/lsp/lsp-local/tests/typescript-server.e2e.ts +++ b/packages/lsp/lsp-local/tests/typescript-server.e2e.ts @@ -9,7 +9,7 @@ import { afterAll, beforeAll, describe, expect, it } from 'vitest' import { mkdtemp, mkdir, rm, writeFile, realpath } from 'node:fs/promises' import { tmpdir } from 'node:os' import { join } from 'node:path' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import LocalSubprocessService from '@deepseek-ai/dsh-subprocess-local' import LocalFileSystem from '@deepseek-ai/dsh-fs-local' import Lsp, { type LspQueryRequest, type LspQueryResult } from '@deepseek-ai/dsh-lsp' diff --git a/packages/lsp/lsp/package.json b/packages/lsp/lsp/package.json index b4a962fb34..d5993b515e 100644 --- a/packages/lsp/lsp/package.json +++ b/packages/lsp/lsp/package.json @@ -28,12 +28,12 @@ "@deepseek-ai/dsh-brand": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-llm": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-brand": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-llm": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/lsp/lsp/src/index.ts b/packages/lsp/lsp/src/index.ts index ec780b76f1..05e2cd3643 100644 --- a/packages/lsp/lsp/src/index.ts +++ b/packages/lsp/lsp/src/index.ts @@ -11,7 +11,7 @@ * @module @deepseek-ai/dsh-lsp */ -import { Context, Service } from 'cordis' +import { Context, Service } from '@deepseek-ai/cordis' import { HarnessError } from '@deepseek-ai/dsh-llm' import type { LspProviderId } from './brand.ts' import type { @@ -35,7 +35,7 @@ export type { LspService, } from './types.ts' -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { lsp: LspService } diff --git a/packages/lsp/lsp/src/invariant.ts b/packages/lsp/lsp/src/invariant.ts index 27481309f4..512775798b 100644 --- a/packages/lsp/lsp/src/invariant.ts +++ b/packages/lsp/lsp/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-lsp' diff --git a/packages/lsp/lsp/tests/lsp.spec.ts b/packages/lsp/lsp/tests/lsp.spec.ts index 86c9b0ac53..0adbf44769 100644 --- a/packages/lsp/lsp/tests/lsp.spec.ts +++ b/packages/lsp/lsp/tests/lsp.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import Lsp, { finalExtension, LspError, diff --git a/packages/lsp/tool-lsp/package.json b/packages/lsp/tool-lsp/package.json index f757df35fd..7b7dc54dc2 100644 --- a/packages/lsp/tool-lsp/package.json +++ b/packages/lsp/tool-lsp/package.json @@ -31,10 +31,10 @@ "@deepseek-ai/dsh-system-prompt": "^0.0.1", "@deepseek-ai/dsh-timeout": "^0.0.1", "@deepseek-ai/dsh-tools": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { "@deepseek-ai/dsh-agent": "workspace:^", @@ -49,6 +49,6 @@ "@deepseek-ai/dsh-timeout": "workspace:^", "@deepseek-ai/dsh-timeout-policy": "workspace:^", "@deepseek-ai/dsh-tools": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/lsp/tool-lsp/src/index.ts b/packages/lsp/tool-lsp/src/index.ts index 688b48b369..f94cb7d5f7 100644 --- a/packages/lsp/tool-lsp/src/index.ts +++ b/packages/lsp/tool-lsp/src/index.ts @@ -10,8 +10,8 @@ * @module @deepseek-ai/dsh-tool-lsp */ -import type { Context } from 'cordis' -import z from 'schemastery' +import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import { defineTool } from '@deepseek-ai/dsh-tools' import { assertNever } from '@deepseek-ai/dsh-llm' import { LspError } from '@deepseek-ai/dsh-lsp' diff --git a/packages/lsp/tool-lsp/src/invariant.ts b/packages/lsp/tool-lsp/src/invariant.ts index a2516e059b..fc9a292fc8 100644 --- a/packages/lsp/tool-lsp/src/invariant.ts +++ b/packages/lsp/tool-lsp/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-tool-lsp' diff --git a/packages/lsp/tool-lsp/tests/integration.spec.ts b/packages/lsp/tool-lsp/tests/integration.spec.ts index 8312a6e3ab..8ad2392adc 100644 --- a/packages/lsp/tool-lsp/tests/integration.spec.ts +++ b/packages/lsp/tool-lsp/tests/integration.spec.ts @@ -3,7 +3,7 @@ import { mkdtemp, mkdir, rm, writeFile, realpath } from 'node:fs/promises' import { tmpdir } from 'node:os' import { join } from 'node:path' import { pathToFileURL } from 'node:url' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import SystemPrompt from '@deepseek-ai/dsh-system-prompt' import ToolRegistry from '@deepseek-ai/dsh-tools' import LocalFileSystem from '@deepseek-ai/dsh-fs-local' diff --git a/packages/lsp/tool-lsp/tests/load-path.spec.ts b/packages/lsp/tool-lsp/tests/load-path.spec.ts index 7b3ec0f241..f5f2b272d7 100644 --- a/packages/lsp/tool-lsp/tests/load-path.spec.ts +++ b/packages/lsp/tool-lsp/tests/load-path.spec.ts @@ -6,7 +6,7 @@ */ import { describe, expect, it } from 'vitest' -import Loader from '@cordisjs/plugin-loader' +import Loader from '@deepseek-ai/cordis-plugin-loader' import * as toolLsp from '@deepseek-ai/dsh-tool-lsp' describe('dsh-tool-lsp Loader export-shape guard', () => { diff --git a/packages/lsp/tool-lsp/tests/tool-lsp.spec.ts b/packages/lsp/tool-lsp/tests/tool-lsp.spec.ts index 846bd702ea..bc6795273e 100644 --- a/packages/lsp/tool-lsp/tests/tool-lsp.spec.ts +++ b/packages/lsp/tool-lsp/tests/tool-lsp.spec.ts @@ -1,7 +1,7 @@ import { describe, expect, it } from 'vitest' import { join, resolve } from 'node:path' import { pathToFileURL } from 'node:url' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import SystemPrompt from '@deepseek-ai/dsh-system-prompt' import ToolRegistry from '@deepseek-ai/dsh-tools' import Lsp, { LspProviderId, type LspProvider, type LspProviderQuery, type LspQueryResult } from '@deepseek-ai/dsh-lsp' diff --git a/packages/mcp/mcp-client/package.json b/packages/mcp/mcp-client/package.json index 3f65271905..e5b110e7db 100644 --- a/packages/mcp/mcp-client/package.json +++ b/packages/mcp/mcp-client/package.json @@ -29,11 +29,11 @@ "@deepseek-ai/dsh-llm": "^0.0.1", "@deepseek-ai/dsh-subprocess": "^0.0.1", "@deepseek-ai/dsh-tools": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { "@modelcontextprotocol/sdk": "^1.12.0", - "schemastery": "^3.18.0", + "@deepseek-ai/schemastery": "^3.18.0", "zod": "^4.4.3" }, "devDependencies": { @@ -43,6 +43,6 @@ "@deepseek-ai/dsh-tools": "workspace:^", "@modelcontextprotocol/server-everything": "^2026.7.4", "@modelcontextprotocol/server-filesystem": "^2026.7.4", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/mcp/mcp-client/src/index.ts b/packages/mcp/mcp-client/src/index.ts index b55896544d..7f35ae3ed3 100644 --- a/packages/mcp/mcp-client/src/index.ts +++ b/packages/mcp/mcp-client/src/index.ts @@ -13,8 +13,8 @@ * @module @deepseek-ai/dsh-mcp-client */ -import type { Context } from 'cordis' -import z from 'schemastery' +import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import { Client } from '@modelcontextprotocol/sdk/client/index.js' import { ToolListChangedNotificationSchema } from '@modelcontextprotocol/sdk/types.js' import { createTransport } from './transport.ts' diff --git a/packages/mcp/mcp-client/src/invariant.ts b/packages/mcp/mcp-client/src/invariant.ts index e2d8ac22cb..6532d8c2ef 100644 --- a/packages/mcp/mcp-client/src/invariant.ts +++ b/packages/mcp/mcp-client/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-mcp-client' diff --git a/packages/mcp/mcp-client/src/tools.ts b/packages/mcp/mcp-client/src/tools.ts index 889684923b..92862fa15f 100644 --- a/packages/mcp/mcp-client/src/tools.ts +++ b/packages/mcp/mcp-client/src/tools.ts @@ -16,7 +16,7 @@ import { createHash } from 'node:crypto' import type { Client } from '@modelcontextprotocol/sdk/client/index.js' import { ListToolsResultSchema } from '@modelcontextprotocol/sdk/types.js' import { z } from 'zod' -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { ToolDefinition, ToolExecution } from '@deepseek-ai/dsh-tools' import { assertSupportedJsonSchema } from '@deepseek-ai/dsh-tools' import type { JsonSchemaNode, JsonValue } from '@deepseek-ai/dsh-tools' diff --git a/packages/mcp/mcp-client/tests/apply.spec.ts b/packages/mcp/mcp-client/tests/apply.spec.ts index e30a1ee716..06d82eb77e 100644 --- a/packages/mcp/mcp-client/tests/apply.spec.ts +++ b/packages/mcp/mcp-client/tests/apply.spec.ts @@ -3,7 +3,7 @@ * Isolated file so vi.mock of the MCP SDK doesn't pollute other test suites. */ import { describe, expect, it, vi, beforeEach } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import SystemPrompt from '@deepseek-ai/dsh-system-prompt' import ToolRegistry from '@deepseek-ai/dsh-tools' import type { Config } from '@deepseek-ai/dsh-mcp-client' diff --git a/packages/mcp/mcp-client/tests/load-path.spec.ts b/packages/mcp/mcp-client/tests/load-path.spec.ts index 5507cd5b83..89d6ce1f2a 100644 --- a/packages/mcp/mcp-client/tests/load-path.spec.ts +++ b/packages/mcp/mcp-client/tests/load-path.spec.ts @@ -11,7 +11,7 @@ */ import { describe, expect, it } from 'vitest' -import Loader from '@cordisjs/plugin-loader' +import Loader from '@deepseek-ai/cordis-plugin-loader' import * as mcpClient from '@deepseek-ai/dsh-mcp-client' describe('dsh-mcp-client real-load-path guard', () => { diff --git a/packages/mcp/mcp-client/tests/mcp-client.e2e.ts b/packages/mcp/mcp-client/tests/mcp-client.e2e.ts index e1f51d20e9..64f76e4a34 100644 --- a/packages/mcp/mcp-client/tests/mcp-client.e2e.ts +++ b/packages/mcp/mcp-client/tests/mcp-client.e2e.ts @@ -14,7 +14,7 @@ import { tmpdir } from 'node:os' import { join } from 'node:path' import { fileURLToPath } from 'node:url' import { afterAll, beforeAll, describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js' import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js' import { z } from 'zod' diff --git a/packages/mcp/mcp-client/tests/mcp-client.spec.ts b/packages/mcp/mcp-client/tests/mcp-client.spec.ts index 22559d74cf..aa97ba34ce 100644 --- a/packages/mcp/mcp-client/tests/mcp-client.spec.ts +++ b/packages/mcp/mcp-client/tests/mcp-client.spec.ts @@ -1,7 +1,7 @@ import { describe, expect, it, vi, beforeEach } from 'vitest' import { Client } from '@modelcontextprotocol/sdk/client/index.js' import { InMemoryTransport } from '@modelcontextprotocol/sdk/inMemory.js' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { CallId } from '@deepseek-ai/dsh-llm' import SystemPrompt from '@deepseek-ai/dsh-system-prompt' import ToolRegistry, { type JsonValue } from '@deepseek-ai/dsh-tools' diff --git a/packages/plan/plan-mode/package.json b/packages/plan/plan-mode/package.json index a810981357..d5c24e3877 100644 --- a/packages/plan/plan-mode/package.json +++ b/packages/plan/plan-mode/package.json @@ -43,7 +43,7 @@ "@deepseek-ai/dsh-system-prompt": "^0.0.1", "@deepseek-ai/dsh-tools": "^0.0.1", "@deepseek-ai/dsh-user-interaction": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "peerDependenciesMeta": { "@deepseek-ai/dsh-commands": { @@ -65,6 +65,6 @@ "@deepseek-ai/dsh-system-prompt": "workspace:^", "@deepseek-ai/dsh-tools": "workspace:^", "@deepseek-ai/dsh-user-interaction": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/plan/plan-mode/src/index.ts b/packages/plan/plan-mode/src/index.ts index 86da4d4935..53cea83f5c 100644 --- a/packages/plan/plan-mode/src/index.ts +++ b/packages/plan/plan-mode/src/index.ts @@ -23,7 +23,7 @@ * @module @deepseek-ai/dsh-plan-mode */ -import { Context, Service } from 'cordis' +import { Context, Service } from '@deepseek-ai/cordis' import { z as zod } from 'zod' import type { ZodType } from 'zod' import type { Agent, PreStepDecision } from '@deepseek-ai/dsh-agent' @@ -54,7 +54,7 @@ declare module '@deepseek-ai/dsh-session/types' { } } -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { planMode: PlanModeService } diff --git a/packages/plan/plan-mode/src/invariant.ts b/packages/plan/plan-mode/src/invariant.ts index 797010c59f..634efadfb5 100644 --- a/packages/plan/plan-mode/src/invariant.ts +++ b/packages/plan/plan-mode/src/invariant.ts @@ -1,6 +1,6 @@ /** Package-owned durable plan-mode invariants. @module @deepseek-ai/dsh-plan-mode/invariant */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { Session, SessionEvent } from '@deepseek-ai/dsh-session' import type { InvariantFailure, InvariantInstaller } from '@deepseek-ai/dsh-invariants' diff --git a/packages/plan/plan-mode/tests/integration.spec.ts b/packages/plan/plan-mode/tests/integration.spec.ts index 34678714fa..f061f12034 100644 --- a/packages/plan/plan-mode/tests/integration.spec.ts +++ b/packages/plan/plan-mode/tests/integration.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import LlmService, { createUserMessage, type StreamChunk } from '@deepseek-ai/dsh-llm' import SessionStore, { SessionId, type SessionEvent } from '@deepseek-ai/dsh-session' import SystemPrompt from '@deepseek-ai/dsh-system-prompt' diff --git a/packages/plan/plan-mode/tests/invariant.spec.ts b/packages/plan/plan-mode/tests/invariant.spec.ts index 7ebee4cdb7..7cab457b6e 100644 --- a/packages/plan/plan-mode/tests/invariant.spec.ts +++ b/packages/plan/plan-mode/tests/invariant.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import SessionStore, { Session, SessionId, type SessionEvent } from '@deepseek-ai/dsh-session' import * as PlanModeInvariant from '@deepseek-ai/dsh-plan-mode/invariant' import InvariantService from '@deepseek-ai/dsh-invariants' diff --git a/packages/plan/plan-mode/tests/plan-mode.spec.ts b/packages/plan/plan-mode/tests/plan-mode.spec.ts index fddee83915..529dde6879 100644 --- a/packages/plan/plan-mode/tests/plan-mode.spec.ts +++ b/packages/plan/plan-mode/tests/plan-mode.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { createUserMessage, CallId } from '@deepseek-ai/dsh-llm' import SystemPrompt from '@deepseek-ai/dsh-system-prompt' import ToolRegistry, { RUN_CODE_NAME, defineContentToolFixture } from '@deepseek-ai/dsh-tools' diff --git a/packages/plan/plan-mode/tests/projection.spec.ts b/packages/plan/plan-mode/tests/projection.spec.ts index b1e546d8b7..b9557c0c7e 100644 --- a/packages/plan/plan-mode/tests/projection.spec.ts +++ b/packages/plan/plan-mode/tests/projection.spec.ts @@ -10,7 +10,7 @@ */ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import AgentRegistry from '@deepseek-ai/dsh-agent' import type { Agent } from '@deepseek-ai/dsh-agent' import SessionStore from '@deepseek-ai/dsh-session' diff --git a/packages/preset/agent-presets/package.json b/packages/preset/agent-presets/package.json index c012dc3eda..5a08e6f99d 100644 --- a/packages/preset/agent-presets/package.json +++ b/packages/preset/agent-presets/package.json @@ -25,23 +25,23 @@ ], "license": "BSD-3-Clause", "peerDependencies": { - "@cordisjs/plugin-include": "^1.0.4", - "@cordisjs/plugin-loader": "^1.0.0-rc.5", + "@deepseek-ai/cordis-plugin-include": "^1.0.4", + "@deepseek-ai/cordis-plugin-loader": "^1.0.0-rc.5", "@deepseek-ai/dsh-atomic-write": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-paths": "^0.0.1", "@deepseek-ai/dsh-scope": "^0.0.1", "@deepseek-ai/dsh-session": "^0.0.1", "@deepseek-ai/dsh-settings": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { "js-yaml": "^4.1.0", - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { - "@cordisjs/plugin-include": "workspace:^", - "@cordisjs/plugin-loader": "workspace:^", + "@deepseek-ai/cordis-plugin-include": "workspace:^", + "@deepseek-ai/cordis-plugin-loader": "workspace:^", "@deepseek-ai/dsh-agent": "workspace:^", "@deepseek-ai/dsh-agent-loop": "workspace:^", "@deepseek-ai/dsh-atomic-write": "workspace:^", @@ -54,6 +54,6 @@ "@deepseek-ai/dsh-settings-local": "workspace:^", "@deepseek-ai/dsh-system-prompt": "workspace:^", "@deepseek-ai/dsh-tools": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/preset/agent-presets/src/discovery.ts b/packages/preset/agent-presets/src/discovery.ts index de8312893a..9e91bc85a2 100644 --- a/packages/preset/agent-presets/src/discovery.ts +++ b/packages/preset/agent-presets/src/discovery.ts @@ -17,7 +17,7 @@ import { readdir, readFile, stat } from 'node:fs/promises' import { join, resolve } from 'node:path' import { load } from 'js-yaml' -import { entryListSchema } from '@cordisjs/plugin-include' +import { entryListSchema } from '@deepseek-ai/cordis-plugin-include' import { expandHomePath } from '@deepseek-ai/dsh-paths' import { readPresetMetadata } from './metadata.ts' import { PRESET_ID, type AgentPreset, type PresetRoot } from './types.ts' diff --git a/packages/preset/agent-presets/src/index.ts b/packages/preset/agent-presets/src/index.ts index 1dde902234..18c57dc17e 100644 --- a/packages/preset/agent-presets/src/index.ts +++ b/packages/preset/agent-presets/src/index.ts @@ -22,8 +22,8 @@ */ import { stat } from 'node:fs/promises' -import { Context, Service } from 'cordis' -import z from 'schemastery' +import { Context, Service } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import { bindScopeParent, createScope, scopeOf, type Scope, type ScopeKey, type ScopeParentBinding } from '@deepseek-ai/dsh-scope' import { settingsNamespace, type SettingsScope, type default as SettingsService } from '@deepseek-ai/dsh-settings' import { discoverPresets } from './discovery.ts' @@ -62,7 +62,7 @@ export { resolveSessionPreset, type PresetBearingSession } from './session.ts' export { PresetMountError, UnknownPresetError } from './types.ts' export type { AgentPreset, Config, PresetRoot, PresetTrust } from './types.ts' -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { agentPresets: AgentPresets } diff --git a/packages/preset/agent-presets/src/invariant.ts b/packages/preset/agent-presets/src/invariant.ts index 7a08eab7f1..72716e328e 100644 --- a/packages/preset/agent-presets/src/invariant.ts +++ b/packages/preset/agent-presets/src/invariant.ts @@ -3,7 +3,7 @@ * @module @deepseek-ai/dsh-agent-presets/invariant */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' // Imported through the package name, not `./mount.ts`: a module shared between // the two build entry points becomes a third chunk that the published `files` diff --git a/packages/preset/agent-presets/src/mount.ts b/packages/preset/agent-presets/src/mount.ts index e968a97c25..d78603b749 100644 --- a/packages/preset/agent-presets/src/mount.ts +++ b/packages/preset/agent-presets/src/mount.ts @@ -16,9 +16,9 @@ import { isAbsolute } from 'node:path' import { pathToFileURL } from 'node:url' -import { Context, type Fiber } from 'cordis' -import { Include } from '@cordisjs/plugin-include' -import type { EntryTree } from '@cordisjs/plugin-loader' +import { Context, type Fiber } from '@deepseek-ai/cordis' +import { Include } from '@deepseek-ai/cordis-plugin-include' +import type { EntryTree } from '@deepseek-ai/cordis-plugin-loader' import { scopeOf, scopeParentOf, type ScopeKey } from '@deepseek-ai/dsh-scope' import { PresetMountError, type AgentPreset } from './types.ts' diff --git a/packages/preset/agent-presets/tests/authoring.spec.ts b/packages/preset/agent-presets/tests/authoring.spec.ts index b6f4ef388a..df69a792d5 100644 --- a/packages/preset/agent-presets/tests/authoring.spec.ts +++ b/packages/preset/agent-presets/tests/authoring.spec.ts @@ -11,9 +11,9 @@ import { existsSync } from 'node:fs' import { tmpdir } from 'node:os' import { dirname, join } from 'node:path' import { fileURLToPath, pathToFileURL } from 'node:url' -import { Context } from 'cordis' -import Loader from '@cordisjs/plugin-loader' -import Include from '@cordisjs/plugin-include' +import { Context } from '@deepseek-ai/cordis' +import Loader from '@deepseek-ai/cordis-plugin-loader' +import Include from '@deepseek-ai/cordis-plugin-include' import { beforeEach, describe, expect, it } from 'vitest' import AgentPresets, { COMPOSITION_FILE, copyComposition, METADATA_FILE, diff --git a/packages/preset/agent-presets/tests/invariant.spec.ts b/packages/preset/agent-presets/tests/invariant.spec.ts index 17d89813c3..4704d9c08e 100644 --- a/packages/preset/agent-presets/tests/invariant.spec.ts +++ b/packages/preset/agent-presets/tests/invariant.spec.ts @@ -1,8 +1,8 @@ import { dirname, join } from 'node:path' import { fileURLToPath, pathToFileURL } from 'node:url' -import { Context } from 'cordis' -import Loader from '@cordisjs/plugin-loader' -import Include from '@cordisjs/plugin-include' +import { Context } from '@deepseek-ai/cordis' +import Loader from '@deepseek-ai/cordis-plugin-loader' +import Include from '@deepseek-ai/cordis-plugin-include' import LlmService from '@deepseek-ai/dsh-llm' import SessionStore, { SessionId } from '@deepseek-ai/dsh-session' import SystemPrompt from '@deepseek-ai/dsh-system-prompt' diff --git a/packages/preset/agent-presets/tests/mount.spec.ts b/packages/preset/agent-presets/tests/mount.spec.ts index afe297a406..c27d0a535b 100644 --- a/packages/preset/agent-presets/tests/mount.spec.ts +++ b/packages/preset/agent-presets/tests/mount.spec.ts @@ -2,9 +2,9 @@ import { mkdir, mkdtemp, readFile, rm, stat, writeFile } from 'node:fs/promises' import { tmpdir } from 'node:os' import { dirname, join } from 'node:path' import { fileURLToPath, pathToFileURL } from 'node:url' -import { Context } from 'cordis' -import Loader from '@cordisjs/plugin-loader' -import Include from '@cordisjs/plugin-include' +import { Context } from '@deepseek-ai/cordis' +import Loader from '@deepseek-ai/cordis-plugin-loader' +import Include from '@deepseek-ai/cordis-plugin-include' import LlmService from '@deepseek-ai/dsh-llm' import SessionStore, { SessionId } from '@deepseek-ai/dsh-session' import SystemPrompt from '@deepseek-ai/dsh-system-prompt' @@ -18,7 +18,7 @@ import AgentPresets, { import type { Config } from '@deepseek-ai/dsh-agent-presets' import { bindScopeParent, createScope, scopeOf } from '@deepseek-ai/dsh-scope' -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { /** Published by the `isolated` fixture preset behind an entry-local realm. */ fixtureIsolatedSvc: { label: string } diff --git a/packages/preset/agent-presets/tests/settings.spec.ts b/packages/preset/agent-presets/tests/settings.spec.ts index 081ffceba4..ef75eb8b78 100644 --- a/packages/preset/agent-presets/tests/settings.spec.ts +++ b/packages/preset/agent-presets/tests/settings.spec.ts @@ -8,9 +8,9 @@ import { mkdir, mkdtemp, writeFile } from 'node:fs/promises' import { tmpdir } from 'node:os' import { dirname, join } from 'node:path' import { fileURLToPath, pathToFileURL } from 'node:url' -import { Context } from 'cordis' -import Loader from '@cordisjs/plugin-loader' -import Include from '@cordisjs/plugin-include' +import { Context } from '@deepseek-ai/cordis' +import Loader from '@deepseek-ai/cordis-plugin-loader' +import Include from '@deepseek-ai/cordis-plugin-include' import LlmService from '@deepseek-ai/dsh-llm' import SessionStore, { SessionId } from '@deepseek-ai/dsh-session' import SystemPrompt from '@deepseek-ai/dsh-system-prompt' diff --git a/packages/preset/persona/package.json b/packages/preset/persona/package.json index 5ec7678d16..cda2faf015 100644 --- a/packages/preset/persona/package.json +++ b/packages/preset/persona/package.json @@ -27,15 +27,15 @@ "peerDependencies": { "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-system-prompt": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-scope": "workspace:^", "@deepseek-ai/dsh-system-prompt": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/preset/persona/src/index.ts b/packages/preset/persona/src/index.ts index ec56bcc780..4690bd2618 100644 --- a/packages/preset/persona/src/index.ts +++ b/packages/preset/persona/src/index.ts @@ -13,8 +13,8 @@ * @module @deepseek-ai/dsh-persona */ -import type { Context } from 'cordis' -import z from 'schemastery' +import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import type {} from '@deepseek-ai/dsh-system-prompt' // Imported rather than restated: the registry declares the slot this row diff --git a/packages/preset/persona/src/invariant.ts b/packages/preset/persona/src/invariant.ts index 5f9068fe24..0f818eb888 100644 --- a/packages/preset/persona/src/invariant.ts +++ b/packages/preset/persona/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-persona' diff --git a/packages/preset/persona/tests/persona.spec.ts b/packages/preset/persona/tests/persona.spec.ts index bb7555df7c..c4dbe825b0 100644 --- a/packages/preset/persona/tests/persona.spec.ts +++ b/packages/preset/persona/tests/persona.spec.ts @@ -1,4 +1,4 @@ -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import SystemPrompt, { renderPrompt } from '@deepseek-ai/dsh-system-prompt' import { createScope, type ScopeKey } from '@deepseek-ai/dsh-scope' import { describe, expect, it } from 'vitest' diff --git a/packages/pty/pty-local/package.json b/packages/pty/pty-local/package.json index 94f98c02d5..82705255dc 100644 --- a/packages/pty/pty-local/package.json +++ b/packages/pty/pty-local/package.json @@ -32,10 +32,10 @@ "@deepseek-ai/dsh-sandbox-policy": "^0.0.1", "@deepseek-ai/dsh-session": "^0.0.1", "@deepseek-ai/dsh-subprocess": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { "@deepseek-ai/dsh-agent": "workspace:^", @@ -46,6 +46,6 @@ "@deepseek-ai/dsh-session": "workspace:^", "@deepseek-ai/dsh-subprocess": "workspace:^", "@deepseek-ai/dsh-subprocess-local": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/pty/pty-local/src/config.ts b/packages/pty/pty-local/src/config.ts index 41733c0959..be9ae3eed3 100644 --- a/packages/pty/pty-local/src/config.ts +++ b/packages/pty/pty-local/src/config.ts @@ -1,6 +1,6 @@ /** Validated configuration for the local PTY backend. */ -import z from 'schemastery' +import z from '@deepseek-ai/schemastery' /** Public plugin configuration. */ export interface Config { diff --git a/packages/pty/pty-local/src/index.ts b/packages/pty/pty-local/src/index.ts index fa2237c959..ee48a5821d 100644 --- a/packages/pty/pty-local/src/index.ts +++ b/packages/pty/pty-local/src/index.ts @@ -4,7 +4,7 @@ * @module @deepseek-ai/dsh-pty-local */ -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import type { Agent } from '@deepseek-ai/dsh-agent' import type { Session, SessionEvent } from '@deepseek-ai/dsh-session' import { PtyBackendCleanupError } from '@deepseek-ai/dsh-pty' diff --git a/packages/pty/pty-local/src/invariant.ts b/packages/pty/pty-local/src/invariant.ts index b54ac50f63..174fab273a 100644 --- a/packages/pty/pty-local/src/invariant.ts +++ b/packages/pty/pty-local/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-pty-local' diff --git a/packages/pty/pty-local/tests/index.spec.ts b/packages/pty/pty-local/tests/index.spec.ts index dd3a956536..fc07fc784c 100644 --- a/packages/pty/pty-local/tests/index.spec.ts +++ b/packages/pty/pty-local/tests/index.spec.ts @@ -1,7 +1,7 @@ import { describe, expect, it, vi } from 'vitest' import { PassThrough } from 'node:stream' -import { Context } from 'cordis' -import Loader from '@cordisjs/plugin-loader' +import { Context } from '@deepseek-ai/cordis' +import Loader from '@deepseek-ai/cordis-plugin-loader' import SessionStore, { Session, SessionId } from '@deepseek-ai/dsh-session' import AgentRegistry, { Inbox, type Agent } from '@deepseek-ai/dsh-agent' import SandboxProvider from '@deepseek-ai/dsh-sandbox' diff --git a/packages/pty/pty-local/tests/local.spec.ts b/packages/pty/pty-local/tests/local.spec.ts index 31ffaf7e3f..f23a6f077a 100644 --- a/packages/pty/pty-local/tests/local.spec.ts +++ b/packages/pty/pty-local/tests/local.spec.ts @@ -2,7 +2,7 @@ import { existsSync, mkdtempSync, readFileSync, realpathSync, rmSync } from 'nod import { tmpdir } from 'node:os' import { join } from 'node:path' import { afterEach, describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { Session, SessionId } from '@deepseek-ai/dsh-session' import AgentRegistry, { Inbox } from '@deepseek-ai/dsh-agent' import type { Agent } from '@deepseek-ai/dsh-agent' diff --git a/packages/pty/pty/package.json b/packages/pty/pty/package.json index 702426a2b7..9671cfd8ca 100644 --- a/packages/pty/pty/package.json +++ b/packages/pty/pty/package.json @@ -28,13 +28,13 @@ "@deepseek-ai/dsh-agent": "^0.0.1", "@deepseek-ai/dsh-brand": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-agent": "workspace:^", "@deepseek-ai/dsh-brand": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-session": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/pty/pty/src/index.ts b/packages/pty/pty/src/index.ts index 8ff4168e1a..fb28107238 100644 --- a/packages/pty/pty/src/index.ts +++ b/packages/pty/pty/src/index.ts @@ -4,7 +4,7 @@ * @module @deepseek-ai/dsh-pty */ -import { Context, Service } from 'cordis' +import { Context, Service } from '@deepseek-ai/cordis' import type { Agent } from '@deepseek-ai/dsh-agent' import { PtyBackendCleanupError } from './types.ts' import type { @@ -45,7 +45,7 @@ export { PtyBackendCleanupError } from './types.ts' /** Opaque identity minted by {@link PtyService} for one live PTY session. */ export type PtySessionId = PtySessionIdValue -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { pty: PtyService } diff --git a/packages/pty/pty/src/invariant.ts b/packages/pty/pty/src/invariant.ts index 9395d2164c..ae8b0110f0 100644 --- a/packages/pty/pty/src/invariant.ts +++ b/packages/pty/pty/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-pty' diff --git a/packages/pty/pty/tests/service.spec.ts b/packages/pty/pty/tests/service.spec.ts index 0301de837a..02dc004ae3 100644 --- a/packages/pty/pty/tests/service.spec.ts +++ b/packages/pty/pty/tests/service.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, expectTypeOf, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { Session, SessionId } from '@deepseek-ai/dsh-session' import AgentRegistry, { Inbox } from '@deepseek-ai/dsh-agent' import type { Agent } from '@deepseek-ai/dsh-agent' diff --git a/packages/pty/tool-bash-persistent/package.json b/packages/pty/tool-bash-persistent/package.json index 23aad9f32e..fdd5688e8e 100644 --- a/packages/pty/tool-bash-persistent/package.json +++ b/packages/pty/tool-bash-persistent/package.json @@ -29,14 +29,14 @@ "@deepseek-ai/dsh-pty": "^0.0.1", "@deepseek-ai/dsh-timeout": "^0.0.1", "@deepseek-ai/dsh-tools": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { - "@cordisjs/plugin-include": "workspace:^", - "@cordisjs/plugin-loader": "workspace:^", + "@deepseek-ai/cordis-plugin-include": "workspace:^", + "@deepseek-ai/cordis-plugin-loader": "workspace:^", "@deepseek-ai/dsh-agent": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-llm": "workspace:^", @@ -49,6 +49,6 @@ "@deepseek-ai/dsh-system-prompt": "workspace:^", "@deepseek-ai/dsh-timeout": "workspace:^", "@deepseek-ai/dsh-tools": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/pty/tool-bash-persistent/src/index.ts b/packages/pty/tool-bash-persistent/src/index.ts index 24cc998cf2..fa2a965231 100644 --- a/packages/pty/tool-bash-persistent/src/index.ts +++ b/packages/pty/tool-bash-persistent/src/index.ts @@ -4,8 +4,8 @@ */ import { randomUUID } from 'node:crypto' -import type { Context } from 'cordis' -import z from 'schemastery' +import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import type { Agent } from '@deepseek-ai/dsh-agent' import type { PtyReadResult, PtySendResult, PtySessionId } from '@deepseek-ai/dsh-pty' import { deadline, timeoutOf } from '@deepseek-ai/dsh-timeout' diff --git a/packages/pty/tool-bash-persistent/src/invariant.ts b/packages/pty/tool-bash-persistent/src/invariant.ts index 5e276d4c45..b06c59764c 100644 --- a/packages/pty/tool-bash-persistent/src/invariant.ts +++ b/packages/pty/tool-bash-persistent/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-tool-bash-persistent' diff --git a/packages/pty/tool-bash-persistent/tests/loader-composition.spec.ts b/packages/pty/tool-bash-persistent/tests/loader-composition.spec.ts index a69048e8d6..90cc6b7422 100644 --- a/packages/pty/tool-bash-persistent/tests/loader-composition.spec.ts +++ b/packages/pty/tool-bash-persistent/tests/loader-composition.spec.ts @@ -3,9 +3,9 @@ import { tmpdir } from 'node:os' import { join } from 'node:path' import { pathToFileURL } from 'node:url' import { afterEach, describe, expect, it } from 'vitest' -import { Context } from 'cordis' -import Loader from '@cordisjs/plugin-loader' -import Include from '@cordisjs/plugin-include' +import { Context } from '@deepseek-ai/cordis' +import Loader from '@deepseek-ai/cordis-plugin-loader' +import Include from '@deepseek-ai/cordis-plugin-include' import { CallId } from '@deepseek-ai/dsh-llm' import { Session, SessionId } from '@deepseek-ai/dsh-session' import AgentRegistry, { Inbox } from '@deepseek-ai/dsh-agent' diff --git a/packages/pty/tool-bash-persistent/tests/tools.spec.ts b/packages/pty/tool-bash-persistent/tests/tools.spec.ts index 28a950eacf..d43fd64399 100644 --- a/packages/pty/tool-bash-persistent/tests/tools.spec.ts +++ b/packages/pty/tool-bash-persistent/tests/tools.spec.ts @@ -1,5 +1,5 @@ import { afterEach, describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { CallId } from '@deepseek-ai/dsh-llm' import { Session, SessionId } from '@deepseek-ai/dsh-session' import AgentRegistry, { Inbox } from '@deepseek-ai/dsh-agent' diff --git a/packages/pty/tool-pty/package.json b/packages/pty/tool-pty/package.json index f443bbbdf4..f3afefdc0a 100644 --- a/packages/pty/tool-pty/package.json +++ b/packages/pty/tool-pty/package.json @@ -25,7 +25,7 @@ ], "license": "BSD-3-Clause", "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "peerDependencies": { "@deepseek-ai/dsh-agent": "^0.0.1", @@ -36,11 +36,11 @@ "@deepseek-ai/dsh-system-prompt": "^0.0.1", "@deepseek-ai/dsh-tasks": "^0.0.1", "@deepseek-ai/dsh-tools": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { - "@cordisjs/plugin-include": "workspace:^", - "@cordisjs/plugin-loader": "workspace:^", + "@deepseek-ai/cordis-plugin-include": "workspace:^", + "@deepseek-ai/cordis-plugin-loader": "workspace:^", "@deepseek-ai/dsh-agent": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-llm": "workspace:^", @@ -56,6 +56,6 @@ "@deepseek-ai/dsh-tasks-local": "workspace:^", "@deepseek-ai/dsh-tool-tasks": "workspace:^", "@deepseek-ai/dsh-tools": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/pty/tool-pty/src/index.ts b/packages/pty/tool-pty/src/index.ts index fc66d2646e..f6dc2fc42c 100644 --- a/packages/pty/tool-pty/src/index.ts +++ b/packages/pty/tool-pty/src/index.ts @@ -4,8 +4,8 @@ * @module @deepseek-ai/dsh-tool-pty */ -import { Context } from 'cordis' -import z from 'schemastery' +import { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import type { Agent } from '@deepseek-ai/dsh-agent' import type { ContentBlock } from '@deepseek-ai/dsh-llm' import { PtySessionId } from '@deepseek-ai/dsh-pty' diff --git a/packages/pty/tool-pty/src/invariant.ts b/packages/pty/tool-pty/src/invariant.ts index f8451af962..05c6fbf9d9 100644 --- a/packages/pty/tool-pty/src/invariant.ts +++ b/packages/pty/tool-pty/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-tool-pty' diff --git a/packages/pty/tool-pty/tests/loader-composition.spec.ts b/packages/pty/tool-pty/tests/loader-composition.spec.ts index 35d0ea5d0a..ff19707d1e 100644 --- a/packages/pty/tool-pty/tests/loader-composition.spec.ts +++ b/packages/pty/tool-pty/tests/loader-composition.spec.ts @@ -3,9 +3,9 @@ import { tmpdir } from 'node:os' import { join } from 'node:path' import { pathToFileURL } from 'node:url' import { afterEach, describe, expect, it } from 'vitest' -import { Context } from 'cordis' -import Loader from '@cordisjs/plugin-loader' -import Include from '@cordisjs/plugin-include' +import { Context } from '@deepseek-ai/cordis' +import Loader from '@deepseek-ai/cordis-plugin-loader' +import Include from '@deepseek-ai/cordis-plugin-include' import { CallId } from '@deepseek-ai/dsh-llm' import { Session, SessionId } from '@deepseek-ai/dsh-session' import AgentRegistry, { Inbox } from '@deepseek-ai/dsh-agent' diff --git a/packages/pty/tool-pty/tests/tools.spec.ts b/packages/pty/tool-pty/tests/tools.spec.ts index 235aad0e02..042c620b29 100644 --- a/packages/pty/tool-pty/tests/tools.spec.ts +++ b/packages/pty/tool-pty/tests/tools.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { CallId } from '@deepseek-ai/dsh-llm' import { Session, SessionId } from '@deepseek-ai/dsh-session' import AgentRegistry, { Inbox } from '@deepseek-ai/dsh-agent' diff --git a/packages/sandbox/sandbox-local/package.json b/packages/sandbox/sandbox-local/package.json index 226c241204..5af6264b4a 100644 --- a/packages/sandbox/sandbox-local/package.json +++ b/packages/sandbox/sandbox-local/package.json @@ -29,18 +29,18 @@ "@deepseek-ai/dsh-llm": "^0.0.1", "@deepseek-ai/dsh-sandbox": "^0.0.1", "@deepseek-ai/dsh-session": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { "@deepseek-ai/dsh-sandbox-windows-acl": "workspace:^", "@deepseek-ai/node-addon-landlock-run": "workspace:*", - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-llm": "workspace:^", "@deepseek-ai/dsh-sandbox": "workspace:^", "@deepseek-ai/dsh-session": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/sandbox/sandbox-local/src/index.ts b/packages/sandbox/sandbox-local/src/index.ts index fc19a8dbea..7288517213 100644 --- a/packages/sandbox/sandbox-local/src/index.ts +++ b/packages/sandbox/sandbox-local/src/index.ts @@ -30,8 +30,8 @@ import { launcherPath as landlockLauncherPath, probe as defaultProbeLandlock, } from '@deepseek-ai/node-addon-landlock-run' -import { Context } from 'cordis' -import z from 'schemastery' +import { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import { assertNever } from '@deepseek-ai/dsh-llm' import { SandboxProvider, SandboxUnavailableError } from '@deepseek-ai/dsh-sandbox' import type { ConfinedArgv, ConfinedSandboxMode, RunnerFailureRule, SandboxEnforcement, SandboxPolicy } from '@deepseek-ai/dsh-sandbox' diff --git a/packages/sandbox/sandbox-local/src/invariant.ts b/packages/sandbox/sandbox-local/src/invariant.ts index e990d46acc..e4f0891631 100644 --- a/packages/sandbox/sandbox-local/src/invariant.ts +++ b/packages/sandbox/sandbox-local/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-sandbox-local' diff --git a/packages/sandbox/sandbox-local/tests/acl-grants.spec.ts b/packages/sandbox/sandbox-local/tests/acl-grants.spec.ts index ca2410c317..3bee8f4b4d 100644 --- a/packages/sandbox/sandbox-local/tests/acl-grants.spec.ts +++ b/packages/sandbox/sandbox-local/tests/acl-grants.spec.ts @@ -11,7 +11,7 @@ import { existsSync, mkdirSync, mkdtempSync, rmSync, symlinkSync } from 'node:fs import { tmpdir } from 'node:os' import { basename, join } from 'node:path' import { beforeEach, describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import type { SandboxPolicy } from '@deepseek-ai/dsh-sandbox' import { SessionId } from '@deepseek-ai/dsh-session' import { LocalSandboxProvider, sessionTempDir } from '@deepseek-ai/dsh-sandbox-local' diff --git a/packages/sandbox/sandbox-local/tests/bwrap.e2e.ts b/packages/sandbox/sandbox-local/tests/bwrap.e2e.ts index 9a093e4632..3da6787049 100644 --- a/packages/sandbox/sandbox-local/tests/bwrap.e2e.ts +++ b/packages/sandbox/sandbox-local/tests/bwrap.e2e.ts @@ -4,7 +4,7 @@ import { mkdtemp, rm } from 'node:fs/promises' import { homedir, tmpdir } from 'node:os' import { join } from 'node:path' import { afterEach, describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import type { SandboxPolicy } from '@deepseek-ai/dsh-sandbox' import { LocalSandboxProvider } from '@deepseek-ai/dsh-sandbox-local' import { bwrapProfileArgs } from '../src/profiles.ts' diff --git a/packages/sandbox/sandbox-local/tests/landlock.e2e.ts b/packages/sandbox/sandbox-local/tests/landlock.e2e.ts index ff4947a4ca..4bee858b78 100644 --- a/packages/sandbox/sandbox-local/tests/landlock.e2e.ts +++ b/packages/sandbox/sandbox-local/tests/landlock.e2e.ts @@ -4,7 +4,7 @@ import { mkdtemp, rm } from 'node:fs/promises' import { homedir, tmpdir } from 'node:os' import { join } from 'node:path' import { afterEach, describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import type { SandboxPolicy } from '@deepseek-ai/dsh-sandbox' import { launcherPath } from '@deepseek-ai/node-addon-landlock-run' import { LocalSandboxProvider } from '@deepseek-ai/dsh-sandbox-local' diff --git a/packages/sandbox/sandbox-local/tests/local.spec.ts b/packages/sandbox/sandbox-local/tests/local.spec.ts index 2edde27ca7..9ad6f5ed9e 100644 --- a/packages/sandbox/sandbox-local/tests/local.spec.ts +++ b/packages/sandbox/sandbox-local/tests/local.spec.ts @@ -11,7 +11,7 @@ import { mkdtempSync, realpathSync, writeFileSync } from 'node:fs' import { tmpdir } from 'node:os' import { join } from 'node:path' import { describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { LAUNCHER_FAILURE_EXIT } from '@deepseek-ai/node-addon-landlock-run' import { SANDBOX_UNAVAILABLE, SandboxUnavailableError } from '@deepseek-ai/dsh-sandbox' import type { SandboxPolicy } from '@deepseek-ai/dsh-sandbox' diff --git a/packages/sandbox/sandbox-local/tests/packed-install.e2e.ts b/packages/sandbox/sandbox-local/tests/packed-install.e2e.ts index 4b95f4da58..6b7e547099 100644 --- a/packages/sandbox/sandbox-local/tests/packed-install.e2e.ts +++ b/packages/sandbox/sandbox-local/tests/packed-install.e2e.ts @@ -7,11 +7,11 @@ import { fileURLToPath } from 'node:url' import { afterAll, beforeAll, describe, expect, it } from 'vitest' /** - * Keyless publish-path rehearsal. It packs the provider, its workspace peers, and the current - * repository's Landlock entry/platform packages, then installs those exact tarballs in an external - * plain-Node consumer. The host launcher comes from the exact local tarballs, so no registry copy, - * tsx, path mapping, or workspace resolution can hide missing files, dependency errors, or lost - * executable modes. npm may still query registry metadata for an incompatible optional platform + * Keyless publish-path rehearsal. It packs the provider, its workspace peers, the vendored framework + * peer, and the current repository's Landlock entry/platform packages, then installs those exact + * tarballs in an external plain-Node consumer. The host launcher comes from the exact local tarballs, + * so no registry copy, tsx, path mapping, or workspace resolution can hide missing files, dependency + * errors, or lost executable modes. npm may still query registry metadata for an incompatible optional platform * package that cannot supply the host launcher. * * The installed launcher must match the host architecture, remain executable, and either confine a @@ -38,6 +38,13 @@ const WORKSPACE_CLOSURE = [ 'packages/util/brand', 'packages/util/timeout', 'packages/support/invariants', + // The framework and the vendored packages the closure declares outright: + // rescoped into @deepseek-ai, so the consumer installs this repository's + // copies. Schemastery is a hard dependency of three members above, not a + // peer, so npm resolves it while installing them. + 'vendor/cordis', + 'vendor/cosmokit', + 'vendor/schemastery', ] /** ELF `e_machine` (offset 18, LE) for this host: x86-64 = 62, AArch64 = 183. */ @@ -96,10 +103,10 @@ describe.skipIf(!packable)('sandbox-local: packed-tarball distribution (publish- } tarballs.push(...nativeTarballs) - // Peer ranges resolve to the tarballs; Cordis is pinned to their peer range. Do not omit optional + // Peer ranges resolve to the tarballs, the framework peer included. Do not omit optional // dependencies because the launcher selects its OS/CPU package through one. writeFileSync(join(consumerDir, 'package.json'), JSON.stringify({ name: 'dsh-packed-consumer', private: true, type: 'module' })) - const install = spawnSync('npm', ['install', '--no-audit', '--no-fund', ...tarballs, 'cordis@4.0.0-rc.7'], { + const install = spawnSync('npm', ['install', '--no-audit', '--no-fund', ...tarballs], { cwd: consumerDir, encoding: 'utf8', timeout: 300_000, @@ -113,7 +120,7 @@ describe.skipIf(!packable)('sandbox-local: packed-tarball distribution (publish- writeFileSync(join(consumerDir, 'consumer.mjs'), ` import { spawnSync } from 'node:child_process' import { existsSync } from 'node:fs' - import { Context } from 'cordis' + import { Context } from '@deepseek-ai/cordis' import { launcherPath } from '@deepseek-ai/node-addon-landlock-run' import { LocalSandboxProvider } from '@deepseek-ai/dsh-sandbox-local' const ctx = new Context() diff --git a/packages/sandbox/sandbox-local/tests/seatbelt.e2e.ts b/packages/sandbox/sandbox-local/tests/seatbelt.e2e.ts index 6d645b1a3b..4ff399dc67 100644 --- a/packages/sandbox/sandbox-local/tests/seatbelt.e2e.ts +++ b/packages/sandbox/sandbox-local/tests/seatbelt.e2e.ts @@ -4,7 +4,7 @@ import { mkdtemp, rm } from 'node:fs/promises' import { homedir, tmpdir } from 'node:os' import { join } from 'node:path' import { afterEach, describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import type { SandboxPolicy } from '@deepseek-ai/dsh-sandbox' import { LocalSandboxProvider } from '@deepseek-ai/dsh-sandbox-local' import { seatbeltProfileArgs } from '../src/profiles.ts' diff --git a/packages/sandbox/sandbox-policy/package.json b/packages/sandbox/sandbox-policy/package.json index 6124a75ff6..7636977d6e 100644 --- a/packages/sandbox/sandbox-policy/package.json +++ b/packages/sandbox/sandbox-policy/package.json @@ -30,10 +30,10 @@ "@deepseek-ai/dsh-sandbox": "^0.0.1", "@deepseek-ai/dsh-session": "^0.0.1", "@deepseek-ai/dsh-system-prompt": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { "@deepseek-ai/dsh-agent": "workspace:^", @@ -41,6 +41,6 @@ "@deepseek-ai/dsh-sandbox": "workspace:^", "@deepseek-ai/dsh-session": "workspace:^", "@deepseek-ai/dsh-system-prompt": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/sandbox/sandbox-policy/src/index.ts b/packages/sandbox/sandbox-policy/src/index.ts index 3a3aac1d70..eee5a43669 100644 --- a/packages/sandbox/sandbox-policy/src/index.ts +++ b/packages/sandbox/sandbox-policy/src/index.ts @@ -19,8 +19,8 @@ */ import { resolve as resolvePath } from 'node:path' -import { Context, Service } from 'cordis' -import z from 'schemastery' +import { Context, Service } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import type {} from '@deepseek-ai/dsh-agent' import { canonicalPath, type SandboxExecutionPolicy, type SandboxMode } from '@deepseek-ai/dsh-sandbox' import type { Session } from '@deepseek-ai/dsh-session' @@ -51,7 +51,7 @@ function renderPolicyContext(policy: SandboxExecutionPolicy): string { } } -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { sandboxPolicy: SandboxPolicyService } diff --git a/packages/sandbox/sandbox-policy/src/invariant.ts b/packages/sandbox/sandbox-policy/src/invariant.ts index 20fd176af6..32e2c998b7 100644 --- a/packages/sandbox/sandbox-policy/src/invariant.ts +++ b/packages/sandbox/sandbox-policy/src/invariant.ts @@ -1,6 +1,6 @@ /** Package-owned session-event invariants for sandbox policy. @module @deepseek-ai/dsh-sandbox-policy/invariant */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { Session, SessionEvent } from '@deepseek-ai/dsh-session' import type { InvariantFailure, InvariantInstaller } from '@deepseek-ai/dsh-invariants' import { SANDBOX_MODES } from './session-mode.ts' diff --git a/packages/sandbox/sandbox-policy/tests/invariant.spec.ts b/packages/sandbox/sandbox-policy/tests/invariant.spec.ts index d3255b305e..5ed924273a 100644 --- a/packages/sandbox/sandbox-policy/tests/invariant.spec.ts +++ b/packages/sandbox/sandbox-policy/tests/invariant.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import SessionStore, { type Session, type SessionEvent } from '@deepseek-ai/dsh-session' import InvariantService, { InvariantError } from '@deepseek-ai/dsh-invariants' import * as SandboxPolicyInvariant from '@deepseek-ai/dsh-sandbox-policy/invariant' diff --git a/packages/sandbox/sandbox-policy/tests/policy.spec.ts b/packages/sandbox/sandbox-policy/tests/policy.spec.ts index 11552f2a3a..0a239114aa 100644 --- a/packages/sandbox/sandbox-policy/tests/policy.spec.ts +++ b/packages/sandbox/sandbox-policy/tests/policy.spec.ts @@ -8,7 +8,7 @@ import { mkdirSync, mkdtempSync, realpathSync, rmSync, symlinkSync } from 'node: import { tmpdir } from 'node:os' import { join, resolve, sep } from 'node:path' import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import type { Agent } from '@deepseek-ai/dsh-agent' import { Session, SessionId } from '@deepseek-ai/dsh-session' import SandboxPolicyService, { SANDBOX_MODES, effectiveSandboxMode, setSandboxMode } from '@deepseek-ai/dsh-sandbox-policy' diff --git a/packages/sandbox/sandbox-windows-acl/package.json b/packages/sandbox/sandbox-windows-acl/package.json index 2f13b71296..8bfb1f3d80 100644 --- a/packages/sandbox/sandbox-windows-acl/package.json +++ b/packages/sandbox/sandbox-windows-acl/package.json @@ -31,7 +31,7 @@ "license": "BSD-3-Clause", "peerDependencies": { "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { "koffi": "^3.1.0" @@ -40,6 +40,6 @@ "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-pwsh-local": "workspace:^", "@deepseek-ai/dsh-sandbox-local": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/sandbox/sandbox-windows-acl/src/invariant.ts b/packages/sandbox/sandbox-windows-acl/src/invariant.ts index 35ea265a4b..95b0555d49 100644 --- a/packages/sandbox/sandbox-windows-acl/src/invariant.ts +++ b/packages/sandbox/sandbox-windows-acl/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-sandbox-windows-acl' diff --git a/packages/sandbox/sandbox-windows-acl/tests/provider-chain.spec.ts b/packages/sandbox/sandbox-windows-acl/tests/provider-chain.spec.ts index 2557b1f43b..4c3db08786 100644 --- a/packages/sandbox/sandbox-windows-acl/tests/provider-chain.spec.ts +++ b/packages/sandbox/sandbox-windows-acl/tests/provider-chain.spec.ts @@ -9,7 +9,7 @@ import { tmpdir } from 'node:os' import { describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import type { SandboxPolicy } from '@deepseek-ai/dsh-sandbox' import { LocalSandboxProvider } from '@deepseek-ai/dsh-sandbox-local' diff --git a/packages/sandbox/sandbox/package.json b/packages/sandbox/sandbox/package.json index 7c91afe76b..558588cfa7 100644 --- a/packages/sandbox/sandbox/package.json +++ b/packages/sandbox/sandbox/package.json @@ -28,12 +28,12 @@ "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-llm": "^0.0.1", "@deepseek-ai/dsh-session": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-llm": "workspace:^", "@deepseek-ai/dsh-session": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/sandbox/sandbox/src/index.ts b/packages/sandbox/sandbox/src/index.ts index 5fa3cc991b..8f69f90bbf 100644 --- a/packages/sandbox/sandbox/src/index.ts +++ b/packages/sandbox/sandbox/src/index.ts @@ -5,7 +5,7 @@ * @module @deepseek-ai/dsh-sandbox */ -import { Context, Service } from 'cordis' +import { Context, Service } from '@deepseek-ai/cordis' import { HarnessError } from '@deepseek-ai/dsh-llm' import type { SessionId } from '@deepseek-ai/dsh-session' @@ -143,7 +143,7 @@ export class SandboxUnavailableError extends HarnessError { } } -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { sandbox: SandboxProvider } diff --git a/packages/sandbox/sandbox/src/invariant.ts b/packages/sandbox/sandbox/src/invariant.ts index 7ee5be733f..4d7f6dcdf0 100644 --- a/packages/sandbox/sandbox/src/invariant.ts +++ b/packages/sandbox/sandbox/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-sandbox' diff --git a/packages/scaffold/client/package.json b/packages/scaffold/client/package.json index 3dbb236ab3..7e0a4b0540 100644 --- a/packages/scaffold/client/package.json +++ b/packages/scaffold/client/package.json @@ -28,13 +28,13 @@ "@deepseek-ai/dsh-llm": "^0.0.1", "@deepseek-ai/dsh-sdk-protocol": "^0.0.1", "@deepseek-ai/dsh-session": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-llm": "workspace:^", "@deepseek-ai/dsh-sdk-protocol": "workspace:^", "@deepseek-ai/dsh-session": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/scaffold/client/src/invariant.ts b/packages/scaffold/client/src/invariant.ts index db40e4e005..b93254ee9f 100644 --- a/packages/scaffold/client/src/invariant.ts +++ b/packages/scaffold/client/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-sdk-client' diff --git a/packages/scaffold/create-sdk/package.json b/packages/scaffold/create-sdk/package.json index 262d375563..4b40b6b2ca 100644 --- a/packages/scaffold/create-sdk/package.json +++ b/packages/scaffold/create-sdk/package.json @@ -33,10 +33,10 @@ }, "peerDependencies": { "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-invariants": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/scaffold/create-sdk/src/invariant.ts b/packages/scaffold/create-sdk/src/invariant.ts index 368b46fc70..a4de619111 100644 --- a/packages/scaffold/create-sdk/src/invariant.ts +++ b/packages/scaffold/create-sdk/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/create-sdk' diff --git a/packages/scaffold/create-sdk/tests/link-workspace.e2e.ts b/packages/scaffold/create-sdk/tests/link-workspace.e2e.ts index b978c8217e..0e995202fd 100644 --- a/packages/scaffold/create-sdk/tests/link-workspace.e2e.ts +++ b/packages/scaffold/create-sdk/tests/link-workspace.e2e.ts @@ -73,7 +73,7 @@ describe.skipIf(!existsSync(builtScripts))('live-linked generated projects', () }) await writeFile(join(root, 'plugins/probe/src/index.ts'), ` import { writeFileSync } from 'node:fs' - import type { Context } from 'cordis' + import type { Context } from '@deepseek-ai/cordis' export const name = 'probe' export function apply(_ctx: Context): void { writeFileSync(new URL('../../../plugin-loaded', import.meta.url), 'loaded\\n') @@ -119,7 +119,7 @@ describe.skipIf(!existsSync(builtScripts))('live-linked generated projects', () const manifest = JSON.parse(await readFile(join(root, 'package.json'), 'utf8')) as { dependencies: Record } - expect(manifest.dependencies.cordis).toMatch(name === 'npm' ? /^file:/ : name === 'pnpm' ? /^link:/ : /^portal:/) + expect(manifest.dependencies['@deepseek-ai/cordis']).toMatch(name === 'npm' ? /^file:/ : name === 'pnpm' ? /^link:/ : /^portal:/) expect(manifest.dependencies).not.toHaveProperty('node-addon-require-builtin') }, 180_000) } diff --git a/packages/scaffold/helper/package.json b/packages/scaffold/helper/package.json index bed70dbbda..f65b51052a 100644 --- a/packages/scaffold/helper/package.json +++ b/packages/scaffold/helper/package.json @@ -34,7 +34,7 @@ "@deepseek-ai/dsh-brand": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-subprocess": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-brand": "workspace:^", @@ -47,6 +47,6 @@ "@deepseek-ai/dsh-tool-subagent": "workspace:^", "@deepseek-ai/dsh-tool-todo": "workspace:^", "@deepseek-ai/dsh-tool-web": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/scaffold/helper/src/features/builtin/index.ts b/packages/scaffold/helper/src/features/builtin/index.ts index abdcc35dd5..38246e6cf2 100644 --- a/packages/scaffold/helper/src/features/builtin/index.ts +++ b/packages/scaffold/helper/src/features/builtin/index.ts @@ -101,7 +101,7 @@ config: id: 'default', label: 'Cordis HMR', default: true, - resources: [{ kind: 'npm-cordis-config-entry', id: 'hmr', package: '@cordisjs/plugin-hmr' }], + resources: [{ kind: 'npm-cordis-config-entry', id: 'hmr', package: '@deepseek-ai/cordis-plugin-hmr' }], }], }, { diff --git a/packages/scaffold/helper/src/features/builtin/spine.ts b/packages/scaffold/helper/src/features/builtin/spine.ts index 3e1acb98fb..26f0d03232 100644 --- a/packages/scaffold/helper/src/features/builtin/spine.ts +++ b/packages/scaffold/helper/src/features/builtin/spine.ts @@ -26,7 +26,7 @@ class SpineOption extends FeatureOption { override contribution(_profile: ProjectProfile): ProjectContribution { return new ProjectContribution([ - ...npmCordisConfigEntry(ID, { id: 'timer', name: '@cordisjs/plugin-timer' }), + ...npmCordisConfigEntry(ID, { id: 'timer', name: '@deepseek-ai/cordis-plugin-timer' }), ...npmCordisConfigEntry(ID, { id: 'llm', name: '@deepseek-ai/dsh-llm' }), ...npmCordisConfigEntry(ID, { id: 'session', name: '@deepseek-ai/dsh-session' }), ...npmCordisConfigEntry(ID, { diff --git a/packages/scaffold/helper/src/invariant.ts b/packages/scaffold/helper/src/invariant.ts index 9185ac8867..dfebbb2006 100644 --- a/packages/scaffold/helper/src/invariant.ts +++ b/packages/scaffold/helper/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-helper' diff --git a/packages/scaffold/helper/src/package-managers/link-workspace.ts b/packages/scaffold/helper/src/package-managers/link-workspace.ts index 3fbc063451..4d185ce4d1 100644 --- a/packages/scaffold/helper/src/package-managers/link-workspace.ts +++ b/packages/scaffold/helper/src/package-managers/link-workspace.ts @@ -73,7 +73,7 @@ export class LinkWorkspace { if (packages.has(manifest.name)) throw new Error(`duplicate linked package name: ${manifest.name}`) packages.set(manifest.name, { directory, manifest }) } - if (!packages.has('cordis') || !packages.has('@deepseek-ai/dsh-scripts')) { + if (!packages.has('@deepseek-ai/cordis') || !packages.has('@deepseek-ai/dsh-scripts')) { throw new Error(`not a DeepSeek Harness repository root: ${absolute}`) } return new LinkWorkspace(absolute, packages) diff --git a/packages/scaffold/helper/src/plugins/local-plugin-blueprint.ts b/packages/scaffold/helper/src/plugins/local-plugin-blueprint.ts index 616d0cedd8..da978e845c 100644 --- a/packages/scaffold/helper/src/plugins/local-plugin-blueprint.ts +++ b/packages/scaffold/helper/src/plugins/local-plugin-blueprint.ts @@ -83,7 +83,7 @@ export class LocalPluginBlueprint { documents(projectName: string, releaseVersion: string): TextProjectFile[] { const name = this.packageName(projectName) const toolName = this.name.replaceAll('-', '_') - const cordisSpec = resolveNpmDependency('cordis', 'devDependencies', releaseVersion).spec + const cordisSpec = resolveNpmDependency('@deepseek-ai/cordis', 'devDependencies', releaseVersion).spec const manifest = { name, version: '0.0.0', @@ -94,10 +94,10 @@ export class LocalPluginBlueprint { exports: { '.': { types: './lib/index.d.ts', default: './lib/index.js' } }, peerDependencies: { ...this.kind === 'tool' ? { '@deepseek-ai/dsh-tools': `^${releaseVersion}` } : {}, - cordis: cordisSpec, + '@deepseek-ai/cordis': cordisSpec, }, devDependencies: { - cordis: cordisSpec, + '@deepseek-ai/cordis': cordisSpec, }, } const tsconfig = { diff --git a/packages/scaffold/helper/src/project/npm-dependency-policy.ts b/packages/scaffold/helper/src/project/npm-dependency-policy.ts index 727bd6648a..a876973a29 100644 --- a/packages/scaffold/helper/src/project/npm-dependency-policy.ts +++ b/packages/scaffold/helper/src/project/npm-dependency-policy.ts @@ -19,17 +19,17 @@ export interface BaselineNpmDependencies { } const EXTERNAL_NPM_DEPENDENCY_SPECS: Readonly> = { - '@cordisjs/plugin-hmr': '^1.0.15', - '@cordisjs/plugin-timer': '^1.1.2', + '@deepseek-ai/cordis-plugin-hmr': '^1.0.15', + '@deepseek-ai/cordis-plugin-timer': '^1.1.2', '@types/node': '^22.20.0', - cordis: '^4.0.0-rc.7', + '@deepseek-ai/cordis': '^4.0.0-rc.7', tsdown: '0.22.2', tsx: '^4.22.4', typescript: '^6.0.3', } const BASELINE_NPM_DEPENDENCY_NAMES: Readonly> = { - dependencies: ['@deepseek-ai/dsh-scripts', 'cordis'], + dependencies: ['@deepseek-ai/dsh-scripts', '@deepseek-ai/cordis'], devDependencies: ['@types/node', 'tsdown', 'tsx', 'typescript'], } diff --git a/packages/scaffold/helper/src/templates/assets/local-plugin.ts.tpl b/packages/scaffold/helper/src/templates/assets/local-plugin.ts.tpl index 2f15bdef91..76b12769bb 100644 --- a/packages/scaffold/helper/src/templates/assets/local-plugin.ts.tpl +++ b/packages/scaffold/helper/src/templates/assets/local-plugin.ts.tpl @@ -1,5 +1,5 @@ /** Local Cordis plugin. */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' export const name = '{{pluginName}}' diff --git a/packages/scaffold/helper/src/templates/assets/local-tool.ts.tpl b/packages/scaffold/helper/src/templates/assets/local-tool.ts.tpl index 4333d41c70..a48a73375c 100644 --- a/packages/scaffold/helper/src/templates/assets/local-tool.ts.tpl +++ b/packages/scaffold/helper/src/templates/assets/local-tool.ts.tpl @@ -1,5 +1,5 @@ /** Project-local model-facing tool. */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { defineTool } from '@deepseek-ai/dsh-tools' export const name = '{{pluginName}}' diff --git a/packages/scaffold/helper/tests/documents.spec.ts b/packages/scaffold/helper/tests/documents.spec.ts index 317a9ed3ab..12e97dc6c0 100644 --- a/packages/scaffold/helper/tests/documents.spec.ts +++ b/packages/scaffold/helper/tests/documents.spec.ts @@ -279,10 +279,10 @@ describe('package manager strategies', () => { expect(inferPackageManagerName(undefined, 'unknown/1')).toBeUndefined() expect(inferPackageManagerName('yarn', undefined)).toBe('yarn') expect(() => createPackageManager('npm', 'invalid')).toThrow('invalid package manager version') - expect(resolveNpmDependency('cordis', 'devDependencies', '0.0.1')).toEqual({ + expect(resolveNpmDependency('@deepseek-ai/cordis', 'devDependencies', '0.0.1')).toEqual({ section: 'devDependencies', spec: '^4.0.0-rc.7', }) - expect(resolveNpmDependency('@cordisjs/plugin-hmr', 'dependencies', '0.0.1').spec).toBe('^1.0.15') + expect(resolveNpmDependency('@deepseek-ai/cordis-plugin-hmr', 'dependencies', '0.0.1').spec).toBe('^1.0.15') expect(resolveNpmDependency('tsdown', 'devDependencies', '0.0.1').spec).toBe('0.22.2') expect(resolveNpmDependency('@deepseek-ai/dsh-tools', 'dependencies', '1.2.3').spec).toBe('^1.2.3') expect(() => resolveNpmDependency('unknown', 'dependencies', '0.0.1')).toThrow('no generated-project') @@ -353,23 +353,23 @@ describe('package manager strategies', () => { await mkdir(join(root, 'vendor', 'cordis'), { recursive: true }) await mkdir(join(root, 'packages', 'sdk', 'scripts'), { recursive: true }) await mkdir(join(root, 'packages', 'sdk', 'helper'), { recursive: true }) - await writeFile(join(root, 'vendor', 'cordis', 'package.json'), JSON.stringify({ name: 'cordis' })) + await writeFile(join(root, 'vendor', 'cordis', 'package.json'), JSON.stringify({ name: '@deepseek-ai/cordis' })) await writeFile(join(root, 'packages', 'sdk', 'helper', 'package.json'), JSON.stringify({ name: '@deepseek-ai/dsh-helper' })) await writeFile(join(root, 'packages', 'sdk', 'scripts', 'package.json'), JSON.stringify({ - name: '@deepseek-ai/dsh-scripts', dependencies: { '@deepseek-ai/dsh-helper': '^0.0.1' }, peerDependencies: { cordis: '^4' }, + name: '@deepseek-ai/dsh-scripts', dependencies: { '@deepseek-ai/dsh-helper': '^0.0.1' }, peerDependencies: { '@deepseek-ai/cordis': '^4' }, })) const workspace = await LinkWorkspace.open(root) expect(workspace.closure(['@deepseek-ai/dsh-scripts'])).toEqual([ - '@deepseek-ai/dsh-helper', '@deepseek-ai/dsh-scripts', 'cordis', + '@deepseek-ai/cordis', '@deepseek-ai/dsh-helper', '@deepseek-ai/dsh-scripts', ]) const manifest = PackageJsonFile.create('{"name":"consumer","description":"test"}') manifest.setNpmDependency('dependencies', '@deepseek-ai/dsh-scripts', '^0.0.1') const pnpmWorkspace = PnpmWorkspaceFile.create() workspace.apply(join(root, 'consumer'), manifest, new PnpmPackageManager('10.0.0'), [pnpmWorkspace]) - expect(manifest.npmDependency('cordis')?.spec).toMatch(/^link:/) + expect(manifest.npmDependency('@deepseek-ai/cordis')?.spec).toMatch(/^link:/) expect(pnpmWorkspace.serialize()).toContain('autoInstallPeers: false') - expect(workspace.packageDirectory('cordis')).toBe(join(root, 'vendor', 'cordis')) - expect(await readFile(join(root, 'vendor', 'cordis', 'package.json'), 'utf8')).toContain('cordis') + expect(workspace.packageDirectory('@deepseek-ai/cordis')).toBe(join(root, 'vendor', 'cordis')) + expect(await readFile(join(root, 'vendor', 'cordis', 'package.json'), 'utf8')).toContain('@deepseek-ai/cordis') expect(workspace.packageDirectory('missing')).toBeUndefined() // A generated workspace member resolves its own dependencies: every local name it // declares relinks, while a peer keeps the range package managers require there. diff --git a/packages/scaffold/helper/tests/project.spec.ts b/packages/scaffold/helper/tests/project.spec.ts index 01918d7570..b803e658d7 100644 --- a/packages/scaffold/helper/tests/project.spec.ts +++ b/packages/scaffold/helper/tests/project.spec.ts @@ -187,12 +187,12 @@ describe('SdkProject and ProjectEditSession', () => { expect(project.cordis.entry('scope-invariant')?.name).toBe('@deepseek-ai/dsh-scope/invariant') expect(project.cordis.entry('agent-loop-invariant')?.name).toBe('@deepseek-ai/dsh-agent-loop/invariant') expect(project.cordis.entry('system-prompt')?.config?.persona).toContain('{{cwd}}') - expect(project.packageManifest().dependencies?.['@cordisjs/plugin-timer']).toBe('^1.1.2') - expect(project.packageManifest().dependencies?.['@cordisjs/plugin-hmr']).toBe('^1.0.15') + expect(project.packageManifest().dependencies?.['@deepseek-ai/cordis-plugin-timer']).toBe('^1.1.2') + expect(project.packageManifest().dependencies?.['@deepseek-ai/cordis-plugin-hmr']).toBe('^1.0.15') expect(project.packageManifest().dependencies?.['@deepseek-ai/dsh-scope']).toBe('^0.0.1') expect(project.packageManifest().dependencies).not.toHaveProperty('@deepseek-ai/dsh-scope/invariant') expect(project.packageManifest().dependencies).not.toHaveProperty('node-addon-require-builtin') - expect(project.cordis.entry('hmr')).toMatchObject({ name: '@cordisjs/plugin-hmr' }) + expect(project.cordis.entry('hmr')).toMatchObject({ name: '@deepseek-ai/cordis-plugin-hmr' }) expect(project.cordis.entry('llm-deepseek')).not.toHaveProperty('config.apiKey') expect(project.cordis.entry('llm-deepseek')?.config).not.toHaveProperty('baseURL') expect(project.cordis.entry('llm-deepseek')?.config).not.toHaveProperty('models') @@ -502,7 +502,7 @@ describe('SdkProject and ProjectEditSession', () => { internals.applyResource(transient, undefined) internals.removeResource(transient) internals.replaceContribution( - new ProjectContribution([{ kind: 'npm-dependency', key: resourceKey('shared'), name: 'cordis', section: 'dependencies' }]), + new ProjectContribution([{ kind: 'npm-dependency', key: resourceKey('shared'), name: '@deepseek-ai/cordis', section: 'dependencies' }]), new ProjectContribution([{ kind: 'cordis-config-entry', key: resourceKey('shared'), entry: { id: 'new', name: 'new' }, ownedConfigKeys: [], }]), diff --git a/packages/scaffold/protocol/package.json b/packages/scaffold/protocol/package.json index fe7d057c11..c0d6ff1046 100644 --- a/packages/scaffold/protocol/package.json +++ b/packages/scaffold/protocol/package.json @@ -28,13 +28,13 @@ "@deepseek-ai/dsh-llm": "^0.0.1", "@deepseek-ai/dsh-session": "^0.0.1", "@deepseek-ai/dsh-subagent": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-llm": "workspace:^", "@deepseek-ai/dsh-session": "workspace:^", "@deepseek-ai/dsh-subagent": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/scaffold/protocol/src/invariant.ts b/packages/scaffold/protocol/src/invariant.ts index c1f0b45f2d..948fb16d13 100644 --- a/packages/scaffold/protocol/src/invariant.ts +++ b/packages/scaffold/protocol/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-sdk-protocol' diff --git a/packages/scaffold/scripts/package.json b/packages/scaffold/scripts/package.json index deef54831f..d6ef776d67 100644 --- a/packages/scaffold/scripts/package.json +++ b/packages/scaffold/scripts/package.json @@ -42,7 +42,7 @@ "peerDependencies": { "@deepseek-ai/dsh-app-boot": "workspace:^", "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.7", + "@deepseek-ai/cordis": "^4.0.0-rc.7", "tsdown": "^0.22.2", "tsx": "^4.22.4" }, @@ -57,7 +57,7 @@ "devDependencies": { "@deepseek-ai/dsh-app-boot": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", - "cordis": "^4.0.0-rc.7", + "@deepseek-ai/cordis": "^4.0.0-rc.7", "tsdown": "^0.22.2", "tsx": "^4.22.4" } diff --git a/packages/scaffold/scripts/src/invariant.ts b/packages/scaffold/scripts/src/invariant.ts index 72e97f3628..b43a6d1cf3 100644 --- a/packages/scaffold/scripts/src/invariant.ts +++ b/packages/scaffold/scripts/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-scripts' diff --git a/packages/scaffold/scripts/src/runtime.ts b/packages/scaffold/scripts/src/runtime.ts index 426ac90e5b..b0d4c8c5ad 100644 --- a/packages/scaffold/scripts/src/runtime.ts +++ b/packages/scaffold/scripts/src/runtime.ts @@ -8,7 +8,7 @@ import { register as registerHook } from 'node:module' import { access, readFile, readdir } from 'node:fs/promises' import { dirname, resolve } from 'node:path' import { fileURLToPath, pathToFileURL } from 'node:url' -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { boot, installFailLoud, loadEnv, resolveConfigPath } from '@deepseek-ai/dsh-app-boot' import { parseSdkBootArgs } from './args.ts' diff --git a/packages/scaffold/scripts/tests/scripts.spec.ts b/packages/scaffold/scripts/tests/scripts.spec.ts index 6d2ea27991..a1a4a07517 100644 --- a/packages/scaffold/scripts/tests/scripts.spec.ts +++ b/packages/scaffold/scripts/tests/scripts.spec.ts @@ -323,7 +323,7 @@ describe('build profiles and invocation', () => { await writeFile(join(root, 'cordis.yml'), '[]\n') const byUrl = await startSDK(pathToFileURL(join(root, 'cordis.yml'))) await byUrl.fiber.dispose() - const byRun = await runSDK(undefined, { cwd: root }) as import('cordis').Context + const byRun = await runSDK(undefined, { cwd: root }) as import('@deepseek-ai/cordis').Context await byRun.fiber.dispose() const dev = await startSDK('./cordis.yml', { cwd: root, dev: true }) await dev.fiber.dispose() diff --git a/packages/scaffold/server/package.json b/packages/scaffold/server/package.json index 573f724ae0..457a375b04 100644 --- a/packages/scaffold/server/package.json +++ b/packages/scaffold/server/package.json @@ -25,7 +25,7 @@ ], "license": "BSD-3-Clause", "dependencies": { - "schemastery": "^3.17.0" + "@deepseek-ai/schemastery": "^3.17.0" }, "peerDependencies": { "@deepseek-ai/dsh-agent": "^0.0.1", @@ -36,10 +36,10 @@ "@deepseek-ai/dsh-sdk-protocol": "^0.0.1", "@deepseek-ai/dsh-session": "^0.0.1", "@deepseek-ai/dsh-subagent": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { - "@cordisjs/plugin-loader": "workspace:^", + "@deepseek-ai/cordis-plugin-loader": "workspace:^", "@deepseek-ai/dsh-agent": "workspace:^", "@deepseek-ai/dsh-agent-spine-demo": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", @@ -50,6 +50,6 @@ "@deepseek-ai/dsh-session": "workspace:^", "@deepseek-ai/dsh-session-persistence-jsonl": "workspace:^", "@deepseek-ai/dsh-subagent": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/scaffold/server/src/index.ts b/packages/scaffold/server/src/index.ts index be7252007a..70f24dfaee 100644 --- a/packages/scaffold/server/src/index.ts +++ b/packages/scaffold/server/src/index.ts @@ -13,9 +13,9 @@ * @module @deepseek-ai/dsh-jsonrpc */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { Readable, Writable } from 'node:stream' -import Schema from 'schemastery' +import Schema from '@deepseek-ai/schemastery' import { JsonRpcLineTransport } from '@deepseek-ai/dsh-sdk-protocol' import { HarnessSdkServer } from './server.ts' diff --git a/packages/scaffold/server/src/invariant.ts b/packages/scaffold/server/src/invariant.ts index 1a3c9b053b..f59a90188b 100644 --- a/packages/scaffold/server/src/invariant.ts +++ b/packages/scaffold/server/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-jsonrpc' diff --git a/packages/scaffold/server/src/server.ts b/packages/scaffold/server/src/server.ts index e6c22d7ff2..da5f2e24c4 100644 --- a/packages/scaffold/server/src/server.ts +++ b/packages/scaffold/server/src/server.ts @@ -5,7 +5,7 @@ * @module @deepseek-ai/dsh-jsonrpc/server */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { resolve } from 'node:path' import type { Agent, AgentHandle } from '@deepseek-ai/dsh-agent' import { createUserMessage } from '@deepseek-ai/dsh-llm' diff --git a/packages/scaffold/server/tests/plugin-apply.spec.ts b/packages/scaffold/server/tests/plugin-apply.spec.ts index b2109b8c51..1e5b9b3212 100644 --- a/packages/scaffold/server/tests/plugin-apply.spec.ts +++ b/packages/scaffold/server/tests/plugin-apply.spec.ts @@ -5,7 +5,7 @@ import { join } from 'node:path' import { tmpdir } from 'node:os' import { PassThrough, Writable } from 'node:stream' import { afterEach, describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import * as agentCore from '@deepseek-ai/dsh-agent-spine-demo' import SessionPersistenceJsonl from '@deepseek-ai/dsh-session-persistence-jsonl' import * as jsonrpc from '../src/index.ts' diff --git a/packages/scaffold/server/tests/plugin-shape.spec.ts b/packages/scaffold/server/tests/plugin-shape.spec.ts index 97afa7d3ed..f268e4c24c 100644 --- a/packages/scaffold/server/tests/plugin-shape.spec.ts +++ b/packages/scaffold/server/tests/plugin-shape.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import Loader from '@cordisjs/plugin-loader' +import Loader from '@deepseek-ai/cordis-plugin-loader' import * as jsonrpc from '../src/index.ts' /** diff --git a/packages/scaffold/server/tests/server.spec.ts b/packages/scaffold/server/tests/server.spec.ts index 714fc0ada3..6cd1c6ed99 100644 --- a/packages/scaffold/server/tests/server.spec.ts +++ b/packages/scaffold/server/tests/server.spec.ts @@ -5,7 +5,7 @@ import { mkdtemp, rm } from 'node:fs/promises' import { join } from 'node:path' import { tmpdir } from 'node:os' import { afterEach, describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import AgentRegistry, { type Agent, type AgentHandle } from '@deepseek-ai/dsh-agent' import SessionStore, { SessionId } from '@deepseek-ai/dsh-session' diff --git a/packages/scaffold/telemetry/package.json b/packages/scaffold/telemetry/package.json index 6fe62e35fc..3ebd894a99 100644 --- a/packages/scaffold/telemetry/package.json +++ b/packages/scaffold/telemetry/package.json @@ -31,12 +31,12 @@ "@deepseek-ai/dsh-brand": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-paths": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-brand": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-paths": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/scaffold/telemetry/src/invariant.ts b/packages/scaffold/telemetry/src/invariant.ts index c3676a1384..bee683c50e 100644 --- a/packages/scaffold/telemetry/src/invariant.ts +++ b/packages/scaffold/telemetry/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-telemetry' diff --git a/packages/self-modification/tool-cordis/package.json b/packages/self-modification/tool-cordis/package.json index 0b1c78cf8f..5544c84b49 100644 --- a/packages/self-modification/tool-cordis/package.json +++ b/packages/self-modification/tool-cordis/package.json @@ -28,14 +28,14 @@ "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-scope": "^0.0.1", "@deepseek-ai/dsh-tools": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { - "@cordisjs/plugin-loader": "^1.0.0-rc.5", - "@cordisjs/plugin-timer": "workspace:^", + "@deepseek-ai/cordis-plugin-loader": "^1.0.0-rc.5", + "@deepseek-ai/cordis-plugin-timer": "workspace:^", "@deepseek-ai/dsh-agent": "workspace:^", "@deepseek-ai/dsh-agent-loop": "workspace:^", "@deepseek-ai/dsh-agent-loop-testkit": "workspace:^", @@ -45,6 +45,6 @@ "@deepseek-ai/dsh-session": "workspace:^", "@deepseek-ai/dsh-system-prompt": "workspace:^", "@deepseek-ai/dsh-tools": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/self-modification/tool-cordis/src/fiber-state.ts b/packages/self-modification/tool-cordis/src/fiber-state.ts index dcd9da149b..2c9dbfd240 100644 --- a/packages/self-modification/tool-cordis/src/fiber-state.ts +++ b/packages/self-modification/tool-cordis/src/fiber-state.ts @@ -5,7 +5,7 @@ * @module @deepseek-ai/dsh-tool-cordis/fiber-state */ -import type { FiberState as FiberStateEnum } from 'cordis' +import type { FiberState as FiberStateEnum } from '@deepseek-ai/cordis' /** Value mirror of the cordis `FiberState` const enum (see the module doc for why a mirror exists). */ export const FiberState = { diff --git a/packages/self-modification/tool-cordis/src/guard.ts b/packages/self-modification/tool-cordis/src/guard.ts index 22d85936f4..7724e339be 100644 --- a/packages/self-modification/tool-cordis/src/guard.ts +++ b/packages/self-modification/tool-cordis/src/guard.ts @@ -12,8 +12,8 @@ * @module @deepseek-ai/dsh-tool-cordis/guard */ -import { Context } from 'cordis' -import type { Plugin } from 'cordis' +import { Context } from '@deepseek-ai/cordis' +import type { Plugin } from '@deepseek-ai/cordis' import { scopeOf } from '@deepseek-ai/dsh-scope' import { assertSupportedJsonSchema, defineTool } from '@deepseek-ai/dsh-tools' import type { ToolDefinition } from '@deepseek-ai/dsh-tools' diff --git a/packages/self-modification/tool-cordis/src/index.ts b/packages/self-modification/tool-cordis/src/index.ts index 46c51fa6ad..272ed800a0 100644 --- a/packages/self-modification/tool-cordis/src/index.ts +++ b/packages/self-modification/tool-cordis/src/index.ts @@ -7,8 +7,8 @@ * @module @deepseek-ai/dsh-tool-cordis */ -import type { Context } from 'cordis' -import z from 'schemastery' +import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import { defineTool } from '@deepseek-ai/dsh-tools' import { STATE_LABELS } from './fiber-state.ts' import { isPlugin, pluginName } from './guard.ts' diff --git a/packages/self-modification/tool-cordis/src/inspect.ts b/packages/self-modification/tool-cordis/src/inspect.ts index 08bbeb44cf..c787be72d2 100644 --- a/packages/self-modification/tool-cordis/src/inspect.ts +++ b/packages/self-modification/tool-cordis/src/inspect.ts @@ -6,7 +6,7 @@ * @module @deepseek-ai/dsh-tool-cordis/inspect */ -import type { Context, Fiber } from 'cordis' +import type { Context, Fiber } from '@deepseek-ai/cordis' import type { ScopeKey } from '@deepseek-ai/dsh-scope' import { EVENT_API, INHERITED_CTX_API, SERVICE_API, TYPE_API } from './api-catalog.ts' import type { EventApiEntry, InheritedApiEntry, ServiceApiEntry, TypeApiEntry } from './api-catalog.ts' diff --git a/packages/self-modification/tool-cordis/src/invariant.ts b/packages/self-modification/tool-cordis/src/invariant.ts index 6fd73d0353..3b58f40fd7 100644 --- a/packages/self-modification/tool-cordis/src/invariant.ts +++ b/packages/self-modification/tool-cordis/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-tool-cordis' diff --git a/packages/self-modification/tool-cordis/src/mount.ts b/packages/self-modification/tool-cordis/src/mount.ts index 942d45eb79..45e0a429fb 100644 --- a/packages/self-modification/tool-cordis/src/mount.ts +++ b/packages/self-modification/tool-cordis/src/mount.ts @@ -9,7 +9,7 @@ * @module @deepseek-ai/dsh-tool-cordis/mount */ -import type { Context, Fiber, Plugin } from 'cordis' +import type { Context, Fiber, Plugin } from '@deepseek-ai/cordis' import { guardedPlugin } from './guard.ts' /** One tracked dynamic mount: the fiber plus the display name captured at mount time. */ diff --git a/packages/self-modification/tool-cordis/tests/cordis-lifecycle.spec.ts b/packages/self-modification/tool-cordis/tests/cordis-lifecycle.spec.ts index b290ae998e..e5bba585a7 100644 --- a/packages/self-modification/tool-cordis/tests/cordis-lifecycle.spec.ts +++ b/packages/self-modification/tool-cordis/tests/cordis-lifecycle.spec.ts @@ -1,4 +1,4 @@ -import { Context, CordisError, FiberState, type Fiber } from 'cordis' +import { Context, CordisError, FiberState, type Fiber } from '@deepseek-ai/cordis' import { describe, expect, it } from 'vitest' /** diff --git a/packages/self-modification/tool-cordis/tests/helpers.ts b/packages/self-modification/tool-cordis/tests/helpers.ts index b049c6c1fa..e608e4633c 100644 --- a/packages/self-modification/tool-cordis/tests/helpers.ts +++ b/packages/self-modification/tool-cordis/tests/helpers.ts @@ -1,5 +1,5 @@ -import { Context } from 'cordis' -import Timer from '@cordisjs/plugin-timer' +import { Context } from '@deepseek-ai/cordis' +import Timer from '@deepseek-ai/cordis-plugin-timer' import { CallId } from '@deepseek-ai/dsh-llm' import SystemPrompt from '@deepseek-ai/dsh-system-prompt' import ToolRegistry from '@deepseek-ai/dsh-tools' diff --git a/packages/self-modification/tool-cordis/tests/inspect.spec.ts b/packages/self-modification/tool-cordis/tests/inspect.spec.ts index ca9fb4e03f..42415619e1 100644 --- a/packages/self-modification/tool-cordis/tests/inspect.spec.ts +++ b/packages/self-modification/tool-cordis/tests/inspect.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import type { Context, Fiber } from 'cordis' +import type { Context, Fiber } from '@deepseek-ai/cordis' import { FiberState } from '../src/fiber-state.ts' import { describeApi, describeEvents, describePlugins, describeServices } from '../src/inspect.ts' import { call, LISTENER_CODE, setup, text } from './helpers.ts' diff --git a/packages/self-modification/tool-cordis/tests/integration.spec.ts b/packages/self-modification/tool-cordis/tests/integration.spec.ts index 488ab996b3..3697ea1b2b 100644 --- a/packages/self-modification/tool-cordis/tests/integration.spec.ts +++ b/packages/self-modification/tool-cordis/tests/integration.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { createUserMessage, CallId } from '@deepseek-ai/dsh-llm' import { SessionId } from '@deepseek-ai/dsh-session' import type { Agent } from '@deepseek-ai/dsh-agent' diff --git a/packages/self-modification/tool-cordis/tests/tool-cordis.spec.ts b/packages/self-modification/tool-cordis/tests/tool-cordis.spec.ts index 32846e35dd..030260d3c8 100644 --- a/packages/self-modification/tool-cordis/tests/tool-cordis.spec.ts +++ b/packages/self-modification/tool-cordis/tests/tool-cordis.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import Loader from '@cordisjs/plugin-loader' +import Loader from '@deepseek-ai/cordis-plugin-loader' import * as tool from '../src/index.ts' import { setup } from './helpers.ts' diff --git a/packages/self-modification/tool-cordis/tests/unmount-hmr.spec.ts b/packages/self-modification/tool-cordis/tests/unmount-hmr.spec.ts index 42c4c0196c..062da430e5 100644 --- a/packages/self-modification/tool-cordis/tests/unmount-hmr.spec.ts +++ b/packages/self-modification/tool-cordis/tests/unmount-hmr.spec.ts @@ -1,5 +1,5 @@ import { afterEach, describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import SystemPrompt from '@deepseek-ai/dsh-system-prompt' import ToolRegistry from '@deepseek-ai/dsh-tools' import * as tool from '../src/index.ts' diff --git a/packages/session-query/session-query-sqlite/package.json b/packages/session-query/session-query-sqlite/package.json index 4813b76b10..d2ca6da01a 100644 --- a/packages/session-query/session-query-sqlite/package.json +++ b/packages/session-query/session-query-sqlite/package.json @@ -29,7 +29,7 @@ "@deepseek-ai/dsh-session": "^0.0.1", "@deepseek-ai/dsh-session-persistence": "^0.0.1", "@deepseek-ai/dsh-session-query": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "peerDependenciesMeta": { "@deepseek-ai/dsh-session-persistence": { @@ -37,15 +37,15 @@ } }, "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { - "@cordisjs/plugin-loader": "workspace:^", + "@deepseek-ai/cordis-plugin-loader": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-session": "workspace:^", "@deepseek-ai/dsh-session-persistence": "workspace:^", "@deepseek-ai/dsh-session-persistence-sqlite": "workspace:^", "@deepseek-ai/dsh-session-query": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/session-query/session-query-sqlite/src/index.ts b/packages/session-query/session-query-sqlite/src/index.ts index dc67665f77..473146168b 100644 --- a/packages/session-query/session-query-sqlite/src/index.ts +++ b/packages/session-query/session-query-sqlite/src/index.ts @@ -6,8 +6,8 @@ import { createHash, randomUUID } from 'node:crypto' import type { DatabaseSync } from 'node:sqlite' -import { Context, Service, type Fiber } from 'cordis' -import z from 'schemastery' +import { Context, Service, type Fiber } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import type { Session, SessionEvent, SessionHeader, SessionId } from '@deepseek-ai/dsh-session' import type SessionPersistence from '@deepseek-ai/dsh-session-persistence' import type { @@ -65,7 +65,7 @@ export { /** Boot-context slot for a launcher-owned absolute path to this process's derived query index. */ export const SESSION_QUERY_SQLITE_PATH_KEY = 'launcherSessionQueryPath' -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { /** Launcher-owned absolute path to this process's disposable derived query index. */ launcherSessionQueryPath?: string diff --git a/packages/session-query/session-query-sqlite/src/invariant.ts b/packages/session-query/session-query-sqlite/src/invariant.ts index 011b121eaf..6d9761807a 100644 --- a/packages/session-query/session-query-sqlite/src/invariant.ts +++ b/packages/session-query/session-query-sqlite/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-session-query-sqlite' diff --git a/packages/session-query/session-query-sqlite/tests/load-path.e2e.ts b/packages/session-query/session-query-sqlite/tests/load-path.e2e.ts index 01bfa60c43..aad427f10f 100644 --- a/packages/session-query/session-query-sqlite/tests/load-path.e2e.ts +++ b/packages/session-query/session-query-sqlite/tests/load-path.e2e.ts @@ -6,8 +6,8 @@ import { createUserMessage } from '@deepseek-ai/dsh-llm' */ import { afterEach, describe, expect, it } from 'vitest' -import { Context } from 'cordis' -import Loader from '@cordisjs/plugin-loader' +import { Context } from '@deepseek-ai/cordis' +import Loader from '@deepseek-ai/cordis-plugin-loader' import { SESSION_FORMAT_VERSION, SessionId } from '@deepseek-ai/dsh-session' import SessionStore from '@deepseek-ai/dsh-session' import SessionPersistenceSqlite from '@deepseek-ai/dsh-session-persistence-sqlite' diff --git a/packages/session-query/session-query-sqlite/tests/sqlite.spec.ts b/packages/session-query/session-query-sqlite/tests/sqlite.spec.ts index 8427ebedc4..bbba91453d 100644 --- a/packages/session-query/session-query-sqlite/tests/sqlite.spec.ts +++ b/packages/session-query/session-query-sqlite/tests/sqlite.spec.ts @@ -1,6 +1,6 @@ import { createAssistantMessage, createUserMessage } from '@deepseek-ai/dsh-llm' import { afterEach, describe, expect, it, vi } from 'vitest' -import { Context, type Fiber } from 'cordis' +import { Context, type Fiber } from '@deepseek-ai/cordis' import { DatabaseSync } from 'node:sqlite' import { chmod, mkdtemp, rm, stat, writeFile } from 'node:fs/promises' import { tmpdir } from 'node:os' diff --git a/packages/session-query/session-query/package.json b/packages/session-query/session-query/package.json index 3a52808f02..30e6a52593 100644 --- a/packages/session-query/session-query/package.json +++ b/packages/session-query/session-query/package.json @@ -31,7 +31,7 @@ "@deepseek-ai/dsh-session": "^0.0.1", "@deepseek-ai/dsh-session-title": "^0.0.1", "@deepseek-ai/dsh-session-persistence": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "peerDependenciesMeta": { "@deepseek-ai/dsh-session-persistence": { @@ -45,6 +45,6 @@ "@deepseek-ai/dsh-session": "workspace:^", "@deepseek-ai/dsh-session-title": "workspace:^", "@deepseek-ai/dsh-session-persistence": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/session-query/session-query/src/corpus.ts b/packages/session-query/session-query/src/corpus.ts index 8711597b69..717b2b5190 100644 --- a/packages/session-query/session-query/src/corpus.ts +++ b/packages/session-query/session-query/src/corpus.ts @@ -1,6 +1,6 @@ /** Live/persisted logical-corpus resolution for session-query. */ -import type { Context, Fiber } from 'cordis' +import type { Context, Fiber } from '@deepseek-ai/cordis' import type { Session, SessionEvent, SessionHeader, SessionId } from '@deepseek-ai/dsh-session' import SessionPersistence, { SessionPersistenceCorruptionError } from '@deepseek-ai/dsh-session-persistence' import type { SessionRecord } from './types.ts' diff --git a/packages/session-query/session-query/src/index.ts b/packages/session-query/session-query/src/index.ts index 919bf00c88..c9cdc62221 100644 --- a/packages/session-query/session-query/src/index.ts +++ b/packages/session-query/session-query/src/index.ts @@ -4,7 +4,7 @@ * @module @deepseek-ai/dsh-session-query */ -import { Context, Service } from 'cordis' +import { Context, Service } from '@deepseek-ai/cordis' import { Session, snapshotSessionEvent, type SessionId } from '@deepseek-ai/dsh-session' import { foldSessionTitle } from '@deepseek-ai/dsh-session-title' import type { SessionTitleSnapshot } from '@deepseek-ai/dsh-session-title' @@ -65,7 +65,7 @@ export { } from './filters.ts' export { assertSessionHeadersCompatible } from './sources.ts' -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { sessionQuery: SessionQueryService } diff --git a/packages/session-query/session-query/src/invariant.ts b/packages/session-query/session-query/src/invariant.ts index d087dd2378..a264b4d279 100644 --- a/packages/session-query/session-query/src/invariant.ts +++ b/packages/session-query/session-query/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-session-query' diff --git a/packages/session-query/session-query/tests/search-helpers.spec.ts b/packages/session-query/session-query/tests/search-helpers.spec.ts index 1b139feacd..14422f4366 100644 --- a/packages/session-query/session-query/tests/search-helpers.spec.ts +++ b/packages/session-query/session-query/tests/search-helpers.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { createUserMessage, CallId , createMessage, createToolResultMessage } from '@deepseek-ai/dsh-llm' import SessionStore, { SESSION_FORMAT_VERSION, diff --git a/packages/session-query/session-query/tests/session-query.spec.ts b/packages/session-query/session-query/tests/session-query.spec.ts index acc993d2b3..5a4228329b 100644 --- a/packages/session-query/session-query/tests/session-query.spec.ts +++ b/packages/session-query/session-query/tests/session-query.spec.ts @@ -1,6 +1,6 @@ import { createUserMessage, createMessage } from '@deepseek-ai/dsh-llm' import { describe, expect, it, vi } from 'vitest' -import { Context, type Fiber } from 'cordis' +import { Context, type Fiber } from '@deepseek-ai/cordis' import SessionStore, { SESSION_FORMAT_VERSION, SessionId } from '@deepseek-ai/dsh-session' import type { SessionEvent, SessionHeader, SessionId as SessionIdType } from '@deepseek-ai/dsh-session' import SessionPersistence, { SessionPersistenceCorruptionError, SessionPersistenceRevision } from '@deepseek-ai/dsh-session-persistence' diff --git a/packages/session-query/session-query/tests/tracing.spec.ts b/packages/session-query/session-query/tests/tracing.spec.ts index 24e8622ab2..8c9588be26 100644 --- a/packages/session-query/session-query/tests/tracing.spec.ts +++ b/packages/session-query/session-query/tests/tracing.spec.ts @@ -1,6 +1,6 @@ import { createUserMessage, createMessage } from '@deepseek-ai/dsh-llm' import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import SessionStore, { SESSION_FORMAT_VERSION, SessionId } from '@deepseek-ai/dsh-session' import type { Session, SessionEvent, SessionHeader, SessionId as SessionIdType } from '@deepseek-ai/dsh-session' import SessionPersistence from '@deepseek-ai/dsh-session-persistence' diff --git a/packages/session-query/tool-session-query/package.json b/packages/session-query/tool-session-query/package.json index 39b5ada943..0e8f8c95ee 100644 --- a/packages/session-query/tool-session-query/package.json +++ b/packages/session-query/tool-session-query/package.json @@ -32,10 +32,10 @@ "@deepseek-ai/dsh-system-prompt": "^0.0.1", "@deepseek-ai/dsh-timeout": "^0.0.1", "@deepseek-ai/dsh-tools": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { "@deepseek-ai/dsh-agent": "workspace:^", @@ -51,6 +51,6 @@ "@deepseek-ai/dsh-timeout": "workspace:^", "@deepseek-ai/dsh-timeout-policy": "workspace:^", "@deepseek-ai/dsh-tools": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/session-query/tool-session-query/src/index.ts b/packages/session-query/tool-session-query/src/index.ts index 5187e254ae..d204184cfe 100644 --- a/packages/session-query/tool-session-query/src/index.ts +++ b/packages/session-query/tool-session-query/src/index.ts @@ -4,8 +4,8 @@ * @module @deepseek-ai/dsh-tool-session-query */ -import type { Context } from 'cordis' -import z from 'schemastery' +import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import { MAX_TIMER_DELAY_MS } from '@deepseek-ai/dsh-timeout' import { defineTool } from '@deepseek-ai/dsh-tools' import type {} from '@deepseek-ai/dsh-system-prompt' diff --git a/packages/session-query/tool-session-query/src/invariant.ts b/packages/session-query/tool-session-query/src/invariant.ts index 73f0e35409..3c8fd74114 100644 --- a/packages/session-query/tool-session-query/src/invariant.ts +++ b/packages/session-query/tool-session-query/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-tool-session-query' diff --git a/packages/session-query/tool-session-query/src/operations.ts b/packages/session-query/tool-session-query/src/operations.ts index f169842823..a8010c0e90 100644 --- a/packages/session-query/tool-session-query/src/operations.ts +++ b/packages/session-query/tool-session-query/src/operations.ts @@ -4,7 +4,7 @@ * @module @deepseek-ai/dsh-tool-session-query/operations */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { HarnessError } from '@deepseek-ai/dsh-llm' import type { SessionId } from '@deepseek-ai/dsh-session' import { diff --git a/packages/session-query/tool-session-query/src/service-boundary.ts b/packages/session-query/tool-session-query/src/service-boundary.ts index 495897fddd..9fbfc0c55c 100644 --- a/packages/session-query/tool-session-query/src/service-boundary.ts +++ b/packages/session-query/tool-session-query/src/service-boundary.ts @@ -4,7 +4,7 @@ * @module @deepseek-ai/dsh-tool-session-query/service-boundary */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { HarnessError } from '@deepseek-ai/dsh-llm' import { SessionQueryError, diff --git a/packages/session-query/tool-session-query/src/workspace-access.ts b/packages/session-query/tool-session-query/src/workspace-access.ts index faba3adf9f..a6c7b1ce40 100644 --- a/packages/session-query/tool-session-query/src/workspace-access.ts +++ b/packages/session-query/tool-session-query/src/workspace-access.ts @@ -4,7 +4,7 @@ * @module @deepseek-ai/dsh-tool-session-query/workspace-access */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { HarnessError } from '@deepseek-ai/dsh-llm' import { SessionId, diff --git a/packages/session-query/tool-session-query/tests/sqlite-integration.spec.ts b/packages/session-query/tool-session-query/tests/sqlite-integration.spec.ts index a00049eb3a..059e32faf1 100644 --- a/packages/session-query/tool-session-query/tests/sqlite-integration.spec.ts +++ b/packages/session-query/tool-session-query/tests/sqlite-integration.spec.ts @@ -1,5 +1,5 @@ import { afterEach, describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { mkdtemp, rm } from 'node:fs/promises' import { tmpdir } from 'node:os' import { join } from 'node:path' diff --git a/packages/session-query/tool-session-query/tests/tool-session-query.spec.ts b/packages/session-query/tool-session-query/tests/tool-session-query.spec.ts index 23ca3f939e..6741adc6eb 100644 --- a/packages/session-query/tool-session-query/tests/tool-session-query.spec.ts +++ b/packages/session-query/tool-session-query/tests/tool-session-query.spec.ts @@ -1,5 +1,5 @@ import { afterEach, describe, expect, it, vi } from 'vitest' -import { Context, type Fiber } from 'cordis' +import { Context, type Fiber } from '@deepseek-ai/cordis' import type { Agent } from '@deepseek-ai/dsh-agent' import { createUserMessage, CallId, HarnessError , createMessage } from '@deepseek-ai/dsh-llm' import { MAX_TIMER_DELAY_MS, TimeoutReason } from '@deepseek-ai/dsh-timeout' diff --git a/packages/session/session-checkpoint-policy/package.json b/packages/session/session-checkpoint-policy/package.json index afbc62345e..6a7a07ad13 100644 --- a/packages/session/session-checkpoint-policy/package.json +++ b/packages/session/session-checkpoint-policy/package.json @@ -31,10 +31,10 @@ "@deepseek-ai/dsh-session": "^0.0.1", "@deepseek-ai/dsh-session-persistence": "^0.0.1", "@deepseek-ai/dsh-tools": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { - "@cordisjs/plugin-loader": "workspace:^", + "@deepseek-ai/cordis-plugin-loader": "workspace:^", "@deepseek-ai/dsh-agent": "workspace:^", "@deepseek-ai/dsh-agent-loop": "workspace:^", "@deepseek-ai/dsh-agent-loop-testkit": "workspace:^", @@ -45,6 +45,6 @@ "@deepseek-ai/dsh-session-persistence-jsonl": "workspace:^", "@deepseek-ai/dsh-system-prompt": "workspace:^", "@deepseek-ai/dsh-tools": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/session/session-checkpoint-policy/src/index.ts b/packages/session/session-checkpoint-policy/src/index.ts index 804ed0dcb1..0fc456eb08 100644 --- a/packages/session/session-checkpoint-policy/src/index.ts +++ b/packages/session/session-checkpoint-policy/src/index.ts @@ -4,7 +4,7 @@ * @module @deepseek-ai/dsh-session-checkpoint-policy */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { Session } from '@deepseek-ai/dsh-session' import type { StreamChunk } from '@deepseek-ai/dsh-llm' import { TOOL_ABORTED_BEFORE_DISPATCH, type ToolExecutionResult } from '@deepseek-ai/dsh-tools' diff --git a/packages/session/session-checkpoint-policy/src/invariant.ts b/packages/session/session-checkpoint-policy/src/invariant.ts index f6baece911..af12673ea1 100644 --- a/packages/session/session-checkpoint-policy/src/invariant.ts +++ b/packages/session/session-checkpoint-policy/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-session-checkpoint-policy' diff --git a/packages/session/session-checkpoint-policy/tests/crash-recovery.e2e.ts b/packages/session/session-checkpoint-policy/tests/crash-recovery.e2e.ts index b64ce563b9..5d782cee1d 100644 --- a/packages/session/session-checkpoint-policy/tests/crash-recovery.e2e.ts +++ b/packages/session/session-checkpoint-policy/tests/crash-recovery.e2e.ts @@ -3,7 +3,7 @@ import { tmpdir } from 'node:os' import { join } from 'node:path' import { fileURLToPath } from 'node:url' import { execa } from 'execa' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { afterEach, describe, expect, it, vi } from 'vitest' import SessionStore, { SessionId, TOOL_OUTCOME_UNKNOWN, diff --git a/packages/session/session-checkpoint-policy/tests/fixtures/crash-child.ts b/packages/session/session-checkpoint-policy/tests/fixtures/crash-child.ts index a27da79e10..288dd21a26 100644 --- a/packages/session/session-checkpoint-policy/tests/fixtures/crash-child.ts +++ b/packages/session/session-checkpoint-policy/tests/fixtures/crash-child.ts @@ -1,5 +1,5 @@ import { writeFile } from 'node:fs/promises' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import AgentLoop from '@deepseek-ai/dsh-agent-loop' import { mountAgentLoopTestDependencies } from '@deepseek-ai/dsh-agent-loop-testkit' import { createUserMessage, CallId, type GenerateOptions, LlmAdapter, type StreamChunk } from '@deepseek-ai/dsh-llm' diff --git a/packages/session/session-checkpoint-policy/tests/session-checkpoint-policy.spec.ts b/packages/session/session-checkpoint-policy/tests/session-checkpoint-policy.spec.ts index dde59610c5..6501941c77 100644 --- a/packages/session/session-checkpoint-policy/tests/session-checkpoint-policy.spec.ts +++ b/packages/session/session-checkpoint-policy/tests/session-checkpoint-policy.spec.ts @@ -1,6 +1,6 @@ import { afterEach, describe, expect, it } from 'vitest' -import { Context } from 'cordis' -import Loader from '@cordisjs/plugin-loader' +import { Context } from '@deepseek-ai/cordis' +import Loader from '@deepseek-ai/cordis-plugin-loader' import { agentEvents, type Agent } from '@deepseek-ai/dsh-agent' import LlmService, { CallId, type GenerateOptions, LlmAdapter, type StreamChunk } from '@deepseek-ai/dsh-llm' import SessionStore, { SessionId } from '@deepseek-ai/dsh-session' diff --git a/packages/session/session-persistence-jsonl/package.json b/packages/session/session-persistence-jsonl/package.json index b09211669b..9960565102 100644 --- a/packages/session/session-persistence-jsonl/package.json +++ b/packages/session/session-persistence-jsonl/package.json @@ -28,16 +28,16 @@ "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-session": "^0.0.1", "@deepseek-ai/dsh-session-persistence": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { "koffi": "^3.1.0", - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-session": "workspace:^", "@deepseek-ai/dsh-session-persistence": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/session/session-persistence-jsonl/src/index.ts b/packages/session/session-persistence-jsonl/src/index.ts index 8d4aad8e7a..a3a4e04164 100644 --- a/packages/session/session-persistence-jsonl/src/index.ts +++ b/packages/session/session-persistence-jsonl/src/index.ts @@ -6,8 +6,8 @@ * @module @deepseek-ai/dsh-session-persistence-jsonl */ -import { Context } from 'cordis' -import z from 'schemastery' +import { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import { readdirSync } from 'node:fs' import { open, mkdir, readFile, readdir, realpath, link, rm, stat, truncate } from 'node:fs/promises' import { dirname, join, resolve } from 'node:path' diff --git a/packages/session/session-persistence-jsonl/src/invariant.ts b/packages/session/session-persistence-jsonl/src/invariant.ts index 94d7c2b494..c48a083e8f 100644 --- a/packages/session/session-persistence-jsonl/src/invariant.ts +++ b/packages/session/session-persistence-jsonl/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-session-persistence-jsonl' diff --git a/packages/session/session-persistence-jsonl/tests/jsonl.spec.ts b/packages/session/session-persistence-jsonl/tests/jsonl.spec.ts index c7b4ab8841..cdb239a982 100644 --- a/packages/session/session-persistence-jsonl/tests/jsonl.spec.ts +++ b/packages/session/session-persistence-jsonl/tests/jsonl.spec.ts @@ -1,6 +1,6 @@ import { MessageId, createUserMessage, createMessage } from '@deepseek-ai/dsh-llm' import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { appendFile, mkdtemp, mkdir, rm, readFile, writeFile, readdir, stat, symlink } from 'node:fs/promises' import { tmpdir } from 'node:os' import { isAbsolute, join, relative, resolve } from 'node:path' diff --git a/packages/session/session-persistence-jsonl/tests/zstd.spec.ts b/packages/session/session-persistence-jsonl/tests/zstd.spec.ts index b459fcac43..569c15cdd1 100644 --- a/packages/session/session-persistence-jsonl/tests/zstd.spec.ts +++ b/packages/session/session-persistence-jsonl/tests/zstd.spec.ts @@ -1,5 +1,5 @@ import { afterEach, describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { appendFile, mkdir, mkdtemp, open, readFile, readdir, rm, stat, writeFile } from 'node:fs/promises' import type { FileHandle } from 'node:fs/promises' import { tmpdir } from 'node:os' diff --git a/packages/session/session-persistence-sqlite/package.json b/packages/session/session-persistence-sqlite/package.json index 90415bd8cc..62bbba8dba 100644 --- a/packages/session/session-persistence-sqlite/package.json +++ b/packages/session/session-persistence-sqlite/package.json @@ -28,15 +28,15 @@ "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-session": "^0.0.1", "@deepseek-ai/dsh-session-persistence": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-session": "workspace:^", "@deepseek-ai/dsh-session-persistence": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/session/session-persistence-sqlite/src/index.ts b/packages/session/session-persistence-sqlite/src/index.ts index b26e273cf1..ab674469d9 100644 --- a/packages/session/session-persistence-sqlite/src/index.ts +++ b/packages/session/session-persistence-sqlite/src/index.ts @@ -6,8 +6,8 @@ * @module @deepseek-ai/dsh-session-persistence-sqlite */ -import { Context } from 'cordis' -import z from 'schemastery' +import { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import { randomUUID } from 'node:crypto' import { statSync } from 'node:fs' import { DatabaseSync } from 'node:sqlite' diff --git a/packages/session/session-persistence-sqlite/src/invariant.ts b/packages/session/session-persistence-sqlite/src/invariant.ts index 9d841a053d..7a5e905e30 100644 --- a/packages/session/session-persistence-sqlite/src/invariant.ts +++ b/packages/session/session-persistence-sqlite/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-session-persistence-sqlite' diff --git a/packages/session/session-persistence-sqlite/tests/sqlite.spec.ts b/packages/session/session-persistence-sqlite/tests/sqlite.spec.ts index afaa060490..5f8f910bde 100644 --- a/packages/session/session-persistence-sqlite/tests/sqlite.spec.ts +++ b/packages/session/session-persistence-sqlite/tests/sqlite.spec.ts @@ -1,6 +1,6 @@ import { createUserMessage, createMessage } from '@deepseek-ai/dsh-llm' import { afterEach, describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { existsSync } from 'node:fs' import { chmod, mkdtemp, rm, stat, symlink, writeFile } from 'node:fs/promises' import { tmpdir } from 'node:os' diff --git a/packages/session/session-persistence/package.json b/packages/session/session-persistence/package.json index 10517be615..94b1455beb 100644 --- a/packages/session/session-persistence/package.json +++ b/packages/session/session-persistence/package.json @@ -29,7 +29,7 @@ "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-session": "^0.0.1", "@deepseek-ai/dsh-timeout": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-brand": "workspace:^", @@ -37,6 +37,6 @@ "@deepseek-ai/dsh-scope": "workspace:^", "@deepseek-ai/dsh-session": "workspace:^", "@deepseek-ai/dsh-timeout": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/session/session-persistence/src/coordinator.ts b/packages/session/session-persistence/src/coordinator.ts index ec4fb72aeb..be1edf01c3 100644 --- a/packages/session/session-persistence/src/coordinator.ts +++ b/packages/session/session-persistence/src/coordinator.ts @@ -5,7 +5,7 @@ * @module @deepseek-ai/dsh-session-persistence/coordinator */ -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { adoptSessionEvent, interruptedTurnClosers, diff --git a/packages/session/session-persistence/src/index.ts b/packages/session/session-persistence/src/index.ts index 5c3df73b30..dc06517367 100644 --- a/packages/session/session-persistence/src/index.ts +++ b/packages/session/session-persistence/src/index.ts @@ -5,7 +5,7 @@ * @module @deepseek-ai/dsh-session-persistence */ -import { Context, Service } from 'cordis' +import { Context, Service } from '@deepseek-ai/cordis' import { SessionPreparation } from '@deepseek-ai/dsh-session' import type { SessionEvent, SessionId, SessionHeader } from '@deepseek-ai/dsh-session' import type { SessionPersistenceRevision } from './revision.ts' @@ -45,7 +45,7 @@ export type { StoredSuffix, } from './coordinator.ts' -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { sessionPersistence: SessionPersistence } diff --git a/packages/session/session-persistence/src/invariant.ts b/packages/session/session-persistence/src/invariant.ts index 316774f3fd..4259c1b065 100644 --- a/packages/session/session-persistence/src/invariant.ts +++ b/packages/session/session-persistence/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-session-persistence' diff --git a/packages/session/session-persistence/tests/coordinator-contract.ts b/packages/session/session-persistence/tests/coordinator-contract.ts index 411df34d8d..c272109f82 100644 --- a/packages/session/session-persistence/tests/coordinator-contract.ts +++ b/packages/session/session-persistence/tests/coordinator-contract.ts @@ -11,7 +11,7 @@ import { createUserMessage } from '@deepseek-ai/dsh-llm' */ import { describe, expect, it, vi } from 'vitest' -import { Context, type Fiber } from 'cordis' +import { Context, type Fiber } from '@deepseek-ai/cordis' import { scopeTarget } from '@deepseek-ai/dsh-scope' import SessionStore, { SESSION_FORMAT_VERSION, Session, SessionId } from '@deepseek-ai/dsh-session' import type { SessionEvent } from '@deepseek-ai/dsh-session' diff --git a/packages/session/session-persistence/tests/persistence.spec.ts b/packages/session/session-persistence/tests/persistence.spec.ts index d3e715b085..b9f7b8672b 100644 --- a/packages/session/session-persistence/tests/persistence.spec.ts +++ b/packages/session/session-persistence/tests/persistence.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import SessionStore, { Session, SessionId, isJsonValue } from '@deepseek-ai/dsh-session' import type { SessionEvent, SessionHeader } from '@deepseek-ai/dsh-session' import { diff --git a/packages/session/session-projection-cache/package.json b/packages/session/session-projection-cache/package.json index 2be692665f..d54b0d18e7 100644 --- a/packages/session/session-projection-cache/package.json +++ b/packages/session/session-projection-cache/package.json @@ -25,7 +25,7 @@ ], "license": "BSD-3-Clause", "dependencies": { - "schemastery": "^3.18.0", + "@deepseek-ai/schemastery": "^3.18.0", "zod": "^4.4.3" }, "peerDependencies": { @@ -34,7 +34,7 @@ "@deepseek-ai/dsh-session-persistence": "^0.0.1", "@deepseek-ai/dsh-session-projection": "^0.0.1", "@deepseek-ai/dsh-storage-domain": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-invariants": "workspace:^", @@ -43,6 +43,6 @@ "@deepseek-ai/dsh-session-projection": "workspace:^", "@deepseek-ai/dsh-storage": "workspace:^", "@deepseek-ai/dsh-storage-domain": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/session/session-projection-cache/src/index.ts b/packages/session/session-projection-cache/src/index.ts index 03b3ed26ee..66ad637402 100644 --- a/packages/session/session-projection-cache/src/index.ts +++ b/packages/session/session-projection-cache/src/index.ts @@ -12,8 +12,8 @@ * @module @deepseek-ai/dsh-session-projection-cache */ -import { Context, Service } from 'cordis' -import z from 'schemastery' +import { Context, Service } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import { snapshotJsonValue } from '@deepseek-ai/dsh-session' import type { Session, SessionEvent, SessionHeader, SessionId } from '@deepseek-ai/dsh-session' // Empty type import: applies the package's cordis Context merge @@ -27,7 +27,7 @@ import type { CheckpointIdentity, CheckpointRecord } from './spec.ts' export { checkpointIdentity, checkpointRecord, checkpointRow, projectionCacheDomainSpec } from './spec.ts' export type { CheckpointIdentity, CheckpointRecord } from './spec.ts' -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { sessionProjectionCache: SessionProjectionCache } diff --git a/packages/session/session-projection-cache/src/invariant.ts b/packages/session/session-projection-cache/src/invariant.ts index 8a119044d8..886f913d30 100644 --- a/packages/session/session-projection-cache/src/invariant.ts +++ b/packages/session/session-projection-cache/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-session-projection-cache' diff --git a/packages/session/session-projection-cache/tests/cache.spec.ts b/packages/session/session-projection-cache/tests/cache.spec.ts index ba9dc39c57..6395ed7d0f 100644 --- a/packages/session/session-projection-cache/tests/cache.spec.ts +++ b/packages/session/session-projection-cache/tests/cache.spec.ts @@ -7,7 +7,7 @@ */ import { afterEach, describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { z } from 'zod' import Storage from '@deepseek-ai/dsh-storage' import { DomainFacility } from '@deepseek-ai/dsh-storage-domain' diff --git a/packages/session/session-projection/package.json b/packages/session/session-projection/package.json index 37a081abfa..46445673ab 100644 --- a/packages/session/session-projection/package.json +++ b/packages/session/session-projection/package.json @@ -35,11 +35,11 @@ "peerDependencies": { "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-session": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-session": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/session/session-projection/src/index.ts b/packages/session/session-projection/src/index.ts index 154a5ca2fa..9f0c24e72e 100644 --- a/packages/session/session-projection/src/index.ts +++ b/packages/session/session-projection/src/index.ts @@ -17,11 +17,11 @@ * @module @deepseek-ai/dsh-session-projection */ -import { Context, Service } from 'cordis' +import { Context, Service } from '@deepseek-ai/cordis' import type { ZodType } from 'zod' import type { Session, SessionEvent } from '@deepseek-ai/dsh-session' -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { sessionProjections: SessionProjectionRegistry } diff --git a/packages/session/session-projection/src/invariant.ts b/packages/session/session-projection/src/invariant.ts index 47934c946c..537015d932 100644 --- a/packages/session/session-projection/src/invariant.ts +++ b/packages/session/session-projection/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-session-projection' diff --git a/packages/session/session-projection/tests/registry.spec.ts b/packages/session/session-projection/tests/registry.spec.ts index 5d0f208743..4ae4a3face 100644 --- a/packages/session/session-projection/tests/registry.spec.ts +++ b/packages/session/session-projection/tests/registry.spec.ts @@ -8,7 +8,7 @@ */ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { z } from 'zod' import SessionStore from '@deepseek-ai/dsh-session' import type { Session, SessionEvent } from '@deepseek-ai/dsh-session' diff --git a/packages/session/session-telemetry-otel/package.json b/packages/session/session-telemetry-otel/package.json index 2af0b5294e..9a8c4e914f 100644 --- a/packages/session/session-telemetry-otel/package.json +++ b/packages/session/session-telemetry-otel/package.json @@ -31,7 +31,7 @@ "@opentelemetry/otlp-exporter-base": "^0.220.0", "@opentelemetry/resources": "^2.9.0", "@opentelemetry/sdk-logs": "^0.220.0", - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "peerDependencies": { "@deepseek-ai/dsh-command-feedback": "^0.0.1", @@ -40,16 +40,16 @@ "@deepseek-ai/dsh-session": "^0.0.1", "@deepseek-ai/dsh-session-telemetry": "^0.0.1", "@deepseek-ai/dsh-user-id": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { - "@cordisjs/plugin-loader": "workspace:^", + "@deepseek-ai/cordis-plugin-loader": "workspace:^", "@deepseek-ai/dsh-command-feedback": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-llm": "workspace:^", "@deepseek-ai/dsh-session": "workspace:^", "@deepseek-ai/dsh-session-telemetry": "workspace:^", "@deepseek-ai/dsh-user-id": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/session/session-telemetry-otel/src/index.ts b/packages/session/session-telemetry-otel/src/index.ts index 50776f7d3f..5a5102ca51 100644 --- a/packages/session/session-telemetry-otel/src/index.ts +++ b/packages/session/session-telemetry-otel/src/index.ts @@ -13,8 +13,8 @@ */ import { createRequire } from 'node:module' -import z from 'schemastery' -import type { Context } from 'cordis' +import z from '@deepseek-ai/schemastery' +import type { Context } from '@deepseek-ai/cordis' import type {} from '@deepseek-ai/dsh-command-feedback' import { Telemetry, diff --git a/packages/session/session-telemetry-otel/src/invariant.ts b/packages/session/session-telemetry-otel/src/invariant.ts index 0eaffeb8b5..31864acb1c 100644 --- a/packages/session/session-telemetry-otel/src/invariant.ts +++ b/packages/session/session-telemetry-otel/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-session-telemetry-otel' diff --git a/packages/session/session-telemetry-otel/tests/otel.spec.ts b/packages/session/session-telemetry-otel/tests/otel.spec.ts index 511c95c0d8..3e14bf3c9d 100644 --- a/packages/session/session-telemetry-otel/tests/otel.spec.ts +++ b/packages/session/session-telemetry-otel/tests/otel.spec.ts @@ -12,9 +12,9 @@ import { mkdtempSync, rmSync } from 'node:fs' import { tmpdir } from 'node:os' import { join } from 'node:path' import { gunzipSync } from 'node:zlib' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { getOrCreateAnonymousUserId } from '@deepseek-ai/dsh-user-id' -import Loader from '@cordisjs/plugin-loader' +import Loader from '@deepseek-ai/cordis-plugin-loader' import { recordFeedback } from '@deepseek-ai/dsh-command-feedback' import SessionStore, { SessionId } from '@deepseek-ai/dsh-session' import TelemetryOtel, { Config, DEFAULT_TELEMETRY_MODE, TelemetryMode } from '../src/index.ts' diff --git a/packages/session/session-telemetry/package.json b/packages/session/session-telemetry/package.json index ff6e31b025..2176d02313 100644 --- a/packages/session/session-telemetry/package.json +++ b/packages/session/session-telemetry/package.json @@ -28,12 +28,12 @@ "@deepseek-ai/dsh-agent": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-session": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-agent": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-session": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/session/session-telemetry/src/coordinator.ts b/packages/session/session-telemetry/src/coordinator.ts index f06d1b7b9e..2d092b4fd7 100644 --- a/packages/session/session-telemetry/src/coordinator.ts +++ b/packages/session/session-telemetry/src/coordinator.ts @@ -14,7 +14,7 @@ * @module @deepseek-ai/dsh-session-telemetry/coordinator */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { Session, SessionEvent } from '@deepseek-ai/dsh-session' import type { Agent } from '@deepseek-ai/dsh-agent' import type { TelemetryBackend, TelemetryRecord, TelemetrySeverity } from './index.ts' diff --git a/packages/session/session-telemetry/src/index.ts b/packages/session/session-telemetry/src/index.ts index 7ddd85fe8e..19b58d1ee2 100644 --- a/packages/session/session-telemetry/src/index.ts +++ b/packages/session/session-telemetry/src/index.ts @@ -14,9 +14,9 @@ * @module @deepseek-ai/dsh-session-telemetry */ -import { Context, Service } from 'cordis' +import { Context, Service } from '@deepseek-ai/cordis' -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { telemetry: Telemetry } diff --git a/packages/session/session-telemetry/src/invariant.ts b/packages/session/session-telemetry/src/invariant.ts index 1c265877f8..ec0928a868 100644 --- a/packages/session/session-telemetry/src/invariant.ts +++ b/packages/session/session-telemetry/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-session-telemetry' diff --git a/packages/session/session-telemetry/tests/redact.spec.ts b/packages/session/session-telemetry/tests/redact.spec.ts index f20891fc0f..15df6f380a 100644 --- a/packages/session/session-telemetry/tests/redact.spec.ts +++ b/packages/session/session-telemetry/tests/redact.spec.ts @@ -6,7 +6,7 @@ import { createUserMessage } from '@deepseek-ai/dsh-llm' */ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import SessionStore, { SessionId } from '@deepseek-ai/dsh-session' import { TelemetryCoordinator, diff --git a/packages/session/session-telemetry/tests/telemetry.spec.ts b/packages/session/session-telemetry/tests/telemetry.spec.ts index 029381fe78..8d758f56b3 100644 --- a/packages/session/session-telemetry/tests/telemetry.spec.ts +++ b/packages/session/session-telemetry/tests/telemetry.spec.ts @@ -7,7 +7,7 @@ import { createToolResultMessage, createUserMessage } from '@deepseek-ai/dsh-llm */ import { describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import SessionStore, { SessionId, type Session, type SessionEvent } from '@deepseek-ai/dsh-session' import type { Agent } from '@deepseek-ai/dsh-agent' import { diff --git a/packages/session/session-title-all-messages-llm/package.json b/packages/session/session-title-all-messages-llm/package.json index 546387c682..70c3b4c255 100644 --- a/packages/session/session-title-all-messages-llm/package.json +++ b/packages/session/session-title-all-messages-llm/package.json @@ -25,10 +25,10 @@ "@deepseek-ai/dsh-session": "^0.0.1", "@deepseek-ai/dsh-session-title": "^0.0.1", "@deepseek-ai/dsh-session-title-llm": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { "@deepseek-ai/dsh-invariants": "workspace:^", @@ -36,6 +36,6 @@ "@deepseek-ai/dsh-session": "workspace:^", "@deepseek-ai/dsh-session-title": "workspace:^", "@deepseek-ai/dsh-session-title-llm": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/session/session-title-all-messages-llm/src/index.ts b/packages/session/session-title-all-messages-llm/src/index.ts index 96bd424434..168aa4b98f 100644 --- a/packages/session/session-title-all-messages-llm/src/index.ts +++ b/packages/session/session-title-all-messages-llm/src/index.ts @@ -1,7 +1,7 @@ /** All-human-messages model provider for `ctx.sessionTitle`. */ -import type { Context } from 'cordis' -import z from 'schemastery' +import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import { registerSessionTitleLlmProvider, SessionTitleLlmConfigFields, diff --git a/packages/session/session-title-all-messages-llm/src/invariant.ts b/packages/session/session-title-all-messages-llm/src/invariant.ts index 79f6eb55ee..1e344d85d9 100644 --- a/packages/session/session-title-all-messages-llm/src/invariant.ts +++ b/packages/session/session-title-all-messages-llm/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-session-title-all-messages-llm' diff --git a/packages/session/session-title-all-messages-llm/tests/provider.spec.ts b/packages/session/session-title-all-messages-llm/tests/provider.spec.ts index 3c6ef6ed0b..6eca8abcbf 100644 --- a/packages/session/session-title-all-messages-llm/tests/provider.spec.ts +++ b/packages/session/session-title-all-messages-llm/tests/provider.spec.ts @@ -1,4 +1,4 @@ -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { describe, expect, it } from 'vitest' import LlmService, { createUserMessage, LlmAdapter } from '@deepseek-ai/dsh-llm' import type { GenerateOptions, StreamChunk } from '@deepseek-ai/dsh-llm' diff --git a/packages/session/session-title-first-message-llm/package.json b/packages/session/session-title-first-message-llm/package.json index 50b4a4d14c..0c934c192b 100644 --- a/packages/session/session-title-first-message-llm/package.json +++ b/packages/session/session-title-first-message-llm/package.json @@ -25,20 +25,20 @@ "@deepseek-ai/dsh-session": "^0.0.1", "@deepseek-ai/dsh-session-title": "^0.0.1", "@deepseek-ai/dsh-session-title-llm": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { - "@cordisjs/plugin-include": "workspace:^", - "@cordisjs/plugin-loader": "workspace:^", + "@deepseek-ai/cordis-plugin-include": "workspace:^", + "@deepseek-ai/cordis-plugin-loader": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-llm": "workspace:^", "@deepseek-ai/dsh-llm-deepseek": "workspace:^", "@deepseek-ai/dsh-session": "workspace:^", "@deepseek-ai/dsh-session-title": "workspace:^", "@deepseek-ai/dsh-session-title-llm": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/session/session-title-first-message-llm/src/index.ts b/packages/session/session-title-first-message-llm/src/index.ts index 51cc8eab44..15aece3fb8 100644 --- a/packages/session/session-title-first-message-llm/src/index.ts +++ b/packages/session/session-title-first-message-llm/src/index.ts @@ -1,7 +1,7 @@ /** First-human-message model provider for `ctx.sessionTitle`. */ -import type { Context } from 'cordis' -import z from 'schemastery' +import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import { registerSessionTitleLlmProvider, SessionTitleLlmConfigFields, diff --git a/packages/session/session-title-first-message-llm/src/invariant.ts b/packages/session/session-title-first-message-llm/src/invariant.ts index bd3662496f..a2e1b5ff91 100644 --- a/packages/session/session-title-first-message-llm/src/invariant.ts +++ b/packages/session/session-title-first-message-llm/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-session-title-first-message-llm' diff --git a/packages/session/session-title-first-message-llm/tests/loader-composition.spec.ts b/packages/session/session-title-first-message-llm/tests/loader-composition.spec.ts index eb0125efd9..28915308a9 100644 --- a/packages/session/session-title-first-message-llm/tests/loader-composition.spec.ts +++ b/packages/session/session-title-first-message-llm/tests/loader-composition.spec.ts @@ -1,7 +1,7 @@ import { afterEach, describe, expect, it } from 'vitest' -import { Context } from 'cordis' -import Loader from '@cordisjs/plugin-loader' -import Include from '@cordisjs/plugin-include' +import { Context } from '@deepseek-ai/cordis' +import Loader from '@deepseek-ai/cordis-plugin-loader' +import Include from '@deepseek-ai/cordis-plugin-include' import { mkdtemp, rm, writeFile } from 'node:fs/promises' import { tmpdir } from 'node:os' import { join } from 'node:path' diff --git a/packages/session/session-title-first-message-llm/tests/provider.e2e.ts b/packages/session/session-title-first-message-llm/tests/provider.e2e.ts index 6f39669cc8..970c45b851 100644 --- a/packages/session/session-title-first-message-llm/tests/provider.e2e.ts +++ b/packages/session/session-title-first-message-llm/tests/provider.e2e.ts @@ -1,6 +1,6 @@ import { createUserMessage } from '@deepseek-ai/dsh-llm' import { afterEach, describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import LlmService from '@deepseek-ai/dsh-llm' import * as LlmDeepSeek from '@deepseek-ai/dsh-llm-deepseek' import SessionStore, { SessionId } from '@deepseek-ai/dsh-session' diff --git a/packages/session/session-title-first-message-llm/tests/provider.spec.ts b/packages/session/session-title-first-message-llm/tests/provider.spec.ts index 79a80745e3..38d41857ed 100644 --- a/packages/session/session-title-first-message-llm/tests/provider.spec.ts +++ b/packages/session/session-title-first-message-llm/tests/provider.spec.ts @@ -1,4 +1,4 @@ -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { describe, expect, it, vi } from 'vitest' import LlmService, { createUserMessage, LlmAdapter } from '@deepseek-ai/dsh-llm' import type { GenerateOptions, StreamChunk } from '@deepseek-ai/dsh-llm' diff --git a/packages/session/session-title-llm/package.json b/packages/session/session-title-llm/package.json index 64e4519662..6e5acac31f 100644 --- a/packages/session/session-title-llm/package.json +++ b/packages/session/session-title-llm/package.json @@ -30,10 +30,10 @@ "@deepseek-ai/dsh-session": "^0.0.1", "@deepseek-ai/dsh-session-title": "^0.0.1", "@deepseek-ai/dsh-timeout": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { "@deepseek-ai/dsh-invariants": "workspace:^", @@ -41,6 +41,6 @@ "@deepseek-ai/dsh-session": "workspace:^", "@deepseek-ai/dsh-session-title": "workspace:^", "@deepseek-ai/dsh-timeout": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/session/session-title-llm/src/index.ts b/packages/session/session-title-llm/src/index.ts index 52572db30d..711d9c5f16 100644 --- a/packages/session/session-title-llm/src/index.ts +++ b/packages/session/session-title-llm/src/index.ts @@ -4,8 +4,8 @@ * @module @deepseek-ai/dsh-session-title-llm */ -import type { Context } from 'cordis' -import z from 'schemastery' +import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import { createUserMessage, BlockAssembler, deepFreeze } from '@deepseek-ai/dsh-llm' import type { FinishReason, GenerateOptions, Message } from '@deepseek-ai/dsh-llm' import { deadline, MAX_TIMER_DELAY_MS } from '@deepseek-ai/dsh-timeout' diff --git a/packages/session/session-title-llm/src/invariant.ts b/packages/session/session-title-llm/src/invariant.ts index 64350ebf20..4c0a98e830 100644 --- a/packages/session/session-title-llm/src/invariant.ts +++ b/packages/session/session-title-llm/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-session-title-llm' diff --git a/packages/session/session-title-llm/tests/llm.spec.ts b/packages/session/session-title-llm/tests/llm.spec.ts index 6572eb89c5..48ae497a7b 100644 --- a/packages/session/session-title-llm/tests/llm.spec.ts +++ b/packages/session/session-title-llm/tests/llm.spec.ts @@ -1,4 +1,4 @@ -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { describe, expect, it, vi } from 'vitest' import LlmService, { createUserMessage, CallId, isAgentLoopRequest, LlmAdapter } from '@deepseek-ai/dsh-llm' import type { FinishReason, GenerateOptions, StreamChunk } from '@deepseek-ai/dsh-llm' diff --git a/packages/session/session-title/package.json b/packages/session/session-title/package.json index d167b257b2..820df4c70d 100644 --- a/packages/session/session-title/package.json +++ b/packages/session/session-title/package.json @@ -39,10 +39,10 @@ "@deepseek-ai/dsh-llm": "^0.0.1", "@deepseek-ai/dsh-session": "^0.0.1", "@deepseek-ai/dsh-session-projection": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { - "schemastery": "^3.18.0", + "@deepseek-ai/schemastery": "^3.18.0", "zod": "^4.4.3" }, "devDependencies": { @@ -53,6 +53,6 @@ "@deepseek-ai/dsh-session-persistence-jsonl": "workspace:^", "@deepseek-ai/dsh-session-persistence-sqlite": "workspace:^", "@deepseek-ai/dsh-session-projection": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/session/session-title/src/index.ts b/packages/session/session-title/src/index.ts index 6f8594edd4..8017555ad3 100644 --- a/packages/session/session-title/src/index.ts +++ b/packages/session/session-title/src/index.ts @@ -3,8 +3,8 @@ * @module @deepseek-ai/dsh-session-title */ -import { Context, FiberState, Service, type Fiber } from 'cordis' -import z from 'schemastery' +import { Context, FiberState, Service, type Fiber } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import { z as zod } from 'zod' import type { Branded } from '@deepseek-ai/dsh-brand' import { assertNever, deepFreeze, isAgentLoopRequest } from '@deepseek-ai/dsh-llm' @@ -85,7 +85,7 @@ export interface Config { readonly maxTitleBytes: number } -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { sessionTitle: SessionTitleService } diff --git a/packages/session/session-title/src/invariant.ts b/packages/session/session-title/src/invariant.ts index a826104489..11337fbf34 100644 --- a/packages/session/session-title/src/invariant.ts +++ b/packages/session/session-title/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantFailure, InvariantInstaller } from '@deepseek-ai/dsh-invariants' import type { SessionEvent } from '@deepseek-ai/dsh-session' diff --git a/packages/session/session-title/tests/invariant.spec.ts b/packages/session/session-title/tests/invariant.spec.ts index d1a6abb527..68c82146a4 100644 --- a/packages/session/session-title/tests/invariant.spec.ts +++ b/packages/session/session-title/tests/invariant.spec.ts @@ -1,7 +1,7 @@ // Title-source invariant: `messageSeqs` is empty iff `source.kind` is `user`. // — the durable relationship every appended session/title event must keep. import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import * as SessionTitleInvariantCompanion from '@deepseek-ai/dsh-session-title/invariant' import InvariantService, { InvariantError } from '@deepseek-ai/dsh-invariants' import SessionStore, { SessionId } from '@deepseek-ai/dsh-session' diff --git a/packages/session/session-title/tests/persistence.spec.ts b/packages/session/session-title/tests/persistence.spec.ts index 7d5428983f..3f9ab211d5 100644 --- a/packages/session/session-title/tests/persistence.spec.ts +++ b/packages/session/session-title/tests/persistence.spec.ts @@ -1,6 +1,6 @@ import { createUserMessage } from '@deepseek-ai/dsh-llm' import { afterEach, describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { mkdtemp, rm } from 'node:fs/promises' import { tmpdir } from 'node:os' import { join } from 'node:path' diff --git a/packages/session/session-title/tests/projection.spec.ts b/packages/session/session-title/tests/projection.spec.ts index 986cafc620..1198e78a23 100644 --- a/packages/session/session-title/tests/projection.spec.ts +++ b/packages/session/session-title/tests/projection.spec.ts @@ -10,7 +10,7 @@ */ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import SessionStore, { SessionId } from '@deepseek-ai/dsh-session' import type { Session } from '@deepseek-ai/dsh-session' import SessionProjectionRegistry from '@deepseek-ai/dsh-session-projection' diff --git a/packages/session/session-title/tests/provider.spec.ts b/packages/session/session-title/tests/provider.spec.ts index 5bfe30ac14..65d913677c 100644 --- a/packages/session/session-title/tests/provider.spec.ts +++ b/packages/session/session-title/tests/provider.spec.ts @@ -1,4 +1,4 @@ -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { describe, expect, it, vi } from 'vitest' import LlmService, { createUserMessage, deepFreeze, markAgentLoopRequest } from '@deepseek-ai/dsh-llm' import SessionStore, { SessionId } from '@deepseek-ai/dsh-session' diff --git a/packages/session/session-title/tests/rename.spec.ts b/packages/session/session-title/tests/rename.spec.ts index ff38900f47..76dfc57e30 100644 --- a/packages/session/session-title/tests/rename.spec.ts +++ b/packages/session/session-title/tests/rename.spec.ts @@ -1,7 +1,7 @@ // SessionTitleService.rename: user-source acceptance, normalization/rejection // boundaries, and the pin (a user-sourced latest title schedules no automatic // revision; explicit refresh stays the unpin). -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { describe, expect, it, vi } from 'vitest' import { createUserMessage } from '@deepseek-ai/dsh-llm' import SessionStore, { Session, SessionId } from '@deepseek-ai/dsh-session' diff --git a/packages/session/session-title/tests/service-contracts.spec.ts b/packages/session/session-title/tests/service-contracts.spec.ts index 28d7e6749e..e57ce60f4d 100644 --- a/packages/session/session-title/tests/service-contracts.spec.ts +++ b/packages/session/session-title/tests/service-contracts.spec.ts @@ -1,5 +1,5 @@ import { createUserMessage } from '@deepseek-ai/dsh-llm' -import { Context, type Fiber } from 'cordis' +import { Context, type Fiber } from '@deepseek-ai/cordis' import { describe, expect, it, vi } from 'vitest' import SessionStore, { Session, SessionId } from '@deepseek-ai/dsh-session' import SessionTitleService, { diff --git a/packages/session/session-title/tests/session-title.spec.ts b/packages/session/session-title/tests/session-title.spec.ts index c6c3c4b9d3..bb8ce4625d 100644 --- a/packages/session/session-title/tests/session-title.spec.ts +++ b/packages/session/session-title/tests/session-title.spec.ts @@ -1,5 +1,5 @@ import { createUserMessage } from '@deepseek-ai/dsh-llm' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { describe, expect, it } from 'vitest' import SessionStore, { Session, SessionId } from '@deepseek-ai/dsh-session' import SessionTitleService, { diff --git a/packages/session/user-id/package.json b/packages/session/user-id/package.json index 2a09c73b0e..5e86cc4a32 100644 --- a/packages/session/user-id/package.json +++ b/packages/session/user-id/package.json @@ -28,12 +28,12 @@ "@deepseek-ai/dsh-brand": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-paths": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-brand": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-paths": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/session/user-id/src/invariant.ts b/packages/session/user-id/src/invariant.ts index b649e23619..710714c605 100644 --- a/packages/session/user-id/src/invariant.ts +++ b/packages/session/user-id/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-user-id' diff --git a/packages/session/user-id/tests/invariant.spec.ts b/packages/session/user-id/tests/invariant.spec.ts index abffc89621..c140b73711 100644 --- a/packages/session/user-id/tests/invariant.spec.ts +++ b/packages/session/user-id/tests/invariant.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import InvariantService from '@deepseek-ai/dsh-invariants' import * as UserIdInvariant from '@deepseek-ai/dsh-user-id/invariant' diff --git a/packages/settings/settings-local/package.json b/packages/settings/settings-local/package.json index 6a9185ec2c..5e086b8efe 100644 --- a/packages/settings/settings-local/package.json +++ b/packages/settings/settings-local/package.json @@ -29,11 +29,11 @@ "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-paths": "^0.0.1", "@deepseek-ai/dsh-settings": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { "chokidar": "^4.0.3", - "schemastery": "^3.18.0", + "@deepseek-ai/schemastery": "^3.18.0", "yaml": "^2.9.0" }, "devDependencies": { @@ -41,6 +41,6 @@ "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-paths": "workspace:^", "@deepseek-ai/dsh-settings": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/settings/settings-local/src/index.ts b/packages/settings/settings-local/src/index.ts index 16bc641f05..5a72afd99a 100644 --- a/packages/settings/settings-local/src/index.ts +++ b/packages/settings/settings-local/src/index.ts @@ -7,8 +7,8 @@ * @module @deepseek-ai/dsh-settings-local */ -import { Context, Service } from 'cordis' -import z from 'schemastery' +import { Context, Service } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import { watch as chokidarWatch } from 'chokidar' import { mkdir, readFile, writeFile } from 'node:fs/promises' import { dirname, extname, join, resolve } from 'node:path' diff --git a/packages/settings/settings-local/src/invariant.ts b/packages/settings/settings-local/src/invariant.ts index b59b798298..a5769dae37 100644 --- a/packages/settings/settings-local/src/invariant.ts +++ b/packages/settings/settings-local/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-settings-local' diff --git a/packages/settings/settings-local/tests/concurrency.spec.ts b/packages/settings/settings-local/tests/concurrency.spec.ts index 5df2179219..138e56cc7c 100644 --- a/packages/settings/settings-local/tests/concurrency.spec.ts +++ b/packages/settings/settings-local/tests/concurrency.spec.ts @@ -3,8 +3,8 @@ // neither knows the other's cache, so only the read-modify-write cycle under // the `.lock` sibling keeps both namespaces alive on disk. import { afterEach, describe, expect, it } from 'vitest' -import { Context } from 'cordis' -import z from 'schemastery' +import { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import { chmod, mkdtemp, readFile, rm, utimes, writeFile } from 'node:fs/promises' import { tmpdir } from 'node:os' import { join } from 'node:path' diff --git a/packages/settings/settings-local/tests/loader-composition.spec.ts b/packages/settings/settings-local/tests/loader-composition.spec.ts index c7cea89e41..f0c80e3d2d 100644 --- a/packages/settings/settings-local/tests/loader-composition.spec.ts +++ b/packages/settings/settings-local/tests/loader-composition.spec.ts @@ -11,10 +11,10 @@ import { tmpdir } from 'node:os' import { join } from 'node:path' import { pathToFileURL } from 'node:url' import { afterEach, describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' -import Loader from '@cordisjs/plugin-loader' -import Include from '@cordisjs/plugin-include' -import z from 'schemastery' +import { Context } from '@deepseek-ai/cordis' +import Loader from '@deepseek-ai/cordis-plugin-loader' +import Include from '@deepseek-ai/cordis-plugin-include' +import z from '@deepseek-ai/schemastery' import { settingsNamespace, type SettingsScope } from '@deepseek-ai/dsh-settings' import SettingsLocal from '../src/index.ts' diff --git a/packages/settings/settings-local/tests/local.spec.ts b/packages/settings/settings-local/tests/local.spec.ts index 8e89cd4643..e2db873764 100644 --- a/packages/settings/settings-local/tests/local.spec.ts +++ b/packages/settings/settings-local/tests/local.spec.ts @@ -1,6 +1,6 @@ import { afterEach, describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' -import z from 'schemastery' +import { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import { chmod, lstat, mkdir, mkdtemp, readFile, readdir, rename, rm, stat, symlink, writeFile } from 'node:fs/promises' import { tmpdir } from 'node:os' import { join } from 'node:path' diff --git a/packages/settings/settings-local/tests/lock-race.spec.ts b/packages/settings/settings-local/tests/lock-race.spec.ts index 46dd24353f..a5f65eab4f 100644 --- a/packages/settings/settings-local/tests/lock-race.spec.ts +++ b/packages/settings/settings-local/tests/lock-race.spec.ts @@ -1,8 +1,8 @@ // A temp-file write failure cannot be timed from outside. The `fs/promises` API // injects it once so the test can prove that the writer lock still releases. import { afterEach, describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' -import z from 'schemastery' +import { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import { access, mkdtemp, readFile, rm, writeFile } from 'node:fs/promises' import { tmpdir } from 'node:os' import { join } from 'node:path' diff --git a/packages/settings/settings-local/tests/watcher.spec.ts b/packages/settings/settings-local/tests/watcher.spec.ts index 7b289b22a3..456bfbb87d 100644 --- a/packages/settings/settings-local/tests/watcher.spec.ts +++ b/packages/settings/settings-local/tests/watcher.spec.ts @@ -1,6 +1,6 @@ import { afterEach, describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' -import z from 'schemastery' +import { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import { chmod, mkdtemp, readFile, rm, writeFile } from 'node:fs/promises' import { tmpdir } from 'node:os' import { join } from 'node:path' diff --git a/packages/settings/settings/package.json b/packages/settings/settings/package.json index 09112147ec..23cb60d13c 100644 --- a/packages/settings/settings/package.json +++ b/packages/settings/settings/package.json @@ -27,13 +27,13 @@ "peerDependencies": { "@deepseek-ai/dsh-brand": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.7", - "schemastery": "^3.18.0" + "@deepseek-ai/cordis": "^4.0.0-rc.7", + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { "@deepseek-ai/dsh-brand": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", - "cordis": "^4.0.0-rc.7", - "schemastery": "^3.18.0" + "@deepseek-ai/cordis": "^4.0.0-rc.7", + "@deepseek-ai/schemastery": "^3.18.0" } } diff --git a/packages/settings/settings/src/index.ts b/packages/settings/settings/src/index.ts index 37d3ec1d50..cacb1c5993 100644 --- a/packages/settings/settings/src/index.ts +++ b/packages/settings/settings/src/index.ts @@ -6,8 +6,8 @@ * @module @deepseek-ai/dsh-settings */ -import { Context, Service } from 'cordis' -import type z from 'schemastery' +import { Context, Service } from '@deepseek-ai/cordis' +import type z from '@deepseek-ai/schemastery' import type { Branded } from '@deepseek-ai/dsh-brand' import { redactSecrets } from './redact.ts' import type { RedactedSecret } from './redact.ts' @@ -133,7 +133,7 @@ export interface SettingsScope { replace(section: object): Promise } -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { settings: Settings } diff --git a/packages/settings/settings/src/invariant.ts b/packages/settings/settings/src/invariant.ts index d8db41bce4..d0e0344b19 100644 --- a/packages/settings/settings/src/invariant.ts +++ b/packages/settings/settings/src/invariant.ts @@ -3,7 +3,7 @@ * @module @deepseek-ai/dsh-settings/invariant */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantFailure, InvariantInstaller } from '@deepseek-ai/dsh-invariants' import { deepEqualJson } from './index.ts' diff --git a/packages/settings/settings/src/redact.ts b/packages/settings/settings/src/redact.ts index c9f4cda347..18664bcbbe 100644 --- a/packages/settings/settings/src/redact.ts +++ b/packages/settings/settings/src/redact.ts @@ -7,7 +7,7 @@ * @module @deepseek-ai/dsh-settings/redact */ -import type z from 'schemastery' +import type z from '@deepseek-ai/schemastery' /** * Minimal structural view of a live schemastery node. Only the relations the diff --git a/packages/settings/settings/tests/invariant.spec.ts b/packages/settings/settings/tests/invariant.spec.ts index 0976827368..179658e3ef 100644 --- a/packages/settings/settings/tests/invariant.spec.ts +++ b/packages/settings/settings/tests/invariant.spec.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' -import z from 'schemastery' +import { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import InvariantService from '@deepseek-ai/dsh-invariants' import * as SettingsInvariant from '../src/invariant.ts' import { settingsNamespace } from '../src/index.ts' diff --git a/packages/settings/settings/tests/redact.spec.ts b/packages/settings/settings/tests/redact.spec.ts index fff6902ea6..dbf02e8ba8 100644 --- a/packages/settings/settings/tests/redact.spec.ts +++ b/packages/settings/settings/tests/redact.spec.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' -import z from 'schemastery' +import { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import { redactSecrets, settingsNamespace } from '../src/index.ts' import { MemorySettings } from './memory.ts' diff --git a/packages/settings/settings/tests/settings.spec.ts b/packages/settings/settings/tests/settings.spec.ts index fb0efe1ff8..154f7ace4e 100644 --- a/packages/settings/settings/tests/settings.spec.ts +++ b/packages/settings/settings/tests/settings.spec.ts @@ -1,6 +1,6 @@ import { describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' -import z from 'schemastery' +import { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import { Settings, SettingsConflictError, deepEqualJson, installSettingsSection, settingsNamespace, type SettingsNamespace, type SettingsScope, type SettingsUpdateSource } from '../src/index.ts' import { MemorySettings } from './memory.ts' diff --git a/packages/skill/skill-badge/package.json b/packages/skill/skill-badge/package.json index b9dc53d9a5..7df1703c0e 100644 --- a/packages/skill/skill-badge/package.json +++ b/packages/skill/skill-badge/package.json @@ -27,11 +27,11 @@ "peerDependencies": { "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-skill": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-skill": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/skill/skill-badge/src/index.ts b/packages/skill/skill-badge/src/index.ts index 9cff2070fb..753d51f817 100644 --- a/packages/skill/skill-badge/src/index.ts +++ b/packages/skill/skill-badge/src/index.ts @@ -6,7 +6,7 @@ import { readFile } from 'node:fs/promises' import { fileURLToPath } from 'node:url' -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { BUNDLED_SKILL_RANK, type SkillCandidate, diff --git a/packages/skill/skill-badge/src/invariant.ts b/packages/skill/skill-badge/src/invariant.ts index c087d5917f..7f36b07a7d 100644 --- a/packages/skill/skill-badge/src/invariant.ts +++ b/packages/skill/skill-badge/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-skill-badge' diff --git a/packages/skill/skill-badge/tests/skill-badge.spec.ts b/packages/skill/skill-badge/tests/skill-badge.spec.ts index e4d62f1c89..1da2765a38 100644 --- a/packages/skill/skill-badge/tests/skill-badge.spec.ts +++ b/packages/skill/skill-badge/tests/skill-badge.spec.ts @@ -1,7 +1,7 @@ import { createHash } from 'node:crypto' import { readFile } from 'node:fs/promises' import { fileURLToPath } from 'node:url' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { describe, expect, it } from 'vitest' import SkillService from '@deepseek-ai/dsh-skill' import * as SkillBadge from '@deepseek-ai/dsh-skill-badge' diff --git a/packages/skill/skill-local/package.json b/packages/skill/skill-local/package.json index 25306774b9..24ce31af02 100644 --- a/packages/skill/skill-local/package.json +++ b/packages/skill/skill-local/package.json @@ -29,11 +29,11 @@ "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-paths": "^0.0.1", "@deepseek-ai/dsh-skill": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { "chokidar": "^5.0.0", - "schemastery": "^3.18.0", + "@deepseek-ai/schemastery": "^3.18.0", "yaml": "^2.4.2" }, "devDependencies": { @@ -41,6 +41,6 @@ "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-paths": "workspace:^", "@deepseek-ai/dsh-skill": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/skill/skill-local/src/index.ts b/packages/skill/skill-local/src/index.ts index 912feaa2ca..190a38c8ee 100644 --- a/packages/skill/skill-local/src/index.ts +++ b/packages/skill/skill-local/src/index.ts @@ -13,10 +13,10 @@ import { access, lstat, readdir, readFile, stat } from 'node:fs/promises' import { unwatchFile, watchFile, type Stats } from 'node:fs' import { dirname, isAbsolute, join, relative, resolve, sep } from 'node:path' import { homedir } from 'node:os' -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import chokidar from 'chokidar' -import z from 'schemastery' -import type Schema from 'schemastery' +import z from '@deepseek-ai/schemastery' +import type Schema from '@deepseek-ai/schemastery' import { parse as parseYaml } from 'yaml' import type { FileSystem, FsDirEntry, FsTarget } from '@deepseek-ai/dsh-fs' import { canonicalizeWatchPath, resolveDshHome } from '@deepseek-ai/dsh-paths' diff --git a/packages/skill/skill-local/src/invariant.ts b/packages/skill/skill-local/src/invariant.ts index 6d4917a4d9..37ddd64c95 100644 --- a/packages/skill/skill-local/src/invariant.ts +++ b/packages/skill/skill-local/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-skill-local' diff --git a/packages/skill/skill-local/tests/skill-local-watcher.spec.ts b/packages/skill/skill-local/tests/skill-local-watcher.spec.ts index 6aa0ef5ca4..dc4d954272 100644 --- a/packages/skill/skill-local/tests/skill-local-watcher.spec.ts +++ b/packages/skill/skill-local/tests/skill-local-watcher.spec.ts @@ -4,7 +4,7 @@ import { mkdir, realpath, rm, symlink, writeFile } from 'node:fs/promises' import { join } from 'node:path' import { tmpdir } from 'node:os' import { beforeEach, describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import SkillService from '@deepseek-ai/dsh-skill' interface FakeWatcherControl { diff --git a/packages/skill/skill-local/tests/skill-local.spec.ts b/packages/skill/skill-local/tests/skill-local.spec.ts index 5bf1d24856..5948ace8a4 100644 --- a/packages/skill/skill-local/tests/skill-local.spec.ts +++ b/packages/skill/skill-local/tests/skill-local.spec.ts @@ -2,7 +2,7 @@ import { describe, expect, it } from 'vitest' import { mkdir, readdir, readFile, rename, rm, stat, symlink, writeFile } from 'node:fs/promises' import { dirname, join } from 'node:path' import { tmpdir } from 'node:os' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import SkillService from '@deepseek-ai/dsh-skill' import { FileSystem, FsError, FsVersion, type FsDirEntry, type FsEditOutcome, type FsEditRequest, type FsInfo, type FsPathInfo, type FsTarget, type FsWriteOutcome } from '@deepseek-ai/dsh-fs' import * as SkillLocal from '../src/index.ts' diff --git a/packages/skill/skill/package.json b/packages/skill/skill/package.json index da51610ec3..20309664cd 100644 --- a/packages/skill/skill/package.json +++ b/packages/skill/skill/package.json @@ -28,15 +28,15 @@ "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-llm": "^0.0.1", "@deepseek-ai/dsh-scope": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-llm": "workspace:^", "@deepseek-ai/dsh-scope": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/skill/skill/src/index.ts b/packages/skill/skill/src/index.ts index c013933547..f5ba597820 100644 --- a/packages/skill/skill/src/index.ts +++ b/packages/skill/skill/src/index.ts @@ -10,12 +10,12 @@ * @module @deepseek-ai/dsh-skill */ -import { Context, Service } from 'cordis' +import { Context, Service } from '@deepseek-ai/cordis' import { assertNever } from '@deepseek-ai/dsh-llm' import { NamedEntries, ScopedLayers, scopeChainOf, scopeOf } from '@deepseek-ai/dsh-scope' import type { ScopeKey, ScopeLayer } from '@deepseek-ai/dsh-scope' -import z from 'schemastery' -import type Schema from 'schemastery' +import z from '@deepseek-ai/schemastery' +import type Schema from '@deepseek-ai/schemastery' const SKILL_NAME = /^[a-z0-9]+(?:-[a-z0-9]+)*$/ const DEFAULT_COLLECT_CACHE_ENTRIES = 128 @@ -281,7 +281,7 @@ export interface Config { readonly collectCacheMaxEntries?: number } -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { skills: SkillService } diff --git a/packages/skill/skill/src/invariant.ts b/packages/skill/skill/src/invariant.ts index 5145dee6da..b047a4476e 100644 --- a/packages/skill/skill/src/invariant.ts +++ b/packages/skill/skill/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-skill' diff --git a/packages/skill/skill/tests/skill.spec.ts b/packages/skill/skill/tests/skill.spec.ts index a5e03b610a..7dae5f5cf6 100644 --- a/packages/skill/skill/tests/skill.spec.ts +++ b/packages/skill/skill/tests/skill.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { bindScopeParent, createScope, scopeOf } from '@deepseek-ai/dsh-scope' import SkillService, { isModelInvocable, diff --git a/packages/skill/tool-skill/package.json b/packages/skill/tool-skill/package.json index e3ff7520b5..07adab663a 100644 --- a/packages/skill/tool-skill/package.json +++ b/packages/skill/tool-skill/package.json @@ -30,10 +30,10 @@ "@deepseek-ai/dsh-llm": "^0.0.1", "@deepseek-ai/dsh-skill": "^0.0.1", "@deepseek-ai/dsh-tools": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { "@deepseek-ai/dsh-agent": "workspace:^", @@ -44,6 +44,6 @@ "@deepseek-ai/dsh-skill": "workspace:^", "@deepseek-ai/dsh-skill-local": "workspace:^", "@deepseek-ai/dsh-tools": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/skill/tool-skill/src/index.ts b/packages/skill/tool-skill/src/index.ts index 634fb7ce02..e2a0cc2dca 100644 --- a/packages/skill/tool-skill/src/index.ts +++ b/packages/skill/tool-skill/src/index.ts @@ -5,8 +5,8 @@ */ import { createHash } from 'node:crypto' -import type { Context } from 'cordis' -import z from 'schemastery' +import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import type { Agent, PreStepDecision } from '@deepseek-ai/dsh-agent' import { defineTool } from '@deepseek-ai/dsh-tools' import { createUserMessage } from '@deepseek-ai/dsh-llm' diff --git a/packages/skill/tool-skill/src/invariant.ts b/packages/skill/tool-skill/src/invariant.ts index 68d70fa2d2..770edf99e5 100644 --- a/packages/skill/tool-skill/src/invariant.ts +++ b/packages/skill/tool-skill/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-tool-skill' diff --git a/packages/skill/tool-skill/tests/tool-skill.spec.ts b/packages/skill/tool-skill/tests/tool-skill.spec.ts index 496fe81d46..f4e5ab9f8e 100644 --- a/packages/skill/tool-skill/tests/tool-skill.spec.ts +++ b/packages/skill/tool-skill/tests/tool-skill.spec.ts @@ -2,7 +2,7 @@ import { describe, expect, it } from 'vitest' import { mkdir, writeFile } from 'node:fs/promises' import { join } from 'node:path' import { tmpdir } from 'node:os' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { createUserMessage, CallId, type Message } from '@deepseek-ai/dsh-llm' import { createScope, type Scope } from '@deepseek-ai/dsh-scope' import { Session, SessionId, type SessionEvent, type UserMessage } from '@deepseek-ai/dsh-session' diff --git a/packages/spill/spill-local/package.json b/packages/spill/spill-local/package.json index f185ab2c11..fcfacf1dcf 100644 --- a/packages/spill/spill-local/package.json +++ b/packages/spill/spill-local/package.json @@ -27,10 +27,10 @@ "peerDependencies": { "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-spill": "^0.0.1", - "cordis": "^4.0.0-rc.6" + "@deepseek-ai/cordis": "^4.0.0-rc.6" }, "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { "@deepseek-ai/dsh-brand": "workspace:^", @@ -38,6 +38,6 @@ "@deepseek-ai/dsh-llm": "workspace:^", "@deepseek-ai/dsh-session": "workspace:^", "@deepseek-ai/dsh-spill": "workspace:^", - "cordis": "^4.0.0-rc.6" + "@deepseek-ai/cordis": "^4.0.0-rc.6" } } diff --git a/packages/spill/spill-local/src/index.ts b/packages/spill/spill-local/src/index.ts index 73e2cad851..54e2e6cd6d 100644 --- a/packages/spill/spill-local/src/index.ts +++ b/packages/spill/spill-local/src/index.ts @@ -8,9 +8,9 @@ * @module @deepseek-ai/dsh-spill-local */ -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { resolve } from 'node:path' -import z from 'schemastery' +import z from '@deepseek-ai/schemastery' import { SpillLocator, SpillStore } from '@deepseek-ai/dsh-spill' import type { SaveTextSpill, SpillRef } from '@deepseek-ai/dsh-spill' import { privateRoot, saveTextFile } from './store.ts' diff --git a/packages/spill/spill-local/src/invariant.ts b/packages/spill/spill-local/src/invariant.ts index 4b44ddbebf..2651172635 100644 --- a/packages/spill/spill-local/src/invariant.ts +++ b/packages/spill/spill-local/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-spill-local' diff --git a/packages/spill/spill-local/tests/spill-local.spec.ts b/packages/spill/spill-local/tests/spill-local.spec.ts index 3c6f9ac82d..fd01babeff 100644 --- a/packages/spill/spill-local/tests/spill-local.spec.ts +++ b/packages/spill/spill-local/tests/spill-local.spec.ts @@ -7,7 +7,7 @@ */ import { describe, expect, it, beforeEach, afterEach } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { mkdtempSync, readFileSync, rmSync, statSync } from 'node:fs' import { tmpdir } from 'node:os' import { basename, dirname, isAbsolute, join, normalize } from 'node:path' diff --git a/packages/spill/spill-policy/package.json b/packages/spill/spill-policy/package.json index f238acd3d6..3d6cda2186 100644 --- a/packages/spill/spill-policy/package.json +++ b/packages/spill/spill-policy/package.json @@ -31,10 +31,10 @@ "@deepseek-ai/dsh-session": "^0.0.1", "@deepseek-ai/dsh-spill": "^0.0.1", "@deepseek-ai/dsh-tools": "^0.0.1", - "cordis": "^4.0.0-rc.6" + "@deepseek-ai/cordis": "^4.0.0-rc.6" }, "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { "@deepseek-ai/dsh-agent": "workspace:^", @@ -45,6 +45,6 @@ "@deepseek-ai/dsh-session": "workspace:^", "@deepseek-ai/dsh-spill": "workspace:^", "@deepseek-ai/dsh-tools": "workspace:^", - "cordis": "^4.0.0-rc.6" + "@deepseek-ai/cordis": "^4.0.0-rc.6" } } diff --git a/packages/spill/spill-policy/src/index.ts b/packages/spill/spill-policy/src/index.ts index 45d7ba2e74..ca71dd8588 100644 --- a/packages/spill/spill-policy/src/index.ts +++ b/packages/spill/spill-policy/src/index.ts @@ -43,8 +43,8 @@ * @module @deepseek-ai/dsh-spill-policy */ -import type { Context } from 'cordis' -import z from 'schemastery' +import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import type { ContentBlock } from '@deepseek-ai/dsh-llm' import { TextRetainer, describeOmitted } from '@deepseek-ai/dsh-retention' import type { Omitted } from '@deepseek-ai/dsh-retention' diff --git a/packages/spill/spill-policy/src/invariant.ts b/packages/spill/spill-policy/src/invariant.ts index 82a4bee211..860b4c5187 100644 --- a/packages/spill/spill-policy/src/invariant.ts +++ b/packages/spill/spill-policy/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-spill-policy' diff --git a/packages/spill/spill-policy/tests/spill-policy.spec.ts b/packages/spill/spill-policy/tests/spill-policy.spec.ts index 0d35927cab..ff8afa22dd 100644 --- a/packages/spill/spill-policy/tests/spill-policy.spec.ts +++ b/packages/spill/spill-policy/tests/spill-policy.spec.ts @@ -9,8 +9,8 @@ */ import { describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' -import Loader from '@cordisjs/plugin-loader' +import { Context } from '@deepseek-ai/cordis' +import Loader from '@deepseek-ai/cordis-plugin-loader' import { createUserMessage, CallId } from '@deepseek-ai/dsh-llm' import type { ContentBlock } from '@deepseek-ai/dsh-llm' import { SessionId } from '@deepseek-ai/dsh-session' diff --git a/packages/spill/spill/package.json b/packages/spill/spill/package.json index 6a87d575a3..996069461e 100644 --- a/packages/spill/spill/package.json +++ b/packages/spill/spill/package.json @@ -29,13 +29,13 @@ "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-llm": "^0.0.1", "@deepseek-ai/dsh-session": "^0.0.1", - "cordis": "^4.0.0-rc.6" + "@deepseek-ai/cordis": "^4.0.0-rc.6" }, "devDependencies": { "@deepseek-ai/dsh-brand": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-llm": "workspace:^", "@deepseek-ai/dsh-session": "workspace:^", - "cordis": "^4.0.0-rc.6" + "@deepseek-ai/cordis": "^4.0.0-rc.6" } } diff --git a/packages/spill/spill/src/index.ts b/packages/spill/spill/src/index.ts index 0d98ea9f66..ed0f8d33eb 100644 --- a/packages/spill/spill/src/index.ts +++ b/packages/spill/spill/src/index.ts @@ -14,13 +14,13 @@ * @module @deepseek-ai/dsh-spill */ -import { Context, Service } from 'cordis' +import { Context, Service } from '@deepseek-ai/cordis' import type { SaveTextSpill, SpillRef } from './types.ts' export { SpillLocator } from './types.ts' export type { SaveTextSpill, SpillOwner, SpillRef, SpillSource } from './types.ts' -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { spillStore: SpillStore } diff --git a/packages/spill/spill/src/invariant.ts b/packages/spill/spill/src/invariant.ts index 5011ac1d52..34e39d2e1d 100644 --- a/packages/spill/spill/src/invariant.ts +++ b/packages/spill/spill/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-spill' diff --git a/packages/spill/spill/tests/service.spec.ts b/packages/spill/spill/tests/service.spec.ts index 141072d67a..c17a77b273 100644 --- a/packages/spill/spill/tests/service.spec.ts +++ b/packages/spill/spill/tests/service.spec.ts @@ -6,7 +6,7 @@ */ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { CallId } from '@deepseek-ai/dsh-llm' import { SessionId } from '@deepseek-ai/dsh-session' import { SpillLocator, SpillStore } from '@deepseek-ai/dsh-spill' diff --git a/packages/storage/storage-domain/package.json b/packages/storage/storage-domain/package.json index aaa277b244..fe5915c2ea 100644 --- a/packages/storage/storage-domain/package.json +++ b/packages/storage/storage-domain/package.json @@ -27,15 +27,15 @@ "peerDependencies": { "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-storage": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { - "schemastery": "^3.18.0", + "@deepseek-ai/schemastery": "^3.18.0", "zod": "^4.4.3" }, "devDependencies": { "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-storage": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/storage/storage-domain/src/domain.ts b/packages/storage/storage-domain/src/domain.ts index 26ed726b93..c4087d6dd2 100644 --- a/packages/storage/storage-domain/src/domain.ts +++ b/packages/storage/storage-domain/src/domain.ts @@ -9,7 +9,7 @@ * @module @deepseek-ai/dsh-storage-domain/src/domain */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { KvUnit } from '@deepseek-ai/dsh-storage' import { DomainError } from './error.ts' import type { DomainSpec, DomainGlobalSpec, TableKeyOf, TableValueOf } from './spec.ts' diff --git a/packages/storage/storage-domain/src/events.ts b/packages/storage/storage-domain/src/events.ts index f70095e5d5..610182d07a 100644 --- a/packages/storage/storage-domain/src/events.ts +++ b/packages/storage/storage-domain/src/events.ts @@ -33,7 +33,7 @@ export interface DomainChangedDeleted extends DomainChangedBase { /** One durable domain change; a closed union — switch on `operation`. */ export type DomainChanged = DomainChangedPut | DomainChangedDeleted -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Events { /** * A domain record or the global singleton changed, emitted once per write diff --git a/packages/storage/storage-domain/src/index.ts b/packages/storage/storage-domain/src/index.ts index cb6c5f0f77..d2c16a3d69 100644 --- a/packages/storage/storage-domain/src/index.ts +++ b/packages/storage/storage-domain/src/index.ts @@ -7,8 +7,8 @@ * @module @deepseek-ai/dsh-storage-domain */ -import type { Context } from 'cordis' -import z from 'schemastery' +import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import { storageBackendServiceKey } from '@deepseek-ai/dsh-storage' import { DomainError } from './error.ts' import { descriptorOf } from './spec.ts' @@ -32,7 +32,7 @@ declare module '@deepseek-ai/dsh-storage' { } } -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { storageDomain: DomainFacility } diff --git a/packages/storage/storage-domain/src/invariant.ts b/packages/storage/storage-domain/src/invariant.ts index b2da8bebe4..5386149115 100644 --- a/packages/storage/storage-domain/src/invariant.ts +++ b/packages/storage/storage-domain/src/invariant.ts @@ -9,7 +9,7 @@ * @module @deepseek-ai/dsh-storage-domain/invariant */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantFailure, InvariantInstaller } from '@deepseek-ai/dsh-invariants' import type { DomainChanged } from './events.ts' diff --git a/packages/storage/storage-domain/tests/domain.spec.ts b/packages/storage/storage-domain/tests/domain.spec.ts index 4a083b3f78..5e1afbc863 100644 --- a/packages/storage/storage-domain/tests/domain.spec.ts +++ b/packages/storage/storage-domain/tests/domain.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { z } from 'zod' import Storage, { storageBackendServiceKey } from '@deepseek-ai/dsh-storage' import { apply, DomainFacility, defineDomain, domainTable } from '../src/index.ts' diff --git a/packages/storage/storage-domain/tests/invariant.spec.ts b/packages/storage/storage-domain/tests/invariant.spec.ts index 80c7264aae..9efe42c108 100644 --- a/packages/storage/storage-domain/tests/invariant.spec.ts +++ b/packages/storage/storage-domain/tests/invariant.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { z } from 'zod' import Storage from '@deepseek-ai/dsh-storage' import InvariantService, { InvariantError } from '@deepseek-ai/dsh-invariants' diff --git a/packages/storage/storage-json/package.json b/packages/storage/storage-json/package.json index 4dc9bec40b..55012ed819 100644 --- a/packages/storage/storage-json/package.json +++ b/packages/storage/storage-json/package.json @@ -27,14 +27,14 @@ "peerDependencies": { "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-storage": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-storage": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/storage/storage-json/src/index.ts b/packages/storage/storage-json/src/index.ts index c2c0ac0dd8..69c42cd194 100644 --- a/packages/storage/storage-json/src/index.ts +++ b/packages/storage/storage-json/src/index.ts @@ -7,8 +7,8 @@ import { mkdir } from 'node:fs/promises' import { join } from 'node:path' -import type { Context } from 'cordis' -import z from 'schemastery' +import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import { StorageError, UNIT_NAME_RE, storageBackendServiceKey } from '@deepseek-ai/dsh-storage' import type { KvFacet, KvUnit, KvUnitDescriptor, StorageBackend } from '@deepseek-ai/dsh-storage' import { openJsonUnit } from './unit.ts' diff --git a/packages/storage/storage-json/src/invariant.ts b/packages/storage/storage-json/src/invariant.ts index 3f3ec4a2d1..915a898e8f 100644 --- a/packages/storage/storage-json/src/invariant.ts +++ b/packages/storage/storage-json/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-storage-json' diff --git a/packages/storage/storage-json/tests/json-backend.spec.ts b/packages/storage/storage-json/tests/json-backend.spec.ts index b8d37eabb9..727981b49b 100644 --- a/packages/storage/storage-json/tests/json-backend.spec.ts +++ b/packages/storage/storage-json/tests/json-backend.spec.ts @@ -2,7 +2,7 @@ import { mkdir, mkdtemp, readFile, rename, rm, writeFile } from 'node:fs/promise import { tmpdir } from 'node:os' import { join } from 'node:path' import { afterAll, describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import Storage, { storageBackendServiceKey } from '@deepseek-ai/dsh-storage' import InvariantService from '@deepseek-ai/dsh-invariants' import { runKvBackendContract } from '../../storage/tests/contract.ts' diff --git a/packages/storage/storage-sqlite/package.json b/packages/storage/storage-sqlite/package.json index cebde3d279..6283822419 100644 --- a/packages/storage/storage-sqlite/package.json +++ b/packages/storage/storage-sqlite/package.json @@ -27,14 +27,14 @@ "peerDependencies": { "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-storage": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-storage": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/storage/storage-sqlite/src/index.ts b/packages/storage/storage-sqlite/src/index.ts index eff5bb80fb..5cd59cadc2 100644 --- a/packages/storage/storage-sqlite/src/index.ts +++ b/packages/storage/storage-sqlite/src/index.ts @@ -5,8 +5,8 @@ * @module @deepseek-ai/dsh-storage-sqlite */ -import type { Context } from 'cordis' -import z from 'schemastery' +import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import type { DatabaseSync } from 'node:sqlite' import { StorageError, UNIT_NAME_RE, storageBackendServiceKey } from '@deepseek-ai/dsh-storage' import type { KvFacet, KvUnit, KvUnitDescriptor, StorageBackend } from '@deepseek-ai/dsh-storage' diff --git a/packages/storage/storage-sqlite/src/invariant.ts b/packages/storage/storage-sqlite/src/invariant.ts index cbfadc8442..1775bd9524 100644 --- a/packages/storage/storage-sqlite/src/invariant.ts +++ b/packages/storage/storage-sqlite/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-storage-sqlite' diff --git a/packages/storage/storage-sqlite/tests/invariant.spec.ts b/packages/storage/storage-sqlite/tests/invariant.spec.ts index 0c23906ca4..3255549a0c 100644 --- a/packages/storage/storage-sqlite/tests/invariant.spec.ts +++ b/packages/storage/storage-sqlite/tests/invariant.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import InvariantService from '@deepseek-ai/dsh-invariants' import * as StorageSqliteInvariant from '../src/invariant.ts' diff --git a/packages/storage/storage-sqlite/tests/sqlite-backend.spec.ts b/packages/storage/storage-sqlite/tests/sqlite-backend.spec.ts index 37cf7ba122..f2fd65ee42 100644 --- a/packages/storage/storage-sqlite/tests/sqlite-backend.spec.ts +++ b/packages/storage/storage-sqlite/tests/sqlite-backend.spec.ts @@ -1,5 +1,5 @@ import { afterEach, describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { chmod, mkdtemp, rm, writeFile } from 'node:fs/promises' import { tmpdir } from 'node:os' import { join } from 'node:path' diff --git a/packages/storage/storage/package.json b/packages/storage/storage/package.json index 1c78c1d434..094814dfa1 100644 --- a/packages/storage/storage/package.json +++ b/packages/storage/storage/package.json @@ -26,10 +26,10 @@ "license": "BSD-3-Clause", "peerDependencies": { "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-invariants": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/storage/storage/src/index.ts b/packages/storage/storage/src/index.ts index 5312513591..9344558e09 100644 --- a/packages/storage/storage/src/index.ts +++ b/packages/storage/storage/src/index.ts @@ -5,7 +5,7 @@ * @module @deepseek-ai/dsh-storage */ -import { Context, Service } from 'cordis' +import { Context, Service } from '@deepseek-ai/cordis' import { StorageError } from './error.ts' import { BackendRegistry } from './registry.ts' @@ -27,7 +27,7 @@ export function storageBackendServiceKey(name: string): string { return `storage.backend.${name}` } -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { storage: Storage } diff --git a/packages/storage/storage/src/invariant.ts b/packages/storage/storage/src/invariant.ts index cac811a39a..1c303c43fa 100644 --- a/packages/storage/storage/src/invariant.ts +++ b/packages/storage/storage/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-storage' diff --git a/packages/storage/storage/tests/registry.spec.ts b/packages/storage/storage/tests/registry.spec.ts index 232efc3640..c23a9a36c7 100644 --- a/packages/storage/storage/tests/registry.spec.ts +++ b/packages/storage/storage/tests/registry.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import Storage, { BackendRegistry, storageBackendServiceKey } from '../src/index.ts' import type { StorageBackend } from '../src/index.ts' diff --git a/packages/subagent/subagent-acp/package.json b/packages/subagent/subagent-acp/package.json index 424cb9cb5c..a99154af56 100644 --- a/packages/subagent/subagent-acp/package.json +++ b/packages/subagent/subagent-acp/package.json @@ -32,14 +32,14 @@ "@deepseek-ai/dsh-subagent": "^0.0.1", "@deepseek-ai/dsh-subprocess": "^0.0.1", "@deepseek-ai/dsh-timeout": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { "@agentclientprotocol/sdk": "0.25.1", - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { - "@cordisjs/plugin-loader": "^1.0.0-rc.5", + "@deepseek-ai/cordis-plugin-loader": "^1.0.0-rc.5", "@deepseek-ai/dsh-agent": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-llm": "workspace:^", @@ -49,6 +49,6 @@ "@deepseek-ai/dsh-subprocess": "workspace:^", "@deepseek-ai/dsh-subprocess-local": "workspace:^", "@deepseek-ai/dsh-timeout": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/subagent/subagent-acp/src/index.ts b/packages/subagent/subagent-acp/src/index.ts index af126b86de..4b526279ba 100644 --- a/packages/subagent/subagent-acp/src/index.ts +++ b/packages/subagent/subagent-acp/src/index.ts @@ -9,8 +9,8 @@ import { accessSync, constants, statSync } from 'node:fs' import { isAbsolute, resolve } from 'node:path' -import type { Context } from 'cordis' -import z from 'schemastery' +import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import type { ResolvedSubagentStartRequest, SubagentCapabilities, diff --git a/packages/subagent/subagent-acp/src/invariant.ts b/packages/subagent/subagent-acp/src/invariant.ts index 85c1601348..536404e6d9 100644 --- a/packages/subagent/subagent-acp/src/invariant.ts +++ b/packages/subagent/subagent-acp/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-subagent-acp' diff --git a/packages/subagent/subagent-acp/tests/subagent-acp.e2e.ts b/packages/subagent/subagent-acp/tests/subagent-acp.e2e.ts index 9216068b07..cacee70a2a 100644 --- a/packages/subagent/subagent-acp/tests/subagent-acp.e2e.ts +++ b/packages/subagent/subagent-acp/tests/subagent-acp.e2e.ts @@ -3,7 +3,7 @@ import { tmpdir } from 'node:os' import { join } from 'node:path' import { fileURLToPath } from 'node:url' import { afterEach, describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import type { Agent } from '@deepseek-ai/dsh-agent' import SubagentService from '@deepseek-ai/dsh-subagent' import LocalSubprocessService from '@deepseek-ai/dsh-subprocess-local' diff --git a/packages/subagent/subagent-acp/tests/subagent-acp.spec.ts b/packages/subagent/subagent-acp/tests/subagent-acp.spec.ts index 122d781b6c..291e02c32a 100644 --- a/packages/subagent/subagent-acp/tests/subagent-acp.spec.ts +++ b/packages/subagent/subagent-acp/tests/subagent-acp.spec.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' -import Loader from '@cordisjs/plugin-loader' +import { Context } from '@deepseek-ai/cordis' +import Loader from '@deepseek-ai/cordis-plugin-loader' import { chmodSync, existsSync, mkdtempSync, realpathSync, rmSync, writeFileSync } from 'node:fs' import { tmpdir } from 'node:os' import { join, resolve } from 'node:path' diff --git a/packages/subagent/subagent-claude-code/package.json b/packages/subagent/subagent-claude-code/package.json index 8b25c6919c..d2234104cb 100644 --- a/packages/subagent/subagent-claude-code/package.json +++ b/packages/subagent/subagent-claude-code/package.json @@ -31,12 +31,12 @@ "@deepseek-ai/dsh-subagent": "^0.0.1", "@deepseek-ai/dsh-subprocess": "^0.0.1", "@deepseek-ai/dsh-timeout": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { "@anthropic-ai/sdk": "0.93.0", "@anthropic-ai/claude-agent-sdk": "0.3.220", - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { "@deepseek-ai/dsh-agent": "workspace:^", @@ -48,6 +48,6 @@ "@deepseek-ai/dsh-subprocess": "workspace:^", "@deepseek-ai/dsh-subprocess-local": "workspace:^", "@deepseek-ai/dsh-timeout": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/subagent/subagent-claude-code/src/index.ts b/packages/subagent/subagent-claude-code/src/index.ts index e4d6fbac5f..ea780401d7 100644 --- a/packages/subagent/subagent-claude-code/src/index.ts +++ b/packages/subagent/subagent-claude-code/src/index.ts @@ -6,8 +6,8 @@ * @module @deepseek-ai/dsh-subagent-claude-code */ -import type { Context } from 'cordis' -import z from 'schemastery' +import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import { MAX_TIMER_DELAY_MS } from '@deepseek-ai/dsh-timeout' import { assertPositiveFinite, diff --git a/packages/subagent/subagent-claude-code/src/invariant.ts b/packages/subagent/subagent-claude-code/src/invariant.ts index 462692590f..44fa400e16 100644 --- a/packages/subagent/subagent-claude-code/src/invariant.ts +++ b/packages/subagent/subagent-claude-code/src/invariant.ts @@ -5,7 +5,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-subagent-claude-code' diff --git a/packages/subagent/subagent-claude-code/tests/real-deepseek.e2e.ts b/packages/subagent/subagent-claude-code/tests/real-deepseek.e2e.ts index 806181ad13..aa77615297 100644 --- a/packages/subagent/subagent-claude-code/tests/real-deepseek.e2e.ts +++ b/packages/subagent/subagent-claude-code/tests/real-deepseek.e2e.ts @@ -10,7 +10,7 @@ import { tmpdir } from 'node:os' import { dirname, join, resolve } from 'node:path' import { fileURLToPath } from 'node:url' import { promisify } from 'node:util' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { afterEach, describe, expect, it, vi } from 'vitest' import type { Agent } from '@deepseek-ai/dsh-agent' import SubagentService from '@deepseek-ai/dsh-subagent' diff --git a/packages/subagent/subagent-claude-code/tests/real-product.spec.ts b/packages/subagent/subagent-claude-code/tests/real-product.spec.ts index 00e56c23b8..558724eee2 100644 --- a/packages/subagent/subagent-claude-code/tests/real-product.spec.ts +++ b/packages/subagent/subagent-claude-code/tests/real-product.spec.ts @@ -15,7 +15,7 @@ import type { SDKMessage, SDKSystemMessage, } from '@anthropic-ai/claude-agent-sdk' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { afterEach, describe, expect, it, vi } from 'vitest' import type { Agent } from '@deepseek-ai/dsh-agent' import SubagentService from '@deepseek-ai/dsh-subagent' diff --git a/packages/subagent/subagent-claude-code/tests/subagent-claude-code.spec.ts b/packages/subagent/subagent-claude-code/tests/subagent-claude-code.spec.ts index 8c4ac1708d..b2cc0d7e37 100644 --- a/packages/subagent/subagent-claude-code/tests/subagent-claude-code.spec.ts +++ b/packages/subagent/subagent-claude-code/tests/subagent-claude-code.spec.ts @@ -6,8 +6,8 @@ import type { SDKResultMessage, SpawnOptions, } from '@anthropic-ai/claude-agent-sdk' -import { Context } from 'cordis' -import Loader from '@cordisjs/plugin-loader' +import { Context } from '@deepseek-ai/cordis' +import Loader from '@deepseek-ai/cordis-plugin-loader' import { afterEach, beforeEach, diff --git a/packages/subagent/subagent-codex/package.json b/packages/subagent/subagent-codex/package.json index 30788aa2e5..a14173e3ee 100644 --- a/packages/subagent/subagent-codex/package.json +++ b/packages/subagent/subagent-codex/package.json @@ -32,13 +32,13 @@ "@deepseek-ai/dsh-subagent": "^0.0.1", "@deepseek-ai/dsh-subprocess": "^0.0.1", "@deepseek-ai/dsh-timeout": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { - "@cordisjs/plugin-loader": "^1.0.0-rc.5", + "@deepseek-ai/cordis-plugin-loader": "^1.0.0-rc.5", "@deepseek-ai/dsh-agent": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-llm": "workspace:^", @@ -50,6 +50,6 @@ "@deepseek-ai/dsh-subprocess-local": "workspace:^", "@deepseek-ai/dsh-timeout": "workspace:^", "@openai/codex": "0.147.0", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/subagent/subagent-codex/src/index.ts b/packages/subagent/subagent-codex/src/index.ts index 23077e3b54..3b1bbec799 100644 --- a/packages/subagent/subagent-codex/src/index.ts +++ b/packages/subagent/subagent-codex/src/index.ts @@ -6,8 +6,8 @@ * @module @deepseek-ai/dsh-subagent-codex */ -import type { Context } from 'cordis' -import z from 'schemastery' +import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import { MAX_TIMER_DELAY_MS } from '@deepseek-ai/dsh-timeout' import { assertPositiveFinite, diff --git a/packages/subagent/subagent-codex/src/invariant.ts b/packages/subagent/subagent-codex/src/invariant.ts index a0c094af9c..ec9a6302c4 100644 --- a/packages/subagent/subagent-codex/src/invariant.ts +++ b/packages/subagent/subagent-codex/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-subagent-codex' diff --git a/packages/subagent/subagent-codex/tests/real-deepseek.e2e.ts b/packages/subagent/subagent-codex/tests/real-deepseek.e2e.ts index 5c39ebfb3d..c184a01bc9 100644 --- a/packages/subagent/subagent-codex/tests/real-deepseek.e2e.ts +++ b/packages/subagent/subagent-codex/tests/real-deepseek.e2e.ts @@ -11,7 +11,7 @@ import { tmpdir } from 'node:os' import { delimiter, join, resolve } from 'node:path' import { fileURLToPath } from 'node:url' import { promisify } from 'node:util' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { afterEach, describe, expect, it, vi } from 'vitest' import type { Agent } from '@deepseek-ai/dsh-agent' import SubagentService from '@deepseek-ai/dsh-subagent' diff --git a/packages/subagent/subagent-codex/tests/real-product.spec.ts b/packages/subagent/subagent-codex/tests/real-product.spec.ts index c39093b041..ef618aaef0 100644 --- a/packages/subagent/subagent-codex/tests/real-product.spec.ts +++ b/packages/subagent/subagent-codex/tests/real-product.spec.ts @@ -11,7 +11,7 @@ import { tmpdir } from 'node:os' import { delimiter, join, resolve } from 'node:path' import { fileURLToPath } from 'node:url' import { promisify } from 'node:util' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { afterEach, describe, expect, it, vi } from 'vitest' import type { Agent } from '@deepseek-ai/dsh-agent' import SubagentService from '@deepseek-ai/dsh-subagent' diff --git a/packages/subagent/subagent-codex/tests/subagent-codex.spec.ts b/packages/subagent/subagent-codex/tests/subagent-codex.spec.ts index 9318c59787..81923f2228 100644 --- a/packages/subagent/subagent-codex/tests/subagent-codex.spec.ts +++ b/packages/subagent/subagent-codex/tests/subagent-codex.spec.ts @@ -1,6 +1,6 @@ import { PassThrough } from 'node:stream' -import { Context } from 'cordis' -import Loader from '@cordisjs/plugin-loader' +import { Context } from '@deepseek-ai/cordis' +import Loader from '@deepseek-ai/cordis-plugin-loader' import { describe, expect, it, vi } from 'vitest' import type { Agent } from '@deepseek-ai/dsh-agent' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' diff --git a/packages/subagent/subagent-dsh-sdk/package.json b/packages/subagent/subagent-dsh-sdk/package.json index 07217be7c1..58bdd83e13 100644 --- a/packages/subagent/subagent-dsh-sdk/package.json +++ b/packages/subagent/subagent-dsh-sdk/package.json @@ -32,13 +32,13 @@ "@deepseek-ai/dsh-session": "^0.0.1", "@deepseek-ai/dsh-subagent": "^0.0.1", "@deepseek-ai/dsh-subprocess": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { - "@cordisjs/plugin-loader": "^1.0.0-rc.5", + "@deepseek-ai/cordis-plugin-loader": "^1.0.0-rc.5", "@deepseek-ai/dsh-agent": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-llm": "workspace:^", @@ -48,6 +48,6 @@ "@deepseek-ai/dsh-session": "workspace:^", "@deepseek-ai/dsh-subagent": "workspace:^", "@deepseek-ai/dsh-subprocess": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/subagent/subagent-dsh-sdk/src/index.ts b/packages/subagent/subagent-dsh-sdk/src/index.ts index 09a1a64d32..c07cb86456 100644 --- a/packages/subagent/subagent-dsh-sdk/src/index.ts +++ b/packages/subagent/subagent-dsh-sdk/src/index.ts @@ -10,8 +10,8 @@ * @module @deepseek-ai/dsh-subagent-dsh-sdk */ -import type { Context } from 'cordis' -import z from 'schemastery' +import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import type { SubagentCapabilities, SubagentProvider, SubagentStartRequest } from '@deepseek-ai/dsh-subagent' import { assertPositiveFinite, NO_START_CAPABILITIES, resolveChildCwd, validateConfiguredCwd } from '@deepseek-ai/dsh-subagent' import { diff --git a/packages/subagent/subagent-dsh-sdk/src/invariant.ts b/packages/subagent/subagent-dsh-sdk/src/invariant.ts index 2aca0413ba..cddaed01bf 100644 --- a/packages/subagent/subagent-dsh-sdk/src/invariant.ts +++ b/packages/subagent/subagent-dsh-sdk/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-subagent-dsh-sdk' diff --git a/packages/subagent/subagent-dsh-sdk/tests/subagent-dsh-sdk.spec.ts b/packages/subagent/subagent-dsh-sdk/tests/subagent-dsh-sdk.spec.ts index e42a76c90c..26043f6a8d 100644 --- a/packages/subagent/subagent-dsh-sdk/tests/subagent-dsh-sdk.spec.ts +++ b/packages/subagent/subagent-dsh-sdk/tests/subagent-dsh-sdk.spec.ts @@ -7,7 +7,7 @@ */ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { existsSync, mkdtempSync, rmSync } from 'node:fs' import { tmpdir } from 'node:os' import { join } from 'node:path' diff --git a/packages/subagent/subagent-fork/package.json b/packages/subagent/subagent-fork/package.json index 1a77983d56..57d79a38d4 100644 --- a/packages/subagent/subagent-fork/package.json +++ b/packages/subagent/subagent-fork/package.json @@ -30,13 +30,13 @@ "@deepseek-ai/dsh-session": "^0.0.1", "@deepseek-ai/dsh-subagent": "^0.0.1", "@deepseek-ai/dsh-subagent-inprocess": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { - "@cordisjs/plugin-loader": "^1.0.0-rc.5", + "@deepseek-ai/cordis-plugin-loader": "^1.0.0-rc.5", "@deepseek-ai/dsh-agent": "workspace:^", "@deepseek-ai/dsh-agent-loop": "workspace:^", "@deepseek-ai/dsh-agent-loop-testkit": "workspace:^", @@ -46,6 +46,6 @@ "@deepseek-ai/dsh-subagent": "workspace:^", "@deepseek-ai/dsh-subagent-inprocess": "workspace:^", "@deepseek-ai/dsh-subagent-spawn": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/subagent/subagent-fork/src/index.ts b/packages/subagent/subagent-fork/src/index.ts index 7257c8dc06..0a3ea21aa2 100644 --- a/packages/subagent/subagent-fork/src/index.ts +++ b/packages/subagent/subagent-fork/src/index.ts @@ -7,8 +7,8 @@ * @module @deepseek-ai/dsh-subagent-fork */ -import type { Context } from 'cordis' -import z from 'schemastery' +import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import type { SessionEvent } from '@deepseek-ai/dsh-session' import type { Agent } from '@deepseek-ai/dsh-agent' import type { diff --git a/packages/subagent/subagent-fork/src/invariant.ts b/packages/subagent/subagent-fork/src/invariant.ts index e3d65701b1..7cff3d76f7 100644 --- a/packages/subagent/subagent-fork/src/invariant.ts +++ b/packages/subagent/subagent-fork/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-subagent-fork' diff --git a/packages/subagent/subagent-fork/tests/multi-subagent.spec.ts b/packages/subagent/subagent-fork/tests/multi-subagent.spec.ts index 490b07f77b..7bff34c35b 100644 --- a/packages/subagent/subagent-fork/tests/multi-subagent.spec.ts +++ b/packages/subagent/subagent-fork/tests/multi-subagent.spec.ts @@ -1,6 +1,6 @@ import { createUserMessage } from '@deepseek-ai/dsh-llm' import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { SessionId } from '@deepseek-ai/dsh-session' import AgentLoop from '@deepseek-ai/dsh-agent-loop' import { mountAgentLoopTestDependencies } from '@deepseek-ai/dsh-agent-loop-testkit' diff --git a/packages/subagent/subagent-fork/tests/subagent-fork.spec.ts b/packages/subagent/subagent-fork/tests/subagent-fork.spec.ts index 70002b0e88..dcd3d0230d 100644 --- a/packages/subagent/subagent-fork/tests/subagent-fork.spec.ts +++ b/packages/subagent/subagent-fork/tests/subagent-fork.spec.ts @@ -1,7 +1,7 @@ import { createUserMessage } from '@deepseek-ai/dsh-llm' import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' -import Loader from '@cordisjs/plugin-loader' +import { Context } from '@deepseek-ai/cordis' +import Loader from '@deepseek-ai/cordis-plugin-loader' import AgentRegistry from '@deepseek-ai/dsh-agent' import { SessionId } from '@deepseek-ai/dsh-session' import AgentLoop from '@deepseek-ai/dsh-agent-loop' diff --git a/packages/subagent/subagent-inprocess/package.json b/packages/subagent/subagent-inprocess/package.json index 36646e7f7a..90a30dc785 100644 --- a/packages/subagent/subagent-inprocess/package.json +++ b/packages/subagent/subagent-inprocess/package.json @@ -34,7 +34,7 @@ "@deepseek-ai/dsh-system-prompt": "^0.0.1", "@deepseek-ai/dsh-tools": "^0.0.1", "@deepseek-ai/dsh-user-approval": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "peerDependenciesMeta": { "@deepseek-ai/dsh-sandbox-policy": { @@ -45,8 +45,8 @@ } }, "devDependencies": { - "@cordisjs/plugin-include": "^1.0.4", - "@cordisjs/plugin-loader": "^1.0.0-rc.5", + "@deepseek-ai/cordis-plugin-include": "^1.0.4", + "@deepseek-ai/cordis-plugin-loader": "^1.0.0-rc.5", "@deepseek-ai/dsh-agent": "workspace:^", "@deepseek-ai/dsh-agent-loop": "workspace:^", "@deepseek-ai/dsh-agent-loop-testkit": "workspace:^", @@ -61,6 +61,6 @@ "@deepseek-ai/dsh-tool-fs": "workspace:^", "@deepseek-ai/dsh-tools": "workspace:^", "@deepseek-ai/dsh-user-approval": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/subagent/subagent-inprocess/src/index.ts b/packages/subagent/subagent-inprocess/src/index.ts index ee7779447a..92718db905 100644 --- a/packages/subagent/subagent-inprocess/src/index.ts +++ b/packages/subagent/subagent-inprocess/src/index.ts @@ -12,7 +12,7 @@ */ import { randomUUID } from 'node:crypto' -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { Agent, AgentHandle } from '@deepseek-ai/dsh-agent' import { findLastMessageTurnEnd, SessionId, type SessionEvent, type TurnEndReason } from '@deepseek-ai/dsh-session' import { createUserMessage, type ContentBlock } from '@deepseek-ai/dsh-llm' diff --git a/packages/subagent/subagent-inprocess/src/invariant.ts b/packages/subagent/subagent-inprocess/src/invariant.ts index 4a2188dcc8..e8639e1f9a 100644 --- a/packages/subagent/subagent-inprocess/src/invariant.ts +++ b/packages/subagent/subagent-inprocess/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-subagent-inprocess' diff --git a/packages/subagent/subagent-inprocess/src/structured.ts b/packages/subagent/subagent-inprocess/src/structured.ts index 6bf5efbd35..d1471b3dde 100644 --- a/packages/subagent/subagent-inprocess/src/structured.ts +++ b/packages/subagent/subagent-inprocess/src/structured.ts @@ -10,7 +10,7 @@ * @module @deepseek-ai/dsh-subagent-inprocess/structured */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { ToolSchema } from '@deepseek-ai/dsh-llm' import type { ToolExecution, ToolRunContext } from '@deepseek-ai/dsh-tools' import { ToolArgsError, validateJsonSchemaValue, type ObjectJsonSchema } from '@deepseek-ai/dsh-tools' diff --git a/packages/subagent/subagent-inprocess/tests/inheritance.spec.ts b/packages/subagent/subagent-inprocess/tests/inheritance.spec.ts index 804249ba77..30026b4ba6 100644 --- a/packages/subagent/subagent-inprocess/tests/inheritance.spec.ts +++ b/packages/subagent/subagent-inprocess/tests/inheritance.spec.ts @@ -4,7 +4,7 @@ import { afterEach, beforeEach, describe, expect, it } from 'vitest' import { mkdtemp, readFile, realpath, rm } from 'node:fs/promises' import { tmpdir } from 'node:os' import { join } from 'node:path' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import type { Agent } from '@deepseek-ai/dsh-agent' import AgentLoop from '@deepseek-ai/dsh-agent-loop' import { mountAgentLoopTestDependencies } from '@deepseek-ai/dsh-agent-loop-testkit' diff --git a/packages/subagent/subagent-inprocess/tests/preset-inheritance.spec.ts b/packages/subagent/subagent-inprocess/tests/preset-inheritance.spec.ts index af199cd867..28306f0dcc 100644 --- a/packages/subagent/subagent-inprocess/tests/preset-inheritance.spec.ts +++ b/packages/subagent/subagent-inprocess/tests/preset-inheritance.spec.ts @@ -10,9 +10,9 @@ import { afterEach, describe, expect, it } from 'vitest' import { dirname, join } from 'node:path' import { fileURLToPath, pathToFileURL } from 'node:url' -import { Context } from 'cordis' -import Loader from '@cordisjs/plugin-loader' -import Include from '@cordisjs/plugin-include' +import { Context } from '@deepseek-ai/cordis' +import Loader from '@deepseek-ai/cordis-plugin-loader' +import Include from '@deepseek-ai/cordis-plugin-include' import type { Agent } from '@deepseek-ai/dsh-agent' import AgentLoop from '@deepseek-ai/dsh-agent-loop' import { mountAgentLoopTestDependencies } from '@deepseek-ai/dsh-agent-loop-testkit' diff --git a/packages/subagent/subagent-inprocess/tests/structured.spec.ts b/packages/subagent/subagent-inprocess/tests/structured.spec.ts index 06fa641336..0fef7f9ef9 100644 --- a/packages/subagent/subagent-inprocess/tests/structured.spec.ts +++ b/packages/subagent/subagent-inprocess/tests/structured.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { createUserMessage, CallId, type ContentBlock, type GenerateOptions } from '@deepseek-ai/dsh-llm' import { SessionId } from '@deepseek-ai/dsh-session' import AgentLoop from '@deepseek-ai/dsh-agent-loop' diff --git a/packages/subagent/subagent-inprocess/tests/subagent-inprocess.spec.ts b/packages/subagent/subagent-inprocess/tests/subagent-inprocess.spec.ts index 46b94f9f5a..c490bc7d3b 100644 --- a/packages/subagent/subagent-inprocess/tests/subagent-inprocess.spec.ts +++ b/packages/subagent/subagent-inprocess/tests/subagent-inprocess.spec.ts @@ -1,6 +1,6 @@ import { createUserMessage } from '@deepseek-ai/dsh-llm' import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { type Agent, type AgentOptions } from '@deepseek-ai/dsh-agent' import { SessionId } from '@deepseek-ai/dsh-session' import AgentLoop from '@deepseek-ai/dsh-agent-loop' diff --git a/packages/subagent/subagent-spawn/package.json b/packages/subagent/subagent-spawn/package.json index 243e7afb52..f20b96227c 100644 --- a/packages/subagent/subagent-spawn/package.json +++ b/packages/subagent/subagent-spawn/package.json @@ -28,13 +28,13 @@ "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-subagent": "^0.0.1", "@deepseek-ai/dsh-subagent-inprocess": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { - "@cordisjs/plugin-loader": "^1.0.0-rc.5", + "@deepseek-ai/cordis-plugin-loader": "^1.0.0-rc.5", "@deepseek-ai/dsh-agent": "workspace:^", "@deepseek-ai/dsh-agent-loop": "workspace:^", "@deepseek-ai/dsh-agent-loop-testkit": "workspace:^", @@ -48,6 +48,6 @@ "@deepseek-ai/dsh-subagent-inprocess": "workspace:^", "@deepseek-ai/dsh-tool-bash": "workspace:^", "@deepseek-ai/dsh-tool-subagent": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/subagent/subagent-spawn/src/index.ts b/packages/subagent/subagent-spawn/src/index.ts index d74114f55a..b7b6456270 100644 --- a/packages/subagent/subagent-spawn/src/index.ts +++ b/packages/subagent/subagent-spawn/src/index.ts @@ -6,8 +6,8 @@ * @module @deepseek-ai/dsh-subagent-spawn */ -import type { Context } from 'cordis' -import z from 'schemastery' +import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import type { ContinuableCreateSpec, ResolvedSubagentStartRequest, diff --git a/packages/subagent/subagent-spawn/src/invariant.ts b/packages/subagent/subagent-spawn/src/invariant.ts index 0ba0182f9f..a6f1e1ccca 100644 --- a/packages/subagent/subagent-spawn/src/invariant.ts +++ b/packages/subagent/subagent-spawn/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-subagent-spawn' diff --git a/packages/subagent/subagent-spawn/tests/harness.ts b/packages/subagent/subagent-spawn/tests/harness.ts index 33de6d0cc6..f8a45aef25 100644 --- a/packages/subagent/subagent-spawn/tests/harness.ts +++ b/packages/subagent/subagent-spawn/tests/harness.ts @@ -1,4 +1,4 @@ -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import type { Agent } from '@deepseek-ai/dsh-agent' import AgentLoop from '@deepseek-ai/dsh-agent-loop' import { mountAgentLoopTestDependencies } from '@deepseek-ai/dsh-agent-loop-testkit' diff --git a/packages/subagent/subagent-spawn/tests/spawn.e2e.ts b/packages/subagent/subagent-spawn/tests/spawn.e2e.ts index 48220c1d9d..ba76c69203 100644 --- a/packages/subagent/subagent-spawn/tests/spawn.e2e.ts +++ b/packages/subagent/subagent-spawn/tests/spawn.e2e.ts @@ -3,7 +3,7 @@ import { mkdtemp, readFile, rm } from 'node:fs/promises' import { tmpdir } from 'node:os' import { join } from 'node:path' import { afterEach, describe, expect, it } from 'vitest' -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { spawnHarness, waitForIdle } from './harness.ts' import { SessionId } from '@deepseek-ai/dsh-session' diff --git a/packages/subagent/subagent-spawn/tests/subagent-spawn.spec.ts b/packages/subagent/subagent-spawn/tests/subagent-spawn.spec.ts index 508d5132fb..fdef892d7f 100644 --- a/packages/subagent/subagent-spawn/tests/subagent-spawn.spec.ts +++ b/packages/subagent/subagent-spawn/tests/subagent-spawn.spec.ts @@ -1,7 +1,7 @@ import { createUserMessage } from '@deepseek-ai/dsh-llm' import { describe, expect, it } from 'vitest' -import { Context, symbols, type EffectMeta } from 'cordis' -import Loader from '@cordisjs/plugin-loader' +import { Context, symbols, type EffectMeta } from '@deepseek-ai/cordis' +import Loader from '@deepseek-ai/cordis-plugin-loader' import AgentRegistry, { type Agent } from '@deepseek-ai/dsh-agent' import { SessionId } from '@deepseek-ai/dsh-session' import AgentLoop from '@deepseek-ai/dsh-agent-loop' diff --git a/packages/subagent/subagent/package.json b/packages/subagent/subagent/package.json index 35504c9dc4..ddecb9f6b1 100644 --- a/packages/subagent/subagent/package.json +++ b/packages/subagent/subagent/package.json @@ -45,7 +45,7 @@ "@deepseek-ai/dsh-session-projection-cache": "^0.0.1", "@deepseek-ai/dsh-tasks": "^0.0.1", "@deepseek-ai/dsh-tools": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "peerDependenciesMeta": { "@deepseek-ai/dsh-agent-presets": { @@ -79,6 +79,6 @@ "@deepseek-ai/dsh-storage-domain": "workspace:^", "@deepseek-ai/dsh-tasks": "workspace:^", "@deepseek-ai/dsh-tools": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/subagent/subagent/src/activation-setup-registry.ts b/packages/subagent/subagent/src/activation-setup-registry.ts index 5681e89863..9317d5a2ac 100644 --- a/packages/subagent/subagent/src/activation-setup-registry.ts +++ b/packages/subagent/subagent/src/activation-setup-registry.ts @@ -11,7 +11,7 @@ * @module @deepseek-ai/dsh-subagent/activation-setup-registry */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { AgentSetupCommit } from '@deepseek-ai/dsh-agent' import { errorChain } from '@deepseek-ai/dsh-llm' import { SubagentError } from './error.ts' diff --git a/packages/subagent/subagent/src/child-agent.ts b/packages/subagent/subagent/src/child-agent.ts index c501a19a56..e9ca1422ce 100644 --- a/packages/subagent/subagent/src/child-agent.ts +++ b/packages/subagent/subagent/src/child-agent.ts @@ -8,7 +8,7 @@ * @module @deepseek-ai/dsh-subagent/child-agent */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { Agent, AgentOptions, CreateAgentOptions } from '@deepseek-ai/dsh-agent' import type { SessionId } from '@deepseek-ai/dsh-session' import type { ToolRestriction } from '@deepseek-ai/dsh-tools' diff --git a/packages/subagent/subagent/src/continuation.ts b/packages/subagent/subagent/src/continuation.ts index 1cb16daca6..1403b29d17 100644 --- a/packages/subagent/subagent/src/continuation.ts +++ b/packages/subagent/subagent/src/continuation.ts @@ -15,7 +15,7 @@ */ import { randomUUID } from 'node:crypto' -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { Agent, AgentHandle, diff --git a/packages/subagent/subagent/src/index.ts b/packages/subagent/subagent/src/index.ts index eddcf63c3c..5c6898723c 100644 --- a/packages/subagent/subagent/src/index.ts +++ b/packages/subagent/subagent/src/index.ts @@ -31,7 +31,7 @@ * @module @deepseek-ai/dsh-subagent */ -import { Context, Service } from 'cordis' +import { Context, Service } from '@deepseek-ai/cordis' import { scopeTarget } from '@deepseek-ai/dsh-scope' import type { Scoped } from '@deepseek-ai/dsh-scope' import { assertObjectJsonSchema } from '@deepseek-ai/dsh-tools' @@ -122,7 +122,7 @@ export type { SubagentDescendantListEntry, SubagentListEntry } from './list-chil export type { SubagentRunEndInfo, SubagentRunInfo } from './types.ts' export type { SubagentIdentityProjection, SubagentTimingProjection } from './projection-types.ts' -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { subagents: SubagentService } diff --git a/packages/subagent/subagent/src/invariant.ts b/packages/subagent/subagent/src/invariant.ts index d9a497eb77..c2ef451920 100644 --- a/packages/subagent/subagent/src/invariant.ts +++ b/packages/subagent/subagent/src/invariant.ts @@ -1,6 +1,6 @@ /** Package-owned subagent registry and lifecycle invariants. @module @deepseek-ai/dsh-subagent/invariant */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantFailure, InvariantInstaller } from '@deepseek-ai/dsh-invariants' import type { SubagentProvider, SubagentRunEndInfo, SubagentRunInfo } from './types.ts' diff --git a/packages/subagent/subagent/src/lifecycle.ts b/packages/subagent/subagent/src/lifecycle.ts index 65c61ae9eb..eff0534d9f 100644 --- a/packages/subagent/subagent/src/lifecycle.ts +++ b/packages/subagent/subagent/src/lifecycle.ts @@ -15,7 +15,7 @@ */ import { randomUUID } from 'node:crypto' -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { Agent } from '@deepseek-ai/dsh-agent' import type { ContentBlock } from '@deepseek-ai/dsh-llm' import { findLastMessageTurnEnd } from '@deepseek-ai/dsh-session' diff --git a/packages/subagent/subagent/src/list-children.ts b/packages/subagent/subagent/src/list-children.ts index 8768a002b6..03f8da6c28 100644 --- a/packages/subagent/subagent/src/list-children.ts +++ b/packages/subagent/subagent/src/list-children.ts @@ -16,7 +16,7 @@ * @module @deepseek-ai/dsh-subagent */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { Session, SessionEvent, SessionHeader, SessionId } from '@deepseek-ai/dsh-session' import type { SessionPersistence } from '@deepseek-ai/dsh-session-persistence' import type { SessionProjectionRegistry } from '@deepseek-ai/dsh-session-projection' diff --git a/packages/subagent/subagent/tests/activation-setup-registry.spec.ts b/packages/subagent/subagent/tests/activation-setup-registry.spec.ts index 6353f486c5..6231ed3936 100644 --- a/packages/subagent/subagent/tests/activation-setup-registry.spec.ts +++ b/packages/subagent/subagent/tests/activation-setup-registry.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import SubagentActivationSetupRegistry from '../src/activation-setup-registry.ts' /** A child-like scoped context with observable disposal. */ diff --git a/packages/subagent/subagent/tests/continuation.spec.ts b/packages/subagent/subagent/tests/continuation.spec.ts index 9370676f76..6bd49312a0 100644 --- a/packages/subagent/subagent/tests/continuation.spec.ts +++ b/packages/subagent/subagent/tests/continuation.spec.ts @@ -2,7 +2,7 @@ import { afterEach, describe, expect, it, vi } from 'vitest' import { mkdtempSync, rmSync } from 'node:fs' import { tmpdir } from 'node:os' import { join } from 'node:path' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import type { Agent } from '@deepseek-ai/dsh-agent' import AgentLoop from '@deepseek-ai/dsh-agent-loop' import { mountAgentLoopTestDependencies } from '@deepseek-ai/dsh-agent-loop-testkit' diff --git a/packages/subagent/subagent/tests/invariant.spec.ts b/packages/subagent/subagent/tests/invariant.spec.ts index 21bdda0e06..615dd02aa5 100644 --- a/packages/subagent/subagent/tests/invariant.spec.ts +++ b/packages/subagent/subagent/tests/invariant.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { scopeTarget } from '@deepseek-ai/dsh-scope' import { SessionId } from '@deepseek-ai/dsh-session' import SubagentService, { SubagentRunId } from '@deepseek-ai/dsh-subagent' diff --git a/packages/subagent/subagent/tests/list-children.spec.ts b/packages/subagent/subagent/tests/list-children.spec.ts index fa2db5fd04..7a7afb5e22 100644 --- a/packages/subagent/subagent/tests/list-children.spec.ts +++ b/packages/subagent/subagent/tests/list-children.spec.ts @@ -3,7 +3,7 @@ import { mkdtempSync, rmSync } from 'node:fs' import { tmpdir } from 'node:os' import { join } from 'node:path' import { z } from 'zod' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { createUserMessage } from '@deepseek-ai/dsh-llm' import AgentLoop from '@deepseek-ai/dsh-agent-loop' import { mountAgentLoopTestDependencies } from '@deepseek-ai/dsh-agent-loop-testkit' diff --git a/packages/subagent/subagent/tests/service.spec.ts b/packages/subagent/subagent/tests/service.spec.ts index a50696cf2a..5106bc3427 100644 --- a/packages/subagent/subagent/tests/service.spec.ts +++ b/packages/subagent/subagent/tests/service.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, expectTypeOf, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { type Agent } from '@deepseek-ai/dsh-agent' import { HarnessError } from '@deepseek-ai/dsh-llm' diff --git a/packages/subagent/subagent/tests/timing-projection.spec.ts b/packages/subagent/subagent/tests/timing-projection.spec.ts index 0165f73714..a854e69df2 100644 --- a/packages/subagent/subagent/tests/timing-projection.spec.ts +++ b/packages/subagent/subagent/tests/timing-projection.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import SessionStore from '@deepseek-ai/dsh-session' import type { SessionEvent } from '@deepseek-ai/dsh-session' import SessionProjectionRegistry from '@deepseek-ai/dsh-session-projection' diff --git a/packages/subagent/tool-subagent-control/package.json b/packages/subagent/tool-subagent-control/package.json index 2848a7d14d..d1ca31c635 100644 --- a/packages/subagent/tool-subagent-control/package.json +++ b/packages/subagent/tool-subagent-control/package.json @@ -35,7 +35,7 @@ "@deepseek-ai/dsh-session": "^0.0.1", "@deepseek-ai/dsh-subagent": "^0.0.1", "@deepseek-ai/dsh-tools": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-agent": "workspace:^", @@ -50,6 +50,6 @@ "@deepseek-ai/dsh-subagent": "workspace:^", "@deepseek-ai/dsh-subagent-spawn": "workspace:^", "@deepseek-ai/dsh-tools": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/subagent/tool-subagent-control/src/index.ts b/packages/subagent/tool-subagent-control/src/index.ts index 43e3f52b4e..67c93cda5c 100644 --- a/packages/subagent/tool-subagent-control/src/index.ts +++ b/packages/subagent/tool-subagent-control/src/index.ts @@ -9,7 +9,7 @@ * @module @deepseek-ai/dsh-tool-subagent-control */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { defineTool } from '@deepseek-ai/dsh-tools' import type { ContentBlock } from '@deepseek-ai/dsh-llm' import { SessionId } from '@deepseek-ai/dsh-session' diff --git a/packages/subagent/tool-subagent-control/src/invariant.ts b/packages/subagent/tool-subagent-control/src/invariant.ts index c993426a26..2538fa5065 100644 --- a/packages/subagent/tool-subagent-control/src/invariant.ts +++ b/packages/subagent/tool-subagent-control/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-tool-subagent-control' diff --git a/packages/subagent/tool-subagent-control/src/list-agents.ts b/packages/subagent/tool-subagent-control/src/list-agents.ts index d47232b3cc..37a4c3bdff 100644 --- a/packages/subagent/tool-subagent-control/src/list-agents.ts +++ b/packages/subagent/tool-subagent-control/src/list-agents.ts @@ -7,7 +7,7 @@ * @module @deepseek-ai/dsh-tool-subagent-control/list-agents */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { defineTool } from '@deepseek-ai/dsh-tools' import type { Agent } from '@deepseek-ai/dsh-agent' import type { SessionId } from '@deepseek-ai/dsh-session' diff --git a/packages/subagent/tool-subagent-control/tests/list-agents.spec.ts b/packages/subagent/tool-subagent-control/tests/list-agents.spec.ts index 0361471031..1c12602dd2 100644 --- a/packages/subagent/tool-subagent-control/tests/list-agents.spec.ts +++ b/packages/subagent/tool-subagent-control/tests/list-agents.spec.ts @@ -2,7 +2,7 @@ import { afterEach, describe, expect, it, vi } from 'vitest' import { mkdtempSync, rmSync } from 'node:fs' import { tmpdir } from 'node:os' import { join } from 'node:path' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { CallId } from '@deepseek-ai/dsh-llm' import AgentLoop from '@deepseek-ai/dsh-agent-loop' import { mountAgentLoopTestDependencies } from '@deepseek-ai/dsh-agent-loop-testkit' diff --git a/packages/subagent/tool-subagent-control/tests/tool-subagent-control.spec.ts b/packages/subagent/tool-subagent-control/tests/tool-subagent-control.spec.ts index c5ea8fd1b8..d24f4cac9b 100644 --- a/packages/subagent/tool-subagent-control/tests/tool-subagent-control.spec.ts +++ b/packages/subagent/tool-subagent-control/tests/tool-subagent-control.spec.ts @@ -2,7 +2,7 @@ import { afterEach, describe, expect, it, vi } from 'vitest' import { mkdtempSync, rmSync } from 'node:fs' import { tmpdir } from 'node:os' import { join } from 'node:path' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { CallId } from '@deepseek-ai/dsh-llm' import AgentLoop from '@deepseek-ai/dsh-agent-loop' import { mountAgentLoopTestDependencies } from '@deepseek-ai/dsh-agent-loop-testkit' diff --git a/packages/subagent/tool-subagent-report/package.json b/packages/subagent/tool-subagent-report/package.json index 12e39c341c..c3f0e530ec 100644 --- a/packages/subagent/tool-subagent-report/package.json +++ b/packages/subagent/tool-subagent-report/package.json @@ -29,10 +29,10 @@ "@deepseek-ai/dsh-llm": "^0.0.1", "@deepseek-ai/dsh-subagent": "^0.0.1", "@deepseek-ai/dsh-tools": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { "@deepseek-ai/dsh-agent": "workspace:^", @@ -47,6 +47,6 @@ "@deepseek-ai/dsh-subagent-spawn": "workspace:^", "@deepseek-ai/dsh-tool-subagent-control": "workspace:^", "@deepseek-ai/dsh-tools": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/subagent/tool-subagent-report/src/index.ts b/packages/subagent/tool-subagent-report/src/index.ts index 962d8cf382..b33a5a29ab 100644 --- a/packages/subagent/tool-subagent-report/src/index.ts +++ b/packages/subagent/tool-subagent-report/src/index.ts @@ -6,8 +6,8 @@ * @module @deepseek-ai/dsh-tool-subagent-report */ -import type { Context } from 'cordis' -import z from 'schemastery' +import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import type { Agent } from '@deepseek-ai/dsh-agent' import type { ContentBlock } from '@deepseek-ai/dsh-llm' import type { SubagentReportDelivery } from '@deepseek-ai/dsh-subagent' diff --git a/packages/subagent/tool-subagent-report/src/invariant.ts b/packages/subagent/tool-subagent-report/src/invariant.ts index 50abca31c6..93777a70ec 100644 --- a/packages/subagent/tool-subagent-report/src/invariant.ts +++ b/packages/subagent/tool-subagent-report/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-tool-subagent-report' diff --git a/packages/subagent/tool-subagent-report/tests/tool-subagent-report.spec.ts b/packages/subagent/tool-subagent-report/tests/tool-subagent-report.spec.ts index 23757c2b54..121fb81f94 100644 --- a/packages/subagent/tool-subagent-report/tests/tool-subagent-report.spec.ts +++ b/packages/subagent/tool-subagent-report/tests/tool-subagent-report.spec.ts @@ -2,7 +2,7 @@ import { afterEach, describe, expect, it, vi } from 'vitest' import { mkdtempSync, rmSync } from 'node:fs' import { tmpdir } from 'node:os' import { join } from 'node:path' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import type { Agent } from '@deepseek-ai/dsh-agent' import AgentLoop from '@deepseek-ai/dsh-agent-loop' import { mountAgentLoopTestDependencies } from '@deepseek-ai/dsh-agent-loop-testkit' diff --git a/packages/subagent/tool-subagent/package.json b/packages/subagent/tool-subagent/package.json index f7d4c4e84e..d5d0da52d4 100644 --- a/packages/subagent/tool-subagent/package.json +++ b/packages/subagent/tool-subagent/package.json @@ -31,13 +31,13 @@ "@deepseek-ai/dsh-subagent": "^0.0.1", "@deepseek-ai/dsh-tasks": "^0.0.1", "@deepseek-ai/dsh-tools": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { - "@cordisjs/plugin-loader": "^1.0.0-rc.5", + "@deepseek-ai/cordis-plugin-loader": "^1.0.0-rc.5", "@deepseek-ai/dsh-agent": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-llm": "workspace:^", @@ -51,6 +51,6 @@ "@deepseek-ai/dsh-tasks-local": "workspace:^", "@deepseek-ai/dsh-tool-tasks": "workspace:^", "@deepseek-ai/dsh-tools": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/subagent/tool-subagent/src/index.ts b/packages/subagent/tool-subagent/src/index.ts index 67894c32cb..31df8f9e9c 100644 --- a/packages/subagent/tool-subagent/src/index.ts +++ b/packages/subagent/tool-subagent/src/index.ts @@ -8,8 +8,8 @@ * @module @deepseek-ai/dsh-tool-subagent */ -import type { Context } from 'cordis' -import z from 'schemastery' +import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import { defineTool } from '@deepseek-ai/dsh-tools' import type { AgentOptions } from '@deepseek-ai/dsh-agent' import type { ContentBlock } from '@deepseek-ai/dsh-llm' diff --git a/packages/subagent/tool-subagent/src/invariant.ts b/packages/subagent/tool-subagent/src/invariant.ts index bd30f4c563..5b8facc900 100644 --- a/packages/subagent/tool-subagent/src/invariant.ts +++ b/packages/subagent/tool-subagent/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-tool-subagent' diff --git a/packages/subagent/tool-subagent/tests/scripted-provider.spec.ts b/packages/subagent/tool-subagent/tests/scripted-provider.spec.ts index 7365348410..84a20e0e68 100644 --- a/packages/subagent/tool-subagent/tests/scripted-provider.spec.ts +++ b/packages/subagent/tool-subagent/tests/scripted-provider.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { type Agent } from '@deepseek-ai/dsh-agent' import SubagentService, { type SubagentStartRequest } from '@deepseek-ai/dsh-subagent' import { SessionId } from '@deepseek-ai/dsh-session' diff --git a/packages/subagent/tool-subagent/tests/scripted-provider.ts b/packages/subagent/tool-subagent/tests/scripted-provider.ts index 01c0769cf8..df35e6dbdd 100644 --- a/packages/subagent/tool-subagent/tests/scripted-provider.ts +++ b/packages/subagent/tool-subagent/tests/scripted-provider.ts @@ -1,6 +1,6 @@ /** Package-local scripted child boundary for deterministic tool-subagent tests. */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { ContentBlock } from '@deepseek-ai/dsh-llm' import { SessionId } from '@deepseek-ai/dsh-session' import type { diff --git a/packages/subagent/tool-subagent/tests/tool-subagent.spec.ts b/packages/subagent/tool-subagent/tests/tool-subagent.spec.ts index 04b127a856..8f289048cb 100644 --- a/packages/subagent/tool-subagent/tests/tool-subagent.spec.ts +++ b/packages/subagent/tool-subagent/tests/tool-subagent.spec.ts @@ -2,8 +2,8 @@ import { afterEach, describe, expect, it, vi } from 'vitest' import { mkdtempSync, rmSync } from 'node:fs' import { tmpdir } from 'node:os' import path from 'node:path' -import { Context } from 'cordis' -import Loader from '@cordisjs/plugin-loader' +import { Context } from '@deepseek-ai/cordis' +import Loader from '@deepseek-ai/cordis-plugin-loader' import { CallId } from '@deepseek-ai/dsh-llm' import SystemPrompt from '@deepseek-ai/dsh-system-prompt' import ToolRegistry, { TOOL_ABORTED_BEFORE_DISPATCH } from '@deepseek-ai/dsh-tools' diff --git a/packages/subprocess/subprocess-local/package.json b/packages/subprocess/subprocess-local/package.json index 7a68a9b91b..d966c0efb8 100644 --- a/packages/subprocess/subprocess-local/package.json +++ b/packages/subprocess/subprocess-local/package.json @@ -32,7 +32,7 @@ "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-subprocess": "^0.0.1", "@deepseek-ai/dsh-timeout": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { "node-pty": "^1.1.0" @@ -41,6 +41,6 @@ "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-subprocess": "workspace:^", "@deepseek-ai/dsh-timeout": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/subprocess/subprocess-local/src/index.ts b/packages/subprocess/subprocess-local/src/index.ts index 858bf3fc75..5242986b3b 100644 --- a/packages/subprocess/subprocess-local/src/index.ts +++ b/packages/subprocess/subprocess-local/src/index.ts @@ -10,7 +10,7 @@ import { constants } from 'node:fs' import { access, stat } from 'node:fs/promises' import { delimiter, extname, isAbsolute, resolve } from 'node:path' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import * as nodePty from 'node-pty' import type { IPtyForkOptions } from 'node-pty' import { SubprocessService } from '@deepseek-ai/dsh-subprocess' diff --git a/packages/subprocess/subprocess-local/src/invariant.ts b/packages/subprocess/subprocess-local/src/invariant.ts index b15b2dd511..335533d854 100644 --- a/packages/subprocess/subprocess-local/src/invariant.ts +++ b/packages/subprocess/subprocess-local/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-subprocess-local' diff --git a/packages/subprocess/subprocess-local/tests/local.spec.ts b/packages/subprocess/subprocess-local/tests/local.spec.ts index c4e3f91522..e3131543f4 100644 --- a/packages/subprocess/subprocess-local/tests/local.spec.ts +++ b/packages/subprocess/subprocess-local/tests/local.spec.ts @@ -1,7 +1,7 @@ import { PassThrough } from 'node:stream' import { describe, expect, it, vi } from 'vitest' import { basename, dirname, relative, resolve } from 'node:path' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import LocalSubprocessService from '@deepseek-ai/dsh-subprocess-local' import type { SubprocessSpawnSpec, SubprocessTerminalHandle, SubprocessTerminalSpawnSpec } from '@deepseek-ai/dsh-subprocess' import { childEnv } from '../src/spawn.ts' diff --git a/packages/subprocess/subprocess-local/tests/spawn.spec.ts b/packages/subprocess/subprocess-local/tests/spawn.spec.ts index 36da8307e3..4cffde6432 100644 --- a/packages/subprocess/subprocess-local/tests/spawn.spec.ts +++ b/packages/subprocess/subprocess-local/tests/spawn.spec.ts @@ -669,7 +669,7 @@ describe('tree-survivor escalation (terminate and bounded waits reach helpers th }) it('service teardown awaits tree survivors, not just handle settlement', async () => { - const { Context } = await import('cordis') + const { Context } = await import('@deepseek-ai/cordis') const { default: LocalSubprocessService } = await import('@deepseek-ai/dsh-subprocess-local') const ctx = new Context() const fiber = await ctx.plugin(LocalSubprocessService) diff --git a/packages/subprocess/subprocess/package.json b/packages/subprocess/subprocess/package.json index b7aa6308ad..f22708c717 100644 --- a/packages/subprocess/subprocess/package.json +++ b/packages/subprocess/subprocess/package.json @@ -26,10 +26,10 @@ "license": "BSD-3-Clause", "peerDependencies": { "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-invariants": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/subprocess/subprocess/src/index.ts b/packages/subprocess/subprocess/src/index.ts index 081ff436ec..bf30817b57 100644 --- a/packages/subprocess/subprocess/src/index.ts +++ b/packages/subprocess/subprocess/src/index.ts @@ -8,7 +8,7 @@ * @module @deepseek-ai/dsh-subprocess */ -import { Context, Service } from 'cordis' +import { Context, Service } from '@deepseek-ai/cordis' import { DSH_ENV_PREFIX } from './types.ts' import type { SubprocessHandle, SubprocessSpawnSpec } from './types.ts' import type { SubprocessTerminalHandle, SubprocessTerminalSpawnSpec } from './types.ts' @@ -65,7 +65,7 @@ export function scrubbedParentEnv(): Record { return env } -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { subprocess: SubprocessService } diff --git a/packages/subprocess/subprocess/src/invariant.ts b/packages/subprocess/subprocess/src/invariant.ts index 3a6ae526b0..c9e6ee904e 100644 --- a/packages/subprocess/subprocess/src/invariant.ts +++ b/packages/subprocess/subprocess/src/invariant.ts @@ -1,6 +1,6 @@ /** Package-owned invariant companion for the subprocess seam. @module @deepseek-ai/dsh-subprocess/invariant */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-subprocess' diff --git a/packages/subprocess/subprocess/tests/service.spec.ts b/packages/subprocess/subprocess/tests/service.spec.ts index e4f770a9a3..e4024b668c 100644 --- a/packages/subprocess/subprocess/tests/service.spec.ts +++ b/packages/subprocess/subprocess/tests/service.spec.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from 'vitest' import { PassThrough } from 'node:stream' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { scrubbedParentEnv, SubprocessService } from '@deepseek-ai/dsh-subprocess' import type { SubprocessHandle, diff --git a/packages/support/acp-snapshot/package.json b/packages/support/acp-snapshot/package.json index b504cbe50d..fb4e13ec1e 100644 --- a/packages/support/acp-snapshot/package.json +++ b/packages/support/acp-snapshot/package.json @@ -32,11 +32,11 @@ "peerDependencies": { "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-session": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-session": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/support/acp-snapshot/src/invariant.ts b/packages/support/acp-snapshot/src/invariant.ts index e94876100e..e9aada2488 100644 --- a/packages/support/acp-snapshot/src/invariant.ts +++ b/packages/support/acp-snapshot/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-acp-snapshot' diff --git a/packages/support/agent-loop-testkit/README.i18n.yaml b/packages/support/agent-loop-testkit/README.i18n.yaml index 2236b6aa8e..80da12640e 100644 --- a/packages/support/agent-loop-testkit/README.i18n.yaml +++ b/packages/support/agent-loop-testkit/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/support/agent-loop-testkit/README.md -README.md: 18c46069d3cfd402c83b5ecab68458667738163b -README.zh.md: 2151591154899094fe33f9c25c9b9144e6d02a22 +README.md: 3b7225b1cdd1960e4ab9fda36f89d1ab1ad672e3 +README.zh.md: b4e38202f45c3ac8f541e42eaba63acea3666ab8 diff --git a/packages/support/agent-loop-testkit/README.md b/packages/support/agent-loop-testkit/README.md index 18c46069d3..3b7225b1cd 100644 --- a/packages/support/agent-loop-testkit/README.md +++ b/packages/support/agent-loop-testkit/README.md @@ -7,7 +7,7 @@ Shared prerequisite mounting for tests that exercise the concrete `AgentLoop`. ` The caller registers adapters and optional plugins, mounts `AgentLoop` with the configuration under test, and disposes its own Context. System-prompt and tool-registry configuration can be forwarded through `options`; the helper does not provide test defaults beyond those owned by the services. A plugin-load failure rejects the helper call, while services activated earlier in the sequence remain owned by the caller's Context. ```ts -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import AgentLoop from '@deepseek-ai/dsh-agent-loop' import { mountAgentLoopTestDependencies } from '@deepseek-ai/dsh-agent-loop-testkit' diff --git a/packages/support/agent-loop-testkit/README.zh.md b/packages/support/agent-loop-testkit/README.zh.md index 2151591154..b4e38202f4 100644 --- a/packages/support/agent-loop-testkit/README.zh.md +++ b/packages/support/agent-loop-testkit/README.zh.md @@ -7,7 +7,7 @@ 调用方注册适配器和可选插件,使用待测配置挂载 `AgentLoop`,并 dispose(资源释放)自己的 Context。系统提示词和工具注册表配置可通过 `options` 转发;该辅助函数不提供超出服务自有默认值的测试默认值。插件加载失败会使辅助函数调用被拒绝,而顺序中较早激活的服务仍归调用方的 Context 所有。 ```ts -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import AgentLoop from '@deepseek-ai/dsh-agent-loop' import { mountAgentLoopTestDependencies } from '@deepseek-ai/dsh-agent-loop-testkit' diff --git a/packages/support/agent-loop-testkit/package.json b/packages/support/agent-loop-testkit/package.json index d6419f38dd..2bbfa195a7 100644 --- a/packages/support/agent-loop-testkit/package.json +++ b/packages/support/agent-loop-testkit/package.json @@ -31,7 +31,7 @@ "@deepseek-ai/dsh-session": "^0.0.1", "@deepseek-ai/dsh-system-prompt": "^0.0.1", "@deepseek-ai/dsh-tools": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-agent": "workspace:^", @@ -41,6 +41,6 @@ "@deepseek-ai/dsh-session": "workspace:^", "@deepseek-ai/dsh-system-prompt": "workspace:^", "@deepseek-ai/dsh-tools": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/support/agent-loop-testkit/src/index.ts b/packages/support/agent-loop-testkit/src/index.ts index c7b0cb7304..95a4052372 100644 --- a/packages/support/agent-loop-testkit/src/index.ts +++ b/packages/support/agent-loop-testkit/src/index.ts @@ -5,7 +5,7 @@ * @module @deepseek-ai/dsh-agent-loop-testkit */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import AgentRegistry from '@deepseek-ai/dsh-agent' import LlmService from '@deepseek-ai/dsh-llm' import SessionStore from '@deepseek-ai/dsh-session' diff --git a/packages/support/agent-loop-testkit/src/invariant.ts b/packages/support/agent-loop-testkit/src/invariant.ts index 33ee4474f9..c9e346921e 100644 --- a/packages/support/agent-loop-testkit/src/invariant.ts +++ b/packages/support/agent-loop-testkit/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-agent-loop-testkit' diff --git a/packages/support/agent-loop-testkit/tests/agent-loop-testkit.spec.ts b/packages/support/agent-loop-testkit/tests/agent-loop-testkit.spec.ts index aa125b561f..233900fc65 100644 --- a/packages/support/agent-loop-testkit/tests/agent-loop-testkit.spec.ts +++ b/packages/support/agent-loop-testkit/tests/agent-loop-testkit.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import AgentLoop from '@deepseek-ai/dsh-agent-loop' import { renderPrompt } from '@deepseek-ai/dsh-system-prompt' import { mountAgentLoopTestDependencies } from '../src/index.ts' diff --git a/packages/support/invariants/README.i18n.yaml b/packages/support/invariants/README.i18n.yaml index ea7fbba8f3..3d484e2ba9 100644 --- a/packages/support/invariants/README.i18n.yaml +++ b/packages/support/invariants/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/support/invariants/README.md -README.md: 9a93187032b6f8e4f5d89e17e742baba41196ff9 -README.zh.md: 7f3fa1e23337e55a73928c3952aa4c925a5fb4e9 +README.md: d3823d05b14afb5f043239cd7153ee40d66f3e4e +README.zh.md: b45e028e0f3865470763360846edfe4beed8a8cb diff --git a/packages/support/invariants/README.md b/packages/support/invariants/README.md index 9a93187032..d3823d05b1 100644 --- a/packages/support/invariants/README.md +++ b/packages/support/invariants/README.md @@ -52,7 +52,7 @@ The root entrypoint of each owner remains independent of diagnostics. Loading th ## Composition ```ts -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import InvariantService from '@deepseek-ai/dsh-invariants' import * as SessionInvariant from '@deepseek-ai/dsh-session/invariant' diff --git a/packages/support/invariants/README.zh.md b/packages/support/invariants/README.zh.md index 7f3fa1e233..b45e028e0f 100644 --- a/packages/support/invariants/README.zh.md +++ b/packages/support/invariants/README.zh.md @@ -52,7 +52,7 @@ interface Config { ## 组合 ```ts -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import InvariantService from '@deepseek-ai/dsh-invariants' import * as SessionInvariant from '@deepseek-ai/dsh-session/invariant' diff --git a/packages/support/invariants/package.json b/packages/support/invariants/package.json index f41c6bfde6..3ef3a80f41 100644 --- a/packages/support/invariants/package.json +++ b/packages/support/invariants/package.json @@ -25,12 +25,12 @@ ], "license": "BSD-3-Clause", "peerDependencies": { - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/support/invariants/src/index.ts b/packages/support/invariants/src/index.ts index 917e5327d4..7bf675243a 100644 --- a/packages/support/invariants/src/index.ts +++ b/packages/support/invariants/src/index.ts @@ -6,10 +6,10 @@ * @module @deepseek-ai/dsh-invariants */ -import { Context, Service } from 'cordis' -import type { Inject } from 'cordis' -import z from 'schemastery' -import type Schema from 'schemastery' +import { Context, Service } from '@deepseek-ai/cordis' +import type { Inject } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' +import type Schema from '@deepseek-ai/schemastery' /** Runtime invariant selection configured on the service plugin. */ export interface Config { @@ -65,7 +65,7 @@ export class InvariantError extends Error { } } -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { invariants: InvariantService } diff --git a/packages/support/invariants/src/invariant.ts b/packages/support/invariants/src/invariant.ts index 7780e987f5..81ecc5b2af 100644 --- a/packages/support/invariants/src/invariant.ts +++ b/packages/support/invariants/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from './index.ts' const PACKAGE_NAME = '@deepseek-ai/dsh-invariants' diff --git a/packages/support/invariants/tests/service.spec.ts b/packages/support/invariants/tests/service.spec.ts index 9000fb8955..483f769916 100644 --- a/packages/support/invariants/tests/service.spec.ts +++ b/packages/support/invariants/tests/service.spec.ts @@ -1,11 +1,11 @@ import { describe, expect, it, vi } from 'vitest' -import { Context, Service } from 'cordis' +import { Context, Service } from '@deepseek-ai/cordis' import InvariantService, { InvariantError, type Config, } from '@deepseek-ai/dsh-invariants' -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { invariantProbe: InvariantProbeService } diff --git a/packages/support/llm-mock-server/package.json b/packages/support/llm-mock-server/package.json index 20b1cf6d85..c342697f01 100644 --- a/packages/support/llm-mock-server/package.json +++ b/packages/support/llm-mock-server/package.json @@ -26,10 +26,10 @@ "license": "BSD-3-Clause", "peerDependencies": { "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-invariants": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/support/llm-mock-server/src/invariant.ts b/packages/support/llm-mock-server/src/invariant.ts index b8fbc2dd40..a77bb42835 100644 --- a/packages/support/llm-mock-server/src/invariant.ts +++ b/packages/support/llm-mock-server/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-llm-mock-server' diff --git a/packages/support/llm-mock-server/tests/invariant.spec.ts b/packages/support/llm-mock-server/tests/invariant.spec.ts index f45320d989..3bd7eb6d7b 100644 --- a/packages/support/llm-mock-server/tests/invariant.spec.ts +++ b/packages/support/llm-mock-server/tests/invariant.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import InvariantService from '@deepseek-ai/dsh-invariants' import * as MockServerInvariant from '../src/invariant.ts' diff --git a/packages/support/llm-replay/package.json b/packages/support/llm-replay/package.json index af5e2929f3..0c85caf96f 100644 --- a/packages/support/llm-replay/package.json +++ b/packages/support/llm-replay/package.json @@ -29,13 +29,13 @@ "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-llm": "^0.0.1", "@deepseek-ai/dsh-session": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-compact": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-llm": "workspace:^", "@deepseek-ai/dsh-session": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/support/llm-replay/src/index.ts b/packages/support/llm-replay/src/index.ts index 868751d969..22757c53a3 100644 --- a/packages/support/llm-replay/src/index.ts +++ b/packages/support/llm-replay/src/index.ts @@ -9,7 +9,7 @@ import { existsSync, readFileSync, writeFileSync } from 'node:fs' import { delimiter as pathDelimiter } from 'node:path' -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type {} from '@deepseek-ai/dsh-compact' import { decodeStorageRecord } from '@deepseek-ai/dsh-session' import type { SessionEvent } from '@deepseek-ai/dsh-session' diff --git a/packages/support/llm-replay/src/invariant.ts b/packages/support/llm-replay/src/invariant.ts index 36a3f8eeca..64fc06a262 100644 --- a/packages/support/llm-replay/src/invariant.ts +++ b/packages/support/llm-replay/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-llm-replay' diff --git a/packages/support/llm-replay/tests/llm-replay.spec.ts b/packages/support/llm-replay/tests/llm-replay.spec.ts index 4b163fdd95..d0bd675b48 100644 --- a/packages/support/llm-replay/tests/llm-replay.spec.ts +++ b/packages/support/llm-replay/tests/llm-replay.spec.ts @@ -2,7 +2,7 @@ import { existsSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs' import { tmpdir } from 'node:os' import { join } from 'node:path' import { afterEach, beforeEach, describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import type { SessionEvent } from '@deepseek-ai/dsh-session' import { CompactionId } from '@deepseek-ai/dsh-compact' import LlmService, { CallId, createUserMessage, GenerateOptions, LlmAdapter, StreamChunk } from '@deepseek-ai/dsh-llm' diff --git a/packages/support/loader-smoke/package.json b/packages/support/loader-smoke/package.json index 5cb8ef96a2..10dc20f863 100644 --- a/packages/support/loader-smoke/package.json +++ b/packages/support/loader-smoke/package.json @@ -33,13 +33,13 @@ "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-llm": "^0.0.1", "@deepseek-ai/dsh-session": "^0.0.1", - "cordis": "^4.0.0-rc.6" + "@deepseek-ai/cordis": "^4.0.0-rc.6" }, "devDependencies": { "@deepseek-ai/dsh-agent": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-llm": "workspace:^", "@deepseek-ai/dsh-session": "workspace:^", - "cordis": "^4.0.0-rc.6" + "@deepseek-ai/cordis": "^4.0.0-rc.6" } } diff --git a/packages/support/loader-smoke/src/agent-turn.ts b/packages/support/loader-smoke/src/agent-turn.ts index ea3a65d725..5638445cbe 100644 --- a/packages/support/loader-smoke/src/agent-turn.ts +++ b/packages/support/loader-smoke/src/agent-turn.ts @@ -3,7 +3,7 @@ * @module @deepseek-ai/dsh-loader-smoke/agent-turn */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { Agent } from '@deepseek-ai/dsh-agent' import { createUserMessage, type TokenUsage } from '@deepseek-ai/dsh-llm' import type { SessionEvent } from '@deepseek-ai/dsh-session' diff --git a/packages/support/loader-smoke/src/invariant.ts b/packages/support/loader-smoke/src/invariant.ts index 1e3cc54b81..36e8d646de 100644 --- a/packages/support/loader-smoke/src/invariant.ts +++ b/packages/support/loader-smoke/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-loader-smoke' diff --git a/packages/support/loader-smoke/tests/agent-turn.spec.ts b/packages/support/loader-smoke/tests/agent-turn.spec.ts index 481b4ef566..4f04efc303 100644 --- a/packages/support/loader-smoke/tests/agent-turn.spec.ts +++ b/packages/support/loader-smoke/tests/agent-turn.spec.ts @@ -1,4 +1,4 @@ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { SessionEvent } from '@deepseek-ai/dsh-session' import { describe, expect, it, vi } from 'vitest' import { runFixtureTurn } from '../src/agent-turn.ts' diff --git a/packages/tasks/tasks-local/package.json b/packages/tasks/tasks-local/package.json index 92e095ffa9..76deaf9b8d 100644 --- a/packages/tasks/tasks-local/package.json +++ b/packages/tasks/tasks-local/package.json @@ -30,7 +30,7 @@ "@deepseek-ai/dsh-scope": "^0.0.1", "@deepseek-ai/dsh-tasks": "^0.0.1", "@deepseek-ai/dsh-timeout": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-agent": "workspace:^", @@ -40,6 +40,6 @@ "@deepseek-ai/dsh-session": "workspace:^", "@deepseek-ai/dsh-tasks": "workspace:^", "@deepseek-ai/dsh-timeout": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/tasks/tasks-local/src/index.ts b/packages/tasks/tasks-local/src/index.ts index c85c3af713..7978944edb 100644 --- a/packages/tasks/tasks-local/src/index.ts +++ b/packages/tasks/tasks-local/src/index.ts @@ -9,7 +9,7 @@ * @module @deepseek-ai/dsh-tasks-local */ -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import type { Agent } from '@deepseek-ai/dsh-agent' import { AnonymousEntries, ScopedLayers, scopeOf } from '@deepseek-ai/dsh-scope' import type { ScopeLayer } from '@deepseek-ai/dsh-scope' diff --git a/packages/tasks/tasks-local/src/invariant.ts b/packages/tasks/tasks-local/src/invariant.ts index 22f2b4fecd..21d00ed155 100644 --- a/packages/tasks/tasks-local/src/invariant.ts +++ b/packages/tasks/tasks-local/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-tasks-local' diff --git a/packages/tasks/tasks-local/tests/tasks.spec.ts b/packages/tasks/tasks-local/tests/tasks.spec.ts index 2c3fd11ef2..b64f2142aa 100644 --- a/packages/tasks/tasks-local/tests/tasks.spec.ts +++ b/packages/tasks/tasks-local/tests/tasks.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, expectTypeOf, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { Session, SessionId } from '@deepseek-ai/dsh-session' import AgentRegistry, { Inbox } from '@deepseek-ai/dsh-agent' import type { Agent } from '@deepseek-ai/dsh-agent' diff --git a/packages/tasks/tasks/package.json b/packages/tasks/tasks/package.json index eea8e2af6b..61b8cd1ab8 100644 --- a/packages/tasks/tasks/package.json +++ b/packages/tasks/tasks/package.json @@ -29,13 +29,13 @@ "@deepseek-ai/dsh-brand": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-session": "^0.0.1", - "cordis": "^4.0.0-rc.6" + "@deepseek-ai/cordis": "^4.0.0-rc.6" }, "devDependencies": { "@deepseek-ai/dsh-agent": "workspace:^", "@deepseek-ai/dsh-brand": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-session": "workspace:^", - "cordis": "^4.0.0-rc.6" + "@deepseek-ai/cordis": "^4.0.0-rc.6" } } diff --git a/packages/tasks/tasks/src/index.ts b/packages/tasks/tasks/src/index.ts index 8c49ec8445..126ba075ff 100644 --- a/packages/tasks/tasks/src/index.ts +++ b/packages/tasks/tasks/src/index.ts @@ -6,7 +6,7 @@ * @module @deepseek-ai/dsh-tasks */ -import { Context, Service } from 'cordis' +import { Context, Service } from '@deepseek-ai/cordis' import type { Agent } from '@deepseek-ai/dsh-agent' import type { TaskDoneListener, TaskId, TaskRead, TaskSnapshot, TaskStart } from './types.ts' @@ -23,7 +23,7 @@ export type { TaskStatus, } from './types.ts' -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { tasks: TaskService } diff --git a/packages/tasks/tasks/src/invariant.ts b/packages/tasks/tasks/src/invariant.ts index a633213607..99f850e929 100644 --- a/packages/tasks/tasks/src/invariant.ts +++ b/packages/tasks/tasks/src/invariant.ts @@ -1,6 +1,6 @@ /** Package-owned background-task snapshot invariants. @module @deepseek-ai/dsh-tasks/invariant */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { Agent } from '@deepseek-ai/dsh-agent' import type { InvariantFailure, InvariantInstaller } from '@deepseek-ai/dsh-invariants' import type { TaskSnapshot } from './types.ts' diff --git a/packages/tasks/tasks/tests/invariant.spec.ts b/packages/tasks/tasks/tests/invariant.spec.ts index e23609df5d..db7ca8bb0e 100644 --- a/packages/tasks/tasks/tests/invariant.spec.ts +++ b/packages/tasks/tasks/tests/invariant.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import type { Agent } from '@deepseek-ai/dsh-agent' import { SessionId } from '@deepseek-ai/dsh-session' import TaskService, { TaskId } from '@deepseek-ai/dsh-tasks' diff --git a/packages/tasks/tasks/tests/service.spec.ts b/packages/tasks/tasks/tests/service.spec.ts index 9c6e2654e3..73b0a3fe25 100644 --- a/packages/tasks/tasks/tests/service.spec.ts +++ b/packages/tasks/tasks/tests/service.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import type { Agent } from '@deepseek-ai/dsh-agent' import { TaskId, TaskService } from '@deepseek-ai/dsh-tasks' import type { TaskDoneListener, TaskRead, TaskSnapshot, TaskStart } from '@deepseek-ai/dsh-tasks' diff --git a/packages/tasks/tool-tasks/package.json b/packages/tasks/tool-tasks/package.json index dfffbf4855..38827df4f8 100644 --- a/packages/tasks/tool-tasks/package.json +++ b/packages/tasks/tool-tasks/package.json @@ -25,7 +25,7 @@ ], "license": "BSD-3-Clause", "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "peerDependencies": { "@deepseek-ai/dsh-agent": "^0.0.1", @@ -35,7 +35,7 @@ "@deepseek-ai/dsh-system-prompt": "^0.0.1", "@deepseek-ai/dsh-tasks": "^0.0.1", "@deepseek-ai/dsh-tools": "^0.0.1", - "cordis": "^4.0.0-rc.6" + "@deepseek-ai/cordis": "^4.0.0-rc.6" }, "devDependencies": { "@deepseek-ai/dsh-agent": "workspace:^", @@ -47,6 +47,6 @@ "@deepseek-ai/dsh-tasks": "workspace:^", "@deepseek-ai/dsh-tasks-local": "workspace:^", "@deepseek-ai/dsh-tools": "workspace:^", - "cordis": "^4.0.0-rc.6" + "@deepseek-ai/cordis": "^4.0.0-rc.6" } } diff --git a/packages/tasks/tool-tasks/src/index.ts b/packages/tasks/tool-tasks/src/index.ts index 720cb51f97..2ec5bdaff7 100644 --- a/packages/tasks/tool-tasks/src/index.ts +++ b/packages/tasks/tool-tasks/src/index.ts @@ -6,8 +6,8 @@ * @module @deepseek-ai/dsh-tool-tasks */ -import type { Context } from 'cordis' -import z from 'schemastery' +import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import { boundContextSummary, createUserMessage, type ContentBlock } from '@deepseek-ai/dsh-llm' import { TextRetainer } from '@deepseek-ai/dsh-retention' import { defineTool } from '@deepseek-ai/dsh-tools' diff --git a/packages/tasks/tool-tasks/src/invariant.ts b/packages/tasks/tool-tasks/src/invariant.ts index cedad9dc1c..d1c9f77bd6 100644 --- a/packages/tasks/tool-tasks/src/invariant.ts +++ b/packages/tasks/tool-tasks/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-tool-tasks' diff --git a/packages/tasks/tool-tasks/tests/tool-tasks.spec.ts b/packages/tasks/tool-tasks/tests/tool-tasks.spec.ts index a213ca83e5..3221c20246 100644 --- a/packages/tasks/tool-tasks/tests/tool-tasks.spec.ts +++ b/packages/tasks/tool-tasks/tests/tool-tasks.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { CallId } from '@deepseek-ai/dsh-llm' import SystemPrompt from '@deepseek-ai/dsh-system-prompt' import ToolRegistry from '@deepseek-ai/dsh-tools' diff --git a/packages/todo/tool-todo/package.json b/packages/todo/tool-todo/package.json index 2c4490589f..ee57660440 100644 --- a/packages/todo/tool-todo/package.json +++ b/packages/todo/tool-todo/package.json @@ -30,7 +30,7 @@ ], "license": "BSD-3-Clause", "dependencies": { - "schemastery": "^3.18.0", + "@deepseek-ai/schemastery": "^3.18.0", "zod": "^4.4.3" }, "peerDependencies": { @@ -39,11 +39,11 @@ "@deepseek-ai/dsh-session": "^0.0.1", "@deepseek-ai/dsh-session-projection": "^0.0.1", "@deepseek-ai/dsh-tools": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { - "@cordisjs/plugin-include": "workspace:^", - "@cordisjs/plugin-loader": "workspace:^", + "@deepseek-ai/cordis-plugin-include": "workspace:^", + "@deepseek-ai/cordis-plugin-loader": "workspace:^", "@deepseek-ai/dsh-agent": "workspace:^", "@deepseek-ai/dsh-agent-loop": "workspace:^", "@deepseek-ai/dsh-agent-loop-testkit": "workspace:^", @@ -55,6 +55,6 @@ "@deepseek-ai/dsh-system-prompt": "workspace:^", "@deepseek-ai/dsh-tools": "workspace:^", "@deepseek-ai/dsh-user-interaction": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/todo/tool-todo/src/index.ts b/packages/todo/tool-todo/src/index.ts index 12e0d164c6..e92af70313 100644 --- a/packages/todo/tool-todo/src/index.ts +++ b/packages/todo/tool-todo/src/index.ts @@ -5,8 +5,8 @@ * @module @deepseek-ai/dsh-tool-todo */ -import type { Context } from 'cordis' -import z from 'schemastery' +import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import { z as zod } from 'zod' import type { ZodType } from 'zod' import { defineTool } from '@deepseek-ai/dsh-tools' diff --git a/packages/todo/tool-todo/src/invariant.ts b/packages/todo/tool-todo/src/invariant.ts index 8c2a7aa7dd..f1b8c63066 100644 --- a/packages/todo/tool-todo/src/invariant.ts +++ b/packages/todo/tool-todo/src/invariant.ts @@ -1,6 +1,6 @@ /** Package-owned durable todo-snapshot invariants. @module @deepseek-ai/dsh-tool-todo/invariant */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { Session, SessionEvent } from '@deepseek-ai/dsh-session' import type { InvariantFailure, InvariantInstaller } from '@deepseek-ai/dsh-invariants' diff --git a/packages/todo/tool-todo/tests/integration.spec.ts b/packages/todo/tool-todo/tests/integration.spec.ts index 568b0f764a..264731bdbc 100644 --- a/packages/todo/tool-todo/tests/integration.spec.ts +++ b/packages/todo/tool-todo/tests/integration.spec.ts @@ -1,6 +1,6 @@ import { createUserMessage } from '@deepseek-ai/dsh-llm' import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { SessionId, type SessionEvent } from '@deepseek-ai/dsh-session' import type { Agent } from '@deepseek-ai/dsh-agent' import AgentLoop from '@deepseek-ai/dsh-agent-loop' diff --git a/packages/todo/tool-todo/tests/invariant.spec.ts b/packages/todo/tool-todo/tests/invariant.spec.ts index ac3c76bf71..c38958df95 100644 --- a/packages/todo/tool-todo/tests/invariant.spec.ts +++ b/packages/todo/tool-todo/tests/invariant.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import SessionStore, { type Session, type SessionEvent } from '@deepseek-ai/dsh-session' import ToolRegistry from '@deepseek-ai/dsh-tools' import * as ToolTodo from '@deepseek-ai/dsh-tool-todo' diff --git a/packages/todo/tool-todo/tests/loader-composition.spec.ts b/packages/todo/tool-todo/tests/loader-composition.spec.ts index 572254e348..41728d93e1 100644 --- a/packages/todo/tool-todo/tests/loader-composition.spec.ts +++ b/packages/todo/tool-todo/tests/loader-composition.spec.ts @@ -6,9 +6,9 @@ import { tmpdir } from 'node:os' import { join } from 'node:path' import { pathToFileURL } from 'node:url' import { afterEach, describe, expect, it } from 'vitest' -import { Context } from 'cordis' -import Loader from '@cordisjs/plugin-loader' -import Include from '@cordisjs/plugin-include' +import { Context } from '@deepseek-ai/cordis' +import Loader from '@deepseek-ai/cordis-plugin-loader' +import Include from '@deepseek-ai/cordis-plugin-include' import { CallId } from '@deepseek-ai/dsh-llm' import { Session, SessionId } from '@deepseek-ai/dsh-session' import AgentRegistry, { Inbox } from '@deepseek-ai/dsh-agent' diff --git a/packages/todo/tool-todo/tests/projection.spec.ts b/packages/todo/tool-todo/tests/projection.spec.ts index 0b214fc311..b53e9dd587 100644 --- a/packages/todo/tool-todo/tests/projection.spec.ts +++ b/packages/todo/tool-todo/tests/projection.spec.ts @@ -8,7 +8,7 @@ */ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import AgentRegistry from '@deepseek-ai/dsh-agent' import type { Agent } from '@deepseek-ai/dsh-agent' import { createUserMessage } from '@deepseek-ai/dsh-llm' diff --git a/packages/todo/tool-todo/tests/tool-todo.spec.ts b/packages/todo/tool-todo/tests/tool-todo.spec.ts index 12d1f5f665..5e79b1a69a 100644 --- a/packages/todo/tool-todo/tests/tool-todo.spec.ts +++ b/packages/todo/tool-todo/tests/tool-todo.spec.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' -import Loader from '@cordisjs/plugin-loader' +import { Context } from '@deepseek-ai/cordis' +import Loader from '@deepseek-ai/cordis-plugin-loader' import { CallId } from '@deepseek-ai/dsh-llm' import SystemPrompt from '@deepseek-ai/dsh-system-prompt' import ToolRegistry from '@deepseek-ai/dsh-tools' diff --git a/packages/typert/generator/package.json b/packages/typert/generator/package.json index 5ffb933214..fd9f14c449 100644 --- a/packages/typert/generator/package.json +++ b/packages/typert/generator/package.json @@ -35,13 +35,13 @@ }, "peerDependencies": { "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-tool-cordis": "workspace:^", "@deepseek-ai/dsh-typert-registry": "workspace:^", - "cordis": "^4.0.0-rc.7", + "@deepseek-ai/cordis": "^4.0.0-rc.7", "zod": "^4.4.3" } } diff --git a/packages/typert/generator/src/analyzer.ts b/packages/typert/generator/src/analyzer.ts index e5ade888cf..358edceb66 100644 --- a/packages/typert/generator/src/analyzer.ts +++ b/packages/typert/generator/src/analyzer.ts @@ -653,7 +653,7 @@ class FaceAnalyzer { for (const statement of sourceFile.statements) { if (!ts.isModuleDeclaration(statement) || !ts.isStringLiteral(statement.name) - || statement.name.text !== 'cordis' + || statement.name.text !== '@deepseek-ai/cordis' || statement.body === undefined || !ts.isModuleBlock(statement.body)) continue for (const member of statement.body.statements) { @@ -2545,7 +2545,7 @@ function sourceFileHasSurface(sourceFile: ts.SourceFile): boolean { } if (!ts.isModuleDeclaration(statement) || !ts.isStringLiteral(statement.name) - || statement.name.text !== 'cordis' + || statement.name.text !== '@deepseek-ai/cordis' || statement.body === undefined || !ts.isModuleBlock(statement.body)) continue if (statement.body.statements.some(member => ts.isInterfaceDeclaration(member) diff --git a/packages/typert/generator/src/invariant.ts b/packages/typert/generator/src/invariant.ts index e4da20785f..1c153f74f4 100644 --- a/packages/typert/generator/src/invariant.ts +++ b/packages/typert/generator/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-typert-generator' diff --git a/packages/typert/generator/tests/__snapshots__/type-model.spec.ts.snap b/packages/typert/generator/tests/__snapshots__/type-model.spec.ts.snap index bcc28cd8b2..da7510736b 100644 --- a/packages/typert/generator/tests/__snapshots__/type-model.spec.ts.snap +++ b/packages/typert/generator/tests/__snapshots__/type-model.spec.ts.snap @@ -407,7 +407,7 @@ exports[`WorkspaceAnalyzer > builds independent face models with an explicit cro { "abstract": false, "async": false, - "id": "@fixture/host:packages/host/src/index.ts#Agent#id@480", + "id": "@fixture/host:packages/host/src/index.ts#Agent#id@493", "kind": "property", "location": { "column": 3, @@ -426,7 +426,7 @@ exports[`WorkspaceAnalyzer > builds independent face models with an explicit cro { "abstract": false, "async": false, - "id": "@fixture/host:packages/host/src/index.ts#Agent#state@502", + "id": "@fixture/host:packages/host/src/index.ts#Agent#state@515", "kind": "property", "location": { "column": 3, @@ -446,7 +446,7 @@ exports[`WorkspaceAnalyzer > builds independent face models with an explicit cro "abstract": false, "async": false, "description": "Read the public display label.", - "id": "@fixture/host:packages/host/src/index.ts#Agent#label@735", + "id": "@fixture/host:packages/host/src/index.ts#Agent#label@748", "jsDoc": "/** Read the public display label. */", "kind": "getter", "location": { @@ -472,7 +472,7 @@ exports[`WorkspaceAnalyzer > builds independent face models with an explicit cro "abstract": false, "async": false, "description": "Accept a public display label.", - "id": "@fixture/host:packages/host/src/index.ts#Agent#label@823", + "id": "@fixture/host:packages/host/src/index.ts#Agent#label@836", "jsDoc": "/** Accept a public display label. */", "kind": "setter", "location": { @@ -507,7 +507,7 @@ exports[`WorkspaceAnalyzer > builds independent face models with an explicit cro "abstract": false, "async": false, "description": "Run one typed input.", - "id": "@fixture/host:packages/host/src/index.ts#Agent#run@902", + "id": "@fixture/host:packages/host/src/index.ts#Agent#run@915", "jsDoc": "/** Run one typed input. */", "kind": "method", "location": { @@ -598,7 +598,7 @@ exports[`WorkspaceAnalyzer > builds independent face models with an explicit cro "abstract": false, "async": false, "description": "Report readiness.", - "id": "@fixture/host:packages/host/src/index.ts#AliasedService#ready@1181", + "id": "@fixture/host:packages/host/src/index.ts#AliasedService#ready@1194", "jsDoc": "/** Report readiness. */", "kind": "method", "location": { @@ -651,7 +651,7 @@ exports[`WorkspaceAnalyzer > builds independent face models with an explicit cro "abstract": false, "async": false, "description": "Report readiness.", - "id": "@fixture/host:packages/host/src/index.ts#DefaultOnlyService#ready@1404", + "id": "@fixture/host:packages/host/src/index.ts#DefaultOnlyService#ready@1417", "jsDoc": "/** Report readiness. */", "kind": "method", "location": { @@ -704,7 +704,7 @@ exports[`WorkspaceAnalyzer > builds independent face models with an explicit cro "abstract": false, "async": false, "description": "Inspect one agent without flattening its generic state.", - "id": "@fixture/host:packages/host/src/index.ts#DemoService#inspect@1767", + "id": "@fixture/host:packages/host/src/index.ts#DemoService#inspect@1780", "jsDoc": "/** Inspect one agent without flattening its generic state. */", "kind": "method", "location": { @@ -747,7 +747,7 @@ exports[`WorkspaceAnalyzer > builds independent face models with an explicit cro "abstract": false, "async": false, "description": "Keep an npm-owned type as External.", - "id": "@fixture/host:packages/host/src/index.ts#DemoService#acceptsExternal@1965", + "id": "@fixture/host:packages/host/src/index.ts#DemoService#acceptsExternal@1978", "jsDoc": "/** Keep an npm-owned type as External. */", "kind": "method", "location": { @@ -782,7 +782,7 @@ exports[`WorkspaceAnalyzer > builds independent face models with an explicit cro "abstract": false, "async": false, "description": "Accept a developer-authored enum without flattening it.", - "id": "@fixture/host:packages/host/src/index.ts#DemoService#setPhase@2102", + "id": "@fixture/host:packages/host/src/index.ts#DemoService#setPhase@2115", "jsDoc": "/** Accept a developer-authored enum without flattening it. */", "kind": "method", "location": { @@ -817,7 +817,7 @@ exports[`WorkspaceAnalyzer > builds independent face models with an explicit cro "abstract": false, "async": false, "description": "Exercise every retained type-graph shape from a public boundary.", - "id": "@fixture/host:packages/host/src/index.ts#DemoService#inspectSyntax@2234", + "id": "@fixture/host:packages/host/src/index.ts#DemoService#inspectSyntax@2247", "jsDoc": "/** Exercise every retained type-graph shape from a public boundary. */", "kind": "method", "location": { @@ -852,7 +852,7 @@ exports[`WorkspaceAnalyzer > builds independent face models with an explicit cro "abstract": false, "async": true, "description": "Preserve async source metadata without changing its type signature.", - "id": "@fixture/host:packages/host/src/index.ts#DemoService#inspectAsync@2369", + "id": "@fixture/host:packages/host/src/index.ts#DemoService#inspectAsync@2382", "jsDoc": "/** Preserve async source metadata without changing its type signature. */", "kind": "method", "location": { @@ -887,7 +887,7 @@ exports[`WorkspaceAnalyzer > builds independent face models with an explicit cro "abstract": false, "async": false, "description": "Retain an authored binding-pattern parameter.", - "id": "@fixture/host:packages/host/src/index.ts#DemoService#destructure@2496", + "id": "@fixture/host:packages/host/src/index.ts#DemoService#destructure@2509", "jsDoc": "/** Retain an authored binding-pattern parameter. */", "kind": "method", "location": { @@ -2816,7 +2816,7 @@ exports[`WorkspaceAnalyzer > builds independent face models with an explicit cro { "abstract": false, "async": false, - "id": "type:packages/host/src/index.ts:116:31#1#ready@3038", + "id": "type:packages/host/src/index.ts:116:31#1#ready@3064", "kind": "property", "location": { "column": 33, @@ -2919,7 +2919,7 @@ exports[`WorkspaceAnalyzer > builds independent face models with an explicit cro { "abstract": false, "async": false, - "id": "type:packages/host/src/index.ts:12:43#1#ready@387", + "id": "type:packages/host/src/index.ts:12:43#1#ready@400", "kind": "property", "location": { "column": 45, @@ -3037,7 +3037,7 @@ exports[`WorkspaceAnalyzer > builds independent face models with an explicit cro { "abstract": false, "async": false, - "id": "type:packages/host/src/index.ts:139:31#1#ready@3476", + "id": "type:packages/host/src/index.ts:139:31#1#ready@3515", "kind": "property", "location": { "column": 33, @@ -3207,7 +3207,7 @@ exports[`WorkspaceAnalyzer > builds independent face models with an explicit cro "name": "Service", "target": { "kind": "external", - "module": "cordis", + "module": "@deepseek-ai/cordis", "name": "Service", "subpath": ".", }, @@ -3224,7 +3224,7 @@ exports[`WorkspaceAnalyzer > builds independent face models with an explicit cro "name": "Service", "target": { "kind": "external", - "module": "cordis", + "module": "@deepseek-ai/cordis", "name": "Service", "subpath": ".", }, @@ -3241,7 +3241,7 @@ exports[`WorkspaceAnalyzer > builds independent face models with an explicit cro "name": "Service", "target": { "kind": "external", - "module": "cordis", + "module": "@deepseek-ai/cordis", "name": "Service", "subpath": ".", }, @@ -3265,7 +3265,7 @@ exports[`WorkspaceAnalyzer > builds independent face models with an explicit cro { "abstract": false, "async": false, - "id": "type:packages/host/src/index.ts:68:24#1#ready@1790", + "id": "type:packages/host/src/index.ts:68:24#1#ready@1803", "kind": "property", "location": { "column": 26, @@ -5711,7 +5711,7 @@ exports[`WorkspaceAnalyzer > builds independent face models with an explicit cro "line": 101, }, "members": [ - "@fixture/host:packages/host/src/index.ts#AliasedService#ready@1181", + "@fixture/host:packages/host/src/index.ts#AliasedService#ready@1194", ], "summary": "Service exported only through a non-default alias.", "symbol": "@fixture/host:packages/host/src/index.ts#AliasedService", @@ -5736,7 +5736,7 @@ exports[`WorkspaceAnalyzer > builds independent face models with an explicit cro "line": 102, }, "members": [ - "@fixture/host:packages/host/src/index.ts#DefaultOnlyService#ready@1404", + "@fixture/host:packages/host/src/index.ts#DefaultOnlyService#ready@1417", ], "summary": "Service exported only through the package default.", "symbol": "@fixture/host:packages/host/src/index.ts#DefaultOnlyService", @@ -5760,12 +5760,12 @@ exports[`WorkspaceAnalyzer > builds independent face models with an explicit cro "line": 100, }, "members": [ - "@fixture/host:packages/host/src/index.ts#DemoService#inspect@1767", - "@fixture/host:packages/host/src/index.ts#DemoService#acceptsExternal@1965", - "@fixture/host:packages/host/src/index.ts#DemoService#setPhase@2102", - "@fixture/host:packages/host/src/index.ts#DemoService#inspectSyntax@2234", - "@fixture/host:packages/host/src/index.ts#DemoService#inspectAsync@2369", - "@fixture/host:packages/host/src/index.ts#DemoService#destructure@2496", + "@fixture/host:packages/host/src/index.ts#DemoService#inspect@1780", + "@fixture/host:packages/host/src/index.ts#DemoService#acceptsExternal@1978", + "@fixture/host:packages/host/src/index.ts#DemoService#setPhase@2115", + "@fixture/host:packages/host/src/index.ts#DemoService#inspectSyntax@2247", + "@fixture/host:packages/host/src/index.ts#DemoService#inspectAsync@2382", + "@fixture/host:packages/host/src/index.ts#DemoService#destructure@2509", ], "summary": "Fixture service with generic, mapped, and truly external boundary types.", "symbol": "@fixture/host:packages/host/src/index.ts#DemoService", @@ -5827,7 +5827,7 @@ exports[`WorkspaceAnalyzer > builds independent face models with an explicit cro "abstract": false, "async": false, "description": "Return the host-owned object unchanged.", - "id": "@fixture/client:packages/client/src/index.ts#ClientBridge#reflect@1096", + "id": "@fixture/client:packages/client/src/index.ts#ClientBridge#reflect@1109", "jsDoc": "/** Return the host-owned object unchanged. */", "kind": "method", "location": { @@ -5888,7 +5888,7 @@ exports[`WorkspaceAnalyzer > builds independent face models with an explicit cro { "abstract": false, "async": false, - "id": "@fixture/client:packages/client/src/index.ts#ClientView#agent@587", + "id": "@fixture/client:packages/client/src/index.ts#ClientView#agent@600", "kind": "property", "location": { "column": 3, @@ -5907,7 +5907,7 @@ exports[`WorkspaceAnalyzer > builds independent face models with an explicit cro { "abstract": false, "async": false, - "id": "@fixture/client:packages/client/src/index.ts#ClientView#inherited@632", + "id": "@fixture/client:packages/client/src/index.ts#ClientView#inherited@645", "kind": "property", "location": { "column": 3, @@ -5926,7 +5926,7 @@ exports[`WorkspaceAnalyzer > builds independent face models with an explicit cro { "abstract": false, "async": false, - "id": "@fixture/client:packages/client/src/index.ts#ClientView#importedAgent@666", + "id": "@fixture/client:packages/client/src/index.ts#ClientView#importedAgent@679", "kind": "property", "location": { "column": 3, @@ -5945,7 +5945,7 @@ exports[`WorkspaceAnalyzer > builds independent face models with an explicit cro { "abstract": false, "async": false, - "id": "@fixture/client:packages/client/src/index.ts#ClientView#importedAgentWithNamedArgument@739", + "id": "@fixture/client:packages/client/src/index.ts#ClientView#importedAgentWithNamedArgument@752", "kind": "property", "location": { "column": 3, @@ -5964,7 +5964,7 @@ exports[`WorkspaceAnalyzer > builds independent face models with an explicit cro { "abstract": false, "async": false, - "id": "@fixture/client:packages/client/src/index.ts#ClientView#namespaceAgent@821", + "id": "@fixture/client:packages/client/src/index.ts#ClientView#namespaceAgent@834", "kind": "property", "location": { "column": 3, @@ -5983,7 +5983,7 @@ exports[`WorkspaceAnalyzer > builds independent face models with an explicit cro { "abstract": false, "async": false, - "id": "@fixture/client:packages/client/src/index.ts#ClientView#defaultService@876", + "id": "@fixture/client:packages/client/src/index.ts#ClientView#defaultService@889", "kind": "property", "location": { "column": 3, @@ -6002,7 +6002,7 @@ exports[`WorkspaceAnalyzer > builds independent face models with an explicit cro { "abstract": false, "async": false, - "id": "@fixture/client:packages/client/src/index.ts#ClientView#payload@915", + "id": "@fixture/client:packages/client/src/index.ts#ClientView#payload@928", "kind": "property", "location": { "column": 3, @@ -6021,7 +6021,7 @@ exports[`WorkspaceAnalyzer > builds independent face models with an explicit cro { "abstract": false, "async": false, - "id": "@fixture/client:packages/client/src/index.ts#ClientView#phase@943", + "id": "@fixture/client:packages/client/src/index.ts#ClientView#phase@956", "kind": "property", "location": { "column": 3, @@ -6084,7 +6084,7 @@ exports[`WorkspaceAnalyzer > builds independent face models with an explicit cro { "abstract": false, "async": false, - "id": "type:packages/client/src/index.ts:11:48#1#ready@469", + "id": "type:packages/client/src/index.ts:11:48#1#ready@482", "kind": "property", "location": { "column": 50, @@ -6130,7 +6130,7 @@ exports[`WorkspaceAnalyzer > builds independent face models with an explicit cro { "abstract": false, "async": false, - "id": "type:packages/client/src/index.ts:15:29#1#ready@615", + "id": "type:packages/client/src/index.ts:15:29#1#ready@628", "kind": "property", "location": { "column": 31, @@ -6188,7 +6188,7 @@ exports[`WorkspaceAnalyzer > builds independent face models with an explicit cro { "abstract": false, "async": false, - "id": "type:packages/client/src/index.ts:17:57#1#ready@722", + "id": "type:packages/client/src/index.ts:17:57#1#ready@735", "kind": "property", "location": { "column": 59, @@ -6264,7 +6264,7 @@ exports[`WorkspaceAnalyzer > builds independent face models with an explicit cro { "abstract": false, "async": false, - "id": "type:packages/client/src/index.ts:19:39#1#ready@859", + "id": "type:packages/client/src/index.ts:19:39#1#ready@872", "kind": "property", "location": { "column": 41, @@ -6334,7 +6334,7 @@ exports[`WorkspaceAnalyzer > builds independent face models with an explicit cro "name": "Service", "target": { "kind": "external", - "module": "cordis", + "module": "@deepseek-ai/cordis", "name": "Service", "subpath": ".", }, @@ -6371,7 +6371,7 @@ exports[`WorkspaceAnalyzer > builds independent face models with an explicit cro { "abstract": false, "async": false, - "id": "type:packages/client/src/index.ts:28:40#1#ready@1135", + "id": "type:packages/client/src/index.ts:28:40#1#ready@1148", "kind": "property", "location": { "column": 42, @@ -6477,7 +6477,7 @@ exports[`WorkspaceAnalyzer > builds independent face models with an explicit cro "line": 35, }, "members": [ - "@fixture/client:packages/client/src/index.ts#ClientBridge#reflect@1096", + "@fixture/client:packages/client/src/index.ts#ClientBridge#reflect@1109", ], "summary": "Client-face service.", "symbol": "@fixture/client:packages/client/src/index.ts#ClientBridge", diff --git a/packages/typert/generator/tests/cordis-catalog-contract.spec.ts b/packages/typert/generator/tests/cordis-catalog-contract.spec.ts index bde52505dc..e7d4acfba1 100644 --- a/packages/typert/generator/tests/cordis-catalog-contract.spec.ts +++ b/packages/typert/generator/tests/cordis-catalog-contract.spec.ts @@ -91,7 +91,7 @@ function fixtureRoot(eventsBlock: string): string { const root = mkdtempSync(join(tmpdir(), 'cordis-catalog-')) writeProject( root, - `declare module 'cordis' {\n interface Events {\n${eventsBlock}\n }\n}\n`, + `declare module '@deepseek-ai/cordis' {\n interface Events {\n${eventsBlock}\n }\n}\n`, ) return root } @@ -103,7 +103,7 @@ function serviceFixtureRoot(classSource: string): string { const root = mkdtempSync(join(tmpdir(), 'cordis-catalog-')) writeProject( root, - `declare module 'cordis' {\n interface Context {\n fix: FixService\n }\n}\n\n${classSource}\n`, + `declare module '@deepseek-ai/cordis' {\n interface Context {\n fix: FixService\n }\n}\n\n${classSource}\n`, ) return root } diff --git a/packages/typert/generator/tests/fixtures/type-model/cordis.d.ts b/packages/typert/generator/tests/fixtures/type-model/cordis.d.ts index 970e8a5dda..fb59bcae21 100644 --- a/packages/typert/generator/tests/fixtures/type-model/cordis.d.ts +++ b/packages/typert/generator/tests/fixtures/type-model/cordis.d.ts @@ -1,4 +1,4 @@ -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { export class Service { protected readonly __service?: never } export interface Context {} diff --git a/packages/typert/generator/tests/fixtures/type-model/packages/client/src/index.ts b/packages/typert/generator/tests/fixtures/type-model/packages/client/src/index.ts index 82080a344e..61dc98ba2f 100644 --- a/packages/typert/generator/tests/fixtures/type-model/packages/client/src/index.ts +++ b/packages/typert/generator/tests/fixtures/type-model/packages/client/src/index.ts @@ -1,4 +1,4 @@ -import { Service } from 'cordis' +import { Service } from '@deepseek-ai/cordis' import type HostDefault from '@fixture/host' import type * as Host from '@fixture/host' import type { AgentPhase } from '@fixture/host' @@ -30,7 +30,7 @@ export class ClientBridge extends Service { } } -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { clientBridge: ClientBridge } diff --git a/packages/typert/generator/tests/fixtures/type-model/packages/host/src/index.ts b/packages/typert/generator/tests/fixtures/type-model/packages/host/src/index.ts index bb73873699..463c4dafc7 100644 --- a/packages/typert/generator/tests/fixtures/type-model/packages/host/src/index.ts +++ b/packages/typert/generator/tests/fixtures/type-model/packages/host/src/index.ts @@ -1,4 +1,4 @@ -import { Service } from 'cordis' +import { Service } from '@deepseek-ai/cordis' import type { ZodType } from 'zod' import type { AgentPhase, Box, Entity, Flags, Payload, Present, SyntaxZoo } from './models.ts' @@ -95,7 +95,7 @@ export class DemoService extends Service { } } -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { demo: DemoService aliased: AliasedService @@ -130,7 +130,7 @@ declare module 'cordis' { type IgnoredDeclaration = string } -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { demo: DemoService } diff --git a/packages/typert/generator/tests/fixtures/type-model/packages/write/src/index.ts b/packages/typert/generator/tests/fixtures/type-model/packages/write/src/index.ts index 290e3944a3..ea6cc55308 100644 --- a/packages/typert/generator/tests/fixtures/type-model/packages/write/src/index.ts +++ b/packages/typert/generator/tests/fixtures/type-model/packages/write/src/index.ts @@ -1,4 +1,4 @@ -import { Service } from 'cordis' +import { Service } from '@deepseek-ai/cordis' /** Service whose public annotations are intentionally absent. */ export class WritableService extends Service { @@ -9,7 +9,7 @@ export class WritableService extends Service { } } -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { writable: WritableService } diff --git a/packages/typert/generator/tests/fixtures/type-model/tsconfig.base.json b/packages/typert/generator/tests/fixtures/type-model/tsconfig.base.json index 3885bac238..8c0dc65be8 100644 --- a/packages/typert/generator/tests/fixtures/type-model/tsconfig.base.json +++ b/packages/typert/generator/tests/fixtures/type-model/tsconfig.base.json @@ -11,7 +11,7 @@ "ignoreDeprecations": "6.0", "types": ["node"], "paths": { - "cordis": ["./cordis.d.ts"], + "@deepseek-ai/cordis": ["./cordis.d.ts"], "@fixture/host": ["./packages/host/src/index.ts"], "@fixture/host/*": ["./packages/host/src/*"], "@fixture/client": ["./packages/client/src/index.ts"], diff --git a/packages/typert/generator/tests/tools-catalog.spec.ts b/packages/typert/generator/tests/tools-catalog.spec.ts index 95c1ab09de..4bb51e89a9 100644 --- a/packages/typert/generator/tests/tools-catalog.spec.ts +++ b/packages/typert/generator/tests/tools-catalog.spec.ts @@ -2,7 +2,7 @@ import { mkdtempSync, rmSync, writeFileSync } from 'node:fs' import { join, resolve } from 'node:path' import { pathToFileURL } from 'node:url' import { afterEach, describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import TypertRegistry from '@deepseek-ai/dsh-typert-registry' import type { TypertContribution } from '@deepseek-ai/dsh-typert-registry/types' import { EVENT_API, SERVICE_API, TYPE_API } from '@deepseek-ai/dsh-tool-cordis/src/api-catalog.ts' diff --git a/packages/typert/generator/tests/type-model.spec.ts b/packages/typert/generator/tests/type-model.spec.ts index 81e7f0b981..6911659222 100644 --- a/packages/typert/generator/tests/type-model.spec.ts +++ b/packages/typert/generator/tests/type-model.spec.ts @@ -834,7 +834,7 @@ describe('WorkspaceAnalyzer', { timeout: 60_000 }, () => { writeFileSync(manifestPath, `${JSON.stringify(manifest, null, 2)}\n`) writeFileSync(join(hostRoot, 'src/index.ts'), [ 'export {}', - "declare module 'cordis' {", + "declare module '@deepseek-ai/cordis' {", ' interface Context {}', ' interface Events {}', ' interface Ignored {}', @@ -1237,10 +1237,10 @@ function configureDualRuntimeClient(root: string, splitProjects: boolean): void } writeFileSync(manifestPath, `${JSON.stringify(manifest, null, 2)}\n`) writeFileSync(join(packageRoot, 'src/client.ts'), [ - "import { Service } from 'cordis'", + "import { Service } from '@deepseek-ai/cordis'", 'export interface ClientOnlyMarker { readonly client: true }', 'export class BrowserBridge extends Service {}', - "declare module 'cordis' { interface Context { browserBridge: BrowserBridge } }", + "declare module '@deepseek-ai/cordis' { interface Context { browserBridge: BrowserBridge } }", '', ].join('\n')) const indexPath = join(packageRoot, 'src/index.ts') @@ -1338,14 +1338,14 @@ function addExplicitServicePackage(root: string, annotation: string, withProtoco ' /** Report protocol readiness. */', ' ready(): boolean', '}', - "declare module 'cordis' {", + "declare module '@deepseek-ai/cordis' {", ' interface Context { detached: DetachedProtocol }', '}', '', ].join('\n')) } writeFileSync(join(packageRoot, 'src/index.ts'), [ - "import { Service } from 'cordis'", + "import { Service } from '@deepseek-ai/cordis'", ...(withProtocol ? ["export type { DetachedProtocol } from './types.ts'"] : []), '/**', ' * Service implementation discovered independently of its protocol package.', diff --git a/packages/typert/loader/package.json b/packages/typert/loader/package.json index ca6db771e3..998c0ec3a5 100644 --- a/packages/typert/loader/package.json +++ b/packages/typert/loader/package.json @@ -25,19 +25,19 @@ ], "license": "BSD-3-Clause", "peerDependencies": { - "@cordisjs/plugin-loader": "^1.0.0-rc.5", + "@deepseek-ai/cordis-plugin-loader": "^1.0.0-rc.5", "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-typert-registry": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { - "@cordisjs/plugin-loader": "workspace:^", + "@deepseek-ai/cordis-plugin-loader": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-typert-registry": "workspace:^", - "cordis": "^4.0.0-rc.7", + "@deepseek-ai/cordis": "^4.0.0-rc.7", "zod": "^4.4.3" } } diff --git a/packages/typert/loader/src/index.ts b/packages/typert/loader/src/index.ts index 2ae9722dea..7cb73c446f 100644 --- a/packages/typert/loader/src/index.ts +++ b/packages/typert/loader/src/index.ts @@ -29,9 +29,9 @@ import { readFileSync } from 'node:fs' import { createRequire } from 'node:module' import { dirname, join } from 'node:path' import { pathToFileURL } from 'node:url' -import type { Context } from 'cordis' -import z from 'schemastery' -import type {} from '@cordisjs/plugin-loader' +import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' +import type {} from '@deepseek-ai/cordis-plugin-loader' import type {} from '@deepseek-ai/dsh-typert-registry' import type { TypertContribution } from '@deepseek-ai/dsh-typert-registry/types' diff --git a/packages/typert/loader/src/invariant.ts b/packages/typert/loader/src/invariant.ts index 393324e7e9..dc7070c6cc 100644 --- a/packages/typert/loader/src/invariant.ts +++ b/packages/typert/loader/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-typert-loader' diff --git a/packages/typert/loader/tests/loader.spec.ts b/packages/typert/loader/tests/loader.spec.ts index 491538a533..ac14d39be5 100644 --- a/packages/typert/loader/tests/loader.spec.ts +++ b/packages/typert/loader/tests/loader.spec.ts @@ -4,8 +4,8 @@ import { tmpdir } from 'node:os' import { join } from 'node:path' import { fileURLToPath, pathToFileURL } from 'node:url' import { afterEach, describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' -import Loader from '@cordisjs/plugin-loader' +import { Context } from '@deepseek-ai/cordis' +import Loader from '@deepseek-ai/cordis-plugin-loader' import TypertRegistry from '@deepseek-ai/dsh-typert-registry' import * as typertLoader from '@deepseek-ai/dsh-typert-loader' import { validateTypertManifest } from '@deepseek-ai/dsh-typert-loader' diff --git a/packages/typert/registry/package.json b/packages/typert/registry/package.json index f094a0c11c..dacb88764b 100644 --- a/packages/typert/registry/package.json +++ b/packages/typert/registry/package.json @@ -51,10 +51,10 @@ }, "peerDependencies": { "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-invariants": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/typert/registry/src/client/index.ts b/packages/typert/registry/src/client/index.ts index e468e78999..1eb4b1246d 100644 --- a/packages/typert/registry/src/client/index.ts +++ b/packages/typert/registry/src/client/index.ts @@ -1,6 +1,6 @@ /** Browser face of the shared TypeRT runtime registry. */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { TypertRegistry } from '../service.ts' /** Required services: none; this is the Client reflection root. */ diff --git a/packages/typert/registry/src/invariant.ts b/packages/typert/registry/src/invariant.ts index 73b01a6742..93c63f786c 100644 --- a/packages/typert/registry/src/invariant.ts +++ b/packages/typert/registry/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-typert-registry' diff --git a/packages/typert/registry/src/service.ts b/packages/typert/registry/src/service.ts index 353ad4c9e0..b8bab3a121 100644 --- a/packages/typert/registry/src/service.ts +++ b/packages/typert/registry/src/service.ts @@ -5,7 +5,7 @@ * @module @deepseek-ai/dsh-typert-registry */ -import { Context, Service } from 'cordis' +import { Context, Service } from '@deepseek-ai/cordis' import { z } from 'zod' import type { InvocationDescriptor, diff --git a/packages/typert/registry/tests/typert.spec.ts b/packages/typert/registry/tests/typert.spec.ts index 92b81803c7..1bc4b65cb1 100644 --- a/packages/typert/registry/tests/typert.spec.ts +++ b/packages/typert/registry/tests/typert.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { z } from 'zod' import TypertRegistry, { typertEndpoint, diff --git a/packages/typert/type-meta/package.json b/packages/typert/type-meta/package.json index e2d7689866..9a1c362780 100644 --- a/packages/typert/type-meta/package.json +++ b/packages/typert/type-meta/package.json @@ -31,10 +31,10 @@ "license": "BSD-3-Clause", "peerDependencies": { "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-invariants": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/typert/type-meta/src/index.ts b/packages/typert/type-meta/src/index.ts index 1375d7872b..40a8b5b2ad 100644 --- a/packages/typert/type-meta/src/index.ts +++ b/packages/typert/type-meta/src/index.ts @@ -4,7 +4,7 @@ * @module @deepseek-ai/dsh-type-meta */ -import { Service, type Context } from 'cordis' +import { Service, type Context } from '@deepseek-ai/cordis' import type { TypeRTContextMap } from './types.ts' const TYPERT_REMOTE_SEGMENT_PATTERN = /^[A-Za-z0-9_$.-]+$/ diff --git a/packages/typert/type-meta/src/invariant.ts b/packages/typert/type-meta/src/invariant.ts index 22dc290a1e..304f0f9ac4 100644 --- a/packages/typert/type-meta/src/invariant.ts +++ b/packages/typert/type-meta/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-type-meta' diff --git a/packages/typert/type-meta/src/types.ts b/packages/typert/type-meta/src/types.ts index c1d6b3dcf9..622698bf6c 100644 --- a/packages/typert/type-meta/src/types.ts +++ b/packages/typert/type-meta/src/types.ts @@ -4,7 +4,7 @@ * @module @deepseek-ai/dsh-type-meta/types */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' declare const LOOKUP_HOST: unique symbol declare const LOOKUP_WIRE: unique symbol @@ -421,7 +421,7 @@ export interface TypeRTService { readonly contexts: TypeRTContextRegistry } -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { typert: TypeRTService } diff --git a/packages/typert/type-meta/tests/fixtures/source-launch.ts b/packages/typert/type-meta/tests/fixtures/source-launch.ts index 14eec6610d..55bea062ae 100644 --- a/packages/typert/type-meta/tests/fixtures/source-launch.ts +++ b/packages/typert/type-meta/tests/fixtures/source-launch.ts @@ -1,4 +1,4 @@ -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { GatewayService, Remote, diff --git a/packages/typert/type-meta/tests/type-meta.spec.ts b/packages/typert/type-meta/tests/type-meta.spec.ts index bfe99630b9..aa77541128 100644 --- a/packages/typert/type-meta/tests/type-meta.spec.ts +++ b/packages/typert/type-meta/tests/type-meta.spec.ts @@ -1,6 +1,6 @@ import { execFileSync } from 'node:child_process' import { fileURLToPath } from 'node:url' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { describe, expect, it } from 'vitest' import { bindTypeRTGateway, diff --git a/packages/util/atomic-write/package.json b/packages/util/atomic-write/package.json index 00de333170..b54b5989cf 100644 --- a/packages/util/atomic-write/package.json +++ b/packages/util/atomic-write/package.json @@ -26,10 +26,10 @@ "license": "BSD-3-Clause", "peerDependencies": { "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-invariants": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/util/atomic-write/src/invariant.ts b/packages/util/atomic-write/src/invariant.ts index 4027dd9bda..241d439cdf 100644 --- a/packages/util/atomic-write/src/invariant.ts +++ b/packages/util/atomic-write/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-atomic-write' diff --git a/packages/util/atomic-write/tests/invariant.spec.ts b/packages/util/atomic-write/tests/invariant.spec.ts index c80346762c..ab77662f47 100644 --- a/packages/util/atomic-write/tests/invariant.spec.ts +++ b/packages/util/atomic-write/tests/invariant.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import InvariantService from '@deepseek-ai/dsh-invariants' import * as AtomicWriteInvariant from '../src/invariant.ts' diff --git a/packages/util/brand/package.json b/packages/util/brand/package.json index 83676d1d5c..534cb20049 100644 --- a/packages/util/brand/package.json +++ b/packages/util/brand/package.json @@ -26,10 +26,10 @@ "license": "BSD-3-Clause", "peerDependencies": { "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-invariants": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/util/brand/src/invariant.ts b/packages/util/brand/src/invariant.ts index bf29a81b4c..cd33bf10cb 100644 --- a/packages/util/brand/src/invariant.ts +++ b/packages/util/brand/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-brand' diff --git a/packages/util/environment/README.i18n.yaml b/packages/util/environment/README.i18n.yaml index c8e36d8a5e..17b9c8d879 100644 --- a/packages/util/environment/README.i18n.yaml +++ b/packages/util/environment/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/util/environment/README.md -README.md: 599a9ba747905b66452b57717dabcc6f4678a3dd -README.zh.md: d728f835b1ece44d2848a618e504951f26fec7e2 +README.md: cdbc5b6dd4a5ea90c323f570598e2db124b43857 +README.zh.md: bbef1719370c787763eaa686a5609ec31833386e diff --git a/packages/util/environment/README.md b/packages/util/environment/README.md index 599a9ba747..cdbc5b6dd4 100644 --- a/packages/util/environment/README.md +++ b/packages/util/environment/README.md @@ -21,7 +21,7 @@ Values do also reach `process.env` — a user's `--config` tree and third-party Names match the way the platform matches them: exactly on POSIX, case-insensitively on Windows. A case-sensitive lookup there would rank the wrong layer — a shell's `deepseek_api_key` and a project `.env`'s `DEEPSEEK_API_KEY` are one variable to the OS, and treating them as two would let the project win. ```ts -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { environmentOf } from '@deepseek-ai/dsh-environment' declare const ctx: Context diff --git a/packages/util/environment/README.zh.md b/packages/util/environment/README.zh.md index d728f835b1..bbef171937 100644 --- a/packages/util/environment/README.zh.md +++ b/packages/util/environment/README.zh.md @@ -21,7 +21,7 @@ 变量名按平台自身的规则匹配:POSIX 上精确匹配,Windows 上不区分大小写。在 Windows 上做大小写敏感的查找会选错层——shell 里的 `deepseek_api_key` 与项目 `.env` 里的 `DEEPSEEK_API_KEY` 对操作系统而言是同一个变量,把它们当成两个就会让项目胜出。 ```ts -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { environmentOf } from '@deepseek-ai/dsh-environment' declare const ctx: Context diff --git a/packages/util/environment/package.json b/packages/util/environment/package.json index 15cbb603a5..113f3b10c9 100644 --- a/packages/util/environment/package.json +++ b/packages/util/environment/package.json @@ -26,10 +26,10 @@ "license": "BSD-3-Clause", "peerDependencies": { "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-invariants": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/util/environment/src/index.ts b/packages/util/environment/src/index.ts index 63a59c7337..d40cbc3c3b 100644 --- a/packages/util/environment/src/index.ts +++ b/packages/util/environment/src/index.ts @@ -6,7 +6,7 @@ * @module @deepseek-ai/dsh-environment */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' /** * Which layer supplied a value, from most to least trusted: the environment @@ -116,7 +116,7 @@ export function environmentOf(ctx: Context): EnvironmentSnapshot { ?? createEnvironmentSnapshot([{ source: 'process', values: process.env as Record }]) } -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { /** Launcher-owned snapshot of this run's environment; absent in compositions the product CLI did not boot. */ launcherEnvironment?: EnvironmentSnapshot diff --git a/packages/util/environment/src/invariant.ts b/packages/util/environment/src/invariant.ts index 96e53828ae..f5ca3b698c 100644 --- a/packages/util/environment/src/invariant.ts +++ b/packages/util/environment/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-environment' diff --git a/packages/util/environment/tests/environment.spec.ts b/packages/util/environment/tests/environment.spec.ts index 5951484a83..4ae4e93d8a 100644 --- a/packages/util/environment/tests/environment.spec.ts +++ b/packages/util/environment/tests/environment.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { createEnvironmentSnapshot, DSH_ENVIRONMENT_KEY, environmentOf, } from '../src/index.ts' diff --git a/packages/util/native-command/package.json b/packages/util/native-command/package.json index d282a128f7..a50e0f2c12 100644 --- a/packages/util/native-command/package.json +++ b/packages/util/native-command/package.json @@ -26,10 +26,10 @@ "license": "BSD-3-Clause", "peerDependencies": { "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-invariants": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/util/native-command/src/invariant.ts b/packages/util/native-command/src/invariant.ts index bec1d4b774..0504f06e3e 100644 --- a/packages/util/native-command/src/invariant.ts +++ b/packages/util/native-command/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-native-command' diff --git a/packages/util/paths/package.json b/packages/util/paths/package.json index cece1ce79e..749d3e7ac9 100644 --- a/packages/util/paths/package.json +++ b/packages/util/paths/package.json @@ -26,10 +26,10 @@ "license": "BSD-3-Clause", "peerDependencies": { "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.6" + "@deepseek-ai/cordis": "^4.0.0-rc.6" }, "devDependencies": { "@deepseek-ai/dsh-invariants": "workspace:^", - "cordis": "^4.0.0-rc.6" + "@deepseek-ai/cordis": "^4.0.0-rc.6" } } diff --git a/packages/util/paths/src/invariant.ts b/packages/util/paths/src/invariant.ts index f1661b7f52..92a636e57b 100644 --- a/packages/util/paths/src/invariant.ts +++ b/packages/util/paths/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-paths' diff --git a/packages/util/retention/package.json b/packages/util/retention/package.json index 80af828263..ad61896d35 100644 --- a/packages/util/retention/package.json +++ b/packages/util/retention/package.json @@ -26,10 +26,10 @@ "license": "BSD-3-Clause", "peerDependencies": { "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.6" + "@deepseek-ai/cordis": "^4.0.0-rc.6" }, "devDependencies": { "@deepseek-ai/dsh-invariants": "workspace:^", - "cordis": "^4.0.0-rc.6" + "@deepseek-ai/cordis": "^4.0.0-rc.6" } } diff --git a/packages/util/retention/src/invariant.ts b/packages/util/retention/src/invariant.ts index 0365793b03..90f7cf5252 100644 --- a/packages/util/retention/src/invariant.ts +++ b/packages/util/retention/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-retention' diff --git a/packages/util/timeout/package.json b/packages/util/timeout/package.json index 853cee4d79..0a398aa7a4 100644 --- a/packages/util/timeout/package.json +++ b/packages/util/timeout/package.json @@ -26,10 +26,10 @@ "license": "BSD-3-Clause", "peerDependencies": { "@deepseek-ai/dsh-invariants": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-invariants": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/util/timeout/src/invariant.ts b/packages/util/timeout/src/invariant.ts index bb9604d6b7..1284ecf8da 100644 --- a/packages/util/timeout/src/invariant.ts +++ b/packages/util/timeout/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-timeout' diff --git a/packages/web/tool-web/package.json b/packages/web/tool-web/package.json index d5d655b2dd..585c5a0e83 100644 --- a/packages/web/tool-web/package.json +++ b/packages/web/tool-web/package.json @@ -30,11 +30,11 @@ "@deepseek-ai/dsh-system-prompt": "^0.0.1", "@deepseek-ai/dsh-tools": "^0.0.1", "@deepseek-ai/dsh-web": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { "@joplin/turndown-plugin-gfm": "^1.0.67", - "schemastery": "^3.18.0", + "@deepseek-ai/schemastery": "^3.18.0", "turndown": "^7.2.4" }, "devDependencies": { @@ -51,6 +51,6 @@ "@deepseek-ai/dsh-web": "workspace:^", "@deepseek-ai/dsh-web-fetch-local": "workspace:^", "@deepseek-ai/dsh-web-search-exa": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/web/tool-web/src/fetch.ts b/packages/web/tool-web/src/fetch.ts index 94130df697..b28af9fa0a 100644 --- a/packages/web/tool-web/src/fetch.ts +++ b/packages/web/tool-web/src/fetch.ts @@ -5,7 +5,7 @@ * signal. A provider timeout remains a backstop for direct service callers. */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import TurndownService from 'turndown' import { gfm } from '@joplin/turndown-plugin-gfm' import { defineTool } from '@deepseek-ai/dsh-tools' diff --git a/packages/web/tool-web/src/index.ts b/packages/web/tool-web/src/index.ts index aad4d8728c..b9bd0ddcc8 100644 --- a/packages/web/tool-web/src/index.ts +++ b/packages/web/tool-web/src/index.ts @@ -6,8 +6,8 @@ * @module @deepseek-ai/dsh-tool-web */ -import type { Context } from 'cordis' -import z from 'schemastery' +import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import type {} from '@deepseek-ai/dsh-web' import { applyWebSearchTool, WEB_SEARCH_MAX_RESULTS } from './search.ts' import { applyWebFetchTool } from './fetch.ts' diff --git a/packages/web/tool-web/src/invariant.ts b/packages/web/tool-web/src/invariant.ts index 435f9ca549..a9ea21c3a9 100644 --- a/packages/web/tool-web/src/invariant.ts +++ b/packages/web/tool-web/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-tool-web' diff --git a/packages/web/tool-web/src/search.ts b/packages/web/tool-web/src/search.ts index 35c97dfda2..e550d10096 100644 --- a/packages/web/tool-web/src/search.ts +++ b/packages/web/tool-web/src/search.ts @@ -5,7 +5,7 @@ * never provider selection or network access. */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { defineTool } from '@deepseek-ai/dsh-tools' import type { GenericCallView, JsonValue, ToolResult, WebSearchResultView, WebSource } from '@deepseek-ai/dsh-tools' import type { WebSearchResult, WebSearchSource } from '@deepseek-ai/dsh-web' diff --git a/packages/web/tool-web/tests/integration.spec.ts b/packages/web/tool-web/tests/integration.spec.ts index e235d4d455..8c64ced81a 100644 --- a/packages/web/tool-web/tests/integration.spec.ts +++ b/packages/web/tool-web/tests/integration.spec.ts @@ -9,7 +9,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' import { createServer, type IncomingMessage, type Server, type ServerResponse } from 'node:http' import { AddressInfo } from 'node:net' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { CallId } from '@deepseek-ai/dsh-llm' import SystemPrompt from '@deepseek-ai/dsh-system-prompt' import ToolRegistry, { type ToolExecutionResult } from '@deepseek-ai/dsh-tools' diff --git a/packages/web/tool-web/tests/load-path.spec.ts b/packages/web/tool-web/tests/load-path.spec.ts index 1df718b871..32b1fe06fc 100644 --- a/packages/web/tool-web/tests/load-path.spec.ts +++ b/packages/web/tool-web/tests/load-path.spec.ts @@ -6,8 +6,8 @@ */ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' -import Loader from '@cordisjs/plugin-loader' +import { Context } from '@deepseek-ai/cordis' +import Loader from '@deepseek-ai/cordis-plugin-loader' import SystemPrompt from '@deepseek-ai/dsh-system-prompt' import ToolRegistry from '@deepseek-ai/dsh-tools' import WebService from '@deepseek-ai/dsh-web' diff --git a/packages/web/tool-web/tests/spill.spec.ts b/packages/web/tool-web/tests/spill.spec.ts index 33279fc9e9..1f972360b8 100644 --- a/packages/web/tool-web/tests/spill.spec.ts +++ b/packages/web/tool-web/tests/spill.spec.ts @@ -13,7 +13,7 @@ import { AddressInfo } from 'node:net' import { mkdtempSync, readFileSync, rmSync } from 'node:fs' import { tmpdir } from 'node:os' import { join } from 'node:path' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { CallId } from '@deepseek-ai/dsh-llm' import { SessionId } from '@deepseek-ai/dsh-session' import SystemPrompt from '@deepseek-ai/dsh-system-prompt' diff --git a/packages/web/tool-web/tests/tool-web.spec.ts b/packages/web/tool-web/tests/tool-web.spec.ts index de9bf79284..781209a9cc 100644 --- a/packages/web/tool-web/tests/tool-web.spec.ts +++ b/packages/web/tool-web/tests/tool-web.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import TurndownService from 'turndown' import { CallId } from '@deepseek-ai/dsh-llm' import SystemPrompt from '@deepseek-ai/dsh-system-prompt' diff --git a/packages/web/web-fetch-local/package.json b/packages/web/web-fetch-local/package.json index e6dc5791d9..cc34f6535d 100644 --- a/packages/web/web-fetch-local/package.json +++ b/packages/web/web-fetch-local/package.json @@ -28,15 +28,15 @@ "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-timeout": "^0.0.1", "@deepseek-ai/dsh-web": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-timeout": "workspace:^", "@deepseek-ai/dsh-web": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/web/web-fetch-local/src/index.ts b/packages/web/web-fetch-local/src/index.ts index a5636b37ee..92fe6c3025 100644 --- a/packages/web/web-fetch-local/src/index.ts +++ b/packages/web/web-fetch-local/src/index.ts @@ -7,8 +7,8 @@ * @module @deepseek-ai/dsh-web-fetch-local */ -import type { Context } from 'cordis' -import z from 'schemastery' +import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import type {} from '@deepseek-ai/dsh-web' import { LocalFetchProvider } from './provider.ts' import type { LocalFetchLimits } from './provider.ts' diff --git a/packages/web/web-fetch-local/src/invariant.ts b/packages/web/web-fetch-local/src/invariant.ts index 053fb12200..13f1990549 100644 --- a/packages/web/web-fetch-local/src/invariant.ts +++ b/packages/web/web-fetch-local/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-web-fetch-local' diff --git a/packages/web/web-fetch-local/tests/fetch-local.spec.ts b/packages/web/web-fetch-local/tests/fetch-local.spec.ts index 092e384d94..8200d0fe1d 100644 --- a/packages/web/web-fetch-local/tests/fetch-local.spec.ts +++ b/packages/web/web-fetch-local/tests/fetch-local.spec.ts @@ -1,7 +1,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' import { createServer, type IncomingMessage, type Server, type ServerResponse } from 'node:http' import { AddressInfo } from 'node:net' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import WebService from '@deepseek-ai/dsh-web' import { LocalFetchProvider, LOCAL_FETCH_PROVIDER_ID } from '@deepseek-ai/dsh-web-fetch-local' import type { LocalFetchLimits } from '@deepseek-ai/dsh-web-fetch-local' diff --git a/packages/web/web-search-deepseek/package.json b/packages/web/web-search-deepseek/package.json index 0ca52390de..cee385654b 100644 --- a/packages/web/web-search-deepseek/package.json +++ b/packages/web/web-search-deepseek/package.json @@ -31,10 +31,10 @@ "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-session": "^0.0.1", "@deepseek-ai/dsh-web": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { "@deepseek-ai/dsh-agent": "workspace:^", @@ -44,6 +44,6 @@ "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-session": "workspace:^", "@deepseek-ai/dsh-web": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/web/web-search-deepseek/src/index.ts b/packages/web/web-search-deepseek/src/index.ts index 5e55e12457..8b465d9617 100644 --- a/packages/web/web-search-deepseek/src/index.ts +++ b/packages/web/web-search-deepseek/src/index.ts @@ -5,8 +5,8 @@ * @module @deepseek-ai/dsh-web-search-deepseek */ -import type { Context } from 'cordis' -import z from 'schemastery' +import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import type {} from '@deepseek-ai/dsh-agent' import { credentialRef } from '@deepseek-ai/dsh-credentials' import { environmentOf } from '@deepseek-ai/dsh-environment' diff --git a/packages/web/web-search-deepseek/src/invariant.ts b/packages/web/web-search-deepseek/src/invariant.ts index d1f707f2bc..1f0b59d9e0 100644 --- a/packages/web/web-search-deepseek/src/invariant.ts +++ b/packages/web/web-search-deepseek/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-web-search-deepseek' diff --git a/packages/web/web-search-deepseek/tests/deepseek.spec.ts b/packages/web/web-search-deepseek/tests/deepseek.spec.ts index 23c2d2c237..af51213660 100644 --- a/packages/web/web-search-deepseek/tests/deepseek.spec.ts +++ b/packages/web/web-search-deepseek/tests/deepseek.spec.ts @@ -2,8 +2,8 @@ import { afterEach, describe, expect, it, vi } from 'vitest' import { mkdtemp, rm } from 'node:fs/promises' import { tmpdir } from 'node:os' import { join } from 'node:path' -import { Context } from 'cordis' -import Loader from '@cordisjs/plugin-loader' +import { Context } from '@deepseek-ai/cordis' +import Loader from '@deepseek-ai/cordis-plugin-loader' import { credentialRef } from '@deepseek-ai/dsh-credentials' import CredentialsLocal from '@deepseek-ai/dsh-credentials-local' import WebService from '@deepseek-ai/dsh-web' diff --git a/packages/web/web-search-exa/package.json b/packages/web/web-search-exa/package.json index c2d55e00ff..1861465ce9 100644 --- a/packages/web/web-search-exa/package.json +++ b/packages/web/web-search-exa/package.json @@ -28,15 +28,15 @@ "@deepseek-ai/dsh-environment": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-web": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { "@deepseek-ai/dsh-environment": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-web": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/web/web-search-exa/src/index.ts b/packages/web/web-search-exa/src/index.ts index 2ecb71336a..0b37cd5c1a 100644 --- a/packages/web/web-search-exa/src/index.ts +++ b/packages/web/web-search-exa/src/index.ts @@ -8,9 +8,9 @@ * @module @deepseek-ai/dsh-web-search-exa */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { environmentOf } from '@deepseek-ai/dsh-environment' -import z from 'schemastery' +import z from '@deepseek-ai/schemastery' import type {} from '@deepseek-ai/dsh-web' import { ExaSearchProvider, diff --git a/packages/web/web-search-exa/src/invariant.ts b/packages/web/web-search-exa/src/invariant.ts index 060ceb78ba..d7ba293ef1 100644 --- a/packages/web/web-search-exa/src/invariant.ts +++ b/packages/web/web-search-exa/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-web-search-exa' diff --git a/packages/web/web-search-exa/tests/exa.spec.ts b/packages/web/web-search-exa/tests/exa.spec.ts index 6e29b10aa8..86c20a3ffb 100644 --- a/packages/web/web-search-exa/tests/exa.spec.ts +++ b/packages/web/web-search-exa/tests/exa.spec.ts @@ -1,5 +1,5 @@ import { afterEach, describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import WebService from '@deepseek-ai/dsh-web' import { ExaSearchProvider, EXA_PROVIDER_ID } from '@deepseek-ai/dsh-web-search-exa' import * as exaPlugin from '@deepseek-ai/dsh-web-search-exa' diff --git a/packages/web/web-search-perplexity/package.json b/packages/web/web-search-perplexity/package.json index 1ece514da9..9c821c8dd7 100644 --- a/packages/web/web-search-perplexity/package.json +++ b/packages/web/web-search-perplexity/package.json @@ -28,15 +28,15 @@ "@deepseek-ai/dsh-environment": "^0.0.1", "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-web": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { "@deepseek-ai/dsh-environment": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-web": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/web/web-search-perplexity/src/index.ts b/packages/web/web-search-perplexity/src/index.ts index e1fe6a2606..e3ac97605d 100644 --- a/packages/web/web-search-perplexity/src/index.ts +++ b/packages/web/web-search-perplexity/src/index.ts @@ -7,9 +7,9 @@ * @module @deepseek-ai/dsh-web-search-perplexity */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import { environmentOf } from '@deepseek-ai/dsh-environment' -import z from 'schemastery' +import z from '@deepseek-ai/schemastery' import type {} from '@deepseek-ai/dsh-web' import { PerplexitySearchProvider, PERPLEXITY_DEFAULT_BASE_URL, PERPLEXITY_DEFAULT_MAX_TOKENS, PERPLEXITY_DEFAULT_MODEL } from './provider.ts' diff --git a/packages/web/web-search-perplexity/src/invariant.ts b/packages/web/web-search-perplexity/src/invariant.ts index cf3e009fed..fa4d1981b6 100644 --- a/packages/web/web-search-perplexity/src/invariant.ts +++ b/packages/web/web-search-perplexity/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-web-search-perplexity' diff --git a/packages/web/web-search-perplexity/tests/perplexity.spec.ts b/packages/web/web-search-perplexity/tests/perplexity.spec.ts index b622342384..d12c3957ca 100644 --- a/packages/web/web-search-perplexity/tests/perplexity.spec.ts +++ b/packages/web/web-search-perplexity/tests/perplexity.spec.ts @@ -1,5 +1,5 @@ import { afterEach, describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import WebService from '@deepseek-ai/dsh-web' import { PerplexitySearchProvider, diff --git a/packages/web/web/package.json b/packages/web/web/package.json index 4ea964ee93..4d4f787412 100644 --- a/packages/web/web/package.json +++ b/packages/web/web/package.json @@ -27,14 +27,14 @@ "peerDependencies": { "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-llm": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-llm": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/web/web/src/index.ts b/packages/web/web/src/index.ts index ded152cc81..eeadfaed77 100644 --- a/packages/web/web/src/index.ts +++ b/packages/web/web/src/index.ts @@ -6,8 +6,8 @@ * @module @deepseek-ai/dsh-web */ -import { Context, Service } from 'cordis' -import z from 'schemastery' +import { Context, Service } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import type { WebFetchProvider, WebFetchRequest, @@ -32,7 +32,7 @@ export type { WebSearchSource, } from './types.ts' -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { web: WebService } diff --git a/packages/web/web/src/invariant.ts b/packages/web/web/src/invariant.ts index 2ac094b34f..4ec2462d13 100644 --- a/packages/web/web/src/invariant.ts +++ b/packages/web/web/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-web' diff --git a/packages/web/web/tests/web.spec.ts b/packages/web/web/tests/web.spec.ts index 978284ee51..7fcb3b1f28 100644 --- a/packages/web/web/tests/web.spec.ts +++ b/packages/web/web/tests/web.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import WebService, { WebError, type WebFetchProvider, diff --git a/packages/workflow/tool-ralph/package.json b/packages/workflow/tool-ralph/package.json index 83bf0d057c..c2ebc18c31 100644 --- a/packages/workflow/tool-ralph/package.json +++ b/packages/workflow/tool-ralph/package.json @@ -32,13 +32,13 @@ "@deepseek-ai/dsh-system-prompt": "^0.0.1", "@deepseek-ai/dsh-tools": "^0.0.1", "@deepseek-ai/dsh-workflow": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { - "@cordisjs/plugin-loader": "workspace:^", + "@deepseek-ai/cordis-plugin-loader": "workspace:^", "@deepseek-ai/dsh-agent": "workspace:^", "@deepseek-ai/dsh-agent-loop": "workspace:^", "@deepseek-ai/dsh-agent-loop-testkit": "workspace:^", @@ -52,6 +52,6 @@ "@deepseek-ai/dsh-tools": "workspace:^", "@deepseek-ai/dsh-workflow": "workspace:^", "@deepseek-ai/dsh-workflow-workerthread": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/workflow/tool-ralph/src/index.ts b/packages/workflow/tool-ralph/src/index.ts index e6e7edfccf..86e7d28843 100644 --- a/packages/workflow/tool-ralph/src/index.ts +++ b/packages/workflow/tool-ralph/src/index.ts @@ -5,8 +5,8 @@ * @module @deepseek-ai/dsh-tool-ralph */ -import type { Context } from 'cordis' -import z from 'schemastery' +import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import type { ContentBlock } from '@deepseek-ai/dsh-llm' import type { JsonValue } from '@deepseek-ai/dsh-session' import type { SubagentProvider } from '@deepseek-ai/dsh-subagent' diff --git a/packages/workflow/tool-ralph/src/invariant.ts b/packages/workflow/tool-ralph/src/invariant.ts index 22a7d1f2ea..3b050136fb 100644 --- a/packages/workflow/tool-ralph/src/invariant.ts +++ b/packages/workflow/tool-ralph/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-tool-ralph' diff --git a/packages/workflow/tool-ralph/tests/integration.spec.ts b/packages/workflow/tool-ralph/tests/integration.spec.ts index eb379dde16..d05d011a41 100644 --- a/packages/workflow/tool-ralph/tests/integration.spec.ts +++ b/packages/workflow/tool-ralph/tests/integration.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import type { Agent } from '@deepseek-ai/dsh-agent' import AgentLoop from '@deepseek-ai/dsh-agent-loop' import { mountAgentLoopTestDependencies } from '@deepseek-ai/dsh-agent-loop-testkit' diff --git a/packages/workflow/tool-ralph/tests/tool-ralph.spec.ts b/packages/workflow/tool-ralph/tests/tool-ralph.spec.ts index 29ba7edd4e..7033b89bd8 100644 --- a/packages/workflow/tool-ralph/tests/tool-ralph.spec.ts +++ b/packages/workflow/tool-ralph/tests/tool-ralph.spec.ts @@ -1,6 +1,6 @@ import { describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' -import Loader from '@cordisjs/plugin-loader' +import { Context } from '@deepseek-ai/cordis' +import Loader from '@deepseek-ai/cordis-plugin-loader' import type { Agent } from '@deepseek-ai/dsh-agent' import { CallId } from '@deepseek-ai/dsh-llm' import { SessionId } from '@deepseek-ai/dsh-session' diff --git a/packages/workflow/tool-workflow/package.json b/packages/workflow/tool-workflow/package.json index 705e4f6e08..0078621f99 100644 --- a/packages/workflow/tool-workflow/package.json +++ b/packages/workflow/tool-workflow/package.json @@ -31,10 +31,10 @@ "@deepseek-ai/dsh-system-prompt": "^0.0.1", "@deepseek-ai/dsh-tools": "^0.0.1", "@deepseek-ai/dsh-workflow": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { "@deepseek-ai/dsh-agent": "workspace:^", @@ -46,6 +46,6 @@ "@deepseek-ai/dsh-tools": "workspace:^", "@deepseek-ai/dsh-workflow": "workspace:^", "@deepseek-ai/dsh-workflow-workerthread": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/workflow/tool-workflow/src/index.ts b/packages/workflow/tool-workflow/src/index.ts index 6c1e9b19bb..af9aeed5e8 100644 --- a/packages/workflow/tool-workflow/src/index.ts +++ b/packages/workflow/tool-workflow/src/index.ts @@ -10,8 +10,8 @@ * @module @deepseek-ai/dsh-tool-workflow */ -import type { Context } from 'cordis' -import z from 'schemastery' +import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import { defineTool } from '@deepseek-ai/dsh-tools' import type { ToolCallView, ToolResultView } from '@deepseek-ai/dsh-tools' import type { ContentBlock } from '@deepseek-ai/dsh-llm' diff --git a/packages/workflow/tool-workflow/src/invariant.ts b/packages/workflow/tool-workflow/src/invariant.ts index 5f3ebc68ce..74edbb21dc 100644 --- a/packages/workflow/tool-workflow/src/invariant.ts +++ b/packages/workflow/tool-workflow/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-tool-workflow' diff --git a/packages/workflow/tool-workflow/tests/tool-workflow.spec.ts b/packages/workflow/tool-workflow/tests/tool-workflow.spec.ts index a61862cffd..687fd675c7 100644 --- a/packages/workflow/tool-workflow/tests/tool-workflow.spec.ts +++ b/packages/workflow/tool-workflow/tests/tool-workflow.spec.ts @@ -1,6 +1,6 @@ import { describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' -import Loader from '@cordisjs/plugin-loader' +import { Context } from '@deepseek-ai/cordis' +import Loader from '@deepseek-ai/cordis-plugin-loader' import SystemPrompt from '@deepseek-ai/dsh-system-prompt' import ToolRegistry, { TOOL_ABORTED_BEFORE_DISPATCH } from '@deepseek-ai/dsh-tools' import type { ToolExecutionResult } from '@deepseek-ai/dsh-tools' diff --git a/packages/workflow/workflow-workerthread/package.json b/packages/workflow/workflow-workerthread/package.json index e019bcaa51..e229c02e37 100644 --- a/packages/workflow/workflow-workerthread/package.json +++ b/packages/workflow/workflow-workerthread/package.json @@ -38,10 +38,10 @@ "@deepseek-ai/dsh-subagent": "^0.0.1", "@deepseek-ai/dsh-tools": "^0.0.1", "@deepseek-ai/dsh-workflow": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { "@deepseek-ai/dsh-agent": "workspace:^", @@ -56,7 +56,7 @@ "@deepseek-ai/dsh-system-prompt": "workspace:^", "@deepseek-ai/dsh-tools": "workspace:^", "@deepseek-ai/dsh-workflow": "workspace:^", - "cordis": "^4.0.0-rc.7", + "@deepseek-ai/cordis": "^4.0.0-rc.7", "tsx": "^4.19.2" } } diff --git a/packages/workflow/workflow-workerthread/src/host.ts b/packages/workflow/workflow-workerthread/src/host.ts index 57570a5098..501a3555c3 100644 --- a/packages/workflow/workflow-workerthread/src/host.ts +++ b/packages/workflow/workflow-workerthread/src/host.ts @@ -9,7 +9,7 @@ import { Worker } from 'node:worker_threads' import type { WorkerOptions } from 'node:worker_threads' import { fileURLToPath } from 'node:url' -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { Agent } from '@deepseek-ai/dsh-agent' import { assertNever } from '@deepseek-ai/dsh-llm' import { snapshotJsonValue } from '@deepseek-ai/dsh-session' diff --git a/packages/workflow/workflow-workerthread/src/index.ts b/packages/workflow/workflow-workerthread/src/index.ts index 33c5917acf..309da3af97 100644 --- a/packages/workflow/workflow-workerthread/src/index.ts +++ b/packages/workflow/workflow-workerthread/src/index.ts @@ -9,8 +9,8 @@ import { randomUUID } from 'node:crypto' import { availableParallelism } from 'node:os' import * as vm from 'node:vm' -import type { Context } from 'cordis' -import z from 'schemastery' +import type { Context } from '@deepseek-ai/cordis' +import z from '@deepseek-ai/schemastery' import WorkflowService, { WorkflowError, WorkflowRunId } from '@deepseek-ai/dsh-workflow' import type { WorkflowRun, WorkflowRunInfo, WorkflowStartRequest } from '@deepseek-ai/dsh-workflow' import { WorkerRun } from './host.ts' diff --git a/packages/workflow/workflow-workerthread/src/invariant.ts b/packages/workflow/workflow-workerthread/src/invariant.ts index 6845aeebff..401292691a 100644 --- a/packages/workflow/workflow-workerthread/src/invariant.ts +++ b/packages/workflow/workflow-workerthread/src/invariant.ts @@ -4,7 +4,7 @@ */ /* jscpd:ignore-start */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' const PACKAGE_NAME = '@deepseek-ai/dsh-workflow-workerthread' diff --git a/packages/workflow/workflow-workerthread/tests/built-worker.e2e.ts b/packages/workflow/workflow-workerthread/tests/built-worker.e2e.ts index e330b3ee83..7b94e48b96 100644 --- a/packages/workflow/workflow-workerthread/tests/built-worker.e2e.ts +++ b/packages/workflow/workflow-workerthread/tests/built-worker.e2e.ts @@ -21,7 +21,7 @@ describe.skipIf(!existsSync(builtIndex) || !existsSync(builtWorker))('built work const driver = join(packageRoot, `.built-worker-driver-${process.pid}.mjs`) try { await writeFile(driver, ` -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import SubagentService from '@deepseek-ai/dsh-subagent' import WorkerWorkflowEngine from '@deepseek-ai/dsh-workflow-workerthread' diff --git a/packages/workflow/workflow-workerthread/tests/integration.spec.ts b/packages/workflow/workflow-workerthread/tests/integration.spec.ts index e137d7f94f..fe71dcf750 100644 --- a/packages/workflow/workflow-workerthread/tests/integration.spec.ts +++ b/packages/workflow/workflow-workerthread/tests/integration.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { SessionId } from '@deepseek-ai/dsh-session' import AgentLoop from '@deepseek-ai/dsh-agent-loop' import { mountAgentLoopTestDependencies } from '@deepseek-ai/dsh-agent-loop-testkit' diff --git a/packages/workflow/workflow-workerthread/tests/source-worker.compat.spec.ts b/packages/workflow/workflow-workerthread/tests/source-worker.compat.spec.ts index 3fb08bb5ba..7eecf1a52b 100644 --- a/packages/workflow/workflow-workerthread/tests/source-worker.compat.spec.ts +++ b/packages/workflow/workflow-workerthread/tests/source-worker.compat.spec.ts @@ -5,7 +5,7 @@ */ import { expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import type { Agent } from '@deepseek-ai/dsh-agent' import SubagentService from '@deepseek-ai/dsh-subagent' import type { SubagentProvider } from '@deepseek-ai/dsh-subagent' diff --git a/packages/workflow/workflow-workerthread/tests/workflow-workerthread.e2e.ts b/packages/workflow/workflow-workerthread/tests/workflow-workerthread.e2e.ts index 08e1845d22..5c6128cb38 100644 --- a/packages/workflow/workflow-workerthread/tests/workflow-workerthread.e2e.ts +++ b/packages/workflow/workflow-workerthread/tests/workflow-workerthread.e2e.ts @@ -1,5 +1,5 @@ import { afterEach, describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import LlmService from '@deepseek-ai/dsh-llm' import SessionStore, { SessionId } from '@deepseek-ai/dsh-session' import SystemPrompt from '@deepseek-ai/dsh-system-prompt' diff --git a/packages/workflow/workflow-workerthread/tests/workflow-workerthread.spec.ts b/packages/workflow/workflow-workerthread/tests/workflow-workerthread.spec.ts index de190349a4..8b580d8ce5 100644 --- a/packages/workflow/workflow-workerthread/tests/workflow-workerthread.spec.ts +++ b/packages/workflow/workflow-workerthread/tests/workflow-workerthread.spec.ts @@ -1,8 +1,8 @@ import { describe, expect, it, vi } from 'vitest' import { fileURLToPath } from 'node:url' import type { Worker } from 'node:worker_threads' -import { Context } from 'cordis' -import Loader from '@cordisjs/plugin-loader' +import { Context } from '@deepseek-ai/cordis' +import Loader from '@deepseek-ai/cordis-plugin-loader' import type { Agent } from '@deepseek-ai/dsh-agent' import SubagentService from '@deepseek-ai/dsh-subagent' import type { SubagentCapabilities, SubagentProvider, SubagentResult, SubagentRun, SubagentStartRequest } from '@deepseek-ai/dsh-subagent' diff --git a/packages/workflow/workflow/package.json b/packages/workflow/workflow/package.json index 53ef7e6f6e..3cc199028a 100644 --- a/packages/workflow/workflow/package.json +++ b/packages/workflow/workflow/package.json @@ -30,7 +30,7 @@ "@deepseek-ai/dsh-invariants": "^0.0.1", "@deepseek-ai/dsh-llm": "^0.0.1", "@deepseek-ai/dsh-session": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "devDependencies": { "@deepseek-ai/dsh-agent": "workspace:^", @@ -38,6 +38,6 @@ "@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-llm": "workspace:^", "@deepseek-ai/dsh-session": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/workflow/workflow/src/index.ts b/packages/workflow/workflow/src/index.ts index 526da15ad8..380729d148 100644 --- a/packages/workflow/workflow/src/index.ts +++ b/packages/workflow/workflow/src/index.ts @@ -4,7 +4,7 @@ * @module @deepseek-ai/dsh-workflow */ -import { Context, Service } from 'cordis' +import { Context, Service } from '@deepseek-ai/cordis' import { HarnessError } from '@deepseek-ai/dsh-llm' import type { WorkflowAgentEndInfo, @@ -30,7 +30,7 @@ export type { WorkflowStopReason, } from './types.ts' -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { workflows: WorkflowService } diff --git a/packages/workflow/workflow/src/invariant.ts b/packages/workflow/workflow/src/invariant.ts index f6b8b8ced2..47dc82d0bf 100644 --- a/packages/workflow/workflow/src/invariant.ts +++ b/packages/workflow/workflow/src/invariant.ts @@ -1,6 +1,6 @@ /** Package-owned workflow lifecycle invariants. @module @deepseek-ai/dsh-workflow/invariant */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantFailure, InvariantInstaller } from '@deepseek-ai/dsh-invariants' import type { WorkflowAgentEndInfo, diff --git a/packages/workflow/workflow/tests/invariant.spec.ts b/packages/workflow/workflow/tests/invariant.spec.ts index 671a7a3e86..54eed758fa 100644 --- a/packages/workflow/workflow/tests/invariant.spec.ts +++ b/packages/workflow/workflow/tests/invariant.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { SessionId } from '@deepseek-ai/dsh-session' import { WorkflowRunId } from '@deepseek-ai/dsh-workflow' import type { diff --git a/packages/workflow/workflow/tests/workflow.spec.ts b/packages/workflow/workflow/tests/workflow.spec.ts index 1cdf15c26d..689d959c9c 100644 --- a/packages/workflow/workflow/tests/workflow.spec.ts +++ b/packages/workflow/workflow/tests/workflow.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it, vi } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import WorkflowServiceDefault, { isFatalWorkflowError, WorkflowError, diff --git a/packages/workspace/workspace/package.json b/packages/workspace/workspace/package.json index 7839b29702..b33296c228 100644 --- a/packages/workspace/workspace/package.json +++ b/packages/workspace/workspace/package.json @@ -36,7 +36,7 @@ "@deepseek-ai/dsh-session": "^0.0.1", "@deepseek-ai/dsh-session-persistence": "^0.0.1", "@deepseek-ai/dsh-storage": "^0.0.1", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { "zod": "^4.4.3" @@ -48,6 +48,6 @@ "@deepseek-ai/dsh-session": "workspace:^", "@deepseek-ai/dsh-session-persistence": "workspace:^", "@deepseek-ai/dsh-storage": "workspace:^", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/packages/workspace/workspace/src/index.ts b/packages/workspace/workspace/src/index.ts index d2d20d65ab..d972085939 100644 --- a/packages/workspace/workspace/src/index.ts +++ b/packages/workspace/workspace/src/index.ts @@ -8,7 +8,7 @@ import { randomUUID } from 'node:crypto' import { stat } from 'node:fs/promises' import { basename } from 'node:path' -import { Context, Service } from 'cordis' +import { Context, Service } from '@deepseek-ai/cordis' import type { SessionHeader, SessionId } from '@deepseek-ai/dsh-session' import type {} from '@deepseek-ai/dsh-session-persistence' import type { DomainGlobal, KvTable } from '@deepseek-ai/dsh-storage-domain' @@ -53,7 +53,7 @@ export class WorkspaceUnknownSessionError extends Error { } -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { workspace: WorkspaceRegistry } diff --git a/packages/workspace/workspace/src/invariant.ts b/packages/workspace/workspace/src/invariant.ts index 808ce1dedf..abcc61bca1 100644 --- a/packages/workspace/workspace/src/invariant.ts +++ b/packages/workspace/workspace/src/invariant.ts @@ -3,7 +3,7 @@ * @module @deepseek-ai/dsh-workspace/invariant */ -import type { Context } from 'cordis' +import type { Context } from '@deepseek-ai/cordis' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' import type { DomainChanged } from '@deepseek-ai/dsh-storage-domain' import { WorkspaceId } from '@deepseek-ai/dsh-workspace' diff --git a/packages/workspace/workspace/tests/invariant.spec.ts b/packages/workspace/workspace/tests/invariant.spec.ts index 0d0556a44a..803a7dfe4b 100644 --- a/packages/workspace/workspace/tests/invariant.spec.ts +++ b/packages/workspace/workspace/tests/invariant.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import InvariantService from '@deepseek-ai/dsh-invariants' import type { DomainChanged } from '@deepseek-ai/dsh-storage-domain' import * as WorkspaceInvariant from '../src/invariant.ts' diff --git a/packages/workspace/workspace/tests/workspace.spec.ts b/packages/workspace/workspace/tests/workspace.spec.ts index 6a562e15bd..3c4b6185fb 100644 --- a/packages/workspace/workspace/tests/workspace.spec.ts +++ b/packages/workspace/workspace/tests/workspace.spec.ts @@ -2,7 +2,7 @@ import { afterEach, describe, expect, it, vi } from 'vitest' import { mkdir, mkdtemp, realpath, rm, symlink, writeFile } from 'node:fs/promises' import { tmpdir } from 'node:os' import { basename, join } from 'node:path' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import Storage from '@deepseek-ai/dsh-storage' import type { StorageBackend } from '@deepseek-ai/dsh-storage' import { DomainFacility } from '@deepseek-ai/dsh-storage-domain' diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 732e00e4ee..77c29b881b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -122,16 +122,19 @@ importers: apps/cli: dependencies: - '@cordisjs/plugin-hmr': + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../vendor/cordis + '@deepseek-ai/cordis-plugin-hmr': specifier: workspace:* version: link:../../vendor/hmr - '@cordisjs/plugin-include': + '@deepseek-ai/cordis-plugin-include': specifier: workspace:* version: link:../../vendor/include - '@cordisjs/plugin-loader': + '@deepseek-ai/cordis-plugin-loader': specifier: workspace:* version: link:../../vendor/loader - '@cordisjs/plugin-timer': + '@deepseek-ai/cordis-plugin-timer': specifier: workspace:* version: link:../../vendor/timer '@deepseek-ai/dsh-agent-tool-mode': @@ -272,9 +275,6 @@ importers: commander: specifier: ^15.0.0 version: 15.0.0 - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../vendor/cordis js-yaml: specifier: ^4.2.0 version: 4.2.0 @@ -337,7 +337,7 @@ importers: specifier: ^18.2.0 version: 18.3.1(react@18.3.1) devDependencies: - '@cordisjs/plugin-group': + '@deepseek-ai/cordis-plugin-group': specifier: workspace:^ version: link:../../vendor/group '@deepseek-ai/dsh-client-modules': @@ -382,16 +382,16 @@ importers: examples: dependencies: - '@cordisjs/plugin-hmr': + '@deepseek-ai/cordis-plugin-hmr': specifier: workspace:* version: link:../vendor/hmr - '@cordisjs/plugin-include': + '@deepseek-ai/cordis-plugin-include': specifier: workspace:* version: link:../vendor/include - '@cordisjs/plugin-logger-console': + '@deepseek-ai/cordis-plugin-logger-console': specifier: workspace:* version: link:../vendor/logger-console - '@cordisjs/plugin-timer': + '@deepseek-ai/cordis-plugin-timer': specifier: workspace:* version: link:../vendor/timer '@deepseek-ai/dsh-acp-demo': @@ -734,10 +734,13 @@ importers: '@agentclientprotocol/sdk': specifier: 0.25.1 version: 0.25.1(zod@4.4.3) - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.17.0 version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-agent': specifier: workspace:^ version: link:../../core/agent @@ -762,9 +765,6 @@ importers: '@deepseek-ai/dsh-user-approval': specifier: workspace:^ version: link:../../interaction/user-approval - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/api/gateway: dependencies: @@ -772,6 +772,9 @@ importers: specifier: workspace:^ version: link:../../typert/type-meta devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-client-connection': specifier: workspace:^ version: link:../../client/connection @@ -784,9 +787,6 @@ importers: '@deepseek-ai/dsh-typert-registry': specifier: workspace:^ version: link:../../typert/registry - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis zod: specifier: ^4.4.3 version: 4.4.3 @@ -797,6 +797,9 @@ importers: specifier: workspace:^ version: link:../../typert/type-meta devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-agent': specifier: workspace:^ version: link:../../core/agent @@ -815,31 +818,31 @@ importers: '@deepseek-ai/dsh-typert-registry': specifier: workspace:^ version: link:../../typert/registry - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/attachment/attachment: devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-brand': specifier: workspace:^ version: link:../../util/brand '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/attachment/attachment-local: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery sharp: specifier: ^0.35.3 version: 0.35.3(@types/node@22.20.0) devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-attachment': specifier: workspace:^ version: link:../attachment @@ -849,12 +852,12 @@ importers: '@deepseek-ai/dsh-paths': specifier: workspace:^ version: link:../../util/paths - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/bash/bash: devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants @@ -864,16 +867,16 @@ importers: '@deepseek-ai/dsh-subprocess': specifier: workspace:^ version: link:../../subprocess/subprocess - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/bash/bash-env: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-agent': specifier: workspace:^ version: link:../../core/agent @@ -895,16 +898,16 @@ importers: '@deepseek-ai/dsh-tools': specifier: workspace:^ version: link:../../core/tools - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/bash/bash-local: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-bash': specifier: workspace:^ version: link:../bash @@ -920,12 +923,12 @@ importers: '@deepseek-ai/dsh-timeout': specifier: workspace:^ version: link:../../util/timeout - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/bash/bash-sandbox: devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-bash': specifier: workspace:^ version: link:../bash @@ -950,16 +953,16 @@ importers: '@deepseek-ai/node-addon-landlock-run': specifier: workspace:* version: link:../../../native/landlock-run/packages/entry - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/bash/pwsh-local: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-bash': specifier: workspace:^ version: link:../bash @@ -975,12 +978,12 @@ importers: '@deepseek-ai/dsh-timeout': specifier: workspace:^ version: link:../../util/timeout - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/bash/pwsh-sandbox: devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-bash': specifier: workspace:^ version: link:../bash @@ -1002,16 +1005,16 @@ importers: '@deepseek-ai/dsh-subprocess-local': specifier: workspace:^ version: link:../../subprocess/subprocess-local - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/bash/tool-bash: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-agent': specifier: workspace:^ version: link:../../core/agent @@ -1069,16 +1072,16 @@ importers: '@deepseek-ai/dsh-user-approval': specifier: workspace:^ version: link:../../interaction/user-approval - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/bash/tool-pwsh: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-agent': specifier: workspace:^ version: link:../../core/agent @@ -1127,9 +1130,6 @@ importers: '@deepseek-ai/dsh-user-approval': specifier: workspace:^ version: link:../../interaction/user-approval - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/boot/app-boot: dependencies: @@ -1137,19 +1137,22 @@ importers: specifier: ^4.2.0 version: 4.2.0 devDependencies: - '@cordisjs/plugin-group': + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis + '@deepseek-ai/cordis-plugin-group': specifier: workspace:^ version: link:../../../vendor/group - '@cordisjs/plugin-hmr': + '@deepseek-ai/cordis-plugin-hmr': specifier: workspace:^ version: link:../../../vendor/hmr - '@cordisjs/plugin-include': + '@deepseek-ai/cordis-plugin-include': specifier: workspace:^ version: link:../../../vendor/include - '@cordisjs/plugin-loader': + '@deepseek-ai/cordis-plugin-loader': specifier: workspace:^ version: link:../../../vendor/loader - '@cordisjs/plugin-timer': + '@deepseek-ai/cordis-plugin-timer': specifier: workspace:^ version: link:../../../vendor/timer '@deepseek-ai/dsh-environment': @@ -1167,16 +1170,13 @@ importers: '@types/js-yaml': specifier: ^4.0.9 version: 4.0.9 - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/bundle/base: dependencies: - '@cordisjs/plugin-hmr': + '@deepseek-ai/cordis-plugin-hmr': specifier: workspace:* version: link:../../../vendor/hmr - '@cordisjs/plugin-timer': + '@deepseek-ai/cordis-plugin-timer': specifier: workspace:* version: link:../../../vendor/timer '@deepseek-ai/dsh-agent': @@ -1405,23 +1405,26 @@ importers: specifier: workspace:^ version: link:../../context/workspace-context devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/bundle/headless: dependencies: '@deepseek-ai/dsh-code-runtime-worker': specifier: workspace:^ version: link:../../code-runtime/code-runtime-worker - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: - '@cordisjs/plugin-loader': + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis + '@deepseek-ai/cordis-plugin-loader': specifier: workspace:^ version: link:../../../vendor/loader '@deepseek-ai/dsh-agent': @@ -1439,9 +1442,6 @@ importers: '@deepseek-ai/dsh-session': specifier: workspace:^ version: link:../../core/session - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/bundle/web-app: dependencies: @@ -1568,10 +1568,13 @@ importers: '@deepseek-ai/dsh-workspace': specifier: workspace:^ version: link:../../workspace/workspace - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-bash-env': specifier: workspace:^ version: link:../../bash/bash-env @@ -1581,9 +1584,6 @@ importers: '@deepseek-ai/dsh-system-prompt': specifier: workspace:^ version: link:../../core/system-prompt - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/client/connection: dependencies: @@ -1605,13 +1605,16 @@ importers: '@deepseek-ai/dsh-tools': specifier: workspace:^ version: link:../../core/tools - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery ws: specifier: ^8.21.0 version: 8.21.0 devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-host-webserver': specifier: workspace:^ version: link:../../host/webserver @@ -1621,17 +1624,17 @@ importers: '@types/ws': specifier: ^8.18.1 version: 8.18.1 - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/client/hmr: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: - '@cordisjs/plugin-loader': + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis + '@deepseek-ai/cordis-plugin-loader': specifier: workspace:^ version: link:../../../vendor/loader '@deepseek-ai/dsh-client-modules': @@ -1643,9 +1646,6 @@ importers: '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/client/locale: dependencies: @@ -1655,10 +1655,13 @@ importers: '@deepseek-ai/dsh-settings': specifier: workspace:^ version: link:../../settings/settings - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-client-runtime': specifier: workspace:^ version: link:../runtime @@ -1674,16 +1677,16 @@ importers: '@types/react': specifier: ~18.3.1 version: 18.3.31 - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis react: specifier: ^18.2.0 version: 18.3.1 packages/client/modules: devDependencies: - '@cordisjs/plugin-loader': + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis + '@deepseek-ai/cordis-plugin-loader': specifier: workspace:^ version: link:../../../vendor/loader '@deepseek-ai/dsh-host-webserver': @@ -1692,9 +1695,6 @@ importers: '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/client/runtime: dependencies: @@ -1750,6 +1750,9 @@ importers: specifier: ~4.4.7 version: 4.4.7(@types/react@18.3.31)(immer@10.2.0)(react@18.3.1) devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants @@ -1762,28 +1765,25 @@ importers: '@deepseek-ai/dsh-typert-registry': specifier: workspace:^ version: link:../../typert/registry + '@deepseek-ai/schemastery': + specifier: ^3.18.0 + version: link:../../../vendor/schemastery '@types/react': specifier: ~18.3.1 version: 18.3.31 - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis - schemastery: - specifier: ^3.18.0 - version: link:../../../vendor/schemastery packages/client/schema-form: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/client/test-runtime: dependencies: @@ -1797,6 +1797,9 @@ importers: specifier: ^4.1.8 version: 4.1.8(@opentelemetry/api@1.9.1)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(jsdom@29.1.1)(vite@8.0.16(@types/node@26.1.2)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.22.4)(yaml@2.9.0)) devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-client-runtime': specifier: workspace:^ version: link:../runtime @@ -1818,9 +1821,6 @@ importers: '@types/react-dom': specifier: ~18.3.0 version: 18.3.7(@types/react@18.3.31) - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis react: specifier: ^18.2.0 version: 18.3.1 @@ -1830,6 +1830,9 @@ importers: packages/client/ui-agent-preset: devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-client-connection': specifier: workspace:^ version: link:../connection @@ -1863,9 +1866,6 @@ importers: '@types/react': specifier: ~18.3.1 version: 18.3.31 - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis react: specifier: ^18.2.0 version: 18.3.1 @@ -1876,6 +1876,9 @@ importers: specifier: ^2.0.0 version: 2.1.1 devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-client-connection': specifier: workspace:^ version: link:../connection @@ -1906,9 +1909,6 @@ importers: '@types/react': specifier: ~18.3.1 version: 18.3.31 - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis react: specifier: ^18.2.0 version: 18.3.1 @@ -1918,13 +1918,16 @@ importers: '@deepseek-ai/dsh-settings': specifier: workspace:^ version: link:../../settings/settings + '@deepseek-ai/schemastery': + specifier: ^3.18.0 + version: link:../../../vendor/schemastery clsx: specifier: ^2.0.0 version: 2.1.1 - schemastery: - specifier: ^3.18.0 - version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-agent': specifier: workspace:^ version: link:../../core/agent @@ -1994,9 +1997,6 @@ importers: '@types/react': specifier: ~18.3.1 version: 18.3.31 - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis react: specifier: ^18.2.0 version: 18.3.1 @@ -2007,6 +2007,9 @@ importers: specifier: ^18.2.0 version: 18.3.1 devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-client-locale': specifier: workspace:^ version: link:../locale @@ -2028,12 +2031,12 @@ importers: '@types/react': specifier: ~18.3.1 version: 18.3.31 - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/client/ui-goal: devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-api-remotes': specifier: workspace:^ version: link:../../api/remotes @@ -2067,9 +2070,6 @@ importers: '@types/react': specifier: ~18.3.1 version: 18.3.31 - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis react: specifier: ^18.2.0 version: 18.3.1 @@ -2079,6 +2079,9 @@ importers: packages/client/ui-layout: devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-client-locale': specifier: workspace:^ version: link:../locale @@ -2097,15 +2100,15 @@ importers: '@types/react': specifier: ~18.3.1 version: 18.3.31 - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis react: specifier: ^18.2.0 version: 18.3.1 packages/client/ui-model: devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-client-connection': specifier: workspace:^ version: link:../connection @@ -2139,15 +2142,15 @@ importers: clsx: specifier: ^2.1.1 version: 2.1.1 - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis react: specifier: ^18.2.0 version: 18.3.1 packages/client/ui-models: devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-client-connection': specifier: workspace:^ version: link:../connection @@ -2181,15 +2184,15 @@ importers: '@types/react': specifier: ~18.3.1 version: 18.3.31 - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis react: specifier: ^18.2.0 version: 18.3.1 packages/client/ui-permission: devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-client-connection': specifier: workspace:^ version: link:../connection @@ -2226,15 +2229,15 @@ importers: '@types/react': specifier: ~18.3.1 version: 18.3.31 - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis react: specifier: ^18.2.0 version: 18.3.1 packages/client/ui-plan: devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-client-connection': specifier: workspace:^ version: link:../connection @@ -2268,9 +2271,6 @@ importers: '@types/react': specifier: ~18.3.1 version: 18.3.31 - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis react: specifier: ^18.2.0 version: 18.3.1 @@ -2338,6 +2338,9 @@ importers: specifier: ^4.3.1 version: 4.3.1 devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants @@ -2347,9 +2350,6 @@ importers: '@types/react-dom': specifier: ~18.3.0 version: 18.3.7(@types/react@18.3.31) - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/client/ui-question: dependencies: @@ -2375,6 +2375,9 @@ importers: specifier: ^18.2.0 version: 18.3.1 devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-agent': specifier: workspace:^ version: link:../../core/agent @@ -2396,9 +2399,6 @@ importers: '@types/react': specifier: ~18.3.1 version: 18.3.31 - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/client/ui-settings: dependencies: @@ -2406,6 +2406,9 @@ importers: specifier: ^2.0.0 version: 2.1.1 devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-client-locale': specifier: workspace:^ version: link:../locale @@ -2430,9 +2433,6 @@ importers: '@types/react-dom': specifier: ~18.3.0 version: 18.3.7(@types/react@18.3.31) - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis react: specifier: ^18.2.0 version: 18.3.1 @@ -2445,10 +2445,13 @@ importers: '@deepseek-ai/dsh-settings': specifier: workspace:^ version: link:../../settings/settings - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-client-connection': specifier: workspace:^ version: link:../connection @@ -2479,9 +2482,6 @@ importers: '@types/react': specifier: ~18.3.1 version: 18.3.31 - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis react: specifier: ^18.2.0 version: 18.3.1 @@ -2492,6 +2492,9 @@ importers: specifier: ^2.0.0 version: 2.1.1 devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-client-locale': specifier: workspace:^ version: link:../locale @@ -2516,15 +2519,15 @@ importers: '@types/react': specifier: ~18.3.1 version: 18.3.31 - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis react: specifier: ^18.2.0 version: 18.3.1 packages/client/ui-skill: devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-client-connection': specifier: workspace:^ version: link:../connection @@ -2558,9 +2561,6 @@ importers: '@types/react': specifier: ~18.3.1 version: 18.3.31 - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis react: specifier: ^18.2.0 version: 18.3.1 @@ -2574,6 +2574,9 @@ importers: specifier: ^2.0.0 version: 2.1.1 devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-client-locale': specifier: workspace:^ version: link:../locale @@ -2595,24 +2598,21 @@ importers: '@types/react': specifier: ~18.3.1 version: 18.3.31 - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis react: specifier: ^18.2.0 version: 18.3.1 packages/client/ui-slots: devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants '@types/react': specifier: ~18.3.1 version: 18.3.31 - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/client/ui-subagent: dependencies: @@ -2620,6 +2620,9 @@ importers: specifier: ^18.2.0 version: 18.3.1 devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-client-locale': specifier: workspace:^ version: link:../locale @@ -2653,9 +2656,6 @@ importers: '@types/react': specifier: ~18.3.1 version: 18.3.31 - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/client/ui-theme: dependencies: @@ -2665,13 +2665,16 @@ importers: '@deepseek-ai/dsh-settings': specifier: workspace:^ version: link:../../settings/settings + '@deepseek-ai/schemastery': + specifier: ^3.18.0 + version: link:../../../vendor/schemastery clsx: specifier: ^2.0.0 version: 2.1.1 - schemastery: - specifier: ^3.18.0 - version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-client-locale': specifier: workspace:^ version: link:../locale @@ -2693,9 +2696,6 @@ importers: '@types/react': specifier: ~18.3.1 version: 18.3.31 - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis react: specifier: ^18.2.0 version: 18.3.1 @@ -2706,6 +2706,9 @@ importers: specifier: ^2.0.0 version: 2.1.1 devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-client-connection': specifier: workspace:^ version: link:../connection @@ -2739,9 +2742,6 @@ importers: '@types/react': specifier: ~18.3.1 version: 18.3.31 - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis react: specifier: ^18.2.0 version: 18.3.1 @@ -2758,6 +2758,9 @@ importers: specifier: ^9.0.0 version: 9.0.0 devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-client-runtime': specifier: workspace:^ version: link:../runtime @@ -2779,9 +2782,6 @@ importers: '@types/react-dom': specifier: ~18.3.0 version: 18.3.7(@types/react@18.3.31) - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis react: specifier: ^18.2.0 version: 18.3.1 @@ -2795,6 +2795,9 @@ importers: specifier: ^2.0.0 version: 2.1.1 devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-client-locale': specifier: workspace:^ version: link:../locale @@ -2822,9 +2825,6 @@ importers: '@types/react': specifier: ~18.3.1 version: 18.3.31 - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis react: specifier: ^18.2.0 version: 18.3.1 @@ -2856,7 +2856,10 @@ importers: specifier: ^18.2.0 version: 18.3.1(react@18.3.1) devDependencies: - '@cordisjs/plugin-loader': + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis + '@deepseek-ai/cordis-plugin-loader': specifier: workspace:^ version: link:../../../vendor/loader '@deepseek-ai/dsh-client-runtime': @@ -2874,9 +2877,6 @@ importers: '@types/react-dom': specifier: ~18.3.0 version: 18.3.7(@types/react@18.3.31) - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis typescript: specifier: ^6.0.3 version: 6.0.3 @@ -2893,31 +2893,34 @@ importers: specifier: 1.2.0 version: 1.2.0(react@18.3.1) devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants '@types/react': specifier: ~18.3.1 version: 18.3.31 - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/code-runtime/code-runtime: devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/code-runtime/code-runtime-worker: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-code-runtime': specifier: workspace:^ version: link:../code-runtime @@ -2930,16 +2933,16 @@ importers: '@deepseek-ai/dsh-timeout': specifier: workspace:^ version: link:../../util/timeout - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/compact/command-compact: devDependencies: - '@cordisjs/plugin-include': + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis + '@deepseek-ai/cordis-plugin-include': specifier: workspace:^ version: link:../../../vendor/include - '@cordisjs/plugin-loader': + '@deepseek-ai/cordis-plugin-loader': specifier: workspace:^ version: link:../../../vendor/loader '@deepseek-ai/dsh-agent': @@ -2960,12 +2963,12 @@ importers: '@deepseek-ai/dsh-session': specifier: workspace:^ version: link:../../core/session - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/compact/compact: devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-brand': specifier: workspace:^ version: link:../../util/brand @@ -2981,20 +2984,20 @@ importers: '@deepseek-ai/dsh-session': specifier: workspace:^ version: link:../../core/session - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/compact/compact-basic: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: - '@cordisjs/plugin-include': + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis + '@deepseek-ai/cordis-plugin-include': specifier: workspace:^ version: link:../../../vendor/include - '@cordisjs/plugin-loader': + '@deepseek-ai/cordis-plugin-loader': specifier: workspace:^ version: link:../../../vendor/loader '@deepseek-ai/dsh-agent': @@ -3033,20 +3036,20 @@ importers: '@deepseek-ai/dsh-tools': specifier: workspace:^ version: link:../../core/tools - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/compact/compact-tool-result-prune: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: - '@cordisjs/plugin-include': + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis + '@deepseek-ai/cordis-plugin-include': specifier: workspace:^ version: link:../../../vendor/include - '@cordisjs/plugin-loader': + '@deepseek-ai/cordis-plugin-loader': specifier: workspace:^ version: link:../../../vendor/loader '@deepseek-ai/dsh-compact': @@ -3064,16 +3067,16 @@ importers: '@deepseek-ai/dsh-token-meter': specifier: workspace:^ version: link:../../llm/token-meter - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/context/session-reference: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-agent': specifier: workspace:^ version: link:../../core/agent @@ -3095,16 +3098,16 @@ importers: '@deepseek-ai/dsh-session-query': specifier: workspace:^ version: link:../../session-query/session-query - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/context/time-context: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-agent': specifier: workspace:^ version: link:../../core/agent @@ -3132,16 +3135,16 @@ importers: '@deepseek-ai/dsh-tools': specifier: workspace:^ version: link:../../core/tools - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/context/tmux-context: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-agent': specifier: workspace:^ version: link:../../core/agent @@ -3160,17 +3163,17 @@ importers: '@deepseek-ai/dsh-system-prompt': specifier: workspace:^ version: link:../../core/system-prompt - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/context/workspace-context: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: - '@cordisjs/plugin-loader': + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.6 + version: link:../../../vendor/cordis + '@deepseek-ai/cordis-plugin-loader': specifier: workspace:^ version: link:../../../vendor/loader '@deepseek-ai/dsh-agent': @@ -3209,12 +3212,12 @@ importers: '@deepseek-ai/dsh-tools': specifier: workspace:^ version: link:../../core/tools - cordis: - specifier: ^4.0.0-rc.6 - version: link:../../../vendor/cordis packages/core/agent: devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants @@ -3236,16 +3239,16 @@ importers: '@deepseek-ai/dsh-typert-registry': specifier: workspace:^ version: link:../../typert/registry - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/core/agent-default-model: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-agent': specifier: workspace:^ version: link:../agent @@ -3258,16 +3261,16 @@ importers: '@deepseek-ai/dsh-settings': specifier: workspace:^ version: link:../../settings/settings - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/core/agent-loop: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-agent': specifier: workspace:^ version: link:../agent @@ -3295,16 +3298,16 @@ importers: '@deepseek-ai/dsh-tools': specifier: workspace:^ version: link:../tools - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/core/agent-tool-mode: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-agent': specifier: workspace:^ version: link:../agent @@ -3326,21 +3329,21 @@ importers: '@deepseek-ai/dsh-tools': specifier: workspace:^ version: link:../tools - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/core/scope: devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/core/session: devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-brand': specifier: workspace:^ version: link:../../util/brand @@ -3359,16 +3362,16 @@ importers: '@deepseek-ai/dsh-typert-registry': specifier: workspace:^ version: link:../../typert/registry - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/core/system-prompt: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants @@ -3378,16 +3381,16 @@ importers: '@deepseek-ai/dsh-scope': specifier: workspace:^ version: link:../scope - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/core/tools: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-agent': specifier: workspace:^ version: link:../agent @@ -3412,34 +3415,34 @@ importers: '@deepseek-ai/dsh-user-approval': specifier: workspace:^ version: link:../../interaction/user-approval - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/credentials/credentials: devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-brand': specifier: workspace:^ version: link:../../util/brand '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/credentials/credentials-local: dependencies: + '@deepseek-ai/schemastery': + specifier: ^3.18.0 + version: link:../../../vendor/schemastery chokidar: specifier: ^4.0.3 version: 4.0.3 - schemastery: - specifier: ^3.18.0 - version: link:../../../vendor/schemastery yaml: specifier: ^2.9.0 version: 2.9.0 devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-atomic-write': specifier: workspace:^ version: link:../../util/atomic-write @@ -3455,19 +3458,19 @@ importers: '@deepseek-ai/dsh-paths': specifier: workspace:^ version: link:../../util/paths - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/e2b/e2b: dependencies: + '@deepseek-ai/schemastery': + specifier: ^3.18.0 + version: link:../../../vendor/schemastery e2b: specifier: 2.29.1 version: 2.29.1 - schemastery: - specifier: ^3.18.0 - version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants @@ -3477,12 +3480,12 @@ importers: '@deepseek-ai/dsh-sandbox-policy': specifier: workspace:^ version: link:../../sandbox/sandbox-policy - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/e2b/fs-e2b: devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-e2b': specifier: workspace:^ version: link:../e2b @@ -3492,16 +3495,16 @@ importers: '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/e2b/subprocess-e2b: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-e2b': specifier: workspace:^ version: link:../e2b @@ -3514,16 +3517,16 @@ importers: '@deepseek-ai/dsh-timeout': specifier: workspace:^ version: link:../../util/timeout - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/examples/acp-demo: devDependencies: - '@cordisjs/plugin-include': + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis + '@deepseek-ai/cordis-plugin-include': specifier: workspace:^ version: link:../../../vendor/include - '@cordisjs/plugin-loader': + '@deepseek-ai/cordis-plugin-loader': specifier: workspace:^ version: link:../../../vendor/loader '@deepseek-ai/dsh-acp': @@ -3562,20 +3565,20 @@ importers: '@deepseek-ai/dsh-workspace-context': specifier: workspace:^ version: link:../../context/workspace-context - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.17.0 version: link:../../../vendor/schemastery packages/examples/agent-spine-demo: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: - '@cordisjs/plugin-timer': + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis + '@deepseek-ai/cordis-plugin-timer': specifier: workspace:^ version: link:../../../vendor/timer '@deepseek-ai/dsh-agent': @@ -3677,9 +3680,6 @@ importers: '@deepseek-ai/node-addon-landlock-run': specifier: workspace:* version: link:../../../native/landlock-run/packages/entry - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/examples/jsonrpc-demo: dependencies: @@ -3687,19 +3687,22 @@ importers: specifier: workspace:^ version: link:../../boot/app-boot devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/feedback/command-feedback: devDependencies: - '@cordisjs/plugin-include': + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis + '@deepseek-ai/cordis-plugin-include': specifier: workspace:^ version: link:../../../vendor/include - '@cordisjs/plugin-loader': + '@deepseek-ai/cordis-plugin-loader': specifier: workspace:^ version: link:../../../vendor/loader '@deepseek-ai/dsh-agent': @@ -3720,12 +3723,12 @@ importers: '@deepseek-ai/dsh-user-id': specifier: workspace:^ version: link:../../session/user-id - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/fs/fs: devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-brand': specifier: workspace:^ version: link:../../util/brand @@ -3738,19 +3741,19 @@ importers: '@deepseek-ai/dsh-sandbox': specifier: workspace:^ version: link:../../sandbox/sandbox - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/fs/fs-local: dependencies: + '@deepseek-ai/schemastery': + specifier: ^3.18.0 + version: link:../../../vendor/schemastery koffi: specifier: ^3.1.0 version: 3.1.1 - schemastery: - specifier: ^3.18.0 - version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-fs': specifier: workspace:^ version: link:../fs @@ -3760,12 +3763,12 @@ importers: '@deepseek-ai/dsh-llm': specifier: workspace:^ version: link:../../llm/llm - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/fs/fs-policy: devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-fs': specifier: workspace:^ version: link:../fs @@ -3775,12 +3778,12 @@ importers: '@deepseek-ai/dsh-llm': specifier: workspace:^ version: link:../../llm/llm - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/fs/fs-sandbox: devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-fs': specifier: workspace:^ version: link:../fs @@ -3796,19 +3799,19 @@ importers: '@deepseek-ai/dsh-sandbox-policy': specifier: workspace:^ version: link:../../sandbox/sandbox-policy - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/fs/tool-fs: dependencies: + '@deepseek-ai/schemastery': + specifier: ^3.18.0 + version: link:../../../vendor/schemastery diff: specifier: ^9.0.0 version: 9.0.0 - schemastery: - specifier: ^3.18.0 - version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-agent': specifier: workspace:^ version: link:../../core/agent @@ -3854,19 +3857,19 @@ importers: '@deepseek-ai/dsh-user-approval': specifier: workspace:^ version: link:../../interaction/user-approval - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/fs/tool-fs-search: dependencies: + '@deepseek-ai/schemastery': + specifier: ^3.18.0 + version: link:../../../vendor/schemastery '@vscode/ripgrep': specifier: ^1.18.0 version: 1.18.0 - schemastery: - specifier: ^3.18.0 - version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.6 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-agent': specifier: workspace:^ version: link:../../core/agent @@ -3900,16 +3903,16 @@ importers: '@deepseek-ai/dsh-tools': specifier: workspace:^ version: link:../../core/tools - cordis: - specifier: ^4.0.0-rc.6 - version: link:../../../vendor/cordis packages/fs/tool-str-replace-editor: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-agent': specifier: workspace:^ version: link:../../core/agent @@ -3946,13 +3949,13 @@ importers: '@deepseek-ai/dsh-tools': specifier: workspace:^ version: link:../../core/tools - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/goal/command-goal: devDependencies: - '@cordisjs/plugin-loader': + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis + '@deepseek-ai/cordis-plugin-loader': specifier: workspace:^ version: link:../../../vendor/loader '@deepseek-ai/dsh-agent': @@ -3973,19 +3976,19 @@ importers: '@deepseek-ai/dsh-session': specifier: workspace:^ version: link:../../core/session - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/goal/goal: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.17.2 version: link:../../../vendor/schemastery zod: specifier: ^4.4.3 version: 4.4.3 devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-agent': specifier: workspace:^ version: link:../../core/agent @@ -4013,12 +4016,12 @@ importers: '@deepseek-ai/dsh-type-meta': specifier: workspace:^ version: link:../../typert/type-meta - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/goal/goal-session: devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-agent': specifier: workspace:^ version: link:../../core/agent @@ -4046,17 +4049,17 @@ importers: '@deepseek-ai/dsh-tools': specifier: workspace:^ version: link:../../core/tools - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/goal/tool-goal: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: - '@cordisjs/plugin-loader': + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis + '@deepseek-ai/cordis-plugin-loader': specifier: workspace:^ version: link:../../../vendor/loader '@deepseek-ai/dsh-agent': @@ -4080,16 +4083,16 @@ importers: '@deepseek-ai/dsh-tools': specifier: workspace:^ version: link:../../core/tools - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/guard/repeat-tool-guard: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-agent': specifier: workspace:^ version: link:../../core/agent @@ -4111,12 +4114,12 @@ importers: '@deepseek-ai/dsh-tools': specifier: workspace:^ version: link:../../core/tools - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/guard/timeout-policy: devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants @@ -4129,12 +4132,12 @@ importers: '@deepseek-ai/dsh-tools': specifier: workspace:^ version: link:../../core/tools - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/hooks/hook-protocol: devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-bash': specifier: workspace:^ version: link:../../bash/bash @@ -4144,16 +4147,16 @@ importers: '@deepseek-ai/dsh-session': specifier: workspace:^ version: link:../../core/session - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/hooks/hooks-claude: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-agent': specifier: workspace:^ version: link:../../core/agent @@ -4196,16 +4199,16 @@ importers: '@deepseek-ai/dsh-tools': specifier: workspace:^ version: link:../../core/tools - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/hooks/hooks-codex: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-agent': specifier: workspace:^ version: link:../../core/agent @@ -4245,9 +4248,6 @@ importers: '@deepseek-ai/dsh-tools': specifier: workspace:^ version: link:../../core/tools - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/host/apiproxy: dependencies: @@ -4323,13 +4323,16 @@ importers: '@deepseek-ai/dsh-workspace': specifier: workspace:^ version: link:../../workspace/workspace - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery zod: specifier: ^4.4.3 version: 4.4.3 devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-agent-presets': specifier: workspace:^ version: link:../../preset/agent-presets @@ -4348,25 +4351,25 @@ importers: '@deepseek-ai/dsh-typert-registry': specifier: workspace:^ version: link:../../typert/registry - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/host/directory-picker: devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/host/directory-picker-auto: devDependencies: - '@cordisjs/plugin-include': + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis + '@deepseek-ai/cordis-plugin-include': specifier: workspace:^ version: link:../../../vendor/include - '@cordisjs/plugin-loader': + '@deepseek-ai/cordis-plugin-loader': specifier: workspace:^ version: link:../../../vendor/loader '@deepseek-ai/dsh-host-directory-picker': @@ -4384,22 +4387,22 @@ importers: '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/host/directory-picker-browse: dependencies: '@deepseek-ai/dsh-host-directory-picker': specifier: workspace:^ version: link:../directory-picker + '@deepseek-ai/schemastery': + specifier: ^3.18.0 + version: link:../../../vendor/schemastery clsx: specifier: ^2.0.0 version: 2.1.1 - schemastery: - specifier: ^3.18.0 - version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-client-locale': specifier: workspace:^ version: link:../../client/locale @@ -4424,9 +4427,6 @@ importers: '@types/react': specifier: ~18.3.1 version: 18.3.31 - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis react: specifier: ^18.2.0 version: 18.3.1 @@ -4443,6 +4443,9 @@ importers: specifier: ^3.1.0 version: 3.1.1 devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-client-runtime': specifier: workspace:^ version: link:../../client/runtime @@ -4458,9 +4461,6 @@ importers: '@types/react': specifier: ~18.3.1 version: 18.3.31 - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis react: specifier: ^18.2.0 version: 18.3.1 @@ -4470,11 +4470,14 @@ importers: packages/host/frontend-static: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: - '@cordisjs/plugin-loader': + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis + '@deepseek-ai/cordis-plugin-loader': specifier: workspace:^ version: link:../../../vendor/loader '@deepseek-ai/dsh-host-webserver': @@ -4483,25 +4486,25 @@ importers: '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/host/webserver: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/interaction/commands: devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-agent': specifier: workspace:^ version: link:../../core/agent @@ -4517,19 +4520,19 @@ importers: '@deepseek-ai/dsh-session': specifier: workspace:^ version: link:../../core/session - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/interaction/permission: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery zod: specifier: ^4.4.3 version: 4.4.3 devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-bash': specifier: workspace:^ version: link:../../bash/bash @@ -4557,12 +4560,12 @@ importers: '@deepseek-ai/dsh-user-approval': specifier: workspace:^ version: link:../user-approval - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/interaction/tool-ask-user: devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-agent': specifier: workspace:^ version: link:../../core/agent @@ -4581,16 +4584,16 @@ importers: '@deepseek-ai/dsh-user-interaction': specifier: workspace:^ version: link:../user-interaction - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/interaction/user-approval: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-agent': specifier: workspace:^ version: link:../../core/agent @@ -4612,12 +4615,12 @@ importers: '@deepseek-ai/dsh-system-prompt': specifier: workspace:^ version: link:../../core/system-prompt - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/interaction/user-interaction: devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-agent': specifier: workspace:^ version: link:../../core/agent @@ -4627,16 +4630,16 @@ importers: '@deepseek-ai/dsh-llm': specifier: workspace:^ version: link:../../llm/llm - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/llm/llm: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-attachment': specifier: workspace:^ version: link:../../attachment/attachment @@ -4649,19 +4652,19 @@ importers: '@deepseek-ai/dsh-timeout': specifier: workspace:^ version: link:../../util/timeout - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/llm/llm-deepseek: dependencies: + '@deepseek-ai/schemastery': + specifier: ^3.18.0 + version: link:../../../vendor/schemastery eventsource-parser: specifier: ^3.1.0 version: 3.1.0 - schemastery: - specifier: ^3.18.0 - version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-credentials': specifier: workspace:^ version: link:../../credentials/credentials @@ -4680,19 +4683,19 @@ importers: '@deepseek-ai/dsh-timeout': specifier: workspace:^ version: link:../../util/timeout - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/llm/llm-pi-ai: dependencies: + '@deepseek-ai/schemastery': + specifier: ^3.18.0 + version: link:../../../vendor/schemastery '@earendil-works/pi-ai': specifier: ^0.82.1 version: 0.82.1(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))(ws@8.21.0)(zod@4.4.3) - schemastery: - specifier: ^3.18.0 - version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-attachment': specifier: workspace:^ version: link:../../attachment/attachment @@ -4717,20 +4720,20 @@ importers: '@deepseek-ai/dsh-timeout': specifier: workspace:^ version: link:../../util/timeout - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/llm/llm-retry: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: - '@cordisjs/plugin-include': + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis + '@deepseek-ai/cordis-plugin-include': specifier: workspace:^ version: link:../../../vendor/include - '@cordisjs/plugin-loader': + '@deepseek-ai/cordis-plugin-loader': specifier: workspace:^ version: link:../../../vendor/loader '@deepseek-ai/dsh-agent': @@ -4775,19 +4778,19 @@ importers: '@deepseek-ai/dsh-tools': specifier: workspace:^ version: link:../../core/tools - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/llm/token-meter: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery zod: specifier: ^4.4.3 version: 4.4.3 devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-compact': specifier: workspace:^ version: link:../../compact/compact @@ -4803,12 +4806,12 @@ importers: '@deepseek-ai/dsh-session-projection': specifier: workspace:^ version: link:../../session/session-projection - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/lsp/lsp: devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-brand': specifier: workspace:^ version: link:../../util/brand @@ -4818,16 +4821,16 @@ importers: '@deepseek-ai/dsh-llm': specifier: workspace:^ version: link:../../llm/llm - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/lsp/lsp-local: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-brand': specifier: workspace:^ version: link:../../util/brand @@ -4855,9 +4858,6 @@ importers: '@deepseek-ai/dsh-timeout': specifier: workspace:^ version: link:../../util/timeout - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis typescript: specifier: ^6.0.3 version: 6.0.3 @@ -4867,10 +4867,13 @@ importers: packages/lsp/tool-lsp: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-agent': specifier: workspace:^ version: link:../../core/agent @@ -4907,22 +4910,22 @@ importers: '@deepseek-ai/dsh-tools': specifier: workspace:^ version: link:../../core/tools - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/mcp/mcp-client: dependencies: + '@deepseek-ai/schemastery': + specifier: ^3.18.0 + version: link:../../../vendor/schemastery '@modelcontextprotocol/sdk': specifier: ^1.12.0 version: 1.29.0(zod@4.4.3) - schemastery: - specifier: ^3.18.0 - version: link:../../../vendor/schemastery zod: specifier: ^4.4.3 version: 4.4.3 devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants @@ -4941,9 +4944,6 @@ importers: '@modelcontextprotocol/server-filesystem': specifier: ^2026.7.4 version: 2026.7.10(zod@4.4.3) - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/plan/plan-mode: dependencies: @@ -4951,6 +4951,9 @@ importers: specifier: ^4.4.3 version: 4.4.3 devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-agent': specifier: workspace:^ version: link:../../core/agent @@ -4984,23 +4987,23 @@ importers: '@deepseek-ai/dsh-user-interaction': specifier: workspace:^ version: link:../../interaction/user-interaction - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/preset/agent-presets: dependencies: + '@deepseek-ai/schemastery': + specifier: ^3.18.0 + version: link:../../../vendor/schemastery js-yaml: specifier: ^4.1.0 version: 4.2.0 - schemastery: - specifier: ^3.18.0 - version: link:../../../vendor/schemastery devDependencies: - '@cordisjs/plugin-include': + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis + '@deepseek-ai/cordis-plugin-include': specifier: workspace:^ version: link:../../../vendor/include - '@cordisjs/plugin-loader': + '@deepseek-ai/cordis-plugin-loader': specifier: workspace:^ version: link:../../../vendor/loader '@deepseek-ai/dsh-agent': @@ -5039,16 +5042,16 @@ importers: '@deepseek-ai/dsh-tools': specifier: workspace:^ version: link:../../core/tools - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/preset/persona: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants @@ -5058,12 +5061,12 @@ importers: '@deepseek-ai/dsh-system-prompt': specifier: workspace:^ version: link:../../core/system-prompt - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/pty/pty: devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-agent': specifier: workspace:^ version: link:../../core/agent @@ -5076,16 +5079,16 @@ importers: '@deepseek-ai/dsh-session': specifier: workspace:^ version: link:../../core/session - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/pty/pty-local: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-agent': specifier: workspace:^ version: link:../../core/agent @@ -5110,20 +5113,20 @@ importers: '@deepseek-ai/dsh-subprocess-local': specifier: workspace:^ version: link:../../subprocess/subprocess-local - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/pty/tool-bash-persistent: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: - '@cordisjs/plugin-include': + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis + '@deepseek-ai/cordis-plugin-include': specifier: workspace:^ version: link:../../../vendor/include - '@cordisjs/plugin-loader': + '@deepseek-ai/cordis-plugin-loader': specifier: workspace:^ version: link:../../../vendor/loader '@deepseek-ai/dsh-agent': @@ -5162,20 +5165,20 @@ importers: '@deepseek-ai/dsh-tools': specifier: workspace:^ version: link:../../core/tools - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/pty/tool-pty: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: - '@cordisjs/plugin-include': + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis + '@deepseek-ai/cordis-plugin-include': specifier: workspace:^ version: link:../../../vendor/include - '@cordisjs/plugin-loader': + '@deepseek-ai/cordis-plugin-loader': specifier: workspace:^ version: link:../../../vendor/loader '@deepseek-ai/dsh-agent': @@ -5223,12 +5226,12 @@ importers: '@deepseek-ai/dsh-tools': specifier: workspace:^ version: link:../../core/tools - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/sandbox/sandbox: devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants @@ -5238,9 +5241,6 @@ importers: '@deepseek-ai/dsh-session': specifier: workspace:^ version: link:../../core/session - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/sandbox/sandbox-local: dependencies: @@ -5250,10 +5250,13 @@ importers: '@deepseek-ai/node-addon-landlock-run': specifier: workspace:* version: link:../../../native/landlock-run/packages/entry - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants @@ -5266,16 +5269,16 @@ importers: '@deepseek-ai/dsh-session': specifier: workspace:^ version: link:../../core/session - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/sandbox/sandbox-policy: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-agent': specifier: workspace:^ version: link:../../core/agent @@ -5291,9 +5294,6 @@ importers: '@deepseek-ai/dsh-system-prompt': specifier: workspace:^ version: link:../../core/system-prompt - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/sandbox/sandbox-windows-acl: dependencies: @@ -5301,6 +5301,9 @@ importers: specifier: ^3.1.0 version: 3.1.1 devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants @@ -5310,12 +5313,12 @@ importers: '@deepseek-ai/dsh-sandbox-local': specifier: workspace:^ version: link:../sandbox-local - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/scaffold/client: devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants @@ -5328,9 +5331,6 @@ importers: '@deepseek-ai/dsh-session': specifier: workspace:^ version: link:../../core/session - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/scaffold/create-sdk: dependencies: @@ -5341,12 +5341,12 @@ importers: specifier: ^15.0.0 version: 15.0.0 devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/scaffold/helper: dependencies: @@ -5366,6 +5366,9 @@ importers: specifier: ^2.9.0 version: 2.9.0 devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-brand': specifier: workspace:^ version: link:../../util/brand @@ -5396,12 +5399,12 @@ importers: '@deepseek-ai/dsh-tool-web': specifier: workspace:^ version: link:../../web/tool-web - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/scaffold/protocol: devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants @@ -5414,9 +5417,6 @@ importers: '@deepseek-ai/dsh-subagent': specifier: workspace:^ version: link:../../subagent/subagent - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/scaffold/scripts: dependencies: @@ -5433,15 +5433,15 @@ importers: specifier: ^0.1.4 version: 0.1.4 devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-app-boot': specifier: workspace:^ version: link:../../boot/app-boot '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis tsdown: specifier: ^0.22.2 version: 0.22.2(oxc-resolver@11.20.0)(publint@0.3.21)(tsx@4.22.4)(typescript@6.0.3) @@ -5451,11 +5451,14 @@ importers: packages/scaffold/server: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.17.0 version: link:../../../vendor/schemastery devDependencies: - '@cordisjs/plugin-loader': + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis + '@deepseek-ai/cordis-plugin-loader': specifier: workspace:^ version: link:../../../vendor/loader '@deepseek-ai/dsh-agent': @@ -5488,9 +5491,6 @@ importers: '@deepseek-ai/dsh-subagent': specifier: workspace:^ version: link:../../subagent/subagent - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/scaffold/telemetry: dependencies: @@ -5498,6 +5498,9 @@ importers: specifier: ^2.9.0 version: 2.9.0 devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-brand': specifier: workspace:^ version: link:../../util/brand @@ -5507,20 +5510,20 @@ importers: '@deepseek-ai/dsh-paths': specifier: workspace:^ version: link:../../util/paths - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/self-modification/tool-cordis: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: - '@cordisjs/plugin-loader': + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis + '@deepseek-ai/cordis-plugin-loader': specifier: ^1.0.0-rc.5 version: link:../../../vendor/loader - '@cordisjs/plugin-timer': + '@deepseek-ai/cordis-plugin-timer': specifier: workspace:^ version: link:../../../vendor/timer '@deepseek-ai/dsh-agent': @@ -5550,12 +5553,12 @@ importers: '@deepseek-ai/dsh-tools': specifier: workspace:^ version: link:../../core/tools - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/session-query/session-query: devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-brand': specifier: workspace:^ version: link:../../util/brand @@ -5574,17 +5577,17 @@ importers: '@deepseek-ai/dsh-session-title': specifier: workspace:^ version: link:../../session/session-title - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/session-query/session-query-sqlite: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: - '@cordisjs/plugin-loader': + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis + '@deepseek-ai/cordis-plugin-loader': specifier: workspace:^ version: link:../../../vendor/loader '@deepseek-ai/dsh-invariants': @@ -5602,16 +5605,16 @@ importers: '@deepseek-ai/dsh-session-query': specifier: workspace:^ version: link:../session-query - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/session-query/tool-session-query: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-agent': specifier: workspace:^ version: link:../../core/agent @@ -5651,13 +5654,13 @@ importers: '@deepseek-ai/dsh-tools': specifier: workspace:^ version: link:../../core/tools - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/session/session-checkpoint-policy: devDependencies: - '@cordisjs/plugin-loader': + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis + '@deepseek-ai/cordis-plugin-loader': specifier: workspace:^ version: link:../../../vendor/loader '@deepseek-ai/dsh-agent': @@ -5690,12 +5693,12 @@ importers: '@deepseek-ai/dsh-tools': specifier: workspace:^ version: link:../../core/tools - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/session/session-persistence: devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-brand': specifier: workspace:^ version: link:../../util/brand @@ -5711,19 +5714,19 @@ importers: '@deepseek-ai/dsh-timeout': specifier: workspace:^ version: link:../../util/timeout - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/session/session-persistence-jsonl: dependencies: + '@deepseek-ai/schemastery': + specifier: ^3.18.0 + version: link:../../../vendor/schemastery koffi: specifier: ^3.1.0 version: 3.1.1 - schemastery: - specifier: ^3.18.0 - version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants @@ -5733,16 +5736,16 @@ importers: '@deepseek-ai/dsh-session-persistence': specifier: workspace:^ version: link:../session-persistence - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/session/session-persistence-sqlite: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants @@ -5752,9 +5755,6 @@ importers: '@deepseek-ai/dsh-session-persistence': specifier: workspace:^ version: link:../session-persistence - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/session/session-projection: dependencies: @@ -5762,25 +5762,28 @@ importers: specifier: ^4.4.3 version: 4.4.3 devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants '@deepseek-ai/dsh-session': specifier: workspace:^ version: link:../../core/session - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/session/session-projection-cache: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery zod: specifier: ^4.4.3 version: 4.4.3 devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants @@ -5799,12 +5802,12 @@ importers: '@deepseek-ai/dsh-storage-domain': specifier: workspace:^ version: link:../../storage/storage-domain - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/session/session-telemetry: devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-agent': specifier: workspace:^ version: link:../../core/agent @@ -5814,12 +5817,12 @@ importers: '@deepseek-ai/dsh-session': specifier: workspace:^ version: link:../../core/session - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/session/session-telemetry-otel: dependencies: + '@deepseek-ai/schemastery': + specifier: ^3.18.0 + version: link:../../../vendor/schemastery '@opentelemetry/api': specifier: ^1.9.1 version: 1.9.1 @@ -5838,11 +5841,11 @@ importers: '@opentelemetry/sdk-logs': specifier: ^0.220.0 version: 0.220.0(@opentelemetry/api@1.9.1) - schemastery: - specifier: ^3.18.0 - version: link:../../../vendor/schemastery devDependencies: - '@cordisjs/plugin-loader': + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis + '@deepseek-ai/cordis-plugin-loader': specifier: workspace:^ version: link:../../../vendor/loader '@deepseek-ai/dsh-command-feedback': @@ -5863,19 +5866,19 @@ importers: '@deepseek-ai/dsh-user-id': specifier: workspace:^ version: link:../user-id - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/session/session-title: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery zod: specifier: ^4.4.3 version: 4.4.3 devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-brand': specifier: workspace:^ version: link:../../util/brand @@ -5897,16 +5900,16 @@ importers: '@deepseek-ai/dsh-session-projection': specifier: workspace:^ version: link:../session-projection - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/session/session-title-all-messages-llm: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants @@ -5922,20 +5925,20 @@ importers: '@deepseek-ai/dsh-session-title-llm': specifier: workspace:^ version: link:../session-title-llm - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/session/session-title-first-message-llm: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: - '@cordisjs/plugin-include': + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis + '@deepseek-ai/cordis-plugin-include': specifier: workspace:^ version: link:../../../vendor/include - '@cordisjs/plugin-loader': + '@deepseek-ai/cordis-plugin-loader': specifier: workspace:^ version: link:../../../vendor/loader '@deepseek-ai/dsh-invariants': @@ -5956,16 +5959,16 @@ importers: '@deepseek-ai/dsh-session-title-llm': specifier: workspace:^ version: link:../session-title-llm - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/session/session-title-llm: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants @@ -5981,12 +5984,12 @@ importers: '@deepseek-ai/dsh-timeout': specifier: workspace:^ version: link:../../util/timeout - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/session/user-id: devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-brand': specifier: workspace:^ version: link:../../util/brand @@ -5996,37 +5999,37 @@ importers: '@deepseek-ai/dsh-paths': specifier: workspace:^ version: link:../../util/paths - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/settings/settings: devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-brand': specifier: workspace:^ version: link:../../util/brand '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery packages/settings/settings-local: dependencies: + '@deepseek-ai/schemastery': + specifier: ^3.18.0 + version: link:../../../vendor/schemastery chokidar: specifier: ^4.0.3 version: 4.0.3 - schemastery: - specifier: ^3.18.0 - version: link:../../../vendor/schemastery yaml: specifier: ^2.9.0 version: 2.9.0 devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-atomic-write': specifier: workspace:^ version: link:../../util/atomic-write @@ -6039,16 +6042,16 @@ importers: '@deepseek-ai/dsh-settings': specifier: workspace:^ version: link:../settings - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/skill/skill: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants @@ -6058,34 +6061,34 @@ importers: '@deepseek-ai/dsh-scope': specifier: workspace:^ version: link:../../core/scope - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/skill/skill-badge: devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants '@deepseek-ai/dsh-skill': specifier: workspace:^ version: link:../skill - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/skill/skill-local: dependencies: + '@deepseek-ai/schemastery': + specifier: ^3.18.0 + version: link:../../../vendor/schemastery chokidar: specifier: ^5.0.0 version: 5.0.0 - schemastery: - specifier: ^3.18.0 - version: link:../../../vendor/schemastery yaml: specifier: ^2.4.2 version: 2.9.0 devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-fs': specifier: workspace:^ version: link:../../fs/fs @@ -6098,16 +6101,16 @@ importers: '@deepseek-ai/dsh-skill': specifier: workspace:^ version: link:../skill - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/skill/tool-skill: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-agent': specifier: workspace:^ version: link:../../core/agent @@ -6132,12 +6135,12 @@ importers: '@deepseek-ai/dsh-tools': specifier: workspace:^ version: link:../../core/tools - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/spill/spill: devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.6 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-brand': specifier: workspace:^ version: link:../../util/brand @@ -6150,16 +6153,16 @@ importers: '@deepseek-ai/dsh-session': specifier: workspace:^ version: link:../../core/session - cordis: - specifier: ^4.0.0-rc.6 - version: link:../../../vendor/cordis packages/spill/spill-local: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.6 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-brand': specifier: workspace:^ version: link:../../util/brand @@ -6175,16 +6178,16 @@ importers: '@deepseek-ai/dsh-spill': specifier: workspace:^ version: link:../spill - cordis: - specifier: ^4.0.0-rc.6 - version: link:../../../vendor/cordis packages/spill/spill-policy: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.6 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-agent': specifier: workspace:^ version: link:../../core/agent @@ -6209,69 +6212,66 @@ importers: '@deepseek-ai/dsh-tools': specifier: workspace:^ version: link:../../core/tools - cordis: - specifier: ^4.0.0-rc.6 - version: link:../../../vendor/cordis packages/storage/storage: devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/storage/storage-domain: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery zod: specifier: ^4.4.3 version: 4.4.3 devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants '@deepseek-ai/dsh-storage': specifier: workspace:^ version: link:../storage - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/storage/storage-json: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants '@deepseek-ai/dsh-storage': specifier: workspace:^ version: link:../storage - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/storage/storage-sqlite: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants '@deepseek-ai/dsh-storage': specifier: workspace:^ version: link:../storage - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/subagent/subagent: dependencies: @@ -6279,6 +6279,9 @@ importers: specifier: ^4.4.3 version: 4.4.3 devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-agent': specifier: workspace:^ version: link:../../core/agent @@ -6321,20 +6324,20 @@ importers: '@deepseek-ai/dsh-tools': specifier: workspace:^ version: link:../../core/tools - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/subagent/subagent-acp: dependencies: '@agentclientprotocol/sdk': specifier: 0.25.1 version: 0.25.1(zod@4.4.3) - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: - '@cordisjs/plugin-loader': + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis + '@deepseek-ai/cordis-plugin-loader': specifier: ^1.0.0-rc.5 version: link:../../../vendor/loader '@deepseek-ai/dsh-agent': @@ -6364,9 +6367,6 @@ importers: '@deepseek-ai/dsh-timeout': specifier: workspace:^ version: link:../../util/timeout - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/subagent/subagent-claude-code: dependencies: @@ -6376,10 +6376,13 @@ importers: '@anthropic-ai/sdk': specifier: 0.93.0 version: 0.93.0(zod@4.4.3) - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-agent': specifier: workspace:^ version: link:../../core/agent @@ -6407,17 +6410,17 @@ importers: '@deepseek-ai/dsh-timeout': specifier: workspace:^ version: link:../../util/timeout - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/subagent/subagent-codex: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: - '@cordisjs/plugin-loader': + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis + '@deepseek-ai/cordis-plugin-loader': specifier: ^1.0.0-rc.5 version: link:../../../vendor/loader '@deepseek-ai/dsh-agent': @@ -6453,17 +6456,17 @@ importers: '@openai/codex': specifier: 0.147.0 version: 0.147.0 - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/subagent/subagent-dsh-sdk: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: - '@cordisjs/plugin-loader': + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis + '@deepseek-ai/cordis-plugin-loader': specifier: ^1.0.0-rc.5 version: link:../../../vendor/loader '@deepseek-ai/dsh-agent': @@ -6493,17 +6496,17 @@ importers: '@deepseek-ai/dsh-subprocess': specifier: workspace:^ version: link:../../subprocess/subprocess - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/subagent/subagent-fork: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: - '@cordisjs/plugin-loader': + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis + '@deepseek-ai/cordis-plugin-loader': specifier: ^1.0.0-rc.5 version: link:../../../vendor/loader '@deepseek-ai/dsh-agent': @@ -6533,16 +6536,16 @@ importers: '@deepseek-ai/dsh-subagent-spawn': specifier: workspace:^ version: link:../subagent-spawn - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/subagent/subagent-inprocess: devDependencies: - '@cordisjs/plugin-include': + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis + '@deepseek-ai/cordis-plugin-include': specifier: ^1.0.4 version: link:../../../vendor/include - '@cordisjs/plugin-loader': + '@deepseek-ai/cordis-plugin-loader': specifier: ^1.0.0-rc.5 version: link:../../../vendor/loader '@deepseek-ai/dsh-agent': @@ -6587,17 +6590,17 @@ importers: '@deepseek-ai/dsh-user-approval': specifier: workspace:^ version: link:../../interaction/user-approval - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/subagent/subagent-spawn: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: - '@cordisjs/plugin-loader': + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis + '@deepseek-ai/cordis-plugin-loader': specifier: ^1.0.0-rc.5 version: link:../../../vendor/loader '@deepseek-ai/dsh-agent': @@ -6639,17 +6642,17 @@ importers: '@deepseek-ai/dsh-tool-subagent': specifier: workspace:^ version: link:../tool-subagent - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/subagent/tool-subagent: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: - '@cordisjs/plugin-loader': + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis + '@deepseek-ai/cordis-plugin-loader': specifier: ^1.0.0-rc.5 version: link:../../../vendor/loader '@deepseek-ai/dsh-agent': @@ -6691,12 +6694,12 @@ importers: '@deepseek-ai/dsh-tools': specifier: workspace:^ version: link:../../core/tools - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/subagent/tool-subagent-control: devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-agent': specifier: workspace:^ version: link:../../core/agent @@ -6733,16 +6736,16 @@ importers: '@deepseek-ai/dsh-tools': specifier: workspace:^ version: link:../../core/tools - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/subagent/tool-subagent-report: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-agent': specifier: workspace:^ version: link:../../core/agent @@ -6779,18 +6782,15 @@ importers: '@deepseek-ai/dsh-tools': specifier: workspace:^ version: link:../../core/tools - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/subprocess/subprocess: devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/subprocess/subprocess-local: dependencies: @@ -6798,6 +6798,9 @@ importers: specifier: ^1.1.0 version: 1.1.0(patch_hash=7a0c04f1f49d798a9ffe2f7f414c01064a44ca2489772d0c3e1235ab336755e6) devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants @@ -6807,9 +6810,6 @@ importers: '@deepseek-ai/dsh-timeout': specifier: workspace:^ version: link:../../util/timeout - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/support/acp-snapshot: dependencies: @@ -6823,18 +6823,21 @@ importers: specifier: ^4.1.8 version: 4.1.8(@opentelemetry/api@1.9.0)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(jsdom@29.1.1)(vite@8.0.16(@types/node@26.1.2)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.22.4)(yaml@2.9.0)) devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../invariants '@deepseek-ai/dsh-session': specifier: workspace:^ version: link:../../core/session - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/support/agent-loop-testkit: devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-agent': specifier: workspace:^ version: link:../../core/agent @@ -6856,31 +6859,31 @@ importers: '@deepseek-ai/dsh-tools': specifier: workspace:^ version: link:../../core/tools - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/support/invariants: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: - cordis: + '@deepseek-ai/cordis': specifier: ^4.0.0-rc.7 version: link:../../../vendor/cordis packages/support/llm-mock-server: devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../invariants - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/support/llm-replay: devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-compact': specifier: workspace:^ version: link:../../compact/compact @@ -6893,9 +6896,6 @@ importers: '@deepseek-ai/dsh-session': specifier: workspace:^ version: link:../../core/session - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/support/loader-smoke: dependencies: @@ -6906,6 +6906,9 @@ importers: specifier: ^4.22.4 version: 4.22.4 devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.6 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-agent': specifier: workspace:^ version: link:../../core/agent @@ -6918,12 +6921,12 @@ importers: '@deepseek-ai/dsh-session': specifier: workspace:^ version: link:../../core/session - cordis: - specifier: ^4.0.0-rc.6 - version: link:../../../vendor/cordis packages/tasks/tasks: devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.6 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-agent': specifier: workspace:^ version: link:../../core/agent @@ -6936,12 +6939,12 @@ importers: '@deepseek-ai/dsh-session': specifier: workspace:^ version: link:../../core/session - cordis: - specifier: ^4.0.0-rc.6 - version: link:../../../vendor/cordis packages/tasks/tasks-local: devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-agent': specifier: workspace:^ version: link:../../core/agent @@ -6963,16 +6966,16 @@ importers: '@deepseek-ai/dsh-timeout': specifier: workspace:^ version: link:../../util/timeout - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/tasks/tool-tasks: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.6 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-agent': specifier: workspace:^ version: link:../../core/agent @@ -7000,23 +7003,23 @@ importers: '@deepseek-ai/dsh-tools': specifier: workspace:^ version: link:../../core/tools - cordis: - specifier: ^4.0.0-rc.6 - version: link:../../../vendor/cordis packages/todo/tool-todo: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery zod: specifier: ^4.4.3 version: 4.4.3 devDependencies: - '@cordisjs/plugin-include': + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis + '@deepseek-ai/cordis-plugin-include': specifier: workspace:^ version: link:../../../vendor/include - '@cordisjs/plugin-loader': + '@deepseek-ai/cordis-plugin-loader': specifier: workspace:^ version: link:../../../vendor/loader '@deepseek-ai/dsh-agent': @@ -7052,9 +7055,6 @@ importers: '@deepseek-ai/dsh-user-interaction': specifier: workspace:^ version: link:../../interaction/user-interaction - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/typert/generator: dependencies: @@ -7065,6 +7065,9 @@ importers: specifier: ^6.0.3 version: 6.0.3 devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants @@ -7074,20 +7077,20 @@ importers: '@deepseek-ai/dsh-typert-registry': specifier: workspace:^ version: link:../registry - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis zod: specifier: ^4.4.3 version: 4.4.3 packages/typert/loader: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: - '@cordisjs/plugin-loader': + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis + '@deepseek-ai/cordis-plugin-loader': specifier: workspace:^ version: link:../../../vendor/loader '@deepseek-ai/dsh-invariants': @@ -7096,9 +7099,6 @@ importers: '@deepseek-ai/dsh-typert-registry': specifier: workspace:^ version: link:../registry - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis zod: specifier: ^4.4.3 version: 4.4.3 @@ -7112,97 +7112,100 @@ importers: specifier: ^4.4.3 version: 4.4.3 devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/typert/type-meta: devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/util/atomic-write: devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/util/brand: devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/util/environment: devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/util/native-command: devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/util/paths: devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.6 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants - cordis: - specifier: ^4.0.0-rc.6 - version: link:../../../vendor/cordis packages/util/retention: devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.6 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants - cordis: - specifier: ^4.0.0-rc.6 - version: link:../../../vendor/cordis packages/util/timeout: devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/web/tool-web: dependencies: + '@deepseek-ai/schemastery': + specifier: ^3.18.0 + version: link:../../../vendor/schemastery '@joplin/turndown-plugin-gfm': specifier: ^1.0.67 version: 1.0.67 - schemastery: - specifier: ^3.18.0 - version: link:../../../vendor/schemastery turndown: specifier: ^7.2.4 version: 7.2.4 devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-agent': specifier: workspace:^ version: link:../../core/agent @@ -7242,32 +7245,32 @@ importers: '@types/turndown': specifier: ^5.0.6 version: 5.0.6 - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/web/web: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants '@deepseek-ai/dsh-llm': specifier: workspace:^ version: link:../../llm/llm - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/web/web-fetch-local: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-invariants': specifier: workspace:^ version: link:../../support/invariants @@ -7277,16 +7280,16 @@ importers: '@deepseek-ai/dsh-web': specifier: workspace:^ version: link:../web - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/web/web-search-deepseek: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-agent': specifier: workspace:^ version: link:../../core/agent @@ -7308,16 +7311,16 @@ importers: '@deepseek-ai/dsh-web': specifier: workspace:^ version: link:../web - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/web/web-search-exa: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-environment': specifier: workspace:^ version: link:../../util/environment @@ -7327,16 +7330,16 @@ importers: '@deepseek-ai/dsh-web': specifier: workspace:^ version: link:../web - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/web/web-search-perplexity: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-environment': specifier: workspace:^ version: link:../../util/environment @@ -7346,17 +7349,17 @@ importers: '@deepseek-ai/dsh-web': specifier: workspace:^ version: link:../web - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/workflow/tool-ralph: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: - '@cordisjs/plugin-loader': + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis + '@deepseek-ai/cordis-plugin-loader': specifier: workspace:^ version: link:../../../vendor/loader '@deepseek-ai/dsh-agent': @@ -7398,16 +7401,16 @@ importers: '@deepseek-ai/dsh-workflow-workerthread': specifier: workspace:^ version: link:../workflow-workerthread - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/workflow/tool-workflow: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-agent': specifier: workspace:^ version: link:../../core/agent @@ -7435,12 +7438,12 @@ importers: '@deepseek-ai/dsh-workflow-workerthread': specifier: workspace:^ version: link:../workflow-workerthread - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/workflow/workflow: devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-agent': specifier: workspace:^ version: link:../../core/agent @@ -7456,16 +7459,16 @@ importers: '@deepseek-ai/dsh-session': specifier: workspace:^ version: link:../../core/session - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis packages/workflow/workflow-workerthread: dependencies: - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../../../vendor/schemastery devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-agent': specifier: workspace:^ version: link:../../core/agent @@ -7502,9 +7505,6 @@ importers: '@deepseek-ai/dsh-workflow': specifier: workspace:^ version: link:../workflow - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis tsx: specifier: ^4.19.2 version: 4.22.4 @@ -7515,6 +7515,9 @@ importers: specifier: ^4.4.3 version: 4.4.3 devDependencies: + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../../../vendor/cordis '@deepseek-ai/dsh-brand': specifier: workspace:^ version: link:../../util/brand @@ -7533,22 +7536,22 @@ importers: '@deepseek-ai/dsh-storage-domain': specifier: workspace:^ version: link:../../storage/storage-domain - cordis: - specifier: ^4.0.0-rc.7 - version: link:../../../vendor/cordis python/sdk-runtime: dependencies: - '@cordisjs/plugin-group': + '@deepseek-ai/cordis': + specifier: workspace:^ + version: link:../../vendor/cordis + '@deepseek-ai/cordis-plugin-group': specifier: workspace:^ version: link:../../vendor/group - '@cordisjs/plugin-include': + '@deepseek-ai/cordis-plugin-include': specifier: workspace:^ version: link:../../vendor/include - '@cordisjs/plugin-loader': + '@deepseek-ai/cordis-plugin-loader': specifier: workspace:^ version: link:../../vendor/loader - '@cordisjs/plugin-timer': + '@deepseek-ai/cordis-plugin-timer': specifier: workspace:^ version: link:../../vendor/timer '@deepseek-ai/dsh-acp': @@ -7845,62 +7848,59 @@ importers: '@deepseek-ai/dsh-workspace-context': specifier: workspace:^ version: link:../../packages/context/workspace-context - cordis: - specifier: workspace:^ - version: link:../../vendor/cordis - schemastery: + '@deepseek-ai/schemastery': specifier: workspace:^ version: link:../../vendor/schemastery vendor/cordis: dependencies: - '@cordisjs/plugin-include': + '@deepseek-ai/cordis-plugin-include': specifier: ^1.0.4 version: link:../include - '@cordisjs/plugin-loader': + '@deepseek-ai/cordis-plugin-loader': specifier: ^1.0.0-rc.5 version: link:../loader + '@deepseek-ai/cosmokit': + specifier: ^1.8.1 + version: link:../cosmokit '@standard-schema/spec': specifier: ^1.1.0 version: 1.1.0 - cosmokit: - specifier: ^1.8.1 - version: link:../cosmokit vendor/cosmokit: {} vendor/group: dependencies: - '@cordisjs/plugin-loader': - specifier: ^1.0.0-rc.5 - version: link:../loader - cordis: + '@deepseek-ai/cordis': specifier: ^4.0.0-rc.7 version: link:../cordis + '@deepseek-ai/cordis-plugin-loader': + specifier: ^1.0.0-rc.5 + version: link:../loader vendor/hmr: dependencies: '@babel/code-frame': specifier: ^7.29.0 version: 7.29.7 - '@cordisjs/plugin-timer': + '@deepseek-ai/cordis': + specifier: ^4.0.0-rc.7 + version: link:../cordis + '@deepseek-ai/cordis-plugin-timer': specifier: ^1.1.2 version: link:../timer + '@deepseek-ai/cosmokit': + specifier: ^1.8.1 + version: link:../cosmokit + '@deepseek-ai/schemastery': + specifier: ^3.18.0 + version: link:../schemastery chokidar: specifier: ^4.0.3 version: 4.0.3 - cordis: - specifier: ^4.0.0-rc.7 - version: link:../cordis - cosmokit: - specifier: ^1.8.1 - version: link:../cosmokit picomatch: specifier: ^4.0.3 version: 4.0.4 - schemastery: - specifier: ^3.18.0 - version: link:../schemastery devDependencies: '@types/babel__code-frame': specifier: ^7.27.0 @@ -7914,13 +7914,13 @@ importers: vendor/include: dependencies: - '@cordisjs/plugin-loader': - specifier: ^1.0.0-rc.5 - version: link:../loader - cordis: + '@deepseek-ai/cordis': specifier: ^4.0.0-rc.7 version: link:../cordis - cosmokit: + '@deepseek-ai/cordis-plugin-loader': + specifier: ^1.0.0-rc.5 + version: link:../loader + '@deepseek-ai/cosmokit': specifier: ^1.8.1 version: link:../cosmokit js-yaml: @@ -7929,10 +7929,10 @@ importers: vendor/loader: dependencies: - cordis: + '@deepseek-ai/cordis': specifier: ^4.0.0-rc.7 version: link:../cordis - cosmokit: + '@deepseek-ai/cosmokit': specifier: ^1.8.1 version: link:../cosmokit node-addon-require-builtin: @@ -7941,13 +7941,13 @@ importers: vendor/logger-console: dependencies: - cordis: + '@deepseek-ai/cordis': specifier: ^4.0.0-rc.7 version: link:../cordis - cosmokit: + '@deepseek-ai/cosmokit': specifier: ^1.8.1 version: link:../cosmokit - schemastery: + '@deepseek-ai/schemastery': specifier: ^3.18.0 version: link:../schemastery supports-color: @@ -7956,19 +7956,19 @@ importers: vendor/schemastery: dependencies: + '@deepseek-ai/cosmokit': + specifier: ^1.8.1 + version: link:../cosmokit '@standard-schema/spec': specifier: ^1.1.0 version: 1.1.0 - cosmokit: - specifier: ^1.8.1 - version: link:../cosmokit vendor/timer: dependencies: - cordis: + '@deepseek-ai/cordis': specifier: ^4.0.0-rc.7 version: link:../cordis - cosmokit: + '@deepseek-ai/cosmokit': specifier: ^1.8.1 version: link:../cosmokit diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 66510d89ec..65208d7da6 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -51,10 +51,6 @@ allowBuilds: '@deepseek-ai/dsh-pty-local@file:packages/pty/pty-local': true minimumReleaseAgeExclude: - # Cordis release candidates are source-vendored and pinned in vendor/README.md - # during the same-day sync that updates package manifests and the lockfile. - - '@cordisjs/plugin-loader@1.0.0-rc.5' - - cordis@4.0.0-rc.7 # Fresh pi-ai releases carry the model catalog updates that are the whole # point of bumping it; waiting out the release age would defeat that. - '@earendil-works/pi-ai@0.82.1' diff --git a/python/sdk-runtime/package.json b/python/sdk-runtime/package.json index d5e90fb1b9..04a182d727 100644 --- a/python/sdk-runtime/package.json +++ b/python/sdk-runtime/package.json @@ -5,10 +5,10 @@ "private": true, "type": "module", "dependencies": { - "@cordisjs/plugin-group": "workspace:^", - "@cordisjs/plugin-include": "workspace:^", - "@cordisjs/plugin-loader": "workspace:^", - "@cordisjs/plugin-timer": "workspace:^", + "@deepseek-ai/cordis-plugin-group": "workspace:^", + "@deepseek-ai/cordis-plugin-include": "workspace:^", + "@deepseek-ai/cordis-plugin-loader": "workspace:^", + "@deepseek-ai/cordis-plugin-timer": "workspace:^", "@deepseek-ai/dsh-acp": "workspace:^", "@deepseek-ai/dsh-agent": "workspace:^", "@deepseek-ai/dsh-agent-loop": "workspace:^", @@ -107,7 +107,7 @@ "@deepseek-ai/dsh-workflow": "workspace:^", "@deepseek-ai/dsh-workflow-workerthread": "workspace:^", "@deepseek-ai/dsh-workspace-context": "workspace:^", - "cordis": "workspace:^", - "schemastery": "workspace:^" + "@deepseek-ai/cordis": "workspace:^", + "@deepseek-ai/schemastery": "workspace:^" } } diff --git a/scripts/check-workspace-constraints.ts b/scripts/check-workspace-constraints.ts index c38197c1e3..bb06639e65 100644 --- a/scripts/check-workspace-constraints.ts +++ b/scripts/check-workspace-constraints.ts @@ -21,15 +21,15 @@ const workspaceGlobs = [ { dir: 'apps', depth: 1 }, ] as const const vendoredPackages = new Set([ - 'cordis', - 'cosmokit', - 'schemastery', - '@cordisjs/plugin-loader', - '@cordisjs/plugin-include', - '@cordisjs/plugin-group', - '@cordisjs/plugin-timer', - '@cordisjs/plugin-hmr', - '@cordisjs/plugin-logger-console', + '@deepseek-ai/cordis', + '@deepseek-ai/cosmokit', + '@deepseek-ai/schemastery', + '@deepseek-ai/cordis-plugin-loader', + '@deepseek-ai/cordis-plugin-include', + '@deepseek-ai/cordis-plugin-group', + '@deepseek-ai/cordis-plugin-timer', + '@deepseek-ai/cordis-plugin-hmr', + '@deepseek-ai/cordis-plugin-logger-console', ]) const publicLandlockPackages = new Set([ '@deepseek-ai/node-addon-landlock-run', @@ -271,13 +271,13 @@ function checkWorkspace({ dir, manifest }: WorkspaceManifest): string[] { } if (dir.startsWith('packages/') && manifest.name?.startsWith('@deepseek-ai/dsh-')) { - const peer = manifest.peerDependencies?.cordis - const dev = manifest.devDependencies?.cordis + const peer = manifest.peerDependencies?.['@deepseek-ai/cordis'] + const dev = manifest.devDependencies?.['@deepseek-ai/cordis'] - if (!peer) errors.push(`${label}: cordis must be a peerDependency`) - if (!dev) errors.push(`${label}: cordis must also be a devDependency`) + if (!peer) errors.push(`${label}: @deepseek-ai/cordis must be a peerDependency`) + if (!dev) errors.push(`${label}: @deepseek-ai/cordis must also be a devDependency`) if (peer && dev && peer !== dev) { - errors.push(`${label}: cordis peer (${peer}) and dev (${dev}) ranges must match`) + errors.push(`${label}: @deepseek-ai/cordis peer (${peer}) and dev (${dev}) ranges must match`) } if (manifest.version !== repositoryVersion) { errors.push(`${label}: package.json version must match root version ${repositoryVersion ?? '(missing)'}`) diff --git a/scripts/cordis-walk.ts b/scripts/cordis-walk.ts index befc6156e1..3a38f0ca29 100644 --- a/scripts/cordis-walk.ts +++ b/scripts/cordis-walk.ts @@ -11,12 +11,12 @@ import ts from 'typescript' /** Cheap textual prefilter for a cordis module merge, quote-style agnostic * (the AST match below reads `stmt.name.text` and never sees the quotes). */ -const MERGE_HEAD = /declare module ['"](?:cordis|\.\/context\.ts)['"]/ +const MERGE_HEAD = /declare module ['"](?:@deepseek-ai\/cordis|\.\/context\.ts)['"]/ /** * Parse every file matching `patterns` (repo-relative, sorted, `/`-normalized) * that textually contains a cordis module merge, yielding one entry per merge - * BLOCK — a file may legally hold several `declare module 'cordis'` blocks + * BLOCK — a file may legally hold several `declare module '@deepseek-ai/cordis'` blocks * (the Typert analyzer reads them all), so the exhaustiveness scan must too. * Files without a merge are skipped. * @param scanRoot - Repository root the patterns are resolved against. @@ -39,14 +39,14 @@ export function contextMergeFiles( return out } -/** Every cordis module-merge body in `sf`: `declare module 'cordis'` (harness +/** Every cordis module-merge body in `sf`: `declare module '@deepseek-ai/cordis'` (harness * packages) or `declare module './context.ts'` (vendor core), in source order. * Module-local: consumers walk blocks through {@link contextMergeFiles}. */ function cordisModuleBodies(sf: ts.SourceFile): ts.ModuleBlock[] { const bodies: ts.ModuleBlock[] = [] for (const stmt of sf.statements) { if (!ts.isModuleDeclaration(stmt) || !ts.isStringLiteral(stmt.name)) continue - if (stmt.name.text !== 'cordis' && stmt.name.text !== './context.ts') continue + if (stmt.name.text !== '@deepseek-ai/cordis' && stmt.name.text !== './context.ts') continue if (stmt.body && ts.isModuleBlock(stmt.body)) bodies.push(stmt.body) } return bodies @@ -60,7 +60,7 @@ export function cordisModuleBody(sf: ts.SourceFile): ts.ModuleBlock | null { } /** - * Every `key: Type` property a `declare module 'cordis'` Context merge + * Every `key: Type` property a `declare module '@deepseek-ai/cordis'` Context merge * declares in one module body. * @param body - The cordis module augmentation block. * @param sf - Owning source file (for text extraction). @@ -79,7 +79,7 @@ export function contextKeyMap(body: ts.ModuleBlock, sf: ts.SourceFile): Map { const dir = join(root, 'packages/client/ui-x/src/client') mkdirSync(dir, { recursive: true }) writeFileSync(join(dir, 'index.ts'), [ - "declare module 'cordis' {", + "declare module '@deepseek-ai/cordis' {", ' interface Events {', " 'x/changed'(): void", ' }', @@ -153,12 +153,12 @@ describe('cordis-walk scan reach', () => { // backstop must not stop at the first one, skip the double-quoted legal // form, or ignore .tsx sources. writeFileSync(join(dir, 'split.ts'), [ - "declare module 'cordis' {", + "declare module '@deepseek-ai/cordis' {", ' interface Context {', ' first: FirstService', ' }', '}', - 'declare module "cordis" {', + 'declare module "@deepseek-ai/cordis" {', ' interface Events {', " 'second/changed'(): void", ' }', @@ -167,7 +167,7 @@ describe('cordis-walk scan reach', () => { '', ].join('\n')) writeFileSync(join(dir, 'view.tsx'), [ - "declare module 'cordis' {", + "declare module '@deepseek-ai/cordis' {", ' interface Context {', ' fromTsx: TsxService', ' }', @@ -189,7 +189,7 @@ describe('cordis-walk scan reach', () => { it('reads string-literal and identifier member names from an Events merge', () => { const sf = ts.createSourceFile('x.ts', [ - "declare module 'cordis' {", + "declare module '@deepseek-ai/cordis' {", ' interface Events {', " 'scope/list'(items: string[]): void", ' plain(): void', diff --git a/scripts/gen-cordis-catalog.ts b/scripts/gen-cordis-catalog.ts index 885e0cf9d2..7ee9320cea 100644 --- a/scripts/gen-cordis-catalog.ts +++ b/scripts/gen-cordis-catalog.ts @@ -99,7 +99,7 @@ export const SERVICE_PAGE: Record = { /** * Context keys declared in `interface Context` merges that the rendering * projection cannot see, each with the reason and its documentation owner. - * The scan that enforces this list reads EVERY `declare module 'cordis'` + * The scan that enforces this list reads EVERY `declare module '@deepseek-ai/cordis'` * Context merge under `packages/x/x/src/**` — any depth, not only root * `index.ts` files with a same-named service class — so a new service can * never silently join this blind spot: it either enters {@link SERVICE_PAGE} @@ -168,7 +168,7 @@ export const EVENT_SCOPE_PAGE: Record = { * Event names declared in `interface Events` merges that the rendering * projection cannot see, each with the reason and its documentation owner. * The mirror of {@link SERVICE_WALK_EXEMPTIONS} for events: an independent - * scan reads EVERY `declare module 'cordis'` Events merge under + * scan reads EVERY `declare module '@deepseek-ai/cordis'` Events merge under * `packages/x/x/src/**`, so a declared event either renders onto a subsystems * page (via {@link EVENT_SCOPE_PAGE}) or names itself here — never vanishes * silently. Keys are full event names, not scopes: client-face events share diff --git a/scripts/gen-scoped-events.ts b/scripts/gen-scoped-events.ts index ead001a79b..9d070def72 100644 --- a/scripts/gen-scoped-events.ts +++ b/scripts/gen-scoped-events.ts @@ -309,14 +309,14 @@ class ScopedEventGenerator { } } -/** Return whether an Events interface is inside declare module 'cordis'. */ +/** Return whether an Events interface is inside declare module '@deepseek-ai/cordis'. */ function isCordisModuleInterface(node: ts.InterfaceDeclaration): boolean { const block = node.parent const declaration = block.parent return ts.isModuleBlock(block) && ts.isModuleDeclaration(declaration) && ts.isStringLiteral(declaration.name) - && declaration.name.text === 'cordis' + && declaration.name.text === '@deepseek-ai/cordis' } /** Return whether a parameter is the explicit TypeScript this receiver. */ diff --git a/scripts/gen-third-party-notices.spec.ts b/scripts/gen-third-party-notices.spec.ts index aa3198057b..eec3a4d942 100644 --- a/scripts/gen-third-party-notices.spec.ts +++ b/scripts/gen-third-party-notices.spec.ts @@ -134,13 +134,17 @@ describe('parseVendoredRows', () => { const rows = parseVendoredRows(readFileSync(resolve(root, 'vendor/README.md'), 'utf8')) expect(rows.length).toBeGreaterThan(0) - expect(rows).toContainEqual({ npmName: 'cordis', upstream: 'https://github.com/cordiverse/cordis' }) + expect(rows).toContainEqual({ + npmName: '@deepseek-ai/cordis', + upstreamName: 'cordis', + upstream: 'https://github.com/cordiverse/cordis', + }) // The upstream column carries a trailing package path for some rows; it is not part of the URL. expect(rows.every(row => /^https:\/\/\S+$/.test(row.upstream))).toBe(true) }) it('yields nothing when the table columns change, so the generator fails loud', () => { - expect(parseVendoredRows('| `cordis/` | cordis | 4.0.0 | https://example.com | `abc123` |\n')).toEqual([]) + expect(parseVendoredRows('| `cordis/` | `@deepseek-ai/cordis` | cordis | 4.0.0 | https://example.com | `abc123` |\n')).toEqual([]) }) it('covers every vendored directory, so no package can drop out of the notices', () => { diff --git a/scripts/gen-third-party-notices.ts b/scripts/gen-third-party-notices.ts index c2ab21688a..e161902974 100644 --- a/scripts/gen-third-party-notices.ts +++ b/scripts/gen-third-party-notices.ts @@ -387,6 +387,8 @@ export function tierExternalDeps(manifests: Map, names: Set `| \`${row.npmName}\` | [${row.upstream.replace('https://', '')}](${row.upstream}) | MIT |`).join('\n')} +| Package | Upstream name | Upstream | License | +| --- | --- | --- | --- | +${vendored.map(row => `| \`${row.npmName}\` | \`${row.upstreamName}\` | [${row.upstream.replace('https://', '')}](${row.upstream}) | MIT |`).join('\n')} ## Runtime npm dependencies diff --git a/scripts/gen-tool-catalog.ts b/scripts/gen-tool-catalog.ts index 942a9ec9e0..0fd9c3265e 100644 --- a/scripts/gen-tool-catalog.ts +++ b/scripts/gen-tool-catalog.ts @@ -8,7 +8,7 @@ import { globSync, readFileSync, writeFileSync } from 'node:fs' import { basename, resolve } from 'node:path' -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import type { ToolSchema } from '@deepseek-ai/dsh-llm' import AgentRegistry from '@deepseek-ai/dsh-agent' import type { Agent } from '@deepseek-ai/dsh-agent' diff --git a/scripts/publish-npm-baseline.ts b/scripts/publish-npm-baseline.ts index 4a33f32e1e..320f11997f 100644 --- a/scripts/publish-npm-baseline.ts +++ b/scripts/publish-npm-baseline.ts @@ -258,7 +258,9 @@ class WorkspacePackageSet { const name = expectString(manifest, 'name', manifestPath) const version = expectString(manifest, 'version', manifestPath) const isVendored = manifestPath.startsWith('vendor/') - if (!isVendored && !name.startsWith('@deepseek-ai/')) { + // Vendored packages are rescoped too (vendor/README.md), so publication + // never carries an upstream name that would squat it on the registry. + if (!name.startsWith('@deepseek-ai/')) { throw new Error(`${manifestPath} must name an @deepseek-ai package`) } if (name === '@deepseek-ai/dsh-root') { diff --git a/scripts/test-invariants.spec.ts b/scripts/test-invariants.spec.ts index db3cae7073..5613ed035e 100644 --- a/scripts/test-invariants.spec.ts +++ b/scripts/test-invariants.spec.ts @@ -1,7 +1,7 @@ import { describe, expect, it, vi } from 'vitest' -import { Context, FiberState, Service, ValidationError } from 'cordis' -import Loader from '@cordisjs/plugin-loader' -import z from 'schemastery' +import { Context, FiberState, Service, ValidationError } from '@deepseek-ai/cordis' +import Loader from '@deepseek-ai/cordis-plugin-loader' +import z from '@deepseek-ai/schemastery' import InvariantService from '@deepseek-ai/dsh-invariants' import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' import { packageInvariantOwners } from './package-invariants.ts' @@ -13,7 +13,7 @@ import { usesManualInvariantTree, } from './test-invariants.ts' -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { testInvariantProbe: TestInvariantProbe } diff --git a/scripts/test-invariants.ts b/scripts/test-invariants.ts index 9235f34e46..fa3c3cc7e4 100644 --- a/scripts/test-invariants.ts +++ b/scripts/test-invariants.ts @@ -6,8 +6,8 @@ */ import { expect } from 'vitest' -import { FiberState, Inject, RegistryService } from 'cordis' -import type { Context, Plugin } from 'cordis' +import { FiberState, Inject, RegistryService } from '@deepseek-ai/cordis' +import type { Context, Plugin } from '@deepseek-ai/cordis' import { AttachmentStore } from '@deepseek-ai/dsh-attachment' import type { ImageAttachmentLimits, diff --git a/scripts/verify-cordis-config.ts b/scripts/verify-cordis-config.ts index b0aef8ddc9..a70dae4d1c 100644 --- a/scripts/verify-cordis-config.ts +++ b/scripts/verify-cordis-config.ts @@ -165,7 +165,7 @@ function validateEntry(value: unknown, file: string, path: string): void { } recordPlugin(value, file) validateMetadata(value, file, path) - if ((value.group === true || value.name === '@cordisjs/plugin-group') && isUnknownArray(value.config)) { + if ((value.group === true || value.name === '@deepseek-ai/cordis-plugin-group') && isUnknownArray(value.config)) { for (let index = 0; index < value.config.length; index++) { validateEntry(value.config[index], file, `${path}.config[${index}]`) } @@ -175,7 +175,7 @@ function validateEntry(value: unknown, file: string, path: string): void { validateEntry(value.insert[index], file, `${path}.insert[${index}]`) } } - if (value.name !== '@cordisjs/plugin-include') return + if (value.name !== '@deepseek-ai/cordis-plugin-include') return const config = value.config if (!isRecord(config) || !isUnknownArray(config.patches)) return for (let index = 0; index < config.patches.length; index++) { diff --git a/tsconfig.base.json b/tsconfig.base.json index 732e740ce7..b5a7e9b1e4 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -28,15 +28,15 @@ // not declaration path aliases, keep each package/vendor source compiled // under its own tsconfig boundary. "paths": { - "cordis": ["./vendor/cordis/src"], - "cosmokit": ["./vendor/cosmokit/src"], - "schemastery": ["./vendor/schemastery/src"], - "@cordisjs/plugin-loader": ["./vendor/loader/src"], - "@cordisjs/plugin-include": ["./vendor/include/src"], - "@cordisjs/plugin-group": ["./vendor/group/src"], - "@cordisjs/plugin-timer": ["./vendor/timer/src"], - "@cordisjs/plugin-hmr": ["./vendor/hmr/src"], - "@cordisjs/plugin-logger-console": ["./vendor/logger-console/src"], + "@deepseek-ai/cordis": ["./vendor/cordis/src"], + "@deepseek-ai/cosmokit": ["./vendor/cosmokit/src"], + "@deepseek-ai/schemastery": ["./vendor/schemastery/src"], + "@deepseek-ai/cordis-plugin-loader": ["./vendor/loader/src"], + "@deepseek-ai/cordis-plugin-include": ["./vendor/include/src"], + "@deepseek-ai/cordis-plugin-group": ["./vendor/group/src"], + "@deepseek-ai/cordis-plugin-timer": ["./vendor/timer/src"], + "@deepseek-ai/cordis-plugin-hmr": ["./vendor/hmr/src"], + "@deepseek-ai/cordis-plugin-logger-console": ["./vendor/logger-console/src"], "@deepseek-ai/node-addon-landlock-run": ["./native/landlock-run/packages/entry/src/index.ts"], "@deepseek-ai/dsh-invariants": ["./packages/support/invariants/src/index.ts"], "@deepseek-ai/dsh-typert-registry": ["./packages/typert/registry/src/index.ts"], diff --git a/vendor/README.md b/vendor/README.md index 87e5859212..470b517549 100644 --- a/vendor/README.md +++ b/vendor/README.md @@ -2,7 +2,7 @@ This directory contains source-vendored copies of the Cordis framework and its foundation libraries. They are copied into this monorepo instead of being depended on via npm, so that the harness fully owns its framework layer (auditable, patchable, pinned). -All vendored packages keep their **original npm names** and are marked `private: true` — they are never published from this repo. `pnpm-workspace.yaml#linkWorkspacePackages` makes matching upstream semver ranges resolve these pinned workspaces, including imports from built `lib/`; disabling it substitutes npm copies behind the same names. The `hygiene` gate `verify-vendored-links` asserts every vendored name resolves to a workspace `link:` in `pnpm-lock.yaml` with no registry copy alongside. Schemastery's manifest additionally declares a conditional `exports` map (import → `.mjs`, require → `.cjs`): pnpm links the directory itself, so without `exports` Node's ESM resolver would fall back to `main` and load the CJS entry whose lazy `require('cosmokit')` can race ESM loading of the same linked module under module-hook hosts (vitest). Upstream MIT `LICENSE` files are preserved in each package directory. +All vendored packages are **renamed into the `@deepseek-ai` scope** (`cordis` → `@deepseek-ai/cordis`, `@cordisjs/plugin-` → `@deepseek-ai/cordis-plugin-`): every harness package declares `cordis` as a peer dependency, so publishing the harness publishes this framework layer too, and a publication under the upstream names would squat them on the registry. Directory names and upstream version numbers are deliberately unchanged, so the manifest below still reads as an upstream snapshot. `pnpm-workspace.yaml#linkWorkspacePackages` makes those preserved semver ranges resolve these pinned workspaces, including imports from built `lib/`. The `hygiene` gate `verify-vendored-links` asserts every vendored name resolves to a workspace `link:` in `pnpm-lock.yaml` with no registry copy alongside. Schemastery's manifest additionally declares a conditional `exports` map (import → `.mjs`, require → `.cjs`): pnpm links the directory itself, so without `exports` Node's ESM resolver would fall back to `main` and load the CJS entry whose lazy `require('@deepseek-ai/cosmokit')` can race ESM loading of the same linked module under module-hook hosts (vitest). Upstream MIT `LICENSE` files are preserved in each package directory. This file covers the manifest, the local-modification log, and the procedure for **updating** an existing vendored package. To **add a new** one, see the cookbook guide: [docs/cookbook/adding-a-vendored-package.md](../docs/cookbook/adding-a-vendored-package.md). @@ -10,17 +10,17 @@ This file covers the manifest, the local-modification log, and the procedure for Upstream workspace: `cordis-workspace` (local checkout: `~/repos/cordis-workspace`). -| Directory | npm name | Version | Upstream repo | Commit | -|---|---|---|---|---| -| `cosmokit/` | `cosmokit` | 1.8.1 | https://github.com/deepseek-harness/cosmokit | `16f6fc058ade66e8ac5da0033d35a8d0f279f544` | -| `schemastery/` | `schemastery` | 3.18.0 | https://github.com/deepseek-harness/schemastery (`packages/core`) | `e67cee00ad725bd1534aee930a979ea3eec6f698` | -| `cordis/` | `cordis` | 4.0.0-rc.7 | https://github.com/cordiverse/cordis (`packages/core`) | `56b3d4f725681cf4556c1a8695a709cc3b6eed74` | -| `loader/` | `@cordisjs/plugin-loader` | 1.0.0-rc.5 | https://github.com/cordiverse/cordis (`packages/loader`) | `56b3d4f725681cf4556c1a8695a709cc3b6eed74` | -| `include/` | `@cordisjs/plugin-include` | 1.0.4 | https://github.com/deepseek-harness/cordis (`packages/include`) | `abb0a307cb1d3b0947f455d590cf5ba922d4caa4` | -| `group/` | `@cordisjs/plugin-group` | 1.0.0 | https://github.com/deepseek-harness/cordis (`packages/group`) | `abb0a307cb1d3b0947f455d590cf5ba922d4caa4` | -| `timer/` | `@cordisjs/plugin-timer` | 1.1.2 | https://github.com/deepseek-harness/cordis (`packages/timer`) | `abb0a307cb1d3b0947f455d590cf5ba922d4caa4` | -| `hmr/` | `@cordisjs/plugin-hmr` | 1.0.15 | https://github.com/deepseek-harness/cordis (`packages/hmr`) | `abb0a307cb1d3b0947f455d590cf5ba922d4caa4` | -| `logger-console/` | `@cordisjs/plugin-logger-console` | 1.0.0 | https://github.com/deepseek-harness/cordis (`packages/logger-console`) | `abb0a307cb1d3b0947f455d590cf5ba922d4caa4` | +| Directory | npm name | Upstream name | Version | Upstream repo | Commit | +|---|---|---|---|---|---| +| `cosmokit/` | `@deepseek-ai/cosmokit` | `cosmokit` | 1.8.1 | https://github.com/deepseek-harness/cosmokit | `16f6fc058ade66e8ac5da0033d35a8d0f279f544` | +| `schemastery/` | `@deepseek-ai/schemastery` | `schemastery` | 3.18.0 | https://github.com/deepseek-harness/schemastery (`packages/core`) | `e67cee00ad725bd1534aee930a979ea3eec6f698` | +| `cordis/` | `@deepseek-ai/cordis` | `cordis` | 4.0.0-rc.7 | https://github.com/cordiverse/cordis (`packages/core`) | `56b3d4f725681cf4556c1a8695a709cc3b6eed74` | +| `loader/` | `@deepseek-ai/cordis-plugin-loader` | `@cordisjs/plugin-loader` | 1.0.0-rc.5 | https://github.com/cordiverse/cordis (`packages/loader`) | `56b3d4f725681cf4556c1a8695a709cc3b6eed74` | +| `include/` | `@deepseek-ai/cordis-plugin-include` | `@cordisjs/plugin-include` | 1.0.4 | https://github.com/deepseek-harness/cordis (`packages/include`) | `abb0a307cb1d3b0947f455d590cf5ba922d4caa4` | +| `group/` | `@deepseek-ai/cordis-plugin-group` | `@cordisjs/plugin-group` | 1.0.0 | https://github.com/deepseek-harness/cordis (`packages/group`) | `abb0a307cb1d3b0947f455d590cf5ba922d4caa4` | +| `timer/` | `@deepseek-ai/cordis-plugin-timer` | `@cordisjs/plugin-timer` | 1.1.2 | https://github.com/deepseek-harness/cordis (`packages/timer`) | `abb0a307cb1d3b0947f455d590cf5ba922d4caa4` | +| `hmr/` | `@deepseek-ai/cordis-plugin-hmr` | `@cordisjs/plugin-hmr` | 1.0.15 | https://github.com/deepseek-harness/cordis (`packages/hmr`) | `abb0a307cb1d3b0947f455d590cf5ba922d4caa4` | +| `logger-console/` | `@deepseek-ai/cordis-plugin-logger-console` | `@cordisjs/plugin-logger-console` | 1.0.0 | https://github.com/deepseek-harness/cordis (`packages/logger-console`) | `abb0a307cb1d3b0947f455d590cf5ba922d4caa4` | Third-party dependencies of the vendored packages stay on npm: `@standard-schema/spec`, `js-yaml`, `chokidar`, `picomatch`, `@babel/code-frame`, `supports-color`, `node-addon-require-builtin`. @@ -44,6 +44,7 @@ Keep this log exhaustive — every divergence from upstream must be listed. 12. **`include/src/index.ts` serialized child-tree mutation and `hmr/src/index.ts` main-watcher initial-scan suppression**: every Include child-tree mutation (initial apply, refresh, `internal/update` patch re-application) runs through one per-Include queue, because the group's transactional `update` is not reentrant — two concurrent applies interleave create and rollback on the same entries and strand the Include fiber without ever settling. The HMR main watcher passes `ignoreInitial: true`: the initial scan re-announced files boot had just consumed, and its `add` for a config file refreshed an Include mid-initial-apply; once serialized, a failing initial apply's rollback disposed HMR, whose teardown drain waited on the queued refresh sitting behind that same apply — a deadlock that exited 13 with no diagnostic. `registerConfig()` keeps its own `ignoreInitial: false` watcher because a user patch layer present at registration must apply once. Covered by the patch-overlay boot-failure built-bin case in `apps/cli/tests/built-bin.e2e.ts`. 13. **`include/src/index.ts` `writeTask` type**: widened the optional `writeTask?: NodeJS.Timeout` property to `NodeJS.Timeout | undefined` — the debounced writer assigns `undefined` on flush, which `exactOptionalPropertyTypes` rejects on a plain optional. Type-only; no behavior change. 14. **`include/src/index.ts` durable debounced writes**: serialized and tracked config-file writes, retried transient `EACCES`/`EBUSY`/`EPERM` rename failures with a bounded backoff, observed asynchronous timer rejections, and drained the latest write during Include teardown. Windows can briefly retain a destination handle after a Loader child disposes; the upstream fire-and-forget rename escaped as an unhandled rejection and could lose the persisted `disabled` state. A terminal failure is logged by the asynchronous writer and remains on the queue so `Include.stop()` rethrows it instead of silently declaring persistence complete; Cordis's ordinary fiber teardown retains its separate error-containment contract. Covered by `packages/host/directory-picker-auto/tests/loader-composition.spec.ts` with injected transient and terminal rename failures. +15. **`@deepseek-ai` rescope**: every vendored manifest `name`, every internal dependency entry among the vendored set, and every module specifier that reaches them use the scoped names in the manifest table's `npm name` column. Directory names, version numbers, and dependency ranges are unchanged, and no upstream runtime identifier is renamed — `Symbol.for('schemastery')` and Schemastery's `vendor:` metadata field keep their upstream values. Re-apply with `pnpm run rescope-vendor --apply` after a sync; the table's two name columns are the mapping, restated for consumers in [docs/rescope.md](../docs/rescope.md). ## Sync procedure diff --git a/vendor/cordis/bin.js b/vendor/cordis/bin.js index 9aecc7ce10..e5ee5224f7 100755 --- a/vendor/cordis/bin.js +++ b/vendor/cordis/bin.js @@ -1,15 +1,15 @@ #!/usr/bin/env node -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import { pathToFileURL } from 'node:url' -import Loader from '@cordisjs/plugin-loader' +import Loader from '@deepseek-ai/cordis-plugin-loader' const ctx = new Context() ctx.baseUrl = pathToFileURL(process.cwd()).href + '/' await ctx.plugin(Loader) await ctx.loader.create({ - name: '@cordisjs/plugin-include', + name: '@deepseek-ai/cordis-plugin-include', config: { path: './cordis.yml', }, diff --git a/vendor/cordis/package.json b/vendor/cordis/package.json index 80a327c2dd..ddc49b0655 100644 --- a/vendor/cordis/package.json +++ b/vendor/cordis/package.json @@ -1,5 +1,5 @@ { - "name": "cordis", + "name": "@deepseek-ai/cordis", "description": "Meta-Framework for Modern JavaScript Applications", "version": "4.0.0-rc.7", "private": true, @@ -25,19 +25,19 @@ "author": "Shigma ", "license": "MIT", "peerDependencies": { - "@cordisjs/plugin-include": "^1.0.4", - "@cordisjs/plugin-loader": "^1.0.0-rc.5" + "@deepseek-ai/cordis-plugin-include": "^1.0.4", + "@deepseek-ai/cordis-plugin-loader": "^1.0.0-rc.5" }, "peerDependenciesMeta": { - "@cordisjs/plugin-include": { + "@deepseek-ai/cordis-plugin-include": { "optional": true }, - "@cordisjs/plugin-loader": { + "@deepseek-ai/cordis-plugin-loader": { "optional": true } }, "dependencies": { "@standard-schema/spec": "^1.1.0", - "cosmokit": "^1.8.1" + "@deepseek-ai/cosmokit": "^1.8.1" } } diff --git a/vendor/cordis/src/context.ts b/vendor/cordis/src/context.ts index 919ae65db3..0488423088 100644 --- a/vendor/cordis/src/context.ts +++ b/vendor/cordis/src/context.ts @@ -1,4 +1,4 @@ -import type { Dict } from 'cosmokit' +import type { Dict } from '@deepseek-ai/cosmokit' import { EventsService } from './events.ts' import { LoggerService } from './logger.ts' import { ReflectService } from './reflect.ts' diff --git a/vendor/cordis/src/events.ts b/vendor/cordis/src/events.ts index 2e862c97d4..e18940a830 100644 --- a/vendor/cordis/src/events.ts +++ b/vendor/cordis/src/events.ts @@ -1,5 +1,5 @@ -import { defineProperty } from 'cosmokit' -import type { Promisify } from 'cosmokit' +import { defineProperty } from '@deepseek-ai/cosmokit' +import type { Promisify } from '@deepseek-ai/cosmokit' import { Context } from './context.ts' import { Fiber, FiberState } from './fiber.ts' import { DisposableList, symbols } from './utils.ts' diff --git a/vendor/cordis/src/fiber.ts b/vendor/cordis/src/fiber.ts index 5511b39036..a8c804207d 100644 --- a/vendor/cordis/src/fiber.ts +++ b/vendor/cordis/src/fiber.ts @@ -1,5 +1,5 @@ -import { defineProperty, isNullable } from 'cosmokit' -import type { Awaitable, Dict } from 'cosmokit' +import { defineProperty, isNullable } from '@deepseek-ai/cosmokit' +import type { Awaitable, Dict } from '@deepseek-ai/cosmokit' import { Context } from './context.ts' import type { Plugin } from './registry.ts' import { buildOuterStack, composeError, DisposableList, getTraceable, isConstructor, isObject, symbols } from './utils.ts' diff --git a/vendor/cordis/src/logger.ts b/vendor/cordis/src/logger.ts index ad266817bb..c905bce865 100644 --- a/vendor/cordis/src/logger.ts +++ b/vendor/cordis/src/logger.ts @@ -1,4 +1,4 @@ -import { defineProperty, hyphenate } from 'cosmokit' +import { defineProperty, hyphenate } from '@deepseek-ai/cosmokit' import { Context } from './context.ts' import { Fiber } from './fiber.ts' import { createCallable, joinPrototype, symbols, type Tracker } from './utils.ts' diff --git a/vendor/cordis/src/reflect.ts b/vendor/cordis/src/reflect.ts index 63dd5b0cd2..7bbe1ae991 100644 --- a/vendor/cordis/src/reflect.ts +++ b/vendor/cordis/src/reflect.ts @@ -1,5 +1,5 @@ -import { defineProperty, isNullable } from 'cosmokit' -import type { Dict } from 'cosmokit' +import { defineProperty, isNullable } from '@deepseek-ai/cosmokit' +import type { Dict } from '@deepseek-ai/cosmokit' import { Context } from './context.ts' import { getTraceable, symbols, withProps } from './utils.ts' import { Fiber, FiberState } from './fiber.ts' diff --git a/vendor/cordis/src/registry.ts b/vendor/cordis/src/registry.ts index d013e86081..478cf036cb 100644 --- a/vendor/cordis/src/registry.ts +++ b/vendor/cordis/src/registry.ts @@ -1,5 +1,5 @@ -import { defineProperty } from 'cosmokit' -import type { Dict } from 'cosmokit' +import { defineProperty } from '@deepseek-ai/cosmokit' +import type { Dict } from '@deepseek-ai/cosmokit' import type { StandardSchemaV1 } from '@standard-schema/spec' import { Context } from './context.ts' import { Fiber } from './fiber.ts' diff --git a/vendor/cordis/src/service.ts b/vendor/cordis/src/service.ts index f58240368d..dc5742f8c2 100644 --- a/vendor/cordis/src/service.ts +++ b/vendor/cordis/src/service.ts @@ -1,4 +1,4 @@ -import { defineProperty } from 'cosmokit' +import { defineProperty } from '@deepseek-ai/cosmokit' import { Context } from './context.ts' import { createCallable, joinPrototype, symbols, type Tracker } from './utils.ts' diff --git a/vendor/cordis/src/utils.ts b/vendor/cordis/src/utils.ts index 2fd499bd0c..024d21f5e0 100644 --- a/vendor/cordis/src/utils.ts +++ b/vendor/cordis/src/utils.ts @@ -1,4 +1,4 @@ -import { defineProperty } from 'cosmokit' +import { defineProperty } from '@deepseek-ai/cosmokit' import type { Context, Service } from './index.ts' /** Ordered collection of disposable values with O(1) deletion by value. */ diff --git a/vendor/cosmokit/package.json b/vendor/cosmokit/package.json index 940fcdb539..db14a695e7 100644 --- a/vendor/cosmokit/package.json +++ b/vendor/cosmokit/package.json @@ -1,5 +1,5 @@ { - "name": "cosmokit", + "name": "@deepseek-ai/cosmokit", "description": "A collection of common utilities", "version": "1.8.1", "private": true, diff --git a/vendor/group/package.json b/vendor/group/package.json index cefb9288fa..9ddb0a132c 100644 --- a/vendor/group/package.json +++ b/vendor/group/package.json @@ -1,5 +1,5 @@ { - "name": "@cordisjs/plugin-group", + "name": "@deepseek-ai/cordis-plugin-group", "description": "Nested plugin group for cordis", "version": "1.0.0", "private": true, @@ -23,7 +23,7 @@ "author": "Shigma ", "license": "MIT", "peerDependencies": { - "@cordisjs/plugin-loader": "^1.0.0-rc.5", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis-plugin-loader": "^1.0.0-rc.5", + "@deepseek-ai/cordis": "^4.0.0-rc.7" } } diff --git a/vendor/group/src/index.ts b/vendor/group/src/index.ts index 7654ba9691..cf27374159 100644 --- a/vendor/group/src/index.ts +++ b/vendor/group/src/index.ts @@ -1,3 +1,3 @@ -import { Group } from '@cordisjs/plugin-loader' +import { Group } from '@deepseek-ai/cordis-plugin-loader' export default Group diff --git a/vendor/hmr/package.json b/vendor/hmr/package.json index 0b498fc90c..4ebaf14959 100644 --- a/vendor/hmr/package.json +++ b/vendor/hmr/package.json @@ -1,5 +1,5 @@ { - "name": "@cordisjs/plugin-hmr", + "name": "@deepseek-ai/cordis-plugin-hmr", "description": "Hot Module Replacement Plugin for Cordis", "version": "1.0.15", "private": true, @@ -22,7 +22,7 @@ ], "author": "Shigma ", "license": "MIT", - "cordis": { + "@deepseek-ai/cordis": { "services": { "required": [ "timer" @@ -34,15 +34,15 @@ } }, "peerDependencies": { - "@cordisjs/plugin-timer": "^1.1.2", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis-plugin-timer": "^1.1.2", + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { "@babel/code-frame": "^7.29.0", "chokidar": "^4.0.3", - "cosmokit": "^1.8.1", + "@deepseek-ai/cosmokit": "^1.8.1", "picomatch": "^4.0.3", - "schemastery": "^3.18.0" + "@deepseek-ai/schemastery": "^3.18.0" }, "devDependencies": { "@types/babel__code-frame": "^7.27.0", diff --git a/vendor/hmr/src/error.ts b/vendor/hmr/src/error.ts index 80045c1765..05e9984278 100644 --- a/vendor/hmr/src/error.ts +++ b/vendor/hmr/src/error.ts @@ -1,4 +1,4 @@ -import { Context } from 'cordis' +import { Context } from '@deepseek-ai/cordis' import type { BuildFailure } from 'esbuild' import { codeFrameColumns } from '@babel/code-frame' import { readFileSync } from 'node:fs' diff --git a/vendor/hmr/src/index.ts b/vendor/hmr/src/index.ts index 169ee2e00a..290899ba1f 100644 --- a/vendor/hmr/src/index.ts +++ b/vendor/hmr/src/index.ts @@ -1,18 +1,18 @@ -import { Context, Service, type Plugin } from 'cordis' -import type { Dict } from 'cosmokit' -import { ModuleLoader, type ModuleJob, type ResolveResult } from '@cordisjs/plugin-loader' -import type { Include } from '@cordisjs/plugin-include' +import { Context, Service, type Plugin } from '@deepseek-ai/cordis' +import type { Dict } from '@deepseek-ai/cosmokit' +import { ModuleLoader, type ModuleJob, type ResolveResult } from '@deepseek-ai/cordis-plugin-loader' +import type { Include } from '@deepseek-ai/cordis-plugin-include' import { FSWatcher, watch, type ChokidarOptions } from 'chokidar' import { dirname, relative, resolve } from 'node:path' import { realpath, stat } from 'node:fs/promises' import { handleError } from './error.ts' -import type {} from '@cordisjs/plugin-timer' +import type {} from '@deepseek-ai/cordis-plugin-timer' import { fileURLToPath, pathToFileURL } from 'node:url' import { createRequire } from 'node:module' import picomatch from 'picomatch' -import z from 'schemastery' +import z from '@deepseek-ai/schemastery' -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context { hmr: Hmr } diff --git a/vendor/include/package.json b/vendor/include/package.json index c588a33d80..3c56bd065b 100644 --- a/vendor/include/package.json +++ b/vendor/include/package.json @@ -1,5 +1,5 @@ { - "name": "@cordisjs/plugin-include", + "name": "@deepseek-ai/cordis-plugin-include", "description": "Include files in cordis configurations", "version": "1.0.4", "private": true, @@ -23,11 +23,11 @@ "author": "Shigma ", "license": "MIT", "peerDependencies": { - "@cordisjs/plugin-loader": "^1.0.0-rc.5", - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis-plugin-loader": "^1.0.0-rc.5", + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { - "cosmokit": "^1.8.1", + "@deepseek-ai/cosmokit": "^1.8.1", "js-yaml": "^4.1.0" } } diff --git a/vendor/include/src/index.ts b/vendor/include/src/index.ts index 59d34c24a3..04079cc598 100644 --- a/vendor/include/src/index.ts +++ b/vendor/include/src/index.ts @@ -1,5 +1,5 @@ -import { EntryTree, isJsExpr, type EntryOptions } from '@cordisjs/plugin-loader' -import { Context, Service } from 'cordis' +import { EntryTree, isJsExpr, type EntryOptions } from '@deepseek-ai/cordis-plugin-loader' +import { Context, Service } from '@deepseek-ai/cordis' import { extname } from 'node:path' import { access, constants, readFile, rename, writeFile } from 'node:fs/promises' import { setTimeout as delay } from 'node:timers/promises' diff --git a/vendor/loader/package.json b/vendor/loader/package.json index 1d4e757099..e535334803 100644 --- a/vendor/loader/package.json +++ b/vendor/loader/package.json @@ -1,5 +1,5 @@ { - "name": "@cordisjs/plugin-loader", + "name": "@deepseek-ai/cordis-plugin-loader", "description": "Plugin loader for cordis", "version": "1.0.0-rc.5", "private": true, @@ -23,7 +23,7 @@ "author": "Shigma ", "license": "MIT", "peerDependencies": { - "cordis": "^4.0.0-rc.7", + "@deepseek-ai/cordis": "^4.0.0-rc.7", "node-addon-require-builtin": "^0.1.4" }, "peerDependenciesMeta": { @@ -32,6 +32,6 @@ } }, "dependencies": { - "cosmokit": "^1.8.1" + "@deepseek-ai/cosmokit": "^1.8.1" } } diff --git a/vendor/loader/src/config/entry.ts b/vendor/loader/src/config/entry.ts index d479fa6c0f..215198468f 100644 --- a/vendor/loader/src/config/entry.ts +++ b/vendor/loader/src/config/entry.ts @@ -1,5 +1,5 @@ -import { Context, Fiber, Inject } from 'cordis' -import { deepEqual, isNullable } from 'cosmokit' +import { Context, Fiber, Inject } from '@deepseek-ai/cordis' +import { deepEqual, isNullable } from '@deepseek-ai/cosmokit' import { Loader } from '../index.ts' import { EntryGroup } from './group.ts' import { EntryTree } from './tree.ts' diff --git a/vendor/loader/src/config/group.ts b/vendor/loader/src/config/group.ts index 8b96187275..a7b0997297 100644 --- a/vendor/loader/src/config/group.ts +++ b/vendor/loader/src/config/group.ts @@ -1,4 +1,4 @@ -import { Context, Service } from 'cordis' +import { Context, Service } from '@deepseek-ai/cordis' import { Entry, type EntryOptions } from './entry.ts' import { EntryTree } from './tree.ts' diff --git a/vendor/loader/src/config/isolate.ts b/vendor/loader/src/config/isolate.ts index 9142f3fda5..0dd2a06c92 100644 --- a/vendor/loader/src/config/isolate.ts +++ b/vendor/loader/src/config/isolate.ts @@ -1,5 +1,5 @@ -import { Context } from 'cordis' -import type { Dict } from 'cosmokit' +import { Context } from '@deepseek-ai/cordis' +import type { Dict } from '@deepseek-ai/cosmokit' import { Entry } from './entry.ts' declare module './entry.ts' { diff --git a/vendor/loader/src/config/tree.ts b/vendor/loader/src/config/tree.ts index 8cb9fb984d..4b5ac78ef7 100644 --- a/vendor/loader/src/config/tree.ts +++ b/vendor/loader/src/config/tree.ts @@ -1,5 +1,5 @@ -import { composeError, Context } from 'cordis' -import { isNonNullable, type Dict } from 'cosmokit' +import { composeError, Context } from '@deepseek-ai/cordis' +import { isNonNullable, type Dict } from '@deepseek-ai/cosmokit' import { Entry, type EntryOptions } from './entry.ts' import { EntryGroup } from './group.ts' diff --git a/vendor/loader/src/config/utils.ts b/vendor/loader/src/config/utils.ts index 4e193fcc4f..cd706c0407 100644 --- a/vendor/loader/src/config/utils.ts +++ b/vendor/loader/src/config/utils.ts @@ -1,4 +1,4 @@ -import { valueMap } from 'cosmokit' +import { valueMap } from '@deepseek-ai/cosmokit' // eslint-disable-next-line no-new-func /** Evaluate a JavaScript expression against a loader context scope. */ diff --git a/vendor/loader/src/index.ts b/vendor/loader/src/index.ts index 798354c7b0..fa1f852cff 100644 --- a/vendor/loader/src/index.ts +++ b/vendor/loader/src/index.ts @@ -1,5 +1,5 @@ -import { Context, Inject, Service } from 'cordis' -import { defineProperty, isNullable, type Dict } from 'cosmokit' +import { Context, Inject, Service } from '@deepseek-ai/cordis' +import { defineProperty, isNullable, type Dict } from '@deepseek-ai/cosmokit' import { ModuleLoader } from './internal.ts' import { Entry, type EntryOptions } from './config/entry.ts' import isolate from './config/isolate.ts' @@ -18,7 +18,7 @@ export * from './config/utils.ts' /** Re-export Node internal module loader compatibility types. */ export * from './internal.ts' -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Events { 'exit'(signal: NodeJS.Signals): Promise 'loader/config-update'(): void diff --git a/vendor/loader/src/internal.ts b/vendor/loader/src/internal.ts index 38d6f589f5..ccf08debc6 100644 --- a/vendor/loader/src/internal.ts +++ b/vendor/loader/src/internal.ts @@ -1,5 +1,5 @@ import { createRequire, type LoadHookContext } from 'node:module' -import type { Dict } from 'cosmokit' +import type { Dict } from '@deepseek-ai/cosmokit' /** Node internal module format names handled by loader hooks. */ export type ModuleFormat = 'builtin' | 'commonjs' | 'json' | 'module' | 'wasm' diff --git a/vendor/logger-console/package.json b/vendor/logger-console/package.json index 7af021c45a..b1cc3734bb 100644 --- a/vendor/logger-console/package.json +++ b/vendor/logger-console/package.json @@ -1,5 +1,5 @@ { - "name": "@cordisjs/plugin-logger-console", + "name": "@deepseek-ai/cordis-plugin-logger-console", "description": "Console logger exporter for cordis", "version": "1.0.0", "private": true, @@ -25,11 +25,11 @@ "author": "Shigma ", "license": "MIT", "peerDependencies": { - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { - "cosmokit": "^1.8.1", - "schemastery": "^3.18.0", + "@deepseek-ai/cosmokit": "^1.8.1", + "@deepseek-ai/schemastery": "^3.18.0", "supports-color": "^9.4.0" } } diff --git a/vendor/logger-console/src/browser.ts b/vendor/logger-console/src/browser.ts index b45a15e228..e77ec3c3fb 100644 --- a/vendor/logger-console/src/browser.ts +++ b/vendor/logger-console/src/browser.ts @@ -1,4 +1,4 @@ -import { Message } from 'cordis' +import { Message } from '@deepseek-ai/cordis' import { ConsoleExporter as Base } from './shared.ts' /** Re-export shared console exporter config and base implementation. */ diff --git a/vendor/logger-console/src/index.ts b/vendor/logger-console/src/index.ts index d46ac6413f..3ed272a9ec 100644 --- a/vendor/logger-console/src/index.ts +++ b/vendor/logger-console/src/index.ts @@ -1,4 +1,4 @@ -import { Formatter } from 'cordis' +import { Formatter } from '@deepseek-ai/cordis' import { inspect } from 'node:util' import supportsColor from 'supports-color' import { ConsoleExporter as Base } from './shared.ts' diff --git a/vendor/logger-console/src/shared.ts b/vendor/logger-console/src/shared.ts index 61d91abcb3..942bc54746 100644 --- a/vendor/logger-console/src/shared.ts +++ b/vendor/logger-console/src/shared.ts @@ -1,6 +1,6 @@ -import { Context, Exporter, Formatter, Logger, Message } from 'cordis' -import { Time } from 'cosmokit' -import z from 'schemastery' +import { Context, Exporter, Formatter, Logger, Message } from '@deepseek-ai/cordis' +import { Time } from '@deepseek-ai/cosmokit' +import z from '@deepseek-ai/schemastery' /** Terminal color support level compatible with supports-color. */ export type ColorSupportLevel = 0 | 1 | 2 | 3 diff --git a/vendor/schemastery/package.json b/vendor/schemastery/package.json index f23fac56db..f2a0c61e5a 100644 --- a/vendor/schemastery/package.json +++ b/vendor/schemastery/package.json @@ -1,5 +1,5 @@ { - "name": "schemastery", + "name": "@deepseek-ai/schemastery", "description": "Type driven schema validator", "version": "3.18.0", "private": true, @@ -27,6 +27,6 @@ "license": "MIT", "dependencies": { "@standard-schema/spec": "^1.1.0", - "cosmokit": "^1.8.1" + "@deepseek-ai/cosmokit": "^1.8.1" } } diff --git a/vendor/schemastery/src/index.ts b/vendor/schemastery/src/index.ts index 5948797ae9..56a499e1cc 100644 --- a/vendor/schemastery/src/index.ts +++ b/vendor/schemastery/src/index.ts @@ -1,4 +1,4 @@ -import { Binary, clone, deepEqual, filterKeys, isNullable, isPlainObject, pick, valueMap, type Dict } from 'cosmokit' +import { Binary, clone, deepEqual, filterKeys, isNullable, isPlainObject, pick, valueMap, type Dict } from '@deepseek-ai/cosmokit' import type { StandardSchemaV1 } from '@standard-schema/spec' const kSchema = Symbol.for('schemastery') diff --git a/vendor/timer/package.json b/vendor/timer/package.json index 4ae59cd0bd..9bf741fc51 100644 --- a/vendor/timer/package.json +++ b/vendor/timer/package.json @@ -1,5 +1,5 @@ { - "name": "@cordisjs/plugin-timer", + "name": "@deepseek-ai/cordis-plugin-timer", "description": "Timer service for cordis", "version": "1.1.2", "private": true, @@ -23,9 +23,9 @@ "author": "Shigma ", "license": "MIT", "peerDependencies": { - "cordis": "^4.0.0-rc.7" + "@deepseek-ai/cordis": "^4.0.0-rc.7" }, "dependencies": { - "cosmokit": "^1.8.1" + "@deepseek-ai/cosmokit": "^1.8.1" } } diff --git a/vendor/timer/src/index.ts b/vendor/timer/src/index.ts index 1a33850aa3..009d14a5d4 100644 --- a/vendor/timer/src/index.ts +++ b/vendor/timer/src/index.ts @@ -1,6 +1,6 @@ -import { Context, Service } from 'cordis' +import { Context, Service } from '@deepseek-ai/cordis' -declare module 'cordis' { +declare module '@deepseek-ai/cordis' { interface Context extends Pick { timer: TimerService }