@deepseek-ai/dsh-tool-cordis 0.1.1-rc.2 → 0.1.2-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.i18n.yaml CHANGED
@@ -2,5 +2,5 @@
2
2
  # side as of the last confirmed-consistent state. Both languages carry equal authority;
3
3
  # after editing either side, bring the other along and re-record with:
4
4
  # pnpm run verify-translation-pairing --write packages/extensions/tool-cordis/README.md
5
- README.md: 396a844014328da8cfad57fa7728793b91a9aff7
6
- README.zh.md: 046f350a6314471c738691ce11249412161650e1
5
+ README.md: 9f564044979e17f1db8b6329ecb95cc9b10fb51d
6
+ README.zh.md: dd4945391d9e215c6db9eeac6b17184a1e5e7b8a
package/README.md CHANGED
@@ -1,65 +1,118 @@
1
+ ---
2
+ description: "Model-facing Cordis runtime tools for agents and maintainers choosing, composing, or debugging dynamic-package workflows."
3
+ kind: "package-reference"
4
+ ---
5
+
1
6
  # @deepseek-ai/dsh-tool-cordis
2
7
 
3
8
  English | [中文](README.zh.md)
4
9
 
5
- The self-referential Cordis toolset: five model-facing tools over the live runtime in the current DSH process. The registry, the vm sandbox, and the browser broadcast belong to [`@deepseek-ai/dsh-cordis-host-runner`](../cordis-host-runner/README.md) (`ctx.dynamic`), which this toolset injects — a composition with these tools but no runner never activates them. Design home — sandbox semantics, dynamic-package lifecycle and composition, standing decisions: [the toolset Agent Note](../../../.agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.md).
10
+ ## Summary
11
+
12
+ `dsh-tool-cordis` gives the model seven tools over the live Cordis runtime of the current DSH process: inspect what is loaded and what a dynamic package may use, define a package with a host half, a browser half, or both, run it, stop it, and remove it. Packages are versioned — a plugin holds immutable package versions, and the model can append a corrected package and update to it after a failure. Definitions live only in process memory and vanish on DSH restart; nothing here writes repository files, installs packages, or changes `cordis.yml`. It also adds a system-prompt section that teaches the workflow; compose it with `@deepseek-ai/dsh-cordis-host-runner`, the package that runs the sandbox and the run round trip.
13
+
14
+ ## Table of Contents
15
+
16
+ - [Use this package](#use-this-package)
17
+ - [Understand the implementation](#understand-the-implementation)
18
+ - [Further Exploration](#further-exploration)
19
+ - [Model Experience](#model-experience)
20
+ - [Known Limitations and Deferred Work](#known-limitations-and-deferred-work)
21
+ - [Dev Note](#dev-note)
22
+
23
+ -----
24
+
25
+ <a id="use-this-package"></a>
26
+ ## Use this package
27
+
28
+ Mount this plugin when a session should be able to extend its own runtime temporarily — for example, a model-written tool, service, or browser UI that helps the current work but should not become a repository plugin. Compose it with the host runner; without the runner the tools never activate, and no shipped bundle mounts the toolset (the web profile already mounts the host runner and the browser faces), so add the tool row explicitly.
29
+
30
+ ### Minimal composition
6
31
 
7
- ## What it does
32
+ ```yaml
33
+ - name: '@deepseek-ai/dsh-cordis-host-runner'
34
+ config:
35
+ vmTimeoutMs: 5000
36
+ - name: '@deepseek-ai/dsh-tool-cordis'
37
+ ```
8
38
 
9
- Two paired verbs, plus the read-only report.
39
+ The CLI example [`apps/cli/config/examples/cordis/cordis.yml`](../../../apps/cli/config/examples/cordis/cordis.yml) composes both. A package with a browser half additionally needs the browser runner and the UI package in the client composition; a host-only package needs none of them.
10
40
 
11
- - `cordis_inspect` — read-only report over the current process: services, all live plugin fibers, registered tools, this session's dynamic packages, the reflection-backed `api` / `events` references, and the compile-time `client` slot surface a browser half can contribute UI into. An exact `name` with `what: "api"`, `what: "events"`, or `what: "client"` narrows the report and adds the full contract.
12
- - `cordis_define` — records a package (`name`, `purpose`, and a host half `code` and/or a browser half `client`) after syntax-checking both halves. Nothing runs; the user sees a card for it in the conversation with a start control. The minted `dyn-<n>` id rides the result value AND the durable presentation metadata, which is how that card addresses the run verbs on replay.
13
- - `cordis_run` — evaluates the host half in the sandbox and delivers the browser half to every open web page. Running an already-running package re-delivers the live version instead of failing, which is how a reloaded page gets it back.
14
- - `cordis_stop` — disposes the host half to quiescence and withdraws the browser half; the definition survives and can run again.
15
- - `cordis_undefine` — stops the package if needed and forgets the definition; its card stays in the conversation as an unloaded record.
41
+ ### What the tools do
16
42
 
17
- Exact model-facing schemas: [the generated tool catalog](../../../docs/tool-catalog.md).
43
+ The three inspect tools are read-only; the four lifecycle tools define and manage packages. All results are JSON rendered as text.
18
44
 
19
- Dynamic packages 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_stop`/`cordis_undefine`, 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. Every verb is session-scoped: a package is visible and controllable only in the session that defined it.
45
+ - `cordis_inspect_list` — list the Inspect Providers (host and client) and their query methods.
46
+ - `cordis_inspect_query` — run one provider query: exact service methods, event modes, builtin signatures, tool schemas, theme tokens, or live slot trees.
47
+ - `cordis_inspect_self` — this session's dynamic plugins: version pointers, latest run, and, for one exact package, its source and runtime diagnostics.
48
+ - `cordis_define` — record a package: a new plugin (`plugin.kind: "new"` with a 3–6-letter `idPrefix`) or a new version of an existing plugin (`plugin.kind: "existing"` with its `pluginId`). It validates parameters and syntax only; nothing runs and no approval is requested.
49
+ - `cordis_run` — activate one package (`mode: "run"` for the first activation or restart, `mode: "update"` to switch versions). A package with a browser half may return `awaiting-approval` until a person allows it; the tool never waits for the final outcome.
50
+ - `cordis_stop` — stop the current run and cancel any pending approval, keeping the plugin and every package version.
51
+ - `cordis_undefine` — stop and permanently remove a plugin and all of its packages.
20
52
 
21
- ## Trust stance
53
+ ### A typical workflow
22
54
 
23
- The sandbox isolates globals but is not a security boundary. Node globals are absent or redirect to Cordis services such as `ctx.fs`, `ctx.web`, and `ctx.bash`, and writes to `globalThis` stay local, but host-realm helpers make escape possible. Mounted plugins receive a façade without framework internals, yet its allowed services affect the live runtime. Dynamic tool schemas and annotations cross the realm through iterative JSON cloning and schema normalization, so valid deep declarations are memory-bounded rather than call-stack-bounded; records with JSON-invisible keys and subclassed or decorated schema arrays reject before normalization. Treat this toolset like bash access; see the [design and trust stance](../../../.agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.md).
55
+ Inspect before writing, then define, then run: `cordis_inspect_query` reads the exact contract of the service or slot the package will use, `cordis_define` records the source (and the conversation shows a define card pointing to the panel where the run control lives), and `cordis_run` activates it. When the user types `@pluginId`, this package injects a context message that pins the referenced plugin, its base package, and the update path. After a technical failure, read the diagnostics with `cordis_inspect_self`, append a corrected package to the same plugin, and update to it.
24
56
 
25
- ## Config
57
+ ### Boundaries to plan around
26
58
 
27
- None. The vm evaluation bound (`vmTimeoutMs`) and the browser acknowledgement window (`ackTimeoutMs`) belong to the runner service that owns the sandbox and the broadcast — see [`@deepseek-ai/dsh-cordis-host-runner`](../cordis-host-runner/README.md#config).
59
+ Definitions are session-scoped and process-local: a package is visible and controllable only in the session that defined it, stays active across later turns, and can affect other sessions in the same process while running. Stopping, removing, unloading the toolset, or restarting DSH clears it. The sandbox isolates globals but is not a security boundary — treat a dynamic package like bash access, and load this plugin as deliberately as you would grant one.
28
60
 
29
- ## The generated client slot catalog
61
+ -----
30
62
 
31
- `src/client-catalog.ts` describes the browser half's seats, generated by `scripts/gen-client-catalog.ts` (freshness-gated by `pnpm run verify-client-catalog` in `doc-sync`) from a lexical scan of every `SlotMap` declaration merge and every `slots.register` call site. It carries the one surface a browser half can act on — the slot keys, each register call's options, the props a component receives, who already occupies the seat, and which owner's mount makes the seat exist — as plain data: this package stays host-side and imports no client module, so the strings are the only thing that crosses. The generator fails loud rather than shipping an entry a model cannot act on: a slot with no registrant-facing prose, a non-literal `kind`/`scope`, owner props no export provides, a duplicate key, or a registration into an undeclared slot all break the gate. Owner props expand one level — the owner declaration with its own member documentation, and the names of the shapes its fields reference — and one slot's whole report is budget-capped, because narrowing to a single slot exists to spend less context, not more.
63
+ <a id="understand-the-implementation"></a>
64
+ ## Understand the implementation
32
65
 
33
- A slot's teaching text is its declaration's JSDoc, so improving what the model reads means editing the contract at its declaring package — not this catalog.
66
+ <details>
67
+ <summary>Implementation internals — click to expand</summary>
34
68
 
35
- ## Where the API report comes from
69
+ This section explains the design behind the tools; the observable behavior is fully covered in [Use this package](#use-this-package).
36
70
 
37
- `cordis_inspect what:"api"` / `what:"events"` renders `src/api-catalog.ts`, the generated projection of the workspace's Cordis declarations: rendered method signatures, source JSDoc, harness events with their dispatch modes, and the type shapes those signatures reference, all produced by the same AST walk as `docs/subsystems`, so the data a model reads and the rendered docs cannot diverge. It is a compile-time fact about the REPOSITORY, so `pnpm run gen-cordis-api` regenerates it and `pnpm run verify-cordis-api` gates its freshness.
71
+ ### Design philosophy
38
72
 
39
- `src/inspect.ts` intersects that catalog with the LIVE service store: what is RUNNING comes from the store, what each service CAN DO comes from the catalog, and a live service the catalog does not cover is reported as reachable with no signatures rather than omitted. A package that needs the list in its own code copies it out of a report — the catalog is a compile-time fact about the repository, so a copied list and a freshly read one say the same thing for any one deployment.
73
+ The toolset is built on one separation: the tools are a thin, model-facing layer over the runner service. Inspection data comes from generated catalogs intersected with the live service store; definition and lifecycle verbs delegate to `ctx.dynamicCordisRunner`, which owns the registry, the vm sandbox, and the browser round trip. The tools add the model-facing judgments: only callable methods are shown, only keys a host half can reach are named, and every refusal is a teaching error the model can act on.
40
74
 
41
- Two model-facing judgements live in this package rather than in the artifacts, because reflection data is faithful to the code while a report has to be useful:
75
+ ### Source map
42
76
 
43
- - **Only callable methods are shown.** Non-method members are state rather than a verb, and their rendered form carries initializers from the implementation body; symbol-keyed members are internal seams between plugins that a package façade deliberately cannot reach, so naming one would advertise a call that cannot be made.
44
- - **Only keys a host half can reach are named to a model.** The reflection model covers every `ctx.<key>` a package declares, including launcher-supplied boot values (`agent`, `headlessIo`, …) and browser-half services (`connection`). `src/curation.ts` classifies each one's `reach` — `injectable`, `not-a-service`, or `other-face` — and only `injectable` keys reach a report: naming a key a package cannot reach advertises a call that cannot be made. The classification is carried as data on each catalog entry rather than applied while rendering, so the exclusion is testable on its own, and `verify-cordis-catalog` pins the classified set to exactly the keys the documentation projection does not render — a newly declared key stops the gate instead of quietly inviting a model to `inject` something that will never arrive. A classified key that nonetheless has a live provider is still reported as running and injectable: the service store is the authority on what exists.
77
+ | File | Role |
78
+ |---|---|
79
+ | [`src/index.ts`](src/index.ts) | Plugin entry: tool registration, system-prompt section, `@pluginId` context injection |
80
+ | [`src/inspect.ts`](src/inspect.ts) | Report rendering: joins the generated API catalog with the live service store |
81
+ | [`src/api-catalog.ts`](src/api-catalog.ts) | Generated projection of the workspace's Cordis declarations (regenerated by `pnpm run gen-cordis-api`, gated by `verify-cordis-api`) |
82
+ | [`src/prompt.ts`](src/prompt.ts) | The `tool:cordis` system-prompt section |
83
+ | [`src/providers.ts`](src/providers.ts) | First-party host Inspect Providers: Service, Event, Builtin, Tool |
84
+ | [`src/present.ts`](src/present.ts) | Replay-safe generic card render intents |
45
85
 
46
- The generated `INHERITED_CTX_API` closes the `api` report with the framework-inherited `ctx` surface (`ctx.on`, `ctx.effect`, `ctx.loader`, the timer helpers): those members are the Context itself rather than service keys, and the framework tier lives in pinned vendor packages outside every analyzed face, so the generator curates that one tier and renders it into both this catalog and `docs/cordis-api/inherited.md`. A live service the catalog does not describe is reported as running and still injectable rather than as absent. Broad `api` / `events` reports render summaries and signatures only; an exact `name` opts into the retained method/event JSDoc, and unknown or non-running service targets fail loud.
86
+ ### How a call flows
47
87
 
48
- ## Rendering
88
+ An inspect call queries `ctx.cordisInspect`: host providers run locally, client providers wait for the first valid page response. Define prechecks each half's syntax by compiling it in the same wrapper the sandbox uses, so unparseable code is refused before an id exists. Run delegates to the runner, which activates host-only packages in-process and suspends browser-half packages on a `cordis/request-run` round trip; the tool returns the runner's receipt (`awaiting-approval`, `starting`, or `running`). When the user writes `@pluginId`, an `agent/pre-step` handler reads the reference and injects a user-role context message naming the base package and the required next steps.
49
89
 
50
- Every tool renders a `generic` card (`read` / `execute` / `delete`); `cordis_define` carries the submitted halves as `rawInput` and titles the card with the label and purpose. Presenters are pure functions of the args, and results keep the default text rendering. A Web client registers its own keyed `cordis_define` row (`@deepseek-ai/dsh-client-ui-cordis`) and reads the label, purpose, and minted id from the call arguments and the result metadata; the generic card is what a surface without that registration falls back to.
90
+ </details>
51
91
 
52
- ## Export shape
92
+ -----
53
93
 
54
- Namespace plugin: named exports `name` / `inject` / `apply`, no default export ([docs/postmortem/0001](../../../docs/postmortem/0001-acp-default-export-drops-inject.md)). It injects `tools` and `dynamicCordisRunner`.
94
+ <a id="further-exploration"></a>
95
+ ## Further Exploration
55
96
 
97
+ Read these pages when the package-level contract is not enough. They move from the shared toolset to the runner internals, the generated schemas, and the subsystem surface.
98
+
99
+ - [Host runner](../cordis-host-runner/README.md) — the registry, sandbox, and run round trip these tools delegate to.
100
+ - [Client runner](../cordis-client-runner/README.md) — the browser half that answers run requests and loads browser-half code.
101
+ - [UI package](../ui-cordis/README.md) — the panel and tool cards users operate definitions with.
102
+ - [Generated tool catalog](../../../docs/tool-catalog.md#deepseek-aidsh-tool-cordis) — the exact schemas the model receives.
103
+ - [Extensions subsystem](../../../docs/subsystems/extensions.md) — the generated `ctx.cordisInspect` and `ctx.dynamicCordisRunner` API.
104
+ - [Self-referential Cordis toolset Agent Note](../../../.agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.md) — design home: sandbox semantics, dynamic-package lifecycle, and composition.
105
+
106
+ -----
107
+
108
+ <a id="model-experience"></a>
56
109
  ## Model Experience
57
110
 
58
111
  ### Tool schemas
59
112
 
60
113
  #### What the model sees
61
114
 
62
- The conversation model sees the generated [`cordis_inspect`, `cordis_define`, `cordis_run`, `cordis_stop`, and `cordis_undefine` schemas](../../../docs/tool-catalog.md#deepseek-aidsh-tool-cordis) whenever this plugin is visible.
115
+ The conversation model sees the generated [`cordis_inspect_list`, `cordis_inspect_query`, `cordis_inspect_self`, `cordis_define`, `cordis_run`, `cordis_stop`, and `cordis_undefine` schemas](../../../docs/tool-catalog.md#deepseek-aidsh-tool-cordis) whenever this plugin is visible.
63
116
 
64
117
  #### Token effect
65
118
 
@@ -67,17 +120,39 @@ Fixed schema cost on every request in that tool view.
67
120
 
68
121
  #### KV Cache effect
69
122
 
70
- Prefix-stable while this tool view is unchanged. Scoping or plugin lifecycle changes that hide these definitions may invalidate reuse from the first changed schema token.
123
+ Prefix-stable while this tool view is unchanged. Scoping or plugin-lifecycle changes that hide these definitions may invalidate reuse from the first changed schema token.
124
+
125
+ ### System prompt section
126
+
127
+ #### What the model sees
128
+
129
+ This package registers one system-prompt section (`tool:cordis`, order 115) teaching when and how to use the dynamic-plugin workflow, the recommended tool sequence, and the high-frequency errors to avoid; the full text lives in [`src/prompt.ts`](src/prompt.ts). The section opens with:
130
+
131
+ ##### Section opening
132
+
133
+ ```markdown
134
+ # Dynamic Cordis Plugins
135
+
136
+ Dynamic Cordis plugins temporarily extend the current DSH process. A Plugin uses apply(ctx) to consume Services, listen to Events, provide Services, register model Tools, or register browser UI in Slots.
137
+ ```
138
+
139
+ #### Token effect
140
+
141
+ The section's rendered text repeats on every request while this plugin is visible.
142
+
143
+ #### KV Cache effect
144
+
145
+ Prefix-stable while the section text and order are unchanged; editing the prompt or changing its order may invalidate reuse from the first changed token.
71
146
 
72
147
  ### Tool-call history and results
73
148
 
74
149
  #### What the model sees
75
150
 
76
- Inspect joins selected sections exactly as `## <section>` then a newline and the data-dependent body, with one blank line between sections; `what: "temporary"` uses the `## Dynamic Packages` heading. Each row reports the id, label, purpose, which halves exist, run state and revision, provided and awaited services, registered host methods, and the last browser-half load report. The empty state explains that definitions live only in this process's memory. Broad API/event reports omit JSDoc; `name` with `what: "api"`, `what: "events"`, or `what: "client"` returns one exact target with its full contract. The `client` section lists one seat per line with its cardinality, scope, summary, and whether registering there replaces shipped UI, then the cross-cutting registrant rules; the per-seat register options, owner and framework props, and runnable example arrive only under an exact `name`. Define answers that the package is defined and NOT running yet with the id to run; run reports the revision, what the host half provides or waits for, and whether a page acknowledged the browser half; stop and undefine acknowledge in one line. Every refusal is a tool error carrying the runner's teaching text. The submitted program remains in assistant tool-call history.
151
+ Inspect outputs are JSON rendered as text: `cordis_inspect_list` returns the provider directory, `cordis_inspect_query` the queried data, and `cordis_inspect_self` a plugin, version, and package summary with source and diagnostics for an exact package. Define answers that the package is defined and not running yet, with the ids to run. Run reports `awaiting-approval`, `starting`, or `running` with the run id and version pointers. Stop and undefine acknowledge in one line. Every refusal is a tool error carrying the runner's teaching text, and the submitted program stays in assistant tool-call history.
77
152
 
78
153
  #### Token effect
79
154
 
80
- Inspect output and submitted package code are data-dependent and resent until compaction; lifecycle acknowledgements are small. The `client` section is bounded by the shipped slot count (two lines each) and its per-seat detail is opt-in, so the default report grows with the slot surface rather than with its documentation.
155
+ Inspect output and submitted package code are data-dependent and resent until compaction; lifecycle acknowledgements are small.
81
156
 
82
157
  #### KV Cache effect
83
158
 
@@ -87,7 +162,7 @@ Append-only; newly visible content follows the reusable request prefix and does
87
162
 
88
163
  #### What the model sees
89
164
 
90
- A running package may register tools, prompt contributions, or listeners that change later requests for the scopes it targets; `cordis_stop` and `cordis_undefine` remove those contributions after quiescence.
165
+ A running package may register tools, prompt contributions, or listeners that change later requests for the scopes it targets; `cordis_stop` and `cordis_undefine` remove those contributions after quiescence. When the user types `@pluginId`, the injected reference context also adds a user-role message naming the base package and the next steps.
91
166
 
92
167
  #### Token effect
93
168
 
@@ -99,6 +174,21 @@ Running or stopping a prompt or tool contribution changes later request prefixes
99
174
 
100
175
  ## Known Limitations and Deferred Work
101
176
 
102
- - **The sandbox is containment for honest code, not a security boundary** — host-realm helpers on the sandbox global are reachable, so package code can reach Node; load this plugin as deliberately as you would grant a bash tool (see § Trust stance).
103
- - **The `ctx` façade exposes no `effect()`** — package code cannot register a bespoke disposer; `on`/`provide`/`tools.register` are the supported cleanup paths.
104
- - **The vm and acknowledgement bounds belong to the runner** — see its [Known Limitations](../cordis-host-runner/README.md#known-limitations-and-deferred-work); an async host-half body escapes `vmTimeoutMs`.
177
+ <a id="known-limitations-and-deferred-work"></a>
178
+
179
+
180
+ These limits define when the toolset is a poor fit or needs special care. They are current package constraints, not a task backlog.
181
+
182
+ - **The sandbox is containment for honest code, not a security boundary** — host-realm helpers on the sandbox global are reachable, so package code can reach Node; load this plugin as deliberately as you would grant a bash tool.
183
+ - **Plain JavaScript only** — dynamic package code is not transformed: no TypeScript, JSX, or imports, and the sandbox withholds Node globals such as `require`, `setTimeout`, and `fetch`, redirecting filesystem, network, and process work to Cordis services.
184
+ - **The vm and approval bounds belong to the runner** — see its [Known Limitations](../cordis-host-runner/README.md#known-limitations-and-deferred-work); an async host-half body escapes `vmTimeoutMs`.
185
+
186
+ <a id="dev-note"></a>
187
+ ### Dev Note
188
+
189
+ <details>
190
+ <summary>Working context for maintainers — click to expand</summary>
191
+
192
+ None.
193
+
194
+ </details>
package/README.zh.md CHANGED
@@ -1,65 +1,118 @@
1
+ ---
2
+ description: "面向 agent 与维护者的 Cordis 运行时工具说明,用于选择、组合或排查动态包工作流。"
3
+ kind: "package-reference"
4
+ ---
5
+
1
6
  # @deepseek-ai/dsh-tool-cordis
2
7
 
3
8
  [English](README.md) | 中文
4
9
 
5
- 自引用 Cordis 工具集:五个面向模型的工具,操作当前 DSH 进程中的实时运行时。注册表、vm 沙箱与浏览器广播属于 [`@deepseek-ai/dsh-cordis-host-runner`](../cordis-host-runner/README.zh.md)(`ctx.dynamic`),本工具集注入它——只装这些工具而不装 runner 的组合永远不会激活它们。沙箱语义、动态包生命周期与组合及既定决策详见[工具集 Agent Note](../../../.agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.zh.md)。
10
+ ## 概述
11
+
12
+ `dsh-tool-cordis` 给模型提供七个作用于当前 DSH 进程实时 Cordis 运行时的工具:检查已加载的内容与动态包可用之物,定义包含 host 半、浏览器半或两者的包,运行它、停止它并移除它。包带版本——插件持有若干不可变的包版本,模型在失败后可以追加修正版并更新过去。定义只存在于进程内存中,DSH 重启即消失;本包不写仓库文件、不安装任何包、不改 `cordis.yml`。它还增加一个教这套工作流的系统提示词章节;把它与 `@deepseek-ai/dsh-cordis-host-runner` 一同组合,后者负责沙箱与运行往返。
13
+
14
+ ## 目录
15
+
16
+ - [使用本包](#use-this-package)
17
+ - [理解实现](#understand-the-implementation)
18
+ - [进一步探索](#further-exploration)
19
+ - [模型体验](#model-experience)
20
+ - [已知限制与延期工作](#known-limitations-and-deferred-work)
21
+ - [开发备注](#dev-note)
22
+
23
+ -----
24
+
25
+ <a id="use-this-package"></a>
26
+ ## 使用本包
27
+
28
+ 当某个会话应当能临时扩展它自己的运行时——例如一个对当前工作有用、但不应成为仓库插件的模型编写的工具、服务或浏览器 UI——挂载本插件。请与 host runner 一同组合;没有 runner,这些工具永远不会激活,而且任何已发布的 bundle 都不会挂载这套工具集(web profile 已挂载 host runner 与浏览器侧组件),所以要显式地添加工具行。
29
+
30
+ ### 最小组合
6
31
 
7
- ## 功能
32
+ ```yaml
33
+ - name: '@deepseek-ai/dsh-cordis-host-runner'
34
+ config:
35
+ vmTimeoutMs: 5000
36
+ - name: '@deepseek-ai/dsh-tool-cordis'
37
+ ```
8
38
 
9
- 两组配对动词,外加只读报告。
39
+ CLI 示例 [`apps/cli/config/examples/cordis/cordis.yml`](../../../apps/cli/config/examples/cordis/cordis.yml) 同时组合了这两者。带浏览器半的包还额外需要客户端组合里的浏览器 runner 与 UI 包;纯 host 包则两者都不需要。
10
40
 
11
- - `cordis_inspect`:当前进程运行时的只读报告,包括服务、全部存活插件 fiber、已注册工具、本会话的动态包、反射支持的 `api`/`events` 参考,以及浏览器半可以向其贡献 UI 的编译期 `client` 槽面。精确的 `name` 配合 `what: "api"`、`what: "events"` 或 `what: "client"` 可缩窄报告,并附上完整约定。
12
- - `cordis_define`:在语法预检两个半之后登记一个包(`name`、`purpose`,以及 host 半 `code` 和/或浏览器半 `client`)。此时不运行任何东西;用户会在会话里看到它的卡片和一个启动控件。铸出的 `dyn-<n>` 标识同时进入结果 value **与**持久的呈现元数据,卡片正是靠后者在 replay 中寻址运行动词。
13
- - `cordis_run`:在沙箱中求值 host 半,并把浏览器半投递给每个打开的网页。对已在运行的包再次运行不会失败,而是重新投递当前版本——这正是被刷新过的页面把包取回来的方式。
14
- - `cordis_stop`:把 host 半 dispose 到完全停稳,并从各页面撤回浏览器半;定义存续,可以再次运行。
15
- - `cordis_undefine`:必要时先停止该包,再忘掉定义;它的卡片作为一条已卸载记录留在会话里。
41
+ ### 工具能做什么
16
42
 
17
- 面向模型的确切 schema 见[生成的工具目录](../../../docs/tool-catalog.zh.md)。
43
+ 三个检查工具只读;四个生命周期工具定义并管理包。所有结果都是渲染成文本的 JSON。
18
44
 
19
- 动态包只存在于共享 DSH 进程内存中。它可跨后续轮次保持活跃,也可能影响同一进程中的其他会话,但会在 `cordis_stop`/`cordis_undefine`、工具集卸载或 DSH 重启后消失。它不会创建插件文件、安装任何包、修改 `cordis.yml` 或个人/项目配置、跨重启存续,也不能自动转为正式插件。若要保留实验结果,应让 agent(智能体)通过常规开发流程实现普通的本地、项目或仓库插件。每个动词都以会话为界:一个包只在定义它的那个会话里可见、可控。
45
+ - `cordis_inspect_list`——列出 Inspect Provider(host 与 client)及其查询方法。
46
+ - `cordis_inspect_query`——执行一次 provider 查询:精确的服务方法、事件分发模式、builtin 签名、工具 schema、主题 token 或实时 slot 树。
47
+ - `cordis_inspect_self`——本会话的动态插件:版本指针、最近一次运行,以及(对某个精确包而言)源码与运行时诊断。
48
+ - `cordis_define`——登记一个包:新插件(`plugin.kind: "new"`,配 3–6 个字母的 `idPrefix`),或既有插件的新版本(`plugin.kind: "existing"`,配其 `pluginId`)。它只校验参数与语法;不运行任何东西,也不请求审批。
49
+ - `cordis_run`——激活一个包(首次激活或重启用 `mode: "run"`,切换版本用 `mode: "update"`)。带浏览器半的包可能先返回 `awaiting-approval`,直到有人允许;工具从不等待最终结果。
50
+ - `cordis_stop`——停止当前运行并取消任何待审批请求,保留插件与全部包版本。
51
+ - `cordis_undefine`——停止并彻底移除一个插件及其全部包。
20
52
 
21
- ## 信任立场
53
+ ### 典型工作流
22
54
 
23
- 该沙箱隔离全局变量,但不是安全边界。Node 全局变量不存在,或会重定向到 `ctx.fs`、`ctx.web`、`ctx.bash` 等 Cordis 服务;写入 `globalThis` 的内容保持局部,但 host realm helper 使逃逸成为可能。运行中的 host 半收到不含框架内部机制的 façade,但获准服务仍会影响存活运行时。动态工具 schema 与 annotation 通过迭代式 JSON 克隆和 schema 规范化跨越 realm,因此有效的深层声明受内存而非调用栈限制;含 JSON 不可见 key 的 record,以及子类化或装饰过的 schema array,会在规范化前被拒绝。应当像对待 bash 访问一样对待该工具集;参见[设计与信任立场](../../../.agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.zh.md)。
55
+ 先检查、再定义、后运行:`cordis_inspect_query` 读取包要用的服务或 slot 的精确约定,`cordis_define` 记录源码(会话里会出现一张 define 卡片,指向存放运行控件的面板),`cordis_run` 激活它。当用户输入 `@pluginId` 时,本包注入一条上下文消息,钉住所引用的插件、其基准包与更新路径。技术性失败之后,用 `cordis_inspect_self` 读取诊断,向同一插件追加修正版,再更新过去。
24
56
 
25
- ## 配置
57
+ ### 需要规划的边界
26
58
 
27
- 无。vm 求值边界(`vmTimeoutMs`)与浏览器确认窗口(`ackTimeoutMs`)属于拥有沙箱与广播的 runner 服务——见 [`@deepseek-ai/dsh-cordis-host-runner`](../cordis-host-runner/README.zh.md#config)。
59
+ 定义以会话为界、以进程为本:包只在定义它的会话里可见可控,可跨后续轮次保持活跃,运行时也可能影响同一进程中的其他会话。停止、移除、卸载工具集或重启 DSH 都会清除它。沙箱隔离全局变量,但不是安全边界——对待动态包要像对待 bash 访问一样,加载本插件时也要像授予 bash 工具那样慎重。
28
60
 
29
- ## 生成的 client 槽目录
61
+ -----
30
62
 
31
- `src/client-catalog.ts` 描述浏览器半的座位,由 `scripts/gen-client-catalog.ts` 生成(新鲜度门禁为 `doc-sync` 中的 `pnpm run verify-client-catalog`),数据来自对每一处 `SlotMap` 声明合并与每一个 `slots.register` 调用点的词法扫描。它承载浏览器半唯一能动的那个面——槽键、每个 register 调用的选项、组件会收到的 props、谁已经占着这个座位、以及哪个 owner 挂着这个座位才存在——并且只以纯数据承载:本包始终在 host 侧、不 import 任何 client 模块,跨越两平面的只有这些字符串。生成器宁可高声失败也不吐出一条模型无法照做的条目:槽缺少面向 registrant 的 JSDoc 正文、`kind`/`scope` 不是字面量、owner props 没有任何导出声明、键重复、或注册进了没人声明的槽,都会让门禁变红。owner props 只展开一层——owner 声明本身连它的成员文档,加上其字段所引用的那些形状的名字——而单个槽的整份报告有行数上限:收窄到一个槽的意义是少花上下文,不是多花。
63
+ <a id="understand-the-implementation"></a>
64
+ ## 理解实现
32
65
 
33
- 一个槽的教学文案就是它声明处的 JSDoc,所以要改模型读到的内容,改的是声明它的那个包里的约定,而不是这份目录。
66
+ <details>
67
+ <summary>实现细节——点击展开</summary>
34
68
 
35
- ## API 报告从哪里来
69
+ 本节解释工具背后的设计;可观察行为已在[使用本包](#use-this-package)中完整说明。
36
70
 
37
- `cordis_inspect what:"api"`/`what:"events"` 渲染的是 `src/api-catalog.ts`,即工作区 Cordis 声明的生成投影:渲染好的方法签名、源码 JSDoc、带分发模式的 harness 事件,以及这些签名引用到的类型形状——全部由与 `docs/subsystems` 同一次 AST 遍历产出,因此模型读到的数据与渲染出的文档不可能彼此偏离。它是关于**仓库**的编译期事实,所以用 `pnpm run gen-cordis-api` 重新生成、用 `pnpm run verify-cordis-api` 守它的新鲜度。
71
+ ### 设计理念
38
72
 
39
- `src/inspect.ts` 把这份目录与**活的**服务存储取交集:**谁在跑**由存储回答,**每个服务能做什么**由目录回答;目录没覆盖到的活服务会被报成可达但没有签名,而不是被省略。包代码若要在自己源码里用这份清单,就从报告里抄出来——目录是关于仓库的编译期事实,所以对任一个部署而言,抄出来的清单与现读的清单说的是同一件事。
73
+ 工具集建立在一个分离之上:工具是 runner 服务之上薄薄的一层模型面向层。检查数据来自生成的目录与实时服务存储的交集;定义与生命周期动词委托给 `ctx.dynamicCordisRunner`,它拥有注册表、vm 沙箱与浏览器往返。工具负责模型面向的判断:只展示可调用的方法、只点名 host 半够得到的键,并且每次拒绝都是模型可以直接行动的教学错误。
40
74
 
41
- 有两项面向模型的判断住在本包里,而不住在产物里,因为反射数据忠于代码,而报告必须有用:
75
+ ### 源码地图
42
76
 
43
- - **只展示可调用的方法。** 非方法成员是状态而不是动词,而它们渲染出来的形式会带上实现体里的初始值;以 symbol 为键的成员是插件之间的内部 seam,包的 façade 刻意无法触达,所以点出其中任何一个,都等于宣传一次根本发不出的调用。
44
- - **只有 host 半够得到的键,才会被点名给模型。** 反射模型覆盖包声明的每一个 `ctx.<key>`,其中包括 launcher 提供的 boot 值(`agent`、`headlessIo` 等)与浏览器半的服务(`connection`)。`src/curation.ts` 会为每一个这样的键归类它的 `reach`——`injectable`、`not-a-service` 或 `other-face`——而只有 `injectable` 的键能进报告:点名一个包够不到的键,就等于宣传一次根本发不出的调用。这份归类是作为每条目录条目上的数据携带的,而不是在渲染时才施加,因此这项排除可以单独测试;同时 `verify-cordis-catalog` 把被归类的集合钉成「文档投影不渲染的键」这个集合本身——新声明一个键会把门禁拦下来,而不是悄悄引诱模型去 `inject` 一个永远不会到来的东西。一个被归类、但确实有存活提供方的键,仍然会被报成在跑且可 inject:服务 store 才是「什么存在」的权威。
77
+ | 文件 | 职责 |
78
+ |---|---|
79
+ | [`src/index.ts`](src/index.ts) | 插件入口:工具注册、系统提示词章节、`@pluginId` 上下文注入 |
80
+ | [`src/inspect.ts`](src/inspect.ts) | 报告渲染:把生成的 API 目录与实时服务存储相交 |
81
+ | [`src/api-catalog.ts`](src/api-catalog.ts) | 工作区 Cordis 声明的生成投影(由 `pnpm run gen-cordis-api` 重新生成,`verify-cordis-api` 守其新鲜度) |
82
+ | [`src/prompt.ts`](src/prompt.ts) | `tool:cordis` 系统提示词章节 |
83
+ | [`src/providers.ts`](src/providers.ts) | 第一方 host Inspect Provider:Service、Event、Builtin、Tool |
84
+ | [`src/present.ts`](src/present.ts) | 可回放的通用卡片渲染意图 |
45
85
 
46
- 生成常量 `INHERITED_CTX_API` 为 `api` 报告收尾,列出框架继承来的 `ctx` 面(`ctx.on`、`ctx.effect`、`ctx.loader`、各 timer 辅助方法):这些成员本身就是 Context,不是某个服务键;而框架层住在 pinned vendor 包里,位于每一个被分析的契约面之外——所以生成器策展这**一层**,并把它同时渲染进本目录与 `docs/cordis-api/inherited.md`。一个活着、但目录并不描述的服务,会被报成“在跑、且仍可 inject”,而不是报成不存在。宽泛的 `api`/`events` 报告只渲染摘要与签名;精确 `name` 会选择保留的方法/事件 JSDoc,未知或未运行的服务目标会高声失败。
86
+ ### 一次调用的流程
47
87
 
48
- ## 渲染
88
+ 检查调用查询 `ctx.cordisInspect`:host provider 本地执行,client provider 等待第一个有效的页面应答。define 用与沙箱相同的包装器编译每一半来做语法预检,因此无法解析的代码在拿到 id 之前就被拒绝。run 委托给 runner:纯 host 包在进程内激活,带浏览器半的包挂起在 `cordis/request-run` 往返上;工具返回 runner 的回执(`awaiting-approval`、`starting` 或 `running`)。当用户写下 `@pluginId` 时,一个 `agent/pre-step` 处理器读取引用,并注入一条 user 角色的上下文消息,点明基准包与必须的后续步骤。
49
89
 
50
- 每个工具都渲染 `generic` 卡片(`read`/`execute`/`delete`);`cordis_define` 以 `rawInput` 携带提交的两个半,并用标签与用途作为卡片标题。presenter 是 args 的纯函数,结果保留默认文本渲染。Web 客户端注册自己的 keyed `cordis_define` 行(`@deepseek-ai/dsh-client-ui-cordis`),从调用参数与结果元数据里取标签、用途和铸出的标识;没有该注册的界面则退回到这张 generic 卡片。
90
+ </details>
51
91
 
52
- ## 导出形式
92
+ -----
53
93
 
54
- Namespace 插件:命名导出 `name`/`inject`/`apply`,无默认导出([docs/postmortem/0001](../../../docs/postmortem/0001-acp-default-export-drops-inject.zh.md))。它注入 `tools` 与 `dynamicCordisRunner`。
94
+ <a id="further-exploration"></a>
95
+ ## 进一步探索
55
96
 
97
+ 当包级约定不够用时阅读以下页面。它们从共享工具集逐步进入 runner 内部、生成 schema 与子系统表面。
98
+
99
+ - [Host runner](../cordis-host-runner/README.zh.md)——这些工具委托的注册表、沙箱与运行往返。
100
+ - [Client runner](../cordis-client-runner/README.zh.md)——应答运行请求并装载浏览器半代码的浏览器半。
101
+ - [UI 包](../ui-cordis/README.zh.md)——用户操作定义所用的面板与工具卡片。
102
+ - [生成的工具目录](../../../docs/tool-catalog.zh.md#deepseek-aidsh-tool-cordis)——模型收到的确切 schema。
103
+ - [extensions 子系统](../../../docs/subsystems/extensions.zh.md)——生成的 `ctx.cordisInspect` 与 `ctx.dynamicCordisRunner` API。
104
+ - [自引用 Cordis 工具集 Agent Note](../../../.agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.zh.md)——设计居所:沙箱语义、动态包生命周期与组合。
105
+
106
+ -----
107
+
108
+ <a id="model-experience"></a>
56
109
  ## 模型体验
57
110
 
58
111
  ### 工具 schema
59
112
 
60
113
  #### 模型看到的内容
61
114
 
62
- 该插件可见时,会话模型会看到生成的 [`cordis_inspect`、`cordis_define`、`cordis_run`、`cordis_stop` 和 `cordis_undefine` schema](../../../docs/tool-catalog.zh.md#deepseek-aidsh-tool-cordis)。
115
+ 该插件可见时,会话模型会看到生成的 [`cordis_inspect_list`、`cordis_inspect_query`、`cordis_inspect_self`、`cordis_define`、`cordis_run`、`cordis_stop` 和 `cordis_undefine` schema](../../../docs/tool-catalog.zh.md#deepseek-aidsh-tool-cordis)。
63
116
 
64
117
  #### Token 影响
65
118
 
@@ -69,25 +122,47 @@ Namespace 插件:命名导出 `name`/`inject`/`apply`,无默认导出(
69
122
 
70
123
  只要该工具视图不变,前缀就保持稳定。隐藏这些定义的 scope 或插件生命周期变更,可能使从第一个变化的 schema token 起的复用失效。
71
124
 
125
+ ### 系统提示词章节
126
+
127
+ #### 模型看到的内容
128
+
129
+ 本包注册一个系统提示词章节(`tool:cordis`,order 115),教模型何时以及如何使用动态包工作流、推荐的工具顺序与必须避免的高频错误;完整文本在 [`src/prompt.ts`](src/prompt.ts) 中。章节开头如下:
130
+
131
+ ##### 章节开头
132
+
133
+ ```markdown
134
+ # Dynamic Cordis Plugins
135
+
136
+ Dynamic Cordis plugins temporarily extend the current DSH process. A Plugin uses apply(ctx) to consume Services, listen to Events, provide Services, register model Tools, or register browser UI in Slots.
137
+ ```
138
+
139
+ #### Token 影响
140
+
141
+ 该插件可见时,章节渲染出的文本会在每次请求中重复。
142
+
143
+ #### KV Cache 影响
144
+
145
+ 只要章节文本与顺序不变,前缀就保持稳定;编辑提示词或改变其顺序可能使从第一个变化 token 起的复用失效。
146
+
72
147
  ### 工具调用历史与结果
73
148
 
74
149
  #### 模型看到的内容
75
150
 
76
- 检查会精确地用 `## <section>` 加换行及取决于数据的正文来拼接选中区段,各区段之间留一个空行;`what: "temporary"` 使用 `## Dynamic Packages` 标题。每一行都会报告标识、标签、用途、存在哪些半、运行状态与版本号、提供和等待的服务、已注册的 host 方法,以及最后一次浏览器半装载上报;空状态说明定义只存在于本进程内存中。宽泛的 API/事件报告省略 JSDoc;`name` 配合 `what: "api"`、`what: "events"` 或 `what: "client"` 返回一个精确目标及其完整约定。`client` 区段每个座位一行,给出其基数、作用域、摘要,以及注册进去是否会替换出厂 UI,随后是跨座位通用的 registrant 纪律;每个座位的 register 选项、owner 与框架 props、可直接运行的示例,只在精确 `name` 时才吐出。define 回答该包已定义、尚未运行,并给出用于运行的标识;run 报告版本号、host 半提供或等待什么,以及是否有页面确认了浏览器半;stop 与 undefine 各以一行确认。每一次拒绝都是携带 runner 教学文案的工具错误。提交的程序保留在 assistant 工具调用历史中。
151
+ 检查输出是渲染成文本的 JSON:`cordis_inspect_list` 返回 provider 目录,`cordis_inspect_query` 返回查询数据,`cordis_inspect_self` 返回插件、版本与包摘要,并在指定精确包时给出源码与诊断。define 回答该包已定义、尚未运行,并给出用于运行的 id。run 报告 `awaiting-approval`、`starting` 或 `running`,附运行 id 与版本指针。stop 与 undefine 各以一行确认。每一次拒绝都是携带 runner 教学文本的工具错误,提交的程序保留在 assistant 工具调用历史中。
77
152
 
78
153
  #### Token 影响
79
154
 
80
- 检查输出与提交的包代码取决于数据,并在压缩(compaction)前重复发送;生命周期确认文本很短。`client` 区段的体量由出厂槽数量决定(每座位两行),每座位细节按需索取,因此默认报告随槽面增长,而不是随其文档量增长。
155
+ 检查输出与提交的包代码取决于数据,并在压缩(compaction)前重复发送;生命周期确认文本很短。
81
156
 
82
157
  #### KV Cache 影响
83
158
 
84
159
  仅追加;新可见内容位于可复用请求前缀之后,不会使现有 KV Cache 条目失效。
85
160
 
86
- ### cordis_run 后的后续请求
161
+ ### cordis_run 之后的后续请求
87
162
 
88
163
  #### 模型看到的内容
89
164
 
90
- 运行中的包可以注册工具、提示词贡献或监听器,改变其目标 scope 的后续请求;`cordis_stop` 与 `cordis_undefine` 会在完全停稳后移除这些贡献。
165
+ 运行中的包可能注册工具、提示词贡献或监听器,改变其目标 scope 的后续请求;`cordis_stop` 与 `cordis_undefine` 会在完全停稳后移除这些贡献。当用户输入 `@pluginId` 时,注入的引用上下文还会增加一条 user 角色的消息,点明基准包与后续步骤。
91
166
 
92
167
  #### Token 影响
93
168
 
@@ -97,8 +172,23 @@ Namespace 插件:命名导出 `name`/`inject`/`apply`,无默认导出(
97
172
 
98
173
  运行或停止提示词/工具贡献会改变后续请求前缀,并可能使从第一个变化的贡献起的复用失效;运行集合不变时,前缀保持稳定。
99
174
 
100
- ## 已知限制与暂缓事项
175
+ ## 已知限制与延期工作
176
+
177
+ <a id="known-limitations-and-deferred-work"></a>
178
+
179
+
180
+ 这些限制说明工具集何时不合适或需要特别小心。它们是当前包约束,不是任务积压。
181
+
182
+ - **沙箱只用于约束诚实代码,并非安全边界**——可以触及沙箱全局变量上的 host realm helper,因此包代码可以触达 Node;加载本插件时,应当像授予 bash 工具一样慎重。
183
+ - **只支持纯 JavaScript**——动态包代码不做任何转换:没有 TypeScript、JSX 或 import,沙箱还扣下 `require`、`setTimeout`、`fetch` 等 Node 全局,把文件、网络与进程工作重定向到 Cordis 服务。
184
+ - **vm 与审批边界属于 runner**——见它的[已知限制](../cordis-host-runner/README.zh.md#known-limitations-and-deferred-work);async 的 host 半主体可逃出 `vmTimeoutMs`。
185
+
186
+ <a id="dev-note"></a>
187
+ ### 开发备注
188
+
189
+ <details>
190
+ <summary>维护者的工作上下文——点击展开</summary>
191
+
192
+ 无。
101
193
 
102
- - **沙箱只用于约束诚实代码,并非安全边界**:可以访问沙箱全局变量上的 host realm helper,因此包代码可以触达 Node;加载该插件时,应当像授予 bash 工具一样慎重(见 § 信任立场)。
103
- - **`ctx` façade 不公开 `effect()`**:包代码无法注册定制 disposer;`on`/`provide`/`tools.register` 是受支持的清理路径。
104
- - **vm 与确认窗口这两个边界属于 runner**:见它的[已知限制](../cordis-host-runner/README.zh.md#known-limitations-and-deferred-work);async 的 host 半主体可逃出 `vmTimeoutMs`。
194
+ </details>