dsh-plugin-workbench 0.0.11 → 0.0.13

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/src/dsh.d.ts CHANGED
@@ -25,6 +25,18 @@ declare module '@deepseek-ai/cordis' {
25
25
  interface Context {
26
26
  /** Register a lifecycle effect; the callback may return a disposer. */
27
27
  effect(callback: () => void | (() => void), name?: string): void
28
+ /** Subscribe to an event; returns the disposer. */
29
+ on(event: string, listener: (...args: unknown[]) => void): () => void
30
+ /** Resolve scoped services and run a callback in that scope. */
31
+ inject(deps: string[], callback: (scope: Context) => void): { dispose(): unknown }
32
+ /** Agent registry (host side; used to teach each agent the mention grammar). */
33
+ agents: {
34
+ list(): Array<{ ctx: Context }>
35
+ }
36
+ systemPrompt: {
37
+ /** Register one ordered system-prompt section; returns the disposer. */
38
+ section(section: { name: string; order: number; text: string | ((context: unknown) => string) }): () => void
39
+ }
28
40
  connection: {
29
41
  rpc: {
30
42
  /** Browser-side unary call over a registered logical channel. */
package/src/index.ts CHANGED
@@ -36,7 +36,7 @@ import { homedir } from 'node:os'
36
36
  import type { Context } from '@deepseek-ai/cordis'
37
37
 
38
38
  export const name = 'dsh-plugin-workbench'
39
- export const inject = ['fs', 'connection', 'webServer']
39
+ export const inject = ['fs', 'connection', 'webServer', 'systemPrompt', 'agents']
40
40
 
41
41
  /** Loopback-only logical RPC channel. */
42
42
  export const CHANNEL = '/dsh-plugin-files'
@@ -330,6 +330,40 @@ function ensureLayoutPatch(): void {
330
330
  }
331
331
  }
332
332
 
333
+ /**
334
+ * Stable system-prompt section teaching the model the workbench `@.\` mention
335
+ * grammar. The core already contributes a generic "paths prefixed with @ are
336
+ * files referenced by the user" section (dsh-file-reference-local, order 99);
337
+ * this one documents the actual syntax the GUI inserts (the `.\` workspace
338
+ * marker, quoted form for paths with spaces) so the model resolves mentions
339
+ * against the session workspace root instead of treating `@.\…` as noise.
340
+ * Static text only — the string is identical on every assembly (KV-cache safe).
341
+ */
342
+ const FILE_MENTION_PROMPT =
343
+ 'Workspace file mentions written by the file panel use the form `@.<relative-path>` (a `.\` or `./` prefix marks a path relative to the current session workspace root; both `\\` and `/` separators are accepted, and paths with spaces use the quoted form `@"<relative-path>"`, for example `@"\\.\\my plan.md"`). Treat any such mention as a file the user wants you to read or edit: resolve the path against the workspace root and act on it with the file tools (read, glob, grep, edit, write); never claim to have inspected a file you did not actually open.'
344
+
345
+ /**
346
+ * File-mention grammar taught to the model (see the FILE_MENTION_PROMPT doc).
347
+ * One section per agent fiber: existing agents at apply time plus every agent
348
+ * created later (agent/created). The core already contributes a generic "paths
349
+ * prefixed with @ are files" section (dsh-file-reference-local, order 99);
350
+ * order 100 puts this more specific grammar right after it.
351
+ */
352
+ function installMentionPrompt(ctx: Context): void {
353
+ const teach = (agent: { ctx: Context }): void => {
354
+ agent.ctx.systemPrompt.section({
355
+ name: 'dsh-plugin-workbench:file-mention',
356
+ order: 100,
357
+ text: FILE_MENTION_PROMPT,
358
+ })
359
+ }
360
+ for (const agent of ctx.agents.list()) teach(agent)
361
+ ctx.on('agent/created', (payload: unknown) => {
362
+ const { agent } = payload as { agent: { ctx: Context } }
363
+ teach(agent)
364
+ })
365
+ }
366
+
333
367
  /**
334
368
  * One filesystem-backed RPC endpoint pair. Reads never mutate; `signal`
335
369
  * cancels the underlying fs call (or aborts between steps).
@@ -337,6 +371,8 @@ function ensureLayoutPatch(): void {
337
371
  export function apply(ctx: Context): void {
338
372
  // Re-apply the ui-layout explorer-column patch when a dsh upgrade reverted it.
339
373
  ensureLayoutPatch()
374
+ // Teach every agent the workbench `@.\` mention grammar (per-agent fiber).
375
+ installMentionPrompt(ctx)
340
376
  // Per-apply watch state: created here (not module-level) so disable/reload
341
377
  // cycles never leak watchers or SSE clients across applies.
342
378
  const watchState: WatchState = {