@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
@@ -3,6 +3,7 @@ import { createPortal } from 'react-dom'
3
3
  import { Mic, MicOff, PhoneOff, Volume2 } from 'lucide-react'
4
4
  import { VoicePoweredOrb } from '../ui/voice-powered-orb'
5
5
  import { Button } from '../ui/button'
6
+ import { ApprovalCard } from './ApprovalCard'
6
7
  import './GeminiLiveOverlay.css'
7
8
 
8
9
  export interface GeminiLiveOverlayProps {
@@ -16,6 +17,8 @@ export interface GeminiLiveOverlayProps {
16
17
  voices: readonly string[]
17
18
  onChangeVoice: (voice: string) => void
18
19
  analyserRef?: RefObject<AnalyserNode | null>
20
+ pendingApproval?: any | null
21
+ onApproval?: (approved: boolean, autoApprove?: boolean, answer?: string) => void
19
22
  }
20
23
  const STATUS_LABEL: Record<GeminiLiveOverlayProps['status'], string> = {
21
24
  connecting: 'Connecting', listening: 'Listening', speaking: 'Speaking',
@@ -30,14 +33,27 @@ const STATUS_HINT: Record<GeminiLiveOverlayProps['status'], string> = {
30
33
  error: 'End this call and try again when you’re ready.',
31
34
  }
32
35
 
36
+ export function resolveLiveOverlayEscape(state: {
37
+ voicePickerOpen: boolean
38
+ hasPendingApproval: boolean
39
+ }): 'close_voice_picker' | 'ignore' | 'end_call' {
40
+ if (state.voicePickerOpen) return 'close_voice_picker'
41
+ if (state.hasPendingApproval) return 'ignore'
42
+ return 'end_call'
43
+ }
44
+
33
45
  export default function GeminiLiveOverlay({
34
46
  status, userTranscript, assistantTranscript, isPaused, onTogglePause, onEndCall,
35
- voice, voices, onChangeVoice, analyserRef,
47
+ voice, voices, onChangeVoice, analyserRef, pendingApproval, onApproval,
36
48
  }: GeminiLiveOverlayProps) {
37
49
  const [voicePickerOpen, setVoicePickerOpen] = useState(false)
38
50
  const dialogRef = useRef<HTMLDivElement>(null)
39
51
  const endCall = useRef(onEndCall)
40
52
  endCall.current = onEndCall
53
+ const voicePickerOpenRef = useRef(voicePickerOpen)
54
+ voicePickerOpenRef.current = voicePickerOpen
55
+ const hasPendingApprovalRef = useRef(Boolean(pendingApproval && onApproval))
56
+ hasPendingApprovalRef.current = Boolean(pendingApproval && onApproval)
41
57
  // The decorative orb must not own a microphone in this call surface.
42
58
  const emptyAnalyser = useRef<AnalyserNode | null>(null)
43
59
  useEffect(() => {
@@ -47,9 +63,26 @@ export default function GeminiLiveOverlay({
47
63
  const dialog = dialogRef.current!
48
64
  dialog.querySelector<HTMLButtonElement>('[data-call-control]:not(:disabled), [aria-label="End Live conversation"]')?.focus()
49
65
  const onKey = (event: KeyboardEvent) => {
50
- if (event.key === 'Escape') { event.preventDefault(); endCall.current(); return }
66
+ if (event.key === 'Escape') {
67
+ const action = resolveLiveOverlayEscape({
68
+ voicePickerOpen: voicePickerOpenRef.current,
69
+ hasPendingApproval: hasPendingApprovalRef.current,
70
+ })
71
+ if (action === 'close_voice_picker') {
72
+ event.preventDefault()
73
+ setVoicePickerOpen(false)
74
+ } else if (action === 'end_call') {
75
+ event.preventDefault()
76
+ endCall.current()
77
+ }
78
+ return
79
+ }
51
80
  if (event.key !== 'Tab') return
52
- const controls = Array.from(dialog.querySelectorAll<HTMLElement>('button:not(:disabled), [tabindex="0"]'))
81
+ const controls = Array.from(
82
+ dialog.querySelectorAll<HTMLElement>(
83
+ 'button:not(:disabled), input:not(:disabled), textarea:not(:disabled), [tabindex="0"]',
84
+ ),
85
+ )
53
86
  const first = controls[0], last = controls[controls.length - 1]
54
87
  if (event.shiftKey && (document.activeElement === first || !dialog.contains(document.activeElement))) {
55
88
  event.preventDefault(); last?.focus()
@@ -85,6 +118,15 @@ export default function GeminiLiveOverlay({
85
118
  {assistantTranscript && <p className="gemini-live-transcript-line"><span className="gemini-live-transcript-speaker">Mint</span>{assistantTranscript}</p>}
86
119
  </> : <p className="live-orb-empty">{status === 'connecting' ? 'Your conversation will appear here.' : status === 'error' ? 'No conversation yet.' : 'Say something to get started…'}</p>}
87
120
  </div>
121
+ {pendingApproval && onApproval && (
122
+ <div className="gemini-live-approval" style={{ width: '100%', textAlign: 'left' }}>
123
+ <ApprovalCard
124
+ key={pendingApproval.id || JSON.stringify(pendingApproval)}
125
+ pendingApproval={pendingApproval}
126
+ onApproval={onApproval}
127
+ />
128
+ </div>
129
+ )}
88
130
  <div className="gemini-live-voice-picker">
89
131
  <Button type="button" variant="ghost" className="gemini-live-voice-btn" aria-label="Change voice" aria-expanded={voicePickerOpen} aria-haspopup="listbox" onClick={() => setVoicePickerOpen(open => !open)}>
90
132
  <Volume2 size={16} aria-hidden="true" /><span>{voice}</span>
@@ -1,7 +1,7 @@
1
1
  import React, { useState, useEffect, useRef, useMemo, useCallback } from 'react'
2
2
  import { useProviderModels } from '@/hooks/useProviderModels'
3
3
  import { catalogPlatform } from '../../platform'
4
- import { HF_MODELS, getModelMetadata, isFreeModel, OPENROUTER_POPULAR_MODELS } from '../../constants/models'
4
+ import { HF_MODELS, getModelMetadata, hasNativeThinkingSupport, isFreeModel, OPENROUTER_POPULAR_MODELS } from '../../constants/models'
5
5
  import type { CustomProviderConfig } from '../../types'
6
6
  import anthropicLogo from '@lobehub/icons-static-svg/icons/anthropic.svg?url'
7
7
  import deepseekLogo from '@lobehub/icons-static-svg/icons/deepseek-color.svg?url'
@@ -427,17 +427,28 @@ export default function ModelSelectorPopover({
427
427
  // Helper to resolve a model's thinking status
428
428
  const getThinkingConfig = useCallback((model: string, provider: string) => {
429
429
  const meta = getModelMetadata(model, provider)
430
+ const hasNative = hasNativeThinkingSupport(model, provider)
431
+ if (!meta.supportsThinking) {
432
+ return {
433
+ supported: false,
434
+ hasNative: false,
435
+ enabled: false,
436
+ effort: 'medium',
437
+ }
438
+ }
430
439
  const override = modelThinkingOverrides[model]
431
440
  if (override) {
432
441
  return {
433
- supported: meta.supportsThinking,
442
+ supported: true,
443
+ hasNative,
434
444
  enabled: override.enabled ?? true,
435
445
  effort: (override.effort || 'medium').toLowerCase(),
436
446
  }
437
447
  }
438
448
  return {
439
- supported: meta.supportsThinking,
440
- enabled: meta.supportsThinking ? (settingsConfig?.thinkingEnabled ?? true) : false,
449
+ supported: true,
450
+ hasNative,
451
+ enabled: hasNative ? (settingsConfig?.thinkingEnabled ?? true) : false,
441
452
  effort: (settingsConfig?.thinkingEffort || 'medium').toLowerCase(),
442
453
  }
443
454
  }, [modelThinkingOverrides, settingsConfig?.thinkingEnabled, settingsConfig?.thinkingEffort])
@@ -567,7 +578,7 @@ export default function ModelSelectorPopover({
567
578
  }, [currentInspected])
568
579
 
569
580
  const inspectedThinking = useMemo(() => {
570
- if (!currentInspected) return { supported: false, enabled: false, effort: 'medium' }
581
+ if (!currentInspected) return { supported: false, hasNative: false, enabled: false, effort: 'medium' }
571
582
  return getThinkingConfig(currentInspected.model, currentInspected.providerId)
572
583
  }, [currentInspected, getThinkingConfig])
573
584
 
@@ -857,9 +868,12 @@ export default function ModelSelectorPopover({
857
868
  <button
858
869
  type="button"
859
870
  role="switch"
871
+ disabled={!inspectedThinking.supported}
860
872
  aria-checked={inspectedThinking.enabled}
861
873
  className={`model-detail-switch ${inspectedThinking.enabled ? 'checked' : ''}`}
874
+ style={!inspectedThinking.supported ? { opacity: 0.45, cursor: 'not-allowed' } : undefined}
862
875
  onClick={() => {
876
+ if (!inspectedThinking.supported) return
863
877
  persistThinking(
864
878
  currentInspected.model,
865
879
  !inspectedThinking.enabled,
@@ -867,7 +881,9 @@ export default function ModelSelectorPopover({
867
881
  )
868
882
  }}
869
883
  title={
870
- inspectedThinking.enabled
884
+ !inspectedThinking.supported
885
+ ? 'Thinking is not available for non-text models'
886
+ : inspectedThinking.enabled
871
887
  ? 'Disable thinking'
872
888
  : 'Enable thinking'
873
889
  }
@@ -876,16 +892,28 @@ export default function ModelSelectorPopover({
876
892
  </button>
877
893
  </div>
878
894
 
879
- {!inspectedThinking.supported && (
880
- <div className="model-unsupported-note" style={{ color: inspectedThinking.enabled ? 'var(--interactive-fg)' : undefined }}>
881
- {inspectedThinking.enabled
882
- ? 'Thinking enabled (force toggle)'
883
- : 'Not flagged as reasoning model by default (toggle to force enable)'}
884
- </div>
885
- )}
895
+ <div
896
+ className="model-unsupported-note"
897
+ style={{
898
+ color:
899
+ inspectedThinking.supported && inspectedThinking.enabled
900
+ ? 'var(--interactive-fg)'
901
+ : undefined,
902
+ }}
903
+ >
904
+ {!inspectedThinking.supported
905
+ ? 'Non-text model (image/audio/embedding) — Thinking is not applicable'
906
+ : inspectedThinking.enabled
907
+ ? inspectedThinking.hasNative
908
+ ? 'Native Reasoning API active'
909
+ : 'Prompted Chain-of-Thought (<think>) active'
910
+ : inspectedThinking.hasNative
911
+ ? 'Supports Native Reasoning API'
912
+ : 'Supports Prompted Chain-of-Thought (<think>)'}
913
+ </div>
886
914
 
887
915
  {/* Effort Section (visible when Thinking is ON) */}
888
- {inspectedThinking.enabled && (
916
+ {inspectedThinking.supported && inspectedThinking.enabled && (
889
917
  <div className="model-effort-section">
890
918
  <div className="model-detail-section-title">Effort</div>
891
919
  <div className="model-effort-list">
@@ -100,7 +100,7 @@ export const RewindModal: React.FC<RewindModalProps> = ({
100
100
  style={{
101
101
  width: '32px',
102
102
  height: '32px',
103
- borderRadius: '8px',
103
+ borderRadius: 'var(--radius-sm, 8px)',
104
104
  background: 'color-mix(in srgb, var(--status-error, #ef4444) 15%, transparent)',
105
105
  color: 'var(--status-error, #ef4444)',
106
106
  display: 'inline-flex',
@@ -133,7 +133,7 @@ export const RewindModal: React.FC<RewindModalProps> = ({
133
133
  color: 'var(--text-muted)',
134
134
  cursor: isLoading ? 'not-allowed' : 'pointer',
135
135
  padding: '6px',
136
- borderRadius: '6px',
136
+ borderRadius: 'var(--radius-xs, 6px)',
137
137
  display: 'flex',
138
138
  alignItems: 'center',
139
139
  justifyContent: 'center',
@@ -152,7 +152,7 @@ export const RewindModal: React.FC<RewindModalProps> = ({
152
152
  <div
153
153
  style={{
154
154
  padding: '12px 14px',
155
- borderRadius: '10px',
155
+ borderRadius: 'var(--radius-md, 10px)',
156
156
  background: 'color-mix(in srgb, var(--status-error, #ef4444) 10%, transparent)',
157
157
  border: '1px solid color-mix(in srgb, var(--status-error, #ef4444) 25%, transparent)',
158
158
  fontSize: '13px',
@@ -181,7 +181,7 @@ export const RewindModal: React.FC<RewindModalProps> = ({
181
181
  style={{
182
182
  background: 'var(--surface-bg)',
183
183
  border: '1px solid var(--border)',
184
- borderRadius: '10px',
184
+ borderRadius: 'var(--radius-md, 10px)',
185
185
  padding: '14px',
186
186
  display: 'flex',
187
187
  flexDirection: 'column',
@@ -213,7 +213,7 @@ export const RewindModal: React.FC<RewindModalProps> = ({
213
213
  <span
214
214
  style={{
215
215
  padding: '3px 8px',
216
- borderRadius: '6px',
216
+ borderRadius: 'var(--radius-xs, 6px)',
217
217
  background: 'color-mix(in srgb, var(--accent) 15%, transparent)',
218
218
  color: 'var(--interactive-fg)',
219
219
  fontWeight: 600,
@@ -225,7 +225,7 @@ export const RewindModal: React.FC<RewindModalProps> = ({
225
225
  <code
226
226
  style={{
227
227
  padding: '3px 7px',
228
- borderRadius: '6px',
228
+ borderRadius: 'var(--radius-xs, 6px)',
229
229
  background: 'var(--bg-input, var(--bg-surface-soft))',
230
230
  color: 'var(--text-main)',
231
231
  fontSize: '12px',
@@ -263,7 +263,7 @@ export const RewindModal: React.FC<RewindModalProps> = ({
263
263
  maxHeight: '160px',
264
264
  overflowY: 'auto',
265
265
  border: '1px solid var(--border)',
266
- borderRadius: '8px',
266
+ borderRadius: 'var(--radius-sm, 8px)',
267
267
  background: 'var(--surface-bg)',
268
268
  display: 'flex',
269
269
  flexDirection: 'column',
@@ -307,7 +307,7 @@ export const RewindModal: React.FC<RewindModalProps> = ({
307
307
  fontSize: '10.5px',
308
308
  fontWeight: 600,
309
309
  padding: '1px 6px',
310
- borderRadius: '4px',
310
+ borderRadius: 'var(--radius-xs, 6px)',
311
311
  background: 'color-mix(in srgb, var(--accent) 15%, transparent)',
312
312
  color: 'var(--interactive-fg)',
313
313
  }}
@@ -354,7 +354,7 @@ export const RewindModal: React.FC<RewindModalProps> = ({
354
354
  disabled={isLoading}
355
355
  style={{
356
356
  padding: '8px 16px',
357
- borderRadius: '8px',
357
+ borderRadius: 'var(--radius-sm, 8px)',
358
358
  border: '1px solid var(--border)',
359
359
  background: 'transparent',
360
360
  color: 'var(--text-main)',
@@ -373,7 +373,7 @@ export const RewindModal: React.FC<RewindModalProps> = ({
373
373
  disabled={isLoading}
374
374
  style={{
375
375
  padding: '8px 18px',
376
- borderRadius: '8px',
376
+ borderRadius: 'var(--radius-sm, 8px)',
377
377
  border: 'none',
378
378
  background: 'var(--status-error, #ef4444)',
379
379
  color: '#ffffff',
@@ -2,6 +2,7 @@ import React from 'react'
2
2
  import { renderToStaticMarkup } from 'react-dom/server'
3
3
  import { describe, expect, it } from 'vitest'
4
4
  import SlashSuggestions from './SlashSuggestions'
5
+ import { executeSlashCommand } from '../../utils/slashCommandProcessor'
5
6
 
6
7
  const render = (message: string, suppressed = false) => renderToStaticMarkup(
7
8
  <SlashSuggestions message={message} onComplete={() => {}} anchorRef={{ current: null }} suppressed={suppressed} />,
@@ -18,6 +19,10 @@ describe('composer command suggestions', () => {
18
19
  const html = render('/st')
19
20
  expect(html.indexOf('>/stats<')).toBeLessThan(html.indexOf('>/mods<'))
20
21
  })
22
+ it('shows /resume above /retry when typing /r', () => {
23
+ const html = render('/r')
24
+ expect(html.indexOf('>/resume<')).toBeLessThan(html.indexOf('>/retry<'))
25
+ })
21
26
  it('keeps a command argument as a usage hint instead of unrelated search results', () => {
22
27
  const html = render('/remember a durable fact')
23
28
  expect(html).toContain('/remember')
@@ -30,4 +35,13 @@ describe('composer command suggestions', () => {
30
35
  expect(html).not.toContain('/theme')
31
36
  expect(render('/', true)).toBe('')
32
37
  })
38
+ it('lists /voice in the graphical menu and routes /voice to start_voice action', () => {
39
+ const html = render('/voice')
40
+ expect(html).toContain('/voice')
41
+ expect(executeSlashCommand('/voice')).toEqual({
42
+ handled: true,
43
+ action: 'start_voice',
44
+ payload: { mode: '' },
45
+ })
46
+ })
33
47
  })
@@ -0,0 +1,53 @@
1
+ import React from 'react'
2
+ import { renderToStaticMarkup } from 'react-dom/server'
3
+ import { describe, expect, it } from 'vitest'
4
+ import SourcesBlock, { groupSourcesByDomain } from './SourcesBlock'
5
+ import type { WebSearchSource } from '../../utils/agentActivity'
6
+
7
+ describe('SourcesBlock', () => {
8
+ const mockSources: WebSearchSource[] = [
9
+ {
10
+ title: 'Nahida Cosplay Album 1',
11
+ url: 'https://mitaku.net/album-1',
12
+ domain: 'mitaku.net',
13
+ faviconUrl: 'https://mitaku.net/favicon.ico',
14
+ },
15
+ {
16
+ title: 'Nahida Cosplay Album 2',
17
+ url: 'https://mitaku.net/album-2',
18
+ domain: 'mitaku.net',
19
+ faviconUrl: 'https://mitaku.net/favicon.ico',
20
+ },
21
+ {
22
+ title: 'Mococo Cosplay',
23
+ url: 'https://e-hentai.org/g/12345',
24
+ domain: 'e-hentai.org',
25
+ faviconUrl: 'https://e-hentai.org/favicon.ico',
26
+ },
27
+ ]
28
+
29
+ it('groups sources by domain correctly', () => {
30
+ const groups = groupSourcesByDomain(mockSources)
31
+ expect(groups.length).toBe(2)
32
+ expect(groups[0].domain).toBe('mitaku.net')
33
+ expect(groups[0].displayDomain).toBe('mitaku')
34
+ expect(groups[0].items.length).toBe(2)
35
+ expect(groups[1].domain).toBe('e-hentai.org')
36
+ expect(groups[1].displayDomain).toBe('e-hentai')
37
+ expect(groups[1].items.length).toBe(1)
38
+ })
39
+
40
+ it('renders domain group cards with extra count badge', () => {
41
+ const html = renderToStaticMarkup(<SourcesBlock sources={mockSources} />)
42
+ expect(html).toContain('Sources')
43
+ expect(html).toContain('mitaku')
44
+ expect(html).toContain('+1')
45
+ expect(html).toContain('e-hentai')
46
+ expect(html).toContain('extra-badge-btn')
47
+ })
48
+
49
+ it('returns null when sources list is empty', () => {
50
+ const html = renderToStaticMarkup(<SourcesBlock sources={[]} />)
51
+ expect(html).toBe('')
52
+ })
53
+ })