English | 中文
Local implementation of the @deepseek-ai/dsh-bash executor seam over the @deepseek-ai/dsh-subprocess service: LocalBashExecutor spawns bash -c <command> per call as a managed process group through ctx.subprocess, and owns everything bash-shaped — command defaulting and caps, timeout/cancel classification, the model-friendly terminal environment, and the model-facing stdout/stderr merge for background reads. Group mechanics (bounded spill-backed output, credential scrub, kill escalation, disposal) are the subprocess service's.
The package root exports the default and named LocalBashExecutor plugin plus its Config.
- id: bash
name: '@deepseek-ai/dsh-bash-local'
config:
cwd: /path/to/workspace # default: process.cwd()
timeoutMs: 120000 # default foreground timeout
maxTimeoutMs: 600000 # cap for per-call overrides
maxOutputBytes: 64000 # per-stream in-memory cap; overflow spills to disk
maxSpillBytes: 67108864 # per-stream full-output spill cap
graceMs: 3000 # kill escalation and post-exit pipe-drain grace
bash -c with no rc files.resolve() fills workdir/timeoutMs/stdoutMaxBytes from config, and every spawn hands the service explicit byte caps, spill cap, and graceMs. Process-group kills, post-exit pipe draining, tail retention, and bounded spill files are dsh-subprocess-local mechanics. A foreground BashExecRequest.stdoutMaxBytes can raise stdout's capture budget for one trusted caller; stderr and background runs still use maxOutputBytes.run() fuses its config-clamped timeout with the caller's signal through one deadline; only the executor's own timeout reports timedOut, an upstream cancel reports aborted, and a self-signaled command reports neither (timeout-library Agent Note).NO_COLOR=1 TERM=dumb PAGER=cat GIT_PAGER=cat prevents pagers and ANSI color from garbling results. These values merge as ordinary env under the service's credential scrub and DSH_* channel rules; an explicit caller entry still wins. See the stdin/env Agent Note and managed environment Agent Note.start() returns a live BashProcess handle immediately with no timeout, and readOutput() merges offset-based stdout/stderr reads into one consuming delta, placing stderr under a [stderr] marker when present. A running process belongs to the subprocess service, survives executor reloads, and is killed and joined on service disposal. Task ids, ownership, polling, and notices belong to the generic ctx.tasks runtime, which the tool layer registers the handle with.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.
dsh-bash-sandbox, while per-call allow/deny/ask policy belongs on tools/pre-execute.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.spawn failed: … into exactly one readOutput() delta; a reader that discards that delta cannot recover it.Scrub-heuristic and spill-retention caveats live with dsh-subprocess-local, which owns those mechanics.