@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,279 @@
1
+ /**
2
+ * dsh-ui-tweaks — browser half.
3
+ *
4
+ * Reads and writes the `ui-tweaks` settings namespace through the same-origin
5
+ * route served by the server half, applies the chosen font size / table style
6
+ * live via a runtime `<style>` element, and renders the Settings
7
+ * panel section that edits them.
8
+ */
9
+ import type { ISessions } from '@deepseek-ai/dsh-api-session-controller/client';
10
+ import type { Context as ClientContext } from '../../context-types.ts';
11
+ /** Client context narrowed to the browser sessions face in this combined build. */
12
+ type UITweaksClientContext = ClientContext & {
13
+ sessions: ISessions;
14
+ };
15
+ interface TweaksValue {
16
+ fontSize?: number;
17
+ /** Code font size as a percentage of the message font size (81 = stock). Legacy input. */
18
+ codeFontScale?: number;
19
+ /** Absolute code font size in px; wins over the legacy percentage. */
20
+ codeFontSize?: number;
21
+ /** 行高 base unit in px; scales message/block gaps, line-height and list/paragraph margins. */
22
+ lineHeight?: number;
23
+ tableStyle?: 'default' | 'claude';
24
+ /** Whether the GitBar (branch / diff / commit pills) is shown. */
25
+ gitBarEnabled?: boolean;
26
+ /** Whether the Archive manager (sidebar entry above Settings) is shown. */
27
+ archiveManagerEnabled?: boolean;
28
+ /** Whether the MCP manager (Settings page listing MCP servers) is shown. */
29
+ mcpManagerEnabled?: boolean;
30
+ /** Whether the /init slash command (AGENTS.md bootstrap prompt) is registered. */
31
+ initCommandEnabled?: boolean;
32
+ /** Whether the whale working indicator above the input is shown. */
33
+ whaleIndicatorEnabled?: boolean;
34
+ /** Whether the stats-line cache-hit figure keeps two decimals. Keep in sync with src/config.ts. */
35
+ preciseCacheHitEnabled?: boolean;
36
+ /** Whether task notifications are active. Keep in sync with src/config.ts. */
37
+ notificationsEnabled?: boolean;
38
+ /** Alert only while the tab is hidden or unfocused. */
39
+ notifyOnlyWhenHidden?: boolean;
40
+ /** Alert when a session completes its turn. */
41
+ notifyOnComplete?: boolean;
42
+ /** Alert when a session blocks on an approval, plan review or question. */
43
+ notifyOnInteraction?: boolean;
44
+ /** Blink an unread counter into the tab title. */
45
+ notifyTitleFlash?: boolean;
46
+ /** Fire desktop-level Web Notifications. */
47
+ notifySystemNotification?: boolean;
48
+ /** Play the synthesized two-note chime. */
49
+ notifySound?: boolean;
50
+ }
51
+ declare const en: {
52
+ readonly nav: "UI Tweaks";
53
+ readonly settingsTitle: "UI Tweaks";
54
+ readonly settingsIntro: "Tune the conversation UI — text, tables and layout, plus optional features: git bar, archive & MCP managers and the /init command. Changes apply live.";
55
+ readonly sectionText: "Text & tables";
56
+ readonly sectionLayout: "Layout";
57
+ readonly sectionFeatures: "Features";
58
+ readonly fontSize: "Message font size";
59
+ readonly fontSizeHint: "Number between 10 and 32; applies to message text, headings, tables and code.";
60
+ readonly codeFontSize: "Code font size";
61
+ readonly codeFontSizeHint: "Absolute code size in px (8–32); 13px is ChatCode CLI's default at a 16px body. Applies to code blocks; inline code follows proportionally.";
62
+ readonly lineHeight: "Line spacing";
63
+ readonly lineHeightHint: "Base vertical spacing in px: gaps between message rows (Think ↔ tool cards) and blocks inside one reply, plus text line-height, paragraph and list margins, all scale from it; 16 is ChatCode CLI's default.";
64
+ readonly tableStyle: "Table style";
65
+ readonly tableStyleHint: "Cell look for markdown tables: stock borders, or the Claude Desktop card style.";
66
+ readonly tableStyleDefault: "Default";
67
+ readonly tableStyleClaude: "Claude Desktop";
68
+ readonly gitBar: "Git bar";
69
+ readonly gitBarHint: "Branch / diff pills above the input inside git repos, with branch management and commit & push; auto-hidden outside git.";
70
+ readonly gitBarOn: "On";
71
+ readonly gitBarOff: "Off";
72
+ readonly archiveManager: "Archive manager";
73
+ readonly archiveManagerHint: "An Archive settings page to restore or permanently delete archived sessions.";
74
+ readonly archiveManagerOn: "On";
75
+ readonly archiveManagerOff: "Off";
76
+ readonly mcpManager: "MCP manager";
77
+ readonly mcpManagerHint: "An MCP settings page listing servers with status and tools; edit and restart them.";
78
+ readonly mcpManagerOn: "On";
79
+ readonly mcpManagerOff: "Off";
80
+ readonly mcpNav: "MCP";
81
+ readonly mcpTitle: "MCP servers";
82
+ readonly mcpEmpty: "No MCP servers configured.";
83
+ readonly mcpStatusActive: "Running";
84
+ readonly mcpStatusFailed: "Failed";
85
+ readonly mcpStatusLoading: "Loading";
86
+ readonly mcpStatusStopped: "Stopped";
87
+ readonly mcpStatusDisabled: "Disabled";
88
+ readonly mcpTools: "tools";
89
+ readonly mcpEnv: "Env";
90
+ readonly mcpAdd: "Add server";
91
+ readonly mcpAddTitle: "Add MCP server";
92
+ readonly mcpEditTitle: "Edit MCP server";
93
+ readonly mcpEdit: "Edit";
94
+ readonly mcpDelete: "Delete";
95
+ readonly mcpEnabledAction: "Enable";
96
+ readonly mcpDisabledAction: "Disable";
97
+ readonly mcpSaved: "Saved.";
98
+ readonly mcpRemoved: "Removed.";
99
+ readonly mcpFormTab: "Form";
100
+ readonly mcpYamlTab: "YAML";
101
+ readonly mcpYamlHint: "Fill in the MCP config directly (serverName / transport / command / args / env / toolCallTimeoutMs / url / headers …). It is validated before saving.";
102
+ readonly mcpYamlPlaceholder: "serverName: my-server\ntransport: stdio\ncommand: npx\nargs:\n - \"-y\"\n - \"@some/mcp-server\"\nenv:\n KEY: value\ntoolCallTimeoutMs: 60000";
103
+ readonly mcpFieldId: "Instance ID";
104
+ readonly mcpFieldIdHint: "Loader entry id (letters, digits, - and _ only); it must be unique.";
105
+ readonly mcpFieldName: "Name";
106
+ readonly mcpFieldNameHint: "Tool namespace `mcp__<name>__*`; letters, digits, - and _ (1–32).";
107
+ readonly mcpFieldType: "Type";
108
+ readonly mcpFieldTimeout: "Timeout (ms)";
109
+ readonly mcpFieldCommand: "Command";
110
+ readonly mcpFieldCommandPlaceholder: "e.g. npx";
111
+ readonly mcpFieldArgs: "Arguments (one per line)";
112
+ readonly mcpFieldEnv: "Environment vars (optional, KEY=value per line)";
113
+ readonly mcpFieldUrl: "URL";
114
+ readonly mcpFieldHeaders: "Headers (optional, Key: value per line)";
115
+ readonly mcpFieldEnabled: "Enabled";
116
+ readonly mcpSave: "Save";
117
+ readonly mcpCancel: "Cancel";
118
+ readonly mcpInvalidId: "Instance ID may only contain letters, digits, - and _.";
119
+ readonly mcpInvalidName: "Name may only contain letters, digits, - and _ (1–32 chars).";
120
+ readonly mcpInvalidTimeout: "Timeout must be a positive integer (ms).";
121
+ readonly mcpInvalidUrl: "URL must start with http:// or https://.";
122
+ readonly mcpInvalidCommand: "Command is required.";
123
+ readonly mcpUnavailable: "MCP manager unavailable.";
124
+ readonly mcpDisabledHint: "MCP management is off. Turn it on in 界面调整 (UI Tweaks) to view and restart MCP servers here.";
125
+ readonly mcpEnable: "Enable MCP manager";
126
+ readonly initCommand: "/init command";
127
+ readonly initCommandHint: "The /init slash command: pick a prompt language and ChatCode CLI analyzes the project and writes AGENTS.md.";
128
+ readonly initCommandOn: "On";
129
+ readonly initCommandOff: "Off";
130
+ readonly whaleIndicator: "Whale indicator";
131
+ readonly whaleIndicatorHint: "A little whale above the input box: translucent while idle; while the model works it swims and breathes blue.";
132
+ readonly whaleIndicatorOn: "On";
133
+ readonly whaleIndicatorOff: "Off";
134
+ readonly preciseCacheHit: "Precise cache hit";
135
+ readonly preciseCacheHitHint: "Rewrites the cache-hit figure in the stats line under the input box to two decimal places (e.g. 96.35%), computed from the raw cached-read / cached-write / uncached-input token buckets instead of the stock rounded integer.";
136
+ readonly preciseCacheHitOn: "On";
137
+ readonly preciseCacheHitOff: "Off";
138
+ readonly sectionNotifications: "Task alerts";
139
+ readonly notifications: "Enable alerts";
140
+ readonly notificationsHint: "Call you back while the tab is in the background: a session finishes its turn, or one starts waiting for your approval, plan review or answer. The switches below apply only while this is on.";
141
+ readonly notifyOn: "On";
142
+ readonly notifyOff: "Off";
143
+ readonly notifyOnComplete: "Alert on finish";
144
+ readonly notifyOnCompleteHint: "Fire when a session ends its turn — completed, interrupted or failed; the notification says which.";
145
+ readonly notifyOnInteraction: "Alert on interaction";
146
+ readonly notifyOnInteractionHint: "Fire when a session waits on you: an approval, a plan review, or a question from the agent.";
147
+ readonly notifyOnlyWhenHidden: "Only when hidden";
148
+ readonly notifyOnlyWhenHiddenHint: "Stay quiet while you are looking at this page; alert only once the tab is hidden or unfocused.";
149
+ readonly notifyTitleFlash: "Tab title flash";
150
+ readonly notifyTitleFlashHint: "Blink an unread counter into the tab title until you come back.";
151
+ readonly notifySystemNotification: "System notifications";
152
+ readonly notifySystemNotificationHint: "Desktop-level notifications; click one to jump straight to that session. Permission is requested when enabled.";
153
+ readonly notifySound: "Chime";
154
+ readonly notifySoundHint: "A soft two-note motif — rising when work finishes, falling when it needs you.";
155
+ readonly notifyTest: "Test";
156
+ readonly notifyTitleDone: "Task finished";
157
+ readonly notifyTitleAborted: "Task interrupted";
158
+ readonly notifyTitleFailed: "Request failed";
159
+ readonly notifyTitlePending: "Needs you";
160
+ readonly bodyComplete: "✅ {title} finished its turn.";
161
+ readonly bodyAborted: "⏹ {title} was interrupted before finishing.";
162
+ readonly bodyFailed: "❌ {title} failed: {error}";
163
+ readonly bodyApproval: "⏸ {title} is waiting for your approval.";
164
+ readonly bodyPlan: "📋 {title} has a plan awaiting your review.";
165
+ readonly bodyQuestion: "❓ {title} asked you a question.";
166
+ readonly mcpServerDetail: "Configured in the profile cordis.patch.yml as @deepseek-ai/dsh-mcp-client instances; add / edit / disable / delete write to that file and apply live.";
167
+ readonly archiveNav: "Archive";
168
+ readonly archiveTitle: "Archived sessions";
169
+ readonly archiveEmpty: "No archived sessions.";
170
+ readonly archiveRestore: "Restore";
171
+ readonly archiveRestoring: "Working…";
172
+ readonly archiveDelete: "Delete";
173
+ readonly archiveDeleteAll: "Delete all";
174
+ readonly archiveRestoreAll: "Restore all";
175
+ readonly archiveCount: "sessions";
176
+ readonly archiveUnavailable: "Archive unavailable.";
177
+ readonly archiveLiveError: "This session is running; close it before permanently deleting it.";
178
+ readonly archiveDisabledHint: "Archive management is off. Turn it on in 界面调整 (UI Tweaks) to restore or permanently delete archived sessions here.";
179
+ readonly archiveEnable: "Enable archive management";
180
+ readonly archiveRestored: "Restored.";
181
+ readonly defaultAction: "Default";
182
+ readonly reset: "Reset";
183
+ readonly resetDone: "Reset to default.";
184
+ readonly applied: "Applied";
185
+ readonly unavailable: "Settings unavailable.";
186
+ readonly loading: "Loading…";
187
+ readonly readOnly: "The active Settings provider is read-only.";
188
+ readonly saved: "Saved.";
189
+ readonly commitMessage: "Commit";
190
+ readonly diffFiles: "files";
191
+ readonly branchLocal: "Local branches";
192
+ readonly branchRemote: "Remote branches";
193
+ readonly branchNew: "New branch";
194
+ readonly branchNewPlaceholder: "Branch name, e.g. fix/typo";
195
+ readonly branchCreate: "Create";
196
+ readonly diffTitle: "Changes";
197
+ readonly diffOnly: "Hunks";
198
+ readonly diffFull: "Full file";
199
+ readonly commitTitle: "Commit changes";
200
+ readonly commitPlaceholder: "Describe your changes…";
201
+ readonly commitHint: "Committing stages the checked files (untracked included) and commits; unchecked files are excluded from this commit. “Commit & push” also pushes; a new branch gets an -u upstream.";
202
+ readonly commitWillCommit: "To commit";
203
+ readonly commitViewDiff: "View";
204
+ readonly commitEmpty: "Write a commit message first";
205
+ readonly commitCancel: "Cancel";
206
+ readonly commitSubmit: "Commit";
207
+ readonly commitSubmitPush: "Commit & push";
208
+ readonly commitBusy: "Task in progress — commit is unavailable while the agent is working.";
209
+ readonly dirty: "Uncommitted changes";
210
+ readonly clean: "Working tree clean";
211
+ readonly noChanges: "No changes here.";
212
+ readonly branchDelete: "Delete branch";
213
+ readonly branchDeleteConfirm: "Confirm?";
214
+ readonly branchRemoteDelete: "Delete remote branch";
215
+ readonly branchFrom: "From branch";
216
+ readonly branchFromHead: "Current HEAD (default)";
217
+ readonly branchGraph: "Graph";
218
+ readonly branchCancel: "Cancel";
219
+ readonly branchRefresh: "Refresh";
220
+ readonly graphTitle: "Commit graph";
221
+ readonly graphColGraph: "Graph";
222
+ readonly graphColCommit: "Commit";
223
+ readonly graphColSubject: "Description";
224
+ readonly graphColAuthor: "Author";
225
+ readonly graphColDate: "Date";
226
+ readonly branchPushRemote: "Push to remote";
227
+ readonly includeFile: "Include in commit";
228
+ readonly excludeFile: "Exclude from commit";
229
+ readonly openProject: "Open project";
230
+ readonly terminal: "Terminal";
231
+ readonly openExplorer: "Explorer";
232
+ readonly openVscode: "VS Code";
233
+ readonly openIdea: "IntelliJ IDEA";
234
+ readonly openGoland: "GoLand";
235
+ readonly openWebstorm: "WebStorm";
236
+ readonly openPycharm: "PyCharm";
237
+ readonly termConnecting: "connecting…";
238
+ readonly termExited: "shell exited";
239
+ readonly termUnavailable: "PTY unavailable: node-pty failed to load on the host.";
240
+ readonly termLost: "connection lost";
241
+ readonly initDesc: "Analyze this project and generate an AGENTS.md for future coding agents";
242
+ readonly initOptionZh: "AGENTS.md — Chinese prompt";
243
+ readonly initOptionZhDetail: "Submit a Chinese prompt asking the agent to analyze the project and write or improve AGENTS.md.";
244
+ readonly initOptionEn: "AGENTS.md — English prompt";
245
+ readonly initOptionEnDetail: "Submit an English prompt asking the agent to analyze the project and write or improve AGENTS.md.";
246
+ readonly initFailed: "/init failed to send the prompt";
247
+ };
248
+ type LocaleKey = keyof typeof en;
249
+ declare module '@deepseek-ai/dsh-client-ui-slots' {
250
+ interface LocaleNamespaceMap {
251
+ /** dsh-ui-tweaks Settings copy. */
252
+ 'ui-tweaks': LocaleKey;
253
+ }
254
+ }
255
+ /** Client-side snapshot store fed by the same-origin Settings route. */
256
+ interface SettingsState {
257
+ status: 'loading' | 'ready' | 'error';
258
+ writable: boolean;
259
+ value: TweaksValue | undefined;
260
+ revision: number | undefined;
261
+ error?: string;
262
+ }
263
+ /** Small external store shared by the Settings route and the CSS engine. */
264
+ export declare class SettingsClient {
265
+ private state;
266
+ private listeners;
267
+ private generation;
268
+ subscribe: (listener: () => void) => (() => void);
269
+ getSnapshot: () => SettingsState;
270
+ private publish;
271
+ load(): Promise<void>;
272
+ private post;
273
+ set(field: string, value: unknown): Promise<void>;
274
+ unset(field: string): Promise<void>;
275
+ }
276
+ /** Required client services: slots (settings.section), locale, sessions (git bar, whale, archive, notifier), the slash-command registry, and the scope-addressed conversation face. */
277
+ export declare const inject: string[];
278
+ export declare function apply(ctx: UITweaksClientContext): void;
279
+ export {};
@@ -0,0 +1,28 @@
1
+ /**
2
+ * dsh-ui-tweaks — MCP manager (browser half).
3
+ *
4
+ * Renders the "MCP 管理" settings section (usable when the mcpManagerEnabled
5
+ * toggle in 界面调整 is on — otherwise it shows an invite card). The section
6
+ * lists every configured MCP server with its status (active / failed / loading
7
+ * / stopped / disabled), command / url, env names, registered tools, and
8
+ * offers per-server actions: **重启** (runtime reload), **启用/停用**,
9
+ * **编辑**, and **删除** (two-click confirm). An **添加服务器** button opens
10
+ * the editor, which supports BOTH a structured **表单** and a raw **YAML**
11
+ * mode (the config is validated on the server before the profile's
12
+ * `cordis.patch.yml` is rewritten; DSH's patch watcher then hot-reloads the
13
+ * loader so the server starts/stops live).
14
+ * @module dsh-ui-tweaks/client/mcp
15
+ */
16
+ import type { SettingsClient } from './index.tsx';
17
+ /** Locale keys the MCP manager reads off the `ui-tweaks` dictionary. */
18
+ type McpLabelKey = 'mcpTitle' | 'mcpEmpty' | 'mcpStatusActive' | 'mcpStatusFailed' | 'mcpStatusLoading' | 'mcpStatusStopped' | 'mcpStatusDisabled' | 'mcpTools' | 'mcpEnv' | 'mcpUnavailable' | 'mcpDisabledHint' | 'mcpEnable' | 'mcpServerDetail' | 'mcpAdd' | 'mcpAddTitle' | 'mcpEditTitle' | 'mcpEdit' | 'mcpDelete' | 'mcpEnabledAction' | 'mcpDisabledAction' | 'mcpSaved' | 'mcpRemoved' | 'mcpFormTab' | 'mcpYamlTab' | 'mcpYamlHint' | 'mcpYamlPlaceholder' | 'mcpFieldId' | 'mcpFieldIdHint' | 'mcpFieldName' | 'mcpFieldNameHint' | 'mcpFieldType' | 'mcpFieldTimeout' | 'mcpFieldCommand' | 'mcpFieldCommandPlaceholder' | 'mcpFieldArgs' | 'mcpFieldEnv' | 'mcpFieldUrl' | 'mcpFieldHeaders' | 'mcpFieldEnabled' | 'mcpSave' | 'mcpCancel' | 'mcpInvalidId' | 'mcpInvalidName' | 'mcpInvalidTimeout' | 'mcpInvalidUrl' | 'mcpInvalidCommand' | 'unavailable' | 'loading';
19
+ type Translate = (key: McpLabelKey) => string;
20
+ export declare const MCP_CSS = "\n.dut-mcp{display:grid;gap:12px;max-width:680px;padding:6px 2px 36px}\n.dut-mcp-head{display:flex;align-items:center;gap:10px;padding:14px 16px 0}\n.dut-mcp-head h2{margin:0;font-size:15px;font-weight:600;letter-spacing:-.01em;color:var(--dsw-alias-label-primary)}\n.dut-mcp-count{font-size:11.5px;color:var(--dsw-alias-label-secondary);padding:2px 8px;border-radius:999px;background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1)}\n.dut-mcp-spacer{flex:1}\n.dut-mcp-btn{display:inline-flex;align-items:center;height:28px;padding:0 12px;border-radius:999px;border:1px solid var(--dsw-alias-border-l1);background:transparent;color:var(--dsw-alias-label-secondary);font:inherit;font-size:12px;cursor:pointer;transition:background .15s ease,color .15s ease,border-color .15s ease}\n.dut-mcp-btn:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}\n.dut-mcp-btn:disabled{opacity:.5;cursor:default}\n.dut-mcp-btn.dut-mcp-del:hover{border-color:color-mix(in srgb,var(--dsw-alias-state-error-primary) 55%,transparent);color:var(--dsw-alias-state-error-primary);background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 10%,transparent)}\n.dut-mcp-btn.dut-mcp-confirm{border-color:color-mix(in srgb,var(--dsw-alias-state-error-primary) 55%,transparent);color:var(--dsw-alias-state-error-primary);font-weight:600}\n.dut-mcp-body{display:grid;gap:2px;margin-top:4px}\n.dut-mcp-row{display:grid;gap:6px;padding:10px 16px;border-radius:12px}\n.dut-mcp-row:hover{background:var(--dsw-alias-interactive-bg-hover)}\n.dut-mcp-row-main{display:flex;align-items:center;gap:8px;min-width:0}\n.dut-mcp-name{font-size:13.5px;font-weight:600;color:var(--dsw-alias-label-primary);white-space:nowrap;text-overflow:ellipsis;overflow:hidden}\n.dut-mcp-badge{flex:none;font-size:11px;line-height:1;padding:4px 9px;border-radius:999px;background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-secondary)}\n.dut-mcp-badge.dut-mcp-ok{background:color-mix(in srgb,var(--dsw-alias-state-success-primary) 12%,transparent);border-color:transparent;color:var(--dsw-alias-state-success-primary)}\n.dut-mcp-badge.dut-mcp-err{background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 12%,transparent);border-color:transparent;color:var(--dsw-alias-state-error-primary)}\n.dut-mcp-badge.dut-mcp-warn{background:color-mix(in srgb,var(--dsw-alias-state-warn-primary) 14%,transparent);border-color:transparent;color:var(--dsw-alias-state-warn-label)}\n.dut-mcp-sub{font-size:11.5px;color:var(--dsw-alias-label-secondary);white-space:nowrap;text-overflow:ellipsis;overflow:hidden}\n.dut-mcp-toggle{flex:none;font-size:11.5px;color:var(--dsw-alias-label-tertiary);background:transparent;border:none;padding:0;cursor:pointer;text-align:left}\n.dut-mcp-toggle:hover{color:var(--dsw-alias-label-primary)}\n.dut-mcp-tools{margin-left:2px;display:flex;flex-wrap:wrap;gap:4px}\n.dut-mcp-tool{font-size:11px;line-height:1;padding:3px 8px;border-radius:999px;background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-secondary)}\n.dut-mcp-note{margin:2px 16px 0;padding:8px 12px;border-radius:10px;font-size:11.5px;line-height:1.55;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1)}\n.dut-mcp-empty{padding:32px 16px;text-align:center;font-size:12.5px;color:var(--dsw-alias-label-secondary)}\n.dut-mcp-alert{margin:8px 16px 0;padding:8px 12px;border-radius:10px;font-size:12px;line-height:1.5;background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 10%,transparent);color:var(--dsw-alias-state-error-primary)}\n.dut-mcp-notice{margin:8px 16px 0;padding:8px 12px;border-radius:10px;font-size:12px;line-height:1.5;background:color-mix(in srgb,var(--dsw-alias-state-success-primary) 12%,transparent);color:var(--dsw-alias-state-success-primary)}\n.dut-mcp-off{padding:20px 16px;display:grid;gap:12px}\n.dut-mcp-off p{margin:0;font-size:12.5px;line-height:1.6;color:var(--dsw-alias-label-secondary)}\n.dut-mcp-overlay{z-index:1100;justify-content:center;align-items:center;display:flex;position:fixed;inset:0}\n.dut-mcp-mask{background:var(--dsw-alias-bg-mask-1);backdrop-filter:var(--dsw-mask-blur);position:absolute;inset:0}\n.dut-mcp-panel{z-index:1;background:var(--dsw-alias-bg-layer-2);box-sizing:border-box;width:720px;max-width:calc(100vw - 48px);height:min(700px,100vh - 48px);box-shadow:var(--dsw-shadow-lv3);--dsh-scrollbar-thumb:var(--dsw-alias-scrollbar-bg-l2);--dsh-scrollbar-thumb-hover:var(--dsw-alias-scrollbar-hover-l2);border-radius:20px;display:flex;flex-direction:column;overflow:hidden}\n.dut-mcp-panel-head{box-sizing:border-box;flex:none;display:flex;align-items:center;gap:10px;height:52px;padding:0 12px 0 20px}\n.dut-mcp-panel-head h2{margin:0;font-size:16px;font-weight:600;letter-spacing:-.01em;color:var(--dsw-alias-label-primary)}\n.dut-mcp-panel-close{cursor:pointer;width:28px;height:28px;color:var(--dsw-alias-label-primary);background:transparent;border:none;border-radius:28px;display:inline-flex;justify-content:center;align-items:center;padding:0;font-size:13px}\n.dut-mcp-panel-close:hover{background:var(--dsw-alias-interactive-bg-hover)}\n.dut-mcp-tabs{flex:none;display:inline-flex;padding:3px;gap:3px;border:1px solid var(--dsw-alias-border-l1);border-radius:10px;background:var(--dsw-alias-bg-layer-2);margin:0 20px 10px;align-self:flex-start}\n.dut-mcp-tabs button{border:none;border-radius:7px;padding:5px 14px;background:transparent;color:var(--dsw-alias-label-secondary);font:inherit;font-size:12.5px;cursor:pointer}\n.dut-mcp-tabs button.dut-mcp-tab-on{background:color-mix(in srgb,var(--dsw-alias-state-business-primary) 12%,transparent);color:var(--dsw-alias-state-business-primary);font-weight:600}\n.dut-mcp-form{flex:1;min-height:0;overflow-y:auto;padding:0 20px 20px;display:grid;gap:12px;align-content:start}\n.dut-mcp-field{display:grid;gap:6px}\n.dut-mcp-field>span{font-size:12px;font-weight:600;color:var(--dsw-alias-label-primary)}\n.dut-mcp-field small{font-size:11px;line-height:1.5;color:var(--dsw-alias-label-tertiary)}\n.dut-mcp-input{box-sizing:border-box;width:100%;height:34px;padding:0 10px;border-radius:9px;border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);font:inherit;font-size:13px}\n.dut-mcp-input:focus{outline:none;border-color:color-mix(in srgb,var(--dsw-alias-state-business-primary) 55%,transparent)}\n.dut-mcp-input:disabled{opacity:.55;cursor:not-allowed}\ntextarea.dut-mcp-input{height:auto;min-height:72px;padding:8px 10px;line-height:1.5;resize:vertical;font-family:var(--dsw-font-markdown-code-block-font-family, Consolas, monospace);font-size:12px}\ntextarea.dut-mcp-input-lg{min-height:120px}\ntextarea.dut-mcp-yaml{min-height:320px}\n.dut-mcp-row2{display:grid;grid-template-columns:1fr 1fr;gap:12px;align-items:start}\n.dut-mcp-field .dut-seg{width:fit-content}\n.dut-mcp-row2 .dut-seg{height:34px;box-sizing:border-box;align-items:center}\n.dut-mcp-row2 .dut-seg button{flex:none;white-space:nowrap;padding:0 16px;height:26px}\n.dut-mcp-foot{flex:none;display:flex;align-items:center;gap:8px;justify-content:flex-end;padding:12px 20px 16px;border-top:1px solid var(--dsw-alias-border-l1)}\n.dut-mcp-error{margin:0 20px 10px;padding:8px 12px;border-radius:10px;font-size:12px;line-height:1.5;background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 10%,transparent);color:var(--dsw-alias-state-error-primary)}\n";
21
+ /** Install the MCP stylesheet once (idempotent); returns the disposer. */
22
+ export declare function installMcpStyles(): () => void;
23
+ export interface McpSectionProps {
24
+ controller: SettingsClient;
25
+ t: Translate;
26
+ }
27
+ export declare function McpSection({ controller, t }: McpSectionProps): import("react").JSX.Element;
28
+ export {};
@@ -0,0 +1,125 @@
1
+ /**
2
+ * dsh-ui-tweaks — task notifications (browser half).
3
+ *
4
+ * Watches the sessions list feed (the same store the sidebar's running flag,
5
+ * amber interaction dot and green "done" reminder project from) and raises a
6
+ * browser-side heads-up when a session finishes its turn or starts blocking
7
+ * on the user — so a backgrounded tab can call you back:
8
+ *
9
+ * - "Finished" = a session's `running` flag drops (true → false) without an
10
+ * interaction taking over, or its host-tracked `completed` reminder rises
11
+ * (finished while not selected). The host `dshTurnOutcome` session
12
+ * projection (`src/turn-outcome.ts`, folded from `turn/end` reasons) says
13
+ * WHY it finished, so the copy distinguishes a clean completion from a
14
+ * user abort and from a failed request (with the error text); when the
15
+ * projection is missing or stale, falls back to a plain-finish announce.
16
+ * - "Interaction" = a session gains `pendingInteraction`
17
+ * ('approval' | 'plan-review' | 'question') — exactly the sidebar's
18
+ * amber-dot classification.
19
+ *
20
+ * Three independent channels, each silently degrading when unavailable:
21
+ * - Title flash: alternates `(N) 🔔 <title>` ↔ `(N) <title>` until the page
22
+ * is visible and focused again, then restores the captured title. DSH may
23
+ * rewrite `document.title` independently; while flashing our ticks win,
24
+ * and on stop we restore the pre-flash capture (worst case a stale base).
25
+ * - System notification: the Web Notifications API; permission is requested
26
+ * from the settings toggle's user gesture (`requestNotifyPermission`).
27
+ * Clicking one focuses the window and opens that session. `silent` tracks
28
+ * the chime channel so the two never double-beep.
29
+ * - Chime: a tiny WebAudio two-note motif (rising = done, falling = needs
30
+ * you), synthesized in-process — no audio assets. Autoplay policy allows
31
+ * this once the user has interacted with the origin (sticky activation),
32
+ * which the settings-toggle clicks provide.
33
+ *
34
+ * Anti-spam: the first snapshot after install only arms the baseline (a page
35
+ * load never fires a burst); events fire on transitions only; a short
36
+ * per-session+kind cooldown absorbs reconnect re-pull flicker. Subagent child
37
+ * rows are skipped — their parent carries the turn, and mid-turn subagent
38
+ * completions would be noise.
39
+ * @module dsh-ui-tweaks/client/notifier
40
+ */
41
+ import type { ISessions } from '@deepseek-ai/dsh-api-session-controller/client';
42
+ import type { SessionPendingInteractionSnapshot } from '@deepseek-ai/dsh-client-ui-session/client';
43
+ import type { HostObservable } from '@deepseek-ai/dsh-client-ui-slots';
44
+ import type { TurnOutcomeValue } from '../../ui-tweaks/turn-outcome.ts';
45
+ declare module '@deepseek-ai/dsh-session-projection/types' {
46
+ interface SessionProjectionMap {
47
+ dshTurnOutcome: TurnOutcomeValue | null;
48
+ }
49
+ }
50
+ /** Interaction kinds the host reports while a session blocks on the user. */
51
+ export type NotifyPendingKind = 'approval' | 'plan-review' | 'question';
52
+ /** Localized copy snapshot the notifier needs (resolved once at install). */
53
+ export interface NotifierText {
54
+ /** System-notification heading for completion events. */
55
+ notifyTitleDone: string;
56
+ /** System-notification heading for user-interrupted turns. */
57
+ notifyTitleAborted: string;
58
+ /** System-notification heading for failed requests. */
59
+ notifyTitleFailed: string;
60
+ /** System-notification heading for interaction events. */
61
+ notifyTitlePending: string;
62
+ /** Completion body template; `{title}` becomes the session display title. */
63
+ bodyComplete: string;
64
+ /** Interruption body template. */
65
+ bodyAborted: string;
66
+ /** Failure body template; `{error}` becomes the truncated failure message. */
67
+ bodyFailed: string;
68
+ /** Approval body template. */
69
+ bodyApproval: string;
70
+ /** Plan-review body template. */
71
+ bodyPlan: string;
72
+ /** Question body template. */
73
+ bodyQuestion: string;
74
+ }
75
+ /**
76
+ * Live-read behavior switches — read through {@link TaskNotifierInput.readState}
77
+ * on every feed tick so settings-panel flips apply without reinstalling.
78
+ */
79
+ export interface NotifierOptions {
80
+ /** Raise alerts only while the page is hidden or unfocused. */
81
+ onlyWhenHidden: boolean;
82
+ /** Alert when a session finishes its turn. */
83
+ onComplete: boolean;
84
+ /** Alert when a session starts waiting on the user. */
85
+ onInteraction: boolean;
86
+ }
87
+ /** Output channels, each independently toggleable. */
88
+ export interface NotifierChannels {
89
+ titleFlash: boolean;
90
+ systemNotification: boolean;
91
+ sound: boolean;
92
+ }
93
+ /** Install-time wiring for {@link installTaskNotifier}. */
94
+ export interface TaskNotifierInput {
95
+ /** The client sessions service whose list feed carries the watch states. */
96
+ sessionsService: ISessions;
97
+ /** Current Session-scoped interactions, published separately from list rows. */
98
+ pendingInteractions: HostObservable<SessionPendingInteractionSnapshot>;
99
+ /** Localized copy snapshot used across the notifier's lifetime. */
100
+ text: NotifierText;
101
+ /** Fresh behavior switches + channel toggles, read on every tick. */
102
+ readState(): {
103
+ options: NotifierOptions;
104
+ channels: NotifierChannels;
105
+ };
106
+ }
107
+ /**
108
+ * Ask the browser for desktop-notification permission. Must run inside a user
109
+ * gesture (the settings toggle's click) to avoid a denied or ignored prompt;
110
+ * repeated calls are cheap no-ops once decided.
111
+ */
112
+ export declare function requestNotifyPermission(): void;
113
+ export declare function previewTitleFlash(durationMs?: number): void;
114
+ /**
115
+ * One-shot self-test for the settings panel's 测试 button: previews every
116
+ * enabled channel — a forced ~6s title-flash blink (the real one would clear
117
+ * instantly on a focused page), the falling (needs-you) chime, and, when
118
+ * permission is already granted, one sample system notification.
119
+ */
120
+ export declare function previewAlerts(channels: NotifierChannels, text: NotifierText): void;
121
+ /**
122
+ * Install the task notifier against the sessions list feed.
123
+ * @returns disposer — unsubscribes, restores the tab title and tears the channels down.
124
+ */
125
+ export declare function installTaskNotifier(input: TaskNotifierInput): () => void;
@@ -0,0 +1,55 @@
1
+ /**
2
+ * dsh-ui-tweaks — whale working indicator (browser half).
3
+ *
4
+ * A compact China-knot brand mark perched on the composer card's top-right
5
+ * corner over drifting red waves. It is resident while the feature is on;
6
+ * idle it rests in brand red, and while the model works it floats and breathes
7
+ * through the red accent spectrum.
8
+ *
9
+ * - Mounted in `conversation.input.dock` (the full-width row stacked by the
10
+ * composer column right above the card), registered only while the
11
+ * `whaleIndicatorEnabled` toggle is on — off costs nothing. The dock row is
12
+ * WIDER than the card (the card is capped at
13
+ * `--dsh-composer-card-max-width` and centered with
14
+ * `--dsh-composer-side-clearance` side padding by the InputBar root), so
15
+ * the row replicates that exact geometry — same max-width, centered, same
16
+ * side padding — before right-aligning; a 6px `translateY` then straddles
17
+ * the card's top edge. The extra 14px right inset centers the whale over
18
+ * the send button (34px round button, 8px tool-row padding → its center
19
+ * sits 25px from the card's right edge; the 22px whale's right edge at
20
+ * 14px puts its center at 25px).
21
+ * - "Working" = the current session's `running` flag on the sessions list
22
+ * feed, OR the input machine's claimed/submitting phases (the window
23
+ * between pressing Enter and the agent actually starting to run).
24
+ * - The mark is self-contained rather than lifted from the host sidebar, so
25
+ * its branding remains consistent while DSH changes its own logo.
26
+ * @module dsh-ui-tweaks/client/whale
27
+ */
28
+ import type { ISessions } from '@deepseek-ai/dsh-api-session-controller/client';
29
+ import type { SessionId } from '@deepseek-ai/dsh-session/types';
30
+ export declare const WHALE_CSS = "\n.duwi-row{box-sizing:border-box;width:100%;max-width:calc(var(--dsh-composer-card-max-width) + 2 * var(--dsh-composer-side-clearance, 0px));margin:0 auto;padding:0 calc(var(--dsh-composer-side-clearance, 0px) + 14px) 0 var(--dsh-composer-side-clearance, 0px);display:flex;align-items:flex-end;justify-content:flex-end;height:27px;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}\n.duwi-stack{display:flex;flex-direction:column;align-items:center;transform:translateY(6px)}\n.duwi-whale{display:block;color:#9B0B09;transform-origin:50% 60%;pointer-events:auto;cursor:pointer}\n.duwi-row.duwi-swim .duwi-whale{animation:duwi-swim 1.9s ease-in-out infinite,duwi-breathe 1.9s ease-in-out infinite}\n.duwi-whale:hover{animation:duwi-swim 1.9s ease-in-out infinite}\n.duwi-waves{display:block;width:26px;height:9px;margin-top:-3px;overflow:hidden}\n.duwi-wave-back{stroke:#d96a65;opacity:.35}\n.duwi-wave-front{stroke:#9B0B09;opacity:.8}\n.duwi-wave-front,.duwi-wave-back{animation:duwi-drift-front 1.9s linear infinite}\n.duwi-wave-back{animation-duration:3.4s;animation-direction:reverse}\n@keyframes duwi-swim{\n0%,100%{transform:translateY(0) rotate(-4deg)}\n50%{transform:translateY(-3.5px) rotate(4deg)}\n}\n@keyframes duwi-breathe{\n0%,100%{color:#9B0B09}\n50%{color:#d94b45}\n}\n@keyframes duwi-drift-front{\nfrom{transform:translateX(0)}\nto{transform:translateX(-8px)}\n}\n@media (prefers-reduced-motion:reduce){\n.duwi-row.duwi-swim .duwi-whale,.duwi-whale:hover{animation:none}\n.duwi-wave-front,.duwi-wave-back{animation:none}\n}\n";
31
+ /** Idempotent installer for the indicator styles (same pattern as the other features). */
32
+ export declare function installWhaleStyles(): () => void;
33
+ /**
34
+ // ---------------------------------------------------------------------------
35
+ // Component.
36
+ // ---------------------------------------------------------------------------
37
+
38
+ /**
39
+ * Structural slice of the framework `InputState` (not re-exported by the
40
+ * package's client entry) — exactly the fields the indicator reads off the
41
+ * dock's owner share.
42
+ */
43
+ interface InputPhaseSnapshot {
44
+ phase: 'plain' | 'adjudicating' | 'claimed' | 'submitting';
45
+ }
46
+ export interface WhaleIndicatorProps {
47
+ /** Framework seat (PropsRuntime): current session id. */
48
+ sessionId: SessionId | undefined;
49
+ /** Owner share (InputZone): live input-machine snapshot — covers the send → run window. */
50
+ input: InputPhaseSnapshot;
51
+ /** Injected: the client sessions service (list feed carrying `running`). */
52
+ sessionsService: ISessions;
53
+ }
54
+ export declare function WhaleIndicator({ sessionId, input, sessionsService }: WhaleIndicatorProps): import("react").JSX.Element;
55
+ export {};
@@ -0,0 +1,69 @@
1
+ /**
2
+ * File-upload plumbing for the files window: turn a file picker or a drag-drop
3
+ * into per-file raw-byte uploads through the sidebar's `/sidebar/upload` route.
4
+ *
5
+ * Folders keep their tree in both flows: the picker's `webkitdirectory`
6
+ * selection arrives as Files with `webkitRelativePath` filled, and dropped
7
+ * folders — which never surface in `dataTransfer.files` — are traversed via
8
+ * `webkitGetAsEntry`, so the relative path is preserved for every nested file
9
+ * and the host recreates the tree under the chosen directory. The File is
10
+ * streamed straight into the POST body (no base64 inflation); uploads run
11
+ * sequentially so one slow file cannot starve the others, and each result
12
+ * reports its own outcome (the tree keeps going after a failure). An
13
+ * optional `AbortSignal` stops the queue at the next item boundary and
14
+ * aborts the in-flight request; the host cleans up its temp file when the
15
+ * request stream dies.
16
+ */
17
+ import { type SessionScope } from './api.ts';
18
+ import type { CopyKey } from './locales.ts';
19
+ /** One pending file: the browser File plus the workspace-relative target path. */
20
+ export interface UploadItem {
21
+ file: File;
22
+ relativePath: string;
23
+ }
24
+ /** One settled upload. */
25
+ export interface UploadResult {
26
+ relativePath: string;
27
+ ok: boolean;
28
+ path?: string;
29
+ /** Wire error code when the host refused the upload ('too-large', ...). */
30
+ code?: string;
31
+ /** The host's error message (English wire text; localize via `code`). */
32
+ error?: string;
33
+ }
34
+ /** Collect a picker selection (webkitdirectory folders carry relative paths). */
35
+ export declare function uploadItemsFromFiles(files: FileList | readonly File[]): UploadItem[];
36
+ /**
37
+ * Collect a drag-drop payload. Dropped folders do NOT surface in
38
+ * `dataTransfer.files` — they arrive as directory items, so entries are
39
+ * captured via `webkitGetAsEntry` and traversed (draining readEntries
40
+ * batches), keeping each nested file's relative path. MUST be invoked
41
+ * synchronously from the drop handler: the dataTransfer enters protected
42
+ * mode once the event dispatch ends, while the captured entry handles stay
43
+ * readable asynchronously. Falls back to the flat file list when the entry
44
+ * API is unavailable; an entry that fails to read is skipped, not fatal.
45
+ */
46
+ export declare function uploadItemsFromDrop(data: DataTransfer | undefined): Promise<UploadItem[]>;
47
+ /**
48
+ * Client-side pre-check cap. Mirrors the host's default (config `uploadLimit`)
49
+ * only — the host enforces the real, configurable limit, so a lowered host
50
+ * limit surfaces as a `too-large` wire error, never as a silent pass.
51
+ */
52
+ export declare const MAX_UPLOAD_BYTES: number;
53
+ /** How long a success hint stays before fading (failures stay until the next action). */
54
+ export declare const UPLOAD_HINT_MS = 3500;
55
+ /**
56
+ * One-line upload progress text: 'Uploading into {dir}…' while no file is in
57
+ * flight, then 'Uploading {done}/{total}: {name}' per file. Shared by the tree
58
+ * hint and the full-window upload overlay.
59
+ */
60
+ export declare function uploadHintText(done: number, total: number, current: string, dir: string, t: (key: CopyKey, params?: Record<string, string | number>) => string): string;
61
+ /**
62
+ * Upload every item into `dir` (absolute, inside the session workspace),
63
+ * sequentially, reporting progress as `(done, total, currentRelativePath)`.
64
+ * Resolves with one result per item — never rejects; `signal.aborted` stops
65
+ * the queue at the next item boundary (completed items stay uploaded).
66
+ */
67
+ export declare function uploadToDir(scope: SessionScope, dir: string, items: UploadItem[], onProgress?: (done: number, total: number, current: string) => void, signal?: AbortSignal): Promise<UploadResult[]>;
68
+ /** Fold a result list into a one-line status for the tree hint. */
69
+ export declare function summarizeResults(results: UploadResult[], t: (key: CopyKey, params?: Record<string, string | number>) => string): string;
@@ -0,0 +1,10 @@
1
+ import type { ChatCodeAuthState } from './api.ts';
2
+ export declare function useChatcodeAccount(): {
3
+ chatcode: ChatCodeAuthState | undefined;
4
+ busy: boolean;
5
+ error: "status" | "operation" | undefined;
6
+ loginUrl: string | undefined;
7
+ startLogin: () => void;
8
+ logout: () => void;
9
+ cancelLogin: () => void;
10
+ };
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Reactive Window Controls Overlay geometry — the STANDARD web mechanism
3
+ * for frameless Chromium shells that draw the native caption buttons
4
+ * (minimize / maximize / close) OVER the web content (Electron
5
+ * `titleBarOverlay` on Windows; issue #257). Feature-detected: absent in
6
+ * plain browsers, macOS, Tauri etc., where the snapshot stays `NONE` and
7
+ * the sidebar adapts nothing — this is the conservative "auto" signal.
8
+ *
9
+ * The API reports the real titlebar rect (CSS px), which differs between
10
+ * shells and Electron versions (32 / 36 …), and fires `geometrychange`
11
+ * when the window maximizes / restores / moves — so the strip must be
12
+ * reactive, not memoized like the URL stamps.
13
+ *
14
+ * Module-level store so the Sidebar shell can subscribe via
15
+ * `useSyncExternalStore`; `setWcoSourceForTests` swaps the source for unit
16
+ * tests (no real API exists in jsdom/headless).
17
+ */
18
+ export interface WcoSource {
19
+ readonly visible: boolean;
20
+ getTitlebarAreaRect(): {
21
+ readonly x: number;
22
+ readonly y: number;
23
+ readonly width: number;
24
+ readonly height: number;
25
+ };
26
+ addEventListener(type: 'geometrychange', listener: () => void): void;
27
+ removeEventListener(type: 'geometrychange', listener: () => void): void;
28
+ }
29
+ /** The current overlay geometry (present=false = API unavailable). */
30
+ export interface WcoSnapshot {
31
+ readonly present: boolean;
32
+ readonly height: number;
33
+ }
34
+ /** Snapshot when the API is unavailable (plain browser / non-overlay shell). */
35
+ export declare const WCO_NONE: WcoSnapshot;
36
+ type Listener = () => void;
37
+ /** Read the current snapshot (returns the frozen NONE when unavailable). */
38
+ export declare function getWcoSnapshot(): WcoSnapshot;
39
+ /**
40
+ * Subscribe to overlay geometry changes. Attaches to the real
41
+ * `navigator.windowControlsOverlay` on first subscribe; the disposer
42
+ * detaches the native listener when the last subscriber leaves.
43
+ */
44
+ export declare function subscribeWco(onChange: Listener): () => void;
45
+ /** Test hook: swap the geometry source (undefined = API unavailable). */
46
+ export declare function setWcoSourceForTests(next: WcoSource | undefined): void;
47
+ export {};