@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,648 @@
1
+ use std::future::Future;
2
+ use std::sync::Arc;
3
+
4
+ use serde::{Deserialize, Serialize};
5
+ use serde_json::Value;
6
+ use thiserror::Error;
7
+
8
+ use crate::CodePatchHunk;
9
+ use crate::agent::chat::{ChatError, ChatResponse};
10
+ use crate::memory::{MemoryError, MemoryStore};
11
+
12
+ use super::reliability;
13
+ use super::trajectory_schema;
14
+
15
+ struct TurnStartListener {
16
+ chat_id: String,
17
+ callback: Arc<dyn Fn(i64) + Send + Sync>,
18
+ }
19
+
20
+ tokio::task_local! {
21
+ static TURN_START_LISTENER: TurnStartListener;
22
+ }
23
+
24
+ /// Reports the persisted turn ID to the initiating transport without changing
25
+ /// the agent/chat interfaces used by CLI, jobs, and background integrations.
26
+ pub async fn with_turn_start_listener<F, R>(
27
+ chat_id: String,
28
+ callback: impl Fn(i64) + Send + Sync + 'static,
29
+ future: F,
30
+ ) -> R
31
+ where
32
+ F: Future<Output = R>,
33
+ {
34
+ TURN_START_LISTENER
35
+ .scope(
36
+ TurnStartListener {
37
+ chat_id,
38
+ callback: Arc::new(callback),
39
+ },
40
+ future,
41
+ )
42
+ .await
43
+ }
44
+
45
+ /// Owns one persisted turn, including its cross-process queue lease. Dropping a
46
+ /// cancelled task marks its prompt interrupted instead of leaving it running.
47
+ pub(super) struct TurnLease {
48
+ pub(super) chat_id: String,
49
+ memory: MemoryStore,
50
+ pub(super) id: i64,
51
+ heartbeat: tokio::task::JoinHandle<()>,
52
+ pub(super) finished: bool,
53
+ pub(super) activity: Arc<std::sync::Mutex<Vec<AgentProgress>>>,
54
+ }
55
+
56
+ impl TurnLease {
57
+ pub(super) async fn start(
58
+ memory: &MemoryStore,
59
+ chat_id: &str,
60
+ text: &str,
61
+ ) -> Result<Self, MemoryError> {
62
+ let id = memory.start_turn(chat_id, text)?;
63
+ crate::tts::playback::cancel_chat(memory, chat_id);
64
+ crate::companion::queued(chat_id, id, text);
65
+ let _ = TURN_START_LISTENER.try_with(|listener| {
66
+ if listener.chat_id == chat_id {
67
+ (listener.callback)(id);
68
+ }
69
+ });
70
+ let heartbeat_memory = memory.clone();
71
+ let heartbeat = tokio::spawn(async move {
72
+ loop {
73
+ tokio::time::sleep(std::time::Duration::from_secs(10)).await;
74
+ if heartbeat_memory.renew_turn(id).is_err() {
75
+ break;
76
+ }
77
+ }
78
+ });
79
+ let mut lease = Self {
80
+ chat_id: chat_id.to_owned(),
81
+ memory: memory.clone(),
82
+ id,
83
+ heartbeat,
84
+ finished: false,
85
+ activity: Arc::new(std::sync::Mutex::new(Vec::new())),
86
+ };
87
+ loop {
88
+ match memory.claim_turn(chat_id, id) {
89
+ Ok(true) => {
90
+ crate::companion::update(
91
+ chat_id,
92
+ id,
93
+ mint_companion_protocol::Status::Thinking,
94
+ None,
95
+ );
96
+ return Ok(lease);
97
+ }
98
+ Ok(false) => tokio::time::sleep(std::time::Duration::from_millis(250)).await,
99
+ Err(error) => {
100
+ lease.fail();
101
+ return Err(error);
102
+ }
103
+ }
104
+ }
105
+ }
106
+
107
+ pub(super) fn persist_activity(&self) {
108
+ if let Ok(lock) = self.activity.lock() {
109
+ let compacted = compact_agent_progress(&lock);
110
+ if !compacted.is_empty() {
111
+ if let Ok(activity_json) = serde_json::to_string(&compacted) {
112
+ let _ = self
113
+ .memory
114
+ .set_interaction_agent_activity_json(self.id, &activity_json);
115
+ }
116
+ }
117
+ }
118
+ }
119
+
120
+ pub(super) fn complete_with_summary(
121
+ &mut self,
122
+ summary: &str,
123
+ provider: &str,
124
+ model: &str,
125
+ fallback_provider: Option<&str>,
126
+ ) -> Result<(), MemoryError> {
127
+ self.persist_activity();
128
+ self.memory
129
+ .finish_turn(self.id, summary, provider, model, fallback_provider)?;
130
+ self.finished = true;
131
+ crate::companion::update(
132
+ &self.chat_id,
133
+ self.id,
134
+ mint_companion_protocol::Status::Completed,
135
+ Some(summary.to_owned()),
136
+ );
137
+ Ok(())
138
+ }
139
+
140
+ pub(super) fn complete(&mut self, response: &ChatResponse) -> Result<(), MemoryError> {
141
+ self.complete_with_summary(
142
+ &response.text,
143
+ &response.provider,
144
+ &response.model,
145
+ response.fallback_provider.as_deref(),
146
+ )
147
+ }
148
+
149
+ pub(super) fn fail(&mut self) {
150
+ self.persist_activity();
151
+ let _ = self.memory.end_turn(self.id, "failed");
152
+ crate::companion::update(
153
+ &self.chat_id,
154
+ self.id,
155
+ mint_companion_protocol::Status::Failed,
156
+ None,
157
+ );
158
+ self.finished = true;
159
+ }
160
+
161
+ pub(super) fn interrupt(&mut self) {
162
+ self.persist_activity();
163
+ let _ = self.memory.end_turn(self.id, "interrupted");
164
+ crate::companion::update(
165
+ &self.chat_id,
166
+ self.id,
167
+ mint_companion_protocol::Status::Interrupted,
168
+ None,
169
+ );
170
+ self.finished = true;
171
+ }
172
+ }
173
+
174
+ impl Drop for TurnLease {
175
+ fn drop(&mut self) {
176
+ self.heartbeat.abort();
177
+ if !self.finished {
178
+ self.persist_activity();
179
+ let _ = self.memory.end_turn(self.id, "interrupted");
180
+ crate::companion::update(
181
+ &self.chat_id,
182
+ self.id,
183
+ mint_companion_protocol::Status::Interrupted,
184
+ None,
185
+ );
186
+ }
187
+ }
188
+ }
189
+
190
+ #[derive(Debug, Error)]
191
+ pub enum OrchestrationError {
192
+ #[error(transparent)]
193
+ Chat(#[from] ChatError),
194
+ #[error(transparent)]
195
+ Memory(#[from] MemoryError),
196
+ #[error("agent error: {0}")]
197
+ Agent(String),
198
+ }
199
+
200
+ /// A selectable option presented to the user during an [`AgentApproval::AskUser`]
201
+ /// prompt, carrying a primary label and optional detail text for both the CLI
202
+ /// picker and the desktop/web approval card.
203
+ #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
204
+ pub struct AskUserOption {
205
+ pub label: String,
206
+ #[serde(default)]
207
+ pub description: Option<String>,
208
+ }
209
+
210
+ #[derive(Debug, Clone, Serialize, Deserialize)]
211
+ pub enum AgentApproval {
212
+ /// Persistent agent instructions need a decision for each concrete diff.
213
+ SkillWrite {
214
+ path: String,
215
+ content: String,
216
+ diff: String,
217
+ },
218
+ WriteFile {
219
+ path: String,
220
+ content: String,
221
+ diff: String,
222
+ },
223
+ ApplyPatch {
224
+ path: String,
225
+ hunks: Vec<CodePatchHunk>,
226
+ diff: String,
227
+ },
228
+ RunShell {
229
+ command: String,
230
+ mode: String,
231
+ background: bool,
232
+ },
233
+ NoteWrite {
234
+ path: String,
235
+ content: String,
236
+ },
237
+ RunPlugin {
238
+ name: String,
239
+ instruction: String,
240
+ },
241
+ McpTool {
242
+ server: String,
243
+ tool: String,
244
+ arguments: Value,
245
+ },
246
+ UserApproval {
247
+ title: String,
248
+ prompt: String,
249
+ },
250
+ AskUser {
251
+ question: String,
252
+ #[serde(default)]
253
+ options: Vec<AskUserOption>,
254
+ #[serde(default)]
255
+ header: Option<String>,
256
+ #[serde(default, rename = "multiSelect")]
257
+ multi_select: bool,
258
+ },
259
+ ExitPlanMode {
260
+ plan: String,
261
+ },
262
+ EnterPlanMode {
263
+ reason: String,
264
+ },
265
+ }
266
+
267
+ #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
268
+ pub enum ApprovalOutcome {
269
+ Approved,
270
+ Denied,
271
+ Intercepted(String),
272
+ }
273
+
274
+ /// The `answer` string a surface returns from an [`AgentApproval::McpTool`]
275
+ /// prompt to mean "run this call **and** persist `allowedMcpTools[server] =
276
+ /// ["*"]`, so this server never prompts again". Travels through the normal
277
+ /// `Intercepted(answer)` channel. The CLI approval picker
278
+ /// (`crates/mint-cli/src/agent.rs`) and the web/desktop `ApprovalCard`
279
+ /// (`src/renderer/shared/components/ApprovalCard.tsx`) send this exact string.
280
+ pub const MCP_ALLOW_ALL_SENTINEL: &str = "__mcp_allow_all__";
281
+
282
+ #[derive(Debug, Clone, Serialize, Deserialize)]
283
+ #[serde(tag = "type", content = "data")]
284
+ pub enum AgentProgress {
285
+ ToolDiscovery {
286
+ server: String,
287
+ tool: String,
288
+ message: String,
289
+ },
290
+ DeviceState {
291
+ #[serde(rename = "callId")]
292
+ call_id: String,
293
+ server: String,
294
+ tool: String,
295
+ update: crate::mcp::device::DeviceUpdate,
296
+ },
297
+ ToolProgress {
298
+ #[serde(rename = "callId")]
299
+ call_id: String,
300
+ server: String,
301
+ tool: String,
302
+ update: crate::mcp::McpProgress,
303
+ },
304
+ ToolArtifacts {
305
+ #[serde(rename = "callId")]
306
+ call_id: String,
307
+ artifacts: Vec<crate::integrations::mcp_result::McpArtifact>,
308
+ warnings: Vec<String>,
309
+ },
310
+ ExecutionUpdate {
311
+ #[serde(rename = "callId")]
312
+ call_id: String,
313
+ executions: Vec<reliability::ExecutionEvidence>,
314
+ },
315
+ Thinking {
316
+ elapsed_secs: u64,
317
+ #[serde(skip_serializing_if = "Option::is_none")]
318
+ agent_name: Option<String>,
319
+ #[serde(skip_serializing_if = "Option::is_none")]
320
+ model_name: Option<String>,
321
+ /// Context-window usage as of the last completed step, 0-100 — the
322
+ /// last thing we actually know, since usage is only reported in a
323
+ /// step's *response*, not predictable mid-generation. `None` until
324
+ /// the first step of a task has completed at least once.
325
+ #[serde(skip_serializing_if = "Option::is_none")]
326
+ context_pct: Option<u8>,
327
+ /// Running sum of `total_tokens` across every step completed so far
328
+ /// this turn — same accumulator as `AgentResult::total_tokens`, just
329
+ /// surfaced live instead of only once the turn finishes, so the CLI
330
+ /// can count it up next to the "Thinking…" label the way Claude Code
331
+ /// does. 0 until the first step has completed.
332
+ #[serde(default)]
333
+ tokens_used: u64,
334
+ /// Prompt/context tokens the *most recent* completed step processed
335
+ /// (system prompt + tool schemas + the whole resent history) — the
336
+ /// `↑` half of the live counter. Latest-step, not summed: it tracks
337
+ /// how full the context window is, and summing would count the resent
338
+ /// history once per step. 0 until the first step has completed.
339
+ #[serde(default)]
340
+ input_tokens: u64,
341
+ /// Running sum of completion tokens the model generated across every
342
+ /// step this turn — the `↓` half. Summed (unlike `input_tokens`),
343
+ /// since each step's output is distinct work. 0 until the first step
344
+ /// has completed.
345
+ #[serde(default)]
346
+ generated_tokens: u64,
347
+ /// Rough char-count-based estimate of the very first request's size
348
+ /// — constant across every step of the turn. Only meaningful to a
349
+ /// consumer while `tokens_used` is still 0 (i.e. step 1's response
350
+ /// hasn't come back yet), as a stand-in until the real number
351
+ /// exists; ignored once `tokens_used` is nonzero.
352
+ #[serde(default)]
353
+ estimated_tokens: u64,
354
+ },
355
+ Thought {
356
+ thought: String,
357
+ },
358
+ /// Incremental model reasoning for the currently active agent step. These
359
+ /// events are live-only; consumers replace them with the matching final
360
+ /// `ExtendedThinking` record instead of persisting every delta.
361
+ ThinkingDelta {
362
+ id: String,
363
+ delta: String,
364
+ elapsed_ms: u64,
365
+ },
366
+ /// Extended reasoning / chain-of-thought from the model's API thinking
367
+ /// tokens (e.g. Claude `<thinking>`, Gemini Thinking, DeepSeek Reasoner,
368
+ /// or `<think>` tags). Semantically distinct from `Thought`, which
369
+ /// carries short, one-line agent notes (fallback warnings, decision
370
+ /// summaries). The CLI renders this as a collapsible block; the web/
371
+ /// desktop UI shows it in a dedicated "Extended Thinking" panel.
372
+ ExtendedThinking {
373
+ #[serde(default, skip_serializing_if = "Option::is_none")]
374
+ id: Option<String>,
375
+ thought: String,
376
+ #[serde(default, skip_serializing_if = "Option::is_none")]
377
+ elapsed_ms: Option<u64>,
378
+ },
379
+ /// Lifecycle of native context summarization, including actionable failures.
380
+ ContextCompaction {
381
+ #[serde(default, skip_serializing_if = "Option::is_none")]
382
+ subagent: Option<String>,
383
+ status: String,
384
+ message: String,
385
+ },
386
+ /// Emitted while retrying a step after every configured provider was
387
+ /// unreachable (`ChatError::NetworkUnavailable`) — distinct from
388
+ /// `Thinking` because there's nothing to wait *on* here except the
389
+ /// network itself coming back, not a model generating a reply.
390
+ WaitingForNetwork {
391
+ attempt: usize,
392
+ max_attempts: usize,
393
+ },
394
+ ToolStart {
395
+ #[serde(default, rename = "callId", skip_serializing_if = "Option::is_none")]
396
+ call_id: Option<String>,
397
+ action: String,
398
+ input: Value,
399
+ /// Name of the subagent this tool call happened inside, if any —
400
+ /// `None` for the top-level agent's own calls. Set by
401
+ /// `dispatch_one_subagent` wrapping the nested loop's `progress` so
402
+ /// the CLI/GUI can render a subagent's own tool calls nested under
403
+ /// its `dispatch_subagent` call instead of indistinguishable from
404
+ /// the parent's.
405
+ #[serde(default, skip_serializing_if = "Option::is_none")]
406
+ subagent: Option<String>,
407
+ },
408
+ ToolEnd {
409
+ #[serde(default, alias = "elapsedMs", skip_serializing_if = "Option::is_none")]
410
+ elapsed_ms: Option<u64>,
411
+ #[serde(default, rename = "callId", skip_serializing_if = "Option::is_none")]
412
+ call_id: Option<String>,
413
+ #[serde(default, skip_serializing_if = "Option::is_none")]
414
+ status: Option<crate::integrations::mcp_result::ToolStatus>,
415
+ action: String,
416
+ input: Value,
417
+ result: String,
418
+ #[serde(default, skip_serializing_if = "Option::is_none")]
419
+ subagent: Option<String>,
420
+ },
421
+ PlanUpdated {
422
+ plan: ActivePlan,
423
+ },
424
+ RunCompleted {
425
+ summary: RunTelemetrySummary,
426
+ },
427
+ SubagentStarted {
428
+ subagent: String,
429
+ profile: String,
430
+ task: String,
431
+ },
432
+ SubagentFinished {
433
+ subagent: String,
434
+ status: String,
435
+ #[serde(default, alias = "elapsed_ms", rename = "elapsedMs")]
436
+ elapsed_ms: u64,
437
+ steps: u32,
438
+ #[serde(default, alias = "summary_preview", rename = "summaryPreview")]
439
+ summary_preview: String,
440
+ },
441
+ }
442
+
443
+ impl From<crate::swarm::SwarmEvent> for AgentProgress {
444
+ fn from(event: crate::swarm::SwarmEvent) -> Self {
445
+ match event {
446
+ crate::swarm::SwarmEvent::Started {
447
+ label,
448
+ profile,
449
+ task,
450
+ } => AgentProgress::SubagentStarted {
451
+ subagent: label,
452
+ profile,
453
+ task,
454
+ },
455
+ crate::swarm::SwarmEvent::Progress(p) => p,
456
+ crate::swarm::SwarmEvent::Finished {
457
+ label,
458
+ status,
459
+ elapsed_ms,
460
+ steps,
461
+ summary_preview,
462
+ } => AgentProgress::SubagentFinished {
463
+ subagent: label,
464
+ status: status.as_str().to_string(),
465
+ elapsed_ms,
466
+ steps,
467
+ summary_preview,
468
+ },
469
+ }
470
+ }
471
+ }
472
+
473
+ /// Determines whether a thought string represents long-form / internal chain-of-thought
474
+ /// (reasoning tokens, <think> tags, or multi-line reasoning) versus a brief agent note.
475
+ pub fn is_internal_cot(text: &str) -> bool {
476
+ let trimmed = text.trim();
477
+ if trimmed.starts_with("<think>") || trimmed.contains("</think>") {
478
+ return true;
479
+ }
480
+ let line_count = trimmed.lines().count();
481
+ let char_count = trimmed.chars().count();
482
+ if trimmed.contains("\n\n") || line_count > 2 || char_count > 180 {
483
+ return true;
484
+ }
485
+ let lower = trimmed.to_lowercase();
486
+ if lower.starts_with("the user ")
487
+ || lower.starts_with("let's think")
488
+ || lower.starts_with("let me analyze")
489
+ || lower.starts_with("per rule")
490
+ || lower.starts_with("note the ")
491
+ || lower.contains("thinking process:")
492
+ {
493
+ return true;
494
+ }
495
+ false
496
+ }
497
+
498
+ /// Compacts an agent progress event stream for storage, removing transport-only
499
+ /// streaming deltas (`ThinkingDelta`) while preserving complete `ExtendedThinking`
500
+ /// blocks, or synthesizing an `ExtendedThinking` block for any interrupted delta sequence.
501
+ pub fn compact_agent_progress(progress: &[AgentProgress]) -> Vec<AgentProgress> {
502
+ let completed_ids: std::collections::HashSet<String> = progress
503
+ .iter()
504
+ .filter_map(|event| match event {
505
+ AgentProgress::ExtendedThinking { id: Some(id), .. } => Some(id.clone()),
506
+ _ => None,
507
+ })
508
+ .collect();
509
+
510
+ let mut result = Vec::new();
511
+ let mut interrupted_order: Vec<String> = Vec::new();
512
+ let mut interrupted: std::collections::HashMap<String, (String, Option<u64>)> =
513
+ std::collections::HashMap::new();
514
+
515
+ let latest_progress: std::collections::HashMap<(u8, &str), usize> = progress
516
+ .iter()
517
+ .enumerate()
518
+ .filter_map(|(i, event)| match event {
519
+ AgentProgress::ToolProgress { call_id, .. } => Some(((0, call_id.as_str()), i)),
520
+ AgentProgress::DeviceState {
521
+ call_id, update, ..
522
+ } if !matches!(update.state, crate::mcp::device::DevicePhase::Accepted) => {
523
+ Some(((1, call_id.as_str()), i))
524
+ }
525
+ AgentProgress::PlanUpdated { .. } => Some(((2, "plan"), i)),
526
+ _ => None,
527
+ })
528
+ .collect();
529
+ for (index, event) in progress.iter().enumerate() {
530
+ let key = match event {
531
+ AgentProgress::ToolProgress { call_id, .. } => Some((0, call_id.as_str())),
532
+ AgentProgress::DeviceState {
533
+ call_id, update, ..
534
+ } if !matches!(update.state, crate::mcp::device::DevicePhase::Accepted) => {
535
+ Some((1, call_id.as_str()))
536
+ }
537
+ AgentProgress::PlanUpdated { .. } => Some((2, "plan")),
538
+ _ => None,
539
+ };
540
+ if key.is_some_and(|key| latest_progress.get(&key) != Some(&index)) {
541
+ continue;
542
+ }
543
+ match event {
544
+ AgentProgress::ThinkingDelta {
545
+ id,
546
+ delta,
547
+ elapsed_ms,
548
+ } => {
549
+ if !completed_ids.contains(id) {
550
+ if !interrupted.contains_key(id) {
551
+ interrupted_order.push(id.clone());
552
+ }
553
+ interrupted
554
+ .entry(id.clone())
555
+ .and_modify(|(text, elapsed)| {
556
+ text.push_str(delta);
557
+ *elapsed = Some(*elapsed_ms);
558
+ })
559
+ .or_insert_with(|| (delta.clone(), Some(*elapsed_ms)));
560
+ }
561
+ }
562
+ _ => {
563
+ result.push(event.clone());
564
+ }
565
+ }
566
+ }
567
+
568
+ for id in interrupted_order {
569
+ if let Some((thought, elapsed_ms)) = interrupted.remove(&id) {
570
+ result.push(AgentProgress::ExtendedThinking {
571
+ id: Some(id),
572
+ thought,
573
+ elapsed_ms,
574
+ });
575
+ }
576
+ }
577
+
578
+ result
579
+ }
580
+
581
+ #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
582
+ #[serde(rename_all = "camelCase")]
583
+ pub struct ToolExecutionRecord {
584
+ pub step: usize,
585
+ pub action: String,
586
+ pub target: String,
587
+ pub success: bool,
588
+ pub retried: bool,
589
+ }
590
+
591
+ #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
592
+ #[serde(rename_all = "camelCase")]
593
+ pub struct RunTelemetrySummary {
594
+ pub run_id: String,
595
+ pub task: String,
596
+ pub outcome: String, // "SUCCESS" | "FAILED" | "ROLLED_BACK"
597
+ pub total_tokens: usize,
598
+ pub tool_calls_count: usize,
599
+ pub files_changed: Vec<String>,
600
+ #[serde(default)]
601
+ pub files_created: Vec<String>,
602
+ pub duration_secs: f64,
603
+ pub tool_timeline: Vec<ToolExecutionRecord>,
604
+ pub retries_count: usize,
605
+ #[serde(default, skip_serializing_if = "Option::is_none")]
606
+ pub trajectory: Option<trajectory_schema::StandardTrajectoryRun>,
607
+ }
608
+
609
+ #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
610
+ #[serde(rename_all = "camelCase")]
611
+ pub struct PlanTaskItem {
612
+ pub id: String,
613
+ pub title: String,
614
+ pub status: String, // "pending", "in_progress", "completed", "failed"
615
+ }
616
+
617
+ #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
618
+ #[serde(rename_all = "camelCase")]
619
+ pub struct ActivePlan {
620
+ pub objective: String,
621
+ pub tasks: Vec<PlanTaskItem>,
622
+ }
623
+
624
+ #[derive(Debug, Clone, Serialize, Deserialize)]
625
+ #[serde(rename_all = "camelCase")]
626
+ pub struct AgentResult {
627
+ pub provider: String,
628
+ pub model: String,
629
+ pub summary: String,
630
+ pub verification: String,
631
+ #[serde(default)]
632
+ pub completion_status: String,
633
+ pub fallback: Option<String>,
634
+ #[serde(default)]
635
+ pub fallback_reason: Option<String>,
636
+ /// Sum of `total_tokens` across every step's API response this turn —
637
+ /// see the doc comment on `turn_total_tokens` where it's accumulated.
638
+ pub total_tokens: u64,
639
+ /// Prompt/context tokens the final step processed (latest-step, not summed
640
+ /// — see `AgentProgress::Thinking::input_tokens`). The `↑` half of the
641
+ /// turn footer's token counter.
642
+ #[serde(default)]
643
+ pub input_tokens: u64,
644
+ /// Sum of completion tokens generated across every step this turn — the
645
+ /// `↓` half of the turn footer's token counter.
646
+ #[serde(default)]
647
+ pub generated_tokens: u64,
648
+ }
@@ -10,9 +10,6 @@ pub(super) fn looks_skill_worthy(step: usize, action_counts: &BTreeMap<String, u
10
10
  "apply_patch",
11
11
  "write_file",
12
12
  "run_shell",
13
- "browser_open",
14
- "browser_click",
15
- "browser_type",
16
13
  "dispatch_agents",
17
14
  "dispatch_subagent",
18
15
  ];
@@ -217,7 +217,6 @@ pub(super) async fn run_shell(
217
217
  command: &str,
218
218
  retry_reason: &str,
219
219
  ) -> Result<String, OrchestrationError> {
220
- tools::shell::prevent_duplicate_browser_launch(command).await?;
221
220
  run_control::check()?;
222
221
  if let Err(reason) = reliability::before_shell(command, retry_reason) {
223
222
  return Ok(format!("Skipped: {reason}"));
@@ -245,9 +244,13 @@ pub(super) async fn run_shell(
245
244
  .map_err(|e| OrchestrationError::Agent(format!("shell command task panicked: {e}")))?
246
245
  .map_err(|e| OrchestrationError::Agent(e.to_string()))?
247
246
  };
248
- let status_str = output
249
- .status
250
- .map_or_else(|| "unknown".into(), |status| status.to_string());
247
+ let status_str = if let Some(job_id) = &output.job_id {
248
+ format!("running_in_background (job_id: {job_id})")
249
+ } else {
250
+ output
251
+ .status
252
+ .map_or_else(|| "unknown".into(), |status| status.to_string())
253
+ };
251
254
 
252
255
  reliability::record_shell(&output);
253
256
 
@@ -257,9 +260,24 @@ pub(super) async fn run_shell(
257
260
  .map(|warning| format!("\n[Warning] {warning}"))
258
261
  .unwrap_or_default();
259
262
 
263
+ let notice = if let Some(job_id) = &output.job_id {
264
+ format!(
265
+ "\n[SYSTEM NOTICE] The command exceeded 180s and is STILL RUNNING in the background (job_id: {job_id}). \
266
+ DO NOT retry or run an alternative script. Use shell_output(job_id: \"{job_id}\") to monitor its progress.\n"
267
+ )
268
+ } else {
269
+ String::new()
270
+ };
271
+
260
272
  Ok(format!(
261
- "exit: {}\nmode: {}\nsandboxed: {}{}\nstdout:\n{}\nstderr:\n{}",
262
- status_str, output.mode, output.sandboxed, warning_line, output.stdout, output.stderr
273
+ "exit: {}\nmode: {}\nsandboxed: {}{}{}\nstdout:\n{}\nstderr:\n{}",
274
+ status_str,
275
+ output.mode,
276
+ output.sandboxed,
277
+ warning_line,
278
+ notice,
279
+ output.stdout,
280
+ output.stderr
263
281
  ))
264
282
  }
265
283