@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
@@ -1,245 +1,255 @@
1
1
  .current-todo-container {
2
- --todo-panel-bg: var(--bg-color);
3
- --todo-panel-muted-bg: var(--tag-bg);
4
- --todo-panel-border: var(--border-color);
5
- --todo-panel-hover-border: var(--primary-color);
6
- --todo-panel-shadow: 0 2px 4px -1px rgba(0, 0, 0, .06);
7
- --todo-overlay-shadow: 0 4px 12px rgba(0, 0, 0, .15);
8
- --todo-track-bg: var(--tag-hover-bg);
2
+ --todo-track-bg: rgba(148, 163, 184, .12);
3
+ --todo-track-fill: linear-gradient(90deg, #22c55e, #16a34a);
9
4
  --todo-text: var(--text-color);
10
5
  --todo-sub-text: var(--sub-text-color);
11
- --todo-pending-icon: var(--placeholder-color);
12
- --todo-hover-bg: var(--tag-bg);
13
- --todo-priority-high-bg: #fee2e2;
14
- --todo-priority-high-text: #ef4444;
15
- --todo-priority-medium-bg: #fef3c7;
16
- --todo-priority-medium-text: #d97706;
17
- --todo-priority-low-bg: #d1fae5;
18
- --todo-priority-low-text: #10b981;
6
+ --todo-pending-icon: #94a3b8;
7
+ --todo-active-icon: var(--primary-color, #2563eb);
8
+ --todo-done-icon: #16a34a;
9
+ --todo-hover-bg: rgba(148, 163, 184, .05);
10
+ --todo-divider: rgba(148, 163, 184, .18);
19
11
 
20
12
  position: relative;
21
- margin: 12px 24px 0 24px;
13
+ width: 100%;
14
+ margin: 0;
22
15
  z-index: 10;
23
16
  display: flex;
24
17
  flex-direction: column;
25
18
 
26
19
  &.empty {
27
20
  opacity: .6;
28
- .todo-progress-bar {
29
- cursor: default;
30
- background: var(--todo-panel-muted-bg);
31
- box-shadow: none;
32
- &:hover {
33
- border-color: var(--todo-panel-border);
34
- }
35
- .progress-info .material-symbols-rounded {
36
- color: var(--todo-pending-icon);
37
- }
38
- }
21
+ }
22
+ }
23
+
24
+ .current-todo-panel {
25
+ position: relative;
26
+ }
27
+
28
+ .current-todo-summary {
29
+ &--empty {
30
+ cursor: default;
39
31
  }
40
32
 
41
- .todo-progress-bar {
42
- background: var(--todo-panel-bg);
43
- border: 1px solid var(--todo-panel-border);
44
- border-radius: 8px;
45
- padding: 8px 16px;
33
+ &__headline,
34
+ &__meta {
46
35
  display: flex;
47
36
  align-items: center;
48
- gap: 12px;
49
- box-shadow: var(--todo-panel-shadow);
50
- cursor: pointer;
51
- transition: all .2s ease;
37
+ gap: 4px;
38
+ min-width: 0;
39
+ }
52
40
 
53
- &:hover {
54
- border-color: var(--todo-panel-hover-border);
55
- }
41
+ &__headline {
42
+ flex: 1;
43
+ gap: 6px;
44
+ }
56
45
 
57
- .progress-info {
58
- display: flex;
59
- align-items: center;
60
- gap: 8px;
61
- flex-shrink: 0;
62
-
63
- .material-symbols-rounded {
64
- font-size: 20px;
65
- color: var(--primary-color);
66
- }
67
-
68
- .text {
69
- font-size: 13px;
70
- font-weight: 500;
71
- color: var(--todo-text);
72
- }
46
+ &__icon {
47
+ font-size: 15px;
48
+ color: var(--todo-active-icon);
49
+ }
50
+
51
+ &__text {
52
+ min-width: 0;
53
+ font-size: 11px;
54
+ font-weight: 600;
55
+ color: var(--todo-text);
56
+ line-height: 1.25;
57
+ }
58
+
59
+ &__meta {
60
+ gap: 0;
61
+ }
62
+
63
+ &__stat {
64
+ display: inline-flex;
65
+ align-items: center;
66
+ gap: 3px;
67
+ padding-left: 5px;
68
+ margin-left: 5px;
69
+ border-left: 1px solid var(--todo-divider);
70
+ color: var(--todo-sub-text);
71
+ font-size: 10px;
72
+ font-weight: 600;
73
+ line-height: 1;
74
+
75
+ .material-symbols-rounded {
76
+ font-size: 12px;
77
+ line-height: 1;
73
78
  }
74
79
 
75
- .progress-track {
76
- flex: 1;
77
- height: 6px;
78
- background: var(--todo-track-bg);
79
- border-radius: 3px;
80
- overflow: hidden;
81
-
82
- .progress-fill {
83
- height: 100%;
84
- background: var(--primary-color);
85
- transition: width .3s ease;
86
- }
80
+ &--active {
81
+ color: var(--todo-active-icon);
87
82
  }
88
83
 
89
- .expand-btn {
90
- background: none;
91
- border: none;
92
- padding: 0;
93
- cursor: pointer;
94
- color: var(--todo-pending-icon);
95
- display: flex;
96
- align-items: center;
97
-
98
- &:hover {
99
- color: var(--todo-text);
100
- }
84
+ &--done {
85
+ color: var(--todo-done-icon);
101
86
  }
102
87
  }
103
88
 
104
- .todo-items-overlay {
105
- position: absolute;
106
- bottom: calc(100% + 8px);
107
- left: 0;
108
- right: 0;
109
- background: var(--todo-panel-bg);
110
- border: 1px solid var(--todo-panel-border);
111
- border-radius: 8px;
112
- box-shadow: var(--todo-overlay-shadow);
113
- animation: slideUp .3s cubic-bezier(.4, 0, .2, 1);
114
- overflow: hidden;
115
- z-index: 100;
116
-
117
- .todo-items-scroll-container {
118
- max-height: calc(36px * 8);
119
- overflow-y: auto;
120
- padding: 8px 0;
121
-
122
- .todo-item-vertical {
123
- display: flex;
124
- align-items: flex-start;
125
- gap: 10px;
126
- padding: 8px 16px;
127
- transition: background-color .2s;
128
-
129
- &:hover {
130
- background-color: var(--todo-hover-bg);
131
- }
132
-
133
- .icon {
134
- font-size: 18px;
135
- margin-top: 1px;
136
- flex-shrink: 0;
137
- }
138
-
139
- &.status-completed {
140
- opacity: .6;
141
- .icon {
142
- color: #10b981;
143
- }
144
- .text {
145
- text-decoration: line-through;
146
- }
147
- }
148
-
149
- &.status-in_progress {
150
- .icon {
151
- color: var(--primary-color);
152
- animation: spin 2s linear infinite;
153
- }
154
- .text {
155
- color: var(--todo-text);
156
- font-weight: 500;
157
- }
158
- }
159
-
160
- &.status-pending {
161
- .icon {
162
- color: var(--todo-pending-icon);
163
- }
164
- .text {
165
- color: var(--todo-sub-text);
166
- }
167
- }
168
-
169
- .todo-content-wrapper {
170
- flex: 1;
171
- display: flex;
172
- align-items: center;
173
- gap: 8px;
174
-
175
- .text {
176
- font-size: 13px;
177
- line-height: 1.5;
178
- }
179
-
180
- .priority-tag {
181
- font-size: 10px;
182
- padding: 1px 4px;
183
- border-radius: 4px;
184
- text-transform: uppercase;
185
- font-weight: 600;
186
-
187
- &.high {
188
- background: var(--todo-priority-high-bg);
189
- color: var(--todo-priority-high-text);
190
- }
191
- &.medium {
192
- background: var(--todo-priority-medium-bg);
193
- color: var(--todo-priority-medium-text);
194
- }
195
- &.low {
196
- background: var(--todo-priority-low-bg);
197
- color: var(--todo-priority-low-text);
198
- }
199
- }
200
- }
201
- }
202
- }
89
+ &__chevron {
90
+ margin-left: 5px;
91
+ padding-left: 5px;
92
+ border-left: 1px solid var(--todo-divider);
93
+ font-size: 14px;
94
+ color: var(--todo-pending-icon);
95
+ transition: transform .22s ease;
96
+ }
97
+ }
98
+
99
+ .current-todo-progress {
100
+ height: 4px;
101
+ margin: 0 6px;
102
+ overflow: hidden;
103
+ background: var(--todo-track-bg);
104
+ border-radius: 999px;
105
+
106
+ &__fill {
107
+ height: 100%;
108
+ background: var(--todo-track-fill);
109
+ border-radius: inherit;
110
+ transition: width .3s ease;
111
+ }
112
+ }
113
+
114
+ .current-todo-list {
115
+ max-height: min(240px, 36vh);
116
+ margin: 0;
117
+ padding: 0;
118
+ overflow: auto;
119
+ list-style: none;
120
+ }
121
+
122
+ .current-todo-item {
123
+ display: grid;
124
+ grid-template-columns: auto auto minmax(0, 1fr);
125
+ align-items: center;
126
+ gap: 6px;
127
+ padding: 6px 5px;
128
+ border-radius: 8px;
129
+ transition: transform .22s ease, opacity .18s ease;
130
+
131
+ & + & {
132
+ margin-top: 1px;
133
+ }
134
+
135
+ &--completed {
136
+ opacity: .72;
137
+ }
138
+ }
139
+
140
+ .current-todo-item__status {
141
+ font-size: 14px;
142
+ line-height: 1;
143
+ color: var(--todo-pending-icon);
144
+ }
145
+
146
+ .current-todo-item__index {
147
+ font-size: 10px;
148
+ font-weight: 700;
149
+ color: var(--todo-sub-text);
150
+ line-height: 1.2;
151
+ }
152
+
153
+ .current-todo-item__body {
154
+ min-width: 0;
155
+ display: flex;
156
+ align-items: center;
157
+ gap: 4px;
158
+ width: 100%;
159
+ }
160
+
161
+ .current-todo-item__text {
162
+ flex: 1;
163
+ min-width: 0;
164
+ font-size: 11px;
165
+ line-height: 1.25;
166
+ color: var(--todo-text);
167
+ }
168
+
169
+ .current-todo-item__priority {
170
+ margin-left: auto;
171
+ flex-shrink: 0;
172
+ font-size: 12px;
173
+ line-height: 1;
174
+
175
+ &--high {
176
+ color: #ef4444;
177
+ }
178
+
179
+ &--medium {
180
+ color: #d97706;
181
+ }
182
+
183
+ &--low {
184
+ color: #10b981;
203
185
  }
204
186
  }
205
187
 
206
188
  html.dark .current-todo-container {
207
- --todo-panel-shadow: 0 8px 24px rgba(0, 0, 0, .24);
208
- --todo-overlay-shadow: 0 16px 36px rgba(0, 0, 0, .32);
209
- --todo-priority-high-bg: rgba(248, 113, 113, .16);
210
- --todo-priority-high-text: #fca5a5;
211
- --todo-priority-medium-bg: rgba(245, 158, 11, .16);
212
- --todo-priority-medium-text: #fcd34d;
213
- --todo-priority-low-bg: rgba(45, 212, 191, .16);
214
- --todo-priority-low-text: #5eead4;
189
+ --todo-track-bg: rgba(71, 85, 105, .48);
190
+ --todo-hover-bg: rgba(51, 65, 85, .48);
191
+ --todo-divider: rgba(71, 85, 105, .45);
215
192
  }
216
193
 
217
- @keyframes slideDown {
218
- from {
219
- opacity: 0;
220
- transform: translateY(-10px);
194
+ .current-todo-item--completed .current-todo-item__status {
195
+ color: var(--todo-done-icon);
196
+ }
197
+
198
+ .current-todo-item--completed .current-todo-item__text {
199
+ text-decoration: line-through;
200
+ }
201
+
202
+ .current-todo-item--in_progress .current-todo-item__status {
203
+ color: var(--todo-active-icon);
204
+ animation: currentTodoSpin 1s linear infinite;
205
+ }
206
+
207
+ .current-todo-item--in_progress .current-todo-item__text {
208
+ font-weight: 600;
209
+ }
210
+
211
+ .current-todo-container.expanded {
212
+ .current-todo-summary__chevron {
213
+ transform: rotate(0deg);
221
214
  }
222
- to {
223
- opacity: 1;
215
+
216
+ .current-todo-item {
224
217
  transform: translateY(0);
218
+ opacity: 1;
225
219
  }
226
220
  }
227
221
 
228
- @keyframes slideUp {
229
- from {
230
- opacity: 0;
231
- transform: translateY(10px);
222
+ .current-todo-container:not(.expanded) {
223
+ .current-todo-summary__chevron {
224
+ transform: rotate(0deg);
232
225
  }
233
- to {
234
- opacity: 1;
235
- transform: translateY(0);
226
+
227
+ .current-todo-item {
228
+ transform: translateY(-4px);
229
+ opacity: .6;
236
230
  }
237
231
  }
238
232
 
239
- @keyframes spin {
233
+ @media (max-width: 900px) {
234
+ .current-todo-summary {
235
+ align-items: flex-start;
236
+
237
+ &,
238
+ &__meta {
239
+ flex-wrap: wrap;
240
+ }
241
+
242
+ &__chevron {
243
+ margin-left: 0;
244
+ }
245
+ }
246
+ }
247
+
248
+ @keyframes currentTodoSpin {
240
249
  from {
241
250
  transform: rotate(0deg);
242
251
  }
252
+
243
253
  to {
244
254
  transform: rotate(360deg);
245
255
  }
@@ -1,10 +1,35 @@
1
1
  import './CurrentTodoList.scss'
2
2
  import type { ChatMessage, ChatMessageContent, ToolInputs } from '@vibe-forge/core'
3
- import React, { useState } from 'react'
3
+ import { useState } from 'react'
4
4
  import { useTranslation } from 'react-i18next'
5
+ import { ChatComposerCard } from './ChatComposerCard'
5
6
 
6
7
  type TodoItem = ToolInputs['adapter:claude-code:TodoWrite']['todos'][number]
7
8
 
9
+ const getTodoStatusIcon = (status: TodoItem['status']) => {
10
+ if (status === 'completed') {
11
+ return 'check_circle'
12
+ }
13
+
14
+ if (status === 'in_progress') {
15
+ return 'progress_activity'
16
+ }
17
+
18
+ return 'radio_button_unchecked'
19
+ }
20
+
21
+ const getPriorityIcon = (priority?: TodoItem['priority']) => {
22
+ if (priority === 'high') {
23
+ return 'keyboard_double_arrow_up'
24
+ }
25
+
26
+ if (priority === 'medium') {
27
+ return 'remove'
28
+ }
29
+
30
+ return 'keyboard_double_arrow_down'
31
+ }
32
+
8
33
  export function CurrentTodoList({ messages }: { messages: ChatMessage[] }) {
9
34
  const { t } = useTranslation()
10
35
  const [isExpanded, setIsExpanded] = useState(false)
@@ -38,66 +63,109 @@ export function CurrentTodoList({ messages }: { messages: ChatMessage[] }) {
38
63
  if (latestTodos.length === 0) return null
39
64
 
40
65
  const completedCount = latestTodos.filter(t => t.status === 'completed').length
66
+ const inProgressCount = latestTodos.filter(t => t.status === 'in_progress').length
41
67
  const totalCount = latestTodos.length
68
+ const pendingCount = totalCount - completedCount - inProgressCount
69
+ const progressPercent = totalCount > 0 ? (completedCount / totalCount) * 100 : 0
42
70
 
43
71
  if (totalCount === 0) {
44
72
  return (
45
73
  <div className='current-todo-container empty'>
46
- <div className='todo-progress-bar empty'>
47
- <div className='progress-info'>
48
- <span className='material-symbols-rounded'>assignment_late</span>
49
- <span className='text'>{t('chat.todo.noTasks')}</span>
50
- </div>
51
- </div>
74
+ <ChatComposerCard
75
+ className='current-todo-panel'
76
+ summaryClassName='current-todo-summary current-todo-summary--empty'
77
+ summary={
78
+ <>
79
+ <span className='material-symbols-rounded'>assignment_late</span>
80
+ <span className='current-todo-summary__text'>{t('chat.todo.noTasks')}</span>
81
+ </>
82
+ }
83
+ narrow
84
+ />
52
85
  </div>
53
86
  )
54
87
  }
55
88
 
89
+ const summaryStats = [
90
+ pendingCount > 0
91
+ ? { icon: 'radio_button_unchecked', count: pendingCount, className: 'current-todo-summary__stat' }
92
+ : null,
93
+ inProgressCount > 0
94
+ ? {
95
+ icon: 'progress_activity',
96
+ count: inProgressCount,
97
+ className: 'current-todo-summary__stat current-todo-summary__stat--active'
98
+ }
99
+ : null,
100
+ completedCount > 0
101
+ ? {
102
+ icon: 'check_circle',
103
+ count: completedCount,
104
+ className: 'current-todo-summary__stat current-todo-summary__stat--done'
105
+ }
106
+ : null
107
+ ].filter((item): item is { icon: string; count: number; className: string } => item != null)
108
+
56
109
  return (
57
110
  <div className={`current-todo-container ${isExpanded ? 'expanded' : ''}`}>
58
- <div className='todo-progress-bar' onClick={() => setIsExpanded(!isExpanded)}>
59
- <div className='progress-info'>
60
- <span className='material-symbols-rounded'>assignment</span>
61
- <span className='text'>{t('chat.todo.progress', { completed: completedCount, total: totalCount })}</span>
62
- </div>
63
- <div className='progress-track'>
64
- <div
65
- className='progress-fill'
66
- style={{ width: `${(completedCount / totalCount) * 100}%` }}
67
- />
68
- </div>
69
- <button className='expand-btn'>
70
- <span className='material-symbols-rounded'>
71
- {isExpanded ? 'expand_more' : 'expand_less'}
72
- </span>
73
- </button>
74
- </div>
75
-
76
- {isExpanded && (
77
- <div className='todo-items-overlay'>
78
- <div className='todo-items-scroll-container'>
79
- {latestTodos.map((todo, idx) => (
80
- <div
81
- key={todo.id || idx}
82
- className={`todo-item-vertical status-${todo.status}`}
83
- >
84
- <span className='material-symbols-rounded icon'>
85
- {todo.status === 'completed'
86
- ? 'check_circle'
87
- : todo.status === 'in_progress'
88
- ? 'clock_loader_40'
89
- : 'radio_button_unchecked'}
111
+ <ChatComposerCard
112
+ className='current-todo-panel'
113
+ summaryClassName='current-todo-summary'
114
+ expanded={isExpanded}
115
+ onToggle={() => setIsExpanded(!isExpanded)}
116
+ progress={
117
+ <div className='current-todo-progress'>
118
+ <div
119
+ className='current-todo-progress__fill'
120
+ style={{ width: `${progressPercent}%` }}
121
+ />
122
+ </div>
123
+ }
124
+ narrow
125
+ summary={
126
+ <>
127
+ <div className='current-todo-summary__headline'>
128
+ <span className='material-symbols-rounded current-todo-summary__icon'>checklist</span>
129
+ <span className='current-todo-summary__text'>
130
+ {t('chat.todo.progress', { completed: completedCount, total: totalCount })}
131
+ </span>
132
+ </div>
133
+ <div className='current-todo-summary__meta'>
134
+ {summaryStats.map(({ icon, count, className }) => (
135
+ <span key={`${icon}-${count}`} className={className}>
136
+ <span className='material-symbols-rounded'>{icon}</span>
137
+ <span>{count}</span>
90
138
  </span>
91
- <div className='todo-content-wrapper'>
92
- <span className='text'>{todo.content}</span>
93
- {todo.priority != null && todo.priority !== '' &&
94
- <span className={`priority-tag ${todo.priority}`}>{todo.priority}</span>}
95
- </div>
139
+ ))}
140
+ <span className='material-symbols-rounded current-todo-summary__chevron'>
141
+ {isExpanded ? 'expand_less' : 'expand_more'}
142
+ </span>
143
+ </div>
144
+ </>
145
+ }
146
+ >
147
+ <ol className='current-todo-list'>
148
+ {latestTodos.map((todo, idx) => (
149
+ <li key={todo.id || idx} className={`current-todo-item current-todo-item--${todo.status}`}>
150
+ <span className='material-symbols-rounded current-todo-item__status'>
151
+ {getTodoStatusIcon(todo.status)}
152
+ </span>
153
+ <span className='current-todo-item__index'>{idx + 1}.</span>
154
+ <div className='current-todo-item__body'>
155
+ <span className='current-todo-item__text'>{todo.content}</span>
156
+ {todo.priority != null && todo.priority !== '' && (
157
+ <span
158
+ className={`material-symbols-rounded current-todo-item__priority current-todo-item__priority--${todo.priority}`}
159
+ title={todo.priority}
160
+ >
161
+ {getPriorityIcon(todo.priority)}
162
+ </span>
163
+ )}
96
164
  </div>
97
- ))}
98
- </div>
99
- </div>
100
- )}
165
+ </li>
166
+ ))}
167
+ </ol>
168
+ </ChatComposerCard>
101
169
  </div>
102
170
  )
103
171
  }