@pheem49/mint 1.17.0 → 1.18.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 (421) hide show
  1. package/Cargo.lock +6 -6
  2. package/Cargo.toml +2 -2
  3. package/README.md +8 -2
  4. package/Release_Note.md +222 -71
  5. package/crates/mint-cli/src/agent/diff_render.rs +66 -44
  6. package/crates/mint-cli/src/agent/live_status.rs +21 -4
  7. package/crates/mint-cli/src/agent/markdown_render.rs +342 -5
  8. package/crates/mint-cli/src/agent.rs +25 -10
  9. package/crates/mint-cli/src/commands/agent.rs +4 -92
  10. package/crates/mint-cli/src/commands/browser.rs +2 -15
  11. package/crates/mint-cli/src/commands/integrations.rs +3 -3
  12. package/crates/mint-cli/src/commands/mod.rs +0 -3
  13. package/crates/mint-cli/src/commands/tailnet_web.rs +1 -0
  14. package/crates/mint-cli/src/interactive/chat_tui/dialog.rs +572 -0
  15. package/crates/mint-cli/src/interactive/chat_tui/mod.rs +1427 -0
  16. package/crates/mint-cli/src/interactive/chat_tui/render.rs +1524 -0
  17. package/crates/mint-cli/src/interactive/chat_tui/selection.rs +401 -0
  18. package/crates/mint-cli/src/interactive/chat_tui/state.rs +1833 -0
  19. package/crates/mint-cli/src/interactive/chat_tui/tests.rs +3414 -0
  20. package/crates/mint-cli/src/interactive/chat_tui/thought.rs +202 -0
  21. package/crates/mint-cli/src/interactive/chat_tui/transcript.rs +728 -0
  22. package/crates/mint-cli/src/interactive/chat_tui/watermark.rs +148 -0
  23. package/crates/mint-cli/src/interactive/command_ui.rs +53 -5
  24. package/crates/mint-cli/src/interactive/composer.rs +186 -0
  25. package/crates/mint-cli/src/interactive/format.rs +78 -3
  26. package/crates/mint-cli/src/interactive/input_box.rs +61 -1
  27. package/crates/mint-cli/src/interactive/resume_picker.rs +367 -25
  28. package/crates/mint-cli/src/interactive/slash_commands.rs +648 -371
  29. package/crates/mint-cli/src/interactive/tool_activity.rs +93 -20
  30. package/crates/mint-cli/src/interactive.rs +37 -0
  31. package/crates/mint-cli/src/main.rs +6 -3
  32. package/crates/mint-cli/src/markdown.rs +2 -37
  33. package/crates/mint-cli/src/onboard.rs +700 -282
  34. package/crates/mint-cli/src/setup.rs +1342 -624
  35. package/crates/mint-cli/src/terminal_theme.rs +159 -35
  36. package/crates/mint-cli/tests/library_intake.rs +1 -0
  37. package/crates/mint-core/src/agent/chat/anthropic.rs +318 -0
  38. package/crates/mint-core/src/agent/chat/custom.rs +149 -0
  39. package/crates/mint-core/src/agent/chat/gemini.rs +518 -0
  40. package/crates/mint-core/src/agent/chat/mod.rs +857 -0
  41. package/crates/mint-core/src/agent/chat/ollama.rs +321 -0
  42. package/crates/mint-core/src/agent/chat/openai.rs +582 -0
  43. package/crates/mint-core/src/agent/chat/streaming.rs +469 -0
  44. package/crates/mint-core/src/agent/chat/tests.rs +1479 -0
  45. package/crates/mint-core/src/agent/memory.rs +56 -2
  46. package/crates/mint-core/src/agent/tasks.rs +2 -2
  47. package/crates/mint-core/src/api_server/routes/chat.rs +24 -2
  48. package/crates/mint-core/src/api_server/routes/gemini_live.rs +14 -1
  49. package/crates/mint-core/src/api_server/routes/html_preview.rs +1 -8
  50. package/crates/mint-core/src/api_server/routes/sessions.rs +21 -0
  51. package/crates/mint-core/src/avatar_bridge.rs +0 -22
  52. package/crates/mint-core/src/browser/cdp.rs +10 -4
  53. package/crates/mint-core/src/browser/headless.rs +582 -0
  54. package/crates/mint-core/src/browser/input.rs +7 -62
  55. package/crates/mint-core/src/browser/interact.rs +0 -14
  56. package/crates/mint-core/src/browser/mod.rs +8 -29
  57. package/crates/mint-core/src/browser/navigate.rs +2 -36
  58. package/crates/mint-core/src/browser/runtime.rs +2 -4
  59. package/crates/mint-core/src/browser/session.rs +50 -466
  60. package/crates/mint-core/src/browser/workflow.rs +142 -32
  61. package/crates/mint-core/src/cron/store.rs +2 -2
  62. package/crates/mint-core/src/integrations/mcp.rs +6 -8
  63. package/crates/mint-core/src/lib.rs +0 -5
  64. package/crates/mint-core/src/media/gemini_live.rs +636 -86
  65. package/crates/mint-core/src/media/library/migration.rs +26 -0
  66. package/crates/mint-core/src/media/library/tests.rs +1 -1
  67. package/crates/mint-core/src/media/library/thumbnails.rs +8 -2
  68. package/crates/mint-core/src/media/pictures.rs +1 -1
  69. package/crates/mint-core/src/media/tool_images.rs +92 -1
  70. package/crates/mint-core/src/mods/manager.rs +101 -35
  71. package/crates/mint-core/src/orchestration/context_render.rs +441 -24
  72. package/crates/mint-core/src/orchestration/decision_parsing.rs +531 -16
  73. package/crates/mint-core/src/orchestration/full_skill_result_tests.rs +12 -0
  74. package/crates/mint-core/src/orchestration/loop_guard.rs +145 -0
  75. package/crates/mint-core/src/orchestration/mcp_outcome_tests.rs +864 -0
  76. package/crates/mint-core/src/orchestration/memory_skill.rs +88 -28
  77. package/crates/mint-core/src/orchestration/mod.rs +320 -4249
  78. package/crates/mint-core/src/orchestration/reliability.rs +67 -27
  79. package/crates/mint-core/src/orchestration/review_regressions.rs +5 -0
  80. package/crates/mint-core/src/orchestration/tests.rs +1665 -0
  81. package/crates/mint-core/src/orchestration/tools/dispatch.rs +967 -0
  82. package/crates/mint-core/src/orchestration/tools/files.rs +1 -0
  83. package/crates/mint-core/src/orchestration/tools/mod.rs +5 -1
  84. package/crates/mint-core/src/orchestration/tools/planning.rs +102 -42
  85. package/crates/mint-core/src/orchestration/tools/shell.rs +129 -58
  86. package/crates/mint-core/src/orchestration/truncation.rs +170 -13
  87. package/crates/mint-core/src/orchestration/types.rs +648 -0
  88. package/crates/mint-core/src/orchestration/verification.rs +0 -3
  89. package/crates/mint-core/src/orchestration/workspace_helpers.rs +24 -6
  90. package/crates/mint-core/src/prompts/agent.rs +52 -76
  91. package/crates/mint-core/src/prompts/tool_catalog.rs +8 -151
  92. package/crates/mint-core/src/search/files.rs +20 -0
  93. package/crates/mint-core/src/slash/mod.rs +228 -265
  94. package/crates/mint-core/src/slash/models.rs +6 -1
  95. package/crates/mint-core/src/system/bg_shell.rs +1 -0
  96. package/crates/mint-core/src/system/config.rs +176 -34
  97. package/crates/mint-mod-runtime/src/lib.rs +37 -23
  98. package/out/web/assets/ArtifactPreviewPanel-Cx6BVOOF.js +2 -0
  99. package/out/web/assets/CalculationCard-D2E74u5q.js +1 -0
  100. package/out/web/assets/CliSessionsView-ZbdtSjvK.css +1 -0
  101. package/out/web/assets/{CliSessionsView-MI8kXMAb.js → CliSessionsView-z5i6qGyb.js} +1 -1
  102. package/out/web/assets/CodeReviewPage-BK2bOScd.css +1 -0
  103. package/out/web/assets/CodeReviewPage-Dp6zHuHu.js +2 -0
  104. package/out/web/assets/{CommandPalette-BD8SlTE5.js → CommandPalette-DaKlzbKs.js} +1 -1
  105. package/out/web/assets/ImageGenCard-BMCJHP9O.js +1 -0
  106. package/out/web/assets/ImageSearchCard-Cld_SOUg.js +1 -0
  107. package/out/web/assets/{ImageStudioPanel-BP7N4rLr.js → ImageStudioPanel-B5N7TjeB.js} +1 -1
  108. package/out/web/assets/LibraryPage-CMB89rJ0.css +1 -0
  109. package/out/web/assets/LibraryPage-DbZEi4W_.js +2 -0
  110. package/out/web/assets/LinkedFoldersView-9B9DIPoZ.js +1 -0
  111. package/out/web/assets/{McpRegistryPicker-CoS83vtc.js → McpRegistryPicker-DnXPlzI7.js} +1 -1
  112. package/out/web/assets/McpServersView-CiNBNUl4.js +1 -0
  113. package/out/web/assets/MermaidCard-BBDNEXbY.js +2 -0
  114. package/out/web/assets/MintDashboard-C_UYPoNV.js +119 -0
  115. package/out/web/assets/MintDashboard-DTd8C_c8.css +1 -0
  116. package/out/web/assets/PlanCard-C2x5pajq.js +1 -0
  117. package/out/web/assets/{PluginsView-jBYmcKh4.js → PluginsView-DoTg9MVa.js} +1 -1
  118. package/out/web/assets/RewindModal-B5oowrR0.js +1 -0
  119. package/out/web/assets/{ScheduledTasksView-5uw9-V9H.js → ScheduledTasksView-BD5DVPkZ.js} +1 -1
  120. package/out/web/assets/{SelectField-DXBQtrUK.js → SelectField-Cy6CghrU.js} +1 -1
  121. package/out/web/assets/SettingsWindow-BYl_oCFh.js +4 -0
  122. package/out/web/assets/SettingsWindow-Ckcgnjt8.css +1 -0
  123. package/out/web/assets/{SkillsView-C-gp9J7m.js → SkillsView-CIeWwq5z.js} +1 -1
  124. package/out/web/assets/StockCard-DxUciKyp.js +1 -0
  125. package/out/web/assets/ToolSurfacePage-qBgs_VHq.css +1 -0
  126. package/out/web/assets/ToolSurfacePage-saVbVrkE.js +38 -0
  127. package/out/web/assets/{UiFeatureCard-6BwxTOCe.js → UiFeatureCard-CdY0hGWy.js} +1 -1
  128. package/out/web/assets/{UiGridCard-DvZcLNxb.js → UiGridCard-BBK3I5hC.js} +1 -1
  129. package/out/web/assets/UiMockupWidget-CpR9EDuc.js +1 -0
  130. package/out/web/assets/{VeoStudioPanel-DOj7_WR3.css → VeoStudioPanel-9kU9YLEN.css} +1 -1
  131. package/out/web/assets/{VeoStudioPanel-DfsOJKv0.js → VeoStudioPanel-Co6-wEWM.js} +2 -2
  132. package/out/web/assets/WeatherCard-Buzi7Vfu.js +1 -0
  133. package/out/web/assets/WorkspacePdfPreview-Bi8Zzyir.js +2 -0
  134. package/out/web/assets/{abnfDiagram-VCTEODGH-BOo3Ckng.js → abnfDiagram-VCTEODGH-CMfR95N2.js} +1 -1
  135. package/out/web/assets/{architecture-7GRP2DOG-ZOwheW3n.js → architecture-7GRP2DOG-DhAM4HyO.js} +1 -1
  136. package/out/web/assets/{architectureDiagram-5GKGNRK7-DC2FDzVd.js → architectureDiagram-5GKGNRK7-Yk3TUJ_F.js} +1 -1
  137. package/out/web/assets/{blockDiagram-I7D4REHJ-BrKFWdAH.js → blockDiagram-I7D4REHJ-X9fBgJik.js} +1 -1
  138. package/out/web/assets/{c4Diagram-7LVT6UL2-BHTHK1Yd.js → c4Diagram-7LVT6UL2-Bk9x7N-8.js} +1 -1
  139. package/out/web/assets/{chunk-4HAMMTFA-BYFkZwNj.js → chunk-4HAMMTFA-Dx5fk1_0.js} +1 -1
  140. package/out/web/assets/{chunk-75Z2AOVW-BSKfSKSA.js → chunk-75Z2AOVW-BszTQoM4.js} +1 -1
  141. package/out/web/assets/{chunk-DU6HZSFF-vIhsiW6n.js → chunk-DU6HZSFF-DK-As3rk.js} +1 -1
  142. package/out/web/assets/{chunk-F27PBJKO-BlYpW9xq.js → chunk-F27PBJKO-LmncZZIS.js} +1 -1
  143. package/out/web/assets/{chunk-GMAD6QVW-BIBz_Ug5.js → chunk-GMAD6QVW-DSQ_sDRJ.js} +1 -1
  144. package/out/web/assets/{chunk-GVQU2GXP-NPSHxeqC.js → chunk-GVQU2GXP-Cno3ulje.js} +1 -1
  145. package/out/web/assets/{chunk-IMKFNOWR-YlJK8_Fp.js → chunk-IMKFNOWR-bIzfY9Jc.js} +1 -1
  146. package/out/web/assets/{chunk-L3NEJ4N5-DMYi4-af.js → chunk-L3NEJ4N5-Dl6eOa0D.js} +1 -1
  147. package/out/web/assets/{chunk-OSK3NFVY-Begd3-jA.js → chunk-OSK3NFVY-BaUGJ-cM.js} +1 -1
  148. package/out/web/assets/{chunk-P2QGCYS3-D1I4xFHN.js → chunk-P2QGCYS3-_066ndhH.js} +1 -1
  149. package/out/web/assets/{chunk-POPQ4Y6H-CafZZzNE.js → chunk-POPQ4Y6H-YT1AKhTv.js} +1 -1
  150. package/out/web/assets/{chunk-PWAF6VOD-Dwh6_Lnt.js → chunk-PWAF6VOD-CrEgDsxh.js} +1 -1
  151. package/out/web/assets/{chunk-SHT3W25Y-B0XrCSEb.js → chunk-SHT3W25Y-_KwaRLOl.js} +1 -1
  152. package/out/web/assets/{chunk-SVP7TREG-CxLsddxC.js → chunk-SVP7TREG-BQ1qb32L.js} +1 -1
  153. package/out/web/assets/{chunk-TICWLB2K-y156QInb.js → chunk-TICWLB2K-BDyehCtg.js} +1 -1
  154. package/out/web/assets/classDiagram-ZZMXUADV-BoSpzRCJ.js +1 -0
  155. package/out/web/assets/classDiagram-v2-VYDZK3BY-BoSpzRCJ.js +1 -0
  156. package/out/web/assets/{config-DqXJXeZM.css → config-2suVFPZg.css} +1 -1
  157. package/out/web/assets/config-CkRCdkxn.js +2 -0
  158. package/out/web/assets/{cynefin-OW5HDTMX-SMVvrLf-.js → cynefin-OW5HDTMX-Dl_31aaN.js} +1 -1
  159. package/out/web/assets/{cynefinDiagram-5FMLGOSQ-rZznN24T.js → cynefinDiagram-5FMLGOSQ-Bpir8jha.js} +1 -1
  160. package/out/web/assets/{dagre-GXQ25YYZ-BOToydFu.js → dagre-GXQ25YYZ-D9xu3nsq.js} +1 -1
  161. package/out/web/assets/{diagram-S7CK7UJ4-TMVaGQEJ.js → diagram-S7CK7UJ4-DeveoEeB.js} +1 -1
  162. package/out/web/assets/{diagram-UQ7AKVKN-C2JK-GP2.js → diagram-UQ7AKVKN-p4xWRESV.js} +1 -1
  163. package/out/web/assets/{diagram-VSXAHHWV-Cw8VSi2K.js → diagram-VSXAHHWV-C7qz9NDF.js} +1 -1
  164. package/out/web/assets/{diagram-VX7I27RA-DXp4fKk9.js → diagram-VX7I27RA-DRiCa3Vd.js} +1 -1
  165. package/out/web/assets/{diagram-Z3DM3KII-CzSicYiW.js → diagram-Z3DM3KII-Bt7zduQX.js} +1 -1
  166. package/out/web/assets/{ebnfDiagram-PWID7BFC-Dqj-zqPu.js → ebnfDiagram-PWID7BFC-DV9WpwdR.js} +1 -1
  167. package/out/web/assets/{erDiagram-RLTQ6QDP-DZwFZAuD.js → erDiagram-RLTQ6QDP-BJ_nwG2m.js} +1 -1
  168. package/out/web/assets/{eventmodeling-NTZA5JFV-C0O-Lvgp.js → eventmodeling-NTZA5JFV-BTBMrfVa.js} +1 -1
  169. package/out/web/assets/flowDiagram-HODETNUW-Cdlq3cJL.js +1 -0
  170. package/out/web/assets/{ganttDiagram-EL5Y4UJY-Da4ULXTl.js → ganttDiagram-EL5Y4UJY-DQLdsXrC.js} +1 -1
  171. package/out/web/assets/{gitGraph-4MIJSDKK-B9wNFZIP.js → gitGraph-4MIJSDKK-CL1OEOQ_.js} +1 -1
  172. package/out/web/assets/{gitGraphDiagram-WWUBYQGX-RjrhB0MP.js → gitGraphDiagram-WWUBYQGX-8cSi42H7.js} +1 -1
  173. package/out/web/assets/index-BocxnrDG.js +168 -0
  174. package/out/web/assets/index-yeh_r55a.css +1 -0
  175. package/out/web/assets/{info-A6RAGUB7-B3dfCpeY.js → info-A6RAGUB7-C1zsX5sc.js} +1 -1
  176. package/out/web/assets/{infoDiagram-27XIBGKW-QVWkLVx7.js → infoDiagram-27XIBGKW-DsRYtIyI.js} +1 -1
  177. package/out/web/assets/{ishikawaDiagram-5VMMS53U-CLFNIRI9.js → ishikawaDiagram-5VMMS53U-B2crwIXj.js} +1 -1
  178. package/out/web/assets/{journeyDiagram-3NMN7TZE-fgOQadYF.js → journeyDiagram-3NMN7TZE-BTH-GyVR.js} +1 -1
  179. package/out/web/assets/{kanban-definition-UXKFOSKX-G3Q_9g9O.js → kanban-definition-UXKFOSKX-BeRfCnuA.js} +1 -1
  180. package/out/web/assets/{mermaid-parser.core-v3Jm7nco.js → mermaid-parser.core-BJwgCBBc.js} +3 -3
  181. package/out/web/assets/{mermaid.core-DTEjLUA1.js → mermaid.core-CsDDodN8.js} +4 -4
  182. package/out/web/assets/{mindmap-definition-YA3MSWOX-C_D42_fF.js → mindmap-definition-YA3MSWOX-B42efOQ1.js} +1 -1
  183. package/out/web/assets/{modelManager-BPLycQrN.js → modelManager-B3ZFMh8v.js} +2 -2
  184. package/out/web/assets/{oauthManager-BUK7ic7q.js → oauthManager-Ch5Du2fF.js} +1 -1
  185. package/out/web/assets/{packet-AYTQ26CC-B-R-SHlF.js → packet-AYTQ26CC-B6xUyE6r.js} +1 -1
  186. package/out/web/assets/{pegDiagram-XKGWAZYB-Da2q_giz.js → pegDiagram-XKGWAZYB-1LabVycL.js} +1 -1
  187. package/out/web/assets/{pie-WAS4IAKB-BC8F0N7-.js → pie-WAS4IAKB-DJwo-nf_.js} +1 -1
  188. package/out/web/assets/{pieDiagram-E7YTZNPT-Iy9REJNC.js → pieDiagram-E7YTZNPT-icmAqzy4.js} +1 -1
  189. package/out/web/assets/{quadrantDiagram-AXDQQJYC-ztsiYw7h.js → quadrantDiagram-AXDQQJYC-CZ-wEx41.js} +1 -1
  190. package/out/web/assets/{radar-RG4KPBEZ-B_1P8Z_z.js → radar-RG4KPBEZ-D7d-Xriw.js} +1 -1
  191. package/out/web/assets/{railroad-74A4TZTK-DuTqczSo.js → railroad-74A4TZTK-viuhdYbs.js} +1 -1
  192. package/out/web/assets/{railroad-abnf-HS5TGJTU-Df29WLmp.js → railroad-abnf-HS5TGJTU-DNXiCNea.js} +1 -1
  193. package/out/web/assets/{railroad-ebnf-LZEXJU2U-ePFMo-qp.js → railroad-ebnf-LZEXJU2U-nkSu1-0C.js} +1 -1
  194. package/out/web/assets/{railroad-peg-WCYAUIDC-DYXLW4_E.js → railroad-peg-WCYAUIDC-BhbMeQzz.js} +1 -1
  195. package/out/web/assets/{railroadDiagram-O6MQD6OU-LStnZf2S.js → railroadDiagram-O6MQD6OU-CLpG1jUX.js} +1 -1
  196. package/out/web/assets/{requirementDiagram-BXWQKSXE-DmzonMH-.js → requirementDiagram-BXWQKSXE-kRDrvWrc.js} +1 -1
  197. package/out/web/assets/{sankeyDiagram-P5KCCOFB-B8vjmUU1.js → sankeyDiagram-P5KCCOFB-DxAwmq4x.js} +1 -1
  198. package/out/web/assets/{sequenceDiagram-WJ2MYXX4-CTnplOAX.js → sequenceDiagram-WJ2MYXX4-aLgY-6Wz.js} +1 -1
  199. package/out/web/assets/{stateDiagram-D77RDMKH-BFrIaLdI.js → stateDiagram-D77RDMKH-D5QWfOhp.js} +1 -1
  200. package/out/web/assets/stateDiagram-v2-MP3YSRHH-D6OiZoAP.js +1 -0
  201. package/out/web/assets/{swimlanes-42K2YHIH-BXGngUNU.js → swimlanes-42K2YHIH-CRs5UyA-.js} +1 -1
  202. package/out/web/assets/swimlanesDiagram-VR7AAH4N-UgEXIsV0.js +8 -0
  203. package/out/web/assets/syntaxHighlight-C-wAGT84.js +3 -0
  204. package/out/web/assets/{timeline-definition-24CTP7MA-CegH7n43.js → timeline-definition-24CTP7MA-Denqd9qb.js} +1 -1
  205. package/out/web/assets/{treeView-Q6P3EWNA-DTpJv2Tw.js → treeView-Q6P3EWNA-0my3Z3s4.js} +1 -1
  206. package/out/web/assets/{treemap-WGGIJYW6-i8M9iJU6.js → treemap-WGGIJYW6-B_EjkLYq.js} +1 -1
  207. package/out/web/assets/{vennDiagram-4TSXK5OY-Dpzo1S8U.js → vennDiagram-4TSXK5OY-DxVg3Ewr.js} +1 -1
  208. package/out/web/assets/{wardley-WFR3VGLG-BrNsgtfw.js → wardley-WFR3VGLG-CGD-Tj4p.js} +1 -1
  209. package/out/web/assets/{wardleyDiagram-VM6X3IG4-lQ92LFE1.js → wardleyDiagram-VM6X3IG4-CmfS39Xm.js} +1 -1
  210. package/out/web/assets/{xychartDiagram-S5SC5T6Z-BaOaEoBd.js → xychartDiagram-S5SC5T6Z-BVM9bKis.js} +1 -1
  211. package/out/web/index-web.html +2 -2
  212. package/out/web/index.html +2 -2
  213. package/package.json +2 -2
  214. package/shared-modules/CODEOWNERS +3 -3
  215. package/shared-modules/SDL2/SDL2_mixer.json +27 -0
  216. package/shared-modules/appstream/README.md +13 -0
  217. package/shared-modules/appstream/appstream-compose.json +111 -0
  218. package/shared-modules/dbus-glib/dbus-glib.json +2 -2
  219. package/shared-modules/libportal/libportal.json +23 -0
  220. package/shared-modules/linux-audio/fluidsynth2-static.json +2 -2
  221. package/shared-modules/linux-audio/fluidsynth2.json +2 -2
  222. package/shared-modules/linux-audio/libinstpatch.json +2 -2
  223. package/shared-modules/linux-audio/liblo-static.json +3 -0
  224. package/shared-modules/luajit/luajit.json +2 -2
  225. package/shared-modules/squashfs-tools/squashfs-tools.json +0 -3
  226. package/slash-commands.json +7 -2
  227. package/src/renderer/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
  228. package/src/renderer/shared/agentProgress.ts +51 -3
  229. package/src/renderer/shared/components/Settings/AutomationTab.tsx +2 -56
  230. package/src/renderer/shared/components/Settings/AvatarCropModal.tsx +15 -1
  231. package/src/renderer/shared/components/Settings/GeneralTab.tsx +25 -12
  232. package/src/renderer/shared/components/Settings/ThemeTab.test.tsx +45 -0
  233. package/src/renderer/shared/components/Settings/ThemeTab.tsx +106 -3
  234. package/src/renderer/shared/components/activity/AgentActivityDrawer.tsx +67 -17
  235. package/src/renderer/shared/components/activity/AgentActivityTable.tsx +376 -134
  236. package/src/renderer/shared/components/activity/AskUserActivityCard.test.tsx +122 -0
  237. package/src/renderer/shared/components/activity/AskUserActivityCard.tsx +70 -0
  238. package/src/renderer/shared/components/activity/McpToolResults.tsx +39 -2
  239. package/src/renderer/shared/components/activity/SubagentDagView.tsx +7 -7
  240. package/src/renderer/shared/components/activity/ViewedImages.tsx +41 -2
  241. package/src/renderer/shared/components/app/ChunkErrorBoundary.tsx +3 -3
  242. package/src/renderer/shared/components/app/CommandPalette.tsx +7 -7
  243. package/src/renderer/shared/components/app/DesktopTitlebar.tsx +2 -2
  244. package/src/renderer/shared/components/app/MintDashboard.tsx +27 -17
  245. package/src/renderer/shared/components/app/ModalErrorBoundary.tsx +3 -3
  246. package/src/renderer/shared/components/cards/CalculationCard.tsx +3 -3
  247. package/src/renderer/shared/components/cards/ImageGenCard.tsx +2 -2
  248. package/src/renderer/shared/components/cards/ImageSearchCard.tsx +2 -2
  249. package/src/renderer/shared/components/cards/MermaidCard.tsx +1 -1
  250. package/src/renderer/shared/components/cards/PlanCard.test.tsx +41 -0
  251. package/src/renderer/shared/components/cards/PlanCard.tsx +32 -0
  252. package/src/renderer/shared/components/cards/ReleaseNotesCard.test.tsx +29 -0
  253. package/src/renderer/shared/components/cards/ReleaseNotesCard.tsx +137 -0
  254. package/src/renderer/shared/components/cards/StockCard.tsx +7 -7
  255. package/src/renderer/shared/components/cards/ToolResultCards.tsx +11 -3
  256. package/src/renderer/shared/components/cards/UiMockupWidget.tsx +4 -4
  257. package/src/renderer/shared/components/cards/WeatherCard.tsx +5 -5
  258. package/src/renderer/shared/components/chat/ApprovalCard.test.tsx +11 -0
  259. package/src/renderer/shared/components/chat/ApprovalCard.tsx +21 -2
  260. package/src/renderer/shared/components/chat/ArtifactCards.test.tsx +69 -0
  261. package/src/renderer/shared/components/chat/ArtifactCards.tsx +238 -0
  262. package/src/renderer/shared/components/chat/AttachedDocumentCard.test.tsx +39 -0
  263. package/src/renderer/shared/components/chat/AttachedDocumentCard.tsx +220 -0
  264. package/src/renderer/shared/components/chat/ChatCodeBlock.test.tsx +33 -0
  265. package/src/renderer/shared/components/chat/ChatCodeBlock.tsx +15 -1
  266. package/src/renderer/shared/components/chat/ChatMessageItem.test.tsx +40 -2
  267. package/src/renderer/shared/components/chat/ChatMessageItem.tsx +180 -34
  268. package/src/renderer/shared/components/chat/ChatModeSelector.css +227 -0
  269. package/src/renderer/shared/components/chat/ChatModeSelector.test.tsx +45 -0
  270. package/src/renderer/shared/components/chat/ChatModeSelector.tsx +198 -0
  271. package/src/renderer/shared/components/chat/ChatPanel.test.tsx +22 -0
  272. package/src/renderer/shared/components/chat/ChatPanel.tsx +227 -53
  273. package/src/renderer/shared/components/chat/DiffReviewModal.tsx +6 -6
  274. package/src/renderer/shared/components/chat/GeminiLiveOverlay.test.tsx +142 -1
  275. package/src/renderer/shared/components/chat/GeminiLiveOverlay.tsx +45 -3
  276. package/src/renderer/shared/components/chat/ModelSelectorPopover.tsx +42 -14
  277. package/src/renderer/shared/components/chat/RewindModal.tsx +10 -10
  278. package/src/renderer/shared/components/chat/SlashSuggestions.test.tsx +14 -0
  279. package/src/renderer/shared/components/chat/SourcesBlock.test.tsx +53 -0
  280. package/src/renderer/shared/components/chat/SourcesBlock.tsx +236 -90
  281. package/src/renderer/shared/components/chat/TurnFileChanges.test.tsx +45 -1
  282. package/src/renderer/shared/components/chat/TurnFileChanges.tsx +202 -169
  283. package/src/renderer/shared/components/extensions/CliSessionsView.tsx +5 -4
  284. package/src/renderer/shared/components/extensions/McpRegistryPicker.tsx +3 -3
  285. package/src/renderer/shared/components/studio/LibraryPage.tsx +48 -5
  286. package/src/renderer/shared/components/workspace/ArtifactPreviewPanel.tsx +125 -13
  287. package/src/renderer/shared/components/workspace/CodeReviewPage.test.tsx +50 -0
  288. package/src/renderer/shared/components/workspace/CodeReviewPage.tsx +77 -16
  289. package/src/renderer/shared/components/workspace/GitBranchSelector.tsx +78 -22
  290. package/src/renderer/shared/components/workspace/ToolSurfacePage.test.tsx +13 -0
  291. package/src/renderer/shared/components/workspace/ToolSurfacePage.tsx +48 -28
  292. package/src/renderer/shared/components/workspace/WorkspacePdfPreview.tsx +266 -47
  293. package/src/renderer/shared/components/workspace/WorkspacePreviewActions.test.tsx +18 -6
  294. package/src/renderer/shared/components/workspace/background-terminals.css +11 -11
  295. package/src/renderer/shared/constants/config.ts +1 -5
  296. package/src/renderer/shared/constants/models.test.ts +51 -0
  297. package/src/renderer/shared/constants/models.ts +139 -32
  298. package/src/renderer/shared/conversation/lifecycle.test.ts +91 -3
  299. package/src/renderer/shared/conversation/lifecycle.ts +104 -5
  300. package/src/renderer/shared/conversation/progressiveStream.test.ts +83 -0
  301. package/src/renderer/shared/conversation/progressiveStream.ts +219 -0
  302. package/src/renderer/shared/css/agent-observability.css +133 -0
  303. package/src/renderer/shared/css/chat-ui-cards.css +13 -13
  304. package/src/renderer/shared/css/code-review.css +63 -34
  305. package/src/renderer/shared/css/code-sessions.css +47 -18
  306. package/src/renderer/shared/css/collapsed-paste.css +1 -1
  307. package/src/renderer/shared/css/error-notice.css +1 -1
  308. package/src/renderer/shared/css/file-changes.css +165 -80
  309. package/src/renderer/shared/css/library.css +105 -10
  310. package/src/renderer/shared/css/management-views.css +1 -1
  311. package/src/renderer/shared/css/mcp-results.css +5 -5
  312. package/src/renderer/shared/css/model-selector.css +18 -18
  313. package/src/renderer/shared/css/mods.css +7 -7
  314. package/src/renderer/shared/css/notification-notice.css +2 -2
  315. package/src/renderer/shared/css/queued-messages.css +5 -5
  316. package/src/renderer/shared/css/settings/general.css +18 -13
  317. package/src/renderer/shared/css/settings/profile.css +5 -5
  318. package/src/renderer/shared/css/settings/theme.css +5 -5
  319. package/src/renderer/shared/css/slash-choice.css +2 -2
  320. package/src/renderer/shared/css/slash-suggestions.css +3 -3
  321. package/src/renderer/shared/css/sources-block.css +41 -2
  322. package/src/renderer/shared/css/tools-panel.css +2 -2
  323. package/src/renderer/shared/css/ui-tailwind.css +8 -0
  324. package/src/renderer/shared/css/veo-studio.css +2 -2
  325. package/src/renderer/shared/css/viewed-images.css +7 -7
  326. package/src/renderer/shared/platform.ts +2 -1
  327. package/src/renderer/shared/theme/themeManager.test.ts +17 -0
  328. package/src/renderer/shared/theme/themeManager.ts +21 -4
  329. package/src/renderer/shared/theme/themes.ts +54 -0
  330. package/src/renderer/shared/theme/tokens.css +6 -4
  331. package/src/renderer/shared/types.ts +1 -1
  332. package/src/renderer/shared/utils/agentActivity.test.ts +468 -2
  333. package/src/renderer/shared/utils/agentActivity.ts +602 -35
  334. package/src/renderer/shared/utils/artifactBrowser.test.ts +37 -32
  335. package/src/renderer/shared/utils/artifactBrowser.ts +17 -19
  336. package/src/renderer/shared/utils/attachedDocument.test.ts +73 -0
  337. package/src/renderer/shared/utils/attachedDocument.ts +49 -0
  338. package/src/renderer/shared/utils/fileIcons.test.ts +59 -0
  339. package/src/renderer/shared/utils/fileIcons.ts +149 -16
  340. package/src/renderer/shared/utils/markdown.tsx +72 -19
  341. package/src/renderer/shared/utils/markdown.webImages.test.tsx +16 -0
  342. package/src/renderer/shared/utils/mcpResults.test.tsx +29 -0
  343. package/src/renderer/shared/utils/slashCommandProcessor.ts +4 -1
  344. package/src/renderer/shared/utils/syntaxHighlight.test.tsx +11 -1
  345. package/src/renderer/shared/utils/syntaxHighlight.tsx +51 -3
  346. package/src/renderer/shared/utils/useGeminiLiveVoice.ts +324 -51
  347. package/src/renderer/shared/utils/workspaceDrag.test.ts +153 -0
  348. package/src/renderer/shared/utils/workspaceDrag.ts +142 -0
  349. package/src/renderer/shared/utils/workspaceMedia.ts +10 -2
  350. package/src/renderer/src/App.tsx +14 -8
  351. package/src/renderer/src/agentProgress.ts +1 -0
  352. package/src/renderer/src/components/ScreenPicker.css +1 -1
  353. package/src/renderer/src/components/WorkspacePanel.tsx +6 -5
  354. package/src/renderer/src/css/app-shell.css +4 -4
  355. package/src/renderer/src/css/chat.css +1261 -241
  356. package/src/renderer/src/css/desktop-tools.css +11 -11
  357. package/src/renderer/src/css/sidebar-workspace.css +2 -2
  358. package/src/renderer/src/css/tool-surfaces.css +12 -12
  359. package/src/renderer/src/index.css +38 -20
  360. package/src/renderer/src/tauri.ts +22 -2
  361. package/src/renderer/src-web/App.tsx +14 -0
  362. package/src/renderer/src-web/agentProgress.ts +1 -0
  363. package/src/renderer/src-web/css/app-shell.css +4 -4
  364. package/src/renderer/src-web/css/chat.css +1278 -190
  365. package/src/renderer/src-web/css/mobile.css +29 -13
  366. package/src/renderer/src-web/css/settings/mobile.css +2 -2
  367. package/src/renderer/src-web/css/sidebar-workspace.css +1 -1
  368. package/src/renderer/src-web/index.css +38 -20
  369. package/src/renderer/src-web/tauri.ts +22 -2
  370. package/src/renderer/tests/browserArtifacts.browser.tsx +1 -1
  371. package/src/renderer/tests/library.browser.tsx +3 -0
  372. package/src/renderer/tests/liveVoice.browser.html +1 -0
  373. package/src/renderer/tests/workspaceDrop.browser.tsx +1 -1
  374. package/src-tauri/src/app/lifecycle.rs +1 -14
  375. package/src-tauri/src/background/headless.rs +14 -8
  376. package/src-tauri/src/commands/conversation.rs +38 -0
  377. package/src-tauri/src/native/mod.rs +0 -1
  378. package/src-tauri/src/native/system.rs +4 -47
  379. package/crates/mint-cli/src/interactive/chat_tui.rs +0 -8855
  380. package/crates/mint-core/src/agent/chat.rs +0 -4394
  381. package/crates/mint-core/src/browser/lifecycle.rs +0 -291
  382. package/crates/mint-core/src/browser/logging.rs +0 -20
  383. package/crates/mint-core/src/orchestration/tools/browser.rs +0 -31
  384. package/out/web/assets/ArtifactPreviewPanel-S0dPfYFx.js +0 -2
  385. package/out/web/assets/CalculationCard-CRjP3E1j.js +0 -1
  386. package/out/web/assets/CliSessionsView-C3Br2v5Y.css +0 -1
  387. package/out/web/assets/CodeReviewPage-CUJceQme.css +0 -1
  388. package/out/web/assets/CodeReviewPage-VCUgPla_.js +0 -2
  389. package/out/web/assets/ImageGenCard-BCXxkVJX.js +0 -1
  390. package/out/web/assets/ImageSearchCard-N3yQOr8Z.js +0 -1
  391. package/out/web/assets/LibraryPage-DAxUTAg7.css +0 -1
  392. package/out/web/assets/LibraryPage-WlviRdR8.js +0 -2
  393. package/out/web/assets/LinkedFoldersView-CKRgroWK.js +0 -1
  394. package/out/web/assets/McpServersView-D3wHnuHg.js +0 -1
  395. package/out/web/assets/MermaidCard-NqrHdyJW.js +0 -2
  396. package/out/web/assets/MintDashboard-B2DJsDDO.css +0 -1
  397. package/out/web/assets/MintDashboard-COw_xol7.js +0 -63
  398. package/out/web/assets/RewindModal-DempuDod.js +0 -1
  399. package/out/web/assets/SettingsWindow-2YP3yj7s.js +0 -4
  400. package/out/web/assets/SettingsWindow-Dz8LQVgD.css +0 -1
  401. package/out/web/assets/StockCard-BDMCe7mx.js +0 -1
  402. package/out/web/assets/ToolSurfacePage-B0J_q0Jl.js +0 -38
  403. package/out/web/assets/ToolSurfacePage-CRIQ1owD.css +0 -1
  404. package/out/web/assets/UiMockupWidget-DD73QWg1.js +0 -1
  405. package/out/web/assets/WeatherCard-CPucIfq8.js +0 -1
  406. package/out/web/assets/WorkspacePdfPreview-Dx_lkjNu.js +0 -2
  407. package/out/web/assets/classDiagram-ZZMXUADV-BgJ5WtSp.js +0 -1
  408. package/out/web/assets/classDiagram-v2-VYDZK3BY-BgJ5WtSp.js +0 -1
  409. package/out/web/assets/config-CvIO5hkn.js +0 -2
  410. package/out/web/assets/flowDiagram-HODETNUW-uqCHJond.js +0 -1
  411. package/out/web/assets/index-BmpulIkg.js +0 -168
  412. package/out/web/assets/index-CkvBwhX_.css +0 -1
  413. package/out/web/assets/stateDiagram-v2-MP3YSRHH-uf3kdNW4.js +0 -1
  414. package/out/web/assets/swimlanesDiagram-VR7AAH4N-Y8q5bQce.js +0 -8
  415. package/shared-modules/libsecret/libsecret.json +0 -23
  416. package/shared-modules/libusb/libusb.json +0 -27
  417. package/shared-modules/lzo/lzo.json +0 -27
  418. package/src/renderer/src/components/BrowserShell.tsx +0 -108
  419. package/src/renderer/src/components/BrowserSuggestionsPopup.tsx +0 -91
  420. package/src/renderer/src/components/browser-shell.css +0 -185
  421. package/src-tauri/src/native/browser.rs +0 -252
@@ -30,7 +30,7 @@ function ImageTile({ image }: { image: ImageSearchHit }) {
30
30
  display: 'flex',
31
31
  flex: '0 0 116px',
32
32
  flexDirection: 'column',
33
- borderRadius: '10px',
33
+ borderRadius: 'var(--radius-md, 10px)',
34
34
  overflow: 'hidden',
35
35
  background: 'var(--surface-strong)',
36
36
  border: '1px solid var(--border)',
@@ -93,7 +93,7 @@ export default function ImageSearchCard({ data }: { data: ImageSearchData }) {
93
93
  style={{
94
94
  background: cardBg,
95
95
  color: cardText,
96
- borderRadius: '12px',
96
+ borderRadius: 'var(--radius-xl, 18px)',
97
97
  padding: '16px 20px',
98
98
  margin: '12px 0',
99
99
  boxShadow: 'var(--shadow-md)',
@@ -210,7 +210,7 @@ export default function MermaidCard({ code }: { code: string }) {
210
210
  style={{
211
211
  background: 'var(--bg-surface-soft)',
212
212
  color: 'var(--text-primary)',
213
- borderRadius: '12px',
213
+ borderRadius: 'var(--radius-xl, 18px)',
214
214
  padding: '16px 20px',
215
215
  margin: '12px 0',
216
216
  boxShadow: 'var(--shadow-md)',
@@ -0,0 +1,41 @@
1
+ import { describe, expect, it } from 'vitest'
2
+ import React from 'react'
3
+ import { renderToStaticMarkup } from 'react-dom/server'
4
+ import { PlanCard } from './PlanCard'
5
+ import { extractToolCardPayloads } from './ToolResultCards'
6
+ import type { AgentProgress } from '../../types'
7
+
8
+ describe('PlanCard and ToolResultCards plan extraction', () => {
9
+ it('extracts planData from exit_plan_mode ToolEnd event', () => {
10
+ const progress: AgentProgress[] = [
11
+ {
12
+ type: 'ToolEnd',
13
+ data: {
14
+ action: 'exit_plan_mode',
15
+ input: { plan: '## Implementation Plan\n1. Step one\n2. Step two' },
16
+ result: 'Plan approved by user',
17
+ },
18
+ },
19
+ ]
20
+
21
+ const payloads = extractToolCardPayloads(progress, 'Proceeding with the implementation.')
22
+ expect(payloads.planData).toBe('## Implementation Plan\n1. Step one\n2. Step two')
23
+ })
24
+
25
+ it('renders PlanCard with Proposed Plan title, Plan badge, and markdown content', () => {
26
+ const sample = '## Objectives\n- [ ] Task 1: Initialize\n- [x] Task 2: Complete'
27
+ const html = renderToStaticMarkup(<PlanCard plan={sample} />)
28
+
29
+ expect(html).toContain('Proposed Plan')
30
+ expect(html).toContain('approval-badge-chip plan')
31
+ expect(html).toContain('Plan')
32
+ expect(html).toContain('Objectives')
33
+ expect(html).toContain('Task 1: Initialize')
34
+ expect(html).toContain('Task 2: Complete')
35
+ })
36
+
37
+ it('returns null if plan is empty', () => {
38
+ const html = renderToStaticMarkup(<PlanCard plan=" " />)
39
+ expect(html).toBe('')
40
+ })
41
+ })
@@ -0,0 +1,32 @@
1
+ import React, { memo } from 'react'
2
+ import { FormattedMessage } from '../../utils/markdown'
3
+
4
+ export interface PlanCardProps {
5
+ plan: string
6
+ }
7
+
8
+ export const PlanCard = memo(function PlanCard({ plan }: PlanCardProps) {
9
+ if (!plan || !plan.trim()) return null
10
+
11
+ return (
12
+ <div
13
+ className="action-card approval-card plan-inline-card"
14
+ style={{ width: '100%', alignItems: 'stretch', textAlign: 'left', marginBottom: '12px' }}
15
+ >
16
+ <div className="approval-card-header" style={{ width: '100%', textAlign: 'left' }}>
17
+ <div className="approval-title-group" style={{ textAlign: 'left' }}>
18
+ <div className="approval-title-text" style={{ textAlign: 'left' }}>Proposed Plan</div>
19
+ </div>
20
+ <span className="approval-badge-chip plan">
21
+ Plan
22
+ </span>
23
+ </div>
24
+
25
+ <div className="approval-content-box plan-review-content" style={{ maxHeight: '420px', overflowY: 'auto' }}>
26
+ <FormattedMessage text={plan.trim()} />
27
+ </div>
28
+ </div>
29
+ )
30
+ })
31
+
32
+ export default PlanCard
@@ -0,0 +1,29 @@
1
+ import { describe, it, expect } from 'vitest'
2
+ import React from 'react'
3
+ import { renderToStaticMarkup } from 'react-dom/server'
4
+ import { ReleaseNotesCard } from './ReleaseNotesCard'
5
+ import { renderFormattedMessage } from '../../utils/markdown'
6
+
7
+ describe('ReleaseNotesCard', () => {
8
+ it('renders release notes with framed card, version badge, and sections', () => {
9
+ const sample = `# Release Notes - Mint Agent v1.18.0\n\n## Smart Thinking\n- **Safe Non-Text Filter**: Excludes media\n- **Unrestricted**: All models`
10
+ const html = renderToStaticMarkup(<ReleaseNotesCard markdown={sample} />)
11
+
12
+ expect(html).toContain('release-notes-card')
13
+ expect(html).toContain('v1.18.0')
14
+ expect(html).toContain('Release Notes')
15
+ expect(html).toContain('Smart Thinking')
16
+ expect(html).toContain('Safe Non-Text Filter')
17
+ expect(html).toContain('Excludes media')
18
+ })
19
+
20
+ it('renders through renderFormattedMessage seamlessly', () => {
21
+ const sample = `# Release Notes - Mint Agent v1.18.0\n\n## UI Ergonomics\n- **Code Blocks**: Clean copying`
22
+ const node = renderFormattedMessage(sample)
23
+ const html = renderToStaticMarkup(<>{node}</>)
24
+
25
+ expect(html).toContain('release-notes-card')
26
+ expect(html).toContain('UI Ergonomics')
27
+ expect(html).toContain('Clean copying')
28
+ })
29
+ })
@@ -0,0 +1,137 @@
1
+ import React, { useMemo } from 'react'
2
+ import { Rocket } from 'lucide-react'
3
+
4
+ export interface ReleaseNotesCardProps {
5
+ markdown: string
6
+ }
7
+
8
+ interface ReleaseSection {
9
+ title: string
10
+ items: { title: string; desc: string; subItems?: string[] }[]
11
+ }
12
+
13
+ export function ReleaseNotesCard({ markdown }: ReleaseNotesCardProps) {
14
+ const { version, sections } = useMemo(() => {
15
+ let version = 'Latest'
16
+ const sections: ReleaseSection[] = []
17
+ let currentSection: ReleaseSection | null = null
18
+ let currentItem: { title: string; desc: string; subItems?: string[] } | null = null
19
+
20
+ for (const rawLine of markdown.split('\n')) {
21
+ const line = rawLine.trim()
22
+ if (!line) continue
23
+
24
+ if (line.startsWith('# ')) {
25
+ const vMatch = line.match(/v\d+\.\d+(?:\.\d+)?/i)
26
+ if (vMatch) version = vMatch[0]
27
+ continue
28
+ }
29
+
30
+ if (line.startsWith('## ')) {
31
+ if (currentItem && currentSection) {
32
+ currentSection.items.push(currentItem)
33
+ currentItem = null
34
+ }
35
+ if (currentSection) {
36
+ sections.push(currentSection)
37
+ }
38
+ currentSection = {
39
+ title: line.replace(/^##\s+/, '').trim(),
40
+ items: [],
41
+ }
42
+ continue
43
+ }
44
+
45
+ const indent = rawLine.length - rawLine.trimStart().length
46
+ if (line.startsWith('- ') || line.startsWith('* ')) {
47
+ const content = line.slice(2).trim()
48
+ if (indent >= 2 && currentItem) {
49
+ if (!currentItem.subItems) currentItem.subItems = []
50
+ currentItem.subItems.push(content)
51
+ continue
52
+ }
53
+ if (currentItem && currentSection) {
54
+ currentSection.items.push(currentItem)
55
+ }
56
+ const boldMatch = content.match(/^\*\*([^*]+)\*\*:\s*(.*)$/)
57
+ if (boldMatch) {
58
+ currentItem = {
59
+ title: boldMatch[1],
60
+ desc: boldMatch[2],
61
+ }
62
+ } else {
63
+ currentItem = {
64
+ title: '',
65
+ desc: content,
66
+ }
67
+ }
68
+ continue
69
+ }
70
+
71
+ if (currentItem) {
72
+ currentItem.desc += ' ' + line
73
+ }
74
+ }
75
+
76
+ if (currentItem && currentSection) {
77
+ currentSection.items.push(currentItem)
78
+ }
79
+ if (currentSection) {
80
+ sections.push(currentSection)
81
+ }
82
+
83
+ return { version, sections }
84
+ }, [markdown])
85
+
86
+ return (
87
+ <div className="release-notes-card">
88
+ <div className="release-notes-header">
89
+ <div className="release-notes-title">
90
+ <Rocket size={18} className="release-notes-icon" />
91
+ <span>Release Notes</span>
92
+ <span className="release-notes-version-badge">{version}</span>
93
+ </div>
94
+ <span className="release-notes-count-badge">
95
+ {sections.length} Highlights
96
+ </span>
97
+ </div>
98
+ <div className="release-notes-track">
99
+ <div className="release-notes-bar" />
100
+ </div>
101
+ <div className="release-notes-body">
102
+ {sections.map((section, sIdx) => (
103
+ <div key={sIdx} className="release-notes-section">
104
+ <div className="release-notes-section-title">
105
+ <span className="release-notes-bullet">●</span>
106
+ <span>{section.title}</span>
107
+ </div>
108
+ <div className="release-notes-items">
109
+ {section.items.map((item, iIdx) => (
110
+ <div key={iIdx} className="release-notes-item">
111
+ <div className="release-notes-item-header">
112
+ <span className="release-notes-item-bullet">•</span>
113
+ {item.title ? (
114
+ <span className="release-notes-item-title">{item.title}:</span>
115
+ ) : null}
116
+ <span className="release-notes-item-desc">{item.desc}</span>
117
+ </div>
118
+ {item.subItems && item.subItems.length > 0 && (
119
+ <div className="release-notes-subitems">
120
+ {item.subItems.map((sub, subIdx) => (
121
+ <div key={subIdx} className="release-notes-subitem">
122
+ <span className="release-notes-subitem-bullet">›</span>
123
+ <span>{sub.replace(/\*\*/g, '')}</span>
124
+ </div>
125
+ ))}
126
+ </div>
127
+ )}
128
+ </div>
129
+ ))}
130
+ </div>
131
+ </div>
132
+ ))}
133
+ </div>
134
+ </div>
135
+ )
136
+ }
137
+ export default ReleaseNotesCard
@@ -60,7 +60,7 @@ export default function StockCard({ data }: { data: StockData }) {
60
60
  style={{
61
61
  background: t.cardBg,
62
62
  color: t.cardText,
63
- borderRadius: '12px',
63
+ borderRadius: 'var(--radius-xl, 18px)',
64
64
  padding: '16px 20px',
65
65
  margin: '12px 0',
66
66
  boxShadow: t.cardShadow,
@@ -80,7 +80,7 @@ export default function StockCard({ data }: { data: StockData }) {
80
80
  fontSize: '11px',
81
81
  fontWeight: 700,
82
82
  padding: '2px 6px',
83
- borderRadius: '4px',
83
+ borderRadius: 'var(--radius-2xs, 4px)',
84
84
  background: t.tagBg,
85
85
  color: t.tagColor,
86
86
  textTransform: 'none',
@@ -98,7 +98,7 @@ export default function StockCard({ data }: { data: StockData }) {
98
98
  background: isPositive ? 'rgba(16, 185, 129, 0.12)' : 'rgba(239, 68, 68, 0.12)',
99
99
  border: `1px solid ${isPositive ? 'rgba(16, 185, 129, 0.3)' : 'rgba(239, 68, 68, 0.3)'}`,
100
100
  padding: '4px 10px',
101
- borderRadius: '20px',
101
+ borderRadius: 'var(--radius-full, 9999px)',
102
102
  display: 'flex',
103
103
  alignItems: 'center',
104
104
  gap: '4px',
@@ -123,26 +123,26 @@ export default function StockCard({ data }: { data: StockData }) {
123
123
 
124
124
  {/* Stats Grid */}
125
125
  <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: '8px' }}>
126
- <div style={{ background: t.statBg, borderRadius: '8px', padding: '8px 10px', border: `1px solid ${t.statBorder}` }}>
126
+ <div style={{ background: t.statBg, borderRadius: 'var(--radius-sm, 8px)', padding: '8px 10px', border: `1px solid ${t.statBorder}` }}>
127
127
  <p style={{ margin: 0, fontSize: '10px', color: t.statLabel, textTransform: 'none' }}>Day high</p>
128
128
  <p style={{ margin: '2px 0 0', fontSize: '12px', fontWeight: 700, color: t.statValue }}>
129
129
  {data.dayHigh ? `${currencySymbol}${data.dayHigh.toFixed(2)}` : 'N/A'}
130
130
  </p>
131
131
  </div>
132
132
 
133
- <div style={{ background: t.statBg, borderRadius: '8px', padding: '8px 10px', border: `1px solid ${t.statBorder}` }}>
133
+ <div style={{ background: t.statBg, borderRadius: 'var(--radius-sm, 8px)', padding: '8px 10px', border: `1px solid ${t.statBorder}` }}>
134
134
  <p style={{ margin: 0, fontSize: '10px', color: t.statLabel, textTransform: 'none' }}>Day low</p>
135
135
  <p style={{ margin: '2px 0 0', fontSize: '12px', fontWeight: 700, color: t.statValue }}>
136
136
  {data.dayLow ? `${currencySymbol}${data.dayLow.toFixed(2)}` : 'N/A'}
137
137
  </p>
138
138
  </div>
139
139
 
140
- <div style={{ background: t.statBg, borderRadius: '8px', padding: '8px 10px', border: `1px solid ${t.statBorder}` }}>
140
+ <div style={{ background: t.statBg, borderRadius: 'var(--radius-sm, 8px)', padding: '8px 10px', border: `1px solid ${t.statBorder}` }}>
141
141
  <p style={{ margin: 0, fontSize: '10px', color: t.statLabel, textTransform: 'none' }}>Market cap</p>
142
142
  <p style={{ margin: '2px 0 0', fontSize: '12px', fontWeight: 700, color: t.statValue }}>{formatLargeNum(data.marketCap)}</p>
143
143
  </div>
144
144
 
145
- <div style={{ background: t.statBg, borderRadius: '8px', padding: '8px 10px', border: `1px solid ${t.statBorder}` }}>
145
+ <div style={{ background: t.statBg, borderRadius: 'var(--radius-sm, 8px)', padding: '8px 10px', border: `1px solid ${t.statBorder}` }}>
146
146
  <p style={{ margin: 0, fontSize: '10px', color: t.statLabel, textTransform: 'none' }}>Volume</p>
147
147
  <p style={{ margin: '2px 0 0', fontSize: '12px', fontWeight: 700, color: t.statValue }}>{formatLargeNum(data.volume)}</p>
148
148
  </div>
@@ -6,6 +6,7 @@ const StockCard = lazy(() => import('./StockCard'))
6
6
  const CalculationCard = lazy(() => import('./CalculationCard'))
7
7
  const ImageSearchCard = lazy(() => import('./ImageSearchCard'))
8
8
  const ImageGenCard = lazy(() => import('./ImageGenCard'))
9
+ const PlanCard = lazy(() => import('./PlanCard'))
9
10
 
10
11
  export interface ToolResultCardsProps {
11
12
  progress?: AgentProgress[]
@@ -41,6 +42,7 @@ export function extractToolCardPayloads(progress?: AgentProgress[], aiText?: str
41
42
  let calcData: any = null
42
43
  let imageSearchData: any = null
43
44
  let imageGenData: any = null
45
+ let planData: string | null = null
44
46
 
45
47
  for (const event of progress || []) {
46
48
  if (event.type !== 'ToolEnd') continue
@@ -56,24 +58,30 @@ export function extractToolCardPayloads(progress?: AgentProgress[], aiText?: str
56
58
  imageSearchData = parseMatchedJson(res, IMAGE_SEARCH_RE)
57
59
  } else if (!skipImageGen && !imageGenData && IMAGE_GEN_ACTIONS.has(actionName)) {
58
60
  imageGenData = parseMatchedJson(res, IMAGE_GEN_RE)
61
+ } else if (!planData && actionName === 'exit_plan_mode') {
62
+ const raw = (event.data?.input as any)?.plan || (event.data as any)?.plan
63
+ if (typeof raw === 'string' && raw.trim()) {
64
+ planData = raw.trim()
65
+ }
59
66
  }
60
67
  }
61
68
 
62
- return { weatherData, stockData, calcData, imageSearchData, imageGenData }
69
+ return { weatherData, stockData, calcData, imageSearchData, imageGenData, planData }
63
70
  }
64
71
 
65
72
  export const ToolResultCards = memo(function ToolResultCards({ progress, aiText }: ToolResultCardsProps) {
66
- const { weatherData, stockData, calcData, imageSearchData, imageGenData } = useMemo(
73
+ const { weatherData, stockData, calcData, imageSearchData, imageGenData, planData } = useMemo(
67
74
  () => extractToolCardPayloads(progress, aiText),
68
75
  [progress, aiText],
69
76
  )
70
77
 
71
- if (!weatherData && !stockData && !calcData && !imageSearchData && !imageGenData) {
78
+ if (!weatherData && !stockData && !calcData && !imageSearchData && !imageGenData && !planData) {
72
79
  return null
73
80
  }
74
81
 
75
82
  return (
76
83
  <Suspense fallback={null}>
84
+ {planData && <PlanCard plan={planData} />}
77
85
  {weatherData && <WeatherCard data={weatherData} />}
78
86
  {stockData && <StockCard data={stockData} />}
79
87
  {calcData && <CalculationCard data={calcData} />}
@@ -30,11 +30,11 @@ export default function UiMockupWidget({ data }: { data: UiMockupData }) {
30
30
 
31
31
  const title = data.title || 'App Preview'
32
32
  const subtitle = data.subtitle
33
- const dropzoneText = data.dropzoneText || 'ลากไฟล์มาวางที่นี่'
34
- const dropzoneHint = data.dropzoneHint || 'หรือเลือกไฟล์จากอุปกรณ์ของคุณ'
35
- const buttonText = data.buttonText || 'เลือกไฟล์'
33
+ const dropzoneText = data.dropzoneText || 'Drag files here'
34
+ const dropzoneHint = data.dropzoneHint || 'or choose files from your device'
35
+ const buttonText = data.buttonText || 'Choose file'
36
36
  const disclaimer =
37
- data.disclaimer || 'ตัวอย่างแนวคิด UI เท่านั้น ยังไม่ใช่เครื่องมือที่ประมวลผลไฟล์ได้จริง'
37
+ data.disclaimer || 'UI mockup preview only, not a live file processor'
38
38
 
39
39
  // Options state
40
40
  let initialOptions: Array<{ label: string; current: string; choices: string[] }> = []
@@ -94,7 +94,7 @@ export default function WeatherCard({ data }: { data: WeatherData }) {
94
94
  style={{
95
95
  background: weatherInfo.gradient,
96
96
  color: '#ffffff',
97
- borderRadius: '12px',
97
+ borderRadius: 'var(--radius-xl, 18px)',
98
98
  padding: '16px 20px',
99
99
  margin: '12px 0',
100
100
  boxShadow: '0 10px 25px -5px rgba(0, 0, 0, 0.4)',
@@ -161,7 +161,7 @@ export default function WeatherCard({ data }: { data: WeatherData }) {
161
161
  alignItems: 'center',
162
162
  background: 'rgba(255, 255, 255, 0.12)',
163
163
  backdropFilter: 'blur(4px)',
164
- borderRadius: '8px',
164
+ borderRadius: 'var(--radius-sm, 8px)',
165
165
  padding: '8px 4px',
166
166
  }}
167
167
  >
@@ -187,7 +187,7 @@ export default function WeatherCard({ data }: { data: WeatherData }) {
187
187
  style={{
188
188
  background: 'rgba(255, 255, 255, 0.12)',
189
189
  backdropFilter: 'blur(4px)',
190
- borderRadius: '8px',
190
+ borderRadius: 'var(--radius-sm, 8px)',
191
191
  padding: '8px 10px',
192
192
  }}
193
193
  >
@@ -199,7 +199,7 @@ export default function WeatherCard({ data }: { data: WeatherData }) {
199
199
  style={{
200
200
  background: 'rgba(255, 255, 255, 0.12)',
201
201
  backdropFilter: 'blur(4px)',
202
- borderRadius: '8px',
202
+ borderRadius: 'var(--radius-sm, 8px)',
203
203
  padding: '8px 10px',
204
204
  }}
205
205
  >
@@ -211,7 +211,7 @@ export default function WeatherCard({ data }: { data: WeatherData }) {
211
211
  style={{
212
212
  background: 'rgba(255, 255, 255, 0.12)',
213
213
  backdropFilter: 'blur(4px)',
214
- borderRadius: '8px',
214
+ borderRadius: 'var(--radius-sm, 8px)',
215
215
  padding: '8px 10px',
216
216
  }}
217
217
  >
@@ -21,4 +21,15 @@ describe('skill approval', () => {
21
21
  expect(html).toContain('Reject')
22
22
  expect(html).not.toContain('Always allow for this session')
23
23
  })
24
+
25
+ it('renders plan review card with markdown body and approve/deny actions', () => {
26
+ const html = renderToStaticMarkup(<ApprovalCard
27
+ pendingApproval={{ approval: { ExitPlanMode: { plan: '## Implementation Steps\n- [ ] Step 1\n- [x] Step 2' } } }}
28
+ onApproval={() => {}}
29
+ />)
30
+ expect(html).toContain('Plan Review')
31
+ expect(html).toContain('Approve and proceed')
32
+ expect(html).toContain('Deny (keep planning)')
33
+ expect(html).not.toContain('Always allow for this session')
34
+ })
24
35
  })
@@ -5,6 +5,7 @@
5
5
  */
6
6
  import React, { useState, useEffect } from 'react'
7
7
  import { renderApprovalDetails, renderDiff } from '../../utils/approval'
8
+ import { FormattedMessage } from '../../utils/markdown'
8
9
  import { DiffReviewModal } from './DiffReviewModal'
9
10
 
10
11
  interface Props {
@@ -32,6 +33,8 @@ export function ApprovalCard({ pendingApproval, onApproval }: Props) {
32
33
  const targetFilePath = skillWrite?.path || writeFile?.path || applyPatch?.path || 'Code Change'
33
34
  const diffText = skillWrite?.diff || writeFile?.diff || applyPatch?.diff
34
35
  const isAskUser = !!pendingApproval.approval?.AskUser
36
+ const isExitPlan = !!pendingApproval.approval?.ExitPlanMode
37
+ const isEnterPlan = !!pendingApproval.approval?.EnterPlanMode
35
38
  const mcpTool = pendingApproval.approval?.McpTool
36
39
  const MCP_ALLOW_ALL_SENTINEL = '__mcp_allow_all__'
37
40
  const askOptions: AskUserOption[] = Array.isArray(pendingApproval.approval?.AskUser?.options)
@@ -58,6 +61,8 @@ export function ApprovalCard({ pendingApproval, onApproval }: Props) {
58
61
 
59
62
  // Get badge label based on action type
60
63
  const getToolMeta = () => {
64
+ if (isExitPlan) return { badge: 'Plan Review', badgeClass: 'plan' }
65
+ if (isEnterPlan) return { badge: 'Plan Mode', badgeClass: 'plan' }
61
66
  if (skillWrite) return { badge: 'Skill Change', badgeClass: 'edit' }
62
67
  if (runShell) return { badge: 'Run Command', badgeClass: details.isDangerous ? 'dangerous' : 'command' }
63
68
  if (writeFile || applyPatch) return { badge: 'File Edit', badgeClass: 'edit' }
@@ -95,6 +100,16 @@ export function ApprovalCard({ pendingApproval, onApproval }: Props) {
95
100
  action: () => onApproval(false),
96
101
  },
97
102
  ]
103
+ : isExitPlan
104
+ ? [
105
+ { key: '1', title: 'Approve and proceed', variant: 'approve', action: () => onApproval(true, false) },
106
+ { key: '2', title: 'Deny (keep planning)', variant: 'cancel', action: () => onApproval(false) },
107
+ ]
108
+ : isEnterPlan
109
+ ? [
110
+ { key: '1', title: 'Enter plan mode', variant: 'approve', action: () => onApproval(true, false) },
111
+ { key: '2', title: 'Cancel', variant: 'cancel', action: () => onApproval(false) },
112
+ ]
98
113
  : [
99
114
  {
100
115
  key: '1',
@@ -181,7 +196,7 @@ export function ApprovalCard({ pendingApproval, onApproval }: Props) {
181
196
  gap: 6,
182
197
  padding: '4px 10px',
183
198
  fontSize: '0.75rem',
184
- borderRadius: '8px',
199
+ borderRadius: 'var(--radius-sm, 8px)',
185
200
  background: 'var(--accent-subtle)',
186
201
  border: '1px solid var(--accent-border)',
187
202
  color: 'var(--interactive-fg)',
@@ -193,6 +208,10 @@ export function ApprovalCard({ pendingApproval, onApproval }: Props) {
193
208
  </div>
194
209
  {renderDiff(diffText)}
195
210
  </div>
211
+ ) : isExitPlan ? (
212
+ <div className="approval-content-box plan-review-content" style={{ maxHeight: '360px', overflowY: 'auto' }}>
213
+ <FormattedMessage text={details.body} />
214
+ </div>
196
215
  ) : (
197
216
  <div className={`approval-content-box ${isAskUser ? 'question-text' : ''}`}>
198
217
  {details.body}
@@ -273,7 +292,7 @@ export function ApprovalCard({ pendingApproval, onApproval }: Props) {
273
292
  <button
274
293
  type="button"
275
294
  className="approval-btn approval-btn-approve"
276
- style={{ whiteSpace: 'nowrap', padding: '9px 16px', borderRadius: '8px' }}
295
+ style={{ whiteSpace: 'nowrap', padding: '9px 16px', borderRadius: 'var(--radius-sm, 8px)' }}
277
296
  disabled={isMultiSelect ? selectedOptions.size === 0 && !askAnswer.trim() : !askAnswer.trim()}
278
297
  onClick={() =>
279
298
  onApproval(true, false, isMultiSelect ? buildMultiSelectAnswer() : askAnswer.trim())
@@ -0,0 +1,69 @@
1
+ /// <reference path="../../env.d.ts" />
2
+ import { describe, it, expect, vi } from 'vitest'
3
+ // @ts-ignore react-dom/server lacks types without @types/react-dom
4
+ import { renderToStaticMarkup } from 'react-dom/server'
5
+ import React from 'react'
6
+ import { ArtifactCards, extractArtifacts } from './ArtifactCards'
7
+
8
+ describe('ArtifactCards', () => {
9
+ it('extracts pdf and pptx files explicitly mentioned in aiText and converts to workspace-relative path', () => {
10
+ const aiText = 'ไฟล์สไลด์: `/home/pheem49/vscode/Project/Demo/AI_and_CLI_Presentation.pdf` และ `slides.pptx` รวมถึง `index.html`'
11
+ const artifacts = extractArtifacts([], aiText, '/home/pheem49/vscode/Project/Demo')
12
+ // Only PDF and PPTX, index.html must be ignored
13
+ expect(artifacts.length).toBe(2)
14
+ // AI_and_CLI_Presentation.pdf should have relative path
15
+ const pdf = artifacts.find(a => a.name === 'AI_and_CLI_Presentation.pdf')
16
+ expect(pdf).toBeDefined()
17
+ expect(pdf?.path).toBe('AI_and_CLI_Presentation.pdf')
18
+ expect(pdf?.type).toBe('pdf')
19
+
20
+ const pptx = artifacts.find(a => a.name === 'slides.pptx')
21
+ expect(pptx).toBeDefined()
22
+ expect(pptx?.type).toBe('presentation')
23
+ })
24
+
25
+ it('does not extract random files from terminal ls or shell output', () => {
26
+ const progress: any[] = [
27
+ {
28
+ type: 'ToolEnd',
29
+ data: {
30
+ action: 'run_shell',
31
+ input: { command: 'ls -la' },
32
+ result: 'file1.pdf file2.pdf old_presentation.pdf',
33
+ },
34
+ },
35
+ ]
36
+ // If aiText doesn't mention them, no cards are created
37
+ const artifacts = extractArtifacts(progress, 'ฉันได้ตรวจสอบโฟลเดอร์เรียบร้อยแล้วค่ะ', '/home/user')
38
+ expect(artifacts.length).toBe(0)
39
+ })
40
+
41
+ it('renders card with relative file path and Open in Side Panel button', () => {
42
+ const onOpenArtifact = vi.fn()
43
+ const aiText = 'สร้างไฟล์เสร็จแล้ว: `/home/user/workspace/presentation.pdf`'
44
+ const html = renderToStaticMarkup(
45
+ <ArtifactCards
46
+ aiText={aiText}
47
+ workspacePath="/home/user/workspace"
48
+ onOpenArtifact={onOpenArtifact}
49
+ />
50
+ )
51
+
52
+ expect(html).toContain('presentation.pdf')
53
+ expect(html).toContain('PDF')
54
+ expect(html).toContain('Open in Side Panel')
55
+ })
56
+
57
+ it('renders cards with draggable attribute so users can drag into chat', () => {
58
+ const aiText = 'ไฟล์สไลด์: `presentation.pdf`'
59
+ const html = renderToStaticMarkup(
60
+ <ArtifactCards
61
+ aiText={aiText}
62
+ workspacePath="/home/user/workspace"
63
+ onOpenArtifact={() => {}}
64
+ />
65
+ )
66
+ expect(html).toMatch(/class="chat-artifact-card[^"]*"[^>]*draggable="true"/)
67
+ expect(html).toContain('width:100%')
68
+ })
69
+ })