@xneog/dsh-tool-bash 0.1.0 → 0.1.3-alpha.1

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/tool-bash/README.md
5
- README.md: 21749bf0a1cd3cdc46257fb2a02ba6b4ab1f5ee6
6
- README.zh.md: e79190ced58abbd73d85127f3a4362f4e6b292cd
5
+ README.md: 72d9553b7134b8e7b485f7b8bef4ffeb44d32da3
6
+ README.zh.md: fdc04ac192571ef06d36d48f7523cfd23d936ad7
package/README.md CHANGED
@@ -1,66 +1,132 @@
1
+ ---
2
+ description: "The model-facing bash tool for users and maintainers choosing, configuring, or debugging one-shot command execution, background jobs, and sandbox escalation."
3
+ kind: "package-reference"
4
+ ---
5
+
1
6
  # @xneog/dsh-tool-bash
2
7
 
3
8
  English | [中文](README.zh.md)
4
9
 
5
- The model-facing `bash` tool registered over the `ctx.shell` executor seam. Foreground execution stays behind that seam; a background process handle is registered with the generic `ctx.jobs` runtime and controlled through `job_output`, `job_list`, and `job_kill` from `@xneog/dsh-tool-jobs`.
10
+ ## Summary
11
+
12
+ `dsh-tool-bash` gives the agent a `bash` tool that runs commands through the mounted shell executor and returns stdout, stderr, and exit markers. Each call runs in a fresh shell — no cwd, variables, or functions survive — and `run_in_background` turns long-running commands into background jobs the agent collects with `job_output` and stops with `job_kill`. Every call runs with the managed `DSH_*` environment from `dsh-shell-env`, and under a sandboxing executor a denied command may be retried once with a wider `sandbox_permissions` mode plus a `justification` through user approval. Non-zero exits are reported, not failed, so the agent decides how to react. Mount it together with an executor provider such as `dsh-bash-local` or `dsh-bash-sandbox` and the `dsh-shell-env` plugin.
13
+
14
+ ## Table of Contents
15
+
16
+ - [Use this package](#use-this-package)
17
+ - [Understand the implementation](#understand-the-implementation)
18
+ - [Further Exploration](#further-exploration)
19
+ - [Model Experience](#model-experience)
20
+ - [Known Limitations and Deferred Work](#known-limitations-and-deferred-work)
21
+ - [Dev Note](#dev-note)
22
+
23
+ -----
24
+
25
+ <a id="use-this-package"></a>
26
+ ## Use this package
27
+
28
+ Load this plugin in any composition where the agent should run bash commands: it registers the `bash` tool once an executor provider and the `dsh-shell-env` registry are mounted, and stays pending until the `tools`, `shell`, `systemPrompt`, and `shellEnv` services exist.
6
29
 
7
- Requires a loaded executor Service Provider (e.g. `@xneog/dsh-bash-local`) and the [`@xneog/dsh-shell-env`](../shell-env/README.md) registry; the plugin stays pending until every injected service exists (`inject: ['tools', 'bash', 'systemPrompt', 'bashEnv']`). The tool contract is bash-dialect — mount a bash-parsing executor.
30
+ ### Minimal configuration
8
31
 
9
- The package root exposes only the Cordis plugin contract (`name`, `inject`, `Config`, `apply`); result rendering and background-process adaptation remain package-internal.
32
+ The common path is an executor provider, the environment registry, and this tool; add the job runtime when the agent may run commands in the background.
10
33
 
11
- The plugin also contributes the `tool:bash` prompt section (order 105): check the `[exit code: N]` marker on every result and investigate failures before moving on.
34
+ ```yaml
35
+ - name: '@xneog/dsh-bash-local'
36
+ - name: '@xneog/dsh-shell-env'
37
+ - name: '@xneog/dsh-tool-bash'
12
38
 
13
- ## Tools
39
+ # Optional: background jobs
40
+ - name: '@xneog/dsh-jobs-local'
41
+ - name: '@xneog/dsh-tool-jobs'
42
+ ```
14
43
 
15
- ### `bash`
44
+ The single config field toggles background support.
16
45
 
17
- | Arg | Type | Notes |
46
+ | Field | Default | Meaning |
18
47
  |---|---|---|
19
- | `command` | string (required) | Run via `bash -c`. No state persists between calls use `workdir`, not `cd`. |
20
- | `description` | string (required) | One-line, active-voice summary of the command (5-10 words), for UI/log display only — no effect on execution. |
21
- | `timeoutMs` | number | Timeout override in milliseconds. The executor applies its configured default and cap. |
22
- | `workdir` | string | Working directory for this call. Defaults to the filesystem identity of the calling agent's session cwd (`session.header.cwd`) so each session runs in its own workspace; a relative `workdir` is resolved against that same identity. |
23
- | `run_in_background` | boolean | Return a job id immediately; no timeout applies. |
24
- | `sandbox_permissions` | string enum | ADVERTISED ONLY when the mounted executor sandboxes (`ctx.shell.sandboxMode` reports a confining default): the wider mode a denied command needs, from the closed target vocabulary `workspace-write`/`danger-full-access` (never cut down to the executor's default — the effective mode is per-session; strict widening is checked at execution against it, and a non-widening request fails without prompting anyone). |
25
- | `justification` | string | Required together with `sandbox_permissions` (each without the other is a validation error): one sentence for the user explaining why this exact command needs the wider access. |
48
+ | `enableRunInBackground` | `true` | Expose `run_in_background`; when `false`, forced background calls are rejected |
49
+
50
+ The generated [configuration catalog](../../../docs/config-catalog.md#xneogdsh-tool-bash) is the exhaustive source for every accepted field and its JSDoc; the generated [tool catalog](../../../docs/tool-catalog.md#xneogdsh-tool-bash) carries the full argument schema.
51
+
52
+ ### Running a command
53
+
54
+ The tool executes `bash -c <command>` and returns the combined output. Commands run in a fresh shell every call, so state never persists — pass `workdir` instead of `cd`. A non-zero exit is reported as `[exit code: N]` for the agent to interpret, not surfaced as a tool error. A `description` in active voice (5–10 words) labels the call in the UI; `timeoutMs` overrides the executor's default and cap. Output beyond the executor's stream caps is truncated to its tail, with the full output saved to a spill file whose path is reported.
55
+
56
+ ### Running long commands in the background
57
+
58
+ Passing `run_in_background: true` returns a job id immediately and no timeout applies; the command keeps running while the agent works on something else. The agent reads its output with `job_output` (non-blocking unless `wait: true`), lists jobs with `job_list`, and stops it with `job_kill`; a finished job notifies the owning agent in-session. Background support needs the generic job runtime (`dsh-jobs-local`) and its control tools (`dsh-tool-jobs`) mounted.
59
+
60
+ ### Sandboxed execution and escalation
26
61
 
27
- `command`, `workdir`, and `timeoutMs` are resolved against the executor's config defaults via `ctx.shell.resolve()` before execution, so the Service Definition (`ShellExecSpec`) receives explicit `workdir`/`timeoutMs` values. The workdir default is applied in the tool layer from the calling agent's `session.header.cwd` BEFORE `resolve()` the per-session cwd must come from `exec.agent`, since N sessions share one executor; only when no session cwd is available does the executor fall back to its own config / `process.cwd()`. When sandbox policy is present, the tool reuses its already-canonical `workspaceRoot` as the workdir base so confinement and process launch cannot resolve the same session spelling differently.
62
+ When the mounted executor confines commands (for example `dsh-bash-sandbox`), a blocked file operation is reported as `[sandbox: file access denied under <mode> mode]` a policy denial, not a command failure. The model may then retry the exact same command once in the same turn with `sandbox_permissions` (the narrowest wider mode that suffices) and a one-sentence `justification`; the approval prompt raised by that retry is how the user consents. Escalation is never speculative: a request with no real prior denial, or one that is not strictly wider than the current mode, fails closed without running anything, and a rejected escalation is final for that command.
28
63
 
29
- ### Managed shell environment
64
+ ### What can go wrong
30
65
 
31
- Every foreground and background model bash call receives a freshly collected trusted `DSH_*` environment through the shared [`dsh-shell-env`](../shell-env/README.md) registry: `DSH_HOME` (the absolute Harness home), `DSH_SHELL=1`, the agent's `DSH_SESSION_ID`, and `DSH_SESSION_JSONL` when the active persistence backend locates one. The registry contract — contributor registration, loud duplicate/undeclared-key failure, the built-in reservations, and the contributor example — lives in that package's README. The snapshot passes through the dedicated `ShellExecRequest.dshEnv` channel; the local executor removes all inherited `DSH_*` before merging it, so nested harnesses and concurrent parent/child agents cannot leak stale identities, and `process.env` is never modified. The tool description teaches the generic `$DSH_*` convention rather than naming persistence-specific variables or adding a permanent system-prompt section.
66
+ A composition with no executor provider never activates the tool. Background calls without the job runtime fail with `background jobs unavailable: load @xneog/dsh-jobs and @xneog/dsh-tool-jobs`, and `sandbox_permissions` without a sandboxing executor fails with `sandbox_permissions is not available in this composition (no sandboxing executor to escalate)`. `enableRunInBackground: false` removes the parameter and rejects a forced background call at execution time.
32
67
 
33
- Result text contains stdout, an optional `[stderr]` section, then applicable sandbox-denial, timeout, signal, exit-code, and truncation markers. Timeout is reported independently of final exit status; nonzero exit remains a model-interpreted result rather than `isError`. Truncation links a safe complete spill file or reports it unavailable. Only infrastructure failures such as spawn errors and aborts produce `isError`.
68
+ -----
34
69
 
35
- The canonical success is `{ kind: 'foreground', ...ShellRunResult }` for a completed foreground process or `{ kind: 'background', jobId }` for a published task. The Native renderer preserves the text above, including exactly `started background job <id>`; programmatic consumers use the typed fields without parsing those strings. Executor stream caps remain acquisition limits on `ShellRunResult` and carry their spill paths.
70
+ <a id="understand-the-implementation"></a>
71
+ ## Understand the implementation
36
72
 
37
- When `run_in_background` is true, this plugin preflights `ctx.jobs.start()` before spawning, registers the calling agent as owner, and adapts the returned `ShellProcess` handle into generic cancel/done/incremental-output hooks. The job runtime owns ids, cross-session isolation, completion notices, waiting, and disposal cleanup; this plugin only maps bash exit/sandbox facts into job output and outcome detail. `enableRunInBackground: false` removes the parameter and rejects a forced background call at execution time.
73
+ <details>
74
+ <summary>Implementation internals — click to expand</summary>
38
75
 
39
- ## UI presentation
76
+ This section explains the design decisions behind the tool and points at the code that realizes them; the observable behavior is fully covered in [Use this package](#use-this-package).
40
77
 
41
- The tool owns its `presentCall`/`presentResult` render intent. A foreground call is a terminal card carrying command, description, cwd, output, and parsed exit status. Because the card shows the exit as its own pill, the `[exit code: N]` / `[killed by signal: …]` marker the parse consumes leaves the output; every other marker (truncation, timeout, sandbox) stays in it. A background start is a generic execute card because it returns only a job id; the generic `job_*` tools own their own cards. These presenters are pure and replay-safe.
78
+ ### Design philosophy
42
79
 
43
- ## The tool builds its request from named args only
80
+ - **Model-facing consumer of the shell seam.** The tool is the Consumer role of the bash capability: it registers the `bash` schema, renders results, and resolves per-call policy, while the executor seam owns process mechanics.
81
+ - **Request from named args only.** The tool never exposes `stdin`, `env`, or `stdoutMaxBytes`; it builds each request from command/workdir/timeout/signal fields plus the registry-collected `dshEnv`, so model-supplied keys cannot replace managed values ([bash stdin/env Agent Note](../../../.agents/notes/implemented/architecture/2026-06-30-bash-stdin-env-trusted-plugin-api.md)).
82
+ - **Non-zero exits are reported, not errored.** Only infrastructure failures (spawn errors, aborts) surface as tool errors; the model interprets exit codes and markers.
83
+ - **Background work belongs to the job runtime.** A background call registers a process handle with `ctx.jobs`; ids, ownership, completion notices, and disposal are the runtime's, and this tool only maps bash exit and sandbox facts into job output.
44
84
 
45
- `ShellExecRequest` carries optional `stdoutMaxBytes`, `stdin`, ordinary `env`, and managed `dshEnv`, used by trusted in-process plugins and this tool's environment registry. The model-facing tool exposes none of `stdoutMaxBytes`, `stdin`, or `env`: it builds requests from named command/workdir/timeout/signal/sandbox fields plus the registry-collected `dshEnv`. Extra model keys are ignored and cannot replace managed values. Shell syntax provides equivalent command-level behavior, while the local executor scrubs ambient credentials and stale `DSH_*` values. See the [stdin/env Agent Note](../../../.agents/notes/implemented/architecture/2026-06-30-bash-stdin-env-trusted-plugin-api.md).
85
+ ### Source map
46
86
 
47
- ## Permissions and escalation
87
+ | File | Role |
88
+ |---|---|
89
+ | [`src/index.ts`](src/index.ts) | Plugin entry: tool registration, prompt section, arg validation, escalation, request assembly |
90
+ | [`src/background.ts`](src/background.ts) | Map a settled background process onto generic job outcome vocabulary |
91
+ | [`src/render.ts`](src/render.ts) | Model-facing result text: streams, markers, truncation notices |
92
+ | — | No runtime invariant companion is published; the environment registry validates ownership and collected values at each mutation/read; it publishes no independent snapshot that a companion could cross-check. |
48
93
 
49
- Commands run with the executor's full authority unless a sandboxing executor ([`dsh-bash-sandbox`](../bash-sandbox/)) confines them — the deny-only sandbox reports denials as result facts, rendered here as the denial marker; per-call allow/deny/ask policy is the `tools/pre-execute` waterfall (see docs/architecture.md).
94
+ ### Request resolution
50
95
 
51
- Escalating bash calls resolve `ctx.approval` before execution. `allowed-once` applies the requested mode only to that call; rejection, cancellation, unavailability, or missing approval context executes nothing and returns a distinct error. On a real denial, the model may retry the same command once in the same turn with the narrowest sufficient mode and justification; the approval prompt itself is the consent step. Escalation is never speculative, and a disabled or rejected approval is final. The [sandbox Agent Note](../../../.agents/notes/implemented/feature/2026-07-06-sandbox.md) owns the rationale.
96
+ The tool resolves the workdir before `ctx.shell.resolve()` runs: an explicit relative `workdir` is resolved against the session cwd, and a sandbox policy's canonical workspace root wins so confinement and launch use the same identity. Sandbox policy resolves per call through `ctx.sandboxPolicy`; an escalation request goes through `ctx.approval` before anything executes, and the tool fails at load if the executor confines but no policy service is mounted.
52
97
 
53
- ## Per-session mode switching
98
+ ### Rendering story
54
99
 
55
- For sandboxing executors, each call resolves mode as one-shot escalation, then session override, then executor default. Non-sandboxing and agent-less calls carry no session override. The policy owner contributes the current capability-neutral standing mode; denial results still own the operation-specific effective mode and retry guidance. See the [`dsh-shell` fold](../shell/README.md) and [sandbox switching contract](../../../.agents/notes/implemented/feature/2026-07-06-sandbox.md).
100
+ The result text is stdout, then a marked `[stderr]` section, then conditional markers: truncation notice, sandbox denial (plus the same-turn escalation hint when the composition advertises escalation), timeout, signal, and exit code each on its own line. The exit marker doubles as the UI card's exit-status pill: the shared `parseExitStatus` from `dsh-shell` consumes it from the output body, so replay shows the pill without duplicating the marker.
56
101
 
102
+ </details>
103
+
104
+ -----
105
+
106
+ <a id="further-exploration"></a>
107
+ ## Further Exploration
108
+
109
+ Read these pages when the package-level contract is not enough. They move from the shell family to the executor seam, the job runtime, and the decision notes behind the behavior.
110
+
111
+ - [shell package map](../README.md) — the bash capability family and its roles.
112
+ - [Bash executor subsystem](../../../docs/subsystems/shell.md) — request/spec vocabulary, results, and background processes.
113
+ - [shell-env](../shell-env/README.md) — the managed `DSH_*` environment every call receives.
114
+ - [tool-jobs](../../jobs/tool-jobs/README.md) — `job_output`, `job_list`, and `job_kill` controls for background runs.
115
+ - [bash stdin/env Agent Note](../../../.agents/notes/implemented/architecture/2026-06-30-bash-stdin-env-trusted-plugin-api.md) — why the tool exposes no stdin or env.
116
+ - [sandbox Agent Note](../../../.agents/notes/implemented/feature/2026-07-06-sandbox.md) — escalation and mode-switching rationale.
117
+ - [Generated tool catalog](../../../docs/tool-catalog.md#xneogdsh-tool-bash) — the exact `bash` argument schema.
118
+ - [Generated configuration catalog](../../../docs/config-catalog.md#xneogdsh-tool-bash) — every accepted config field and its source declaration.
119
+
120
+ -----
121
+
122
+ <a id="model-experience"></a>
57
123
  ## Model Experience
58
124
 
59
125
  ### System prompt
60
126
 
61
127
  #### What the model sees
62
128
 
63
- Every request in this plugin's registration scope contains the bash guidance below. The policy owner contributes current sandbox state through its cache-safe runtime context rather than changing this section. Scoped tool restrictions can hide the schemas without removing this independently registered section.
129
+ Every request in this plugin's registration scope contains the bash guidance below at first-party order 1000. The policy owner contributes current sandbox state through its cache-safe runtime context rather than changing this section. Scoped tool restrictions can hide the schema without removing this independently registered section.
64
130
 
65
131
  ##### Bash guidance
66
132
 
@@ -80,7 +146,7 @@ Prefix-stable while the registration scope and prompt text are unchanged. Plugin
80
146
 
81
147
  #### What the model sees
82
148
 
83
- The model sees the generated [`bash` schema](../../../docs/tool-catalog.md#deepseek-aidsh-tool-bash). `run_in_background` appears only when this producer enables it; `sandbox_permissions` and `justification` appear only when the mounted executor advertises sandboxing. Agent-scoped tool restrictions can remove the definition for that agent.
149
+ The model sees the generated [`bash` schema](../../../docs/tool-catalog.md#xneogdsh-tool-bash). `run_in_background` appears only when this producer enables it; `sandbox_permissions` and `justification` appear only when the mounted executor advertises sandboxing. Agent-scoped tool restrictions can remove the definition for that agent.
84
150
 
85
151
  #### Token effect
86
152
 
@@ -122,7 +188,7 @@ Append-only; newly visible content follows the reusable request prefix and does
122
188
 
123
189
  #### What the model sees
124
190
 
125
- Validation and policy failures are normalized as `Error: <message>`. This package's stable messages are `invalid command: expected a non-empty string`, `invalid description: expected a non-empty string`, `invalid timeoutMs: expected a positive number, got <value>`, `invalid escalation: sandbox_permissions requires a justification`, `invalid escalation: justification is only valid together with sandbox_permissions`, `invalid justification: expected a non-empty sentence`, `background execution is disabled for this bash tool`, `background jobs unavailable: load @xneog/dsh-jobs and @xneog/dsh-tool-jobs`, `sandbox_permissions is not available in this composition (no sandboxing executor to escalate)`, `sandbox escalation to "<mode>" is not strictly wider than this call's current "<mode>" mode`, the approval-availability/rejection/cancellation variants, and `tool call aborted`.
191
+ Validation and policy failures are normalized as `Error: <message>`. This package's stable messages are `invalid command: expected a non-empty string`, `invalid description: expected a non-empty string`, `invalid timeoutMs: expected a positive number, got <value>`, the escalation pairing failures, `run_in_background is disabled for this deployment (enableRunInBackground: false)`, `background jobs unavailable: load @xneog/dsh-jobs and @xneog/dsh-tool-jobs`, `sandbox_permissions is not available in this composition (no sandboxing executor to escalate)`, the approval availability/rejection/cancellation variants, and `tool call aborted`.
126
192
 
127
193
  #### Token effect
128
194
 
@@ -134,6 +200,21 @@ Append-only; newly visible content follows the reusable request prefix and does
134
200
 
135
201
  ## Known Limitations and Deferred Work
136
202
 
203
+ <a id="known-limitations-and-deferred-work"></a>
204
+
205
+
206
+ These limits define when the tool is a poor fit or needs special care. They are current package constraints, not a task backlog.
207
+
137
208
  - **Replay exit pills parse from result text** — output whose final line happens to be exactly `[exit code: N]` / `[killed by signal: …]` shows a wrong pill on session replay and loses that line from the card body, because the parse treats it as the marker it consumes; a display-only known residual.
138
209
  - **The `bash` tool opts out of `timeout-policy` budgets** — it keeps the executor-owned `BASH_TIMEOUT` path, per [the tool-call timeout-policy Agent Note](../../../.agents/notes/implemented/architecture/2026-07-07-tool-call-timeout-policy.md).
139
210
  - **Background processes have no executor timeout** — callers must use `job_kill`, or rely on owner/service disposal, when work no longer matters.
211
+
212
+ <a id="dev-note"></a>
213
+ ### Dev Note
214
+
215
+ <details>
216
+ <summary>Working context for maintainers — click to expand</summary>
217
+
218
+ None.
219
+
220
+ </details>
package/README.zh.md CHANGED
@@ -1,66 +1,132 @@
1
+ ---
2
+ description: "面向模型的 bash 工具,供选择、配置或排查一次性命令执行、后台任务与沙箱升权的使用者与维护者阅读。"
3
+ kind: "package-reference"
4
+ ---
5
+
1
6
  # @xneog/dsh-tool-bash
2
7
 
3
8
  [English](README.md) | 中文
4
9
 
5
- 模型侧 `bash` 工具,注册在 `ctx.shell` 执行器 seam 上。前台执行始终位于该 seam 之后;后台进程句柄会注册到通用 `ctx.jobs` 运行时,并通过 `job_output`、`job_list` 和 `job_kill` 控制;这些工具由 `@xneog/dsh-tool-jobs` 提供。
10
+ ## 概述
11
+
12
+ `dsh-tool-bash` 为 agent 提供 `bash` 工具,通过已挂载的 shell 执行器运行命令并返回 stdout、stderr 与退出标记。每次调用都运行在全新 shell 中——cwd、变量或函数都不会保留——而 `run_in_background` 把长时间运行的命令变成后台任务,agent 用 `job_output` 收集、用 `job_kill` 停止。每次调用都运行在来自 `dsh-shell-env` 的受管 `DSH_*` 环境中;在沙箱执行器下,被拒绝的命令可以携带更宽的 `sandbox_permissions` 模式和一句 `justification`,经用户审批后在同一轮次内重试一次。非零退出只会被报告、不会失败,因此由 agent 决定如何应对。请与 `dsh-bash-local` 或 `dsh-bash-sandbox` 等执行器提供方以及 `dsh-shell-env` 插件一起挂载。
13
+
14
+ ## 目录
15
+
16
+ - [使用本包](#use-this-package)
17
+ - [理解实现](#understand-the-implementation)
18
+ - [进一步探索](#further-exploration)
19
+ - [模型体验](#model-experience)
20
+ - [已知限制与延期工作](#known-limitations-and-deferred-work)
21
+ - [开发备注](#dev-note)
22
+
23
+ -----
24
+
25
+ <a id="use-this-package"></a>
26
+ ## 使用本包
27
+
28
+ 在 agent 需要运行 bash 命令的任何组合中加载本插件:一旦挂载执行器提供方与 `dsh-shell-env` 注册表,它就注册 `bash` 工具,并在 `tools`、`shell`、`systemPrompt` 与 `shellEnv` 服务就绪之前保持等待。
6
29
 
7
- 需要加载执行器 Service Provider(例如 `@xneog/dsh-bash-local`)与 [`@xneog/dsh-shell-env`](../shell-env/README.md) 注册表;在每个注入服务就绪之前,插件会保持等待状态(`inject: ['tools', 'bash', 'systemPrompt', 'bashEnv']`)。工具约定是 bash 方言——请挂载能解析 bash 的执行器。
30
+ ### 最小配置
8
31
 
9
- 包根只公开 Cordis 插件约定(`name`、`inject`、`Config`、`apply`);结果渲染和后台进程适配仍保留在包内部。
32
+ 常用路径是执行器提供方、环境注册表与本工具;当 agent 需要后台运行命令时,再添加任务运行时。
10
33
 
11
- 插件还会提供 `tool:bash` 提示词段落(顺序 105):检查每个结果中的 `[exit code: N]` 标记,发现失败时先调查原因再继续。
34
+ ```yaml
35
+ - name: '@xneog/dsh-bash-local'
36
+ - name: '@xneog/dsh-shell-env'
37
+ - name: '@xneog/dsh-tool-bash'
12
38
 
13
- ## 工具
39
+ # Optional: background jobs
40
+ - name: '@xneog/dsh-jobs-local'
41
+ - name: '@xneog/dsh-tool-jobs'
42
+ ```
14
43
 
15
- ### `bash`
44
+ 唯一的配置字段用于开关后台支持。
16
45
 
17
- | 参数 | 类型 | 说明 |
46
+ | 字段 | 默认值 | 含义 |
18
47
  |---|---|---|
19
- | `command` | string(必填) | 通过 `bash -c` 运行。调用之间不保留状态;请使用 `workdir`,不要使用 `cd`。 |
20
- | `description` | string(必填) | 用一行主动语态概述命令(5~10 个词),仅用于 UI/日志显示,不影响执行。 |
21
- | `timeoutMs` | number | 以毫秒为单位覆盖超时时间。执行器会应用其配置的默认值和上限。 |
22
- | `workdir` | string | 本次调用的工作目录。默认为调用方 agent(智能体)会话 cwd 的文件系统标识(`session.header.cwd`),使每个会话都在自己的工作区中运行;相对 `workdir` 也以同一标识为基准解析。 |
23
- | `run_in_background` | boolean | 立即返回 job id;不应用超时。 |
24
- | `sandbox_permissions` | string enum | 仅当已挂载的执行器启用沙箱时才会公开(`ctx.shell.sandboxMode` 报告一个具有限制作用的默认值):被拒命令所需的更宽模式,取自封闭的目标词汇 `workspace-write`/`danger-full-access`(绝不能缩减为执行器默认值;有效模式按会话确定,执行时会基于它检查是否严格拓宽,未拓宽的请求直接失败,不会向任何人发起提示)。 |
25
- | `justification` | string | 必须与 `sandbox_permissions` 一同提供(缺少任一项都会产生验证错误):用一句话向用户解释此命令为何需要这项更宽权限。 |
48
+ | `enableRunInBackground` | `true` | 暴露 `run_in_background`;为 `false` 时拒绝强制后台调用 |
49
+
50
+ 生成的[配置目录](../../../docs/config-catalog.zh.md#xneogdsh-tool-bash)是每个受支持字段及其 JSDoc 的穷尽式真源;生成的[工具目录](../../../docs/tool-catalog.zh.md#xneogdsh-tool-bash)携带完整参数 schema。
51
+
52
+ ### 运行命令
53
+
54
+ 工具执行 `bash -c <command>` 并返回合并后的输出。命令每次调用都运行在全新 shell 中,因此状态从不保留——请传 `workdir` 而不是 `cd`。非零退出以 `[exit code: N]` 报告给 agent 解读,而不是作为工具错误抛出。主动语态的 `description`(5–10 个词)在 UI 中标注该调用;`timeoutMs` 覆盖执行器的默认值与上限。超出执行器流上限的输出会被截断为尾部,完整输出保存到 spill 文件并报告其路径。
55
+
56
+ ### 后台运行长时间命令
57
+
58
+ 传入 `run_in_background: true` 会立即返回 job id,不应用超时;命令继续运行,agent 同时处理其他事情。agent 用 `job_output` 读取输出(除非 `wait: true`,否则非阻塞)、用 `job_list` 列出任务、用 `job_kill` 停止任务;完成的任务会在会话内通知拥有它的 agent。后台支持需要挂载通用任务运行时(`dsh-jobs-local`)及其控制工具(`dsh-tool-jobs`)。
59
+
60
+ ### 沙箱执行与升权
26
61
 
27
- 执行前,`command`、`workdir` `timeoutMs` 会通过 `ctx.shell.resolve()` 依据执行器配置默认值完成解析,因此 Service Definition(`ShellExecSpec`)收到显式的 `workdir`/`timeoutMs` 值。工具层会根据调用方 agent `session.header.cwd` 应用工作目录默认值,然后才调用 `resolve()`:由于 N 个会话共享一个执行器,逐会话 cwd 必须来自 `exec.agent`;只有无法取得会话 cwd 时,执行器才回退到自身配置/`process.cwd()`。存在沙箱策略时,工具会复用已经规范化的 `workspaceRoot` 作为工作目录基准,防止限制逻辑与进程启动过程对同一个会话路径拼写产生不同解析结果。
62
+ 当已挂载的执行器约束命令(例如 `dsh-bash-sandbox`)时,被阻止的文件操作会报告为 `[sandbox: file access denied under <mode> mode]`——这是策略拒绝,不是命令失败。模型随后可以在同一轮次中用 `sandbox_permissions`(满足需要的最窄更宽模式)与一句 `justification` 重试完全相同的命令一次;该重试引发的审批提示就是用户同意的方式。升权绝不能预先推测:没有真实拒绝依据的请求,或没有严格宽于当前模式的请求,会在不运行任何东西的情况下失败关闭,被拒绝的升权对该命令即为最终结果。
28
63
 
29
- ### 托管 shell 环境
64
+ ### 可能出什么问题
30
65
 
31
- 每次模型发起的前台或后台 bash 调用都会通过共享的 [`dsh-shell-env`](../shell-env/README.md) 注册表收到新收集的一组可信 `DSH_*` 环境变量:`DSH_HOME`(Harness home 绝对路径)、`DSH_SHELL=1`、agent `DSH_SESSION_ID`,以及当活跃持久化后端能定位时的 `DSH_SESSION_JSONL`。注册表约定——贡献方注册、重复键/未声明键的显式报错机制、内置项保留与贡献方示例——载于该包的 README。快照通过专用的 `ShellExecRequest.dshEnv` 通道传递;本地执行器会先删除继承的所有 `DSH_*` 再合并,因此嵌套 harness 和并发的父/子 agent 不会泄漏陈旧身份,且绝不修改 `process.env`。工具说明只教授通用 `$DSH_*` 约定,不会点名持久化专用变量,也不会添加永久的系统提示词段落。
66
+ 没有执行器提供方的组合永远不会激活该工具。没有任务运行时的后台调用会以 `background jobs unavailable: load @xneog/dsh-jobs and @xneog/dsh-tool-jobs` 失败;没有沙箱执行器时的 `sandbox_permissions` 会以 `sandbox_permissions is not available in this composition (no sandboxing executor to escalate)` 失败。`enableRunInBackground: false` 会移除该参数,并在执行时拒绝强制后台调用。
32
67
 
33
- 结果文本依次包含 stdout、可选的 `[stderr]` 段落和适用的沙箱拒绝、超时、信号、退出代码及截断标记。超时与最终退出状态分别报告;非零退出仍是由模型解释的结果,不会成为 `isError`。截断结果会链接安全的完整 spill 文件,或报告文件不可用。只有 spawn 错误和中止等基础设施故障才会产生 `isError`。
68
+ -----
34
69
 
35
- 已完成前台进程的规范成功值为 `{ kind: 'foreground', ...ShellRunResult }`,已发布任务则为 `{ kind: 'background', jobId }`。Native renderer 保留上述文本,包括精确的 `started background job <id>`;程序化消费方使用带类型字段,无需解析这些字符串。执行器的流上限仍是 `ShellRunResult` 的采集限制,并携带其 spill 路径。
70
+ <a id="understand-the-implementation"></a>
71
+ ## 理解实现
36
72
 
37
- 当 `run_in_background` 为 true 时,此插件会在 spawn 前预检 `ctx.jobs.start()`,把调用方 agent 注册为持有者,并将返回的 `ShellProcess` 句柄适配为通用的取消/完成/增量输出钩子。任务运行时负责 job id、跨会话隔离、完成通知、等待和 dispose(资源释放)清理;此插件只把 bash 退出/沙箱事实映射为任务输出和结果详情。`enableRunInBackground: false` 会移除该参数,并在执行时拒绝强制后台调用。
73
+ <details>
74
+ <summary>实现细节——点击展开</summary>
38
75
 
39
- ## UI 展示
76
+ 本节解释工具背后的设计决策,并指出实现它们的代码位置;可观察行为已在[使用本包](#use-this-package)中完整说明。
40
77
 
41
- 工具持有自己的 `presentCall`/`presentResult` 渲染意图。前台调用是终端卡片,包含命令、说明、cwd、输出和解析后的退出状态。由于卡片以独立的 pill 展示退出状态,解析所消耗的 `[exit code: N]` / `[killed by signal: …]` 标记会从输出中移除;其他所有标记(截断、超时、沙箱)都保留在输出中。后台启动只返回 job id,因此使用通用执行卡片;通用 `job_*` 工具持有各自的卡片。这些 presenter 是纯函数,可安全回放。
78
+ ### 设计理念
42
79
 
43
- ## 工具仅使用具名参数构建请求
80
+ - **shell seam 的模型侧消费方。** 本工具是 bash 能力的 Consumer 角色:它注册 `bash` schema、渲染结果并解析每次调用的策略,进程机制归执行器 seam 所有。
81
+ - **请求只来自命名参数。** 工具从不暴露 `stdin`、`env` 或 `stdoutMaxBytes`;它只用命令/workdir/超时/信号字段加上注册表收集的 `dshEnv` 构建每个请求,因此模型提供的键无法替换受管值([bash stdin/env Agent Note](../../../.agents/notes/implemented/architecture/2026-06-30-bash-stdin-env-trusted-plugin-api.zh.md))。
82
+ - **非零退出只报告、不失败。** 只有基础设施故障(spawn 错误、中止)才会作为工具错误暴露;模型解读退出码与标记。
83
+ - **后台工作归任务运行时。** 后台调用把进程句柄注册到 `ctx.jobs`;job id、所有权、完成通知与释放都是运行时的职责,本工具只把 bash 退出与沙箱事实映射为任务输出。
44
84
 
45
- `ShellExecRequest` 携带可选的 `stdoutMaxBytes`、`stdin`、普通 `env` 和托管 `dshEnv`,供可信进程内插件及此工具的环境注册表使用。模型侧工具不公开 `stdoutMaxBytes`、`stdin` 或 `env`:它使用具名的命令/工作目录/超时/信号/沙箱字段,加上从注册表收集的 `dshEnv` 来构建请求。额外模型键会被忽略,无法替换托管值。Shell 语法可以提供等价的命令级行为,而本地执行器会清除环境中的凭据和陈旧 `DSH_*` 值。参见 [stdin/env Agent Note](../../../.agents/notes/implemented/architecture/2026-06-30-bash-stdin-env-trusted-plugin-api.md)。
85
+ ### 源码地图
46
86
 
47
- ## 权限与升权
87
+ | 文件 | 职责 |
88
+ |---|---|
89
+ | [`src/index.ts`](src/index.ts) | 插件入口:工具注册、提示词区段、参数校验、升权、请求组装 |
90
+ | [`src/background.ts`](src/background.ts) | 把已结算的后台进程映射为通用任务结果词汇 |
91
+ | [`src/render.ts`](src/render.ts) | 模型侧结果文本:流、标记、截断通知 |
92
+ | — | 不发布运行时不变式伴生入口;执行关系归能力 seam 所有。 |
48
93
 
49
- 除非启用沙箱的执行器([`dsh-bash-sandbox`](../bash-sandbox/))限制命令,否则命令以执行器的完整权限运行。仅拒绝型沙箱会把拒绝作为结果事实报告,并在此渲染为拒绝标记;逐调用的允许/拒绝/询问策略由 `tools/pre-execute` waterfall(瀑布式事件)负责(参见 docs/architecture.md)。
94
+ ### 请求解析
50
95
 
51
- 需要升权的 bash 调用会在执行前解析 `ctx.approval`。`allowed-once` 只对该次调用应用请求模式;审批被拒、取消、不可用或缺少审批上下文时,命令完全不会执行,并返回不同的错误。发生真实拒绝后,模型可以在同一轮次中使用满足需要的最窄模式和理由重试同一命令一次;审批提示本身就是征求同意的步骤。升权绝不能预先推测,禁用或拒绝审批即为最终结果。其理由见 [沙箱 Agent Note](../../../.agents/notes/implemented/feature/2026-07-06-sandbox.md)。
96
+ 工具在 `ctx.shell.resolve()` 运行前解析 workdir:显式的相对 `workdir` 相对会话 cwd 解析,沙箱策略的规范化 workspace root 优先,使约束与启动使用同一身份。沙箱策略通过 `ctx.sandboxPolicy` 按调用解析;升权请求在任何执行前经由 `ctx.approval`,若执行器会约束命令却没有挂载策略服务,工具在加载时失败。
52
97
 
53
- ## 逐会话模式切换
98
+ ### 渲染故事
54
99
 
55
- 对于启用沙箱的执行器,每次调用依次按单次升权、会话覆盖、执行器默认值解析模式。未启用沙箱以及没有 agent 的调用不携带会话覆盖。策略归属方贡献当前且不区分具体能力的常驻模式;拒绝结果仍负责特定于该操作的有效模式与重试引导。参见 [`dsh-shell` 折叠计算](../shell/README.md)和[沙箱切换约定](../../../.agents/notes/implemented/feature/2026-07-06-sandbox.md)。
100
+ 结果文本为 stdout,然后是带标记的 `[stderr]` 区段,再是条件标记:截断通知、沙箱拒绝(组合声明升权时附带同轮次升权提示)、超时、信号与退出码——每个占一行。退出标记同时充当 UI 卡片的退出状态 pill:`dsh-shell` 共享的 `parseExitStatus` 会从输出体中消费它,因此回放显示 pill 而不重复标记。
56
101
 
102
+ </details>
103
+
104
+ -----
105
+
106
+ <a id="further-exploration"></a>
107
+ ## 进一步探索
108
+
109
+ 当包级约定不够用时阅读以下页面。它们从 shell 家族逐步进入执行器 seam、任务运行时,以及行为背后的决策笔记。
110
+
111
+ - [shell 包映射](../README.zh.md)——bash 能力家族及其角色。
112
+ - [Bash 执行器子系统](../../../docs/subsystems/shell.zh.md)——请求/spec 词汇、结果与后台进程。
113
+ - [shell-env](../shell-env/README.zh.md)——每次调用都会收到的受管 `DSH_*` 环境。
114
+ - [tool-jobs](../../jobs/tool-jobs/README.zh.md)——后台运行的 `job_output`、`job_list` 与 `job_kill` 控制。
115
+ - [bash stdin/env Agent Note](../../../.agents/notes/implemented/architecture/2026-06-30-bash-stdin-env-trusted-plugin-api.zh.md)——为什么工具不暴露 stdin 或 env。
116
+ - [沙箱 Agent Note](../../../.agents/notes/implemented/feature/2026-07-06-sandbox.zh.md)——升权与模式切换的理由。
117
+ - [生成的工具目录](../../../docs/tool-catalog.zh.md#xneogdsh-tool-bash)——`bash` 参数 schema 的确切内容。
118
+ - [生成的配置目录](../../../docs/config-catalog.zh.md#xneogdsh-tool-bash)——每个受支持配置字段及其源声明。
119
+
120
+ -----
121
+
122
+ <a id="model-experience"></a>
57
123
  ## 模型体验
58
124
 
59
125
  ### 系统提示词
60
126
 
61
- #### 模型看到的内容
127
+ #### 模型看到什么
62
128
 
63
- 此插件注册作用域内的每个请求都包含下方 bash 指引。策略归属方通过自身的缓存安全运行时上下文贡献当前沙箱状态,而不改变此段落。作用域工具限制可以隐藏 schema,但不会移除这个独立注册的段落。
129
+ 该插件注册 scope 中的每次请求都在 first-party 顺序 1000 处包含以下 bash 指引。策略归属方通过其缓存安全的运行时上下文贡献当前沙箱状态,而不修改本区段。按 scope 限制工具可以隐藏 schema,却不会移除这个独立注册的区段。
64
130
 
65
131
  ##### Bash 指引
66
132
 
@@ -70,17 +136,17 @@ Check the [exit code: N] marker on every bash result; investigate failures befor
70
136
 
71
137
  #### Token 影响
72
138
 
73
- 插件活跃期间,每个请求都会产生少量固定输入开销,不受沙箱模式或模式切换影响。
139
+ 插件激活期间,每次请求都会产生少量固定的输入 token 开销,不随沙箱模式或模式切换而变。
74
140
 
75
141
  #### KV Cache 影响
76
142
 
77
- 只要注册作用域和提示词文本不变,前缀即可稳定复用。插件激活或 dispose 可能从此提示词段落开始使复用失效;沙箱模式切换不会。
143
+ 只要注册 scope 与提示词文本不变,前缀就保持稳定。插件激活或释放可能使从该提示词区段起的复用失效;沙箱模式切换不会。
78
144
 
79
145
  ### 工具 schema
80
146
 
81
- #### 模型看到的内容
147
+ #### 模型看到什么
82
148
 
83
- 模型会看到生成的 [`bash` schema](../../../docs/tool-catalog.md#deepseek-aidsh-tool-bash)。仅当此生产方启用 `run_in_background` 时,该字段才会出现;仅当已挂载执行器声明支持沙箱时,`sandbox_permissions` 和 `justification` 才会出现。Agent 作用域的工具限制可以移除该 agent 的定义。
149
+ 模型会看到生成的 [`bash` schema](../../../docs/tool-catalog.zh.md#xneogdsh-tool-bash)。仅当本生产方启用 `run_in_background` 时,该字段才会出现;仅当已挂载执行器声明支持沙箱时,`sandbox_permissions` 和 `justification` 才会出现。按 agent(智能体)scope 限制工具可以移除该 agent 的定义。
84
150
 
85
151
  #### Token 影响
86
152
 
@@ -88,41 +154,41 @@ Check the [exit code: N] marker on every bash result; investigate failures befor
88
154
 
89
155
  #### KV Cache 影响
90
156
 
91
- 只要可见性、后台支持和执行器沙箱能力保持不变,前缀即可稳定复用。限制、配置或执行器发生变化时,可能从首个变化的工具定义开始使复用失效。
157
+ 只要可见性、后台支持与执行器沙箱能力不变,前缀就保持稳定。限制、配置或执行器发生变化时,可能从首个变化的工具定义开始使复用失效。
92
158
 
93
159
  ### 前台结果
94
160
 
95
- #### 模型看到的内容
161
+ #### 模型看到什么
96
162
 
97
- renderer 先输出依数据而定的 stdout 尾部,再输出可选的 `[stderr]` 和 stderr 尾部。没有输出时,它会精确输出 `(no output)`。条件行精确为 `[output truncated; full output: <path-or-(unavailable)>]`、`[sandbox: file access denied under <mode> mode]`、`[timed out after <timeoutMs>ms]`、`[killed by signal: <signal>]` `[exit code: <exitCode>]`;沙箱升权与 runner 故障行原文列于 [`dsh-bash-sandbox`](../bash-sandbox/README.md)。
163
+ renderer 输出依数据而定的 stdout 尾部,再输出可选的 `[stderr]` 和 stderr 尾部。没有输出时,它精确输出 `(no output)`。条件行精确为 `[output truncated; full output: <path-or-(unavailable)>]`、`[sandbox: file access denied under <mode> mode]`、`[timed out after <timeoutMs>ms]`、`[killed by signal: <signal>]` `[exit code: <exitCode>]`;沙箱升权与 runner 故障行原文列于 [`dsh-bash-sandbox`](../bash-sandbox/README.zh.md)。
98
164
 
99
165
  #### Token 影响
100
166
 
101
- 调用前结果 token 为零。每条流的输出有界,每个已输出行则会保留在历史中,直至压缩(compaction)。
167
+ 调用前的结果 token 为零。输出按流设界,而每行已发出的内容在压缩(compaction)前保留于历史。
102
168
 
103
169
  #### KV Cache 影响
104
170
 
105
- 仅追加;新可见内容位于可复用请求前缀之后,不会使现有 KV Cache 条目失效。
171
+ 仅追加;新可见内容位于可复用请求前缀之后,不会使现有 KV-cache 条目失效。
106
172
 
107
173
  ### 后台任务上下文与结果
108
174
 
109
- #### 模型看到的内容
175
+ #### 模型看到什么
110
176
 
111
- 启动会精确返回 `started background job <jobId>`。此生产方会向通用任务运行时提供增量进程输出、可选的 `[some output was dropped from memory; full output: <paths-or-(unavailable)>]`、沙箱事实,以及 `exit code: <exitCode>` 或 `signal: <signal>` 等终止详情。[`dsh-tool-jobs`](../../jobs/tool-jobs/README.md) 负责模型可见的状态行、完成通知、列表和取消响应。
177
+ 启动会精确返回 `started background job <jobId>`。本生产方会向通用任务运行时提供增量进程输出、可选的 `[some output was dropped from memory; full output: <paths-or-(unavailable)>]`、沙箱事实,以及 `exit code: <exitCode>` 或 `signal: <signal>` 等终止详情。[`dsh-tool-jobs`](../../jobs/tool-jobs/README.zh.md) 负责模型可见的状态行、完成通知、列表和取消响应。
112
178
 
113
179
  #### Token 影响
114
180
 
115
- 启动确认很短并会保留;收集到的输出依数据而定,并受执行器流缓冲区限制。消费式读取不会重复先前输出。
181
+ 启动确认很小且会被保留;收集到的输出依数据而定,受执行器流缓冲设界。消费性读取不会重复先前输出。
116
182
 
117
183
  #### KV Cache 影响
118
184
 
119
- 仅追加;新可见内容位于可复用请求前缀之后,不会使现有 KV Cache 条目失效。
185
+ 仅追加;新可见内容位于可复用请求前缀之后,不会使现有 KV-cache 条目失效。
120
186
 
121
187
  ### 工具错误
122
188
 
123
- #### 模型看到的内容
189
+ #### 模型看到什么
124
190
 
125
- 验证和策略失败统一为 `Error: <message>`。此包的稳定消息包括 `invalid command: expected a non-empty string`、`invalid description: expected a non-empty string`、`invalid timeoutMs: expected a positive number, got <value>`、`invalid escalation: sandbox_permissions requires a justification`、`invalid escalation: justification is only valid together with sandbox_permissions`、`invalid justification: expected a non-empty sentence`、`background execution is disabled for this bash tool`、`background jobs unavailable: load @xneog/dsh-jobs and @xneog/dsh-tool-jobs`、`sandbox_permissions is not available in this composition (no sandboxing executor to escalate)`、`sandbox escalation to "<mode>" is not strictly wider than this call's current "<mode>" mode`、审批不可用/拒绝/取消变体,以及 `tool call aborted`。
191
+ 验证与策略失败统一为 `Error: <message>`。本包的稳定消息包括 `invalid command: expected a non-empty string`、`invalid description: expected a non-empty string`、`invalid timeoutMs: expected a positive number, got <value>`、升权配对失败、`run_in_background is disabled for this deployment (enableRunInBackground: false)`、`background jobs unavailable: load @xneog/dsh-jobs and @xneog/dsh-tool-jobs`、`sandbox_permissions is not available in this composition (no sandboxing executor to escalate)`、审批不可用/拒绝/取消变体,以及 `tool call aborted`。
126
192
 
127
193
  #### Token 影响
128
194
 
@@ -130,10 +196,25 @@ renderer 先输出依数据而定的 stdout 尾部,再输出可选的 `[stderr
130
196
 
131
197
  #### KV Cache 影响
132
198
 
133
- 仅追加;新可见内容位于可复用请求前缀之后,不会使现有 KV Cache 条目失效。
199
+ 仅追加;新可见内容位于可复用请求前缀之后,不会使现有 KV-cache 条目失效。
134
200
 
135
201
  ## 已知限制与延期工作
136
202
 
137
- - **回放退出状态 pill 从结果文本解析**:如果输出最后一行恰好精确为 `[exit code: N]` / `[killed by signal: …]`,会话回放将显示错误的 pill,并且该行会从卡片正文中丢失,因为解析会把它当作自己消耗的标记;这是仅影响展示的已知残留问题。
138
- - **`bash` 工具不采用 `timeout-policy` 预算**:根据[工具调用 timeout-policy Agent Note](../../../.agents/notes/implemented/architecture/2026-07-07-tool-call-timeout-policy.md),它保留由执行器持有的 `BASH_TIMEOUT` 路径。
139
- - **后台进程没有执行器超时**:工作不再需要时,调用方必须使用 `job_kill`,或依赖持有者/服务的 dispose。
203
+ <a id="known-limitations-and-deferred-work"></a>
204
+
205
+
206
+ 这些限制说明工具何时不合适或需要特别小心。它们是当前包约束,不是任务积压。
207
+
208
+ - **回放的退出 pill 从结果文本解析**——输出最后一行恰好是 `[exit code: N]` / `[killed by signal: …]` 时,会话回放会显示错误的 pill 并从卡片正文丢失该行,因为解析把它当作要消费的标记;这是仅影响显示的已知残留。
209
+ - **`bash` 工具不参与 `timeout-policy` 预算**——它保留执行器自有的 `BASH_TIMEOUT` 路径,见[工具调用超时策略 Agent Note](../../../.agents/notes/implemented/architecture/2026-07-07-tool-call-timeout-policy.zh.md)。
210
+ - **后台进程没有执行器超时**——工作不再需要时,调用方必须使用 `job_kill`,或依赖持有者/服务的释放。
211
+
212
+ <a id="dev-note"></a>
213
+ ### 开发备注
214
+
215
+ <details>
216
+ <summary>维护者的工作上下文——点击展开</summary>
217
+
218
+ 无。
219
+
220
+ </details>
package/lib/index.js CHANGED
@@ -253,7 +253,7 @@ function apply(ctx, config = {}) {
253
253
  };
254
254
  ctx.systemPrompt.section({
255
255
  name: "tool:bash",
256
- order: 105,
256
+ order: ctx.systemPrompt.getSectionOrder("TOOL_BASH"),
257
257
  text: "Check the [exit code: N] marker on every bash result; investigate failures before moving on."
258
258
  });
259
259
  ctx.tools.register(defineTool({
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@xneog/dsh-tool-bash",
3
3
  "description": "Model-facing bash tool with optional generic background-job and sandbox-escalation support",
4
- "version": "0.1.0",
4
+ "version": "0.1.3-alpha.1",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -18,56 +18,50 @@
18
18
  "types": "./lib/types/index.d.ts",
19
19
  "default": "./lib/index.js"
20
20
  },
21
- "./invariant": {
22
- "types": "./lib/types/invariant.d.ts",
23
- "default": "./lib/invariant.js"
24
- },
25
21
  "./src/*": "./src/*",
26
22
  "./package.json": "./package.json"
27
23
  },
28
24
  "files": [
29
25
  "lib/index.js",
30
- "lib/invariant.js",
31
26
  "lib/types/**/*.d.ts"
32
27
  ],
33
28
  "license": "MIT",
34
29
  "peerDependencies": {
35
- "@xneog/dsh-agent": "0.1.0",
36
- "@xneog/dsh-shell": "0.1.0",
37
- "@xneog/dsh-shell-env": "0.1.0",
38
- "@xneog/dsh-invariants": "0.1.0",
39
- "@xneog/dsh-llm": "0.1.0",
40
- "@xneog/dsh-sandbox": "0.1.0",
41
- "@xneog/dsh-sandbox-policy": "0.1.0",
42
- "@xneog/dsh-system-prompt": "0.1.0",
43
- "@xneog/dsh-jobs": "0.1.0",
44
- "@xneog/dsh-tools": "0.1.0",
45
- "@xneog/dsh-user-approval": "0.1.0",
46
- "@xneog/cordis": "0.1.0"
30
+ "@xneog/dsh-agent": "^0.1.3-alpha.1",
31
+ "@xneog/dsh-shell": "^0.1.3-alpha.1",
32
+ "@xneog/dsh-shell-env": "^0.1.3-alpha.1",
33
+ "@xneog/dsh-llm": "^0.1.3-alpha.1",
34
+ "@xneog/dsh-sandbox": "^0.1.3-alpha.1",
35
+ "@xneog/dsh-sandbox-policy": "^0.1.3-alpha.1",
36
+ "@xneog/dsh-system-prompt": "^0.1.3-alpha.1",
37
+ "@xneog/dsh-jobs": "^0.1.3-alpha.1",
38
+ "@xneog/dsh-tools": "^0.1.3-alpha.1",
39
+ "@xneog/dsh-user-approval": "^0.1.3-alpha.1",
40
+ "@xneog/cordis": "^4.0.2"
47
41
  },
48
42
  "dependencies": {
49
- "@xneog/schemastery": "0.1.0"
43
+ "@xneog/schemastery": "^3.18.2"
50
44
  },
51
45
  "devDependencies": {
52
- "@xneog/dsh-agent": "0.1.0",
53
- "@xneog/dsh-agent-loop": "0.1.0",
54
- "@xneog/dsh-agent-loop-testkit": "0.1.0",
55
- "@xneog/dsh-shell": "0.1.0",
56
- "@xneog/dsh-shell-env": "0.1.0",
57
- "@xneog/dsh-bash-local": "0.1.0",
58
- "@xneog/dsh-invariants": "0.1.0",
59
- "@xneog/dsh-llm": "0.1.0",
60
- "@xneog/dsh-subprocess-local": "0.1.0",
61
- "@xneog/dsh-sandbox": "0.1.0",
62
- "@xneog/dsh-sandbox-policy": "0.1.0",
63
- "@xneog/dsh-session": "0.1.0",
64
- "@xneog/dsh-session-persistence-jsonl": "0.1.0",
65
- "@xneog/dsh-system-prompt": "0.1.0",
66
- "@xneog/dsh-jobs": "0.1.0",
67
- "@xneog/dsh-jobs-local": "0.1.0",
68
- "@xneog/dsh-tool-jobs": "0.1.0",
69
- "@xneog/dsh-tools": "0.1.0",
70
- "@xneog/dsh-user-approval": "0.1.0",
71
- "@xneog/cordis": "0.1.0"
46
+ "@xneog/dsh-agent-loop": "^0.1.3-alpha.1",
47
+ "@xneog/dsh-agent": "^0.1.3-alpha.1",
48
+ "@xneog/dsh-bash-local": "^0.1.3-alpha.1",
49
+ "@xneog/dsh-shell-env": "^0.1.3-alpha.1",
50
+ "@xneog/dsh-agent-loop-testkit": "^0.1.3-alpha.1",
51
+ "@xneog/dsh-llm": "^0.1.3-alpha.1",
52
+ "@xneog/dsh-sandbox": "^0.1.3-alpha.1",
53
+ "@xneog/dsh-sandbox-policy": "^0.1.3-alpha.1",
54
+ "@xneog/dsh-session-persistence-jsonl": "^0.1.3-alpha.1",
55
+ "@xneog/dsh-session": "^0.1.3-alpha.1",
56
+ "@xneog/dsh-jobs": "^0.1.3-alpha.1",
57
+ "@xneog/dsh-shell": "^0.1.3-alpha.1",
58
+ "@xneog/dsh-system-prompt": "^0.1.3-alpha.1",
59
+ "@xneog/dsh-subprocess-local": "^0.1.3-alpha.1",
60
+ "@xneog/dsh-tools": "^0.1.3-alpha.1",
61
+ "@xneog/dsh-tool-jobs": "^0.1.3-alpha.1",
62
+ "@xneog/dsh-jobs-local": "^0.1.3-alpha.1",
63
+ "@xneog/cordis": "^4.0.2",
64
+ "@xneog/dsh-user-approval": "^0.1.3-alpha.1",
65
+ "@xneog/dsh-session-projection": "^0.1.3-alpha.1"
72
66
  }
73
67
  }
package/lib/invariant.js DELETED
@@ -1,23 +0,0 @@
1
- //#region lib/types/invariant.js
2
- /**
3
- * Package-owned invariant companion for `@xneog/dsh-tool-bash`.
4
- * @module @xneog/dsh-tool-bash/invariant
5
- */
6
- const PACKAGE_NAME = "@xneog/dsh-tool-bash";
7
- /** Cordis companion plugin name. */
8
- const name = "tool-bash-invariant";
9
- /** Service required before the companion can reserve package ownership. */
10
- const inject = ["invariants"];
11
- /**
12
- * No runtime invariant: the environment registry validates ownership and collected values at each
13
- * mutation/read; it publishes no independent snapshot that a companion could cross-check.
14
- */
15
- const install = () => {};
16
- /**
17
- * Register this package's invariant companion.
18
- * @param ctx - Cordis context carrying the invariant service.
19
- * @returns the installed registration's disposer after setup succeeds.
20
- */
21
- const apply = (ctx) => Promise.resolve(ctx.invariants.register(PACKAGE_NAME, install));
22
- //#endregion
23
- export { apply, inject, name };
@@ -1,16 +0,0 @@
1
- /**
2
- * Package-owned invariant companion for `@xneog/dsh-tool-bash`.
3
- * @module @xneog/dsh-tool-bash/invariant
4
- */
5
- import type { Context } from '@xneog/cordis';
6
- /** Cordis companion plugin name. */
7
- export declare const name = "tool-bash-invariant";
8
- /** Service required before the companion can reserve package ownership. */
9
- export declare const inject: string[];
10
- /**
11
- * Register this package's invariant companion.
12
- * @param ctx - Cordis context carrying the invariant service.
13
- * @returns the installed registration's disposer after setup succeeds.
14
- */
15
- export declare const apply: (ctx: Context) => Promise<() => void>;
16
- //# sourceMappingURL=invariant.d.ts.map