DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

sujalmandal /

sujalmandal/dsh-tab-plan-toggle

Verified

Toggle DeepSeek Harness plan mode with Tab in the composer

★ 0 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHub
READMESource: main@f49a3fc9

dsh-tab-plan-toggle

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

Press Result
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)  ─────────────────┘
      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.
  • pending from planMode.get() is the service's queued target, so it counts as the effective state: a second press reverses a queued change instead of becoming a no-op.
  • Each entry acts only for the composer it is mounted in: the guard resolves the composer holding this entry's marker and requires the focused editor to sit inside it.
  • The 0.1.0 guard asked only whether the focused element sat in some [data-input-scroll], so with another conversation's entry still mounted, one press toggled both conversations.

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];
  • that editor belongs to the same composer as this entry's marker, so other conversations' composers cannot match;
  • 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

Symptom Check
Tab does nothing The composer's editor is Lexical's contenteditable host, not a TEXTAREA — a guard that requires TEXTAREA can never match. Verify the editor reports isContentEditable. Also confirm the entry's marker sits inside the same composer card as the editor.
Tab toggles another conversation Fixed in 0.1.1. On 0.1.0 each mounted composer added its own document keydown listener and any focused composer satisfied every one of them, so one press toggled every open conversation.
Tab still dead after an upgrade Only 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 console An older build read session.events; the Session API exposes snapshotEvents(). Upgrade.
Tab hijacks other editors The guard requires the editor to sit inside [data-input-scroll]; report the app surface if it does not.

License

MIT

—/ 5

No ratings yet

Verified DSH bundle

Commit f49a3fc95f59

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout