dsh-screen-switcher
v0.1.2
Published
Ctrl+Tab switcher for DeepSeek Harness: an Alt-Tab-style list of every place you visited — sessions, Settings sections and plugin pages — most recently visited first. Hold Ctrl to see it, release to switch.
Maintainers
Readme
dsh-screen-switcher
Ctrl+Tab for DeepSeek Harness, the way Alt+Tab works on the desktop.
Hold Ctrl and press Tab: an Alt-Tab-style list of every place you have been appears — sessions, Settings sections, the Plugins page and a plugin's own page — most recently visited first. Each further Tab moves down the list, Shift+Tab moves back, and releasing Ctrl goes to the highlighted place. Esc cancels. A single Ctrl+Tab-and-release returns to the previous session.
What makes it different
The community catalog already has session cyclers and tab bars. This plugin is the one that shows the list while Ctrl is held — nothing switches until you release, and Esc leaves you exactly where you were. Places are more than sessions: a Settings section and a plugin's page are places of their own, and returning to them restores that section and that plugin card. No new chrome, no extra windows — one chord, one overlay.
What counts as a place
| Place | How it is read | How it is restored |
|---|---|---|
| Session | the Session the main view retains (ctx.sessions.list) | ctx.uiWorkspace.openSession() |
| Page | the selected global panel (ctx.layout.panelInfo) | ctx.layout.selectPanel() |
| Plugin page | the Plugins page's own store (view, tab) | that store's setView/setTab |
| Settings | the Settings shell store (open, activeId) | its open()/openSection() |
Each Session row carries the sidebar's own status dot: yellow if it waits for an approval, a plan review or an answer, a spinner while it runs, green when it finished with unread output, grey when idle.
Visited places persist in localStorage under dsh.screen-switcher.v1, so the
switcher still knows your recent screens after a reload or restart. The list
has no fixed size: a place stays until it stops existing. Deleted and archived
Sessions and Settings sections that are no longer registered are dropped from
both the list and the stored document when the switcher opens. Visiting a
plugin card whose package is gone from the Plugins page drops the place once
that page renders its list, and leaves the list on screen; a page that never
renders a list keeps the place, because nothing proves the package is missing.
Install
Install the directory as a bundle in the current profile — from the Plugin Manager, or with the CLI for a published copy:
dsh plugin --profile "$DSH_PROFILE" add dsh-screen-switcherRestart the app once after installing a new package; Client code changes made to an already installed copy hot-reload.
Behaviour details
- Ctrl+Tab and Ctrl+Shift+Tab are handled in the page and take priority over editors and dialogs, except inside a terminal pane and while a shortcut is being recorded.
- The list is a shell overlay portalled to
document.body, so it stays on top of the Settings dialog — the place you are leaving is still visible behind it. - Clicking a row switches to it; clicking outside cancels.
- Switching to a Session closes Settings first and clears the selected page.
- A failed navigation (deleted Session, withdrawn page) leaves the list intact and logs one warning; the next open shows where you actually are.
Limits
- Browsers reserve Ctrl+Tab for their own tabs, so the web build only works in the desktop app or in a browser where that shortcut can be delivered to the page.
- Screen history stops at the global page level; the right sidebar (files, terminal, browser) is not part of the list.
- Settings sub-tabs whose state lives inside a section component (for example the read-only inventory tabs under Built-in plugins) are restored to the section, not to the exact tab.
Development
node scripts/verify.mjs # headless: fake Client services, real key eventsscripts/verify.mjs loads client.js through the same window.__ModuleLoader__
facade the app uses, then drives Ctrl+Tab against fake services: visited order,
cycling, commit/cancel, Settings reopen, plugin page restore and persistence.
It does not check pixels; the running app is the authority on how the overlay
looks.
No build step: client.js is the browser artifact, written against the module
table the app provides (react, react-dom).
License
MIT
