chendefine/dsh-sidebar-vscode ↗★ 0

dsh-sidebar-vscode

DSH web plugin: an official right-Sidebar tab type ('vscode') that embeds the VS Code web workbench opened at the current session workspace — same-origin by default through the plugin's built-in reverse proxy (/sidebar/vscode), or via a gateway subpath / any configured editor base URL. Editor selections land as atomic reference chips whose canonical mentions the host half expands into <text-selection> context at agent/pre-step; explorer files/folders land as path-only resource chips expanded into content-less <file-selection>/<folder-selection> markers. Chat-originated file opens (the sidebarRight openResource funnel), the collapsed column's expand button, and the settings page's open-document button are taken over into the workbench behind the openAsDefault switch; its configuration derives from the plugin entry's volatile Config schema (namespace 'dsh-sidebar-vscode', edited on the Plugins page). 适合需要在对话中直接编辑代码并发送代码片段到会话的开发者。

패키지
dsh-sidebar-vscode
호환성
미검증
Harness peer 범위
*
Cordis peer 범위
>=4.0.1-rc.1 <5
버전
0.3.3
라이선스
MIT
최근 업데이트
2026. 9. 28.

설치

$npx -p @deepseek-ai/dsh dsh plugin --profile web add github:chendefine/dsh-sidebar-vscode

Usage

Opening the tab

Expand the right sidebar and pick the VSCode 工作台 / VSCode workbench entry box on the guide ("开始") page — it opens in the guide tab's place. The layout is in-memory: a page refresh folds every session back to its collapsed default. The toolbar shows the workspace path;「⧉ open in new window」pops a standalone one.

Sending a selection

  1. Select code in the embedded editor (multi-cursor = one chip each);
  2. Right-click → "DSH: Send Selection to Session", or press Ctrl/Cmd+Alt+C;
  3. The atomic chip @src/main.ts L10-L12 appears in the composer — success is silent (the chip is the feedback); only degradations/failures flash an amber notice in the toolbar;
  4. Type and submit as usual. The chip is rewritten to the readable @path L10-L12, and the `` context is injected right after the message.

Selection reference details:

  • Dedup: within one step by (path, start, end) — sending the same selection twice injects one context; the same range with different content (file changed) keeps the newest capture;
  • Freshness: at submit the disk range is re-read confined to the session cwd and hash-compared — a mismatch marks stale="true"; a truncated snapshot instead verifies its kept head/tail halves (truncation alone never marks stale); an unsaved buffer marks dirty="true"; the snapshot text is always injected (no filesystem dependency), and the leading comment tells the model to re-read before editing;
  • Truncation: beyond maxLines (default 200) / maxBytes (default 20000, guards minified single-line files) the head and tail halves are kept with the middle omitted inline as ... (N lines omitted, L51-L150) ..., the tag carries truncated="true", and the real line range is preserved;
  • The context message source is { kind: 'vscode-mention', form: 'notice', version: 1, path, startLine, endLine, language?, contentHash, bytes, truncated, dirty, stale }.

Sending files / folders

Select files/folders in the explorer (multi- and mixed-select work), right-click → Send File/Folder to Session (the entry sits near "Copy Path"). One chip per item: @src/main.ts (file icon) or @src (folder icon); the kind comes from the extension's workspace.fs.stat (symlinks classify by target). On submit each expands to / with source { kind: 'vscode-resource', form: 'notice', version: 1, path, type }. Resource references do no freshness check and ignore the truncation caps; within one step they dedupe by (path, kind), and a selection reference and a resource reference on the same path stay independent.

Managing references

  • The rail above the composer lists every VS Code reference (truncated … badge, folder icon, ×N count); a tag's × removes all chips of that reference at once;
  • One backspace deletes a whole chip; once no mention of a reference remains in the draft, submit injects nothing for it;
  • Copying a (rendered) chip and pasting it back rebuilds atomic chips.

Settings

Settings derive from the plugin entry's volatile Config schema (src/config.ts) and are edited on the official Plugins page — 设置 → 插件 → dsh-sidebar-vscode 的配置区 (the bundle's own config form between its description and its rows) or the row's configure control: the settings service keys the derived section by the composition entry id dsh-sidebar-vscode, the browser half registers the SAME card in the two seats the Plugins page offers (plugins.bundle.config keyed by package name, plugins.row.config keyed #, both mounted while the Host serves the section), and every row commits through the shared config form (ctx.configForms: set/unset; the footer's "Reset to defaults" clears the user layer so each field re-inherits the composition base — the shipped base layer travels in cordis.patch.yml). Not hand-registered anywhere (pathMap below is served by the same section but deliberately has no card row):

KeyDefaultDescription
openAsDefaultfalseGates the three file-open takeovers (chat file clicks, the settings「打开配置文件」button, and the right-sidebar expand button). Off restores the official stock behavior everywhere
openBlocklist(unset = pdf, docx, xlsx, pptx, png, jpeg, jpg)"File types never opened in VS Code": an array of extensions rendered as a tag editor (tags carry a × remove button; a free-form input adds entries on Enter/comma, with a dropdown suggesting common binary types). A chat click on a matching file is NOT taken over — it falls through to the stock routing, where the official sidebar's viewers claim it (the builtin text preview today; future viewer plugins register their own official tab types). Unset = the seven defaults; an emptied list stores [], letting VS Code open everything (distinct meanings). Matching is case-insensitive, by "base name ends with ." (a.notpdf does not match pdf; entries may contain inner dots, e.g. tar.gz; extension-less files never match); settings are read per click, so edits apply immediately. The settings「打开配置文件」takeover is deliberately not affected
serverUrl(empty = http://127.0.0.1:8000)The full address code serve-web prints (base path and ?tkn= token included); empty = the default http://127.0.0.1:8000 (a bare local server). Whenever the proxy is reachable the workbench opens at the same-origin /sidebar/vscode/; a host-unreachable full URL falls back to a direct connection (same-origin bridge degrades); an explicit relative subpath (e.g. /vscode) is used with gateway semantics when the proxy is off
pathMap(empty = no mapping)Document-only — no card row (rare, split-container deployments). DSH prefix → VS Code container prefix as src=dst pairs joined by ;; longest source prefix wins; a path already under a destination passes through unchanged. When empty, no mapping is applied at all — the session cwd and clicked files open at their raw absolute paths (the same-container default). Rules are prefix rewriters, not a whitelist: absolute paths no rule matches pass through as-is (VS Code itself reports a genuinely missing file)
maxLines200 (range 1–2000)Max rendered code lines per reference; overflow keeps head+tail halves and marks the omitted middle inline
maxBytes20000 (range 1000–200000)UTF-8 byte cap per reference (guards minified single-line files)

(Selection injection itself is always on — no switch.) Number rows enforce their range as you type (red field + inline hint; out-of-range edits snap to the nearest bound on commit); text rows stack description-over-input; the openBlocklist row is tags + an inline input (junk flags a red hint, duplicate adds are silent no-ops). A read-only scope (memory-mode remote browser) disables every control and shows the effective values.

Troubleshooting

SymptomFix
The tab stays blank / the loading hint never clearsCheck serverUrl reachability; diagnose via "open in new window"; with a cross-origin URL the bridge is off by design (paste fallback still works). On the built-in proxy, confirm serve-web answers at the configured upstream (default http://127.0.0.1:8000; any base path works)
A file matching openBlocklist opens in the stock viewer instead of VS CodeA blocklist hit falls through to the official routing — the builtin text preview (or a future viewer plugin's type) claims it, never the Host OS opener. Remove the extension from the list if you want VS Code to open that type
"Workspace path is not absolute…" noticeFires only when the session cwd is not an absolute path (the workbench then opened its default view); healthy deployments never trigger it — no mapping needed
No DSH command in the context menu / paletteExtension not installed, serve-web not restarted (the manifest is scanned at startup only), or the workspace is untrusted (restricted mode) — see the FAQ in scripts/install-extension.md
No chip after sending; a code snippet appears on the clipboardLanding failed and the readable fallback reached the clipboard (no composer / cross-origin); paste it into the composer to recover chips
"Injected as a text reference…" noticeThe composer was mid-submit so the chip degraded to a plain-text mention — submitting works the same
Caret vanishes from the composer ~1s after creating a session, or focus jumps into the sidebar's open file after switching back from another workspace's session (older-version symptoms)The booted workbench focuses itself (Getting Started page on render, a restored editor on workspace restore): a boot behind a collapsed panel stole the caret invisibly, and the re-insertion reload a workspace switch-back triggers landed focus in the restored file right after the composer was autofocused. Current versions guard it generically — the first load is deferred until the tab has been seen, and every boot of the frame gets a focus fence that bounces uninvited grabs back unless the user actually clicks into the workbench (see "Focus guards" below); the first workbench load on expansion arrives slightly later by design