@vibe-forge/client 0.8.4 → 0.10.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 (301) hide show
  1. package/AGENTS.md +75 -0
  2. package/dist/assets/abap-DLDM7-KI.js +1 -0
  3. package/dist/assets/apex-DNDY2TF8.js +1 -0
  4. package/dist/assets/{arc-DCuZPvAs.js → arc-CCXV7u3V.js} +1 -1
  5. package/dist/assets/azcli-Y6nb8tq_.js +1 -0
  6. package/dist/assets/bat-BwHxbl9M.js +1 -0
  7. package/dist/assets/bicep-CFznDFnq.js +2 -0
  8. package/dist/assets/{blockDiagram-c4efeb88-C39d7-Bu.js → blockDiagram-c4efeb88-Bm52FmvT.js} +1 -1
  9. package/dist/assets/{c4Diagram-c83219d4-jWPBJdeq.js → c4Diagram-c83219d4-C8tTEpcK.js} +1 -1
  10. package/dist/assets/cameligo-Bf6VGUru.js +1 -0
  11. package/dist/assets/channel-gq_WMRvv.js +1 -0
  12. package/dist/assets/{classDiagram-beda092f-Bo7Yvv2T.js → classDiagram-beda092f-CNAIBAH1.js} +1 -1
  13. package/dist/assets/{classDiagram-v2-2358418a-DfoCP9XM.js → classDiagram-v2-2358418a-BHeZAVdc.js} +1 -1
  14. package/dist/assets/clojure-Dnu-v4kV.js +1 -0
  15. package/dist/assets/clone-XxGY7A5N.js +1 -0
  16. package/dist/assets/codicon-ngg6Pgfi.ttf +0 -0
  17. package/dist/assets/coffee-Bd8akH9Z.js +1 -0
  18. package/dist/assets/cpp-BbWJElDN.js +1 -0
  19. package/dist/assets/{createText-1719965b-8_Ez5rxh.js → createText-1719965b-BS2hLG8t.js} +1 -1
  20. package/dist/assets/csharp-Co3qMtFm.js +1 -0
  21. package/dist/assets/csp-D-4FJmMZ.js +1 -0
  22. package/dist/assets/css-DdJfP1eB.js +3 -0
  23. package/dist/assets/css.worker-BvV5MPou.js +93 -0
  24. package/dist/assets/cssMode-WHcTFAOU.js +1 -0
  25. package/dist/assets/cypher-cTPe9QuQ.js +1 -0
  26. package/dist/assets/dart-BOtBlQCF.js +1 -0
  27. package/dist/assets/dockerfile-BG73LgW2.js +1 -0
  28. package/dist/assets/ecl-BEgZUVRK.js +1 -0
  29. package/dist/assets/{edges-96097737-BEegO-R-.js → edges-96097737-C07f4iWA.js} +1 -1
  30. package/dist/assets/editor.worker-CKy7Pnvo.js +26 -0
  31. package/dist/assets/elixir-BkW5O-1t.js +1 -0
  32. package/dist/assets/{erDiagram-0228fc6a-derRgkLz.js → erDiagram-0228fc6a-BytsAWUs.js} +1 -1
  33. package/dist/assets/flow9-BeJ5waoc.js +1 -0
  34. package/dist/assets/{flowDb-c6c81e3f-ChtOxgsJ.js → flowDb-c6c81e3f-CQJkOpAs.js} +1 -1
  35. package/dist/assets/{flowDiagram-50d868cf-Bm4ufmmA.js → flowDiagram-50d868cf-CD5Tng2S.js} +1 -1
  36. package/dist/assets/flowDiagram-v2-4f6560a1-DIBOANLV.js +1 -0
  37. package/dist/assets/{flowchart-elk-definition-6af322e1-BRYLO-BL.js → flowchart-elk-definition-6af322e1-ylso-GWH.js} +1 -1
  38. package/dist/assets/freemarker2-U_9Jyyr3.js +3 -0
  39. package/dist/assets/fsharp-PahG7c26.js +1 -0
  40. package/dist/assets/{ganttDiagram-a2739b55-CbP6dzRO.js → ganttDiagram-a2739b55-Cg98bJx5.js} +1 -1
  41. package/dist/assets/{gitGraphDiagram-82fe8481-Du44v02s.js → gitGraphDiagram-82fe8481-7Yp4hz0N.js} +1 -1
  42. package/dist/assets/go-acbASCJo.js +1 -0
  43. package/dist/assets/{graph-0_VzJX6O.js → graph-Ig3nvzvL.js} +1 -1
  44. package/dist/assets/graphql-BxJiqAUM.js +1 -0
  45. package/dist/assets/handlebars-DQyCBwHe.js +1 -0
  46. package/dist/assets/hcl-DtV1sZF8.js +1 -0
  47. package/dist/assets/html-CNC2AT5k.js +1 -0
  48. package/dist/assets/html.worker-BLJhxQJQ.js +470 -0
  49. package/dist/assets/htmlMode-DlATk4xW.js +1 -0
  50. package/dist/assets/{index-5325376f-DLP7F7of.js → index-5325376f-C4zed9sb.js} +1 -1
  51. package/dist/assets/index-DRLsOoqb.css +32 -0
  52. package/dist/assets/index-Dbx0JG0p.js +1511 -0
  53. package/dist/assets/{infoDiagram-8eee0895-DY19rRl6.js → infoDiagram-8eee0895-C8oSBaFs.js} +1 -1
  54. package/dist/assets/ini-Kd9XrMLS.js +1 -0
  55. package/dist/assets/java-CXBNlu9o.js +1 -0
  56. package/dist/assets/javascript-9wv9uKW4.js +1 -0
  57. package/dist/assets/{journeyDiagram-c64418c1-4Asnwc86.js → journeyDiagram-c64418c1-D5kJldvy.js} +1 -1
  58. package/dist/assets/json.worker-usMZ-FED.js +58 -0
  59. package/dist/assets/jsonMode-45dv39mU.js +7 -0
  60. package/dist/assets/julia-cl7-CwDS.js +1 -0
  61. package/dist/assets/kotlin-s7OhZKlX.js +1 -0
  62. package/dist/assets/{layout-BILp7GjD.js → layout-DYNFLnIl.js} +1 -1
  63. package/dist/assets/less-9HpZscsL.js +2 -0
  64. package/dist/assets/lexon-OrD6JF1K.js +1 -0
  65. package/dist/assets/{line-D0Xqr8mi.js → line-1gvOYQYZ.js} +1 -1
  66. package/dist/assets/{linear-LpL8RZsq.js → linear-DHGm6Zdw.js} +1 -1
  67. package/dist/assets/liquid-BGoxrdXO.js +1 -0
  68. package/dist/assets/lspLanguageFeatures-CpCCXhrd.js +4 -0
  69. package/dist/assets/lua-Cyyb5UIc.js +1 -0
  70. package/dist/assets/m3-B8OfTtLu.js +1 -0
  71. package/dist/assets/markdown-BFxVWTOG.js +1 -0
  72. package/dist/assets/mdx-Dc2iMbEw.js +1 -0
  73. package/dist/assets/{mermaid.core-Bk0Y_0sz.js → mermaid.core-Cq2bBFF1.js} +6 -6
  74. package/dist/assets/{mindmap-definition-8da855dc-eCAgn5kY.js → mindmap-definition-8da855dc-y5l6GRVh.js} +1 -1
  75. package/dist/assets/mips-CiqrrVzr.js +1 -0
  76. package/dist/assets/msdax-DmeGPVcC.js +1 -0
  77. package/dist/assets/mysql-C_tMU-Nz.js +1 -0
  78. package/dist/assets/objective-c-BDtDVThU.js +1 -0
  79. package/dist/assets/pascal-vHIfCaH5.js +1 -0
  80. package/dist/assets/pascaligo-DtZ0uQbO.js +1 -0
  81. package/dist/assets/perl-Ub6l9XKa.js +1 -0
  82. package/dist/assets/pgsql-BlNEE0v7.js +1 -0
  83. package/dist/assets/php-BBUBE1dy.js +1 -0
  84. package/dist/assets/{pieDiagram-a8764435-BeGFFS1p.js → pieDiagram-a8764435-PNROcv9y.js} +1 -1
  85. package/dist/assets/pla-DSh2-awV.js +1 -0
  86. package/dist/assets/postiats-CocnycG-.js +1 -0
  87. package/dist/assets/powerquery-tScXyioY.js +1 -0
  88. package/dist/assets/powershell-COWaemsV.js +1 -0
  89. package/dist/assets/protobuf-Brw8urJB.js +2 -0
  90. package/dist/assets/pug-8SOpv6rk.js +1 -0
  91. package/dist/assets/python-DjYAge7h.js +1 -0
  92. package/dist/assets/qsharp-Bw9ernYp.js +1 -0
  93. package/dist/assets/{quadrantDiagram-1e28029f-tLqbYOHC.js → quadrantDiagram-1e28029f-CFJ3VPpp.js} +1 -1
  94. package/dist/assets/r-j7ic8hl3.js +1 -0
  95. package/dist/assets/razor-OIY8fx_i.js +1 -0
  96. package/dist/assets/redis-Bu5POkcn.js +1 -0
  97. package/dist/assets/redshift-Bs9aos_-.js +1 -0
  98. package/dist/assets/{requirementDiagram-08caed73-DCverr_g.js → requirementDiagram-08caed73-BpzDIINS.js} +1 -1
  99. package/dist/assets/restructuredtext-CqXO7rUv.js +1 -0
  100. package/dist/assets/ruby-zBfavPgS.js +1 -0
  101. package/dist/assets/rust-BzKRNQWT.js +1 -0
  102. package/dist/assets/{sankeyDiagram-a04cb91d-DidhF5PL.js → sankeyDiagram-a04cb91d-CH69-iIn.js} +1 -1
  103. package/dist/assets/sb-BBc9UKZt.js +1 -0
  104. package/dist/assets/scala-D9hQfWCl.js +1 -0
  105. package/dist/assets/scheme-BPhDTwHR.js +1 -0
  106. package/dist/assets/scss-CBJaRo0y.js +3 -0
  107. package/dist/assets/{sequenceDiagram-c5b8d532-CEKaiwTo.js → sequenceDiagram-c5b8d532-yBBEeVFU.js} +1 -1
  108. package/dist/assets/shell-DiJ1NA_G.js +1 -0
  109. package/dist/assets/solidity-Db0IVjzk.js +1 -0
  110. package/dist/assets/sophia-CnS9iZB_.js +1 -0
  111. package/dist/assets/sparql-CJmd_6j2.js +1 -0
  112. package/dist/assets/sql-ClhHkBeG.js +1 -0
  113. package/dist/assets/st-CHwy0fLd.js +1 -0
  114. package/dist/assets/{stateDiagram-1ecb1508-Cj9ZY7RH.js → stateDiagram-1ecb1508-BvF4sign.js} +1 -1
  115. package/dist/assets/{stateDiagram-v2-c2b004d7-Gsmps-dk.js → stateDiagram-v2-c2b004d7-BeyT7Ghx.js} +1 -1
  116. package/dist/assets/{styles-b4e223ce-D7E8Th0j.js → styles-b4e223ce-C58zxmK6.js} +1 -1
  117. package/dist/assets/{styles-ca3715f6-tTC26Jsm.js → styles-ca3715f6-DCE5sFi5.js} +1 -1
  118. package/dist/assets/{styles-d45a18b0-Bf6oqNdR.js → styles-d45a18b0-CG-C1aM8.js} +1 -1
  119. package/dist/assets/{svgDrawCommon-b86b1483-BxKi01m2.js → svgDrawCommon-b86b1483-F-K8GeDd.js} +1 -1
  120. package/dist/assets/swift-Bqt4WxQ4.js +3 -0
  121. package/dist/assets/systemverilog-Bs9z6M-B.js +1 -0
  122. package/dist/assets/tcl-Dm6ycUr_.js +1 -0
  123. package/dist/assets/{timeline-definition-faaaa080-D6PePEip.js → timeline-definition-faaaa080-DPv4uqVX.js} +1 -1
  124. package/dist/assets/ts.worker-DGHjMaqB.js +67731 -0
  125. package/dist/assets/tsMode-BtU8ZELV.js +11 -0
  126. package/dist/assets/twig-Csy3S7wG.js +1 -0
  127. package/dist/assets/typescript-CJHgISWo.js +1 -0
  128. package/dist/assets/typespec-Btyra-wh.js +1 -0
  129. package/dist/assets/vb-Db0cS2oM.js +1 -0
  130. package/dist/assets/wgsl-BTesnYfV.js +298 -0
  131. package/dist/assets/xml-C_TJw4Bi.js +1 -0
  132. package/dist/assets/{xychartDiagram-f5964ef8-BuP4qfXm.js → xychartDiagram-f5964ef8-BmXlhBzX.js} +1 -1
  133. package/dist/assets/yaml-BujeJOJ6.js +1 -0
  134. package/dist/favicon.svg +3 -3
  135. package/dist/index.html +2 -2
  136. package/package.json +14 -10
  137. package/public/favicon.svg +3 -3
  138. package/src/api/sessions.ts +36 -0
  139. package/src/api/workspace.ts +19 -0
  140. package/src/api.ts +4 -0
  141. package/src/components/NavRail.scss +9 -10
  142. package/src/components/ShortcutDisplay.scss +38 -0
  143. package/src/components/ShortcutDisplay.tsx +37 -0
  144. package/src/components/ShortcutTooltip.scss +36 -0
  145. package/src/components/ShortcutTooltip.tsx +84 -0
  146. package/src/components/Sidebar.scss +55 -13
  147. package/src/components/Sidebar.tsx +141 -52
  148. package/src/components/chat/AGENTS.md +163 -0
  149. package/src/components/chat/ChatHeader.scss +308 -49
  150. package/src/components/chat/ChatHeader.tsx +394 -80
  151. package/src/components/chat/ChatHistoryView.tsx +284 -69
  152. package/src/components/chat/ChatSettingsView.tsx +5 -3
  153. package/src/components/chat/ChatTimelineView.scss +3 -2
  154. package/src/components/chat/{sender/ThinkingStatus.tsx → ThinkingStatus.tsx} +1 -1
  155. package/src/components/chat/messages/MessageContextMenu.scss +145 -0
  156. package/src/components/chat/messages/MessageContextMenu.tsx +108 -0
  157. package/src/components/chat/messages/MessageContextMenuContent.tsx +87 -0
  158. package/src/components/chat/messages/MessageFooter.tsx +44 -24
  159. package/src/components/chat/messages/MessageItem.scss +147 -10
  160. package/src/components/chat/messages/MessageItem.tsx +378 -13
  161. package/src/components/chat/messages/build-message-context-menu-entries.ts +166 -0
  162. package/src/components/chat/messages/message-content-utils.ts +121 -0
  163. package/src/components/chat/messages/message-turns.ts +88 -0
  164. package/src/components/chat/messages/message-utils.ts +19 -1
  165. package/src/components/chat/sender/@components/adapter-select/AdapterSelectControl.scss +86 -0
  166. package/src/components/chat/sender/@components/adapter-select/AdapterSelectControl.tsx +54 -0
  167. package/src/components/chat/sender/@components/adapter-select/AdapterSelectDropdown.scss +42 -0
  168. package/src/components/chat/sender/@components/effort-select/EffortSelectControl.scss +68 -0
  169. package/src/components/chat/sender/@components/effort-select/EffortSelectControl.tsx +137 -0
  170. package/src/components/chat/sender/@components/effort-select/EffortSelectDropdown.scss +96 -0
  171. package/src/components/chat/sender/@components/model-select/ModelSelectControl.scss +82 -0
  172. package/src/components/chat/sender/@components/model-select/ModelSelectControl.tsx +171 -0
  173. package/src/components/chat/sender/@components/model-select/ModelSelectMenu.scss +95 -0
  174. package/src/components/chat/sender/@components/model-select/ModelSelectMenuLabels.scss +144 -0
  175. package/src/components/chat/sender/@components/model-select/ModelSelectOptionLabel.tsx +109 -0
  176. package/src/components/chat/sender/@components/reference-actions/ReferenceActionsControl.scss +106 -0
  177. package/src/components/chat/sender/@components/reference-actions/ReferenceActionsControl.tsx +156 -0
  178. package/src/components/chat/sender/@components/reference-actions/ReferenceActionsOption.scss +34 -0
  179. package/src/components/chat/sender/@components/reference-actions/ReferencePermissionActionsPopover.tsx +111 -0
  180. package/src/components/chat/sender/@components/sender-attachments/SenderAttachments.scss +103 -0
  181. package/src/components/chat/sender/@components/sender-attachments/SenderAttachments.tsx +47 -0
  182. package/src/components/chat/sender/@components/sender-body/SenderBody.tsx +137 -0
  183. package/src/components/chat/sender/@components/sender-interaction-panel/SenderInteractionPanel.scss +178 -0
  184. package/src/components/chat/sender/@components/sender-interaction-panel/SenderInteractionPanel.tsx +145 -0
  185. package/src/components/chat/sender/@components/sender-monaco-editor/SenderMonacoEditor.scss +47 -0
  186. package/src/components/chat/sender/@components/sender-monaco-editor/SenderMonacoEditor.tsx +121 -0
  187. package/src/components/chat/sender/@components/sender-monaco-editor/monaco-runtime.ts +99 -0
  188. package/src/components/chat/sender/@components/sender-monaco-editor/use-sender-editor-handle.ts +48 -0
  189. package/src/components/chat/sender/@components/sender-monaco-editor/use-sender-monaco-editor.ts +209 -0
  190. package/src/components/chat/sender/@components/sender-monaco-editor/use-sender-monaco-theme.ts +24 -0
  191. package/src/components/chat/sender/@components/sender-submit-action/SenderSubmitAction.scss +54 -0
  192. package/src/components/chat/sender/@components/sender-submit-action/SenderSubmitAction.tsx +80 -0
  193. package/src/components/chat/sender/@components/sender-toolbar/SenderSelectBase.scss +71 -0
  194. package/src/components/chat/sender/@components/sender-toolbar/SenderSelectShared.scss +118 -0
  195. package/src/components/chat/sender/@components/sender-toolbar/SenderToolbar.scss +99 -0
  196. package/src/components/chat/sender/@components/sender-toolbar/SenderToolbar.tsx +87 -0
  197. package/src/components/chat/sender/@core/build-sender-controller-result.ts +119 -0
  198. package/src/components/chat/sender/@core/build-sender-toolbar.ts +122 -0
  199. package/src/components/chat/sender/@core/content-attachments.ts +76 -0
  200. package/src/components/chat/sender/@core/create-sender-toolbar-handlers.ts +115 -0
  201. package/src/components/chat/sender/@core/get-sender-interaction-state.ts +18 -0
  202. package/src/components/chat/sender/@core/get-sender-runtime-state.ts +14 -0
  203. package/src/components/chat/sender/@core/interaction-request.ts +5 -0
  204. package/src/components/chat/sender/@core/sender-toolbar-bindings.ts +155 -0
  205. package/src/components/chat/sender/@hooks/use-model-select-browser.tsx +189 -0
  206. package/src/components/chat/sender/@hooks/use-sender-attachments.ts +143 -0
  207. package/src/components/chat/sender/@hooks/use-sender-autofocus.ts +34 -0
  208. package/src/components/chat/sender/@hooks/use-sender-completion.ts +62 -0
  209. package/src/components/chat/sender/@hooks/use-sender-composer-state.ts +34 -0
  210. package/src/components/chat/sender/@hooks/use-sender-controller.ts +193 -0
  211. package/src/components/chat/sender/@hooks/use-sender-focus-restore.ts +72 -0
  212. package/src/components/chat/sender/@hooks/use-sender-history.ts +79 -0
  213. package/src/components/chat/sender/@hooks/use-sender-keydown.ts +113 -0
  214. package/src/components/chat/sender/@hooks/use-sender-reference-actions.ts +191 -0
  215. package/src/components/chat/sender/@hooks/use-sender-reference-focus-restore.ts +21 -0
  216. package/src/components/chat/sender/@hooks/use-sender-refs.ts +19 -0
  217. package/src/components/chat/sender/@hooks/use-sender-select-overlays.ts +83 -0
  218. package/src/components/chat/sender/@hooks/use-sender-shortcuts.ts +78 -0
  219. package/src/components/chat/sender/@hooks/use-sender-submit.ts +81 -0
  220. package/src/components/chat/sender/@types/sender-composer.ts +19 -0
  221. package/src/components/chat/sender/@types/sender-editor.ts +12 -0
  222. package/src/components/chat/sender/@types/sender-props.ts +50 -0
  223. package/src/components/chat/sender/@types/sender-toolbar-types.ts +83 -0
  224. package/src/components/chat/sender/@types/sender-types.ts +21 -0
  225. package/src/components/chat/sender/@utils/sender-completion.ts +164 -0
  226. package/src/components/chat/sender/@utils/sender-constants.ts +18 -0
  227. package/src/components/chat/sender/@utils/sender-utils.ts +45 -0
  228. package/src/components/chat/sender/Sender.scss +8 -605
  229. package/src/components/chat/sender/Sender.tsx +54 -880
  230. package/src/components/chat/session-metadata.ts +55 -0
  231. package/src/components/chat/terminal/@hooks/use-terminal-instance.ts +152 -0
  232. package/src/components/chat/terminal/@hooks/use-terminal-session.ts +196 -0
  233. package/src/components/chat/terminal/ChatTerminalView.scss +62 -0
  234. package/src/components/chat/terminal/ChatTerminalView.tsx +114 -0
  235. package/src/components/chat/tools/core/ToolGroup.scss +7 -0
  236. package/src/components/chat/tools/core/ToolGroup.tsx +97 -56
  237. package/src/components/config/ConfigSectionForm.tsx +8 -1
  238. package/src/components/config/ConfigShortcutInput.tsx +9 -2
  239. package/src/components/config/configSchema.ts +12 -2
  240. package/src/components/config/record-editors/ModelServicesRecordEditor.tsx +0 -14
  241. package/src/components/dock-panel/DockPanel.scss +152 -0
  242. package/src/components/dock-panel/DockPanel.tsx +195 -0
  243. package/src/components/layout/AppShell.scss +40 -2
  244. package/src/components/layout/AppShell.tsx +25 -10
  245. package/src/components/sidebar/SessionContextMenu.scss +143 -0
  246. package/src/components/sidebar/SessionContextMenu.tsx +196 -0
  247. package/src/components/sidebar/SessionContextMenuContent.tsx +89 -0
  248. package/src/components/sidebar/SessionItem.scss +150 -67
  249. package/src/components/sidebar/SessionItem.tsx +183 -134
  250. package/src/components/sidebar/SessionList.scss +47 -17
  251. package/src/components/sidebar/SessionList.tsx +31 -16
  252. package/src/components/sidebar/SidebarHeader.scss +329 -49
  253. package/src/components/sidebar/SidebarHeader.tsx +108 -86
  254. package/src/components/sidebar/SidebarHeaderBatchActions.tsx +81 -0
  255. package/src/components/sidebar/SidebarHeaderSearchActions.tsx +176 -0
  256. package/src/components/sidebar/SidebarHeaderSelectField.tsx +24 -0
  257. package/src/components/sidebar/filter-utils.ts +23 -0
  258. package/src/components/workspace/ContextFilePicker.scss +64 -0
  259. package/src/components/workspace/ContextFilePicker.tsx +171 -0
  260. package/src/connectionManager.ts +4 -2
  261. package/src/hooks/chat/interaction-state.ts +104 -0
  262. package/src/hooks/chat/model-selector-data-builders.ts +146 -0
  263. package/src/hooks/chat/model-selector-data-option-utils.ts +62 -0
  264. package/src/hooks/chat/model-selector-data-types.ts +27 -0
  265. package/src/hooks/chat/model-selector-data.ts +109 -0
  266. package/src/hooks/chat/model-selector-recommendations.ts +69 -0
  267. package/src/hooks/chat/model-selector.ts +9 -0
  268. package/src/hooks/chat/use-chat-interaction.ts +13 -8
  269. package/src/hooks/chat/use-chat-model-adapter-selection.tsx +167 -164
  270. package/src/hooks/chat/use-chat-models.tsx +46 -23
  271. package/src/hooks/chat/use-chat-session-actions.ts +69 -23
  272. package/src/hooks/chat/use-chat-session-messages.ts +165 -60
  273. package/src/hooks/chat/use-chat-session.ts +34 -9
  274. package/src/hooks/chat/use-chat-view.ts +26 -6
  275. package/src/hooks/chat/use-composer-control-shortcuts.ts +69 -0
  276. package/src/hooks/chat/use-terminal-dock-visibility.ts +39 -0
  277. package/src/hooks/use-roving-focus-list.ts +104 -0
  278. package/src/hooks/use-sidebar-navigation.ts +9 -4
  279. package/src/hooks/use-sidebar-query-state.ts +79 -0
  280. package/src/main.tsx +6 -1
  281. package/src/resources/locales/en.json +151 -6
  282. package/src/resources/locales/zh.json +151 -6
  283. package/src/routes/ChatRoute.scss +159 -4
  284. package/src/routes/ChatRoute.tsx +43 -9
  285. package/src/runtime-config.ts +21 -0
  286. package/src/store/index.ts +1 -3
  287. package/src/styles/global.scss +12 -2
  288. package/src/utils/chat-links.ts +21 -0
  289. package/src/utils/copy.ts +18 -0
  290. package/src/utils/shortcutUtils.ts +111 -1
  291. package/src/vite-env.d.ts +1 -0
  292. package/src/ws.ts +6 -5
  293. package/vite.config.ts +71 -7
  294. package/dist/assets/channel-bLjHfx-Q.js +0 -1
  295. package/dist/assets/clone-upfY39Je.js +0 -1
  296. package/dist/assets/flowDiagram-v2-4f6560a1-F66FzZTY.js +0 -1
  297. package/dist/assets/index-C1O04Df8.js +0 -557
  298. package/dist/assets/index-sE8VA1N7.css +0 -1
  299. package/src/components/chat/sender/CompletionMenu.scss +0 -70
  300. package/src/components/chat/sender/CompletionMenu.tsx +0 -58
  301. /package/src/components/chat/{sender/ThinkingStatus.scss → ThinkingStatus.scss} +0 -0
@@ -1,19 +1,44 @@
1
1
  import './ChatHeader.scss'
2
2
 
3
+ import type { Session } from '@vibe-forge/core'
3
4
  import type { SessionInfo } from '@vibe-forge/types'
4
- import { App, Button, Dropdown, Radio } from 'antd'
5
+ import { App, Button, Dropdown, Tooltip } from 'antd'
5
6
  import type { MenuProps } from 'antd'
6
7
  import { useAtomValue } from 'jotai'
7
8
  import { useEffect, useMemo, useRef, useState } from 'react'
8
9
  import { useTranslation } from 'react-i18next'
9
10
 
10
11
  import { deleteSession, getApiErrorMessage, updateSession } from '../../api'
12
+ import { useQueryParams } from '../../hooks/useQueryParams'
11
13
  import { isSidebarCollapsedAtom, isSidebarResizingAtom } from '../../store/index'
12
14
  import { ConfigSectionPanel } from '../config'
13
15
  import type { FieldSpec } from '../config/configSchema'
16
+ import {
17
+ formatToolLabel,
18
+ getSessionAssetWarnings,
19
+ getSessionSelectionWarnings,
20
+ getSessionToolGroups
21
+ } from './session-metadata'
14
22
 
15
23
  export type ChatHeaderView = 'history' | 'timeline' | 'settings'
16
24
 
25
+ interface SessionDebugItem {
26
+ icon: string
27
+ key: string
28
+ label: string
29
+ value: string
30
+ }
31
+
32
+ const DEBUG_MONO_KEYS = new Set([
33
+ 'sessionId',
34
+ 'uuid',
35
+ 'leafUuid',
36
+ 'adapter',
37
+ 'model',
38
+ 'version',
39
+ 'cwd'
40
+ ])
41
+
17
42
  export function ChatHeader({
18
43
  sessionInfo,
19
44
  sessionId,
@@ -24,7 +49,9 @@ export function ChatHeader({
24
49
  lastMessage,
25
50
  lastUserMessage,
26
51
  activeView,
27
- onViewChange
52
+ isTerminalOpen,
53
+ onViewChange,
54
+ onToggleTerminal
28
55
  }: {
29
56
  sessionInfo: SessionInfo | null
30
57
  sessionId?: string
@@ -35,17 +62,28 @@ export function ChatHeader({
35
62
  lastMessage?: string
36
63
  lastUserMessage?: string
37
64
  activeView: ChatHeaderView
65
+ isTerminalOpen: boolean
38
66
  onViewChange: (view: ChatHeaderView) => void
67
+ onToggleTerminal: () => void
39
68
  }) {
40
69
  const { t } = useTranslation()
41
70
  const { message } = App.useApp()
42
71
  const isSidebarCollapsed = useAtomValue(isSidebarCollapsedAtom)
43
72
  const isResizing = useAtomValue(isSidebarResizingAtom)
44
- const [editTitle, setEditTitle] = useState('')
73
+ const { searchParams, update: updateQuery } = useQueryParams<{ debug: string }>({
74
+ keys: ['debug'],
75
+ omit: {
76
+ debug: value => value === ''
77
+ }
78
+ })
79
+ const titleClickCountRef = useRef(0)
80
+ const titleClickTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)
81
+ const hasDebugQuery = searchParams.has('debug')
82
+ const isDebugMode = searchParams.get('debug') === 'true'
83
+ const shouldShowDebugButton = hasDebugQuery
45
84
 
46
85
  const summary = sessionInfo?.type === 'summary' ? sessionInfo.summary : null
47
86
  const title = (sessionInfo?.type === 'init' ? sessionInfo.title : null) ?? sessionTitle
48
- const cwd = sessionInfo?.type === 'init' ? sessionInfo.cwd : null
49
87
  const displayTitle = (title != null && title !== '')
50
88
  ? title
51
89
  : (summary != null && summary !== '')
@@ -55,12 +93,15 @@ export function ChatHeader({
55
93
  : (lastMessage != null && lastMessage !== '')
56
94
  ? lastMessage
57
95
  : t('common.newChat')
96
+ const toggleDebugMode = () => {
97
+ updateQuery({ debug: isDebugMode ? 'false' : 'true' })
98
+ }
58
99
 
59
- useEffect(() => {
60
- if (title != null && title !== '') {
61
- setEditTitle(title)
62
- }
63
- }, [title])
100
+ const viewItems = [
101
+ { value: 'history' as const, icon: 'forum', title: t('chat.viewHistory') },
102
+ { value: 'timeline' as const, icon: 'timeline', title: t('chat.viewTimeline') },
103
+ { value: 'settings' as const, icon: 'tune', title: t('chat.viewSettings') }
104
+ ]
64
105
 
65
106
  const handleToggleStar = async () => {
66
107
  if (sessionId == null || sessionId === '') return
@@ -86,7 +127,7 @@ export function ChatHeader({
86
127
  {
87
128
  key: 'star',
88
129
  label: isStarred ? t('common.unstar') : t('common.star'),
89
- icon: <span className={`material-symbols-rounded ${isStarred ? 'is-filled' : ''}`} style={{ fontSize: '18px' }}>
130
+ icon: <span className={`material-symbols-rounded chat-header-icon ${isStarred ? 'is-filled' : ''}`}>
90
131
  {isStarred ? 'star' : 'star_border'}
91
132
  </span>,
92
133
  onClick: () => {
@@ -96,7 +137,7 @@ export function ChatHeader({
96
137
  {
97
138
  key: 'archive',
98
139
  label: isArchived ? t('common.restore') : t('common.archive'),
99
- icon: <span className='material-symbols-rounded' style={{ fontSize: '18px' }}>
140
+ icon: <span className='material-symbols-rounded chat-header-icon'>
100
141
  {isArchived ? 'unarchive' : 'archive'}
101
142
  </span>,
102
143
  onClick: () => {
@@ -105,97 +146,125 @@ export function ChatHeader({
105
146
  }
106
147
  ]
107
148
 
149
+ useEffect(() => {
150
+ return () => {
151
+ if (titleClickTimerRef.current != null) {
152
+ clearTimeout(titleClickTimerRef.current)
153
+ }
154
+ }
155
+ }, [])
156
+
157
+ const handleTitleClick = () => {
158
+ if (titleClickTimerRef.current != null) {
159
+ clearTimeout(titleClickTimerRef.current)
160
+ }
161
+
162
+ titleClickCountRef.current += 1
163
+
164
+ if (titleClickCountRef.current >= 5) {
165
+ titleClickCountRef.current = 0
166
+ titleClickTimerRef.current = null
167
+ toggleDebugMode()
168
+ // eslint-disable-next-line no-console
169
+ console.log('Session Full Info:', {
170
+ sessionId,
171
+ sessionTitle,
172
+ isStarred,
173
+ isArchived,
174
+ tags,
175
+ lastMessage,
176
+ lastUserMessage,
177
+ sessionInfo
178
+ })
179
+ return
180
+ }
181
+
182
+ titleClickTimerRef.current = setTimeout(() => {
183
+ titleClickCountRef.current = 0
184
+ titleClickTimerRef.current = null
185
+ }, 500)
186
+ }
187
+
108
188
  return (
109
189
  <div className={`chat-header ${isSidebarCollapsed ? 'is-collapsed' : ''} ${isResizing ? 'is-resizing' : ''}`}>
110
- <div style={{ display: 'flex', alignItems: 'center', gap: '12px', flex: 1, minWidth: 0 }}>
190
+ <div className='chat-header-main'>
111
191
  <div className='chat-header-info'>
112
- <div className='chat-header-title'>
113
- {displayTitle}
114
- </div>
115
192
  <div
116
- className='chat-header-subtitle'
117
- onDoubleClick={() => {
118
- // eslint-disable-next-line no-console
119
- console.log('Session Full Info:', {
120
- sessionId,
121
- sessionTitle,
122
- isStarred,
123
- isArchived,
124
- tags,
125
- lastMessage,
126
- lastUserMessage,
127
- sessionInfo
128
- })
129
- }}
130
- style={{ cursor: 'pointer', userSelect: 'all' }}
193
+ className='chat-header-title'
194
+ onClick={handleTitleClick}
131
195
  >
132
- {sessionId ?? t('chat.selectModel')}
196
+ {displayTitle}
133
197
  </div>
134
198
  </div>
135
199
  </div>
136
200
 
137
201
  <div className='chat-header-actions'>
138
- <Radio.Group
139
- className='chat-header-view-group'
140
- value={activeView}
141
- optionType='button'
142
- buttonStyle='solid'
143
- size='small'
144
- onChange={(event) => {
145
- onViewChange(event.target.value as ChatHeaderView)
146
- }}
147
- options={[
148
- {
149
- label: (
150
- <span className='chat-header-view-option material-symbols-rounded'>
151
- forum
152
- </span>
153
- ),
154
- value: 'history'
155
- },
156
- {
157
- label: (
158
- <span className='chat-header-view-option material-symbols-rounded'>
159
- timeline
160
- </span>
161
- ),
162
- value: 'timeline'
163
- },
164
- {
165
- label: (
166
- <span className='chat-header-view-option material-symbols-rounded'>
167
- tune
168
- </span>
169
- ),
170
- value: 'settings'
171
- }
172
- ]}
173
- />
174
- <div className='chat-header-divider' />
175
- <Dropdown menu={{ items: moreItems }} placement='bottomRight' trigger={['click']}>
202
+ {viewItems.map(item => (
203
+ <Tooltip key={item.value} title={item.title}>
204
+ <Button
205
+ type='text'
206
+ className={`chat-header-action-button ${activeView === item.value ? 'is-active' : ''}`}
207
+ title={item.title}
208
+ aria-label={item.title}
209
+ onClick={() => {
210
+ onViewChange(item.value)
211
+ }}
212
+ icon={<span className='chat-header-view-option material-symbols-rounded'>{item.icon}</span>}
213
+ />
214
+ </Tooltip>
215
+ ))}
216
+ <Tooltip title={t('chat.viewTerminal')}>
176
217
  <Button
177
218
  type='text'
178
- icon={<span className='material-symbols-rounded'>more_vert</span>}
219
+ className={`chat-header-action-button ${isTerminalOpen ? 'is-active' : ''}`}
220
+ title={t('chat.viewTerminal')}
221
+ aria-label={t('chat.viewTerminal')}
222
+ onClick={onToggleTerminal}
223
+ icon={<span className='chat-header-view-option material-symbols-rounded'>terminal</span>}
179
224
  />
180
- </Dropdown>
225
+ </Tooltip>
226
+ {shouldShowDebugButton && (
227
+ <Tooltip title={isDebugMode ? t('chat.debugDisable') : t('chat.debugEnable')}>
228
+ <Button
229
+ type='text'
230
+ className={`chat-header-action-button ${isDebugMode ? 'is-debug-active' : ''}`}
231
+ title={isDebugMode ? t('chat.debugDisable') : t('chat.debugEnable')}
232
+ aria-label={isDebugMode ? t('chat.debugDisable') : t('chat.debugEnable')}
233
+ onClick={toggleDebugMode}
234
+ icon={<span className='chat-header-view-option material-symbols-rounded'>bug_report</span>}
235
+ />
236
+ </Tooltip>
237
+ )}
238
+ <Tooltip title={t('common.moreActions')}>
239
+ <Dropdown menu={{ items: moreItems }} placement='bottomRight' trigger={['click']}>
240
+ <Button
241
+ type='text'
242
+ className='chat-header-action-button'
243
+ title={t('common.moreActions')}
244
+ aria-label={t('common.moreActions')}
245
+ icon={<span className='chat-header-view-option material-symbols-rounded'>more_vert</span>}
246
+ />
247
+ </Dropdown>
248
+ </Tooltip>
181
249
  </div>
182
250
  </div>
183
251
  )
184
252
  }
185
253
 
186
254
  export function SessionSettingsPanel({
187
- sessionId,
188
- initialTitle,
189
- initialTags = [],
255
+ session,
256
+ sessionInfo,
190
257
  onClose
191
258
  }: {
192
- sessionId: string
193
- initialTitle?: string
194
- initialTags?: string[]
259
+ session: Session
260
+ sessionInfo: SessionInfo | null
195
261
  onClose: () => void
196
262
  }) {
197
263
  const { t } = useTranslation()
198
264
  const { message, modal } = App.useApp()
265
+ const { searchParams } = useQueryParams<{ debug: string }>({ keys: ['debug'] })
266
+ const isDebugMode = searchParams.get('debug') === 'true'
267
+ const sessionId = session.id
199
268
  const fields = useMemo<FieldSpec[]>(() => [
200
269
  {
201
270
  path: ['title'],
@@ -214,10 +283,11 @@ export function SessionSettingsPanel({
214
283
  }
215
284
  ], [])
216
285
  const initialValue = useMemo(() => ({
217
- title: initialTitle ?? '',
218
- tags: initialTags
219
- }), [initialTags, initialTitle])
286
+ title: session.title ?? '',
287
+ tags: session.tags ?? []
288
+ }), [session.tags, session.title])
220
289
  const [draft, setDraft] = useState(initialValue)
290
+ const [collapsedToolGroupKeys, setCollapsedToolGroupKeys] = useState<Record<string, boolean>>({})
221
291
  const draftsRef = useRef(initialValue)
222
292
  const saveTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)
223
293
  const savingRef = useRef(false)
@@ -239,6 +309,141 @@ export function SessionSettingsPanel({
239
309
  }
240
310
  }, [])
241
311
 
312
+ const toolGroups = useMemo(() => getSessionToolGroups(sessionInfo), [sessionInfo])
313
+ const assetWarnings = useMemo(() => getSessionAssetWarnings(sessionInfo), [sessionInfo])
314
+ const selectionWarnings = useMemo(() => getSessionSelectionWarnings(sessionInfo), [sessionInfo])
315
+ const debugItems = useMemo<SessionDebugItem[]>(() => {
316
+ const emptyValue = t('chat.timelineEmptyValue')
317
+ const booleanValue = (value: boolean | undefined) =>
318
+ value ? t('chat.debugEnabledValue') : t('chat.debugDisabledValue')
319
+ const tags = session.tags ?? []
320
+ const items: SessionDebugItem[] = [
321
+ {
322
+ key: 'sessionId',
323
+ label: t('chat.debugSessionId'),
324
+ value: session.id,
325
+ icon: 'fingerprint'
326
+ },
327
+ {
328
+ key: 'view',
329
+ label: t('chat.debugView'),
330
+ value: t('chat.viewSettings'),
331
+ icon: 'tune'
332
+ },
333
+ {
334
+ key: 'starred',
335
+ label: t('chat.debugStarred'),
336
+ value: booleanValue(session.isStarred),
337
+ icon: 'star'
338
+ },
339
+ {
340
+ key: 'archived',
341
+ label: t('chat.debugArchived'),
342
+ value: booleanValue(session.isArchived),
343
+ icon: 'archive'
344
+ }
345
+ ]
346
+
347
+ if (tags.length > 0) {
348
+ items.push({
349
+ key: 'tags',
350
+ label: t('chat.debugTags'),
351
+ value: tags.join(', '),
352
+ icon: 'sell'
353
+ })
354
+ }
355
+
356
+ if (sessionInfo?.type === 'init') {
357
+ items.push(
358
+ {
359
+ key: 'type',
360
+ label: t('chat.debugType'),
361
+ value: sessionInfo.type,
362
+ icon: 'deployed_code'
363
+ },
364
+ {
365
+ key: 'uuid',
366
+ label: t('chat.debugUuid'),
367
+ value: sessionInfo.uuid,
368
+ icon: 'tag'
369
+ },
370
+ {
371
+ key: 'adapter',
372
+ label: t('chat.debugAdapter'),
373
+ value: sessionInfo.adapter ?? emptyValue,
374
+ icon: 'extension'
375
+ },
376
+ {
377
+ key: 'model',
378
+ label: t('chat.debugModel'),
379
+ value: sessionInfo.model,
380
+ icon: 'model_training'
381
+ },
382
+ {
383
+ key: 'effort',
384
+ label: t('chat.debugEffort'),
385
+ value: sessionInfo.effort ?? emptyValue,
386
+ icon: 'psychology'
387
+ },
388
+ {
389
+ key: 'version',
390
+ label: t('chat.debugVersion'),
391
+ value: sessionInfo.version,
392
+ icon: 'deployed_code_update'
393
+ },
394
+ {
395
+ key: 'tools',
396
+ label: t('chat.debugTools'),
397
+ value: String(sessionInfo.tools.length),
398
+ icon: 'handyman'
399
+ },
400
+ {
401
+ key: 'agents',
402
+ label: t('chat.debugAgents'),
403
+ value: String(sessionInfo.agents.length),
404
+ icon: 'hub'
405
+ },
406
+ {
407
+ key: 'cwd',
408
+ label: t('chat.debugCwd'),
409
+ value: sessionInfo.cwd,
410
+ icon: 'folder_open'
411
+ }
412
+ )
413
+ }
414
+
415
+ if (sessionInfo?.type === 'summary') {
416
+ items.push(
417
+ {
418
+ key: 'type',
419
+ label: t('chat.debugType'),
420
+ value: sessionInfo.type,
421
+ icon: 'deployed_code'
422
+ },
423
+ {
424
+ key: 'leafUuid',
425
+ label: t('chat.debugLeafUuid'),
426
+ value: sessionInfo.leafUuid,
427
+ icon: 'call_split'
428
+ }
429
+ )
430
+ }
431
+ return items
432
+ }, [session.id, session.isArchived, session.isStarred, session.tags, sessionInfo, t])
433
+
434
+ const formatSelectionWarning = (warning: (typeof selectionWarnings)[number]) => {
435
+ const reason = warning.reason === 'excluded'
436
+ ? t('chat.selectionWarningReasonExcluded')
437
+ : t('chat.selectionWarningReasonNotIncluded')
438
+
439
+ return t('chat.selectionWarningFallback', {
440
+ adapter: warning.adapter,
441
+ requestedModel: warning.requestedModel,
442
+ resolvedModel: warning.resolvedModel,
443
+ reason
444
+ })
445
+ }
446
+
242
447
  const scheduleSave = (nextValue: { title: string; tags: string[] }) => {
243
448
  const serialized = JSON.stringify(nextValue ?? {})
244
449
  if (lastSavedRef.current === serialized) return
@@ -298,6 +503,13 @@ export function SessionSettingsPanel({
298
503
  })
299
504
  }
300
505
 
506
+ const toggleToolGroup = (key: string) => {
507
+ setCollapsedToolGroupKeys((prev) => ({
508
+ ...prev,
509
+ [key]: !prev[key]
510
+ }))
511
+ }
512
+
301
513
  return (
302
514
  <div className='session-settings-drawer'>
303
515
  <ConfigSectionPanel
@@ -314,6 +526,108 @@ export function SessionSettingsPanel({
314
526
  className='session-settings-drawer__form'
315
527
  />
316
528
 
529
+ <div className='settings-section session-runtime-section'>
530
+ <div className='section-header'>
531
+ <span className='material-symbols-rounded'>build</span>
532
+ <span>{t('chat.availableTools')}</span>
533
+ </div>
534
+
535
+ {selectionWarnings.length > 0 && (
536
+ <div className='session-info-note-list'>
537
+ <div className='session-info-note-list__title'>{t('chat.selectionWarningsTitle')}</div>
538
+ {selectionWarnings.map((warning, index) => (
539
+ <div
540
+ key={`${warning.adapter}:${warning.requestedModel}:${warning.resolvedModel}:${index}`}
541
+ className='session-info-note session-info-note--warning'
542
+ >
543
+ <span className='material-symbols-rounded'>warning</span>
544
+ <span>{formatSelectionWarning(warning)}</span>
545
+ </div>
546
+ ))}
547
+ </div>
548
+ )}
549
+
550
+ {assetWarnings.length > 0 && (
551
+ <div className='session-info-note-list'>
552
+ <div className='session-info-note-list__title'>{t('chat.assetWarningsTitle')}</div>
553
+ {assetWarnings.map((warning) => (
554
+ <div key={warning.assetId} className='session-info-note'>
555
+ <span className='material-symbols-rounded'>warning</span>
556
+ <div className='session-info-note__content'>
557
+ <code>{warning.assetId}</code>
558
+ <span>{warning.reason}</span>
559
+ </div>
560
+ </div>
561
+ ))}
562
+ </div>
563
+ )}
564
+
565
+ {toolGroups.length > 0
566
+ ? (
567
+ <div className='session-tool-groups'>
568
+ {toolGroups.map((group) => (
569
+ <div key={group.key} className='session-tool-group-card'>
570
+ <button
571
+ type='button'
572
+ className='session-tool-group-card__header'
573
+ onClick={() => toggleToolGroup(group.key)}
574
+ >
575
+ <div className='session-tool-group-card__title'>
576
+ <span className='material-symbols-rounded'>{group.icon}</span>
577
+ <span>{t(group.labelKey)}</span>
578
+ </div>
579
+ <div className='session-tool-group-card__meta'>
580
+ <span className='session-tool-group-card__count'>{group.tools.length}</span>
581
+ <span className='material-symbols-rounded session-tool-group-card__expand'>
582
+ {collapsedToolGroupKeys[group.key] ? 'expand_more' : 'expand_less'}
583
+ </span>
584
+ </div>
585
+ </button>
586
+ {!collapsedToolGroupKeys[group.key] && (
587
+ <div className='session-tool-group-card__list'>
588
+ {group.tools.map(tool => (
589
+ <div key={tool} className='session-tool-row' title={formatToolLabel(tool)}>
590
+ <span className='session-tool-row__dot' />
591
+ <code>{formatToolLabel(tool)}</code>
592
+ </div>
593
+ ))}
594
+ </div>
595
+ )}
596
+ </div>
597
+ ))}
598
+ </div>
599
+ )
600
+ : (
601
+ <div className='session-settings-empty'>
602
+ {t('chat.availableToolsEmpty')}
603
+ </div>
604
+ )}
605
+ </div>
606
+
607
+ {isDebugMode && debugItems.length > 0 && (
608
+ <div className='settings-section session-debug-section'>
609
+ <div className='section-header'>
610
+ <span className='material-symbols-rounded'>bug_report</span>
611
+ <span>{t('chat.debugSectionTitle')}</span>
612
+ </div>
613
+
614
+ <div className='session-debug-panel'>
615
+ <div className='session-debug-list'>
616
+ {debugItems.map(item => (
617
+ <div key={item.key} className='session-debug-row'>
618
+ <span className='session-debug-row__label'>{item.label}</span>
619
+ <span
620
+ className={`session-debug-row__value ${DEBUG_MONO_KEYS.has(item.key) ? 'is-mono' : ''}`}
621
+ >
622
+ {item.value}
623
+ </span>
624
+ </div>
625
+ ))}
626
+ </div>
627
+ </div>
628
+ </div>
629
+ )}
630
+
317
631
  <div className='settings-footer'>
318
632
  <div className='danger-zone'>
319
633
  <div className='delete-session-row'>