description: "The default POSIX Bash executor for deployments and maintainers choosing, configuring, or debugging unconfined command execution over the shell seam."
English | 中文
dsh-bash-local is the default Bash executor for POSIX: every command runs as a fresh, non-login bash -c process with no rc files, so no shell state survives between calls. It applies configured budgets — working directory, timeout, output caps — to each command, classifies timeouts and cancellations, and returns bounded output with spill-file recovery when a stream overflows. Commands run with the harness process's own authority: this executor confines nothing, so compose dsh-bash-sandbox when commands need the sandbox capability. The model-facing bash tool talks to it once it is mounted.
Mount this executor when a composition needs Bash command execution on POSIX without confinement. It registers as ctx.shell, and the model-facing bash tool works over it immediately: an agent calls the tool, and the command runs as a fresh bash -c process with the budgets below.
Load the executor with the budgets you want; every field has a default, so the smallest composition is the plugin entry alone. The settings provider (when composed) layers a user section over this entry, so budgets can change at runtime without a reload (see Adjusting budgets at runtime).
- id: bash
name: '@deepseek-ai/dsh-bash-local'
config:
cwd: /path/to/workspace
timeoutMs: 120000
| Field | Default | Meaning |
|---|---|---|
cwd |
process.cwd() |
Default working directory for commands |
timeoutMs |
120,000 |
Default foreground timeout, in milliseconds |
maxTimeoutMs |
600,000 |
Cap for per-call timeout overrides |
maxOutputBytes |
64,000 |
Per-stream in-memory output cap; overflow spills to a temp file |
maxSpillBytes |
67,108,864 |
Per-stream full-output spill cap |
graceMs |
3,000 |
Grace period for kill escalation and post-exit pipe draining |
The generated configuration catalog is the exhaustive source for every accepted field and its JSDoc.
Run a command with run and read its output from the result. A nonzero exit, a timeout, or a cancellation resolves with a descriptive result — only infrastructure failures reject. Per-call timeoutMs overrides are capped by the configuration, while workdir falls back to the configured default when unset; a trusted foreground caller can also raise the stdout capture budget for one call, while stderr and background runs keep maxOutputBytes. The environment is model-friendly by default: NO_COLOR=1 TERM=dumb PAGER=cat GIT_PAGER=cat keep pagers and ANSI colors from garbling output, and an explicit caller-provided entry still wins.
const result = await ctx.shell.run(ctx.shell.resolve({ command: 'ls -la' }))
if (result.timedOut) console.log('timed out after', result.timeoutMs)
Call start to run a command in the background; it returns a handle immediately and no timeout applies. readOutput() merges the stream deltas into one consuming read, marking stderr under a [stderr] section; kill() terminates the provider-managed range; done settles when the direct command closes and never rejects. Job ids, ownership, polling, and notices belong to the generic ctx.jobs runtime, which the tool layer registers the handle with.
When a settings provider is composed, this executor registers the capability's shared shell settings namespace with the composition entry as its base, so a user section in settings.yaml layers over it and the next command runs with the new budgets. Values the schema cannot judge — positive and finite numbers, and the graceMs timer bound — are refused at the write, leaving the running executor on its last good section; without a provider, the composition entry is what runs.
Read these pages when the executor contract is not enough. They move from the seam to the confining sibling and the mechanics underneath.
bash tool over this executor.Indirectly, through dsh-tool-bash, which renders this executor's bounded stdout/stderr tails, background-process deltas, spill-file paths, and infrastructure failures.
No direct invalidation; the named consumer owns any request-prefix changes.
These limits define when this executor is a poor fit. They are current package constraints, not a roadmap.
dsh-bash-sandbox, while per-call allow/deny/ask policy belongs on the tools' pre-execute waterfall.bash -c; cwd-only persistence and interactive terminal sessions remain deferred until a real workflow requires them.bash binary is hardcoded and the underlying service's group semantics are POSIX; Windows is unsupported.SubprocessHandle.done can reject before or after target execution begins, so the executor injects the stage-neutral subprocess failed before reporting an outcome: … into exactly one readOutput() delta; a reader that discards that delta cannot recover it.