@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
@@ -12,140 +12,167 @@ import { GitWorktreeDropdown } from './GitWorktreeDropdown'
12
12
  import { useChatGitControls } from './use-chat-git-controls'
13
13
 
14
14
  export function ChatGitControls({
15
+ compact = false,
16
+ placement = 'bottomLeft',
15
17
  sessionId
16
18
  }: {
19
+ compact?: boolean
20
+ placement?: 'bottomLeft' | 'topLeft'
17
21
  sessionId: string
18
22
  }) {
19
23
  const { t } = useTranslation()
20
24
  const git = useChatGitControls(sessionId)
21
25
 
22
- if (git.repoState?.available !== true) {
26
+ if (git.workspace == null && git.repoState?.available !== true) {
23
27
  return null
24
28
  }
25
29
 
26
30
  return (
27
31
  <>
28
- <div className='chat-header-git'>
29
- <GitOperationsDropdown
30
- isBusy={git.isBusy}
31
- open={git.operationsMenuOpen}
32
- repoState={git.repoState}
33
- onOpenChange={(nextOpen) => {
34
- git.setOperationsMenuOpen(nextOpen)
35
- if (nextOpen) {
36
- git.setBranchMenuOpen(false)
37
- git.setWorktreeMenuOpen(false)
38
- }
39
- }}
40
- onOpenCommit={() => {
41
- git.setOperationsMenuOpen(false)
42
- git.setCommitMessageError('')
43
- git.setCommitModalOpen(true)
44
- }}
45
- onPush={git.handleOpenPushModal}
46
- onSync={() => {
47
- void git.runMutation(
48
- 'sync',
49
- () => syncSessionGitBranch(sessionId),
50
- t('chat.gitSyncSuccess'),
51
- () => git.setOperationsMenuOpen(false)
52
- )
32
+ <div className={`chat-header-git ${compact ? 'chat-header-git--compact' : ''}`.trim()}>
33
+ <GitWorktreeDropdown
34
+ compact={compact}
35
+ open={git.worktreeMenuOpen}
36
+ placement={placement}
37
+ workspace={git.workspace}
38
+ worktrees={git.worktrees}
39
+ currentBranch={git.repoState?.currentBranch}
40
+ mode={{
41
+ type: 'session',
42
+ isBusy: git.isBusy,
43
+ canCreateManagedWorktree: git.repoState?.available === true &&
44
+ git.workspace != null &&
45
+ git.workspace.kind !== 'managed_worktree' &&
46
+ (git.workspace.worktreePath == null || git.workspace.worktreePath.trim() === ''),
47
+ canTransferToLocal: git.workspace?.kind === 'managed_worktree',
48
+ onCreateManagedWorktree: git.handleCreateManagedWorktree,
49
+ onTransferToLocal: git.handleTransferWorkspaceToLocal
53
50
  }}
54
- />
55
-
56
- <BranchSwitcherDropdown
57
- availableLocalBranches={git.availableLocalBranches}
58
- currentBranchLabel={git.currentBranchLabel}
59
- isBusy={git.isBusy}
60
- isLoading={git.isBranchListLoading}
61
- open={git.branchMenuOpen}
62
- repoState={git.repoState}
63
- branchQuery={git.branchQuery}
64
- canCreateBranch={git.canCreateBranch}
65
- hasBranchResults={git.hasBranchResults}
66
- remoteBranches={git.remoteBranches}
67
- onCreateBranch={git.handleCreateBranch}
68
51
  onOpenChange={(nextOpen) => {
69
- git.setBranchMenuOpen(nextOpen)
52
+ git.setWorktreeMenuOpen(nextOpen)
70
53
  if (nextOpen) {
71
54
  git.setOperationsMenuOpen(false)
72
- git.setWorktreeMenuOpen(false)
73
- git.setShouldLoadBranches(true)
74
- return
55
+ git.setBranchMenuOpen(false)
75
56
  }
76
- git.setBranchQuery('')
77
57
  }}
78
- onQueryChange={git.setBranchQuery}
79
- onSwitchBranch={git.handleBranchSwitch}
80
58
  />
81
59
 
82
- {git.showWorktreeButton && (
83
- <GitWorktreeDropdown
84
- open={git.worktreeMenuOpen}
85
- worktrees={git.worktrees}
86
- onOpenChange={(nextOpen) => {
87
- git.setWorktreeMenuOpen(nextOpen)
88
- if (nextOpen) {
60
+ {git.repoState?.available === true && (
61
+ <>
62
+ <GitOperationsDropdown
63
+ compact={compact}
64
+ isBusy={git.isBusy}
65
+ open={git.operationsMenuOpen}
66
+ placement={placement}
67
+ repoState={git.repoState}
68
+ onOpenChange={(nextOpen) => {
69
+ git.setOperationsMenuOpen(nextOpen)
70
+ if (nextOpen) {
71
+ git.setBranchMenuOpen(false)
72
+ git.setWorktreeMenuOpen(false)
73
+ }
74
+ }}
75
+ onOpenCommit={() => {
89
76
  git.setOperationsMenuOpen(false)
90
- git.setBranchMenuOpen(false)
91
- }
92
- }}
93
- />
94
- )}
77
+ git.setCommitMessageError('')
78
+ git.setCommitModalOpen(true)
79
+ }}
80
+ onPush={git.handleOpenPushModal}
81
+ onSync={() => {
82
+ void git.runMutation(
83
+ 'sync',
84
+ () => syncSessionGitBranch(sessionId),
85
+ t('chat.gitSyncSuccess'),
86
+ () => git.setOperationsMenuOpen(false)
87
+ )
88
+ }}
89
+ />
95
90
 
96
- <div className='chat-header-git__separator' />
91
+ <BranchSwitcherDropdown
92
+ availableLocalBranches={git.availableLocalBranches}
93
+ compact={compact}
94
+ currentBranchLabel={git.currentBranchLabel}
95
+ isBusy={git.isBusy}
96
+ isLoading={git.isBranchListLoading}
97
+ open={git.branchMenuOpen}
98
+ placement={placement}
99
+ repoState={git.repoState}
100
+ branchQuery={git.branchQuery}
101
+ canCreateBranch={git.canCreateBranch}
102
+ hasBranchResults={git.hasBranchResults}
103
+ remoteBranches={git.remoteBranches}
104
+ onCreateBranch={git.handleCreateBranch}
105
+ onOpenChange={(nextOpen) => {
106
+ git.setBranchMenuOpen(nextOpen)
107
+ if (nextOpen) {
108
+ git.setOperationsMenuOpen(false)
109
+ git.setWorktreeMenuOpen(false)
110
+ git.setShouldLoadBranches(true)
111
+ return
112
+ }
113
+ git.setBranchQuery('')
114
+ }}
115
+ onQueryChange={git.setBranchQuery}
116
+ onSwitchBranch={git.handleBranchSwitch}
117
+ />
118
+ </>
119
+ )}
97
120
  </div>
98
121
 
99
- <GitCommitModal
100
- canCommitAndPush={git.canCommitAndPush}
101
- canSubmit={git.canSubmitCommit}
102
- commitAmend={git.commitAmend}
103
- commitBlockedMessage={git.commitBlockedMessage}
104
- commitForcePush={git.commitForcePush}
105
- commitIncludeUnstagedChanges={git.commitIncludeUnstagedChanges}
106
- commitMessage={git.commitMessage}
107
- commitMessageError={git.commitMessageError}
108
- commitNextStep={git.commitNextStep}
109
- commitSkipHooks={git.commitSkipHooks}
110
- commitSummary={git.commitSummary}
111
- currentBranchLabel={git.currentBranchLabel}
112
- headCommit={git.repoState.headCommit ?? null}
113
- open={git.commitModalOpen}
114
- pending={git.pendingAction === 'commit' || git.pendingAction === 'commit-and-push'}
115
- onCancel={git.resetCommitState}
116
- onCommit={git.handleCommit}
117
- onNextStepChange={git.setCommitNextStep}
118
- onToggleAmend={(checked) => {
119
- git.setCommitAmend(checked)
120
- if (git.commitMessageError !== '') {
121
- git.setCommitMessageError('')
122
- }
123
- }}
124
- onToggleForcePush={git.setCommitForcePush}
125
- onToggleIncludeUnstagedChanges={(checked) => {
126
- git.setCommitIncludeUnstagedChanges(checked)
127
- }}
128
- onToggleSkipHooks={git.setCommitSkipHooks}
129
- onMessageChange={(value) => {
130
- git.setCommitMessage(value)
131
- if (git.commitMessageError !== '') {
132
- git.setCommitMessageError('')
133
- }
134
- }}
135
- />
122
+ {git.repoState?.available === true && (
123
+ <>
124
+ <GitCommitModal
125
+ canCommitAndPush={git.canCommitAndPush}
126
+ canSubmit={git.canSubmitCommit}
127
+ commitAmend={git.commitAmend}
128
+ commitBlockedMessage={git.commitBlockedMessage}
129
+ commitForcePush={git.commitForcePush}
130
+ commitIncludeUnstagedChanges={git.commitIncludeUnstagedChanges}
131
+ commitMessage={git.commitMessage}
132
+ commitMessageError={git.commitMessageError}
133
+ commitNextStep={git.commitNextStep}
134
+ commitSkipHooks={git.commitSkipHooks}
135
+ commitSummary={git.commitSummary}
136
+ currentBranchLabel={git.currentBranchLabel}
137
+ headCommit={git.repoState.headCommit ?? null}
138
+ open={git.commitModalOpen}
139
+ pending={git.pendingAction === 'commit' || git.pendingAction === 'commit-and-push'}
140
+ onCancel={git.resetCommitState}
141
+ onCommit={git.handleCommit}
142
+ onNextStepChange={git.setCommitNextStep}
143
+ onToggleAmend={(checked) => {
144
+ git.setCommitAmend(checked)
145
+ if (git.commitMessageError !== '') {
146
+ git.setCommitMessageError('')
147
+ }
148
+ }}
149
+ onToggleForcePush={git.setCommitForcePush}
150
+ onToggleIncludeUnstagedChanges={(checked) => {
151
+ git.setCommitIncludeUnstagedChanges(checked)
152
+ }}
153
+ onToggleSkipHooks={git.setCommitSkipHooks}
154
+ onMessageChange={(value) => {
155
+ git.setCommitMessage(value)
156
+ if (git.commitMessageError !== '') {
157
+ git.setCommitMessageError('')
158
+ }
159
+ }}
160
+ />
136
161
 
137
- <GitPushModal
138
- blockedMessage={git.pushBlockedMessage}
139
- currentBranchLabel={git.currentBranchLabel}
140
- forcePush={git.pushForce}
141
- hasUpstream={git.repoState.upstream != null && git.repoState.upstream.trim() !== ''}
142
- open={git.pushModalOpen}
143
- pending={git.pendingAction === 'push'}
144
- upstreamLabel={git.repoState.upstream?.trim() || t('chat.gitNoUpstream')}
145
- onCancel={git.resetPushState}
146
- onPush={git.handlePush}
147
- onToggleForcePush={git.setPushForce}
148
- />
162
+ <GitPushModal
163
+ blockedMessage={git.pushBlockedMessage}
164
+ currentBranchLabel={git.currentBranchLabel}
165
+ forcePush={git.pushForce}
166
+ hasUpstream={git.repoState.upstream != null && git.repoState.upstream.trim() !== ''}
167
+ open={git.pushModalOpen}
168
+ pending={git.pendingAction === 'push'}
169
+ upstreamLabel={git.repoState.upstream?.trim() || t('chat.gitNoUpstream')}
170
+ onCancel={git.resetPushState}
171
+ onPush={git.handlePush}
172
+ onToggleForcePush={git.setPushForce}
173
+ />
174
+ </>
175
+ )}
149
176
  </>
150
177
  )
151
178
  }
@@ -0,0 +1,91 @@
1
+ import './ChatGitControls.scss'
2
+
3
+ import { useTranslation } from 'react-i18next'
4
+
5
+ import type { ChatSessionWorkspaceDraft } from '#~/hooks/chat/chat-session-workspace-draft'
6
+
7
+ import { BranchSwitcherDropdown } from './BranchSwitcherDropdown'
8
+ import { GitWorktreeDropdown } from './GitWorktreeDropdown'
9
+ import { useChatDraftGitControls } from './use-chat-draft-git-controls'
10
+
11
+ export function DraftGitControls({
12
+ compact = false,
13
+ disabled = false,
14
+ draft,
15
+ placement = 'topLeft',
16
+ onChange
17
+ }: {
18
+ compact?: boolean
19
+ disabled?: boolean
20
+ draft: ChatSessionWorkspaceDraft
21
+ placement?: 'bottomLeft' | 'topLeft'
22
+ onChange: (nextDraft: ChatSessionWorkspaceDraft) => void
23
+ }) {
24
+ const { t } = useTranslation()
25
+ const git = useChatDraftGitControls({
26
+ draft,
27
+ onChange
28
+ })
29
+
30
+ return (
31
+ <div className={`chat-draft-git ${compact ? 'chat-draft-git--compact' : ''}`.trim()}>
32
+ {git.repoState.available
33
+ ? (
34
+ <div className='chat-header-git chat-draft-git__controls'>
35
+ <GitWorktreeDropdown
36
+ compact={compact}
37
+ currentBranch={git.repoState.currentBranch}
38
+ open={git.worktreeMenuOpen}
39
+ placement={placement}
40
+ mode={{
41
+ type: 'draft',
42
+ createWorktree: draft.createWorktree,
43
+ disabled,
44
+ onCreateWorktreeChange: git.handleCreateWorktreeChange
45
+ }}
46
+ worktrees={git.worktrees}
47
+ onOpenChange={(nextOpen) => {
48
+ git.setWorktreeMenuOpen(nextOpen)
49
+ if (nextOpen) {
50
+ git.setBranchMenuOpen(false)
51
+ }
52
+ }}
53
+ />
54
+
55
+ <BranchSwitcherDropdown
56
+ availableLocalBranches={git.availableLocalBranches}
57
+ branchQuery={git.branchQuery}
58
+ compact={compact}
59
+ canCreateBranch={git.canCreateBranch}
60
+ currentBranchLabel={git.currentBranchLabel}
61
+ hasBranchResults={git.hasBranchResults}
62
+ isBusy={disabled}
63
+ isLoading={git.isBranchListLoading}
64
+ open={git.branchMenuOpen}
65
+ placement={placement}
66
+ remoteBranches={git.remoteBranches}
67
+ repoState={git.repoState}
68
+ onCreateBranch={git.handleCreateBranch}
69
+ onOpenChange={(nextOpen) => {
70
+ git.setBranchMenuOpen(nextOpen)
71
+ if (nextOpen) {
72
+ git.setWorktreeMenuOpen(false)
73
+ git.setShouldLoadBranches(true)
74
+ return
75
+ }
76
+ git.setBranchQuery('')
77
+ }}
78
+ onQueryChange={git.setBranchQuery}
79
+ onSwitchBranch={git.handleBranchSwitch}
80
+ />
81
+ </div>
82
+ )
83
+ : (
84
+ <div className='chat-draft-git__unavailable'>
85
+ <span className='material-symbols-rounded'>info</span>
86
+ <span>{t('chat.sessionWorkspaceDraftGitUnavailable')}</span>
87
+ </div>
88
+ )}
89
+ </div>
90
+ )
91
+ }
@@ -7,16 +7,20 @@ import type { GitOperationKind } from './git-operation-utils'
7
7
  import { getPrimaryGitOperationKind, isGitOperationDisabled } from './git-operation-utils'
8
8
 
9
9
  export function GitOperationsDropdown({
10
+ compact = false,
10
11
  isBusy,
11
12
  open,
13
+ placement = 'bottomLeft',
12
14
  repoState,
13
15
  onOpenChange,
14
16
  onOpenCommit,
15
17
  onPush,
16
18
  onSync
17
19
  }: {
20
+ compact?: boolean
18
21
  isBusy: boolean
19
22
  open: boolean
23
+ placement?: 'bottomLeft' | 'topLeft'
20
24
  repoState: GitRepositoryState
21
25
  onOpenChange: (open: boolean) => void
22
26
  onOpenCommit: () => void
@@ -59,7 +63,11 @@ export function GitOperationsDropdown({
59
63
  const primaryAction = primaryActionKind != null ? actionMap[primaryActionKind] : null
60
64
 
61
65
  return (
62
- <div className={`chat-header-git__split ${open ? 'is-open' : ''}`}>
66
+ <div
67
+ className={`chat-header-git__split chat-header-git__split--operations ${open ? 'is-open' : ''} ${
68
+ compact ? 'is-compact' : ''
69
+ }`.trim()}
70
+ >
63
71
  <Button
64
72
  type='text'
65
73
  className='chat-header-git__split-main'
@@ -84,7 +92,7 @@ export function GitOperationsDropdown({
84
92
 
85
93
  <Dropdown
86
94
  open={open}
87
- placement='bottomLeft'
95
+ placement={placement}
88
96
  trigger={['click']}
89
97
  onOpenChange={onOpenChange}
90
98
  dropdownRender={() => (