dsh-coding-sidebar 1.0.7 → 1.0.9

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.
Files changed (81) hide show
  1. package/README.md +2 -2
  2. package/lib/client-editor.js +485 -228
  3. package/lib/client-registry.js +1238 -7583
  4. package/lib/client-terminal.js +345 -189
  5. package/lib/client.js +1213 -7558
  6. package/lib/index.js +518 -69
  7. package/lib/types/agent-pty.d.ts +62 -4
  8. package/lib/types/bundle-route.d.ts +1 -1
  9. package/lib/types/client/DiffView.d.ts +33 -1
  10. package/lib/types/client/EditorHost.d.ts +4 -1
  11. package/lib/types/client/FileTree.d.ts +6 -2
  12. package/lib/types/client/TerminalWaitBanner.d.ts +6 -0
  13. package/lib/types/client/TreePanel.d.ts +4 -1
  14. package/lib/types/client/api.d.ts +26 -0
  15. package/lib/types/client/chunk-loader.d.ts +1 -1
  16. package/lib/types/client/chunks/locale.d.ts +3 -0
  17. package/lib/types/client/conversation-draft.d.ts +85 -4
  18. package/lib/types/client/locales.d.ts +13 -20
  19. package/lib/types/client/selection-popup.d.ts +58 -0
  20. package/lib/types/client/service.d.ts +1 -1
  21. package/lib/types/client/state.d.ts +15 -0
  22. package/lib/types/client/terminal-font.d.ts +25 -2
  23. package/lib/types/context-types.d.ts +3 -1
  24. package/lib/types/fs-operations.d.ts +42 -0
  25. package/lib/types/git.d.ts +15 -0
  26. package/lib/types/index.d.ts +9 -0
  27. package/lib/types/prefs-shared.d.ts +7 -5
  28. package/lib/types/pty-manager.d.ts +53 -0
  29. package/lib/types/wire.d.ts +6 -2
  30. package/package.json +1 -1
  31. package/src/agent-pty.ts +221 -33
  32. package/src/bundle-route.ts +1 -1
  33. package/src/client/DiffTab.tsx +10 -1
  34. package/src/client/DiffView.tsx +174 -19
  35. package/src/client/EditorHost.tsx +9 -2
  36. package/src/client/FileTree.tsx +151 -8
  37. package/src/client/Sidebar.tsx +95 -25
  38. package/src/client/TerminalView.tsx +41 -0
  39. package/src/client/TerminalWaitBanner.tsx +32 -0
  40. package/src/client/TextEditor.tsx +27 -45
  41. package/src/client/TreePanel.tsx +22 -2
  42. package/src/client/api.ts +20 -0
  43. package/src/client/chunk-loader.ts +1 -1
  44. package/src/client/chunks/locale.tsx +60 -0
  45. package/src/client/conversation-draft.ts +233 -7
  46. package/src/client/index.tsx +19 -8
  47. package/src/client/locales-ar.ts +17 -4
  48. package/src/client/locales-de.ts +17 -4
  49. package/src/client/locales-fr.ts +17 -4
  50. package/src/client/locales-hi.ts +17 -4
  51. package/src/client/locales-id.ts +17 -4
  52. package/src/client/locales-it.ts +17 -4
  53. package/src/client/locales-ja.ts +17 -4
  54. package/src/client/locales-ko.ts +17 -4
  55. package/src/client/locales-nl.ts +17 -4
  56. package/src/client/locales-pl.ts +17 -4
  57. package/src/client/locales-pt.ts +17 -4
  58. package/src/client/locales-ru.ts +17 -4
  59. package/src/client/locales-sv.ts +17 -4
  60. package/src/client/locales-th.ts +17 -4
  61. package/src/client/locales-tr.ts +17 -4
  62. package/src/client/locales-vi.ts +17 -4
  63. package/src/client/locales-zh-HK.ts +17 -4
  64. package/src/client/locales-zh-MO.ts +17 -4
  65. package/src/client/locales-zh-TW.ts +17 -4
  66. package/src/client/locales.ts +41 -51
  67. package/src/client/selection-popup.ts +155 -0
  68. package/src/client/service.ts +1 -1
  69. package/src/client/sidebar.module.css +68 -0
  70. package/src/client/state.ts +56 -10
  71. package/src/client/terminal-font.ts +34 -3
  72. package/src/context-types.ts +3 -2
  73. package/src/fs-operations.ts +126 -4
  74. package/src/git.ts +56 -3
  75. package/src/index.ts +82 -7
  76. package/src/open-external.ts +3 -4
  77. package/src/prefs-shared.ts +7 -5
  78. package/src/pty-manager.ts +176 -5
  79. package/src/sidechat-routes.ts +13 -1
  80. package/src/tools.ts +24 -6
  81. package/src/wire.ts +3 -0
@@ -26,6 +26,7 @@ import type { Agent, AgentSetup, CreateAgentOptions, ResumeAgentOptions } from '
26
26
  import { snapshotSubagentDescriptor } from '@deepseek-ai/dsh-subagent'
27
27
  import type { Context as CordisContext } from '@deepseek-ai/cordis'
28
28
  import type { SessionEvent, SessionId } from '@deepseek-ai/dsh-session'
29
+ import { SessionLogOffset } from '@deepseek-ai/dsh-session'
29
30
  import type { SidebarSessionEvent } from './context-types.ts'
30
31
  import type {
31
32
  Context,
@@ -196,17 +197,28 @@ export function buildSidechatApi(ctx: Context): SidechatRoutes {
196
197
  data: descriptor as unknown as Record<string, unknown>,
197
198
  }
198
199
  const seed = [...inheritance.seed, descriptorEvent]
200
+ // Fork-marker fields (the exact shape the host's own session.fork uses):
201
+ // without `isSeeded` + `inheritedEventCount` the session treats the whole
202
+ // seed as the child's OWN events, so the child's Inbox constructor
203
+ // replays the parent's `agent/inbox/spliced` events and inherits
204
+ // whatever input sat UNCLAIMED in the parent at the click moment (a
205
+ // queued follow-up, or a tool-result context spliced into next-step
206
+ // between step boundaries of a long-running turn). The first side
207
+ // prompt would then claim and send that stale message BEFORE the
208
+ // boundary + question. The marker keeps `ownEvents()` at the end-seed
209
+ // boundary, so the inherited inbox replays to empty.
199
210
  const options: CreateAgentOptions = {
200
211
  sessionId: childId,
201
212
  meta: {
202
213
  ...(parentSession.header.cwd === undefined ? {} : { cwd: parentSession.header.cwd }),
203
214
  parentSession: parentSession.id,
204
- isSeeded: seed.length > 0,
215
+ isSeeded: true,
205
216
  origin: 'subagent',
206
217
  delegationDepth: (parentSession.header.delegationDepth ?? 0) + 1,
207
218
  ...(agentPreset === undefined ? {} : { agentPreset }),
208
219
  },
209
220
  seed: seed as unknown as readonly SessionEvent[],
221
+ inheritedEventCount: SessionLogOffset(seed.length),
210
222
  agentOptions: { ...parent.options },
211
223
  setup,
212
224
  signal: AbortSignal.timeout(CREATE_TIMEOUT_MS),
package/src/tools.ts CHANGED
@@ -287,13 +287,17 @@ export function registerTools(
287
287
  register(defineTool({
288
288
  name: 'terminal_wait_for',
289
289
  description:
290
- 'Block until a substring appears in a terminal\'s retained transcript, or until the timeout elapses, or until the terminal exits — whichever happens first. '
290
+ 'Block until a pattern appears in a terminal\'s retained transcript, or until the timeout elapses, or until the terminal exits — whichever happens first. '
291
291
  + 'Use this to synchronize on command completion cues ( e.g. a shell prompt, "done", "Listening on", "Build successful" ) '
292
292
  + 'without busy-polling terminal_read. '
293
+ + 'The needle is a JavaScript regular expression ( a pattern that fails to compile falls back to verbatim substring matching ). '
294
+ + 'One needle may cover MULTIPLE outcomes — e.g. wait on `(BUILD_OK|BUILD_FAIL)` or `Build (succeeded|failed)` returns as soon as EITHER marker appears, '
295
+ + 'and the found result\'s `match` field tells which alternative hit ( build success vs failure ). '
293
296
  + 'The wait scans the FULL retained transcript (up to ~1 MiB) on every poll, so a needle that scrolled past the most recent chunk is still a match. '
294
- + 'Returns `found` with the line/column of the first occurrence, `timeout` if the needle did not appear in time, or `exited` if the terminal process died before the needle appeared. '
297
+ + 'Returns `found` with the line/column and the matched text, `timeout` if the needle did not appear in time, or `exited` if the terminal process died before the needle appeared. '
295
298
  + 'Default timeout is 10 seconds; raise it for long-running commands ( dev servers, test suites ). '
296
- + 'The wait is cooperative: a tool-call cancel ( or agent turn end ) aborts it immediately.',
299
+ + 'The wait is cooperative: a tool-call cancel ( or agent turn end ) aborts it immediately. '
300
+ + 'The user can skip the wait from the sidebar ( a banner on the terminal\'s tab shows the needle and a skip button ) — the tool then returns `skipped`.',
297
301
  parameters: {
298
302
  uuid: {
299
303
  type: 'string',
@@ -303,7 +307,8 @@ export function registerTools(
303
307
  needle: {
304
308
  type: 'string',
305
309
  required: true,
306
- description: 'Substring to wait for (case-sensitive, verbatim). Must be non-empty.',
310
+ description: 'JavaScript regular expression to wait for (case-sensitive); a pattern that fails to compile falls back to verbatim substring matching. '
311
+ + 'May cover several outcomes in one wait ( e.g. `(BUILD_OK|BUILD_FAIL)` for build success/failure ) — check `match` in the found result to see which one hit. Must be non-empty.',
307
312
  },
308
313
  timeout_ms: {
309
314
  type: 'number',
@@ -321,6 +326,7 @@ export function registerTools(
321
326
  needle: { type: 'string', required: true },
322
327
  line: { type: 'integer', required: true, description: '0-based line index in the retained transcript where the needle first appeared.' },
323
328
  column: { type: 'integer', required: true, description: '0-based column index within that line where the match starts.' },
329
+ match: { type: 'string', required: true, description: 'The text that actually matched — for multi-outcome patterns ( e.g. `(BUILD_OK|BUILD_FAIL)` ) this tells which alternative matched.' },
324
330
  elapsedMs: { type: 'integer', required: true, description: 'Wall-clock milliseconds from wait start to match.' },
325
331
  },
326
332
  },
@@ -344,16 +350,28 @@ export function registerTools(
344
350
  exitSignal: { oneOf: [{ type: 'string' }, { type: 'null' }], description: 'Exit signal name, if killed by a signal.' },
345
351
  },
346
352
  },
353
+ {
354
+ type: 'object',
355
+ additionalProperties: false,
356
+ properties: {
357
+ kind: { type: 'string', required: true, const: 'skipped' },
358
+ needle: { type: 'string', required: true },
359
+ },
360
+ },
347
361
  ],
348
362
  },
349
363
  render: (_args, value) => {
350
- const v = value as { kind: 'found' | 'timeout' | 'exited'; needle: string; elapsedMs?: number; timeoutMs?: number; line?: number; column?: number; exitCode?: number | null; exitSignal?: string | null }
364
+ const v = value as { kind: 'found' | 'timeout' | 'exited' | 'skipped'; needle: string; elapsedMs?: number; timeoutMs?: number; line?: number; column?: number; match?: string; exitCode?: number | null; exitSignal?: string | null }
351
365
  if (v.kind === 'found') {
352
- return [{ type: 'text', text: `Found "${v.needle}" at line ${v.line}, column ${v.column} (after ${v.elapsedMs}ms).` }]
366
+ const matched = v.match !== undefined && v.match !== '' ? `, matched "${v.match}"` : ''
367
+ return [{ type: 'text', text: `Found "${v.needle}" at line ${v.line}, column ${v.column}${matched} (after ${v.elapsedMs}ms).` }]
353
368
  }
354
369
  if (v.kind === 'timeout') {
355
370
  return [{ type: 'text', text: `Timed out after ${v.timeoutMs}ms waiting for "${v.needle}". Call terminal_read to inspect the transcript.` }]
356
371
  }
372
+ if (v.kind === 'skipped') {
373
+ return [{ type: 'text', text: `Skipped by user while waiting for "${v.needle}" — the wait ended early. Call terminal_read to inspect the transcript and decide how to proceed.` }]
374
+ }
357
375
  const exitInfo = v.exitCode !== undefined && v.exitCode !== null ? ` (exit code ${v.exitCode})` : ''
358
376
  return [{ type: 'text', text: `Terminal exited before "${v.needle}" appeared${exitInfo}.` }]
359
377
  },
package/src/wire.ts CHANGED
@@ -17,6 +17,7 @@ export type SidebarErrorCode =
17
17
  | 'git-error'
18
18
  | 'pty-error'
19
19
  | 'pty-deps-missing'
20
+ | 'shell-not-found'
20
21
  | 'job-error'
21
22
  | 'cdp-down'
22
23
  | 'sidechat-error'
@@ -31,6 +32,8 @@ export class SidebarError extends Error {
31
32
  readonly code: SidebarErrorCode,
32
33
  message: string,
33
34
  readonly status = 400,
35
+ /** Optional structured context (e.g. `{ shell }` for shell-not-found). */
36
+ readonly meta?: Record<string, string>,
34
37
  ) {
35
38
  super(message)
36
39
  }