Merge remote-tracking branch 'origin/master' into feature/subagent-policy-inheritance
# Conflicts: # .agents/notes/implemented/feature/2026-07-06-approval-seam.i18n.yaml # examples/acp-agent/tests/acp.snapshot.ts
This commit is contained in:
6
packages/cordis/README.i18n.yaml
Normal file
6
packages/cordis/README.i18n.yaml
Normal 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
|
||||
README.md: b3a70b07c57ae1a2e3dd975a64c840d90c5a84ad
|
||||
README.zh.md: 5832310cfe14a299ac5998a28bcbbb500caf86b5
|
||||
@@ -1,5 +1,7 @@
|
||||
# packages/cordis — the self-referential runtime toolset
|
||||
|
||||
English | [中文](README.zh.md)
|
||||
|
||||
Model-facing tools over the live cordis runtime the agent itself runs inside: inspect the loaded plugins and service surface, mount model-written plugins, and dispose them again. Design home: [the toolset Agent Note](../../.agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.md).
|
||||
|
||||
| Package | Role | ctx key |
|
||||
|
||||
9
packages/cordis/README.zh.md
Normal file
9
packages/cordis/README.zh.md
Normal file
@@ -0,0 +1,9 @@
|
||||
# packages/cordis:自指运行时工具集
|
||||
|
||||
[English](README.md) | 中文
|
||||
|
||||
面向模型、作用于 agent(智能体)自身所在实时 Cordis 运行时的工具:检查已加载插件与服务接口、挂载模型编写的插件,以及再次释放这些插件。设计归档见[工具集 Agent Note(agent 决策记录)](../../.agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.md)。
|
||||
|
||||
| 包(package) | 角色 | ctx 键 |
|
||||
|---|---|---|
|
||||
| [`tool-cordis/`](tool-cordis/README.md) | `cordis_inspect`/`cordis_mount`/`cordis_unmount` 工具:读取运行时、在 `node:vm` 沙箱中求值模型编写的插件代码,并在同一个分组 fiber 下管理动态挂载 | 注册到 `ctx.tools` |
|
||||
6
packages/cordis/tool-cordis/README.i18n.yaml
Normal file
6
packages/cordis/tool-cordis/README.i18n.yaml
Normal 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
|
||||
README.md: 022e25decad650e03aa621cfa2b3f33ccc8d9743
|
||||
README.zh.md: 99a79209a2a895ee8e11e3b7345a305da514ac1e
|
||||
@@ -1,5 +1,7 @@
|
||||
# @deepseek-ai/dsh-tool-cordis
|
||||
|
||||
English | [中文](README.zh.md)
|
||||
|
||||
The self-referential cordis toolset: three model-facing tools over the live runtime the agent runs inside. Design home — sandbox semantics, mount lifecycle, cross-mount composition, the generated API catalog, standing decisions: [the toolset Agent Note](../../../.agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.md).
|
||||
|
||||
## What it does
|
||||
|
||||
87
packages/cordis/tool-cordis/README.zh.md
Normal file
87
packages/cordis/tool-cordis/README.zh.md
Normal file
@@ -0,0 +1,87 @@
|
||||
# @deepseek-ai/dsh-tool-cordis
|
||||
|
||||
[English](README.md) | 中文
|
||||
|
||||
自引用 cordis 工具集:三个面向模型的工具,操作 agent 所处的存活运行时。设计归属(沙箱语义、挂载生命周期、跨挂载组合、生成的 API 目录、既定决策)见[工具集 Agent Note](../../../.agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.md)。
|
||||
|
||||
## 功能
|
||||
|
||||
- `cordis_inspect`:运行时的只读报告,包括服务、已加载插件列表、已注册工具、动态挂载表,以及目录支持的 `api`/`events` 参考。精确的 `name` 配合 `what: "api"` 或 `what: "events"` 可缩窄报告,并附上原始源代码 JSDoc。
|
||||
- `cordis_mount`:在 `node:vm` 沙箱中求值模型编写的 JavaScript(一个 async 函数的主体);代码必须 `return` 一个 cordis 插件,系统将其挂载在 `cordis-dynamic` 分组 fiber 下,并以 `dyn-<n>` 跟踪。
|
||||
- `cordis_unmount`:按 id 释放一项挂载,只在完全停稳后返回。
|
||||
|
||||
精确的面向模型 schema 见[生成的工具目录](../../../docs/tool-catalog.md)。
|
||||
|
||||
规范成功值分别为检查字符串、挂载 `{ id, pluginName, state, provides, waitingFor }`,以及卸载 `{ id, pluginName }`。原生 renderer 保留现有文本,因此程序可以使用 `mounted.id`,普通 Function Calling 仍会看到 `mounted dyn-1 (...)`。
|
||||
|
||||
## 信任立场
|
||||
|
||||
该沙箱隔离全局变量,但不是安全边界。Node 全局变量不存在,或会重定向到 `ctx.fs`、`ctx.web`、`ctx.bash` 等 Cordis 服务;写入 `globalThis` 的内容保持局部,但 host realm helper 使逃逸成为可能。已挂载插件收到不含框架内部机制的 façade,但获准服务仍会影响存活运行时。动态工具 schema 与 annotation 通过迭代式 JSON 克隆和 schema 规范化跨越 realm,因此有效的深层声明受内存而非调用栈限制;含 JSON 不可见 key 的 record,以及子类化或装饰过的 schema array,会在规范化前被拒绝。应当像对待 bash 访问一样对待该工具集;参见[设计与信任立场](../../../.agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.md)。
|
||||
|
||||
## 配置
|
||||
|
||||
| 字段 | 默认值 | 含义 |
|
||||
|---|---|---|
|
||||
| `vmTimeoutMs` | `5000` | 挂载代码求值中同步部分的边界;async 主体可逃出该边界 |
|
||||
|
||||
## 生成的 API 目录
|
||||
|
||||
`src/api-catalog.ts` 由 `scripts/gen-cordis-api.ts` 生成,使用与 [docs/cordis-catalog](../../../docs/cordis-catalog/services.md) 相同的 AST 遍历,并由 `pnpm run verify-cordis-api`(位于 `doc-sync` 中)实施新鲜度门禁,绝不可手工编辑。`cordis_inspect` 在调用时把该目录与存活服务 store 取交集。宽泛的 `api`/`events` 报告只渲染摘要与签名;精确 `name` 会选择保留的方法/事件 JSDoc,未知或未运行的服务目标会高声失败。
|
||||
|
||||
## 渲染
|
||||
|
||||
三个工具都渲染 `generic` 卡片(`read`/`execute`/`delete`);`cordis_mount` 以 `rawInput` 携带挂载代码。presenter 是 args 的纯函数;结果保留默认文本渲染。
|
||||
|
||||
## 导出形状
|
||||
|
||||
Namespace 插件:命名导出 `name`/`inject`/`Config`/`apply`,无默认导出([docs/postmortem/0001](../../../docs/postmortem/0001-acp-default-export-drops-inject.md))。
|
||||
|
||||
## 模型体验
|
||||
|
||||
### 工具 schema
|
||||
|
||||
#### 模型看到的内容
|
||||
|
||||
该插件可见时,会话模型会看到生成的 [`cordis_inspect`、`cordis_mount` 和 `cordis_unmount` schema](../../../docs/tool-catalog.md#deepseek-aidsh-tool-cordis)。
|
||||
|
||||
#### Token 影响
|
||||
|
||||
该工具视图中的每次请求承担固定 schema 成本。
|
||||
|
||||
#### KV Cache 影响
|
||||
|
||||
只要该工具视图不变,前缀就保持稳定。隐藏这些定义的 scope 或插件生命周期变更,可能使从第一个变化的 schema token 起的复用失效。
|
||||
|
||||
### 工具调用历史与结果
|
||||
|
||||
#### 模型看到的内容
|
||||
|
||||
检查会精确地用 `## <section>` 加换行及数据相关主体来拼接选中区段,各区段之间留一个空行。宽泛的 API/事件报告省略 JSDoc;`name` 配合 `what: "api"` 或 `what: "events"` 返回一个精确目标及其原始 JSDoc。挂载返回 `mounted <id> (plugin "<name>", state: <state>)`,并可在右括号前插入 ` — waiting for service(s): <names> (activates when provided)`。卸载返回 `unmounted <id> (plugin "<name>")`;未知 id 会变成 `Error: no dynamic plugin with id "<id>" (list mounts with cordis_inspect what:"dynamic")`。提交的挂载程序保留在 assistant 工具调用历史中。
|
||||
|
||||
#### Token 影响
|
||||
|
||||
检查输出与挂载代码取决于数据,并在压缩前重复发送;生命周期确认文本很短。
|
||||
|
||||
#### KV Cache 影响
|
||||
|
||||
仅追加;新可见内容位于可复用请求前缀之后,不会使现有 KV-cache 配置项失效。
|
||||
|
||||
### 挂载后的后续请求
|
||||
|
||||
#### 模型看到的内容
|
||||
|
||||
已挂载插件可以注册工具、提示词贡献或监听器,改变其目标 scope 的后续请求;卸载会在完全停稳后移除这些贡献。
|
||||
|
||||
#### Token 影响
|
||||
|
||||
间接 token 影响等于已挂载插件的贡献,且只在挂载生命周期内持续。
|
||||
|
||||
#### KV Cache 影响
|
||||
|
||||
挂载或卸载提示词/工具贡献会改变后续请求前缀,并可能使从第一个变化的贡献起的复用失效;挂载集合不变时,前缀保持稳定。
|
||||
|
||||
## 已知限制与暂缓事项
|
||||
|
||||
- **沙箱只用于约束诚实代码,并非安全边界**:可以访问沙箱全局变量上的 host realm helper,因此挂载代码可以触达 Node;加载该插件时,应当像授予 bash 工具一样慎重(见 § 信任立场)。
|
||||
- **`ctx` façade 不公开 `effect()`**:挂载代码无法注册定制 disposer;`on`/`provide`/`tools.register` 已覆盖目前出现的每项挂载,受保护的 `effect` 会等待真实需求(`FIXME(sandbox-effect)`)。
|
||||
- **`vmTimeoutMs` 只限制同步求值**:async 挂载主体可逃出该边界;挂载代码没有 async 预算。
|
||||
@@ -525,16 +525,16 @@ export const SERVICE_API: readonly ServiceApiEntry[] = [
|
||||
jsDoc: '/**\n * Load a header and balanced contiguous log. A complete interrupted final\n * turn is preserved and durably closed with missing tool errors plus any open\n * step and turn boundaries; only a torn final record is discarded. Unknown\n * versions and corruption in the committed prefix reject. Implementations\n * MUST NOT crash-repair an identity still bound to a live Session: a balanced\n * live log may return with its stored header as a durable snapshot, while an\n * open live turn rejects.\n * A coordinator-backed cold load reserves the identity across storage awaits,\n * so concurrent publication of a same-id live Session rejects.\n * @param id - the persisted session to reload.\n * @returns the header and a log ending on a balanced `turn/end`.\n */',
|
||||
},
|
||||
{
|
||||
signature: 'abstract inspect(id: SessionId): Promise<{ meta: SessionHeader; events: SessionEvent[] }>',
|
||||
jsDoc: '/**\n * Inspect a header and its valid contiguous stored prefix without repairing\n * a torn tail, closing an interrupted turn, or publishing coordinator state.\n * This read is serialized with writes for the same id and returns detached\n * values, so observers cannot mutate backend-owned state.\n * @param id - the persisted session to inspect.\n * @returns the header and valid stored event prefix exactly as observed.\n */',
|
||||
signature: 'abstract inspect(id: SessionId, signal?: AbortSignal): Promise<{ meta: SessionHeader; events: SessionEvent[] }>',
|
||||
jsDoc: '/**\n * Inspect a header and its valid contiguous stored prefix without repairing\n * a torn tail, closing an interrupted turn, or publishing coordinator state.\n * This read is serialized with writes for the same id and returns detached\n * values, so observers cannot mutate backend-owned state.\n * @param id - the persisted session to inspect.\n * @param signal - optional cancellation for queued and backend read work.\n * @returns the header and valid stored event prefix exactly as observed.\n */',
|
||||
},
|
||||
{
|
||||
signature: 'abstract list(): Promise<SessionHeader[]>',
|
||||
jsDoc: '/**\n * Lightweight listing from metadata, without a full-log parse.\n * @returns one header per materialized session.\n */',
|
||||
signature: 'abstract list(signal?: AbortSignal): Promise<SessionHeader[]>',
|
||||
jsDoc: '/**\n * Lightweight listing from metadata, without a full-log parse.\n * @param signal - optional cancellation for backend listing work.\n * @returns one header per materialized session.\n */',
|
||||
},
|
||||
{
|
||||
signature: 'abstract listSnapshots(): Promise<SessionPersistenceSnapshot[]>',
|
||||
jsDoc: '/**\n * List materialized sessions with cheap per-log change tokens.\n *\n * Repeated observations of an unchanged log return the same revision. A\n * successful mutating {@link load} repair changes the next listed revision.\n * Revisions also distinguish independently backed stores so backend-local\n * counters cannot compare equal across different persistence sources.\n * @returns one header and opaque revision per materialized session without loading full logs.\n */',
|
||||
signature: 'abstract listSnapshots(signal?: AbortSignal): Promise<SessionPersistenceSnapshot[]>',
|
||||
jsDoc: '/**\n * List materialized sessions with cheap per-log change tokens.\n *\n * Repeated observations of an unchanged log return the same revision. A\n * successful mutating {@link load} repair changes the next listed revision.\n * Revisions also distinguish independently backed stores so backend-local\n * counters cannot compare equal across different persistence sources.\n * @param signal - optional cancellation for backend snapshot-listing work.\n * @returns one header and opaque revision per materialized session without loading full logs.\n */',
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -547,24 +547,32 @@ export const SERVICE_API: readonly ServiceApiEntry[] = [
|
||||
jsDoc: '/**\n * Search the live-preferred logical corpus and group by session.\n * @param request - query text, metadata filters, page size, and cursor.\n * @param exec - optional cancellation control.\n * @returns session hits ranked by their strongest matching event.\n */',
|
||||
},
|
||||
{
|
||||
signature: 'abstract searchEvents( request: SessionEventSearchRequest, exec?: SessionSearchExecContext, ): Promise<SessionSearchPage<SessionEventSearchHit>>',
|
||||
jsDoc: '/**\n * Search events within one live-preferred logical session.\n * @param request - target session, query text, filters, page size, and cursor.\n * @param exec - optional cancellation control.\n * @returns matching event hits in deterministic relevance order.\n */',
|
||||
signature: 'abstract searchEvents( request: SessionEventSearchRequest, exec?: SessionSearchExecContext, ): Promise<SessionEventSearchPage>',
|
||||
jsDoc: '/**\n * Search events within one live-preferred logical session.\n * @param request - target session, query text, filters, page size, and cursor.\n * @param exec - optional cancellation control.\n * @returns matching event hits and their target header from one indexed generation.\n */',
|
||||
},
|
||||
{
|
||||
signature: 'listSessions(): Promise<SessionRecord[]>',
|
||||
jsDoc: '/**\n * List the complete logical corpus using live-preferred records.\n * @returns deterministic newest-first cloned session records.\n */',
|
||||
signature: 'listSessions(signal?: AbortSignal): Promise<SessionRecord[]>',
|
||||
jsDoc: '/**\n * List the complete logical corpus using live-preferred records.\n * @param signal - optional cancellation for persistence listing.\n * @returns deterministic newest-first cloned session records.\n */',
|
||||
},
|
||||
{
|
||||
signature: 'async readSession(sessionId: SessionId): Promise<SessionLogSnapshot>',
|
||||
jsDoc: '/**\n * Read and replay-validate one complete logical session log without making it live.\n * @param sessionId - live or persisted session id to read.\n * @returns cloned header and complete raw event log from one observation.\n * @throws when persistence, header compatibility, or replay validation fails.\n */',
|
||||
},
|
||||
{
|
||||
signature: 'async filterSessions(filters: readonly SessionResultFilter[]): Promise<SessionRecord[]>',
|
||||
jsDoc: '/**\n * Filter the complete logical corpus with provider-independent predicates.\n * @param filters - ANDed session metadata and availability clauses.\n * @returns matching cloned records in deterministic newest-first order.\n */',
|
||||
signature: 'async filterSessions( filters: readonly SessionResultFilter[], signal?: AbortSignal, ): Promise<SessionRecord[]>',
|
||||
jsDoc: '/**\n * Filter the complete logical corpus with provider-independent predicates.\n * @param filters - ANDed session metadata and availability clauses.\n * @param signal - optional cancellation for persistence listing.\n * @returns matching cloned records in deterministic newest-first order.\n */',
|
||||
},
|
||||
{
|
||||
signature: 'async readTitle(sessionId: SessionId): Promise<SessionTitleSnapshot | undefined>',
|
||||
jsDoc: '/**\n * Fold the latest log-backed title from one live-preferred logical session.\n * @param sessionId - live or persisted session id to read.\n * @returns latest title snapshot, or `undefined` when the log has no title event.\n */',
|
||||
signature: 'async readTitle( sessionId: SessionId, signal?: AbortSignal, ): Promise<SessionTitleSnapshot | undefined>',
|
||||
jsDoc: '/**\n * Fold the latest log-backed title from one live-preferred logical session.\n * @param sessionId - live or persisted session id to read.\n * @param signal - optional cancellation for source resolution and title folding.\n * @returns latest title snapshot, or `undefined` when the log has no title event.\n */',
|
||||
},
|
||||
{
|
||||
signature: 'async readTitleSnapshot( sessionId: SessionId, signal?: AbortSignal, ): Promise<SessionTitleObservation>',
|
||||
jsDoc: '/**\n * Fold the latest title and return its source header from one corpus observation.\n * @param sessionId - live or persisted session id to read.\n * @param signal - optional cancellation for source resolution and title folding.\n * @returns cloned source header and optional latest title snapshot.\n */',
|
||||
},
|
||||
{
|
||||
signature: 'async readTitleSnapshots( sessionIds: readonly SessionId[], signal?: AbortSignal, ): Promise<SessionTitleObservationResult[]>',
|
||||
jsDoc: '/**\n * Fold titles for unique sessions from one cancellable corpus observation.\n *\n * Results preserve first-occurrence input order. Operational failures stay\n * isolated per session, while cancellation rejects the complete operation.\n * @param sessionIds - live or persisted session ids to observe.\n * @param signal - optional cancellation shared by all source reads.\n * @returns one fulfilled or rejected result per unique requested id.\n */',
|
||||
},
|
||||
{
|
||||
signature: 'async listEvents(sessionId: SessionId): Promise<SessionEventRecord[]>',
|
||||
@@ -579,16 +587,16 @@ export const SERVICE_API: readonly ServiceApiEntry[] = [
|
||||
jsDoc: '/**\n * Read one session\'s complete current model surface from one corpus observation.\n * @param sessionId - live-preferred session id to read.\n * @returns cloned header, current surface, and raw-log capture boundary.\n * @throws when source resolution fails or the session surface is invalid.\n */',
|
||||
},
|
||||
{
|
||||
signature: 'async traceSession(sessionId: SessionId): Promise<SessionLineageTrace>',
|
||||
jsDoc: '/**\n * Trace known ancestry and descendants from one corpus observation.\n * @param sessionId - logical session id to trace.\n * @returns a complete lineage or an explicit unresolved parent boundary.\n * @throws when corpus resolution fails, the target is absent, or its known ancestry cycles.\n */',
|
||||
signature: 'async traceSession(sessionId: SessionId, signal?: AbortSignal): Promise<SessionLineageTrace>',
|
||||
jsDoc: '/**\n * Trace known ancestry and descendants from one corpus observation.\n * @param sessionId - logical session id to trace.\n * @param signal - optional cancellation for persistence listing.\n * @returns a complete lineage or an explicit unresolved parent boundary.\n * @throws when corpus resolution fails, the target is absent, or its known ancestry cycles.\n */',
|
||||
},
|
||||
{
|
||||
signature: 'async traceEvent(request: SessionEventTraceRequest): Promise<SessionEventTrace>',
|
||||
jsDoc: '/**\n * Trace one event\'s direct positional and provenance relationships.\n * @param request - target session id and event seq.\n * @returns direct links plus the target\'s positional replacement chain.\n * @throws when source resolution fails, the target is absent, or surface/provenance validation fails.\n */',
|
||||
signature: 'async traceEvent(request: SessionEventTraceRequest, signal?: AbortSignal): Promise<SessionEventTraceObservation>',
|
||||
jsDoc: '/**\n * Trace one event\'s direct positional and provenance relationships.\n * @param request - target session id and event seq.\n * @param signal - optional cancellation for persisted source resolution.\n * @returns source header, direct links, and the target\'s positional replacement chain.\n * @throws when source resolution fails, the target is absent, or surface/provenance validation fails.\n */',
|
||||
},
|
||||
{
|
||||
signature: 'async readEvent(request: SessionEventReadRequest): Promise<SessionEventWindow>',
|
||||
jsDoc: '/**\n * Read one full event plus a bounded raw-log context window.\n * @param request - target session/seq and context sizes.\n * @returns cloned target and neighboring events.\n */',
|
||||
signature: 'async readEvent(request: SessionEventReadRequest, signal?: AbortSignal): Promise<SessionEventWindow>',
|
||||
jsDoc: '/**\n * Read one full event plus a bounded raw-log context window.\n * @param request - target session/seq and context sizes.\n * @param signal - optional cancellation for persisted source resolution.\n * @returns cloned target and neighboring events.\n */',
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -712,6 +720,24 @@ export const SERVICE_API: readonly ServiceApiEntry[] = [
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
key: 'storageDomain',
|
||||
summary: 'The mounted domain facility.',
|
||||
methods: [
|
||||
{
|
||||
signature: 'async open<S extends DomainSpec>(spec: S): Promise<Domain<S>>',
|
||||
jsDoc: '/**\n * Open one declared domain. Steps, each failing the whole call: reject a\n * name that is already open (`already-open`); resolve the backend route\n * (`backend-not-found` passes through from the hub); require its `kv` facet\n * (`facet-unsupported`); open the unit projected from the spec (backend\n * `version-mismatch`/`malformed-medium` pass through); load and validate\n * every stored record against the spec\'s zod schemas (`invalid-record`\n * with the offending table and key); construct the domain.\n *\n * Lifecycle: the CALLER owns the returned handle and closes it via\n * `Domain.close()` (typically as its own `ctx.effect` disposer) — the\n * facility does not tie the domain to any consumer fiber. Domains still\n * open when the facility unmounts are closed by the plugin disposer.\n * @param spec - The domain declaration, typically from `defineDomain`.\n * @returns the opened domain handle, typed by the spec.\n */',
|
||||
},
|
||||
{
|
||||
signature: 'get(name: string): DomainImpl | undefined',
|
||||
jsDoc: '/**\n * Look up an open domain by name, untyped. Diagnostic surface (the package\n * invariant cross-checks change events against live domain state); typed\n * consumers hold the handle returned by {@link open}.\n * @param name - Domain name.\n * @returns the open domain runtime, or `undefined` when not open.\n */',
|
||||
},
|
||||
{
|
||||
signature: 'async closeAll(): Promise<void>',
|
||||
jsDoc: '/**\n * Close every domain still open on this facility. The unmount path for\n * consumers that never called `Domain.close()` themselves; closing is\n * idempotent, so double-closing an already-closed domain is harmless.\n * @returns resolution after every unit is released.\n */',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
key: 'subagents',
|
||||
summary: 'Named provider registry and capability-checked start surface.',
|
||||
@@ -918,23 +944,23 @@ export const SERVICE_API: readonly ServiceApiEntry[] = [
|
||||
},
|
||||
{
|
||||
key: 'workspace',
|
||||
summary: 'The workspace registry service.',
|
||||
summary: 'Durable workspace registry.',
|
||||
methods: [
|
||||
{
|
||||
signature: 'async create(path: string, title?: string): Promise<Workspace>',
|
||||
jsDoc: '/**\n * Create a workspace over an existing directory. The path is canonicalized\n * through `fs.realpath` first — a nonexistent path rejects with the\n * original `ENOENT`, a path resolving to anything but a directory rejects,\n * and a canonical path already owned by another workspace (including a\n * symlink resolving to it) rejects.\n * @param path - Directory the workspace points at; canonicalized before storing.\n * @param title - Display title; defaults to `basename` of the canonical path.\n * @returns the created workspace after durability.\n */',
|
||||
jsDoc: '/**\n * Create or reuse a workspace for an existing directory. The path is\n * canonicalized through `fs.realpath`; a nonexistent path rejects with the\n * original error and a non-directory rejects. Repeated calls for the same\n * canonical path return the existing entity without changing its title.\n * A newly created workspace is prepended to the durable registry order.\n * A different canonical path cannot create a duplicate display title.\n * @param path - Existing directory to own, in any path spelling.\n * @param title - Display title used only when a new record is created.\n * @returns the existing or newly durable workspace.\n */',
|
||||
},
|
||||
{
|
||||
signature: 'get(id: WorkspaceId): Workspace | undefined',
|
||||
jsDoc: '/**\n * Look up a workspace by id.\n * @param id - The workspace id.\n * @returns the workspace, or `undefined` when unknown.\n */',
|
||||
jsDoc: '/**\n * Look up a workspace by id.\n * @param id - Workspace id.\n * @returns the workspace, or `undefined` when unknown.\n */',
|
||||
},
|
||||
{
|
||||
signature: 'list(): Workspace[]',
|
||||
jsDoc: '/**\n * Snapshot of all workspaces, in load-then-creation order.\n * @returns a fresh array of the cached entities.\n */',
|
||||
jsDoc: '/**\n * Synchronous workspace projection in durable registry order. Every\n * entity\'s `sessionIds` getter is already filtered by the startup/live\n * canonical-cwd header index; this method performs no persistence reads.\n * @returns a fresh ordered array of workspace entities.\n */',
|
||||
},
|
||||
{
|
||||
signature: 'async resolveByPath(path: string): Promise<Workspace | undefined>',
|
||||
jsDoc: '/**\n * Resolve a workspace by directory path, through the same `fs.realpath`\n * canon as {@link create} (hence async). A path that does not exist rejects\n * with the original error — a missing directory has no canonical form to\n * compare (a workspace whose recorded directory vanished is only reachable\n * by id; see `Workspace.status`).\n * @param path - Directory path in any spelling (symlinks, `..`, trailing slash).\n * @returns the owning workspace, or `undefined` when none matches.\n */',
|
||||
jsDoc: '/**\n * Resolve by canonical directory path without creating or mutating a\n * workspace. A missing path rejects during `realpath`; an existing unowned\n * directory returns `undefined`.\n * @param path - Existing directory path in any spelling.\n * @returns the workspace owning the canonical path, when one exists.\n */',
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -1506,6 +1532,34 @@ export const TYPE_API: readonly TypeApiEntry[] = [
|
||||
name: 'DiffResultView',
|
||||
declaration: 'export interface DiffResultView {\n card: \'diff\';\n title?: string;\n diffs: FileDiff[];\n}',
|
||||
},
|
||||
{
|
||||
name: 'Domain',
|
||||
declaration: 'export interface Domain<S extends DomainSpec> {\n readonly name: string;\n readonly global: DomainGlobalHandleOf<S>;\n table<N extends keyof S[\'tables\'] & string>(name: N): KvTable<TableKeyOf<S, N>, TableValueOf<S, N>>;\n close(): Promise<void>;\n}',
|
||||
},
|
||||
{
|
||||
name: 'DomainGlobal',
|
||||
declaration: 'export interface DomainGlobal<G> {\n get(): G;\n set(value: G): Promise<void>;\n}',
|
||||
},
|
||||
{
|
||||
name: 'DomainGlobalHandleOf',
|
||||
declaration: 'export type DomainGlobalHandleOf<S extends DomainSpec> = S extends {\n readonly global: DomainGlobalSpec<infer G>;\n} ? DomainGlobal<G> : never;',
|
||||
},
|
||||
{
|
||||
name: 'DomainGlobalSpec',
|
||||
declaration: 'export interface DomainGlobalSpec<G> {\n readonly schema: ZodType<G>;\n readonly initial: G;\n}',
|
||||
},
|
||||
{
|
||||
name: 'DomainImpl',
|
||||
declaration: 'export class DomainImpl {\n readonly name: string;\n constructor(private readonly ctx: Context, spec: DomainSpec, private readonly unit: KvUnit, records: Map<string, Map<string, unknown>>, globalValue: unknown, private readonly onClosed: () => void);\n get global(): DomainGlobal<unknown>;\n table(name: string): KvTable<string, unknown>;\n close(): Promise<void>;\n}',
|
||||
},
|
||||
{
|
||||
name: 'DomainSpec',
|
||||
declaration: 'export interface DomainSpec {\n readonly name: string;\n readonly version: number;\n readonly global?: DomainGlobalSpec<unknown>;\n readonly tables: Record<string, DomainTableSpec>;\n}',
|
||||
},
|
||||
{
|
||||
name: 'DomainTableSpec',
|
||||
declaration: 'export interface DomainTableSpec<K extends string = string, V = unknown> {\n readonly valueSchema: ZodType<V>;\n readonly __key?: K;\n}',
|
||||
},
|
||||
{
|
||||
name: 'DshEnvironment',
|
||||
declaration: 'export type DshEnvironment = Readonly<Record<DshEnvironmentKey, string>>;',
|
||||
@@ -1650,6 +1704,14 @@ export const TYPE_API: readonly TypeApiEntry[] = [
|
||||
name: 'JsonValue',
|
||||
declaration: 'export type JsonValue = null | boolean | number | string | JsonValue[] | {\n [key: string]: JsonValue;\n};',
|
||||
},
|
||||
{
|
||||
name: 'KvTable',
|
||||
declaration: 'export interface KvTable<K extends string, V> {\n get(key: K): V | undefined;\n entries(): IterableIterator<[\n K,\n V\n ]>;\n keys(): IterableIterator<K>;\n readonly size: number;\n put(key: K, value: V): Promise<void>;\n delete(key: K): Promise<boolean>;\n update(key: K, fn: (current: V) => V): Promise<V>;\n}',
|
||||
},
|
||||
{
|
||||
name: 'KvUnit',
|
||||
declaration: 'export interface KvUnit {\n loadAll(): Promise<{\n tables: Record<string, Record<string, unknown>>;\n global: unknown;\n }>;\n putRecord(table: string, key: string, value: unknown): Promise<void>;\n deleteRecord(table: string, key: string): Promise<void>;\n setGlobal(value: unknown): Promise<void>;\n close(): Promise<void>;\n}',
|
||||
},
|
||||
{
|
||||
name: 'LlmAdapter',
|
||||
declaration: 'export abstract class LlmAdapter {\n providerInfo(provider: string): LlmProviderInfo;\n listModels(_provider: string): Promise<readonly LlmModelInfo[]>;\n resolveModelContext(_provider: string, _model: string): Promise<LlmModelContext | undefined>;\n abstract stream(options: GenerateOptions): AsyncIterable<StreamChunk>;\n}',
|
||||
@@ -1902,6 +1964,10 @@ export const TYPE_API: readonly TypeApiEntry[] = [
|
||||
name: 'SessionEventSearchHit',
|
||||
declaration: 'export interface SessionEventSearchHit extends SessionEventRecord {\n snippet: string;\n}',
|
||||
},
|
||||
{
|
||||
name: 'SessionEventSearchPage',
|
||||
declaration: 'export interface SessionEventSearchPage extends SessionSearchPage<SessionEventSearchHit> {\n session: SessionHeader;\n}',
|
||||
},
|
||||
{
|
||||
name: 'SessionEventSearchRequest',
|
||||
declaration: 'export interface SessionEventSearchRequest {\n sessionId: SessionId;\n query: string;\n filters?: readonly SessionEventMetadataFilter[];\n limit?: number;\n cursor?: SessionSearchCursor;\n}',
|
||||
@@ -1914,6 +1980,10 @@ export const TYPE_API: readonly TypeApiEntry[] = [
|
||||
name: 'SessionEventTrace',
|
||||
declaration: 'export interface SessionEventTrace {\n target: SessionEventRecord;\n replacedBy?: number;\n replacementChain: number[];\n replacedEventSeqs: number[];\n sourceEventSeqs: number[];\n derivedEventSeqs: number[];\n}',
|
||||
},
|
||||
{
|
||||
name: 'SessionEventTraceObservation',
|
||||
declaration: 'export interface SessionEventTraceObservation extends SessionEventTrace {\n session: SessionHeader;\n}',
|
||||
},
|
||||
{
|
||||
name: 'SessionEventTraceRequest',
|
||||
declaration: 'export interface SessionEventTraceRequest {\n sessionId: SessionId;\n seq: number;\n}',
|
||||
@@ -2022,6 +2092,14 @@ export const TYPE_API: readonly TypeApiEntry[] = [
|
||||
name: 'SessionTitleModelProvenance',
|
||||
declaration: 'export interface SessionTitleModelProvenance {\n readonly provider: string;\n readonly model: string;\n}',
|
||||
},
|
||||
{
|
||||
name: 'SessionTitleObservation',
|
||||
declaration: 'export interface SessionTitleObservation {\n session: SessionHeader;\n title?: SessionTitleSnapshot;\n}',
|
||||
},
|
||||
{
|
||||
name: 'SessionTitleObservationResult',
|
||||
declaration: 'export type SessionTitleObservationResult = {\n sessionId: SessionId;\n status: \'fulfilled\';\n value: SessionTitleObservation;\n} | {\n sessionId: SessionId;\n status: \'rejected\';\n reason: unknown;\n};',
|
||||
},
|
||||
{
|
||||
name: 'SessionTitleProvider',
|
||||
declaration: 'export interface SessionTitleProvider {\n readonly id: SessionTitleProviderId;\n readonly automatic: SessionTitleAutomaticMode;\n generate(request: SessionTitleProviderRequest): Promise<SessionTitleProviderResult>;\n}',
|
||||
@@ -2150,6 +2228,14 @@ export const TYPE_API: readonly TypeApiEntry[] = [
|
||||
name: 'SurfaceOp',
|
||||
declaration: 'export type SurfaceOp = \'append\' | {\n op: \'replace\';\n start: number;\n end: number;\n};',
|
||||
},
|
||||
{
|
||||
name: 'TableKeyOf',
|
||||
declaration: 'export type TableKeyOf<S extends DomainSpec, N extends keyof S[\'tables\']> = S[\'tables\'][N] extends DomainTableSpec<infer K> ? K : never;',
|
||||
},
|
||||
{
|
||||
name: 'TableValueOf',
|
||||
declaration: 'export type TableValueOf<S extends DomainSpec, N extends keyof S[\'tables\']> = S[\'tables\'][N] extends DomainTableSpec<string, infer V> ? V : never;',
|
||||
},
|
||||
{
|
||||
name: 'TaskDoneListener',
|
||||
declaration: 'export type TaskDoneListener = (snapshot: TaskSnapshot, owner: Agent | undefined) => void | PromiseLike<void>;',
|
||||
@@ -2448,7 +2534,7 @@ export const TYPE_API: readonly TypeApiEntry[] = [
|
||||
},
|
||||
{
|
||||
name: 'Workspace',
|
||||
declaration: 'export interface Workspace {\n readonly id: WorkspaceId;\n readonly path: string;\n readonly title: string;\n readonly sessionIds: readonly SessionId[];\n setTitle(title: string): Promise<void>;\n attachSession(sessionId: SessionId): Promise<void>;\n detachSession(sessionId: SessionId): Promise<void>;\n status(): Promise<\'ok\' | \'missing-dir\'>;\n}',
|
||||
declaration: 'export interface Workspace {\n readonly id: WorkspaceId;\n readonly path: string;\n readonly title: string;\n readonly createdAt: string;\n readonly updatedAt: string;\n readonly sessionIds: readonly SessionId[];\n setTitle(title: string): Promise<void>;\n attachSession(sessionId: SessionId): Promise<void>;\n insertSessionBefore(sessionId: SessionId, beforeSessionId?: SessionId): Promise<void>;\n detachSession(sessionId: SessionId): Promise<void>;\n status(): Promise<\'ok\' | \'missing-dir\'>;\n}',
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user