sujalmandal/dsh-tab-plan-toggle ↗★ 0

dsh-tab-plan-toggle

Toggle DeepSeek Harness plan mode with Tab in the composer 适合希望在输入框中通过快捷键快速开关计划模式的用户。

パッケージ
dsh-tab-plan-toggle
互換性
未検証
バージョン
0.1.0
ライセンス
MIT
最終更新
2026/09/24

インストール

$npx -p @deepseek-ai/dsh dsh plugin --profile web add github:sujalmandal/dsh-tab-plan-toggle

ドキュメント

README 全文を読む ↗

dsh-tab-plan-toggle

Toggle DeepSeek Harness plan mode with Tab while the composer textarea has focus.

PressResult
Tab (composer focused, plan mode off)plan mode on
Tab (composer focused, plan mode on)plan mode off

Install

dsh plugin --profile web add dsh-tab-plan-toggle
dsh web

Straight from the repository, before (or instead of) a registry release:

dsh plugin --profile web add git+https://github.com/sujalmandal/dsh-tab-plan-toggle.git

Verify the row is composed before restarting:

dsh --profile web --dump-config   # look for "# == dsh-tab-plan-toggle"

How it works

composer Tab keydown ──rpc /dsh-tab-plan-toggle──▶ host half
                                                    │
      ctx.get('agentPresets').serviceFor(agent,'planMode')
                                                    │
      target = !(pending ? !active : active)  ───────┘
      planMode.set(agent, target)
  • The host half calls the plan-mode service, so entering and leaving produce the same narration notice as /plan — with no command/run row added to the conversation.
  • Plan mode lives inside an agent preset's isolate realm on dsh web, so a host row can only reach it through agentPresets.serviceFor(agent, 'planMode'). When that service is unavailable the plugin falls back to appending plan/mode to the session log.
  • The effective state mirrors the composer's built-in Plan chip: a queued selection (pending) already counts as its target, so a double press cannot desync the toggle.

Guards

Tab is only intercepted when all of these hold:

  • no ⌘/Ctrl/Alt/Shift, and no IME composition in flight;
  • the focused element is the composer's editor — its Lexical contenteditable host, or a TEXTAREA — and it sits inside [data-input-scroll];
  • no suggestion menu is open ([data-trigger-menu] absent): inside the / or @ menu, Tab means Browse folder.

Everywhere else Tab keeps its normal behaviour.

Troubleshooting

SymptomCheck
Tab does nothingThe composer's editor is Lexical's contenteditable host, not a TEXTAREA — a guard that requires TEXTAREA can never match. Verify the editor reports isContentEditable.
Tab still dead after an upgradeOnly one dsh-tab-plan-toggle row in --dump-config. Two mounts means two handlers, and Tab toggles twice — a net no-op.
… is not iterable in the browser consoleAn older build read session.events; the Session API exposes snapshotEvents(). Upgrade.
Tab hijacks other editorsThe guard requires the editor to sit inside [data-input-scroll]; report the app surface if it does not.

License

MIT