Files
deepseek-harness/website/zh-CN/api/harness/bash.md
lintianle fcd9d8c391 website: fix nine review findings (generator coverage, loader facts, mode semantics)
Generator (all four structural gaps):
- harness service pages now render public properties/accessors, not just
  methods (ctx.codeRuntime.language/isolation were missing);
- the class page merges the same-named interface half, so ctx.root/baseUrl/
  events/logger/reflect/registry appear on Context (vendor root JSDoc gains
  prose alongside @experimental);
- Pick<…> heritage on a Context merge resolves to the picked class members,
  giving ctx.effect a documented signature on the Fiber page;
- {@link} tags normalize to code spans; merge sections get their own h2 so
  reflect members no longer nest under 'Static members'.

verify-website-yaml: reject the unloadable 'group:' pseudo-name (tree.import
only special-cases 'cordis:'; no builtin is registered here) and recurse into
@cordisjs/plugin-group nested entry lists instead.

Prose corrected against loader/cordis source: service.md isolation example
uses the real group plugin + group: true + the required isolate map;
config.md documents concurrent entry startup (Promise.all; order via inject)
and the real hmr defaults (root ['.'], base/ignored/debounce); events.md
fixes emit (synchronous, not parallel), bail (null/false also delegate), and
serial (stops at the first bail value).
2026-07-16 21:15:44 +08:00

139 lines
6.1 KiB
Markdown

<!-- Generated by scripts/gen-website-api.ts — do not edit by hand. Run `pnpm run gen-website-api` to regenerate. -->
# ctx.bash
`BashExecutor` (abstract seam) — provided by `@deepseek-ai/dsh-bash`.
Abstract bash execution service. Subclass, implement the abstract methods, and load the subclass as a plugin — it registers as `ctx.bash` (one implementation per context; loading a second throws, which is cordis' standard duplicate-service behavior).
Semantics every implementation must honor:
- run REJECTS only for infrastructure failures (unusable workdir, missing shell, pre-aborted signal). Nonzero exits, timeout kills, and abort kills RESOLVE with a descriptive BashRunResult — reporting a failed command is the tool layer's job, not an exception.
- start returns immediately; no timeout applies to background tasks (callers stop them via kill or the spec's AbortSignal). Completion must fire the onTaskDone listeners exactly once per task, and must NOT fire after the service is disposed.
- readOutput is incremental: consecutive reads never re-deliver output. Implementations bound their buffers; reads that lost data flag `lossy` and point at full-stream spill files when available.
- Disposal kills every running task and awaits their exit (no orphan processes survive `fiber.dispose()`).
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/bash/bash/src/index.ts#L59)
### ctx.bash.resolve(request)
```ts website-api
abstract resolve(request: BashExecRequest): BashExecSpec
```
Resolve a caller's BashExecRequest into a fully-specified BashExecSpec, applying this implementation's config defaults and caps (working directory, default/max timeout). Consumers (tool layer) call this, then pass the result to run/start — keeping defaulting in the implementation that owns the config while the seam type stays explicit (no hidden `?? default` inside run/start).
- `request` — the caller's request; omitted fields get this implementation's defaults, capped fields are clamped.
**Returns** the fully-specified spec to hand to `run`/`start`.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/bash/bash/src/index.ts#L84)
### ctx.bash.run(spec)
```ts website-api
abstract run(spec: BashExecSpec): Promise<BashRunResult>
```
Run a command in the foreground; resolves when it finishes.
- `spec` — a resolved spec from `resolve`, never a raw request.
**Returns** the outcome; nonzero exits, timeout kills, and abort kills resolve with a descriptive result rather than reject.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/bash/bash/src/index.ts#L92)
### ctx.bash.start(spec)
```ts website-api
abstract start(spec: BashExecSpec): BashTask
```
Start a background task and return its handle immediately.
- `spec` — a resolved spec from `resolve`, never a raw request.
**Returns** the live task handle; completion fires `onTaskDone`.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/bash/bash/src/index.ts#L99)
### ctx.bash.get(id)
```ts website-api
abstract get(id: BashTaskId): BashTask | undefined
```
Look up a background task by id.
- `id` — the task id to look up.
**Returns** the tracked task, or undefined for an id this executor never issued.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/bash/bash/src/index.ts#L106)
### ctx.bash.ownerOf(id)
```ts website-api
abstract ownerOf(id: BashTaskId): OwnerToken | undefined
```
The opaque OWNER token recorded for a background task at start (from the BashExecSpec's `owner`), or `undefined` for an unknown id OR a known-but-ownerless task. The executor stores and returns the token verbatim — it never interprets it; the access POLICY (who may read/kill a task) lives in the consumer (`@deepseek-ai/dsh-tool-bash`), which compares `ownerOf(id)` to the caller's token. Collapsing unknown-id and known-but-unowned into the same `undefined` is fine: the consumer's access gate treats `undefined` as "open", and a genuinely unknown id then fails loudly at the subsequent readOutput/kill ("unknown task"). Storing ownership in the executor (disposed with ITS fiber) — not in the tool plugin — is what makes ownership survive a `tool-bash` HMR reload.
- `id` — the background task id to look up ownership for.
**Returns** the token recorded at start, verbatim; undefined for an unknown id or a known-but-ownerless task.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/bash/bash/src/index.ts#L124)
### ctx.bash.list()
```ts website-api
abstract list(): BashTask[]
```
All tracked background tasks (insertion order).
**Returns** every task this executor started, running or finished.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/bash/bash/src/index.ts#L130)
### ctx.bash.readOutput(id)
```ts website-api
abstract readOutput(id: BashTaskId): BashTaskRead
```
Read output produced since the previous read. Throws for unknown ids.
- `id` — the task to read from.
**Returns** the incremental read; consecutive reads never re-deliver output.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/bash/bash/src/index.ts#L137)
### ctx.bash.kill(id)
```ts website-api
abstract kill(id: BashTaskId): boolean
```
Kill a running background task. Returns false when it had already finished (no-op). Throws for unknown ids.
- `id` — the task to kill.
**Returns** true when this call killed it, false when it had already finished.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/bash/bash/src/index.ts#L145)
### ctx.bash.onTaskDone(listener)
```ts website-api
onTaskDone(listener: BashTaskListener): () => void
```
Register a background-task completion listener (disposed with the calling fiber). Listeners never fire after this service is disposed.
- `listener` — called exactly once per task completion.
**Returns** the disposer that unregisters the listener.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/bash/bash/src/index.ts#L153)