BanboLee/banbo-dsh--plugins-fish-shell ↗★ 0
@banbolee/dsh-fish-shell
Fish shell executors and tool for DeepSeek Harness: run commands with fish instead of bash. 适合偏好 fish 的用户;需在目标场景挂载后再通过配置切换执行器。
Install
npx -p @deepseek-ai/dsh dsh plugin --profile web add github:BanboLee/banbo-dsh#a785b690cd3a271225efba76ae2079e8fbf2df51&path:plugins/fish-shellREADME
Read the full README ↗@banbolee/dsh-fish-shell
Fish shell executors and tool for DeepSeek Harness: run commands with fish instead of bash. Distribution-ready and surface-agnostic: works in any profile that mounts it — preset-roster based (dsh-tui, web) or host-tool based (headless).
What this bundle does
- Executor, sandboxed (
index.js, default export):FishSandboxExecutor, aSandboxBashExecutorsubclass that confinesfish -ccommands instead ofbash -c. Mounted asctx.shellin place of the basebash-sandboxexecutor. The sandbox backend, denial classification, runner-failure facts, and thesandboxModecapability fact (required bydsh-permission-presets) are inherited. Both the confined and thedanger-full-accesspaths run fish (the base class's full-access branch falls through to hardcoded bash, so it is overridden). - Executor, unconfined (
local.js, exported as@banbolee/dsh-fish-shell/local):FishLocalExecutor, aLocalBashExecutorsubclass runningfish -cwithout a sandbox. For custom compositions that deliberately run without a sandbox; composing it withdsh-permission-presetsfails loud at load. - Tool (
tool.js, exported as@banbolee/dsh-fish-shell/tool): a model-facingfishtool mounted host-globally, executing throughctx.shell. It passes the calling session's resolved sandbox policy (so/permissionswitches and the session workspace root are honored), collects the managedDSH_*environment fromctx.shellEnv, and renders the harness marker contract ([exit code: N],[stderr],[sandbox: file access denied under mode],[output truncated; full output: ]). Its description teaches the model fish syntax. - Agent preset (bundled at
presets/fish/): a copy of the shippedstandardpreset with the shell section removed (thefishtool is host-global, so the preset needs no shell row). The bundle patch adds the package'spresets/directory as a system preset root and switches the preset-roster default tofishfor both roster row ids (agent-presetsused by web,dsh-tui-agent-presetsused by dsh-tui). The tool plugin also installs the preset under$DSH_HOME/.agent-presets/fishcreate-only (never overwrites an existing file, including a user-authored one; a failed write is a warning) as a fallback for rosters whose row this bundle does not patch.
Install
From npm (recommended) — no clone needed:
dsh plugin --profile add @banbolee/dsh-fish-shell
From this checkout, per profile:
dsh plugin --profile add ./plugins/fish-shell
Add it to every profile that should default to fish (dsh-tui, web, headless, …). The bundle patch is a no-op (with a warning) for a roster row id that the profile does not have, so one patch file is safe across surfaces.
Deployed copy and the symlink chain
The executors subclass @deepseek-ai/dsh-bash-local /
@deepseek-ai/dsh-bash-sandbox. Those imports must resolve to the same
runtime instance the harness uses — the launcher-maintained
profiles/node_modules/@deepseek-ai/* symlink chain. A plain link: to this
checkout (outside the profile tree) would resolve no @deepseek-ai package,
so the deployed copy lives at profiles/node_modules/@banbolee/dsh-fish-shell (inside
the tree). scripts/sync-to-profile.sh copies the plugin there after edits
and checks the bundled fish preset for drift against the shipped standard
preset; a pnpm file: dependency points each profile at the deployed copy. A
package published to npm installs normally (its realpath already lies inside
the profile tree).
Per-surface behavior
- Preset-roster surfaces (dsh-tui, web): agents compose tools from the
fishpreset (default) —standardminus the shell rows — and see exactly one shell tool,fish. Upstream presets (standard,code) are not fish-safe: they register abash-named tool that still executes through the fish executor, so the name/description lie about the shell. Only the bundledfishpreset is fish-only. (minimalhas no one-shot shell tool.) - Host-tool surfaces (headless): the agent uses host-plane tools; the
disabled host
tool-bashand the host-globalfishtool make fish the agent's only shell tool.
Behavior
- Every shell call spawns a fresh non-login shell (under the configured
sandbox backend for
FishSandboxExecutor); no state (cwd, variables, functions, history) persists between calls. - Output is bounded per stream by the executor's configured caps; timeouts are clamped to the executor's cap; the model sees the harness marker contract.
- Requires
fishon PATH; the executors fail loud when it is missing.
Known Limitations
- Models default to bash idioms; the
fishtool description teaches fish syntax, but a command written in bash dialect fails under fish. This is the intended trade of swapping the shell. - The
fishtool has norun_in_backgroundparameter and no sandbox escalation (sandbox_permissions) parameters yet; long commands must finish within the timeout, and a denied command cannot be re-run wider (the executor'sstart()and the approval stack are available to in-process consumers). - Upstream presets (
standard,code) are not fish-safe; see Per-surface behavior. - POSIX only: the
fishbinary and the underlying process-group semantics are not available on Windows (the pwsh family covers Windows).