dsh-code-server-app 0.3.58 → 0.3.63
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-Apache-2.0.txt +201 -0
- package/README.en.md +215 -98
- package/README.md +186 -94
- package/THIRD_PARTY_NOTICES.md +60 -0
- package/assets/extensions/dshcs-editor-bridge/extension.js +192 -222
- package/assets/extensions/dshcs-editor-bridge/lib/bridge-client.js +43 -39
- package/assets/extensions/dshcs-editor-bridge/lib/fim-completion.js +264 -0
- package/assets/extensions/dshcs-editor-bridge/package.json +2 -2
- package/lib/bridge-session.mjs +55 -5
- package/lib/bridge.mjs +14 -7
- package/lib/client.js +1061 -90
- package/lib/fim-adapter.mjs +603 -0
- package/lib/index.js +366 -205
- package/package.json +21 -41
- package/vendor/VENDOR.json +5 -5
- package/assets/extensions/dshcs-editor-bridge/lib/ask-panel.js +0 -416
- package/assets/extensions/dshcs-editor-bridge/webview/THIRD-PARTY.md +0 -22
- package/assets/extensions/dshcs-editor-bridge/webview/src/app.jsx +0 -242
- package/assets/extensions/dshcs-editor-bridge/webview/src/approval.jsx +0 -61
- package/assets/extensions/dshcs-editor-bridge/webview/src/official-tokens.css +0 -576
- package/assets/extensions/dshcs-editor-bridge/webview/src/panel.css +0 -380
- package/assets/extensions/dshcs-editor-bridge/webview/src/thread.jsx +0 -160
- package/assets/extensions/dshcs-editor-bridge/webview/thread.css +0 -1
- package/assets/extensions/dshcs-editor-bridge/webview/thread.js +0 -465
package/README.en.md
CHANGED
|
@@ -12,10 +12,12 @@
|
|
|
12
12
|
|
|
13
13
|
A static profile plugin (npm package with host + client bundle) that ships the **VS Code server tree** from a [code-server](https://github.com/coder/code-server) release as a **platform-independent dependency package** (pack-time artifact `vendor/vscode` → `@jinsiyu/dshcs-vscode-server`, no install scripts, no postinstall). The code-server **Node service layer is replaced by the plugin's own `lib/launcher.mjs`**: it drives `<tree>/lib/vscode/out/server-main.js` (`loadCodeWithNls()` / `createServer()` / `handleRequest()` / `handleUpgrade()`) directly and re-adds the few HTTP endpoints code-server used to provide (`/healthz`, `/manifest.json`, `/_static/*`, `/proxy/:port`). The 16 native modules (node-pty / @vscode/sqlite3 / spdlog / …) come from `@jinsiyu/dshcs-*` sub-packages declared **directly on the plugin's dependency table** under their real names (os/cpu-gated per target), with the original import names restored by runtime junctions. VS Code's inner dependencies and the prebuilt native modules are **all installed by the package manager together with the plugin** — no global npm install, no `bin` configuration, no profile config changes, no second install command, **no argon2/C++ toolchain**.
|
|
14
14
|
|
|
15
|
-
>
|
|
16
|
-
>
|
|
17
|
-
>
|
|
18
|
-
>
|
|
15
|
+
> **The "ask DSH" dialog** renders the session's new content with **DSH's own Markdown renderer** and can
|
|
16
|
+
> **answer approval requests in place** (writing outside the workspace / running commands). The panel is a
|
|
17
|
+
> hand-written React component inside `lib/client.js`: it requires `react-dom/client` and
|
|
18
|
+
> `@deepseek-ai/dsh-client-ui-primitives` straight from the DSH page's module table (the very instance the UI
|
|
19
|
+
> uses), so typography, highlighting and math match the UI and a renderer version mismatch is impossible.
|
|
20
|
+
> There is **no build step anywhere on that chain**. See "Working with DSH: the editor bridge".
|
|
19
21
|
|
|
20
22
|
## UI carrier and required DSH version (0.2.3: right-sidebar DSH only)
|
|
21
23
|
|
|
@@ -48,7 +50,7 @@ A static profile plugin (npm package with host + client bundle) that ships the *
|
|
|
48
50
|
the narrow-viewport handling). When the button is missing it keeps the current mode and logs one `console.warn` — panel
|
|
49
51
|
rendering is never affected.
|
|
50
52
|
- **Resident IDE (0.2.2, on by default)**: switching to another tab or collapsing the sidebar and coming back **no longer reloads** code-server — unsaved editor buffers, terminals and debug sessions all stay put (see "Why switching tabs no longer reloads" below).
|
|
51
|
-
- The settings card has exactly **
|
|
53
|
+
- The settings card has exactly **four settings**: "**Claim types**", "**Fullscreen on open**", "Resident in background" and "**FIM completion (experimental, off by default)**" — no other rows (0.2.7 removed the "Entry", "dependency install" and "environment check" rows).
|
|
52
54
|
Open the IDE from the **Code Server box** on the sidebar's guide page, or by clicking DSH's own produced-file chips / delivered-file previews / inline file names;
|
|
53
55
|
diagnostics stay out of the UI — the `[code-server]` lines in the DSH host log are the place to look (`/api/code-server/status` still returns `env` for scripts).
|
|
54
56
|
The old `windowedOpen` (open in a window) and `reserveComposer` were **removed in 0.2.6**: leftover keys in an old settings document neither fail nor apply (they are no longer part of the schema).
|
|
@@ -225,62 +227,70 @@ only the editor knows, and lets editor gestures drive the current session.
|
|
|
225
227
|
| Direction | Capability | Mechanism |
|
|
226
228
|
|---|---|---|
|
|
227
229
|
| editor → agent | **unsaved buffers** (disk ≠ what the user sees), active file and selection, **language-server diagnostics** with `file:line`, source and code | agent tools `editor_context` / `editor_diagnostics`; plus a notice attached before writing a dirty file |
|
|
228
|
-
| editor → DSH | select code → context menu **"DSH: ask about selection"** → an **ask
|
|
229
|
-
| DSH → editor (approval) | when the agent wants to **write outside the workspace or run a command**, the approval request shows up as a card in the
|
|
230
|
+
| editor → DSH | select code → context menu **"DSH: ask about selection"** → an **ask dialog** opens in the DSH page (its title bar carries `file:line`); the question enters the current session as **user input**, and that session's **new content** is rendered in the dialog by DSH's own Markdown renderer | extension command `dsh-code-server.askAboutSelection` (one of the **top two** editor context-menu items) → bridge `POST /event {kind:'ask-open'}` → the client half's `POST /api/code-server/ask/send` |
|
|
231
|
+
| DSH → editor (approval) | when the agent wants to **write outside the workspace or run a command**, the approval request shows up as a card in the dialog (tool, reason, countdown); "allow once" / "reject" takes effect immediately | the `approvals` field of `/api/code-server/ask/state` + `POST /api/code-server/ask/approve` (the plugin's **only** write route; constraints under "Security model") |
|
|
230
232
|
| agent → editor | the agent changed a file → a **native diff** opens (left = the **full pre-write text**, right = what is on disk now); if that buffer has unsaved changes you get a warning and **no overwrite** | the host reads `result.value.before` (the complete pre-write text) in `tools/post-execute` into a bounded snapshot cache → the `tools/result` event carries an opaque key → the extension fetches the text and opens the diff |
|
|
231
233
|
|
|
232
234
|
- The tools are only registered while the bridge is live (so the model never sees an unusable tool), and the
|
|
233
235
|
system-prompt section renders only then too.
|
|
234
|
-
- **Ask
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
the
|
|
239
|
-
|
|
240
|
-
only when something is actually selected, while "ask about file" **never carries line numbers or a selection** —
|
|
241
|
-
cursor line is irrelevant to the question and only misleads the agent. With no selection, the selection
|
|
242
|
-
degrades to the plain file.
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
236
|
+
- **Ask dialog**: the context-menu command only reports its intent to the host; the dialog itself is popped up by
|
|
237
|
+
the plugin's client half inside the DSH page — draggable, resizable (bottom-right, ✕ closes it), leaving the
|
|
238
|
+
editor layout alone. The selection can still be changed while the dialog stays open.
|
|
239
|
+
When the host cannot prove the dialog is alive (page not open / browser still running an old client) you get a
|
|
240
|
+
one-line notice telling you to open or refresh the Code Server tab — there is **no second ask UI** in the editor.
|
|
241
|
+
- **The two commands remember their intent**: "ask about selection" carries a **line range + selection text**
|
|
242
|
+
only when something is actually selected, while "ask about file" **never carries line numbers or a selection** —
|
|
243
|
+
the cursor line is irrelevant to the question and only misleads the agent. With no selection, the selection
|
|
244
|
+
command also degrades to the plain file. The host takes that context from its cached editor state; the extension
|
|
245
|
+
only reports the intent.
|
|
246
|
+
- **Follow-ups are delivered according to DSH's own setting**: `ui-conversation.busyEnter` (Settings → Conversation,
|
|
247
|
+
"Enter while busy") accepts `queue` (the default) or `steer`. Pressing Enter in the dialog is the same gesture as
|
|
248
|
+
pressing Enter in the main composer, so it reads the same value: `steer` ⇒ the host calls `agent.steer()` and the
|
|
249
|
+
follow-up is consumed at the **running turn's next step boundary** (answered within that turn); `queue` ⇒ the host
|
|
250
|
+
calls `agent.followup()` and the question becomes **its own later turn**, leaving the running one alone. If the
|
|
251
|
+
setting cannot be read (namespace unregistered / minimal composition) or the host has no `agent.steer`, delivery
|
|
252
|
+
falls back to `queue` — a setting never makes a question undeliverable. The panel's status row **says which one was
|
|
253
|
+
used** ("inserted into the current turn…" / "queued for the next turn…"), because while `queue` is in effect the
|
|
254
|
+
**DSH main UI cannot show that message yet**: it sits in the host-side pending queue (`next-turn`) and the main
|
|
255
|
+
client does not render pending queues (it joins the chat flow only once it becomes its own turn). The message is
|
|
256
|
+
not lost.
|
|
257
|
+
- **Injected context is collapsed**: the location line plus the selection code block the bridge adds to the
|
|
258
|
+
message are split out into a collapsed Context row (click it to see the code), while the bubble keeps only the
|
|
259
|
+
user's own words — the same treatment the DSH UI gives injected context.
|
|
260
|
+
- **The body is exactly what DSH renders**: it is handed to DSH's official Markdown renderer
|
|
261
|
+
(`MarkdownText` from `@deepseek-ai/dsh-client-ui-primitives`) — the same micromark/mdast pipeline, the same
|
|
262
|
+
incremental streaming parser, the same shiki highlighting (DSH's own lazily-loaded grammar set), KaTeX math and
|
|
263
|
+
the same heading/table typography. Only **new content** is rendered (from the moment the dialog subscribes);
|
|
264
|
+
history is **not replayed** and there is no "load earlier". If the official components cannot be resolved the
|
|
265
|
+
body degrades to plain-text `<pre>` instead of a blank panel.
|
|
266
|
+
- **Thinking shows up like in DSH**: assistant reasoning becomes a Think row — **collapsed by default**,
|
|
252
267
|
showing its first line (or the latest line while streaming) and expanding on a row click, built from the official
|
|
253
268
|
`DisclosureRow` plus the official think icon and typography language.
|
|
254
|
-
- **Approvals are handled right in the
|
|
255
|
-
session's approval requests ask the
|
|
256
|
-
immediately; **closing the
|
|
257
|
-
path (the DSH UI shows the same card).
|
|
258
|
-
grey before anyone could click (reported as "the approval box stopped working"); the window is now 5 minutes and
|
|
259
|
-
closing the panel hands off immediately instead of waiting it out.
|
|
269
|
+
- **Approvals are handled right in the dialog**: while it is open, that
|
|
270
|
+
session's approval requests ask the dialog first (5-minute window). Clicking "allow once" / "reject" settles it
|
|
271
|
+
immediately; **closing the dialog** or letting the window expire hands the request back **unchanged** to the official
|
|
272
|
+
path (the DSH UI shows the same card).
|
|
260
273
|
**Nothing is ever auto-approved** — `allowed-once` can only come from a click, and there is no "always allow".
|
|
261
|
-
- The question enters the DSH session as a **plain user message** (`source: { kind: 'user' }
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
(see invariant 2 below). The agent's writes still go through its own `fs` tools; the bridge only *knows about*
|
|
267
|
-
and carries your answer back.
|
|
274
|
+
- The question enters the DSH session as a **plain user message** (`source: { kind: 'user' }`): provenance stays in
|
|
275
|
+
the first line of the text (`From the editor: <file>[:<line>]`), and the panel folds it into the Context row.
|
|
276
|
+
- **The bridge is completely read-only**: it never writes files, applies edits, or runs commands — all four routes
|
|
277
|
+
(`/health`, `/sync`, `/old`, `/event`) are reads. The only route that can change state is the DSH-same-origin
|
|
278
|
+
`POST /api/code-server/ask/approve`, which can only **answer an approval request that already exists**
|
|
279
|
+
(see invariant 2 below). The agent's writes still go through its own `fs` tools; the bridge only *knows about*
|
|
280
|
+
them and carries your answer back.
|
|
268
281
|
- Status bar shows `$(plug) DSH` while connected (click it for the log in the "DSH Editor Bridge" output channel).
|
|
269
|
-
- **The extension ships as a built-in
|
|
270
|
-
`<tree>/lib/vscode/extensions/` next to `dshcs-open-file
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
every start, so **the bridge never reported any state**. To turn the bridge off use the plugin setting
|
|
274
|
-
`editorBridge=false` (no mount, no tools) rather than uninstalling the extension from the Extensions view.
|
|
282
|
+
- **The extension ships as a built-in**: `dshcs-editor-bridge` is installed into
|
|
283
|
+
`<tree>/lib/vscode/extensions/` next to `dshcs-open-file` — an extension left in the *user* extensions folder is
|
|
284
|
+
marked `.obsolete` (log line `Marked extension as removed`) by the VS Code server and skipped forever.
|
|
285
|
+
To turn the bridge off use the plugin setting `editorBridge=false` (no mount, no tools).
|
|
275
286
|
|
|
276
287
|
### The channels (since 0.3.13 over **local IPC**: a Windows named pipe / unix socket)
|
|
277
288
|
|
|
278
289
|
```
|
|
279
|
-
extension → host POST /code-server-bridge/sync one round trip: push editor state
|
|
280
|
-
extension → host POST /code-server-bridge/ask push an editor question into the current session
|
|
281
|
-
extension → host POST /code-server-bridge/approve answer an approval request that **already exists** (the only non-read-only route)
|
|
290
|
+
extension → host POST /code-server-bridge/sync one round trip: push editor state + take events and the capability bit
|
|
282
291
|
extension → host GET /code-server-bridge/health unauthenticated liveness probe
|
|
283
|
-
extension → host
|
|
292
|
+
extension → host GET /code-server-bridge/old fetch one "pre-write text" snapshot (events carry an opaque key)
|
|
293
|
+
extension → host POST /code-server-bridge/event report intent: open the dialog / open·close a file etc. (host log tail)
|
|
284
294
|
host → extension <extensionsDir>/.dshcs-bridge/bridge.json endpoint + token, re-read every 5s
|
|
285
295
|
(the same content is also written **next to the built-in extension** in
|
|
286
296
|
`<tree>/lib/vscode/extensions/.dshcs-bridge/` — the env var is only injected when the host
|
|
@@ -289,14 +299,19 @@ host → extension <extensionsDir>/.dshcs-bridge/bridge.json endpoint + toke
|
|
|
289
299
|
```
|
|
290
300
|
|
|
291
301
|
Requests use `http.request({ socketPath })` (`fetch` has no socket support) and **no port is ever opened**.
|
|
302
|
+
All four routes are **read-only**; questions and approval answers do not go through the bridge but through the
|
|
303
|
+
DSH-same-origin `/api/code-server/ask/*` (called by the plugin's client half inside the DSH page, under DSH's own
|
|
304
|
+
cookie/Origin checks).
|
|
292
305
|
|
|
293
|
-
The
|
|
306
|
+
The four state fields the dialog actually consumes (`GET /api/code-server/ask/state?rev=N`; an unchanged revision
|
|
307
|
+
returns a single number):
|
|
294
308
|
|
|
295
309
|
| Field | Content | How the panel uses it |
|
|
296
310
|
|---|---|---|
|
|
297
|
-
| `
|
|
298
|
-
| `approvals` | pending approval requests `[{id, toolName, reason, at}]` (≤4) | renders the card with a countdown; a click posts `/approve` |
|
|
299
|
-
| `approvalHoldMs`
|
|
311
|
+
| `entries` | **new content** entries (user / assistant / tool / approval) of the session the dialog watches; bounded: ≤120 entries per session, ≤8000 chars per body, ≤4 watched sessions | assistant bodies go to the official renderer; tools and approvals become compact summary rows |
|
|
312
|
+
| `approvals` | pending approval requests `[{id, toolName, reason, at}]` (≤4) | renders the card with a countdown; a click posts `/ask/approve` |
|
|
313
|
+
| `approvalHoldMs` | the approval window (300000 ms = 5 minutes by default) | countdown basis |
|
|
314
|
+
| `contextText` / `mode` | the title line (from the host's cached editor state) plus the ask intent | title text; `mode` decides whether line numbers / the selection travel with the question |
|
|
300
315
|
|
|
301
316
|
> **Why not HTTP (settled in 0.3.13, all three measured)**
|
|
302
317
|
> 1. **Desktop has no HTTP surface at all**: the renderer calls `host.fetch()` through Electron IPC
|
|
@@ -339,10 +354,15 @@ Regression: the "push → take → clear, twice" case in `scripts/test-bridge-ro
|
|
|
339
354
|
The token lives in `<extensionsDir>/.dshcs-bridge/bridge.json`, **readable by any process of the same local
|
|
340
355
|
user**, so:
|
|
341
356
|
|
|
342
|
-
1. **`/code-server-bridge/*` is read-only, with
|
|
357
|
+
1. **`/code-server-bridge/*` is read-only, with two bounded exceptions.** No route writes files,
|
|
343
358
|
edits documents, runs commands, or spawns processes. A leaked token is therefore bounded to "sees information
|
|
344
359
|
that is in the editor" and **can never** become arbitrary file writes or command execution. A whitelist
|
|
345
360
|
assertion in `scripts/test-bridge-routes.mjs` guards this.
|
|
361
|
+
`/complete` (0.3.61, **experimental FIM completion, off by default**) is the one route that makes a **model
|
|
362
|
+
call**: it takes two strings (the text before/after the cursor) and returns one string. It still writes
|
|
363
|
+
nothing and runs nothing, is disabled unless the setting is on (403 otherwise), and is bounded by
|
|
364
|
+
length/rate/concurrency/timeout caps — so the worst case for a leaked token grows only to "spends a little
|
|
365
|
+
completion budget and reads back one completion".
|
|
346
366
|
`/old` (added in 0.3.55) lives under the same invariant: it only reads the bounded cache of "pre-write copies of
|
|
347
367
|
the last few agent writes" (≤8 entries, ≤1 MB each, ≤4 MB total, 5-minute TTL) by **opaque key**, 404s when it
|
|
348
368
|
is gone, takes no path argument (so it cannot read arbitrary files) and does not consume (repeat polls get the
|
|
@@ -355,7 +375,7 @@ user**, so:
|
|
|
355
375
|
(d) when no panel is watching, the panel is closed, or the window (5 minutes by default) expires, the request goes
|
|
356
376
|
**back to the official
|
|
357
377
|
path** — never auto-approved (DSH's `approval/request` itself fails closed; this bridge can only keep
|
|
358
|
-
"nobody answered" as "nobody answered"). `pnpm test:
|
|
378
|
+
"nobody answered" as "nobody answered"). `pnpm test:ask-dialog` asserts these four plus the host-side whitelist.
|
|
359
379
|
3. **Any request carrying `Origin` gets 403.** Browsers always send one (including a sandboxed iframe's literal
|
|
360
380
|
`Origin: null`); the Node extension host never does. Origin is checked **before** the token — otherwise the
|
|
361
381
|
bridge would be a "did you guess the token right" oracle for a web page.
|
|
@@ -379,6 +399,64 @@ as stated for the loopback port.
|
|
|
379
399
|
Diagnostics: `GET /api/code-server/status` exposes
|
|
380
400
|
`bridge: { enabled, live, toolsRegistered, supported, url, file }` — **never the token** (that only exists in the file).
|
|
381
401
|
|
|
402
|
+
## FIM completion (experimental, since 0.3.61, **off by default**)
|
|
403
|
+
|
|
404
|
+
When you pause while typing, a grey continuation appears after the cursor (Tab accepts, Esc discards).
|
|
405
|
+
It is **off by default**; turn it on with that row in the settings card — it takes effect immediately
|
|
406
|
+
(no host restart, no reinstall).
|
|
407
|
+
|
|
408
|
+
| Item | Value |
|
|
409
|
+
|---|---|
|
|
410
|
+
| Endpoint | DeepSeek **FIM (Beta)**: `POST https://api.deepseek.com/beta/completions`, params `prompt` (prefix) + `suffix` (suffix) |
|
|
411
|
+
| Model | `deepseek-flash` (the model the official FIM doc uses — also this deployment's default) |
|
|
412
|
+
| Credential | Reuses the `DEEPSEEK_API_KEY` DSH already has: `ctx.get('credentials').resolve(...)`, the same path the official adapter takes (falling back to the launch environment) |
|
|
413
|
+
| Measured latency | **112–416 ms** (non-streaming; streaming was *slower*, hence non-streaming on purpose) |
|
|
414
|
+
| When it fires | After a ≥250 ms pause and only past the gates: non-empty selection / non-`file` document / empty context / document >20k lines — those **never send a request** |
|
|
415
|
+
|
|
416
|
+
**How it is wired in (option A)**: FIM speaks the Completions API, while `ctx.llm.stream(GenerateOptions)`
|
|
417
|
+
only knows `messages` (no `prompt`/`suffix`; `purpose` is a closed union of `'compaction' | 'session-title'`).
|
|
418
|
+
So the plugin **registers its own LLM adapter route** `dshcs-fim`: the prefix/suffix travel inside a
|
|
419
|
+
`messages` envelope with a fixed marker (`dshcs-fim/1 `), and the adapter decodes it before hitting that
|
|
420
|
+
endpoint. The call therefore still goes **through DSH's LLM service** — cancellation, timeouts, terminal
|
|
421
|
+
chunks and stable error codes all follow the service contract (instead of the plugin bypassing it with a
|
|
422
|
+
raw fetch). Evidence and measurements: B6/B7 of `docs/analysis-continuedev-reuse.md`.
|
|
423
|
+
|
|
424
|
+
**Three knobs (0.3.62, all in the settings card, effective immediately)**:
|
|
425
|
+
|
|
426
|
+
| Setting | Default | Effect |
|
|
427
|
+
|---|---|---|
|
|
428
|
+
| Pause in ms | `250` | How long typing must stop before a request. Range 100–3000 ms (clamped on save); the endpoint round trip measured **112–416 ms**, so the pause *is* the perceived latency |
|
|
429
|
+
| Allow multi-line | on | Off ⇒ the host returns the first line only; an empty first line means no completion. Turn it off to be less intrusive |
|
|
430
|
+
| Disable by glob | empty | In these files **no request is sent at all**. Semantics: `*` does not cross directories, `**` does, a pattern without `/` matches the basename, a pattern with `/` matches any path suffix (so `vendor/**` and `src/*.ts` work at any depth), a trailing `/` means `/**`. Example: `*.md;vendor/**;**/dist/**` |
|
|
431
|
+
|
|
432
|
+
> Both sides implement these semantics independently (the extension is a static file shipped with the package
|
|
433
|
+
> and cannot import host code); `scripts/test-fim.mjs` pins their equivalence with one shared (pattern, path)
|
|
434
|
+
> corpus.
|
|
435
|
+
|
|
436
|
+
**Safety and bounds** (this is the only capability of the plugin that sends content out):
|
|
437
|
+
|
|
438
|
+
- **Still read-only**: the extension never writes files and never runs commands — it only *proposes* text;
|
|
439
|
+
insertion happens when you press Tab;
|
|
440
|
+
- The bridge gains its fifth route `POST /complete` (**the only route that makes a model call**) only while
|
|
441
|
+
the setting is on; with it off the route answers 403 and no request is made;
|
|
442
|
+
- Bounded: prefix/suffix ≤6000/2000 chars (120/40 lines, whichever comes first), output ≤2000 chars,
|
|
443
|
+
4 s timeout, 120 ms minimum interval, concurrency 1, 60 calls/minute; over-limit requests are rejected
|
|
444
|
+
(409/429) and the extension simply shows no completion for that beat;
|
|
445
|
+
- One more layer in the extension: turning the setting off disposes the provider immediately (no requests at
|
|
446
|
+
all), and identical context hits a local 2-minute cache;
|
|
447
|
+
|
|
448
|
+
**Usage is visible in exactly two places**: these calls are **not session requests**, so they are not written
|
|
449
|
+
to the session log and DSH's own token accounting (per-turn usage, context pressure, telemetry) **excludes
|
|
450
|
+
them**. Usage therefore shows up in ① the IDE status bar's DSH item — a `$(zap) 1.2k` counter when on, with
|
|
451
|
+
input/output/cache-read/last-latency/last-error on hover, and ② the `fim` field of
|
|
452
|
+
`GET /api/code-server/status` (same snapshot).
|
|
453
|
+
|
|
454
|
+
**Known limits**: the model occasionally invents an insertion where nothing is needed (2/2 reproduced at a
|
|
455
|
+
cursor position that needed none); the filter pipeline strips code fences and control markers, but "should
|
|
456
|
+
this be completed at all" stays your call — Esc or typing on makes it disappear. A more reliable shape needs
|
|
457
|
+
a faster completion route, or DSH making completion a first-class request (at which point only the adapter's
|
|
458
|
+
data call changes; the caller stays as it is).
|
|
459
|
+
|
|
382
460
|
## Legacy DSH (unsupported since 0.2.3)
|
|
383
461
|
|
|
384
462
|
**Behaviour**: when `sidebarRightTabs` / `sidebarRight` cannot be found, the plugin registers a single settings card:
|
|
@@ -438,10 +516,11 @@ Diagnostics: `GET /api/code-server/status` exposes
|
|
|
438
516
|
crash/exit updates status live; after a DSH host restart the plugin **adopts** a still-running instance (verifies pid + `/healthz`), without duplicate start or killing unrelated processes;
|
|
439
517
|
- `node_modules` and the pack-time artifact `vendor/` are git-ignored; after cloning, follow
|
|
440
518
|
"Install the plugin (script-free install; code-server bundled)" below — `pnpm install` → `pnpm run vendor:vscode` →
|
|
441
|
-
`pnpm
|
|
519
|
+
`pnpm pack` + `dsh plugin --profile web add` (after 0.3.58/0.3.59 the client half **and** the ask panel are
|
|
520
|
+
committed hand-written source: there is no build step anywhere on that chain).
|
|
442
521
|
|
|
443
522
|
> Verified locally (BM: Windows 11 ARM64): the whole tree/dependency chain hangs directly off the plugin's
|
|
444
|
-
> dependency table — the tree package `@jinsiyu/dshcs-vscode-server` (currently 4.
|
|
523
|
+
> dependency table — the tree package `@jinsiyu/dshcs-vscode-server` (currently 4.138.0, a 50.9 MB tarball),
|
|
445
524
|
> the pure-JS inner dependencies plus the 8 platform-independent repacks in `dependencies`, and the 8
|
|
446
525
|
> platform-specific repacks (win32-arm64 / win32-x64) in `optionalDependencies` with their own os/cpu gates;
|
|
447
526
|
> the original names are restored by junctions created at runtime (`lib/native.js`)
|
|
@@ -452,13 +531,12 @@ Diagnostics: `GET /api/code-server/status` exposes
|
|
|
452
531
|
|
|
453
532
|
```powershell
|
|
454
533
|
cd C:\Users\User\Desktop\dsh-code-server-app
|
|
455
|
-
pnpm install # dev
|
|
456
|
-
pnpm run build:webview # ask panel: official Markdown renderer + panel shell → webview/thread.{js,css} (not committed; must be built first)
|
|
534
|
+
pnpm install # one dev dependency left (@deepseek-ai/schemastery); allowBuilds is explicit → no postinstall runs
|
|
457
535
|
pnpm run vendor:check # optional: show the bundled tree version vs the latest code-server release
|
|
458
536
|
pnpm run vendor:vscode # ① produce vendor/vscode (the trimmed VS Code tree, ~197MB)
|
|
459
537
|
pnpm run repack:build -- --target win32-arm64,win32-x64 --pack # ② one script builds every sub-package
|
|
460
538
|
pnpm run publish:repacks # ③ publish every @jinsiyu/* sub-package (default dist-tag: next)
|
|
461
|
-
pnpm pack # ④ → dsh-code-server-app-<version>.tgz
|
|
539
|
+
pnpm pack # ④ → dsh-code-server-app-<version>.tgz
|
|
462
540
|
pnpm run publish:plugin # ⑤ publish the plugin itself (default dist-tag: next)
|
|
463
541
|
# once the user has restarted dsh web and confirmed it works, promote latest:
|
|
464
542
|
pnpm run promote -- <version>
|
|
@@ -473,13 +551,11 @@ pnpm run promote -- <version>
|
|
|
473
551
|
> so their dist-tags do not affect resolution, but they default to `next` as well.
|
|
474
552
|
> Inspect the current tags with `npm dist-tag ls dsh-code-server-app`.
|
|
475
553
|
|
|
476
|
-
>
|
|
477
|
-
>
|
|
478
|
-
>
|
|
479
|
-
>
|
|
480
|
-
>
|
|
481
|
-
> Rationale (why not an iframe, where the tokens come from, size trade-offs) is section 21 of
|
|
482
|
-
> `docs/analysis-code-server-as-dsh-plugin.md`.
|
|
554
|
+
> **There is no build step on this chain**: `lib/client.js` — including the "ask DSH" dialog panel — is committed
|
|
555
|
+
> hand-written source, and so is the extension (plain JS). `prepack` is down to `vendor:vscode`, the published
|
|
556
|
+
> package carries no frontend bundle, and `devDependencies` holds exactly one entry (`@deepseek-ai/schemastery`,
|
|
557
|
+
> used by the tests).
|
|
558
|
+
> The per-version analysis of the panel and the DSH page lives in `docs/analysis-code-server-as-dsh-plugin.md`.
|
|
483
559
|
|
|
484
560
|
`repack:build` (`scripts/vendor-repacks.mjs`) is the **single script that produces every sub-package**:
|
|
485
561
|
|
|
@@ -492,7 +568,7 @@ pnpm run promote -- <version>
|
|
|
492
568
|
| Goal | Command |
|
|
493
569
|
|---|---|
|
|
494
570
|
| **Build from the latest upstream release** | `pnpm run vendor:latest` (= `--force`): pulls `code-server@latest`'s tree into `vendor/vscode`; afterwards you **must** re-run `repack:build` and republish every sub-package |
|
|
495
|
-
| **Pin a version** | `pnpm run vendor:vscode -- --version 4.
|
|
571
|
+
| **Pin a version** | `pnpm run vendor:vscode -- --version 4.138.0` |
|
|
496
572
|
| **Snapshot from an existing tree** | `pnpm run vendor:vscode -- --from <code-server dir>` (seconds) |
|
|
497
573
|
| **Rebuild every sub-package** | `pnpm run repack:build -- --target win32-arm64,win32-x64 --pack` (without `--from` it npm-installs and compiles the source tree itself — slow) |
|
|
498
574
|
| **Rebuild only the tree + dependency table** | `node scripts/vendor-repacks.mjs --reuse --target win32-arm64,win32-x64 --pack` (reuses the natives already in `repack/build`; also rewrites `lib/vendored.json` and the plugin dependency table) |
|
|
@@ -513,7 +589,7 @@ Both workflows live in `.github/workflows/`, and the regression list exists exac
|
|
|
513
589
|
|
|
514
590
|
| Workflow | Trigger | What it does |
|
|
515
591
|
|---|---|---|
|
|
516
|
-
| `ci.yml` | push to `main` / PR / manual | `ubuntu-latest` + `windows-latest` matrix: `pnpm install --frozen-lockfile` → `
|
|
592
|
+
| `ci.yml` | push to `main` / PR / manual | `ubuntu-latest` + `windows-latest` matrix: `pnpm install --frozen-lockfile` → `pnpm test` (the whole suite; since 0.3.59 there is **no build step in front of it**) → `vendor:check` (report only) |
|
|
517
593
|
| `release.yml` | push a `v<version>` tag / manual (rehearsal, never publishes) | prepares `vendor/vscode` **at the version pinned in `dependencies`** → builds → full suite → `pnpm pack` → verifies the tarball manifest → **really installs it twice** (windows-latest proves the 16 win32 sub-packages, ubuntu-latest the 10 Linux ones: each deploys a real DSH, installs via the official path `dsh plugin --profile web add <tgz>`, then runs the `test:installed` + `dump-config` assertions; both legs must pass before anything is published) → publishes to npm **`next`** → creates a GitHub Release with the tgz attached |
|
|
518
594
|
| `linux-repack-probe.yml` | push to this file / manual | **feasibility probe (never publishes; superseded by the Linux legs of `repacks.yml`)**: on Linux, builds the platform-specific repack packages per target (`linux-x64` → `ubuntu-latest`, `linux-arm64` → `ubuntu-24.04-arm`) and reports which modules really produce a `.node` and which are Windows-only. It runs the existing `vendor-repacks.mjs` itself; all writes happen in a copy of the repo under `$RUNNER_TEMP`. **Note**: it emits one notice per module, which hits GitHub's ~20-annotations-per-check-run cap and leaves only the tail; for the full verdict use the Linux legs of `repacks.yml` (one summary line per target) |
|
|
519
595
|
| `repacks.yml` | manual (`publish` and `probe_oidc` both default to **false**, the four `build_*` legs default to **true**) / push to this file / push `.github/oidc-probe.enabled` | **builds and publishes the platform-specific sub-packages** (`@jinsiyu/dshcs-*`): one host-architecture runner per target (`win32-x64` → `windows-latest`, `win32-arm64` → `windows-11-arm`, `linux-x64` → `ubuntu-latest`, `linux-arm64` → `ubuntu-24.04-arm`); by default it only builds and uploads `repack/tgz/*.tgz`, and only publishes to npm (default `next`) when `publish` is checked. Ownership and ordering (**five legs, disjoint sets**): the `independent` leg runs **first** (windows-latest; it produces the **VS Code tree package + the 8 platform-independent repacks**, which are the same artifact for all four targets and are therefore published only once); the four platform-specific legs `needs: independent`, build with `--skip-independent` and publish with `--only <their own target>` ⇒ a broken base layer blocks the rest (no half-published state) and no package name is ever published twice. **Auth**: with no `NPM_TOKEN` it uses OIDC (per-package trust entries, all with workflow `repacks.yml` — see below). The Linux legs additionally verify that the `lib/vendored.json` / `package.json` they generate match the committed ones (the platform policy is meant to be host-independent). A `probe-oidc` job additionally does a **staged-only** probe of that OIDC route, so the channel can be proven without publishing anything real |
|
|
@@ -612,8 +688,8 @@ pnpm test:apply # apply() under a stub ctx
|
|
|
612
688
|
pnpm test:claim-types # claim-type syntax and defaults
|
|
613
689
|
pnpm test:bridge-routes # bridge route whitelist (read-only + /approve + /old) / Origin-vs-token order / token header agreement
|
|
614
690
|
pnpm test:edit-snapshot # pre-write snapshots: value.before from tools/post-execute, session-cwd path resolution, triple-bounded cache, /old's 400-404-200
|
|
615
|
-
pnpm test:bridge-extension # extension-side pure logic (dirty buffers, diagnostics, diff old-side priority, delivery,
|
|
616
|
-
pnpm test:
|
|
691
|
+
pnpm test:bridge-extension # extension-side pure logic (dirty buffers, diagnostics, diff old-side priority, delivery, ask intent + "dialog unavailable" notice)
|
|
692
|
+
pnpm test:ask-dialog # ask-dialog wiring: no artifacts/build chain left, the host's four ask routes, the extension only reporting editor state, the four approval constraints, the bridge's safety invariants
|
|
617
693
|
pnpm test:launcher-routes # launcher HTTP surface (spawns a real process; slow)
|
|
618
694
|
pnpm test:workspace-switch # switching workspaces does not restart the process
|
|
619
695
|
pnpm test:workspace-cwd # "current workspace directory" resolution (DSH 0.1.6-alpha.2 sessionId vs. the older current)
|
|
@@ -726,9 +802,6 @@ one itself (with no `NPM_TOKEN` it uses OIDC):
|
|
|
726
802
|
probe versions (`npm stage list`, then `npm stage reject <id>`; needs 2FA on your machine) — do **not**
|
|
727
803
|
approve, since approving is what would turn a probe into a real version. Delete the sentinel file to
|
|
728
804
|
return to "no automatic probe".
|
|
729
|
-
- **Optional** repository variable `DSH_UI_VERSION` = the version of `@deepseek-ai/dsh-web-frontend` in the current
|
|
730
|
-
deployment: when set, `release.yml` enforces that the panel renderer matches the deployed UI (the local
|
|
731
|
-
`build:webview` always checks this; a runner has no DSH deployment).
|
|
732
805
|
|
|
733
806
|
Things you must know:
|
|
734
807
|
|
|
@@ -741,8 +814,9 @@ Things you must know:
|
|
|
741
814
|
assertion). Packing happens only in `release.yml`, after
|
|
742
815
|
`node scripts/vendor-vscode-server.mjs --version <pinned>`.
|
|
743
816
|
- **Release gates** (any failure stops the run; `next` is never advanced): tag ≠ `package.json.version`, the
|
|
744
|
-
version already exists on npm, the tree version does not match (`test:vendored`), the suite fails, or
|
|
745
|
-
|
|
817
|
+
version already exists on npm, the tree version does not match (`test:vendored`), the suite fails, or the
|
|
818
|
+
tarball manifest / the two real-install legs disagree. (0.3.59 dropped one gate: the panel renderer no longer
|
|
819
|
+
needs to match the deployed DSH UI — it *is* that instance.)
|
|
746
820
|
- `@deepseek-ai/schemastery` is a **devDependency** (pinned to 3.18.2, the version the deployment uses):
|
|
747
821
|
`lib/index.js` normally takes it from the DSH deployment (in production, the copy hoisted inside the
|
|
748
822
|
profile), and a clean clone / CI runner has no DSH at all — without this devDependency the `apply`-style
|
|
@@ -857,7 +931,7 @@ Costs and rules (read before editing `lib/client.js`):
|
|
|
857
931
|
| Rule | Why | Enforced by |
|
|
858
932
|
|---|---|---|
|
|
859
933
|
| No top-level `import`/`export`/`await` | syntax errors in a classic script ⇒ the whole client half fails to load (empty UI) | `pnpm test:client-entry` E1 + the harness really loading it (E3) |
|
|
860
|
-
| `require(...)` may only name `react` / `react/jsx-runtime` | the DSH module table is frozen; anything else throws "unknown module" | E1 |
|
|
934
|
+
| `require(...)` may only name DSH module-table seed words (`react` / `react/jsx-runtime` / `react-dom/client` / `@deepseek-ai/dsh-client-ui-primitives`) | the DSH module table is frozen; anything else throws "unknown module" | E1 (and, when a local DSH install exists, it cross-checks the real `staticModules` list word by word) |
|
|
861
935
|
| Every section's top-level identifiers share one scope | after inlining, a `var`/`function` collision is a **silent overwrite** (real hit: `state` existed in both the surface and the plugin body — the former is now `surfaceState`) | no automatic guard ⇒ grep before adding a top-level name |
|
|
862
936
|
| The claim-types section is a **copy** | a classic script cannot reach the host module `lib/claim-types.js` | E2 compares both over a sample table |
|
|
863
937
|
|
|
@@ -865,8 +939,35 @@ Size: ~114 KB uncompressed (was a 49.7 KB minified artifact) — a one-time down
|
|
|
865
939
|
unchanged. Test hook: the entry exports `__internals` only when `window.__dshcsTestHooks === true` (used by
|
|
866
940
|
`test-workspace-cwd.mjs` / `test-sidebar-fullscreen.mjs` to call pure functions); DSH never sets that flag.
|
|
867
941
|
|
|
868
|
-
|
|
869
|
-
|
|
942
|
+
### Why the "ask DSH" dialog has no build step
|
|
943
|
+
|
|
944
|
+
The dialog's panel (conversation stream, collapsible thinking rows, approval cards, input box) lives **inside
|
|
945
|
+
`lib/client.js`** — hand-written, committed, with no artifact, no `/ask/bundle`, no injected `<script>` and no fake
|
|
946
|
+
`acquireVsCodeApi`.
|
|
947
|
+
|
|
948
|
+
Why it can work that way: the dialog already runs **inside the DSH page**, and the shell's module table
|
|
949
|
+
(`staticModules` of `dsh-web-frontend`) freezes `react` / `react/jsx-runtime` / `react-dom` / `react-dom/client` /
|
|
950
|
+
`@deepseek-ai/dsh-client-ui-primitives` / … — so the panel simply requires them:
|
|
951
|
+
|
|
952
|
+
- the renderer, the design tokens, the KaTeX styles and the shiki grammars **all come from the page** (the same
|
|
953
|
+
instance the DSH UI uses) ⇒ typography matches the UI and a version mismatch is impossible;
|
|
954
|
+
- the panel creates its own React root via `require('react-dom/client')` (its container is the dialog's own div);
|
|
955
|
+
- opening the dialog has no "fetch + parse + execute" step to wait for — there is no artifact.
|
|
956
|
+
|
|
957
|
+
Costs and rules:
|
|
958
|
+
|
|
959
|
+
| Rule | Why | Enforced by |
|
|
960
|
+
|---|---|---|
|
|
961
|
+
| CSS injected into the page may only target `.dshcs-*` | the styles land in DSH's own document; touching `:root`/`body` would restyle the whole UI | `pnpm test:ask-panel` P3 (every selector + a ban on at-rules) |
|
|
962
|
+
| Every `var(--vscode-*)` needs a fallback | the DSH page has no `--vscode-*`; a bare `var()` is invalid at computed-value time ⇒ transparent buttons/inputs | P3 |
|
|
963
|
+
| A component with hooks may only be written as `React.createElement(Name, …)` | there is no JSX here; `Name({…})` puts the child's `useState` into the parent's hook chain, and a changed branch throws "Rendered more hooks than during the previous render" | P4 (source-level lookbehind regex) |
|
|
964
|
+
| Official components must be resolved as "function **or** `{$$typeof}` object" | `MarkdownText` is a `React.memo` product (an **object**); testing `typeof === 'function'` silently degraded every body to `<pre>` | P4's `askComponent` cases |
|
|
965
|
+
| Missing seed words / official components must degrade | the panel is the primary path; a blank panel means asking is broken | P5 (`<pre>` body, native `button`) + an error boundary |
|
|
966
|
+
| Three message routes (ask / approve / close) | panel and shell share one window (no postMessage), so messages must reach `/ask/send|approve|close` | P6 |
|
|
967
|
+
|
|
968
|
+
The extension side has no build step either: it is plain JS (`extension.js` + `lib/*.js`) and only reports intent.
|
|
969
|
+
Those two "no build step" claims are guarded by `pnpm test:client-entry` / `pnpm test:ask-panel` (the panel itself)
|
|
970
|
+
and `pnpm test:ask-dialog` (the wiring, plus "not one trace of the build chain may remain").
|
|
870
971
|
|
|
871
972
|
### Development: install from source (changes take effect immediately)
|
|
872
973
|
|
|
@@ -879,13 +980,12 @@ dsh plugin --profile web add C:\Users\User\Desktop\dsh-code-server-app
|
|
|
879
980
|
> too — but the not-yet-published local `@jinsiyu/*` packages must either be published first, or the
|
|
880
981
|
> `repack/tgz/*.tgz` files must be installed into the profile as `file:` dependencies.
|
|
881
982
|
>
|
|
882
|
-
> **Changing the client half**: edit `lib/client.js` directly (
|
|
883
|
-
>
|
|
884
|
-
>
|
|
885
|
-
>
|
|
886
|
-
>
|
|
887
|
-
>
|
|
888
|
-
> to pick it up, because the extension host caches the webview resources).
|
|
983
|
+
> **Changing the client half / the ask dialog**: edit `lib/client.js` directly (it is **hand-written source**:
|
|
984
|
+
> no build step, no `src/**` layer; the format rules are in that file's header and are enforced by
|
|
985
|
+
> `pnpm test:client-entry` and `pnpm test:ask-panel`). After installing into a profile a hard refresh picks it up.
|
|
986
|
+
> **Changing the extension**: edit `assets/extensions/dshcs-editor-bridge/{extension.js,lib/*.js}` (plain JS, no
|
|
987
|
+
> build). The IDE side needs one restart to load the new extension code, because the extension host caches loaded
|
|
988
|
+
> extensions.
|
|
889
989
|
|
|
890
990
|
### Pack-machine environment (the user machine needs nothing)
|
|
891
991
|
|
|
@@ -919,7 +1019,7 @@ dsh plugin --profile web add C:\Users\User\Desktop\dsh-code-server-app
|
|
|
919
1019
|
### Upgrading the VS Code tree (upstream = a code-server release)
|
|
920
1020
|
|
|
921
1021
|
- **The version is decided at pack time**: `pnpm run vendor:latest` (= `--force`) pulls the tree of the npm **latest**
|
|
922
|
-
release; or use `pnpm run vendor:vscode -- --version 4.
|
|
1022
|
+
release; or use `pnpm run vendor:vscode -- --version 4.138.0` / `DSHCS_CODE_SERVER_VERSION`.
|
|
923
1023
|
With an existing `vendor/vscode`, a plain `pnpm pack` never upgrades (it is a no-op).
|
|
924
1024
|
**Source-tree precedence (fixed in 0.2.13)**: an explicit `--from` uses that tree, while an explicit
|
|
925
1025
|
`--force`/`--version` now **always goes to the registry** — before the fix a local source tree won
|
|
@@ -934,13 +1034,14 @@ dsh plugin --profile web add C:\Users\User\Desktop\dsh-code-server-app
|
|
|
934
1034
|
- **A version bump means rebuilding and republishing the sub-packages** (all with the same script):
|
|
935
1035
|
1. `pnpm run repack:build -- --target win32-arm64,win32-x64 --pack` → the new tree package
|
|
936
1036
|
(`@jinsiyu/dshcs-vscode-server@<new version>`) and the natives rebuilt against the new inner dependencies (the
|
|
937
|
-
script also rewrites the plugin's pure-JS `dependencies
|
|
938
|
-
|
|
1037
|
+
script also rewrites the plugin's pure-JS `dependencies`, writes the 16 repacks under their real names into
|
|
1038
|
+
`dependencies` / `optionalDependencies`, and rewrites `lib/vendored.json`);
|
|
1039
|
+
2. `pnpm run publish:repacks` → publish; then bump the plugin version → `pnpm pack`
|
|
939
1040
|
→ publish the plugin.
|
|
940
1041
|
- `productPath` (`<quality>-<commit>`, part of the client WebSocket path) is **computed from `lib/vscode/product.json`**,
|
|
941
1042
|
so upgrading the tree needs no code change — but the routes are registered at activation, so restart `dsh web` afterwards.
|
|
942
1043
|
- **No runtime auto-upgrade anymore**: nothing fetches latest at startup; the version is fully determined by the bundled artifact.
|
|
943
|
-
- Bundled locally right now: the tree of `code-server@4.
|
|
1044
|
+
- Bundled locally right now: the tree of `code-server@4.138.0` (VS Code 1.138.0, `productPath=stable-59c988c7…`).
|
|
944
1045
|
|
|
945
1046
|
### Compatibility with the old install locations
|
|
946
1047
|
|
|
@@ -959,8 +1060,12 @@ persisted via the official settings domain (`settingsScope`, namespace `code-ser
|
|
|
959
1060
|
| `claimExtensions` | `*` + three exclusion groups (preview-friendly / executables / Office; full lists in the "Claim types" section) | **Claim types** (0.2.11, replaces 0.2.5's `fileOpenScope`): decides by extension which files go to VS Code, semicolon-separated; `*` claims every other type, `!ext` excludes (exclusion wins). The default leaves the four categories DSH's preview renders well (markdown/html/images/PDF) to DSH and sends everything else to the IDE; an empty value claims nothing. **Scope (session vs absolute) is no longer distinguished** |
|
|
960
1061
|
| `fullscreenOnOpen` | `true` | **Fullscreen on open** (0.2.9): opening the Code Server tab (including clicking a file) switches the right sidebar to fullscreen (fills the window); off keeps DSH's default push mode (side by side with the conversation). Only the moment of opening is affected — a manual "Exit fullscreen" is never fought back |
|
|
961
1062
|
| `keepResident` | `true` | **Resident in background**: on, the host preloads the IDE into a parked surface right after start — switching tabs or collapsing the sidebar never reloads it and the first open needs no cold start; off loads it only when the panel is opened (saves memory) |
|
|
1063
|
+
| `fim` | `false` | **FIM completion (experimental, 0.3.61)**: when on, pausing while typing shows a grey inline continuation (Tab accepts, Esc discards). **Off by default** — it is the only capability of this plugin that sends content out (a bounded slice of code around the cursor, per completion), and those calls **do not enter DSH's token accounting**, so usage is visible only in the IDE status bar. See the "FIM completion" section |
|
|
1064
|
+
| `fimDebounceMs` | `250` | **FIM · pause in milliseconds** (0.3.62): how long typing must stop before one completion request is sent. Effective range **100–3000 ms**, clamped on save (same rule as the host); empty/invalid falls back to 250 |
|
|
1065
|
+
| `fimMultiline` | `true` | **FIM · allow multi-line completions** (0.3.62): off means the host returns the first line only (an empty first line = no completion this time). The model does invent insertions where none are needed, and multi-line amplifies that noise |
|
|
1066
|
+
| `fimDisableGlobs` | empty | **FIM · disable by glob** (0.3.62): semicolon/newline separated. `*` does not cross directories, `**` does, a pattern without `/` matches the basename, a pattern with `/` matches any path suffix, and a trailing `/` means `/**`. Examples: `*.md`, `vendor/**`, `**/dist/**`. **Checked on both sides**: the extension first (no request at all), the host again |
|
|
962
1067
|
|
|
963
|
-
(Since 0.2.9 the card keeps only those three
|
|
1068
|
+
(Since 0.2.9 the card keeps only those settings (0.3.61 added FIM completion, 0.3.62 its three sub-rows); `windowedOpen` and `reserveComposer` are gone — leftover keys in an old
|
|
964
1069
|
settings document neither fail nor apply. `serve` remains a key in the settings namespace (usable from a settings document) but
|
|
965
1070
|
has **no card row** — see "Serving mode".)
|
|
966
1071
|
|
|
@@ -1093,6 +1198,22 @@ What remains on the plugin side:
|
|
|
1093
1198
|
**built-in** extension (in `lib/vscode/extensions`), so users cannot remove it from the extensions panel, and the
|
|
1094
1199
|
installer re-syncs it whenever its content changes.
|
|
1095
1200
|
|
|
1201
|
+
## Third-party and license
|
|
1202
|
+
|
|
1203
|
+
This project is **MIT**-licensed (see [`LICENSE`](LICENSE)). Its experimental **FIM completion** feature was
|
|
1204
|
+
**designed with reference to** [continuedev/continue](https://github.com/continuedev/continue)
|
|
1205
|
+
(Apache License 2.0, Copyright 2023 Continue) — specifically the settings taxonomy of upstream
|
|
1206
|
+
`tabAutocompleteOptions` (`debounceDelay`, `useAutocompleteMultilineCompletions`, `disableInFiles`) and its
|
|
1207
|
+
debounce / cursor-window / filtering / bounded-cache approach.
|
|
1208
|
+
|
|
1209
|
+
**No source code, template strings or files from continuedev/continue are included here** (completion
|
|
1210
|
+
requests target DeepSeek's official FIM (Beta) endpoint; the prompt shape comes from DeepSeek's docs and
|
|
1211
|
+
local measurement). The standard Apache License 2.0 text ships as
|
|
1212
|
+
[`LICENSE-Apache-2.0.txt`](LICENSE-Apache-2.0.txt), and the per-location reference log is
|
|
1213
|
+
[`THIRD_PARTY_NOTICES.md`](THIRD_PARTY_NOTICES.md) — so Apache-2.0's obligations (notices, marking modified
|
|
1214
|
+
files, keeping an upstream NOTICE if one appears) are already satisfied should a code fragment ever be ported
|
|
1215
|
+
in. Apache-2.0 grants no trademark rights; this project does not use "Continue" as a name or in promotion.
|
|
1216
|
+
|
|
1096
1217
|
## Known limitations
|
|
1097
1218
|
|
|
1098
1219
|
- **~~The editor bridge needs DSH to provide `webServer`~~ no longer true (fixed in 0.3.13)**: the bridge now runs
|
|
@@ -1105,16 +1226,12 @@ What remains on the plugin side:
|
|
|
1105
1226
|
or by simply calling `editor_context` — 0.3.0–0.3.11 sat in the state "health says bridge:true, extension never
|
|
1106
1227
|
loaded" (cause above: the user-level install was marked `.obsolete`).
|
|
1107
1228
|
- **Bridged state can lag by up to 600 ms**, and the tools say "stale" rather than serving data older than 10 s.
|
|
1108
|
-
- **The
|
|
1229
|
+
- **The dialog renders only "new content"**: the subscription starts when the dialog opens, the history
|
|
1109
1230
|
`records` from `follow`'s opening frame are discarded, and the panel has **no "load earlier"** (the history-paging
|
|
1110
1231
|
API `sessionController.page()` is deliberately not called in this version). Switch to the DSH UI for older content.
|
|
1111
|
-
- **
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
For the full set: `node scripts/build-webview.mjs --all-grammars`.
|
|
1115
|
-
- **Panel assets are pinned to the DSH version**: the renderer is bundled against the UI version of the deployed
|
|
1116
|
-
DSH, so after upgrading DSH you must rebuild the panel (`pnpm run build:webview`; the build fails loudly on a
|
|
1117
|
-
version mismatch). The panel also shows a mismatch notice at runtime instead of silently using the wrong renderer.
|
|
1232
|
+
- **Highlighting follows DSH's own lazily-loaded grammar set**: the panel uses the page's renderer instance, so
|
|
1233
|
+
there is no "the artifact only carries a few grammars" limitation.
|
|
1234
|
+
- **A renderer version mismatch is impossible**: the panel requires the very instance the UI uses.
|
|
1118
1235
|
- **The approval window in the panel is 5 minutes**: while the panel is open, approvals ask the panel first (the card
|
|
1119
1236
|
shows a countdown); **closing the panel** or letting the 5 minutes run out hands the request back to the DSH UI —
|
|
1120
1237
|
after that, that request can **only** be answered there (the card disappears from the panel and the thread keeps an
|