dsh-coding-sidebar 1.0.0

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 (277) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +524 -0
  3. package/cordis.patch.yml +49 -0
  4. package/lib/client-editor.js +48229 -0
  5. package/lib/client-mermaid.js +200745 -0
  6. package/lib/client-registry.js +21867 -0
  7. package/lib/client-terminal.js +9361 -0
  8. package/lib/client.js +21867 -0
  9. package/lib/index.js +4556 -0
  10. package/lib/invariant.js +22 -0
  11. package/lib/types/agent-opens.d.ts +65 -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 +39 -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 +13 -0
  19. package/lib/types/client/FileTree.d.ts +38 -0
  20. package/lib/types/client/FreeWindow.d.ts +29 -0
  21. package/lib/types/client/GitView.d.ts +10 -0
  22. package/lib/types/client/MarkdownHtml.d.ts +32 -0
  23. package/lib/types/client/OrphanedTab.d.ts +11 -0
  24. package/lib/types/client/PdfView.d.ts +6 -0
  25. package/lib/types/client/RenderBoundary.d.ts +32 -0
  26. package/lib/types/client/SandboxStatusBar.d.ts +10 -0
  27. package/lib/types/client/SideCardSection.d.ts +74 -0
  28. package/lib/types/client/SideChatView.d.ts +16 -0
  29. package/lib/types/client/Sidebar.d.ts +6 -0
  30. package/lib/types/client/SubagentView.d.ts +16 -0
  31. package/lib/types/client/TabBar.d.ts +54 -0
  32. package/lib/types/client/TerminalView.d.ts +24 -0
  33. package/lib/types/client/TextEditor.d.ts +10 -0
  34. package/lib/types/client/TreePanel.d.ts +24 -0
  35. package/lib/types/client/UploadOverlay.d.ts +20 -0
  36. package/lib/types/client/add-plugin-modal.d.ts +15 -0
  37. package/lib/types/client/api.d.ts +275 -0
  38. package/lib/types/client/binary-download.d.ts +12 -0
  39. package/lib/types/client/breakpoints.d.ts +17 -0
  40. package/lib/types/client/browser.d.ts +60 -0
  41. package/lib/types/client/builtins/index.d.ts +18 -0
  42. package/lib/types/client/builtins/tabs.d.ts +11 -0
  43. package/lib/types/client/builtins/viewers.d.ts +3 -0
  44. package/lib/types/client/chunk-loader.d.ts +131 -0
  45. package/lib/types/client/chunks/editor.d.ts +9 -0
  46. package/lib/types/client/chunks/mermaid.d.ts +10 -0
  47. package/lib/types/client/chunks/terminal.d.ts +9 -0
  48. package/lib/types/client/cm-themes.d.ts +24 -0
  49. package/lib/types/client/conversation-draft.d.ts +14 -0
  50. package/lib/types/client/desktop-env.d.ts +35 -0
  51. package/lib/types/client/editor-load.d.ts +66 -0
  52. package/lib/types/client/frame-batcher.d.ts +24 -0
  53. package/lib/types/client/icons.d.ts +59 -0
  54. package/lib/types/client/image-types.d.ts +3 -0
  55. package/lib/types/client/ime-guard.d.ts +36 -0
  56. package/lib/types/client/index.d.ts +25 -0
  57. package/lib/types/client/intercept.d.ts +46 -0
  58. package/lib/types/client/lang.d.ts +14 -0
  59. package/lib/types/client/layout-push.d.ts +15 -0
  60. package/lib/types/client/lazy-chunk.d.ts +25 -0
  61. package/lib/types/client/link-intercept.d.ts +42 -0
  62. package/lib/types/client/locales-ar.d.ts +18 -0
  63. package/lib/types/client/locales-de.d.ts +4 -0
  64. package/lib/types/client/locales-fr.d.ts +10 -0
  65. package/lib/types/client/locales-hi.d.ts +17 -0
  66. package/lib/types/client/locales-id.d.ts +15 -0
  67. package/lib/types/client/locales-it.d.ts +8 -0
  68. package/lib/types/client/locales-ja.d.ts +17 -0
  69. package/lib/types/client/locales-ko.d.ts +9 -0
  70. package/lib/types/client/locales-nl.d.ts +16 -0
  71. package/lib/types/client/locales-pl.d.ts +19 -0
  72. package/lib/types/client/locales-pt.d.ts +1 -0
  73. package/lib/types/client/locales-ru.d.ts +13 -0
  74. package/lib/types/client/locales-sv.d.ts +1 -0
  75. package/lib/types/client/locales-th.d.ts +17 -0
  76. package/lib/types/client/locales-tr.d.ts +17 -0
  77. package/lib/types/client/locales-vi.d.ts +17 -0
  78. package/lib/types/client/locales-zh-HK.d.ts +32 -0
  79. package/lib/types/client/locales-zh-MO.d.ts +32 -0
  80. package/lib/types/client/locales-zh-TW.d.ts +32 -0
  81. package/lib/types/client/locales.d.ts +452 -0
  82. package/lib/types/client/markdown-html.d.ts +96 -0
  83. package/lib/types/client/markdown-images.d.ts +45 -0
  84. package/lib/types/client/markdown-labels.d.ts +38 -0
  85. package/lib/types/client/md-toc.d.ts +4 -0
  86. package/lib/types/client/mermaid-blocks.d.ts +47 -0
  87. package/lib/types/client/mermaid-sanitize.d.ts +2 -0
  88. package/lib/types/client/mermaid.d.ts +12 -0
  89. package/lib/types/client/open-when-sized.d.ts +20 -0
  90. package/lib/types/client/open-with-settings.d.ts +4 -0
  91. package/lib/types/client/open-with.d.ts +87 -0
  92. package/lib/types/client/openpath-intercept.d.ts +85 -0
  93. package/lib/types/client/paths.d.ts +43 -0
  94. package/lib/types/client/pdf-types.d.ts +2 -0
  95. package/lib/types/client/pinned.d.ts +86 -0
  96. package/lib/types/client/plugin-settings.d.ts +8 -0
  97. package/lib/types/client/plugins-shared.d.ts +27 -0
  98. package/lib/types/client/plugins-tabs.d.ts +3 -0
  99. package/lib/types/client/plugins-viewers.d.ts +3 -0
  100. package/lib/types/client/prefs.d.ts +41 -0
  101. package/lib/types/client/produced-files.d.ts +29 -0
  102. package/lib/types/client/selection-payload.d.ts +27 -0
  103. package/lib/types/client/service.d.ts +439 -0
  104. package/lib/types/client/settings-nav-icon.d.ts +19 -0
  105. package/lib/types/client/shell-presets.d.ts +48 -0
  106. package/lib/types/client/sidechat-transcript.d.ts +103 -0
  107. package/lib/types/client/split-pane.d.ts +36 -0
  108. package/lib/types/client/state.d.ts +432 -0
  109. package/lib/types/client/subagent-detect.d.ts +54 -0
  110. package/lib/types/client/subagent-jobs.d.ts +63 -0
  111. package/lib/types/client/tab-content-memo.d.ts +40 -0
  112. package/lib/types/client/terminal-font.d.ts +78 -0
  113. package/lib/types/client/terminal-links.d.ts +119 -0
  114. package/lib/types/client/theme.d.ts +45 -0
  115. package/lib/types/client/titlebar-strip.d.ts +23 -0
  116. package/lib/types/client/upload.d.ts +69 -0
  117. package/lib/types/client/wco.d.ts +47 -0
  118. package/lib/types/config.d.ts +64 -0
  119. package/lib/types/context-types.d.ts +605 -0
  120. package/lib/types/fs-operations.d.ts +28 -0
  121. package/lib/types/fs-search.d.ts +24 -0
  122. package/lib/types/fs-tree.d.ts +51 -0
  123. package/lib/types/git.d.ts +124 -0
  124. package/lib/types/html-route.d.ts +59 -0
  125. package/lib/types/index.d.ts +47 -0
  126. package/lib/types/invariant.d.ts +15 -0
  127. package/lib/types/jobs-routes.d.ts +45 -0
  128. package/lib/types/open-external.d.ts +24 -0
  129. package/lib/types/path-security.d.ts +20 -0
  130. package/lib/types/prefs-shared.d.ts +236 -0
  131. package/lib/types/pty-deps.d.ts +78 -0
  132. package/lib/types/pty-manager.d.ts +168 -0
  133. package/lib/types/sidechat-core.d.ts +172 -0
  134. package/lib/types/sidechat-routes.d.ts +30 -0
  135. package/lib/types/subagent-activity.d.ts +44 -0
  136. package/lib/types/subagent-live-route.d.ts +44 -0
  137. package/lib/types/tools.d.ts +34 -0
  138. package/lib/types/trust-fence.d.ts +24 -0
  139. package/lib/types/wire.d.ts +38 -0
  140. package/package.json +172 -0
  141. package/scripts/install.ps1 +306 -0
  142. package/scripts/install.sh +287 -0
  143. package/src/agent-opens.ts +265 -0
  144. package/src/agent-pty.ts +527 -0
  145. package/src/browser-probe.ts +26 -0
  146. package/src/bundle-route.ts +129 -0
  147. package/src/client/BrowserView.tsx +289 -0
  148. package/src/client/DiffTab.tsx +114 -0
  149. package/src/client/DiffView.tsx +305 -0
  150. package/src/client/EditorHost.tsx +558 -0
  151. package/src/client/FileTree.tsx +669 -0
  152. package/src/client/FreeWindow.tsx +337 -0
  153. package/src/client/GitView.tsx +717 -0
  154. package/src/client/MarkdownHtml.tsx +296 -0
  155. package/src/client/OrphanedTab.tsx +27 -0
  156. package/src/client/PdfView.tsx +110 -0
  157. package/src/client/RenderBoundary.tsx +49 -0
  158. package/src/client/SandboxStatusBar.tsx +60 -0
  159. package/src/client/SideCardSection.module.css +960 -0
  160. package/src/client/SideCardSection.tsx +1163 -0
  161. package/src/client/SideChatView.module.css +437 -0
  162. package/src/client/SideChatView.tsx +645 -0
  163. package/src/client/Sidebar.tsx +1370 -0
  164. package/src/client/SubagentView.module.css +547 -0
  165. package/src/client/SubagentView.tsx +883 -0
  166. package/src/client/TabBar.tsx +365 -0
  167. package/src/client/TerminalView.tsx +424 -0
  168. package/src/client/TextEditor.tsx +468 -0
  169. package/src/client/TreePanel.tsx +275 -0
  170. package/src/client/UploadOverlay.tsx +62 -0
  171. package/src/client/add-plugin-modal.tsx +199 -0
  172. package/src/client/api.ts +357 -0
  173. package/src/client/binary-download.tsx +23 -0
  174. package/src/client/breakpoints.ts +61 -0
  175. package/src/client/browser.ts +167 -0
  176. package/src/client/builtins/index.ts +37 -0
  177. package/src/client/builtins/tabs.tsx +340 -0
  178. package/src/client/builtins/viewers.tsx +125 -0
  179. package/src/client/chunk-loader.ts +358 -0
  180. package/src/client/chunks/editor.tsx +9 -0
  181. package/src/client/chunks/mermaid.tsx +10 -0
  182. package/src/client/chunks/terminal.tsx +9 -0
  183. package/src/client/cm-themes.ts +129 -0
  184. package/src/client/conversation-draft.ts +29 -0
  185. package/src/client/css-modules.d.ts +5 -0
  186. package/src/client/desktop-env.ts +72 -0
  187. package/src/client/editor-load.ts +92 -0
  188. package/src/client/frame-batcher.ts +56 -0
  189. package/src/client/icons.tsx +152 -0
  190. package/src/client/image-types.ts +8 -0
  191. package/src/client/ime-guard.ts +47 -0
  192. package/src/client/index.tsx +427 -0
  193. package/src/client/intercept.tsx +188 -0
  194. package/src/client/lang.ts +225 -0
  195. package/src/client/layout-push.ts +24 -0
  196. package/src/client/layout.css +90 -0
  197. package/src/client/lazy-chunk.tsx +89 -0
  198. package/src/client/link-intercept.ts +73 -0
  199. package/src/client/locales-ar.ts +368 -0
  200. package/src/client/locales-de.ts +353 -0
  201. package/src/client/locales-fr.ts +360 -0
  202. package/src/client/locales-hi.ts +367 -0
  203. package/src/client/locales-id.ts +365 -0
  204. package/src/client/locales-it.ts +358 -0
  205. package/src/client/locales-ja.ts +367 -0
  206. package/src/client/locales-ko.ts +359 -0
  207. package/src/client/locales-nl.ts +365 -0
  208. package/src/client/locales-pl.ts +369 -0
  209. package/src/client/locales-pt.ts +350 -0
  210. package/src/client/locales-ru.ts +365 -0
  211. package/src/client/locales-sv.ts +350 -0
  212. package/src/client/locales-th.ts +367 -0
  213. package/src/client/locales-tr.ts +367 -0
  214. package/src/client/locales-vi.ts +367 -0
  215. package/src/client/locales-zh-HK.ts +382 -0
  216. package/src/client/locales-zh-MO.ts +382 -0
  217. package/src/client/locales-zh-TW.ts +382 -0
  218. package/src/client/locales.ts +894 -0
  219. package/src/client/markdown-html.ts +331 -0
  220. package/src/client/markdown-images.ts +137 -0
  221. package/src/client/markdown-labels.tsx +52 -0
  222. package/src/client/md-toc.tsx +127 -0
  223. package/src/client/mermaid-blocks.ts +110 -0
  224. package/src/client/mermaid-sanitize.ts +93 -0
  225. package/src/client/mermaid.tsx +406 -0
  226. package/src/client/open-when-sized.ts +43 -0
  227. package/src/client/open-with-settings.tsx +135 -0
  228. package/src/client/open-with.ts +221 -0
  229. package/src/client/openpath-intercept.ts +143 -0
  230. package/src/client/paths.ts +63 -0
  231. package/src/client/pdf-types.ts +4 -0
  232. package/src/client/pinned.ts +183 -0
  233. package/src/client/plugin-settings.ts +43 -0
  234. package/src/client/plugins-shared.ts +29 -0
  235. package/src/client/plugins-tabs.ts +96 -0
  236. package/src/client/plugins-viewers.ts +30 -0
  237. package/src/client/prefs.ts +210 -0
  238. package/src/client/produced-files.ts +120 -0
  239. package/src/client/selection-payload.ts +86 -0
  240. package/src/client/service.ts +859 -0
  241. package/src/client/settings-nav-icon.ts +45 -0
  242. package/src/client/shell-presets.ts +83 -0
  243. package/src/client/sidebar.module.css +2788 -0
  244. package/src/client/sidechat-transcript.ts +321 -0
  245. package/src/client/split-pane.tsx +331 -0
  246. package/src/client/state.ts +1497 -0
  247. package/src/client/subagent-detect.ts +137 -0
  248. package/src/client/subagent-jobs.ts +161 -0
  249. package/src/client/tab-content-memo.ts +55 -0
  250. package/src/client/terminal-font.ts +224 -0
  251. package/src/client/terminal-links.ts +194 -0
  252. package/src/client/theme.ts +110 -0
  253. package/src/client/titlebar-strip.ts +37 -0
  254. package/src/client/upload.ts +187 -0
  255. package/src/client/wco.ts +120 -0
  256. package/src/config.ts +154 -0
  257. package/src/context-types.ts +611 -0
  258. package/src/fs-operations.ts +95 -0
  259. package/src/fs-search.ts +113 -0
  260. package/src/fs-tree.ts +158 -0
  261. package/src/git.ts +446 -0
  262. package/src/html-route.ts +106 -0
  263. package/src/index.ts +1291 -0
  264. package/src/invariant.ts +32 -0
  265. package/src/jobs-routes.ts +257 -0
  266. package/src/open-external.ts +90 -0
  267. package/src/path-security.ts +75 -0
  268. package/src/prefs-shared.ts +280 -0
  269. package/src/pty-deps.ts +240 -0
  270. package/src/pty-manager.ts +376 -0
  271. package/src/sidechat-core.ts +468 -0
  272. package/src/sidechat-routes.ts +344 -0
  273. package/src/subagent-activity.ts +91 -0
  274. package/src/subagent-live-route.ts +93 -0
  275. package/src/tools.ts +482 -0
  276. package/src/trust-fence.ts +84 -0
  277. package/src/wire.ts +100 -0
@@ -0,0 +1,22 @@
1
+ //#region src/invariant.ts
2
+ const PACKAGE_NAME = "dsh-coding-sidebar";
3
+ /** Cordis companion plugin name. */
4
+ const name = "dsh-coding-sidebar-invariant";
5
+ /** Service required before the companion can reserve package ownership. */
6
+ const inject = ["invariants"];
7
+ /**
8
+ * No runtime invariant: the sidebar owns no service state or event protocol
9
+ * of its own — every route is mounted under the host's webServer fence, the
10
+ * pty lifecycle is exercised by the smoke spec, and the panel's store is a
11
+ * plain snapshot registry asserted by the behavior specs. The route fence,
12
+ * pty quota, and store semantics are each observed through their seams.
13
+ */
14
+ const install = () => {};
15
+ /**
16
+ * Register this package's invariant companion.
17
+ * @param ctx - Cordis context carrying the invariant service.
18
+ * @returns the installed registration's disposer after setup succeeds.
19
+ */
20
+ const apply = (ctx) => Promise.resolve(ctx.invariants.register(PACKAGE_NAME, install));
21
+ //#endregion
22
+ export { apply, inject, name };
@@ -0,0 +1,65 @@
1
+ import type { Context } from './context-types.ts';
2
+ import type { SidebarPrefs } from './prefs-shared.ts';
3
+ /** What the model asked to open. */
4
+ export type AgentOpenKind = 'file' | 'folder' | 'url';
5
+ /** One pending/broadcast open request (the wire face over the push socket). */
6
+ export interface AgentOpenRequest {
7
+ /** Opaque id (host-generated; the client ignores it beyond dedupe/debug). */
8
+ id: string;
9
+ /** The session whose sidebar the open is targeted at. */
10
+ sessionId: string;
11
+ kind: AgentOpenKind;
12
+ /** Absolute local path (file/folder) or http(s) URL. */
13
+ target: string;
14
+ /** Tab title the client should use (basename / hostname / caller-supplied). */
15
+ title: string;
16
+ }
17
+ /** One subscribed sidebar view's sender. */
18
+ type Sender = (request: AgentOpenRequest) => void;
19
+ /**
20
+ * Per-session queue of open requests plus the connected sidebar views.
21
+ *
22
+ * Lifecycle: `enqueue` adds a request and — when at least one view for the
23
+ * session is attached — pushes it immediately and removes it from the queue
24
+ * (consume-on-send: a reconnect must never replay an open the client already
25
+ * applied, and the browser tab type has no per-URL dedupe, so replaying
26
+ * would mint duplicate tabs). With no attached view the request stays queued
27
+ * and `attach` replays it on connect. `drainAll` drops every queued request
28
+ * (the feature was turned off); `dispose` also drops every subscriber.
29
+ */
30
+ export declare class AgentOpenRegistry {
31
+ private pending;
32
+ private subscribers;
33
+ /** Queue one open and deliver it immediately when a view is attached.
34
+ * @returns the request id and whether a connected view received it now. */
35
+ enqueue(sessionId: string, kind: AgentOpenKind, target: string, title: string): {
36
+ id: string;
37
+ delivered: boolean;
38
+ };
39
+ /** Attach one sidebar view (replays queued requests; consume-on-send).
40
+ * @returns the disposer detaching the view. */
41
+ attach(sessionId: string, send: Sender): () => void;
42
+ /** Drop every queued request (the feature was turned off mid-session). */
43
+ drainAll(): void;
44
+ /** Drop the queue and every subscriber (plugin teardown). */
45
+ dispose(): void;
46
+ }
47
+ /**
48
+ * Register the `sidebar_open` tool against the host tool registry. The tool
49
+ * is gated by the side-card setting `agentOpenTools` (the caller registers
50
+ * and unregisters it); `readPrefs` supplies the live prefs so a disabled
51
+ * target tab type (editor/browser) is reported to the model instead of
52
+ * silently no-oping on the client. `resolveCwd` threads the calling
53
+ * session's live cwd so relative paths resolve the same way the sidebar's
54
+ * own routes do.
55
+ * @param ctx - host plugin context (carries the tools service).
56
+ * @param registry - the open-request registry (per-session queue + views).
57
+ * @param resolveCwd - async cwd resolver for one session id. Resolves through
58
+ * the session header, the client-supplied cwd, and the persistence index
59
+ * before falling back to the host process cwd (production always provides
60
+ * persistence, so the fallback is reached only in tests / stripped-down hosts).
61
+ * @param readPrefs - live resolved side card prefs (for tab enable gates).
62
+ * @returns a disposer that unregisters the tool.
63
+ */
64
+ export declare function registerOpenTool(ctx: Context, registry: AgentOpenRegistry, resolveCwd: (sessionId: string) => Promise<string>, readPrefs: () => SidebarPrefs): () => void;
65
+ export {};
@@ -0,0 +1,226 @@
1
+ import type { IPty } from 'node-pty';
2
+ import { type NodePtyModule } from './pty-deps.ts';
3
+ /** POSIX signals the registry forwards to a live pty. */
4
+ export declare const ALLOWED_SIGNALS: readonly ["SIGINT", "SIGTERM", "SIGKILL", "SIGHUP", "SIGTSTP"];
5
+ /** Signal name accepted by `signal()`. */
6
+ export type AgentTerminalSignal = (typeof ALLOWED_SIGNALS)[number];
7
+ /** Default read page size (lines) when the caller omits `count`. */
8
+ export declare const DEFAULT_READ_COUNT = 500;
9
+ /** Smallest pty dimension the registry accepts (mirrors the tool contract). */
10
+ export declare const TERMINAL_DIM_MIN = 2;
11
+ /** Largest pty dimension the registry accepts (mirrors the tool contract). */
12
+ export declare const TERMINAL_DIM_MAX = 1024;
13
+ /** Clamp one cols×rows pair into the supported pty range (flooring decimals). */
14
+ export declare function clampDims(cols: number, rows: number): {
15
+ cols: number;
16
+ rows: number;
17
+ };
18
+ /**
19
+ * Serializable snapshot of one agent terminal — the shape the model sees
20
+ * through `terminal_list` and the sidebar sees through the push endpoint.
21
+ * Carries no pty reference and no transcript (those are reached through
22
+ * dedicated read/attach paths), and no sessionId: ownership is registry
23
+ * internals, scoped by the caller (list filters by session, the push
24
+ * endpoint scopes by its query param), never part of the serialized view.
25
+ */
26
+ export interface AgentTerminalSnapshot {
27
+ /** Stable opaque handle the model passes back to other terminal_* tools. */
28
+ uuid: string;
29
+ /** Display title the model chose at create time. */
30
+ title: string;
31
+ /** The command the model asked to run at create time (verbatim). */
32
+ command: string;
33
+ /** Whether the top-level process has exited. */
34
+ exited: boolean;
35
+ /** Exit code if exited normally; absent until the process exits. */
36
+ exitCode?: number | null;
37
+ /** Exit signal name if the process was killed by a signal; null otherwise. */
38
+ exitSignal?: string | null;
39
+ }
40
+ /** One live agent terminal. */
41
+ export interface AgentTerminalHandle {
42
+ /** Stable opaque handle. */
43
+ uuid: string;
44
+ /** Owning conversation id. */
45
+ sessionId: string;
46
+ /** Display title. */
47
+ title: string;
48
+ /** The command written to stdin right after spawn. */
49
+ command: string;
50
+ /** The working directory the process was spawned with. */
51
+ cwd: string;
52
+ /** The live pty process. */
53
+ pty: IPty;
54
+ /** Output accumulated since spawn (bounded; head dropped when over the limit). */
55
+ transcript: string;
56
+ /** Whether the top-level process exited (transcript stays replayable). */
57
+ exited: boolean;
58
+ /** Exit code once known. */
59
+ exitCode?: number | null;
60
+ /** Exit signal number once known (POSIX only; undefined on Windows). */
61
+ exitSignal?: number | null;
62
+ }
63
+ /** Read result shape (mirrors the official tool-pty terminal_read contract). */
64
+ export interface AgentTerminalReadResult {
65
+ /** The slice of transcript text for the requested page. */
66
+ text: string;
67
+ /** Total lines in the retained transcript (the page may be a subset). */
68
+ totalLines: number;
69
+ /** 0-based index of the first line in `text` (inclusive). */
70
+ lineBegin: number;
71
+ /** 0-based index of the last line in `text` (exclusive). */
72
+ lineEnd: number;
73
+ }
74
+ /** Outcome of {@link AgentPtyRegistry.waitFor}. */
75
+ export type AgentTerminalWaitResult = {
76
+ /** The needle was found in the transcript. */
77
+ kind: 'found';
78
+ /** The matched substring. */
79
+ needle: string;
80
+ /** 0-based line index (in the retained transcript) where the needle first appeared. */
81
+ line: number;
82
+ /** 0-based column index within that line where the match starts. */
83
+ column: number;
84
+ /** Elapsed wall-clock milliseconds from the wait start to the match. */
85
+ elapsedMs: number;
86
+ } | {
87
+ /** The needle did not appear before the timeout. */
88
+ kind: 'timeout';
89
+ /** The needle that was awaited. */
90
+ needle: string;
91
+ /** The configured timeout in milliseconds. */
92
+ timeoutMs: number;
93
+ /** Total lines retained when the timeout fired (call terminal_read to inspect). */
94
+ totalLines: number;
95
+ } | {
96
+ /** The terminal exited before the needle appeared. */
97
+ kind: 'exited';
98
+ /** The needle that was awaited. */
99
+ needle: string;
100
+ /** The exit code, if known. */
101
+ exitCode?: number | null;
102
+ /** The exit signal name, if the process was killed by a signal. */
103
+ exitSignal?: string | null;
104
+ };
105
+ /** Snapshot projection of a handle (drops the pty reference and transcript). */
106
+ export declare function snapshotOf(handle: AgentTerminalHandle): AgentTerminalSnapshot;
107
+ /**
108
+ * The agent terminal registry. The constructor takes the resolved shell
109
+ * binary (the same `defaultShell()` the UI-tab registry uses) and runs the
110
+ * spawn-helper chmod fix once at construction so the first agent terminal
111
+ * does not race a lazy fixer.
112
+ */
113
+ export declare class AgentPtyRegistry {
114
+ private readonly shell;
115
+ private readonly shellArgs;
116
+ /** The loaded node-pty module (injected so a broken install degrades instead of crashing the plugin). */
117
+ private readonly nodePty;
118
+ private readonly sessions;
119
+ private readonly changeListeners;
120
+ constructor(shell: string, shellArgs?: string[],
121
+ /** The loaded node-pty module (injected so a broken install degrades instead of crashing the plugin). */
122
+ nodePty?: NodePtyModule);
123
+ /**
124
+ * Spawn one agent terminal: start the shell in `cwd`, then write
125
+ * `command + '\n'` to stdin so the command runs in the fresh shell. The
126
+ * terminal stays alive after the command exits — the model can send more
127
+ * input through `terminal_send` until it calls `terminal_close` or the
128
+ * user closes the sidebar tab. An empty `command` spawns a bare shell.
129
+ * @returns the new handle's uuid (the model-facing opaque id).
130
+ */
131
+ create(sessionId: string, title: string, command: string, cwd: string, cols?: number, rows?: number, shell?: string, shellArgs?: string[]): string;
132
+ /** All live agent terminals belonging to one conversation. */
133
+ list(sessionId: string): AgentTerminalSnapshot[];
134
+ /** Resolve a live handle by uuid, or throw `not-found`. */
135
+ private expect;
136
+ /**
137
+ * Resolve a live handle that belongs to `sessionId`, or throw `not-found`.
138
+ * The model-facing tools call this before every uuid-keyed operation: a
139
+ * uuid from another session is indistinguishable from an unknown one, so a
140
+ * model can never reach (or probe) a terminal it does not own.
141
+ */
142
+ assertOwned(uuid: string, sessionId: string): AgentTerminalHandle;
143
+ /** Resolve a handle's snapshot, or undefined if it does not exist. */
144
+ snapshot(uuid: string): AgentTerminalSnapshot | undefined;
145
+ /** Write raw text to a terminal's stdin (tmux `send-keys` semantics). */
146
+ send(uuid: string, text: string): void;
147
+ /**
148
+ * Read one bounded page of the retained transcript. `offset` is a 0-based
149
+ * line index from the start of the retained transcript (default 0);
150
+ * `count` caps the page size (default 500). A negative `offset` reads
151
+ * from the end (e.g. -50 reads the last 50 lines). Returns `totalLines`
152
+ * so the model can paginate.
153
+ */
154
+ read(uuid: string, offset?: number, count?: number): AgentTerminalReadResult;
155
+ /**
156
+ * Resize a terminal's pty, clamped to the 2..1024 sane range.
157
+ * @returns the dimensions actually applied (the caller echoes these, so the
158
+ * reported value always matches the pty).
159
+ */
160
+ resize(uuid: string, cols: number, rows: number): {
161
+ cols: number;
162
+ rows: number;
163
+ };
164
+ /**
165
+ * Wait for `needle` to appear in a terminal's transcript, or for the
166
+ * terminal to exit, or for the timeout to elapse — whichever happens
167
+ * first. The wait polls the live transcript every ~50ms and short-circuits
168
+ * on `signal` abort (re-thrown as the abort reason so the tool layer
169
+ * surfaces cancellation).
170
+ *
171
+ * The match scans the FULL retained transcript on each poll, not just the
172
+ * delta since the last poll — a needle that scrolled past the most recent
173
+ * chunk but is still within the ~1 MiB bound is still a match. The
174
+ * returned line/column locate the FIRST occurrence (oldest), which is what
175
+ * a user watching the terminal would have seen first.
176
+ *
177
+ * The implementation uses polling (not pty onData subscription) because
178
+ * node-pty's onData fires before the registry's own onData listener
179
+ * updates the transcript (listener order is not guaranteed), and on
180
+ * Windows ConPTY output can arrive in bursts with batching delays that
181
+ * make event-driven wakeups unreliable. A 50ms poll is fast enough for
182
+ * interactive use and simple enough to be obviously correct.
183
+ * @param uuid - terminal to watch.
184
+ * @param needle - substring to search for (case-sensitive, verbatim).
185
+ * @param timeoutMs - max wait; default 10000 (10s). Clamped to ≥100ms.
186
+ * @param signal - caller-owned cancellation; aborts the wait re-throwing.
187
+ * @returns one of `found` / `timeout` / `exited`.
188
+ */
189
+ waitFor(uuid: string, needle: string, timeoutMs?: number, signal?: AbortSignal): Promise<AgentTerminalWaitResult>;
190
+ /**
191
+ * Send a POSIX signal to a terminal's foreground process.
192
+ *
193
+ * Two delivery paths, by signal kind:
194
+ * - **Interactive control signals** (SIGINT, SIGTSTP) are delivered by
195
+ * writing the corresponding control character to the pty stdin. This is
196
+ * how a real terminal sends Ctrl+C / Ctrl+Z: the byte hits the kernel
197
+ * line discipline (POSIX ISIG mode) or the ConPTY input pipeline
198
+ * (Windows), which translates it into a SIGINT/SIGTSTP for the
199
+ * foreground process group. This works on every platform — calling
200
+ * `node-pty.kill('SIGINT')` throws on Windows and is fragile on POSIX,
201
+ * but writing `\x03` is universally correct.
202
+ * - **Termination signals** (SIGKILL, SIGTERM, SIGHUP) use `pty.kill()`,
203
+ * which maps to the platform's process-termination path (POSIX
204
+ * `kill(2)`, Windows `TerminateProcess`). These cannot be faked with
205
+ * control characters.
206
+ */
207
+ signal(uuid: string, signal: AgentTerminalSignal): void;
208
+ /**
209
+ * Close a terminal and drop its state. Idempotent: a second close of the
210
+ * same uuid is a no-op. Returns true iff a live handle was actually
211
+ * dropped.
212
+ */
213
+ close(uuid: string): boolean;
214
+ /** Resolve a live handle by uuid (for the WS attach path). */
215
+ get(uuid: string): AgentTerminalHandle | undefined;
216
+ /**
217
+ * Subscribe to registry changes (create / close / exit). The sidebar push
218
+ * endpoint uses this to forward snapshots to the connected view. Returns
219
+ * the unsubscribe function.
220
+ */
221
+ subscribe(listener: () => void): () => void;
222
+ /** Close every agent terminal (plugin teardown). */
223
+ disposeAll(): void;
224
+ /** Fire every change listener (callers wrap in try/catch if needed). */
225
+ private notify;
226
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Pure helpers for the `browser.probe` route (sidebar browser): the host
3
+ * fetches the response HEADERS of a URL the user is browsing and the client
4
+ * decides whether the target site forbids being embedded (X-Frame-Options /
5
+ * CSP frame-ancestors are exactly the signals the browser enforces when it
6
+ * refuses an iframe load). Kept dependency-free so the parser is
7
+ * unit-testable.
8
+ */
9
+ /**
10
+ * Extract the `frame-ancestors` source list of a Content-Security-Policy
11
+ * header, or undefined when the directive is absent (or empty). The
12
+ * directive is the only one with a source list; sources are space-separated
13
+ * tokens (`'none'`, `'self'`, `*`, or origins).
14
+ */
15
+ export declare function extractFrameAncestors(csp: string | null): string[] | undefined;
@@ -0,0 +1,12 @@
1
+ import type { Context, SidebarHttpRequest, SidebarHttpResponse } from './context-types.ts';
2
+ /** The chunk names the client may request (mirror of src/client/chunk-loader.ts). */
3
+ export declare const CHUNK_NAMES: readonly ["terminal", "editor", "mermaid"];
4
+ export type ChunkName = (typeof CHUNK_NAMES)[number];
5
+ /**
6
+ * Build the /sidebar/bundle route handler. `fence` is the shared browser-
7
+ * trust check every /sidebar route applies; `chunkDir` is the directory the
8
+ * chunk scripts live in (overridable for tests).
9
+ */
10
+ export declare function createBundleRouteHandler(fence: (req: SidebarHttpRequest) => boolean, chunkDir?: string): (req: SidebarHttpRequest, res: SidebarHttpResponse) => Promise<void>;
11
+ /** Register the /sidebar/bundle route (disposed with the fiber). */
12
+ export declare function registerBundleRoute(ctx: Context, fence: (req: SidebarHttpRequest) => boolean): () => void;
@@ -0,0 +1,39 @@
1
+ import type { TabComponentProps } from './service.ts';
2
+ /**
3
+ * The browser iframe sandbox tokens. NO allow-same-origin (opaque origin —
4
+ * no GUI storage/API access), NO allow-top-navigation (a browsed page must
5
+ * not hijack the GUI). allow-forms/allow-popups/allow-downloads/allow-modals
6
+ * keep login flows working; allow-popups-to-escape-sandbox lets OAuth
7
+ * popups open as normal tabs (they are cross-origin to the GUI either way).
8
+ */
9
+ export declare const BROWSER_IFRAME_SANDBOX = "allow-scripts allow-forms allow-popups allow-downloads allow-modals allow-popups-to-escape-sandbox";
10
+ /**
11
+ * The sandbox tokens for one URL: allowlisted loopback addresses (local dev
12
+ * servers the user explicitly trusts) additionally get `allow-same-origin`
13
+ * so Vite/module/HMR pipelines that need a real origin work; every other
14
+ * site keeps the opaque-origin sandbox. `allow-same-origin` does NOT give
15
+ * the page access to the GUI — it stays cross-origin to it and to every
16
+ * other site — but it does give it its OWN origin privileges (localStorage,
17
+ * fetch without CORS), so it is only granted for the explicit allowlist.
18
+ *
19
+ * The GUI itself is the one hard exception: even when its own host is
20
+ * allowlisted (a bare-host entry covers every port, so the GUI origin
21
+ * matches), a page at the GUI's exact origin must never get
22
+ * `allow-same-origin` — that would make it same-origin with its parent and
23
+ * hand it the GUI's storage/API (and the ability to shed the sandbox). The
24
+ * GUI keeps the opaque-origin sandbox no matter what the allowlist says.
25
+ */
26
+ export declare function iframeSandboxFor(url: string | undefined, allowedLoopback: string, selfOrigin?: string): string | undefined;
27
+ export declare function BrowserView(props: TabComponentProps): import("react").JSX.Element;
28
+ /**
29
+ * The embed-refusal panel: shown when the probed site forbids being
30
+ * displayed inside other pages (X-Frame-Options / frame-ancestors) — the
31
+ * iframe would only show the browser's "refused to connect" blank. Explains
32
+ * the reason and offers the real-browser open plus a load-anyway escape.
33
+ * Exported so the copy and the actions are testable without a DOM.
34
+ */
35
+ export declare function BrowserEmbedBlocked(props: {
36
+ url: string;
37
+ onOpenInBrowser: () => void;
38
+ onLoadAnyway: () => void;
39
+ }): import("react").JSX.Element;
@@ -0,0 +1,6 @@
1
+ import type { SidebarDiffRef } from './state.ts';
2
+ export declare function DiffTab(props: {
3
+ sessionId: string;
4
+ cwd: string | undefined;
5
+ diff: SidebarDiffRef;
6
+ }): import("react").JSX.Element;
@@ -0,0 +1,51 @@
1
+ /** One rendered diff line. */
2
+ export interface DiffLine {
3
+ kind: 'ctx' | 'del' | 'add' | 'meta';
4
+ /** The line content without its diff marker ('' for the no-newline marker). */
5
+ text: string;
6
+ /** Old-side line number (null for pure additions / metadata). */
7
+ oldNum: number | null;
8
+ /** New-side line number (null for pure deletions / metadata). */
9
+ newNum: number | null;
10
+ }
11
+ /** One parsed hunk. */
12
+ export interface DiffHunk {
13
+ /** The old-side start line (`-a[,b]`). */
14
+ oldStart: number;
15
+ /** The new-side start line (`+c[,d]`). */
16
+ newStart: number;
17
+ /** The section text after the trailing `@@` (may be empty). */
18
+ header: string;
19
+ lines: DiffLine[];
20
+ }
21
+ /** One parsed file section of a unified diff. */
22
+ export interface DiffFile {
23
+ /** The `---` path verbatim ('/dev/null' for a new file). */
24
+ oldPath: string;
25
+ /** The `+++` path verbatim ('/dev/null' for a deleted file). */
26
+ newPath: string;
27
+ /** The file changed with binary content: no hunks to draw. */
28
+ binary: boolean;
29
+ hunks: DiffHunk[];
30
+ }
31
+ /** The parsed unified diff. */
32
+ export interface ParsedDiff {
33
+ files: DiffFile[];
34
+ }
35
+ /**
36
+ * Parse `git diff --no-color` output into file sections and hunks. Rows
37
+ * outside a file section (leading noise) and metadata rows between the
38
+ * `diff --git`/`---`/`+++` headers and the first hunk (index lines, mode
39
+ * changes, rename/similarity lines) are skipped; a section that never
40
+ * reaches a hunk (a mode/rename-only change) stays hunkless so the caller
41
+ * can still draw its path.
42
+ */
43
+ export declare function parseUnifiedDiff(text: string): ParsedDiff;
44
+ export interface DiffViewProps {
45
+ /** Unified diff text (`git.diff` or `git.commit-diff` payloads). */
46
+ diff: string;
47
+ /** Untracked-file content: when present, renders as a full-file addition instead of parsing. */
48
+ untrackedPath?: string;
49
+ untrackedContent?: string;
50
+ }
51
+ export declare function DiffView({ diff, untrackedPath, untrackedContent }: DiffViewProps): import("react").JSX.Element | null;
@@ -0,0 +1,13 @@
1
+ import type { Context } from '../context-types.ts';
2
+ import { type SessionScope } from './api.ts';
3
+ import { type SidebarStore, type SidebarTab } from './state.ts';
4
+ export declare function EditorHost(props: {
5
+ ctx: Context;
6
+ store: SidebarStore;
7
+ scope: SessionScope;
8
+ tab: SidebarTab;
9
+ expanded: string[];
10
+ revealed: string[];
11
+ onToggleDir: (path: string) => void;
12
+ onReferenceFile: (path: string) => void;
13
+ }): import("react").JSX.Element;
@@ -0,0 +1,38 @@
1
+ import type { OpenWithTarget } from './open-with.ts';
2
+ import { type UploadItem } from './upload.ts';
3
+ /** Root label: the last path segment (mirror of the host rootLabel). */
4
+ export declare function baseName(path: string): string;
5
+ export declare function FileTree(props: {
6
+ sessionId: string;
7
+ cwd: string | undefined;
8
+ expanded: string[];
9
+ /** Files highlighted by a "Show in folder" reveal (absolute paths). */
10
+ revealed: string[];
11
+ onToggle: (path: string) => void;
12
+ onOpenFile: (path: string) => void;
13
+ /** Context-menu "open in a new tab" (file rows; absent → no entry). */
14
+ onOpenFileNewTab?: (path: string) => void;
15
+ /** Context-menu "open to the side" (file rows; absent → no entry). */
16
+ onOpenFileSide?: (path: string) => void;
17
+ /**
18
+ * The "open with" menu: resolved external targets (already SSH-filtered
19
+ * and in menu order). Absent → the whole section is hidden.
20
+ */
21
+ openWithTargets?: OpenWithTarget[];
22
+ /** Ids of targets pinned to the menu's top level (subset of the ids). */
23
+ openWithPinned?: string[];
24
+ /** Whether the workspace is remote (appends the SSH hint to target labels). */
25
+ openWithSsh?: boolean;
26
+ /** Open one target externally (reveal or URL — the caller decides). */
27
+ onOpenWith?: (targetId: string, path: string) => void;
28
+ /** Toggle one target's pinned state (the submenu row's pushpin). */
29
+ onToggleOpenWithPin?: (targetId: string) => void;
30
+ /** Insert `@<relative path>` into the composer draft. */
31
+ onReferenceFile: (path: string) => void;
32
+ /** Bump to wipe the level cache and reload the visible set. */
33
+ refreshTick: number;
34
+ /** Upload into `dir` (absolute, inside the workspace); runs in the caller. */
35
+ onUploadRequest: (dir: string, items: UploadItem[]) => void;
36
+ /** True while an upload is in flight (drops are ignored). */
37
+ busy: boolean;
38
+ }): import("react").JSX.Element;
@@ -0,0 +1,29 @@
1
+ /**
2
+ * One free window: a tab dragged out of the workbench floating over the
3
+ * conversation area at viewport coordinates (rendered inside the panel host,
4
+ * so desktop-shell transforms can never hijack its fixed containing block).
5
+ *
6
+ * The header drags the window with the panel-resize pattern — pointer
7
+ * capture + per-frame direct DOM writes + a store commit on release — and
8
+ * doubling as the DOCK-BACK gesture: while the pointer is over a workbench
9
+ * pane ([data-dsh-pane], either panel), that pane highlights live and
10
+ * releasing docks the tab into it (center merge); releasing anywhere else
11
+ * just moves the window. The SE corner resizes, any press raises (the
12
+ * floats array's order is the stacking order), the header right-click menu
13
+ * and the X button dock / close. The tab content reuses the regular tab
14
+ * renderer, so every tab type (terminal, editor, plugin tabs) floats
15
+ * unchanged.
16
+ */
17
+ import { type ReactNode } from 'react';
18
+ import type { FloatWindow, SidebarTab } from './state.ts';
19
+ export declare function FreeWindow(props: {
20
+ float: FloatWindow;
21
+ renderTab: (tab: SidebarTab, active: boolean, paneId: string) => ReactNode;
22
+ getTabIcon?: (tab: SidebarTab) => ReactNode;
23
+ onRaise: () => void;
24
+ onMove: (x: number, y: number) => void;
25
+ onResize: (w: number, h: number) => void;
26
+ /** Dock the tab back; the pane id, or null for the active pane. */
27
+ onDock: (paneId: string | null) => void;
28
+ onClose: () => void;
29
+ }): import("react").JSX.Element;
@@ -0,0 +1,10 @@
1
+ import type { SessionScope } from './api.ts';
2
+ import type { SidebarTab } from './state.ts';
3
+ export declare function GitView(props: {
4
+ scope: SessionScope;
5
+ onOpenFile: (path: string) => void;
6
+ /** Open a diff tab (the shell places it below the git pane on first use). */
7
+ onOpenDiff: (tab: SidebarTab) => void;
8
+ /** Poll only while the tab is actually visible. */
9
+ visible: boolean;
10
+ }): import("react").JSX.Element;
@@ -0,0 +1,32 @@
1
+ import { type ReactNode } from 'react';
2
+ import { type AnalyzedMarkdownHtml } from './markdown-html.ts';
3
+ import { type MermaidMarkdownProps } from './mermaid-blocks.ts';
4
+ import type { SessionScope } from './api.ts';
5
+ /** The chunk-resident markdown renderer (mermaid lazy chunk), shared with the
6
+ * legacy no-HTML preview path in TextEditor. */
7
+ export declare const LazyMermaidMarkdown: (props: MermaidMarkdownProps) => ReactNode;
8
+ /** Everything the sanitizers need to resolve local media + scope the route. */
9
+ export interface MarkdownHtmlMedia {
10
+ scope: SessionScope;
11
+ path: string;
12
+ origin: string;
13
+ }
14
+ interface MarkdownDocumentProps {
15
+ info: AnalyzedMarkdownHtml;
16
+ media: MarkdownHtmlMedia;
17
+ codeLabels: {
18
+ copyLabel: string;
19
+ copiedLabel: string;
20
+ };
21
+ }
22
+ /**
23
+ * The split-document renderer: markdown runs render through MarkdownSegment,
24
+ * HTML runs render as sanitized leaves, and unclosed block elements lower the
25
+ * following runs into themselves until their close part pops the frame (the
26
+ * renderer's frame stack persists across segments). Stray closes at the top
27
+ * level render nothing (the sanitizer/parser would drop them anyway), and
28
+ * frames still open at the end of the document are closed like a browser
29
+ * parser would. Sanitization runs once per prepared change, in a memo.
30
+ */
31
+ export declare function MarkdownDocument({ info, media, codeLabels }: MarkdownDocumentProps): ReactNode;
32
+ export {};
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Placeholder shown when a persisted tab's type is not registered (the
3
+ * contributing plugin is not installed / not yet loaded). The tab is kept
4
+ * in state so it can recover if the plugin loads later; the user can close
5
+ * it through the tab bar's X button as usual. This is the graceful-
6
+ * degradation path for the open tab-type set: {@link Sidebar} renders this
7
+ * instead of crashing on an unknown type.
8
+ */
9
+ import type { ReactNode } from 'react';
10
+ import type { TabComponentProps } from './service.ts';
11
+ export declare function OrphanedTab(props: TabComponentProps): ReactNode;
@@ -0,0 +1,6 @@
1
+ import { type SessionScope } from './api.ts';
2
+ export declare function PdfView(props: {
3
+ scope: SessionScope;
4
+ path: string;
5
+ title: string;
6
+ }): import("react").JSX.Element;
@@ -0,0 +1,32 @@
1
+ /**
2
+ * The generic render error boundary for the sidebar tree: a render error in
3
+ * the wrapped subtree shows a dismissible error strip (retry re-renders the
4
+ * children) instead of blanking the shell. Used at two scopes:
5
+ *
6
+ * - ROOT (index.tsx, `css.boundaryError`): last-resort containment for
7
+ * errors in the sidebar shell itself (Workbench, drag layout, …) — a full
8
+ * swap keeps the page alive.
9
+ * - PER-TAB (Sidebar.tsx TabContent, `css.tabBoundaryError`): a crashing
10
+ * viewer/editor shows a strip inside ITS OWN pane; the toggle cluster, the
11
+ * other tabs, and the panel itself stay alive (issue #31 — a tab crash
12
+ * must never take down the whole sidebar).
13
+ *
14
+ * The className prop selects the strip's geometry: the root's full-height
15
+ * fixed rail vs. the tab's pane-filling block.
16
+ */
17
+ import { Component, type ErrorInfo, type ReactNode } from 'react';
18
+ export declare class RenderBoundary extends Component<{
19
+ children?: ReactNode;
20
+ className?: string;
21
+ }, {
22
+ error: string | null;
23
+ }> {
24
+ state: {
25
+ error: string | null;
26
+ };
27
+ static getDerivedStateFromError(error: unknown): {
28
+ error: string;
29
+ };
30
+ componentDidCatch(error: Error, info: ErrorInfo): void;
31
+ render(): ReactNode;
32
+ }
@@ -0,0 +1,10 @@
1
+ export declare function SandboxStatusBar(props: {
2
+ /** The effective sandbox state (global pref OR the local temporary unlock). */
3
+ sandboxed: boolean;
4
+ /** Whether the sandbox is off due to the LOCAL temporary unlock (shows the restore action). */
5
+ local: boolean;
6
+ /** The red-state explanation (e.g. "the page runs with full GUI privileges"). */
7
+ dangerCopy: string;
8
+ onUnlock: () => void;
9
+ onRestore: () => void;
10
+ }): import("react").JSX.Element;