@vibe-forge/client 0.9.0 → 0.10.1

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-D9HxM0yv.js → arc-C1rWFTer.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-C_pTeiD4.js → blockDiagram-c4efeb88-DlZ9x70F.js} +1 -1
  9. package/dist/assets/{c4Diagram-c83219d4-_oYrCrLr.js → c4Diagram-c83219d4-BKKxi__y.js} +1 -1
  10. package/dist/assets/cameligo-Bf6VGUru.js +1 -0
  11. package/dist/assets/channel-F1aqMANO.js +1 -0
  12. package/dist/assets/{classDiagram-beda092f-9dnkgPhR.js → classDiagram-beda092f-CVGPySZq.js} +1 -1
  13. package/dist/assets/{classDiagram-v2-2358418a-BUIeZpdO.js → classDiagram-v2-2358418a-7kp8GVVj.js} +1 -1
  14. package/dist/assets/clojure-Dnu-v4kV.js +1 -0
  15. package/dist/assets/clone-B-GCuXNo.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-DuRFplcD.js → createText-1719965b-Dykv8kT9.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-B59COYVW.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-CTpq6Ih_.js → edges-96097737-CkZ1ZBro.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-CWFgdO1E.js → erDiagram-0228fc6a-281ADcRp.js} +1 -1
  33. package/dist/assets/flow9-BeJ5waoc.js +1 -0
  34. package/dist/assets/{flowDb-c6c81e3f-8Vdx29oZ.js → flowDb-c6c81e3f-BQjX_flP.js} +1 -1
  35. package/dist/assets/{flowDiagram-50d868cf-6S9wOVNl.js → flowDiagram-50d868cf-DMHZTjES.js} +1 -1
  36. package/dist/assets/flowDiagram-v2-4f6560a1-C5FzdVl1.js +1 -0
  37. package/dist/assets/{flowchart-elk-definition-6af322e1-DVcZ-ZBQ.js → flowchart-elk-definition-6af322e1-CI3yz4z8.js} +1 -1
  38. package/dist/assets/freemarker2-DWnWjibn.js +3 -0
  39. package/dist/assets/fsharp-PahG7c26.js +1 -0
  40. package/dist/assets/{ganttDiagram-a2739b55-DY1QSl-x.js → ganttDiagram-a2739b55-B3IING9L.js} +1 -1
  41. package/dist/assets/{gitGraphDiagram-82fe8481-BP08OBKL.js → gitGraphDiagram-82fe8481-CnArIr_T.js} +1 -1
  42. package/dist/assets/go-acbASCJo.js +1 -0
  43. package/dist/assets/{graph-D8GCszcN.js → graph-BZ1F0Yve.js} +1 -1
  44. package/dist/assets/graphql-BxJiqAUM.js +1 -0
  45. package/dist/assets/handlebars-C1QH9qTz.js +1 -0
  46. package/dist/assets/hcl-DtV1sZF8.js +1 -0
  47. package/dist/assets/html-D1NkqHjC.js +1 -0
  48. package/dist/assets/html.worker-BLJhxQJQ.js +470 -0
  49. package/dist/assets/htmlMode-DAZCE_rA.js +1 -0
  50. package/dist/assets/{index-5325376f-OOoAXU1u.js → index-5325376f-Da9zSHjA.js} +1 -1
  51. package/dist/assets/index-C0vjF3D0.js +1511 -0
  52. package/dist/assets/index-vzEbM21t.css +32 -0
  53. package/dist/assets/{infoDiagram-8eee0895-BHgkXjhJ.js → infoDiagram-8eee0895-DYbFvRM7.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-CoMjGRHa.js +1 -0
  57. package/dist/assets/{journeyDiagram-c64418c1-BljInElp.js → journeyDiagram-c64418c1-Boebox0b.js} +1 -1
  58. package/dist/assets/json.worker-usMZ-FED.js +58 -0
  59. package/dist/assets/jsonMode-D__gAvuz.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-Cw-SwAFD.js → layout-CTcHNbHp.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-Q-uZLuUr.js → line-4AwinCz2.js} +1 -1
  66. package/dist/assets/{linear-BahOnNn3.js → linear-CeSMLzJW.js} +1 -1
  67. package/dist/assets/liquid-DZF6egdE.js +1 -0
  68. package/dist/assets/lspLanguageFeatures-6K4lv5S2.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-Cnt4ka6w.js +1 -0
  73. package/dist/assets/{mermaid.core-BR0Qh3Rd.js → mermaid.core-B0yG5s4D.js} +6 -6
  74. package/dist/assets/{mindmap-definition-8da855dc-Brq2OJUZ.js → mindmap-definition-8da855dc-KJEvXMKj.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-uhYdiXro.js → pieDiagram-a8764435-17nFAXPJ.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-DA3TtjDv.js +1 -0
  92. package/dist/assets/qsharp-Bw9ernYp.js +1 -0
  93. package/dist/assets/{quadrantDiagram-1e28029f-TwqtEe7e.js → quadrantDiagram-1e28029f-Dt4vubi-.js} +1 -1
  94. package/dist/assets/r-j7ic8hl3.js +1 -0
  95. package/dist/assets/razor-CWDJgvX_.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-DSXnPRDS.js → requirementDiagram-08caed73-H6aDyDK-.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-EADpJeAn.js → sankeyDiagram-a04cb91d-DxsVtbjI.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-C8qXvt9z.js → sequenceDiagram-c5b8d532-BHa148XJ.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-5W0ghy_S.js → stateDiagram-1ecb1508-DgwBm8LO.js} +1 -1
  115. package/dist/assets/{stateDiagram-v2-c2b004d7-BfwOQJw4.js → stateDiagram-v2-c2b004d7-BK7IQLVc.js} +1 -1
  116. package/dist/assets/{styles-b4e223ce-EkKH_ULb.js → styles-b4e223ce-DzW27Bc-.js} +1 -1
  117. package/dist/assets/{styles-ca3715f6-DwhrtqlU.js → styles-ca3715f6-Dex2GiLT.js} +1 -1
  118. package/dist/assets/{styles-d45a18b0-yqL8KH6x.js → styles-d45a18b0-B6fGtDKS.js} +1 -1
  119. package/dist/assets/{svgDrawCommon-b86b1483--5VjnjhC.js → svgDrawCommon-b86b1483-B4HYgfV5.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-CWOTwik9.js → timeline-definition-faaaa080--QSbWb25.js} +1 -1
  124. package/dist/assets/ts.worker-DGHjMaqB.js +67731 -0
  125. package/dist/assets/tsMode-ZM7ocZCH.js +11 -0
  126. package/dist/assets/twig-Csy3S7wG.js +1 -0
  127. package/dist/assets/typescript-CKWDmBCc.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-DuEUAzPi.js +1 -0
  132. package/dist/assets/{xychartDiagram-f5964ef8-CZg47H1t.js → xychartDiagram-f5964ef8-D09Zkv2K.js} +1 -1
  133. package/dist/assets/yaml-DL7QPRYk.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 +353 -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 +157 -10
  160. package/src/components/chat/messages/MessageItem.tsx +382 -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/sender-toolbar-bindings.ts +155 -0
  204. package/src/components/chat/sender/@hooks/use-model-select-browser.tsx +189 -0
  205. package/src/components/chat/sender/@hooks/use-sender-attachments.ts +143 -0
  206. package/src/components/chat/sender/@hooks/use-sender-autofocus.ts +34 -0
  207. package/src/components/chat/sender/@hooks/use-sender-completion.ts +62 -0
  208. package/src/components/chat/sender/@hooks/use-sender-composer-state.ts +34 -0
  209. package/src/components/chat/sender/@hooks/use-sender-controller.ts +193 -0
  210. package/src/components/chat/sender/@hooks/use-sender-focus-restore.ts +72 -0
  211. package/src/components/chat/sender/@hooks/use-sender-history.ts +79 -0
  212. package/src/components/chat/sender/@hooks/use-sender-keydown.ts +113 -0
  213. package/src/components/chat/sender/@hooks/use-sender-reference-actions.ts +191 -0
  214. package/src/components/chat/sender/@hooks/use-sender-reference-focus-restore.ts +21 -0
  215. package/src/components/chat/sender/@hooks/use-sender-refs.ts +19 -0
  216. package/src/components/chat/sender/@hooks/use-sender-select-overlays.ts +83 -0
  217. package/src/components/chat/sender/@hooks/use-sender-shortcuts.ts +78 -0
  218. package/src/components/chat/sender/@hooks/use-sender-submit.ts +81 -0
  219. package/src/components/chat/sender/@types/sender-composer.ts +19 -0
  220. package/src/components/chat/sender/@types/sender-editor.ts +12 -0
  221. package/src/components/chat/sender/@types/sender-props.ts +50 -0
  222. package/src/components/chat/sender/@types/sender-toolbar-types.ts +83 -0
  223. package/src/components/chat/sender/@types/sender-types.ts +21 -0
  224. package/src/components/chat/sender/@utils/sender-completion.ts +164 -0
  225. package/src/components/chat/sender/@utils/sender-constants.ts +18 -0
  226. package/src/components/chat/sender/@utils/sender-utils.ts +45 -0
  227. package/src/components/chat/sender/Sender.scss +6 -737
  228. package/src/components/chat/sender/Sender.tsx +53 -921
  229. package/src/components/chat/session-metadata.ts +55 -0
  230. package/src/components/chat/terminal/@hooks/use-terminal-instance.ts +152 -0
  231. package/src/components/chat/terminal/@hooks/use-terminal-session.ts +196 -0
  232. package/src/components/chat/terminal/ChatTerminalView.scss +62 -0
  233. package/src/components/chat/terminal/ChatTerminalView.tsx +114 -0
  234. package/src/components/chat/tools/core/ToolGroup.scss +7 -0
  235. package/src/components/chat/tools/core/ToolGroup.tsx +94 -44
  236. package/src/components/config/ConfigSectionForm.tsx +8 -1
  237. package/src/components/config/ConfigShortcutInput.tsx +9 -2
  238. package/src/components/config/configSchema.ts +12 -2
  239. package/src/components/config/record-editors/ModelServicesRecordEditor.tsx +0 -14
  240. package/src/components/dock-panel/DockPanel.scss +152 -0
  241. package/src/components/dock-panel/DockPanel.tsx +195 -0
  242. package/src/components/layout/AppShell.scss +40 -2
  243. package/src/components/layout/AppShell.tsx +25 -10
  244. package/src/components/sidebar/SessionContextMenu.scss +143 -0
  245. package/src/components/sidebar/SessionContextMenu.tsx +196 -0
  246. package/src/components/sidebar/SessionContextMenuContent.tsx +89 -0
  247. package/src/components/sidebar/SessionItem.scss +150 -67
  248. package/src/components/sidebar/SessionItem.tsx +183 -134
  249. package/src/components/sidebar/SessionList.scss +47 -17
  250. package/src/components/sidebar/SessionList.tsx +31 -16
  251. package/src/components/sidebar/SidebarHeader.scss +329 -49
  252. package/src/components/sidebar/SidebarHeader.tsx +108 -86
  253. package/src/components/sidebar/SidebarHeaderBatchActions.tsx +81 -0
  254. package/src/components/sidebar/SidebarHeaderSearchActions.tsx +176 -0
  255. package/src/components/sidebar/SidebarHeaderSelectField.tsx +24 -0
  256. package/src/components/sidebar/filter-utils.ts +23 -0
  257. package/src/components/workspace/ContextFilePicker.scss +64 -0
  258. package/src/components/workspace/ContextFilePicker.tsx +171 -0
  259. package/src/connectionManager.ts +4 -2
  260. package/src/hooks/chat/interaction-state.ts +67 -0
  261. package/src/hooks/chat/model-selector-data-builders.ts +146 -0
  262. package/src/hooks/chat/model-selector-data-option-utils.ts +62 -0
  263. package/src/hooks/chat/model-selector-data-types.ts +27 -0
  264. package/src/hooks/chat/model-selector-data.ts +109 -0
  265. package/src/hooks/chat/model-selector-recommendations.ts +69 -0
  266. package/src/hooks/chat/model-selector.ts +9 -0
  267. package/src/hooks/chat/use-chat-interaction.ts +13 -8
  268. package/src/hooks/chat/use-chat-model-adapter-selection.tsx +167 -164
  269. package/src/hooks/chat/use-chat-models.tsx +46 -23
  270. package/src/hooks/chat/use-chat-session-actions.ts +69 -23
  271. package/src/hooks/chat/use-chat-session-messages.ts +158 -60
  272. package/src/hooks/chat/use-chat-session.ts +34 -9
  273. package/src/hooks/chat/use-chat-view.ts +26 -6
  274. package/src/hooks/chat/use-composer-control-shortcuts.ts +69 -0
  275. package/src/hooks/chat/use-terminal-dock-visibility.ts +39 -0
  276. package/src/hooks/use-roving-focus-list.ts +104 -0
  277. package/src/hooks/use-sidebar-navigation.ts +9 -4
  278. package/src/hooks/use-sidebar-query-state.ts +79 -0
  279. package/src/main.tsx +6 -1
  280. package/src/resources/locales/en.json +140 -6
  281. package/src/resources/locales/zh.json +140 -6
  282. package/src/routes/ChatRoute.scss +159 -4
  283. package/src/routes/ChatRoute.tsx +72 -10
  284. package/src/runtime-config.ts +21 -0
  285. package/src/store/index.ts +1 -3
  286. package/src/styles/global.scss +12 -2
  287. package/src/utils/chat-links.ts +21 -0
  288. package/src/utils/copy.ts +18 -0
  289. package/src/utils/shortcutUtils.ts +111 -1
  290. package/src/vite-env.d.ts +1 -0
  291. package/src/ws.ts +6 -5
  292. package/vite.config.ts +71 -7
  293. package/dist/assets/channel-Di8KkPU4.js +0 -1
  294. package/dist/assets/clone-B065n6L-.js +0 -1
  295. package/dist/assets/flowDiagram-v2-4f6560a1-nj-oVLPK.js +0 -1
  296. package/dist/assets/index-BZe1Qtye.css +0 -1
  297. package/dist/assets/index-DV3eI2aD.js +0 -557
  298. package/src/components/chat/sender/CompletionMenu.scss +0 -70
  299. package/src/components/chat/sender/CompletionMenu.tsx +0 -58
  300. /package/src/components/chat/{sender/ThinkingStatus.scss → ThinkingStatus.scss} +0 -0
  301. /package/src/components/chat/sender/{interaction-request.ts → @core/interaction-request.ts} +0 -0
@@ -25,6 +25,7 @@
25
25
  "batchRestoreFailed": "部分会话还原失败",
26
26
  "cancel": "取消",
27
27
  "confirm": "确定",
28
+ "confirmAction": "确认{{action}}",
28
29
  "startNewChat": "暂时没有未归档的历史会话,聊点什么吧",
29
30
  "backToHome": "返回首页",
30
31
  "noData": "暂无数据",
@@ -44,7 +45,14 @@
44
45
  "batchDeleteSuccess": "批量删除成功",
45
46
  "batchDeleteFailed": "部分会话删除失败",
46
47
  "selectedCount": "已选中 {{count}} 个会话",
48
+ "selectAll": "全选",
49
+ "deselectAll": "取消全选",
47
50
  "collapse": "收起侧边栏",
51
+ "close": "关闭",
52
+ "sort": "排序规则",
53
+ "allTags": "全部标签",
54
+ "allAdapters": "全部适配器",
55
+ "searchActions": "搜索与筛选",
48
56
  "expandChildren": "展开子会话",
49
57
  "collapseChildren": "收起子会话",
50
58
  "childSummary": "{{count}} 个子会话",
@@ -52,10 +60,20 @@
52
60
  "deleteConfirm": "确定要删除选中的 {{count}} 个会话吗?",
53
61
  "deleteSuccess": "删除成功",
54
62
  "deleteFailed": "删除失败",
63
+ "operationFailed": "操作失败",
64
+ "copyFailed": "复制失败",
55
65
  "star": "收藏",
56
66
  "unstar": "取消收藏",
67
+ "rename": "重命名",
68
+ "renameSession": "重命名会话",
57
69
  "addTag": "标签",
58
70
  "actions": "操作",
71
+ "copySessionLink": "复制会话链接",
72
+ "copySessionId": "复制会话 ID",
73
+ "copyResumeCommand": "复制控制台指令",
74
+ "moreActions": "更多操作",
75
+ "sessionLinkCopied": "会话链接已复制到剪贴板",
76
+ "resumeCommandCopied": "控制台指令已复制到剪贴板",
59
77
  "sessionIdCopied": "Session ID 已复制到剪贴板",
60
78
  "doubleClickToCopy": "双击复制 Session ID",
61
79
  "status": {
@@ -308,19 +326,52 @@
308
326
  "modelUnavailable": "暂无可用模型",
309
327
  "modelConfigRequired": "请先在配置中添加模型服务后再开始会话",
310
328
  "connectionErrorTitle": "连接异常",
329
+ "sessionErrorTitle": "任务失败",
311
330
  "connectionError": "WebSocket 连接失败,请检查服务状态后重试",
312
331
  "connectionClosed": "WebSocket 连接已关闭,请重试",
313
332
  "retryConnection": "重试连接",
314
333
  "permissionRequestBadge": "权限请求",
334
+ "permissionRequestTitleWithTool": "正在请求使用【{{tool}}】的调用权限,请选择通过",
335
+ "permissionSubject": "审批范围",
336
+ "permissionProjectConfig": "项目配置",
315
337
  "permissionCurrentMode": "当前模式",
316
338
  "permissionSuggestedMode": "建议模式",
317
339
  "permissionDeniedTools": "受限工具",
318
340
  "permissionReasons": "原因",
341
+ "permissionExpandOptions": "展开更多选项",
342
+ "permissionCollapseOptions": "收起更多选项",
319
343
  "tooltipSlashCommands": "快捷指令",
320
344
  "tooltipMentionAgents": "提及代理",
321
345
  "tooltipInjectContext": "注入上下文",
322
346
  "tooltipUploadImages": "上传图片",
347
+ "tooltipReferenceActions": "更多",
348
+ "referenceActionsShortcutTooltip": "更多 / 权限模式",
349
+ "modelShortcutTooltip": "切换模型",
350
+ "modelAddRecommendation": "加入推荐模型",
351
+ "modelAlreadyRecommended": "已在推荐模型中",
352
+ "modelRemoveRecommendation": "从推荐模型中移除",
353
+ "effortShortcutTooltip": "切换推理强度",
354
+ "sendShortcutTooltip": "发送消息",
355
+ "adapterLockedTooltip": "创建会话后适配器会锁定",
356
+ "referenceActionsShort": "更多",
357
+ "referenceActionsTitle": "更多",
358
+ "referenceActionsDescription": "添加照片、文件和权限相关设置。",
359
+ "referenceAttachments": "添加照片和文件",
360
+ "referenceAttachmentsDescription": "选择图片或项目文件作为引用内容。",
361
+ "referencePermission": "权限模式",
362
+ "referencePermissionDescription": "控制工具执行前的授权策略。",
363
+ "referenceImage": "图片",
364
+ "referenceImageDescription": "从本地选择图片并附在消息中。",
365
+ "referenceFile": "文件",
366
+ "referenceFileDescription": "从当前项目目录树中选择要引用的文件。",
323
367
  "effortSelectPlaceholder": "推理强度",
368
+ "effortLabels": {
369
+ "default": "默认",
370
+ "low": "低",
371
+ "medium": "中",
372
+ "high": "高",
373
+ "max": "最高"
374
+ },
324
375
  "permissionModeSelectPlaceholder": "权限模式",
325
376
  "assetWarningsTitle": "兼容性提示",
326
377
  "assetWarningsCount": "{{count}} 个资产告警",
@@ -330,18 +381,52 @@
330
381
  "selectionWarningReasonExcluded": "该模型被适配器规则排除了",
331
382
  "selectionWarningReasonNotIncluded": "该模型不在适配器允许列表中",
332
383
  "selectionWarningFallback": "适配器 {{adapter}} 已将模型从 {{requestedModel}} 切换到 {{resolvedModel}},原因:{{reason}}。",
384
+ "modelGroupBuiltin": "{{adapter}} 内置模型",
385
+ "modelGroupServices": "模型服务",
333
386
  "imageTooLarge": "图片大小不能超过 5MB",
334
387
  "imageReadFailed": "图片读取失败",
335
388
  "imageNotSupportedInInteraction": "当前交互不支持图片",
389
+ "fileNotSupportedInInteraction": "当前交互不支持文件上下文",
390
+ "contextPickerTitle": "引用文件",
391
+ "contextPickerDescription": "从当前项目目录树中选择一个或多个文件。",
392
+ "contextPickerConfirm": "引用文件",
393
+ "contextPickerLoading": "正在加载项目目录树...",
394
+ "contextPickerEmpty": "当前目录下没有可选文件",
395
+ "contextPickerLoadFailed": "项目目录树加载失败",
336
396
  "modelGroupRecommended": "推荐模型",
397
+ "modelMoreModels": "更多模型",
337
398
  "availableTools": "可用工具",
399
+ "availableToolsEmpty": "当前会话没有可展示的工具。",
338
400
  "toolGroupChromeDevtools": "ChromeDevtools",
339
401
  "toolGroupSystem": "系统",
340
402
  "toolsCount": "{{count}} 个工具",
341
403
  "usedTools": "使用了 {{count}} 个工具",
342
- "viewInitInfo": "双击查看初始化信息",
404
+ "debugSessionId": "会话",
405
+ "debugType": "类型",
406
+ "debugUuid": "UUID",
407
+ "debugLeafUuid": "Leaf",
408
+ "debugAdapter": "适配器",
409
+ "debugModel": "模型",
410
+ "debugEffort": "推理强度",
411
+ "debugVersion": "版本",
412
+ "debugTools": "工具数",
413
+ "debugAgents": "代理数",
414
+ "debugCwd": "目录",
415
+ "debugTags": "标签",
416
+ "debugView": "视图",
417
+ "debugStarred": "收藏",
418
+ "debugArchived": "归档",
419
+ "debugEnable": "开启调试模式",
420
+ "debugDisable": "关闭调试模式",
421
+ "debugEnabledValue": "开启",
422
+ "debugDisabledValue": "关闭",
423
+ "debugSectionTitle": "调试会话信息",
424
+ "debugModeTitle": "调试模式已开启",
425
+ "debugModeDescription": "当前 URL 带有 debug query,所以这里会展示平时隐藏的会话元信息。",
426
+ "viewInitInfo": "连续点击标题 5 次切换调试模式",
343
427
  "viewHistory": "历史",
344
428
  "viewTimeline": "时序",
429
+ "viewTerminal": "终端",
345
430
  "viewSettings": "配置",
346
431
  "deleteSessionTitle": "删除会话",
347
432
  "deleteSessionDesc": "删除会话会永久移除全部消息与上下文,请确认后再继续。",
@@ -381,6 +466,42 @@
381
466
  "destroyLabel": "销毁 {{name}}({{end}})",
382
467
  "rangeLabel": "{{name}}({{start}} → {{end}})"
383
468
  },
469
+ "messageActions": {
470
+ "copy": "复制原文",
471
+ "copySuccess": "消息原文已复制",
472
+ "copyFailed": "复制消息原文失败",
473
+ "copyLink": "复制消息链接",
474
+ "copyLinkSuccess": "消息链接已复制",
475
+ "copyId": "复制消息 ID",
476
+ "copyIdSuccess": "消息 ID 已复制",
477
+ "copyJson": "复制消息结构 JSON",
478
+ "copyJsonSuccess": "消息结构 JSON 已复制",
479
+ "copyTimestamp": "复制时间戳",
480
+ "copyTimestampSuccess": "时间戳已复制",
481
+ "edit": "编辑消息",
482
+ "editInProgress": "已有一条消息正在编辑,请先发送或取消当前编辑",
483
+ "saveEdit": "保存并分叉",
484
+ "confirmInline": "确认",
485
+ "recall": "撤回到此处",
486
+ "fork": "从此处分叉",
487
+ "recallConfirmTitle": "确认撤回到此处",
488
+ "recallConfirmContent": "后续消息会被回退到这条消息之后,是否继续?",
489
+ "forkConfirmTitle": "确认从此处分叉",
490
+ "forkConfirmContent": "将基于这条消息创建一个新的会话分支,是否继续?"
491
+ },
492
+ "messageFooter": {
493
+ "tokens": "Token 数",
494
+ "copyTimestampSuccess": "ISO 时间已复制到剪贴板",
495
+ "copyTimestampTitle": "双击复制 ISO 时间并在控制台输出消息结构"
496
+ },
497
+ "turnProcessedDuration": "已处理 {{duration}}",
498
+ "turnDurationUnderSecond": "1 秒内",
499
+ "turnDurationHours": "{{count}} 小时",
500
+ "turnDurationMinutes": "{{count}} 分",
501
+ "turnDurationSeconds": "{{count}} 秒",
502
+ "turnSummaryCount": "{{count}} 条中间消息",
503
+ "turnExpandAction": "展开",
504
+ "turnCollapseAction": "收起",
384
505
  "hint": "按 Enter 发送,Shift + Enter 换行,输入 / @ # 触发补全",
385
506
  "newSessionGuide": {
386
507
  "loading": "正在加载...",
@@ -441,6 +562,11 @@
441
562
  "viewCommand": "查看指令",
442
563
  "unknown": "未知工具"
443
564
  },
565
+ "terminal": {
566
+ "connectionError": "终端连接失败,请检查服务状态后重试",
567
+ "exitSummary": "终端已退出,exitCode={{code}},signal={{signal}}",
568
+ "resizePanel": "拖动调整终端高度"
569
+ },
444
570
  "sessionSettings": "会话设置",
445
571
  "enterTitle": "输入会话标题...",
446
572
  "tags": "标签",
@@ -692,7 +818,7 @@
692
818
  "models": {
693
819
  "items": {
694
820
  "label": "模型选择器明细",
695
- "desc": "按 `service` 或 `service,model` 选择器配置元信息"
821
+ "desc": "按 `service` 或 `service,model` 配置模型元信息;展示元数据如 alias/title/description 仅在 `model` 或 `service,model` 精确匹配时生效"
696
822
  }
697
823
  },
698
824
  "modelServices": {
@@ -721,10 +847,6 @@
721
847
  "label": "模型列表",
722
848
  "desc": "该服务支持的模型名称"
723
849
  },
724
- "modelsAlias": {
725
- "label": "模型别名",
726
- "desc": "模型别名映射"
727
- },
728
850
  "timeoutMs": {
729
851
  "label": "超时(毫秒)",
730
852
  "desc": "模型服务超时。Codex 会映射为流空闲超时,Claude Code Router 会映射为全局 API 超时。"
@@ -827,6 +949,18 @@
827
949
  "clearInput": {
828
950
  "label": "清空输入框",
829
951
  "desc": "清空输入框内容的快捷键"
952
+ },
953
+ "switchModel": {
954
+ "label": "切换模型",
955
+ "desc": "激活模型选择框并支持键盘切换"
956
+ },
957
+ "switchEffort": {
958
+ "label": "切换推理强度",
959
+ "desc": "激活推理强度选择框并支持键盘切换"
960
+ },
961
+ "switchPermissionMode": {
962
+ "label": "切换权限等级",
963
+ "desc": "打开权限模式菜单并支持键盘切换"
830
964
  }
831
965
  }
832
966
  },
@@ -1,7 +1,10 @@
1
1
  .chat-container {
2
2
  display: flex;
3
3
  flex-direction: column;
4
+ flex: 1;
4
5
  height: 100%;
6
+ min-width: 0;
7
+ min-height: 0;
5
8
  background-color: var(--bg-color);
6
9
  position: relative;
7
10
 
@@ -32,7 +35,7 @@
32
35
  .chat-messages {
33
36
  flex: 1;
34
37
  overflow-y: auto;
35
- padding: 12px 24px 0 24px;
38
+ padding: 6px 12px 0;
36
39
  position: relative;
37
40
  opacity: 0;
38
41
  background-color: var(--bg-color);
@@ -46,16 +49,165 @@
46
49
  .chat-messages-content {
47
50
  display: flex;
48
51
  flex-direction: column;
49
- gap: 12px;
52
+ gap: 6px;
50
53
  min-height: 100%;
51
54
  }
52
55
 
56
+ .chat-turn {
57
+ display: flex;
58
+ flex-direction: column;
59
+ gap: 6px;
60
+ min-width: 0;
61
+ }
62
+
63
+ .chat-turn__summary-region {
64
+ display: flex;
65
+ flex-direction: column;
66
+ gap: 0;
67
+ min-width: 0;
68
+ }
69
+
70
+ .chat-turn__summary-region.is-expanded {
71
+ gap: 6px;
72
+ }
73
+
74
+ .chat-turn__collapsible {
75
+ display: grid;
76
+ grid-template-rows: 0fr;
77
+ min-width: 0;
78
+ opacity: 0;
79
+ visibility: hidden;
80
+ transform: translateY(-4px);
81
+ pointer-events: none;
82
+ transition:
83
+ grid-template-rows .24s cubic-bezier(.4, 0, .2, 1),
84
+ opacity .18s ease,
85
+ transform .24s cubic-bezier(.4, 0, .2, 1),
86
+ visibility 0s linear .24s;
87
+ }
88
+
89
+ .chat-turn__collapsible.is-expanded {
90
+ grid-template-rows: 1fr;
91
+ opacity: 1;
92
+ visibility: visible;
93
+ transform: translateY(0);
94
+ pointer-events: auto;
95
+ transition:
96
+ grid-template-rows .24s cubic-bezier(.4, 0, .2, 1),
97
+ opacity .18s ease .04s,
98
+ transform .24s cubic-bezier(.4, 0, .2, 1),
99
+ visibility 0s linear 0s;
100
+ }
101
+
102
+ .chat-turn__collapsible-inner {
103
+ min-height: 0;
104
+ overflow: hidden;
105
+ display: flex;
106
+ flex-direction: column;
107
+ gap: 6px;
108
+ }
109
+
110
+ .chat-turn-summary {
111
+ display: flex;
112
+ align-items: center;
113
+ gap: 12px;
114
+ margin: 0;
115
+ color: var(--sub-text-color);
116
+ font-size: 13px;
117
+ line-height: 1.4;
118
+
119
+ &::before,
120
+ &::after {
121
+ content: '';
122
+ flex: 1;
123
+ min-width: 48px;
124
+ height: 1px;
125
+ background: rgba(15, 23, 42, .12);
126
+ }
127
+
128
+ &.is-collapsed {
129
+ color: var(--text-color);
130
+ }
131
+
132
+ &.is-collapsed::before,
133
+ &.is-collapsed::after {
134
+ background: rgba(15, 23, 42, .18);
135
+ }
136
+ }
137
+
138
+ .chat-turn-summary__content {
139
+ display: inline-flex;
140
+ align-items: center;
141
+ gap: 10px;
142
+ min-width: 0;
143
+ }
144
+
145
+ .chat-turn-summary__meta {
146
+ display: inline-flex;
147
+ align-items: center;
148
+ gap: 8px;
149
+ min-width: 0;
150
+ }
151
+
152
+ .chat-turn-summary__time,
153
+ .chat-turn-summary__count {
154
+ display: inline-flex;
155
+ align-items: center;
156
+ white-space: nowrap;
157
+ }
158
+
159
+ .chat-turn-summary__time {
160
+ opacity: .72;
161
+ }
162
+
163
+ .chat-turn-summary__count::before {
164
+ content: '·';
165
+ margin-right: 8px;
166
+ }
167
+
168
+ .chat-turn-summary__count {
169
+ font-weight: 500;
170
+ }
171
+
172
+ .chat-turn-summary__toggle {
173
+ display: inline-flex;
174
+ align-items: center;
175
+ flex-shrink: 0;
176
+ justify-content: center;
177
+ width: 20px;
178
+ height: 20px;
179
+ padding: 0;
180
+ border: 0;
181
+ border-radius: 999px;
182
+ background: transparent;
183
+ color: inherit;
184
+ font-size: 12px;
185
+ line-height: 1;
186
+ cursor: pointer;
187
+ transition: background-color .2s ease, color .2s ease;
188
+
189
+ &:hover {
190
+ background: rgba(15, 23, 42, .06);
191
+ }
192
+
193
+ .material-symbols-rounded {
194
+ font-size: 16px;
195
+ transition: transform .2s ease;
196
+ }
197
+ }
198
+
199
+ .chat-turn-summary.is-expanded {
200
+ .chat-turn-summary__toggle .material-symbols-rounded {
201
+ transform: rotate(90deg);
202
+ }
203
+ }
204
+
53
205
  .chat-pending-session-banner {
54
206
  align-self: center;
55
207
  display: inline-flex;
56
208
  align-items: center;
57
209
  gap: 8px;
58
- margin: 0 auto 4px;
210
+ margin: 0 auto;
59
211
  padding: 8px 14px;
60
212
  border: 1px solid rgba(59, 130, 246, .18);
61
213
  border-radius: 999px;
@@ -79,7 +231,7 @@
79
231
  display: flex;
80
232
  flex-direction: column;
81
233
  justify-content: flex-end;
82
- padding: 0 24px 24px;
234
+ padding: 0 12px 12px;
83
235
  transition:
84
236
  flex .4s cubic-bezier(.4, 0, .2, 1),
85
237
  padding-bottom .4s cubic-bezier(.4, 0, .2, 1);
@@ -120,7 +272,10 @@
120
272
  }
121
273
 
122
274
  .chat-route__empty-state {
275
+ flex: 1;
123
276
  height: 100%;
277
+ min-width: 0;
278
+ min-height: 0;
124
279
  display: grid;
125
280
  place-items: center;
126
281
  align-content: center;
@@ -1,8 +1,9 @@
1
1
  import './ChatRoute.scss'
2
2
 
3
3
  import { Button, Empty } from 'antd'
4
+ import { useEffect, useRef } from 'react'
4
5
  import { useTranslation } from 'react-i18next'
5
- import { useNavigate, useParams } from 'react-router-dom'
6
+ import { useNavigate, useParams, useSearchParams } from 'react-router-dom'
6
7
  import useSWR from 'swr'
7
8
 
8
9
  import type { Session } from '@vibe-forge/core'
@@ -12,7 +13,9 @@ import { ChatHeader } from '#~/components/chat/ChatHeader.js'
12
13
  import { ChatHistoryView } from '#~/components/chat/ChatHistoryView.js'
13
14
  import { ChatSettingsView } from '#~/components/chat/ChatSettingsView.js'
14
15
  import { ChatTimelineView } from '#~/components/chat/ChatTimelineView.js'
16
+ import { ChatTerminalView } from '#~/components/chat/terminal/ChatTerminalView.js'
15
17
  import { useChatSession } from '#~/hooks/chat/use-chat-session'
18
+ import { useTerminalDockVisibility } from '#~/hooks/chat/use-terminal-dock-visibility'
16
19
 
17
20
  export function ChatRoute() {
18
21
  const { t } = useTranslation()
@@ -45,19 +48,27 @@ function ChatRouteView({
45
48
  }: {
46
49
  session?: Session
47
50
  }) {
51
+ const [searchParams] = useSearchParams()
48
52
  const {
49
53
  messages,
50
54
  sessionInfo,
51
55
  interactionRequest,
52
56
  isReady,
53
- connectionError,
57
+ errorBanner,
54
58
  retryConnection,
55
59
  activeView,
60
+ isTerminalOpen,
56
61
  setActiveView,
62
+ setIsTerminalOpen,
57
63
  handleInteractionResponse,
58
64
  setMessages,
59
65
  placeholder,
60
- modelOptions,
66
+ modelMenuGroups,
67
+ modelSearchOptions,
68
+ recommendedModelOptions,
69
+ servicePreviewModelOptions,
70
+ toggleRecommendedModel,
71
+ updatingRecommendedModelValue,
61
72
  selectedModel,
62
73
  modelForQuery,
63
74
  setSelectedModel,
@@ -73,10 +84,41 @@ function ChatRouteView({
73
84
  hasAvailableModels,
74
85
  modelUnavailable
75
86
  } = useChatSession({ session })
87
+ const targetMessageId = searchParams.get('messageId') ?? undefined
88
+ const targetToolUseId = searchParams.get('toolUseId') ?? undefined
89
+ const deepLinkTargetKey = targetToolUseId?.trim()
90
+ ? `tool:${targetToolUseId.trim()}`
91
+ : targetMessageId?.trim()
92
+ ? `message:${targetMessageId.trim()}`
93
+ : ''
76
94
  const isEmptyNewSession = !session?.id && messages.length === 0
95
+ const resolvedActiveView = session?.id != null ? activeView : 'history'
96
+ const shouldShowTerminal = session?.id != null && isTerminalOpen
97
+ const { isRendered: isTerminalRendered, isVisible: isTerminalVisible } = useTerminalDockVisibility(shouldShowTerminal)
98
+ const handledDeepLinkTargetRef = useRef('')
99
+
100
+ useEffect(() => {
101
+ if (deepLinkTargetKey === '') {
102
+ handledDeepLinkTargetRef.current = ''
103
+ return
104
+ }
105
+
106
+ if (handledDeepLinkTargetRef.current === deepLinkTargetKey) {
107
+ return
108
+ }
109
+
110
+ handledDeepLinkTargetRef.current = deepLinkTargetKey
111
+ if (activeView !== 'history') {
112
+ setActiveView('history')
113
+ }
114
+ }, [activeView, deepLinkTargetKey, setActiveView])
77
115
 
78
116
  return (
79
- <div className={`chat-container ${isReady ? 'ready' : ''} ${isEmptyNewSession ? 'is-new-session' : ''}`}>
117
+ <div
118
+ className={`chat-container ${isReady ? 'ready' : ''} ${isEmptyNewSession ? 'is-new-session' : ''} ${
119
+ shouldShowTerminal ? 'has-terminal' : ''
120
+ }`}
121
+ >
80
122
  {session?.id && (
81
123
  <ChatHeader
82
124
  sessionInfo={sessionInfo}
@@ -87,25 +129,36 @@ function ChatRouteView({
87
129
  tags={session.tags}
88
130
  lastMessage={session.lastMessage}
89
131
  lastUserMessage={session.lastUserMessage}
90
- activeView={activeView}
132
+ activeView={resolvedActiveView}
133
+ isTerminalOpen={isTerminalOpen}
91
134
  onViewChange={setActiveView}
135
+ onToggleTerminal={() => {
136
+ setIsTerminalOpen(!isTerminalOpen)
137
+ }}
92
138
  />
93
139
  )}
94
140
 
95
- {activeView === 'history' && (
141
+ {resolvedActiveView === 'history' && (
96
142
  <ChatHistoryView
97
143
  isReady={isReady}
98
144
  messages={messages}
99
145
  session={session}
146
+ targetMessageId={targetMessageId}
147
+ targetToolUseId={targetToolUseId}
100
148
  sessionInfo={sessionInfo}
101
- connectionError={connectionError}
149
+ errorBanner={errorBanner}
102
150
  onRetryConnection={retryConnection}
103
151
  interactionRequest={interactionRequest}
104
152
  onInteractionResponse={handleInteractionResponse}
105
153
  setMessages={setMessages}
106
154
  onClearMessages={() => setMessages([])}
107
155
  placeholder={placeholder}
108
- modelOptions={modelOptions}
156
+ modelMenuGroups={modelMenuGroups}
157
+ modelSearchOptions={modelSearchOptions}
158
+ recommendedModelOptions={recommendedModelOptions}
159
+ servicePreviewModelOptions={servicePreviewModelOptions}
160
+ onToggleRecommendedModel={toggleRecommendedModel}
161
+ updatingRecommendedModelValue={updatingRecommendedModelValue}
109
162
  selectedModel={selectedModel}
110
163
  modelForQuery={modelForQuery}
111
164
  onModelChange={setSelectedModel}
@@ -123,16 +176,25 @@ function ChatRouteView({
123
176
  />
124
177
  )}
125
178
 
126
- {activeView === 'timeline' && (
179
+ {resolvedActiveView === 'timeline' && (
127
180
  <ChatTimelineView messages={messages} />
128
181
  )}
129
182
 
130
- {activeView === 'settings' && session?.id && (
183
+ {resolvedActiveView === 'settings' && session?.id && (
131
184
  <ChatSettingsView
132
185
  session={session}
186
+ sessionInfo={sessionInfo}
133
187
  onClose={() => setActiveView('history')}
134
188
  />
135
189
  )}
190
+
191
+ {isTerminalRendered && session?.id && (
192
+ <ChatTerminalView
193
+ isOpen={isTerminalVisible}
194
+ sessionId={session.id}
195
+ onClose={() => setIsTerminalOpen(false)}
196
+ />
197
+ )}
136
198
  </div>
137
199
  )
138
200
  }
@@ -5,6 +5,27 @@ export type RuntimeEnv = Partial<{
5
5
  __VF_PROJECT_AI_CLIENT_BASE__: string
6
6
  }>
7
7
 
8
+ export const resolveDevDocumentTitle = (
9
+ baseTitle: string,
10
+ input: {
11
+ isDev: boolean
12
+ gitRef?: string
13
+ }
14
+ ) => {
15
+ const normalizedBaseTitle = (baseTitle.trim() === '' ? 'Vibe Forge Web' : baseTitle.trim())
16
+ .replace(/\s+\[[^\]]+\]$/, '')
17
+ if (!input.isDev) {
18
+ return normalizedBaseTitle
19
+ }
20
+
21
+ const gitRef = input.gitRef?.trim()
22
+ if (gitRef == null || gitRef === '') {
23
+ return normalizedBaseTitle
24
+ }
25
+
26
+ return `${normalizedBaseTitle} [${gitRef}]`
27
+ }
28
+
8
29
  const getGlobalRuntimeEnv = () => {
9
30
  const globalScope = globalThis as { __VF_PROJECT_AI_RUNTIME_ENV__?: RuntimeEnv }
10
31
  return globalScope.__VF_PROJECT_AI_RUNTIME_ENV__
@@ -9,9 +9,7 @@ export const sidebarWidthAtom = atom(
9
9
  export const isSidebarResizingAtom = atom<boolean>(false)
10
10
 
11
11
  // 侧边栏是否折叠
12
- export const isSidebarCollapsedAtom = atom(
13
- localStorage.getItem('sidebarCollapsed') === 'true'
14
- )
12
+ export const isSidebarCollapsedAtom = atom(false)
15
13
 
16
14
  // 当前选中的会话 ID (全局 UI 状态,用于控制高亮等)
17
15
  export const activeSessionIdAtom = atom<string | undefined>(undefined)
@@ -47,7 +47,8 @@ html, body, #root, .ant-app {
47
47
  --code-bg: #f0f2f4; /* 代码块背景 */
48
48
  --code-border: #f1f5f9; /* 代码块边框 */
49
49
  --star-color: #f59e0b; /* 收藏/星标颜色 */
50
- --primary-color: #6366f1; /* 主色调/主行动强调 */
50
+ --primary-color: #2563eb; /* 主色调/主行动强调 */
51
+ --primary-soft-bg: #eff6ff; /* 主色调的弱化背景 */
51
52
  --success-color: #0f766e; /* 成功状态颜色 */
52
53
  --warning-color: #b45309; /* 警告状态颜色 */
53
54
  --primary-text-color: #1d4ed8; /* 链接/强调文字颜色 */
@@ -74,7 +75,8 @@ html.dark {
74
75
  --code-bg: #1e293b; /* 代码块背景 */
75
76
  --code-border: #334155; /* 代码块边框 */
76
77
  --star-color: #ffb81c; /* 收藏/星标颜色 */
77
- --primary-color: #818cf8; /* 主色调/主行动强调 */
78
+ --primary-color: #3b82f6; /* 主色调/主行动强调 */
79
+ --primary-soft-bg: #111b26; /* 主色调的弱化背景 */
78
80
  --success-color: #2dd4bf; /* 成功状态颜色 */
79
81
  --warning-color: #f59e0b; /* 警告状态颜色 */
80
82
  --primary-text-color: #60a5fa; /* 链接/强调文字颜色 */
@@ -98,3 +100,11 @@ html.dark {
98
100
  background-color: var(--primary-color);
99
101
  color: #ffffff;
100
102
  }
103
+
104
+ .ant-tooltip {
105
+ .ant-tooltip-inner {
106
+ font-size: 12px;
107
+ line-height: 1.4;
108
+ min-height: 28px;
109
+ }
110
+ }