dsh-plan-build-switch
中文 | English
A composer Plan/Build mode switch for DeepSeek Harness web (dsh --profile web). It adds a neutral segmented Plan | Build control to the chat input tool row, a customizable global keyboard shortcut, and a fully custom plan indicator — the shipped "Plan ✕" chip is shadowed, so there is never a duplicated or clashing plan affordance.
Features
- Segmented toggle in the composer tool row: highlights the active mode, click (or press the shortcut) to switch. Plan mode = the agent plans only; Build mode = the default execution mode.
- Customizable shortcut: default
Alt+P, change it in Settings → General → "Plan mode shortcut" by clicking the pill and pressing a new combination (Esc cancels). Any combo may be recorded, bare keys included. Persisted per browser in localStorage (dsh.planBuildSwitch.shortcut).
- Fully custom plan surface: registers a shadow occupant at priority
-1 over the official conversation.input.plan seat, so the shipped amber "Plan ✕" chip never renders. This control is the only plan indicator, styled neutrally with theme tokens.
- No layout jitter: the status slot keeps a fixed width and the disabled state changes no colors; the clicked segment highlights optimistically and the live
plan projection reconciles it.
- Typing-safe keys: modifier-less shortcuts do not fire while you type a character in a text field (bare
P won't toggle on every typed "p"); non-typing keys such as Tab or arrows fire immediately anywhere.
- Bilingual (zh/en) via the
planBuildSwitch locale namespace.
Requirements
dsh (DeepSeek Harness) web profile (dsh --profile web or dsh web), any recent build that ships @deepseek-ai/dsh-web-app with the browser plugin roster.
Install
Prerequisite: pnpm on PATH (dsh plugin forwards its arguments to pnpm inside the profile directory). Install it with corepack enable or npm i -g pnpm.
From the npm registry
dsh plugin --profile web add dsh-plan-build-switch
That is the whole install: the package is a profile bundle (dsh.bundle), so dsh plugin auto-appends it to the profile's dsh.profile.bundles and its bundled cordis.patch.yml self-inserts the plugin row at boot — no manual patch entry needed.
Restart dsh web (or dsh --profile web). Pages served after the install carry a tiny roster watcher that reloads the page automatically when the module graph changes, so an open page picks the toggle up on its own after a restart or update (the very first install needs one manual refresh — the page that predates the install has no watcher yet).
Uninstall:
dsh plugin --profile web remove dsh-plan-build-switch
Before publishing / offline (tarball fallback)
From the repository checkout:
npm pack # produces dsh-plan-build-switch-<version>.tgz
dsh plugin --profile web add ./dsh-plan-build-switch-<version>.tgz
(dsh plugin anchors relative path specs to the directory you invoke it from. The same bundle reconcile applies.)
Upgrading from 0.1.x
0.1.x was a plain client module that required a manual row in cordis.patch.yml. After upgrading:
dsh plugin --profile web add dsh-plan-build-switch@0.2.0 # bumps the dep and appends the bundle
then delete any manually added plan-build-switch row from your cordis.patch.yml files (the bundle now supplies it) and restart dsh web.
Troubleshooting
| Symptom | Cause | Fix |
|---|
pnpm failed in profile directory ... + 404 / ERR_PNPM_NO_MATCHING_VERSION | package not published yet, or your npm registry mirror has not synced | check pnpm config get registry; wait for mirror sync or use the tarball fallback above |
pnpm not found on PATH | pnpm missing | corepack enable or npm i -g pnpm |
[WARN] Issues with peer dependencies found | normal: the profile supplies peers from the DSH shell at runtime (autoInstallPeers: false) | ignore |
| installed but the toggle does not appear | dsh not restarted, or the page predates the install (no roster watcher) | restart dsh web; refresh the page once |
Usage
- Click Plan / Build in the composer tool row, or press the shortcut (
Alt+P by default).
- The active segment is highlighted; a
… status slot indicates a switch that applies at the next step (mid-turn switches).
- To change the shortcut: open Settings (sidebar foot) → General, find "Plan mode shortcut", click the pill and press the new combination.
Behavior notes
- The switch executes the host
/plan and /plan off commands through the commands Remote — exactly the same channel the shipped plan chip uses, owned by the per-agent plan-mode service.
- Switching produces the plan-mode service's own narration message in the session log (one per committed switch); that is host behavior, not rendered by this plugin.
- The shortcut preference is per browser (localStorage), not synced across devices.
Development
src/
index.js node half (pure UI plugin, empty apply)
client/
index.js plugin entry: registrations + locale dictionaries
mode-switch.js composer toggle component
shortcut.js shortcut state + key normalization
settings-row.js General-settings recorder row
styles.css styles (inlined into the bundle at build time)
build.mjs zero-dependency build → lib/ (also runs on `npm pack` via prepack)
smoke.mjs bundle materialization + registration/render smoke test
npm install --no-save # only needed if you want to run the smoke test's tooling manually
node build.mjs # regenerate lib/ from src/
node smoke.mjs # materialize lib/client.js like the browser loader and exercise registrations/renders
npm pack # build a publishable tarball
Publishing
npm login
npm publish
The package is MIT licensed. Set the repository field in package.json to your repo before publishing.
License
MIT