@vibe-forge/client 0.11.2 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (232) hide show
  1. package/cli.cjs +6 -11
  2. package/dist/assets/{arc-De_WjPJ3.js → arc-CbOXL0l9.js} +1 -1
  3. package/dist/assets/{blockDiagram-c4efeb88-C4aR2zTE.js → blockDiagram-c4efeb88-CqxINvsS.js} +1 -1
  4. package/dist/assets/{c4Diagram-c83219d4-BZH3rq_m.js → c4Diagram-c83219d4-BKazU0hb.js} +1 -1
  5. package/dist/assets/channel-Dnopc5A6.js +1 -0
  6. package/dist/assets/{classDiagram-beda092f-BzJgBrIK.js → classDiagram-beda092f-fAFX5BpB.js} +1 -1
  7. package/dist/assets/{classDiagram-v2-2358418a-5ZtXcnT3.js → classDiagram-v2-2358418a-w1VkNGJj.js} +1 -1
  8. package/dist/assets/clone-sQthahUA.js +1 -0
  9. package/dist/assets/{createText-1719965b-DUVvEtmR.js → createText-1719965b-CEinakVP.js} +1 -1
  10. package/dist/assets/{cssMode-GoTNjuXX.js → cssMode-DPqRki4y.js} +1 -1
  11. package/dist/assets/{edges-96097737-Dd7m4Cvs.js → edges-96097737-Cb0F1_3K.js} +1 -1
  12. package/dist/assets/{erDiagram-0228fc6a-DxqFlG_f.js → erDiagram-0228fc6a-C-N2fx-J.js} +1 -1
  13. package/dist/assets/{flowDb-c6c81e3f-DU0C5kCI.js → flowDb-c6c81e3f-D1Xz_8Gf.js} +1 -1
  14. package/dist/assets/{flowDiagram-50d868cf-Di1uDa_X.js → flowDiagram-50d868cf-DyPSZyAj.js} +1 -1
  15. package/dist/assets/flowDiagram-v2-4f6560a1-OazrdWQO.js +1 -0
  16. package/dist/assets/{flowchart-elk-definition-6af322e1-CwG8aty5.js → flowchart-elk-definition-6af322e1-Dr1DDXwE.js} +1 -1
  17. package/dist/assets/{freemarker2-j39cqTlI.js → freemarker2-C3DvPFaK.js} +1 -1
  18. package/dist/assets/{ganttDiagram-a2739b55-baO_lzL-.js → ganttDiagram-a2739b55-DmvY1GRj.js} +1 -1
  19. package/dist/assets/{gitGraphDiagram-82fe8481-COoHjYMf.js → gitGraphDiagram-82fe8481-CoXfPYYi.js} +1 -1
  20. package/dist/assets/{graph-KxESr4M5.js → graph-BkDQy7Qt.js} +1 -1
  21. package/dist/assets/{handlebars-BgjdZO8G.js → handlebars-BcTFdqjl.js} +1 -1
  22. package/dist/assets/{html-Ba7tYObe.js → html-Dg-O6XFr.js} +1 -1
  23. package/dist/assets/{htmlMode-Bztvbig1.js → htmlMode-B_wqYWvn.js} +1 -1
  24. package/dist/assets/{index-5325376f-BMTAx2mL.js → index-5325376f-kxPTR3_e.js} +1 -1
  25. package/dist/assets/index-o93dlo92.css +32 -0
  26. package/dist/assets/{index-Pm_kLJvG.js → index-wkhI4dr6.js} +350 -329
  27. package/dist/assets/{infoDiagram-8eee0895-CC74qbHY.js → infoDiagram-8eee0895-BEvqkwPI.js} +1 -1
  28. package/dist/assets/{javascript-C1e1cllX.js → javascript-DhlOH8_z.js} +1 -1
  29. package/dist/assets/{journeyDiagram-c64418c1-C4MyOdE6.js → journeyDiagram-c64418c1-gKtLYmmp.js} +1 -1
  30. package/dist/assets/{jsonMode-BC98AlvF.js → jsonMode-DxTbF9OD.js} +1 -1
  31. package/dist/assets/{layout-CxAyTlr7.js → layout-CDaZEk6E.js} +1 -1
  32. package/dist/assets/{line-DhaUfI71.js → line-DNRQu8iq.js} +1 -1
  33. package/dist/assets/{linear-MYukzldK.js → linear-Cph9Z6_j.js} +1 -1
  34. package/dist/assets/{liquid-DahfJEYl.js → liquid-ByZ6JgRG.js} +1 -1
  35. package/dist/assets/{lspLanguageFeatures-BWDJcswW.js → lspLanguageFeatures-DzvhkgnM.js} +1 -1
  36. package/dist/assets/{mdx-BELlF_FD.js → mdx-D8RGHTl6.js} +1 -1
  37. package/dist/assets/{mermaid.core-BrQnSGSY.js → mermaid.core-BgcryF__.js} +4 -4
  38. package/dist/assets/{mindmap-definition-8da855dc-B0FoxTiy.js → mindmap-definition-8da855dc-WrxK0FcB.js} +1 -1
  39. package/dist/assets/{pieDiagram-a8764435-Ddr2cjSL.js → pieDiagram-a8764435-VsZBsiQy.js} +1 -1
  40. package/dist/assets/{python--C9if_AD.js → python-CXVtk_cg.js} +1 -1
  41. package/dist/assets/{quadrantDiagram-1e28029f-BlEs7Mrl.js → quadrantDiagram-1e28029f-BVlgwOvU.js} +1 -1
  42. package/dist/assets/{razor-B9U9JxKn.js → razor-0tind7h2.js} +1 -1
  43. package/dist/assets/{requirementDiagram-08caed73-kEFOAu2v.js → requirementDiagram-08caed73-CpPMPoYp.js} +1 -1
  44. package/dist/assets/{sankeyDiagram-a04cb91d-BBghez8I.js → sankeyDiagram-a04cb91d-Cm5nnRmc.js} +1 -1
  45. package/dist/assets/{sequenceDiagram-c5b8d532-CJqgzdUE.js → sequenceDiagram-c5b8d532-DpMlJvJB.js} +1 -1
  46. package/dist/assets/{stateDiagram-1ecb1508-BER4XEI6.js → stateDiagram-1ecb1508-DU1zc7vq.js} +1 -1
  47. package/dist/assets/{stateDiagram-v2-c2b004d7-EBV2vSks.js → stateDiagram-v2-c2b004d7-D-0RgmAp.js} +1 -1
  48. package/dist/assets/{styles-b4e223ce-k0eswZsE.js → styles-b4e223ce-BSO-yNWV.js} +1 -1
  49. package/dist/assets/{styles-ca3715f6-Ckr7GA-0.js → styles-ca3715f6-CHnsn2Ro.js} +1 -1
  50. package/dist/assets/{styles-d45a18b0-C1bpSwV3.js → styles-d45a18b0-B-rVGjEq.js} +1 -1
  51. package/dist/assets/{svgDrawCommon-b86b1483-CDtKpGvy.js → svgDrawCommon-b86b1483-CA3Pl89f.js} +1 -1
  52. package/dist/assets/{timeline-definition-faaaa080-BeGR-vua.js → timeline-definition-faaaa080-BcihLR6s.js} +1 -1
  53. package/dist/assets/{tsMode-D_gJXIy3.js → tsMode-D9GGa5Ur.js} +1 -1
  54. package/dist/assets/{typescript-BoKcNXkN.js → typescript-BT9CK_EL.js} +1 -1
  55. package/dist/assets/{xml-DZvURlJ-.js → xml-DNO75J-T.js} +1 -1
  56. package/dist/assets/{xychartDiagram-f5964ef8-DxfeLuYV.js → xychartDiagram-f5964ef8-DJTwe32X.js} +1 -1
  57. package/dist/assets/{yaml-CTC8PAGY.js → yaml-7CVzhiP2.js} +1 -1
  58. package/dist/index.html +2 -2
  59. package/package.json +13 -10
  60. package/src/api/git.ts +12 -0
  61. package/src/api/sessions.ts +131 -4
  62. package/src/api/types.ts +2 -1
  63. package/src/api.ts +13 -0
  64. package/src/components/ArchiveView.scss +143 -54
  65. package/src/components/ArchiveView.tsx +181 -167
  66. package/src/components/CodeBlock.scss +5 -0
  67. package/src/components/ConfigView.scss +142 -31
  68. package/src/components/ConfigView.tsx +161 -86
  69. package/src/components/MarkdownContent.tsx +7 -0
  70. package/src/components/NavRail.scss +248 -0
  71. package/src/components/NavRail.tsx +80 -107
  72. package/src/components/NavRailCompact.tsx +107 -0
  73. package/src/components/NavRailCompactMoreSheet.tsx +141 -0
  74. package/src/components/ShortcutTooltip.tsx +4 -2
  75. package/src/components/Sidebar.scss +51 -0
  76. package/src/components/Sidebar.tsx +43 -16
  77. package/src/components/automation-view/RuleFormPanel.scss +40 -13
  78. package/src/components/automation-view/RuleSidebar.scss +73 -47
  79. package/src/components/automation-view/RuleSidebar.tsx +9 -13
  80. package/src/components/automation-view/RunHistoryPanel.scss +141 -13
  81. package/src/components/automation-view/RunHistoryPanel.tsx +203 -161
  82. package/src/components/automation-view/TaskList.scss +44 -13
  83. package/src/components/automation-view/TriggerList.scss +46 -14
  84. package/src/components/automation-view/index.scss +82 -10
  85. package/src/components/automation-view/index.tsx +108 -55
  86. package/src/components/benchmark-view/BenchmarkCasePanel.scss +36 -16
  87. package/src/components/benchmark-view/BenchmarkSidebar.scss +44 -22
  88. package/src/components/benchmark-view/BenchmarkSidebar.tsx +0 -6
  89. package/src/components/benchmark-view/BenchmarkView.scss +63 -20
  90. package/src/components/benchmark-view/index.tsx +71 -34
  91. package/src/components/chat/AGENTS.md +14 -2
  92. package/src/components/chat/ChatComposerCard.scss +77 -0
  93. package/src/components/chat/ChatComposerCard.tsx +59 -0
  94. package/src/components/chat/ChatHeader.scss +187 -0
  95. package/src/components/chat/ChatHeader.tsx +209 -57
  96. package/src/components/chat/ChatHistoryView.tsx +279 -52
  97. package/src/components/chat/ChatTimelineView.scss +94 -1
  98. package/src/components/chat/ChatTimelineView.tsx +42 -0
  99. package/src/components/chat/CurrentTodoList.scss +210 -200
  100. package/src/components/chat/CurrentTodoList.tsx +116 -48
  101. package/src/components/chat/NewSessionGuide.scss +139 -1
  102. package/src/components/chat/NewSessionGuide.tsx +57 -100
  103. package/src/components/chat/NewSessionGuideCompactPanel.tsx +130 -0
  104. package/src/components/chat/NewSessionGuideGrid.tsx +141 -0
  105. package/src/components/chat/QueuedMessagesCard.scss +195 -0
  106. package/src/components/chat/QueuedMessagesCard.tsx +170 -0
  107. package/src/components/chat/git-controls/BranchSwitcherDropdown.tsx +61 -56
  108. package/src/components/chat/git-controls/BranchSwitcherResults.tsx +167 -0
  109. package/src/components/chat/git-controls/BranchTreeEntries.tsx +99 -0
  110. package/src/components/chat/git-controls/ChatGitControls.scss +437 -5
  111. package/src/components/chat/git-controls/ChatGitControls.tsx +136 -109
  112. package/src/components/chat/git-controls/DraftGitControls.tsx +91 -0
  113. package/src/components/chat/git-controls/GitOperationsDropdown.tsx +10 -2
  114. package/src/components/chat/git-controls/GitWorktreeDropdown.tsx +301 -28
  115. package/src/components/chat/git-controls/git-branch-tree.ts +148 -0
  116. package/src/components/chat/git-controls/use-chat-draft-git-controls.ts +168 -0
  117. package/src/components/chat/git-controls/use-chat-git-controls.ts +76 -3
  118. package/src/components/chat/messages/MessageContextMenu.tsx +3 -1
  119. package/src/components/chat/messages/MessageItem.scss +78 -4
  120. package/src/components/chat/messages/MessageItem.tsx +47 -3
  121. package/src/components/chat/sender/@components/adapter-select/AdapterSelectControl.scss +23 -0
  122. package/src/components/chat/sender/@components/reference-actions/ReferenceActionsControl.scss +17 -0
  123. package/src/components/chat/sender/@components/reference-actions/ReferencePermissionActionsPopover.tsx +4 -1
  124. package/src/components/chat/sender/@components/sender-attachments/SenderAttachments.scss +167 -30
  125. package/src/components/chat/sender/@components/sender-attachments/SenderAttachments.tsx +95 -23
  126. package/src/components/chat/sender/@components/sender-body/SenderBody.tsx +10 -0
  127. package/src/components/chat/sender/@components/sender-interaction-panel/SenderInteractionPanel.scss +161 -45
  128. package/src/components/chat/sender/@components/sender-interaction-panel/SenderInteractionPanel.tsx +310 -71
  129. package/src/components/chat/sender/@components/sender-monaco-editor/SenderMonacoEditor.tsx +18 -0
  130. package/src/components/chat/sender/@components/sender-monaco-editor/use-sender-monaco-editor.ts +86 -9
  131. package/src/components/chat/sender/@components/sender-monaco-editor/use-sender-monaco-theme.ts +52 -3
  132. package/src/components/chat/sender/@components/sender-submit-action/SenderSubmitAction.scss +110 -1
  133. package/src/components/chat/sender/@components/sender-submit-action/SenderSubmitAction.tsx +137 -17
  134. package/src/components/chat/sender/@components/sender-toolbar/SenderSelectBase.scss +21 -0
  135. package/src/components/chat/sender/@components/sender-toolbar/SenderSelectShared.scss +21 -0
  136. package/src/components/chat/sender/@components/sender-toolbar/SenderToolbar.scss +63 -0
  137. package/src/components/chat/sender/@components/sender-toolbar/SenderToolbar.tsx +12 -6
  138. package/src/components/chat/sender/@core/build-sender-controller-result.ts +6 -0
  139. package/src/components/chat/sender/@core/build-sender-toolbar.ts +25 -2
  140. package/src/components/chat/sender/@core/create-sender-toolbar-handlers.ts +9 -2
  141. package/src/components/chat/sender/@core/get-sender-runtime-state.ts +1 -1
  142. package/src/components/chat/sender/@core/interaction-request.ts +2 -2
  143. package/src/components/chat/sender/@core/sender-toolbar-bindings.ts +28 -4
  144. package/src/components/chat/sender/@hooks/use-model-select-browser.tsx +4 -2
  145. package/src/components/chat/sender/@hooks/use-sender-controller.ts +56 -11
  146. package/src/components/chat/sender/@hooks/use-sender-keydown.ts +64 -0
  147. package/src/components/chat/sender/@hooks/use-sender-shortcuts.ts +16 -1
  148. package/src/components/chat/sender/@hooks/use-sender-submit.ts +16 -8
  149. package/src/components/chat/sender/@types/sender-props.ts +20 -3
  150. package/src/components/chat/sender/@types/sender-toolbar-types.ts +12 -1
  151. package/src/components/chat/sender/Sender.scss +4 -1
  152. package/src/components/chat/sender/Sender.tsx +3 -12
  153. package/src/components/chat/session-timeline-panel/EventList.scss +88 -0
  154. package/src/components/chat/session-timeline-panel/EventList.tsx +99 -47
  155. package/src/components/chat/session-timeline-panel/gantt.ts +23 -7
  156. package/src/components/chat/session-timeline-panel/git-graph.ts +6 -1
  157. package/src/components/chat/session-timeline-panel/index.scss +14 -1
  158. package/src/components/chat/session-timeline-panel/index.tsx +86 -10
  159. package/src/components/chat/session-timeline-panel/types.ts +4 -0
  160. package/src/components/chat/status-bar/ChatStatusBar.scss +27 -0
  161. package/src/components/chat/status-bar/ChatStatusBar.tsx +39 -0
  162. package/src/components/chat/terminal/ChatTerminalView.tsx +6 -0
  163. package/src/components/chat/tools/core/ToolCallBox.scss +19 -0
  164. package/src/components/chat/tools/core/ToolGroup.scss +32 -0
  165. package/src/components/chat/tools/task/components/TaskToolCard.scss +59 -1
  166. package/src/components/config/ConfigEditors.scss +20 -6
  167. package/src/components/config/ConfigFieldRow.scss +57 -17
  168. package/src/components/config/ConfigSectionForm.scss +10 -4
  169. package/src/components/config/ConfigSectionPanel.tsx +18 -11
  170. package/src/components/config/configSchema.ts +1 -0
  171. package/src/components/config/record-editors/RecordEditors.scss +42 -9
  172. package/src/components/dock-panel/DockPanel.scss +6 -2
  173. package/src/components/dock-panel/DockPanel.tsx +12 -16
  174. package/src/components/knowledge-base/KnowledgeBaseView.scss +180 -6
  175. package/src/components/knowledge-base/KnowledgeBaseView.tsx +98 -26
  176. package/src/components/knowledge-base/components/ActionButton.scss +4 -0
  177. package/src/components/knowledge-base/components/EmptyState.scss +5 -8
  178. package/src/components/knowledge-base/components/EntitiesTab.tsx +8 -2
  179. package/src/components/knowledge-base/components/EntityItem.scss +10 -3
  180. package/src/components/knowledge-base/components/FilterBar.scss +13 -2
  181. package/src/components/knowledge-base/components/FlowsTab.tsx +8 -2
  182. package/src/components/knowledge-base/components/KnowledgeBaseHeader.scss +2 -23
  183. package/src/components/knowledge-base/components/KnowledgeBaseHeader.tsx +0 -5
  184. package/src/components/knowledge-base/components/KnowledgeList.scss +15 -6
  185. package/src/components/knowledge-base/components/LoadingState.scss +4 -0
  186. package/src/components/knowledge-base/components/RuleItem.scss +86 -0
  187. package/src/components/knowledge-base/components/RuleItem.tsx +2 -0
  188. package/src/components/knowledge-base/components/RulesTab.tsx +8 -2
  189. package/src/components/knowledge-base/components/SectionHeader.scss +3 -18
  190. package/src/components/knowledge-base/components/SectionHeader.tsx +3 -7
  191. package/src/components/knowledge-base/components/SkillsTab.tsx +8 -3
  192. package/src/components/knowledge-base/components/SpecItem.scss +16 -7
  193. package/src/components/layout/@hooks/use-mobile-sidebar-modal.ts +190 -0
  194. package/src/components/layout/AppShell.scss +106 -6
  195. package/src/components/layout/AppShell.tsx +118 -10
  196. package/src/components/layout/PageShell.scss +41 -0
  197. package/src/components/layout/PageShell.tsx +32 -0
  198. package/src/components/layout/mobile-sidebar-constants.ts +1 -0
  199. package/src/components/nav-rail-compact-config.ts +114 -0
  200. package/src/components/nav-rail-items.tsx +181 -0
  201. package/src/components/sidebar/SessionContextMenu.tsx +3 -1
  202. package/src/components/sidebar/SessionItem.scss +62 -0
  203. package/src/components/sidebar/SessionItem.tsx +97 -52
  204. package/src/components/sidebar/SessionList.tsx +6 -0
  205. package/src/components/sidebar/SidebarHeader.scss +49 -0
  206. package/src/components/sidebar/SidebarHeader.tsx +27 -5
  207. package/src/components/sidebar/SidebarHeaderBatchActions.tsx +8 -4
  208. package/src/components/sidebar/SidebarHeaderSearchActions.tsx +6 -3
  209. package/src/components/sidebar/SidebarUtilityFooter.tsx +69 -0
  210. package/src/components/workspace/ContextFilePicker.tsx +12 -4
  211. package/src/hooks/chat/chat-session-workspace-draft.ts +25 -0
  212. package/src/hooks/chat/session-view-cache.ts +4 -1
  213. package/src/hooks/chat/use-chat-adapter.ts +5 -1
  214. package/src/hooks/chat/use-chat-model-adapter-selection.tsx +5 -1
  215. package/src/hooks/chat/use-chat-scroll.ts +24 -7
  216. package/src/hooks/chat/use-chat-session-actions.ts +118 -6
  217. package/src/hooks/chat/use-chat-session-messages.ts +20 -1
  218. package/src/hooks/chat/use-chat-session.ts +2 -0
  219. package/src/hooks/use-responsive-layout.ts +115 -0
  220. package/src/main.tsx +8 -0
  221. package/src/resources/adapters.ts +15 -0
  222. package/src/resources/locales/en.json +84 -1
  223. package/src/resources/locales/zh.json +84 -1
  224. package/src/routes/ChatRoute.scss +152 -9
  225. package/src/routes/ChatRoute.tsx +31 -34
  226. package/src/store/index.ts +2 -0
  227. package/dist/assets/channel-BvERb8WU.js +0 -1
  228. package/dist/assets/clone-B9_0v-6Y.js +0 -1
  229. package/dist/assets/flowDiagram-v2-4f6560a1-LpS8Kb00.js +0 -1
  230. package/dist/assets/index-C1oh0w9H.css +0 -32
  231. package/src/components/chat/ThinkingStatus.scss +0 -70
  232. package/src/components/chat/ThinkingStatus.tsx +0 -13
@@ -30,6 +30,13 @@
30
30
  min-width: 0;
31
31
  }
32
32
 
33
+ &-leading-actions {
34
+ display: flex;
35
+ align-items: center;
36
+ gap: 4px;
37
+ flex-shrink: 0;
38
+ }
39
+
33
40
  &-title {
34
41
  font-weight: 600;
35
42
  color: var(--text-color);
@@ -41,6 +48,45 @@
41
48
  }
42
49
  }
43
50
 
51
+ .chat-header.is-compact {
52
+ padding: 10px 12px 8px;
53
+ align-items: center;
54
+ gap: 8px;
55
+
56
+ .chat-header-main {
57
+ align-items: center;
58
+ gap: 8px;
59
+ }
60
+
61
+ .chat-header-leading-actions {
62
+ gap: 4px;
63
+ }
64
+
65
+ .chat-header-title {
66
+ line-height: 1.3;
67
+ white-space: nowrap;
68
+ display: block;
69
+ }
70
+
71
+ .chat-header-actions {
72
+ flex-shrink: 0;
73
+ margin-left: auto;
74
+ justify-content: flex-end;
75
+ flex-wrap: nowrap;
76
+ }
77
+
78
+ .chat-header-action-button.ant-btn.ant-btn-text {
79
+ width: 36px;
80
+ min-width: 36px;
81
+ height: 36px;
82
+ border-radius: 8px;
83
+
84
+ .chat-header-view-option.material-symbols-rounded {
85
+ font-size: 18px;
86
+ }
87
+ }
88
+ }
89
+
44
90
  .chat-header-icon.material-symbols-rounded {
45
91
  font-size: 18px;
46
92
  }
@@ -49,6 +95,7 @@
49
95
  display: flex;
50
96
  align-items: center;
51
97
  gap: 4px;
98
+ min-width: 0;
52
99
  }
53
100
 
54
101
  .chat-header-action-button.ant-btn.ant-btn-text {
@@ -586,6 +633,146 @@ html.dark .chat-header-action-button.ant-btn.ant-btn-text {
586
633
  font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
587
634
  }
588
635
 
636
+ @media (max-width: 768px) {
637
+ .session-settings-drawer {
638
+ gap: 10px;
639
+
640
+ .settings-section {
641
+ gap: 10px;
642
+
643
+ .section-header {
644
+ font-size: 11px;
645
+ letter-spacing: .08em;
646
+ }
647
+ }
648
+
649
+ &__form {
650
+ .config-view__field-row {
651
+ gap: 10px;
652
+ padding: 10px 12px;
653
+ }
654
+
655
+ .config-view__field-meta {
656
+ gap: 8px;
657
+ }
658
+
659
+ .config-view__field-title,
660
+ .config-view__field-desc {
661
+ white-space: normal;
662
+ }
663
+
664
+ .config-view__field-control {
665
+ min-width: 0;
666
+ width: 100%;
667
+ }
668
+
669
+ .config-view__array-list {
670
+ gap: 6px;
671
+ }
672
+
673
+ .config-view__array-item {
674
+ align-items: flex-start;
675
+ }
676
+
677
+ .config-view__icon-button--compact {
678
+ width: 30px;
679
+ min-width: 30px;
680
+ height: 30px;
681
+ }
682
+
683
+ .config-view__icon-button--full {
684
+ width: 100%;
685
+ min-width: 100%;
686
+ height: 36px;
687
+ justify-content: flex-start;
688
+ gap: 6px;
689
+ padding: 0 12px;
690
+ border-radius: 8px;
691
+ border: 1px dashed var(--border-color) !important;
692
+ background: var(--sub-bg-color) !important;
693
+ color: var(--sub-text-color) !important;
694
+ align-self: stretch;
695
+
696
+ &::after {
697
+ content: attr(aria-label);
698
+ font-size: 12px;
699
+ font-weight: 500;
700
+ }
701
+ }
702
+ }
703
+ }
704
+
705
+ .session-tool-groups {
706
+ gap: 10px;
707
+ }
708
+
709
+ .session-tool-group-card {
710
+ padding: 12px 12px 0;
711
+ border-radius: 12px;
712
+ }
713
+
714
+ .session-tool-group-card__header {
715
+ align-items: flex-start;
716
+ padding-bottom: 10px;
717
+ }
718
+
719
+ .session-tool-group-card__title {
720
+ gap: 8px;
721
+ font-size: 12px;
722
+
723
+ .material-symbols-rounded {
724
+ width: 24px;
725
+ height: 24px;
726
+ border-radius: 8px;
727
+ font-size: 14px;
728
+ }
729
+ }
730
+
731
+ .session-tool-group-card__meta {
732
+ gap: 6px;
733
+ }
734
+
735
+ .session-tool-group-card__count {
736
+ padding: 1px 6px;
737
+ font-size: 11px;
738
+ }
739
+
740
+ .session-tool-group-card__list {
741
+ max-height: none;
742
+ margin: 0 -12px;
743
+ padding: 0 12px;
744
+ }
745
+
746
+ .session-tool-row {
747
+ height: 34px;
748
+ }
749
+
750
+ .session-debug-panel {
751
+ padding: 0 10px;
752
+ }
753
+
754
+ .session-debug-row {
755
+ grid-template-columns: 72px minmax(0, 1fr);
756
+ gap: 8px;
757
+ height: auto;
758
+ min-height: 34px;
759
+ padding: 6px 0;
760
+ }
761
+
762
+ .settings-footer {
763
+ gap: 16px;
764
+ padding-top: 16px;
765
+
766
+ .danger-zone {
767
+ .delete-session-row {
768
+ flex-direction: column;
769
+ align-items: stretch;
770
+ padding: 12px;
771
+ }
772
+ }
773
+ }
774
+ }
775
+
589
776
  html.dark {
590
777
  .session-settings-drawer {
591
778
  .settings-footer {
@@ -1,6 +1,6 @@
1
1
  import './ChatHeader.scss'
2
2
 
3
- import type { Session } from '@vibe-forge/core'
3
+ import type { Session, SessionStatus } from '@vibe-forge/core'
4
4
  import type { SessionInfo } from '@vibe-forge/types'
5
5
  import { App, Button, Dropdown, Tooltip } from 'antd'
6
6
  import type { MenuProps } from 'antd'
@@ -8,12 +8,12 @@ import { useAtomValue } from 'jotai'
8
8
  import { useEffect, useMemo, useRef, useState } from 'react'
9
9
  import { useTranslation } from 'react-i18next'
10
10
 
11
- import { deleteSession, getApiErrorMessage, updateSession } from '../../api'
11
+ import { ApiError, deleteSession, getApiErrorMessage, updateSession } from '../../api'
12
+ import { useResponsiveLayout } from '../../hooks/use-responsive-layout'
12
13
  import { useQueryParams } from '../../hooks/useQueryParams'
13
14
  import { isSidebarCollapsedAtom, isSidebarResizingAtom } from '../../store/index'
14
15
  import { ConfigSectionPanel } from '../config'
15
16
  import type { FieldSpec } from '../config/configSchema'
16
- import { ChatGitControls } from './git-controls/ChatGitControls'
17
17
  import {
18
18
  formatToolLabel,
19
19
  getSessionAssetWarnings,
@@ -44,6 +44,7 @@ export function ChatHeader({
44
44
  sessionInfo,
45
45
  sessionId,
46
46
  sessionTitle,
47
+ sessionStatus,
47
48
  isStarred,
48
49
  isArchived,
49
50
  tags,
@@ -51,12 +52,15 @@ export function ChatHeader({
51
52
  lastUserMessage,
52
53
  activeView,
53
54
  isTerminalOpen,
55
+ onCreateSession,
56
+ onOpenSidebar,
54
57
  onViewChange,
55
58
  onToggleTerminal
56
59
  }: {
57
60
  sessionInfo: SessionInfo | null
58
61
  sessionId?: string
59
62
  sessionTitle?: string
63
+ sessionStatus?: SessionStatus
60
64
  isStarred?: boolean
61
65
  isArchived?: boolean
62
66
  tags?: string[]
@@ -64,11 +68,14 @@ export function ChatHeader({
64
68
  lastUserMessage?: string
65
69
  activeView: ChatHeaderView
66
70
  isTerminalOpen: boolean
71
+ onCreateSession?: () => void
72
+ onOpenSidebar?: () => void
67
73
  onViewChange: (view: ChatHeaderView) => void
68
74
  onToggleTerminal: () => void
69
75
  }) {
70
76
  const { t } = useTranslation()
71
77
  const { message } = App.useApp()
78
+ const { isCompactLayout, isTouchInteraction } = useResponsiveLayout()
72
79
  const isSidebarCollapsed = useAtomValue(isSidebarCollapsedAtom)
73
80
  const isResizing = useAtomValue(isSidebarResizingAtom)
74
81
  const { searchParams, update: updateQuery } = useQueryParams<{ debug: string }>({
@@ -82,6 +89,8 @@ export function ChatHeader({
82
89
  const hasDebugQuery = searchParams.has('debug')
83
90
  const isDebugMode = searchParams.get('debug') === 'true'
84
91
  const shouldShowDebugButton = hasDebugQuery
92
+ const hasSession = sessionId != null && sessionId !== ''
93
+ const resolveTooltipTitle = (title: string) => isTouchInteraction ? undefined : title
85
94
 
86
95
  const summary = sessionInfo?.type === 'summary' ? sessionInfo.summary : null
87
96
  const title = (sessionInfo?.type === 'init' ? sessionInfo.title : null) ?? sessionTitle
@@ -103,6 +112,7 @@ export function ChatHeader({
103
112
  { value: 'timeline' as const, icon: 'timeline', title: t('chat.viewTimeline') },
104
113
  { value: 'settings' as const, icon: 'tune', title: t('chat.viewSettings') }
105
114
  ]
115
+ const activeViewItem = viewItems.find((item) => item.value === activeView) ?? viewItems[0]!
106
116
 
107
117
  const handleToggleStar = async () => {
108
118
  if (sessionId == null || sessionId === '') return
@@ -146,6 +156,37 @@ export function ChatHeader({
146
156
  }
147
157
  }
148
158
  ]
159
+ const compactViewItems: MenuProps['items'] = viewItems.map((item) => ({
160
+ key: `view:${item.value}`,
161
+ label: item.title,
162
+ icon: <span className={`material-symbols-rounded chat-header-icon ${activeView === item.value ? 'is-filled' : ''}`}>
163
+ {item.icon}
164
+ </span>,
165
+ onClick: () => {
166
+ onViewChange(item.value)
167
+ }
168
+ }))
169
+ 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
+ ...moreItems,
179
+ ...(shouldShowDebugButton
180
+ ? [{
181
+ key: 'debug',
182
+ label: isDebugMode ? t('chat.debugDisable') : t('chat.debugEnable'),
183
+ icon: <span className={`material-symbols-rounded chat-header-icon ${isDebugMode ? 'is-filled' : ''}`}>
184
+ bug_report
185
+ </span>,
186
+ onClick: toggleDebugMode
187
+ }]
188
+ : [])
189
+ ]
149
190
 
150
191
  useEffect(() => {
151
192
  return () => {
@@ -187,8 +228,40 @@ export function ChatHeader({
187
228
  }
188
229
 
189
230
  return (
190
- <div className={`chat-header ${isSidebarCollapsed ? 'is-collapsed' : ''} ${isResizing ? 'is-resizing' : ''}`}>
231
+ <div
232
+ className={`chat-header ${isSidebarCollapsed ? 'is-collapsed' : ''} ${isResizing ? 'is-resizing' : ''} ${
233
+ isCompactLayout ? 'is-compact' : ''
234
+ }`}
235
+ >
191
236
  <div className='chat-header-main'>
237
+ {isCompactLayout && (
238
+ <div className='chat-header-leading-actions'>
239
+ {onOpenSidebar != null && (
240
+ <Tooltip title={resolveTooltipTitle(t('common.sessions'))}>
241
+ <Button
242
+ type='text'
243
+ className='chat-header-action-button'
244
+ title={t('common.sessions')}
245
+ aria-label={t('common.sessions')}
246
+ onClick={onOpenSidebar}
247
+ icon={<span className='chat-header-view-option material-symbols-rounded'>menu</span>}
248
+ />
249
+ </Tooltip>
250
+ )}
251
+ {onCreateSession != null && (
252
+ <Tooltip title={resolveTooltipTitle(t('common.newChat'))}>
253
+ <Button
254
+ type='text'
255
+ className={`chat-header-action-button ${!hasSession ? 'is-active' : ''}`}
256
+ title={t('common.newChat')}
257
+ aria-label={t('common.newChat')}
258
+ onClick={onCreateSession}
259
+ icon={<span className='chat-header-view-option material-symbols-rounded'>edit_square</span>}
260
+ />
261
+ </Tooltip>
262
+ )}
263
+ </div>
264
+ )}
192
265
  <div className='chat-header-info'>
193
266
  <div
194
267
  className='chat-header-title'
@@ -200,56 +273,92 @@ export function ChatHeader({
200
273
  </div>
201
274
 
202
275
  <div className='chat-header-actions'>
203
- {sessionId != null && sessionId !== '' && (
204
- <ChatGitControls sessionId={sessionId} />
205
- )}
206
- {viewItems.map(item => (
207
- <Tooltip key={item.value} title={item.title}>
208
- <Button
209
- type='text'
210
- className={`chat-header-action-button ${activeView === item.value ? 'is-active' : ''}`}
211
- title={item.title}
212
- aria-label={item.title}
213
- onClick={() => {
214
- onViewChange(item.value)
215
- }}
216
- icon={<span className='chat-header-view-option material-symbols-rounded'>{item.icon}</span>}
217
- />
218
- </Tooltip>
219
- ))}
220
- <Tooltip title={t('chat.viewTerminal')}>
221
- <Button
222
- type='text'
223
- className={`chat-header-action-button ${isTerminalOpen ? 'is-active' : ''}`}
224
- title={t('chat.viewTerminal')}
225
- aria-label={t('chat.viewTerminal')}
226
- onClick={onToggleTerminal}
227
- icon={<span className='chat-header-view-option material-symbols-rounded'>terminal</span>}
228
- />
229
- </Tooltip>
230
- {shouldShowDebugButton && (
231
- <Tooltip title={isDebugMode ? t('chat.debugDisable') : t('chat.debugEnable')}>
232
- <Button
233
- type='text'
234
- className={`chat-header-action-button ${isDebugMode ? 'is-debug-active' : ''}`}
235
- title={isDebugMode ? t('chat.debugDisable') : t('chat.debugEnable')}
236
- aria-label={isDebugMode ? t('chat.debugDisable') : t('chat.debugEnable')}
237
- onClick={toggleDebugMode}
238
- icon={<span className='chat-header-view-option material-symbols-rounded'>bug_report</span>}
239
- />
240
- </Tooltip>
241
- )}
242
- <Tooltip title={t('common.moreActions')}>
243
- <Dropdown menu={{ items: moreItems }} placement='bottomRight' trigger={['click']}>
244
- <Button
245
- type='text'
246
- className='chat-header-action-button'
247
- title={t('common.moreActions')}
248
- aria-label={t('common.moreActions')}
249
- icon={<span className='chat-header-view-option material-symbols-rounded'>more_vert</span>}
250
- />
251
- </Dropdown>
252
- </Tooltip>
276
+ {isCompactLayout
277
+ ? (
278
+ <>
279
+ {hasSession && (
280
+ <Tooltip title={resolveTooltipTitle(activeViewItem.title)}>
281
+ <Dropdown menu={{ items: compactViewItems }} placement='bottomRight' trigger={['click']}>
282
+ <Button
283
+ type='text'
284
+ className='chat-header-action-button'
285
+ title={activeViewItem.title}
286
+ aria-label={activeViewItem.title}
287
+ icon={
288
+ <span className='chat-header-view-option material-symbols-rounded'>
289
+ {activeViewItem.icon}
290
+ </span>
291
+ }
292
+ />
293
+ </Dropdown>
294
+ </Tooltip>
295
+ )}
296
+ {hasSession && (
297
+ <Tooltip title={resolveTooltipTitle(t('common.moreActions'))}>
298
+ <Dropdown menu={{ items: compactMoreItems }} placement='bottomRight' trigger={['click']}>
299
+ <Button
300
+ type='text'
301
+ className='chat-header-action-button'
302
+ title={t('common.moreActions')}
303
+ aria-label={t('common.moreActions')}
304
+ icon={<span className='chat-header-view-option material-symbols-rounded'>more_vert</span>}
305
+ />
306
+ </Dropdown>
307
+ </Tooltip>
308
+ )}
309
+ </>
310
+ )
311
+ : (
312
+ <>
313
+ {viewItems.map(item => (
314
+ <Tooltip key={item.value} title={resolveTooltipTitle(item.title)}>
315
+ <Button
316
+ type='text'
317
+ className={`chat-header-action-button ${activeView === item.value ? 'is-active' : ''}`}
318
+ title={item.title}
319
+ aria-label={item.title}
320
+ onClick={() => {
321
+ onViewChange(item.value)
322
+ }}
323
+ icon={<span className='chat-header-view-option material-symbols-rounded'>{item.icon}</span>}
324
+ />
325
+ </Tooltip>
326
+ ))}
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 && (
338
+ <Tooltip title={resolveTooltipTitle(isDebugMode ? t('chat.debugDisable') : t('chat.debugEnable'))}>
339
+ <Button
340
+ type='text'
341
+ className={`chat-header-action-button ${isDebugMode ? 'is-debug-active' : ''}`}
342
+ title={isDebugMode ? t('chat.debugDisable') : t('chat.debugEnable')}
343
+ aria-label={isDebugMode ? t('chat.debugDisable') : t('chat.debugEnable')}
344
+ onClick={toggleDebugMode}
345
+ icon={<span className='chat-header-view-option material-symbols-rounded'>bug_report</span>}
346
+ />
347
+ </Tooltip>
348
+ )}
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>
360
+ </>
361
+ )}
253
362
  </div>
254
363
  </div>
255
364
  )
@@ -265,6 +374,7 @@ export function SessionSettingsPanel({
265
374
  onClose: () => void
266
375
  }) {
267
376
  const { t } = useTranslation()
377
+ const { isCompactLayout } = useResponsiveLayout()
268
378
  const { message, modal } = App.useApp()
269
379
  const { searchParams } = useQueryParams<{ debug: string }>({ keys: ['debug'] })
270
380
  const isDebugMode = searchParams.get('debug') === 'true'
@@ -316,6 +426,27 @@ export function SessionSettingsPanel({
316
426
  const toolGroups = useMemo(() => getSessionToolGroups(sessionInfo), [sessionInfo])
317
427
  const assetWarnings = useMemo(() => getSessionAssetWarnings(sessionInfo), [sessionInfo])
318
428
  const selectionWarnings = useMemo(() => getSessionSelectionWarnings(sessionInfo), [sessionInfo])
429
+
430
+ useEffect(() => {
431
+ if (!isCompactLayout || toolGroups.length === 0) {
432
+ return
433
+ }
434
+
435
+ setCollapsedToolGroupKeys((prev) => {
436
+ const next = { ...prev }
437
+ let changed = false
438
+
439
+ for (const group of toolGroups) {
440
+ if (!(group.key in next)) {
441
+ next[group.key] = true
442
+ changed = true
443
+ }
444
+ }
445
+
446
+ return changed ? next : prev
447
+ })
448
+ }, [isCompactLayout, toolGroups])
449
+
319
450
  const debugItems = useMemo<SessionDebugItem[]>(() => {
320
451
  const emptyValue = t('chat.timelineEmptyValue')
321
452
  const booleanValue = (value: boolean | undefined) =>
@@ -489,6 +620,12 @@ export function SessionSettingsPanel({
489
620
  }
490
621
 
491
622
  const handleDelete = () => {
623
+ const runDelete = async (force = false) => {
624
+ await deleteSession(sessionId, { force })
625
+ void message.success(t('common.deleteSuccess'))
626
+ onClose()
627
+ }
628
+
492
629
  modal.confirm({
493
630
  title: t('common.deleteSession'),
494
631
  content: t('common.deleteSessionConfirm'),
@@ -497,10 +634,25 @@ export function SessionSettingsPanel({
497
634
  cancelText: t('common.cancel'),
498
635
  onOk: async () => {
499
636
  try {
500
- await deleteSession(sessionId)
501
- void message.success(t('common.deleteSuccess'))
502
- onClose()
637
+ await runDelete()
503
638
  } catch (err) {
639
+ if (err instanceof ApiError && err.code === 'session_worktree_not_clean') {
640
+ modal.confirm({
641
+ title: t('chat.sessionWorkspaceForceDeleteTitle'),
642
+ content: t('chat.sessionWorkspaceForceDeleteDescription'),
643
+ okText: t('common.delete'),
644
+ okType: 'danger',
645
+ cancelText: t('common.cancel'),
646
+ onOk: async () => {
647
+ try {
648
+ await runDelete(true)
649
+ } catch (forceError) {
650
+ void message.error(getApiErrorMessage(forceError, t('common.deleteFailed')))
651
+ }
652
+ }
653
+ })
654
+ return
655
+ }
504
656
  void message.error(getApiErrorMessage(err, t('common.deleteFailed')))
505
657
  }
506
658
  }