Merge remote-tracking branch 'origin/master' into worktree/custom-provider-edit-parity-f8c160

This commit is contained in:
Yichen Jiang
2026-08-11 15:16:23 +08:00
2325 changed files with 38307 additions and 17353 deletions

View File

@@ -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/api-gateway.md
api-gateway.md: 81cd80893d53212edc74cc85e3e05731fa05f411
api-gateway.zh.md: 692cf825f619f71e86ae801e04246e9feb4a4c36
api-gateway.md: 3065f3f10861965b327a4412049878dc1ba7faec
api-gateway.zh.md: aa9b726c33fd9f51fc0b2d2ed95c4c9658662796

View File

@@ -17,7 +17,7 @@ Services normally extend `GatewayService` so the constructor explicitly binds th
```ts
import type { Agent } from '@deepseek-ai/dsh-agent'
import { GatewayService, Remote, RemoteScope } from '@deepseek-ai/dsh-type-meta'
import type { Context } from 'cordis'
import type { Context } from '@deepseek-ai/cordis'
export interface CreateGoalRequest {
objective: string
@@ -60,7 +60,7 @@ The Client uses concrete functions on ordinary objects, not a JavaScript Proxy.
```ts ignore-check
import type { SessionId } from '@deepseek-ai/dsh-session/types'
import type { AgentContext } from '@deepseek-ai/dsh-client-runtime/client'
import type { Context } from 'cordis'
import type { Context } from '@deepseek-ai/cordis'
import type {} from '@deepseek-ai/dsh-api-remotes/client'
export const inject = ['remote', 'remote.goals']
@@ -138,16 +138,10 @@ SRC solves only dispatch for a Host process running from source. The Client does
## Development mode
A complete build generates Host contracts before compiling the Host, Client, and Web, so it is the deterministic entry for creating or refreshing all artifacts:
The repository `dsh` script completes the Host, Client, and Web build before starting the source Host. Web development runs that command and the Client plugin watcher in separate terminals:
```sh
pnpm run build
```
Web development normally starts the source Host after one complete build and runs the Client plugin watcher in another terminal:
```sh
pnpm run dsh -- web --dev
pnpm dsh web --dev
pnpm run dev:web
```

View File

@@ -17,7 +17,7 @@ Service 通常继承 `GatewayService`,让 Cordis service key 与默认 Remote
```ts
import type { Agent } from '@deepseek-ai/dsh-agent'
import { GatewayService, Remote, RemoteScope } from '@deepseek-ai/dsh-type-meta'
import type { Context } from 'cordis'
import type { Context } from '@deepseek-ai/cordis'
export interface CreateGoalRequest {
objective: string
@@ -60,7 +60,7 @@ Client 使用普通对象上的具体函数,不使用 JavaScript Proxy。直
```ts ignore-check
import type { SessionId } from '@deepseek-ai/dsh-session/types'
import type { AgentContext } from '@deepseek-ai/dsh-client-runtime/client'
import type { Context } from 'cordis'
import type { Context } from '@deepseek-ai/cordis'
import type {} from '@deepseek-ai/dsh-api-remotes/client'
export const inject = ['remote', 'remote.goals']
@@ -138,16 +138,10 @@ SRC 只解决 Host 源码进程的分发问题。Client 不会从运行中的 Ho
## 开发模式
完整构建会先成 Host 约定,再编译 Host、Client 与 Web因此是建立或刷新所有产物的确定性入口
仓库的 `dsh` 脚本会先成 Host、Client 与 Web 构建,再启动源码 Host。Web 开发需要在两个终端中分别运行该命令和 Client plugin watcher
```sh
pnpm run build
```
Web 开发通常在完成一次构建后启动源码 Host并在另一个终端运行 Client plugin watcher
```sh
pnpm run dsh -- web --dev
pnpm dsh web --dev
pnpm run dev:web
```

View File

@@ -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/architecture.md
architecture.md: 8d1c5a1be391e2455aefc69db89d96027aaf3efa
architecture.zh.md: 53bf9f54a5503ae40aa62a348822f9d92162dda2
architecture.md: aeda7f9674e75a1e97549f25c13d571b3b37ee8c
architecture.zh.md: a25f20ba9babefeaab4636027e97d6f2d4ae8caf

View File

@@ -42,6 +42,7 @@ Harnesses are [Cordis](cordis-primer.md) contexts; packages contribute services,
| `ctx.tasks` | [`tasks/`](../packages/tasks/README.md) | background task registry, generic `task_*` controls |
| `ctx.workflows` | [`workflow/`](../packages/workflow/README.md) | script-driven multi-agent orchestration |
| `ctx.goals` | [`goal/`](../packages/goal/README.md) | persisted same-session goals |
| `ctx.messageFeedback` | [`feedback/`](../packages/feedback/README.md) | lifecycle-bound editable feedback for individual assistant messages and its Host Remote contract |
| `ctx.sessionPersistence` | [`session/`](../packages/session/README.md) | durable session-log storage |
| `ctx.sessionQuery` | [`session-query/`](../packages/session-query/README.md) | live-preferred exact/filter/trace queries over SQLite FTS, workspace-authorized model tools |
| `ctx.sessionTitle` | [`session/session-title`](../packages/session/README.md) | log-backed fallbacks, one optional asynchronous provider |

View File

@@ -42,6 +42,7 @@
| `ctx.tasks` | [`tasks/`](../packages/tasks/README.md) | 后台任务注册表和通用 `task_*` 控制 |
| `ctx.workflows` | [`workflow/`](../packages/workflow/README.md) | 脚本驱动的多 agent 编排 |
| `ctx.goals` | [`goal/`](../packages/goal/README.md) | 持久化的同会话目标 |
| `ctx.messageFeedback` | [`feedback/`](../packages/feedback/README.md) | 绑定生命周期的单条 assistant 消息可编辑反馈及其 Host Remote 契约 |
| `ctx.sessionPersistence` | [`session/`](../packages/session/README.md) | 会话日志的持久化存储 |
| `ctx.sessionQuery` | [`session-query/`](../packages/session-query/README.md) | 基于 SQLite 全文搜索的实时优先精确检索/过滤/追踪、经工作区授权的模型工具 |
| `ctx.sessionTitle` | [`session/session-title`](../packages/session/README.md) | 基于日志的回退标题和单个可选异步提供方 |

View File

@@ -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/capability-seams.md
capability-seams.md: c102167aa76b9ba613b1b434cb0aa58765d26106
capability-seams.zh.md: 7c4eab8d5a2d890bdf4513bb9acdc81f55414642
capability-seams.md: 64d20b1bfb609aec3acb3673e4589516bb315bfa
capability-seams.zh.md: 10b5116d12991319df55c551d51840bb566ac898

View File

@@ -30,6 +30,7 @@ flowchart LR
pkg_session_query_sqlite["session-query-sqlite"]
pkg_subagent_inprocess["subagent-inprocess"]
pkg_invariants["invariants"]
pkg_message_feedback["message-feedback"]
svc_invariants["ctx.invariants<br/>Package-owned invariant registry"]
pkg_scope["scope"]
pkg_typert_registry["typert-registry"]
@@ -60,6 +61,7 @@ flowchart LR
pkg_storage_domain["storage-domain"]
svc_storageDomain["ctx.storageDomain<br/>Domain data facility"]
pkg_workspace["workspace"]
svc_messageFeedback["ctx.messageFeedback<br/>Lifecycle-bound message feedback"]
svc_workspace["ctx.workspace<br/>Workspace entity registry"]
svc_sessionQuery["ctx.sessionQuery<br/>Session reads, traces, filters, and search"]
pkg_session_reference["session-reference"]
@@ -218,6 +220,7 @@ flowchart LR
pkg_llm_deepseek --> svc_llm
pkg_llm_pi_ai --> svc_llm
pkg_llm_replay --> svc_llm
pkg_message_feedback --> svc_messageFeedback
pkg_modules --> svc_clientModuleHost
pkg_permission --> svc_permission
pkg_plan_mode --> svc_planMode
@@ -322,6 +325,7 @@ flowchart LR
svc_sessionPersistence --> pkg_agent_loop
svc_sessionPersistence --> pkg_hooks_claude
svc_sessionPersistence --> pkg_hooks_codex
svc_sessionPersistence --> pkg_message_feedback
svc_sessionPersistence --> pkg_session_query
svc_sessionPersistence --> pkg_session_query_sqlite
svc_sessionPersistence --> pkg_tool_bash
@@ -334,6 +338,7 @@ flowchart LR
svc_sessions --> pkg_agent
svc_sessions --> pkg_agent_loop
svc_sessions --> pkg_invariants
svc_sessions --> pkg_message_feedback
svc_sessions --> pkg_session_persistence
svc_sessions --> pkg_session_query
svc_sessions --> pkg_session_query_sqlite
@@ -344,6 +349,7 @@ flowchart LR
svc_skills --> pkg_tool_skill
svc_spillStore --> pkg_spill_policy
svc_storage --> pkg_storage_domain
svc_storageDomain --> pkg_message_feedback
svc_storageDomain --> pkg_workspace
svc_subagents --> pkg_tool_ralph
svc_subagents --> pkg_tool_subagent
@@ -392,16 +398,17 @@ flowchart LR
| `ctx.llm` | `seam` | [`llm`](../packages/llm/llm) | [`llm-deepseek`](../packages/llm/llm-deepseek), [`llm-pi-ai`](../packages/llm/llm-pi-ai), [`llm-replay`](../packages/support/llm-replay) | [`agent-loop`](../packages/core/agent-loop), [`compact-basic`](../packages/compact/compact-basic) | - | Adapters register provider implementations; the loop and compaction call the provider-neutral stream service. |
| `ctx.tokenMeter` | `core` | [`token-meter`](../packages/llm/token-meter) | - | [`compact-basic`](../packages/compact/compact-basic) | - | Owns isolated per-session replay folds; pressure consumers share immutable revisioned measurements. |
| `ctx.toolResultPrune` | `core` | [`compact-tool-result-prune`](../packages/compact/compact-tool-result-prune) | - | [`compact-basic`](../packages/compact/compact-basic) | - | Rewrites oversized current tool results through replayable single-node surface replacements before summary compaction. |
| `ctx.sessions` | `core` | [`session`](../packages/core/session) | - | [`agent-loop`](../packages/core/agent-loop), [`agent`](../packages/core/agent), [`session-persistence`](../packages/session/session-persistence), [`session-query`](../packages/session-query/session-query), [`session-query-sqlite`](../packages/session-query/session-query-sqlite), [`subagent-inprocess`](../packages/subagent/subagent-inprocess), [`invariants`](../packages/support/invariants) | - | Owns append-only Session instances and emits the durable session event feed. |
| `ctx.sessions` | `core` | [`session`](../packages/core/session) | - | [`agent-loop`](../packages/core/agent-loop), [`agent`](../packages/core/agent), [`session-persistence`](../packages/session/session-persistence), [`session-query`](../packages/session-query/session-query), [`session-query-sqlite`](../packages/session-query/session-query-sqlite), [`subagent-inprocess`](../packages/subagent/subagent-inprocess), [`invariants`](../packages/support/invariants), [`message-feedback`](../packages/feedback/message-feedback) | - | Owns append-only Session instances and emits the durable session event feed. |
| `ctx.invariants` | `core` | [`invariants`](../packages/support/invariants) | - | [`session`](../packages/core/session), [`agent`](../packages/core/agent), [`scope`](../packages/core/scope), [`agent-loop`](../packages/core/agent-loop) | - | Companion subpaths register owner-local checks; the service owns selection, uniqueness, child fibers, and package-attributed failures. |
| `ctx.typert` | `core` | [`typert-registry`](../packages/typert/registry) | - | [`typert-loader`](../packages/typert/loader), [`api-gateway`](../packages/api/gateway) | - | Plugins register live zod contributions directly or through dsh-typert-loader; the API gateway consumes invocation descriptors and providers, while other runtime consumers query schemas and reflection metadata at their own edges. |
| `ctx.typertGateway` | `core` | [`api-gateway`](../packages/api/gateway) | - | - | - | Associates generated Remote descriptors with live Cordis services, resolves registered identities, and exposes unary calls through the shared Connection RPC carrier. |
| `ctx.sessionPersistence` | `seam` | [`session-persistence`](../packages/session/session-persistence) | [`session-persistence-jsonl`](../packages/session/session-persistence-jsonl), [`session-persistence-sqlite`](../packages/session/session-persistence-sqlite) | [`agent-loop`](../packages/core/agent-loop), [`tool-bash`](../packages/bash/tool-bash), [`hooks-claude`](../packages/hooks/hooks-claude), [`hooks-codex`](../packages/hooks/hooks-codex), [`session-query`](../packages/session-query/session-query), [`session-query-sqlite`](../packages/session-query/session-query-sqlite) | - | Backends persist the same SessionEvent vocabulary; apps choose a backend at composition time. |
| `ctx.sessionPersistence` | `seam` | [`session-persistence`](../packages/session/session-persistence) | [`session-persistence-jsonl`](../packages/session/session-persistence-jsonl), [`session-persistence-sqlite`](../packages/session/session-persistence-sqlite) | [`agent-loop`](../packages/core/agent-loop), [`tool-bash`](../packages/bash/tool-bash), [`hooks-claude`](../packages/hooks/hooks-claude), [`hooks-codex`](../packages/hooks/hooks-codex), [`session-query`](../packages/session-query/session-query), [`session-query-sqlite`](../packages/session-query/session-query-sqlite), [`message-feedback`](../packages/feedback/message-feedback) | - | Backends persist the same SessionEvent vocabulary; apps choose a backend at composition time. |
| `ctx.settings` | `seam` | [`settings`](../packages/settings/settings) | [`settings-local`](../packages/settings/settings-local) | [`llm-deepseek`](../packages/llm/llm-deepseek), [`llm-pi-ai`](../packages/llm/llm-pi-ai), `apiproxy` | - | Plugins register namespace schemas and resolve layered values; providers store the raw document. The LLM adapters register their entry config as the composition base under the user section; the web gateway serves redacted layered descriptors and writes the user layer. |
| `ctx.credentials` | `seam` | [`credentials`](../packages/credentials/credentials) | [`credentials-local`](../packages/credentials/credentials-local) | [`llm-deepseek`](../packages/llm/llm-deepseek), [`llm-pi-ai`](../packages/llm/llm-pi-ai), `apiproxy` | - | Configuration carries references to secrets; providers own the values. Consumers resolve per operation, so a rotated credential reaches the very next request; the web gateway exposes value-free views and write-only storage. |
| `ctx.telemetry` | `seam` | [`session-telemetry`](../packages/session/session-telemetry) | [`session-telemetry-otel`](../packages/session/session-telemetry-otel) | - | - | The seam captures, redacts, and hands session records to one backend; nothing else consumes the service — its output leaves the process. |
| `ctx.storage` | `seam` | [`storage`](../packages/storage/storage) | [`storage-json`](../packages/storage/storage-json), [`storage-sqlite`](../packages/storage/storage-sqlite) | [`storage-domain`](../packages/storage/storage-domain) | - | Backends register side by side under names; data forms (domain first) mount on the hub and translate typed operations into opaque KV-unit primitives. |
| `ctx.storageDomain` | `core` | [`storage-domain`](../packages/storage/storage-domain) | - | [`workspace`](../packages/workspace/workspace) | - | Waits for every configured backend, then publishes the domain form as one lifecycle-bound service for typed durable state. |
| `ctx.storageDomain` | `core` | [`storage-domain`](../packages/storage/storage-domain) | - | [`workspace`](../packages/workspace/workspace), [`message-feedback`](../packages/feedback/message-feedback) | - | Waits for every configured backend, then publishes the domain form as one lifecycle-bound service for typed durable state. |
| `ctx.messageFeedback` | `core` | [`message-feedback`](../packages/feedback/message-feedback) | - | - | - | Owns local per-assistant-message feedback, lifecycle and target validation, per-item compare-and-set, and the Host unary Remote contract without entering Session history or telemetry. |
| `ctx.workspace` | `core` | [`workspace`](../packages/workspace/workspace) | - | `apiproxy` | - | Owns WorkspaceId-branded records over the domain facility; stable sessionIds accounts drive Host RPC and GUI projections. |
| `ctx.sessionQuery` | `seam` | [`session-query`](../packages/session-query/session-query) | [`session-query-sqlite`](../packages/session-query/session-query-sqlite) | [`session-reference`](../packages/context/session-reference), [`tool-session-query`](../packages/session-query/tool-session-query) | - | The interface supplies exact reads, filters, and traces; its concrete backend adds full-text reconciliation, ranking, snippets, and cursor generations, while the model consumer owns workspace authority and cursor-free rendering. |
| `ctx.sessionReferences` | `core` | [`session-reference`](../packages/context/session-reference) | - | - | - | Projects bounded current-surface conversation snapshots into durable untrusted message context; host adapters own mention syntax. |

View File

@@ -32,6 +32,7 @@ flowchart LR
pkg_session_query_sqlite["session-query-sqlite"]
pkg_subagent_inprocess["subagent-inprocess"]
pkg_invariants["invariants"]
pkg_message_feedback["message-feedback"]
svc_invariants["ctx.invariants<br/>Package-owned invariant registry"]
pkg_scope["scope"]
pkg_typert_registry["typert-registry"]
@@ -62,6 +63,7 @@ flowchart LR
pkg_storage_domain["storage-domain"]
svc_storageDomain["ctx.storageDomain<br/>Domain data facility"]
pkg_workspace["workspace"]
svc_messageFeedback["ctx.messageFeedback<br/>Lifecycle-bound message feedback"]
svc_workspace["ctx.workspace<br/>Workspace entity registry"]
svc_sessionQuery["ctx.sessionQuery<br/>Session reads, traces, filters, and search"]
pkg_session_reference["session-reference"]
@@ -220,6 +222,7 @@ flowchart LR
pkg_llm_deepseek --> svc_llm
pkg_llm_pi_ai --> svc_llm
pkg_llm_replay --> svc_llm
pkg_message_feedback --> svc_messageFeedback
pkg_modules --> svc_clientModuleHost
pkg_permission --> svc_permission
pkg_plan_mode --> svc_planMode
@@ -324,6 +327,7 @@ flowchart LR
svc_sessionPersistence --> pkg_agent_loop
svc_sessionPersistence --> pkg_hooks_claude
svc_sessionPersistence --> pkg_hooks_codex
svc_sessionPersistence --> pkg_message_feedback
svc_sessionPersistence --> pkg_session_query
svc_sessionPersistence --> pkg_session_query_sqlite
svc_sessionPersistence --> pkg_tool_bash
@@ -336,6 +340,7 @@ flowchart LR
svc_sessions --> pkg_agent
svc_sessions --> pkg_agent_loop
svc_sessions --> pkg_invariants
svc_sessions --> pkg_message_feedback
svc_sessions --> pkg_session_persistence
svc_sessions --> pkg_session_query
svc_sessions --> pkg_session_query_sqlite
@@ -346,6 +351,7 @@ flowchart LR
svc_skills --> pkg_tool_skill
svc_spillStore --> pkg_spill_policy
svc_storage --> pkg_storage_domain
svc_storageDomain --> pkg_message_feedback
svc_storageDomain --> pkg_workspace
svc_subagents --> pkg_tool_ralph
svc_subagents --> pkg_tool_subagent
@@ -394,16 +400,17 @@ flowchart LR
| `ctx.llm` | `seam` | [`llm`](../packages/llm/llm) | [`llm-deepseek`](../packages/llm/llm-deepseek)、[`llm-pi-ai`](../packages/llm/llm-pi-ai)、[`llm-replay`](../packages/support/llm-replay) | [`agent-loop`](../packages/core/agent-loop)、[`compact-basic`](../packages/compact/compact-basic) | - | 适配器注册提供方实现agent loop智能体循环与压缩功能调用提供方无关的流服务。 |
| `ctx.tokenMeter` | `core` | [`token-meter`](../packages/llm/token-meter) | - | [`compact-basic`](../packages/compact/compact-basic) | - | 拥有按会话隔离的回放折叠区;压力消费方共享不可变且带修订版本的测量结果。 |
| `ctx.toolResultPrune` | `core` | [`compact-tool-result-prune`](../packages/compact/compact-tool-result-prune) | - | [`compact-basic`](../packages/compact/compact-basic) | - | 在摘要压缩前,通过可回放的单节点表层替换来改写过大的当前工具结果。 |
| `ctx.sessions` | `core` | [`session`](../packages/core/session) | - | [`agent-loop`](../packages/core/agent-loop)、[`agent`](../packages/core/agent)、[`session-persistence`](../packages/session/session-persistence)、[`session-query`](../packages/session-query/session-query)、[`session-query-sqlite`](../packages/session-query/session-query-sqlite)、[`subagent-inprocess`](../packages/subagent/subagent-inprocess)、[`invariants`](../packages/support/invariants) | - | 拥有仅追加的 Session 实例,并发出持久的会话事件流。 |
| `ctx.sessions` | `core` | [`session`](../packages/core/session) | - | [`agent-loop`](../packages/core/agent-loop)、[`agent`](../packages/core/agent)、[`session-persistence`](../packages/session/session-persistence)、[`session-query`](../packages/session-query/session-query)、[`session-query-sqlite`](../packages/session-query/session-query-sqlite)、[`subagent-inprocess`](../packages/subagent/subagent-inprocess)、[`invariants`](../packages/support/invariants)、[`message-feedback`](../packages/feedback/message-feedback) | - | 拥有仅追加的 Session 实例,并发出持久的会话事件流。 |
| `ctx.invariants` | `core` | [`invariants`](../packages/support/invariants) | - | [`session`](../packages/core/session)、[`agent`](../packages/core/agent)、[`scope`](../packages/core/scope)、[`agent-loop`](../packages/core/agent-loop) | - | 配套子路径注册所属包本地的检查;该服务负责选择、唯一性、子 fiber以及标明所属包的失败。 |
| `ctx.typert` | `core` | [`typert-registry`](../packages/typert/registry) | - | [`typert-loader`](../packages/typert/loader)、[`api-gateway`](../packages/api/gateway) | - | 插件直接或通过 dsh-typert-loader 注册实时 zod 贡献API 网关消费调用描述符和提供方,其他运行时消费方则在各自边界查询 schema 与反射元数据。 |
| `ctx.typertGateway` | `core` | [`api-gateway`](../packages/api/gateway) | - | - | - | 将生成的 Remote 描述符与实时 Cordis 服务关联,解析已注册的身份,并通过共享的 Connection RPC 载体提供一元调用。 |
| `ctx.sessionPersistence` | `seam` | [`session-persistence`](../packages/session/session-persistence) | [`session-persistence-jsonl`](../packages/session/session-persistence-jsonl)、[`session-persistence-sqlite`](../packages/session/session-persistence-sqlite) | [`agent-loop`](../packages/core/agent-loop)、[`tool-bash`](../packages/bash/tool-bash)、[`hooks-claude`](../packages/hooks/hooks-claude)、[`hooks-codex`](../packages/hooks/hooks-codex)、[`session-query`](../packages/session-query/session-query)、[`session-query-sqlite`](../packages/session-query/session-query-sqlite) | - | 各后端持久化同一套 SessionEvent 词汇;应用在组合时选择后端。 |
| `ctx.sessionPersistence` | `seam` | [`session-persistence`](../packages/session/session-persistence) | [`session-persistence-jsonl`](../packages/session/session-persistence-jsonl)、[`session-persistence-sqlite`](../packages/session/session-persistence-sqlite) | [`agent-loop`](../packages/core/agent-loop)、[`tool-bash`](../packages/bash/tool-bash)、[`hooks-claude`](../packages/hooks/hooks-claude)、[`hooks-codex`](../packages/hooks/hooks-codex)、[`session-query`](../packages/session-query/session-query)、[`session-query-sqlite`](../packages/session-query/session-query-sqlite)、[`message-feedback`](../packages/feedback/message-feedback) | - | 各后端持久化同一套 SessionEvent 词汇;应用在组合时选择后端。 |
| `ctx.settings` | `seam` | [`settings`](../packages/settings/settings) | [`settings-local`](../packages/settings/settings-local) | [`llm-deepseek`](../packages/llm/llm-deepseek)、[`llm-pi-ai`](../packages/llm/llm-pi-ai)、`apiproxy` | - | 插件注册命名空间 schema 并解析分层值提供方存储原始文档。LLM大语言模型适配器在用户分区下将其入口配置注册为组合基础Web 网关提供经过脱敏的分层描述符,并写入用户层。 |
| `ctx.credentials` | `seam` | [`credentials`](../packages/credentials/credentials) | [`credentials-local`](../packages/credentials/credentials-local) | [`llm-deepseek`](../packages/llm/llm-deepseek)、[`llm-pi-ai`](../packages/llm/llm-pi-ai)、`apiproxy` | - | 配置携带对机密信息的引用提供方拥有实际值。消费方按操作解析因此轮换后的凭据会在紧接着的下一次请求中生效Web 网关提供不含实际值的视图和只写存储。 |
| `ctx.telemetry` | `seam` | [`session-telemetry`](../packages/session/session-telemetry) | [`session-telemetry-otel`](../packages/session/session-telemetry-otel) | - | - | 该 seam 捕获会话记录、进行脱敏并交给一个后端;没有其他组件消费该服务,其输出会离开当前进程。 |
| `ctx.storage` | `seam` | [`storage`](../packages/storage/storage) | [`storage-json`](../packages/storage/storage-json)、[`storage-sqlite`](../packages/storage/storage-sqlite) | [`storage-domain`](../packages/storage/storage-domain) | - | 各后端以不同名称并列注册;数据形态(领域优先)挂载到枢纽上,并将类型化操作转换为不透明的 KV 单元原语。 |
| `ctx.storageDomain` | `core` | [`storage-domain`](../packages/storage/storage-domain) | - | [`workspace`](../packages/workspace/workspace) | - | 等待所有已配置后端就绪,然后将领域形态发布为一个受生命周期约束的服务,用于类型化持久状态。 |
| `ctx.storageDomain` | `core` | [`storage-domain`](../packages/storage/storage-domain) | - | [`workspace`](../packages/workspace/workspace)、[`message-feedback`](../packages/feedback/message-feedback) | - | 等待所有已配置后端就绪,然后将领域形态发布为一个受生命周期约束的服务,用于类型化持久状态。 |
| `ctx.messageFeedback` | `core` | [`message-feedback`](../packages/feedback/message-feedback) | - | - | - | 拥有本地逐 assistant 消息反馈、生命周期与目标校验、逐条目 compare-and-set 及 Host 一元 Remote 契约,且不进入 Session 历史或遥测。 |
| `ctx.workspace` | `core` | [`workspace`](../packages/workspace/workspace) | - | `apiproxy` | - | 通过领域设施拥有带 WorkspaceId 品牌类型的记录;稳定的 sessionIds 账户驱动 Host RPC 与 GUI 投影。 |
| `ctx.sessionQuery` | `seam` | [`session-query`](../packages/session-query/session-query) | [`session-query-sqlite`](../packages/session-query/session-query-sqlite) | [`session-reference`](../packages/context/session-reference)、[`tool-session-query`](../packages/session-query/tool-session-query) | - | 该接口提供精确读取、过滤和追踪;具体后端还提供全文协调、排序、摘要片段和游标世代,而模型消费方负责工作区权限与不含游标的渲染。 |
| `ctx.sessionReferences` | `core` | [`session-reference`](../packages/context/session-reference) | - | - | - | 将当前表层中有界的对话快照投影为持久但不可信的消息上下文Host 适配器负责提及语法。 |

View File

@@ -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: 1e2416d479daaef0f9b6b03846406fab4c30f21a
config-catalog.zh.md: 5a9ecc5b30c55f70b2685fe9633430e68f30f6c8

View File

@@ -259,7 +259,7 @@ export interface Config {
Depends on: [`ToolPresentationMode`](subsystems/tools.md)
Source: [`packages/core/agent-tool-mode/src/index.ts:36`](../packages/core/agent-tool-mode/src/index.ts)
Source: [`packages/core/agent-tool-mode/src/index.ts:38`](../packages/core/agent-tool-mode/src/index.ts)
## `@deepseek-ai/dsh-attachment-local`
@@ -533,7 +533,7 @@ export interface Config {
}
```
Source: [`packages/fs/fs-local/src/index.ts:40`](../packages/fs/fs-local/src/index.ts)
Source: [`packages/fs/fs-local/src/index.ts:41`](../packages/fs/fs-local/src/index.ts)
## `@deepseek-ai/dsh-fs-sandbox`
@@ -572,7 +572,7 @@ Source: [`packages/goal/goal/src/index.ts:116`](../packages/goal/goal/src/index.
Requires: `agentDefaultModel` · `agents` · `sessions`
```ts config-catalog
/** Plugin config: the task, patched in by the launcher. */
/** Plugin config: the task resolved from this app's injected provider service. */
export interface Config {
/** The prompt text for the single run. */
task: string
@@ -986,6 +986,8 @@ export interface ReplayModelConfig {
description?: string
/** Optional positive integer context capacity published by the replay adapter. */
contextWindow?: number
/** Optional declared input modalities, so a scenario can exercise capability gates (e.g. image-capable `read_image`). */
inputModalities?: readonly ModelModality[]
/**
* Optional per-request output cap the replay route materializes when callers
* omit one, so replay reconstructs the request header a live catalog produced.
@@ -1001,9 +1003,9 @@ export interface ReplayModelConfig {
}
```
Depends on: [`RetryPolicyConfig`](../packages/llm/llm/src/index.ts)
Depends on: [`ModelModality`](../packages/llm/llm/src/index.ts) · [`RetryPolicyConfig`](../packages/llm/llm/src/index.ts)
Source: [`packages/support/llm-replay/src/index.ts:769`](../packages/support/llm-replay/src/index.ts)
Source: [`packages/support/llm-replay/src/index.ts:776`](../packages/support/llm-replay/src/index.ts)
## `@deepseek-ai/dsh-llm-retry`
@@ -1086,6 +1088,8 @@ export interface StdioConfig {
toolCallTimeoutMs: number
/** Fail plugin activation when the initial connection or tool synchronization fails. */
failOnStartupError: boolean
/** Automatic reconnect policy after a lost connection; omission uses the defaults. */
reconnect?: ReconnectConfig
}
/** Config for connecting to an MCP server over Streamable HTTP (SSE). */
@@ -1106,10 +1110,38 @@ export interface StreamableHttpConfig {
toolCallTimeoutMs: number
/** Fail plugin activation when the initial connection or tool synchronization fails. */
failOnStartupError: boolean
/** Automatic reconnect policy after a lost connection; omission uses the defaults. */
reconnect?: ReconnectConfig
}
/** Automatic reconnect policy for one MCP server connection. */
export interface ReconnectConfig {
/** Reconnect automatically after a lost connection (default true). */
enabled?: boolean
/** First reconnect delay in milliseconds; doubles per consecutive failed attempt (default 500). */
initialDelayMs?: number
/** Backoff ceiling in milliseconds; also the uptime after which the attempt budget resets (default 30000). */
maxDelayMs?: number
/** Consecutive failed attempts per outage before giving up for good (default 10). */
maxAttempts?: number
}
```
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-message-feedback`
Requires: `storageDomain` · `sessionPersistence` · `sessions`
```ts config-catalog
/** Required deployment policy for optional notes. */
export interface Config {
/** Maximum UTF-8 byte length accepted for one note. */
readonly maxNoteBytes: number
}
```
Source: [`packages/feedback/message-feedback/src/index.ts:49`](../packages/feedback/message-feedback/src/index.ts)
## `@deepseek-ai/dsh-permission`
@@ -1161,6 +1193,8 @@ export interface Config {
* variables. Empty text drops the section at render, matching the registry.
*/
text: string
/** Make this persona the complete system prompt, suppressing every other section. */
complete?: boolean
}
```
@@ -1306,22 +1340,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
@@ -1350,7 +1368,7 @@ export interface Config {
}
```
Source: [`packages/sandbox/sandbox-local/src/index.ts:43`](../packages/sandbox/sandbox-local/src/index.ts)
Source: [`packages/sandbox/sandbox-local/src/index.ts:44`](../packages/sandbox/sandbox-local/src/index.ts)
## `@deepseek-ai/dsh-sandbox-policy`
@@ -1412,7 +1430,7 @@ export interface Config {
export type JsonlCompression = 'zstd' | 'none'
```
Source: [`packages/session/session-persistence-jsonl/src/index.ts:59`](../packages/session/session-persistence-jsonl/src/index.ts)
Source: [`packages/session/session-persistence-jsonl/src/index.ts:60`](../packages/session/session-persistence-jsonl/src/index.ts)
## `@deepseek-ai/dsh-session-persistence-sqlite`
@@ -1455,7 +1473,7 @@ export interface Config {
export type JournalMode = 'wal' | 'delete' | 'truncate' | 'persist'
```
Source: [`packages/session/session-persistence-sqlite/src/index.ts:67`](../packages/session/session-persistence-sqlite/src/index.ts)
Source: [`packages/session/session-persistence-sqlite/src/index.ts:70`](../packages/session/session-persistence-sqlite/src/index.ts)
## `@deepseek-ai/dsh-session-projection-cache`
@@ -1576,7 +1594,7 @@ export enum TelemetryMode {
Depends on: `BatchLogRecordProcessorOptions` (`@opentelemetry/sdk-logs`) · `OTLPExporterNodeConfigBase` (`@opentelemetry/otlp-exporter-base`)
Source: [`packages/session/session-telemetry-otel/src/index.ts:79`](../packages/session/session-telemetry-otel/src/index.ts)
Source: [`packages/session/session-telemetry-otel/src/index.ts:91`](../packages/session/session-telemetry-otel/src/index.ts)
## `@deepseek-ai/dsh-session-title`
@@ -2003,7 +2021,7 @@ export interface Config {
}
```
Source: [`packages/core/system-prompt/src/index.ts:177`](../packages/core/system-prompt/src/index.ts)
Source: [`packages/core/system-prompt/src/index.ts:186`](../packages/core/system-prompt/src/index.ts)
## `@deepseek-ai/dsh-time-context`
@@ -2114,7 +2132,7 @@ export interface Config {
}
```
Source: [`packages/fs/tool-fs/src/index.ts:24`](../packages/fs/tool-fs/src/index.ts)
Source: [`packages/fs/tool-fs/src/index.ts:25`](../packages/fs/tool-fs/src/index.ts)
## `@deepseek-ai/dsh-tool-fs-search`
@@ -2534,33 +2552,28 @@ Source: [`packages/web/web/src/index.ts:55`](../packages/web/web/src/index.ts)
Requires: `httpServer`
```ts config-catalog
/** Plugin config: the surface facts the launcher patches over this bundle's defaults. */
/** Plugin config: composed deployment settings plus per-invocation command-line values. */
export interface Config {
/** Whether this process mounted the client-plugin HMR receiver (`dsh web --dev`). */
mode: WebMode
/** Print the URL line on activation; a headless layer over this bundle turns it off. */
/** Print the URL line on activation; a non-interactive layer can turn it off. */
printUrl: boolean
/**
* Register the model-visible surface context (the `app:web-surface` prompt
* section and the `DSH_WEB_URL`/`DSH_WEB_MODE` bash variables). A one-shot
* layer turns it off: its user is not interacting through the GUI, so the
* non-interactive layer can turn it off when its user is not in the GUI, so the
* orientation text would be false.
*/
surfaceContext: boolean
/**
* LAN IPv4 addresses sampled once by the launcher when the effective bind
* is all-interfaces — the exact snapshot the /api trust fence was
* configured with, so the printed LAN URL can never name an address the
* fence rejects. Empty on a loopback bind.
*/
lanAddresses: string[]
/** Explicit `--trusted-host` authorities from this invocation. */
trustedHosts: string[]
}
/** Web runtime mode: production, or development when the client-plugin HMR receiver is active. */
export type WebMode = 'production' | 'development'
```
Source: [`packages/bundle/web-app/src/index.ts:32`](../packages/bundle/web-app/src/index.ts)
Source: [`packages/bundle/web-app/src/index.ts:43`](../packages/bundle/web-app/src/index.ts)
## `@deepseek-ai/dsh-web-fetch-local`
@@ -2739,6 +2752,7 @@ These load from a `cordis.yml` entry with no `config:` block; they declare no co
- `@deepseek-ai/dsh-client-ui-skill` ([`packages/client/ui-skill/src/index.ts`](../packages/client/ui-skill/src/index.ts))
- `@deepseek-ai/dsh-client-ui-slash` ([`packages/client/ui-slash/src/index.ts`](../packages/client/ui-slash/src/index.ts))
- `@deepseek-ai/dsh-client-ui-subagent` ([`packages/client/ui-subagent/src/index.ts`](../packages/client/ui-subagent/src/index.ts))
- `@deepseek-ai/dsh-client-ui-task` ([`packages/client/ui-task/src/index.ts`](../packages/client/ui-task/src/index.ts))
- `@deepseek-ai/dsh-client-ui-theme` ([`packages/client/ui-theme/src/index.ts`](../packages/client/ui-theme/src/index.ts))
- `@deepseek-ai/dsh-client-ui-tool` ([`packages/client/ui-tool/src/index.ts`](../packages/client/ui-tool/src/index.ts))
- `@deepseek-ai/dsh-client-ui-trajectory` ([`packages/client/ui-trajectory/src/index.ts`](../packages/client/ui-trajectory/src/index.ts))
@@ -2806,6 +2820,7 @@ Imported as libraries by other packages; a `cordis.yml` cannot load them.
- `@deepseek-ai/dsh-client-ui-slots` ([`packages/client/ui-slots/src/index.ts`](../packages/client/ui-slots/src/index.ts))
- `@deepseek-ai/dsh-client-web` ([`packages/client/web/src/index.ts`](../packages/client/web/src/index.ts))
- `@deepseek-ai/dsh-client-web-react` ([`packages/client/web-react/src/index.ts`](../packages/client/web-react/src/index.ts))
- `@deepseek-ai/dsh-cmdline` ([`packages/boot/cmdline/src/index.ts`](../packages/boot/cmdline/src/index.ts))
- `@deepseek-ai/dsh-environment` ([`packages/util/environment/src/index.ts`](../packages/util/environment/src/index.ts))
- `@deepseek-ai/dsh-helper` ([`packages/scaffold/helper/src/index.ts`](../packages/scaffold/helper/src/index.ts))
- `@deepseek-ai/dsh-hook-protocol` ([`packages/hooks/hook-protocol/src/index.ts`](../packages/hooks/hook-protocol/src/index.ts))

View File

@@ -261,7 +261,7 @@ export interface Config {
依赖:[`ToolPresentationMode`](subsystems/tools.md)
来源:[`packages/core/agent-tool-mode/src/index.ts:36`](../packages/core/agent-tool-mode/src/index.ts)
来源:[`packages/core/agent-tool-mode/src/index.ts:38`](../packages/core/agent-tool-mode/src/index.ts)
## `@deepseek-ai/dsh-attachment-local`
@@ -574,7 +574,7 @@ export interface Config {
需要:`agentDefaultModel` · `agents` · `sessions`
```ts config-catalog
/** Plugin config: the task, patched in by the launcher. */
/** Plugin config: the task resolved from this app's injected provider service. */
export interface Config {
/** The prompt text for the single run. */
task: string
@@ -988,6 +988,8 @@ export interface ReplayModelConfig {
description?: string
/** Optional positive integer context capacity published by the replay adapter. */
contextWindow?: number
/** Optional declared input modalities, so a scenario can exercise capability gates (e.g. image-capable `read_image`). */
inputModalities?: readonly ModelModality[]
/**
* Optional per-request output cap the replay route materializes when callers
* omit one, so replay reconstructs the request header a live catalog produced.
@@ -1003,9 +1005,9 @@ export interface ReplayModelConfig {
}
```
依赖:[`RetryPolicyConfig`](../packages/llm/llm/src/index.ts)
依赖:[`ModelModality`](../packages/llm/llm/src/index.ts) · [`RetryPolicyConfig`](../packages/llm/llm/src/index.ts)
来源:[`packages/support/llm-replay/src/index.ts:769`](../packages/support/llm-replay/src/index.ts)
来源:[`packages/support/llm-replay/src/index.ts:776`](../packages/support/llm-replay/src/index.ts)
## `@deepseek-ai/dsh-llm-retry`
@@ -1088,6 +1090,8 @@ export interface StdioConfig {
toolCallTimeoutMs: number
/** Fail plugin activation when the initial connection or tool synchronization fails. */
failOnStartupError: boolean
/** Automatic reconnect policy after a lost connection; omission uses the defaults. */
reconnect?: ReconnectConfig
}
/** Config for connecting to an MCP server over Streamable HTTP (SSE). */
@@ -1108,10 +1112,38 @@ export interface StreamableHttpConfig {
toolCallTimeoutMs: number
/** Fail plugin activation when the initial connection or tool synchronization fails. */
failOnStartupError: boolean
/** Automatic reconnect policy after a lost connection; omission uses the defaults. */
reconnect?: ReconnectConfig
}
/** Automatic reconnect policy for one MCP server connection. */
export interface ReconnectConfig {
/** Reconnect automatically after a lost connection (default true). */
enabled?: boolean
/** First reconnect delay in milliseconds; doubles per consecutive failed attempt (default 500). */
initialDelayMs?: number
/** Backoff ceiling in milliseconds; also the uptime after which the attempt budget resets (default 30000). */
maxDelayMs?: number
/** Consecutive failed attempts per outage before giving up for good (default 10). */
maxAttempts?: number
}
```
来源:[`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-message-feedback`
需要:`storageDomain` · `sessionPersistence` · `sessions`
```ts config-catalog
/** Required deployment policy for optional notes. */
export interface Config {
/** Maximum UTF-8 byte length accepted for one note. */
readonly maxNoteBytes: number
}
```
来源:[`packages/feedback/message-feedback/src/index.ts:49`](../packages/feedback/message-feedback/src/index.ts)
## `@deepseek-ai/dsh-permission`
@@ -1163,6 +1195,8 @@ export interface Config {
* variables. Empty text drops the section at render, matching the registry.
*/
text: string
/** Make this persona the complete system prompt, suppressing every other section. */
complete?: boolean
}
```
@@ -1308,22 +1342,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
@@ -1352,7 +1370,7 @@ export interface Config {
}
```
来源:[`packages/sandbox/sandbox-local/src/index.ts:43`](../packages/sandbox/sandbox-local/src/index.ts)
来源:[`packages/sandbox/sandbox-local/src/index.ts:44`](../packages/sandbox/sandbox-local/src/index.ts)
## `@deepseek-ai/dsh-sandbox-policy`
@@ -1457,7 +1475,7 @@ export interface Config {
export type JournalMode = 'wal' | 'delete' | 'truncate' | 'persist'
```
来源:[`packages/session/session-persistence-sqlite/src/index.ts:67`](../packages/session/session-persistence-sqlite/src/index.ts)
来源:[`packages/session/session-persistence-sqlite/src/index.ts:70`](../packages/session/session-persistence-sqlite/src/index.ts)
## `@deepseek-ai/dsh-session-projection-cache`
@@ -2005,7 +2023,7 @@ export interface Config {
}
```
来源:[`packages/core/system-prompt/src/index.ts:177`](../packages/core/system-prompt/src/index.ts)
来源:[`packages/core/system-prompt/src/index.ts:186`](../packages/core/system-prompt/src/index.ts)
## `@deepseek-ai/dsh-time-context`
@@ -2535,33 +2553,28 @@ export interface WebServiceConfig {
需要:`httpServer`
```ts config-catalog
/** Plugin config: the surface facts the launcher patches over this bundle's defaults. */
/** Plugin config: composed deployment settings plus per-invocation command-line values. */
export interface Config {
/** Whether this process mounted the client-plugin HMR receiver (`dsh web --dev`). */
mode: WebMode
/** Print the URL line on activation; a headless layer over this bundle turns it off. */
/** Print the URL line on activation; a non-interactive layer can turn it off. */
printUrl: boolean
/**
* Register the model-visible surface context (the `app:web-surface` prompt
* section and the `DSH_WEB_URL`/`DSH_WEB_MODE` bash variables). A one-shot
* layer turns it off: its user is not interacting through the GUI, so the
* non-interactive layer can turn it off when its user is not in the GUI, so the
* orientation text would be false.
*/
surfaceContext: boolean
/**
* LAN IPv4 addresses sampled once by the launcher when the effective bind
* is all-interfaces — the exact snapshot the /api trust fence was
* configured with, so the printed LAN URL can never name an address the
* fence rejects. Empty on a loopback bind.
*/
lanAddresses: string[]
/** Explicit `--trusted-host` authorities from this invocation. */
trustedHosts: string[]
}
/** Web runtime mode: production, or development when the client-plugin HMR receiver is active. */
export type WebMode = 'production' | 'development'
```
来源:[`packages/bundle/web-app/src/index.ts:32`](../packages/bundle/web-app/src/index.ts)
来源:[`packages/bundle/web-app/src/index.ts:43`](../packages/bundle/web-app/src/index.ts)
## `@deepseek-ai/dsh-web-fetch-local`
@@ -2740,6 +2753,7 @@ export interface Config {
- `@deepseek-ai/dsh-client-ui-skill`[`packages/client/ui-skill/src/index.ts`](../packages/client/ui-skill/src/index.ts)
- `@deepseek-ai/dsh-client-ui-slash`[`packages/client/ui-slash/src/index.ts`](../packages/client/ui-slash/src/index.ts)
- `@deepseek-ai/dsh-client-ui-subagent`[`packages/client/ui-subagent/src/index.ts`](../packages/client/ui-subagent/src/index.ts)
- `@deepseek-ai/dsh-client-ui-task`[`packages/client/ui-task/src/index.ts`](../packages/client/ui-task/src/index.ts)
- `@deepseek-ai/dsh-client-ui-theme`[`packages/client/ui-theme/src/index.ts`](../packages/client/ui-theme/src/index.ts)
- `@deepseek-ai/dsh-client-ui-tool`[`packages/client/ui-tool/src/index.ts`](../packages/client/ui-tool/src/index.ts)
- `@deepseek-ai/dsh-client-ui-trajectory`[`packages/client/ui-trajectory/src/index.ts`](../packages/client/ui-trajectory/src/index.ts)
@@ -2806,6 +2820,7 @@ export interface Config {
- `@deepseek-ai/dsh-client-ui-slots`[`packages/client/ui-slots/src/index.ts`](../packages/client/ui-slots/src/index.ts)
- `@deepseek-ai/dsh-client-web`[`packages/client/web/src/index.ts`](../packages/client/web/src/index.ts)
- `@deepseek-ai/dsh-client-web-react`[`packages/client/web-react/src/index.ts`](../packages/client/web-react/src/index.ts)
- `@deepseek-ai/dsh-cmdline`[`packages/boot/cmdline/src/index.ts`](../packages/boot/cmdline/src/index.ts)
- `@deepseek-ai/dsh-environment`[`packages/util/environment/src/index.ts`](../packages/util/environment/src/index.ts)
- `@deepseek-ai/dsh-helper`[`packages/scaffold/helper/src/index.ts`](../packages/scaffold/helper/src/index.ts)
- `@deepseek-ai/dsh-hook-protocol`[`packages/hooks/hook-protocol/src/index.ts`](../packages/hooks/hook-protocol/src/index.ts)

View File

@@ -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-conversation-node.md
adding-a-conversation-node.md: ea4ec73eb109af6b0e4c7cf50fc8692942c75dd4
adding-a-conversation-node.zh.md: 4b9a8049e2f1d060ec4bc3334036559b989ea562
adding-a-conversation-node.md: c1965dc8a3081eebb8c1026ac53d2f7b8964edb7
adding-a-conversation-node.zh.md: 92445e1432369a4e42cc372b5d5869c3cdeada4a

View File

@@ -120,6 +120,7 @@ function viewData(state: ReviewState): ReviewChatData {
const reviewDefinition: ConversationNodeDefinition<ReviewState> = {
kind: 'review-job',
target: 'chat',
match: (event) => {
if (event.type === 'review/start') {
return { id: String(event.data.reviewId), role: 'start' }
@@ -161,8 +162,8 @@ const reviewDefinition: ConversationNodeDefinition<ReviewState> = {
value: viewData(context.state),
}
},
buildViewNode: (context, target) => {
if (target !== 'chat' || context.state === undefined) return null
buildViewNode: (context) => {
if (context.state === undefined) return null
return {
key: context.key,
kind: 'review-job',
@@ -196,7 +197,7 @@ export function apply(ctx: ClientContext): void {
`buildLocationData(context, scope)` optionally publishes Definition-owned data onto an engine-owned Turn or Step. Use declaration merging to give each key a precise value type. Another Node in the same Location can consume that value through its constrained slot hook, such as `useTurnData(key)`, without receiving the Session or scanning `snapshot.chat.nodes`.
`buildViewNode(context, target)` materializes the final target-specific Node. Preserve `context.key` as the React-facing identity, choose `anchorSeq` from durable ordering evidence, and return only renderer-ready data. Once a target Node has been published, keep returning the same key; use `visibility: 'hidden'` when it must temporarily leave the visible flow rather than withdrawing it with `null`.
`target` and `buildViewNode(context)` declare one target-owned rendering contribution and must appear together. Preserve `context.key` as the React-facing identity, choose `anchorSeq` from durable ordering evidence, and return only renderer-ready data. Once a target Node has been published, keep returning the same key; use `visibility: 'hidden'` when it must temporarily leave the visible flow rather than withdrawing it with `null`.
## 3. Query an earlier business Context only at start

View File

@@ -120,6 +120,7 @@ function viewData(state: ReviewState): ReviewChatData {
const reviewDefinition: ConversationNodeDefinition<ReviewState> = {
kind: 'review-job',
target: 'chat',
match: (event) => {
if (event.type === 'review/start') {
return { id: String(event.data.reviewId), role: 'start' }
@@ -161,8 +162,8 @@ const reviewDefinition: ConversationNodeDefinition<ReviewState> = {
value: viewData(context.state),
}
},
buildViewNode: (context, target) => {
if (target !== 'chat' || context.state === undefined) return null
buildViewNode: (context) => {
if (context.state === undefined) return null
return {
key: context.key,
kind: 'review-job',
@@ -196,7 +197,7 @@ export function apply(ctx: ClientContext): void {
`buildLocationData(context, scope)` 可以把 Definition 拥有的数据发布到引擎拥有的 Turn 或 Step 上。通过 declaration merging 为每个 key 指定精确 value 类型。同一 Location 内的另一个 Node 可以使用受限 slot hook例如 `useTurnData(key)`)读取该值,无须取得 Session也无须扫描 `snapshot.chat.nodes`。
`buildViewNode(context, target)` 物化最终的目标专用 Node。把 `context.key` 保留为 React 侧身份,根据持久排序证据选择 `anchorSeq`,并且只返回 renderer 可以直接使用的数据。某个 target Node 一旦发布,就要继续返回同一个 key需要暂时离开可见流时使用 `visibility: 'hidden'`,不要改为返回 `null` 撤回它。
`target` 与 `buildViewNode(context)` 必须同时声明一项由 target 拥有的渲染贡献。把 `context.key` 保留为 React 侧身份,根据持久排序证据选择 `anchorSeq`,并且只返回 renderer 可以直接使用的数据。某个 target Node 一旦发布,就要继续返回同一个 key需要暂时离开可见流时使用 `visibility: 'hidden'`,不要改为返回 `null` 撤回它。
## 3. 只在 start 时查询更早的业务 Context

View File

@@ -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-package.md
adding-a-package.md: dcd5fa66f3616c2c22930babd09cb3edab38e182
adding-a-package.zh.md: c8769197e0b1db31348b7f2442dbcd636bf43cb2
adding-a-package.md: e108b9e88e0f0e470f96173306af79c69ff695fb
adding-a-package.zh.md: 97b4df150fda7010fba048d7acb5e23a87519911

View File

@@ -22,7 +22,7 @@ packages/<group>/<pkg>/
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.

View File

@@ -22,7 +22,7 @@ packages/<group>/<pkg>/
当已有分组与包的角色匹配时,选择该分组(`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` 文件。

View File

@@ -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

View File

@@ -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'

View File

@@ -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'

View File

@@ -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

View File

@@ -8,7 +8,7 @@ When the harness needs another upstream Cordis package (e.g. `@cordisjs/plugin-h
```
vendor/<dir>/
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/<dir>/
}
```
`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.

View File

@@ -8,7 +8,7 @@
```
vendor/<dir>/
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/<dir>/
}
```
`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 消费方能够解析。

View File

@@ -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

View File

@@ -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<boolean>
@@ -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']

View File

@@ -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<boolean>
@@ -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) 是仅面向自动化的完整示例:它通过 ACPAgent Client ProtocolJSON-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']

View File

@@ -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-api/fiber.md
fiber.md: 36d2861ac6a53e8186a92d86c65ba228d4b59ee5
fiber.zh.md: fafa559ca911677c43893862190009d82c39c56b
fiber.md: 182b77390b29b8a90504437d0ccc2dfeba23921a
fiber.zh.md: 9ed3e52618586dc3815b9d913439d11a227fb64b

View File

@@ -34,7 +34,7 @@ Register a cleanup-aware effect on this fiber.
**Returns** a disposer that tears the effect down and settles once done.
[Source](../../vendor/cordis/src/fiber.ts#L420)
[Source](../../vendor/cordis/src/fiber.ts#L415)
### ctx.fiber
@@ -97,7 +97,7 @@ public state
Current lifecycle state; transitions emit `internal/status`.
[Source](../../vendor/cordis/src/fiber.ts#L192)
[Source](../../vendor/cordis/src/fiber.ts#L194)
### fiber.dispose
@@ -108,7 +108,7 @@ public readonly dispose: () => Promise<void>
Dispose this fiber: unload the plugin, then settle once cleanup finished.
[Source](../../vendor/cordis/src/fiber.ts#L194)
[Source](../../vendor/cordis/src/fiber.ts#L196)
### fiber.store
@@ -119,7 +119,7 @@ public store: Dict<Impl> | undefined
Snapshot of required service implementations while loaded; `undefined` otherwise.
[Source](../../vendor/cordis/src/fiber.ts#L196)
[Source](../../vendor/cordis/src/fiber.ts#L198)
### fiber.inertia
@@ -130,7 +130,7 @@ public inertia: Promise<void> | undefined
The in-flight load/unload transition, if one is currently running.
[Source](../../vendor/cordis/src/fiber.ts#L198)
[Source](../../vendor/cordis/src/fiber.ts#L200)
### fiber.name
@@ -141,7 +141,7 @@ get name()
The plugin's display name, inherited from the nearest named ancestor, else `'root'`.
[Source](../../vendor/cordis/src/fiber.ts#L341)
[Source](../../vendor/cordis/src/fiber.ts#L336)
### fiber.assertActive()
@@ -159,7 +159,7 @@ Throw if the fiber has already been disposed.
**Returns** nothing when the fiber is still active.
[Source](../../vendor/cordis/src/fiber.ts#L356)
[Source](../../vendor/cordis/src/fiber.ts#L351)
### fiber.effect(execute, label?)
@@ -190,7 +190,7 @@ Register a cleanup-aware effect on this fiber.
**Returns** a disposer that tears the effect down and settles once done.
[Source](../../vendor/cordis/src/fiber.ts#L420)
[Source](../../vendor/cordis/src/fiber.ts#L415)
### fiber.getEffects()
@@ -207,7 +207,7 @@ Return metadata for currently registered effects.
**Returns** one `EffectMeta` tree per labeled live effect.
[Source](../../vendor/cordis/src/fiber.ts#L573)
[Source](../../vendor/cordis/src/fiber.ts#L568)
### fiber.await()
@@ -225,7 +225,7 @@ Wait for current lifecycle work and rethrow startup errors.
**Returns** this fiber, once it has settled into a stable state.
[Source](../../vendor/cordis/src/fiber.ts#L702)
[Source](../../vendor/cordis/src/fiber.ts#L704)
### fiber.restart()
@@ -243,7 +243,7 @@ Dispose and immediately reload this plugin with its current config.
**Returns** a promise resolving once the reload settled.
[Source](../../vendor/cordis/src/fiber.ts#L716)
[Source](../../vendor/cordis/src/fiber.ts#L718)
### fiber.update(config, noSave?)
@@ -271,7 +271,7 @@ Runs the `internal/update` waterfall first, so update hooks (and HMR) can veto o
**Returns** the update waterfall result; the default restart returns a promise.
[Source](../../vendor/cordis/src/fiber.ts#L734)
[Source](../../vendor/cordis/src/fiber.ts#L736)
## Effect

View File

@@ -36,7 +36,7 @@ effect(execute: () => Effect, label?: string): AsyncDisposable<Promise<void>>
**返回**一个用于撤销该作用的清理函数,并在清理完成后结算。
[源码](../../vendor/cordis/src/fiber.ts#L420)
[源码](../../vendor/cordis/src/fiber.ts#L415)
### ctx.fiber
@@ -99,7 +99,7 @@ public state
当前生命周期状态;状态转换会发出 `internal/status`。
[源码](../../vendor/cordis/src/fiber.ts#L192)
[源码](../../vendor/cordis/src/fiber.ts#L194)
### fiber.dispose
@@ -110,7 +110,7 @@ public readonly dispose: () => Promise<void>
dispose 此 fiber卸载插件并在清理完成后结算。
[源码](../../vendor/cordis/src/fiber.ts#L194)
[源码](../../vendor/cordis/src/fiber.ts#L196)
### fiber.store
@@ -121,7 +121,7 @@ public store: Dict<Impl> | undefined
加载期间所需服务实现的快照;其他情况下为 `undefined`。
[源码](../../vendor/cordis/src/fiber.ts#L196)
[源码](../../vendor/cordis/src/fiber.ts#L198)
### fiber.inertia
@@ -132,7 +132,7 @@ public inertia: Promise<void> | undefined
当前正在进行的加载或卸载转换;如果没有此类转换,则为 undefined。
[源码](../../vendor/cordis/src/fiber.ts#L198)
[源码](../../vendor/cordis/src/fiber.ts#L200)
### fiber.name
@@ -143,7 +143,7 @@ get name()
插件的显示名称,继承自最近的具名祖先;如果不存在,则为 `'root'`。
[源码](../../vendor/cordis/src/fiber.ts#L341)
[源码](../../vendor/cordis/src/fiber.ts#L336)
### fiber.assertActive()
@@ -161,7 +161,7 @@ assertActive()
**返回**fiber 仍处于活动状态时不返回任何内容。
[源码](../../vendor/cordis/src/fiber.ts#L356)
[源码](../../vendor/cordis/src/fiber.ts#L351)
### fiber.effect(execute, label?)
@@ -192,7 +192,7 @@ effect(execute: () => Effect, label?: string): AsyncDisposable<Promise<void>>
**返回**一个用于撤销该作用的清理函数,并在清理完成后结算。
[源码](../../vendor/cordis/src/fiber.ts#L420)
[源码](../../vendor/cordis/src/fiber.ts#L415)
### fiber.getEffects()
@@ -209,7 +209,7 @@ getEffects()
**返回**:每个带标签的活动作用对应一棵 `EffectMeta` 树。
[源码](../../vendor/cordis/src/fiber.ts#L573)
[源码](../../vendor/cordis/src/fiber.ts#L568)
### fiber.await()
@@ -227,7 +227,7 @@ async await()
**返回**:进入稳定状态后的此 fiber。
[源码](../../vendor/cordis/src/fiber.ts#L702)
[源码](../../vendor/cordis/src/fiber.ts#L704)
### fiber.restart()
@@ -245,7 +245,7 @@ dispose 此插件,并立即使用其当前配置重新加载。
**返回**一个在重新加载完成后兑现的 promise。
[源码](../../vendor/cordis/src/fiber.ts#L716)
[源码](../../vendor/cordis/src/fiber.ts#L718)
### fiber.update(config, noSave?)
@@ -273,7 +273,7 @@ update(config: any, noSave = false)
**返回**更新 waterfall 的结果;默认的重新启动操作返回一个 promise。
[源码](../../vendor/cordis/src/fiber.ts#L734)
[源码](../../vendor/cordis/src/fiber.ts#L736)
## Effect

View File

@@ -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: d1e7c5fd8eaaa89fe448d238359389d945cd6346
cordis-primer.zh.md: d6ce0f2024f65b006c9505daffaa06a08bb56875

View File

@@ -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. Loader interpolates only an entry's `config`, after declared injections activate, against that plugin context (`ctx.serviceName`); Include preserves nested row expressions until target activation. Entry metadata (`id`, `name`, `group`, `disabled`, `inject`, `intercept`, `isolate`) stays literal, so `disabled: !!js ...` always disables the entry. Use overlays when the environment selects plugins.
## Practical Rules

View File

@@ -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 只在声明的注入激活后,基于该插件上下文(`ctx.serviceName`)插值条目的 `config`Include 会保留嵌套行表达式,直到目标行激活。条目元数据(`id``name``group``disabled``inject``intercept``isolate`)保持字面值因此 `disabled: !!js ...` 始终禁用该条目。由环境选择插件时,请使用 overlay
## 实践规则

View File

@@ -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: 79df2f42df1f34a7ef32cc81607e1b926a1854ae
01-first-plugin.zh.md: 87cd7a96843d69d68fb95662e59bbfb9ebfc2a37

View File

@@ -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) {}
@@ -92,4 +92,4 @@ One caveat worth knowing early: a config entry whose module cannot be **resolved
Next: [Lifecycle and effects](02-lifecycle-and-effects.md) — what happens when a plugin unloads.
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness-sdk)
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness)

View File

@@ -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) {}
@@ -92,4 +92,4 @@ export function apply(ctx: Context) {
下一章:[生命周期与 effect](02-lifecycle-and-effects.md):插件卸载时会发生什么。
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness-sdk)
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness)

View File

@@ -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: 8e75708eb0cba1aceb7fa3dae5ae334995eb113f
02-lifecycle-and-effects.zh.md: bc4489e702ab58b5d1efd8a72fc693ee48af2624

View File

@@ -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'
@@ -95,4 +95,4 @@ One ordering caveat: disposers start in reverse registration order, but multiple
Next: [Services](03-services.md) — how plugins share capabilities.
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness-sdk)
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness)

View File

@@ -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'
@@ -95,4 +95,4 @@ PENDING → LOADING → ACTIVE → UNLOADING → DISPOSED
下一章:[服务](03-services.md):插件如何共享功能。
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness-sdk)
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness)

View File

@@ -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: 32007284be99ef46b4621089c9b3a80317e77189
03-services.zh.md: d82be29aa69686b8dc10cc6a45a658683c017cbd

View File

@@ -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']
@@ -95,4 +95,4 @@ Service names live in one flat namespace per application. Prefix or namespace yo
Next: [Events](04-events.md) — communication without a shared service.
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness-sdk)
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness)

View File

@@ -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']
@@ -95,4 +95,4 @@ export function apply(ctx: Context) {
下一章:[事件](04-events.md):无需共享服务即可通信。
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness-sdk)
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness)

View File

@@ -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: db911b9a06d7304d73030a2020de3d465fde2f9c
04-events.zh.md: e0357b2c04785d52a54f839d1b8ff3ecccb027ed

View File

@@ -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<string>): Promise<string>
}
@@ -141,4 +141,4 @@ The harness uses waterfalls for decisions that cooperating plugins may wrap or a
Next: [Configuration](05-config.md) — plugin options from `cordis.yml`.
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness-sdk)
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness)

View File

@@ -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<string>): Promise<string>
}
@@ -141,4 +141,4 @@ harness 使用 waterfall 处理协作插件可以包装或回答的决策:[`ag
下一章:[配置](05-config.md):来自 `cordis.yml` 的插件选项。
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness-sdk)
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness)

View File

@@ -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: 2357f663135d6fc78a65f9d0952e0bc3f5eefae4
05-config.zh.md: fbd94d179494ad0b6f73baff2ca525c786cc9e33

View File

@@ -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'
@@ -81,4 +81,4 @@ The loader used in this repo supports a `!!js` tag for config values that must b
Next: [Composition and HMR](06-composition-and-hmr.md) — treating `cordis.yml` as the application.
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness-sdk)
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness)

View File

@@ -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'
@@ -81,4 +81,4 @@ ValidationError: invalid config:
下一章:[组合与 HMR热模块替换](06-composition-and-hmr.md):将 `cordis.yml` 视为应用。
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness-sdk)
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness)

View File

@@ -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: 87ea26014657ae8c8199e1ebb486556c827d96ca
06-composition-and-hmr.zh.md: 830f55de7c1be351fe701cb068197543602619a7

View File

@@ -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,8 +106,8 @@ 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.
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness-sdk)
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness)

View File

@@ -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,8 +106,8 @@ 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 服务。
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness-sdk)
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness)

View File

@@ -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: 2d3c23f9f7f7fc6bd6cabd4e7e68ebfc46e20665
07-into-the-harness.zh.md: 45dc0ee6f07ab3b0275499cd4ab0c436eebdddef

View File

@@ -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'
@@ -104,4 +104,4 @@ Where to go next:
- The generated `cordis-surface` regions on the [subsystem pages](../subsystems/core.md) — everything you can inject and listen to, each on its owning page.
- [Architecture](../architecture.md) — the system map these plugins live in.
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness-sdk)
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness)

View File

@@ -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'
@@ -104,4 +104,4 @@ logger 会先触发:`tools/result` 在结果物化过程中发出,发生在
- [子系统页面](../subsystems/core.md)上生成的 `cordis-surface` 区块:可以注入和监听的所有内容,各在其所属页面上。
- [架构](../architecture.md):这些插件所处的系统地图。
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness-sdk)
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness)

View File

@@ -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: fb700344e6d07d3864655009d2edac15ee9eede8
index.zh.md: a68e931d81e745164d8f9a5dc7ec9aec4cd0e590

View File

@@ -13,7 +13,7 @@ If you want the condensed concept reference instead of a walkthrough, read the [
You need a clone of this repository with dependencies installed — the [quick start](../user/guide/quickstart.md) covers prerequisites. No API key is needed for this tutorial; every example runs keylessly.
```sh
git clone https://github.com/deepseek-ai/deepseek-harness-sdk.git
git clone https://github.com/deepseek-ai/deepseek-harness.git
cd deepseek-harness
pnpm install
```
@@ -50,9 +50,9 @@ 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<Config>` to say which object fields a schema validates. You can copy those declarations as shown; the surrounding text explains what each one connects.
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness-sdk)
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness)

View File

@@ -13,7 +13,7 @@ Cordis 是 DeepSeek Harness SDK 底层的插件框架:它是一个小型运行
你需要克隆本仓库并安装依赖,具体前置条件见[快速入门](../user/guide/quickstart.md)。本教程不需要 API 密钥;所有示例均可在无密钥环境中运行。
```sh
git clone https://github.com/deepseek-ai/deepseek-harness-sdk.git
git clone https://github.com/deepseek-ai/deepseek-harness.git
cd deepseek-harness
pnpm install
```
@@ -50,9 +50,9 @@ 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<Config>` 这类泛型表示 schema 校验哪些对象字段。你可以直接照写这些声明;周围的正文会解释每项声明连接了什么。
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness-sdk)
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness)

View File

@@ -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/development.md
development.md: 8e565f21c6e2ede7dab7dbda3c4b18b77ce0920f
development.zh.md: d9c0fbfbb663334b8f7e2ca11d4e8d9a0652c22e
development.md: 7d6ca74df1311560b0d61444c92e74927639ca31
development.zh.md: 1461717cf496b1863f2f0c47ad4b42990dc789e9

View File

@@ -129,7 +129,7 @@ The root [contributor instructions](../AGENTS.md#commands) summarize common comm
The one-shot Headless coding agent needs `DEEPSEEK_API_KEY` in the environment or repo-root `.env`:
```sh
pnpm run demo:headless "summarize this workspace"
pnpm dsh --profile headless "summarize this workspace"
```
The self-referential cordis demo can inspect and modify its live plugin runtime and needs the same credentials (`web` by default, or `acp`):

View File

@@ -129,7 +129,7 @@ keyless [CI 工作流](../.github/workflows/ci.yml) 将独立门禁分组到若
单次运行的 Headless coding agent 需要环境变量或仓库根目录 `.env` 中的 `DEEPSEEK_API_KEY`
```sh
pnpm run demo:headless "summarize this workspace"
pnpm dsh --profile headless "summarize this workspace"
```
自指的 cordis 演示可以检查并修改其实时插件运行时,并需要相同的凭证(默认 `web`,也可用 `acp`

View File

@@ -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: d2e5cd66c2406cf84320fc1c0537d580214dd93d
event-producer-consumer.zh.md: 12ac194d68ed6121cc0b2c5e9bf2c7f77944f57b
event-producer-consumer.md: 55a57480e0311aa047e9b5f0f90b6457fc9a007f
event-producer-consumer.zh.md: c84c621befefdab7e668d64e90dcb14e28fd74ea

View File

@@ -8,7 +8,7 @@ This matrix shows which packages dispatch each harness-owned event and which pac
| Event | Mode | Declared in | Dispatchers | Listeners |
| --- | --- | --- | --- | --- |
| `agent-loop/config-start-failed` | `emit` | [`packages/core/agent-loop/src/index.ts:182`](../packages/core/agent-loop/src/index.ts) | [`agent-loop`](../packages/core/agent-loop) (`events.dispatch`) | - |
| `agent/created` | `emit` | [`packages/core/agent/src/runtime-types.ts:159`](../packages/core/agent/src/runtime-types.ts) | [`agent`](../packages/core/agent) (`events.dispatch`) | [`goal-session`](../packages/goal/goal-session) |
| `agent/created` | `emit` | [`packages/core/agent/src/runtime-types.ts:159`](../packages/core/agent/src/runtime-types.ts) | [`agent`](../packages/core/agent) (`events.dispatch`) | [`agent-presets`](../packages/preset/agent-presets), [`goal-session`](../packages/goal/goal-session) |
| `agent/disposed` | `emit` | [`packages/core/agent/src/runtime-types.ts:168`](../packages/core/agent/src/runtime-types.ts) | [`agent`](../packages/core/agent) (`events.dispatch`) | [`agent-loop`](../packages/core/agent-loop), [`goal-session`](../packages/goal/goal-session), [`subagent`](../packages/subagent/subagent) |
| `agent/error` | `emit` | [`packages/core/agent/src/runtime-types.ts:290`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`acp`](../packages/acp/acp), `apiproxy`, [`goal-session`](../packages/goal/goal-session), [`session-telemetry`](../packages/session/session-telemetry) |
| `agent/inbox/claimed` | `emit` | [`packages/core/agent/src/runtime-types.ts:197`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`acp`](../packages/acp/acp), [`goal-session`](../packages/goal/goal-session), [`subagent`](../packages/subagent/subagent) |
@@ -30,19 +30,19 @@ This matrix shows which packages dispatch each harness-owned event and which pac
| `goal/changed` | `emit` | [`packages/goal/goal/src/domain.ts:114`](../packages/goal/goal/src/domain.ts) | [`goal`](../packages/goal/goal) (`emit`) | [`goal-session`](../packages/goal/goal-session) |
| `llm/adapters-updated` | `emit` | [`packages/llm/llm/src/index.ts:75`](../packages/llm/llm/src/index.ts) | [`llm`](../packages/llm/llm) (`events.dispatch`) | `apiproxy`, [`llm`](../packages/llm/llm) |
| `llm/stream` | `waterfall` | [`packages/llm/llm/src/index.ts:64`](../packages/llm/llm/src/index.ts) | [`llm`](../packages/llm/llm) (`waterfall`) | [`agent-loop`](../packages/core/agent-loop), [`llm`](../packages/llm/llm), [`llm-replay`](../packages/support/llm-replay), [`session-checkpoint-policy`](../packages/session/session-checkpoint-policy), [`session-title`](../packages/session/session-title) |
| `session/created` | `emit` | [`packages/core/session/src/index.ts:74`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | `apiproxy`, [`compact`](../packages/compact/compact), [`goal`](../packages/goal/goal), [`hook-protocol`](../packages/hooks/hook-protocol), [`llm-retry`](../packages/llm/llm-retry), [`permission`](../packages/interaction/permission), [`plan-mode`](../packages/plan/plan-mode), `server`, [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`session-telemetry`](../packages/session/session-telemetry), [`tools`](../packages/core/tools), [`user-approval`](../packages/interaction/user-approval) |
| `session/disposed` | `emit` | [`packages/core/session/src/index.ts:84`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`agent-loop`](../packages/core/agent-loop), `apiproxy`, [`session-persistence`](../packages/session/session-persistence), [`session-projection-cache`](../packages/session/session-projection-cache), [`session-telemetry`](../packages/session/session-telemetry), [`session-title`](../packages/session/session-title) |
| `session/event` | `emit` | [`packages/core/session/src/index.ts:96`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`acp`](../packages/acp/acp), [`agent-loop`](../packages/core/agent-loop), `apiproxy`, [`compact`](../packages/compact/compact), [`compact-basic`](../packages/compact/compact-basic), [`goal`](../packages/goal/goal), [`goal-session`](../packages/goal/goal-session), [`hook-protocol`](../packages/hooks/hook-protocol), [`loader-smoke`](../packages/support/loader-smoke), `server`, [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`session-projection`](../packages/session/session-projection), [`session-projection-cache`](../packages/session/session-projection-cache), [`session-telemetry`](../packages/session/session-telemetry), [`session-telemetry-otel`](../packages/session/session-telemetry-otel), [`session-title`](../packages/session/session-title), [`token-meter`](../packages/llm/token-meter), [`tools`](../packages/core/tools), [`user-approval`](../packages/interaction/user-approval), [`workspace-context`](../packages/context/workspace-context) |
| `session/flush` | `parallel` | [`packages/core/session/src/index.ts:105`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`session-persistence`](../packages/session/session-persistence), [`session-telemetry`](../packages/session/session-telemetry) |
| `session/created` | `emit` | [`packages/core/session/src/index.ts:75`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | `apiproxy`, [`compact`](../packages/compact/compact), [`goal`](../packages/goal/goal), [`hook-protocol`](../packages/hooks/hook-protocol), [`llm-retry`](../packages/llm/llm-retry), [`permission`](../packages/interaction/permission), [`plan-mode`](../packages/plan/plan-mode), `server`, [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`session-telemetry`](../packages/session/session-telemetry), [`tools`](../packages/core/tools), [`user-approval`](../packages/interaction/user-approval) |
| `session/disposed` | `emit` | [`packages/core/session/src/index.ts:85`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`agent-loop`](../packages/core/agent-loop), `apiproxy`, [`session-persistence`](../packages/session/session-persistence), [`session-projection-cache`](../packages/session/session-projection-cache), [`session-telemetry`](../packages/session/session-telemetry), [`session-title`](../packages/session/session-title) |
| `session/event` | `emit` | [`packages/core/session/src/index.ts:97`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`acp`](../packages/acp/acp), [`agent-loop`](../packages/core/agent-loop), `apiproxy`, [`compact`](../packages/compact/compact), [`compact-basic`](../packages/compact/compact-basic), [`goal`](../packages/goal/goal), [`goal-session`](../packages/goal/goal-session), [`hook-protocol`](../packages/hooks/hook-protocol), [`loader-smoke`](../packages/support/loader-smoke), `server`, [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`session-projection`](../packages/session/session-projection), [`session-projection-cache`](../packages/session/session-projection-cache), [`session-telemetry`](../packages/session/session-telemetry), [`session-telemetry-otel`](../packages/session/session-telemetry-otel), [`session-title`](../packages/session/session-title), [`token-meter`](../packages/llm/token-meter), [`tools`](../packages/core/tools), [`user-approval`](../packages/interaction/user-approval), [`workspace-context`](../packages/context/workspace-context) |
| `session/flush` | `parallel` | [`packages/core/session/src/index.ts:106`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`session-persistence`](../packages/session/session-persistence), [`session-telemetry`](../packages/session/session-telemetry) |
| `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:297`](../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) |
| `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`) | - |
| `subagent/end` | `emit` | [`packages/subagent/subagent/src/index.ts:165`](../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:139`](../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:145`](../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:156`](../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:31`](../packages/core/system-prompt/src/index.ts) | [`system-prompt`](../packages/core/system-prompt) (`waterfall`) | [`agent`](../packages/core/agent), [`agent-presets`](../packages/preset/agent-presets), [`system-prompt`](../packages/core/system-prompt) |
| `system-prompt/change` | `emit` | [`packages/core/system-prompt/src/index.ts:37`](../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`) | - |
| `tools/change` | `emit` | [`packages/core/tools/src/index.ts:193`](../packages/core/tools/src/index.ts) | [`tools`](../packages/core/tools) (`emit`) | - |
| `tools/code-dispatch-log` | `waterfall` | [`packages/core/tools/src/index.ts:175`](../packages/core/tools/src/index.ts) | [`tools`](../packages/core/tools) (`waterfall`) | [`spill-policy`](../packages/spill/spill-policy) |

View File

@@ -10,7 +10,7 @@
| 事件 | 模式 | 声明位置 | 派发方 | 监听方 |
| --- | --- | --- | --- | --- |
| `agent-loop/config-start-failed` | `emit` | [`packages/core/agent-loop/src/index.ts:182`](../packages/core/agent-loop/src/index.ts) | [`agent-loop`](../packages/core/agent-loop) (`events.dispatch`) | - |
| `agent/created` | `emit` | [`packages/core/agent/src/runtime-types.ts:159`](../packages/core/agent/src/runtime-types.ts) | [`agent`](../packages/core/agent) (`events.dispatch`) | [`goal-session`](../packages/goal/goal-session) |
| `agent/created` | `emit` | [`packages/core/agent/src/runtime-types.ts:159`](../packages/core/agent/src/runtime-types.ts) | [`agent`](../packages/core/agent) (`events.dispatch`) | [`agent-presets`](../packages/preset/agent-presets), [`goal-session`](../packages/goal/goal-session) |
| `agent/disposed` | `emit` | [`packages/core/agent/src/runtime-types.ts:168`](../packages/core/agent/src/runtime-types.ts) | [`agent`](../packages/core/agent) (`events.dispatch`) | [`agent-loop`](../packages/core/agent-loop), [`goal-session`](../packages/goal/goal-session), [`subagent`](../packages/subagent/subagent) |
| `agent/error` | `emit` | [`packages/core/agent/src/runtime-types.ts:290`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`acp`](../packages/acp/acp), `apiproxy`, [`goal-session`](../packages/goal/goal-session), [`session-telemetry`](../packages/session/session-telemetry) |
| `agent/inbox/claimed` | `emit` | [`packages/core/agent/src/runtime-types.ts:197`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`acp`](../packages/acp/acp), [`goal-session`](../packages/goal/goal-session), [`subagent`](../packages/subagent/subagent) |
@@ -32,19 +32,19 @@
| `goal/changed` | `emit` | [`packages/goal/goal/src/domain.ts:114`](../packages/goal/goal/src/domain.ts) | [`goal`](../packages/goal/goal) (`emit`) | [`goal-session`](../packages/goal/goal-session) |
| `llm/adapters-updated` | `emit` | [`packages/llm/llm/src/index.ts:75`](../packages/llm/llm/src/index.ts) | [`llm`](../packages/llm/llm) (`events.dispatch`) | `apiproxy`, [`llm`](../packages/llm/llm) |
| `llm/stream` | `waterfall` | [`packages/llm/llm/src/index.ts:64`](../packages/llm/llm/src/index.ts) | [`llm`](../packages/llm/llm) (`waterfall`) | [`agent-loop`](../packages/core/agent-loop), [`llm`](../packages/llm/llm), [`llm-replay`](../packages/support/llm-replay), [`session-checkpoint-policy`](../packages/session/session-checkpoint-policy), [`session-title`](../packages/session/session-title) |
| `session/created` | `emit` | [`packages/core/session/src/index.ts:74`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | `apiproxy`, [`compact`](../packages/compact/compact), [`goal`](../packages/goal/goal), [`hook-protocol`](../packages/hooks/hook-protocol), [`llm-retry`](../packages/llm/llm-retry), [`permission`](../packages/interaction/permission), [`plan-mode`](../packages/plan/plan-mode), `server`, [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`session-telemetry`](../packages/session/session-telemetry), [`tools`](../packages/core/tools), [`user-approval`](../packages/interaction/user-approval) |
| `session/disposed` | `emit` | [`packages/core/session/src/index.ts:84`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`agent-loop`](../packages/core/agent-loop), `apiproxy`, [`session-persistence`](../packages/session/session-persistence), [`session-projection-cache`](../packages/session/session-projection-cache), [`session-telemetry`](../packages/session/session-telemetry), [`session-title`](../packages/session/session-title) |
| `session/event` | `emit` | [`packages/core/session/src/index.ts:96`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`acp`](../packages/acp/acp), [`agent-loop`](../packages/core/agent-loop), `apiproxy`, [`compact`](../packages/compact/compact), [`compact-basic`](../packages/compact/compact-basic), [`goal`](../packages/goal/goal), [`goal-session`](../packages/goal/goal-session), [`hook-protocol`](../packages/hooks/hook-protocol), [`loader-smoke`](../packages/support/loader-smoke), `server`, [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`session-projection`](../packages/session/session-projection), [`session-projection-cache`](../packages/session/session-projection-cache), [`session-telemetry`](../packages/session/session-telemetry), [`session-telemetry-otel`](../packages/session/session-telemetry-otel), [`session-title`](../packages/session/session-title), [`token-meter`](../packages/llm/token-meter), [`tools`](../packages/core/tools), [`user-approval`](../packages/interaction/user-approval), [`workspace-context`](../packages/context/workspace-context) |
| `session/flush` | `parallel` | [`packages/core/session/src/index.ts:105`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`session-persistence`](../packages/session/session-persistence), [`session-telemetry`](../packages/session/session-telemetry) |
| `session/created` | `emit` | [`packages/core/session/src/index.ts:75`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | `apiproxy`, [`compact`](../packages/compact/compact), [`goal`](../packages/goal/goal), [`hook-protocol`](../packages/hooks/hook-protocol), [`llm-retry`](../packages/llm/llm-retry), [`permission`](../packages/interaction/permission), [`plan-mode`](../packages/plan/plan-mode), `server`, [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`session-telemetry`](../packages/session/session-telemetry), [`tools`](../packages/core/tools), [`user-approval`](../packages/interaction/user-approval) |
| `session/disposed` | `emit` | [`packages/core/session/src/index.ts:85`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`agent-loop`](../packages/core/agent-loop), `apiproxy`, [`session-persistence`](../packages/session/session-persistence), [`session-projection-cache`](../packages/session/session-projection-cache), [`session-telemetry`](../packages/session/session-telemetry), [`session-title`](../packages/session/session-title) |
| `session/event` | `emit` | [`packages/core/session/src/index.ts:97`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`acp`](../packages/acp/acp), [`agent-loop`](../packages/core/agent-loop), `apiproxy`, [`compact`](../packages/compact/compact), [`compact-basic`](../packages/compact/compact-basic), [`goal`](../packages/goal/goal), [`goal-session`](../packages/goal/goal-session), [`hook-protocol`](../packages/hooks/hook-protocol), [`loader-smoke`](../packages/support/loader-smoke), `server`, [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`session-projection`](../packages/session/session-projection), [`session-projection-cache`](../packages/session/session-projection-cache), [`session-telemetry`](../packages/session/session-telemetry), [`session-telemetry-otel`](../packages/session/session-telemetry-otel), [`session-title`](../packages/session/session-title), [`token-meter`](../packages/llm/token-meter), [`tools`](../packages/core/tools), [`user-approval`](../packages/interaction/user-approval), [`workspace-context`](../packages/context/workspace-context) |
| `session/flush` | `parallel` | [`packages/core/session/src/index.ts:106`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`session-persistence`](../packages/session/session-persistence), [`session-telemetry`](../packages/session/session-telemetry) |
| `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:297`](../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) |
| `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`) | - |
| `subagent/end` | `emit` | [`packages/subagent/subagent/src/index.ts:165`](../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:139`](../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:145`](../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:156`](../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:31`](../packages/core/system-prompt/src/index.ts) | [`system-prompt`](../packages/core/system-prompt) (`waterfall`) | [`agent`](../packages/core/agent), [`agent-presets`](../packages/preset/agent-presets), [`system-prompt`](../packages/core/system-prompt) |
| `system-prompt/change` | `emit` | [`packages/core/system-prompt/src/index.ts:37`](../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`) | - |
| `tools/change` | `emit` | [`packages/core/tools/src/index.ts:193`](../packages/core/tools/src/index.ts) | [`tools`](../packages/core/tools) (`emit`) | - |
| `tools/code-dispatch-log` | `waterfall` | [`packages/core/tools/src/index.ts:175`](../packages/core/tools/src/index.ts) | [`tools`](../packages/core/tools) (`waterfall`) | [`spill-policy`](../packages/spill/spill-policy) |

View File

@@ -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: 84fcd63100fb16a0ac26bc8f2f33fdd65bcf4e91
module-graph.zh.md: 7aa6a57be53fbc74ed3017dd9d06400f176b99a6

View File

@@ -133,6 +133,7 @@ flowchart TD
end
subgraph group_boot["packages/boot"]
pkg_app_boot["app-boot"]
pkg_cmdline["cmdline"]
end
subgraph group_bundle["packages/bundle"]
pkg_base["base"]
@@ -166,6 +167,7 @@ flowchart TD
pkg_client_ui_slash["client-ui-slash"]
pkg_client_ui_slots["client-ui-slots"]
pkg_client_ui_subagent["client-ui-subagent"]
pkg_client_ui_task["client-ui-task"]
pkg_client_ui_theme["client-ui-theme"]
pkg_client_ui_tool["client-ui-tool"]
pkg_client_ui_trajectory["client-ui-trajectory"]
@@ -199,6 +201,7 @@ flowchart TD
end
subgraph group_feedback["packages/feedback"]
pkg_command_feedback["command-feedback"]
pkg_message_feedback["message-feedback"]
end
subgraph group_guard["packages/guard"]
pkg_repeat_tool_guard["repeat-tool-guard"]
@@ -253,7 +256,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"]
@@ -314,6 +316,7 @@ flowchart TD
pkg_timeout --> pkg_invariants
pkg_scope --> pkg_invariants
pkg_llm_mock_server --> pkg_invariants
pkg_cmdline --> pkg_invariants
pkg_base --> pkg_invariants
pkg_client_modules --> pkg_invariants
pkg_client_schema_form --> pkg_invariants
@@ -398,9 +401,6 @@ flowchart TD
pkg_client_ui_settings --> pkg_client_ui_primitives
pkg_client_ui_settings --> pkg_client_ui_slots
pkg_client_ui_settings --> pkg_invariants
pkg_client_ui_trajectory --> pkg_client_runtime
pkg_client_ui_trajectory --> pkg_client_ui_primitives
pkg_client_ui_trajectory --> pkg_invariants
pkg_credentials_local --> pkg_atomic_write
pkg_credentials_local --> pkg_credentials
pkg_credentials_local --> pkg_environment
@@ -515,12 +515,6 @@ flowchart TD
pkg_host_directory_picker_native --> pkg_client_ui_slots
pkg_host_directory_picker_native --> pkg_client_ui_workspace
pkg_host_directory_picker_native --> pkg_invariants
pkg_agent_presets --> pkg_atomic_write
pkg_agent_presets --> pkg_invariants
pkg_agent_presets --> pkg_paths
pkg_agent_presets --> pkg_scope
pkg_agent_presets --> pkg_session
pkg_agent_presets --> pkg_settings
pkg_persona --> pkg_invariants
pkg_persona --> pkg_system_prompt
pkg_sandbox --> pkg_invariants
@@ -572,8 +566,13 @@ flowchart TD
pkg_time_context --> pkg_agent
pkg_time_context --> pkg_invariants
pkg_time_context --> pkg_session
pkg_host_apiproxy --> pkg_agent_presets
pkg_host_apiproxy --> pkg_invariants
pkg_message_feedback --> pkg_brand
pkg_message_feedback --> pkg_invariants
pkg_message_feedback --> pkg_llm
pkg_message_feedback --> pkg_session
pkg_message_feedback --> pkg_session_persistence
pkg_message_feedback --> pkg_storage_domain
pkg_message_feedback --> pkg_type_meta
pkg_host_directory_picker_auto --> pkg_host_directory_picker_browse
pkg_host_directory_picker_auto --> pkg_host_directory_picker_native
pkg_host_directory_picker_auto --> pkg_host_webserver
@@ -593,6 +592,14 @@ flowchart TD
pkg_user_interaction --> pkg_agent
pkg_user_interaction --> pkg_invariants
pkg_user_interaction --> pkg_llm
pkg_agent_presets --> pkg_agent
pkg_agent_presets --> pkg_atomic_write
pkg_agent_presets --> pkg_invariants
pkg_agent_presets --> pkg_paths
pkg_agent_presets --> pkg_scope
pkg_agent_presets --> pkg_session
pkg_agent_presets --> pkg_settings
pkg_agent_presets --> pkg_system_prompt
pkg_pty --> pkg_agent
pkg_pty --> pkg_brand
pkg_pty --> pkg_invariants
@@ -702,11 +709,6 @@ flowchart TD
pkg_headless --> pkg_invariants
pkg_headless --> pkg_llm
pkg_headless --> pkg_session
pkg_client_test_runtime --> pkg_client_runtime
pkg_client_test_runtime --> pkg_client_ui_slots
pkg_client_test_runtime --> pkg_client_web_react
pkg_client_test_runtime --> pkg_host_apiproxy
pkg_client_test_runtime --> pkg_invariants
pkg_tmux_context --> pkg_agent
pkg_tmux_context --> pkg_bash
pkg_tmux_context --> pkg_invariants
@@ -717,7 +719,10 @@ flowchart TD
pkg_command_feedback --> pkg_commands
pkg_command_feedback --> pkg_invariants
pkg_command_feedback --> pkg_session
pkg_command_feedback --> pkg_session_telemetry
pkg_command_feedback --> pkg_user_id
pkg_host_apiproxy --> pkg_agent_presets
pkg_host_apiproxy --> pkg_invariants
pkg_permission --> pkg_bash
pkg_permission --> pkg_commands
pkg_permission --> pkg_invariants
@@ -793,6 +798,7 @@ flowchart TD
pkg_fs_sandbox --> pkg_invariants
pkg_fs_sandbox --> pkg_sandbox
pkg_fs_sandbox --> pkg_sandbox_policy
pkg_tool_fs --> pkg_attachment
pkg_tool_fs --> pkg_fs
pkg_tool_fs --> pkg_invariants
pkg_tool_fs --> pkg_llm
@@ -829,6 +835,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
@@ -836,6 +844,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
@@ -889,6 +898,18 @@ flowchart TD
pkg_llm_replay --> pkg_invariants
pkg_llm_replay --> pkg_llm
pkg_llm_replay --> pkg_session
pkg_client_test_runtime --> pkg_client_runtime
pkg_client_test_runtime --> pkg_client_ui_slots
pkg_client_test_runtime --> pkg_client_web_react
pkg_client_test_runtime --> pkg_host_apiproxy
pkg_client_test_runtime --> pkg_invariants
pkg_client_ui_trajectory --> pkg_agent
pkg_client_ui_trajectory --> pkg_client_locale
pkg_client_ui_trajectory --> pkg_client_runtime
pkg_client_ui_trajectory --> pkg_client_ui_primitives
pkg_client_ui_trajectory --> pkg_compact
pkg_client_ui_trajectory --> pkg_invariants
pkg_client_ui_trajectory --> pkg_tools
pkg_session_reference --> pkg_agent
pkg_session_reference --> pkg_compact
pkg_session_reference --> pkg_invariants
@@ -923,6 +944,7 @@ flowchart TD
pkg_mcp_client --> pkg_invariants
pkg_mcp_client --> pkg_llm
pkg_mcp_client --> pkg_subprocess
pkg_mcp_client --> pkg_timeout
pkg_mcp_client --> pkg_tools
pkg_tool_bash_persistent --> pkg_agent
pkg_tool_bash_persistent --> pkg_invariants
@@ -1018,12 +1040,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
@@ -1069,10 +1089,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
@@ -1158,6 +1174,12 @@ flowchart TD
pkg_client_ui_subagent --> pkg_invariants
pkg_client_ui_subagent --> pkg_subagent
pkg_client_ui_subagent --> pkg_token_meter
pkg_client_ui_task --> pkg_client_locale
pkg_client_ui_task --> pkg_client_runtime
pkg_client_ui_task --> pkg_client_ui_conversation
pkg_client_ui_task --> pkg_client_ui_primitives
pkg_client_ui_task --> pkg_client_ui_slots
pkg_client_ui_task --> pkg_invariants
pkg_client_ui_tool --> pkg_client_locale
pkg_client_ui_tool --> pkg_client_runtime
pkg_client_ui_tool --> pkg_client_ui_conversation
@@ -1256,6 +1278,7 @@ flowchart TD
| [`timeout`](../packages/util/timeout) | `util` | [`invariants`](../packages/support/invariants) |
| [`scope`](../packages/core/scope) | `core` | [`invariants`](../packages/support/invariants) |
| [`llm-mock-server`](../packages/support/llm-mock-server) | `support` | [`invariants`](../packages/support/invariants) |
| [`cmdline`](../packages/boot/cmdline) | `boot` | [`invariants`](../packages/support/invariants) |
| [`base`](../packages/bundle/base) | `bundle` | [`invariants`](../packages/support/invariants) |
| [`client-modules`](../packages/client/modules) | `client` | [`invariants`](../packages/support/invariants) |
| [`client-schema-form`](../packages/client/schema-form) | `client` | [`invariants`](../packages/support/invariants) |
@@ -1296,7 +1319,6 @@ flowchart TD
| [`client-locale`](../packages/client/locale) | `client` | [`client-connection`](../packages/client/connection), [`client-runtime`](../packages/client/runtime), [`client-ui-primitives`](../packages/client/ui-primitives), [`client-ui-slots`](../packages/client/ui-slots), [`invariants`](../packages/support/invariants) |
| [`client-ui-models`](../packages/client/ui-models) | `client` | [`client-connection`](../packages/client/connection), [`client-runtime`](../packages/client/runtime), [`client-schema-form`](../packages/client/schema-form), [`client-ui-primitives`](../packages/client/ui-primitives), [`client-ui-slots`](../packages/client/ui-slots), [`client-web-react`](../packages/client/web-react), [`invariants`](../packages/support/invariants) |
| [`client-ui-settings`](../packages/client/ui-settings) | `client` | [`client-runtime`](../packages/client/runtime), [`client-ui-primitives`](../packages/client/ui-primitives), [`client-ui-slots`](../packages/client/ui-slots), [`invariants`](../packages/support/invariants) |
| [`client-ui-trajectory`](../packages/client/ui-trajectory) | `client` | [`client-runtime`](../packages/client/runtime), [`client-ui-primitives`](../packages/client/ui-primitives), [`invariants`](../packages/support/invariants) |
| [`credentials-local`](../packages/credentials/credentials-local) | `credentials` | [`atomic-write`](../packages/util/atomic-write), [`credentials`](../packages/credentials/credentials), [`environment`](../packages/util/environment), [`invariants`](../packages/support/invariants), [`paths`](../packages/util/paths) |
| [`settings-local`](../packages/settings/settings-local) | `settings` | [`atomic-write`](../packages/util/atomic-write), [`invariants`](../packages/support/invariants), [`paths`](../packages/util/paths), [`settings`](../packages/settings/settings) |
| [`llm-deepseek`](../packages/llm/llm-deepseek) | `llm` | [`credentials`](../packages/credentials/credentials), [`environment`](../packages/util/environment), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`settings`](../packages/settings/settings), [`timeout`](../packages/util/timeout) |
@@ -1324,7 +1346,6 @@ flowchart TD
| [`code-runtime-worker`](../packages/code-runtime/code-runtime-worker) | `code-runtime` | [`code-runtime`](../packages/code-runtime/code-runtime), [`invariants`](../packages/support/invariants), [`session`](../packages/core/session), [`timeout`](../packages/util/timeout) |
| [`host-directory-picker-browse`](../packages/host/directory-picker-browse) | `host` | [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-primitives`](../packages/client/ui-primitives), [`client-ui-slots`](../packages/client/ui-slots), [`client-ui-workspace`](../packages/client/ui-workspace), [`invariants`](../packages/support/invariants) |
| [`host-directory-picker-native`](../packages/host/directory-picker-native) | `host` | [`client-runtime`](../packages/client/runtime), [`client-ui-slots`](../packages/client/ui-slots), [`client-ui-workspace`](../packages/client/ui-workspace), [`invariants`](../packages/support/invariants) |
| [`agent-presets`](../packages/preset/agent-presets) | `preset` | [`atomic-write`](../packages/util/atomic-write), [`invariants`](../packages/support/invariants), [`paths`](../packages/util/paths), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`settings`](../packages/settings/settings) |
| [`persona`](../packages/preset/persona) | `preset` | [`invariants`](../packages/support/invariants), [`system-prompt`](../packages/core/system-prompt) |
| [`sandbox`](../packages/sandbox/sandbox) | `sandbox` | [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session) |
| [`session-persistence`](../packages/session/session-persistence) | `session` | [`brand`](../packages/util/brand), [`invariants`](../packages/support/invariants), [`session`](../packages/core/session), [`timeout`](../packages/util/timeout) |
@@ -1338,11 +1359,12 @@ flowchart TD
| [`spill-local`](../packages/spill/spill-local) | `spill` | [`invariants`](../packages/support/invariants), [`spill`](../packages/spill/spill) |
| [`loader-smoke`](../packages/support/loader-smoke) | `support` | [`agent`](../packages/core/agent), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session) |
| [`time-context`](../packages/context/time-context) | `context` | [`agent`](../packages/core/agent), [`invariants`](../packages/support/invariants), [`session`](../packages/core/session) |
| [`host-apiproxy`](../packages/host/apiproxy) | `host` | [`agent-presets`](../packages/preset/agent-presets), [`invariants`](../packages/support/invariants) |
| [`message-feedback`](../packages/feedback/message-feedback) | `feedback` | [`brand`](../packages/util/brand), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`storage-domain`](../packages/storage/storage-domain), [`type-meta`](../packages/typert/type-meta) |
| [`host-directory-picker-auto`](../packages/host/directory-picker-auto) | `host` | [`host-directory-picker-browse`](../packages/host/directory-picker-browse), [`host-directory-picker-native`](../packages/host/directory-picker-native), [`host-webserver`](../packages/host/webserver), [`invariants`](../packages/support/invariants) |
| [`commands`](../packages/interaction/commands) | `interaction` | [`agent`](../packages/core/agent), [`brand`](../packages/util/brand), [`invariants`](../packages/support/invariants), [`scope`](../packages/core/scope), [`session`](../packages/core/session) |
| [`user-approval`](../packages/interaction/user-approval) | `interaction` | [`agent`](../packages/core/agent), [`brand`](../packages/util/brand), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`system-prompt`](../packages/core/system-prompt) |
| [`user-interaction`](../packages/interaction/user-interaction) | `interaction` | [`agent`](../packages/core/agent), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm) |
| [`agent-presets`](../packages/preset/agent-presets) | `preset` | [`agent`](../packages/core/agent), [`atomic-write`](../packages/util/atomic-write), [`invariants`](../packages/support/invariants), [`paths`](../packages/util/paths), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`settings`](../packages/settings/settings), [`system-prompt`](../packages/core/system-prompt) |
| [`pty`](../packages/pty/pty) | `pty` | [`agent`](../packages/core/agent), [`brand`](../packages/util/brand), [`invariants`](../packages/support/invariants) |
| [`sandbox-local`](../packages/sandbox/sandbox-local) | `sandbox` | [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`sandbox`](../packages/sandbox/sandbox), [`session`](../packages/core/session) |
| [`sandbox-policy`](../packages/sandbox/sandbox-policy) | `sandbox` | [`agent`](../packages/core/agent), [`invariants`](../packages/support/invariants), [`sandbox`](../packages/sandbox/sandbox), [`session`](../packages/core/session), [`system-prompt`](../packages/core/system-prompt) |
@@ -1369,10 +1391,10 @@ flowchart TD
| [`acp`](../packages/acp/acp) | `acp` | [`agent`](../packages/core/agent), [`invariants`](../packages/support/invariants), [`session`](../packages/core/session), [`user-approval`](../packages/interaction/user-approval) |
| [`api-remotes`](../packages/api/remotes) | `api` | [`agent`](../packages/core/agent), [`goal`](../packages/goal/goal), [`invariants`](../packages/support/invariants), [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`typert-registry`](../packages/typert/registry) |
| [`headless`](../packages/bundle/headless) | `bundle` | [`agent`](../packages/core/agent), [`agent-default-model`](../packages/core/agent-default-model), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session) |
| [`client-test-runtime`](../packages/client/test-runtime) | `client` | [`client-runtime`](../packages/client/runtime), [`client-ui-slots`](../packages/client/ui-slots), [`client-web-react`](../packages/client/web-react), [`host-apiproxy`](../packages/host/apiproxy), [`invariants`](../packages/support/invariants) |
| [`tmux-context`](../packages/context/tmux-context) | `context` | [`agent`](../packages/core/agent), [`bash`](../packages/bash/bash), [`invariants`](../packages/support/invariants), [`session`](../packages/core/session) |
| [`fs-e2b`](../packages/e2b/fs-e2b) | `e2b` | [`e2b`](../packages/e2b/e2b), [`fs`](../packages/fs/fs), [`invariants`](../packages/support/invariants) |
| [`command-feedback`](../packages/feedback/command-feedback) | `feedback` | [`commands`](../packages/interaction/commands), [`invariants`](../packages/support/invariants), [`session`](../packages/core/session), [`user-id`](../packages/session/user-id) |
| [`command-feedback`](../packages/feedback/command-feedback) | `feedback` | [`commands`](../packages/interaction/commands), [`invariants`](../packages/support/invariants), [`session`](../packages/core/session), [`session-telemetry`](../packages/session/session-telemetry), [`user-id`](../packages/session/user-id) |
| [`host-apiproxy`](../packages/host/apiproxy) | `host` | [`agent-presets`](../packages/preset/agent-presets), [`invariants`](../packages/support/invariants) |
| [`permission`](../packages/interaction/permission) | `interaction` | [`bash`](../packages/bash/bash), [`commands`](../packages/interaction/commands), [`invariants`](../packages/support/invariants), [`sandbox`](../packages/sandbox/sandbox), [`sandbox-policy`](../packages/sandbox/sandbox-policy), [`session`](../packages/core/session), [`session-projection`](../packages/session/session-projection), [`settings`](../packages/settings/settings), [`user-approval`](../packages/interaction/user-approval) |
| [`lsp-local`](../packages/lsp/lsp-local) | `lsp` | [`brand`](../packages/util/brand), [`fs`](../packages/fs/fs), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`lsp`](../packages/lsp/lsp), [`subprocess`](../packages/subprocess/subprocess), [`timeout`](../packages/util/timeout) |
| [`pty-local`](../packages/pty/pty-local) | `pty` | [`agent`](../packages/core/agent), [`invariants`](../packages/support/invariants), [`pty`](../packages/pty/pty), [`sandbox`](../packages/sandbox/sandbox), [`sandbox-policy`](../packages/sandbox/sandbox-policy), [`session`](../packages/core/session), [`subprocess`](../packages/subprocess/subprocess) |
@@ -1386,12 +1408,12 @@ flowchart TD
| [`bash-sandbox`](../packages/bash/bash-sandbox) | `bash` | [`bash`](../packages/bash/bash), [`bash-local`](../packages/bash/bash-local), [`invariants`](../packages/support/invariants), [`sandbox`](../packages/sandbox/sandbox), [`sandbox-policy`](../packages/sandbox/sandbox-policy) |
| [`pwsh-sandbox`](../packages/bash/pwsh-sandbox) | `bash` | [`bash`](../packages/bash/bash), [`invariants`](../packages/support/invariants), [`pwsh-local`](../packages/bash/pwsh-local), [`sandbox`](../packages/sandbox/sandbox), [`sandbox-policy`](../packages/sandbox/sandbox-policy) |
| [`fs-sandbox`](../packages/fs/fs-sandbox) | `fs` | [`fs`](../packages/fs/fs), [`fs-local`](../packages/fs/fs-local), [`invariants`](../packages/support/invariants), [`sandbox`](../packages/sandbox/sandbox), [`sandbox-policy`](../packages/sandbox/sandbox-policy) |
| [`tool-fs`](../packages/fs/tool-fs) | `fs` | [`fs`](../packages/fs/fs), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`sandbox`](../packages/sandbox/sandbox), [`sandbox-policy`](../packages/sandbox/sandbox-policy), [`session`](../packages/core/session), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools), [`user-approval`](../packages/interaction/user-approval) |
| [`tool-fs`](../packages/fs/tool-fs) | `fs` | [`attachment`](../packages/attachment/attachment), [`fs`](../packages/fs/fs), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`sandbox`](../packages/sandbox/sandbox), [`sandbox-policy`](../packages/sandbox/sandbox-policy), [`session`](../packages/core/session), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools), [`user-approval`](../packages/interaction/user-approval) |
| [`tool-fs-search`](../packages/fs/tool-fs-search) | `fs` | [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`retention`](../packages/util/retention), [`session`](../packages/core/session), [`spill`](../packages/spill/spill), [`subprocess`](../packages/subprocess/subprocess), [`system-prompt`](../packages/core/system-prompt), [`timeout`](../packages/util/timeout), [`tools`](../packages/core/tools) |
| [`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), [`agent-presets`](../packages/preset/agent-presets), [`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), [`agent-presets`](../packages/preset/agent-presets), [`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) |
@@ -1401,13 +1423,15 @@ flowchart TD
| [`tool-session-query`](../packages/session-query/tool-session-query) | `session-query` | [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`session-query`](../packages/session-query/session-query), [`system-prompt`](../packages/core/system-prompt), [`timeout`](../packages/util/timeout), [`tools`](../packages/core/tools) |
| [`agent-loop-testkit`](../packages/support/agent-loop-testkit) | `support` | [`agent`](../packages/core/agent), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools) |
| [`llm-replay`](../packages/support/llm-replay) | `support` | [`compact`](../packages/compact/compact), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session) |
| [`client-test-runtime`](../packages/client/test-runtime) | `client` | [`client-runtime`](../packages/client/runtime), [`client-ui-slots`](../packages/client/ui-slots), [`client-web-react`](../packages/client/web-react), [`host-apiproxy`](../packages/host/apiproxy), [`invariants`](../packages/support/invariants) |
| [`client-ui-trajectory`](../packages/client/ui-trajectory) | `client` | [`agent`](../packages/core/agent), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-primitives`](../packages/client/ui-primitives), [`compact`](../packages/compact/compact), [`invariants`](../packages/support/invariants), [`tools`](../packages/core/tools) |
| [`session-reference`](../packages/context/session-reference) | `context` | [`agent`](../packages/core/agent), [`compact`](../packages/compact/compact), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`retention`](../packages/util/retention), [`session`](../packages/core/session), [`session-query`](../packages/session-query/session-query) |
| [`workspace-context`](../packages/context/workspace-context) | `context` | [`agent`](../packages/core/agent), [`fs`](../packages/fs/fs), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`paths`](../packages/util/paths), [`session`](../packages/core/session), [`tools`](../packages/core/tools) |
| [`repeat-tool-guard`](../packages/guard/repeat-tool-guard) | `guard` | [`agent`](../packages/core/agent), [`invariants`](../packages/support/invariants), [`tools`](../packages/core/tools) |
| [`timeout-policy`](../packages/guard/timeout-policy) | `guard` | [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`timeout`](../packages/util/timeout), [`tools`](../packages/core/tools) |
| [`tool-ask-user`](../packages/interaction/tool-ask-user) | `interaction` | [`agent`](../packages/core/agent), [`invariants`](../packages/support/invariants), [`tools`](../packages/core/tools), [`user-interaction`](../packages/interaction/user-interaction) |
| [`tool-lsp`](../packages/lsp/tool-lsp) | `lsp` | [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`lsp`](../packages/lsp/lsp), [`system-prompt`](../packages/core/system-prompt), [`timeout`](../packages/util/timeout), [`tools`](../packages/core/tools) |
| [`mcp-client`](../packages/mcp/mcp-client) | `mcp` | [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`subprocess`](../packages/subprocess/subprocess), [`tools`](../packages/core/tools) |
| [`mcp-client`](../packages/mcp/mcp-client) | `mcp` | [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`subprocess`](../packages/subprocess/subprocess), [`timeout`](../packages/util/timeout), [`tools`](../packages/core/tools) |
| [`tool-bash-persistent`](../packages/pty/tool-bash-persistent) | `pty` | [`agent`](../packages/core/agent), [`invariants`](../packages/support/invariants), [`pty`](../packages/pty/pty), [`timeout`](../packages/util/timeout), [`tools`](../packages/core/tools) |
| [`tool-pty`](../packages/pty/tool-pty) | `pty` | [`agent`](../packages/core/agent), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`pty`](../packages/pty/pty), [`retention`](../packages/util/retention), [`system-prompt`](../packages/core/system-prompt), [`tasks`](../packages/tasks/tasks), [`tools`](../packages/core/tools) |
| [`tool-cordis`](../packages/self-modification/tool-cordis) | `self-modification` | [`invariants`](../packages/support/invariants), [`scope`](../packages/core/scope), [`tools`](../packages/core/tools) |
@@ -1422,7 +1446,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) |
@@ -1430,7 +1454,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) |
@@ -1443,6 +1466,7 @@ flowchart TD
| [`client-ui-goal`](../packages/client/ui-goal) | `client` | [`api-remotes`](../packages/api/remotes), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-primitives`](../packages/client/ui-primitives), [`client-ui-slots`](../packages/client/ui-slots), [`goal`](../packages/goal/goal), [`invariants`](../packages/support/invariants) |
| [`client-ui-plan`](../packages/client/ui-plan) | `client` | [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-primitives`](../packages/client/ui-primitives), [`client-ui-slots`](../packages/client/ui-slots), [`invariants`](../packages/support/invariants), [`plan-mode`](../packages/plan/plan-mode) |
| [`client-ui-subagent`](../packages/client/ui-subagent) | `client` | [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-primitives`](../packages/client/ui-primitives), [`client-ui-slash`](../packages/client/ui-slash), [`client-ui-slots`](../packages/client/ui-slots), [`invariants`](../packages/support/invariants), [`subagent`](../packages/subagent/subagent), [`token-meter`](../packages/llm/token-meter) |
| [`client-ui-task`](../packages/client/ui-task) | `client` | [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-primitives`](../packages/client/ui-primitives), [`client-ui-slots`](../packages/client/ui-slots), [`invariants`](../packages/support/invariants) |
| [`client-ui-tool`](../packages/client/ui-tool) | `client` | [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-primitives`](../packages/client/ui-primitives), [`client-ui-slots`](../packages/client/ui-slots), [`invariants`](../packages/support/invariants) |
| [`agent-spine-demo`](../packages/examples/agent-spine-demo) | `examples` | [`agent`](../packages/core/agent), [`agent-loop`](../packages/core/agent-loop), [`bash-env`](../packages/bash/bash-env), [`goal`](../packages/goal/goal), [`goal-session`](../packages/goal/goal-session), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`llm-retry`](../packages/llm/llm-retry), [`paths`](../packages/util/paths), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`session-title`](../packages/session/session-title), [`skill`](../packages/skill/skill), [`skill-local`](../packages/skill/skill-local), [`system-prompt`](../packages/core/system-prompt), [`tasks-local`](../packages/tasks/tasks-local), [`tool-bash`](../packages/bash/tool-bash), [`tool-goal`](../packages/goal/tool-goal), [`tool-skill`](../packages/skill/tool-skill), [`tool-tasks`](../packages/tasks/tool-tasks), [`tools`](../packages/core/tools), [`workspace-context`](../packages/context/workspace-context) |
| [`jsonrpc`](../packages/scaffold/server) | `scaffold` | [`agent`](../packages/core/agent), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`llm-deepseek`](../packages/llm/llm-deepseek), [`scope`](../packages/core/scope), [`sdk-protocol`](../packages/scaffold/protocol), [`session`](../packages/core/session), [`subagent`](../packages/subagent/subagent) |

View File

@@ -135,6 +135,7 @@ flowchart TD
end
subgraph group_boot["packages/boot"]
pkg_app_boot["app-boot"]
pkg_cmdline["cmdline"]
end
subgraph group_bundle["packages/bundle"]
pkg_base["base"]
@@ -168,6 +169,7 @@ flowchart TD
pkg_client_ui_slash["client-ui-slash"]
pkg_client_ui_slots["client-ui-slots"]
pkg_client_ui_subagent["client-ui-subagent"]
pkg_client_ui_task["client-ui-task"]
pkg_client_ui_theme["client-ui-theme"]
pkg_client_ui_tool["client-ui-tool"]
pkg_client_ui_trajectory["client-ui-trajectory"]
@@ -201,6 +203,7 @@ flowchart TD
end
subgraph group_feedback["packages/feedback"]
pkg_command_feedback["command-feedback"]
pkg_message_feedback["message-feedback"]
end
subgraph group_guard["packages/guard"]
pkg_repeat_tool_guard["repeat-tool-guard"]
@@ -255,7 +258,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"]
@@ -316,6 +318,7 @@ flowchart TD
pkg_timeout --> pkg_invariants
pkg_scope --> pkg_invariants
pkg_llm_mock_server --> pkg_invariants
pkg_cmdline --> pkg_invariants
pkg_base --> pkg_invariants
pkg_client_modules --> pkg_invariants
pkg_client_schema_form --> pkg_invariants
@@ -400,9 +403,6 @@ flowchart TD
pkg_client_ui_settings --> pkg_client_ui_primitives
pkg_client_ui_settings --> pkg_client_ui_slots
pkg_client_ui_settings --> pkg_invariants
pkg_client_ui_trajectory --> pkg_client_runtime
pkg_client_ui_trajectory --> pkg_client_ui_primitives
pkg_client_ui_trajectory --> pkg_invariants
pkg_credentials_local --> pkg_atomic_write
pkg_credentials_local --> pkg_credentials
pkg_credentials_local --> pkg_environment
@@ -517,12 +517,6 @@ flowchart TD
pkg_host_directory_picker_native --> pkg_client_ui_slots
pkg_host_directory_picker_native --> pkg_client_ui_workspace
pkg_host_directory_picker_native --> pkg_invariants
pkg_agent_presets --> pkg_atomic_write
pkg_agent_presets --> pkg_invariants
pkg_agent_presets --> pkg_paths
pkg_agent_presets --> pkg_scope
pkg_agent_presets --> pkg_session
pkg_agent_presets --> pkg_settings
pkg_persona --> pkg_invariants
pkg_persona --> pkg_system_prompt
pkg_sandbox --> pkg_invariants
@@ -574,8 +568,13 @@ flowchart TD
pkg_time_context --> pkg_agent
pkg_time_context --> pkg_invariants
pkg_time_context --> pkg_session
pkg_host_apiproxy --> pkg_agent_presets
pkg_host_apiproxy --> pkg_invariants
pkg_message_feedback --> pkg_brand
pkg_message_feedback --> pkg_invariants
pkg_message_feedback --> pkg_llm
pkg_message_feedback --> pkg_session
pkg_message_feedback --> pkg_session_persistence
pkg_message_feedback --> pkg_storage_domain
pkg_message_feedback --> pkg_type_meta
pkg_host_directory_picker_auto --> pkg_host_directory_picker_browse
pkg_host_directory_picker_auto --> pkg_host_directory_picker_native
pkg_host_directory_picker_auto --> pkg_host_webserver
@@ -595,6 +594,14 @@ flowchart TD
pkg_user_interaction --> pkg_agent
pkg_user_interaction --> pkg_invariants
pkg_user_interaction --> pkg_llm
pkg_agent_presets --> pkg_agent
pkg_agent_presets --> pkg_atomic_write
pkg_agent_presets --> pkg_invariants
pkg_agent_presets --> pkg_paths
pkg_agent_presets --> pkg_scope
pkg_agent_presets --> pkg_session
pkg_agent_presets --> pkg_settings
pkg_agent_presets --> pkg_system_prompt
pkg_pty --> pkg_agent
pkg_pty --> pkg_brand
pkg_pty --> pkg_invariants
@@ -704,11 +711,6 @@ flowchart TD
pkg_headless --> pkg_invariants
pkg_headless --> pkg_llm
pkg_headless --> pkg_session
pkg_client_test_runtime --> pkg_client_runtime
pkg_client_test_runtime --> pkg_client_ui_slots
pkg_client_test_runtime --> pkg_client_web_react
pkg_client_test_runtime --> pkg_host_apiproxy
pkg_client_test_runtime --> pkg_invariants
pkg_tmux_context --> pkg_agent
pkg_tmux_context --> pkg_bash
pkg_tmux_context --> pkg_invariants
@@ -719,7 +721,10 @@ flowchart TD
pkg_command_feedback --> pkg_commands
pkg_command_feedback --> pkg_invariants
pkg_command_feedback --> pkg_session
pkg_command_feedback --> pkg_session_telemetry
pkg_command_feedback --> pkg_user_id
pkg_host_apiproxy --> pkg_agent_presets
pkg_host_apiproxy --> pkg_invariants
pkg_permission --> pkg_bash
pkg_permission --> pkg_commands
pkg_permission --> pkg_invariants
@@ -795,6 +800,7 @@ flowchart TD
pkg_fs_sandbox --> pkg_invariants
pkg_fs_sandbox --> pkg_sandbox
pkg_fs_sandbox --> pkg_sandbox_policy
pkg_tool_fs --> pkg_attachment
pkg_tool_fs --> pkg_fs
pkg_tool_fs --> pkg_invariants
pkg_tool_fs --> pkg_llm
@@ -831,6 +837,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
@@ -838,6 +846,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
@@ -891,6 +900,18 @@ flowchart TD
pkg_llm_replay --> pkg_invariants
pkg_llm_replay --> pkg_llm
pkg_llm_replay --> pkg_session
pkg_client_test_runtime --> pkg_client_runtime
pkg_client_test_runtime --> pkg_client_ui_slots
pkg_client_test_runtime --> pkg_client_web_react
pkg_client_test_runtime --> pkg_host_apiproxy
pkg_client_test_runtime --> pkg_invariants
pkg_client_ui_trajectory --> pkg_agent
pkg_client_ui_trajectory --> pkg_client_locale
pkg_client_ui_trajectory --> pkg_client_runtime
pkg_client_ui_trajectory --> pkg_client_ui_primitives
pkg_client_ui_trajectory --> pkg_compact
pkg_client_ui_trajectory --> pkg_invariants
pkg_client_ui_trajectory --> pkg_tools
pkg_session_reference --> pkg_agent
pkg_session_reference --> pkg_compact
pkg_session_reference --> pkg_invariants
@@ -925,6 +946,7 @@ flowchart TD
pkg_mcp_client --> pkg_invariants
pkg_mcp_client --> pkg_llm
pkg_mcp_client --> pkg_subprocess
pkg_mcp_client --> pkg_timeout
pkg_mcp_client --> pkg_tools
pkg_tool_bash_persistent --> pkg_agent
pkg_tool_bash_persistent --> pkg_invariants
@@ -1020,12 +1042,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
@@ -1071,10 +1091,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
@@ -1160,6 +1176,12 @@ flowchart TD
pkg_client_ui_subagent --> pkg_invariants
pkg_client_ui_subagent --> pkg_subagent
pkg_client_ui_subagent --> pkg_token_meter
pkg_client_ui_task --> pkg_client_locale
pkg_client_ui_task --> pkg_client_runtime
pkg_client_ui_task --> pkg_client_ui_conversation
pkg_client_ui_task --> pkg_client_ui_primitives
pkg_client_ui_task --> pkg_client_ui_slots
pkg_client_ui_task --> pkg_invariants
pkg_client_ui_tool --> pkg_client_locale
pkg_client_ui_tool --> pkg_client_runtime
pkg_client_ui_tool --> pkg_client_ui_conversation
@@ -1246,7 +1268,7 @@ flowchart TD
pkg_acp_demo --> pkg_workspace_context
```
| 包 | 分组 | 依赖项 |
| Package | Group | Depends on |
| --- | --- | --- |
| [`invariants`](../packages/support/invariants) | `support` | — |
| [`atomic-write`](../packages/util/atomic-write) | `util` | [`invariants`](../packages/support/invariants) |
@@ -1258,6 +1280,7 @@ flowchart TD
| [`timeout`](../packages/util/timeout) | `util` | [`invariants`](../packages/support/invariants) |
| [`scope`](../packages/core/scope) | `core` | [`invariants`](../packages/support/invariants) |
| [`llm-mock-server`](../packages/support/llm-mock-server) | `support` | [`invariants`](../packages/support/invariants) |
| [`cmdline`](../packages/boot/cmdline) | `boot` | [`invariants`](../packages/support/invariants) |
| [`base`](../packages/bundle/base) | `bundle` | [`invariants`](../packages/support/invariants) |
| [`client-modules`](../packages/client/modules) | `client` | [`invariants`](../packages/support/invariants) |
| [`client-schema-form`](../packages/client/schema-form) | `client` | [`invariants`](../packages/support/invariants) |
@@ -1298,7 +1321,6 @@ flowchart TD
| [`client-locale`](../packages/client/locale) | `client` | [`client-connection`](../packages/client/connection), [`client-runtime`](../packages/client/runtime), [`client-ui-primitives`](../packages/client/ui-primitives), [`client-ui-slots`](../packages/client/ui-slots), [`invariants`](../packages/support/invariants) |
| [`client-ui-models`](../packages/client/ui-models) | `client` | [`client-connection`](../packages/client/connection), [`client-runtime`](../packages/client/runtime), [`client-schema-form`](../packages/client/schema-form), [`client-ui-primitives`](../packages/client/ui-primitives), [`client-ui-slots`](../packages/client/ui-slots), [`client-web-react`](../packages/client/web-react), [`invariants`](../packages/support/invariants) |
| [`client-ui-settings`](../packages/client/ui-settings) | `client` | [`client-runtime`](../packages/client/runtime), [`client-ui-primitives`](../packages/client/ui-primitives), [`client-ui-slots`](../packages/client/ui-slots), [`invariants`](../packages/support/invariants) |
| [`client-ui-trajectory`](../packages/client/ui-trajectory) | `client` | [`client-runtime`](../packages/client/runtime), [`client-ui-primitives`](../packages/client/ui-primitives), [`invariants`](../packages/support/invariants) |
| [`credentials-local`](../packages/credentials/credentials-local) | `credentials` | [`atomic-write`](../packages/util/atomic-write), [`credentials`](../packages/credentials/credentials), [`environment`](../packages/util/environment), [`invariants`](../packages/support/invariants), [`paths`](../packages/util/paths) |
| [`settings-local`](../packages/settings/settings-local) | `settings` | [`atomic-write`](../packages/util/atomic-write), [`invariants`](../packages/support/invariants), [`paths`](../packages/util/paths), [`settings`](../packages/settings/settings) |
| [`llm-deepseek`](../packages/llm/llm-deepseek) | `llm` | [`credentials`](../packages/credentials/credentials), [`environment`](../packages/util/environment), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`settings`](../packages/settings/settings), [`timeout`](../packages/util/timeout) |
@@ -1326,7 +1348,6 @@ flowchart TD
| [`code-runtime-worker`](../packages/code-runtime/code-runtime-worker) | `code-runtime` | [`code-runtime`](../packages/code-runtime/code-runtime), [`invariants`](../packages/support/invariants), [`session`](../packages/core/session), [`timeout`](../packages/util/timeout) |
| [`host-directory-picker-browse`](../packages/host/directory-picker-browse) | `host` | [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-primitives`](../packages/client/ui-primitives), [`client-ui-slots`](../packages/client/ui-slots), [`client-ui-workspace`](../packages/client/ui-workspace), [`invariants`](../packages/support/invariants) |
| [`host-directory-picker-native`](../packages/host/directory-picker-native) | `host` | [`client-runtime`](../packages/client/runtime), [`client-ui-slots`](../packages/client/ui-slots), [`client-ui-workspace`](../packages/client/ui-workspace), [`invariants`](../packages/support/invariants) |
| [`agent-presets`](../packages/preset/agent-presets) | `preset` | [`atomic-write`](../packages/util/atomic-write), [`invariants`](../packages/support/invariants), [`paths`](../packages/util/paths), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`settings`](../packages/settings/settings) |
| [`persona`](../packages/preset/persona) | `preset` | [`invariants`](../packages/support/invariants), [`system-prompt`](../packages/core/system-prompt) |
| [`sandbox`](../packages/sandbox/sandbox) | `sandbox` | [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session) |
| [`session-persistence`](../packages/session/session-persistence) | `session` | [`brand`](../packages/util/brand), [`invariants`](../packages/support/invariants), [`session`](../packages/core/session), [`timeout`](../packages/util/timeout) |
@@ -1340,11 +1361,12 @@ flowchart TD
| [`spill-local`](../packages/spill/spill-local) | `spill` | [`invariants`](../packages/support/invariants), [`spill`](../packages/spill/spill) |
| [`loader-smoke`](../packages/support/loader-smoke) | `support` | [`agent`](../packages/core/agent), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session) |
| [`time-context`](../packages/context/time-context) | `context` | [`agent`](../packages/core/agent), [`invariants`](../packages/support/invariants), [`session`](../packages/core/session) |
| [`host-apiproxy`](../packages/host/apiproxy) | `host` | [`agent-presets`](../packages/preset/agent-presets), [`invariants`](../packages/support/invariants) |
| [`message-feedback`](../packages/feedback/message-feedback) | `feedback` | [`brand`](../packages/util/brand), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`storage-domain`](../packages/storage/storage-domain), [`type-meta`](../packages/typert/type-meta) |
| [`host-directory-picker-auto`](../packages/host/directory-picker-auto) | `host` | [`host-directory-picker-browse`](../packages/host/directory-picker-browse), [`host-directory-picker-native`](../packages/host/directory-picker-native), [`host-webserver`](../packages/host/webserver), [`invariants`](../packages/support/invariants) |
| [`commands`](../packages/interaction/commands) | `interaction` | [`agent`](../packages/core/agent), [`brand`](../packages/util/brand), [`invariants`](../packages/support/invariants), [`scope`](../packages/core/scope), [`session`](../packages/core/session) |
| [`user-approval`](../packages/interaction/user-approval) | `interaction` | [`agent`](../packages/core/agent), [`brand`](../packages/util/brand), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`system-prompt`](../packages/core/system-prompt) |
| [`user-interaction`](../packages/interaction/user-interaction) | `interaction` | [`agent`](../packages/core/agent), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm) |
| [`agent-presets`](../packages/preset/agent-presets) | `preset` | [`agent`](../packages/core/agent), [`atomic-write`](../packages/util/atomic-write), [`invariants`](../packages/support/invariants), [`paths`](../packages/util/paths), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`settings`](../packages/settings/settings), [`system-prompt`](../packages/core/system-prompt) |
| [`pty`](../packages/pty/pty) | `pty` | [`agent`](../packages/core/agent), [`brand`](../packages/util/brand), [`invariants`](../packages/support/invariants) |
| [`sandbox-local`](../packages/sandbox/sandbox-local) | `sandbox` | [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`sandbox`](../packages/sandbox/sandbox), [`session`](../packages/core/session) |
| [`sandbox-policy`](../packages/sandbox/sandbox-policy) | `sandbox` | [`agent`](../packages/core/agent), [`invariants`](../packages/support/invariants), [`sandbox`](../packages/sandbox/sandbox), [`session`](../packages/core/session), [`system-prompt`](../packages/core/system-prompt) |
@@ -1371,10 +1393,10 @@ flowchart TD
| [`acp`](../packages/acp/acp) | `acp` | [`agent`](../packages/core/agent), [`invariants`](../packages/support/invariants), [`session`](../packages/core/session), [`user-approval`](../packages/interaction/user-approval) |
| [`api-remotes`](../packages/api/remotes) | `api` | [`agent`](../packages/core/agent), [`goal`](../packages/goal/goal), [`invariants`](../packages/support/invariants), [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`typert-registry`](../packages/typert/registry) |
| [`headless`](../packages/bundle/headless) | `bundle` | [`agent`](../packages/core/agent), [`agent-default-model`](../packages/core/agent-default-model), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session) |
| [`client-test-runtime`](../packages/client/test-runtime) | `client` | [`client-runtime`](../packages/client/runtime), [`client-ui-slots`](../packages/client/ui-slots), [`client-web-react`](../packages/client/web-react), [`host-apiproxy`](../packages/host/apiproxy), [`invariants`](../packages/support/invariants) |
| [`tmux-context`](../packages/context/tmux-context) | `context` | [`agent`](../packages/core/agent), [`bash`](../packages/bash/bash), [`invariants`](../packages/support/invariants), [`session`](../packages/core/session) |
| [`fs-e2b`](../packages/e2b/fs-e2b) | `e2b` | [`e2b`](../packages/e2b/e2b), [`fs`](../packages/fs/fs), [`invariants`](../packages/support/invariants) |
| [`command-feedback`](../packages/feedback/command-feedback) | `feedback` | [`commands`](../packages/interaction/commands), [`invariants`](../packages/support/invariants), [`session`](../packages/core/session), [`user-id`](../packages/session/user-id) |
| [`command-feedback`](../packages/feedback/command-feedback) | `feedback` | [`commands`](../packages/interaction/commands), [`invariants`](../packages/support/invariants), [`session`](../packages/core/session), [`session-telemetry`](../packages/session/session-telemetry), [`user-id`](../packages/session/user-id) |
| [`host-apiproxy`](../packages/host/apiproxy) | `host` | [`agent-presets`](../packages/preset/agent-presets), [`invariants`](../packages/support/invariants) |
| [`permission`](../packages/interaction/permission) | `interaction` | [`bash`](../packages/bash/bash), [`commands`](../packages/interaction/commands), [`invariants`](../packages/support/invariants), [`sandbox`](../packages/sandbox/sandbox), [`sandbox-policy`](../packages/sandbox/sandbox-policy), [`session`](../packages/core/session), [`session-projection`](../packages/session/session-projection), [`settings`](../packages/settings/settings), [`user-approval`](../packages/interaction/user-approval) |
| [`lsp-local`](../packages/lsp/lsp-local) | `lsp` | [`brand`](../packages/util/brand), [`fs`](../packages/fs/fs), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`lsp`](../packages/lsp/lsp), [`subprocess`](../packages/subprocess/subprocess), [`timeout`](../packages/util/timeout) |
| [`pty-local`](../packages/pty/pty-local) | `pty` | [`agent`](../packages/core/agent), [`invariants`](../packages/support/invariants), [`pty`](../packages/pty/pty), [`sandbox`](../packages/sandbox/sandbox), [`sandbox-policy`](../packages/sandbox/sandbox-policy), [`session`](../packages/core/session), [`subprocess`](../packages/subprocess/subprocess) |
@@ -1388,12 +1410,12 @@ flowchart TD
| [`bash-sandbox`](../packages/bash/bash-sandbox) | `bash` | [`bash`](../packages/bash/bash), [`bash-local`](../packages/bash/bash-local), [`invariants`](../packages/support/invariants), [`sandbox`](../packages/sandbox/sandbox), [`sandbox-policy`](../packages/sandbox/sandbox-policy) |
| [`pwsh-sandbox`](../packages/bash/pwsh-sandbox) | `bash` | [`bash`](../packages/bash/bash), [`invariants`](../packages/support/invariants), [`pwsh-local`](../packages/bash/pwsh-local), [`sandbox`](../packages/sandbox/sandbox), [`sandbox-policy`](../packages/sandbox/sandbox-policy) |
| [`fs-sandbox`](../packages/fs/fs-sandbox) | `fs` | [`fs`](../packages/fs/fs), [`fs-local`](../packages/fs/fs-local), [`invariants`](../packages/support/invariants), [`sandbox`](../packages/sandbox/sandbox), [`sandbox-policy`](../packages/sandbox/sandbox-policy) |
| [`tool-fs`](../packages/fs/tool-fs) | `fs` | [`fs`](../packages/fs/fs), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`sandbox`](../packages/sandbox/sandbox), [`sandbox-policy`](../packages/sandbox/sandbox-policy), [`session`](../packages/core/session), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools), [`user-approval`](../packages/interaction/user-approval) |
| [`tool-fs`](../packages/fs/tool-fs) | `fs` | [`attachment`](../packages/attachment/attachment), [`fs`](../packages/fs/fs), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`sandbox`](../packages/sandbox/sandbox), [`sandbox-policy`](../packages/sandbox/sandbox-policy), [`session`](../packages/core/session), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools), [`user-approval`](../packages/interaction/user-approval) |
| [`tool-fs-search`](../packages/fs/tool-fs-search) | `fs` | [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`retention`](../packages/util/retention), [`session`](../packages/core/session), [`spill`](../packages/spill/spill), [`subprocess`](../packages/subprocess/subprocess), [`system-prompt`](../packages/core/system-prompt), [`timeout`](../packages/util/timeout), [`tools`](../packages/core/tools) |
| [`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), [`agent-presets`](../packages/preset/agent-presets), [`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), [`agent-presets`](../packages/preset/agent-presets), [`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) |
@@ -1403,13 +1425,15 @@ flowchart TD
| [`tool-session-query`](../packages/session-query/tool-session-query) | `session-query` | [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`session-query`](../packages/session-query/session-query), [`system-prompt`](../packages/core/system-prompt), [`timeout`](../packages/util/timeout), [`tools`](../packages/core/tools) |
| [`agent-loop-testkit`](../packages/support/agent-loop-testkit) | `support` | [`agent`](../packages/core/agent), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools) |
| [`llm-replay`](../packages/support/llm-replay) | `support` | [`compact`](../packages/compact/compact), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session) |
| [`client-test-runtime`](../packages/client/test-runtime) | `client` | [`client-runtime`](../packages/client/runtime), [`client-ui-slots`](../packages/client/ui-slots), [`client-web-react`](../packages/client/web-react), [`host-apiproxy`](../packages/host/apiproxy), [`invariants`](../packages/support/invariants) |
| [`client-ui-trajectory`](../packages/client/ui-trajectory) | `client` | [`agent`](../packages/core/agent), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-primitives`](../packages/client/ui-primitives), [`compact`](../packages/compact/compact), [`invariants`](../packages/support/invariants), [`tools`](../packages/core/tools) |
| [`session-reference`](../packages/context/session-reference) | `context` | [`agent`](../packages/core/agent), [`compact`](../packages/compact/compact), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`retention`](../packages/util/retention), [`session`](../packages/core/session), [`session-query`](../packages/session-query/session-query) |
| [`workspace-context`](../packages/context/workspace-context) | `context` | [`agent`](../packages/core/agent), [`fs`](../packages/fs/fs), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`paths`](../packages/util/paths), [`session`](../packages/core/session), [`tools`](../packages/core/tools) |
| [`repeat-tool-guard`](../packages/guard/repeat-tool-guard) | `guard` | [`agent`](../packages/core/agent), [`invariants`](../packages/support/invariants), [`tools`](../packages/core/tools) |
| [`timeout-policy`](../packages/guard/timeout-policy) | `guard` | [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`timeout`](../packages/util/timeout), [`tools`](../packages/core/tools) |
| [`tool-ask-user`](../packages/interaction/tool-ask-user) | `interaction` | [`agent`](../packages/core/agent), [`invariants`](../packages/support/invariants), [`tools`](../packages/core/tools), [`user-interaction`](../packages/interaction/user-interaction) |
| [`tool-lsp`](../packages/lsp/tool-lsp) | `lsp` | [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`lsp`](../packages/lsp/lsp), [`system-prompt`](../packages/core/system-prompt), [`timeout`](../packages/util/timeout), [`tools`](../packages/core/tools) |
| [`mcp-client`](../packages/mcp/mcp-client) | `mcp` | [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`subprocess`](../packages/subprocess/subprocess), [`tools`](../packages/core/tools) |
| [`mcp-client`](../packages/mcp/mcp-client) | `mcp` | [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`subprocess`](../packages/subprocess/subprocess), [`timeout`](../packages/util/timeout), [`tools`](../packages/core/tools) |
| [`tool-bash-persistent`](../packages/pty/tool-bash-persistent) | `pty` | [`agent`](../packages/core/agent), [`invariants`](../packages/support/invariants), [`pty`](../packages/pty/pty), [`timeout`](../packages/util/timeout), [`tools`](../packages/core/tools) |
| [`tool-pty`](../packages/pty/tool-pty) | `pty` | [`agent`](../packages/core/agent), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`pty`](../packages/pty/pty), [`retention`](../packages/util/retention), [`system-prompt`](../packages/core/system-prompt), [`tasks`](../packages/tasks/tasks), [`tools`](../packages/core/tools) |
| [`tool-cordis`](../packages/self-modification/tool-cordis) | `self-modification` | [`invariants`](../packages/support/invariants), [`scope`](../packages/core/scope), [`tools`](../packages/core/tools) |
@@ -1424,7 +1448,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) |
@@ -1432,7 +1456,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) |
@@ -1445,6 +1468,7 @@ flowchart TD
| [`client-ui-goal`](../packages/client/ui-goal) | `client` | [`api-remotes`](../packages/api/remotes), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-primitives`](../packages/client/ui-primitives), [`client-ui-slots`](../packages/client/ui-slots), [`goal`](../packages/goal/goal), [`invariants`](../packages/support/invariants) |
| [`client-ui-plan`](../packages/client/ui-plan) | `client` | [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-primitives`](../packages/client/ui-primitives), [`client-ui-slots`](../packages/client/ui-slots), [`invariants`](../packages/support/invariants), [`plan-mode`](../packages/plan/plan-mode) |
| [`client-ui-subagent`](../packages/client/ui-subagent) | `client` | [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-primitives`](../packages/client/ui-primitives), [`client-ui-slash`](../packages/client/ui-slash), [`client-ui-slots`](../packages/client/ui-slots), [`invariants`](../packages/support/invariants), [`subagent`](../packages/subagent/subagent), [`token-meter`](../packages/llm/token-meter) |
| [`client-ui-task`](../packages/client/ui-task) | `client` | [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-primitives`](../packages/client/ui-primitives), [`client-ui-slots`](../packages/client/ui-slots), [`invariants`](../packages/support/invariants) |
| [`client-ui-tool`](../packages/client/ui-tool) | `client` | [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-primitives`](../packages/client/ui-primitives), [`client-ui-slots`](../packages/client/ui-slots), [`invariants`](../packages/support/invariants) |
| [`agent-spine-demo`](../packages/examples/agent-spine-demo) | `examples` | [`agent`](../packages/core/agent), [`agent-loop`](../packages/core/agent-loop), [`bash-env`](../packages/bash/bash-env), [`goal`](../packages/goal/goal), [`goal-session`](../packages/goal/goal-session), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`llm-retry`](../packages/llm/llm-retry), [`paths`](../packages/util/paths), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`session-title`](../packages/session/session-title), [`skill`](../packages/skill/skill), [`skill-local`](../packages/skill/skill-local), [`system-prompt`](../packages/core/system-prompt), [`tasks-local`](../packages/tasks/tasks-local), [`tool-bash`](../packages/bash/tool-bash), [`tool-goal`](../packages/goal/tool-goal), [`tool-skill`](../packages/skill/tool-skill), [`tool-tasks`](../packages/tasks/tool-tasks), [`tools`](../packages/core/tools), [`workspace-context`](../packages/context/workspace-context) |
| [`jsonrpc`](../packages/scaffold/server) | `scaffold` | [`agent`](../packages/core/agent), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`llm-deepseek`](../packages/llm/llm-deepseek), [`scope`](../packages/core/scope), [`sdk-protocol`](../packages/scaffold/protocol), [`session`](../packages/core/session), [`subagent`](../packages/subagent/subagent) |

View File

@@ -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/persistence-catalog.md
persistence-catalog.md: f44569d3bacec0a832f4b4bca6acf4abb0846a0d
persistence-catalog.zh.md: 21ed29a3da2587a604ec90d201030fd644fc5bd4
persistence-catalog.md: 88d8f833ce3e6c51692db74519279a5354a1759b
persistence-catalog.zh.md: 5ab0fa0c6ccb099ba10b9021625f20486a02d94c

View File

@@ -7,7 +7,7 @@ Every event type that can appear in a session's durable event log: the complete
This file is GENERATED from source (`scripts/gen-persistence-catalog.ts`) and verified fresh by `pnpm run verify-persistence-catalog` (part of `doc-sync`) — do not edit it by hand. Declaration blocks retain the source declaration and nested property JSDoc, removing only the indentation imposed by a containing interface/module, and use a `ts persistence-catalog` fence (skipped by doc-typecheck because declarations reference types from their owning modules). Type names in a payload link to the page that documents them. See [the persistence-log-catalog Agent Note](../.agents/notes/archived/process/2026-07-04-persistence-log-catalog.md).
The envelope declarations below compose each event's `type`, monotonic `seq`, epoch-ms `time`, `data`, and the conditional `surfaceOp`/`sourceEventSeqs` fields. **surface** marks a `SurfaceEventType` member: it produces an LLM message and declares how it joins the surface list. **log-only** marks everything else: a durable, replayable record with no derived-history contribution. Every payload is JSON-serializable (enforced at `Session.append`), and the whole format is pinned at `SESSION_FORMAT_VERSION = 0` — pre-release, no compatibility implied ([the version stance](subsystems/persistence.md)). Scope: the packages in this repo; a downstream plugin can merge further event types, which are outside this catalog by construction.
The envelope declarations below compose each event's `type`, monotonic `seq`, epoch-ms `time`, `data`, the optional `ignorable` unknown-type skip marker, and the conditional `surfaceOp`/`sourceEventSeqs` fields. **surface** marks a `SurfaceEventType` member: it produces an LLM message and declares how it joins the surface list. **log-only** marks everything else: a durable, replayable record with no derived-history contribution. Every payload is JSON-serializable (enforced at `Session.append`), and the whole format is pinned at `SESSION_FORMAT_VERSION = 0` — pre-release, no compatibility implied ([the version stance](subsystems/persistence.md)). Scope: the packages in this repo; a downstream plugin can merge further event types, which are outside this catalog by construction.
## Event envelope
@@ -63,6 +63,17 @@ export type SessionEvent<T extends SessionEventType = SessionEventType> = {
/** Unix epoch milliseconds. */
time: number
data: SessionEventMap[K]
/**
* Marks an event a reader may safely skip when it does not recognize
* `type`. Absent means required: a reader meeting an unrecognized type
* without this marker MUST refuse to reconstruct the session instead of
* silently dropping the event, because an unrecognized required event may
* change how the rest of the log is interpreted. A writer sets `true` only
* on purely informational records whose loss cannot affect reconstruction;
* defaulting to required means a forgotten marker over-refuses (an
* inconvenience) rather than silently resuming a gutted session.
*/
ignorable?: true
} & (K extends SurfaceEventType ? {
/**
* Seq numbers of earlier events that this event cites as sources
@@ -79,7 +90,7 @@ export type SessionEvent<T extends SessionEventType = SessionEventType> = {
}[T]
```
Sources: [`packages/core/session/src/types.ts:316`](../packages/core/session/src/types.ts) · [`packages/core/session/src/types.ts:323`](../packages/core/session/src/types.ts) · [`packages/core/session/src/types.ts:352`](../packages/core/session/src/types.ts) · [`packages/core/session/src/types.ts:384`](../packages/core/session/src/types.ts)
Sources: [`packages/core/session/src/types.ts:331`](../packages/core/session/src/types.ts) · [`packages/core/session/src/types.ts:338`](../packages/core/session/src/types.ts) · [`packages/core/session/src/types.ts:367`](../packages/core/session/src/types.ts) · [`packages/core/session/src/types.ts:399`](../packages/core/session/src/types.ts)
## Events
@@ -192,7 +203,7 @@ Source: [`packages/interaction/user-approval/src/index.ts:67`](../packages/inter
Types: [StreamChunk](subsystems/llm-streaming.md)
Source: [`packages/core/session/src/types.ts:246`](../packages/core/session/src/types.ts)
Source: [`packages/core/session/src/types.ts:261`](../packages/core/session/src/types.ts)
#### `assistant/message` — surface
@@ -208,7 +219,7 @@ Source: [`packages/core/session/src/types.ts:246`](../packages/core/session/src/
Types: [TokenUsage](subsystems/llm-streaming.md)
Source: [`packages/core/session/src/types.ts:253`](../packages/core/session/src/types.ts)
Source: [`packages/core/session/src/types.ts:268`](../packages/core/session/src/types.ts)
### `command/*`
@@ -364,7 +375,7 @@ Source: [`packages/compact/compact/src/types.ts:33`](../packages/compact/compact
'feedback/record': { text: string }
```
Source: [`packages/feedback/command-feedback/src/index.ts:25`](../packages/feedback/command-feedback/src/index.ts)
Source: [`packages/feedback/command-feedback/src/index.ts:62`](../packages/feedback/command-feedback/src/index.ts)
### `goal/*`
@@ -488,7 +499,7 @@ Source: [`packages/plan/plan-mode/src/index.ts:53`](../packages/plan/plan-mode/s
'request/context': RequestContext
```
Source: [`packages/core/session/src/types.ts:289`](../packages/core/session/src/types.ts)
Source: [`packages/core/session/src/types.ts:304`](../packages/core/session/src/types.ts)
#### `request/header` — log-only
@@ -500,7 +511,7 @@ Source: [`packages/core/session/src/types.ts:289`](../packages/core/session/src/
'request/header': { header: EpochHeader; reason: RequestHeaderReason }
```
Source: [`packages/core/session/src/types.ts:284`](../packages/core/session/src/types.ts)
Source: [`packages/core/session/src/types.ts:299`](../packages/core/session/src/types.ts)
### `sandbox/*`
@@ -553,7 +564,7 @@ Source: [`packages/sandbox/sandbox-policy/src/session-mode.ts:33`](../packages/s
'session/end-seed': Record<string, never>
```
Source: [`packages/core/session/src/types.ts:312`](../packages/core/session/src/types.ts)
Source: [`packages/core/session/src/types.ts:327`](../packages/core/session/src/types.ts)
#### `session/title` — log-only
@@ -589,7 +600,7 @@ Source: [`packages/session/session-title-llm/src/index.ts:43`](../packages/sessi
'step/end': { turn: number; step: number }
```
Source: [`packages/core/session/src/types.ts:236`](../packages/core/session/src/types.ts)
Source: [`packages/core/session/src/types.ts:251`](../packages/core/session/src/types.ts)
#### `step/start` — log-only
@@ -598,7 +609,7 @@ Source: [`packages/core/session/src/types.ts:236`](../packages/core/session/src/
'step/start': { turn: number; step: number }
```
Source: [`packages/core/session/src/types.ts:234`](../packages/core/session/src/types.ts)
Source: [`packages/core/session/src/types.ts:249`](../packages/core/session/src/types.ts)
### `subagent/*`
@@ -628,7 +639,7 @@ Source: [`packages/subagent/subagent/src/descriptor.ts:37`](../packages/subagent
Types: [TodoItem](subsystems/session.md)
Source: [`packages/core/session/src/types.ts:279`](../packages/core/session/src/types.ts)
Source: [`packages/core/session/src/types.ts:294`](../packages/core/session/src/types.ts)
### `tool/*`
@@ -645,7 +656,7 @@ Source: [`packages/core/session/src/types.ts:279`](../packages/core/session/src/
Types: [CallId](subsystems/core.md)
Source: [`packages/core/session/src/types.ts:259`](../packages/core/session/src/types.ts)
Source: [`packages/core/session/src/types.ts:274`](../packages/core/session/src/types.ts)
#### `tool/code-dispatch` — log-only
@@ -714,7 +725,7 @@ Source: [`packages/core/tools/src/types.ts:40`](../packages/core/tools/src/types
}
```
Source: [`packages/core/session/src/types.ts:271`](../packages/core/session/src/types.ts)
Source: [`packages/core/session/src/types.ts:286`](../packages/core/session/src/types.ts)
### `turn/*`
@@ -734,7 +745,7 @@ Source: [`packages/core/session/src/types.ts:271`](../packages/core/session/src/
Types: [TurnEndReason](subsystems/session.md)
Source: [`packages/core/session/src/types.ts:232`](../packages/core/session/src/types.ts)
Source: [`packages/core/session/src/types.ts:247`](../packages/core/session/src/types.ts)
#### `turn/start` — log-only
@@ -748,7 +759,7 @@ Source: [`packages/core/session/src/types.ts:232`](../packages/core/session/src/
'turn/start': { turn: number }
```
Source: [`packages/core/session/src/types.ts:223`](../packages/core/session/src/types.ts)
Source: [`packages/core/session/src/types.ts:238`](../packages/core/session/src/types.ts)
### `user/*`
@@ -765,7 +776,7 @@ Source: [`packages/core/session/src/types.ts:223`](../packages/core/session/src/
'user/message': UserMessage
```
Source: [`packages/core/session/src/types.ts:244`](../packages/core/session/src/types.ts)
Source: [`packages/core/session/src/types.ts:259`](../packages/core/session/src/types.ts)
### `web/*`

View File

@@ -9,7 +9,7 @@
英文源文件根据源码生成(`scripts/gen-persistence-catalog.ts`),并由 `pnpm run verify-persistence-catalog``doc-sync`(文档同步门禁)的一部分)验证新鲜度;本中文文件作为经评审对侧通过双语配对维护。声明块保留源码声明和嵌套属性的 JSDoc只移除其所在接口模块带来的缩进并使用 `ts persistence-catalog` 围栏doc-typecheck 会跳过这些围栏因为声明引用了其所属模块中的类型。payload 中的类型名称会链接到记录该类型的页面。参见 [persistence-log-catalog Agent Note](../.agents/notes/archived/process/2026-07-04-persistence-log-catalog.md)。
以下信封声明组合了每个事件的 `type`、单调递增的 `seq`、以 epoch 毫秒表示的 `time``data`,以及条件字段 `surfaceOp``sourceEventSeqs`。**surface** 表示 `SurfaceEventType` 成员:它会生成一条 LLM大语言模型消息并声明该事件如何加入 surface 列表。**log-only** 表示其他所有事件:这类记录可持久化、可回放,但不参与派生历史。每个 payload 均可进行 JSON 序列化(在 `Session.append` 处强制执行),整个格式固定为 `SESSION_FORMAT_VERSION = 0`:这是预发布格式,不暗示任何兼容性(参见[版本立场](subsystems/persistence.md))。范围仅限本仓库中的包;下游插件可以继续合并其他事件类型,而这些类型按设计不属于本目录。
以下信封声明组合了每个事件的 `type`、单调递增的 `seq`、以 epoch 毫秒表示的 `time``data`、可选的未知类型跳过标记 `ignorable`,以及条件字段 `surfaceOp``sourceEventSeqs`。**surface** 表示 `SurfaceEventType` 成员:它会生成一条 LLM大语言模型消息并声明该事件如何加入 surface 列表。**log-only** 表示其他所有事件:这类记录可持久化、可回放,但不参与派生历史。每个 payload 均可进行 JSON 序列化(在 `Session.append` 处强制执行),整个格式固定为 `SESSION_FORMAT_VERSION = 0`:这是预发布格式,不暗示任何兼容性(参见[版本立场](subsystems/persistence.md))。范围仅限本仓库中的包;下游插件可以继续合并其他事件类型,而这些类型按设计不属于本目录。
## 事件信封
@@ -65,6 +65,17 @@ export type SessionEvent<T extends SessionEventType = SessionEventType> = {
/** Unix epoch milliseconds. */
time: number
data: SessionEventMap[K]
/**
* Marks an event a reader may safely skip when it does not recognize
* `type`. Absent means required: a reader meeting an unrecognized type
* without this marker MUST refuse to reconstruct the session instead of
* silently dropping the event, because an unrecognized required event may
* change how the rest of the log is interpreted. A writer sets `true` only
* on purely informational records whose loss cannot affect reconstruction;
* defaulting to required means a forgotten marker over-refuses (an
* inconvenience) rather than silently resuming a gutted session.
*/
ignorable?: true
} & (K extends SurfaceEventType ? {
/**
* Seq numbers of earlier events that this event cites as sources

6
docs/rescope.i18n.yaml Normal file
View File

@@ -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

53
docs/rescope.md Normal file
View File

@@ -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.

53
docs/rescope.zh.md Normal file
View File

@@ -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`

View File

@@ -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/README.md
README.md: fddbf460c8e9e7c6f9ed1d3375bdabe65947661f
README.zh.md: febc5a97426fef5ec4b2b80d9677957369994a3b
README.md: 560851eeda607b762456fe20c874b4497704709f
README.zh.md: 4acba4372e995b54a3bb326bec0cf9606f997773

View File

@@ -18,6 +18,7 @@ One page per subsystem of the DeepSeek Harness: what it is, the data structures
| [settings.md](settings.md) | the user-settings seam: `SettingsNamespace` registration, layered resolution (defaults → composition `base` → user document), owner scopes, hot commits |
| [credentials.md](credentials.md) | the credential seam: `CredentialRef` references (never values) in configuration, per-operation resolution, UI-safe `CredentialInfo`, provider source layers |
| [session-query.md](session-query.md) | logical records, bounded exact-event reads, relationship traces, semantic filters/documents, and full-text result pages |
| [feedback.md](feedback.md) | lifecycle-bound per-message feedback records, optimistic versions, sidecar persistence, and the Host Remote contract |
| [session-title.md](session-title.md) | durable title snapshots, cited source-message seqs, and the asynchronous provider contract |
| [session-reference.md](session-reference.md) | structured cross-session references: `SessionReferenceInput`/`Candidate`, prepared message contexts, the stable error taxonomy |
| [system-prompt.md](system-prompt.md) | per-assembly context, tool-provider results, prompt sections, and cooperative assembly |

View File

@@ -18,6 +18,7 @@
| [settings.md](settings.md) | 用户设置 seam`SettingsNamespace` 注册、分层解析(默认值 → 组合 `base` → 用户文档、owner scope、热提交 |
| [credentials.md](credentials.md) | 凭据 seam配置中的 `CredentialRef` 引用(绝不含值)、按操作解析、对 UI 安全的 `CredentialInfo`、provider 来源层 |
| [session-query.md](session-query.md) | 逻辑记录、有界精确事件读取、关系追踪、语义筛选器/文档与全文检索结果页 |
| [feedback.md](feedback.md) | 绑定生命周期的逐消息反馈记录、乐观版本、伴随记录持久化与 Host Remote 契约 |
| [session-title.md](session-title.md) | 持久标题快照、被引用的来源消息 seq 与异步提供方约定 |
| [session-reference.md](session-reference.md) | 结构化跨会话引用:`SessionReferenceInput`/`Candidate`、prepared 消息上下文、稳定错误分类 |
| [system-prompt.md](system-prompt.md) | 逐次组装的上下文、工具提供方结果、提示词段落与协作式组装 |

View File

@@ -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/core.md
core.md: ad00c4da7d77b0e1ab4728173b202ebc17fb56a0
core.zh.md: 9c606023c85369643e7148f829526b1f75ea3631
core.md: 96655026f5affda6fed080496d975e2366f0356f
core.zh.md: e2cde8845ddf6b78f64d062fd8860c0c88b7ce11

View File

@@ -546,7 +546,7 @@ async standingKeyFor(id?: string): Promise<ScopeKey>
Types: [ScopeKey](scope.md)
Source: [`packages/preset/agent-presets/src/index.ts:78`](../../packages/preset/agent-presets/src/index.ts)
Source: [`packages/preset/agent-presets/src/index.ts:80`](../../packages/preset/agent-presets/src/index.ts)
<a id="ctxagents--agentregistry"></a>

View File

@@ -554,7 +554,7 @@ async standingKeyFor(id?: string): Promise<ScopeKey>
Types: [ScopeKey](scope.md)
Source: [`packages/preset/agent-presets/src/index.ts:78`](../../packages/preset/agent-presets/src/index.ts)
Source: [`packages/preset/agent-presets/src/index.ts:80`](../../packages/preset/agent-presets/src/index.ts)
<a id="ctxagents--agentregistry"></a>

View File

@@ -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/subsystems/feedback.md
feedback.md: 76a29f7d6ba604fa07ed56429c9b066e22639671
feedback.zh.md: 5a409832de68b6d0bc9688a907c0f22edd3b0a43

256
docs/subsystems/feedback.md Normal file
View File

@@ -0,0 +1,256 @@
# Message Feedback
English | [中文](feedback.zh.md)
[`@deepseek-ai/dsh-message-feedback`](../../packages/feedback/message-feedback) owns editable feedback for individual assistant messages. It is deliberately separate from the immutable Session-level `feedback/record` event: message feedback is a local storage-domain sidecar, not Session-log content or a projection, and it performs no telemetry handoff.
Source: [`packages/feedback/message-feedback/src/types.ts`](../../packages/feedback/message-feedback/src/types.ts)
## Public types
```ts type-equiv
/** Opaque compare-and-set token for one exact feedback item revision. */
type MessageFeedbackVersion = Branded<'MessageFeedbackVersion'>
```
```ts type-equiv
/** The human's overall judgment of one assistant message. */
type MessageFeedbackRating = 'positive' | 'negative'
```
```ts type-equiv
/** One current feedback value and its opaque mutation token. */
interface MessageFeedbackItem {
/** Stable identity of the assistant message inside the owning Session. */
readonly messageId: MessageId
/** Overall positive or negative judgment. */
readonly rating: MessageFeedbackRating
/** Optional explanation, preserved verbatim after validation. */
readonly note?: string
/** Equality-only token replaced by every material create or update. */
readonly version: MessageFeedbackVersion
/** Host-assigned creation time in Unix epoch milliseconds. */
readonly createdAt: number
/** Host-assigned time of the most recent material update. */
readonly updatedAt: number
}
```
```ts type-equiv
/** Read all message feedback belonging to one persisted Session lifecycle. */
interface MessageFeedbackListRequest {
/** Persisted Session whose sidecar should be read. */
readonly sessionId: SessionId
}
```
```ts type-equiv
/** Current feedback values for one Session, in first-creation order. */
interface MessageFeedbackListValue {
/** Fresh immutable item snapshots. */
readonly items: readonly MessageFeedbackItem[]
}
```
```ts type-equiv
/** Create or replace feedback for one assistant message. */
interface MessageFeedbackPutRequest {
/** Persisted Session that owns the target message. */
readonly sessionId: SessionId
/** Target assistant-message identity. */
readonly messageId: MessageId
/** Desired overall judgment. */
readonly rating: MessageFeedbackRating
/** Optional non-blank explanation. */
readonly note?: string
/** Observed item version, or `null` to require that no item exists. */
readonly ifVersion: MessageFeedbackVersion | null
}
```
```ts type-equiv
/** Delete feedback for one message after observing its current version. */
interface MessageFeedbackDeleteRequest {
/** Persisted Session that owns the sidecar. */
readonly sessionId: SessionId
/** Message whose feedback should be absent after this operation. */
readonly messageId: MessageId
/** Observed item version; ignored when the item is already absent. */
readonly ifVersion: MessageFeedbackVersion
}
```
```ts type-equiv
/** Idempotent deletion acknowledgement. */
interface MessageFeedbackDeleteValue {
/** Stable postcondition shared by the first deletion and every retry. */
readonly absent: true
}
```
```ts type-equiv
/** No persisted Session header exists for the requested id. */
interface MessageFeedbackSessionNotFound {
readonly code: 'session-not-found'
readonly sessionId: SessionId
}
```
```ts type-equiv
/** The id does not name a derived, append-origin assistant message. */
interface MessageFeedbackTargetNotFound {
readonly code: 'target-not-found'
readonly sessionId: SessionId
readonly messageId: MessageId
}
```
```ts type-equiv
/** A material mutation did not match the addressed item's current version. */
interface MessageFeedbackVersionConflict {
readonly code: 'version-conflict'
/** Authoritative current item, or `null` when it does not exist. */
readonly current: MessageFeedbackItem | null
}
```
```ts type-equiv
/** A supplied note contains no non-whitespace character. */
interface MessageFeedbackNoteBlank {
readonly code: 'note-blank'
}
```
```ts type-equiv
/** A supplied note exceeds the configured UTF-8 byte limit. */
interface MessageFeedbackNoteTooLarge {
readonly code: 'note-too-large'
readonly maxBytes: number
readonly actualBytes: number
}
```
```ts type-equiv
/** Failures shared by the public message-feedback operations. */
type MessageFeedbackFailure =
| MessageFeedbackSessionNotFound
| MessageFeedbackTargetNotFound
| MessageFeedbackVersionConflict
| MessageFeedbackNoteBlank
| MessageFeedbackNoteTooLarge
```
```ts type-equiv
/** Successful public operation result. */
interface MessageFeedbackSuccess<T> {
readonly ok: true
readonly value: T
}
```
```ts type-equiv
/** Rejected public operation result with a stable business failure. */
interface MessageFeedbackRejected<E extends MessageFeedbackFailure> {
readonly ok: false
readonly error: E
}
```
```ts type-equiv
/** Result returned by the message-feedback `list` operation. */
type MessageFeedbackListResult =
| MessageFeedbackSuccess<MessageFeedbackListValue>
| MessageFeedbackRejected<MessageFeedbackSessionNotFound>
```
```ts type-equiv
/** Result returned by the message-feedback `put` operation. */
type MessageFeedbackPutResult =
| MessageFeedbackSuccess<MessageFeedbackItem>
| MessageFeedbackRejected<
| MessageFeedbackSessionNotFound
| MessageFeedbackTargetNotFound
| MessageFeedbackVersionConflict
| MessageFeedbackNoteBlank
| MessageFeedbackNoteTooLarge
>
```
```ts type-equiv
/** Result returned by the message-feedback `delete` operation. */
type MessageFeedbackDeleteResult =
| MessageFeedbackSuccess<MessageFeedbackDeleteValue>
| MessageFeedbackRejected<MessageFeedbackSessionNotFound | MessageFeedbackVersionConflict>
```
## Data and concurrency
One Session sidecar row contains its header identity `{createdAt, cwd}` and feedback items keyed by `MessageId`. Each item carries a positive or negative rating, an optional note, Host-assigned `createdAt`/`updatedAt` timestamps, and its own opaque version. Versions are compared only for equality and only against the addressed message; callers do not order or synthesize them.
`put` uses strict optimistic concurrency: every request for an existing item must match its current `ifVersion`, including a no-op. A conflict returns the authoritative current item (or `null`), so a caller can reconcile a lost response or a concurrent edit without another read. Deleting an already absent item succeeds. A per-Session queue encloses inspection, read, conflict evaluation, and whole-row write, so these guarantees cover concurrent calls in one Host process.
## Target and lifecycle authority
`SessionPersistence.inspect()` supplies the target Session observation without publishing or resuming an Agent and without committing cold repair. A cold `listSnapshots()` preflight classifies definite absence; inspection failure for a catalogued Session propagates as infrastructure failure. `put` accepts only a non-empty, append-origin `assistant/message` with the requested `MessageId`; replacement-origin, usage-only empty, and non-assistant records are not feedback targets.
The stored `{createdAt, cwd}` identity must match the inspected header. A mismatch is treated as absence: `list` returns no items, while `put` may replace the stale row with one bound to the current header identity. Forks use a new Session identity and receive no sidecar copy even when their seed contains the same messages.
## Persistence and Remote contract
The service stores whole Session rows in the `message_feedback` storage domain through `ctx.storageDomain`. Before `put` commits a row that references a target message, a matching live target passes through the canonical `ctx.sessions.flush` checkpoint; both live and cold paths are then physically read from sequence zero through `SessionPersistence.readFrom`. The resulting observation is revalidated before the sidecar write, so the durable target log always precedes its sidecar commit. `maxNoteBytes` is required and bounds note text by UTF-8 bytes; the Web Host composition sets `8192`. The package publishes the Host `messageFeedback.list`, `messageFeedback.put`, and `messageFeedback.delete` unary Remote contract through `GatewayService` and `@Remote`; the generated Cordis surface below is the method-level authority.
Plugin disposal closes mutation admission, drains accepted per-Session queue work, and then closes the storage domain.
## Boundaries and limitations
- The client Remote aggregate mount and UI consumer are separately owned and deferred.
- The mutation queue is process-local. Storage-domain has no cross-process conditional write, so multiple Host writers to one storage root have no compare-and-swap or lost-update guarantee.
- Session persistence has no durable deletion surface. The service does not treat `session/disposed` or `host/session-removed` as deletion and therefore performs no fake cascade; orphan sidecar rows may remain after out-of-band log removal.
- A request in the narrow interval after live detach but before the persistence catalog materializes the header can receive `session-not-found`; callers retry after retirement materialization.
- Cold requests scan the complete Session snapshot catalog because persistence has no lookup-by-id metadata operation. One Session row also has no item-count or aggregate-byte cap; `maxNoteBytes` bounds only each note until a concrete consumer owns a row policy.
- Header identity detects a reused id only when `{createdAt, cwd}` differs; a cloned log retaining the same header identity is indistinguishable by this contract.
- The Host contract records no authenticated actor or audit identity and therefore assumes a trusted caller boundary.
<!-- BEGIN GENERATED cordis-surface (gen-cordis-catalog.ts) — do not edit between markers -->
<a id="cordis-surface"></a>
## Cordis surface
Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — this section is byte-identical in both language sides of the page. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` surface lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
<a id="ctxmessagefeedback--messagefeedbackservice"></a>
### `ctx.messageFeedback` — `MessageFeedbackService`
Storage-domain sidecar service. It inspects persisted Session history and never creates or resumes an Agent or Session.
```ts cordis-catalog
/**
* Read feedback belonging to the current persisted Session lifecycle.
* A stale row from a reused Session id is invisible.
* @param request - Session identity to inspect and list.
* @returns current immutable items or `session-not-found`.
*/
@Remote('list') async list(request: MessageFeedbackListRequest): Promise<MessageFeedbackListResult>
/**
* Create or replace feedback for one derived append-origin assistant
* message. Every request must match the addressed item's current version;
* a matching no-op returns the stored item without changing its revision.
* @param request - target, desired value, and observed item version.
* @returns the committed item or an explicit business failure.
*/
@Remote('put') put(request: MessageFeedbackPutRequest): Promise<MessageFeedbackPutResult>
/**
* Delete one feedback item. Absence is successful regardless of the
* supplied version; an existing item requires an exact version match.
* @param request - Session, message, and observed item version.
* @returns the stable absent postcondition, or an explicit failure.
*/
@Remote('delete') delete(request: MessageFeedbackDeleteRequest): Promise<MessageFeedbackDeleteResult>
```
Source: [`packages/feedback/message-feedback/src/index.ts:150`](../../packages/feedback/message-feedback/src/index.ts)
<!-- END GENERATED cordis-surface -->

View File

@@ -0,0 +1,256 @@
# 消息反馈
[English](feedback.md) | 中文
[`@deepseek-ai/dsh-message-feedback`](../../packages/feedback/message-feedback)拥有针对单条 assistant 消息的可编辑反馈。它刻意与不可变的 Session 级 `feedback/record` 事件分离message feedback 是本地 storage-domain 伴随记录sidecar不是 Session 日志内容或投影,也不执行遥测交接。
来源:[`packages/feedback/message-feedback/src/types.ts`](../../packages/feedback/message-feedback/src/types.ts)
## 公开类型
```ts type-equiv
/** Opaque compare-and-set token for one exact feedback item revision. */
type MessageFeedbackVersion = Branded<'MessageFeedbackVersion'>
```
```ts type-equiv
/** The human's overall judgment of one assistant message. */
type MessageFeedbackRating = 'positive' | 'negative'
```
```ts type-equiv
/** One current feedback value and its opaque mutation token. */
interface MessageFeedbackItem {
/** Stable identity of the assistant message inside the owning Session. */
readonly messageId: MessageId
/** Overall positive or negative judgment. */
readonly rating: MessageFeedbackRating
/** Optional explanation, preserved verbatim after validation. */
readonly note?: string
/** Equality-only token replaced by every material create or update. */
readonly version: MessageFeedbackVersion
/** Host-assigned creation time in Unix epoch milliseconds. */
readonly createdAt: number
/** Host-assigned time of the most recent material update. */
readonly updatedAt: number
}
```
```ts type-equiv
/** Read all message feedback belonging to one persisted Session lifecycle. */
interface MessageFeedbackListRequest {
/** Persisted Session whose sidecar should be read. */
readonly sessionId: SessionId
}
```
```ts type-equiv
/** Current feedback values for one Session, in first-creation order. */
interface MessageFeedbackListValue {
/** Fresh immutable item snapshots. */
readonly items: readonly MessageFeedbackItem[]
}
```
```ts type-equiv
/** Create or replace feedback for one assistant message. */
interface MessageFeedbackPutRequest {
/** Persisted Session that owns the target message. */
readonly sessionId: SessionId
/** Target assistant-message identity. */
readonly messageId: MessageId
/** Desired overall judgment. */
readonly rating: MessageFeedbackRating
/** Optional non-blank explanation. */
readonly note?: string
/** Observed item version, or `null` to require that no item exists. */
readonly ifVersion: MessageFeedbackVersion | null
}
```
```ts type-equiv
/** Delete feedback for one message after observing its current version. */
interface MessageFeedbackDeleteRequest {
/** Persisted Session that owns the sidecar. */
readonly sessionId: SessionId
/** Message whose feedback should be absent after this operation. */
readonly messageId: MessageId
/** Observed item version; ignored when the item is already absent. */
readonly ifVersion: MessageFeedbackVersion
}
```
```ts type-equiv
/** Idempotent deletion acknowledgement. */
interface MessageFeedbackDeleteValue {
/** Stable postcondition shared by the first deletion and every retry. */
readonly absent: true
}
```
```ts type-equiv
/** No persisted Session header exists for the requested id. */
interface MessageFeedbackSessionNotFound {
readonly code: 'session-not-found'
readonly sessionId: SessionId
}
```
```ts type-equiv
/** The id does not name a derived, append-origin assistant message. */
interface MessageFeedbackTargetNotFound {
readonly code: 'target-not-found'
readonly sessionId: SessionId
readonly messageId: MessageId
}
```
```ts type-equiv
/** A material mutation did not match the addressed item's current version. */
interface MessageFeedbackVersionConflict {
readonly code: 'version-conflict'
/** Authoritative current item, or `null` when it does not exist. */
readonly current: MessageFeedbackItem | null
}
```
```ts type-equiv
/** A supplied note contains no non-whitespace character. */
interface MessageFeedbackNoteBlank {
readonly code: 'note-blank'
}
```
```ts type-equiv
/** A supplied note exceeds the configured UTF-8 byte limit. */
interface MessageFeedbackNoteTooLarge {
readonly code: 'note-too-large'
readonly maxBytes: number
readonly actualBytes: number
}
```
```ts type-equiv
/** Failures shared by the public message-feedback operations. */
type MessageFeedbackFailure =
| MessageFeedbackSessionNotFound
| MessageFeedbackTargetNotFound
| MessageFeedbackVersionConflict
| MessageFeedbackNoteBlank
| MessageFeedbackNoteTooLarge
```
```ts type-equiv
/** Successful public operation result. */
interface MessageFeedbackSuccess<T> {
readonly ok: true
readonly value: T
}
```
```ts type-equiv
/** Rejected public operation result with a stable business failure. */
interface MessageFeedbackRejected<E extends MessageFeedbackFailure> {
readonly ok: false
readonly error: E
}
```
```ts type-equiv
/** Result returned by the message-feedback `list` operation. */
type MessageFeedbackListResult =
| MessageFeedbackSuccess<MessageFeedbackListValue>
| MessageFeedbackRejected<MessageFeedbackSessionNotFound>
```
```ts type-equiv
/** Result returned by the message-feedback `put` operation. */
type MessageFeedbackPutResult =
| MessageFeedbackSuccess<MessageFeedbackItem>
| MessageFeedbackRejected<
| MessageFeedbackSessionNotFound
| MessageFeedbackTargetNotFound
| MessageFeedbackVersionConflict
| MessageFeedbackNoteBlank
| MessageFeedbackNoteTooLarge
>
```
```ts type-equiv
/** Result returned by the message-feedback `delete` operation. */
type MessageFeedbackDeleteResult =
| MessageFeedbackSuccess<MessageFeedbackDeleteValue>
| MessageFeedbackRejected<MessageFeedbackSessionNotFound | MessageFeedbackVersionConflict>
```
## 数据与并发
每个 Session 的一条伴随记录包含 header 身份 `{createdAt, cwd}` 和以 `MessageId` 为键的反馈条目。每个条目携带好评或差评、可选备注、Host 分配的 `createdAt`/`updatedAt` 时间戳及自己的 opaque version。version 只能用于相等比较,且只与目标消息比较;调用方不能排序或自行合成它。
`put` 采用严格乐观并发:已有条目的每次请求都必须匹配当前 `ifVersion`,即使请求不会改变目标值。冲突会返回权威当前条目(不存在时为 `null`),因此调用方无需额外读取,即可协调丢失响应或并发编辑。删除已经不存在的条目同样成功。按 Session 划分的队列覆盖检查、读取、冲突判断与整行写入,因此这些保证适用于单个 Host 进程中的并发调用。
## 目标与生命周期权威
`SessionPersistence.inspect()` 提供目标 Session 的观测,且不会发布或恢复 Agent也不会提交 cold repair。cold 路径先由 `listSnapshots()` 预检明确不存在;已进入目录的 Session 若检查失败,会按基础设施故障原样传播。`put` 只接受具有指定 `MessageId` 的非空、append-origin `assistant/message`replacement-origin、仅承载 usage 的空记录和非 assistant 记录都不是反馈目标。
存储的 `{createdAt, cwd}` 身份必须与检查所得 header 匹配。不匹配按不存在处理:`list` 返回空条目,`put` 则可用绑定当前 header 身份的新记录替换陈旧行。fork 使用新的 Session 身份,即使种子包含相同消息,也不获得伴随记录副本。
## 持久化与 Remote 契约
服务通过 `ctx.storageDomain` 在 `message_feedback` 存储域中保存完整 Session 行。`put` 提交引用目标消息的伴随记录前,身份匹配的 live 目标先经过权威 `ctx.sessions.flush` checkpoint随后 live 与 cold 路径都会通过 `SessionPersistence.readFrom` 从序列零做物理复读。写入伴随记录前会再次校验所得观测,因此目标日志的持久提交始终先于其伴随记录。`maxNoteBytes` 为必填项,按 UTF-8 字节限制备注文本Web Host 组合将其设为 `8192`。该包通过 `GatewayService` 与 `@Remote` 发布 Host `messageFeedback.list`、`messageFeedback.put` 和 `messageFeedback.delete` 一元 Remote 契约;下方生成的 Cordis surface 是方法级权威。
Plugin disposal 会先关闭变更接纳,排空已进入各 Session 队列的工作,然后才关闭 storage domain。
## 边界与限制
- 客户端 Remote 聚合挂载与 UI 消费方由各自边界负责并保持延后。
- 变更队列仅在进程内生效。storage-domain 没有跨进程条件写,因此多个 Host 写入同一存储根目录时,不提供 compare-and-swap 或防止丢失更新的保证。
- Session persistence 没有持久删除接口。服务不把 `session/disposed` 或 `host/session-removed` 当作删除,因此不伪造级联;在带外移除日志后,孤儿伴随记录可能继续存在。
- 请求若恰好落在 live detach 之后、persistence catalog 物化 header 之前的极短窗口,可能收到 `session-not-found`;调用方应在 retirement materialization 后重试。
- 由于 persistence 没有按 id 读取元数据的操作cold 请求会扫描完整的 Session snapshot 目录。单个 Session 行也没有条目数或聚合字节上限;在具体消费方拥有行策略之前,`maxNoteBytes` 只限制每条备注。
- 只有 `{createdAt, cwd}` 不同时header 身份才能识别复用的 id本契约无法区分保留相同 header 身份的克隆日志。
- Host 契约不记录已认证的 actor 或审计身份,因此假设调用方边界可信。
<!-- BEGIN GENERATED cordis-surface (gen-cordis-catalog.ts) — do not edit between markers -->
<a id="cordis-surface"></a>
## Cordis surface
Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — this section is byte-identical in both language sides of the page. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` surface lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
<a id="ctxmessagefeedback--messagefeedbackservice"></a>
### `ctx.messageFeedback` — `MessageFeedbackService`
Storage-domain sidecar service. It inspects persisted Session history and never creates or resumes an Agent or Session.
```ts cordis-catalog
/**
* Read feedback belonging to the current persisted Session lifecycle.
* A stale row from a reused Session id is invisible.
* @param request - Session identity to inspect and list.
* @returns current immutable items or `session-not-found`.
*/
@Remote('list') async list(request: MessageFeedbackListRequest): Promise<MessageFeedbackListResult>
/**
* Create or replace feedback for one derived append-origin assistant
* message. Every request must match the addressed item's current version;
* a matching no-op returns the stored item without changing its revision.
* @param request - target, desired value, and observed item version.
* @returns the committed item or an explicit business failure.
*/
@Remote('put') put(request: MessageFeedbackPutRequest): Promise<MessageFeedbackPutResult>
/**
* Delete one feedback item. Absence is successful regardless of the
* supplied version; an existing item requires an exact version match.
* @param request - Session, message, and observed item version.
* @returns the stable absent postcondition, or an explicit failure.
*/
@Remote('delete') delete(request: MessageFeedbackDeleteRequest): Promise<MessageFeedbackDeleteResult>
```
Source: [`packages/feedback/message-feedback/src/index.ts:150`](../../packages/feedback/message-feedback/src/index.ts)
<!-- END GENERATED cordis-surface -->

View File

@@ -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/filesystem.md
filesystem.md: 00e28130db9f60e6ad5f8c582ca5531482cdeb32
filesystem.zh.md: 5cf6be12f41b36c8149a941a4d251c4497ed4738
filesystem.md: 01fe2d07f5497374019855ca46ced7e173d21445
filesystem.zh.md: e68246d7a44b8812e132e02979a2c0cda6adb792

View File

@@ -52,7 +52,7 @@ type FsTargetKey = Branded<'FsTargetKey'>
type FsVersion = Branded<'FsVersion'>
```
`stat` returns metadata (never content), or `undefined` when the target is absent. `type` lets the tool reject directories/special files before reading, and `size` lets it choose `readText` vs `streamText` without probing by failure. A protocol consumer that needs a byte ceiling applies it while consuming `streamText`, so the filesystem seam needs no consumer-specific bounded-read primitive.
`stat` returns metadata (never content), or `undefined` when the target is absent. `type` lets consumers reject directories and special files before reading, and `size` lets text consumers choose `readText` vs `streamText` without probing by failure. A text consumer applies its own retention ceiling while consuming `streamText`. Raw-byte consumers use `readBytes(target, signal, maxBytes)`; its required complete-content cap makes a known or discovered overflow fail with `FS_TOO_LARGE` instead of truncating or buffering without a bound.
```ts type-equiv
/**
@@ -256,6 +256,7 @@ type FsErrorCode =
| 'FS_NOT_DIRECTORY'
| 'FS_NOT_TEXT'
| 'FS_NOT_REGULAR_FILE'
| 'FS_TOO_LARGE'
| 'FS_PERMISSION_DENIED'
| 'FS_SANDBOX_DENIED'
| 'FS_IO_ERROR'
@@ -274,7 +275,7 @@ type FsErrorCode =
## The service and the plugin
`FileSystem` (`ctx.fs`, abstract) owns the provider primitives: `resolve`, `processPath`, `fileUrl`, `contains`, `stat`, `lstat`, `readText`, `streamText`, `listDir`, `writeText`, and `editText`. `dsh-fs-policy` registers **no service** — it is a plugin that adds policy through the `fs/*` event gate: it decides the write/edit intent waterfalls from unseen/absent/present state and records `FsObservation` values. The executor is `dsh-tool-fs`: it reads/writes/edits through `ctx.fs`, dispatches the waterfalls, and emits the recording event. The generated [`ctx.fs` section](#ctxfs--filesystem-abstract-seam) below shows the exact signatures.
`FileSystem` (`ctx.fs`, abstract) owns the provider primitives: `resolve`, `processPath`, `fileUrl`, `contains`, `stat`, `lstat`, `readText`, `streamText`, `readBytes`, `listDir`, `writeText`, and `editText`. `dsh-fs-policy` registers **no service** — it is a plugin that adds policy through the `fs/*` event gate: it decides the write/edit intent waterfalls from unseen/absent/present state and records `FsObservation` values. The executor is `dsh-tool-fs`: it reads/writes/edits through `ctx.fs`, dispatches the waterfalls, and emits the recording event. The generated [`ctx.fs` section](#ctxfs--filesystem-abstract-seam) below shows the exact signatures.
<!-- BEGIN GENERATED cordis-surface (gen-cordis-catalog.ts) — do not edit between markers -->
@@ -373,6 +374,18 @@ abstract readText(target: FsTarget, signal?: AbortSignal): Promise<string>
*/
abstract streamText(target: FsTarget, signal?: AbortSignal): Promise<AsyncIterable<string>>
/**
* Read the whole regular file as raw bytes with no decoding or binary
* rejection. The bound lives at this seam so a backend can never buffer an
* unbounded file: a target known or discovered to exceed `maxBytes` fails
* with `FS_TOO_LARGE` instead of returning a truncated result.
* @param target - the resolved target to read.
* @param signal - aborts the read.
* @param maxBytes - inclusive byte cap on the complete content.
* @returns the full raw content, at most `maxBytes` long.
*/
abstract readBytes(target: FsTarget, signal: AbortSignal | undefined, maxBytes: number): Promise<Uint8Array>
/**
* List direct children of a directory in stable name order. Returns resolved
* child targets plus cheap metadata only; never reads file contents.

View File

@@ -52,7 +52,7 @@ type FsTargetKey = Branded<'FsTargetKey'>
type FsVersion = Branded<'FsVersion'>
```
`stat` 返回元数据(从不返回内容),目标不存在时返回 `undefined`。`type` 让工具在读取前拒绝目录特殊文件;`size` 让工具无需通过失败探测即可选择 `readText` 还是 `streamText`。需要字节上限的协议消费方在消费 `streamText` 时执行该上限,因此文件系统 seam 无需消费方专用的有界读取原语
`stat` 返回元数据(从不返回内容),目标不存在时返回 `undefined`。`type` 让消费方在读取前拒绝目录特殊文件;`size` 让文本消费方无需通过失败探测即可选择 `readText` 还是 `streamText`。文本消费方在消费 `streamText` 时执行自己的保留量上限。原始字节消费方调用 `readBytes(target, signal, maxBytes)`;其必填的完整内容上限会使已知或读取中发现的超限以 `FS_TOO_LARGE` 失败,不会截断结果或无界缓冲
```ts type-equiv
/**
@@ -256,6 +256,7 @@ type FsErrorCode =
| 'FS_NOT_DIRECTORY'
| 'FS_NOT_TEXT'
| 'FS_NOT_REGULAR_FILE'
| 'FS_TOO_LARGE'
| 'FS_PERMISSION_DENIED'
| 'FS_SANDBOX_DENIED'
| 'FS_IO_ERROR'
@@ -274,7 +275,7 @@ type FsErrorCode =
## 服务与插件
`FileSystem``ctx.fs`abstract拥有提供方原语`resolve`、`processPath`、`fileUrl`、`contains`、`stat`、`lstat`、`readText`、`streamText`、`listDir`、`writeText` 与 `editText`。`dsh-fs-policy` **不注册服务**——它是一个通过 `fs/*` 事件门禁添加策略的插件:根据未见/缺失/存在状态对写入与编辑意图 waterfall 作出决策,并记录 `FsObservation` 值。执行器是 `dsh-tool-fs`:它通过 `ctx.fs` 读取/写入/编辑,分发 waterfall并 emit 记录事件。下方生成的 [`ctx.fs` 小节](#ctxfs--filesystem-abstract-seam) 展示确切的 `ctx.fs` 签名。
`FileSystem``ctx.fs`abstract拥有提供方原语`resolve`、`processPath`、`fileUrl`、`contains`、`stat`、`lstat`、`readText`、`streamText`、`readBytes`、`listDir`、`writeText` 与 `editText`。`dsh-fs-policy` **不注册服务**——它是一个通过 `fs/*` 事件门禁添加策略的插件:根据未见/缺失/存在状态对写入与编辑意图 waterfall 作出决策,并记录 `FsObservation` 值。执行器是 `dsh-tool-fs`:它通过 `ctx.fs` 读取/写入/编辑,分发 waterfall并 emit 记录事件。下方生成的 [`ctx.fs` 小节](#ctxfs--filesystem-abstract-seam) 展示确切的 `ctx.fs` 签名。
<!-- BEGIN GENERATED cordis-surface (gen-cordis-catalog.ts) — do not edit between markers -->
@@ -373,6 +374,18 @@ abstract readText(target: FsTarget, signal?: AbortSignal): Promise<string>
*/
abstract streamText(target: FsTarget, signal?: AbortSignal): Promise<AsyncIterable<string>>
/**
* Read the whole regular file as raw bytes with no decoding or binary
* rejection. The bound lives at this seam so a backend can never buffer an
* unbounded file: a target known or discovered to exceed `maxBytes` fails
* with `FS_TOO_LARGE` instead of returning a truncated result.
* @param target - the resolved target to read.
* @param signal - aborts the read.
* @param maxBytes - inclusive byte cap on the complete content.
* @returns the full raw content, at most `maxBytes` long.
*/
abstract readBytes(target: FsTarget, signal: AbortSignal | undefined, maxBytes: number): Promise<Uint8Array>
/**
* List direct children of a directory in stable name order. Returns resolved
* child targets plus cheap metadata only; never reads file contents.

View File

@@ -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/llm-streaming.md
llm-streaming.md: 8ae4e8b376b4c4221e6179eb719fcf162f3031e4
llm-streaming.zh.md: 7d244ab882521a90217873fc3cdee12cd5232db8
llm-streaming.md: 17f984166906914c49b2c330bdf57b3cecdbd013
llm-streaming.zh.md: 6519710dad8a174418bcc97f1bc4b36296ab969e

View File

@@ -234,7 +234,7 @@ interface AppIdentity {
product: string
/** Product version; sourced from package metadata, never hand-copied. */
version: string
/** Public home URL of the app, used as the `User-Agent` comment. */
/** Repository home URL of the app, used as the `User-Agent` comment. */
url: string
}
```

View File

@@ -238,7 +238,7 @@ interface AppIdentity {
product: string
/** Product version; sourced from package metadata, never hand-copied. */
version: string
/** Public home URL of the app, used as the `User-Agent` comment. */
/** Repository home URL of the app, used as the `User-Agent` comment. */
url: string
}
```

View File

@@ -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/persistence.md
persistence.md: 0266d17393d07c258036f7054a02c4ab9d3c74a2
persistence.zh.md: ced83440160ae91ae37025d8024068fb8148b0c6
persistence.md: fd694161ed8ae4c364de5c22d8eb06f1b0a91aec
persistence.zh.md: b616b282204e946e18e90271d1eaeb2d4ed70fc3

View File

@@ -87,6 +87,10 @@ interface SessionHeader {
}
```
## Format refusal — logs a build cannot faithfully read
A backend refuses a log it cannot faithfully interpret with `SessionFormatUnsupportedError`, distinct from `SessionPersistenceCorruptionError` because nothing is damaged. A header `version` ahead of `SESSION_FORMAT_VERSION` names the direction ("written by a newer harness — upgrade the harness to open it"); one behind it states that this build ships no upgrade path. After legacy-shape normalization, an event type outside this build's generated vocabulary (`KNOWN_SESSION_EVENT_TYPES`, emitted by `gen-persistence-catalog`) refuses the same way unless the event's envelope carries `ignorable: true` — silently skipping an unrecognized required event could change how the rest of the log must be read. The message appends the raw log path when the backend keeps one artifact per session, so the refused text stays reachable. The JSONL backend refuses a foreign version straight from the raw header line, before validating today's header shape or decoding any event row — a structurally different future format still reports the upgrade direction, never "corrupt"; SQLite gates whole-file structure through its own `SCHEMA_VERSION` pragma first. Design rationale and the deferred upgrader chain live in the [session-log-version-mechanism note](../../.agents/notes/implemented/architecture/2026-08-10-session-log-version-mechanism.md).
## `CreateSessionOptions` — seeding and metadata
Creating a `Session` through the store takes a `seed` (initial replay or fork history) and `meta` (the storage-level fields the store folds into a `SessionHeader`). The store fills in `version`/`id` and defaults `createdAt`; the caller may supply the validated absolute `cwd`, the `parentSession` lineage, the `seedLength` seed boundary, the optional coarse `origin`, the `delegationDepth`, the `agentPreset` the agent was composed from, and an existing `createdAt`. `origin: 'subagent'` lets product navigation hide duplicate child rows; it does not prove that a descriptor is valid or that the child can resume.
@@ -118,6 +122,22 @@ interface CreateSessionOptions {
Replay/fork is therefore `ctx.sessions.create(id, { seed: seedEvents })`; resuming a *persisted* session into a live agent is `ctx.agents.resume({ resumeSessionId })`.
## `SessionRawArtifact` — verbatim stored artifact text
A backend's own artifact text for one session, byte-identical to what it durably wrote (decoded from its physical encoding). `readRaw` returns it without reconstructing from parsed events, so backend-specific serialization (chunk packing, key order, line breaks) survives; backends without a per-session artifact, such as SQLite, inherit the `undefined` default.
```ts type-equiv
/** A backend's own raw artifact text for one session, verbatim. */
interface SessionRawArtifact {
/** The session header parsed from the artifact's own first line. */
readonly meta: SessionHeader
/** The artifact's base filename on disk, without any physical encoding suffix. */
readonly filename: string
/** The artifact's full text content, decoded from the backend's physical encoding. */
readonly content: string
}
```
## Preparation and restoration ownership
`SessionStore.prepare()` accepts ordinary creation options or fresh persistence graphs transferred through `RestoredSessionOptions`. The restoration branch validates and freezes the transferred header and events in place, so callers must retain no mutable aliases. `SessionPreparation` then owns the exact unpublished Session until publication or rollback; disposal is synchronous and idempotent. Persistence inspection exposes only `SessionInspection`, an immutable logical view borrowed from the same prepared Session.
@@ -237,6 +257,21 @@ Durable append-only session storage. Implementations preserve contiguous, lossle
*/
abstract locate(meta: SessionHeader): SessionLocation | undefined
/**
* Read a session's backend-owned artifact text verbatim — the exact durable
* bytes the backend wrote (decoded from its physical encoding, e.g. a
* decompressed JSONL). The returned `content` is the raw text, not a
* reconstruction from parsed events, so it preserves backend-specific
* serialization (chunk packing, key order, line breaks). Backends without a
* per-session artifact (SQLite) inherit the `undefined` default.
* @param _id - the persisted session to read (unused by the default: no
* per-session artifact).
* @param signal - optional cancellation for backend read work.
* @returns the raw artifact plus its parsed header, or `undefined` when the
* session is absent or the backend owns no per-session artifact.
*/
readRaw(_id: SessionId, signal?: AbortSignal): Promise<SessionRawArtifact | undefined>
/**
* Register a new session's metadata. A backend MAY defer the physical write
* until the first {@link append} (lazy materialization), in which case a
@@ -342,5 +377,5 @@ abstract listSnapshots(signal?: AbortSignal): Promise<SessionPersistenceSnapshot
Types: [SessionEvent](session.md) · [SessionId](core.md)
Source: [`packages/session/session-persistence/src/index.ts:72`](../../packages/session/session-persistence/src/index.ts)
Source: [`packages/session/session-persistence/src/index.ts:84`](../../packages/session/session-persistence/src/index.ts)
<!-- END GENERATED cordis-surface -->

View File

@@ -87,6 +87,10 @@ interface SessionHeader {
}
```
## 格式拒绝:本构建无法可靠读取的日志
后端用 `SessionFormatUnsupportedError` 拒绝无法可靠解读的日志,它与 `SessionPersistenceCorruptionError` 区分因为数据没有损坏。header 的 `version` 比 `SESSION_FORMAT_VERSION` 新时,消息说明方向("由更新的 harness 写入,请升级 harness 后打开");比它旧时说明本构建没有升级路径。经过 legacy 形状归一化后,本构建生成词汇表(`KNOWN_SESSION_EVENT_TYPES`,由 `gen-persistence-catalog` 生成)之外的事件类型同样被拒绝,除非该事件的信封带 `ignorable: true`静默跳过一个不认识的必需事件可能改变日志其余部分的解读方式。后端为每个会话保留独立文件时消息附上原始日志路径被拒绝的文本仍然可读。JSONL 后端直接从原始 header 行拒绝外来版本,先于当前 header 形状校验和任何事件行解码,因此结构完全不同的未来格式仍会报告升级方向,绝不会报"损坏"SQLite 则先由自己的 `SCHEMA_VERSION` pragma 把关整个文件的结构。设计理由与推迟建设的升级器链见 [session-log 版本机制 Agent Note](../../.agents/notes/implemented/architecture/2026-08-10-session-log-version-mechanism.md)。
## `CreateSessionOptions`seed 与元数据
通过 store 创建 `Session` 时会接收 `seed`(初始回放或 fork 历史)与 `meta`store 折叠进 `SessionHeader` 的存储层字段。store 填充 `version`/`id` 并为 `createdAt` 提供默认值;调用方可以提供已校验的绝对 `cwd`、`parentSession` 谱系、`seedLength` 种子边界、可选的粗粒度 `origin`、`delegationDepth`、该 agent 所依据组装的 `agentPreset` 以及已有的 `createdAt`。`origin: 'subagent'` 让产品导航能够隐藏重复的 child 行;它不证明描述符有效,也不证明 child 可以恢复。
@@ -118,6 +122,22 @@ interface CreateSessionOptions {
因此,回放/fork 的调用方式为 `ctx.sessions.create(id, { seed: seedEvents })`;将一个*持久化*会话恢复为活跃 agent 的调用方式为 `ctx.agents.resume({ resumeSessionId })`。
## `SessionRawArtifact`——逐字存储工件文本
后端为单个会话自持的工件文本,与其持久化写入的字节逐字一致(按物理编码解码)。`readRaw` 返回它而不从解析后事件重建因此后端特定的序列化chunk 打包、键序、换行)得以保留;没有每会话工件的后端(如 SQLite继承 `undefined` 默认。
```ts type-equiv
/** A backend's own raw artifact text for one session, verbatim. */
interface SessionRawArtifact {
/** The session header parsed from the artifact's own first line. */
readonly meta: SessionHeader
/** The artifact's base filename on disk, without any physical encoding suffix. */
readonly filename: string
/** The artifact's full text content, decoded from the backend's physical encoding. */
readonly content: string
}
```
## 准备与恢复所有权
`SessionStore.prepare()` 接收普通创建选项,或通过 `RestoredSessionOptions` 转移所有权的新鲜持久化对象图。恢复分支会直接验证并冻结转移来的 header 与事件,因此调用方不得保留可变别名。`SessionPreparation` 随后持有该精确的未发布 Session直至发布或回滚dispose 是同步且幂等的。持久化检查只暴露 `SessionInspection`,即从同一个已准备 Session 借用的不可变逻辑视图。
@@ -237,6 +257,21 @@ Durable append-only session storage. Implementations preserve contiguous, lossle
*/
abstract locate(meta: SessionHeader): SessionLocation | undefined
/**
* Read a session's backend-owned artifact text verbatim — the exact durable
* bytes the backend wrote (decoded from its physical encoding, e.g. a
* decompressed JSONL). The returned `content` is the raw text, not a
* reconstruction from parsed events, so it preserves backend-specific
* serialization (chunk packing, key order, line breaks). Backends without a
* per-session artifact (SQLite) inherit the `undefined` default.
* @param _id - the persisted session to read (unused by the default: no
* per-session artifact).
* @param signal - optional cancellation for backend read work.
* @returns the raw artifact plus its parsed header, or `undefined` when the
* session is absent or the backend owns no per-session artifact.
*/
readRaw(_id: SessionId, signal?: AbortSignal): Promise<SessionRawArtifact | undefined>
/**
* Register a new session's metadata. A backend MAY defer the physical write
* until the first {@link append} (lazy materialization), in which case a
@@ -342,5 +377,5 @@ abstract listSnapshots(signal?: AbortSignal): Promise<SessionPersistenceSnapshot
Types: [SessionEvent](session.md) · [SessionId](core.md)
Source: [`packages/session/session-persistence/src/index.ts:72`](../../packages/session/session-persistence/src/index.ts)
Source: [`packages/session/session-persistence/src/index.ts:84`](../../packages/session/session-persistence/src/index.ts)
<!-- END GENERATED cordis-surface -->

View File

@@ -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/sandbox.md
sandbox.md: 20e0f36a5edb211ea409208d4e5e4a9be2e91d46
sandbox.zh.md: 5f5465af46aa88d72b4a39f728f18855156b24ba
sandbox.md: 0478e30ada949102193407ee536d4974c841e371
sandbox.zh.md: d2a59d1703b22deb1a4206911f488b4e30059580

View File

@@ -2,13 +2,13 @@
English | [中文](sandbox.zh.md)
The process-sandbox seam of [dsh-sandbox](../../packages/sandbox/sandbox) wraps a same-world subprocess argv in a file-effect policy without coupling consumers to a platform runner. [dsh-sandbox-local](../../packages/sandbox/sandbox-local) supplies the Linux bwrap/Landlock and macOS Seatbelt backends; [dsh-bash-sandbox](../../packages/bash/bash-sandbox) is the first consumer. Containers, microVMs, and remote execution are sibling implementations of whole capability seams, not providers of `ctx.sandbox`.
The process-sandbox seam of [dsh-sandbox](../../packages/sandbox/sandbox) wraps a same-world subprocess argv in a file-effect policy without coupling consumers to a platform runner. [dsh-sandbox-local](../../packages/sandbox/sandbox-local) supplies Linux bwrap/Landlock, macOS Seatbelt, and the Windows ACL restricted-token backend; [dsh-bash-sandbox](../../packages/bash/bash-sandbox) and [dsh-pwsh-sandbox](../../packages/bash/pwsh-sandbox) consume it. Containers, microVMs, and remote execution are sibling implementations of whole capability seams, not providers of `ctx.sandbox`.
Source: [`packages/sandbox/sandbox/src/index.ts`](../../packages/sandbox/sandbox/src/index.ts)
## Modes and enforcement
`SandboxMode` governs filesystem effects only. `read-only` denies every write — the POSIX runners additionally grant the `/dev/null` sink their shells require, while the Windows ACL runner grants nothing; `workspace-write` permits writes under the workspace root and the backend's promised temp area; `danger-full-access` bypasses confinement. Network and process visibility are outside this vocabulary.
`SandboxMode` governs filesystem effects only. `read-only` asks the backend to deny writes — the POSIX runners additionally grant the `/dev/null` sink their shells require, while the Windows ACL runner grants no explicit writable root and reports partial enforcement for its ambient ACL gaps; `workspace-write` permits writes under the workspace root and the backend's promised temp area; `danger-full-access` bypasses confinement. Network and process visibility are outside this vocabulary.
```ts type-equiv
/**
@@ -27,7 +27,7 @@ Only the first two modes can be sent to a provider. A `danger-full-access` consu
type ConfinedSandboxMode = Exclude<SandboxMode, 'danger-full-access'>
```
Enforcement is a reported fact. `full` means the backend governs every file effect promised by the mode; `partial` means an active backend or older kernel ABI governs only a subset, so consumers that require the absolute promise must reject or surface that distinction.
Enforcement is a reported fact. `full` means the backend governs every file effect promised by the mode; `partial` means an active backend or older kernel ABI governs only a subset, so consumers that require the absolute promise must reject or surface that distinction. Older Landlock ABIs and the Windows ACL runner's Everyone/hard-link boundaries are current partial cases.
```ts type-equiv
/**
@@ -55,10 +55,10 @@ interface SandboxExecutionPolicy {
workspaceRoot: string
/**
* Opaque identity of the calling session (the branded `dsh-session`
* SessionId). Backends key per-session state off it (e.g. the windows-acl
* per-session private temp subdirectory — the write grant itself is
* per-workspace, derived from the workspace root); absent for agentless
* calls, which fall back to per-call backend state.
* SessionId). Backends key per-session state off it (e.g. windows-acl gives
* each live session/workspace pair a random private temp directory and SID,
* while the workspace SID and standing grant remain per-workspace); absent
* for agentless calls, which fall back to per-call backend state.
*/
sessionId?: SessionId
}

View File

@@ -2,13 +2,13 @@
[English](sandbox.md) | 中文
[dsh-sandbox](../../packages/sandbox/sandbox) 的进程沙箱 seam 将与宿主共享文件系统和内核的子进程 argv 包装在文件效果策略中,而不将消费方耦合到特定平台运行器。[dsh-sandbox-local](../../packages/sandbox/sandbox-local) 提供 Linux bwrap/LandlockmacOS Seatbelt 后端;[dsh-bash-sandbox](../../packages/bash/bash-sandbox) 是第一个消费方。容器、microVM 和远程执行是完整能力 seam 的同级实现,而非 `ctx.sandbox` 的提供方。
[dsh-sandbox](../../packages/sandbox/sandbox) 的进程沙箱 seam 将与宿主共享文件系统和内核的子进程 argv 包装在文件效果策略中,而不将消费方耦合到特定平台运行器。[dsh-sandbox-local](../../packages/sandbox/sandbox-local) 提供 Linux bwrap/LandlockmacOS Seatbelt 与 Windows ACL 受限令牌后端;[dsh-bash-sandbox](../../packages/bash/bash-sandbox) 和 [dsh-pwsh-sandbox](../../packages/bash/pwsh-sandbox) 是其消费方。容器、microVM 和远程执行是完整能力 seam 的同级实现,而非 `ctx.sandbox` 的提供方。
源码:[`packages/sandbox/sandbox/src/index.ts`](../../packages/sandbox/sandbox/src/index.ts)
## 模式与强制执行
`SandboxMode` 仅管控文件系统效果。`read-only` 拒绝所有写入——POSIX runner 还会授予其 shell 所需的 `/dev/null` 接收器,而 Windows ACL runner 不授予任何写入`workspace-write` 允许在工作区根目录及后端承诺的临时区域下写入;`danger-full-access` 绕过隔离。网络与进程可见性不在此处的定义范围内。
`SandboxMode` 仅管控文件系统效果。`read-only` 要求后端拒绝写入——POSIX runner 还会授予其 shell 所需的 `/dev/null` 接收器,而 Windows ACL runner 不授予任何显式可写根目录,并因环境 ACL 缺口报告部分强制执行`workspace-write` 允许在工作区根目录及后端承诺的临时区域下写入;`danger-full-access` 绕过隔离。网络与进程可见性不在此处的定义范围内。
```ts type-equiv
/**
@@ -27,7 +27,7 @@ type SandboxMode = 'read-only' | 'workspace-write' | 'danger-full-access'
type ConfinedSandboxMode = Exclude<SandboxMode, 'danger-full-access'>
```
强制执行完整性是后端报告的事实。`full` 表示后端管控了该模式承诺的所有文件效果;`partial` 表示活跃后端或较旧的内核 ABI 仅管控其中一个子集,因此要求绝对保证的消费方必须拒绝或向上暴露这一区别。
强制执行完整性是后端报告的事实。`full` 表示后端管控了该模式承诺的所有文件效果;`partial` 表示活跃后端或较旧的内核 ABI 仅管控其中一个子集,因此要求绝对保证的消费方必须拒绝或向上暴露这一区别。当前的部分强制执行情形包括较旧的 Landlock ABI以及 Windows ACL runner 的 Everyone 与硬链接边界。
```ts type-equiv
/**
@@ -55,10 +55,10 @@ interface SandboxExecutionPolicy {
workspaceRoot: string
/**
* Opaque identity of the calling session (the branded `dsh-session`
* SessionId). Backends key per-session state off it (e.g. the windows-acl
* per-session private temp subdirectory — the write grant itself is
* per-workspace, derived from the workspace root); absent for agentless
* calls, which fall back to per-call backend state.
* SessionId). Backends key per-session state off it (e.g. windows-acl gives
* each live session/workspace pair a random private temp directory and SID,
* while the workspace SID and standing grant remain per-workspace); absent
* for agentless calls, which fall back to per-call backend state.
*/
sessionId?: SessionId
}

View File

@@ -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/session.md
session.md: 0b78e51ebf6e2ad5c312268ad4bfb4392b0486df
session.zh.md: d1e91f684a835e08406f524efe876baa1a6a72cb
session.md: 990b249cde9f02343f2c668aee5d7c000837df56
session.zh.md: 39e8ff1e8831fd75c8929c93e263622bb5aa6ea4

View File

@@ -215,6 +215,17 @@ type SessionEvent<T extends SessionEventType = SessionEventType> = {
/** Unix epoch milliseconds. */
time: number
data: SessionEventMap[K]
/**
* Marks an event a reader may safely skip when it does not recognize
* `type`. Absent means required: a reader meeting an unrecognized type
* without this marker MUST refuse to reconstruct the session instead of
* silently dropping the event, because an unrecognized required event may
* change how the rest of the log is interpreted. A writer sets `true` only
* on purely informational records whose loss cannot affect reconstruction;
* defaulting to required means a forgotten marker over-refuses (an
* inconvenience) rather than silently resuming a gutted session.
*/
ignorable?: true
} & (K extends SurfaceEventType ? {
/**
* Seq numbers of earlier events that this event cites as sources
@@ -733,7 +744,7 @@ fork(source: SessionForkSource, boundary?: number, childSessionId?: SessionId):
Types: [CreateSessionOptions](persistence.md) · [PrepareSessionOptions](persistence.md) · [SessionId](core.md)
Source: [`packages/core/session/src/index.ts:810`](../../packages/core/session/src/index.ts)
Source: [`packages/core/session/src/index.ts:813`](../../packages/core/session/src/index.ts)
<a id="session-events"></a>
@@ -762,7 +773,7 @@ Creation announcement during session publication. A synchronous throw vetoes and
Types: [Scoped](scope.md)
Source: [`packages/core/session/src/index.ts:74`](../../packages/core/session/src/index.ts)
Source: [`packages/core/session/src/index.ts:75`](../../packages/core/session/src/index.ts)
<a id="sessiondisposed--emit"></a>
@@ -785,7 +796,7 @@ Emitted once when an announced session leaves the store, including publication r
Types: [Scoped](scope.md)
Source: [`packages/core/session/src/index.ts:84`](../../packages/core/session/src/index.ts)
Source: [`packages/core/session/src/index.ts:85`](../../packages/core/session/src/index.ts)
<a id="sessionevent--emit"></a>
@@ -810,7 +821,7 @@ Post-commit, fire-and-forget append feed. The listener snapshot resolves before
Types: [Scoped](scope.md)
Source: [`packages/core/session/src/index.ts:96`](../../packages/core/session/src/index.ts)
Source: [`packages/core/session/src/index.ts:97`](../../packages/core/session/src/index.ts)
<a id="sessionflush--parallel"></a>
@@ -832,5 +843,5 @@ Awaited parallel durability checkpoint: every listener runs and the caller await
Types: [Scoped](scope.md)
Source: [`packages/core/session/src/index.ts:105`](../../packages/core/session/src/index.ts)
Source: [`packages/core/session/src/index.ts:106`](../../packages/core/session/src/index.ts)
<!-- END GENERATED cordis-surface -->

View File

@@ -217,6 +217,17 @@ type SessionEvent<T extends SessionEventType = SessionEventType> = {
/** Unix epoch milliseconds. */
time: number
data: SessionEventMap[K]
/**
* Marks an event a reader may safely skip when it does not recognize
* `type`. Absent means required: a reader meeting an unrecognized type
* without this marker MUST refuse to reconstruct the session instead of
* silently dropping the event, because an unrecognized required event may
* change how the rest of the log is interpreted. A writer sets `true` only
* on purely informational records whose loss cannot affect reconstruction;
* defaulting to required means a forgotten marker over-refuses (an
* inconvenience) rather than silently resuming a gutted session.
*/
ignorable?: true
} & (K extends SurfaceEventType ? {
/**
* Seq numbers of earlier events that this event cites as sources
@@ -737,7 +748,7 @@ fork(source: SessionForkSource, boundary?: number, childSessionId?: SessionId):
Types: [CreateSessionOptions](persistence.md) · [PrepareSessionOptions](persistence.md) · [SessionId](core.md)
Source: [`packages/core/session/src/index.ts:810`](../../packages/core/session/src/index.ts)
Source: [`packages/core/session/src/index.ts:813`](../../packages/core/session/src/index.ts)
<a id="session-events"></a>
@@ -766,7 +777,7 @@ Creation announcement during session publication. A synchronous throw vetoes and
Types: [Scoped](scope.md)
Source: [`packages/core/session/src/index.ts:74`](../../packages/core/session/src/index.ts)
Source: [`packages/core/session/src/index.ts:75`](../../packages/core/session/src/index.ts)
<a id="sessiondisposed--emit"></a>
@@ -789,7 +800,7 @@ Emitted once when an announced session leaves the store, including publication r
Types: [Scoped](scope.md)
Source: [`packages/core/session/src/index.ts:84`](../../packages/core/session/src/index.ts)
Source: [`packages/core/session/src/index.ts:85`](../../packages/core/session/src/index.ts)
<a id="sessionevent--emit"></a>
@@ -814,7 +825,7 @@ Post-commit, fire-and-forget append feed. The listener snapshot resolves before
Types: [Scoped](scope.md)
Source: [`packages/core/session/src/index.ts:96`](../../packages/core/session/src/index.ts)
Source: [`packages/core/session/src/index.ts:97`](../../packages/core/session/src/index.ts)
<a id="sessionflush--parallel"></a>
@@ -836,5 +847,5 @@ Awaited parallel durability checkpoint: every listener runs and the caller await
Types: [Scoped](scope.md)
Source: [`packages/core/session/src/index.ts:105`](../../packages/core/session/src/index.ts)
Source: [`packages/core/session/src/index.ts:106`](../../packages/core/session/src/index.ts)
<!-- END GENERATED cordis-surface -->

View File

@@ -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: 961a16f58cb936205290d23ce6b9d94cb94607d5
subagent.zh.md: ac97d27d9824ca62701e11ae99264adbddafbbd8
subagent.md: cf728d9f15fdaaf8199954e91b564167e8efe439
subagent.zh.md: 1a8e2e5837b8ac88f7d7b7ca767fb7aa21391a9f

View File

@@ -293,7 +293,12 @@ The outcome of a one-shot run, resolved by `SubagentRun.result`. `structured` is
* The terminal outcome of a subagent run, resolved by {@link SubagentRun.result}.
*/
interface SubagentResult {
/** The child's final assistant output (the last assistant message's content). */
/**
* The child's final assistant output is the content of its last non-empty
* assistant message. Empty-content messages, including usage-only messages,
* are skipped. Without a non-empty message, the output is its accumulated
* assistant text stream, or `[]` when the child produced neither.
*/
readonly output: ContentBlock[]
/**
* The structured result after a requested `outputSchema` was successfully
@@ -385,7 +390,10 @@ Each provider is a named child-agent transport, and multiple providers may coexi
/**
* One registered transport for running child agents. Providers are trusted
* same-process implementations; callers treat descriptors and returned values
* as borrowed immutable data.
* as borrowed immutable data. The service may call one provider concurrently
* for distinct children. Providers isolate operation-local mutable state; a
* shared capacity controller may delay an operation but must not couple its
* settlement or cleanup to a sibling.
*/
interface SubagentProvider {
/** Unique registry name (e.g. `spawn`, `fork`, `acp`). */
@@ -406,7 +414,8 @@ interface SubagentProvider {
* initial turn. Before fulfillment, the provider owns setup and cleans any
* unpublished partial resources before rejecting. Ownership transfers on
* fulfillment; subsequent turn or infrastructure failure settles through
* the returned run.
* the returned run. Distinct starts may overlap; cancellation, failure,
* result settlement, and disposal remain independent for each run.
*/
start(request: ResolvedSubagentStartRequest): Promise<SubagentRun>
/**
@@ -421,6 +430,8 @@ interface SubagentProvider {
* continuation manager owns identity reservation, composition, Agent
* creation, prompt delivery, cold resume, ownership, and disposal, so a
* provider never sees the child's Agent, handle, turns, or teardown.
* Distinct preparations may overlap; each follows its own signal and returns
* data belonging only to `request.sessionId`.
*/
prepareContinuable?(request: ContinuableCreateRequest): Promise<ContinuableCreateSpec>
}
@@ -614,7 +625,7 @@ async start(name: string, request: SubagentStartRequest): Promise<SubagentRun>
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:170`](../../packages/subagent/subagent/src/index.ts)
<a id="subagent-events"></a>
@@ -640,7 +651,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:165`](../../packages/subagent/subagent/src/index.ts)
<a id="subagentprovider-added--emit"></a>
@@ -657,7 +668,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:139`](../../packages/subagent/subagent/src/index.ts)
<a id="subagentprovider-removed--emit"></a>
@@ -674,7 +685,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:145`](../../packages/subagent/subagent/src/index.ts)
<a id="subagentstart--emit"></a>
@@ -698,5 +709,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:156`](../../packages/subagent/subagent/src/index.ts)
<!-- END GENERATED cordis-surface -->

View File

@@ -293,7 +293,12 @@ type SubagentDescendantListEntry = SubagentListEntry & {
* The terminal outcome of a subagent run, resolved by {@link SubagentRun.result}.
*/
interface SubagentResult {
/** The child's final assistant output (the last assistant message's content). */
/**
* The child's final assistant output is the content of its last non-empty
* assistant message. Empty-content messages, including usage-only messages,
* are skipped. Without a non-empty message, the output is its accumulated
* assistant text stream, or `[]` when the child produced neither.
*/
readonly output: ContentBlock[]
/**
* The structured result after a requested `outputSchema` was successfully
@@ -387,7 +392,10 @@ interface SubagentRun {
/**
* One registered transport for running child agents. Providers are trusted
* same-process implementations; callers treat descriptors and returned values
* as borrowed immutable data.
* as borrowed immutable data. The service may call one provider concurrently
* for distinct children. Providers isolate operation-local mutable state; a
* shared capacity controller may delay an operation but must not couple its
* settlement or cleanup to a sibling.
*/
interface SubagentProvider {
/** Unique registry name (e.g. `spawn`, `fork`, `acp`). */
@@ -408,7 +416,8 @@ interface SubagentProvider {
* initial turn. Before fulfillment, the provider owns setup and cleans any
* unpublished partial resources before rejecting. Ownership transfers on
* fulfillment; subsequent turn or infrastructure failure settles through
* the returned run.
* the returned run. Distinct starts may overlap; cancellation, failure,
* result settlement, and disposal remain independent for each run.
*/
start(request: ResolvedSubagentStartRequest): Promise<SubagentRun>
/**
@@ -423,6 +432,8 @@ interface SubagentProvider {
* continuation manager owns identity reservation, composition, Agent
* creation, prompt delivery, cold resume, ownership, and disposal, so a
* provider never sees the child's Agent, handle, turns, or teardown.
* Distinct preparations may overlap; each follows its own signal and returns
* data belonging only to `request.sessionId`.
*/
prepareContinuable?(request: ContinuableCreateRequest): Promise<ContinuableCreateSpec>
}
@@ -616,7 +627,7 @@ async start(name: string, request: SubagentStartRequest): Promise<SubagentRun>
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:170`](../../packages/subagent/subagent/src/index.ts)
<a id="subagent-events"></a>
@@ -642,7 +653,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:165`](../../packages/subagent/subagent/src/index.ts)
<a id="subagentprovider-added--emit"></a>
@@ -659,7 +670,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:139`](../../packages/subagent/subagent/src/index.ts)
<a id="subagentprovider-removed--emit"></a>
@@ -676,7 +687,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:145`](../../packages/subagent/subagent/src/index.ts)
<a id="subagentstart--emit"></a>
@@ -700,5 +711,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:156`](../../packages/subagent/subagent/src/index.ts)
<!-- END GENERATED cordis-surface -->

View File

@@ -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/system-prompt.md
system-prompt.md: bdc0e994fb8e784a19814574c405d8cc3dce2d11
system-prompt.zh.md: db6932b18f4721020fed567d49727f863eb06608
system-prompt.md: 56617ef9d3d8da89673a4624abcef73e58d72cab
system-prompt.zh.md: cafea4f9689879b3fd8d0e1fff7249fcb02a7c12

Some files were not shown because too many files have changed in this diff Show More