Back to home

houlain

dsh-workspace-studio

DeepSeek Harness plugin: workspace file browser + code viewer + session change diff + per-hunk partial revert (Trae-style). Windows verified only; Linux/macOS untested — use with caution.

Stars
0
Language
TypeScript
Created
Aug 16, 2026
Updated
Aug 16, 2026

Introduction

dsh-workspace-studio

License: MIT Platform

⚠️ Platform status: Windows verified only. This plugin has been tested on Windows (PowerShell). It has NOT been verified on Linux or macOS — path handling, shell behavior, and sandbox interactions may differ on those platforms. Use with caution on non-Windows systems.

A DeepSeek Harness (dsh) plugin that turns the Web UI into a lightweight coding workspace with Trae-style partial revert:

  1. Workspace file browser — collapsible file tree; build-artifact noise filtered; folders containing changed files are auto-expanded with count badges; modified files are marked with a dot.
  2. Code viewer — click any file to view its content with line numbers.
  3. Change review (git-style diff) — every write / edit the agent makes is tracked with full before/after snapshots and rendered as line-level diff hunks, with live SSE updates.
  4. Per-hunk partial revert / accept — revert one change block at a time (like Trae), or mark it as accepted; resolved changes stop being shown and stop being marked. Conflict protection rejects reverts when the region was modified afterwards.

⚠️ Important notes

  • Windows-only (verified). Linux/macOS are unverified — use at your own risk on those platforms.
  • Change tracking is per session — a session only sees its own changes (by design).
  • Only write / edit tool calls are tracked. Direct file edits made outside those tools (e.g. in your own editor) are not recorded.

Install

From GitHub (recommended)

dsh plugin --profile web add github:houlain/dsh-workspace-studio

Then restart dsh web and open a new session.

Manually (no pnpm required)

  1. Copy the package into the profile's node_modules:

    $src = "<your-clone-path>\dsh-workspace-studio"
    $dst = "$env:USERPROFILE\.dsh\profiles\web\node_modules\dsh-workspace-studio"
    Copy-Item -Recurse -Force $src $dst
    
  2. Register it in the profile's package.json:

    {
      "dependencies": { "dsh-workspace-studio": "0.1.0" },
      "dsh": { "profile": { "bundles": ["@deepseek-ai/dsh-base", "@deepseek-ai/dsh-web-app", "dsh-workspace-studio"] } }
    }
    
  3. Restart dsh web.

The package ships pre-built (lib/), so no build step is needed for installation. The installed copy must be a copy, not a symlink into a directory you keep editing — rebuild and re-copy after updating.

Usage

  1. Open a session in the Web UI and switch to the 「Studio」 tab (next to Chat).
  2. The left pane shows the workspace file tree:
    • Folders are collapsible ( / ); folders containing pending changes show a count badge and auto-expand.
    • Files modified by the agent carry a marker.
  3. Click a file to view its content (top-right) and its change panel (bottom-right).
  4. Each change operation shows one or more change blocks (hunks) with two actions:
    • 「撤回此块」(Revert this block) — undoes only that block; other blocks stay. A confirm dialog appears, then the file is rewritten on disk.
    • 「认可」(Accept) — keeps the change; the block stops being shown/marked and can no longer be reverted.
  5. 「撤回全部修改」(Revert all) restores the file to its state before this session's first recorded change (files created in this session are deleted).
  6. 「清空」(Clear) removes this session's change records (does not touch file contents).
  7. The Studio tab label shows a badge with the number of files that still have pending changes; it and all markers update in real time via SSE when the agent edits files.

Revert safety rules

  • A hunk can only be reverted if its exact lines are still present in the file. If a later change modified that region, the revert is rejected with a hint (conflict protection).
  • A hunk that was reverted or accepted cannot be acted on again.
  • Reverting a hunk of an old operation works even when later operations shifted line numbers elsewhere.

Architecture

One package, two halves (dsh.bundle + dsh.client manifests), mounted as a single loader entry:

dsh-workspace-studio/
├── src/
│   ├── core/        # Pure logic, zero deps, fully unit-tested
│   │   ├── diff.ts       # LCS line diff → hunks with context
│   │   ├── ledger.ts     # before/after snapshot ledger + persistence
│   │   ├── hunkRevert.ts # per-hunk reverse apply + conflict detection
│   │   └── fileTree.ts   # tree builder with ignore rules
│   ├── host/        # Node half: tools/result listener, HTTP/SSE routes, ctx.fs
│   ├── client/      # Browser half: Studio view (React, no external deps)
│   └── shared/      # Payload types shared by both halves
├── lib/             # Pre-built bundles (lib/index.js host, lib/client.js browser)
└── tests/           # 67 tests (node:test, no test framework dependency)

HTTP routes (same-origin, all under /ws-studio/*)

RouteMethodPurpose
/ws-studio/tree?root=GETWorkspace file tree
/ws-studio/file?path=GETFile content (size-capped)
/ws-studio/ops?session=GETChange operations with hunks (pending only in the file list)
/ws-studio/revert?session=POSTRevert one hunk, or the whole file (no op/hunk)
/ws-studio/accept?session=POSTAccept one hunk
/ws-studio/clear?session=POSTClear the session's change records
/ws-studio/context?session=GETSession working directory
/ws-studio/eventsGET (SSE)Live change notifications

Data & persistence

  • Change snapshots persist to <profile-dir>/ws-studio-state.json (e.g. ~/.dsh/profiles/web/ws-studio-state.json), debounced, atomic write, flushed on exit.
  • Per-file capacity guards: max 100 operations per file, 120 KB per snapshot (oversized operations are recorded without content — visible but not revertible).

Sandbox awareness

  • Revert writes go through the harness filesystem service (ctx.fs) with a session-level sandbox policy (workspace-write + the session's workspace root), so writes outside the session workspace are rejected by the harness sandbox itself.
  • File tree and reads also go through ctx.fs when available (fallback: node:fs).

Security & privacy

  • No telemetry, no analytics, no external network calls. All routes are same-origin; the plugin never contacts any third-party server.
  • The plugin does not read or store credentials, API keys, environment secrets, or OS/user metadata.
  • The only data stored on disk is the change ledger (file paths + file contents that were edited during a session) plus UI state.
  • Sandbox policies of the harness still apply to revert writes.

Configuration

The file tree ignores common noise by default (.git, node_modules, dist, build, lockfiles, coverage, etc.). The ignore list lives in src/core/fileTree.ts (DEFAULT_TREE_OPTIONS) — rebuild if you want to customize it.

Development

Requirements: Node.js ≥ 22.6 (tests run via Node's native TypeScript type-stripping — no build needed for tests), npm.

npm install        # dev dependency: esbuild
npm run build      # bundles lib/index.js (host) + lib/client.js (browser)
npm test           # 67 tests via node --test

Notes for contributors:

  • The browser half uses React.createElement (no JSX) and a tiny local react stub under node_modules/react so tests can assert the rendered element tree without a DOM. Do not delete the stub; a real npm install react would replace it.
  • Code must stay erasable-syntax TypeScript (no enums, no parameter properties) so Node's type-stripping can run the tests directly.
  • Relative imports use explicit .ts extensions (NodeNext).

Known limitations

  • Platform: verified on Windows only; Linux/macOS untested — use with caution.
  • Change tracking is per-session and covers only write/edit tool calls.
  • Diff is line-based LCS; hunk display is simplified (no intra-line character diff).
  • Reverting a middle hunk of an old operation requires the region's lines to still be intact; overlapping later edits reject the revert.
  • Whole-file revert restores the state before the session's first recorded operation on that file.
  • Very large files (> 2 MB) are refused by the viewer; oversized change snapshots (> 120 KB) are not revertible.

License

MIT © 2026 houlain