@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,57 @@
1
+ /**
2
+ * dsh-ui-tweaks — turn outcome projection (host half).
3
+ *
4
+ * Registers the `dshTurnOutcome` session projection unit: the outcome of the
5
+ * session's most recent agent turn, folded from the log's `turn/end` events.
6
+ * The task notifier reads it off each sessions-list row (`projectionValues`)
7
+ * so it can announce WHY a turn ended — completed vs user-aborted vs failed —
8
+ * instead of announcing every running-drop as a plain finish.
9
+ *
10
+ * Whole-value rule: every `turn/end` replaces the previous value outright
11
+ * (last-wins), and `null` means no completed turn yet. Error turns keep a
12
+ * truncated copy of the structured failure message for notification bodies.
13
+ *
14
+ * `TurnEndReason` is merge-extensible upstream; unknown future kinds flow
15
+ * through as their literal kind string and the client falls back to a generic
16
+ * finish announcement.
17
+ * @module dsh-ui-tweaks/turn-outcome
18
+ */
19
+ import type { Context } from '@deepseek-ai/cordis';
20
+ import type { ProjectionDefinition } from '@deepseek-ai/dsh-session-projection';
21
+ /** Projection key the browser notifier reads through list-row `projectionValues`. */
22
+ export declare const TURN_OUTCOME_PROJECTION_KEY = "dshTurnOutcome";
23
+ /** The stock `TurnEndReason` kinds (the map is merge-extensible upstream). */
24
+ export type TurnOutcomeKind = 'completed' | 'aborted' | 'blocked' | 'error' | 'max-tokens' | 'interrupted';
25
+ /** Whole projection value: why the latest turn ended. */
26
+ export interface TurnOutcomeValue {
27
+ kind: TurnOutcomeKind;
28
+ /** Unix epoch ms of the `turn/end` event. */
29
+ time: number;
30
+ /** Turn number carried by the same event. */
31
+ turn?: number;
32
+ /** Truncated human-readable failure text; present only on `error` outcomes. */
33
+ errorMessage?: string;
34
+ }
35
+ declare module '@deepseek-ai/dsh-session-projection/types' {
36
+ interface SessionProjectionMap {
37
+ /** Outcome of the session's most recent agent turn; null before the first one ends. */
38
+ dshTurnOutcome: TurnOutcomeValue | null;
39
+ }
40
+ interface SessionProjectionStateMap {
41
+ /** Host fold state for the turn-outcome key (same shape as the wire value). */
42
+ dshTurnOutcome: TurnOutcomeValue | null;
43
+ }
44
+ }
45
+ /** Registration-ready unit type with the client-visible `wire` block narrowed in. */
46
+ type TurnOutcomeProjectionUnit = Omit<ProjectionDefinition<'dshTurnOutcome', TurnOutcomeValue | null>, 'wire'> & {
47
+ wire: NonNullable<ProjectionDefinition<'dshTurnOutcome', TurnOutcomeValue | null>['wire']>;
48
+ };
49
+ /** The `dshTurnOutcome` projection unit: last-wins fold over `turn/end`. */
50
+ export declare const turnOutcomeProjectionDefinition: TurnOutcomeProjectionUnit;
51
+ /**
52
+ * Register the projection whenever the `sessionProjections` service is
53
+ * present. Headless assemblies without the registry stay unaffected.
54
+ * @param ctx - plugin context owning the registration effect.
55
+ */
56
+ export declare function installTurnOutcomeProjection(ctx: Context): void;
57
+ export {};
@@ -0,0 +1,55 @@
1
+ /**
2
+ * dsh-ui-tweaks — optional Web routes.
3
+ *
4
+ * The browser Settings panel reads and writes the `ui-tweaks` namespace through
5
+ * this same-origin route, because the Web settings RPC only exposes a fixed
6
+ * allowlist of namespaces (hardcoded in dsh-host-apiproxy since rc.6). The route
7
+ * proxies to the real `ctx.settings` service, so the settings document
8
+ * (settings.yaml) stays the single source of truth and hand edits keep working.
9
+ * @module dsh-ui-tweaks/web
10
+ */
11
+ import type { IncomingMessage, ServerResponse } from 'node:http';
12
+ import type { Context } from '@deepseek-ai/cordis';
13
+ /** Exact route used by the browser Settings page. */
14
+ export declare const SETTINGS_ROUTE = "/_dsh/ui-tweaks/settings";
15
+ /** Project-owned logo, served to the browser from the packaged assets folder. */
16
+ export declare const LOGO_ROUTE = "/_dsh/ui-tweaks/assets/logo.svg";
17
+ /** Public Settings snapshot; no secrets exist in this namespace. */
18
+ export interface UITweaksSnapshot {
19
+ writable: boolean;
20
+ value: unknown;
21
+ revision: number;
22
+ }
23
+ type JsonResponse<T> = {
24
+ ok: true;
25
+ value: T;
26
+ } | {
27
+ ok: false;
28
+ error: {
29
+ code: string;
30
+ message: string;
31
+ };
32
+ };
33
+ /** Accept state-changing requests only from the DSH Web application's origin. */
34
+ export declare function sameOriginPost(req: IncomingMessage): boolean;
35
+ export declare function isRecord(value: unknown): value is Record<string, unknown>;
36
+ export declare function json<T>(res: ServerResponse, status: number, body: JsonResponse<T>): void;
37
+ export declare function requestError(res: ServerResponse, status: number, code: string, message: string): void;
38
+ export declare function readJson(req: IncomingMessage, maxBytes?: number): Promise<unknown>;
39
+ export declare function messageOf(error: unknown): string;
40
+ /** Same-origin Settings read/write handler. */
41
+ export declare class UITweaksWebBackend {
42
+ private readonly ctx;
43
+ constructor(ctx: Context);
44
+ private descriptor;
45
+ private snapshot;
46
+ /** Handle the exact Settings route. */
47
+ handle(req: IncomingMessage, res: ServerResponse): Promise<void>;
48
+ }
49
+ /**
50
+ * Attach the Settings route whenever a webServer service is present.
51
+ * @param ctx - plugin context owning route effects.
52
+ * @param backend - Settings handler.
53
+ */
54
+ export declare function installUITweaksWeb(ctx: Context, backend: UITweaksWebBackend): void;
55
+ export {};
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Wire helpers for the /sidebar JSON API: bounded body reading, response
3
+ * writing, and the shared error envelope. Every API method returns
4
+ * `{ok: true, value}` on success and `{ok: false, error: {code, message}}`
5
+ * (HTTP 4xx/5xx matching the code) on failure.
6
+ */
7
+ import type { SidebarHttpRequest, SidebarHttpResponse } from './context-types.ts';
8
+ /** Machine-readable error codes of the sidebar API. */
9
+ export type SidebarErrorCode = 'bad-request' | 'not-found' | 'forbidden' | 'method-error' | 'too-large' | 'fs-error' | 'git-error' | 'pty-error' | 'pty-deps-missing' | 'job-error' | 'sidechat-error' | 'subagents-unavailable' | 'chatcode-unavailable' | 'chatcode-unauthorized' | 'chatcode-stats-unreachable' | 'chatcode-stats-http' | 'chatcode-stats-rejected' | 'chatcode-update-fetch' | 'chatcode-update-install' | 'release-note-unreachable' | 'release-note-http' | 'release-note-rejected' | 'settings-rejected' | 'settings-conflict' | 'internal';
10
+ /** One API failure with its wire code and HTTP status. */
11
+ export declare class SidebarError extends Error {
12
+ readonly code: SidebarErrorCode;
13
+ readonly status: number;
14
+ constructor(code: SidebarErrorCode, message: string, status?: number);
15
+ }
16
+ /** Success envelope of one API method. */
17
+ export interface SidebarOk<T> {
18
+ ok: true;
19
+ value: T;
20
+ }
21
+ /** Failure envelope of one API method. */
22
+ export interface SidebarErr {
23
+ ok: false;
24
+ error: {
25
+ code: SidebarErrorCode;
26
+ message: string;
27
+ };
28
+ }
29
+ /** Read and parse the JSON request body (bounded; malformed → bad-request). */
30
+ export declare function readJsonBody(req: SidebarHttpRequest): Promise<unknown>;
31
+ /** Write a JSON response with the given status. */
32
+ export declare function writeJson(res: SidebarHttpResponse, status: number, body: unknown): void;
33
+ /** Write the success envelope. */
34
+ export declare function writeOk(res: SidebarHttpResponse, value: unknown): void;
35
+ /** Write the failure envelope for any thrown value (unknown → internal 500). */
36
+ export declare function writeError(res: SidebarHttpResponse, error: unknown): void;
37
+ /** Narrow an unknown payload value to a string, else throw bad-request. */
38
+ export declare function requireString(payload: unknown, key: string): string;
package/package.json ADDED
@@ -0,0 +1,213 @@
1
+ {
2
+ "name": "@chatcode/cco-better-sidebar",
3
+ "version": "0.18.0-alpha.0",
4
+ "description": "ChatCode CLI Web plugin: a VS Code-like right sidebar (explorer / editor / terminal / git / browser), isolated per conversation session. Exposes a service for other plugins to register sidebar tabs and file viewers.",
5
+ "type": "module",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/omdsh-dev/DSH-better-sidebar"
9
+ },
10
+ "publishConfig": {
11
+ "access": "public"
12
+ },
13
+ "main": "lib/index.js",
14
+ "types": "lib/types/index.d.ts",
15
+ "exports": {
16
+ ".": {
17
+ "types": "./lib/types/index.d.ts",
18
+ "default": "./lib/index.js"
19
+ },
20
+ "./invariant": {
21
+ "types": "./lib/types/invariant.d.ts",
22
+ "default": "./lib/invariant.js"
23
+ },
24
+ "./client": {
25
+ "types": "./lib/types/client/index.d.ts",
26
+ "default": "./lib/client.js"
27
+ },
28
+ "./client/service": {
29
+ "types": "./lib/types/client/service.d.ts",
30
+ "default": "./lib/client.js"
31
+ },
32
+ "./client/api": {
33
+ "types": "./lib/types/client/service.d.ts",
34
+ "default": "./lib/client.js"
35
+ },
36
+ "./src/*": "./src/*",
37
+ "./package.json": "./package.json"
38
+ },
39
+ "engines": {
40
+ "node": ">=20"
41
+ },
42
+ "dsh": {
43
+ "bundle": {
44
+ "patch": "./cordis.patch.yml"
45
+ },
46
+ "client": {
47
+ "inject": [
48
+ "@deepseek-ai/dsh-api-session-controller",
49
+ "@deepseek-ai/dsh-api-workspace-controller",
50
+ "@deepseek-ai/dsh-client-locale",
51
+ "@deepseek-ai/dsh-client-ui-commands",
52
+ "@deepseek-ai/dsh-client-ui-slots",
53
+ "@deepseek-ai/dsh-client-ui-settings",
54
+ "@deepseek-ai/dsh-client-ui-conversation",
55
+ "@deepseek-ai/dsh-client-ui-session",
56
+ "@deepseek-ai/dsh-client-ui-workspace",
57
+ "@deepseek-ai/dsh-client-modules"
58
+ ],
59
+ "platform": "web"
60
+ }
61
+ },
62
+ "files": [
63
+ "lib/index.js",
64
+ "lib/invariant.js",
65
+ "lib/client.js",
66
+ "lib/client-registry.js",
67
+ "lib/client-terminal.js",
68
+ "lib/client-editor.js",
69
+ "lib/client-mermaid.js",
70
+ "lib/types/**/*.d.ts",
71
+ "src",
72
+ "assets/logo.svg",
73
+ "vendor",
74
+ "scripts/install.sh",
75
+ "scripts/install.ps1",
76
+ "cordis.patch.yml",
77
+ "README.md",
78
+ "README_EN.md",
79
+ "LICENSE"
80
+ ],
81
+ "license": "MIT",
82
+ "peerDependencies": {
83
+ "@deepseek-ai/cordis": "^4.0.1",
84
+ "@deepseek-ai/dsh-agent": "^0.1.2-alpha.2",
85
+ "@deepseek-ai/dsh-api-session-controller": "^0.1.2-alpha.2",
86
+ "@deepseek-ai/dsh-api-workspace-controller": "^0.1.2-alpha.2",
87
+ "@deepseek-ai/dsh-client-locale": "^0.1.2-alpha.2",
88
+ "@deepseek-ai/dsh-client-ui-commands": "^0.1.2-alpha.1",
89
+ "@deepseek-ai/dsh-client-ui-conversation": "^0.1.2-alpha.2",
90
+ "@deepseek-ai/dsh-client-ui-primitives": "^0.1.2-alpha.2",
91
+ "@deepseek-ai/dsh-client-ui-session": "^0.1.2-alpha.2",
92
+ "@deepseek-ai/dsh-client-ui-settings": "^0.1.2-alpha.2",
93
+ "@deepseek-ai/dsh-client-ui-slots": "^0.1.2-alpha.2",
94
+ "@deepseek-ai/dsh-client-ui-workspace": "^0.1.2-alpha.2",
95
+ "@deepseek-ai/dsh-host-webserver": "^0.1.2-alpha.2",
96
+ "@deepseek-ai/dsh-invariants": "^0.1.2-alpha.2",
97
+ "@deepseek-ai/dsh-llm": "^0.1.2-alpha.2",
98
+ "@deepseek-ai/dsh-session": "^0.1.2-alpha.2",
99
+ "@deepseek-ai/dsh-session-projection": "^0.1.2-alpha.1",
100
+ "@deepseek-ai/dsh-settings": "^0.1.2-alpha.2",
101
+ "@deepseek-ai/dsh-storage-domain": "^0.1.2-alpha.1",
102
+ "@deepseek-ai/dsh-subagent": "^0.1.2-alpha.2",
103
+ "@deepseek-ai/dsh-tools": "^0.1.2-alpha.2",
104
+ "@deepseek-ai/dsh-workspace": "^0.1.2-alpha.1",
105
+ "@deepseek-ai/schemastery": "^3.18.0",
106
+ "@huanlin/dsh-plugin-better-locale": "^0.1.0",
107
+ "react": "^18.2.0",
108
+ "react-dom": "^18.2.0"
109
+ },
110
+ "peerDependenciesMeta": {
111
+ "@huanlin/dsh-plugin-better-locale": {
112
+ "optional": true
113
+ }
114
+ },
115
+ "dependencies": {
116
+ "@codemirror/commands": "^6.10.4",
117
+ "@codemirror/lang-cpp": "^6.0.3",
118
+ "@codemirror/lang-css": "^6.3.1",
119
+ "@codemirror/lang-go": "^6.0.1",
120
+ "@codemirror/lang-html": "^6.4.12",
121
+ "@codemirror/lang-java": "^6.0.2",
122
+ "@codemirror/lang-javascript": "^6.2.5",
123
+ "@codemirror/lang-json": "^6.0.2",
124
+ "@codemirror/lang-markdown": "^6.5.2",
125
+ "@codemirror/lang-php": "^6.0.2",
126
+ "@codemirror/lang-python": "^6.2.1",
127
+ "@codemirror/lang-rust": "^6.0.2",
128
+ "@codemirror/lang-sql": "^6.10.0",
129
+ "@codemirror/lang-vue": "^0.1.3",
130
+ "@codemirror/lang-xml": "^6.1.0",
131
+ "@codemirror/lang-yaml": "^6.1.3",
132
+ "@codemirror/language": "^6.12.4",
133
+ "@codemirror/legacy-modes": "^6.5.3",
134
+ "@codemirror/search": "^6.7.1",
135
+ "@codemirror/state": "^6.7.1",
136
+ "@codemirror/view": "^6.43.8",
137
+ "@lezer/highlight": "^1.2.3",
138
+ "clsx": "^2.1.1",
139
+ "dompurify": "^3.4.14",
140
+ "mermaid": "^11.16.1",
141
+ "node-pty": "^1.1.0",
142
+ "react-icons": "5.7.0",
143
+ "rxjs": "^7.8.2",
144
+ "schemastery": "^3.18.0",
145
+ "ws": "^8.18.0",
146
+ "yaml": "2.9.0",
147
+ "@chatcode/cco-builtin-browser": "0.1.21"
148
+ },
149
+ "devDependencies": {
150
+ "@cordisjs/plugin-loader": "^1.0.0-rc.5",
151
+ "@deepseek-ai/cordis": "4.0.1",
152
+ "@deepseek-ai/dsh-agent": "0.1.2-alpha.2",
153
+ "@deepseek-ai/dsh-attachment": "0.1.1-rc.1",
154
+ "@deepseek-ai/dsh-api-session-controller": "0.1.2-alpha.2",
155
+ "@deepseek-ai/dsh-api-workspace-controller": "0.1.2-alpha.2",
156
+ "@deepseek-ai/dsh-client-locale": "0.1.2-alpha.2",
157
+ "@deepseek-ai/dsh-client-store": "0.1.2-alpha.2",
158
+ "@deepseek-ai/dsh-client-ui-commands": "^0.1.1-rc.2",
159
+ "@deepseek-ai/dsh-client-ui-conversation": "0.1.2-alpha.2",
160
+ "@deepseek-ai/dsh-client-ui-primitives": "0.1.2-alpha.2",
161
+ "@deepseek-ai/dsh-client-ui-session": "0.1.2-alpha.2",
162
+ "@deepseek-ai/dsh-client-ui-settings": "0.1.2-alpha.2",
163
+ "@deepseek-ai/dsh-client-ui-slots": "0.1.2-alpha.2",
164
+ "@deepseek-ai/dsh-client-ui-workspace": "0.1.2-alpha.2",
165
+ "@deepseek-ai/dsh-code-runtime": "0.1.1-rc.1",
166
+ "@deepseek-ai/dsh-host-webserver": "0.1.2-alpha.2",
167
+ "@deepseek-ai/dsh-invariants": "0.1.2-alpha.2",
168
+ "@deepseek-ai/dsh-llm": "0.1.2-alpha.2",
169
+ "@deepseek-ai/dsh-scope": "0.1.1-rc.1",
170
+ "@deepseek-ai/dsh-session": "0.1.2-alpha.2",
171
+ "@deepseek-ai/dsh-session-persistence": "^0.1.1-rc.2",
172
+ "@deepseek-ai/dsh-session-projection": "^0.1.1-rc.2",
173
+ "@deepseek-ai/dsh-settings": "0.1.2-alpha.2",
174
+ "@deepseek-ai/dsh-storage": "^0.1.1-rc.2",
175
+ "@deepseek-ai/dsh-storage-domain": "^0.1.1-rc.2",
176
+ "@deepseek-ai/dsh-subagent": "0.1.2-alpha.2",
177
+ "@deepseek-ai/dsh-system-prompt": "0.1.1-rc.1",
178
+ "@deepseek-ai/dsh-tools": "0.1.2-alpha.2",
179
+ "@deepseek-ai/dsh-user-approval": "0.1.1-rc.1",
180
+ "@deepseek-ai/dsh-util-time": "0.1.2-alpha.2",
181
+ "@deepseek-ai/dsh-workspace": "^0.1.1-rc.2",
182
+ "@deepseek-ai/schemastery": "^3.18.0",
183
+ "@huanlin/dsh-plugin-better-locale": "^0.1.0",
184
+ "@playwright/test": "^1.62.1",
185
+ "@types/node": "^24.0.0",
186
+ "@types/react": "~18.3.1",
187
+ "@types/react-dom": "~18.3.1",
188
+ "@types/ws": "^8.5.10",
189
+ "@xterm/addon-fit": "^0.11.0",
190
+ "@xterm/xterm": "^5.5.0",
191
+ "cordis": "^4.0.0-rc.8",
192
+ "jsdom": "^29.1.1",
193
+ "lightningcss": "^1.32.0",
194
+ "react": "^18.2.0",
195
+ "react-dom": "18.2.0",
196
+ "tsdown": "^0.22.2",
197
+ "typescript": "^5.6.0",
198
+ "unrun": "^0.2.39",
199
+ "vitest": "^4.1.8",
200
+ "zod": "^4.4.3"
201
+ },
202
+ "scripts": {
203
+ "build": "node -e \"require('node:fs').rmSync('lib',{recursive:true,force:true})\" && tsc -p tsconfig.build.json && tsdown",
204
+ "typecheck": "tsc --noEmit",
205
+ "bundle": "tsdown",
206
+ "watch": "tsdown --watch",
207
+ "test": "vitest run",
208
+ "test:browser": "pnpm --filter @chatcode/cco-builtin-browser build && pnpm --filter @chatcode/cco-builtin-browser test",
209
+ "test:mount": "bash scripts/e2e-mount.sh",
210
+ "verify:brand": "node scripts/verify-brand.mjs",
211
+ "check:consumer-types": "bash scripts/check-consumer-types.sh"
212
+ }
213
+ }
@@ -0,0 +1,310 @@
1
+ ## =============================================================================
2
+ # dsh-better-sidebar 一键安装脚本(官方 CLI 方式,Windows PowerShell 5.1+ / pwsh)
3
+ #
4
+ # 通过 ChatCode CLI 插件命令安装 npm 包并自动挂载:
5
+ # chatcode-cli plugin --profile web add @chatcode/cco-better-sidebar@<version>
6
+ #
7
+ # 包内声明了 dsh.bundle.patch(cordis.patch.yml):CLI 的 bundle 协调会把它
8
+ # 自动加进 profile 的 dsh.profile.bundles,下次启动即挂载——无需手动写
9
+ # cordis.patch.yml 挂载行。符合仓库硬约束:不修改宿主源码,插件永远作为
10
+ # 独立包被 profile 引用。
11
+ #
12
+ # 用法(任选其一):
13
+ # # 默认最新版
14
+ # $script = (irm 'https://raw.githubusercontent.com/omdsh-dev/DSH-better-sidebar/main/scripts/install.ps1').TrimStart([char]0xFEFF)
15
+ # & ([scriptblock]::Create($script))
16
+ # # 指定版本 / 装完重启
17
+ # $script = (irm 'https://raw.githubusercontent.com/omdsh-dev/DSH-better-sidebar/main/scripts/install.ps1').TrimStart([char]0xFEFF)
18
+ # & ([scriptblock]::Create($script)) -Version 0.10.2 -Restart
19
+ # # 本地保存后运行
20
+ # powershell -ExecutionPolicy Bypass -File install.ps1 -Version 0.10.2 -DryRun
21
+ # # 修复 node-pty 依赖(终端提示「node-pty 加载失败」时用,见 issue #140)
22
+ # powershell -ExecutionPolicy Bypass -File install.ps1 -Repair
23
+ #
24
+ # 参数:
25
+ # -Version npm 版本号/范围,缺省 latest(自动解析为最新)。
26
+ # -Repair 修复模式:不重装插件,只确保 profile 的 pnpm-workspace.yaml
27
+ # 放行 node-pty 构建脚本,然后重跑 pnpm install + pnpm rebuild
28
+ # node-pty。
29
+ # -Profile 目标 profile 名(缺省 web);安装与修复模式均适用。
30
+ # -Restart 装完后尝试 `pm2 restart chatcode-cli-web`(无 pm2 时仅提示)。会断开当前页面会话。
31
+ # -DryRun 只打印将要执行的操作,不写任何文件。
32
+ #
33
+ # 环境变量(均可省略):
34
+ # CHATCODE_CLI_HOME 默认 %USERPROFILE%\.chatcode-cli(兼容读取旧 DSH_HOME)
35
+ # REGISTRY 默认 https://registry.npmjs.org
36
+ # CHATCODE_CLI_CMD 默认优先 PATH 上的 chatcode-cli(兼容读取旧 DSH_CMD)
37
+ #
38
+ # 说明:
39
+ # - pnpm 11 的 strict-dep-builds 会拦截 node-pty/protobufjs 的构建脚本并使
40
+ # `chatcode-cli plugin add` 非零退出。脚本会先把这两个构建许可写进 profile 的
41
+ # pnpm-workspace.yaml(幂等),保证 CLI 一步成功。
42
+ # - pnpm 11 的 minimumReleaseAge 会拒绝发布 <24h 的新版本。脚本会预写
43
+ # minimumReleaseAgeExclude(幂等),放行本插件,避免"重跑一次才成功"。
44
+ # - 老版本(<0.10.2)用手动挂载行,bundle 通道激活后需移除,否则双挂载。
45
+ # 脚本会幂等移除 better-sidebar 挂载行。
46
+ # =============================================================================
47
+ param(
48
+ [string]$Version = '',
49
+ [switch]$Restart,
50
+ [switch]$DryRun,
51
+ [switch]$Repair,
52
+ [string]$Profile = 'web'
53
+ )
54
+
55
+ $PKG = '@chatcode/cco-better-sidebar'
56
+ $REGISTRY = if ($env:REGISTRY) { $env:REGISTRY } else { 'https://registry.npmjs.org' }
57
+
58
+ # Home 优先级:CHATCODE_CLI_HOME > 兼容 DSH_HOME > %USERPROFILE% > $HOME
59
+ if ($env:CHATCODE_CLI_HOME) {
60
+ $CLI_HOME = $env:CHATCODE_CLI_HOME
61
+ } elseif ($env:DSH_HOME) {
62
+ $CLI_HOME = $env:DSH_HOME
63
+ } elseif ($env:USERPROFILE) {
64
+ $CLI_HOME = Join-Path $env:USERPROFILE '.chatcode-cli'
65
+ } else {
66
+ $CLI_HOME = Join-Path $HOME '.chatcode-cli'
67
+ }
68
+ $PROFILE_DIR = Join-Path $CLI_HOME "profiles\$Profile"
69
+ $WS_YML = Join-Path $PROFILE_DIR 'pnpm-workspace.yaml'
70
+ $PATCH_YML = Join-Path $PROFILE_DIR 'cordis.patch.yml'
71
+
72
+ function Say([string]$m) { Write-Host "[install] $m" -ForegroundColor Green }
73
+ function Warn([string]$m) { Write-Host "[warn] $m" -ForegroundColor Yellow }
74
+ function Die([string]$m) { Write-Host "[error] $m" -ForegroundColor Red; exit 1 }
75
+
76
+ # 解析版本 -> npm spec("x.y.z" / "^x.y.z" / latest)
77
+ function Resolve-Spec {
78
+ param([string]$Given)
79
+ if ([string]::IsNullOrWhiteSpace($Given) -or $Given -eq 'latest') {
80
+ $v = $null
81
+ foreach ($tool in @('npm', 'pnpm')) {
82
+ if (Get-Command $tool -ErrorAction SilentlyContinue) {
83
+ $v = (& $tool view $PKG version "--registry=$REGISTRY" 2>$null | Select-Object -Last 1)
84
+ if ($v) { break }
85
+ }
86
+ }
87
+ if ($v) { return ([string]$v).Trim() }
88
+ Warn '无法联网解析最新版本(npm/pnpm 查询失败),回退为 latest,由 pnpm 直接解析。'
89
+ Warn '若已知版本号,可显式传入:-Version 0.10.2'
90
+ return 'latest'
91
+ }
92
+ return $Given
93
+ }
94
+
95
+ # 组装 ChatCode CLI:正式变量/命令优先,旧变量仅作兼容输入
96
+ function Get-ChatCodeCli {
97
+ if ($env:CHATCODE_CLI_CMD) { return $env:CHATCODE_CLI_CMD }
98
+ if ($env:DSH_CMD) { return $env:DSH_CMD }
99
+ if (Get-Command chatcode-cli -ErrorAction SilentlyContinue) { return 'chatcode-cli' }
100
+ if (Get-Command cco -ErrorAction SilentlyContinue) { return 'cco' }
101
+ if (Get-Command npx -ErrorAction SilentlyContinue) { return 'npx' }
102
+ return $null
103
+ }
104
+
105
+ # 步骤 1(安装与修复共用):预写 workspace 设置(幂等),保证 pnpm 不拦截
106
+ # node-pty/protobufjs 构建脚本、放行本插件新版本
107
+ function Ensure-WorkspaceSettings {
108
+ $wsScript = @'
109
+ const fs = require("fs");
110
+ const p = process.argv[2];
111
+ let t = fs.readFileSync(p, "utf8");
112
+ const before = t;
113
+ t = t.replace(/^(\s*)(node-pty|protobufjs):.*$/gm, "$1$2: true");
114
+ if (!/^\s*allowBuilds:\s*$/m.test(t)) {
115
+ t += "\nallowBuilds:\n node-pty: true\n protobufjs: true\n";
116
+ } else {
117
+ for (const k of ["node-pty", "protobufjs"]) {
118
+ if (!new RegExp("^\\s*" + k + ":\\s*true\\s*$", "m").test(t)) {
119
+ t = t.replace(/^(\s*allowBuilds:\s*)$/m, "$1\n " + k + ": true");
120
+ }
121
+ }
122
+ }
123
+ if (!/^\s*-\s+@chatcode\/cco-better-sidebar\s*$/m.test(t)) {
124
+ if (/^\s*minimumReleaseAgeExclude:\s*$/m.test(t)) {
125
+ t = t.replace(/^(\s*minimumReleaseAgeExclude:\s*)$/m, "$1\n - @chatcode/cco-better-sidebar");
126
+ } else {
127
+ t += "\nminimumReleaseAgeExclude:\n - @chatcode/cco-better-sidebar\n";
128
+ }
129
+ }
130
+ if (t !== before) fs.writeFileSync(p, t);
131
+ console.log(t === before ? "unchanged" : "updated");
132
+ '@
133
+ # PowerShell 5.1 把含内嵌双引号的多行 JS 作为参数传给 `node -e` 时,引号会被
134
+ # Windows 命令行解析吞掉,导致 JS 语法错误(Expected ',', got ':')。
135
+ # 改用临时文件方式,兼容 PS 5.1 与 pwsh 7。
136
+ $wsJs = Join-Path $env:TEMP ("dshbs-ws-" + [guid]::NewGuid().ToString("N") + ".js")
137
+ Set-Content -LiteralPath $wsJs -Value $wsScript -Encoding UTF8
138
+ $wsOut = node $wsJs "$WS_YML" 2>&1
139
+ $wsCode = $LASTEXITCODE
140
+ Remove-Item -LiteralPath $wsJs -Force -ErrorAction SilentlyContinue
141
+ $wsResult = (($wsOut | Out-String)).Trim()
142
+ if ($wsCode -ne 0) { Die "处理 $WS_YML 失败(node 退出码 $wsCode):$wsResult" }
143
+ if ($wsResult -eq 'updated') {
144
+ Say "已确保 $WS_YML:allowBuilds(node-pty/protobufjs: true)+ minimumReleaseAgeExclude($PKG)"
145
+ } else {
146
+ Say 'workspace 设置已就绪,跳过'
147
+ }
148
+ }
149
+
150
+ # 前置校验
151
+ if (-not (Get-Command node -ErrorAction SilentlyContinue)) {
152
+ Die '未找到 node(ChatCode CLI 运行需要 Node.js >= 20),请先安装 Node.js 并加入 PATH。'
153
+ }
154
+ if (-not (Get-Command pnpm -ErrorAction SilentlyContinue)) {
155
+ Die '未找到 pnpm;安装脚本需要 pnpm >= 10。请先安装或升级 pnpm 并加入 PATH。'
156
+ }
157
+ $pnpmVersion = (& pnpm --version 2>$null | Select-Object -Last 1)
158
+ if ($LASTEXITCODE -ne 0 -or -not $pnpmVersion) {
159
+ Die '无法读取 pnpm 版本;安装脚本需要 pnpm >= 10。'
160
+ }
161
+ $pnpmVersionText = ([string]$pnpmVersion).Trim()
162
+ $pnpmMajor = 0
163
+ if (-not [int]::TryParse(($pnpmVersionText -split '\.')[0], [ref]$pnpmMajor)) {
164
+ Die "无法解析 pnpm 版本(输出:$pnpmVersionText);安装脚本需要 pnpm >= 10。"
165
+ }
166
+ if ($pnpmMajor -lt 10) {
167
+ Die "安装脚本需要 pnpm >= 10;当前版本为 $pnpmVersionText。请升级 pnpm 后重试。"
168
+ }
169
+ if (-not (Test-Path $PROFILE_DIR)) {
170
+ Die "找不到 profile 目录:$PROFILE_DIR(请先安装并运行过一次 chatcode-cli web)"
171
+ }
172
+ if (-not (Test-Path $WS_YML)) {
173
+ Die "找不到 $WS_YML(请先初始化 $Profile profile)"
174
+ }
175
+
176
+ # ── 修复模式(issue #140):不重装插件,只修复 node-pty 依赖 ────────────
177
+ # 终端提示「node-pty 加载失败」时运行:确保 allowBuilds 后重跑
178
+ # pnpm install + pnpm rebuild node-pty(重放被 pnpm 11 拦截的构建脚本)。
179
+ if ($Repair) {
180
+ if ($DryRun) {
181
+ Say "[dry-run] 修复:确保 $WS_YML 含 allowBuilds(node-pty: true)"
182
+ Say "[dry-run] 修复:cd $PROFILE_DIR; pnpm install; pnpm rebuild node-pty"
183
+ exit 0
184
+ }
185
+ Say "修复模式:重装 node-pty(profile: $Profile,$PROFILE_DIR)..."
186
+ Ensure-WorkspaceSettings
187
+ Push-Location $PROFILE_DIR
188
+ try {
189
+ pnpm install
190
+ if ($LASTEXITCODE -ne 0) { Die "pnpm install 失败(退出码 $LASTEXITCODE)。请确认 pnpm 在 PATH 上、网络可用,然后重试。" }
191
+ pnpm rebuild node-pty
192
+ if ($LASTEXITCODE -ne 0) { Die "pnpm rebuild node-pty 失败(退出码 $LASTEXITCODE)。请确认 pnpm 在 PATH 上,然后重试。" }
193
+ } finally {
194
+ Pop-Location
195
+ }
196
+ Say '修复完成:node-pty 已重装(与 ChatCode CLI 核心保持同一版本)。请重启 ChatCode CLI 后重试终端。'
197
+ exit 0
198
+ }
199
+
200
+ $SPEC = Resolve-Spec $Version
201
+ $CLI = Get-ChatCodeCli
202
+ if (-not $CLI) {
203
+ Die '未找到 chatcode-cli、cco 或 npx。请先安装 ChatCode CLI(并确保 Node/npm 可用),或用 CHATCODE_CLI_CMD 指定。'
204
+ }
205
+ Say "目标:$CLI plugin --profile $Profile add $PKG@$SPEC(profile: $PROFILE_DIR)"
206
+
207
+ if ($DryRun) {
208
+ Say "[dry-run] 步骤 1:确保 $WS_YML 含 allowBuilds(node-pty/protobufjs: true)与 minimumReleaseAgeExclude($PKG)"
209
+ Say "[dry-run] 步骤 2:执行 $CLI plugin --profile $Profile add $PKG@$SPEC(安装 + bundle 自动注册)"
210
+ Say "[dry-run] 步骤 3:校验 dsh.profile.bundles 含 $PKG"
211
+ Say "[dry-run] 步骤 4:幂等移除 $PATCH_YML 里旧的 better-sidebar 手动挂载行(避免双挂载)"
212
+ if ($Restart) { Say '[dry-run] 步骤 5:pm2 restart chatcode-cli-web' } else { Say '[dry-run] 步骤 5:提示用户手动重启 ChatCode CLI' }
213
+ exit 0
214
+ }
215
+
216
+ # 步骤 1:预写 workspace 设置(幂等),保证 pnpm 不拦截构建、放行本插件新版本
217
+ Ensure-WorkspaceSettings
218
+
219
+ # 步骤 2:官方 CLI 安装 + bundle 自动注册(含挂载)
220
+ if ($CLI -ne 'npx') {
221
+ $cliArgs = @('plugin', '--profile', $Profile, 'add', "$PKG@$SPEC")
222
+ } else {
223
+ $cliArgs = @('-y', '--package', '@chatcode/chatcode-cli', 'chatcode-cli', 'plugin', '--profile', $Profile, 'add', "$PKG@$SPEC")
224
+ }
225
+ Say "执行 $CLI plugin --profile $Profile add $PKG@$SPEC ..."
226
+ $addOut = & $CLI @cliArgs 2>&1
227
+ $addCode = $LASTEXITCODE
228
+ $addOut | ForEach-Object { $_ }
229
+ if ($addCode -ne 0) {
230
+ Warn 'ChatCode CLI plugin add 失败。已预写 allowBuilds 与 minimumReleaseAgeExclude,仍失败的可能原因:'
231
+ Warn ' - 网络/登录问题:npm registry 不可达或需要登录。'
232
+ Warn " - 依赖安装冲突:可手动重试 cd $PROFILE_DIR; pnpm install。"
233
+ exit 1
234
+ }
235
+
236
+ # 步骤 3:校验 bundle 已注册(挂载生效的判据)
237
+ $pkgJson = Get-Content -Raw (Join-Path $PROFILE_DIR 'package.json') | ConvertFrom-Json
238
+ $bundles = $pkgJson.dsh.profile.bundles
239
+ if ($bundles -notcontains $PKG) {
240
+ Warn '@chatcode/cco-better-sidebar 未出现在 dsh.profile.bundles 中——挂载未注册。'
241
+ Warn "若上面的 pnpm 输出提示 ignored build scripts,请确认 $WS_YML 的 allowBuilds 后重跑本脚本。"
242
+ exit 1
243
+ }
244
+ Say "bundle 已注册:dsh.profile.bundles 包含 $PKG(下次启动自动挂载)"
245
+
246
+ # 步骤 4:幂等移除旧的 manual 挂载行(避免与 bundle 双挂载)
247
+ $mountScript = @'
248
+ const fs = require("fs");
249
+ const p = process.argv[2];
250
+ const lines = fs.readFileSync(p, "utf8").split("\n");
251
+ const out = [];
252
+ let i = 0;
253
+ let removed = false;
254
+ while (i < lines.length) {
255
+ const line = lines[i];
256
+ if (/^[ \t]*- insert:\s*$/.test(line)) {
257
+ const block = [line];
258
+ let j = i + 1;
259
+ while (j < lines.length && lines[j].trim() !== "" && !/^-\s/.test(lines[j])) {
260
+ block.push(lines[j]);
261
+ j++;
262
+ }
263
+ if (block.some((l) => /id:\s*better-sidebar\b/.test(l))) {
264
+ while (out.length && /^[ \t]*#/.test(out[out.length - 1])) out.pop();
265
+ i = j;
266
+ removed = true;
267
+ continue;
268
+ }
269
+ }
270
+ out.push(line);
271
+ i++;
272
+ }
273
+ if (!removed) {
274
+ console.log("none");
275
+ } else {
276
+ const t = out.join("\n").replace(/\n{3,}/g, "\n\n");
277
+ fs.writeFileSync(p, t);
278
+ console.log("removed");
279
+ }
280
+ '@
281
+ $mountJs = Join-Path $env:TEMP ("dshbs-mount-" + [guid]::NewGuid().ToString("N") + ".js")
282
+ Set-Content -LiteralPath $mountJs -Value $mountScript -Encoding UTF8
283
+ $mountOut = node $mountJs "$PATCH_YML" 2>&1
284
+ $mountCode = $LASTEXITCODE
285
+ Remove-Item -LiteralPath $mountJs -Force -ErrorAction SilentlyContinue
286
+ $mountResult = (($mountOut | Out-String)).Trim()
287
+ if ($mountCode -ne 0) { Die "处理 $PATCH_YML 失败(node 退出码 $mountCode):$mountResult" }
288
+ if ($mountResult -eq 'removed') {
289
+ Say "已从 $PATCH_YML 移除旧的 better-sidebar 手动挂载行(bundle 通道接管挂载)"
290
+ } else {
291
+ Say '无旧手动挂载行,跳过'
292
+ }
293
+
294
+ Say "安装完成:$PKG@$SPEC"
295
+
296
+ # 步骤 5:重启提示
297
+ if ($Restart) {
298
+ if (Get-Command pm2 -ErrorAction SilentlyContinue) {
299
+ Say '重启 chatcode-cli-web(pm2)...'
300
+ pm2 restart chatcode-cli-web
301
+ if ($LASTEXITCODE -ne 0) { Warn 'pm2 restart 失败,请手动重启 ChatCode CLI' }
302
+ } else {
303
+ Warn '未找到 pm2,请手动重启 ChatCode CLI(如:chatcode-cli web)'
304
+ }
305
+ } else {
306
+ Say '下一步:重启 ChatCode CLI 并硬刷新(Ctrl+Shift+R / Cmd+Shift+R)使新副本生效。'
307
+ if (Get-Command pm2 -ErrorAction SilentlyContinue) {
308
+ Say '本机可用:pm2 restart chatcode-cli-web(会短暂断开当前页面会话)'
309
+ }
310
+ }