Windows-native execution foundation: PwshLocalExecutor implements the bash executor seam over ctx.subprocess (pwsh -NoLogo -NoProfile -NonInteractive -Command, one argv element, no quoting layer; resolvePwshPath probes PowerShell 7 / PATH / Windows PowerShell 5.1 as a pure function), and tool-pwsh is the minimal PowerShell-dialect model-facing tool over ctx.bash (foreground only, managed DSH_* env, timeout/signal/exit markers, terminal and generic presenters). Both packages carry full suites (real pwsh, self-skipping without it) at per-file 100% coverage; vitest's Windows exclusion narrows from packages/bash/* to the bash-requiring packages so the pwsh suites run natively on Windows too. The CLI gains the workspace deps and tsconfig projects without mounting either plugin; the Windows-default roadmap is recorded as a proposed Agent Note.
6.5 KiB
@deepseek-ai/dsh-tool-pwsh
English | 中文
The model-facing pwsh tool registered over the ctx.bash executor seam. Intended for Windows compositions where a PowerShell executor (e.g. @deepseek-ai/dsh-pwsh-local) backs ctx.bash; the tool contract is PowerShell-dialect: native C:\... paths and $env:NAME variables. Minimal by design — no background tasks, no sandbox escalation, no persistent shell: this is the "works on my Windows machine" profile until the full bash-tool feature set gets a PowerShell twin.
Requires a loaded executor implementation; the plugin stays pending until ctx.bash exists (inject: ['tools', 'bash', 'systemPrompt']).
The package root exposes only the Cordis plugin contract (name, inject, Config, apply) plus the pure renderPwshOutput helper and its result type; execution and presentation remain implementation details covered by same-package tests.
The plugin also contributes the tool:pwsh prompt section (order 105): check the [exit code: N] marker on every result and investigate failures before moving on.
Tools
pwsh
| Arg | Type | Notes |
|---|---|---|
command |
string (required) | Run via pwsh -Command. No state persists between calls — use workdir, not cd. |
description |
string (required) | One-line, active-voice summary of the command (5-10 words), for UI/log display only — no effect on execution. |
timeoutMs |
number | Timeout override in milliseconds. The executor applies its configured default and cap. |
workdir |
string | Working directory for this call. Defaults to 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. |
command, workdir, and timeoutMs are resolved against the executor's config defaults via ctx.bash.resolve() before execution. 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().
Managed shell environment
Every call receives a freshly collected trusted DSH_* environment. DSH_HOME is the absolute Harness home resolved by @deepseek-ai/dsh-paths (dshHome config, then ambient $DSH_HOME, then ~/.dsh) and DSH_SHELL=1 identifies the managed child. Agent calls additionally receive DSH_SESSION_ID=agent.session.header.id. The snapshot passes through the dedicated BashExecRequest.dshEnv channel; process.env is never modified.
Result text contains stdout, an optional [stderr] section, then applicable timeout, signal, and exit-code markers: [timed out after <timeoutMs>ms], [killed by signal: <signal>], and [exit code: N], each separated by a newline only when the accumulated text lacks one. Nonzero exit remains a model-interpreted result rather than isError. Only infrastructure failures — spawn errors and aborts (tool call aborted) — produce isError.
The canonical success is { kind: 'foreground', ...BashRunResult } for a completed foreground process. Programmatic consumers use the typed fields without parsing the rendered text.
UI presentation
The tool owns its presentCall/presentResult render intent. A call is a terminal card carrying command, description, and optional cwd; a completed result is a generic card with the rendered output in a console fence. These presenters are pure and replay-safe.
Model Experience
System prompt
What the model sees
Every request in this plugin's registration scope contains the pwsh guidance below. Scoped tool restrictions can hide the schema without removing this independently registered section.
Pwsh guidance
Check the [exit code: N] marker on every pwsh result; investigate failures before moving on.
Token effect
Small fixed input cost per request while the plugin is active.
KV Cache effect
Prefix-stable while the registration scope and prompt text are unchanged. Plugin activation or disposal may invalidate reuse from this prompt section.
Tool schemas
What the model sees
The model sees the generated pwsh schema. Agent-scoped tool restrictions can remove the definition for that agent.
Token effect
Fixed schema cost on every request where the tool is visible.
KV Cache effect
Prefix-stable while visibility and the tool definition are unchanged. A restriction or config change may invalidate reuse from the first changed token.
Foreground result
What the model sees
The renderer emits the data-dependent stdout tail, then optional [stderr] and the stderr tail. Conditional lines are exactly [timed out after <timeoutMs>ms], [killed by signal: <signal>], and [exit code: <exitCode>].
Token effect
Zero result tokens before a call. Output is bounded per stream, while each emitted line remains in history until compaction.
KV Cache effect
Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
Tool errors
What the model sees
Validation and infrastructure 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>, and tool call aborted.
Token effect
Only the failing call adds these retained tokens; an aborted call adds no command output.
KV Cache effect
Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
Known Limitations and Deferred Work
- Foreground-only — no
run_in_background; long-running work must stay within the executor timeout or wait for the bash-tool twin. - No sandbox escalation —
sandbox_permissions/justificationare absent; a confining composition denies through the executor, and escalation waits for the full twin. - PowerShell-dialect contract — the model must write PowerShell (native paths,
$env:variables), not bash; there is no dialect translation. - Windows-default roadmap deferred — defaulting Windows hosts to
pwshoverbash, and pwsh TUI/GUI rendering support, are planned separately and deliberately not part of this package yet.