@vibe-forge/client 2.0.0 → 2.0.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 (347) hide show
  1. package/AGENTS.md +4 -1
  2. package/dist/assets/{arc-CbOXL0l9.js → arc-CqviK3HX.js} +1 -1
  3. package/dist/assets/{blockDiagram-c4efeb88-CqxINvsS.js → blockDiagram-c4efeb88-BEp50UHp.js} +1 -1
  4. package/dist/assets/{c4Diagram-c83219d4-BKazU0hb.js → c4Diagram-c83219d4-C5w55JzM.js} +1 -1
  5. package/dist/assets/channel-C6LTxxLg.js +1 -0
  6. package/dist/assets/{classDiagram-beda092f-fAFX5BpB.js → classDiagram-beda092f-CQJVtHEy.js} +1 -1
  7. package/dist/assets/{classDiagram-v2-2358418a-w1VkNGJj.js → classDiagram-v2-2358418a-B37Xl9jB.js} +1 -1
  8. package/dist/assets/clone-CG6ZcokX.js +1 -0
  9. package/dist/assets/{createText-1719965b-CEinakVP.js → createText-1719965b-9YwvWMdV.js} +1 -1
  10. package/dist/assets/{cssMode-DPqRki4y.js → cssMode-BX88r5f4.js} +1 -1
  11. package/dist/assets/{edges-96097737-Cb0F1_3K.js → edges-96097737-CNHoXVrD.js} +1 -1
  12. package/dist/assets/{erDiagram-0228fc6a-C-N2fx-J.js → erDiagram-0228fc6a-BoYldy0g.js} +1 -1
  13. package/dist/assets/{flowDb-c6c81e3f-D1Xz_8Gf.js → flowDb-c6c81e3f-CoPw_R-Q.js} +1 -1
  14. package/dist/assets/{flowDiagram-50d868cf-DyPSZyAj.js → flowDiagram-50d868cf-nCqbSXd-.js} +1 -1
  15. package/dist/assets/flowDiagram-v2-4f6560a1-CSZTI7GQ.js +1 -0
  16. package/dist/assets/{flowchart-elk-definition-6af322e1-Dr1DDXwE.js → flowchart-elk-definition-6af322e1-BwMuPTrV.js} +1 -1
  17. package/dist/assets/{freemarker2-C3DvPFaK.js → freemarker2-DUFDSvgj.js} +1 -1
  18. package/dist/assets/{ganttDiagram-a2739b55-DmvY1GRj.js → ganttDiagram-a2739b55-CLNH3S_C.js} +1 -1
  19. package/dist/assets/{gitGraphDiagram-82fe8481-CoXfPYYi.js → gitGraphDiagram-82fe8481-uDu1ectX.js} +1 -1
  20. package/dist/assets/{graph-BkDQy7Qt.js → graph-DuC4kt4I.js} +1 -1
  21. package/dist/assets/{handlebars-BcTFdqjl.js → handlebars-BSd4a6l9.js} +1 -1
  22. package/dist/assets/{html-Dg-O6XFr.js → html-H48gEjQd.js} +1 -1
  23. package/dist/assets/{htmlMode-B_wqYWvn.js → htmlMode-Nqw7-Nqh.js} +1 -1
  24. package/dist/assets/{index-5325376f-kxPTR3_e.js → index-5325376f-rnz0GXAT.js} +1 -1
  25. package/dist/assets/{index-wkhI4dr6.js → index-DeQLT67a.js} +398 -377
  26. package/dist/assets/index-DiOCtPLP.css +32 -0
  27. package/dist/assets/{infoDiagram-8eee0895-BEvqkwPI.js → infoDiagram-8eee0895-BsGB550b.js} +1 -1
  28. package/dist/assets/{javascript-DhlOH8_z.js → javascript-0g2herYV.js} +1 -1
  29. package/dist/assets/{journeyDiagram-c64418c1-gKtLYmmp.js → journeyDiagram-c64418c1-DLldlz0H.js} +1 -1
  30. package/dist/assets/{jsonMode-DxTbF9OD.js → jsonMode-CN5ZURMh.js} +1 -1
  31. package/dist/assets/{layout-CDaZEk6E.js → layout-QKUiDNJK.js} +1 -1
  32. package/dist/assets/{line-DNRQu8iq.js → line-CeP3XWjD.js} +1 -1
  33. package/dist/assets/{linear-Cph9Z6_j.js → linear-74cQVgWT.js} +1 -1
  34. package/dist/assets/{liquid-ByZ6JgRG.js → liquid-B6cRrfrb.js} +1 -1
  35. package/dist/assets/{lspLanguageFeatures-DzvhkgnM.js → lspLanguageFeatures-C5ogOh5E.js} +1 -1
  36. package/dist/assets/{mdx-D8RGHTl6.js → mdx-BBIy-KRj.js} +1 -1
  37. package/dist/assets/{mermaid.core-BgcryF__.js → mermaid.core-BhdbV0mr.js} +4 -4
  38. package/dist/assets/{mindmap-definition-8da855dc-WrxK0FcB.js → mindmap-definition-8da855dc-B67VKJuD.js} +1 -1
  39. package/dist/assets/{pieDiagram-a8764435-VsZBsiQy.js → pieDiagram-a8764435-Cxv9WY_E.js} +1 -1
  40. package/dist/assets/{python-CXVtk_cg.js → python-CBdGo8__.js} +1 -1
  41. package/dist/assets/{quadrantDiagram-1e28029f-BVlgwOvU.js → quadrantDiagram-1e28029f-BTkj65P_.js} +1 -1
  42. package/dist/assets/{razor-0tind7h2.js → razor-azKH0Dwj.js} +1 -1
  43. package/dist/assets/{requirementDiagram-08caed73-CpPMPoYp.js → requirementDiagram-08caed73-D4jVXpOT.js} +1 -1
  44. package/dist/assets/{sankeyDiagram-a04cb91d-Cm5nnRmc.js → sankeyDiagram-a04cb91d-CXhutIA1.js} +1 -1
  45. package/dist/assets/{sequenceDiagram-c5b8d532-DpMlJvJB.js → sequenceDiagram-c5b8d532-B56TTZlx.js} +1 -1
  46. package/dist/assets/{stateDiagram-1ecb1508-DU1zc7vq.js → stateDiagram-1ecb1508-Cs0plMcS.js} +1 -1
  47. package/dist/assets/{stateDiagram-v2-c2b004d7-D-0RgmAp.js → stateDiagram-v2-c2b004d7-LSJaXPJN.js} +1 -1
  48. package/dist/assets/{styles-b4e223ce-BSO-yNWV.js → styles-b4e223ce-UdXfHMuu.js} +1 -1
  49. package/dist/assets/{styles-ca3715f6-CHnsn2Ro.js → styles-ca3715f6-EuRy_hTu.js} +1 -1
  50. package/dist/assets/{styles-d45a18b0-B-rVGjEq.js → styles-d45a18b0-B24zVoK3.js} +1 -1
  51. package/dist/assets/{svgDrawCommon-b86b1483-CA3Pl89f.js → svgDrawCommon-b86b1483-B2S0NW3K.js} +1 -1
  52. package/dist/assets/{timeline-definition-faaaa080-BcihLR6s.js → timeline-definition-faaaa080-DFWKh9mU.js} +1 -1
  53. package/dist/assets/{tsMode-D9GGa5Ur.js → tsMode-FZsHWiOn.js} +1 -1
  54. package/dist/assets/{typescript-BT9CK_EL.js → typescript-CYdJ3s3D.js} +1 -1
  55. package/dist/assets/{xml-DNO75J-T.js → xml-C16X_hpZ.js} +1 -1
  56. package/dist/assets/{xychartDiagram-f5964ef8-DJTwe32X.js → xychartDiagram-f5964ef8-DyBiBYci.js} +1 -1
  57. package/dist/assets/{yaml-7CVzhiP2.js → yaml-CRjA4-Rj.js} +1 -1
  58. package/dist/index.html +8 -3
  59. package/dist/manifest.webmanifest +30 -0
  60. package/dist/pwa-icon-192.png +0 -0
  61. package/dist/pwa-icon-512.png +0 -0
  62. package/dist/sw.js +105 -0
  63. package/index.html +6 -1
  64. package/package.json +13 -13
  65. package/public/manifest.webmanifest +30 -0
  66. package/public/pwa-icon-192.png +0 -0
  67. package/public/pwa-icon-512.png +0 -0
  68. package/public/sw.js +105 -0
  69. package/src/App.tsx +13 -1
  70. package/src/api/README.md +1 -0
  71. package/src/api/adapters.ts +63 -0
  72. package/src/api/auth-token.ts +51 -0
  73. package/src/api/auth.ts +46 -0
  74. package/src/api/automation.ts +10 -0
  75. package/src/api/base.ts +20 -17
  76. package/src/api/config.ts +5 -1
  77. package/src/api/knowledge.ts +59 -0
  78. package/src/api/sessions.ts +35 -3
  79. package/src/api/skill-hub.ts +126 -0
  80. package/src/api/workspace.ts +33 -1
  81. package/src/api/worktree-environments.ts +53 -0
  82. package/src/api.ts +62 -7
  83. package/src/client-build-info.ts +19 -0
  84. package/src/components/ConfigView.scss +595 -28
  85. package/src/components/ConfigView.tsx +568 -138
  86. package/src/components/NavRail.scss +1 -2
  87. package/src/components/NavRail.tsx +33 -3
  88. package/src/components/Sidebar.scss +0 -44
  89. package/src/components/Sidebar.tsx +109 -37
  90. package/src/components/auth/AuthGate.scss +79 -0
  91. package/src/components/auth/AuthGate.tsx +174 -0
  92. package/src/components/automation-view/@components/AutomationTaskComposer.tsx +218 -0
  93. package/src/components/automation-view/@components/AutomationTriggerRow.tsx +192 -0
  94. package/src/components/automation-view/@hooks/use-automation-startup-options-data.tsx +289 -0
  95. package/src/components/automation-view/@hooks/use-automation-startup-static-options.ts +51 -0
  96. package/src/components/automation-view/@utils/sender-model-options.tsx +52 -0
  97. package/src/components/automation-view/@utils/startup-options.ts +26 -0
  98. package/src/components/automation-view/AutomationEmptyGuide.tsx +61 -0
  99. package/src/components/automation-view/AutomationEmptyLanding.scss +165 -0
  100. package/src/components/automation-view/AutomationEmptyLanding.tsx +199 -0
  101. package/src/components/automation-view/AutomationRuleDetailPreview.tsx +179 -0
  102. package/src/components/automation-view/PanelTitleActions.tsx +66 -0
  103. package/src/components/automation-view/RuleFormPanel.scss +172 -49
  104. package/src/components/automation-view/RuleFormPanel.tsx +196 -91
  105. package/src/components/automation-view/RuleSidebar.scss +128 -41
  106. package/src/components/automation-view/RuleSidebar.tsx +173 -89
  107. package/src/components/automation-view/RunHistoryPanel.scss +307 -72
  108. package/src/components/automation-view/RunHistoryPanel.tsx +185 -165
  109. package/src/components/automation-view/TaskList.scss +126 -64
  110. package/src/components/automation-view/TaskList.tsx +15 -31
  111. package/src/components/automation-view/TriggerList.scss +87 -8
  112. package/src/components/automation-view/TriggerList.tsx +14 -173
  113. package/src/components/automation-view/index.scss +165 -37
  114. package/src/components/automation-view/index.tsx +174 -87
  115. package/src/components/automation-view/types.ts +13 -0
  116. package/src/components/chat/AGENTS.md +3 -1
  117. package/src/components/chat/ChatHeader.tsx +56 -33
  118. package/src/components/chat/ChatHistoryView.tsx +250 -121
  119. package/src/components/chat/NewSessionGuide.scss +274 -204
  120. package/src/components/chat/NewSessionGuide.tsx +40 -111
  121. package/src/components/chat/NewSessionGuideStarterList.tsx +187 -0
  122. package/src/components/chat/NewSessionGuideStarterSection.tsx +120 -0
  123. package/src/components/chat/bottom-dock-constants.ts +4 -0
  124. package/src/components/chat/conversation-starter-apply.ts +181 -0
  125. package/src/components/chat/git-controls/ChatGitControls.scss +65 -0
  126. package/src/components/chat/git-controls/DraftGitControls.tsx +14 -0
  127. package/src/components/chat/git-controls/DraftWorktreeEnvironmentDropdown.tsx +115 -0
  128. package/src/components/chat/messages/MessageItem.tsx +3 -2
  129. package/src/components/chat/messages/MessageStatusNotice.tsx +12 -4
  130. package/src/components/chat/messages/build-chat-history-status-notices.ts +18 -13
  131. package/src/components/chat/messages/message-action-utils.ts +18 -0
  132. package/src/components/chat/new-session-guide-config.ts +19 -0
  133. package/src/components/chat/new-session-guide-items.ts +172 -0
  134. package/src/components/chat/new-session-guide-list-order.ts +58 -0
  135. package/src/components/chat/sender/@components/account-select/AccountSelectControl.scss +112 -0
  136. package/src/components/chat/sender/@components/account-select/AccountSelectControl.tsx +280 -0
  137. package/src/components/chat/sender/@components/account-select/AccountSelectDropdown.scss +155 -0
  138. package/src/components/chat/sender/@components/adapter-select/AdapterSelectControl.scss +51 -12
  139. package/src/components/chat/sender/@components/adapter-select/AdapterSelectDropdown.scss +14 -0
  140. package/src/components/chat/sender/@components/effort-select/EffortSelectControl.scss +36 -0
  141. package/src/components/chat/sender/@components/effort-select/EffortSelectControl.tsx +17 -12
  142. package/src/components/chat/sender/@components/model-select/ModelSelectControl.scss +62 -0
  143. package/src/components/chat/sender/@components/model-select/ModelSelectControl.tsx +17 -12
  144. package/src/components/chat/sender/@components/model-select/ModelSelectMenu.scss +2 -0
  145. package/src/components/chat/sender/@components/model-select/ModelSelectMenuLabels.scss +24 -0
  146. package/src/components/chat/sender/@components/permission-mode-control/PermissionModeControl.scss +199 -0
  147. package/src/components/chat/sender/@components/permission-mode-control/PermissionModeControl.tsx +172 -0
  148. package/src/components/chat/sender/@components/reference-actions/ReferenceActionsControl.scss +1 -10
  149. package/src/components/chat/sender/@components/reference-actions/ReferenceActionsControl.tsx +16 -65
  150. package/src/components/chat/sender/@components/sender-body/SenderBody.tsx +13 -1
  151. package/src/components/chat/sender/@components/sender-header-controls/SenderHeaderControls.tsx +157 -0
  152. package/src/components/chat/sender/@components/sender-monaco-editor/monaco-runtime.ts +1 -17
  153. package/src/components/chat/sender/@components/sender-toolbar/SenderSelectBase.scss +18 -2
  154. package/src/components/chat/sender/@components/sender-toolbar/SenderSelectShared.scss +18 -1
  155. package/src/components/chat/sender/@components/sender-toolbar/SenderToolbar.scss +2 -0
  156. package/src/components/chat/sender/@components/sender-toolbar/SenderToolbar.tsx +40 -40
  157. package/src/components/chat/sender/@components/session-target/SenderSessionTargetBar.scss +215 -0
  158. package/src/components/chat/sender/@components/session-target/SenderSessionTargetBar.tsx +185 -0
  159. package/src/components/chat/sender/@core/build-sender-toolbar.ts +6 -0
  160. package/src/components/chat/sender/@core/create-sender-toolbar-handlers.ts +21 -1
  161. package/src/components/chat/sender/@core/get-sender-runtime-state.ts +3 -2
  162. package/src/components/chat/sender/@core/sender-toolbar-bindings.ts +12 -0
  163. package/src/components/chat/sender/@hooks/use-sender-controller.ts +56 -1
  164. package/src/components/chat/sender/@hooks/use-sender-reference-actions.ts +9 -66
  165. package/src/components/chat/sender/@types/sender-props.ts +18 -0
  166. package/src/components/chat/sender/@types/sender-toolbar-types.ts +8 -1
  167. package/src/components/chat/sender/@types/sender-types.ts +1 -3
  168. package/src/components/chat/sender/@utils/sender-constants.ts +1 -1
  169. package/src/components/chat/sender/Sender.scss +245 -2
  170. package/src/components/chat/sender/Sender.tsx +1 -0
  171. package/src/components/chat/status-bar/ChatStatusBar.scss +85 -0
  172. package/src/components/chat/status-bar/ChatStatusBar.tsx +48 -0
  173. package/src/components/chat/terminal/@components/TerminalManagerList.tsx +191 -0
  174. package/src/components/chat/terminal/@components/TerminalPane.scss +71 -0
  175. package/src/components/chat/terminal/@components/TerminalPane.tsx +137 -0
  176. package/src/components/chat/terminal/@components/TerminalPanelActions.tsx +75 -0
  177. package/src/components/chat/terminal/@hooks/use-terminal-instance.ts +36 -0
  178. package/src/components/chat/terminal/@hooks/use-terminal-session.ts +18 -21
  179. package/src/components/chat/terminal/@hooks/use-terminal-title-editor.ts +72 -0
  180. package/src/components/chat/terminal/@utils/terminal-keyboard.ts +141 -0
  181. package/src/components/chat/terminal/@utils/terminal-panes.ts +123 -0
  182. package/src/components/chat/terminal/ChatTerminalView.scss +310 -38
  183. package/src/components/chat/terminal/ChatTerminalView.tsx +151 -79
  184. package/src/components/chat/tools/core/ToolDiffViewer.tsx +3 -17
  185. package/src/components/chat/workspace-drawer/ChatWorkspaceDrawer.scss +778 -0
  186. package/src/components/chat/workspace-drawer/ChatWorkspaceDrawer.tsx +112 -0
  187. package/src/components/chat/workspace-drawer/ChatWorkspaceDrawerToolbar.tsx +183 -0
  188. package/src/components/chat/workspace-drawer/WorkspaceDrawerChangedFileRow.tsx +75 -0
  189. package/src/components/chat/workspace-drawer/WorkspaceDrawerChangedFiles.tsx +161 -0
  190. package/src/components/chat/workspace-drawer/WorkspaceDrawerChangedFolderTree.tsx +191 -0
  191. package/src/components/chat/workspace-drawer/WorkspaceDrawerTree.tsx +35 -0
  192. package/src/components/chat/workspace-drawer/WorkspaceDrawerTreeState.tsx +17 -0
  193. package/src/components/chat/workspace-drawer/changed-files-model.ts +152 -0
  194. package/src/components/chat/workspace-drawer/workspace-drawer-icons.ts +110 -0
  195. package/src/components/chat/workspace-file-editor/WorkspaceFileBreadcrumb.tsx +17 -0
  196. package/src/components/chat/workspace-file-editor/WorkspaceFileEditorView.scss +283 -0
  197. package/src/components/chat/workspace-file-editor/WorkspaceFileEditorView.tsx +165 -0
  198. package/src/components/chat/workspace-file-editor/WorkspaceFileTabs.tsx +135 -0
  199. package/src/components/chat/workspace-file-editor/use-workspace-file-editor-state.ts +113 -0
  200. package/src/components/chat/workspace-file-editor/workspace-file-editor-language.ts +55 -0
  201. package/src/components/composer-landing/ComposerLanding.scss +75 -0
  202. package/src/components/composer-landing/ComposerLanding.tsx +47 -0
  203. package/src/components/config/AGENTS.md +45 -0
  204. package/src/components/config/AdapterAccountsManager.scss +540 -0
  205. package/src/components/config/AdapterAccountsManager.tsx +846 -0
  206. package/src/components/config/AppSettingsPanel.tsx +24 -2
  207. package/src/components/config/ConfigAboutSection.scss +7 -1
  208. package/src/components/config/ConfigAboutSection.tsx +21 -3
  209. package/src/components/config/ConfigEditors.scss +12 -0
  210. package/src/components/config/ConfigFieldRow.scss +88 -4
  211. package/src/components/config/ConfigSectionForm.scss +88 -3
  212. package/src/components/config/ConfigSectionForm.tsx +948 -138
  213. package/src/components/config/ConfigSectionPanel.tsx +188 -12
  214. package/src/components/config/ConfigSourceSwitch.tsx +32 -18
  215. package/src/components/config/DetailCollectionFieldActions.tsx +63 -0
  216. package/src/components/config/DetailListField.tsx +413 -0
  217. package/src/components/config/McpServerItemEditor.tsx +154 -0
  218. package/src/components/config/RecommendedModelsItemEditor.tsx +146 -0
  219. package/src/components/config/WorktreeEnvironmentDetailView.tsx +126 -0
  220. package/src/components/config/WorktreeEnvironmentListView.tsx +126 -0
  221. package/src/components/config/WorktreeEnvironmentPanel.scss +430 -0
  222. package/src/components/config/WorktreeEnvironmentPanel.tsx +147 -0
  223. package/src/components/config/WorktreeEnvironmentScriptEditorCard.tsx +125 -0
  224. package/src/components/config/WorktreeEnvironmentScriptEditors.tsx +189 -0
  225. package/src/components/config/configConflict.ts +41 -0
  226. package/src/components/config/configDetail.ts +381 -0
  227. package/src/components/config/configSchema.ts +850 -179
  228. package/src/components/config/configUtils.ts +1 -1
  229. package/src/components/config/record-editors/RecordEditors.scss +187 -2
  230. package/src/components/config/record-editors/RecordJsonEditor.tsx +27 -2
  231. package/src/components/config/record-editors/SchemaObjectEditor.tsx +183 -0
  232. package/src/components/config/record-editors/SchemaRecordEditor.tsx +184 -0
  233. package/src/components/config/record-editors/index.tsx +2 -1
  234. package/src/components/config/record-editors/schemaRecordUtils.ts +55 -0
  235. package/src/components/config/use-worktree-environment-auto-save.ts +386 -0
  236. package/src/components/config/worktree-environment-panel-model.ts +108 -0
  237. package/src/components/dock-panel/DockPanel.scss +84 -17
  238. package/src/components/dock-panel/DockPanel.tsx +37 -34
  239. package/src/components/dock-panel/DockPanelHeader.tsx +65 -0
  240. package/src/components/dock-panel/use-dock-panel-fullscreen.ts +51 -0
  241. package/src/components/knowledge-base/KnowledgeBaseView.scss +276 -38
  242. package/src/components/knowledge-base/KnowledgeBaseView.tsx +252 -46
  243. package/src/components/knowledge-base/components/ActionButton.scss +30 -4
  244. package/src/components/knowledge-base/components/ActionButton.tsx +13 -3
  245. package/src/components/knowledge-base/components/CreateSkillModal.tsx +59 -0
  246. package/src/components/knowledge-base/components/EmptyState.scss +4 -2
  247. package/src/components/knowledge-base/components/EntitiesTab.tsx +20 -20
  248. package/src/components/knowledge-base/components/EntityList.scss +3 -0
  249. package/src/components/knowledge-base/components/FilterBar.scss +1 -0
  250. package/src/components/knowledge-base/components/FilterBar.tsx +12 -8
  251. package/src/components/knowledge-base/components/FlowsTab.tsx +20 -20
  252. package/src/components/knowledge-base/components/KnowledgeBaseHeader.tsx +7 -6
  253. package/src/components/knowledge-base/components/KnowledgeContentControls.tsx +35 -0
  254. package/src/components/knowledge-base/components/KnowledgeList.scss +14 -3
  255. package/src/components/knowledge-base/components/KnowledgeMobilePanel.tsx +122 -0
  256. package/src/components/knowledge-base/components/KnowledgeSidebar.tsx +97 -0
  257. package/src/components/knowledge-base/components/LoadingState.scss +2 -1
  258. package/src/components/knowledge-base/components/ProjectSkillsList.tsx +79 -0
  259. package/src/components/knowledge-base/components/RuleList.scss +3 -0
  260. package/src/components/knowledge-base/components/RulesTab.tsx +31 -30
  261. package/src/components/knowledge-base/components/SectionHeader.scss +13 -1
  262. package/src/components/knowledge-base/components/SectionHeader.tsx +5 -3
  263. package/src/components/knowledge-base/components/SkillArchiveInput.tsx +43 -0
  264. package/src/components/knowledge-base/components/SkillHubResultItem.tsx +112 -0
  265. package/src/components/knowledge-base/components/SkillMarketResults.tsx +98 -0
  266. package/src/components/knowledge-base/components/SkillMarketView.tsx +198 -0
  267. package/src/components/knowledge-base/components/SkillMarketView.types.ts +28 -0
  268. package/src/components/knowledge-base/components/SkillRegistryErrors.tsx +21 -0
  269. package/src/components/knowledge-base/components/SkillRegistryModal.tsx +74 -0
  270. package/src/components/knowledge-base/components/SkillsCliModal.tsx +154 -0
  271. package/src/components/knowledge-base/components/SkillsTab.scss +424 -0
  272. package/src/components/knowledge-base/components/SkillsTab.tsx +319 -35
  273. package/src/components/knowledge-base/components/SkillsTabActions.tsx +88 -0
  274. package/src/components/knowledge-base/components/SpecList.scss +3 -0
  275. package/src/components/knowledge-base/components/TabContent.scss +4 -3
  276. package/src/components/knowledge-base/components/skill-hub-utils.ts +108 -0
  277. package/src/components/knowledge-base/components/use-skill-market-filters.ts +37 -0
  278. package/src/components/knowledge-base/components/use-skill-market-query-input.ts +44 -0
  279. package/src/components/knowledge-base/components/use-skill-market-search.ts +49 -0
  280. package/src/components/knowledge-base/components/use-skill-registry-modal.ts +68 -0
  281. package/src/components/monaco/monaco-runtime.ts +44 -0
  282. package/src/components/monaco/use-monaco-theme.ts +63 -0
  283. package/src/components/nav-rail-account-actions.tsx +104 -0
  284. package/src/components/server-connection/ServerConnectionGate.scss +356 -0
  285. package/src/components/server-connection/ServerConnectionGate.tsx +238 -0
  286. package/src/components/server-connection/ServerConnectionProfileModal.tsx +145 -0
  287. package/src/components/server-connection/ServerConnectionProfiles.tsx +113 -0
  288. package/src/components/server-connection/ServerConnectionUrlInput.tsx +85 -0
  289. package/src/components/sidebar/SidebarHeader.scss +5 -41
  290. package/src/components/sidebar/SidebarHeader.tsx +74 -66
  291. package/src/components/sidebar/SidebarHeaderSearchActions.tsx +24 -28
  292. package/src/components/sidebar-list/SidebarListHeader.scss +246 -0
  293. package/src/components/sidebar-list/SidebarListHeader.tsx +146 -0
  294. package/src/components/workspace/ContextFilePicker.scss +9 -26
  295. package/src/components/workspace/ContextFilePicker.tsx +31 -113
  296. package/src/components/workspace/context-file-types.ts +36 -0
  297. package/src/components/workspace/project-file-tree/ProjectFileTree.scss +298 -0
  298. package/src/components/workspace/project-file-tree/ProjectFileTree.tsx +138 -0
  299. package/src/components/workspace/project-file-tree/ProjectFileTreeRow.tsx +167 -0
  300. package/src/components/workspace/project-file-tree/ProjectFileTreeRowContextMenu.tsx +106 -0
  301. package/src/components/workspace/project-file-tree/ProjectFileTreeRows.tsx +139 -0
  302. package/src/components/workspace/project-file-tree/project-file-tree-helpers.ts +101 -0
  303. package/src/components/workspace/project-file-tree/project-file-tree-icons.ts +93 -0
  304. package/src/components/workspace/project-file-tree/project-file-tree-types.ts +27 -0
  305. package/src/components/workspace/project-file-tree/use-project-file-tree-data.ts +197 -0
  306. package/src/components/workspace/project-file-tree/use-project-file-tree-selection.ts +144 -0
  307. package/src/hooks/chat/chat-session-target.ts +69 -0
  308. package/src/hooks/chat/chat-session-workspace-draft.ts +11 -4
  309. package/src/hooks/chat/interaction-state.ts +1 -0
  310. package/src/hooks/chat/optimistic-session-creation.ts +189 -0
  311. package/src/hooks/chat/use-chat-adapter-account-selection.tsx +156 -0
  312. package/src/hooks/chat/use-chat-route-bottom-panel.ts +181 -0
  313. package/src/hooks/chat/use-chat-route-deep-link-view.ts +33 -0
  314. package/src/hooks/chat/use-chat-session-actions.ts +259 -65
  315. package/src/hooks/chat/use-chat-session-messages.ts +71 -4
  316. package/src/hooks/chat/use-chat-session.ts +36 -1
  317. package/src/hooks/chat/workspace-file-panel-state.ts +43 -0
  318. package/src/hooks/session-subscription-cache.ts +25 -0
  319. package/src/hooks/use-chat-layout-query-state.ts +29 -0
  320. package/src/hooks/use-sender-header-query-state.ts +35 -0
  321. package/src/hooks/use-session-subscription.ts +17 -8
  322. package/src/i18n-resources.ts +44 -0
  323. package/src/i18n.ts +21 -6
  324. package/src/main.tsx +8 -0
  325. package/src/pwa.ts +46 -0
  326. package/src/resources/locales/en.json +729 -24
  327. package/src/resources/locales/zh.json +731 -26
  328. package/src/routes/ChatRoute.scss +105 -7
  329. package/src/routes/ChatRoute.tsx +11 -165
  330. package/src/routes/ChatRouteBottomPanel.tsx +47 -0
  331. package/src/routes/ChatRouteView.tsx +199 -0
  332. package/src/runtime-config.ts +155 -2
  333. package/src/server-connection-history.ts +179 -0
  334. package/src/store/index.ts +40 -0
  335. package/src/styles/global.scss +3 -0
  336. package/src/utils/mobile-viewport.ts +67 -0
  337. package/src/version-compatibility.ts +37 -0
  338. package/src/vite-env.d.ts +9 -0
  339. package/src/ws.ts +20 -9
  340. package/vite.config.ts +23 -1
  341. package/dist/assets/channel-Dnopc5A6.js +0 -1
  342. package/dist/assets/clone-sQthahUA.js +0 -1
  343. package/dist/assets/flowDiagram-v2-4f6560a1-OazrdWQO.js +0 -1
  344. package/dist/assets/index-o93dlo92.css +0 -32
  345. package/src/components/chat/NewSessionGuideCompactPanel.tsx +0 -130
  346. package/src/components/chat/NewSessionGuideGrid.tsx +0 -141
  347. package/src/components/chat/sender/@components/reference-actions/ReferencePermissionActionsPopover.tsx +0 -114
@@ -52,10 +52,12 @@ export function ChatHeader({
52
52
  lastUserMessage,
53
53
  activeView,
54
54
  isTerminalOpen,
55
+ isWorkspaceDrawerOpen,
55
56
  onCreateSession,
56
57
  onOpenSidebar,
57
58
  onViewChange,
58
- onToggleTerminal
59
+ onToggleTerminal,
60
+ onToggleWorkspaceDrawer
59
61
  }: {
60
62
  sessionInfo: SessionInfo | null
61
63
  sessionId?: string
@@ -68,10 +70,12 @@ export function ChatHeader({
68
70
  lastUserMessage?: string
69
71
  activeView: ChatHeaderView
70
72
  isTerminalOpen: boolean
73
+ isWorkspaceDrawerOpen: boolean
71
74
  onCreateSession?: () => void
72
75
  onOpenSidebar?: () => void
73
76
  onViewChange: (view: ChatHeaderView) => void
74
77
  onToggleTerminal: () => void
78
+ onToggleWorkspaceDrawer: () => void
75
79
  }) {
76
80
  const { t } = useTranslation()
77
81
  const { message } = App.useApp()
@@ -94,7 +98,9 @@ export function ChatHeader({
94
98
 
95
99
  const summary = sessionInfo?.type === 'summary' ? sessionInfo.summary : null
96
100
  const title = (sessionInfo?.type === 'init' ? sessionInfo.title : null) ?? sessionTitle
97
- const displayTitle = (title != null && title !== '')
101
+ const displayTitle = !hasSession
102
+ ? t('chat.newSessionTitle')
103
+ : (title != null && title !== '')
98
104
  ? title
99
105
  : (summary != null && summary !== '')
100
106
  ? summary
@@ -167,14 +173,6 @@ export function ChatHeader({
167
173
  }
168
174
  }))
169
175
  const compactMoreItems: MenuProps['items'] = [
170
- {
171
- key: 'terminal',
172
- label: t('chat.viewTerminal'),
173
- icon: <span className={`material-symbols-rounded chat-header-icon ${isTerminalOpen ? 'is-filled' : ''}`}>
174
- terminal
175
- </span>,
176
- onClick: onToggleTerminal
177
- },
178
176
  ...moreItems,
179
177
  ...(shouldShowDebugButton
180
178
  ? [{
@@ -187,6 +185,35 @@ export function ChatHeader({
187
185
  }]
188
186
  : [])
189
187
  ]
188
+ const terminalButton = (
189
+ <Tooltip title={resolveTooltipTitle(t('chat.viewTerminal'))}>
190
+ <Button
191
+ type='text'
192
+ className={`chat-header-action-button ${isTerminalOpen ? 'is-active' : ''}`}
193
+ title={t('chat.viewTerminal')}
194
+ aria-label={t('chat.viewTerminal')}
195
+ onClick={onToggleTerminal}
196
+ icon={<span className='chat-header-view-option material-symbols-rounded'>terminal</span>}
197
+ />
198
+ </Tooltip>
199
+ )
200
+ const workspaceDrawerButton = (
201
+ <Tooltip title={resolveTooltipTitle(t('chat.workspaceDrawerToggle'))}>
202
+ <Button
203
+ type='text'
204
+ className={`chat-header-action-button ${isWorkspaceDrawerOpen ? 'is-active' : ''}`}
205
+ title={t('chat.workspaceDrawerToggle')}
206
+ aria-label={t('chat.workspaceDrawerToggle')}
207
+ aria-pressed={isWorkspaceDrawerOpen}
208
+ onClick={onToggleWorkspaceDrawer}
209
+ icon={
210
+ <span className='chat-header-view-option material-symbols-rounded'>
211
+ {isWorkspaceDrawerOpen ? 'folder_open' : 'folder'}
212
+ </span>
213
+ }
214
+ />
215
+ </Tooltip>
216
+ )
190
217
 
191
218
  useEffect(() => {
192
219
  return () => {
@@ -293,6 +320,8 @@ export function ChatHeader({
293
320
  </Dropdown>
294
321
  </Tooltip>
295
322
  )}
323
+ {terminalButton}
324
+ {workspaceDrawerButton}
296
325
  {hasSession && (
297
326
  <Tooltip title={resolveTooltipTitle(t('common.moreActions'))}>
298
327
  <Dropdown menu={{ items: compactMoreItems }} placement='bottomRight' trigger={['click']}>
@@ -310,7 +339,7 @@ export function ChatHeader({
310
339
  )
311
340
  : (
312
341
  <>
313
- {viewItems.map(item => (
342
+ {hasSession && viewItems.map(item => (
314
343
  <Tooltip key={item.value} title={resolveTooltipTitle(item.title)}>
315
344
  <Button
316
345
  type='text'
@@ -324,17 +353,9 @@ export function ChatHeader({
324
353
  />
325
354
  </Tooltip>
326
355
  ))}
327
- <Tooltip title={resolveTooltipTitle(t('chat.viewTerminal'))}>
328
- <Button
329
- type='text'
330
- className={`chat-header-action-button ${isTerminalOpen ? 'is-active' : ''}`}
331
- title={t('chat.viewTerminal')}
332
- aria-label={t('chat.viewTerminal')}
333
- onClick={onToggleTerminal}
334
- icon={<span className='chat-header-view-option material-symbols-rounded'>terminal</span>}
335
- />
336
- </Tooltip>
337
- {shouldShowDebugButton && (
356
+ {terminalButton}
357
+ {workspaceDrawerButton}
358
+ {hasSession && shouldShowDebugButton && (
338
359
  <Tooltip title={resolveTooltipTitle(isDebugMode ? t('chat.debugDisable') : t('chat.debugEnable'))}>
339
360
  <Button
340
361
  type='text'
@@ -346,17 +367,19 @@ export function ChatHeader({
346
367
  />
347
368
  </Tooltip>
348
369
  )}
349
- <Tooltip title={resolveTooltipTitle(t('common.moreActions'))}>
350
- <Dropdown menu={{ items: moreItems }} placement='bottomRight' trigger={['click']}>
351
- <Button
352
- type='text'
353
- className='chat-header-action-button'
354
- title={t('common.moreActions')}
355
- aria-label={t('common.moreActions')}
356
- icon={<span className='chat-header-view-option material-symbols-rounded'>more_vert</span>}
357
- />
358
- </Dropdown>
359
- </Tooltip>
370
+ {hasSession && (
371
+ <Tooltip title={resolveTooltipTitle(t('common.moreActions'))}>
372
+ <Dropdown menu={{ items: moreItems }} placement='bottomRight' trigger={['click']}>
373
+ <Button
374
+ type='text'
375
+ className='chat-header-action-button'
376
+ title={t('common.moreActions')}
377
+ aria-label={t('common.moreActions')}
378
+ icon={<span className='chat-header-view-option material-symbols-rounded'>more_vert</span>}
379
+ />
380
+ </Dropdown>
381
+ </Tooltip>
382
+ )}
360
383
  </>
361
384
  )}
362
385
  </div>
@@ -13,13 +13,22 @@ import type {
13
13
  SessionQueuedMessage,
14
14
  SessionQueuedMessageMode
15
15
  } from '@vibe-forge/core'
16
- import type { ConfigResponse, SessionInfo } from '@vibe-forge/types'
16
+ import type { ConfigResponse, ConversationStarterConfig, SessionInfo } from '@vibe-forge/types'
17
17
 
18
18
  import { getConfig } from '#~/api'
19
+ import { ComposerLanding, ComposerStack } from '#~/components/composer-landing/ComposerLanding'
20
+ import type { ContextReferenceRequest } from '#~/components/workspace/context-file-types'
21
+ import {
22
+ DEFAULT_CHAT_SESSION_TARGET_DRAFT,
23
+ getChatSessionTargetDraftFromSession,
24
+ isChatSessionTargetReady
25
+ } from '#~/hooks/chat/chat-session-target'
26
+ import type { ChatSessionTargetDraft } from '#~/hooks/chat/chat-session-target'
19
27
  import {
20
28
  DEFAULT_CHAT_SESSION_WORKSPACE_DRAFT,
21
29
  getChatSessionWorkspaceDraftFromConfig
22
30
  } from '#~/hooks/chat/chat-session-workspace-draft'
31
+ import type { ChatAdapterAccountOption } from '#~/hooks/chat/use-chat-adapter-account-selection'
23
32
  import type { ChatEffort } from '#~/hooks/chat/use-chat-effort'
24
33
  import type { ModelSelectMenuGroup, ModelSelectOption } from '#~/hooks/chat/use-chat-model-adapter-selection'
25
34
  import type { PermissionMode } from '#~/hooks/chat/use-chat-permission-mode'
@@ -33,8 +42,15 @@ import { QueuedMessagesCard } from './QueuedMessagesCard'
33
42
  import { MessageItem } from './messages/MessageItem'
34
43
  import { MessageStatusNotice } from './messages/MessageStatusNotice'
35
44
  import type { ChatHistoryStatusNotice } from './messages/build-chat-history-status-notices'
45
+ import { getLastAssistantActionAnchorId } from './messages/message-action-utils'
36
46
  import { buildMessageTurns } from './messages/message-turns'
37
47
  import { processMessages } from './messages/message-utils'
48
+ import {
49
+ buildConversationStarterInitialContent,
50
+ buildConversationStarterTargetDraft,
51
+ buildConversationStarterWorkspacePatch,
52
+ getNewSessionGuideData
53
+ } from './new-session-guide-config'
38
54
  import { SenderInteractionPanel } from './sender/@components/sender-interaction-panel/SenderInteractionPanel'
39
55
  import { Sender } from './sender/Sender'
40
56
  import { ChatStatusBar } from './status-bar/ChatStatusBar'
@@ -73,8 +89,13 @@ export function ChatHistoryView({
73
89
  selectedAdapter,
74
90
  adapterOptions,
75
91
  onAdapterChange,
92
+ selectedAccount,
93
+ accountOptions,
94
+ showAccountSelector,
95
+ onAccountChange,
76
96
  modelUnavailable,
77
- hasAvailableModels
97
+ hasAvailableModels,
98
+ contextReferenceRequest
78
99
  }: {
79
100
  isReady: boolean
80
101
  messages: ChatMessage[]
@@ -108,8 +129,13 @@ export function ChatHistoryView({
108
129
  selectedAdapter?: string
109
130
  adapterOptions: Array<{ value: string; label: React.ReactNode }>
110
131
  onAdapterChange: (adapter: string) => void
132
+ selectedAccount?: string
133
+ accountOptions: ChatAdapterAccountOption[]
134
+ showAccountSelector: boolean
135
+ onAccountChange: (account: string) => void
111
136
  modelUnavailable: boolean
112
137
  hasAvailableModels: boolean
138
+ contextReferenceRequest?: ContextReferenceRequest | null
113
139
  }) {
114
140
  const { t } = useTranslation()
115
141
  const { message } = App.useApp()
@@ -121,17 +147,18 @@ export function ChatHistoryView({
121
147
  [configRes]
122
148
  )
123
149
  const workspaceDraftDirtyRef = useRef(false)
150
+ const [sessionTargetDraft, setSessionTargetDraft] = useState<ChatSessionTargetDraft>(() => ({
151
+ ...DEFAULT_CHAT_SESSION_TARGET_DRAFT
152
+ }))
124
153
  const [workspaceDraft, setWorkspaceDraft] = useState(() => ({
125
154
  ...DEFAULT_CHAT_SESSION_WORKSPACE_DRAFT
126
155
  }))
127
- const historyRenderCount = messages.length + historyStatusNotices.length
128
- const { messagesEndRef, messagesContainerRef, messagesContentRef, showScrollBottom, scrollToBottom } = useChatScroll({
129
- contentVersion: historyRenderCount
130
- })
156
+ const [newSessionInitialContent, setNewSessionInitialContent] = useState<ChatMessageContent[] | undefined>(undefined)
131
157
  const {
132
158
  isCreating,
133
159
  send,
134
160
  sendContent,
161
+ retrySessionCreation,
135
162
  enqueueContent,
136
163
  removeQueuedContent,
137
164
  moveQueuedContent,
@@ -148,9 +175,16 @@ export function ChatHistoryView({
148
175
  effort,
149
176
  permissionMode,
150
177
  adapter: selectedAdapter,
178
+ account: selectedAccount,
179
+ sessionTargetDraft,
151
180
  workspaceDraft,
152
181
  onClearMessages
153
182
  })
183
+ const showThinkingIndicator = isCreating || session?.status === 'running'
184
+ const historyRenderCount = messages.length + historyStatusNotices.length + (showThinkingIndicator ? 1 : 0)
185
+ const { messagesEndRef, messagesContainerRef, messagesContentRef, showScrollBottom, scrollToBottom } = useChatScroll({
186
+ contentVersion: historyRenderCount
187
+ })
154
188
  const initialScrollDoneRef = useRef(false)
155
189
  const handledHashAnchorIdRef = useRef('')
156
190
  const handledTargetScrollKeyRef = useRef('')
@@ -160,6 +194,10 @@ export function ChatHistoryView({
160
194
  const [queuedDraft, setQueuedDraft] = useState<{ content: ChatMessageContent[] } | null>(null)
161
195
  const [activeInteractionOptionIndex, setActiveInteractionOptionIndex] = useState(0)
162
196
  const interactionOptions = interactionRequest?.payload.options ?? []
197
+ const { announcements, startupPresets, builtinActions } = useMemo(
198
+ () => getNewSessionGuideData(configRes),
199
+ [configRes]
200
+ )
163
201
  const buildUserMessage = (content: string | ChatMessageContent[]): ChatMessage => {
164
202
  const id = globalThis.crypto?.randomUUID
165
203
  ? globalThis.crypto.randomUUID()
@@ -171,8 +209,20 @@ export function ChatHistoryView({
171
209
  createdAt: Date.now()
172
210
  }
173
211
  }
212
+ const validateSessionTarget = () => {
213
+ if (session?.id != null || isChatSessionTargetReady(sessionTargetDraft)) {
214
+ return true
215
+ }
216
+
217
+ void message.warning(t('chat.sessionTarget.missingResourceWarning'))
218
+ return false
219
+ }
174
220
 
175
221
  const handleSendContent = async (content: ChatMessageContent[], mode?: SessionQueuedMessageMode) => {
222
+ if (!validateSessionTarget()) {
223
+ return false
224
+ }
225
+
176
226
  const resolvedMode = mode ?? queueMode
177
227
 
178
228
  if (session?.id && session.status === 'running') {
@@ -185,12 +235,7 @@ export function ChatHistoryView({
185
235
  }
186
236
 
187
237
  if (!session?.id) {
188
- const optimisticMessage = buildUserMessage(content)
189
- setMessages((prev) => [...prev, optimisticMessage])
190
238
  const didSend = await sendContent(content, mode)
191
- if (!didSend) {
192
- setMessages((prev) => prev.filter((message) => message.id !== optimisticMessage.id))
193
- }
194
239
  if (didSend && queuedDraft != null) {
195
240
  setQueuedDraft(null)
196
241
  setQueueMode('steer')
@@ -210,6 +255,10 @@ export function ChatHistoryView({
210
255
  }
211
256
 
212
257
  const handleSend = async (text: string, mode?: SessionQueuedMessageMode) => {
258
+ if (!validateSessionTarget()) {
259
+ return false
260
+ }
261
+
213
262
  const resolvedMode = mode ?? queueMode
214
263
 
215
264
  if (session?.id && session.status === 'running') {
@@ -222,12 +271,7 @@ export function ChatHistoryView({
222
271
  }
223
272
 
224
273
  if (!session?.id) {
225
- const optimisticMessage = buildUserMessage(text)
226
- setMessages((prev) => [...prev, optimisticMessage])
227
274
  const didSend = await send(text, mode)
228
- if (!didSend) {
229
- setMessages((prev) => prev.filter((message) => message.id !== optimisticMessage.id))
230
- }
231
275
  if (didSend && queuedDraft != null) {
232
276
  setQueuedDraft(null)
233
277
  setQueueMode('steer')
@@ -253,7 +297,13 @@ export function ChatHistoryView({
253
297
  setExpandedTurnIds(new Set())
254
298
  setQueuedDraft(null)
255
299
  setQueueMode('steer')
256
- }, [session?.id])
300
+ setNewSessionInitialContent(undefined)
301
+ setSessionTargetDraft(
302
+ session?.id != null
303
+ ? getChatSessionTargetDraftFromSession(session)
304
+ : { ...DEFAULT_CHAT_SESSION_TARGET_DRAFT }
305
+ )
306
+ }, [session?.id, session?.promptName, session?.promptType])
257
307
  useEffect(() => {
258
308
  if (session?.id != null) {
259
309
  return
@@ -339,6 +389,56 @@ export function ChatHistoryView({
339
389
  }
340
390
  const isInlineEditing = editingMessageId != null
341
391
  const shouldShowNewSessionGuide = !session?.id && messages.length === 0 && historyStatusNotices.length === 0
392
+ const handleApplyConversationStarter = useCallback((starter: ConversationStarterConfig) => {
393
+ if (session?.id != null) {
394
+ return
395
+ }
396
+
397
+ if (starter.mode != null) {
398
+ setSessionTargetDraft(buildConversationStarterTargetDraft(starter))
399
+ }
400
+
401
+ const workspacePatch = buildConversationStarterWorkspacePatch(starter)
402
+ if (workspacePatch != null) {
403
+ workspaceDraftDirtyRef.current = true
404
+ setWorkspaceDraft(current => ({
405
+ ...current,
406
+ ...workspacePatch
407
+ }))
408
+ }
409
+
410
+ const model = starter.model?.trim()
411
+ if (model != null && model !== '') {
412
+ onModelChange(model)
413
+ }
414
+
415
+ const adapter = starter.adapter?.trim()
416
+ if (adapter != null && adapter !== '') {
417
+ onAdapterChange(adapter)
418
+ }
419
+
420
+ const account = starter.account?.trim()
421
+ if (account != null && account !== '') {
422
+ onAccountChange(account)
423
+ }
424
+
425
+ if (starter.effort != null) {
426
+ onEffortChange(starter.effort)
427
+ }
428
+
429
+ if (starter.permissionMode != null) {
430
+ onPermissionModeChange(starter.permissionMode)
431
+ }
432
+
433
+ setNewSessionInitialContent(buildConversationStarterInitialContent(starter))
434
+ }, [
435
+ onAccountChange,
436
+ onAdapterChange,
437
+ onEffortChange,
438
+ onModelChange,
439
+ onPermissionModeChange,
440
+ session?.id
441
+ ])
342
442
  const renderItems = useMemo(() => processMessages(messages), [messages])
343
443
  const hashAnchorId = useMemo(() => decodeURIComponent(location.hash.replace(/^#/, '')), [location.hash])
344
444
  const targetAnchorId = useMemo(() => {
@@ -365,16 +465,7 @@ export function ChatHistoryView({
365
465
  hashAnchorId: hashAnchorId !== '' ? hashAnchorId : targetAnchorId,
366
466
  keepLastTurnExpanded: isCreating || session?.status === 'running' || session?.status === 'waiting_input'
367
467
  }), [expandedTurnIds, hashAnchorId, isCreating, renderItems, session?.status, targetAnchorId])
368
- const lastAssistantActionAnchorId = useMemo(() => {
369
- for (let index = renderItems.length - 1; index >= 0; index -= 1) {
370
- const item = renderItems[index]
371
- if (item == null) continue
372
- if (item.type === 'tool-group') continue
373
- if (item.message.role === 'user') continue
374
- return item.anchorId
375
- }
376
- return null
377
- }, [renderItems])
468
+ const lastAssistantActionAnchorId = useMemo(() => getLastAssistantActionAnchorId(renderItems), [renderItems])
378
469
  const handleEditQueuedMessage = async (item: SessionQueuedMessage) => {
379
470
  const removed = await removeQueuedContent(item.id)
380
471
  if (!removed) {
@@ -604,6 +695,111 @@ export function ChatHistoryView({
604
695
  )
605
696
  }
606
697
 
698
+ const composerContent = (
699
+ <>
700
+ {isPermissionInteraction && interactionPanel}
701
+ <CurrentTodoList messages={messages} />
702
+ {!isInlineEditing && (
703
+ <QueuedMessagesCard
704
+ mode='next'
705
+ items={queuedMessages.next}
706
+ onMove={(item, targetMode) => void handleMoveQueuedMessage(item, targetMode)}
707
+ onDelete={(item) => void removeQueuedContent(item.id)}
708
+ onEdit={(item) => void handleEditQueuedMessage(item)}
709
+ onReorder={(ids) => reorderQueuedContent('next', ids)}
710
+ />
711
+ )}
712
+ {!isInlineEditing && (
713
+ <QueuedMessagesCard
714
+ mode='steer'
715
+ items={queuedMessages.steer}
716
+ onMove={(item, targetMode) => void handleMoveQueuedMessage(item, targetMode)}
717
+ onDelete={(item) => void removeQueuedContent(item.id)}
718
+ onEdit={(item) => void handleEditQueuedMessage(item)}
719
+ onReorder={(ids) => reorderQueuedContent('steer', ids)}
720
+ />
721
+ )}
722
+ {!isPermissionInteraction && interactionPanel}
723
+ {!isInlineEditing && (
724
+ <div className='sender-container'>
725
+ <Sender
726
+ onSend={handleSend}
727
+ onSendContent={handleSendContent}
728
+ adapterLocked={session?.id != null}
729
+ sessionId={session?.id}
730
+ sessionStatus={isCreating ? 'running' : session?.status}
731
+ onInterrupt={interrupt}
732
+ onClear={clearMessages}
733
+ sessionInfo={sessionInfo}
734
+ interactionRequest={interactionRequest}
735
+ onInteractionResponse={onInteractionResponse}
736
+ interactionOptionNavigation={interactionRequest != null && interactionOptions.length > 0
737
+ ? {
738
+ optionCount: interactionOptions.length,
739
+ activeIndex: activeInteractionOptionIndex,
740
+ onMove: handleMoveInteractionOption,
741
+ onSubmit: handleSubmitActiveInteractionOption
742
+ }
743
+ : undefined}
744
+ initialContent={queuedDraft?.content ?? newSessionInitialContent}
745
+ placeholder={placeholder}
746
+ submitLabel={queuedDraft != null ? t('chat.queue.requeueMessage') : undefined}
747
+ modelMenuGroups={modelMenuGroups}
748
+ modelSearchOptions={modelSearchOptions}
749
+ recommendedModelOptions={recommendedModelOptions}
750
+ servicePreviewModelOptions={servicePreviewModelOptions}
751
+ onToggleRecommendedModel={onToggleRecommendedModel}
752
+ updatingRecommendedModelValue={updatingRecommendedModelValue}
753
+ selectedModel={selectedModel}
754
+ onModelChange={onModelChange}
755
+ effort={effort}
756
+ effortOptions={effortOptions}
757
+ onEffortChange={onEffortChange}
758
+ permissionMode={permissionMode}
759
+ permissionModeOptions={permissionModeOptions}
760
+ onPermissionModeChange={onPermissionModeChange}
761
+ selectedAdapter={selectedAdapter}
762
+ adapterOptions={adapterOptions}
763
+ onAdapterChange={onAdapterChange}
764
+ selectedAccount={selectedAccount}
765
+ accountOptions={accountOptions}
766
+ showAccountSelector={showAccountSelector}
767
+ onAccountChange={onAccountChange}
768
+ modelUnavailable={modelUnavailable}
769
+ sessionTarget={{
770
+ draft: session?.id != null ? getChatSessionTargetDraftFromSession(session) : sessionTargetDraft,
771
+ locked: session?.id != null,
772
+ disabled: isCreating,
773
+ onChange: setSessionTargetDraft
774
+ }}
775
+ queueMode={queueMode}
776
+ onQueueModeChange={setQueueMode}
777
+ contextReferenceRequest={contextReferenceRequest}
778
+ />
779
+ <ChatStatusBar
780
+ draftWorkspace={workspaceDraft}
781
+ isCreating={isCreating}
782
+ sessionId={session?.id}
783
+ adapterLocked={session?.id != null}
784
+ isThinking={isCreating || session?.status === 'running'}
785
+ modelUnavailable={modelUnavailable}
786
+ selectedAdapter={selectedAdapter}
787
+ adapterOptions={adapterOptions}
788
+ onAdapterChange={onAdapterChange}
789
+ selectedAccount={selectedAccount}
790
+ accountOptions={accountOptions}
791
+ showAccountSelector={showAccountSelector}
792
+ onAccountChange={onAccountChange}
793
+ onDraftWorkspaceChange={(nextDraft) => {
794
+ workspaceDraftDirtyRef.current = true
795
+ setWorkspaceDraft(nextDraft)
796
+ }}
797
+ />
798
+ </div>
799
+ )}
800
+ </>
801
+ )
802
+
607
803
  return (
608
804
  <>
609
805
  <div className={`chat-messages ${isReady ? 'ready' : ''}`} ref={messagesContainerRef}>
@@ -644,8 +840,16 @@ export function ChatHistoryView({
644
840
  key={notice.id}
645
841
  notice={notice}
646
842
  onRetryConnection={onRetryConnection}
843
+ onRetrySessionCreation={() => {
844
+ void retrySessionCreation()
845
+ }}
647
846
  />
648
847
  ))}
848
+ {showThinkingIndicator && (
849
+ <div className='chat-thinking-indicator' role='status' aria-live='polite'>
850
+ <span className='chat-thinking-indicator__text'>{t('chat.thinking')}</span>
851
+ </div>
852
+ )}
649
853
  <div ref={messagesEndRef} />
650
854
  </div>
651
855
 
@@ -656,101 +860,26 @@ export function ChatHistoryView({
656
860
  )}
657
861
  </div>
658
862
 
659
- {shouldShowNewSessionGuide && !isCompactLayout && (
660
- <div className='new-session-guide-wrapper'>
661
- <NewSessionGuide />
662
- </div>
663
- )}
664
-
665
- {shouldShowNewSessionGuide && isCompactLayout && (
666
- <div className='new-session-guide-wrapper is-compact-layout'>
667
- <NewSessionGuide />
668
- </div>
669
- )}
670
-
671
- <div className='chat-composer-stack'>
672
- <div className='chat-composer-stack__inner'>
673
- {isPermissionInteraction && interactionPanel}
674
- <CurrentTodoList messages={messages} />
675
- {!isInlineEditing && (
676
- <QueuedMessagesCard
677
- mode='next'
678
- items={queuedMessages.next}
679
- onMove={(item, targetMode) => void handleMoveQueuedMessage(item, targetMode)}
680
- onDelete={(item) => void removeQueuedContent(item.id)}
681
- onEdit={(item) => void handleEditQueuedMessage(item)}
682
- onReorder={(ids) => reorderQueuedContent('next', ids)}
863
+ {shouldShowNewSessionGuide
864
+ ? (
865
+ <ComposerLanding
866
+ compact={isCompactLayout}
867
+ composer={composerContent}
868
+ contentClassName='chat-history-view__new-session-content'
869
+ >
870
+ <NewSessionGuide
871
+ announcements={announcements}
872
+ startupPresets={startupPresets}
873
+ builtinActions={builtinActions}
874
+ onApplyStarter={handleApplyConversationStarter}
683
875
  />
684
- )}
685
- {!isInlineEditing && (
686
- <QueuedMessagesCard
687
- mode='steer'
688
- items={queuedMessages.steer}
689
- onMove={(item, targetMode) => void handleMoveQueuedMessage(item, targetMode)}
690
- onDelete={(item) => void removeQueuedContent(item.id)}
691
- onEdit={(item) => void handleEditQueuedMessage(item)}
692
- onReorder={(ids) => reorderQueuedContent('steer', ids)}
693
- />
694
- )}
695
- {!isPermissionInteraction && interactionPanel}
696
- {!isInlineEditing && (
697
- <div className='sender-container'>
698
- <Sender
699
- onSend={handleSend}
700
- onSendContent={handleSendContent}
701
- adapterLocked={session?.id != null}
702
- sessionId={session?.id}
703
- sessionStatus={isCreating ? 'running' : session?.status}
704
- onInterrupt={interrupt}
705
- onClear={clearMessages}
706
- sessionInfo={sessionInfo}
707
- interactionRequest={interactionRequest}
708
- onInteractionResponse={onInteractionResponse}
709
- interactionOptionNavigation={interactionRequest != null && interactionOptions.length > 0
710
- ? {
711
- optionCount: interactionOptions.length,
712
- activeIndex: activeInteractionOptionIndex,
713
- onMove: handleMoveInteractionOption,
714
- onSubmit: handleSubmitActiveInteractionOption
715
- }
716
- : undefined}
717
- initialContent={queuedDraft?.content}
718
- placeholder={placeholder}
719
- submitLabel={queuedDraft != null ? t('chat.queue.requeueMessage') : undefined}
720
- modelMenuGroups={modelMenuGroups}
721
- modelSearchOptions={modelSearchOptions}
722
- recommendedModelOptions={recommendedModelOptions}
723
- servicePreviewModelOptions={servicePreviewModelOptions}
724
- onToggleRecommendedModel={onToggleRecommendedModel}
725
- updatingRecommendedModelValue={updatingRecommendedModelValue}
726
- selectedModel={selectedModel}
727
- onModelChange={onModelChange}
728
- effort={effort}
729
- effortOptions={effortOptions}
730
- onEffortChange={onEffortChange}
731
- permissionMode={permissionMode}
732
- permissionModeOptions={permissionModeOptions}
733
- onPermissionModeChange={onPermissionModeChange}
734
- selectedAdapter={selectedAdapter}
735
- adapterOptions={adapterOptions}
736
- onAdapterChange={onAdapterChange}
737
- modelUnavailable={modelUnavailable}
738
- queueMode={queueMode}
739
- onQueueModeChange={setQueueMode}
740
- />
741
- <ChatStatusBar
742
- draftWorkspace={workspaceDraft}
743
- isCreating={isCreating}
744
- sessionId={session?.id}
745
- onDraftWorkspaceChange={(nextDraft) => {
746
- workspaceDraftDirtyRef.current = true
747
- setWorkspaceDraft(nextDraft)
748
- }}
749
- />
750
- </div>
751
- )}
752
- </div>
753
- </div>
876
+ </ComposerLanding>
877
+ )
878
+ : (
879
+ <ComposerStack>
880
+ {composerContent}
881
+ </ComposerStack>
882
+ )}
754
883
  </>
755
884
  )
756
885
  }