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,74 @@
1
+ import type { PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
2
+ import { type SidebarPrefs } from '../prefs-shared.ts';
3
+ import type { SidebarStore } from './state.ts';
4
+ import type { BetterSidebarService, FileViewerDescriptor, SidebarSettingToggle, TabDescriptor } from './service.ts';
5
+ /** Injected business face: the shared store (prefs cache) + the sidebar service (registries). */
6
+ export interface SideCardSectionInjected {
7
+ store: SidebarStore;
8
+ service: BetterSidebarService;
9
+ }
10
+ /** Full section props: the runtime share plus the injected face. */
11
+ export type SideCardSectionProps = PropsRuntime<'settings.section'> & SideCardSectionInjected;
12
+ /**
13
+ * Merge one plugin-owned setting into a pluginSettings map (pure, v0.12.0+).
14
+ * Sequential merges are additive: each call spreads the map it was GIVEN,
15
+ * so building from the latest optimistic map keeps earlier keys intact
16
+ * (two same-tick writes must not drop each other).
17
+ */
18
+ export declare function mergePluginSetting(pluginSettings: Record<string, Record<string, unknown>>, descriptorId: string, key: string, value: unknown): Record<string, Record<string, unknown>>;
19
+ /**
20
+ * The body of a feature's secondary settings popup: one row (title/desc +
21
+ * control) per declared setting. Switches render the custom switch; text and
22
+ * number rows render a free-form / numeric input committed on blur/Enter
23
+ * (clamped to the declared min/max). Extracted so the rows are testable
24
+ * without opening the Modal (the Modal portal renders only while open).
25
+ */
26
+ export declare function FeatureSettingsRows(props: {
27
+ toggles: readonly SidebarSettingToggle[];
28
+ prefs: SidebarPrefs;
29
+ onToggle: (toggle: SidebarSettingToggle, next: boolean) => void;
30
+ /** Commit one text/number row; returns the canonical value the row should
31
+ * display (clamped for numbers, the current pref when the input is
32
+ * invalid). Optional: rows with no handler keep their draft. */
33
+ onCommit?: (toggle: SidebarSettingToggle, raw: string) => string;
34
+ /** Commit one select row: the picked option's value (single) or the array
35
+ * of picked values (`multi: true`). Optional: rows with no handler are
36
+ * display-only. */
37
+ onSelectValue?: (toggle: SidebarSettingToggle, next: unknown) => void;
38
+ /** Explicit value source (v0.12.0+): when given, rows read their values
39
+ * from it instead of the `prefs` face — plugin-owned rows read their
40
+ * own blob, so a plugin key can never collide with (or silently read)
41
+ * a host pref of the same name. (Named `valueSource`, not `valueOf`:
42
+ * the latter collides with the inherited Object.prototype.valueOf.) */
43
+ valueSource?: (key: string) => unknown;
44
+ }): import("react").JSX.Element;
45
+ /**
46
+ * The secondary settings popup body of one feature (tab or viewer):
47
+ * - the host-prefs `toggles` rows, then the plugin-owned `pluginToggles`
48
+ * rows (their values live in `pluginSettings[feature.id]`, projected onto
49
+ * the prefs face so the shared row renderer reads them);
50
+ * - `settings.render` (custom panel) AFTER those rows when declared — the
51
+ * custom panel is an extension of the row list, not a replacement, so a
52
+ * feature can keep its declarative rows (e.g. the editor's
53
+ * open-behavior picker) and still ship a custom configuration area.
54
+ */
55
+ export declare function SettingsBody(props: {
56
+ feature: TabDescriptor | FileViewerDescriptor;
57
+ prefs: SidebarPrefs;
58
+ store: SidebarStore;
59
+ service: BetterSidebarService;
60
+ onToggle: (toggle: SidebarSettingToggle, next: boolean) => void;
61
+ onCommit: (toggle: SidebarSettingToggle, raw: string) => string;
62
+ onSelectValue: (toggle: SidebarSettingToggle, next: unknown) => void;
63
+ onPluginToggle: (toggle: SidebarSettingToggle, next: boolean) => void;
64
+ onPluginCommit: (toggle: SidebarSettingToggle, raw: string) => string;
65
+ onPluginSelectValue: (toggle: SidebarSettingToggle, next: unknown) => void;
66
+ onPluginWrite: (key: string, value: unknown) => void;
67
+ onClose: () => void;
68
+ }): import("react").JSX.Element | null;
69
+ /**
70
+ * Render the Side card preferences section.
71
+ * @param props - composed slot props (runtime share + injected store/service).
72
+ * @returns the section element tree.
73
+ */
74
+ export declare function SideCardSection({ store, service }: SideCardSectionProps): import("react").JSX.Element;
@@ -0,0 +1,16 @@
1
+ import type { Context } from '../context-types.ts';
2
+ import type { SessionScope } from './api.ts';
3
+ import type { SidebarTab } from './state.ts';
4
+ /** The thread a tab is bound to (durable in tab.meta across refreshes). */
5
+ export declare function sidechatThreadIdOf(tab: SidebarTab): string | undefined;
6
+ /** Park a thread id for the NEXT sidechat openTab to reattach. */
7
+ export declare function parkSidechatReopen(threadId: string): void;
8
+ /** Consume the parked reopen target (undefined = mint a fresh thread tab). */
9
+ export declare function consumeSidechatSeed(): string | undefined;
10
+ /** One side conversation tab (one thread per tab, Codex-style). */
11
+ export declare function SideChatView(props: {
12
+ ctx: Context;
13
+ scope: SessionScope;
14
+ tab: SidebarTab;
15
+ visible: boolean;
16
+ }): React.ReactNode;
@@ -0,0 +1,6 @@
1
+ import type { Context } from '../context-types.ts';
2
+ import { type SidebarStore } from './state.ts';
3
+ export declare function Sidebar(props: {
4
+ ctx: Context;
5
+ store: SidebarStore;
6
+ }): import("react").JSX.Element;
@@ -0,0 +1,16 @@
1
+ import type { Context, SidebarSubagentAddress } from '../context-types.ts';
2
+ /**
3
+ * The sidebar's Subagent topology page.
4
+ * @param props - current session id, whether the page is actually visible
5
+ * (active tab + open panel), the client context, and an optional
6
+ * jump-notify hook fired right before `openSubagent` (lets the sidebar
7
+ * shell re-open the Subagent page after the conversation switch lands on
8
+ * the child session).
9
+ * @returns the main agent's topology tree, or the empty/error/loading states.
10
+ */
11
+ export declare function SubagentView(props: {
12
+ sessionId: string;
13
+ active: boolean;
14
+ ctx: Context;
15
+ onOpenChild?: (address: SidebarSubagentAddress) => void;
16
+ }): import("react").JSX.Element;
@@ -0,0 +1,54 @@
1
+ /**
2
+ * The tab strip of one pane: tabs capped at TAB_MAX_WIDTH (ellipsized),
3
+ * overflow scrolls horizontally, a close button per tab, a four-way split
4
+ * button cluster, and the + menu that opens new tabs (explorer / git /
5
+ * terminal). Tabs are draggable; dropping onto another tab inserts before it,
6
+ * dropping on the strip background appends to this pane. Right-clicking a
7
+ * tab opens the tab context menu (float as a free window / close / close
8
+ * others / close to the left / close to the right, the close ones scoped to
9
+ * this pane).
10
+ */
11
+ import { type ReactNode } from 'react';
12
+ import type { SidebarTab } from './state.ts';
13
+ /** One + menu option. */
14
+ export interface NewTabOption {
15
+ id: string;
16
+ label: string;
17
+ disabled?: boolean;
18
+ /** Leading icon (Menu row). */
19
+ icon?: ReactNode;
20
+ }
21
+ /** Drag payload for tab moves (HTML5 DnD dataTransfer). */
22
+ export declare const TAB_DRAG_TYPE = "application/x-dsh-tab";
23
+ export interface TabDragPayload {
24
+ tabId: string;
25
+ paneId: string;
26
+ }
27
+ export declare function serializeDrag(payload: TabDragPayload): string;
28
+ export declare function parseDrag(raw: string): TabDragPayload | null;
29
+ export declare function TabBar(props: {
30
+ paneId: string;
31
+ tabs: SidebarTab[];
32
+ active: string | null;
33
+ onActivate: (tabId: string) => void;
34
+ onClose: (tabId: string) => void;
35
+ onNewTab: (optionId: string) => void;
36
+ newTabOptions: NewTabOption[];
37
+ /** Drop of a tab from any pane: (payload, insertBeforeTabId | null). */
38
+ onDropTab: (payload: TabDragPayload, before: string | null) => void;
39
+ /** Float a tab out as a free window (the tab context menu's entry; the
40
+ * drag-to-conversation gesture is handled at the Sidebar shell level). */
41
+ onFloatTab: (tabId: string) => void;
42
+ /**
43
+ * Pin/unpin a terminal tab (v0.17.0+). Called with `'workspace'` or
44
+ * `'global'` to pin (the shell snapshots the home cwd), or `null` to
45
+ * unpin. Non-terminal tabs never trigger this callback. Optional: the
46
+ * menu hides the pin entry when unset (legacy callers).
47
+ */
48
+ onPinTab?: (tabId: string, scope: 'workspace' | 'global' | null) => void;
49
+ /** Icon resolver for tab labels (reads from the tab descriptor registry). */
50
+ getTabIcon?: (tab: SidebarTab) => ReactNode;
51
+ /** Badge resolver for tab labels (reads the descriptor's `badge`; the
52
+ * resolver returns the rendered pill or null). */
53
+ getTabBadge?: (tab: SidebarTab) => ReactNode;
54
+ }): import("react").JSX.Element;
@@ -0,0 +1,24 @@
1
+ import '@xterm/xterm/css/xterm.css';
2
+ import { type SessionScope, type TerminalDepsStatus } from './api.ts';
3
+ import { type SidebarStore } from './state.ts';
4
+ /** The degraded-mode payload rendered by {@link TerminalDepsBanner}. */
5
+ type TerminalDepsInfo = Extract<TerminalDepsStatus, {
6
+ ok: false;
7
+ }>;
8
+ export declare function TerminalView(props: {
9
+ scope: SessionScope;
10
+ tabId: string;
11
+ store: SidebarStore;
12
+ }): import("react").JSX.Element;
13
+ /**
14
+ * The node-pty dependency failure banner (issue #140): explains that the
15
+ * terminal's native dependency failed to load and shows the PASTEABLE repair
16
+ * command (bash / cmd / PowerShell) with a copy button — the user pastes it
17
+ * into a terminal where their DSH profile lives and runs it, then retries.
18
+ * Extracted as a standalone component for direct testing.
19
+ */
20
+ export declare function TerminalDepsBanner(props: {
21
+ deps: TerminalDepsInfo;
22
+ onRetry: () => void;
23
+ }): import("react").JSX.Element;
24
+ export {};
@@ -0,0 +1,10 @@
1
+ import type { FileViewerProps } from './service.ts';
2
+ /**
3
+ * The sandbox tokens of the HTML preview iframe. NO allow-same-origin (the
4
+ * preview must stay in an opaque origin — with the route's own origin it
5
+ * could read session data) and NO allow-top-navigation (a previewed page
6
+ * must not hijack the GUI). The user can disable the sandbox per-feature
7
+ * in the side card settings (warned); the toggle below reflects it.
8
+ */
9
+ export declare const HTML_IFRAME_SANDBOX = "allow-scripts allow-popups allow-downloads allow-modals";
10
+ export declare function TextEditor(props: FileViewerProps): import("react").JSX.Element;
@@ -0,0 +1,24 @@
1
+ import type { OpenWithTarget } from './open-with.ts';
2
+ export declare function TreePanel(props: {
3
+ sessionId: string;
4
+ cwd: string | undefined;
5
+ expanded: string[];
6
+ revealed: string[];
7
+ onToggle: (path: string) => void;
8
+ onOpenFile: (path: string) => void;
9
+ /** File context-menu "open in a new tab" (passed through to FileTree). */
10
+ onOpenFileNewTab?: (path: string) => void;
11
+ /** File context-menu "open to the side" (passed through to FileTree). */
12
+ onOpenFileSide?: (path: string) => void;
13
+ /** The "open with" menu surface (passed through to FileTree; absent →
14
+ * the whole section is hidden). */
15
+ openWithTargets?: OpenWithTarget[];
16
+ openWithPinned?: string[];
17
+ openWithSsh?: boolean;
18
+ onOpenWith?: (targetId: string, path: string) => void;
19
+ onToggleOpenWithPin?: (targetId: string) => void;
20
+ onReferenceFile: (path: string) => void;
21
+ /** Full-window presentation: the panel fills its host instead of docking
22
+ * at a fixed width. */
23
+ full?: boolean;
24
+ }): import("react").JSX.Element;
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Full-window upload progress over the files tree: a blurred scrim (same mask
3
+ * token as the repo's Modal primitive) with a card showing the target
4
+ * directory, file-level progress, and a cancel button. Esc cancels too —
5
+ * clicking the scrim does not, so a stray click can never abort an upload.
6
+ * Rendered inside TreePanel (absolute inset-0), so it covers only the file
7
+ * window and never the conversation column.
8
+ */
9
+ import { type ReactNode } from 'react';
10
+ export declare function UploadOverlay(props: {
11
+ /** Absolute upload directory (the session workspace or a tree directory). */
12
+ dir: string;
13
+ done: number;
14
+ total: number;
15
+ /** Relative path of the file being uploaded ('' when none is in flight). */
16
+ current: string;
17
+ onCancel: () => void;
18
+ /** True while cancellation is in flight (disables the cancel button). */
19
+ cancelling?: boolean;
20
+ }): ReactNode;
@@ -0,0 +1,15 @@
1
+ import type { BetterSidebarService } from './service.ts';
2
+ /** Which extension point the modal is adding a plugin for. */
3
+ export type PluginKind = 'tab' | 'viewer';
4
+ /** The modal body: the GitHub topic button + the recommended plugin list
5
+ * with per-entry jump/copy buttons (extracted for direct testing). */
6
+ export declare function PluginListBody(props: {
7
+ service: BetterSidebarService;
8
+ kind: PluginKind;
9
+ }): import("react").JSX.Element;
10
+ /** The modal itself (mounted only while open — see the module comment). */
11
+ export declare function AddPluginModal(props: {
12
+ service: BetterSidebarService;
13
+ onClose: () => void;
14
+ kind: PluginKind;
15
+ }): import("react").JSX.Element;
@@ -0,0 +1,275 @@
1
+ import type { LastActivity } from '../subagent-activity.ts';
2
+ import type { SidechatThreadInfo } from '../sidechat-core.ts';
3
+ import type { BrowserProbeResult } from './browser.ts';
4
+ /** One wire failure. */
5
+ export declare class SidebarApiError extends Error {
6
+ readonly code: string;
7
+ constructor(code: string, message: string);
8
+ }
9
+ /** Explorer row (host fs-tree shape). */
10
+ export interface FsEntry {
11
+ name: string;
12
+ path: string;
13
+ isDir: boolean;
14
+ hidden: boolean;
15
+ /** Whether the row is a symlink; `isDir` then describes the link's target. */
16
+ isSymlink: boolean;
17
+ /** For symlinks: the target is missing or unreadable (stat failed). */
18
+ broken: boolean;
19
+ }
20
+ /** Git status entry (host git shape). */
21
+ export interface GitStatusEntry {
22
+ path: string;
23
+ xy: string;
24
+ }
25
+ /** Git status snapshot. */
26
+ export interface GitStatusResult {
27
+ isRepo: boolean;
28
+ branch?: string;
29
+ entries: GitStatusEntry[];
30
+ /** True when the host capped `entries` (huge untracked set); the panel
31
+ * shows a truncation notice instead of freezing (#369). */
32
+ truncated?: boolean;
33
+ root?: string;
34
+ repositories?: string[];
35
+ }
36
+ /** One linked Git checkout. */
37
+ export interface GitWorktree {
38
+ path: string;
39
+ branch: string;
40
+ current: boolean;
41
+ changes: number;
42
+ }
43
+ /** One git log row. */
44
+ export interface GitLogEntry {
45
+ /** Short hash (7+ chars, display). */
46
+ hash: string;
47
+ /** Full 40-char hash (advanced operations). */
48
+ hashFull: string;
49
+ subject: string;
50
+ author: string;
51
+ /** ISO 8601 author date (`%ai`). */
52
+ date: string;
53
+ /** Ref decorations (--decorate=short), e.g. `HEAD -> main, origin/main`; '' when none. */
54
+ refs: string;
55
+ }
56
+ /** Text read result. */
57
+ export interface FsTextResult {
58
+ kind: 'text';
59
+ content: string;
60
+ truncated: boolean;
61
+ }
62
+ /** Binary read result (no content; images load through the media route).
63
+ * `head` carries the first bytes (base64) for viewer detect sniffing. */
64
+ export interface FsBinaryResult {
65
+ kind: 'binary';
66
+ size: number;
67
+ truncated: boolean;
68
+ head: string;
69
+ }
70
+ /**
71
+ * One jobs.output response: the output the MODEL has read so far for the
72
+ * job (replayed from the owner session's event log — the model's
73
+ * job_output cursor is never touched, so the pane can never steal the
74
+ * agent's bytes). `read` is false until the model actually called
75
+ * job_output for the job.
76
+ */
77
+ export interface JobOutputResult {
78
+ text: string;
79
+ /** True when the host capped the text at its output limit. */
80
+ truncated: boolean;
81
+ /** Whether the model has read the job at least once. */
82
+ read: boolean;
83
+ }
84
+ /** The `subagents.live` response: running child id → latest activity. */
85
+ export type SubagentLiveResult = {
86
+ live: Record<string, LastActivity>;
87
+ };
88
+ /** Terminal dependency status (mirror of the host's depsStatus; issue #140). */
89
+ export type TerminalDepsStatus = {
90
+ ok: true;
91
+ } | {
92
+ ok: false;
93
+ /** The require-time error message (module missing, native binding broken…). */
94
+ cause: string;
95
+ /** The pasteable repair command (terminal/cmd). */
96
+ command: string;
97
+ /** The detected profile name (null when undetected → the command defaults to web). */
98
+ profile: string | null;
99
+ /** Optional supplementary hint (fallback command only). */
100
+ note?: string;
101
+ };
102
+ /** One request's session scope: the conversation id plus its cwd when known. */
103
+ export interface SessionScope {
104
+ sessionId: string;
105
+ /** The session's working directory from the client list summary (optional). */
106
+ cwd?: string;
107
+ /** Selected Git repository when cwd is a workspace container. */
108
+ repoRoot?: string;
109
+ }
110
+ /** The sidebar API surface (session scope threaded through every call). */
111
+ export declare const api: {
112
+ sessionCwd: (scope: SessionScope, signal?: AbortSignal) => Promise<{
113
+ sessionId: string;
114
+ cwd: string;
115
+ root: string;
116
+ parent: string | null;
117
+ }>;
118
+ fsTree: (scope: SessionScope, path: string, signal?: AbortSignal) => Promise<{
119
+ path: string;
120
+ entries: FsEntry[];
121
+ truncated: boolean;
122
+ }>;
123
+ /** Global recursive file-name search rooted at the session cwd (the editor
124
+ * side panel's search box); matches are cwd-relative '/'-separated paths. */
125
+ fsSearch: (scope: SessionScope, query: string, signal?: AbortSignal) => Promise<{
126
+ matches: string[];
127
+ truncated: boolean;
128
+ }>;
129
+ fsRead: (scope: SessionScope, path: string, signal?: AbortSignal) => Promise<FsTextResult | FsBinaryResult>;
130
+ fsWrite: (scope: SessionScope, path: string, content: string) => Promise<{
131
+ ok: true;
132
+ }>;
133
+ /** Upload one file's raw bytes into `dir` (keeps the folder tree via
134
+ * `relativePath`); the host streams it under the session workspace. */
135
+ uploadFile: (scope: SessionScope, dir: string, relativePath: string, body: Blob, signal?: AbortSignal) => Promise<{
136
+ path: string;
137
+ size: number;
138
+ }>;
139
+ gitWorktrees: (scope: SessionScope, signal?: AbortSignal) => Promise<GitWorktree[]>;
140
+ gitStatus: (scope: SessionScope, worktree?: string, signal?: AbortSignal) => Promise<GitStatusResult>;
141
+ gitDiff: (scope: SessionScope, path: string | undefined, staged: boolean, worktree?: string, signal?: AbortSignal) => Promise<{
142
+ diff: string;
143
+ }>;
144
+ gitStage: (scope: SessionScope, path?: string, worktree?: string) => Promise<{
145
+ ok: true;
146
+ }>;
147
+ gitUnstage: (scope: SessionScope, path?: string, worktree?: string) => Promise<{
148
+ ok: true;
149
+ }>;
150
+ gitCommit: (scope: SessionScope, message: string, worktree?: string) => Promise<{
151
+ ok: true;
152
+ }>;
153
+ gitBranch: (scope: SessionScope, worktree?: string, signal?: AbortSignal) => Promise<{
154
+ current: string;
155
+ names: string[];
156
+ }>;
157
+ gitCheckout: (scope: SessionScope, branch: string, worktree?: string) => Promise<{
158
+ ok: true;
159
+ }>;
160
+ /** Recent commit history, lazily pageable (skip/count; defaults 0/30). */
161
+ gitLog: (scope: SessionScope, count?: number, skip?: number, worktree?: string, signal?: AbortSignal) => Promise<GitLogEntry[]>;
162
+ /** Full patch text of one commit (diff display for the history rows). */
163
+ gitCommitDiff: (scope: SessionScope, hash: string, worktree?: string, signal?: AbortSignal) => Promise<{
164
+ diff: string;
165
+ }>;
166
+ /** Discard the worktree changes of one file (the index is untouched). */
167
+ gitDiscard: (scope: SessionScope, path: string, worktree?: string) => Promise<{
168
+ ok: true;
169
+ }>;
170
+ /** Revert one commit onto the current branch. */
171
+ gitRevert: (scope: SessionScope, hash: string, worktree?: string) => Promise<{
172
+ ok: true;
173
+ }>;
174
+ /** Cherry-pick one commit onto the current branch. */
175
+ gitCherryPick: (scope: SessionScope, hash: string, worktree?: string) => Promise<{
176
+ ok: true;
177
+ }>;
178
+ /** Release a terminal's process immediately (tab closed; the WS close frame
179
+ * may be unreachable while the socket is down, so the host also accepts
180
+ * this explicit route). */
181
+ ptyClose: (scope: SessionScope, tab: string) => Promise<{
182
+ ok: true;
183
+ }>;
184
+ /** Release an agent terminal by uuid (tab closed while WS was down). */
185
+ agentPtyClose: (uuid: string) => Promise<{
186
+ ok: true;
187
+ }>;
188
+ /** Terminal dependency status (issue #140): after a WS close 1011 with
189
+ * reason `pty-deps-missing` the view fetches the full repair details here
190
+ * (the close reason itself is capped at 123 bytes). */
191
+ terminalDeps: () => Promise<TerminalDepsStatus>;
192
+ /**
193
+ * The output the model has read so far for one background job (replayed
194
+ * from the owner session's event log — never the model's job_output
195
+ * cursor). The scope MUST be the job's OWNER session.
196
+ */
197
+ jobOutput: (scope: SessionScope, id: string, signal?: AbortSignal) => Promise<JobOutputResult>;
198
+ /** Request cancellation of one background job (live jobs flip to stopping). */
199
+ jobKill: (scope: SessionScope, id: string, reason?: string) => Promise<{
200
+ ok: true;
201
+ outcome: "requested" | "already-finished";
202
+ }>;
203
+ /**
204
+ * One batch live-preview fetch for the whole Subagent tree. The payload is
205
+ * the already-resolved topology ROOT (not a session scope); the host
206
+ * enumerates descendants once and folds running children's activity.
207
+ */
208
+ subagentsLive: (rootSessionId: string, signal?: AbortSignal) => Promise<SubagentLiveResult>;
209
+ /** Create a Side Chat thread: a child session seeded with the parent's
210
+ * full log up to now. Empty question = immediate create (Codex-style):
211
+ * the thread opens empty, the first prompt carries the boundary. */
212
+ sidechatStart: (sessionId: string, question?: string) => Promise<{
213
+ childId: string;
214
+ }>;
215
+ /** Deliver one follow-up message to a Side Chat thread. */
216
+ sidechatPrompt: (childId: string, text: string) => Promise<{
217
+ accepted: true;
218
+ }>;
219
+ /** Abort a Side Chat thread's running turn (queued work is preserved). */
220
+ sidechatCancel: (childId: string) => Promise<{
221
+ accepted: true;
222
+ }>;
223
+ /** Release a Side Chat thread's live agent (history stays persisted). */
224
+ sidechatDispose: (childId: string) => Promise<{
225
+ accepted: true;
226
+ }>;
227
+ /** Live state + agent identity (provider/model/preset) of a thread. */
228
+ sidechatInfo: (childId: string) => Promise<SidechatThreadInfo>;
229
+ /** The effective terminal shell and its display name (plugin-global). */
230
+ shellGet: () => Promise<{
231
+ shell: string;
232
+ name: string;
233
+ }>;
234
+ /** Read the side card preferences (plugin-global, no session scope). */
235
+ settingsGet: () => Promise<{
236
+ value?: unknown;
237
+ revision?: number;
238
+ externalDisable?: boolean;
239
+ }>;
240
+ /** Merge a patch into the side card preferences (revision-guarded). */
241
+ settingsUpdate: (patch: Record<string, unknown>, expectedRevision?: number) => Promise<{
242
+ value?: unknown;
243
+ revision?: number;
244
+ }>;
245
+ /** Probe a URL's response headers (the sidebar browser's embeddability
246
+ * check; see the host's browser.probe route). */
247
+ browserProbe: (url: string, signal?: AbortSignal) => Promise<BrowserProbeResult>;
248
+ /** External open for the file tree's "open with" menu: reveal a path in
249
+ * the OS file manager, or hand a custom-scheme URL (vscode://, cursor://,
250
+ * zed://, custom editors) to its registered handler. The host launches
251
+ * the platform opener (argv, no shell). */
252
+ openExternal: (payload: {
253
+ action: "reveal";
254
+ path: string;
255
+ } | {
256
+ action: "url";
257
+ url: string;
258
+ }) => Promise<{
259
+ started: boolean;
260
+ }>;
261
+ };
262
+ /** Absolute URL of the media route for one path (images only). */
263
+ export declare function mediaUrl(scope: SessionScope, path: string): string;
264
+ /** Absolute URL of the download route: serves raw bytes (binary-safe) with
265
+ * `Content-Disposition: attachment`, so the browser saves the file. */
266
+ export declare function downloadUrl(scope: SessionScope, path: string): string;
267
+ /**
268
+ * Absolute URL of the HTML preview route (see html-route.ts): the path is
269
+ * fully encoded so the previewed page's relative assets resolve back into
270
+ * the same route with the session scope intact. The UNC marker is
271
+ * platform-neutral — the host's requireAbsolute resolves the decoded
272
+ * forward-slash `//server/share/...` form on both win32 and POSIX — so no
273
+ * client-side platform signal is needed.
274
+ */
275
+ export declare function htmlUrl(scope: SessionScope, path: string): string;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * The "no preview — download instead" pane: shown by the editor host when no
3
+ * viewer can render a file (binary without a registered renderer, or the
4
+ * `binary-download` strategy) and registered as the `binary-download` viewer
5
+ * component so the declarative route and the host fallback share one UI.
6
+ */
7
+ import type { ReactNode } from 'react';
8
+ import type { SessionScope } from './api.ts';
9
+ export declare function BinaryDownload(props: {
10
+ scope: SessionScope;
11
+ path: string;
12
+ }): ReactNode;
@@ -0,0 +1,17 @@
1
+ /** Viewport widths strictly below this are "mobile" (paired CSS: max-width: 767px). */
2
+ export declare const NARROW_MAX_WIDTH = 768;
3
+ /** Whether a viewport width is narrow (mobile). */
4
+ export declare function isNarrowWidth(width: number): boolean;
5
+ export interface ViewportSize {
6
+ width: number;
7
+ height: number;
8
+ }
9
+ /**
10
+ * Live narrow-viewport flag for components. Reads `window.innerWidth` and
11
+ * re-measures on resize (rAF-throttled, the repo's existing drag pattern).
12
+ * Deliberately avoids `matchMedia` (jsdom does not implement it) — the
13
+ * resize listener is equally exact for a breakpoint that never changes
14
+ * while the page is open.
15
+ */
16
+ export declare function useViewportSize(): ViewportSize;
17
+ export declare function useNarrowViewport(): boolean;
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Pure URL policy for the built-in browser tab: normalize user input into
3
+ * an http(s) URL, and refuse destinations that would be dangerous to embed
4
+ * in the sidebar iframe. Kept dependency-free so it is unit-testable.
5
+ *
6
+ * The iframe sandbox (opaque origin, no allow-same-origin / top-navigation)
7
+ * is the primary security boundary; this module is the address-bar gate on
8
+ * top of it: only http/https may be navigated, and loopback addresses are
9
+ * refused so a browsed page cannot probe local services by user action.
10
+ * The GUI's OWN origin is explicitly ALLOWED — the user may open the GUI
11
+ * itself in the sidebar (debugging, mirroring); the sandbox still renders
12
+ * it in an opaque origin with no same-origin privileges, exactly like any
13
+ * other site.
14
+ */
15
+ /** Why a navigation attempt was refused. */
16
+ export type BrowserBlockReason = 'scheme' | 'loopback';
17
+ /** Result of normalizing one address-bar input. */
18
+ export type BrowserNavigateResult = {
19
+ kind: 'ok';
20
+ url: string;
21
+ } | {
22
+ kind: 'blocked';
23
+ reason: BrowserBlockReason;
24
+ } | {
25
+ kind: 'invalid';
26
+ };
27
+ /** One browser.probe wire result (host fetch of the target's headers). */
28
+ export interface BrowserProbeResult {
29
+ reachable: boolean;
30
+ /** The final (post-redirect) URL; present when reachable. */
31
+ url?: string;
32
+ status?: number;
33
+ xFrameOptions?: string;
34
+ /** The CSP frame-ancestors source list; present when the directive exists. */
35
+ frameAncestors?: string[];
36
+ }
37
+ /** Embeddability verdict of one probe. */
38
+ export type Embeddability = 'embeddable' | 'blocked' | 'unknown';
39
+ /**
40
+ * Decide whether a site can render inside the sidebar iframe. The signals
41
+ * are exactly the ones the BROWSER enforces when it refuses an iframe load:
42
+ * X-Frame-Options DENY/SAMEORIGIN, or a frame-ancestors directive that does
43
+ * not allow `*` ('self' here means the SITE's own origin — never ours, so
44
+ * it also blocks the sidebar). A site we could not reach yields 'unknown'
45
+ * and the plain iframe stays.
46
+ */
47
+ export declare function embeddabilityOf(probe: BrowserProbeResult): Embeddability;
48
+ /** A loopback hostname (localhost, IPv6 ::1, 127.0.0.0/8, 0.0.0.0). */
49
+ export declare function isLoopbackHostname(hostname: string): boolean;
50
+ /** Parse the loopback allowlist into a matcher predicate over host:port. */
51
+ export declare function parseLoopbackAllowlist(allowlist: string): (host: string, port: string) => boolean;
52
+ /**
53
+ * Whether a loopback URL is explicitly allowlisted by the side card prefs
54
+ * (`browserAllowedLoopback`). Only allowlisted local addresses may run with
55
+ * `allow-same-origin` in the sidebar iframe — needed for local dev servers
56
+ * (Vite etc.) whose module/HMR/fetch pipeline requires a real origin, while
57
+ * the page stays cross-origin to the GUI and to every other site.
58
+ */
59
+ export declare function isAllowedLoopbackUrl(url: string, allowlist: string): boolean;
60
+ export declare function normalizeBrowserUrl(input: string, selfOrigin: string, allowedLoopback?: string): BrowserNavigateResult;
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Built-in registration: the plugin registers its own tab pages and file
3
+ * previewers through the same {@link BetterSidebarService} external plugins
4
+ * use — eating its own dogfood. The descriptors live next to their feature
5
+ * modules (tabs.tsx / viewers.tsx); this module only aggregates them and
6
+ * owns the disposer lifecycle (cordis auto-invokes it on fiber disposal,
7
+ * HMR-safe).
8
+ */
9
+ import type { Context } from '../../context-types.ts';
10
+ import type { BetterSidebarService } from '../service.ts';
11
+ import { type BuiltinTabOptions } from './tabs.tsx';
12
+ /**
13
+ * Register all built-in tabs and viewers with the service. Returns a
14
+ * disposer that unregisters everything (cordis auto-invokes it on fiber
15
+ * disposal). The `ctx` is threaded into tab descriptors that need it
16
+ * (EditorHost reads `ctx.betterSidebar` for file-viewer matching).
17
+ */
18
+ export declare function registerBuiltins(ctx: Context, service: BetterSidebarService, options?: BuiltinTabOptions): () => void;