@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
@@ -1,61 +1,66 @@
1
1
  import { describe, expect, it, vi } from 'vitest'
2
2
  import { installRendererPlatform } from '../platform'
3
3
  import * as desktopAdapter from '../../src/tauri'
4
- import { openArtifactInMintBrowser } from './artifactBrowser'
4
+ import { openArtifactInBrowser } from './artifactBrowser'
5
5
 
6
6
  const native = vi.hoisted(() => ({ invoke: vi.fn(async () => undefined) }))
7
7
  vi.mock('@tauri-apps/api/core', () => ({ invoke: native.invoke }))
8
8
 
9
9
  const url = 'http://127.0.0.1:12345/site/index.html'
10
- describe('opening a preview in Mint Browser', () => {
11
- it('opens an existing served URL through Mint Browser on Desktop', async () => {
10
+ describe('opening a preview in system browser', () => {
11
+ it('opens an existing served URL through browser on Desktop', async () => {
12
12
  const opened: string[] = []
13
- await openArtifactInMintBrowser({ path: 'site/index.html', url }, '/projects/Demo', {
13
+ await openArtifactInBrowser({ path: 'site/index.html', url }, '/projects/Demo', {
14
14
  desktop: true,
15
15
  startPreview: async () => { throw new Error('An existing URL must be reused') },
16
- openMintBrowser: async (target) => { opened.push(target) },
16
+ openBrowser: async (target) => { opened.push(target) },
17
17
  })
18
18
  expect(opened).toEqual([url])
19
19
  })
20
- it('serves chat artifacts from their pinned project before opening Mint Browser', async () => {
20
+ it('serves chat artifacts from their pinned project before opening browser', async () => {
21
21
  const actions: unknown[] = []
22
- await openArtifactInMintBrowser({ path: 'site/index.html', workspacePath: '/projects/Original' }, '/projects/Other', {
22
+ await openArtifactInBrowser({ path: 'site/index.html', workspacePath: '/projects/Original' }, '/projects/Other', {
23
23
  desktop: true,
24
- startPreview: async (root, path, mint) => { actions.push([root, path, mint]); return { url, jobId: 'preview-1' } },
25
- openMintBrowser: async (target) => { actions.push(target) },
24
+ startPreview: async (root, path) => { actions.push([root, path]); return { url, jobId: 'preview-1' } },
25
+ openBrowser: async (target) => { actions.push(target) },
26
26
  })
27
- expect(actions).toEqual([['/projects/Original', 'site/index.html', false], url])
27
+ expect(actions).toEqual([['/projects/Original', 'site/index.html'], url])
28
28
  })
29
- it('opens the controlled browser through the authenticated local backend on Web', async () => {
30
- const requests: unknown[] = []
31
- await openArtifactInMintBrowser({ path: 'site/index.html', url, workspacePath: '/projects/Demo' }, undefined, {
29
+ it('opens preview via system browser on Web', async () => {
30
+ const actions: unknown[] = []
31
+ await openArtifactInBrowser({ path: 'site/index.html', url, workspacePath: '/projects/Demo' }, undefined, {
32
32
  desktop: false,
33
- startPreview: async (root, path, mint) => { requests.push([root, path, mint]); return { url, jobId: 'preview-1' } },
34
- openMintBrowser: async () => { throw new Error('Web must not call native IPC') },
33
+ startPreview: async (root, path) => { actions.push([root, path]); return { url, jobId: 'preview-1' } },
34
+ openBrowser: async (target) => { actions.push(target) },
35
35
  })
36
- expect(requests).toEqual([['/projects/Demo', 'site/index.html', true]])
36
+ expect(actions).toEqual([url])
37
37
  })
38
38
  it('reports browser launch failures so the button can show an error', async () => {
39
- await expect(openArtifactInMintBrowser({ path: 'site/index.html', url }, undefined, {
39
+ await expect(openArtifactInBrowser({ path: 'site/index.html', url }, undefined, {
40
40
  desktop: true,
41
41
  startPreview: async () => { throw new Error('Unexpected server startup') },
42
- openMintBrowser: async () => { throw new Error('Chrome unavailable') },
43
- })).rejects.toThrow('Chrome unavailable')
42
+ openBrowser: async () => { throw new Error('Browser unavailable') },
43
+ })).rejects.toThrow('Browser unavailable')
44
44
  })
45
45
  it('does not start a server without a source project', async () => {
46
- await expect(openArtifactInMintBrowser({ path: 'site/index.html' }, undefined, {
46
+ await expect(openArtifactInBrowser({ path: 'site/index.html' }, undefined, {
47
47
  desktop: true,
48
48
  startPreview: async () => { throw new Error('Unexpected server startup') },
49
- openMintBrowser: async () => { throw new Error('Unexpected browser startup') },
49
+ openBrowser: async () => { throw new Error('Unexpected browser startup') },
50
50
  })).rejects.toThrow('Select a project')
51
51
  })
52
52
  })
53
53
 
54
- it('sends the existing open_mint_browser IPC command for the default Desktop action', async () => {
55
- installRendererPlatform({ ...desktopAdapter, isTauriRuntime: () => true })
56
- native.invoke.mockClear()
57
- await openArtifactInMintBrowser({ path: 'site/index.html', url }, undefined)
58
- expect(native.invoke).toHaveBeenCalledWith('open_mint_browser', { url })
54
+ it('sends the open_url desktop action for the default Desktop action', async () => {
55
+ vi.stubGlobal('window', { __TAURI_INTERNALS__: {} })
56
+ try {
57
+ installRendererPlatform({ ...desktopAdapter, isTauriRuntime: () => true })
58
+ native.invoke.mockClear()
59
+ await openArtifactInBrowser({ path: 'site/index.html', url }, undefined)
60
+ expect(native.invoke).toHaveBeenCalledWith('run_desktop_action', { action: { type: 'open_url', target: url } })
61
+ } finally {
62
+ vi.unstubAllGlobals()
63
+ }
59
64
  })
60
65
 
61
66
  it.each([
@@ -63,18 +68,18 @@ it.each([
63
68
  ['C:\\Projects\\Demo', 'c:\\projects\\demo\\site\\index.html', 'site/index.html'],
64
69
  ])('opens absolute artifact paths relative to their source project %s', async (root, path, relative) => {
65
70
  const requests: unknown[] = []
66
- await openArtifactInMintBrowser({ path, workspacePath: root }, '/projects/Other', {
71
+ await openArtifactInBrowser({ path, workspacePath: root }, '/projects/Other', {
67
72
  desktop: true,
68
- startPreview: async (workspace, file, mint) => { requests.push([workspace, file, mint]); return { url, jobId: 'preview-1' } },
69
- openMintBrowser: async () => {},
73
+ startPreview: async (workspace, file) => { requests.push([workspace, file]); return { url, jobId: 'preview-1' } },
74
+ openBrowser: async () => {},
70
75
  })
71
- expect(requests).toEqual([[root, relative, false]])
76
+ expect(requests).toEqual([[root, relative]])
72
77
  })
73
78
 
74
79
  it('rejects an absolute artifact from a different project without starting a server', async () => {
75
- await expect(openArtifactInMintBrowser({ path: '/projects/Demo-copy/index.html', workspacePath: '/projects/Demo' }, undefined, {
80
+ await expect(openArtifactInBrowser({ path: '/projects/Demo-copy/index.html', workspacePath: '/projects/Demo' }, undefined, {
76
81
  desktop: true,
77
82
  startPreview: async () => { throw new Error('Unexpected server startup') },
78
- openMintBrowser: async () => {},
83
+ openBrowser: async () => {},
79
84
  })).rejects.toThrow('outside its source project')
80
85
  })
@@ -1,30 +1,28 @@
1
1
  import type { ArtifactFile } from './artifacts'
2
2
  import { runtimePlatform, workspacePlatform } from '../platform'
3
3
 
4
- interface BrowserApi {
5
- desktop: boolean
6
- startPreview(root: string, path: string, mintBrowser: boolean): Promise<{ url: string; jobId: string }>
7
- openMintBrowser(url: string): Promise<void>
4
+ export interface BrowserApi {
5
+ desktop?: boolean
6
+ startPreview?(root: string, path: string): Promise<{ url: string; jobId: string }>
7
+ openBrowser?(url: string): Promise<void>
8
8
  }
9
9
 
10
- export async function openArtifactInMintBrowser(
10
+ export async function openArtifactInBrowser(
11
11
  artifact: ArtifactFile,
12
12
  workspace: string | undefined,
13
- api: BrowserApi = {
14
- desktop: runtimePlatform.isTauriRuntime(),
15
- startPreview: (root, path, mint) => workspacePlatform.startHtmlPreview(root, path, mint),
16
- openMintBrowser: async (url) => {
17
- const { invoke } = await import('@tauri-apps/api/core')
18
- await invoke('open_mint_browser', { url })
19
- },
20
- },
13
+ api: BrowserApi = {},
21
14
  ): Promise<void> {
22
- if (api.desktop && artifact.url) {
23
- await api.openMintBrowser(artifact.url)
15
+ const openBrowser = api.openBrowser ?? (async (targetUrl: string) => {
16
+ await runtimePlatform.openExternal(targetUrl)
17
+ })
18
+ const startPreview = api.startPreview ?? ((root: string, targetPath: string) => workspacePlatform.startHtmlPreview(root, targetPath))
19
+
20
+ if (artifact.url) {
21
+ await openBrowser(artifact.url)
24
22
  return
25
23
  }
26
24
  const root = (artifact.workspacePath ?? workspace)?.trim()
27
- if (!root) throw new Error('Select a project before opening its preview in Mint Browser')
25
+ if (!root) throw new Error('Select a project before opening its preview in browser')
28
26
  let path = artifact.path.replace(/\\/g, '/')
29
27
  if (/^(\/|[a-z]:\/)/i.test(path)) {
30
28
  const normalizedRoot = root.replace(/\\/g, '/').replace(/\/+$/, '')
@@ -35,7 +33,7 @@ export async function openArtifactInMintBrowser(
35
33
  }
36
34
  path = path.slice(prefix.length)
37
35
  }
38
- // The authenticated local Web endpoint launches the same automation browser on the backend.
39
- const preview = await api.startPreview(root, path, !api.desktop)
40
- if (api.desktop) await api.openMintBrowser(preview.url)
36
+ const preview = await startPreview(root, path)
37
+ await openBrowser(preview.url)
41
38
  }
39
+
@@ -0,0 +1,73 @@
1
+ /// <reference path="../../env.d.ts" />
2
+ import { describe, it, expect } from 'vitest'
3
+ import { parseAttachedDocument } from './attachedDocument'
4
+
5
+ describe('parseAttachedDocument', () => {
6
+ it('returns raw text unchanged when no document attachment pattern is present', () => {
7
+ const raw = 'สวัสดีครับ ช่วยดูโค้ดนี้หน่อย'
8
+ const res = parseAttachedDocument(raw)
9
+ expect(res.userText).toBe(raw)
10
+ expect(res.attachedDocument).toBeUndefined()
11
+ })
12
+
13
+ it('handles null, undefined, and empty string', () => {
14
+ expect(parseAttachedDocument(null).userText).toBe('')
15
+ expect(parseAttachedDocument(undefined).userText).toBe('')
16
+ expect(parseAttachedDocument('').userText).toBe('')
17
+ })
18
+
19
+ it('parses user text and attached document payload accurately', () => {
20
+ const raw = `@generate_harness_pdf.py ขอปรับหน่อยอะ ไฟล์ที่ลากมาวา
21
+
22
+ Attached document: LICENSE.electron.txt
23
+ Use the extracted document text below when answering. If the user asks for a summary, summarize this document.
24
+
25
+ --- Extracted document text ---
26
+ Copyright (c) Electron contributors
27
+ Copyright (c) 2013-2020 GitHub Inc.
28
+
29
+ Permission is hereby granted, free of charge.
30
+ --- End extracted document text ---`
31
+
32
+ const res = parseAttachedDocument(raw)
33
+ expect(res.userText).toBe('@generate_harness_pdf.py ขอปรับหน่อยอะ ไฟล์ที่ลากมาวา')
34
+ expect(res.attachedDocument).toBeDefined()
35
+ expect(res.attachedDocument?.filename).toBe('LICENSE.electron.txt')
36
+ expect(res.attachedDocument?.lineCount).toBe(4)
37
+ expect(res.attachedDocument?.content).toContain('Copyright (c) Electron contributors')
38
+ expect(res.attachedDocument?.content).toContain('Permission is hereby granted, free of charge.')
39
+ })
40
+
41
+ it('handles when the user sent only an attachment without typing any message', () => {
42
+ const raw = `Attached document: notes.md
43
+ Use the extracted document text below when answering. If the user asks for a summary, summarize this document.
44
+
45
+ --- Extracted document text ---
46
+ # Notes
47
+ Here are the notes.
48
+ --- End extracted document text ---`
49
+
50
+ const res = parseAttachedDocument(raw)
51
+ expect(res.userText).toBe('')
52
+ expect(res.attachedDocument?.filename).toBe('notes.md')
53
+ expect(res.attachedDocument?.lineCount).toBe(2)
54
+ })
55
+
56
+ it('handles truncated document notice properly', () => {
57
+ const raw = `Check this file
58
+
59
+ Attached document: large.json
60
+ Use the extracted document text below when answering. If the user asks for a summary, summarize this document.
61
+
62
+ --- Extracted document text ---
63
+ {"key": "val"}
64
+
65
+ [Document text truncated because it is long.]
66
+ --- End extracted document text ---`
67
+
68
+ const res = parseAttachedDocument(raw)
69
+ expect(res.userText).toBe('Check this file')
70
+ expect(res.attachedDocument?.filename).toBe('large.json')
71
+ expect(res.attachedDocument?.content).toContain('[Document text truncated because it is long.]')
72
+ })
73
+ })
@@ -0,0 +1,49 @@
1
+ /**
2
+ * shared/utils/attachedDocument.ts
3
+ *
4
+ * Parses document attachment text and boilerplate injected into `interaction.userText`
5
+ * by the backend (`with_document_text`), allowing the chat interface to separate
6
+ * authentic user prompt text from the attached file contents.
7
+ */
8
+
9
+ export interface AttachedDocumentPayload {
10
+ filename: string
11
+ content: string
12
+ lineCount: number
13
+ charCount: number
14
+ }
15
+
16
+ export interface ParsedUserMessage {
17
+ userText: string
18
+ attachedDocument?: AttachedDocumentPayload
19
+ }
20
+
21
+ const ATTACHED_DOC_REGEX =
22
+ /(?:^|\n\n)Attached document: ([^\n]+)\nUse the extracted document text below when answering[^\n]*\n\n--- Extracted document text ---\n([\s\S]*?)\n--- End extracted document text ---$/
23
+
24
+ export function parseAttachedDocument(rawText: string | null | undefined): ParsedUserMessage {
25
+ if (!rawText || typeof rawText !== 'string') {
26
+ return { userText: '' }
27
+ }
28
+
29
+ const match = rawText.match(ATTACHED_DOC_REGEX)
30
+ if (!match || match.index === undefined) {
31
+ return { userText: rawText }
32
+ }
33
+
34
+ const userText = rawText.slice(0, match.index).trim()
35
+ const filename = match[1].trim()
36
+ const content = match[2]
37
+ const lineCount = content ? content.split('\n').length : 0
38
+ const charCount = content ? content.length : 0
39
+
40
+ return {
41
+ userText,
42
+ attachedDocument: {
43
+ filename,
44
+ content,
45
+ lineCount,
46
+ charCount,
47
+ },
48
+ }
49
+ }
@@ -0,0 +1,59 @@
1
+ import { describe, expect, it } from 'vitest'
2
+ import {
3
+ getExtension,
4
+ materialFileIcon,
5
+ materialFolderIcon,
6
+ documentIcon,
7
+ folderIcon,
8
+ folderOpenIcon,
9
+ FILE_ICONS_BY_EXTENSION,
10
+ FILE_ICONS_BY_NAME,
11
+ } from './fileIcons'
12
+
13
+ describe('fileIcons utility', () => {
14
+ it('correctly extracts extensions case-insensitively', () => {
15
+ expect(getExtension('main.py')).toBe('py')
16
+ expect(getExtension('foo.BAR.TSX')).toBe('tsx')
17
+ expect(getExtension('Dockerfile')).toBe('')
18
+ expect(getExtension('.gitignore')).toBe('gitignore')
19
+ })
20
+
21
+ it('maps python files (.py, .pyw, .ipynb) to Python/Jupyter icons', () => {
22
+ const pyIcon = materialFileIcon('script.py', 'py')
23
+ expect(pyIcon).toBeDefined()
24
+ expect(pyIcon).not.toBe(documentIcon)
25
+ expect(pyIcon).toBe(FILE_ICONS_BY_EXTENSION['py'])
26
+
27
+ const ipynbIcon = materialFileIcon('analysis.ipynb', 'ipynb')
28
+ expect(ipynbIcon).toBe(FILE_ICONS_BY_EXTENSION['ipynb'])
29
+ })
30
+
31
+ it('maps major programming languages to their dedicated icons', () => {
32
+ expect(materialFileIcon('main.rs', 'rs')).toBe(FILE_ICONS_BY_EXTENSION['rs'])
33
+ expect(materialFileIcon('main.go', 'go')).toBe(FILE_ICONS_BY_EXTENSION['go'])
34
+ expect(materialFileIcon('Main.java', 'java')).toBe(FILE_ICONS_BY_EXTENSION['java'])
35
+ expect(materialFileIcon('app.c', 'c')).toBe(FILE_ICONS_BY_EXTENSION['c'])
36
+ expect(materialFileIcon('app.cpp', 'cpp')).toBe(FILE_ICONS_BY_EXTENSION['cpp'])
37
+ expect(materialFileIcon('App.cs', 'cs')).toBe(FILE_ICONS_BY_EXTENSION['cs'])
38
+ expect(materialFileIcon('script.sh', 'sh')).toBe(FILE_ICONS_BY_EXTENSION['sh'])
39
+ expect(materialFileIcon('query.sql', 'sql')).toBe(FILE_ICONS_BY_EXTENSION['sql'])
40
+ expect(materialFileIcon('doc.pdf', 'pdf')).toBe(FILE_ICONS_BY_EXTENSION['pdf'])
41
+ })
42
+
43
+ it('maps special file names by exact or lowercased name', () => {
44
+ expect(materialFileIcon('Dockerfile', '')).toBe(FILE_ICONS_BY_NAME['dockerfile'])
45
+ expect(materialFileIcon('.gitignore', 'gitignore')).toBe(FILE_ICONS_BY_NAME['.gitignore'])
46
+ expect(materialFileIcon('package.json', 'json')).toBe(FILE_ICONS_BY_NAME['package.json'])
47
+ })
48
+
49
+ it('falls back to documentIcon for unrecognized extensions', () => {
50
+ expect(materialFileIcon('mystery.unrecognizedext123', 'unrecognizedext123')).toBe(documentIcon)
51
+ })
52
+
53
+ it('returns appropriate folder icons', () => {
54
+ expect(materialFolderIcon('unknown_folder', false)).toBe(folderIcon)
55
+ expect(materialFolderIcon('unknown_folder', true)).toBe(folderOpenIcon)
56
+ expect(materialFolderIcon('src', false)).not.toBe(folderIcon)
57
+ expect(materialFolderIcon('src', true)).not.toBe(folderOpenIcon)
58
+ })
59
+ })
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * shared/utils/fileIcons.ts
3
3
  * Utility mapping and resolution functions for Material Icon Theme icons.
4
- * Extracted from WorkspacePanel to be shared across multiple components (e.g. AgentActivityTable).
4
+ * Extracted from WorkspacePanel to be shared across multiple components (e.g. AgentActivityTable, TurnFileChanges).
5
5
  */
6
6
 
7
7
  import folderIcon from 'material-icon-theme/icons/folder.svg?url'
@@ -40,25 +40,57 @@ import folderUiIcon from 'material-icon-theme/icons/folder-ui.svg?url'
40
40
  import folderUiOpenIcon from 'material-icon-theme/icons/folder-ui-open.svg?url'
41
41
  import folderUtilsIcon from 'material-icon-theme/icons/folder-utils.svg?url'
42
42
  import folderUtilsOpenIcon from 'material-icon-theme/icons/folder-utils-open.svg?url'
43
+
44
+ // Language & file icons
45
+ import audioIcon from 'material-icon-theme/icons/audio.svg?url'
46
+ import cIcon from 'material-icon-theme/icons/c.svg?url'
47
+ import consoleIcon from 'material-icon-theme/icons/console.svg?url'
48
+ import cppIcon from 'material-icon-theme/icons/cpp.svg?url'
49
+ import csharpIcon from 'material-icon-theme/icons/csharp.svg?url'
43
50
  import cssIcon from 'material-icon-theme/icons/css.svg?url'
51
+ import dartIcon from 'material-icon-theme/icons/dart.svg?url'
52
+ import databaseIcon from 'material-icon-theme/icons/database.svg?url'
53
+ import dockerIcon from 'material-icon-theme/icons/docker.svg?url'
44
54
  import documentIcon from 'material-icon-theme/icons/document.svg?url'
55
+ import fontIcon from 'material-icon-theme/icons/font.svg?url'
56
+ import gitIcon from 'material-icon-theme/icons/git.svg?url'
57
+ import goIcon from 'material-icon-theme/icons/go.svg?url'
58
+ import graphqlIcon from 'material-icon-theme/icons/graphql.svg?url'
45
59
  import htmlIcon from 'material-icon-theme/icons/html.svg?url'
46
60
  import imageIcon from 'material-icon-theme/icons/image.svg?url'
61
+ import javaIcon from 'material-icon-theme/icons/java.svg?url'
47
62
  import javascriptIcon from 'material-icon-theme/icons/javascript.svg?url'
48
63
  import jsonIcon from 'material-icon-theme/icons/json.svg?url'
64
+ import jupyterIcon from 'material-icon-theme/icons/jupyter.svg?url'
65
+ import kotlinIcon from 'material-icon-theme/icons/kotlin.svg?url'
49
66
  import lockIcon from 'material-icon-theme/icons/lock.svg?url'
50
67
  import logIcon from 'material-icon-theme/icons/log.svg?url'
68
+ import luaIcon from 'material-icon-theme/icons/lua.svg?url'
51
69
  import markdownIcon from 'material-icon-theme/icons/markdown.svg?url'
52
70
  import npmIcon from 'material-icon-theme/icons/npm.svg?url'
71
+ import pdfIcon from 'material-icon-theme/icons/pdf.svg?url'
72
+ import phpIcon from 'material-icon-theme/icons/php.svg?url'
73
+ import powershellIcon from 'material-icon-theme/icons/powershell.svg?url'
74
+ import pythonIcon from 'material-icon-theme/icons/python.svg?url'
75
+ import rIcon from 'material-icon-theme/icons/r.svg?url'
53
76
  import reactIcon from 'material-icon-theme/icons/react.svg?url'
54
77
  import reactTsIcon from 'material-icon-theme/icons/react_ts.svg?url'
78
+ import rubyIcon from 'material-icon-theme/icons/ruby.svg?url'
55
79
  import rustIcon from 'material-icon-theme/icons/rust.svg?url'
80
+ import sassIcon from 'material-icon-theme/icons/sass.svg?url'
81
+ import scalaIcon from 'material-icon-theme/icons/scala.svg?url'
56
82
  import settingsIcon from 'material-icon-theme/icons/settings.svg?url'
83
+ import svelteIcon from 'material-icon-theme/icons/svelte.svg?url'
84
+ import swiftIcon from 'material-icon-theme/icons/swift.svg?url'
57
85
  import tauriIcon from 'material-icon-theme/icons/tauri.svg?url'
58
86
  import tomlIcon from 'material-icon-theme/icons/toml.svg?url'
59
87
  import typescriptIcon from 'material-icon-theme/icons/typescript.svg?url'
88
+ import videoIcon from 'material-icon-theme/icons/video.svg?url'
60
89
  import viteIcon from 'material-icon-theme/icons/vite.svg?url'
90
+ import vueIcon from 'material-icon-theme/icons/vue.svg?url'
91
+ import xmlIcon from 'material-icon-theme/icons/xml.svg?url'
61
92
  import yamlIcon from 'material-icon-theme/icons/yaml.svg?url'
93
+ import zipIcon from 'material-icon-theme/icons/zip.svg?url'
62
94
 
63
95
  export const FOLDER_ICONS: Record<string, { closed: string; open: string }> = {
64
96
  '.cargo_home': { closed: folderRustIcon, open: folderRustOpenIcon },
@@ -86,23 +118,111 @@ export const FOLDER_ICONS: Record<string, { closed: string; open: string }> = {
86
118
  }
87
119
 
88
120
  export const FILE_ICONS_BY_EXTENSION: Record<string, string> = {
121
+ // Web & Styles
89
122
  css: cssIcon,
123
+ scss: sassIcon,
124
+ sass: sassIcon,
125
+ less: cssIcon,
90
126
  html: htmlIcon,
91
- jpeg: imageIcon,
92
- jpg: imageIcon,
127
+ htm: htmlIcon,
128
+ graphql: graphqlIcon,
129
+ gql: graphqlIcon,
130
+ vue: vueIcon,
131
+ svelte: svelteIcon,
132
+
133
+ // JavaScript & TypeScript
93
134
  js: javascriptIcon,
94
- json: jsonIcon,
95
- lock: lockIcon,
96
- log: logIcon,
97
- md: markdownIcon,
98
- png: imageIcon,
99
- rs: rustIcon,
100
- svg: imageIcon,
101
- toml: tomlIcon,
135
+ mjs: javascriptIcon,
136
+ cjs: javascriptIcon,
137
+ jsx: reactIcon,
102
138
  ts: typescriptIcon,
139
+ mts: typescriptIcon,
140
+ cts: typescriptIcon,
103
141
  tsx: reactTsIcon,
142
+
143
+ // Python & Data Science
144
+ py: pythonIcon,
145
+ pyc: pythonIcon,
146
+ pyd: pythonIcon,
147
+ pyw: pythonIcon,
148
+ ipynb: jupyterIcon,
149
+
150
+ // Systems & Compiled Languages
151
+ rs: rustIcon,
152
+ c: cIcon,
153
+ h: cIcon,
154
+ cpp: cppIcon,
155
+ cc: cppIcon,
156
+ cxx: cppIcon,
157
+ hpp: cppIcon,
158
+ hh: cppIcon,
159
+ hxx: cppIcon,
160
+ cs: csharpIcon,
161
+ go: goIcon,
162
+ java: javaIcon,
163
+ jar: javaIcon,
164
+ kt: kotlinIcon,
165
+ kts: kotlinIcon,
166
+ php: phpIcon,
167
+ rb: rubyIcon,
168
+ swift: swiftIcon,
169
+ scala: scalaIcon,
170
+ dart: dartIcon,
171
+ lua: luaIcon,
172
+ r: rIcon,
173
+
174
+ // Shell & Scripts
175
+ sh: consoleIcon,
176
+ bash: consoleIcon,
177
+ zsh: consoleIcon,
178
+ fish: consoleIcon,
179
+ ps1: powershellIcon,
180
+ psm1: powershellIcon,
181
+ bat: consoleIcon,
182
+ cmd: consoleIcon,
183
+
184
+ // Data, Config & Docs
185
+ json: jsonIcon,
186
+ json5: jsonIcon,
187
+ jsonc: jsonIcon,
104
188
  yaml: yamlIcon,
105
189
  yml: yamlIcon,
190
+ toml: tomlIcon,
191
+ xml: xmlIcon,
192
+ sql: databaseIcon,
193
+ db: databaseIcon,
194
+ sqlite: databaseIcon,
195
+ sqlite3: databaseIcon,
196
+ md: markdownIcon,
197
+ mdx: markdownIcon,
198
+ pdf: pdfIcon,
199
+ log: logIcon,
200
+ lock: lockIcon,
201
+
202
+ // Media, Fonts & Archives
203
+ png: imageIcon,
204
+ jpg: imageIcon,
205
+ jpeg: imageIcon,
206
+ gif: imageIcon,
207
+ webp: imageIcon,
208
+ svg: imageIcon,
209
+ ico: imageIcon,
210
+ mp3: audioIcon,
211
+ wav: audioIcon,
212
+ ogg: audioIcon,
213
+ mp4: videoIcon,
214
+ webm: videoIcon,
215
+ mov: videoIcon,
216
+ zip: zipIcon,
217
+ tar: zipIcon,
218
+ gz: zipIcon,
219
+ tgz: zipIcon,
220
+ '7z': zipIcon,
221
+ rar: zipIcon,
222
+ woff: fontIcon,
223
+ woff2: fontIcon,
224
+ ttf: fontIcon,
225
+ otf: fontIcon,
106
226
  }
107
227
 
108
228
  export const FILE_ICONS_BY_NAME: Record<string, string> = {
@@ -111,6 +231,18 @@ export const FILE_ICONS_BY_NAME: Record<string, string> = {
111
231
  'tauri.conf.json': tauriIcon,
112
232
  'vite.config.ts': viteIcon,
113
233
  'vite.config.web.ts': viteIcon,
234
+ 'vite.config.js': viteIcon,
235
+ 'dockerfile': dockerIcon,
236
+ 'containerfile': dockerIcon,
237
+ 'docker-compose.yml': dockerIcon,
238
+ 'docker-compose.yaml': dockerIcon,
239
+ '.gitignore': gitIcon,
240
+ '.gitattributes': gitIcon,
241
+ '.gitmodules': gitIcon,
242
+ '.env': settingsIcon,
243
+ '.env.local': settingsIcon,
244
+ '.env.development': settingsIcon,
245
+ '.env.production': settingsIcon,
114
246
  }
115
247
 
116
248
  export function getExtension(name: string): string {
@@ -125,11 +257,12 @@ export function materialFolderIcon(name: string, open: boolean): string {
125
257
  }
126
258
 
127
259
  export function materialFileIcon(name: string, fileExtension: string): string {
128
- if (name.endsWith('.config.ts') || name.endsWith('.config.js')) return settingsIcon
129
- if (name.endsWith('.tsx')) return reactTsIcon
130
- if (name.endsWith('.jsx')) return reactIcon
131
- return FILE_ICONS_BY_NAME[name.toLowerCase()] || FILE_ICONS_BY_EXTENSION[fileExtension] || documentIcon
260
+ const lowerName = name.toLowerCase()
261
+ if (FILE_ICONS_BY_NAME[lowerName]) return FILE_ICONS_BY_NAME[lowerName]
262
+ if (lowerName.endsWith('.config.ts') || lowerName.endsWith('.config.js') || lowerName.endsWith('.config.mjs')) return settingsIcon
263
+ if (lowerName.endsWith('.tsx')) return reactTsIcon
264
+ if (lowerName.endsWith('.jsx')) return reactIcon
265
+ return FILE_ICONS_BY_EXTENSION[fileExtension.toLowerCase()] || documentIcon
132
266
  }
133
267
 
134
268
  export { folderIcon, folderOpenIcon, documentIcon }
135
-