@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
@@ -0,0 +1,122 @@
1
+ import React from 'react'
2
+ import { renderToStaticMarkup } from 'react-dom/server'
3
+ import { describe, expect, it } from 'vitest'
4
+ import { AskUserActivityCard } from './AskUserActivityCard'
5
+ import { AgentActivityTable } from './AgentActivityTable'
6
+ import { activitiesFrom } from '../../utils/agentActivity'
7
+
8
+ describe('AskUserActivityCard', () => {
9
+ it('returns null when questions list is empty', () => {
10
+ const html = renderToStaticMarkup(<AskUserActivityCard questions={[]} />)
11
+ expect(html).toBe('')
12
+ })
13
+
14
+ it('renders single question card with "1 question" header and answer', () => {
15
+ const html = renderToStaticMarkup(
16
+ <AskUserActivityCard
17
+ questions={[
18
+ {
19
+ question: 'Which framework should we use?',
20
+ answer: 'React + TypeScript',
21
+ },
22
+ ]}
23
+ />,
24
+ )
25
+
26
+ expect(html).toContain('1 question')
27
+ expect(html).toContain('Which framework should we use?')
28
+ expect(html).toContain('React + TypeScript')
29
+ expect(html).toContain('modern-ask-user-card')
30
+ expect(html).toContain('modern-ask-user-header')
31
+ })
32
+
33
+ it('renders multi-question card matching user design with "3 questions"', () => {
34
+ const html = renderToStaticMarkup(
35
+ <AskUserActivityCard
36
+ questions={[
37
+ {
38
+ question: 'คุณต้องการใช้ภาษาและเทคโนโลยีใดในการสร้าง MCP Server (Hardware Tooling)?',
39
+ answer: '(Recommended) Python (ใช้ FastMCP / mcp SDK + pyserial + psutil) — พัฒนาไวและมีไลบรารีฮาร์ดแวร์/OS ครบครัน',
40
+ },
41
+ {
42
+ question: 'คุณต้องการให้สร้างโมดูลใดบ้างในเวอร์ชันแรกนี้?',
43
+ answer: 'USB / Serial Bridge, Hardware Flashing & Toolchains, Process & Port Management',
44
+ },
45
+ {
46
+ question: 'สำหรับฝั่ง Toolchain & Flashing คุณใช้งานเครื่องมือตัวไหนเป็นหลัก?',
47
+ answer: 'Arduino CLI (arduino-cli), PlatformIO (pio), ESP-IDF / esptool',
48
+ },
49
+ ]}
50
+ />,
51
+ )
52
+
53
+ expect(html).toContain('3 questions')
54
+ expect(html).toContain('คุณต้องการใช้ภาษาและเทคโนโลยีใดในการสร้าง MCP Server')
55
+ expect(html).toContain('(Recommended) Python')
56
+ expect(html).toContain('คุณต้องการให้สร้างโมดูลใดบ้างในเวอร์ชันแรกนี้?')
57
+ expect(html).toContain('USB / Serial Bridge')
58
+ expect(html).toContain('Toolchain')
59
+ expect(html).toContain('Flashing คุณใช้งานเครื่องมือตัวไหนเป็นหลัก?')
60
+ expect(html).toContain('Arduino CLI')
61
+ })
62
+
63
+ it('renders optional header in headerText if specified', () => {
64
+ const html = renderToStaticMarkup(
65
+ <AskUserActivityCard
66
+ header="MCP Config"
67
+ questions={[
68
+ {
69
+ question: 'Port number?',
70
+ answer: '3000',
71
+ },
72
+ ]}
73
+ />,
74
+ )
75
+
76
+ expect(html).toContain('1 question · MCP Config')
77
+ expect(html).toContain('Port number?')
78
+ expect(html).toContain('3000')
79
+ })
80
+
81
+ it('renders within AgentActivityTable when activity is answered (done)', () => {
82
+ const view = activitiesFrom([
83
+ {
84
+ type: 'ToolStart',
85
+ data: {
86
+ action: 'ask_user',
87
+ input: { query: 'Which model should be used?' },
88
+ },
89
+ },
90
+ {
91
+ type: 'ToolEnd',
92
+ data: {
93
+ action: 'ask_user',
94
+ result: 'User answered: Gemini 2.5 Pro',
95
+ },
96
+ },
97
+ ])
98
+
99
+ const html = renderToStaticMarkup(<AgentActivityTable activityView={view} />)
100
+ expect(html).toContain('modern-ask-user-card')
101
+ expect(html).toContain('1 question')
102
+ expect(html).toContain('Which model should be used?')
103
+ expect(html).toContain('Gemini 2.5 Pro')
104
+ })
105
+
106
+ it('renders standard active item while ask_user is waiting to be answered', () => {
107
+ const view = activitiesFrom([
108
+ {
109
+ type: 'ToolStart',
110
+ data: {
111
+ action: 'ask_user',
112
+ input: { query: 'Waiting for your answer...' },
113
+ },
114
+ },
115
+ ])
116
+
117
+ const html = renderToStaticMarkup(<AgentActivityTable activityView={view} />)
118
+ expect(html).not.toContain('modern-ask-user-card')
119
+ expect(html).toContain('Asked')
120
+ expect(html).toContain('Waiting for your answer...')
121
+ })
122
+ })
@@ -0,0 +1,70 @@
1
+ /**
2
+ * shared/components/activity/AskUserActivityCard.tsx
3
+ * Sleek questions & answers card rendered in the agent activity timeline after
4
+ * the user has answered an ask_user prompt.
5
+ * Shared across Desktop and Web — do NOT duplicate.
6
+ */
7
+ import React, { memo } from 'react'
8
+ import type { AskUserItem } from '../../utils/agentActivity'
9
+ import { renderFormattedMessage } from '../../utils/markdown'
10
+
11
+ export interface AskUserActivityCardProps {
12
+ questions: AskUserItem[]
13
+ header?: string
14
+ className?: string
15
+ }
16
+
17
+ export const AskUserActivityCard = memo(function AskUserActivityCard({
18
+ questions,
19
+ header,
20
+ className,
21
+ }: AskUserActivityCardProps) {
22
+ if (!questions || questions.length === 0) return null
23
+
24
+ const count = questions.length
25
+ const countLabel = count === 1 ? '1 question' : `${count} questions`
26
+ const headerText = header ? `${countLabel} · ${header}` : countLabel
27
+
28
+ return (
29
+ <div
30
+ className={`modern-ask-user-card ${className || ''}`.trim()}
31
+ data-testid="ask-user-activity-card"
32
+ >
33
+ <div className="modern-ask-user-header">
34
+ <span className="modern-ask-user-header-icon" aria-hidden="true">
35
+ <svg
36
+ width="14"
37
+ height="14"
38
+ viewBox="0 0 24 24"
39
+ fill="none"
40
+ stroke="currentColor"
41
+ strokeWidth="2"
42
+ strokeLinecap="round"
43
+ strokeLinejoin="round"
44
+ className="modern-ask-user-icon"
45
+ >
46
+ <rect x="3" y="3" width="18" height="18" rx="4" />
47
+ <path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3" />
48
+ <line x1="12" y1="17" x2="12.01" y2="17" strokeWidth="2.5" />
49
+ </svg>
50
+ </span>
51
+ <span className="modern-ask-user-header-text">{headerText}</span>
52
+ </div>
53
+
54
+ <div className="modern-ask-user-items">
55
+ {questions.map((item, index) => (
56
+ <div key={index} className="modern-ask-user-item">
57
+ <div className="modern-ask-user-question">
58
+ {renderFormattedMessage(item.question) ?? item.question}
59
+ </div>
60
+ {item.answer && (
61
+ <div className="modern-ask-user-answer">
62
+ {renderFormattedMessage(item.answer) ?? item.answer}
63
+ </div>
64
+ )}
65
+ </div>
66
+ ))}
67
+ </div>
68
+ </div>
69
+ )
70
+ })
@@ -46,7 +46,21 @@ function Artifact({ artifact, chatId }: { artifact: McpArtifact; chatId?: string
46
46
  </div>
47
47
  }
48
48
 
49
- export default memo(function McpToolResults({ progress, running = false, interrupted = false, chatId }: { progress: AgentProgress[]; running?: boolean; interrupted?: boolean; chatId?: string }) {
49
+ export interface McpToolResultsProps {
50
+ progress: AgentProgress[]
51
+ running?: boolean
52
+ interrupted?: boolean
53
+ chatId?: string
54
+ mode?: 'full' | 'artifacts-only'
55
+ }
56
+
57
+ export default memo(function McpToolResults({
58
+ progress,
59
+ running = false,
60
+ interrupted = false,
61
+ chatId,
62
+ mode = 'full',
63
+ }: McpToolResultsProps) {
50
64
  const [, tick] = useState(0)
51
65
  const started = useRef(new Map<string, number>())
52
66
  const { calls, discovery, artifacts, warnings } = useMemo(() => {
@@ -86,8 +100,31 @@ export default memo(function McpToolResults({ progress, running = false, interru
86
100
  const timer = setInterval(() => tick(n => n + 1), 1000)
87
101
  return () => clearInterval(timer)
88
102
  }, [hasActiveCalls])
89
- if (!calls.size && !displayedArtifacts.length && !warnings.size && !discovery.size) return null
90
103
  const isOnlyWarnings = !calls.size && !displayedArtifacts.length && !discovery.size && warnings.size > 0
104
+
105
+ if (mode === 'artifacts-only') {
106
+ if (!displayedArtifacts.length && !warnings.size) return null
107
+ const artifactsOnlyWarnings = !displayedArtifacts.length && warnings.size > 0
108
+ return (
109
+ <section className={`mcp-results${artifactsOnlyWarnings ? ' mcp-results-compact' : ''}`} aria-label="MCP results">
110
+ {displayedArtifacts.length > 0 && (
111
+ <div className="mcp-artifacts">
112
+ {displayedArtifacts.map(artifact => (
113
+ <Artifact key={artifact.id} artifact={artifact} chatId={chatId} />
114
+ ))}
115
+ </div>
116
+ )}
117
+ {[...warnings].map(warning => (
118
+ <div key={warning} className="mcp-warning-banner" role="status">
119
+ <Info size={14} className="mcp-warning-icon" aria-hidden="true" />
120
+ <span className="mcp-warning-text">{warning}</span>
121
+ </div>
122
+ ))}
123
+ </section>
124
+ )
125
+ }
126
+
127
+ if (!calls.size && !displayedArtifacts.length && !warnings.size && !discovery.size) return null
91
128
  return <section className={`mcp-results${isOnlyWarnings ? ' mcp-results-compact' : ''}`} aria-label="MCP results">
92
129
  {[...discovery].map(([label,message])=><div key={label} className="mcp-call-status" role="status"><strong>{label}</strong><span>{message}</span></div>)}
93
130
  {[...calls].map(([id, call]) => {
@@ -202,7 +202,7 @@ export function SubagentDagView({ progress, isLive = false }: Props) {
202
202
  alignItems: 'center',
203
203
  gap: '10px',
204
204
  padding: '10px 18px',
205
- borderRadius: '12px',
205
+ borderRadius: 'var(--radius-xl, 18px)',
206
206
  background: 'linear-gradient(135deg, var(--accent-subtle), color-mix(in srgb, var(--status-info, #3b82f6) 15%, transparent))',
207
207
  border: '1px solid var(--accent-border)',
208
208
  boxShadow: 'var(--shadow-md)',
@@ -213,7 +213,7 @@ export function SubagentDagView({ progress, isLive = false }: Props) {
213
213
  style={{
214
214
  width: '32px',
215
215
  height: '32px',
216
- borderRadius: '8px',
216
+ borderRadius: 'var(--radius-sm, 8px)',
217
217
  background: 'var(--accent)',
218
218
  color: 'var(--text-on-accent)',
219
219
  display: 'flex',
@@ -272,7 +272,7 @@ export function SubagentDagView({ progress, isLive = false }: Props) {
272
272
  flexDirection: 'column',
273
273
  width: '260px',
274
274
  padding: '12px',
275
- borderRadius: '10px',
275
+ borderRadius: 'var(--radius-lg, 14px)',
276
276
  background: isSelected ? 'var(--bg-surface-raised)' : 'var(--bg-surface)',
277
277
  border: `1px solid ${isSelected ? statusColor : 'var(--border-default)'}`,
278
278
  cursor: 'pointer',
@@ -298,7 +298,7 @@ export function SubagentDagView({ progress, isLive = false }: Props) {
298
298
  fontSize: '0.68rem',
299
299
  fontWeight: 600,
300
300
  padding: '2px 6px',
301
- borderRadius: '4px',
301
+ borderRadius: 'var(--radius-2xs, 4px)',
302
302
  textTransform: 'none',
303
303
  background: `color-mix(in srgb, ${statusColor} 15%, transparent)`,
304
304
  color: statusColor,
@@ -345,7 +345,7 @@ export function SubagentDagView({ progress, isLive = false }: Props) {
345
345
  style={{
346
346
  background: 'var(--bg-surface-raised)',
347
347
  border: '1px solid var(--border-default)',
348
- borderRadius: '10px',
348
+ borderRadius: 'var(--radius-lg, 14px)',
349
349
  padding: '14px',
350
350
  marginTop: '8px',
351
351
  }}
@@ -379,7 +379,7 @@ export function SubagentDagView({ progress, isLive = false }: Props) {
379
379
  style={{
380
380
  background: 'var(--bg-surface-soft)',
381
381
  border: '1px solid var(--border-subtle)',
382
- borderRadius: '6px',
382
+ borderRadius: 'var(--radius-xs, 6px)',
383
383
  padding: '8px 10px',
384
384
  fontSize: '0.76rem',
385
385
  }}
@@ -395,7 +395,7 @@ export function SubagentDagView({ progress, isLive = false }: Props) {
395
395
  padding: '4px 6px',
396
396
  background: 'var(--bg-canvas)',
397
397
  border: '1px solid var(--border-subtle)',
398
- borderRadius: '4px',
398
+ borderRadius: 'var(--radius-2xs, 4px)',
399
399
  color: 'var(--text-secondary)',
400
400
  fontSize: '0.72rem',
401
401
  overflowX: 'auto',
@@ -3,6 +3,7 @@ import { memo, useEffect, useMemo, useRef, useState } from 'react'
3
3
  import { X } from 'lucide-react'
4
4
  import type { AgentProgress } from '../../types'
5
5
  import { viewedImagesFrom, type ViewedImageItem } from '../../utils/viewedImages'
6
+ import { setWorkspaceDragData } from '../../utils/workspaceDrag'
6
7
  import { mediaPlatform } from '../../platform'
7
8
  import '../../css/viewed-images.css'
8
9
 
@@ -76,8 +77,27 @@ export function ViewedImage({
76
77
  aria-label={`Expand ${image.name}`}
77
78
  title={onOpenArtifact ? 'Open full image in Tools Surface' : `Expand ${image.name}`}
78
79
  onClick={handleOpen}
80
+ draggable
81
+ onDragStart={(event) => {
82
+ setWorkspaceDragData(event.dataTransfer, {
83
+ path: image.path || image.name,
84
+ url: src,
85
+ })
86
+ }}
79
87
  >
80
- <img src={src} alt={`Viewed image: ${image.name}`} loading="lazy" onError={() => setBroken(true)} />
88
+ <img
89
+ src={src}
90
+ alt={`Viewed image: ${image.name}`}
91
+ loading="lazy"
92
+ onError={() => setBroken(true)}
93
+ draggable
94
+ onDragStart={(event) => {
95
+ setWorkspaceDragData(event.dataTransfer, {
96
+ path: image.path || image.name,
97
+ url: src,
98
+ })
99
+ }}
100
+ />
81
101
  <span className="viewed-image-inline-overlay">
82
102
  <span className="viewed-image-inline-badge">{onOpenArtifact ? 'Open in Tools' : 'Click to zoom'}</span>
83
103
  </span>
@@ -110,8 +130,27 @@ export function ViewedImage({
110
130
  aria-label={`Expand ${image.name}`}
111
131
  title={onOpenArtifact ? 'Open full image in Tools Surface' : `Expand ${image.name}`}
112
132
  onClick={handleOpen}
133
+ draggable
134
+ onDragStart={(event) => {
135
+ setWorkspaceDragData(event.dataTransfer, {
136
+ path: image.path || image.name,
137
+ url: src,
138
+ })
139
+ }}
113
140
  >
114
- <img src={src} alt={`Viewed image: ${image.name}`} loading="lazy" onError={() => setBroken(true)} />
141
+ <img
142
+ src={src}
143
+ alt={`Viewed image: ${image.name}`}
144
+ loading="lazy"
145
+ onError={() => setBroken(true)}
146
+ draggable
147
+ onDragStart={(event) => {
148
+ setWorkspaceDragData(event.dataTransfer, {
149
+ path: image.path || image.name,
150
+ url: src,
151
+ })
152
+ }}
153
+ />
115
154
  </button>}
116
155
  <figcaption title={image.path}>{image.name}</figcaption>
117
156
  <dialog ref={dialog} className="viewed-image-dialog" aria-label={`Image preview: ${image.name}`}
@@ -126,7 +126,7 @@ export default class ChunkErrorBoundary extends React.Component<Props, State> {
126
126
  border: 'none',
127
127
  color: 'var(--text-muted, #9ca3af)',
128
128
  cursor: 'pointer',
129
- borderRadius: 4,
129
+ borderRadius: 'var(--radius-2xs, 4px)',
130
130
  display: 'flex',
131
131
  alignItems: 'center',
132
132
  justifyContent: 'center',
@@ -146,7 +146,7 @@ export default class ChunkErrorBoundary extends React.Component<Props, State> {
146
146
  border: 'none',
147
147
  color: 'var(--text-muted, #9ca3af)',
148
148
  cursor: 'pointer',
149
- borderRadius: 4,
149
+ borderRadius: 'var(--radius-2xs, 4px)',
150
150
  display: 'flex',
151
151
  alignItems: 'center',
152
152
  justifyContent: 'center',
@@ -166,7 +166,7 @@ export default class ChunkErrorBoundary extends React.Component<Props, State> {
166
166
  border: 'none',
167
167
  color: 'var(--text-muted, #9ca3af)',
168
168
  cursor: 'pointer',
169
- borderRadius: 4,
169
+ borderRadius: 'var(--radius-2xs, 4px)',
170
170
  display: 'flex',
171
171
  alignItems: 'center',
172
172
  justifyContent: 'center',
@@ -381,7 +381,7 @@ export function CommandPalette({
381
381
  maxWidth: '620px',
382
382
  background: 'var(--bg-overlay)',
383
383
  border: '1px solid var(--border-default)',
384
- borderRadius: '14px',
384
+ borderRadius: 'var(--radius-2xl, 22px)',
385
385
  boxShadow: 'var(--shadow-lg)',
386
386
  overflow: 'hidden',
387
387
  display: 'flex',
@@ -435,7 +435,7 @@ export function CommandPalette({
435
435
  <kbd
436
436
  style={{
437
437
  padding: '2px 7px',
438
- borderRadius: '4px',
438
+ borderRadius: 'var(--radius-2xs, 4px)',
439
439
  background: 'var(--bg-surface-soft)',
440
440
  color: 'var(--text-muted)',
441
441
  fontSize: '0.7rem',
@@ -493,7 +493,7 @@ export function CommandPalette({
493
493
  alignItems: 'center',
494
494
  justifyContent: 'space-between',
495
495
  padding: '9px 12px',
496
- borderRadius: '8px',
496
+ borderRadius: 'var(--radius-sm, 8px)',
497
497
  cursor: 'pointer',
498
498
  background: isSelected ? 'var(--accent-subtle)' : 'transparent',
499
499
  border: `1px solid ${isSelected ? 'var(--accent-border)' : 'transparent'}`,
@@ -506,7 +506,7 @@ export function CommandPalette({
506
506
  fontSize: '0.68rem',
507
507
  fontWeight: 700,
508
508
  padding: '2px 5px',
509
- borderRadius: '4px',
509
+ borderRadius: 'var(--radius-2xs, 4px)',
510
510
  background: 'var(--bg-surface-soft)',
511
511
  color: isSelected ? 'var(--interactive-fg)' : 'var(--text-muted)',
512
512
  fontFamily: 'monospace',
@@ -553,7 +553,7 @@ export function CommandPalette({
553
553
  color: 'var(--interactive-fg)',
554
554
  fontWeight: 600,
555
555
  padding: '2px 6px',
556
- borderRadius: '4px',
556
+ borderRadius: 'var(--radius-2xs, 4px)',
557
557
  background: 'var(--accent-subtle)',
558
558
  }}
559
559
  >
@@ -582,8 +582,8 @@ export function CommandPalette({
582
582
  }}
583
583
  >
584
584
  <div style={{ display: 'flex', gap: '12px' }}>
585
- <span><kbd style={{ background: 'var(--bg-surface-soft)', border: '1px solid var(--border-subtle)', padding: '1px 4px', borderRadius: '3px' }}>↑</kbd> <kbd style={{ background: 'var(--bg-surface-soft)', border: '1px solid var(--border-subtle)', padding: '1px 4px', borderRadius: '3px' }}>↓</kbd> to navigate</span>
586
- <span><kbd style={{ background: 'var(--bg-surface-soft)', border: '1px solid var(--border-subtle)', padding: '1px 4px', borderRadius: '3px' }}>↵</kbd> to select</span>
585
+ <span><kbd style={{ background: 'var(--bg-surface-soft)', border: '1px solid var(--border-subtle)', padding: '1px 4px', borderRadius: 'var(--radius-2xs, 4px)' }}>↑</kbd> <kbd style={{ background: 'var(--bg-surface-soft)', border: '1px solid var(--border-subtle)', padding: '1px 4px', borderRadius: 'var(--radius-2xs, 4px)' }}>↓</kbd> to navigate</span>
586
+ <span><kbd style={{ background: 'var(--bg-surface-soft)', border: '1px solid var(--border-subtle)', padding: '1px 4px', borderRadius: 'var(--radius-2xs, 4px)' }}>↵</kbd> to select</span>
587
587
  </div>
588
588
  <span>Universal command palette</span>
589
589
  </div>
@@ -235,7 +235,7 @@ export default function DesktopTitlebar({
235
235
  View: [
236
236
  { label: sidebarCollapsed ? 'Show sidebar' : 'Hide sidebar', shortcut: 'Ctrl+B', action: onToggleSidebar },
237
237
  { label: 'Toggle terminal', shortcut: 'Ctrl+`', action: onToggleTerminal },
238
- { label: 'Open Browser panel', shortcut: 'Ctrl+Shift+B', action: onOpenBrowser },
238
+ { label: 'Open in default browser', shortcut: 'Ctrl+Shift+B', action: onOpenBrowser },
239
239
  { label: 'Zoom in', shortcut: 'Ctrl++', action: () => updateZoom(zoom + 0.1) },
240
240
  { label: 'Zoom out', shortcut: 'Ctrl+-', action: () => updateZoom(zoom - 0.1) },
241
241
  { label: 'Reset zoom', shortcut: 'Ctrl+0', disabled: zoom === 1, action: () => updateZoom(1) },
@@ -328,7 +328,7 @@ export default function DesktopTitlebar({
328
328
  <div><dt>Open workspace</dt><dd><kbd>Ctrl+O</kbd></dd></div>
329
329
  <div><dt>Toggle sidebar</dt><dd><kbd>Ctrl+B</kbd></dd></div>
330
330
  <div><dt>Toggle terminal</dt><dd><kbd>Ctrl+`</kbd></dd></div>
331
- <div><dt>Open Browser panel</dt><dd><kbd>Ctrl+Shift+B</kbd></dd></div>
331
+ <div><dt>Open in default browser</dt><dd><kbd>Ctrl+Shift+B</kbd></dd></div>
332
332
  <div><dt>Settings</dt><dd><kbd>Ctrl+,</kbd></dd></div>
333
333
  <div><dt>Zoom</dt><dd><kbd>Ctrl++</kbd> <kbd>Ctrl+-</kbd> <kbd>Ctrl+0</kbd></dd></div>
334
334
  <div><dt>Fullscreen</dt><dd><kbd>F11</kbd></dd></div>
@@ -751,33 +751,25 @@ export default function MintDashboard() {
751
751
  }
752
752
 
753
753
  const openMintBrowser = async (url: string, throwOnError = false) => {
754
- if (!isDesktopApp) {
755
- window.open(url, '_blank', 'noopener,noreferrer')
756
- return
757
- }
758
754
  try {
759
- showToast('Opening Co-browsing browser (Mint Auto)...')
760
- const { invoke } = await import('@tauri-apps/api/core')
761
- await invoke('open_mint_browser', { url })
755
+ showToast('Opening in system browser...')
756
+ await runtimePlatform.openExternal(url)
762
757
  } catch (error) {
763
758
  if (throwOnError) throw error
764
759
  showToast(`Could not open browser: ${String(error)}`)
765
760
  }
766
761
  }
767
762
 
768
- const openHtmlFile = async (root: string, relativePath: string, mode: 'external' | 'mint') => {
763
+ const openHtmlFile = async (root: string, relativePath: string, _mode: 'external' | 'mint' = 'external') => {
769
764
  if (!isDesktopApp && !['localhost', '127.0.0.1', '[::1]', '::1'].includes(window.location.hostname)) {
770
765
  throw new Error('HTML preview requires a browser on the same machine as the Mint backend.')
771
766
  }
772
- const popup = !isDesktopApp && mode === 'external' ? window.open('about:blank', '_blank') : null
767
+ const popup = !isDesktopApp ? window.open('about:blank', '_blank') : null
773
768
  if (popup) popup.opener = null
774
769
  try {
775
- const preview = await workspacePlatform.startHtmlPreview(root, relativePath, !isDesktopApp && mode === 'mint')
776
- if (mode === 'mint') {
777
- if (isDesktopApp) await openMintBrowser(preview.url, true)
778
- } else if (isDesktopApp) {
779
- const { invoke } = await import('@tauri-apps/api/core')
780
- await invoke('run_desktop_action', { action: { type: 'open_url', target: preview.url } })
770
+ const preview = await workspacePlatform.startHtmlPreview(root, relativePath)
771
+ if (isDesktopApp) {
772
+ await runtimePlatform.openExternal(preview.url)
781
773
  } else {
782
774
  if (!popup) throw new Error('Allow browser popups, then open the HTML file again.')
783
775
  popup.location.replace(preview.url)
@@ -1061,6 +1053,9 @@ export default function MintDashboard() {
1061
1053
  } else if (slashResult.action === 'open_settings') {
1062
1054
  window.location.hash = '#/settings'
1063
1055
  return
1056
+ } else if (slashResult.action === 'start_voice') {
1057
+ window.dispatchEvent(new CustomEvent('mint:trigger-voice'))
1058
+ return
1064
1059
  } else if (slashResult.action === 'resume_session') {
1065
1060
  const query = (slashResult.payload?.query || '').trim().toLowerCase()
1066
1061
  const target = query
@@ -1747,6 +1742,7 @@ export default function MintDashboard() {
1747
1742
  onSelectVideo: selectVideo,
1748
1743
  onSelectDocument: selectDocument,
1749
1744
  onPasteImage: pasteImage,
1745
+ onAttachImage: (image) => conversationActions.attachImage(image),
1750
1746
  onSetMessage: conversationActions.compose,
1751
1747
  subscribeMessage: conversationActions.subscribe,
1752
1748
  getMessage: () => conversationActions.getSnapshot().message,
@@ -1771,12 +1767,26 @@ export default function MintDashboard() {
1771
1767
  onToggleMobileSidebar: () => setMobileSidebarOpen(!mobileSidebarOpen),
1772
1768
  onBackToCode: () => changeView('code'),
1773
1769
  onOpenArtifact: openArtifactSurface,
1774
- onOpenReview: isDesktopApp ? openReviewSurface : undefined,
1770
+ onOpenReview: openReviewSurface,
1775
1771
  onRemoveQueuedPrompt: conversationActions.removeQueuedPrompt,
1776
1772
  onEditQueuedPrompt: conversationActions.editQueuedPrompt,
1777
1773
  onClearQueuedPrompts: conversationActions.clearQueuedPrompts,
1778
1774
  onSteerQueuedPrompt: conversationActions.steerQueuedPrompt,
1779
1775
  onResumeQueue: conversationActions.resumeQueue,
1776
+ onSyncHistory: () => {
1777
+ void conversationActions.syncHistory()
1778
+ },
1779
+ onReceiveApproval: (approval) => {
1780
+ conversationActions.receiveApproval(conversationId, approval)
1781
+ },
1782
+ onResendFrom: async (fromId: number, newPrompt: string) => {
1783
+ if (conversationActions.getSnapshot().sending) return
1784
+ setError('')
1785
+ liveThinkingOpenRef.current = true
1786
+ liveExtendedThinkingOpenRef.current = true
1787
+ setThinkingExpanded(current => ({ ...current, live: true, 'live-extended': true }))
1788
+ await conversationActions.resendFromInteraction(fromId, newPrompt, { agentMode, planMode })
1789
+ },
1780
1790
  }
1781
1791
 
1782
1792
  const stableToggleSidebar = useLatestCallback(toggleSidebar)
@@ -1876,7 +1886,7 @@ export default function MintDashboard() {
1876
1886
  }}
1877
1887
  />
1878
1888
  )}
1879
- {toastMessage && <div role="status" style={{ position: 'fixed', bottom: 22, right: 22, zIndex: 10000, padding: '12px 18px', borderRadius: 10, background: 'var(--bg-surface)', color: 'var(--text-main)', border: '1px solid var(--border-color)' }}>{toastMessage}</div>}
1889
+ {toastMessage && <div role="status" style={{ position: 'fixed', bottom: 22, right: 22, zIndex: 10000, padding: '12px 18px', borderRadius: 'var(--radius-lg, 14px)', background: 'var(--bg-surface)', color: 'var(--text-main)', border: '1px solid var(--border-color)' }}>{toastMessage}</div>}
1880
1890
  <DashboardSidebar
1881
1891
  view={view}
1882
1892
  sidebarCollapsed={sidebarCollapsed}
@@ -77,7 +77,7 @@ export default class ModalErrorBoundary extends React.Component<Props, State> {
77
77
  color: 'var(--status-error, #ef4444)',
78
78
  background: 'color-mix(in srgb, var(--status-error, #ef4444) 12%, transparent)',
79
79
  padding: '6px 12px',
80
- borderRadius: 6,
80
+ borderRadius: 'var(--radius-xs, 6px)',
81
81
  maxWidth: 460,
82
82
  wordBreak: 'break-word',
83
83
  }}
@@ -91,7 +91,7 @@ export default class ModalErrorBoundary extends React.Component<Props, State> {
91
91
  onClick={this.handleRetry}
92
92
  style={{
93
93
  padding: '8px 20px',
94
- borderRadius: 8,
94
+ borderRadius: 'var(--radius-sm, 8px)',
95
95
  border: 'none',
96
96
  background: 'var(--accent, #10b981)',
97
97
  color: 'var(--text-on-accent, #ffffff)',
@@ -107,7 +107,7 @@ export default class ModalErrorBoundary extends React.Component<Props, State> {
107
107
  onClick={() => this.props.onClose?.()}
108
108
  style={{
109
109
  padding: '8px 20px',
110
- borderRadius: 8,
110
+ borderRadius: 'var(--radius-sm, 8px)',
111
111
  border: '1px solid var(--border-default, rgba(255, 255, 255, 0.15))',
112
112
  background: 'transparent',
113
113
  color: 'var(--text-main, #e4e4e7)',
@@ -31,7 +31,7 @@ export default function CalculationCard({ data }: { data: CalculationData }) {
31
31
  style={{
32
32
  background: t.cardBg,
33
33
  color: t.cardText,
34
- borderRadius: '12px',
34
+ borderRadius: 'var(--radius-xl, 18px)',
35
35
  padding: '16px 20px',
36
36
  margin: '12px 0',
37
37
  boxShadow: t.cardShadow,
@@ -52,7 +52,7 @@ export default function CalculationCard({ data }: { data: CalculationData }) {
52
52
  style={{
53
53
  background: t.exprBg,
54
54
  border: `1px solid ${t.exprBorder}`,
55
- borderRadius: '8px',
55
+ borderRadius: 'var(--radius-sm, 8px)',
56
56
  padding: '10px 14px',
57
57
  fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace',
58
58
  fontSize: '14px',
@@ -73,7 +73,7 @@ export default function CalculationCard({ data }: { data: CalculationData }) {
73
73
  style={{
74
74
  background: t.resultBg,
75
75
  border: `1px solid ${t.resultBorder}`,
76
- borderRadius: '10px',
76
+ borderRadius: 'var(--radius-md, 10px)',
77
77
  padding: '12px 18px',
78
78
  }}
79
79
  >
@@ -41,7 +41,7 @@ function GeneratedImageTile({ url, single }: { url: string; single: boolean }) {
41
41
  style={{
42
42
  position: 'relative',
43
43
  display: 'block',
44
- borderRadius: '10px',
44
+ borderRadius: 'var(--radius-md, 10px)',
45
45
  overflow: 'hidden',
46
46
  aspectRatio: single ? undefined : '1 / 1',
47
47
  background: 'var(--surface-strong)',
@@ -81,7 +81,7 @@ export default function ImageGenCard({ data }: { data: ImageGenData }) {
81
81
  style={{
82
82
  background: cardBg,
83
83
  color: cardText,
84
- borderRadius: '12px',
84
+ borderRadius: 'var(--radius-xl, 18px)',
85
85
  padding: '16px 20px',
86
86
  margin: '12px 0',
87
87
  boxShadow: 'var(--shadow-md)',