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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.i18n.yaml CHANGED
@@ -2,5 +2,5 @@
2
2
  # side as of the last confirmed-consistent state. Both languages carry equal authority;
3
3
  # after editing either side, bring the other along and re-record with:
4
4
  # pnpm run verify-translation-pairing --write packages/shell/shell/README.md
5
- README.md: a15980ead797a73c18dd6d8825a4b38cf845df60
6
- README.zh.md: 008b19835697d5d9514cf5472696852cfc684acd
5
+ README.md: 1400947fc7cda0d45a050e45008356aebbd33776
6
+ README.zh.md: bde496672866bb182f883d0fe0d8d793624cfa49
package/README.md CHANGED
@@ -1,44 +1,116 @@
1
+ ---
2
+ description: "The bash executor seam for developers and maintainers choosing, composing, or implementing command execution over ctx.shell."
3
+ kind: "package-reference"
4
+ ---
5
+
1
6
  # @deepseek-ai/dsh-shell
2
7
 
3
8
  English | [中文](README.zh.md)
4
9
 
5
- The **`ShellExecutor`** (`ctx.shell`) defines WHAT a bash backend does — run foreground commands and start background processes — without saying HOW. Job ids, ownership, collection, cancellation, and notices belong to the generic `ctx.jobs` runtime.
10
+ ## Summary
6
11
 
7
- This package owns the Service Definition role of the bash capability, split so each role can evolve (and be swapped) independently:
12
+ `dsh-shell` defines the executor service (`ctx.shell`) that runs shell commands for the harness: foreground commands that resolve with bounded output when they finish, and background processes that return a handle immediately. Every shell executor in the repository — local Bash, sandboxed Bash, local PowerShell, sandboxed PowerShell — implements this one contract, so the model-facing `bash` and `pwsh` tools work unchanged over any of them. Callers pass a request and receive a fully-resolved spec with explicit defaults and caps before any command runs. The service itself never renders anything to a model; the shell tools own all model-visible output and sandbox guidance.
8
13
 
9
- | Package | Role |
10
- |---|---|
11
- | `@deepseek-ai/dsh-shell` (this) | Service Definition: abstract service + vocabulary types |
12
- | `@deepseek-ai/dsh-bash-local` | Service Provider: local subprocesses |
13
- | `@deepseek-ai/dsh-bash-sandbox` | Service Provider: `dsh-bash-local`'s mechanics with every spawn confined via [`ctx.sandbox`](../../sandbox/sandbox/), denials reported as result facts |
14
- | `@deepseek-ai/dsh-tool-bash` | the model-facing tool schemas over `ctx.shell` |
14
+ ## Table of Contents
15
+
16
+ - [Use this package](#use-this-package)
17
+ - [Understand the implementation](#understand-the-implementation)
18
+ - [Further Exploration](#further-exploration)
19
+ - [Model Experience](#model-experience)
20
+ - [Known Limitations and Deferred Work](#known-limitations-and-deferred-work)
21
+ - [Dev Note](#dev-note)
22
+
23
+ -----
24
+
25
+ <a id="use-this-package"></a>
26
+ ## Use this package
27
+
28
+ Use `ctx.shell` when an agent or an in-process plugin needs to run a shell command and read its output, or start a background process and poll it. It is the contract every shell executor and the model-facing `bash`/`pwsh` tools build on, so code written against it works over any executor implementation.
29
+
30
+ ### Foreground commands
31
+
32
+ Call `run` with a resolved spec to execute a command in the foreground. The promise resolves when the command finishes: a nonzero exit, an executor timeout kill, or a caller abort kill is a result, never a rejection. `run` rejects only for infrastructure failures such as an unusable working directory or a missing shell. The result carries the exit code or signal, whether a timeout or an abort cut the run short, and the collected stdout/stderr with spill-file paths when a stream overflowed its budget.
33
+
34
+ ```text
35
+ const result = await ctx.shell.run(ctx.shell.resolve({ command: 'ls -la' }))
36
+ console.log(result.exitCode, result.stdout.text)
37
+ ```
38
+
39
+ ### Background processes
40
+
41
+ Call `start` with a resolved spec to launch a background process; it returns a handle immediately and no timeout applies. Read output incrementally with `readOutput()` — consecutive reads never repeat output, and lossy reads point at full-stream spill files. Kill the process group with `kill()` (returns `false` once it has finished) and await `done` for settlement. Job ids, ownership, polling, and notices belong to the generic `ctx.jobs` runtime, where the tool layer registers the handle.
42
+
43
+ ### Requests and resolved specs
44
+
45
+ Every execution starts from a `ShellExecRequest` with optional fields; the executor's `resolve()` turns it into a fully-resolved `ShellExecSpec` with explicit defaults and caps before anything runs. This request/spec split is the repository's template for explicit resolution at package boundaries: callers never rely on hidden defaults inside `run` or `start`. `resolve()` fills the working directory and timeout from the executor's configuration, caps per-call overrides, and carries optional inputs — `stdin`, ordinary `env`, and the trusted `DSH_*` snapshot — through verbatim.
46
+
47
+ ### Choosing and composing an executor
48
+
49
+ The seam is not an executor: mount exactly one provider per composition, and the tools work unchanged. On POSIX, `dsh-bash-local` runs commands as fresh `bash -c` processes and `dsh-bash-sandbox` confines every command through the sandbox capability; on Windows, `dsh-pwsh-local` and `dsh-pwsh-sandbox` are the counterparts. The `bash` and `pwsh` tools advertise escalation fields only while a sandboxing executor is mounted. The smallest composition is the executor alone:
50
+
51
+ ```yaml
52
+ - id: bash
53
+ name: '@deepseek-ai/dsh-bash-local'
54
+ config:
55
+ cwd: /path/to/workspace
56
+ ```
57
+
58
+ ### The shared exit-status contract
15
59
 
16
- The split is a standard capability seam ([capability-seams Agent Note](../../../.agents/notes/implemented/architecture/2026-06-13-capability-seams.md)): `dsh-bash-sandbox` is a sandboxing executor behind the same Service Definition the Consumer detects its `sandboxMode` capability and adds escalation fields without importing the provider and a containerized or remote executor slots in the same way.
60
+ Tool results end with a machine-readable exit marker — `[exit code: N]` or `[killed by signal: X]` so the model can always tell how a command ended. The seam owns that marker format and the `parseExitStatus` helper that splits a rendered result back into its output body and structured exit status, keeping the `bash` and `pwsh` tools from drifting on it.
17
61
 
18
- ## Service API (`ctx.shell`)
62
+ -----
19
63
 
20
- | Member | Semantics |
64
+ <a id="understand-the-implementation"></a>
65
+ ## Understand the implementation
66
+
67
+ <details>
68
+ <summary>Implementation internals — click to expand</summary>
69
+
70
+ This section explains the design of the seam and points at the code that realizes it; the observable behavior is fully covered in [Use this package](#use-this-package).
71
+
72
+ ### Design philosophy
73
+
74
+ The package is one role of a standard capability seam: the Service Definition that names the executor contract, with Service Providers and Consumers split so each role evolves independently (see the [capability-seams note](../../../.agents/notes/implemented/architecture/2026-06-13-capability-seams.md)). Two decisions anchor the contract:
75
+
76
+ - **Explicit resolution at the boundary.** `resolve(request)` is the single place defaults and caps are applied; `run` and `start` accept only resolved specs and never re-default, so no hidden fallback lives inside an implementation.
77
+ - **Task-free background handles.** `start` returns a `ShellProcess` with no id or owner; job identity, ownership, and lifecycle belong to the generic `ctx.jobs` runtime, keeping executors independent of sessions.
78
+
79
+ ### Source map
80
+
81
+ | File | Role |
21
82
  |---|---|
22
- | `run(spec)` | Foreground execution. Resolves when the command finishes. **Rejects only for infrastructure failures** (unusable workdir, missing shell, pre-aborted signal); nonzero exits, timeout kills, and abort kills resolve with a descriptive `ShellRunResult`. |
23
- | `start(spec)` | Background execution. Returns a task-free `ShellProcess` handle immediately; **no timeout applies**. The caller may adapt it into `ctx.jobs`. |
24
- | `sandboxMode` | The capability fact for the tool layer: the default mode a SANDBOXING executor confines under (`undefined` in the base class — "this executor does not sandbox"). `dsh-tool-bash` reads it at registration to advertise the escalation fields only when the composition honors them. |
25
- | `ShellProcess.readOutput()` | **Incremental** output read consecutive reads never re-deliver. Reads that lost data to buffer bounds flag `lossy` and point at full-stream spill files. |
26
- | `ShellProcess.kill()` | Kill the process group. Returns `false` when it already finished. |
83
+ | [`src/index.ts`](src/index.ts) | Plugin entry: abstract `ShellExecutor` service and the shared settings namespace |
84
+ | [`src/types.ts`](src/types.ts) | Request/spec vocabulary, `ShellRunResult`, `ShellProcess`, and sandbox facts |
85
+ | [`src/render.ts`](src/render.ts) | `parseExitStatus`: the exit-status marker contract the shell tools share |
86
+ | [`src/invariant.ts`](src/invariant.ts) | Invariant companion (no runtime invariant; executors and policy own observations) |
87
+
88
+ ### Settings namespace
89
+
90
+ `SHELL_SETTINGS_NAMESPACE` is exported here rather than by a provider because it names the capability, not an implementation: a host composes exactly one provider of `ctx.shell`, so the providers share one namespace without colliding, and a settings document carried between platforms keeps resolving on both.
27
91
 
28
- Implementations subclass `ShellExecutor` and implement the abstract methods. Disposal must kill every running process and await its exit.
92
+ ### Background lifecycle and ownership
29
93
 
30
- `SHELL_SETTINGS_NAMESPACE` (`bash`) is exported here rather than by a provider because it names the capability, not an implementation. A host composes exactly one provider of `ctx.shell` — the win32 layer swaps the POSIX rows for the pwsh ones, and mounting both fails loud on a duplicate service registration so every provider can register this one namespace with its own schema and composition entry without two of them ever colliding, and a `settings.yaml` carried between platforms keeps resolving on both.
94
+ A background process belongs to the subprocess service, not to the executor: it survives an executor-only reload and is killed and joined when the composition tears down. Implementations must honor the seam's semantics `run` rejects only for infrastructure failures; `start` returns immediately with no timeout and its `done` never rejects (spawn failures settle as `killed` with the error on stderr); `readOutput` is consuming and lossy reads report spill files.
31
95
 
32
- ## Vocabulary
96
+ </details>
33
97
 
34
- `ShellExecRequest` (command, workdir?, timeoutMs?, stdoutMaxBytes?, signal?, stdin?, env?, dshEnv?, sandboxPolicy?) resolves to `ShellExecSpec` (command, workdir, timeoutMs, stdoutMaxBytes, signal?, stdin?, env?, dshEnv?, sandboxPolicy) before execution. `stdoutMaxBytes` is a trusted foreground-run capture budget for consumers that must parse complete bounded stdout; the model-facing bash tool does not expose it. `sandboxPolicy` is optional on the request and required-but-nullable on the resolved spec: it carries the complete per-call mode and workspace root. The sandbox tool path resolves it from the calling session through `ctx.sandboxPolicy`; a direct sandbox-executor caller falls back to deployment policy, while a non-sandboxing executor carries the field and confines nothing.
98
+ -----
35
99
 
36
- The per-session sandbox-mode override vocabulary (the `'sandbox/mode'` event, the `effectiveSandboxMode(events)` fold, and the `setSandboxMode(session, mode)` write path) is NOT here — it is policy state shared by every enforcing family, owned by [`@deepseek-ai/dsh-sandbox-policy`](../../sandbox/sandbox-policy/). `run()` returns `ShellRunResult`; `start()` returns `ShellProcess`, whose incremental read and kill methods are adapted by `dsh-tool-bash` into a generic task registration. A sandboxing executor stamps `ShellSandboxInfo` on foreground results and settled process handles. See `src/types.ts` and [subsystems/shell.md](../../../docs/subsystems/shell.md).
100
+ <a id="further-exploration"></a>
101
+ ## Further Exploration
37
102
 
38
- `stdin` and ordinary `env` are set by in-process plugins (the hooks bridges, native plugins) to feed a hook command its JSON payload and `CLAUDE_PROJECT_DIR`/`CLAUDE_PLUGIN_ROOT` values. `dshEnv` is a separate trusted overlay restricted by type to managed keys; the exported `DSH_ENV_PREFIX` is the single source for that namespace, its `DshEnvironmentKey` template type, executor scrubbing, registry validation, derived built-in names, and model guidance. Model bash uses the current snapshot collected by `ctx.shellEnv`. Implementations remove inherited managed keys, then merge `dshEnv` after ordinary `env`, so an omitted current fact cannot fall back to stale ambient state and an `env` entry cannot displace a managed value. The model-facing tool exposes none of these as parameters. All three remain optional on the resolved spec; absent means no input/overlay. See [the bash-stdin-env Agent Note](../../../.agents/notes/implemented/architecture/2026-06-30-bash-stdin-env-trusted-plugin-api.md) and [the session environment Agent Note](../../../.agents/notes/implemented/feature/2026-07-10-agent-session-identity-and-log-location.md).
103
+ Read these pages when the seam contract is not enough. They move from the shared subsystem reference to the concrete executors and the model-facing tools.
39
104
 
40
- The exported `parseExitStatus` (with `ParsedExitStatus`) is the shared rendering contract half of the shell tools: the inverse of the `[exit code: N]` / `[killed by signal: X]` markers `dsh-tool-bash`'s `renderResult` and `dsh-tool-pwsh`'s `renderPwshResult` append. Both tools' `presentResult` use it to split the rendered text into the terminal card's output body and its exit-status pill; it lives with the Service Definition so the two tools never drift on the marker contract.
105
+ - [Bash executor subsystem](../../../docs/subsystems/shell.md) the request/spec vocabulary, results, and service contract in full.
106
+ - [bash-local](../bash-local/README.md) — the default POSIX executor: fresh `bash -c` processes, budgets, and deadlines.
107
+ - [bash-sandbox](../bash-sandbox/README.md) — the confining executor: sandbox modes, denials, and escalation.
108
+ - [tool-bash](../tool-bash/README.md) — the model-facing `bash` tool over this seam.
109
+ - [Capability seams note](../../../.agents/notes/implemented/architecture/2026-06-13-capability-seams.md) — the Service Definition / Provider / Consumer split this seam follows.
41
110
 
111
+ -----
112
+
113
+ <a id="model-experience"></a>
42
114
  ## Model Experience
43
115
 
44
116
  Indirectly, through `dsh-tool-bash`, which turns executor output and sandbox facts into guidance and retained tool-result tokens.
@@ -49,5 +121,20 @@ No direct invalidation; the named consumer owns any request-prefix changes.
49
121
 
50
122
  ## Known Limitations and Deferred Work
51
123
 
124
+ <a id="known-limitations-and-deferred-work"></a>
125
+
126
+
127
+ These limits define what the seam does not provide. They are current package constraints, not a roadmap.
128
+
52
129
  - **No interactive-input vocabulary** — `stdin` is written once at spawn and closed; the seam has no channel to feed a running task and no PTY session concept.
53
- - **Foreground timeouts are always executor-owned** — a caller-owned-deadline mode on the seam is explicitly deferred by [the tool-call timeout-policy Agent Note](../../../.agents/notes/implemented/architecture/2026-07-07-tool-call-timeout-policy.md).
130
+ - **Foreground timeouts are always executor-owned** — a caller-owned-deadline mode on the seam is explicitly deferred by the [tool-call timeout-policy note](../../../.agents/notes/implemented/architecture/2026-07-07-tool-call-timeout-policy.md).
131
+
132
+ <a id="dev-note"></a>
133
+ ### Dev Note
134
+
135
+ <details>
136
+ <summary>Working context for maintainers — click to expand</summary>
137
+
138
+ None.
139
+
140
+ </details>
package/README.zh.md CHANGED
@@ -1,53 +1,140 @@
1
+ ---
2
+ description: "面向开发者与维护者的 bash 执行器 seam 说明,用于选择、组合或实现基于 ctx.shell 的命令执行。"
3
+ kind: "package-reference"
4
+ ---
5
+
1
6
  # @deepseek-ai/dsh-shell
2
7
 
3
8
  [English](README.md) | 中文
4
9
 
5
- **`ShellExecutor`**(`ctx.shell`)定义 bash 后端做什么,即运行前台命令与启动后台进程,但不规定如何实现。job id、所有权、收集、取消与通知属于通用 `ctx.jobs` 运行时。
10
+ ## 概述
6
11
 
7
- 本包承担 bash 能力的 Service Definition 角色,各角色因此可以独立演进(和替换):
12
+ `dsh-shell` 定义运行 shell 命令的执行器服务(`ctx.shell`):前台命令在结束时以有界输出 resolve,后台进程则立即返回句柄。仓库中的每个 shell 执行器——本地 Bash、沙箱 Bash、本地 PowerShell、沙箱 PowerShell——都实现这同一个约定,因此面向模型的 `bash` `pwsh` 工具在任何一个之上都能不加改动地工作。调用方先提交请求,再在任何命令运行前拿到一份默认值与上限都已显式填好的 spec。该服务本身从不向模型渲染任何内容;所有模型可见的输出与沙箱指引都归 shell 工具所有。
8
13
 
9
- | 包 | 职责 |
10
- |---|---|
11
- | `@deepseek-ai/dsh-shell`(本包) | Service Definition:抽象服务 + 词汇类型 |
12
- | `@deepseek-ai/dsh-bash-local` | Service Provider:本地子进程 |
13
- | `@deepseek-ai/dsh-bash-sandbox` | Service Provider:沿用 `dsh-bash-local` 的机制,但通过 [`ctx.sandbox`](../../sandbox/sandbox/) 限制每次 spawn,并将拒绝报告为结果事实 |
14
- | `@deepseek-ai/dsh-tool-bash` | 基于 `ctx.shell`、面向模型的工具 schema |
14
+ ## 目录
15
+
16
+ - [使用本包](#use-this-package)
17
+ - [理解实现](#understand-the-implementation)
18
+ - [进一步探索](#further-exploration)
19
+ - [模型体验](#model-experience)
20
+ - [已知限制与延期工作](#known-limitations-and-deferred-work)
21
+ - [开发备注](#dev-note)
22
+
23
+ -----
24
+
25
+ <a id="use-this-package"></a>
26
+ ## 使用本包
27
+
28
+ 当 agent 或进程内插件需要运行 shell 命令并读取输出,或启动后台进程并轮询它时,使用 `ctx.shell`。它是每个 shell 执行器与面向模型的 `bash`/`pwsh` 工具共同依赖的约定,因此基于它编写的代码可以运行在任意执行器实现之上。
29
+
30
+ ### 前台命令
31
+
32
+ 用已解析的 spec 调用 `run` 即可在前台执行命令。promise 在命令结束时 resolve:非零退出、执行器超时终止或调用方中止终止都是结果,绝不是 rejection。`run` 只在基础设施失败时 reject,例如工作目录不可用或缺少 shell。结果携带退出码或信号、是超时还是中止截断了运行,以及收集到的 stdout/stderr;流超出预算时还附带 spill 文件路径。
33
+
34
+ ```text
35
+ const result = await ctx.shell.run(ctx.shell.resolve({ command: 'ls -la' }))
36
+ console.log(result.exitCode, result.stdout.text)
37
+ ```
38
+
39
+ ### 后台进程
40
+
41
+ 用已解析的 spec 调用 `start` 即可启动后台进程;它会立即返回句柄,且不应用任何超时。用 `readOutput()` 增量读取输出——连续读取绝不会重复交付,有损读取会指向完整流的 spill 文件。用 `kill()` 终止进程组(进程结束后返回 `false`),并等待 `done` 结算。job id、所有权、轮询与通知属于通用 `ctx.jobs` 运行时,工具层会把句柄注册进去。
42
+
43
+ ### 请求与已解析 spec
44
+
45
+ 每次执行都从带可选字段的 `ShellExecRequest` 开始;执行器的 `resolve()` 在任何东西运行之前,把它变成默认值与上限都已显式填好的 `ShellExecSpec`。这一请求/spec 拆分正是仓库在包边界显式解析的模板:调用方绝不依赖 `run` 或 `start` 内部隐藏的默认值。`resolve()` 从执行器配置填充工作目录与超时、对每次调用的覆盖值设上限,并按原样携带可选输入——`stdin`、普通 `env` 与受信任的 `DSH_*` 快照。
46
+
47
+ ### 选择并组合一个执行器
48
+
49
+ seam 本身不是执行器:每个组合只挂载一个提供方,工具即可不加改动地工作。在 POSIX 上,`dsh-bash-local` 以全新的 `bash -c` 进程运行命令,`dsh-bash-sandbox` 则通过沙箱能力限制每条命令;在 Windows 上,对应实现是 `dsh-pwsh-local` 与 `dsh-pwsh-sandbox`。`bash` 与 `pwsh` 工具只在挂载沙箱执行器时公布升权字段。最小的组合只需执行器本身:
50
+
51
+ ```yaml
52
+ - id: bash
53
+ name: '@deepseek-ai/dsh-bash-local'
54
+ config:
55
+ cwd: /path/to/workspace
56
+ ```
57
+
58
+ ### 共享的退出状态约定
15
59
 
16
- 该拆分是一个标准的能力 seam([capability-seams Agent Note](../../../.agents/notes/implemented/architecture/2026-06-13-capability-seams.zh.md)):`dsh-bash-sandbox` 是位于同一 Service Definition 之后的沙箱执行器——Consumer 检测其 `sandboxMode` 能力并添加升权字段,无需导入提供方——容器化或远程执行器也可以同样接入。
60
+ 工具结果以机器可读的退出标记结尾——`[exit code: N]` `[killed by signal: X]`——模型因此总能知道命令如何结束。seam 拥有该标记格式,以及把渲染结果拆回输出正文与结构化退出状态的 `parseExitStatus` 辅助函数,使 `bash` 与 `pwsh` 两个工具永远不会在此漂移。
17
61
 
18
- ## 服务 API(`ctx.shell`)
62
+ -----
19
63
 
20
- | 成员 | 语义 |
64
+ <a id="understand-the-implementation"></a>
65
+ ## 理解实现
66
+
67
+ <details>
68
+ <summary>实现细节——点击展开</summary>
69
+
70
+ 本节解释 seam 的设计并指出实现它们的代码位置;可观察行为已在[使用本包](#use-this-package)中完整说明。
71
+
72
+ ### 设计理念
73
+
74
+ 本包是标准能力 seam 中的一个角色:命名执行器约定的 Service Definition,Service Provider 与 Consumer 各自拆分,使每个角色都能独立演进(见[能力 seam 笔记](../../../.agents/notes/implemented/architecture/2026-06-13-capability-seams.zh.md))。两项决策锚定了该约定:
75
+
76
+ - **边界处的显式解析。** `resolve(request)` 是应用默认值与上限的唯一位置;`run` 与 `start` 只接受已解析的 spec,绝不再次默认化,因此实现内部不会藏有隐藏的兜底值。
77
+ - **无任务语义的后台句柄。** `start` 返回不带 id 或所有者的 `ShellProcess`;job 身份、所有权与生命周期属于通用 `ctx.jobs` 运行时,使执行器与会话保持独立。
78
+
79
+ ### 源码地图
80
+
81
+ | 文件 | 职责 |
21
82
  |---|---|
22
- | `run(spec)` | 前台执行。命令完成时 resolve。**只会因基础设施失败而 reject**(工作目录不可用、shell 缺失、信号已在调用前中止);非零退出、超时终止和中止导致的终止都会 resolve 为描述性 `ShellRunResult`。 |
23
- | `start(spec)` | 后台执行。立即返回不含任务语义的 `ShellProcess` 句柄;**不应用超时**。调用方可以将其适配到 `ctx.jobs`。 |
24
- | `sandboxMode` | 工具层的能力事实:沙箱执行器用于限制执行的默认模式(基类中为 `undefined`,即「此执行器不使用沙箱」)。`dsh-tool-bash` 会在注册时读取它,仅当组合确实支持升权字段时才公布这些字段。 |
25
- | `ShellProcess.readOutput()` | **增量** 读取输出:连续读取绝不会重复交付。因缓冲区容量限制而丢失数据的读取会标记 `lossy`,并指向完整流 spill 文件。 |
26
- | `ShellProcess.kill()` | 终止进程组。如果进程已结束,返回 `false`。 |
83
+ | [`src/index.ts`](src/index.ts) | 插件入口:抽象 `ShellExecutor` 服务与共享设置命名空间 |
84
+ | [`src/types.ts`](src/types.ts) | 请求/spec 词汇、`ShellRunResult`、`ShellProcess` 与沙箱事实 |
85
+ | [`src/render.ts`](src/render.ts) | `parseExitStatus`:shell 工具共享的退出状态标记约定 |
86
+ | [`src/invariant.ts`](src/invariant.ts) | 不变式伴生插件(无运行时不变式;执行器与策略负责观察) |
87
+
88
+ ### 设置命名空间
89
+
90
+ `SHELL_SETTINGS_NAMESPACE` 由此处导出而非由某个提供方导出,因为它命名的是能力而不是实现:一个宿主只组装一个 `ctx.shell` 提供方,因此各提供方共享同一个命名空间而永不冲突,在平台间携带的设置文档也能在两边继续解析。
27
91
 
28
- 实现会继承 `ShellExecutor` 并实现抽象方法。dispose(资源释放)必须终止每个运行中的进程并等待其退出。
92
+ ### 后台生命周期与归属
29
93
 
30
- `SHELL_SETTINGS_NAMESPACE`(`bash`)由此处导出而非由某个提供方导出,因为它命名的是能力而不是实现。一个宿主只组装一个 `ctx.shell` 提供方——win32 层会把 POSIX 行换成 pwsh 行,同时挂载两者会因服务重复注册而在加载期失败——所以每个提供方都能用自己的 schema 与组装条目注册这同一个命名空间,两者永不相撞;在平台间携带的 `settings.yaml` 也能在两边继续解析。
94
+ 后台进程属于 subprocess 服务而非执行器:它能在仅重载执行器后存活,并在组合拆解时被终止并 join。实现必须遵守 seam 的语义——`run` 只在基础设施失败时 reject;`start` 立即返回且不设超时,其 `done` 绝不 reject(spawn 失败以 `killed` 结算,错误进入 stderr);`readOutput` 是消费式的,有损读取会报告 spill 文件。
31
95
 
32
- ## 词汇
96
+ </details>
33
97
 
34
- `ShellExecRequest`(command、workdir?、timeoutMs?、stdoutMaxBytes?、signal?、stdin?、env?、dshEnv?、sandboxPolicy?)在执行前解析为 `ShellExecSpec`(command、workdir、timeoutMs、stdoutMaxBytes、signal?、stdin?、env?、dshEnv?、sandboxPolicy)。`stdoutMaxBytes` 是受信任前台运行的捕获预算,用于必须解析完整有界 stdout 的消费方;面向模型的 bash 工具不公开该字段。`sandboxPolicy` 在请求上可选,在已解析 spec 上必填但可为 null:它携带完整的每次调用模式与工作区根目录。沙箱工具路径通过 `ctx.sandboxPolicy` 从调用会话解析它;沙箱执行器的直接调用方回退到部署策略,非沙箱执行器则携带该字段但不作限制。
98
+ -----
35
99
 
36
- 每会话沙箱模式覆盖词汇(`'sandbox/mode'` 事件、`effectiveSandboxMode(events)` fold 以及 `setSandboxMode(session, mode)` 写入路径)不位于此处。它是所有强制执行家族共享的策略状态,属于 [`@deepseek-ai/dsh-sandbox-policy`](../../sandbox/sandbox-policy/)。`run()` 返回 `ShellRunResult`;`start()` 返回 `ShellProcess`,其增量读取与终止方法由 `dsh-tool-bash` 适配为通用任务注册。沙箱执行器会在前台结果与已结算进程句柄上标记 `ShellSandboxInfo`。详见 `src/types.ts` 与 [subsystems/shell.md](../../../docs/subsystems/shell.zh.md)。
100
+ <a id="further-exploration"></a>
101
+ ## 进一步探索
37
102
 
38
- `stdin` 与普通 `env` 由同进程插件(hooks 桥接、原生插件)设置,用于向 hook 命令提供其 JSON payload 和 `CLAUDE_PROJECT_DIR`/`CLAUDE_PLUGIN_ROOT` 值。`dshEnv` 是受类型限制、仅允许受管 key 的独立受信任 overlay;导出的 `DSH_ENV_PREFIX` 是该 namespace、其 `DshEnvironmentKey` 模板类型、执行器清理、注册表验证、派生内置名称与模型指引的统一来源。模型 bash 使用 `ctx.shellEnv` 收集的当前快照。实现会移除继承的受管 key,再在普通 `env` 之后合并 `dshEnv`,因此省略的当前事实不会回退到陈旧环境状态,`env` 条目也无法顶掉受管值。面向模型的工具不将这三者中的任何一个公开为参数。这三者在已解析 spec 上仍然可选;缺失表示没有输入/overlay。详见 [bash-stdin-env Agent Note](../../../.agents/notes/implemented/architecture/2026-06-30-bash-stdin-env-trusted-plugin-api.zh.md) 与 [会话环境 Agent Note](../../../.agents/notes/implemented/feature/2026-07-10-agent-session-identity-and-log-location.zh.md)。
103
+ seam 约定不够用时阅读以下页面。它们从共享子系统参考逐步进入具体执行器与面向模型的工具。
39
104
 
40
- 导出的 `parseExitStatus`(连同 `ParsedExitStatus`)是 shell 工具共享渲染约定的另一半:`dsh-tool-bash` 的 `renderResult` 与 `dsh-tool-pwsh` 的 `renderPwshResult` 追加的 `[exit code: N]`/`[killed by signal: X]` marker 的逆解析。两个工具的 `presentResult` 都用它把渲染文本拆成 terminal 卡的输出正文与其退出状态 pill;它放在 Service Definition 中,两个工具便永远不会在 marker 约定上漂移。
105
+ - [Bash 执行器子系统](../../../docs/subsystems/shell.zh.md) —— 请求/spec 词汇、结果与完整的服务约定。
106
+ - [bash-local](../bash-local/README.zh.md) —— 默认 POSIX 执行器:全新的 `bash -c` 进程、预算与 deadline。
107
+ - [bash-sandbox](../bash-sandbox/README.zh.md) —— 受限执行器:沙箱模式、拒绝与升权。
108
+ - [tool-bash](../tool-bash/README.zh.md) —— 基于该 seam 的面向模型 `bash` 工具。
109
+ - [能力 seam 笔记](../../../.agents/notes/implemented/architecture/2026-06-13-capability-seams.zh.md) —— 本 seam 遵循的 Service Definition / Provider / Consumer 拆分。
41
110
 
111
+ -----
112
+
113
+ <a id="model-experience"></a>
42
114
  ## 模型体验
43
115
 
44
116
  通过 `dsh-tool-bash` 间接影响;该工具会将执行器输出与沙箱事实转为指引和保留的工具结果 token。
45
117
 
46
118
  #### KV Cache 影响
47
119
 
48
- 不会直接导致 KV Cache 失效;请求前缀变更由具名消费方负责。
120
+ 不会直接导致 KV Cache 失效;请求前缀的任何变更由具名消费方负责。
121
+
122
+ ## 已知限制与延期工作
123
+
124
+ <a id="known-limitations-and-deferred-work"></a>
125
+
126
+
127
+ 这些限制说明该 seam 不提供什么。它们是当前包约束,不是路线图。
128
+
129
+ - **没有交互式输入词汇**——`stdin` 只在 spawn 时写入一次并关闭;seam 没有向运行中任务继续输入的通道,也没有 PTY 会话概念。
130
+ - **前台超时始终由执行器负责**——seam 上由调用方负责 deadline 的模式已由[工具调用超时策略笔记](../../../.agents/notes/implemented/architecture/2026-07-07-tool-call-timeout-policy.zh.md)明确延期。
131
+
132
+ <a id="dev-note"></a>
133
+ ### 开发备注
134
+
135
+ <details>
136
+ <summary>维护者的工作上下文——点击展开</summary>
49
137
 
50
- ## 已知限制与暂缓事项
138
+ None.
51
139
 
52
- - **没有交互式输入词汇**:`stdin` 只会在 spawn 时写入一次并关闭;seam 不提供向运行中任务继续输入的通道,也没有 PTY 会话概念。
53
- - **前台超时始终由执行器负责**:seam 上由调用方负责 deadline 的模式已由 [工具调用超时策略 Agent Note](../../../.agents/notes/implemented/architecture/2026-07-07-tool-call-timeout-policy.zh.md) 明确暂缓。
140
+ </details>
package/lib/index.js CHANGED
@@ -1,11 +1,11 @@
1
1
  import { Service } from "@deepseek-ai/cordis";
2
- import { settingsNamespace } from "@deepseek-ai/dsh-settings";
3
2
  import { DSH_ENV_PREFIX } from "@deepseek-ai/dsh-subprocess";
4
3
  //#region lib/types/render.js
5
4
  /**
6
5
  * Shared rendering helpers for the shell tools (`dsh-tool-bash`,
7
- * `dsh-tool-pwsh`): the exit-status marker contract the tools' renderers
8
- * emit and the presentation layer parses back.
6
+ * `dsh-tool-pwsh`): the exit-status marker contract the tools' renderers emit,
7
+ * Host `presentResult` implementations parse here, and the Web terminal card
8
+ * model mirrors without importing Host code.
9
9
  * @module @deepseek-ai/dsh-shell/render
10
10
  */
11
11
  /**
@@ -61,7 +61,7 @@ function parseExitStatus(text) {
61
61
  * registering it twice, and a settings document carried between platforms
62
62
  * keeps resolving on both.
63
63
  */
64
- const SHELL_SETTINGS_NAMESPACE = settingsNamespace("shell");
64
+ const SHELL_SETTINGS_NAMESPACE = "shell";
65
65
  /**
66
66
  * Abstract bash execution service. Subclass, implement the abstract methods,
67
67
  * and load the subclass as a plugin — it registers as `ctx.shell` (one
@@ -16,7 +16,7 @@ import type { ShellExecRequest, ShellExecSpec, ShellProcess, ShellRunResult } fr
16
16
  * registering it twice, and a settings document carried between platforms
17
17
  * keeps resolving on both.
18
18
  */
19
- export declare const SHELL_SETTINGS_NAMESPACE: import("@deepseek-ai/dsh-settings").SettingsNamespace;
19
+ export declare const SHELL_SETTINGS_NAMESPACE = "shell";
20
20
  export { DSH_ENV_PREFIX } from './types.ts';
21
21
  export type { ShellExecRequest, ShellExecSpec, ShellProcess, ShellProcessRead, ShellProcessStatus, ShellRunResult, ShellSandboxInfo, CollectedOutput, DshEnvironment, DshEnvironmentKey, } from './types.ts';
22
22
  export { parseExitStatus } from './render.ts';
@@ -1,7 +1,8 @@
1
1
  /**
2
2
  * Shared rendering helpers for the shell tools (`dsh-tool-bash`,
3
- * `dsh-tool-pwsh`): the exit-status marker contract the tools' renderers
4
- * emit and the presentation layer parses back.
3
+ * `dsh-tool-pwsh`): the exit-status marker contract the tools' renderers emit,
4
+ * Host `presentResult` implementations parse here, and the Web terminal card
5
+ * model mirrors without importing Host code.
5
6
  * @module @deepseek-ai/dsh-shell/render
6
7
  */
7
8
  /**
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@deepseek-ai/dsh-shell",
3
3
  "description": "Abstract bash executor seam (ctx.shell) for the DeepSeek Harness",
4
- "version": "0.1.1-rc.2",
4
+ "version": "0.1.2-alpha.2",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -32,17 +32,17 @@
32
32
  ],
33
33
  "license": "MIT",
34
34
  "peerDependencies": {
35
- "@deepseek-ai/dsh-invariants": "^0.1.1-rc.2",
36
- "@deepseek-ai/dsh-subprocess": "^0.1.1-rc.2",
37
- "@deepseek-ai/dsh-sandbox": "^0.1.1-rc.2",
38
- "@deepseek-ai/cordis": "^4.0.1",
39
- "@deepseek-ai/dsh-settings": "^0.1.1-rc.2"
35
+ "@deepseek-ai/dsh-invariants": "^0.1.2-alpha.2",
36
+ "@deepseek-ai/dsh-sandbox": "^0.1.2-alpha.2",
37
+ "@deepseek-ai/cordis": "^4.0.2",
38
+ "@deepseek-ai/dsh-settings": "^0.1.2-alpha.2",
39
+ "@deepseek-ai/dsh-subprocess": "^0.1.2-alpha.2"
40
40
  },
41
41
  "devDependencies": {
42
- "@deepseek-ai/dsh-invariants": "^0.1.1-rc.2",
43
- "@deepseek-ai/dsh-sandbox": "^0.1.1-rc.2",
44
- "@deepseek-ai/cordis": "^4.0.1",
45
- "@deepseek-ai/dsh-settings": "^0.1.1-rc.2",
46
- "@deepseek-ai/dsh-subprocess": "^0.1.1-rc.2"
42
+ "@deepseek-ai/dsh-subprocess": "^0.1.2-alpha.2",
43
+ "@deepseek-ai/dsh-sandbox": "^0.1.2-alpha.2",
44
+ "@deepseek-ai/dsh-invariants": "^0.1.2-alpha.2",
45
+ "@deepseek-ai/cordis": "^4.0.2",
46
+ "@deepseek-ai/dsh-settings": "^0.1.2-alpha.2"
47
47
  }
48
48
  }