Read-only git workspace status chip for the dsh web composer: shows the current branch, ahead/behind counts, and dirty-file counts next to the input area — the DSH ↔ Claude Desktop parity feature requested upstream in deepseek-ai/deepseek-harness discussion #5073.
This plugin is a working reference implementation for that feature
request: it demonstrates the third-party client-plugin channel end to end
(node half + dsh.client browser half + SSE bridge), so maintainers can lift
the pattern if the feature is adopted upstream.
┌─────────────────────────────────────────────── composer ───┐
│ [main ↳ ↑3 ↓1 ●5] Ask anything… (send) │
└─────────────────────────────────────────────────────────────┘
- Node half runs
git status --porcelain=v2 --branchread-only (no mutation commands, ever) and serves the summarized snapshot over an SSE channel (/plugins/git-status), pushing a new frame only when the status changes. - Client half (browser) subscribes to the SSE channel and renders the chip
into the
conversation.composer.dockslot via the samectx.slots.registerAPI the built-in UI uses. The browser never runs git — it only renders the snapshot (the "UI only renders the snapshot" boundary). - Non-git fallback: a directory that is not a git repository renders
nothing; the node half reports a typed
not-a-repoframe instead of crashing or spamming.
# add to your dsh profile's user layer (cordis.patch.yml)
dsh plugin add @argszero/cordis-plugin-git-statusor insert into the user-layer cordis.patch.yml yourself:
plugins:
'@argszero/cordis-plugin-git-status': {}plugins:
'@argszero/cordis-plugin-git-status':
root: /absolute/path/to/repo # default: the dsh process cwd
intervalMs: 5000 # poll interval (min 500)
path: /plugins/git-status # SSE endpoint- The package declares
"dsh": { "client": { ... } }in package.json — theDshClientDeclarationschema (packages/client/modules/src/index.ts:55-69). - The
client-modulesnode half scans the host Loader entries for that declaration (index.ts:2-3), bundles the./clientexport, and serves it. - The browser boot loads the bundle through its own client-side Cordis
Loader (
packages/client/web/src/boot.ts:113-135). - The frozen module table (
packages/client/web/src/seed.ts) exposes@deepseek-ai/dsh-client-ui-slots, so the client half registers into the measured composer dock slot (packages/client/ui-conversation/src/client/ contract/slots.ts:131) exactly like the built-in StatsLine (packages/client/ui-chat/src/client/apply.ts:152-154). - The SSE bridge follows the in-tree
/plugins/eventschannel of@deepseek-ai/dsh-client-hmr.
npm install
npm run typecheck # strict tsc over both halves
npm test # parser unit tests + real-git-repo integration test
npm run build # esbuild bundles → lib/index.js (node) + lib/client.js (browser)Requires Node ^22.19 || >=24 (native TypeScript type stripping for tests).
MIT