@keith9681/dsh-sidebar 0.15.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.
Files changed (220) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +0 -0
  3. package/README_EN.md +0 -0
  4. package/cordis.patch.yml +49 -0
  5. package/lib/client-editor.js +34651 -0
  6. package/lib/client-mermaid.js +200629 -0
  7. package/lib/client-registry.js +13388 -0
  8. package/lib/client-terminal.js +8904 -0
  9. package/lib/client.js +13388 -0
  10. package/lib/index.js +3959 -0
  11. package/lib/invariant.js +22 -0
  12. package/lib/types/agent-pty.d.ts +226 -0
  13. package/lib/types/browser-probe.d.ts +15 -0
  14. package/lib/types/bundle-route.d.ts +12 -0
  15. package/lib/types/client/BrowserView.d.ts +22 -0
  16. package/lib/types/client/DiffTab.d.ts +6 -0
  17. package/lib/types/client/DiffView.d.ts +51 -0
  18. package/lib/types/client/EditorHost.d.ts +12 -0
  19. package/lib/types/client/FileTree.d.ts +36 -0
  20. package/lib/types/client/GitView.d.ts +8 -0
  21. package/lib/types/client/OrphanedTab.d.ts +11 -0
  22. package/lib/types/client/PdfView.d.ts +6 -0
  23. package/lib/types/client/RenderBoundary.d.ts +32 -0
  24. package/lib/types/client/SandboxStatusBar.d.ts +10 -0
  25. package/lib/types/client/SideCardSection.d.ts +74 -0
  26. package/lib/types/client/SideChatView.d.ts +16 -0
  27. package/lib/types/client/Sidebar.d.ts +6 -0
  28. package/lib/types/client/SubagentView.d.ts +16 -0
  29. package/lib/types/client/TabBar.d.ts +43 -0
  30. package/lib/types/client/TerminalView.d.ts +24 -0
  31. package/lib/types/client/TextEditor.d.ts +10 -0
  32. package/lib/types/client/TreePanel.d.ts +23 -0
  33. package/lib/types/client/UploadOverlay.d.ts +20 -0
  34. package/lib/types/client/add-plugin-modal.d.ts +15 -0
  35. package/lib/types/client/api.d.ts +268 -0
  36. package/lib/types/client/binary-download.d.ts +12 -0
  37. package/lib/types/client/breakpoints.d.ts +12 -0
  38. package/lib/types/client/browser.d.ts +50 -0
  39. package/lib/types/client/builtins/index.d.ts +18 -0
  40. package/lib/types/client/builtins/tabs.d.ts +11 -0
  41. package/lib/types/client/builtins/viewers.d.ts +3 -0
  42. package/lib/types/client/chunk-loader.d.ts +124 -0
  43. package/lib/types/client/chunks/editor.d.ts +9 -0
  44. package/lib/types/client/chunks/mermaid.d.ts +10 -0
  45. package/lib/types/client/chunks/terminal.d.ts +9 -0
  46. package/lib/types/client/cm-themes.d.ts +24 -0
  47. package/lib/types/client/conversation-draft.d.ts +14 -0
  48. package/lib/types/client/desktop-env.d.ts +35 -0
  49. package/lib/types/client/editable-state.d.ts +27 -0
  50. package/lib/types/client/editor-load.d.ts +66 -0
  51. package/lib/types/client/frame-batcher.d.ts +24 -0
  52. package/lib/types/client/icons.d.ts +57 -0
  53. package/lib/types/client/image-types.d.ts +3 -0
  54. package/lib/types/client/ime-guard.d.ts +36 -0
  55. package/lib/types/client/index.d.ts +19 -0
  56. package/lib/types/client/intercept.d.ts +33 -0
  57. package/lib/types/client/lang.d.ts +12 -0
  58. package/lib/types/client/lazy-chunk.d.ts +25 -0
  59. package/lib/types/client/link-intercept.d.ts +42 -0
  60. package/lib/types/client/locales.d.ts +366 -0
  61. package/lib/types/client/mermaid-blocks.d.ts +41 -0
  62. package/lib/types/client/mermaid-sanitize.d.ts +2 -0
  63. package/lib/types/client/mermaid.d.ts +12 -0
  64. package/lib/types/client/open-when-sized.d.ts +20 -0
  65. package/lib/types/client/open-with-settings.d.ts +4 -0
  66. package/lib/types/client/open-with.d.ts +87 -0
  67. package/lib/types/client/openpath-intercept.d.ts +41 -0
  68. package/lib/types/client/paths.d.ts +35 -0
  69. package/lib/types/client/pdf-types.d.ts +2 -0
  70. package/lib/types/client/plugin-settings.d.ts +8 -0
  71. package/lib/types/client/plugins-shared.d.ts +27 -0
  72. package/lib/types/client/plugins-tabs.d.ts +3 -0
  73. package/lib/types/client/plugins-viewers.d.ts +3 -0
  74. package/lib/types/client/prefs.d.ts +41 -0
  75. package/lib/types/client/produced-files.d.ts +23 -0
  76. package/lib/types/client/selection-payload.d.ts +27 -0
  77. package/lib/types/client/service.d.ts +440 -0
  78. package/lib/types/client/settings-nav-icon.d.ts +19 -0
  79. package/lib/types/client/shell-presets.d.ts +48 -0
  80. package/lib/types/client/sidechat-transcript.d.ts +103 -0
  81. package/lib/types/client/split-pane.d.ts +30 -0
  82. package/lib/types/client/state.d.ts +359 -0
  83. package/lib/types/client/subagent-detect.d.ts +54 -0
  84. package/lib/types/client/subagent-jobs.d.ts +63 -0
  85. package/lib/types/client/tab-content-memo.d.ts +33 -0
  86. package/lib/types/client/terminal-font.d.ts +20 -0
  87. package/lib/types/client/theme.d.ts +45 -0
  88. package/lib/types/client/titlebar-strip.d.ts +23 -0
  89. package/lib/types/client/upload.d.ts +69 -0
  90. package/lib/types/client/wco.d.ts +47 -0
  91. package/lib/types/config.d.ts +64 -0
  92. package/lib/types/context-types.d.ts +603 -0
  93. package/lib/types/fs-operations.d.ts +28 -0
  94. package/lib/types/fs-search.d.ts +24 -0
  95. package/lib/types/fs-tree.d.ts +51 -0
  96. package/lib/types/git.d.ts +82 -0
  97. package/lib/types/html-route.d.ts +59 -0
  98. package/lib/types/index.d.ts +47 -0
  99. package/lib/types/invariant.d.ts +15 -0
  100. package/lib/types/jobs-routes.d.ts +45 -0
  101. package/lib/types/open-external.d.ts +24 -0
  102. package/lib/types/prefs-shared.d.ts +225 -0
  103. package/lib/types/pty-deps.d.ts +78 -0
  104. package/lib/types/pty-manager.d.ts +168 -0
  105. package/lib/types/sidechat-core.d.ts +172 -0
  106. package/lib/types/sidechat-routes.d.ts +30 -0
  107. package/lib/types/subagent-activity.d.ts +44 -0
  108. package/lib/types/subagent-live-route.d.ts +44 -0
  109. package/lib/types/tools.d.ts +31 -0
  110. package/lib/types/trust-fence.d.ts +24 -0
  111. package/lib/types/wire.d.ts +38 -0
  112. package/package.json +173 -0
  113. package/scripts/install.ps1 +289 -0
  114. package/scripts/install.sh +287 -0
  115. package/src/agent-pty.ts +527 -0
  116. package/src/browser-probe.ts +26 -0
  117. package/src/bundle-route.ts +129 -0
  118. package/src/client/BrowserView.tsx +253 -0
  119. package/src/client/DiffTab.tsx +110 -0
  120. package/src/client/DiffView.tsx +305 -0
  121. package/src/client/EditorHost.tsx +525 -0
  122. package/src/client/FileTree.tsx +653 -0
  123. package/src/client/GitView.tsx +558 -0
  124. package/src/client/OrphanedTab.tsx +27 -0
  125. package/src/client/PdfView.tsx +110 -0
  126. package/src/client/RenderBoundary.tsx +49 -0
  127. package/src/client/SandboxStatusBar.tsx +60 -0
  128. package/src/client/SideCardSection.module.css +960 -0
  129. package/src/client/SideCardSection.tsx +1152 -0
  130. package/src/client/SideChatView.module.css +437 -0
  131. package/src/client/SideChatView.tsx +644 -0
  132. package/src/client/Sidebar.tsx +1148 -0
  133. package/src/client/SubagentView.module.css +547 -0
  134. package/src/client/SubagentView.tsx +883 -0
  135. package/src/client/TabBar.tsx +305 -0
  136. package/src/client/TerminalView.tsx +383 -0
  137. package/src/client/TextEditor.tsx +500 -0
  138. package/src/client/TreePanel.tsx +273 -0
  139. package/src/client/UploadOverlay.tsx +62 -0
  140. package/src/client/add-plugin-modal.tsx +199 -0
  141. package/src/client/api.ts +335 -0
  142. package/src/client/binary-download.tsx +23 -0
  143. package/src/client/breakpoints.ts +51 -0
  144. package/src/client/browser.ts +119 -0
  145. package/src/client/builtins/index.ts +37 -0
  146. package/src/client/builtins/tabs.tsx +331 -0
  147. package/src/client/builtins/viewers.tsx +125 -0
  148. package/src/client/chunk-loader.ts +351 -0
  149. package/src/client/chunks/editor.tsx +9 -0
  150. package/src/client/chunks/mermaid.tsx +10 -0
  151. package/src/client/chunks/terminal.tsx +9 -0
  152. package/src/client/cm-themes.ts +129 -0
  153. package/src/client/conversation-draft.ts +29 -0
  154. package/src/client/css-modules.d.ts +5 -0
  155. package/src/client/desktop-env.ts +72 -0
  156. package/src/client/editable-state.ts +70 -0
  157. package/src/client/editor-load.ts +92 -0
  158. package/src/client/frame-batcher.ts +56 -0
  159. package/src/client/icons.tsx +161 -0
  160. package/src/client/image-types.ts +8 -0
  161. package/src/client/ime-guard.ts +47 -0
  162. package/src/client/index.tsx +369 -0
  163. package/src/client/intercept.tsx +110 -0
  164. package/src/client/lang.ts +103 -0
  165. package/src/client/layout.css +94 -0
  166. package/src/client/lazy-chunk.tsx +89 -0
  167. package/src/client/link-intercept.ts +73 -0
  168. package/src/client/locales.ts +734 -0
  169. package/src/client/mermaid-blocks.ts +110 -0
  170. package/src/client/mermaid-sanitize.ts +93 -0
  171. package/src/client/mermaid.tsx +401 -0
  172. package/src/client/open-when-sized.ts +43 -0
  173. package/src/client/open-with-settings.tsx +135 -0
  174. package/src/client/open-with.ts +221 -0
  175. package/src/client/openpath-intercept.ts +62 -0
  176. package/src/client/paths.ts +47 -0
  177. package/src/client/pdf-types.ts +4 -0
  178. package/src/client/plugin-settings.ts +43 -0
  179. package/src/client/plugins-shared.ts +29 -0
  180. package/src/client/plugins-tabs.ts +87 -0
  181. package/src/client/plugins-viewers.ts +30 -0
  182. package/src/client/prefs.ts +207 -0
  183. package/src/client/produced-files.ts +91 -0
  184. package/src/client/selection-payload.ts +86 -0
  185. package/src/client/service.ts +838 -0
  186. package/src/client/settings-nav-icon.ts +45 -0
  187. package/src/client/shell-presets.ts +83 -0
  188. package/src/client/sidebar.module.css +2577 -0
  189. package/src/client/sidechat-transcript.ts +321 -0
  190. package/src/client/split-pane.tsx +322 -0
  191. package/src/client/state.ts +1175 -0
  192. package/src/client/subagent-detect.ts +137 -0
  193. package/src/client/subagent-jobs.ts +161 -0
  194. package/src/client/tab-content-memo.ts +46 -0
  195. package/src/client/terminal-font.ts +28 -0
  196. package/src/client/theme.ts +110 -0
  197. package/src/client/titlebar-strip.ts +37 -0
  198. package/src/client/upload.ts +187 -0
  199. package/src/client/wco.ts +120 -0
  200. package/src/config.ts +155 -0
  201. package/src/context-types.ts +610 -0
  202. package/src/fs-operations.ts +99 -0
  203. package/src/fs-search.ts +86 -0
  204. package/src/fs-tree.ts +158 -0
  205. package/src/git.ts +244 -0
  206. package/src/html-route.ts +106 -0
  207. package/src/index.ts +1132 -0
  208. package/src/invariant.ts +32 -0
  209. package/src/jobs-routes.ts +257 -0
  210. package/src/open-external.ts +90 -0
  211. package/src/prefs-shared.ts +268 -0
  212. package/src/pty-deps.ts +240 -0
  213. package/src/pty-manager.ts +376 -0
  214. package/src/sidechat-core.ts +468 -0
  215. package/src/sidechat-routes.ts +344 -0
  216. package/src/subagent-activity.ts +91 -0
  217. package/src/subagent-live-route.ts +93 -0
  218. package/src/tools.ts +479 -0
  219. package/src/trust-fence.ts +77 -0
  220. package/src/wire.ts +100 -0
@@ -0,0 +1,610 @@
1
+ /**
2
+ * Structural types for the cordis services this plugin consumes, plus the
3
+ * Context augmentation both halves share. A third-party plugin resolves
4
+ * outside the DSH monorepo's single cordis instance, so the upstream
5
+ * `declare module 'cordis'` augmentations do not reach this Context — and
6
+ * the npm cordis package does not declare the DSH-vendored runtime members
7
+ * (`ctx.effect`, service properties). The members below mirror the actual
8
+ * runtime shapes this plugin touches:
9
+ * - webServer: @deepseek-ai/dsh-host-webserver (the WebServer)
10
+ * - sessions: host side @deepseek-ai/dsh-session (SessionStore), client
11
+ * side the runtime ISessions list feed
12
+ * - conversation: client side ui-conversation's IConversation (composer
13
+ * draft), read lazily through `ctx.get` — cross-plugin service reads need
14
+ * an inject declaration, so the direct property is never typed here
15
+ * - webRuntime: @deepseek-ai/dsh-web-app (bind-derived trusted hosts)
16
+ * - slots: the client runtime SlotRegistry
17
+ * - effect: the DSH-vendored cordis lifecycle helper
18
+ * Drift from upstream is contained to this file.
19
+ *
20
+ * This file must stay FREE of Node.js types (`node:http`, `node:stream`,
21
+ * `Buffer`): it is part of the CLIENT-reachable declaration graph (the
22
+ * `Context` in `TabComponentProps` and the `declare module` augmentation),
23
+ * so a Node import here would leak into browser-only consumer builds. The
24
+ * webServer faces below are therefore structural mirrors with plain
25
+ * interfaces (the host casts to real Node types at the few boundaries that
26
+ * need them — e.g. the `ws` upgrade hook in src/index.ts).
27
+ */
28
+ import type { Context } from 'cordis'
29
+ import type { BetterSidebarService } from './client/service.ts'
30
+
31
+ /** The request face route handlers see (structural subset of node's
32
+ * IncomingMessage: the URL/method/header reads and the async body
33
+ * iteration `readJsonBody` uses). */
34
+ export interface SidebarHttpRequest {
35
+ url?: string
36
+ method?: string
37
+ headers: Record<string, string | string[] | undefined>
38
+ [Symbol.asyncIterator](): AsyncIterator<string | Uint8Array>
39
+ }
40
+
41
+ /** The response face route handlers write to (structural subset of node's
42
+ * ServerResponse: the status/header/body writes the routes use). */
43
+ export interface SidebarHttpResponse {
44
+ statusCode: number
45
+ writeHead(status: number, headers?: Record<string, string>): void
46
+ end(body?: string | Uint8Array): void
47
+ }
48
+
49
+ /** The upgrade socket face (structural subset: the destroy the fences use). */
50
+ export interface SidebarUpgradeSocket {
51
+ destroy(): void
52
+ }
53
+
54
+ /** The upgrade head bytes (Buffer at runtime; typed as bytes so no Node
55
+ * global leaks into the declaration graph). */
56
+ export type SidebarUpgradeHead = Uint8Array
57
+
58
+ /** One named webserver route (mirror of the host-webserver WebRoute). */
59
+ export interface SidebarWebRoute {
60
+ kind: 'exact' | 'prefix'
61
+ path: string
62
+ handler: (req: SidebarHttpRequest, res: SidebarHttpResponse) => void | Promise<void>
63
+ }
64
+
65
+ /** One exact-path HTTP upgrade registration (mirror of WebUpgradeRoute). */
66
+ export interface SidebarWebUpgradeRoute {
67
+ path: string
68
+ handler: (req: SidebarHttpRequest, socket: SidebarUpgradeSocket, head: SidebarUpgradeHead) => void | Promise<void>
69
+ }
70
+
71
+ /** The webServer service face this plugin uses. */
72
+ export interface SidebarWebServer {
73
+ register(route: SidebarWebRoute): () => void
74
+ registerUpgrade(route: SidebarWebUpgradeRoute): () => void
75
+ }
76
+
77
+ /** A published session's header slice the sidebar reads (authoritative cwd). */
78
+ export interface SidebarSessionHeader {
79
+ cwd?: string
80
+ }
81
+
82
+ /** The host session store face (`ctx.sessions.get(id)` returns the live session). */
83
+ export interface SidebarSessionStore {
84
+ get(id: string): {
85
+ header: SidebarSessionHeader
86
+ /**
87
+ * The live session's append-only event log (immutable snapshot; absent
88
+ * on sessions the runtime has not hydrated). Read-only access — the
89
+ * jobs.output route replays `job_output` tool/result rows from it.
90
+ */
91
+ events?: readonly SidebarSessionEvent[]
92
+ } | undefined
93
+ }
94
+
95
+ /**
96
+ * The web runtime service face (mirror of @deepseek-ai/dsh-web-app's
97
+ * WebRuntimeValues): the bind-derived trust list the /api gateway's fence
98
+ * accepts — LAN IP literals sampled when the server binds all interfaces,
99
+ * plus explicit `--trusted-host` authorities.
100
+ */
101
+ export interface SidebarWebRuntime {
102
+ trustedHosts: readonly string[]
103
+ }
104
+
105
+ /** Registration options the sidebar passes to `ctx.slots.register` (subset of the real options). */
106
+ export interface SidebarSlotRegisterOptions {
107
+ name: string
108
+ key?: string
109
+ id?: string
110
+ order?: number
111
+ label?: string | (() => string)
112
+ /** Chain routing selector (returns the matched value, or null to pass on). */
113
+ select?: (owner: unknown) => unknown
114
+ priority?: number
115
+ locale?: string
116
+ registrant?: string
117
+ /** Business-face factory; args depend on the slot scope. */
118
+ inject?: (...args: any[]) => Record<string, unknown>
119
+ children?: Record<string, unknown>
120
+ }
121
+
122
+ /** The client slots service face (register returns the disposer). */
123
+ export interface SidebarSlotsService {
124
+ register(options: SidebarSlotRegisterOptions, component: unknown): () => void
125
+ /**
126
+ * Run a callback for each declaration lifetime of a slot (the runtime
127
+ * SlotRegistry.inject): a no-op while the slot is undeclared, so the
128
+ * settings section registration waits for the settings shell.
129
+ */
130
+ inject(key: string, callback: () => () => void): () => void
131
+ }
132
+
133
+ /** The client session list row the sidebar reads (cwd for the explorer). */
134
+ export interface SidebarSessionSummary {
135
+ id: string
136
+ cwd?: string
137
+ displayTitle: string
138
+ /** Coarse durable origin for navigation filtering (subagent children). */
139
+ origin?: 'subagent'
140
+ /** Durable direct parent session id (present on subagent children). */
141
+ parentId?: string
142
+ /** Whether the session's agent is currently running. */
143
+ running?: boolean
144
+ }
145
+
146
+ /** One healthy subagent catalog child row (structural mirror of the runtime). */
147
+ export interface SidebarSubagentChildEntry {
148
+ kind: 'child'
149
+ id: string
150
+ /** Whether the child Agent driver is running at the Host sampling boundary. */
151
+ activity: 'running' | 'inactive'
152
+ /** Whether a direct descendant has durable `origin: 'subagent'`. */
153
+ hasChildren: boolean
154
+ mode: 'one-shot' | 'continuable'
155
+ label?: string
156
+ }
157
+
158
+ /** One unreadable catalog row (corrupt / unsupported / unavailable). */
159
+ export interface SidebarSubagentDiagnosticEntry {
160
+ kind: 'diagnostic'
161
+ id: string
162
+ reason: 'corrupt' | 'unsupported' | 'unavailable'
163
+ }
164
+
165
+ /** The per-parent lazy catalog delivered through the sessions list feed. */
166
+ export interface SidebarSubagentCatalog {
167
+ entries: Array<SidebarSubagentChildEntry | SidebarSubagentDiagnosticEntry>
168
+ parentAvailable: boolean
169
+ state: 'loading' | 'ready' | 'error'
170
+ error: { code?: string; message?: string } | null
171
+ }
172
+
173
+ /** Durable parent/child address that selects subagent transport in the client. */
174
+ export interface SidebarSubagentAddress {
175
+ parentSessionId: string
176
+ childSessionId: string
177
+ mode: 'one-shot' | 'continuable'
178
+ }
179
+
180
+ /** Minimal structural mirror of one session event (the subagent history tail). */
181
+ export interface SidebarSessionEvent {
182
+ type: string
183
+ seq: number
184
+ time: number
185
+ data: Record<string, unknown>
186
+ }
187
+
188
+ /** One history row: the durable event plus an optional tool presentation view. */
189
+ export interface SidebarHistoryEntry {
190
+ event: SidebarSessionEvent
191
+ view?: unknown
192
+ }
193
+
194
+ /** Lifecycle status set of one background job (closed wire union). */
195
+ export type SidebarJobStatus = 'running' | 'stopping' | 'completed' | 'killed' | 'failed'
196
+
197
+ /**
198
+ * One background job as the client mirror sees it (wire `JobView` shape:
199
+ * id/kind/label/status/detail?/startedAt/finishedAt?).
200
+ */
201
+ export interface SidebarJobView {
202
+ /** Registry-issued `<kind>-N` identity, stable for the job's whole life. */
203
+ id: string
204
+ /** Producer kind (`bash`, `pwsh`, `subagent`, …; open string by design). */
205
+ kind: string
206
+ /** Producer-supplied one-line label: the command, or the delegation description. */
207
+ label: string
208
+ /** Current lifecycle state. */
209
+ status: SidebarJobStatus
210
+ /** Kind-specific status detail ('exit code: 3'), present once supplied. */
211
+ detail?: string
212
+ /** Epoch ms when the job was registered. */
213
+ startedAt: number
214
+ /** Epoch ms when the job settled; absent while live. */
215
+ finishedAt?: number
216
+ }
217
+
218
+ /** The host jobs registry face the sidebar routes touch (structural mirror of `JobRegistry`). */
219
+ export interface SidebarJobsService {
220
+ /** Request cancellation; throws for an unknown or foreign job. */
221
+ kill(id: string, caller?: SidebarAgent, reason?: string): 'requested' | 'already-finished'
222
+ }
223
+
224
+ /** The host agent registry face (structural mirror of the runtime `ctx.agents`). */
225
+ export interface SidebarAgentsService {
226
+ /** The live agent registered under a session id, or undefined when not live. */
227
+ get(id: string): SidebarAgent | undefined
228
+ /**
229
+ * Create a session + agent with a custom seed (mirror of the runtime
230
+ * AgentRegistry.create) — the Side Chat thread-creation seam: the SAME
231
+ * public seam api-proxy's session.fork and the subagent fork provider use.
232
+ */
233
+ create?(options: unknown): Promise<{ agent: SidebarAgent; dispose(): Promise<void> }>
234
+ /**
235
+ * Resume an agent on a persisted session (mirror of the runtime
236
+ * AgentRegistry.resume) — the Side Chat cold-continuation seam after a
237
+ * DSH restart or a closed thread.
238
+ */
239
+ resume?(options: unknown): Promise<{ agent: SidebarAgent; dispose(): Promise<void> }>
240
+ }
241
+
242
+ /** The host subagent runtime face (`ctx.subagents`; optional — the live
243
+ * batch route degrades to a 503 when the deployment lacks it). Only the
244
+ * read-only descendant enumeration this plugin needs is mirrored. */
245
+ export interface SidebarSubagentsService {
246
+ /**
247
+ * Enumerate the root's complete session-backed subagent tree in stable
248
+ * pre-order without loading or resuming an Agent (mirror of
249
+ * `SubagentRuntime.listDescendants`).
250
+ */
251
+ listDescendants(
252
+ rootSessionId: string,
253
+ signal?: AbortSignal,
254
+ ): Promise<SidebarSubagentDescendantEntry[]>
255
+ }
256
+
257
+ /** One descendant row of `ctx.subagents.listDescendants` (structural mirror). */
258
+ export type SidebarSubagentDescendantEntry =
259
+ | {
260
+ kind: 'child'
261
+ id: string
262
+ activity: 'running' | 'inactive'
263
+ hasChildren: boolean
264
+ mode: 'one-shot' | 'continuable'
265
+ label?: string
266
+ parentId: string
267
+ depth: number
268
+ }
269
+ | {
270
+ kind: 'diagnostic'
271
+ id: string
272
+ reason: 'corrupt' | 'unsupported' | 'unavailable'
273
+ parentId: string
274
+ depth: number
275
+ }
276
+
277
+ /** The host agent-presets service face (mirror of the runtime agentPresets
278
+ * service): resolves and mounts the preset composition a session recorded,
279
+ * so a resumed or forked session rebuilds the same tool/prompt world its
280
+ * history was produced under. */
281
+ export interface SidebarAgentPresetsService {
282
+ /** Resolve a preset id; undefined resolves the deployment default. */
283
+ resolve(presetId?: string): Promise<{ id: string }>
284
+ /** Mount a preset's composition into an agent scope before publication. */
285
+ mount(agentCtx: unknown, presetId: string): Promise<void>
286
+ }
287
+
288
+ /** The host session-title service face (mirror of the sessionTitle service). */
289
+ export interface SidebarSessionTitleService {
290
+ /** Rename one live session's title (pins it against auto-regeneration). */
291
+ rename(session: unknown, title: string): { title: string; eventSeq: number }
292
+ }
293
+
294
+ /** The host session-persistence face (mirror of the sessionPersistence
295
+ * service): detached inspection of a persisted session, used to compose the
296
+ * recorded preset when a Side Chat thread cold-resumes. */
297
+ export interface SidebarSessionPersistenceService {
298
+ inspect(sessionId: string): Promise<{
299
+ meta: { cwd?: string; agentPreset?: string }
300
+ events: readonly SidebarSessionEvent[]
301
+ }>
302
+ }
303
+
304
+ /** RPC result slot mirror (`RpcResult<T>` on the wire). */
305
+ export type SidebarRpcResult<T> = { ok: true; value: T } | { ok: false; error: { code: string; message: string } }
306
+
307
+ /** Unary response mirror (`RpcResponse<T>` on the wire). */
308
+ export interface SidebarRpcResponse<T> {
309
+ rpcId: unknown
310
+ result: SidebarRpcResult<T>
311
+ }
312
+
313
+ /** The generic session-history RPC face the Side Chat transcript polls
314
+ * (subagent.history verifies subagent-catalog membership, which our custom
315
+ * side-thread children do not have — the generic session.history reads any
316
+ * durable log directly). */
317
+ export interface SidebarSessionHistoryRpc {
318
+ history(
319
+ payload: { sessionId: string; beforeSeq?: number; maxMessages?: number },
320
+ signal?: AbortSignal,
321
+ ): Promise<SidebarRpcResponse<{ events: SidebarHistoryEntry[]; hasMore: boolean }>>
322
+ }
323
+
324
+ /** The wire face the Subagent activity summary needs (subset of `ctx.connection`). */
325
+ export interface SidebarConnectionHandle {
326
+ api: {
327
+ sessions: SidebarSessionHistoryRpc
328
+ subagents: {
329
+ history(
330
+ payload: SidebarSubagentAddress & { beforeSeq?: number; maxMessages?: number },
331
+ signal?: AbortSignal,
332
+ ): Promise<SidebarRpcResponse<{ events: SidebarHistoryEntry[]; hasMore: boolean }>>
333
+ }
334
+ }
335
+ }
336
+
337
+ /** The client session list snapshot the sidebar subscribes to. */
338
+ export interface SidebarSessionList {
339
+ current: string | undefined
340
+ byId: Record<string, SidebarSessionSummary>
341
+ /** Direct durable catalogs keyed by their selected parent address. */
342
+ subagentsByParent?: Readonly<Record<string, SidebarSubagentCatalog>>
343
+ /**
344
+ * Background jobs per session, last-wins from the harness's `session/jobs`
345
+ * push (a missing key is an empty set). Absent on runtime snapshots older
346
+ * than the jobs mirror — the sidebar simply shows no job rows.
347
+ */
348
+ jobsBySession?: Readonly<Record<string, readonly SidebarJobView[]>>
349
+ }
350
+
351
+ /** The client sessions service face (only the list feed is needed). */
352
+ export interface SidebarSessionsService {
353
+ list: {
354
+ getSnapshot(): SidebarSessionList
355
+ subscribe(fn: () => void): () => void
356
+ }
357
+ /**
358
+ * Select a listed session as current (mirror of the runtime ISessions.open)
359
+ * — used to jump back to the main agent from the topology root node.
360
+ */
361
+ open?(id: string): void
362
+ /**
363
+ * Fork a session from a completed-turn prefix of the source and resolve
364
+ * the child session id (mirror of the runtime ISessions.fork — throws on
365
+ * failure). The Side Chat "save as new session" action uses this to
366
+ * promote a hidden side thread into a top-level session.
367
+ */
368
+ fork?(opts: { sessionId: string; atSeq?: number; increaseTitle?: boolean }): Promise<string>
369
+ /**
370
+ * Resolve the stable session binding of one listed session (mirror of the
371
+ * runtime ISessions.binding); the saved-session rename uses the face's
372
+ * behavior verbs.
373
+ */
374
+ binding?(id: string): {
375
+ session: {
376
+ rename(title: string): Promise<unknown>
377
+ }
378
+ } | undefined
379
+ /**
380
+ * Resolve an Agent-scoped context view for one session (mirror of the
381
+ * runtime ISessions.scope) — the ticket `ctx.conversation.input.for`
382
+ * requires to reach that session's composer.
383
+ */
384
+ scope(id: string): Context | undefined
385
+ /**
386
+ * Open a healthy catalog child through its exact direct-parent address
387
+ * (mirror of the runtime ISessions.openSubagent).
388
+ */
389
+ openSubagent?(address: SidebarSubagentAddress): void
390
+ /**
391
+ * Resolve an already discovered direct-parent address without opening it.
392
+ */
393
+ subagentAddress?(id: string): SidebarSubagentAddress | undefined
394
+ /**
395
+ * Mark whether a catalog surface is consuming live membership updates.
396
+ */
397
+ setSubagentCatalogOpen?(parentSessionId: string, open: boolean): void
398
+ /**
399
+ * Refresh one direct-child catalog.
400
+ */
401
+ refreshSubagents?(parentSessionId: string): Promise<void>
402
+ }
403
+
404
+ /**
405
+ * The client locale service face (mirror of @deepseek-ai/dsh-client-locale's
406
+ * LocaleRuntime — only the slices the sidebar touches). The sidebar follows
407
+ * the DSH i18n system: the active locale is the Host-backed preference
408
+ * (`locale.preference` in settings.yaml) rather than the raw browser
409
+ * language, and the sidebar's zh/en dictionaries register into the service's
410
+ * namespace registry under `betterSidebar`.
411
+ */
412
+ export interface SidebarLocaleService {
413
+ /** Current immutable locale snapshot (uSES-safe; `active` is 'zh' | 'en' today). */
414
+ getSnapshot(): { active: string }
415
+ /** Subscribe to snapshot changes (locale switch or dictionary registration). */
416
+ subscribe(fn: () => void): () => void
417
+ /** Register one locale's dictionary for a namespace; returns the disposer. */
418
+ register(ns: string, locale: string, dict: Record<string, string>): () => void
419
+ }
420
+
421
+ /** The composer draft face the sidebar reaches through `ctx.conversation.input`. */
422
+ export interface SidebarSessionInput {
423
+ /** The live input store (draft read for append). */
424
+ state: {
425
+ getSnapshot(): { draft: string }
426
+ }
427
+ /** Replace the draft text (the input machine's single public write path). */
428
+ setDraft(text: string): void
429
+ }
430
+
431
+ /** The composer draft face the sidebar reaches through `ctx.get('conversation')`. */
432
+ export interface SidebarConversation {
433
+ input: {
434
+ for(actx: Context): SidebarSessionInput
435
+ }
436
+ }
437
+
438
+ /**
439
+ * The client workspaces service face (mirror of the runtime IWorkspaces). Only
440
+ * the chat's file-open funnel is touched: `openPath` hands an absolute path
441
+ * to the Host OS's default application, and every chat-side file open
442
+ * (tool rows, produced-files, prose mentions) funnels through it.
443
+ */
444
+ export interface SidebarWorkspacesService {
445
+ /** Open a filesystem path with the Host operating system's default application. */
446
+ openPath(path: string): Promise<void>
447
+ }
448
+
449
+ /**
450
+ * The invariant service face (mirror of @deepseek-ai/dsh-invariants'
451
+ * InvariantRegistry). The upstream augmentation does not reach this Context
452
+ * (dual-cordis-instance resolution), so the register signature is restated
453
+ * structurally, exactly like the other service faces above.
454
+ */
455
+ export interface SidebarInvariantsService {
456
+ /** Reserve one package's checks and install them in the service's child fiber. */
457
+ register(
458
+ packageName: string,
459
+ installer: (ctx: Context, fail: (message: string) => never) => void | Promise<void>,
460
+ ): () => void
461
+ }
462
+
463
+ /** The settings service face (mirror of @deepseek-ai/dsh-settings' SettingsProvider). */
464
+ export interface SidebarSettingsService {
465
+ /**
466
+ * Register one namespace schema (the resolved value layers schema defaults,
467
+ * then the composition base, then the user document).
468
+ */
469
+ register<T>(
470
+ ns: string,
471
+ schema: unknown,
472
+ options?: { base?: Partial<T>; applies?: 'live' | 'restart' },
473
+ ): {
474
+ get(): T
475
+ watch(callback: (next: T, prev: T) => void | Promise<void>): () => void
476
+ update(patch: object): Promise<void>
477
+ replace(section: object): Promise<void>
478
+ }
479
+ /** Redacted descriptors of every registered namespace (secrets stripped). */
480
+ describe(options?: { redactSecrets?: boolean }): Array<{
481
+ ns: string
482
+ value?: unknown
483
+ base?: unknown
484
+ user?: unknown
485
+ applies: 'live' | 'restart'
486
+ revision: number
487
+ }>
488
+ /** Service-level merge write with the revision guard (a stale writer is refused). */
489
+ update(ns: string, patch: object, expectedRevision?: number): Promise<void>
490
+ }
491
+
492
+ /**
493
+ * The tools service face (mirror of @deepseek-ai/dsh-tools' ToolRuntime).
494
+ * The host half registers model-facing tools here; the registry attaches the
495
+ * returned disposer to the contributing fiber so unloading unregisters them.
496
+ */
497
+ export interface SidebarToolsService {
498
+ /** Register one tool definition (raw JSON-Schema or defineTool-sugar form). */
499
+ register(tool: unknown): () => void
500
+ }
501
+
502
+ /**
503
+ * The agent face a tool sees on `exec.agent` (mirror of @deepseek-ai/dsh-agent's
504
+ * Agent). Only the slices the terminal tools touch are restated: the live
505
+ * session identity and its header cwd, both readonly.
506
+ */
507
+ export interface SidebarAgent {
508
+ /** The live session identity shared with the session log. */
509
+ readonly id: string
510
+ /** The live session this agent drives. */
511
+ readonly session: {
512
+ /** The session's header (validated cwd, lineage metadata). */
513
+ readonly header: { readonly cwd?: string }
514
+ }
515
+ }
516
+
517
+ declare module 'cordis' {
518
+ interface Context {
519
+ webServer: SidebarWebServer
520
+ sessions: SidebarSessionStore & SidebarSessionsService
521
+ connection: SidebarConnectionHandle
522
+ webRuntime: SidebarWebRuntime
523
+ slots: SidebarSlotsService
524
+ workspaces: SidebarWorkspacesService
525
+ settings: SidebarSettingsService
526
+ invariants: SidebarInvariantsService
527
+ tools: SidebarToolsService
528
+ /**
529
+ * The client locale service (`@deepseek-ai/dsh-client-locale`): the
530
+ * sidebar's copy follows its active locale and registers its
531
+ * dictionaries under the `betterSidebar` namespace. Client side only.
532
+ */
533
+ locale: SidebarLocaleService
534
+ /**
535
+ * The client module system (rc.8+): resolves module-table specifiers
536
+ * (seed words, graph rows) — the chunk loader's externals go through it
537
+ * (`ctx.modules.import`). rc.7 exposed the same surface as the
538
+ * `window.__DSH_MODULES__` page global; the loader keeps that fallback.
539
+ */
540
+ modules: { import(specifier: string): Promise<unknown> }
541
+ /**
542
+ * The host background-job registry (`ctx.get('jobs')`; optional — the
543
+ * sidebar routes degrade to a 503 when the deployment lacks it).
544
+ */
545
+ jobs: SidebarJobsService
546
+ /**
547
+ * The host live-agent registry (`ctx.get('agents')`; optional — used to
548
+ * resolve the caller the jobs fence compares against, and to create /
549
+ * resume the Side Chat thread agents).
550
+ */
551
+ agents: SidebarAgentsService
552
+ /**
553
+ * The host subagent runtime (`ctx.subagents`; optional — the Subagent
554
+ * page's live batch route reads descendant catalogs through it).
555
+ */
556
+ subagents: SidebarSubagentsService
557
+ /**
558
+ * The host agent-presets service (`ctx.get('agentPresets')`; optional —
559
+ * absent deployments compose nothing and every session shares the host
560
+ * composition).
561
+ */
562
+ agentPresets: SidebarAgentPresetsService
563
+ /**
564
+ * The host session-title service (`ctx.get('sessionTitle')`; optional —
565
+ * the Side Chat thread label pin degrades to the auto-generated title).
566
+ */
567
+ sessionTitle: SidebarSessionTitleService
568
+ /**
569
+ * The host session-persistence service (`ctx.get('sessionPersistence')`;
570
+ * optional — needed only for the Side Chat cold-resume composition).
571
+ */
572
+ sessionPersistence: SidebarSessionPersistenceService
573
+ /**
574
+ * The client-side sidebar registry: external plugins register tab types
575
+ * and file previewers here. Provided by the client half (see
576
+ * {@link ./client/index.tsx}); undefined on the host side.
577
+ */
578
+ betterSidebar: BetterSidebarService
579
+ /**
580
+ * Subscribe to the session append feed (mirror of the cordis event API):
581
+ * the listener receives every appended session event with the LIVE
582
+ * Session instance that appended it. The api-proxy pushes the same feed
583
+ * to browsers; the sidebar uses it to mirror job_output events the
584
+ * session store's own log can lag behind (restart divergence). Returns
585
+ * the disposer.
586
+ */
587
+ on(event: string, listener: (session: unknown, event: SidebarSessionEvent) => void): () => void
588
+ /**
589
+ * Register a lifecycle callback (DSH-vendored cordis): runs at plugin
590
+ * activation; its returned cleanup runs at disposal.
591
+ */
592
+ effect(fn: () => void | (() => void), label?: string): void
593
+ }
594
+ }
595
+
596
+ /**
597
+ * Dual cordis-scope augmentation: DSH's runtime (and the public packages)
598
+ * resolve against the vendored `@deepseek-ai/cordis` scope, which DSH's own
599
+ * packages already augment with `effect`/`on`/service members. This side only
600
+ * adds the sidebar service member so consumers importing `Context` from
601
+ * `@deepseek-ai/cordis` (instead of the public `cordis` above) still see
602
+ * `ctx.betterSidebar`.
603
+ */
604
+ declare module '@deepseek-ai/cordis' {
605
+ interface Context {
606
+ betterSidebar: BetterSidebarService
607
+ }
608
+ }
609
+
610
+ export type { Context }