dsh-vscode-plugin
v0.1.3
Published
High-performance code viewer plugin for DSH: file tree, git status/diff/log, code search, Ctrl+P file search
Readme
dsh-vscode-plugin
A VS Code–style workbench plugin for DeepSeek Harness (DSH). It embeds a full code browser — file tree, multi-tab Monaco editor, Git SCM panel, terminal, and code search — into the DSH web GUI.
Published on npm as dsh-vscode-plugin.
Features
- Workbench layout — activity bar, sidebar, multi-tab editor area, bottom panel, status bar
- File tree — lazy-loading tree of the current workspace (hides
.gitand dotfiles) - Monaco editor — syntax-highlighted file editing with tab bar and dirty indicators
- Git SCM panel — staged / unstaged / untracked / conflict groups, stage/unstage/discard, commit
- Git sync — Push / Pull / Sync (pull + push) / Fetch actions in the SCM panel, plus a status-bar sync button with ahead/behind counts (
↑1 ↓2) - Branch picker — click the branch name in the status bar to switch branches or create a new one (
git checkout -b); remote branches are checked out as local tracking branches - Git diff — click a changed file to open a Monaco DiffEditor tab in the main editor area (side-by-side)
- Git log — commit history with author, date, subject
- Code search —
git grepwith debounced query and grouped results - Terminal — integrated xterm.js panel (resizable)
- Ctrl+P / Cmd+P — global fuzzy file search overlay
- State persistence — open tabs and file-tree expansion restored per workspace (IndexedDB)
Keyboard shortcuts
| Shortcut | Action |
|----------|--------|
| Ctrl+P / Cmd+P | Fuzzy file search overlay |
| Ctrl+S / Cmd+S | Save the active file |
| Ctrl+Enter (in commit input) | Commit |
| Ctrl+Shift+G / Cmd+Shift+G | Open the Source Control view |
| Ctrl+Shift+S / Cmd+Shift+S | Sync Changes (pull + push) |
| Ctrl+Shift+U / Cmd+Shift+U | Git: Push |
| Ctrl+Shift+D / Cmd+Shift+D | Git: Pull |
(Shortcuts are ignored while typing in an input/textarea, so they never fight the commit message box.)
Install
Prerequisites
- DSH installed (
dshCLI available) pnpmon PATH (thedsh plugincommand forwards to pnpm)
1. Install the plugin
Recommended — dsh plugin:
dsh plugin --profile web add dsh-vscode-pluginThis installs the package into the profile and registers it as a profile
bundle automatically: the host half (DshVscodeGateway) is added to the
profile's layer stack, and the client half is injected via the package's
dsh.client declaration. No manual cordis.patch.yml edit is needed.
Install a specific version or channel:
dsh plugin --profile web add [email protected] # latest stable
dsh plugin --profile web add dsh-vscode-plugin@beta # beta channelAlternative — npm install:
cd ~/.dsh/profiles/web
npm install dsh-vscode-plugin2. Register the plugin (only for the npm install method)
With dsh plugin add, skip this step. For the npm install method, add the
following to ~/.dsh/profiles/web/cordis.patch.yml (create the file if it
does not exist):
- insert:
- id: dsh-vscode
name: 'dsh-vscode-plugin'Or apply the patch from this repo:
dsh --profile web --patch /path/to/dsh-vscode/cordis.patch.yml3. Start DSH
dsh webOpen the URL shown in the terminal (default http://127.0.0.1:3080). A Code button appears in the sidebar footer; click it to open the workbench. Ctrl+P / Cmd+P opens the file search overlay.
Upgrade
dsh plugin --profile web add dsh-vscode-plugin@latest
# restart dsh web, then hard-refresh the browser (Cmd+Shift+R)Uninstall
dsh plugin --profile web remove dsh-vscode-plugin
# for the npm install method: cd ~/.dsh/profiles/web && npm uninstall dsh-vscode-plugin
# then remove the dsh-vscode entry from cordis.patch.ymlTroubleshooting
| Symptom | Cause | Fix |
|---------|-------|-----|
| Git diff shows "transport failure" / 404 | Old gateway without gitDiffContents | Upgrade to 0.1.1+, restart dsh web |
| git push / pull / fetch fail with cannot open '.git/FETCH_HEAD': Operation not permitted | The sandboxing shell executor falls back to the deployment policy (rooted at the dsh process cwd) when no explicit sandboxPolicy is passed, so git's .git writes are denied | Upgrade to a build with the gateway fix (git commands now pass the workspace/git root as the writable root, same as writeFile), then restart dsh web |
| git push / pull fail with could not read Username for 'https://github.com' / failed to get: -67674 | Git needs credentials but the workbench runs git non-interactively (no TTY) and the sandbox blocks the macOS keychain, so neither the prompt nor osxkeychain can supply credentials | The workbench now shows an authentication input dialog (VS Code style): enter your GitHub username + Personal Access Token once; the gateway keeps it in memory for the session and injects it into git via an inline credential.helper. If you cancel, the toast shows the manual one-time setup (credential.helper store) and SSH alternatives |
| UI changes not visible after upgrade | Browser cache | Hard refresh (Cmd+Shift+R) and restart dsh web |
| Plugin button missing | Not registered in cordis.patch.yml | Run dsh plugin --profile web add dsh-vscode-plugin or add the plugin entry (see above) |
Architecture
Browser (client) Host (Node.js)
──────────────── ─────────────
React Workbench UI DshVscodeGateway
├─ FileTree / GitPanel ├─ @Remote readFile / writeFile / listDir
├─ DshVscode (Monaco editor) ├─ @Remote gitStatus / gitDiffContents / gitLog
├─ MonacoGitDiff (DiffEditor) ├─ @Remote gitStage / gitCommit / searchCode
├─ TerminalPanel └─ ctx.shell (git) + ctx.fs (files)
└─ CodeSearch
│
└────── Typert Remote RPC ───────────────▲
ctx.remote.dshVscode.*The host half (DshVscodeGateway) extends TypertRemoteService and runs git via ctx.shell and file I/O via ctx.fs. The client half mounts a TypertRemoteContribution and calls ctx.remote.dshVscode.*.
Directory layout
src/
├── index.ts # Host entry — exports DshVscodeGateway (Cordis class plugin)
├── gateway.ts # DshVscodeGateway — @Remote methods
├── types.ts # Shared wire types
├── typert/
│ ├── host.ts # TYPERT host manifest
│ ├── remote-client.ts # TYPERT remote contribution + type augmentation
│ └── schemas.ts # Zod wire schemas
└── client/
├── index.ts # Client entry — apply() / inject()
├── locale/{zh,en}.ts # i18n dictionaries
└── components/
├── CodeBrowserEntry.tsx # Sidebar footer "Code" button + overlay portal
├── GitPanel/GitPanel.tsx # Git SCM panel (stage, commit, file list)
├── DshVscode/DshVscode.tsx # Monaco single-file editor
└── Workbench/
├── Workbench.tsx # Main layout (activity bar, sidebar, editor, panel)
├── EditorArea.tsx # Multi-tab editor region
├── MonacoGitDiff.tsx # Monaco DiffEditor for git diffs
└── TerminalPanel.tsx # Integrated terminalBuild (from source)
cd dsh-vscode
npm install
npm run build # tsc (host) + client bundle + typert manifests + workersOutputs land in lib/ (index.js, gateway.js, client.js, typert.*).
Local debug (symlink)
For iterative development without publishing:
npm run build
ln -sf "$(pwd)" ~/.dsh/profiles/web/node_modules/dsh-vscode-plugin
dsh --profile web --patch "$(pwd)/cordis.patch.yml"
dsh webRebuild after source changes:
npm run build:client # client UI only
node scripts/build-typert.mjs # typert manifests onlyRestart dsh web after host (gateway.js) changes.
Performance roadmap (planned)
| Technique | Status | Purpose |
|-----------|--------|---------|
| Virtual scrolling | planned | File tree / diff / log for 10K+ files |
| DedicatedWorker (shiki) | planned | Offload syntax highlighting |
| WASM (Myers diff, fuzzy) | planned | Accelerate diff + fuzzy search |
| IndexedDB cache | planned | Persist file contents + git data |
| Streams (fs.streamText) | planned | Large-file incremental reads |
| Service Worker | planned | Offline + app-shell cache |
| SharedWorker + Web Locks + BroadcastChannel | planned | Multi-tab sync |
| requestIdleCallback | planned | Background search index |
| Performance API | planned | mark/measure instrumentation |
License
MIT
