dsh-workspace-ide 0.0.0-stage → 1.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 echoVic
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,250 @@
1
- # Temporary Holding Version
1
+ # dsh-workspace-ide
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ [![test](https://github.com/echoVic/dsh-workspace-ide/actions/workflows/test.yml/badge.svg)](https://github.com/echoVic/dsh-workspace-ide/actions/workflows/test.yml)
4
+ [![license](https://img.shields.io/github/license/echoVic/dsh-workspace-ide)](LICENSE)
5
+
6
+ A VS Code-like workspace panel plugin for
7
+ [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) (DSH): browse the
8
+ workspace, search it, and read its git state without leaving the conversation.
9
+
10
+ ![Files: tree + line-numbered editor with save](docs/screenshot-files.png)
11
+
12
+ | Surface | What it does |
13
+ |---|---|
14
+ | **Files** | Lazy directory tree for the whole workspace, resizable split, line-numbered **syntax-highlighted** code viewer with **git change marks in the gutter**, **clickable breadcrumbs**, **soft-wrap** (`Alt+Z`), **go-to-line** (`Ctrl/Cmd+G`), **in-file find & replace** (`Ctrl/Cmd+F` / `Ctrl/Cmd+H`, case/whole-word/regex, all-match highlight), **quick open** (`Ctrl/Cmd+P`), **multi-tab editing** with per-tab drafts and unsaved-change guards (`Ctrl/Cmd+W` closes), **back/forward navigation** (`Ctrl/Cmd+Alt+←/→`) a JetBrains-style status bar and **editor zoom** (`Ctrl/Cmd+=` / `-`, `Ctrl/Cmd+0` resets), inline editing with `Ctrl/Cmd+S` save, selection-aware `Tab` indentation, `Ctrl/Cmd+D` duplicate-line, `Alt+Shift+↑/↓` move-line, `Ctrl/Cmd+Shift+T` reopen-closed-tab, **bracket matching / auto-pair / smart indent / indent guides / current-line highlight** and `Cmd/Ctrl+/` comment toggling, rendered **Markdown preview** with source toggle, **image / SVG preview**, large-file/binary guards |
15
+ | **Search** | Full-text workspace search with case / regex / whole-word toggles and an include filter; hits are grouped per file, highlighted, and jump straight to the matching line in the viewer |
16
+ | **Git** | Current branch with ahead/behind, staged / unstaged / untracked / conflicted groups with colourised unified diffs, and a commit history with per-commit diffs; a non-git workspace lists other git workspaces for one-click switching |
17
+
18
+ ### Colour themes
19
+
20
+ The panel ships the mainstream VS Code palettes and switches between them without touching
21
+ the rest of the DSH UI:
22
+
23
+ | Selection | Palette |
24
+ |---|---|
25
+ | **Follow DSH theme** (default) | the live `--dsw-alias-*` values, so it matches the app light/dark theme |
26
+ | **Dark+** | VS Code's default dark palette |
27
+ | **Light+** | VS Code's default light palette |
28
+ | **One Dark Pro** | Atom's One Dark |
29
+ | **Dracula** | the official Dracula palette |
30
+ | **GitHub Dark** | GitHub's dark palette |
31
+ | **Solarized Light** | Ethan Schoonover's Solarized Light |
32
+
33
+ ![Theme picker with all VSCode palettes](docs/screenshot-themes.png)
34
+
35
+ > All screenshots in this README are rendered from a **synthetic demo workspace**
36
+ > (`aurora-dashboard`) with mock files, git history and diffs — never real user data.
37
+ > They are generated reproducibly by
38
+ > [`scripts/screenshots/build-screenshots.py`](scripts/screenshots/build-screenshots.py),
39
+ > which mounts the real client bundle against a stubbed fetch layer.
40
+
41
+ Each theme is a table of `--dsw-alias-*` custom-property overrides scoped to the panel root;
42
+ every surface (tree, editor gutter, search highlights, git diff colours, scrollbars) follows
43
+ the selection, and the choice is remembered in `localStorage`. The toolbar glyphs are
44
+ borderless — an inactive tab is just the icon, the active tab is a rounded background, and
45
+ the focus ring appears only for keyboard navigation.
46
+
47
+ ![Dracula theme](docs/screenshot-theme-dark.png)
48
+ ![Light+ theme](docs/screenshot-theme-light.png)
49
+
50
+ ### Syntax highlighting
51
+
52
+ The editor colours code with a small, dependency-free highlighter written for this panel —
53
+ no Shiki/Prism bundle and no extra runtime dependency (the whole browser half still only
54
+ requires `react`). It covers every language the Host reports: JavaScript / TypeScript /
55
+ JSX / TSX, JSON, Markdown, CSS, HTML/XML, Python, Go, Rust, Java, Kotlin, Swift, C/C++, C#,
56
+ Ruby, PHP, Shell, PowerShell, YAML, TOML, INI, SQL, GraphQL and the tag level of
57
+ Vue/Svelte; unknown files and files over 300 KB fall back to plain text for rendering speed.
58
+
59
+ Token colours follow the selected palette: **Follow DSH theme** inherits the app's own
60
+ `--shiki-token-*` colours (so it matches the surrounding light/dark UI), and each VSCode
61
+ theme ships its own keyword / string / comment / number / function / type / variable table.
62
+
63
+ The editor stays editable while highlighted: a transparent-text `textarea` sits over the
64
+ syntax-coloured layer, with caret, selection, both scroll axes and the line-number gutter
65
+ kept in sync. Read-only previews reuse the same coloured rendering.
66
+
67
+ Editing keeps the VSCode muscle memory: **`Cmd/Ctrl+/` toggles comments** for the current
68
+ line or every selected line (the per-language token table covers `//`, `#`, `--`, `;` and
69
+ `/* */` / `<!-- -->` block wrapping for CSS, HTML, XML, Markdown, Vue and Svelte), and the
70
+ toggle is reversible, indent-preserving and leaves blank lines untouched.
71
+
72
+ ### Editor: JetBrains-style workflow
73
+
74
+ Beyond editing and saving, the viewer follows the interactions JetBrains IDEs made
75
+ standard:
76
+
77
+ - **Find & replace** (`Ctrl/Cmd+F` / `Ctrl/Cmd+H`) with match counter, previous/next,
78
+ case / whole-word / regex toggles, Replace and Replace All, and a highlight layer that
79
+ paints every match behind the text.
80
+ - **Quick Open** (`Ctrl/Cmd+P`) ranks the whole workspace file index locally with a fuzzy
81
+ subsequence score; **Go to Symbol** (`Ctrl/Cmd+Shift+O`) jumps to functions, classes,
82
+ types, constants and (in Markdown/JSON) headings or keys in the current file
83
+ (`Alt+↑/↓` walks symbols; the header shows the enclosing symbol);
84
+ **Recent Locations** (`Ctrl/Cmd+Shift+E`) reopens any earlier file:line,
85
+ **bookmarks** (`F11` / `Shift+F11`) mark and revisit lines, and **case toggle** /
86
+ **join lines** round out the editing shortcuts.
87
+ - **Tabs** keep one tab per open file with dirty markers; unsaved drafts and carets survive
88
+ tab switches, and closing a dirty tab asks before discarding.
89
+ - **Bracket matching / auto-pair / smart indent / current line / indent guides** make the
90
+ same gestures feel native: matched brackets highlight, openers auto-close, Enter inherits
91
+ indentation, and Shift+Tab outdents.
92
+
93
+ ![Find & replace with match counter and all-match highlight](docs/screenshot-find.png)
94
+
95
+ ![Quick Open palette](docs/screenshot-quick-open.png)
96
+
97
+ ![Multi-tab editing with dirty marker and unsaved-change hint](docs/screenshot-tabs.png)
98
+
99
+ ![Bracket matching, current line and indent guides](docs/screenshot-brackets.png)
100
+
101
+ ### Markdown preview
102
+
103
+ `.md` files switch between editable source and a rendered preview from the file header, or
104
+ with `Cmd/Ctrl+Shift+V`. The preview is built from React elements — never injected HTML — and
105
+ covers headings, fenced code blocks (highlighted by the same engine, in the selected theme),
106
+ ordered/unordered and task lists, blockquotes, GFM tables, links, images and rules;
107
+ `javascript:`/`data:` URLs are dropped. It renders the current draft, so unsaved edits
108
+ preview immediately, and read-only/oversized Markdown files still preview.
109
+
110
+ ![Markdown preview with source toggle](docs/screenshot-markdown.png)
111
+
112
+ ### Images and SVG
113
+
114
+ Raster images (PNG, JPEG, GIF, WebP, BMP, ICO, AVIF) open in a centred preview over a
115
+ checkerboard surface, with the file's natural dimensions and size in the status bar. SVGs
116
+ get both a rendered preview and editable source, switchable with the `图片 / 源码` toggle or
117
+ `Cmd/Ctrl+Shift+V`; the preview is rendered from the current source, so editing the SVG
118
+ updates the picture immediately. Image bytes come from a dedicated Host route that verifies
119
+ every file against its magic number and caps reads at 8 MiB.
120
+
121
+ ![Image preview](docs/screenshot-image.png)
122
+ ![SVG preview with image/source toggle](docs/screenshot-svg.png)
123
+
124
+ ![Files: syntax-highlighted editor](docs/screenshot-files.png)
125
+
126
+ The panel opens from the left rail (**工作区 / Workspace**, next to *Plugins*, *Scheduled
127
+ tasks*, *Usage stats*). The three-icon strip at the top switches between Files / Search /
128
+ Git — the file-copy, list-search and git-branch activity icons. The workspace picker on
129
+ the right follows the session the app is currently viewing, and a manual pick sticks for
130
+ that session.
131
+
132
+ ![Search: grouped hits with highlights](docs/screenshot-search.png)
133
+
134
+ ![Git: commit history and coloured diff](docs/screenshot-git.png)
135
+
136
+ ![Git: a non-repository workspace offers git workspaces to switch to](docs/screenshot-git-empty.png)
137
+
138
+ ## Install
139
+
140
+ From a DSH session, install the bundle from this directory with the plugin manager
141
+ (absolute path required):
142
+
143
+ ```
144
+ plugin_manager {
145
+ action: "install_bundle",
146
+ target: "/absolute/path/to/dsh-workspace-ide"
147
+ }
148
+ ```
149
+
150
+ The bundle is profile-wide and survives restarts. `application: "applied"` in the result
151
+ means it activated immediately; client-side changes are picked up by DSH's client HMR,
152
+ host-side changes load on the next Host start.
153
+
154
+ Or install straight from GitHub instead of a local checkout:
155
+
156
+ ```text
157
+ plugin_manager { action: "install_bundle", target: "echoVic/dsh-workspace-ide" }
158
+ # or pin a release tarball:
159
+ plugin_manager { action: "install_bundle", target: "https://github.com/echoVic/dsh-workspace-ide/archive/refs/tags/v1.0.0.tar.gz" }
160
+ ```
161
+
162
+ ## How it works
163
+
164
+ - **Host half** (`lib/index.js`, `lib/host/*.js`): registers nine authenticated fetch
165
+ routes through `ctx.connection.fetch.register` — `workspaces`, `list`, `files`, `file`,
166
+ `image`, `search`, `git`, `save`, `ping`. Filesystem access is path-checked (absolute paths, `..` escapes,
167
+ symlink escapes and roots outside known workspaces are rejected); everything is
168
+ read-only except `save` (atomic overwrite of an existing regular file only) and `ping`
169
+ (one diagnostic line in `$DSH_HOME/workspace-ide/status.jsonl`, used by the client to
170
+ prove it executed). Git runs through `child_process.execFile` with bounded output; a
171
+ non-repository root is a normal answer, not an error.
172
+ - **Client half** (`lib/client.js`, generated from `src/client/*.js` + compiled
173
+ TypeScript fragments by `scripts/build-client.mjs`): one `window.__ModuleLoader__.load(...)` browser module that
174
+ registers a `sidebar.panellist` icon and the matching keyed `main` panel. It only uses
175
+ `require('react')`, the `--dsw-alias-*` theme tokens (dark and light), a built-in zh/en
176
+ dictionary, and the DSH frame's `--dsh-frame-*` chrome insets; the page is wrapped in an
177
+ error boundary. The panel follows the viewed session's workspace via the slot kit's
178
+ `useWorkspaces` hook, and falls back safely when that hook is absent.
179
+ - **Icons**: the whole toolbar/tree/git/theme icon set is the open-source
180
+ [Lucide](https://lucide.dev) set (ISC, with Feather-derived glyphs under MIT). Its SVG
181
+ node data is vendored at authoring time in `src/client/05-icons.ts` — no runtime icon
182
+ dependency — and renders through one factory so every glyph shares the 24px grid, round
183
+ caps and `currentColor` stroke. Licenses: [`THIRD_PARTY_NOTICES.md`](THIRD_PARTY_NOTICES.md),
184
+ [`licenses/lucide-LICENSE.txt`](licenses/lucide-LICENSE.txt).
185
+
186
+ ## Development
187
+
188
+ ```bash
189
+ npm ci # dev-only tooling: TypeScript type checker
190
+ npm run typecheck # tsc --checkJs, strict, over lib/ + src/client + scripts + tests (no emit)
191
+ npm run typecheck:host # lib/ additionally under noImplicitAny (see tsconfig.host.json)
192
+ npm run typecheck:client # all client sources under noImplicitAny (tsconfig.client.json)
193
+ node scripts/build-client.mjs # rebuild lib/client.js from src/client/ (.js + compiled .ts)
194
+ node scripts/build-client.mjs --check # fail when lib/client.js is stale
195
+ node --check lib/client.js
196
+ node --test test/host/ # Host route unit tests (node:test, 118)
197
+ node test/smoke/client-smoke.mjs # headless client module/face smoke test (43 checks)
198
+ node --test test/review/*.test.mjs # independent adversarial + contract suites (78)
199
+ python3 scripts/screenshots/build-screenshots.py # rebuild docs/ screenshots (mock data)
200
+ ```
201
+
202
+ TypeScript is used **only as a dev-time type checker**: sources stay plain JavaScript with
203
+ JSDoc annotations, and `tsc --noEmit --checkJs` checks `lib/`, `src/client/`, `scripts/` and
204
+ the tests with `strict: true` (the one deferred strict flag is `noImplicitAny`, see
205
+ `CONTRACT.md`). `types/client-globals.d.ts` declares the shared factory scope and the React
206
+ element alias; `types/dsh-services.d.ts` declares the optional Host context/services.
207
+ There is still no client bundler, no build step for the Host and no runtime dependency —
208
+ `npm ci` installs `typescript`, `@types/node` and `@types/react` into devDependencies only.
209
+
210
+ The client half is authored in TypeScript: script-style fragments in
211
+ `src/client/*.ts` compiled by `tsc` into `build/client-parts/` (never shipped,
212
+ git-ignored) and concatenated into one plain script — still no bundler, and
213
+ `lib/client.js` keeps its exact loader contract.
214
+
215
+ `lib/client.js` is served directly by the Host and DSH's client HMR watches installed
216
+ bundle artifacts, so saving a rebuilt `lib/client.js` updates an open Harness page without
217
+ a restart.
218
+
219
+ ## Layout
220
+
221
+ ```
222
+ lib/index.js Host plugin entry (`apply`, `inject`, `name`)
223
+ lib/host/ filesystem / search / git route implementation
224
+ lib/client.js built browser module (committed)
225
+ tsconfig.json dev-only type checker config (allowJs + checkJs, strict, no emit)
226
+ tsconfig.host.json Host-only config adding noImplicitAny
227
+ tsconfig.client.json all client sources under noImplicitAny
228
+ types/ ambient declarations: client factory scope + Host context/services
229
+ src/client/ browser sources (TS): core, icons (vendored Lucide), highlighter,
230
+ shell, files, search, git, module face
231
+ THIRD_PARTY_NOTICES.md icon license attribution
232
+ licenses/ full third-party license texts
233
+ scripts/build-client.mjs concatenating build + staleness check
234
+ test/host/ node:test suites (122 tests)
235
+ test/smoke/ headless client-module smoke test (43 checks)
236
+ test/review/ independent adversarial + client-contract suites (78 tests)
237
+ docs/ screenshots
238
+ ```
239
+
240
+ ## Changelog
241
+
242
+ Release history and feature milestones: [CHANGELOG.md](CHANGELOG.md).
243
+
244
+ ## License
245
+
246
+ [MIT](LICENSE) © 2026 echoVic.
247
+
248
+ The vendored Lucide icon set (and the Feather-derived glyphs inside it) keep their own
249
+ licenses — full texts and attribution are in [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md)
250
+ and [licenses/](licenses/).
@@ -0,0 +1,19 @@
1
+ # Third-party notices
2
+
3
+ ## Lucide icons
4
+
5
+ `src/client/05-icons.js` vendors the SVG node data of the following
6
+ [Lucide](https://lucide.dev) icons (lucide-static v0.460.0) so the client bundle
7
+ stays a single plain-JavaScript module with `react` as its only runtime import:
8
+
9
+ `files`, `text-search`, `git-branch`, `folder`, `file`, `chevron-right`,
10
+ `refresh-cw`, `save`, `x`, `triangle-alert`, `lock`, `circle`,
11
+ `loader-circle`, `folder-tree`, `palette`, `check`
12
+
13
+ Lucide is licensed under the ISC License; the icons listed as derived from the
14
+ Feather project (`chevron-right`, `circle`, `lock`, `x`, …) additionally carry
15
+ the Feather MIT License. The full license texts ship in
16
+ [`licenses/lucide-LICENSE.txt`](licenses/lucide-LICENSE.txt).
17
+
18
+ The plugin's own layout, styles and remaining glyph composition are original to
19
+ this package (`dsh-workspace-ide`, MIT).
@@ -0,0 +1,8 @@
1
+ # Bundle patch layer for dsh-workspace-ide.
2
+ #
3
+ # One row inserts this package into the profile's Loader tree. The row `name`
4
+ # is the module specifier, which is also what the client module scan keys on —
5
+ # it must equal the package name in package.json.
6
+ - insert:
7
+ - id: workspace-ide
8
+ name: 'dsh-workspace-ide'
package/icon.svg ADDED
@@ -0,0 +1,8 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none">
2
+ <g stroke="#7aa2f7" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round">
3
+ <path d="M20 10a1 1 0 0 0 1-1V6a1 1 0 0 0-1-1h-2.5a1 1 0 0 1-.8-.4l-.9-1.2A1 1 0 0 0 15 3h-2a1 1 0 0 0-1 1v5a1 1 0 0 0 1 1Z" />
4
+ <path d="M20 21a1 1 0 0 0 1-1v-3a1 1 0 0 0-1-1h-2.9a1 1 0 0 1-.88-.55l-.42-.85a1 1 0 0 0-.92-.6H13a1 1 0 0 0-1 1v5a1 1 0 0 0 1 1Z" />
5
+ <path d="M3 5a2 2 0 0 0 2 2h3" />
6
+ <path d="M3 3v13a2 2 0 0 0 2 2h3" />
7
+ </g>
8
+ </svg>