@chatcode/cco-better-sidebar 0.18.0-alpha.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 (329) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +554 -0
  3. package/README_EN.md +563 -0
  4. package/assets/logo.svg +1 -0
  5. package/cordis.patch.yml +79 -0
  6. package/lib/client-editor.js +55744 -0
  7. package/lib/client-mermaid.js +208256 -0
  8. package/lib/client-registry.js +30378 -0
  9. package/lib/client-terminal.js +16894 -0
  10. package/lib/client.js +30378 -0
  11. package/lib/index.js +6897 -0
  12. package/lib/invariant.js +22 -0
  13. package/lib/types/agent-opens.d.ts +65 -0
  14. package/lib/types/agent-pty.d.ts +226 -0
  15. package/lib/types/browser-probe.d.ts +15 -0
  16. package/lib/types/bundle-route.d.ts +12 -0
  17. package/lib/types/chatcode-update.d.ts +47 -0
  18. package/lib/types/client/AccountMenu.d.ts +1 -0
  19. package/lib/types/client/AiRatioSection.d.ts +3 -0
  20. package/lib/types/client/BrowserView.d.ts +39 -0
  21. package/lib/types/client/ChatcodeGate.d.ts +6 -0
  22. package/lib/types/client/CodingPlanModelsSettings.d.ts +9 -0
  23. package/lib/types/client/DiffTab.d.ts +6 -0
  24. package/lib/types/client/DiffView.d.ts +51 -0
  25. package/lib/types/client/EditorHost.d.ts +13 -0
  26. package/lib/types/client/FenceErrorNotice.d.ts +5 -0
  27. package/lib/types/client/FileTree.d.ts +41 -0
  28. package/lib/types/client/FreeWindow.d.ts +29 -0
  29. package/lib/types/client/GitView.d.ts +12 -0
  30. package/lib/types/client/MarkdownHtml.d.ts +32 -0
  31. package/lib/types/client/OrphanedTab.d.ts +11 -0
  32. package/lib/types/client/PdfView.d.ts +6 -0
  33. package/lib/types/client/ReleaseNotesDialog.d.ts +11 -0
  34. package/lib/types/client/RenderBoundary.d.ts +32 -0
  35. package/lib/types/client/SandboxStatusBar.d.ts +10 -0
  36. package/lib/types/client/SideCardSection.d.ts +74 -0
  37. package/lib/types/client/Sidebar.d.ts +8 -0
  38. package/lib/types/client/TabBar.d.ts +54 -0
  39. package/lib/types/client/TerminalView.d.ts +24 -0
  40. package/lib/types/client/TextEditor.d.ts +10 -0
  41. package/lib/types/client/TreePanel.d.ts +27 -0
  42. package/lib/types/client/UpdateDialog.d.ts +10 -0
  43. package/lib/types/client/UpdateSettingsPanel.d.ts +1 -0
  44. package/lib/types/client/UpdateSettingsSection.d.ts +10 -0
  45. package/lib/types/client/UploadOverlay.d.ts +20 -0
  46. package/lib/types/client/UsageHeatmapSection.d.ts +4 -0
  47. package/lib/types/client/add-plugin-modal.d.ts +15 -0
  48. package/lib/types/client/api.d.ts +345 -0
  49. package/lib/types/client/binary-download.d.ts +12 -0
  50. package/lib/types/client/breakpoints.d.ts +17 -0
  51. package/lib/types/client/browser.d.ts +60 -0
  52. package/lib/types/client/builtins/index.d.ts +18 -0
  53. package/lib/types/client/builtins/tabs.d.ts +11 -0
  54. package/lib/types/client/builtins/viewers.d.ts +3 -0
  55. package/lib/types/client/chat-presentation.d.ts +13 -0
  56. package/lib/types/client/chunk-loader.d.ts +124 -0
  57. package/lib/types/client/chunks/editor.d.ts +9 -0
  58. package/lib/types/client/chunks/mermaid.d.ts +10 -0
  59. package/lib/types/client/chunks/terminal.d.ts +9 -0
  60. package/lib/types/client/cm-themes.d.ts +24 -0
  61. package/lib/types/client/conversation-draft.d.ts +14 -0
  62. package/lib/types/client/desktop-env.d.ts +35 -0
  63. package/lib/types/client/editor-load.d.ts +66 -0
  64. package/lib/types/client/frame-batcher.d.ts +24 -0
  65. package/lib/types/client/icons.d.ts +66 -0
  66. package/lib/types/client/image-types.d.ts +3 -0
  67. package/lib/types/client/ime-guard.d.ts +36 -0
  68. package/lib/types/client/index.d.ts +19 -0
  69. package/lib/types/client/intercept.d.ts +44 -0
  70. package/lib/types/client/lang.d.ts +14 -0
  71. package/lib/types/client/layout-push.d.ts +15 -0
  72. package/lib/types/client/lazy-chunk.d.ts +25 -0
  73. package/lib/types/client/link-intercept.d.ts +42 -0
  74. package/lib/types/client/locales-ar.d.ts +18 -0
  75. package/lib/types/client/locales-de.d.ts +4 -0
  76. package/lib/types/client/locales-fr.d.ts +10 -0
  77. package/lib/types/client/locales-hi.d.ts +17 -0
  78. package/lib/types/client/locales-id.d.ts +15 -0
  79. package/lib/types/client/locales-it.d.ts +8 -0
  80. package/lib/types/client/locales-ja.d.ts +17 -0
  81. package/lib/types/client/locales-ko.d.ts +9 -0
  82. package/lib/types/client/locales-nl.d.ts +16 -0
  83. package/lib/types/client/locales-pl.d.ts +19 -0
  84. package/lib/types/client/locales-pt.d.ts +1 -0
  85. package/lib/types/client/locales-ru.d.ts +13 -0
  86. package/lib/types/client/locales-sv.d.ts +1 -0
  87. package/lib/types/client/locales-th.d.ts +17 -0
  88. package/lib/types/client/locales-tr.d.ts +17 -0
  89. package/lib/types/client/locales-vi.d.ts +17 -0
  90. package/lib/types/client/locales-zh-HK.d.ts +32 -0
  91. package/lib/types/client/locales-zh-MO.d.ts +32 -0
  92. package/lib/types/client/locales-zh-TW.d.ts +32 -0
  93. package/lib/types/client/locales.d.ts +571 -0
  94. package/lib/types/client/markdown-html.d.ts +96 -0
  95. package/lib/types/client/markdown-images.d.ts +45 -0
  96. package/lib/types/client/markdown-labels.d.ts +21 -0
  97. package/lib/types/client/md-toc.d.ts +4 -0
  98. package/lib/types/client/mermaid-blocks.d.ts +47 -0
  99. package/lib/types/client/mermaid-sanitize.d.ts +2 -0
  100. package/lib/types/client/mermaid.d.ts +12 -0
  101. package/lib/types/client/open-when-sized.d.ts +20 -0
  102. package/lib/types/client/open-with-settings.d.ts +4 -0
  103. package/lib/types/client/open-with.d.ts +87 -0
  104. package/lib/types/client/openpath-intercept.d.ts +52 -0
  105. package/lib/types/client/paths.d.ts +43 -0
  106. package/lib/types/client/pdf-types.d.ts +2 -0
  107. package/lib/types/client/pinned.d.ts +86 -0
  108. package/lib/types/client/plugin-settings.d.ts +8 -0
  109. package/lib/types/client/plugins-shared.d.ts +27 -0
  110. package/lib/types/client/plugins-tabs.d.ts +3 -0
  111. package/lib/types/client/plugins-viewers.d.ts +3 -0
  112. package/lib/types/client/prefs.d.ts +41 -0
  113. package/lib/types/client/produced-files.d.ts +29 -0
  114. package/lib/types/client/selection-payload.d.ts +27 -0
  115. package/lib/types/client/service.d.ts +445 -0
  116. package/lib/types/client/session-pins.d.ts +14 -0
  117. package/lib/types/client/settings-nav-icon.d.ts +27 -0
  118. package/lib/types/client/shell-presets.d.ts +48 -0
  119. package/lib/types/client/split-pane.d.ts +38 -0
  120. package/lib/types/client/state.d.ts +480 -0
  121. package/lib/types/client/tab-content-memo.d.ts +40 -0
  122. package/lib/types/client/terminal-font.d.ts +78 -0
  123. package/lib/types/client/terminal-links.d.ts +119 -0
  124. package/lib/types/client/theme.d.ts +45 -0
  125. package/lib/types/client/titlebar-strip.d.ts +23 -0
  126. package/lib/types/client/ui-tweaks/appicons.d.ts +16 -0
  127. package/lib/types/client/ui-tweaks/archive.d.ts +42 -0
  128. package/lib/types/client/ui-tweaks/branding.d.ts +45 -0
  129. package/lib/types/client/ui-tweaks/cachehit.d.ts +41 -0
  130. package/lib/types/client/ui-tweaks/gitbar.d.ts +103 -0
  131. package/lib/types/client/ui-tweaks/index.d.ts +279 -0
  132. package/lib/types/client/ui-tweaks/mcp.d.ts +28 -0
  133. package/lib/types/client/ui-tweaks/notifier.d.ts +125 -0
  134. package/lib/types/client/ui-tweaks/whale.d.ts +55 -0
  135. package/lib/types/client/upload.d.ts +69 -0
  136. package/lib/types/client/useChatcodeAccount.d.ts +10 -0
  137. package/lib/types/client/wco.d.ts +47 -0
  138. package/lib/types/codingplan.d.ts +37 -0
  139. package/lib/types/config.d.ts +95 -0
  140. package/lib/types/context-types.d.ts +540 -0
  141. package/lib/types/fs-operations.d.ts +30 -0
  142. package/lib/types/fs-search.d.ts +24 -0
  143. package/lib/types/fs-tree.d.ts +51 -0
  144. package/lib/types/git.d.ts +124 -0
  145. package/lib/types/html-route.d.ts +59 -0
  146. package/lib/types/index.d.ts +47 -0
  147. package/lib/types/invariant.d.ts +15 -0
  148. package/lib/types/login-route.d.ts +2 -0
  149. package/lib/types/open-external.d.ts +24 -0
  150. package/lib/types/path-security.d.ts +26 -0
  151. package/lib/types/prefs-shared.d.ts +257 -0
  152. package/lib/types/pty-deps.d.ts +79 -0
  153. package/lib/types/pty-manager.d.ts +168 -0
  154. package/lib/types/tools.d.ts +34 -0
  155. package/lib/types/trust-fence.d.ts +24 -0
  156. package/lib/types/ui-tweaks/archive.d.ts +71 -0
  157. package/lib/types/ui-tweaks/config.d.ts +186 -0
  158. package/lib/types/ui-tweaks/git-web.d.ts +43 -0
  159. package/lib/types/ui-tweaks/git.d.ts +311 -0
  160. package/lib/types/ui-tweaks/index.d.ts +17 -0
  161. package/lib/types/ui-tweaks/mcp.d.ts +103 -0
  162. package/lib/types/ui-tweaks/turn-outcome.d.ts +57 -0
  163. package/lib/types/ui-tweaks/web.d.ts +55 -0
  164. package/lib/types/wire.d.ts +38 -0
  165. package/package.json +213 -0
  166. package/scripts/install.ps1 +310 -0
  167. package/scripts/install.sh +287 -0
  168. package/src/agent-opens.ts +265 -0
  169. package/src/agent-pty.ts +527 -0
  170. package/src/browser-probe.ts +26 -0
  171. package/src/bundle-route.ts +129 -0
  172. package/src/chatcode-update.ts +193 -0
  173. package/src/client/AccountMenu.tsx +177 -0
  174. package/src/client/AiRatioSection.module.css +329 -0
  175. package/src/client/AiRatioSection.tsx +292 -0
  176. package/src/client/BrowserView.tsx +289 -0
  177. package/src/client/ChatcodeGate.tsx +35 -0
  178. package/src/client/CodingPlanModelsSettings.module.css +118 -0
  179. package/src/client/CodingPlanModelsSettings.tsx +101 -0
  180. package/src/client/DiffTab.tsx +114 -0
  181. package/src/client/DiffView.tsx +305 -0
  182. package/src/client/EditorHost.tsx +563 -0
  183. package/src/client/FenceErrorNotice.tsx +40 -0
  184. package/src/client/FileTree.tsx +701 -0
  185. package/src/client/FreeWindow.tsx +337 -0
  186. package/src/client/GitView.tsx +722 -0
  187. package/src/client/MarkdownHtml.tsx +296 -0
  188. package/src/client/OrphanedTab.tsx +27 -0
  189. package/src/client/PdfView.tsx +110 -0
  190. package/src/client/ReleaseNotesDialog.tsx +91 -0
  191. package/src/client/RenderBoundary.tsx +49 -0
  192. package/src/client/SandboxStatusBar.tsx +60 -0
  193. package/src/client/SideCardSection.module.css +932 -0
  194. package/src/client/SideCardSection.tsx +1169 -0
  195. package/src/client/Sidebar.tsx +1857 -0
  196. package/src/client/TabBar.tsx +365 -0
  197. package/src/client/TerminalView.tsx +424 -0
  198. package/src/client/TextEditor.tsx +468 -0
  199. package/src/client/TreePanel.tsx +279 -0
  200. package/src/client/UpdateDialog.tsx +186 -0
  201. package/src/client/UpdateSettingsPanel.tsx +29 -0
  202. package/src/client/UpdateSettingsSection.tsx +22 -0
  203. package/src/client/UploadOverlay.tsx +62 -0
  204. package/src/client/UsageHeatmapSection.module.css +440 -0
  205. package/src/client/UsageHeatmapSection.tsx +301 -0
  206. package/src/client/add-plugin-modal.tsx +199 -0
  207. package/src/client/api.ts +433 -0
  208. package/src/client/binary-download.tsx +23 -0
  209. package/src/client/breakpoints.ts +61 -0
  210. package/src/client/browser.ts +167 -0
  211. package/src/client/builtins/index.ts +37 -0
  212. package/src/client/builtins/tabs.tsx +275 -0
  213. package/src/client/builtins/viewers.tsx +125 -0
  214. package/src/client/chat-presentation.ts +95 -0
  215. package/src/client/chunk-loader.ts +350 -0
  216. package/src/client/chunks/editor.tsx +9 -0
  217. package/src/client/chunks/mermaid.tsx +10 -0
  218. package/src/client/chunks/terminal.tsx +9 -0
  219. package/src/client/cm-themes.ts +129 -0
  220. package/src/client/conversation-draft.ts +29 -0
  221. package/src/client/css-modules.d.ts +5 -0
  222. package/src/client/desktop-env.ts +72 -0
  223. package/src/client/editor-load.ts +92 -0
  224. package/src/client/frame-batcher.ts +56 -0
  225. package/src/client/icons.tsx +170 -0
  226. package/src/client/image-types.ts +8 -0
  227. package/src/client/ime-guard.ts +47 -0
  228. package/src/client/index.tsx +501 -0
  229. package/src/client/intercept.tsx +172 -0
  230. package/src/client/lang.ts +225 -0
  231. package/src/client/layout-push.ts +37 -0
  232. package/src/client/layout.css +156 -0
  233. package/src/client/lazy-chunk.tsx +89 -0
  234. package/src/client/link-intercept.ts +73 -0
  235. package/src/client/locales-ar.ts +387 -0
  236. package/src/client/locales-de.ts +372 -0
  237. package/src/client/locales-fr.ts +379 -0
  238. package/src/client/locales-hi.ts +386 -0
  239. package/src/client/locales-id.ts +384 -0
  240. package/src/client/locales-it.ts +377 -0
  241. package/src/client/locales-ja.ts +486 -0
  242. package/src/client/locales-ko.ts +378 -0
  243. package/src/client/locales-nl.ts +384 -0
  244. package/src/client/locales-pl.ts +388 -0
  245. package/src/client/locales-pt.ts +369 -0
  246. package/src/client/locales-ru.ts +384 -0
  247. package/src/client/locales-sv.ts +369 -0
  248. package/src/client/locales-th.ts +386 -0
  249. package/src/client/locales-tr.ts +386 -0
  250. package/src/client/locales-vi.ts +386 -0
  251. package/src/client/locales-zh-HK.ts +401 -0
  252. package/src/client/locales-zh-MO.ts +401 -0
  253. package/src/client/locales-zh-TW.ts +401 -0
  254. package/src/client/locales.ts +1229 -0
  255. package/src/client/markdown-html.ts +331 -0
  256. package/src/client/markdown-images.ts +137 -0
  257. package/src/client/markdown-labels.tsx +31 -0
  258. package/src/client/md-toc.tsx +127 -0
  259. package/src/client/mermaid-blocks.ts +110 -0
  260. package/src/client/mermaid-sanitize.ts +93 -0
  261. package/src/client/mermaid.tsx +406 -0
  262. package/src/client/open-when-sized.ts +43 -0
  263. package/src/client/open-with-settings.tsx +135 -0
  264. package/src/client/open-with.ts +221 -0
  265. package/src/client/openpath-intercept.ts +79 -0
  266. package/src/client/paths.ts +63 -0
  267. package/src/client/pdf-types.ts +4 -0
  268. package/src/client/pinned.ts +184 -0
  269. package/src/client/plugin-settings.ts +43 -0
  270. package/src/client/plugins-shared.ts +29 -0
  271. package/src/client/plugins-tabs.ts +153 -0
  272. package/src/client/plugins-viewers.ts +44 -0
  273. package/src/client/prefs.ts +216 -0
  274. package/src/client/produced-files.ts +120 -0
  275. package/src/client/selection-payload.ts +86 -0
  276. package/src/client/service.ts +873 -0
  277. package/src/client/session-pins.tsx +334 -0
  278. package/src/client/settings-nav-icon.ts +55 -0
  279. package/src/client/shell-presets.ts +83 -0
  280. package/src/client/sidebar.module.css +3607 -0
  281. package/src/client/split-pane.tsx +333 -0
  282. package/src/client/state.ts +1646 -0
  283. package/src/client/tab-content-memo.ts +55 -0
  284. package/src/client/terminal-font.ts +224 -0
  285. package/src/client/terminal-links.ts +194 -0
  286. package/src/client/theme.ts +110 -0
  287. package/src/client/titlebar-strip.ts +37 -0
  288. package/src/client/ui-tweaks/appicons.ts +24 -0
  289. package/src/client/ui-tweaks/archive.tsx +281 -0
  290. package/src/client/ui-tweaks/branding.tsx +232 -0
  291. package/src/client/ui-tweaks/cachehit.tsx +122 -0
  292. package/src/client/ui-tweaks/gitbar.tsx +2559 -0
  293. package/src/client/ui-tweaks/index.tsx +1696 -0
  294. package/src/client/ui-tweaks/mcp.tsx +582 -0
  295. package/src/client/ui-tweaks/notifier.ts +514 -0
  296. package/src/client/ui-tweaks/whale.tsx +171 -0
  297. package/src/client/upload.ts +187 -0
  298. package/src/client/useChatcodeAccount.ts +103 -0
  299. package/src/client/wco.ts +120 -0
  300. package/src/codingplan.ts +146 -0
  301. package/src/config.ts +207 -0
  302. package/src/context-types.ts +559 -0
  303. package/src/fs-operations.ts +97 -0
  304. package/src/fs-search.ts +113 -0
  305. package/src/fs-tree.ts +158 -0
  306. package/src/git.ts +446 -0
  307. package/src/html-route.ts +106 -0
  308. package/src/index.ts +1524 -0
  309. package/src/invariant.ts +32 -0
  310. package/src/login-route.ts +26 -0
  311. package/src/open-external.ts +90 -0
  312. package/src/path-security.ts +81 -0
  313. package/src/prefs-shared.ts +303 -0
  314. package/src/pty-deps.ts +241 -0
  315. package/src/pty-manager.ts +376 -0
  316. package/src/tools.ts +482 -0
  317. package/src/trust-fence.ts +84 -0
  318. package/src/ui-tweaks/archive.ts +293 -0
  319. package/src/ui-tweaks/config.ts +257 -0
  320. package/src/ui-tweaks/git-web.ts +421 -0
  321. package/src/ui-tweaks/git.ts +1524 -0
  322. package/src/ui-tweaks/index.ts +61 -0
  323. package/src/ui-tweaks/mcp.ts +535 -0
  324. package/src/ui-tweaks/turn-outcome.ts +105 -0
  325. package/src/ui-tweaks/web.ts +225 -0
  326. package/src/wire.ts +110 -0
  327. package/vendor/addon-fit.js +2 -0
  328. package/vendor/xterm.css +218 -0
  329. package/vendor/xterm.js +5 -0
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Raw-HTML block detection for the markdown preview. The shared `MarkdownText`
3
+ * renders raw HTML as literal text (a chat-security stance), so a GitHub-style
4
+ * README (`<div align="center">` badge walls, `<details>` collapsibles with
5
+ * markdown inside, table cells full of inline tags) previews as source soup.
6
+ * This module's pure splitter lifts those HTML runs OUT of the markdown stream
7
+ * before rendering: markdown runs keep flowing through `MarkdownText` (shiki /
8
+ * KaTeX / GFM intact, mermaid chunk path unchanged) while HTML runs render as
9
+ * sanitized DOM (see markdown-html.tsx).
10
+ *
11
+ * Splitting follows CommonMark's shape closely enough for real-world READMEs:
12
+ * a line outside code fences that starts with a block-level tag (type-6 list
13
+ * below) or `<!--` opens an HTML run that extends to the next blank line
14
+ * (comments end at the line containing `-->`). Inline-only tags (`<b>`, `<br>`,
15
+ * `<a>`…) never open a run — they stay in the markdown stream and are handled
16
+ * by the inline pass instead. Unclosed block tags (`<details>` … markdown …
17
+ * `</details>`) are surfaced by {@link analyzeHtmlSegment} as ordered parts so
18
+ * the renderer can nest the in-between markdown inside the open element, the
19
+ * way GitHub's linear HTML output nests.
20
+ */
21
+ /** A run of raw HTML lines lifted out of the markdown stream. */
22
+ export interface HtmlSegment {
23
+ kind: 'html';
24
+ text: string;
25
+ }
26
+ /** A run of markdown source (may contain non-mermaid fences, inline HTML…). */
27
+ export interface MarkdownHtmlSegment {
28
+ kind: 'markdown';
29
+ text: string;
30
+ }
31
+ export type MdHtmlSegment = MarkdownHtmlSegment | HtmlSegment;
32
+ /** The doc-wide analysis the preview consumes (all pure, unit-tested here). */
33
+ export interface AnalyzedMarkdownHtml {
34
+ /** The document split into markdown / html runs (empty input → []). */
35
+ segments: MdHtmlSegment[];
36
+ /** True when at least one html run was lifted out. */
37
+ hasBlockHtml: boolean;
38
+ /** True when the source contains any tag-like text (block OR inline). */
39
+ hasInlineHtml: boolean;
40
+ /** Every reference definition found in the markdown runs (`[label]: dest`
41
+ * lines), joined — appended to each markdown run so `[text][id]` keeps
42
+ * resolving across the lifted HTML runs (first-match wins makes the
43
+ * appended copy inert inside runs that already define it). */
44
+ referenceDefinitions: string;
45
+ }
46
+ /**
47
+ * CommonMark HTML-block type-6 tag names (block-level elements), lowercased.
48
+ * A line starting with one of these (open or close) outside a fence begins an
49
+ * HTML run. `<summary>` is CommonMark-inline but intentionally included: it is
50
+ * the idiomatic first child of a `<details>` run in GitHub-flavored READMEs.
51
+ */
52
+ export declare const HTML_BLOCK_TAGS: ReadonlySet<string>;
53
+ /** One structural piece of a lifted HTML run, in document order. */
54
+ export type HtmlPart = {
55
+ kind: 'html';
56
+ html: string;
57
+ } | {
58
+ kind: 'open';
59
+ tag: string;
60
+ attrs: string;
61
+ } | {
62
+ kind: 'close';
63
+ tag: string;
64
+ };
65
+ /** The run's structure relative to the surrounding document nesting. */
66
+ export interface HtmlSegmentShape {
67
+ parts: HtmlPart[];
68
+ }
69
+ /**
70
+ * Reduce a lifted HTML run to ordered parts: balanced spans become `html`
71
+ * leaves, unclosed open tags become `open` (a wrapper the renderer lowers
72
+ * following markdown runs into), unmatched closes become `close` (pops one
73
+ * wrapper level). A mismatched close pops through the matching open — the
74
+ * HTML parser's implicit-close behavior. Runs with no structural tags reduce
75
+ * to a single `html` part.
76
+ */
77
+ export declare function analyzeHtmlSegment(source: string): HtmlSegmentShape;
78
+ /**
79
+ * Split markdown source into markdown / html runs (fence-aware: an HTML-looking
80
+ * line inside any fenced code block is content, not a run start). Blank lines
81
+ * terminate HTML runs and are dropped between segments (they carry no markdown
82
+ * semantics the preview needs); everything else stays byte-identical.
83
+ */
84
+ export declare function splitHtmlBlocks(text: string): MdHtmlSegment[];
85
+ /**
86
+ * Collect the reference definitions of every markdown run (HTML runs cannot
87
+ * define them), in document order, newline-joined for appending.
88
+ */
89
+ export declare function collectReferenceDefinitions(segments: readonly MdHtmlSegment[]): string;
90
+ /**
91
+ * The whole-document gate + split the preview consumes. `hasInlineHtml` is a
92
+ * cheap source-level regex (code-fence content may false-positive; the inline
93
+ * pass skips rendered code blocks anyway, so a false positive only costs the
94
+ * enhanced render path, never a behavior change).
95
+ */
96
+ export declare function analyzeMarkdownHtml(text: string): AnalyzedMarkdownHtml;
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Markdown-preview local-image resolution. The shared `MarkdownText` (from
3
+ * @deepseek-ai/dsh-client-ui-primitives) only renders absolute http(s) image
4
+ * URLs — relative links are disabled for chat security — so a local image in
5
+ * a previewed `.md` (`![alt](./img.png)`, an absolute `/cwd/img.png`, or a
6
+ * reference definition) would otherwise fall back to its alt text. This
7
+ * dependency-free helper rewrites those destinations into absolute
8
+ * `/sidebar/file` media URLs (prefixed with the GUI's own origin) so
9
+ * `MarkdownText` accepts them; the host media route then serves the bytes,
10
+ * still restricted to files under the session cwd.
11
+ */
12
+ import type { SessionScope } from './api.ts';
13
+ /**
14
+ * Rewrite markdown image destinations that point at local files into
15
+ * absolute `/sidebar/file` media URLs. Relative destinations resolve against
16
+ * the opened file's directory (normalizing `.`/`..` segments); absolute
17
+ * local paths pass through. Remote (http/https/data/mailto) and `#`-anchor
18
+ * destinations are left untouched for `MarkdownText`. Reference-style images
19
+ * (`![x][id]` + `[id]: url`) are covered by rewriting their definition lines.
20
+ *
21
+ * Code spans (`` `...` ``) and fenced code blocks (``` ```...``` ```) are
22
+ * masked before rewriting so documentation that demonstrates `![alt](./img.png)`
23
+ * is not mutated into a `/sidebar/file` URL. Reference definitions are only
24
+ * rewritten when their label is actually referenced by an image (collapsed
25
+ * `[![][id]]`, full `![alt][id]`, or shortcut `![]` referencing the next
26
+ * definition) — a plain link `[text][id]` must not have its destination
27
+ * redirected to the media route.
28
+ * @param text - The raw markdown source (inline + reference images).
29
+ * @param scope - The session scope (sessionId + cwd) for the media route.
30
+ * @param filePath - The absolute path of the opened `.md` file.
31
+ * @param origin - The GUI's own origin (`window.location.origin`); injected
32
+ * so the core rewrite stays pure and unit-testable.
33
+ * @returns The markdown with local image destinations rewritten in place.
34
+ */
35
+ /**
36
+ * Resolve one media destination against the session's media route: local
37
+ * (relative or absolute) paths become absolute `/sidebar/file` URLs (prefixed
38
+ * with the GUI's own origin so the shared MarkdownText http(s) allowlist
39
+ * accepts them), while remote URLs, `#`-anchors and empty destinations are
40
+ * returned untouched. Shared by the markdown image rewriter below and by the
41
+ * preview's raw-HTML sanitizer (`markdown-html.tsx`, which meets the same
42
+ * allowlist when rendering `<img src="./x.png">` inside HTML blocks).
43
+ */
44
+ export declare function resolveLocalMediaDest(dest: string, scope: SessionScope, filePath: string, origin: string): string;
45
+ export declare function rewriteLocalImageUrls(text: string, scope: SessionScope, filePath: string, origin: string): string;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Copy-button / chrome labels for DSH's shared `MarkdownText` (DSH
3
+ * 0.1.2-alpha contract): the renderer takes a REQUIRED nested `labels` prop
4
+ * — `labels.code.copyLabel` / `labels.code.copiedLabel` for the fence copy
5
+ * buttons plus a screen-reader-only `labels.footnotes` heading — and the
6
+ * MarkdownText/CodeBlock are cordis-free, falling back to HARDCODED Chinese
7
+ * when the labels are omitted, so every render site threads the plugin
8
+ * dictionary's localized pair through here (re-evaluated per render).
9
+ * `footnotes` is left empty (the heading is sr-only; give it a real string
10
+ * only if a locale key ever earns its place in all 19 dictionaries).
11
+ */
12
+ import type { ComponentProps } from 'react';
13
+ import { MarkdownText } from '@deepseek-ai/dsh-client-ui-primitives';
14
+ /** The flat copy-button pair the plugin threads through its own props (e.g.
15
+ * MermaidMarkdownProps.codeLabels — the chunk contract stays put). */
16
+ export interface MarkdownCopyLabels {
17
+ copyLabel: string;
18
+ copiedLabel: string;
19
+ }
20
+ /** MarkdownText props carrying the nested chrome labels. */
21
+ export declare function markdownTextProps(text: string, labels: MarkdownCopyLabels): ComponentProps<typeof MarkdownText>;
@@ -0,0 +1,4 @@
1
+ import type { ReactNode } from 'react';
2
+ /** Fewer headings than this and the button stays hidden (no outline value). */
3
+ export declare const TOC_MIN_HEADINGS = 3;
4
+ export declare function MdToc(): ReactNode;
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Markdown/mermaid fence detection for the markdown preview. The preview
3
+ * renders the WHOLE document through one DSH `MarkdownText` pass (so
4
+ * cross-fence semantics — reference-style links, footnotes, list
5
+ * continuity — stay intact) and the mermaid lazy chunk then swaps the
6
+ * rendered `language-mermaid` code blocks for diagrams. This module's pure
7
+ * splitter exists to detect whether the source contains a mermaid fence at
8
+ * all, so the mermaid chunk is only fetched when needed (unit-tested in
9
+ * tests/mermaid-blocks.spec.ts).
10
+ */
11
+ /** One fenced mermaid diagram lifted out of the markdown source. */
12
+ export interface MermaidBlock {
13
+ kind: 'mermaid';
14
+ /** The raw diagram source between the fences (info string stripped). */
15
+ code: string;
16
+ }
17
+ /** A span of plain markdown source (may itself contain non-mermaid fences). */
18
+ export interface MarkdownBlock {
19
+ kind: 'markdown';
20
+ text: string;
21
+ }
22
+ export type MdBlock = MarkdownBlock | MermaidBlock;
23
+ /** Props of the chunk-resident `MermaidMarkdown` component (shared contract). */
24
+ export interface MermaidMarkdownProps {
25
+ /** The full markdown source (rendered in a single MarkdownText pass). */
26
+ text: string;
27
+ codeLabels: {
28
+ copyLabel: string;
29
+ copiedLabel: string;
30
+ };
31
+ }
32
+ /** CommonMark opening fence: 0-3 spaces indent + a run of 3+ backticks or tildes. */
33
+ export declare const OPEN_FENCE_RE: RegExp;
34
+ /** A closing-fence line: 0-3 spaces indent + 3+ backticks/tildes + trailing spaces only. */
35
+ export declare const CLOSE_FENCE_RE: RegExp;
36
+ /** Parse the info string from the line tail after the fence run; null when invalid. */
37
+ export declare function fenceInfo(rest: string, fence: string): string | null;
38
+ /**
39
+ * Split markdown source into md/mermaid blocks for detection: only fences
40
+ * whose info string names mermaid are lifted; every other line stays in the
41
+ * markdown stream untouched. CommonMark fence rules are honored — opening
42
+ * fences of 3+ backticks OR tildes, and a closing fence must use the same
43
+ * character with at least as many characters as the opening fence. An
44
+ * unterminated mermaid fence swallows the rest of the file (the same
45
+ * recovery CommonMark applies to open fences).
46
+ */
47
+ export declare function splitMermaidBlocks(text: string): MdBlock[];
@@ -0,0 +1,2 @@
1
+ /** A parse failure keeps nothing of the input: the caller shows the error. */
2
+ export declare function sanitizeSvg(svg: string): string;
@@ -0,0 +1,12 @@
1
+ import type { MermaidMarkdownProps } from './mermaid-blocks.ts';
2
+ /**
3
+ * The chunk-resident markdown preview renderer: ONE MarkdownText pass over
4
+ * the full source (cross-fence reference/footnote/list semantics intact),
5
+ * then every rendered `language-mermaid` code block is swapped for a
6
+ * `MermaidDiagram`. The `.md-code-block` host stays in the React tree —
7
+ * only its children are replaced — so reconciliation never loses the host;
8
+ * a block that stops being a mermaid fence gets its original children back.
9
+ * Only mounted when the source contains at least one mermaid fence (see
10
+ * TextEditor.tsx).
11
+ */
12
+ export declare function MermaidMarkdown({ text, codeLabels }: MermaidMarkdownProps): React.ReactNode;
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Deferred one-shot open for hosts that may not have a real size yet.
3
+ *
4
+ * xterm's `Terminal.open()` must not run in a zero-size container: the
5
+ * renderer creation fails there (the DomRenderer is built from the host's
6
+ * dimensions), leaving the render service's renderer `undefined`, and the
7
+ * next Viewport refresh crashes reading `.dimensions` off it. WebKit-based
8
+ * hosts (WKWebView) reliably report zero while the bottom panel's expand
9
+ * slide is in flight; any `display:none`-hidden ancestor does the same.
10
+ *
11
+ * The caller's `open` callback (open + fit + resize) is invoked exactly
12
+ * once, on the first frame where the host reports a real size. While the
13
+ * host stays zero-sized the polling continues every frame; it stops when
14
+ * the host leaves the document (`isConnected`), so a pending open never
15
+ * fires after unmount. The returned cancel function drops a pending frame
16
+ * immediately (idempotent).
17
+ *
18
+ * `raf`/`caf` are injectable so tests can drive the polling deterministically.
19
+ */
20
+ export declare function openWhenSized(host: HTMLElement, open: () => void, raf?: (cb: FrameRequestCallback) => number, caf?: (id: number) => void): () => void;
@@ -0,0 +1,4 @@
1
+ export declare function OpenWithSettings(props: {
2
+ pluginSettings: Record<string, unknown>;
3
+ updatePluginSetting: (key: string, value: unknown) => void;
4
+ }): import("react").JSX.Element;
@@ -0,0 +1,87 @@
1
+ /**
2
+ * The file tree's "open with" vocabulary: which external editors / file
3
+ * managers the context menu can hand a row's path to, how the per-user
4
+ * configuration (custom editors, SSH host, pinned ids) is parsed out of the
5
+ * persisted blob, and how the external URL is built (local `file` URLs and
6
+ * VSCode-family SSH-remote URLs).
7
+ *
8
+ * Pure by design (no React / no `api`), so the whole surface is unit-testable
9
+ * without a DOM or a host route. The menu and the settings panel only consume
10
+ * the exported types and functions.
11
+ */
12
+ import type { CopyKey } from './locales.ts';
13
+ /** One user-configured editor (persisted in `pluginSettings['editor'].openWith`). */
14
+ export interface CustomEditor {
15
+ id: string;
16
+ /** Human label shown in the menu (e.g. "Windsurf"). */
17
+ name: string;
18
+ /** URL template with a `{path}` placeholder (e.g. `cursor://file/{path}`). */
19
+ urlTemplate: string;
20
+ /** Whether the editor speaks the VSCode URL dialect — the only editors
21
+ * with an SSH-remote form (`<scheme>://vscode-remote/ssh-remote+<host>/…`). */
22
+ isVscodeFamily: boolean;
23
+ }
24
+ /** The per-user "open with" configuration (one key of the editor blob). */
25
+ export interface OpenWithConfig {
26
+ /** SSH host (user@host or an ~/.ssh/config alias); '' = local workspace. */
27
+ sshHost: string;
28
+ /** User-defined editors, appended after the built-ins. */
29
+ customEditors: CustomEditor[];
30
+ /** Ids of open-with targets pinned to the menu's top level
31
+ * ('explorer' | 'vscode' | 'cursor' | 'zed' | 'custom:<id>'). */
32
+ pinned: string[];
33
+ }
34
+ /** One menu-visible open target (built-in or custom, SSH-filtered). */
35
+ export interface OpenWithTarget {
36
+ /** Stable id (`explorer` / `vscode` / `cursor` / `zed` / `custom:<id>`). */
37
+ id: string;
38
+ /** Locale key of a built-in label (custom editors carry `name` instead). */
39
+ nameKey?: CopyKey;
40
+ /** User-defined label (custom editors only; '' for built-ins). */
41
+ name: string;
42
+ /** 'reveal' = show in the OS file manager; 'url' = open a URL. */
43
+ kind: 'reveal' | 'url';
44
+ /** URL template with `{path}`; undefined for reveal targets. */
45
+ urlTemplate?: string;
46
+ /** Whether the editor talks the VSCode URL dialect. */
47
+ isVscodeFamily: boolean;
48
+ /** Hidden in SSH mode (a host-local opener cannot reach a remote path). */
49
+ localOnly: boolean;
50
+ }
51
+ /** The default open-with configuration (fresh documents). */
52
+ export declare const OPEN_WITH_DEFAULTS: OpenWithConfig;
53
+ /** The built-in open targets, in menu order. */
54
+ export declare const OPEN_WITH_BUILTINS: readonly OpenWithTarget[];
55
+ /**
56
+ * Parse the persisted `openWith` blob (tolerant): malformed fields fall back
57
+ * to the defaults, malformed custom-editor rows are dropped, and pinned ids
58
+ * are kept verbatim (unknown ids are pruned when the targets are resolved —
59
+ * the menu is the only consumer of the resolved list).
60
+ */
61
+ export declare function parseOpenWithConfig(raw: unknown): OpenWithConfig;
62
+ /**
63
+ * The menu-visible open targets, in order (built-ins then custom editors).
64
+ * In SSH mode the local-only targets (the OS file manager, Zed, custom
65
+ * editors without the VSCode dialect) are dropped — they cannot reach a
66
+ * remote path. Unknown pinned ids are pruned here too.
67
+ */
68
+ export declare function resolveOpenWithTargets(config: OpenWithConfig): OpenWithTarget[];
69
+ /** The SSH hint appended to a target's label in remote mode. */
70
+ export declare function openWithSshActive(config: OpenWithConfig): boolean;
71
+ /**
72
+ * The URL to open for one resolved target, or undefined when the target has
73
+ * no URL form (reveal) or the template is malformed. The path is inserted
74
+ * RAW into the template (browsers percent-encode as needed; VSCode-family
75
+ * URL parsers consume the absolute path with its leading slash, e.g.
76
+ * `vscode://file//home/u/f.ts` or `vscode://file/C:/Users/u/f.ts`).
77
+ */
78
+ export declare function openWithUrl(target: OpenWithTarget, path: string, config: OpenWithConfig): string | undefined;
79
+ /** Normalize a filesystem path for embedding in a URL (backslashes → '/'). */
80
+ export declare function normalizeUrlPath(path: string): string;
81
+ /** A fresh custom-editor id (uuid when available, time-based fallback). */
82
+ export declare function newCustomEditorId(): string;
83
+ /** Validate one custom-editor row before the settings panel accepts it. */
84
+ export declare function isValidCustomEditor(row: {
85
+ name: string;
86
+ urlTemplate: string;
87
+ }): boolean;
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Interception of the chat's file-open funnel. The client runtime's
3
+ * `ctx.workspaces.openPath` is the SINGLE door every chat-side file open goes
4
+ * through — ui-conversation's apply.ts resolves the path against the session
5
+ * cwd and calls it for tool-row path links, the produced-files row, and
6
+ * prose file mentions alike (verified against the DSH source:
7
+ * `packages/client/ui-conversation/src/client/apply.ts` is the only
8
+ * production caller). Wrapping that one method reroutes those opens into the
9
+ * sidebar editor instead of the Host OS — no DSH modification needed.
10
+ *
11
+ * The wrapper is dependency-free by design (no React / ui-primitives), so
12
+ * the takeover logic is unit-testable and the file stays importable from the
13
+ * test runtime.
14
+ */
15
+ /** The one service method the wrapper replaces (mirror of the runtime IWorkspaces). */
16
+ export interface OpenPathService {
17
+ openPath(path: string): Promise<void>;
18
+ }
19
+ /** Per-call decisions the wrapper needs (wired to the store + ctx in the client half). */
20
+ export interface OpenPathInterceptDeps {
21
+ /**
22
+ * Whether to take over this call: the `interceptOpenPath` pref AND the
23
+ * editor tab's own enable switch must both be on (an editor that cannot
24
+ * open must not swallow opens — they fall through to the Host).
25
+ */
26
+ takeoverEnabled(): boolean;
27
+ /** The session whose scope the sidebar editor loads the file in (current session). */
28
+ currentSessionId(): string | undefined;
29
+ /** Route the open into the sidebar editor (the established openSidebarFile). */
30
+ openInSidebar(path: string, sessionId: string): void;
31
+ /** Route a folder-reveal gesture ("Show in folder" passes '.') into the sidebar explorer. */
32
+ revealInExplorer(path: string, sessionId: string): void;
33
+ }
34
+ /**
35
+ * Whether a path is the "Show in folder" folder-reveal gesture. The stock
36
+ * ui-deliverables row passes `'.'` (the session workspace root, resolved by
37
+ * the chat view to `"<cwd>/."`); any path whose final segment is `.` is the
38
+ * same gesture. A directory has no editor content, so these opens must reach
39
+ * the explorer instead of an editor tab.
40
+ */
41
+ export declare function isFolderRevealPath(path: string): boolean;
42
+ /**
43
+ * Wrap `workspaces.openPath`: intercepted calls open the file in the sidebar
44
+ * editor instead of the Host OS and resolve as success (the original's
45
+ * callers ignore the result); anything that declines falls through to the
46
+ * original method untouched. The one exception is the folder-reveal gesture,
47
+ * which is routed to {@link OpenPathInterceptDeps.revealInExplorer} instead.
48
+ * @param workspaces - the client workspaces service to wrap.
49
+ * @param deps - per-call takeover decisions.
50
+ * @returns the disposer restoring the original method (HMR-safe).
51
+ */
52
+ export declare function wrapOpenPath(workspaces: OpenPathService, deps: OpenPathInterceptDeps): () => void;
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Path projection helpers shared by the explorer rows: a path relative to
3
+ * the session cwd (for the @-reference button and "copy relative path").
4
+ * The fs-tree joins with '/' even on Windows, so both separators normalize
5
+ * to '/' before comparison.
6
+ *
7
+ * This module is dependency-free (no node:path in the client bundle): the
8
+ * host is the authority for path semantics, so this mirror deliberately
9
+ * accepts a SUPERSET of absolute forms — anything a Windows host would emit
10
+ * (drive letters, UNC) plus POSIX roots. A form the host would reject
11
+ * (e.g. a backslash UNC path on a POSIX host) passes through here and then
12
+ * fails loudly in the host's requireAbsolute instead of being silently
13
+ * joined onto the cwd.
14
+ */
15
+ /**
16
+ * Mirror of the host's absolute-path notion (see fs-tree.requireAbsolute):
17
+ * POSIX roots, Windows drive letters, and Windows UNC network shares in
18
+ * both backslash (`\\server\share\...`) and forward-slash
19
+ * (`//server/share/...`) form. Deliberately a superset — see the module
20
+ * comment — so a produced UNC path is never joined onto the cwd.
21
+ */
22
+ export declare function isAbsolutePath(path: string): boolean;
23
+ /**
24
+ * The path relative to the session's working directory.
25
+ * @param cwd - the explorer root (absolute).
26
+ * @param path - an absolute entry path from the fs-tree.
27
+ * @returns the relative path with '/' separators ('.' for the cwd itself),
28
+ * or `path` unchanged when it lies outside the cwd.
29
+ *
30
+ * The prefix test is case-insensitive: Windows paths (and macOS's
31
+ * case-insensitive volumes) may arrive with different casing than the cwd
32
+ * row, and the containment decision must not depend on it. The returned
33
+ * relative text keeps the caller's own casing.
34
+ */
35
+ export declare function relativeTo(cwd: string, path: string): string;
36
+ /**
37
+ * Whether `target` lies under `base` (or equals it), tolerant of separator
38
+ * style and — on Windows-style drive paths — of letter case. A client-side
39
+ * mirror of the host's `isWithin` (fs-tree.ts) used to decide whether a
40
+ * git-derived path can be opened in the editor (a linked worktree outside
41
+ * the session workspace cannot: the host's workspace fence would reject it).
42
+ */
43
+ export declare function isWithinWorkspace(base: string, target: string): boolean;
@@ -0,0 +1,2 @@
1
+ /** Pure PDF extension dispatch, separate from React for unit testing. */
2
+ export declare function isPdfExt(ext: string): boolean;
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Cross-session pinned-terminal resolution (v0.17.0+).
3
+ *
4
+ * A pinned terminal tab lives in its HOME session's state (the only
5
+ * authoritative copy) — switching sessions never copies or projects it.
6
+ * The viewer session's TabBar renders the tabs OTHER sessions have pinned
7
+ * as VIRTUAL tabs appended to the first leaf's tab list, so the user sees
8
+ * them inline with their own tabs. Clicking a virtual tab activates it
9
+ * in-place: TerminalView connects to the home session's PTY via WebSocket
10
+ * (sessionId + tab query params resolve to the home PTY on the host side),
11
+ * so the terminal renders in the current workbench without jumping sessions.
12
+ *
13
+ * Visibility rule:
14
+ *
15
+ * | pin.scope | visible when |
16
+ * |-----------|--------------|
17
+ * | `global` | any session (cwd-independent) |
18
+ * | `workspace` | `viewer.cwd === tab.pin.homeCwd` (both undefined match; viewer.cwd unknown → conservative visible) |
19
+ *
20
+ * The "viewer.cwd unknown → visible" branch is intentional: during
21
+ * hydration the session summary may carry no cwd yet, and hiding pinned
22
+ * workspace tabs on first paint would flash them away. Once the cwd
23
+ * resolves, the next store notify re-runs the resolver with the real cwd.
24
+ *
25
+ * The viewer's OWN session is excluded: its pinned tabs are already on its
26
+ * own tab strip, so rendering them again as virtual tabs would double-show.
27
+ * Tabs whose `pin` field is missing or whose `type` is not `'terminal'` are
28
+ * ignored — only terminal tabs can be pinned.
29
+ */
30
+ import type { SidebarState, SidebarTab, SplitNode } from './state.ts';
31
+ /** A pinned terminal surfaced to the viewer, paired with its home session. */
32
+ export interface PinnedTabEntry {
33
+ tab: SidebarTab;
34
+ homeSessionId: string;
35
+ }
36
+ /** A viewer's session identity for visibility resolution. */
37
+ export interface PinnedViewer {
38
+ sessionId: string;
39
+ cwd: string | undefined;
40
+ }
41
+ /** The home-session scope stored on a pinned virtual tab's meta, so
42
+ * TerminalView connects to the home session's PTY (not the viewer's). */
43
+ export interface PinnedHomeScope {
44
+ sessionId: string;
45
+ cwd: string | undefined;
46
+ /** The original tab id in the home session (TerminalView's `tab` param). */
47
+ tabId: string;
48
+ }
49
+ /** Whether a tab id is a pinned virtual id (prefixed). */
50
+ export declare function isPinnedVirtualId(tabId: string): boolean;
51
+ /** Parse a pinned virtual id into its home session id and original tab id.
52
+ * Format: `pinned:<homeSessionId>:<originalTabId>` — session ids are UUIDs
53
+ * (no colons), so the first colon after the prefix delimits the session. */
54
+ export declare function parsePinnedVirtualId(tabId: string): {
55
+ homeSessionId: string;
56
+ tabId: string;
57
+ };
58
+ /** Extract the home scope from a pinned virtual tab's meta (undefined for
59
+ * regular tabs). */
60
+ export declare function getPinnedHomeScope(tab: SidebarTab): PinnedHomeScope | undefined;
61
+ /** Whether a tab is a pinned virtual tab (injected from another session). */
62
+ export declare function isPinnedVirtualTab(tab: SidebarTab): boolean;
63
+ /** Create a virtual SidebarTab for a pinned entry. The virtual id is unique
64
+ * (prefixed with home session) to avoid collision with the viewer's own
65
+ * tab ids; the original id is stored in meta for TerminalView. */
66
+ export declare function createPinnedVirtualTab(entry: PinnedTabEntry): SidebarTab;
67
+ /** Inject pinned virtual tabs into the first leaf of a split tree, and
68
+ * override that leaf's `active` when a pinned tab is activated. Returns
69
+ * the original tree when there are no pinned tabs and no active override. */
70
+ export declare function injectPinnedIntoTree(tree: SplitNode, pinned: readonly SidebarTab[], activePinnedId: string | null): SplitNode;
71
+ /**
72
+ * Whether a pinned tab is visible to the viewer session. Conservative on
73
+ * unknown cwd: a `workspace` pin with no `homeCwd` is visible everywhere
74
+ * (the pin was set before the home session's cwd resolved), and a viewer
75
+ * whose cwd is unknown sees every workspace pin (avoids hydration flash).
76
+ */
77
+ export declare function pinnedVisibleTo(tab: SidebarTab, viewer: PinnedViewer): boolean;
78
+ /**
79
+ * Collect every pinned terminal visible to the viewer across ALL cached
80
+ * session states. Excludes the viewer's own session (those tabs are on its
81
+ * own strip). Order is stable: sessions in the cache's insertion order,
82
+ * tabs in tree order (splits → bottomSplits → floats) within each session
83
+ * — the order tabs were opened/pinned, so the rail never reorders between
84
+ * renders.
85
+ */
86
+ export declare function collectPinnedTabs(bySession: ReadonlyMap<string, SidebarState>, viewer: PinnedViewer): PinnedTabEntry[];
@@ -0,0 +1,8 @@
1
+ import type { SidebarStore } from './state.ts';
2
+ /**
3
+ * Merge one plugin-owned settings blob of one descriptor and persist it.
4
+ * @param store - the sidebar store (its prefs are replaced by the write result).
5
+ * @param descriptorId - the descriptor whose blob is patched ('editor' here).
6
+ * @param updater - pure patch function; receives a shallow copy of the blob.
7
+ */
8
+ export declare function updatePluginSettings(store: SidebarStore, descriptorId: string, updater: (blob: Record<string, unknown>) => Record<string, unknown>): void;
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Shared vocabulary of the recommended plugin catalogs: the entry shape and
3
+ * the GitHub topic URL. The two catalogs live in sibling modules —
4
+ * `plugins-tabs.ts` (tab registrations) and `plugins-viewers.ts` (file
5
+ * previewer registrations) — and are shown in the two "add plugin" modals
6
+ * (Side card settings → the dashed cards at the end of the 侧边栏内容 /
7
+ * 文件预览 grids).
8
+ */
9
+ /** The GitHub topic page listing every repo tagged `dsh-better-sidebar`. */
10
+ export declare const PLUGIN_TOPIC_URL = "https://github.com/topics/dsh-better-sidebar";
11
+ /** One curated plugin entry (name / url / description / install script). */
12
+ export interface PluginEntry {
13
+ /** Unique id (the npm package name). */
14
+ id: string;
15
+ /** Short display name. */
16
+ name: string;
17
+ /** GitHub repository URL. */
18
+ url: string;
19
+ /** One-line description (i18n friendly: string or () => string). */
20
+ description: string | (() => string);
21
+ /** Optional catalog group heading (i18n friendly); entries without one
22
+ * render under the plain list (a flat catalog stays flat). */
23
+ category?: string | (() => string);
24
+ /** The full shell command pre-filled into the install terminal (not
25
+ * executed until the user presses Enter). */
26
+ install: string;
27
+ }
@@ -0,0 +1,3 @@
1
+ import type { PluginEntry } from './plugins-shared.ts';
2
+ /** Tab-registration plugins (alphabetical order). */
3
+ export declare const builtinTabPlugins: readonly PluginEntry[];
@@ -0,0 +1,3 @@
1
+ import type { PluginEntry } from './plugins-shared.ts';
2
+ /** File-previewer plugins (alphabetical order). */
3
+ export declare const builtinViewerPlugins: readonly PluginEntry[];
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Client-side read of the user-facing "Side card" preferences. The host owns
3
+ * the namespace through the settings seam (in-process); the DSH settings RPC
4
+ * domain only serves allowlisted namespaces to configuration clients, so the
5
+ * client reads and writes THIS namespace through the plugin's own fenced
6
+ * /sidebar routes instead (api.settingsGet/settingsUpdate). Any failure
7
+ * (route rejected, namespace absent, a field of the wrong type, a value out
8
+ * of the contract range) falls back to the schema defaults — the side card
9
+ * must keep working exactly as composed when the settings surface is missing.
10
+ */
11
+ import type { api } from './api.ts';
12
+ import { clampTerminalFontSize, clampTitleBarStrip, clampWidthPercent, SIDEBAR_PREFS_DEFAULTS, TITLE_BAR_SCHEMES, TITLE_BAR_STRIP_DEFAULT, type SidebarPrefs, type TitleBarScheme } from '../prefs-shared.ts';
13
+ export { SIDEBAR_PREFS_DEFAULTS, TITLE_BAR_SCHEMES, TITLE_BAR_STRIP_DEFAULT, clampTerminalFontSize, clampTitleBarStrip, clampWidthPercent, };
14
+ export type { SidebarPrefs, TitleBarScheme };
15
+ /** The settings wire face the preferences need (a subset of the plugin api). */
16
+ export type SidebarSettingsClient = Pick<typeof api, 'settingsGet' | 'settingsUpdate'>;
17
+ /** Validate one raw resolved value into {@link SidebarPrefs}. Used for the
18
+ * settings.get payload AND the settings.update response (both carry the
19
+ * layered resolved value); any malformed field falls back to its default.
20
+ * @param value - the raw resolved section from the settings wire.
21
+ * @returns validated prefs (always well-formed).
22
+ */
23
+ export declare function parsePrefs(value: unknown): SidebarPrefs;
24
+ /**
25
+ * Read the resolved side card preferences through the plugin's settings route.
26
+ * @param settings - the settings wire face (the plugin api by default).
27
+ * @returns validated prefs, or the schema defaults when the route rejects,
28
+ * the namespace is absent, or a stored value violates the contract.
29
+ */
30
+ export declare function loadPrefs(settings: SidebarSettingsClient): Promise<SidebarPrefs>;
31
+ /**
32
+ * Read the external-disable flag from the same settings route: the
33
+ * dsh-web-ui family's aionui-panel provider choice. True only when the host
34
+ * resolved `aionui-panel.rightPanel` to 'aionui-panel' — while true the
35
+ * sidebar must not mount (the two right panels are mutually exclusive). Any
36
+ * failure (route rejected, aionui absent, malformed response) reads false,
37
+ * so a missing family never hides the sidebar.
38
+ * @param settings - the settings wire face (the plugin api by default).
39
+ * @returns the external-disable flag (false on any failure).
40
+ */
41
+ export declare function loadExternalDisable(settings: SidebarSettingsClient): Promise<boolean>;