@pheem49/mint 1.15.0 → 1.16.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 (644) hide show
  1. package/Cargo.lock +1012 -69
  2. package/Cargo.toml +5 -2
  3. package/LICENSE +21 -654
  4. package/README.md +92 -817
  5. package/Release_Note.md +53 -560
  6. package/apps/mint-companion/src-tauri/Cargo.toml +20 -0
  7. package/apps/mint-companion/src-tauri/build.rs +3 -0
  8. package/apps/mint-companion/src-tauri/src/main.rs +468 -0
  9. package/apps/mint-companion/tsconfig.json +20 -0
  10. package/apps/mint-companion/vite.config.ts +3 -0
  11. package/components.json +19 -0
  12. package/crates/mint-cli/Cargo.toml +6 -0
  13. package/crates/mint-cli/src/agent/live_status.rs +187 -39
  14. package/crates/mint-cli/src/agent.rs +323 -95
  15. package/crates/mint-cli/src/commands/agent.rs +69 -55
  16. package/crates/mint-cli/src/commands/integrations.rs +7 -0
  17. package/crates/mint-cli/src/commands/knowledge.rs +12 -32
  18. package/crates/mint-cli/src/commands/mod.rs +44 -0
  19. package/crates/mint-cli/src/image.rs +31 -33
  20. package/crates/mint-cli/src/interactive/chat_tui.rs +3594 -483
  21. package/crates/mint-cli/src/interactive/input_box.rs +56 -6
  22. package/crates/mint-cli/src/interactive/slash_commands.rs +208 -56
  23. package/crates/mint-cli/src/interactive/tool_activity.rs +328 -0
  24. package/crates/mint-cli/src/interactive.rs +64 -40
  25. package/crates/mint-cli/src/main.rs +13 -7
  26. package/crates/mint-cli/src/mcp.rs +5 -0
  27. package/crates/mint-cli/src/mod_host.rs +6 -0
  28. package/crates/mint-cli/src/mods_cli.rs +62 -0
  29. package/crates/mint-cli/src/mods_ui.rs +187 -0
  30. package/crates/mint-cli/src/onboard.rs +5 -31
  31. package/crates/mint-cli/src/terminal_theme.rs +3 -1
  32. package/crates/mint-cli/src/updater.rs +56 -2
  33. package/crates/mint-cli/tests/library_intake.rs +77 -0
  34. package/crates/mint-cli/tests/mods_testing.rs +133 -0
  35. package/crates/mint-companion-protocol/Cargo.toml +10 -0
  36. package/crates/mint-companion-protocol/src/lib.rs +163 -0
  37. package/crates/mint-core/Cargo.toml +6 -3
  38. package/crates/mint-core/build.rs +26 -0
  39. package/crates/mint-core/src/agent/chat.rs +167 -39
  40. package/crates/mint-core/src/agent/code_tools.rs +15 -0
  41. package/crates/mint-core/src/agent/memory/sources.rs +240 -0
  42. package/crates/mint-core/src/agent/memory.rs +147 -13
  43. package/crates/mint-core/src/agent/skill_inventory.rs +325 -0
  44. package/crates/mint-core/src/agent/skills.rs +437 -90
  45. package/crates/mint-core/src/agent.rs +1 -0
  46. package/crates/mint-core/src/api_server/routes/background_jobs.rs +310 -0
  47. package/crates/mint-core/src/api_server/routes/chat.rs +216 -199
  48. package/crates/mint-core/src/api_server/routes/html_preview.rs +77 -0
  49. package/crates/mint-core/src/api_server/routes/library.rs +97 -0
  50. package/crates/mint-core/src/api_server/routes/media_gen.rs +10 -57
  51. package/crates/mint-core/src/api_server/routes/misc.rs +104 -107
  52. package/crates/mint-core/src/api_server/routes/mod.rs +6 -0
  53. package/crates/mint-core/src/api_server/routes/mods.rs +31 -0
  54. package/crates/mint-core/src/api_server/routes/sessions.rs +41 -0
  55. package/crates/mint-core/src/api_server/routes/skills_subagents.rs +12 -42
  56. package/crates/mint-core/src/api_server/routes/slash.rs +50 -1
  57. package/crates/mint-core/src/api_server/routes/sources.rs +101 -0
  58. package/crates/mint-core/src/api_server.rs +118 -9
  59. package/crates/mint-core/src/avatar_bridge.rs +11 -2
  60. package/crates/mint-core/src/browser/session.rs +52 -0
  61. package/crates/mint-core/src/companion.rs +716 -0
  62. package/crates/mint-core/src/cron/scheduler.rs +34 -2
  63. package/crates/mint-core/src/integrations/channels.rs +87 -345
  64. package/crates/mint-core/src/integrations/mcp.rs +397 -50
  65. package/crates/mint-core/src/integrations/mcp_calls.rs +823 -0
  66. package/crates/mint-core/src/integrations/mcp_catalog.rs +267 -0
  67. package/crates/mint-core/src/integrations/mcp_device.rs +319 -0
  68. package/crates/mint-core/src/integrations/mcp_result.rs +356 -0
  69. package/crates/mint-core/src/integrations/webhooks.rs +539 -0
  70. package/crates/mint-core/src/integrations.rs +2 -0
  71. package/crates/mint-core/src/lib.rs +85 -26
  72. package/crates/mint-core/src/media/gemini_live.rs +134 -14
  73. package/crates/mint-core/src/media/image_models.rs +3 -27
  74. package/crates/mint-core/src/media/image_workflow.rs +216 -0
  75. package/crates/mint-core/src/media/library/intake.rs +144 -0
  76. package/crates/mint-core/src/media/library/migration.rs +56 -0
  77. package/crates/mint-core/src/media/library/removal.rs +55 -0
  78. package/crates/mint-core/src/media/library/tests.rs +730 -0
  79. package/crates/mint-core/src/media/library/thumbnails.rs +72 -0
  80. package/crates/mint-core/src/media/library.rs +545 -0
  81. package/crates/mint-core/src/media/model_catalog.rs +375 -0
  82. package/crates/mint-core/src/media/pictures.rs +79 -222
  83. package/crates/mint-core/src/media/video_models.rs +3 -22
  84. package/crates/mint-core/src/media.rs +3 -0
  85. package/crates/mint-core/src/mods/manager.rs +1124 -0
  86. package/crates/mint-core/src/mods/mod.rs +569 -0
  87. package/crates/mint-core/src/mods/operations.rs +204 -0
  88. package/crates/mint-core/src/mods/session.rs +146 -0
  89. package/crates/mint-core/src/mods/slash.rs +59 -0
  90. package/crates/mint-core/src/mods/telemetry.rs +306 -0
  91. package/crates/mint-core/src/orchestration/approvals.rs +344 -0
  92. package/crates/mint-core/src/orchestration/context_render.rs +104 -0
  93. package/crates/mint-core/src/orchestration/mcp_review.rs +153 -0
  94. package/crates/mint-core/src/orchestration/memory_skill.rs +104 -32
  95. package/crates/mint-core/src/orchestration/mod.rs +2139 -244
  96. package/crates/mint-core/src/orchestration/mod_authoring_regressions.rs +209 -0
  97. package/crates/mint-core/src/orchestration/progress_clock.rs +80 -0
  98. package/crates/mint-core/src/orchestration/repeated_failures.rs +116 -0
  99. package/crates/mint-core/src/orchestration/review_regressions.rs +449 -0
  100. package/crates/mint-core/src/orchestration/run_control.rs +196 -0
  101. package/crates/mint-core/src/orchestration/tools/files.rs +161 -14
  102. package/crates/mint-core/src/orchestration/tools/media.rs +37 -41
  103. package/crates/mint-core/src/orchestration/tools/misc.rs +3 -2
  104. package/crates/mint-core/src/orchestration/tools/mod.rs +2 -0
  105. package/crates/mint-core/src/orchestration/tools/mods.rs +161 -0
  106. package/crates/mint-core/src/orchestration/tools/plugins_mcp.rs +303 -71
  107. package/crates/mint-core/src/orchestration/tools/shell.rs +95 -2
  108. package/crates/mint-core/src/orchestration/workspace_helpers.rs +4 -1
  109. package/crates/mint-core/src/prompts/agent.rs +17 -2
  110. package/crates/mint-core/src/prompts/tool_catalog.rs +28 -2
  111. package/crates/mint-core/src/search/knowledge.rs +7 -1
  112. package/crates/mint-core/src/search/linked_folders/index.rs +177 -13
  113. package/crates/mint-core/src/search/linked_folders.rs +83 -2
  114. package/crates/mint-core/src/slash/catalog.rs +1 -1
  115. package/crates/mint-core/src/slash/mod.rs +174 -11
  116. package/crates/mint-core/src/slash/mods.rs +155 -0
  117. package/crates/mint-core/src/system/bg_shell.rs +1129 -95
  118. package/crates/mint-core/src/system/config.rs +5 -10
  119. package/crates/mint-core/src/system/html_preview.rs +398 -0
  120. package/crates/mint-core/src/system/mint_web.rs +164 -0
  121. package/crates/mint-core/src/system/release_notes.rs +18 -0
  122. package/crates/mint-core/src/system/shell.rs +21 -6
  123. package/crates/mint-core/src/system/workspace.rs +72 -8
  124. package/crates/mint-core/src/system/workspace_history.rs +604 -0
  125. package/crates/mint-core/src/system.rs +4 -0
  126. package/crates/mint-core/tests/background_retention.rs +34 -0
  127. package/crates/mint-core/tests/background_shutdown.rs +24 -0
  128. package/crates/mint-core/tests/library_http.rs +209 -0
  129. package/crates/mint-core/tests/mcp_contract.rs +283 -0
  130. package/crates/mint-core/tests/mcp_stdio.rs +11 -10
  131. package/crates/mint-core/tests/media_model_catalog_http.rs +403 -0
  132. package/crates/mint-core/tests/mods_http.rs +215 -0
  133. package/crates/mint-core/tests/terminal_shutdown.rs +109 -0
  134. package/crates/mint-mod-runtime/Cargo.toml +18 -0
  135. package/crates/mint-mod-runtime/src/lib.rs +507 -0
  136. package/crates/mint-mod-runtime/src/sdk.js +56 -0
  137. package/crates/mint-mod-runtime/src/test_sdk.js +32 -0
  138. package/crates/mint-mod-runtime/src/testing.rs +94 -0
  139. package/crates/mint-mod-runtime/tests/runtime.rs +156 -0
  140. package/docs/mods/AUTHORING.md +61 -0
  141. package/docs/mods/README.md +139 -0
  142. package/docs/mods/TESTING.md +56 -0
  143. package/docs/mods/mint-mods.d.ts +66 -0
  144. package/examples/device-mcp/README.md +22 -0
  145. package/examples/device-mcp/contract.md +49 -0
  146. package/examples/device-mcp/mock-device.mjs +66 -0
  147. package/examples/device-mcp/server.mjs +48 -0
  148. package/examples/device-mcp/server.test.mjs +78 -0
  149. package/examples/mods/task-checklist/README.md +1 -0
  150. package/examples/mods/task-checklist/main.ts +17 -0
  151. package/examples/mods/task-checklist/manifest.json +1 -0
  152. package/examples/mods/task-checklist/tests/checklist.test.ts +15 -0
  153. package/examples/mods/token-meter/README.md +1 -0
  154. package/examples/mods/token-meter/main.ts +8 -0
  155. package/examples/mods/token-meter/manifest.json +1 -0
  156. package/examples/mods/tool-guard/README.md +1 -0
  157. package/examples/mods/tool-guard/main.ts +9 -0
  158. package/examples/mods/tool-guard/manifest.json +1 -0
  159. package/out/web/assets/CliSessionsView-CtzUJpK_.css +1 -0
  160. package/out/web/assets/CliSessionsView-D7hw0Mgj.js +1 -0
  161. package/out/web/assets/CodeReviewPage-C7bEOJfd.js +4 -0
  162. package/out/web/assets/CodeReviewPage-Dte9uLiL.css +1 -0
  163. package/out/web/assets/CommandPalette-0RrF-AOT.js +1 -0
  164. package/out/web/assets/ImageStudioPanel-CdxkAf_r.js +1 -0
  165. package/out/web/assets/LibraryPage--Qfisp6D.js +2 -0
  166. package/out/web/assets/LibraryPage-DAxUTAg7.css +1 -0
  167. package/out/web/assets/LinkedFoldersView-2nfZbDgN.js +1 -0
  168. package/out/web/assets/McpRegistryPicker-h9uS8_wT.js +1 -0
  169. package/out/web/assets/McpServersView-slfQJzNB.js +1 -0
  170. package/out/web/assets/MintDashboard-BSR5XpXh.js +25 -0
  171. package/out/web/assets/MintDashboard-CWUcCGhd.css +1 -0
  172. package/out/web/assets/PluginsView-l7LSm503.js +1 -0
  173. package/out/web/assets/ScheduledTasksView-CttmLbq1.js +1 -0
  174. package/out/web/assets/SettingsWindow-BCMLYvEV.js +4 -0
  175. package/out/web/assets/SettingsWindow-DcMVmU9u.css +1 -0
  176. package/out/web/assets/SkillsView-rNs1qr_U.js +2 -0
  177. package/out/web/assets/ToolSurfacePage-B9DzEPWN.js +37 -0
  178. package/out/web/assets/ToolSurfacePage-CTfgggF2.css +1 -0
  179. package/out/web/assets/VeoStudioPanel-DiJs_Cg2.js +4 -0
  180. package/out/web/assets/WorkspaceSelector-B2xIp04D.js +1 -0
  181. package/out/web/assets/WorkspaceSelector-Ca8uJOsS.css +1 -0
  182. package/out/web/assets/{abnfDiagram-VCTEODGH-ByMyfanq.js → abnfDiagram-VCTEODGH-CD0CjoGl.js} +1 -1
  183. package/out/web/assets/{architecture-7GRP2DOG-CLq2kEOB.js → architecture-7GRP2DOG-RKV83OeZ.js} +1 -1
  184. package/out/web/assets/{architectureDiagram-5GKGNRK7-6PoVSmNG.js → architectureDiagram-5GKGNRK7-nN_HAFct.js} +1 -1
  185. package/out/web/assets/{blockDiagram-NRAW4CY4-cKw9mAKi.js → blockDiagram-NRAW4CY4-BrrqzHW5.js} +1 -1
  186. package/out/web/assets/{c4Diagram-UCG6FXSJ-Cqy8N5Ge.js → c4Diagram-UCG6FXSJ-DTdV8_zE.js} +1 -1
  187. package/out/web/assets/{chunk-75Z2AOVW-3qybijF5.js → chunk-75Z2AOVW-_M0z5olV.js} +1 -1
  188. package/out/web/assets/chunk-CKBBP62Z-BpQEgeHF.js +2 -0
  189. package/out/web/assets/{chunk-CLGD4ZFX-CndDQkww.js → chunk-CLGD4ZFX-D54yGvGS.js} +1 -1
  190. package/out/web/assets/{chunk-DSNCTWBM-Cc4NxvgD.js → chunk-DSNCTWBM-C-gvT2ru.js} +1 -1
  191. package/out/web/assets/{chunk-DU6HZSFF-drzh6GsU.js → chunk-DU6HZSFF-CnFngIhW.js} +1 -1
  192. package/out/web/assets/{chunk-F27PBJKO-FiY35l4v.js → chunk-F27PBJKO-BqtWrnEO.js} +1 -1
  193. package/out/web/assets/{chunk-G27WJ6UU-Bjt9Il4A.js → chunk-G27WJ6UU-Ckoq5mi2.js} +1 -1
  194. package/out/web/assets/{chunk-GMAD6QVW-Bppi3Ctd.js → chunk-GMAD6QVW-BuhEcgHq.js} +1 -1
  195. package/out/web/assets/{chunk-JQ64N6SF-DGg5kcEV.js → chunk-JQ64N6SF-CF8T7GiZ.js} +1 -1
  196. package/out/web/assets/{chunk-LCL6LL3I-CCYcjd7p.js → chunk-LCL6LL3I-BhXV9zyH.js} +1 -1
  197. package/out/web/assets/{chunk-OBVCFTLP-DJeNil5M.js → chunk-OBVCFTLP-CRIkunUB.js} +1 -1
  198. package/out/web/assets/{chunk-P2QGCYS3-lRzkRjBB.js → chunk-P2QGCYS3-UFEU6BxZ.js} +1 -1
  199. package/out/web/assets/{chunk-POPQ4Y6H-DouASMBW.js → chunk-POPQ4Y6H-CQcrNbjr.js} +1 -1
  200. package/out/web/assets/{chunk-PWAF6VOD-DMmD1vVf.js → chunk-PWAF6VOD-Cc2uVDsG.js} +1 -1
  201. package/out/web/assets/{chunk-R7TYR2AO-CYLA5UC5.js → chunk-R7TYR2AO-DiCxzdAY.js} +1 -1
  202. package/out/web/assets/{chunk-RHFEMEQ7-BiXwEcUT.js → chunk-RHFEMEQ7-b7hnPmrR.js} +1 -1
  203. package/out/web/assets/{chunk-SVP7TREG-BV-zPslF.js → chunk-SVP7TREG-Bu_yYb-V.js} +1 -1
  204. package/out/web/assets/{chunk-TEH6E4GO-B2RGEohZ.js → chunk-TEH6E4GO-G4Cdlyrt.js} +1 -1
  205. package/out/web/assets/classDiagram-DTDB5LWJ-RnC2mYO4.js +1 -0
  206. package/out/web/assets/classDiagram-v2-JRS7N3AN-RnC2mYO4.js +1 -0
  207. package/out/web/assets/config-CnvCChUM.js +2 -0
  208. package/out/web/assets/config-DM6oIVO3.css +1 -0
  209. package/out/web/assets/core-DsKkQ7ig.js +1 -0
  210. package/out/web/assets/{cynefin-OW5HDTMX-Cas4csHM.js → cynefin-OW5HDTMX-CnzQfOGp.js} +1 -1
  211. package/out/web/assets/{cynefinDiagram-5FMLGOSQ-Bbpj66Y3.js → cynefinDiagram-5FMLGOSQ-DVtQnfpm.js} +1 -1
  212. package/out/web/assets/{dagre-3AP2YEHR-B0-2RDEd.js → dagre-3AP2YEHR-DG76_k5_.js} +1 -1
  213. package/out/web/assets/{diagram-S7CK7UJ4-BdzEjUyH.js → diagram-S7CK7UJ4-CaouUoze.js} +1 -1
  214. package/out/web/assets/{diagram-UQ7AKVKN-CJDwyPxF.js → diagram-UQ7AKVKN-B4bEc26B.js} +1 -1
  215. package/out/web/assets/{diagram-VSXAHHWV-BxaG1r_B.js → diagram-VSXAHHWV-BJ86Ov2Y.js} +1 -1
  216. package/out/web/assets/{diagram-VX7I27RA-BMmUqm8f.js → diagram-VX7I27RA-7hH5IPYf.js} +1 -1
  217. package/out/web/assets/{diagram-Z3DM3KII-CFtd03eE.js → diagram-Z3DM3KII-CCM4clo8.js} +1 -1
  218. package/out/web/assets/dist-js-BkYNznHX.js +1 -0
  219. package/out/web/assets/{ebnfDiagram-PWID7BFC-DwAen1hO.js → ebnfDiagram-PWID7BFC-Da7WAM3k.js} +1 -1
  220. package/out/web/assets/{erDiagram-SSCWMZ5O-BCZSHACj.js → erDiagram-SSCWMZ5O-CzzmnZWT.js} +1 -1
  221. package/out/web/assets/{event-ChBVpRy0.js → event-Cdt7Byyj.js} +1 -1
  222. package/out/web/assets/{eventmodeling-NTZA5JFV-XHStE4E_.js → eventmodeling-NTZA5JFV-xcfsA0XD.js} +1 -1
  223. package/out/web/assets/flowDiagram-A5DVABFB-JdtH1673.js +1 -0
  224. package/out/web/assets/{ganttDiagram-EL5Y4UJY-BAEu1Cql.js → ganttDiagram-EL5Y4UJY-B3ClFGmL.js} +1 -1
  225. package/out/web/assets/{gitGraph-4MIJSDKK-r32Vyper.js → gitGraph-4MIJSDKK-BZ_y_cDU.js} +1 -1
  226. package/out/web/assets/{gitGraphDiagram-WWUBYQGX-z9o9qt6V.js → gitGraphDiagram-WWUBYQGX-drhRSYm3.js} +1 -1
  227. package/out/web/assets/index-BZ9xgmMP.css +1 -0
  228. package/out/web/assets/index-Ca8cCS4h.js +168 -0
  229. package/out/web/assets/{info-A6RAGUB7-BvLaC2cw.js → info-A6RAGUB7-B7I3K0F1.js} +1 -1
  230. package/out/web/assets/{infoDiagram-RXCK75RN-Be6WAXXw.js → infoDiagram-RXCK75RN-deX_1MPh.js} +1 -1
  231. package/out/web/assets/{ishikawaDiagram-5VMMS53U-DZjoHJHC.js → ishikawaDiagram-5VMMS53U-s38yo28y.js} +1 -1
  232. package/out/web/assets/{journeyDiagram-EYS64GPL-CtVkjkGm.js → journeyDiagram-EYS64GPL-CZn2kB8b.js} +1 -1
  233. package/out/web/assets/jsx-runtime-DN4NhQUK.js +1 -0
  234. package/out/web/assets/{kanban-definition-3QL26DDD-CW5FMv1w.js → kanban-definition-3QL26DDD-DodjgySL.js} +1 -1
  235. package/out/web/assets/markdown-CMhYIcWB.js +39 -0
  236. package/out/web/assets/{mermaid-parser.core-aUgCqsZ5.js → mermaid-parser.core-Whu2rlJC.js} +3 -3
  237. package/out/web/assets/{mermaid.core-D57sEiSL.js → mermaid.core-CKyPo8VH.js} +4 -4
  238. package/out/web/assets/{mindmap-definition-FBJOCRG2-DAmSpM3a.js → mindmap-definition-FBJOCRG2-260WBDxZ.js} +1 -1
  239. package/out/web/assets/modelManager-CUaGWMWu.js +2 -0
  240. package/out/web/assets/{oauthManager-9jxicDWJ.js → oauthManager-DlNhXJr6.js} +1 -1
  241. package/out/web/assets/{packet-AYTQ26CC-DJ27iIoJ.js → packet-AYTQ26CC-CEeIRKRG.js} +1 -1
  242. package/out/web/assets/{pegDiagram-XKGWAZYB-Bj3ii-gS.js → pegDiagram-XKGWAZYB-BYadI-KO.js} +1 -1
  243. package/out/web/assets/{pie-WAS4IAKB-DG5mCUbc.js → pie-WAS4IAKB-D8uf4dh5.js} +1 -1
  244. package/out/web/assets/{pieDiagram-E7YTZNPT-BrJLPnDA.js → pieDiagram-E7YTZNPT-CjSDy4hO.js} +1 -1
  245. package/out/web/assets/{quadrantDiagram-AXDQQJYC-3x_TmF3j.js → quadrantDiagram-AXDQQJYC-B8D3gU5d.js} +1 -1
  246. package/out/web/assets/{radar-RG4KPBEZ-CrXaTTuV.js → radar-RG4KPBEZ-DZJxnokY.js} +1 -1
  247. package/out/web/assets/{railroad-74A4TZTK-BpqMH9BE.js → railroad-74A4TZTK-DBysUiUi.js} +1 -1
  248. package/out/web/assets/{railroad-abnf-HS5TGJTU-DHI0uLlV.js → railroad-abnf-HS5TGJTU-CHWxoJYg.js} +1 -1
  249. package/out/web/assets/{railroad-ebnf-LZEXJU2U-CQCb316y.js → railroad-ebnf-LZEXJU2U-DDv7X6bY.js} +1 -1
  250. package/out/web/assets/{railroad-peg-WCYAUIDC-Ph1giKkH.js → railroad-peg-WCYAUIDC-DpfcYYNJ.js} +1 -1
  251. package/out/web/assets/{railroadDiagram-O6MQD6OU-BRq6wIxx.js → railroadDiagram-O6MQD6OU-CYtyv0t3.js} +1 -1
  252. package/out/web/assets/{requirementDiagram-EFPCY7ZU-DIJj6G1g.js → requirementDiagram-EFPCY7ZU-D2X-Ewik.js} +1 -1
  253. package/out/web/assets/{sankeyDiagram-P5KCCOFB-DZajSryq.js → sankeyDiagram-P5KCCOFB-Bn2x6C4Y.js} +1 -1
  254. package/out/web/assets/{sequenceDiagram-WJ2MYXX4-DxJCWyZS.js → sequenceDiagram-WJ2MYXX4-BvFLKtPd.js} +1 -1
  255. package/out/web/assets/{stateDiagram-HBIQ2CUA-k6voi8Vf.js → stateDiagram-HBIQ2CUA-Bx0GWeaY.js} +1 -1
  256. package/out/web/assets/stateDiagram-v2-4QOOHH4V--hol1yg_.js +1 -0
  257. package/out/web/assets/{swimlanes-XN3QIQJK-igYhTjXB.js → swimlanes-XN3QIQJK-CCma0T7L.js} +1 -1
  258. package/out/web/assets/swimlanesDiagram-VK2B7HYN-BkohoVsU.js +8 -0
  259. package/out/web/assets/{timeline-definition-24CTP7MA-Dke2p93p.js → timeline-definition-24CTP7MA-iCRhhJ7C.js} +1 -1
  260. package/out/web/assets/{treeView-Q6P3EWNA-hNELnXUs.js → treeView-Q6P3EWNA-DZ-y08qp.js} +1 -1
  261. package/out/web/assets/{treemap-WGGIJYW6-D2B6wDsx.js → treemap-WGGIJYW6-De0CxzMx.js} +1 -1
  262. package/out/web/assets/{vennDiagram-4TSXK5OY-CDkW7rUP.js → vennDiagram-4TSXK5OY-w_7aZ6xe.js} +1 -1
  263. package/out/web/assets/{wardley-WFR3VGLG-BECdXETi.js → wardley-WFR3VGLG-DT0y0xJ4.js} +1 -1
  264. package/out/web/assets/{wardleyDiagram-VM6X3IG4-B5BycpQ4.js → wardleyDiagram-VM6X3IG4-DAdXELbQ.js} +1 -1
  265. package/out/web/assets/window-BJCVtyET.js +1 -0
  266. package/out/web/assets/{xychartDiagram-S5SC5T6Z-CtJS3b--.js → xychartDiagram-S5SC5T6Z-IZIXf3Vo.js} +1 -1
  267. package/out/web/index-web.html +3 -2
  268. package/out/web/index.html +3 -2
  269. package/package.json +71 -22
  270. package/shared-modules/.github/workflows/ci.yml +120 -0
  271. package/shared-modules/.github/workflows/update.yaml +28 -0
  272. package/slash-commands.json +7 -2
  273. package/src/bin/auto-build.js +66 -0
  274. package/src/bin/desktop.js +113 -0
  275. package/src/bin/desktop.test.js +113 -0
  276. package/src/bin/index.js +18 -25
  277. package/src/bin/index.test.js +89 -0
  278. package/src/bin/measure-effects.mjs +53 -0
  279. package/src/bin/package.test.js +28 -0
  280. package/src/bin/release-notes.test.js +84 -0
  281. package/src/bin/styles.test.js +20 -0
  282. package/src/bin/web.js +5 -0
  283. package/src/bin/web.test.js +39 -0
  284. package/src/renderer/index.html +0 -2
  285. package/src/renderer/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
  286. package/src/renderer/shared/agentProgress.ts +33 -0
  287. package/src/renderer/shared/components/AgentActivityDrawer.tsx +3 -2
  288. package/src/renderer/shared/components/AgentActivityTable.tsx +1 -1
  289. package/src/renderer/shared/components/ApprovalCard.test.tsx +24 -0
  290. package/src/renderer/shared/components/ApprovalCard.tsx +10 -3
  291. package/src/renderer/shared/components/ArtifactPreviewPanel.tsx +88 -37
  292. package/src/renderer/shared/components/AuthGate.tsx +75 -39
  293. package/src/renderer/shared/components/BackgroundTerminals.tsx +181 -0
  294. package/src/renderer/shared/components/ChatCodeBlock.tsx +8 -4
  295. package/src/renderer/shared/components/ChatMessageItem.test.tsx +68 -0
  296. package/src/renderer/shared/components/ChatMessageItem.tsx +36 -16
  297. package/src/renderer/shared/components/ChatPanel.test.tsx +21 -0
  298. package/src/renderer/shared/components/ChatPanel.tsx +294 -272
  299. package/src/renderer/shared/components/ChunkErrorBoundary.tsx +4 -102
  300. package/src/renderer/shared/components/CliSessionsView.test.tsx +125 -0
  301. package/src/renderer/shared/components/CliSessionsView.tsx +61 -13
  302. package/src/renderer/shared/components/CodeReviewPage.tsx +111 -8
  303. package/src/renderer/shared/components/CollapsiblePasteInput.tsx +90 -0
  304. package/src/renderer/shared/components/ContextCompactionStatus.tsx +17 -0
  305. package/src/renderer/shared/components/DashboardSidebar.tsx +15 -128
  306. package/src/renderer/shared/components/DesktopTitlebar.tsx +45 -19
  307. package/src/renderer/shared/components/ErrorNotice.tsx +29 -0
  308. package/src/renderer/shared/components/FormattedMessage.tsx +11 -0
  309. package/src/renderer/shared/components/GeminiLiveOverlay.css +86 -0
  310. package/src/renderer/shared/components/GeminiLiveOverlay.test.tsx +24 -0
  311. package/src/renderer/shared/components/GeminiLiveOverlay.tsx +85 -101
  312. package/src/renderer/shared/components/GlideSelect.css +138 -0
  313. package/src/renderer/shared/components/GlideSelect.d.ts +31 -0
  314. package/src/renderer/shared/components/GlideSelect.jsx +266 -0
  315. package/src/renderer/shared/components/ImageSearchCard.tsx +46 -56
  316. package/src/renderer/shared/components/ImageStudioPanel.tsx +9 -8
  317. package/src/renderer/shared/components/LibraryItemCard.tsx +72 -0
  318. package/src/renderer/shared/components/LibraryPage.tsx +165 -0
  319. package/src/renderer/shared/components/LibraryPreview.tsx +59 -0
  320. package/src/renderer/shared/components/McpServersView.tsx +27 -8
  321. package/src/renderer/shared/components/McpToolAllowlist.tsx +2 -4
  322. package/src/renderer/shared/components/McpToolResults.tsx +99 -0
  323. package/src/renderer/shared/components/MintDashboard.tsx +308 -770
  324. package/src/renderer/shared/components/ModSessionControls.tsx +8 -0
  325. package/src/renderer/shared/components/ModUi.test.tsx +65 -0
  326. package/src/renderer/shared/components/ModUi.tsx +26 -0
  327. package/src/renderer/shared/components/ModelSelectorPopover.tsx +14 -7
  328. package/src/renderer/shared/components/ModsPanel.tsx +156 -0
  329. package/src/renderer/shared/components/ProgressActivity.tsx +17 -0
  330. package/src/renderer/shared/components/ReviewHistory.tsx +42 -0
  331. package/src/renderer/shared/components/RewindModal.tsx +5 -12
  332. package/src/renderer/shared/components/RunSummaryDashboard.tsx +6 -12
  333. package/src/renderer/shared/components/ScheduledTasksView.tsx +7 -6
  334. package/src/renderer/shared/components/SelectField.test.tsx +27 -0
  335. package/src/renderer/shared/components/SelectField.tsx +38 -0
  336. package/src/renderer/shared/components/SessionSources.tsx +48 -0
  337. package/src/renderer/shared/components/SessionSourcesPopover.tsx +61 -0
  338. package/src/renderer/shared/components/Settings/AgentsTab.tsx +7 -6
  339. package/src/renderer/shared/components/Settings/AudioTab.tsx +8 -7
  340. package/src/renderer/shared/components/Settings/AutomationTab.tsx +2 -2
  341. package/src/renderer/shared/components/Settings/GeneralTab.tsx +33 -32
  342. package/src/renderer/shared/components/Settings/MemoryTab.test.tsx +37 -0
  343. package/src/renderer/shared/components/Settings/MemoryTab.tsx +71 -31
  344. package/src/renderer/shared/components/Settings/NotificationsTab.test.tsx +15 -0
  345. package/src/renderer/shared/components/Settings/NotificationsTab.tsx +84 -0
  346. package/src/renderer/shared/components/Settings/ThemeTab.tsx +19 -11
  347. package/src/renderer/shared/components/SlashChoicePanel.tsx +88 -0
  348. package/src/renderer/shared/components/SlashSuggestions.test.tsx +33 -0
  349. package/src/renderer/shared/components/SlashSuggestions.tsx +38 -10
  350. package/src/renderer/shared/components/SourcesBlock.tsx +12 -20
  351. package/src/renderer/shared/components/ToolSurfacePage.test.tsx +32 -0
  352. package/src/renderer/shared/components/ToolSurfacePage.tsx +59 -11
  353. package/src/renderer/shared/components/ToolsPanelToggle.tsx +13 -0
  354. package/src/renderer/shared/components/VeoStudioPanel.tsx +9 -8
  355. package/src/renderer/shared/components/ViewedImages.tsx +36 -0
  356. package/src/renderer/shared/components/VirtualChatHistory.tsx +82 -0
  357. package/src/renderer/shared/components/VoicePill.css +85 -0
  358. package/src/renderer/shared/components/VoicePill.d.ts +12 -0
  359. package/src/renderer/shared/components/VoicePill.jsx +190 -0
  360. package/src/renderer/shared/components/VoicePill.test.tsx +22 -0
  361. package/src/renderer/shared/components/WorkspaceContextPopover.tsx +20 -15
  362. package/src/renderer/shared/components/WorkspacePaneResizer.tsx +92 -0
  363. package/src/renderer/shared/components/WorkspacePreviewActions.test.tsx +44 -0
  364. package/src/renderer/shared/components/WorkspacePreviewActions.tsx +19 -0
  365. package/src/renderer/shared/components/WorkspaceSelector.tsx +13 -8
  366. package/src/renderer/shared/components/background-terminals.css +292 -0
  367. package/src/renderer/shared/components/ui/README.md +52 -0
  368. package/src/renderer/shared/components/ui/button.tsx +37 -0
  369. package/src/renderer/shared/components/ui/demo.tsx +26 -0
  370. package/src/renderer/shared/components/ui/error-recovery.css +35 -0
  371. package/src/renderer/shared/components/ui/error-recovery.tsx +35 -0
  372. package/src/renderer/shared/components/ui/voice-powered-orb.css +6 -0
  373. package/src/renderer/shared/components/ui/voice-powered-orb.tsx +374 -0
  374. package/src/renderer/shared/components/workspace-selector.css +248 -0
  375. package/src/renderer/shared/constants/config.ts +30 -1
  376. package/src/renderer/shared/constants/slashCommands.ts +1 -1
  377. package/src/renderer/shared/conversation/lifecycle.test.ts +362 -0
  378. package/src/renderer/shared/conversation/lifecycle.ts +418 -0
  379. package/src/renderer/shared/conversation/projectNavigation.test.ts +105 -0
  380. package/src/renderer/shared/conversation/projectNavigation.ts +39 -0
  381. package/src/renderer/shared/conversation/sourcesTransport.ts +27 -0
  382. package/src/renderer/shared/conversation/syncView.test.ts +1 -34
  383. package/src/renderer/shared/conversation/syncView.ts +0 -37
  384. package/src/renderer/shared/conversation/transport.test.ts +163 -0
  385. package/src/renderer/shared/conversation/transport.ts +159 -0
  386. package/src/renderer/shared/conversation/useConversationCoordinator.ts +30 -72
  387. package/src/renderer/shared/css/agent-observability.css +20 -21
  388. package/src/renderer/shared/css/auth-gate.css +112 -13
  389. package/src/renderer/shared/css/code-review.css +33 -0
  390. package/src/renderer/shared/css/code-sessions.css +27 -0
  391. package/src/renderer/shared/css/collapsed-paste.css +35 -0
  392. package/src/renderer/shared/css/effects.css +15 -0
  393. package/src/renderer/shared/css/error-notice.css +60 -0
  394. package/src/renderer/shared/css/library.css +476 -0
  395. package/src/renderer/shared/css/management-views.css +138 -0
  396. package/src/renderer/shared/css/mcp-results.css +11 -0
  397. package/src/renderer/shared/css/model-selector.css +163 -105
  398. package/src/renderer/shared/css/mods.css +77 -0
  399. package/src/renderer/shared/css/notification-notice.css +28 -0
  400. package/src/renderer/shared/css/session-sources-popover.css +9 -0
  401. package/src/renderer/shared/css/session-sources.css +23 -0
  402. package/src/renderer/shared/css/settings/memory.css +154 -0
  403. package/src/renderer/shared/css/settings/notifications.css +11 -0
  404. package/src/renderer/shared/css/settings/theme.css +5 -0
  405. package/src/renderer/shared/css/slash-choice.css +95 -0
  406. package/src/renderer/shared/css/slash-suggestions.css +68 -0
  407. package/src/renderer/shared/css/sources-block.css +91 -0
  408. package/src/renderer/shared/css/thinking-status.css +46 -0
  409. package/src/renderer/shared/css/tools-panel.css +7 -0
  410. package/src/renderer/shared/css/ui-tailwind.css +19 -0
  411. package/src/renderer/shared/css/viewed-images.css +15 -0
  412. package/src/renderer/shared/fonts.css +46 -0
  413. package/src/renderer/shared/fonts.ts +3 -12
  414. package/src/renderer/shared/lib/utils.ts +6 -0
  415. package/src/renderer/shared/library/controller.test.ts +61 -0
  416. package/src/renderer/shared/library/controller.ts +57 -0
  417. package/src/renderer/shared/library/transport.test.ts +26 -0
  418. package/src/renderer/shared/library/transport.ts +60 -0
  419. package/src/renderer/shared/library/useLibraryFile.ts +38 -0
  420. package/src/renderer/shared/mods.ts +58 -0
  421. package/src/renderer/shared/platform.test.ts +57 -1
  422. package/src/renderer/shared/platform.ts +46 -1
  423. package/src/renderer/shared/theme/themeManager.test.ts +43 -0
  424. package/src/renderer/shared/theme/themeManager.ts +17 -4
  425. package/src/renderer/shared/types.ts +56 -2
  426. package/src/renderer/shared/utils/agentActivity.test.ts +75 -0
  427. package/src/renderer/shared/utils/agentActivity.ts +42 -3
  428. package/src/renderer/shared/utils/approval.tsx +7 -0
  429. package/src/renderer/shared/utils/artifactBrowser.test.ts +80 -0
  430. package/src/renderer/shared/utils/artifactBrowser.ts +41 -0
  431. package/src/renderer/shared/utils/contextCompaction.test.tsx +48 -0
  432. package/src/renderer/shared/utils/contextCompaction.ts +21 -0
  433. package/src/renderer/shared/utils/effectVisibility.ts +9 -0
  434. package/src/renderer/shared/utils/markdown.tsx +3 -3
  435. package/src/renderer/shared/utils/mcpResults.test.tsx +91 -0
  436. package/src/renderer/shared/utils/modViewport.ts +7 -0
  437. package/src/renderer/shared/utils/nativeRecordingSession.test.ts +61 -0
  438. package/src/renderer/shared/utils/nativeRecordingSession.ts +46 -0
  439. package/src/renderer/shared/utils/notificationSettings.test.ts +14 -0
  440. package/src/renderer/shared/utils/notificationSettings.ts +23 -0
  441. package/src/renderer/shared/utils/notifications.test.ts +51 -0
  442. package/src/renderer/shared/utils/notifications.ts +54 -0
  443. package/src/renderer/shared/utils/pastedText.test.ts +20 -0
  444. package/src/renderer/shared/utils/pastedText.ts +13 -0
  445. package/src/renderer/shared/utils/progressCache.test.ts +32 -0
  446. package/src/renderer/shared/utils/sessionSources.test.ts +31 -0
  447. package/src/renderer/shared/utils/sessionSources.ts +34 -0
  448. package/src/renderer/shared/utils/slashCommandProcessor.ts +1 -1
  449. package/src/renderer/shared/utils/sourceAttachments.ts +28 -0
  450. package/src/renderer/shared/utils/speech.ts +51 -9
  451. package/src/renderer/shared/utils/syntaxHighlight.test.tsx +22 -0
  452. package/src/renderer/shared/utils/syntaxHighlight.tsx +26 -0
  453. package/src/renderer/shared/utils/useGeminiLiveVoice.ts +49 -5
  454. package/src/renderer/shared/utils/useLatestCallback.ts +9 -0
  455. package/src/renderer/shared/utils/useNativeVoiceInput.ts +80 -72
  456. package/src/renderer/shared/utils/useSessionSources.ts +33 -0
  457. package/src/renderer/shared/utils/viewedImages.ts +26 -0
  458. package/src/renderer/shared/utils/workspacePane.test.ts +33 -0
  459. package/src/renderer/shared/utils/workspacePane.ts +20 -0
  460. package/src/renderer/shared/utils/workspacePreview.test.ts +24 -0
  461. package/src/renderer/shared/utils/workspacePreview.ts +16 -0
  462. package/src/renderer/shared/utils/workspaceSnapshot.test.ts +49 -0
  463. package/src/renderer/shared/utils/workspaceSnapshot.ts +26 -0
  464. package/src/renderer/shared/utils/workspaces.ts +10 -0
  465. package/src/renderer/shared/workspaceUndo.ts +88 -0
  466. package/src/renderer/src/App.tsx +9 -1
  467. package/src/renderer/src/components/LiveTranslateControls.tsx +65 -0
  468. package/src/renderer/src/components/PicturesLibrary.tsx +2 -288
  469. package/src/renderer/src/components/ScreenPicker.css +67 -30
  470. package/src/renderer/src/components/ScreenPicker.tsx +201 -60
  471. package/src/renderer/src/components/SettingsWindow.tsx +10 -5
  472. package/src/renderer/src/components/WorkspacePanel.tsx +222 -32
  473. package/src/renderer/src/components/browser-shell.css +1 -1
  474. package/src/renderer/src/components/browser-suggestions-popup.css +1 -1
  475. package/src/renderer/src/components/liveTranslateFrames.test.ts +26 -5
  476. package/src/renderer/src/components/liveTranslateFrames.ts +18 -7
  477. package/src/renderer/src/components/liveTranslateLanguage.ts +6 -0
  478. package/src/renderer/src/css/app-shell.css +52 -137
  479. package/src/renderer/src/css/chat.css +21 -495
  480. package/src/renderer/src/css/desktop-tools.css +199 -1
  481. package/src/renderer/src/css/misc.css +0 -52
  482. package/src/renderer/src/css/pictures.css +2 -415
  483. package/src/renderer/src/css/settings/base.css +50 -47
  484. package/src/renderer/src/css/sidebar-workspace.css +151 -94
  485. package/src/renderer/src/css/tool-surfaces.css +65 -9
  486. package/src/renderer/src/css/widget.css +1 -1
  487. package/src/renderer/src/env.d.ts +1 -9
  488. package/src/renderer/src/index.css +1 -1
  489. package/src/renderer/src/main.tsx +2 -1
  490. package/src/renderer/src/proactiveSuggestions.ts +29 -0
  491. package/src/renderer/src/tauri.ts +122 -330
  492. package/src/renderer/src/voiceInput.ts +2 -1
  493. package/src/renderer/src-web/components/PicturesLibrary.tsx +2 -285
  494. package/src/renderer/src-web/components/PullToRefresh.tsx +1 -1
  495. package/src/renderer/src-web/components/SettingsWindow.tsx +10 -5
  496. package/src/renderer/src-web/css/app-shell.css +24 -121
  497. package/src/renderer/src-web/css/chat.css +21 -495
  498. package/src/renderer/src-web/css/misc.css +0 -52
  499. package/src/renderer/src-web/css/mobile.css +15 -14
  500. package/src/renderer/src-web/css/pictures.css +2 -462
  501. package/src/renderer/src-web/css/settings/base.css +50 -47
  502. package/src/renderer/src-web/css/sidebar-workspace.css +9 -95
  503. package/src/renderer/src-web/css/widget.css +1 -1
  504. package/src/renderer/src-web/env.d.ts +1 -12
  505. package/src/renderer/src-web/index.css +1 -1
  506. package/src/renderer/src-web/main.tsx +2 -1
  507. package/src/renderer/src-web/proactiveSuggestions.ts +3 -0
  508. package/src/renderer/src-web/tauri.ts +129 -354
  509. package/src/renderer/tests/backgroundTerminals.browser.html +81 -0
  510. package/src/renderer/tests/chatPanelFixture.ts +23 -0
  511. package/src/renderer/tests/chatPerformance.browser.html +71 -0
  512. package/src/renderer/tests/cliSessions.browser.html +82 -0
  513. package/src/renderer/tests/collapsedPaste.browser.html +70 -0
  514. package/src/renderer/tests/composerMenus.browser.html +116 -0
  515. package/src/renderer/tests/contextCompaction.browser.html +17 -0
  516. package/src/renderer/tests/conversationLifecycle.browser.html +70 -0
  517. package/src/renderer/tests/effectsPerformance.browser.html +13 -0
  518. package/src/renderer/tests/errorRecovery.browser.html +21 -0
  519. package/src/renderer/tests/glideSelect.browser.html +71 -0
  520. package/src/renderer/tests/glideSelect.preview.html +27 -0
  521. package/src/renderer/tests/library.browser.html +1 -0
  522. package/src/renderer/tests/library.browser.tsx +78 -0
  523. package/src/renderer/tests/liveOrb.browser.html +49 -0
  524. package/src/renderer/tests/liveVoice.browser.html +29 -0
  525. package/src/renderer/tests/modInput.browser.html +22 -0
  526. package/src/renderer/tests/sessionSources.browser.html +1 -0
  527. package/src/renderer/tests/sessionSources.browser.tsx +107 -0
  528. package/src/renderer/tests/skills.browser.html +24 -0
  529. package/src/renderer/tests/toolsPanel.browser.html +1 -0
  530. package/src/renderer/tests/toolsPanel.browser.tsx +113 -0
  531. package/src/renderer/tests/viewedImages.browser.html +1 -0
  532. package/src/renderer/tests/viewedImages.browser.tsx +93 -0
  533. package/src/renderer/tests/voicePill.browser.html +80 -0
  534. package/src/renderer/tests/voicePill.preview.html +34 -0
  535. package/src/renderer/tests/webSources.browser.html +1 -0
  536. package/src/renderer/tests/webSources.browser.tsx +98 -0
  537. package/src/renderer/tests/workspaceUndo.browser.html +92 -0
  538. package/src-tauri/Cargo.toml +40 -0
  539. package/src-tauri/build.rs +3 -0
  540. package/src-tauri/src/app/lifecycle.rs +277 -0
  541. package/src-tauri/src/app/mod.rs +4 -0
  542. package/src-tauri/src/app/shortcuts.rs +40 -0
  543. package/src-tauri/src/app/tray.rs +52 -0
  544. package/src-tauri/src/background/events.rs +70 -0
  545. package/src-tauri/src/background/headless.rs +230 -0
  546. package/src-tauri/src/background/mod.rs +4 -0
  547. package/src-tauri/src/background/proactive.rs +262 -0
  548. package/src-tauri/src/commands/approvals.rs +20 -0
  549. package/src-tauri/src/commands/auth.rs +127 -0
  550. package/src-tauri/src/commands/conversation.rs +642 -0
  551. package/src-tauri/src/commands/integrations.rs +157 -0
  552. package/src-tauri/src/commands/media.rs +179 -0
  553. package/src-tauri/src/commands/mod.rs +11 -0
  554. package/src-tauri/src/commands/mods.rs +6 -0
  555. package/src-tauri/src/commands/settings.rs +141 -0
  556. package/src-tauri/src/commands/voice.rs +153 -0
  557. package/src-tauri/src/commands/workspace.rs +501 -0
  558. package/src-tauri/src/lib.rs +10 -0
  559. package/src-tauri/src/main.rs +3 -0
  560. package/src-tauri/src/native/actions.rs +206 -0
  561. package/src-tauri/src/native/browser.rs +252 -0
  562. package/src-tauri/src/native/capture.rs +695 -0
  563. package/src-tauri/src/native/discord_rpc.rs +99 -0
  564. package/src-tauri/src/native/integrations.rs +126 -0
  565. package/src-tauri/src/native/mod.rs +12 -0
  566. package/src-tauri/src/native/notifications.rs +51 -0
  567. package/src-tauri/src/native/plugins.rs +14 -0
  568. package/src-tauri/src/native/system.rs +250 -0
  569. package/src-tauri/src/native/terminal.rs +201 -0
  570. package/src-tauri/src/native/updater.rs +148 -0
  571. package/src-tauri/src/native/windows.rs +143 -0
  572. package/tsconfig.json +2 -0
  573. package/vite.config.ts +4 -1
  574. package/vite.config.web.ts +4 -0
  575. package/.cargo/config.toml +0 -13
  576. package/.claude/settings.local.json +0 -182
  577. package/.codex +0 -0
  578. package/CLAUDE.md +0 -102
  579. package/ROADMAP.md +0 -30
  580. package/mint-presentation-demo.mp4 +0 -0
  581. package/out/web/Live2DCubismCore.js +0 -9
  582. package/out/web/assets/CliSessionsView-BxUVWEEL.js +0 -1
  583. package/out/web/assets/CliSessionsView-CBDTXuQv.css +0 -1
  584. package/out/web/assets/CodeReviewPage-DkMgfcos.css +0 -1
  585. package/out/web/assets/CodeReviewPage-jKlmLJwT.js +0 -3
  586. package/out/web/assets/CommandPalette-DnwPA5hy.js +0 -1
  587. package/out/web/assets/ImageStudioPanel-BR1XFwhR.js +0 -1
  588. package/out/web/assets/LinkedFoldersView-bi-CWQ-I.js +0 -1
  589. package/out/web/assets/McpRegistryPicker-D5tEFnyq.js +0 -1
  590. package/out/web/assets/McpServersView-BGG1dhFM.js +0 -1
  591. package/out/web/assets/MintDashboard-BIglDEWX.js +0 -20
  592. package/out/web/assets/MintDashboard-DSMywSgs.css +0 -1
  593. package/out/web/assets/ModelPanel-CbJ1PFoZ.js +0 -1
  594. package/out/web/assets/PicturesLibrary-CQP0fLP1.css +0 -1
  595. package/out/web/assets/PicturesLibrary-DoYN7T1p.js +0 -1
  596. package/out/web/assets/PluginsView-CU1HWXGk.js +0 -1
  597. package/out/web/assets/ScheduledTasksView-Bnl36y2N.js +0 -1
  598. package/out/web/assets/SettingsWindow-DhWLAn9T.css +0 -1
  599. package/out/web/assets/SettingsWindow-Dw8L01pw.js +0 -2
  600. package/out/web/assets/SkillsView-cnl8aY5p.js +0 -2
  601. package/out/web/assets/ToolSurfacePage-CgsQw6l5.css +0 -1
  602. package/out/web/assets/ToolSurfacePage-Cz2VJAPZ.js +0 -37
  603. package/out/web/assets/VeoStudioPanel-D4JnERWR.js +0 -4
  604. package/out/web/assets/chunk-CKBBP62Z-cIrXq6jN.js +0 -2
  605. package/out/web/assets/classDiagram-DTDB5LWJ-Dq0smRWk.js +0 -1
  606. package/out/web/assets/classDiagram-v2-JRS7N3AN-Dq0smRWk.js +0 -1
  607. package/out/web/assets/config-C-ZFtipU.css +0 -1
  608. package/out/web/assets/config-eEDngJXO.js +0 -1
  609. package/out/web/assets/core-hQ2VA9Ti.js +0 -1
  610. package/out/web/assets/dist-js-Bf2bhoku.js +0 -1
  611. package/out/web/assets/flowDiagram-A5DVABFB-BLg7nEcd.js +0 -1
  612. package/out/web/assets/index-Btsf4L8M.css +0 -1
  613. package/out/web/assets/index-D8D9MeRA.js +0 -11
  614. package/out/web/assets/lucide-react-Ip3L6Jtn.js +0 -1
  615. package/out/web/assets/markdown-BSeeUbJH.js +0 -38
  616. package/out/web/assets/modelManager-tMVmJVAW.js +0 -2
  617. package/out/web/assets/prompt-latin-400-normal-BQ9zjSN8.woff2 +0 -0
  618. package/out/web/assets/prompt-latin-400-normal-CxU4ec_r.woff +0 -0
  619. package/out/web/assets/prompt-latin-500-normal-B1edBDQ9.woff +0 -0
  620. package/out/web/assets/prompt-latin-500-normal-CxzxEHZc.woff2 +0 -0
  621. package/out/web/assets/prompt-latin-600-normal-CSDDLorv.woff +0 -0
  622. package/out/web/assets/prompt-latin-600-normal-hKZWXsc1.woff2 +0 -0
  623. package/out/web/assets/prompt-latin-700-normal-BfbftDSq.woff +0 -0
  624. package/out/web/assets/prompt-latin-700-normal-I2gc831J.woff2 +0 -0
  625. package/out/web/assets/prompt-thai-400-normal-BrkKv8cO.woff2 +0 -0
  626. package/out/web/assets/prompt-thai-400-normal-DJypnfr3.woff +0 -0
  627. package/out/web/assets/prompt-thai-500-normal-C18pDUoL.woff2 +0 -0
  628. package/out/web/assets/prompt-thai-500-normal-D7YNqUJD.woff +0 -0
  629. package/out/web/assets/prompt-thai-600-normal-CYPViXds.woff +0 -0
  630. package/out/web/assets/prompt-thai-600-normal-MrdfU7zR.woff2 +0 -0
  631. package/out/web/assets/prompt-thai-700-normal-Cb5ilR-c.woff +0 -0
  632. package/out/web/assets/prompt-thai-700-normal-Cg4aQ0Nn.woff2 +0 -0
  633. package/out/web/assets/stateDiagram-v2-4QOOHH4V-DeEc0lGZ.js +0 -1
  634. package/out/web/assets/swimlanesDiagram-VK2B7HYN-DpVik9v7.js +0 -8
  635. package/out/web/assets/window-5qYXKoW7.js +0 -1
  636. package/skills-lock.json +0 -77
  637. package/src/renderer/public/Live2DCubismCore.js +0 -9
  638. package/src/renderer/src/companionWidget.ts +0 -95
  639. package/src/renderer/src/components/Live2DStage.tsx +0 -412
  640. package/src/renderer/src/components/ModelPanel.tsx +0 -155
  641. package/src/renderer/src/css/model.css +0 -628
  642. package/src/renderer/src-web/companionWidget.ts +0 -37
  643. package/src/renderer/src-web/components/ModelPanel.tsx +0 -12
  644. package/src/renderer/src-web/css/model.css +0 -628
@@ -1,3 +1,5 @@
1
+ import '../css/effects.css'
2
+ import { initializeEffectVisibility } from '../utils/effectVisibility'
1
3
  /**
2
4
  * shared/theme/themeManager.ts
3
5
  * Centralized theme controller and runtime state manager.
@@ -47,7 +49,9 @@ export const applyTheme = (cfg: any): void => {
47
49
  if (typeof document === 'undefined') return
48
50
 
49
51
  const rawTheme = cfg.theme || 'dark'
50
- const surfaceStyle = cfg.surfaceStyle || (cfg.glassBlur === 'none' ? 'opaque' : 'glass')
52
+ // Match Settings: disabling glass also disables translucent surfaces, even
53
+ // when an older configuration still contains surfaceStyle: 'glass'.
54
+ const surfaceStyle = cfg.glassBlur === 'none' ? 'opaque' : (cfg.surfaceStyle || 'glass')
51
55
  const accentColor = cfg.accentColor || '#10b981'
52
56
  const rgb = hexToRgb(accentColor)
53
57
  const contrastText = getContrastText(accentColor)
@@ -72,6 +76,9 @@ export const applyTheme = (cfg: any): void => {
72
76
  systemThemeMediaQuery = null
73
77
  }
74
78
 
79
+ initializeEffectVisibility()
80
+ document.documentElement.setAttribute('data-reduced-effects', String(cfg.reducedEffects === true))
81
+
75
82
  // Set DOM data attributes
76
83
  document.documentElement.setAttribute('data-theme', effectiveTheme)
77
84
  document.documentElement.setAttribute('data-surface', surfaceStyle)
@@ -118,9 +125,15 @@ export const applyTheme = (cfg: any): void => {
118
125
  }
119
126
  if (cfg.customPanelBg) {
120
127
  const pRgb = hexToRgb(cfg.customPanelBg)
121
- document.documentElement.style.setProperty('--bg-surface', `rgba(${pRgb.r}, ${pRgb.g}, ${pRgb.b}, 0.75)`)
122
- document.documentElement.style.setProperty('--panel-bg', `rgba(${pRgb.r}, ${pRgb.g}, ${pRgb.b}, 0.75)`)
123
- document.documentElement.style.setProperty('--surface-bg', `rgba(${pRgb.r}, ${pRgb.g}, ${pRgb.b}, 0.62)`)
128
+ const panelSurface = surfaceStyle === 'opaque'
129
+ ? cfg.customPanelBg
130
+ : `rgba(${pRgb.r}, ${pRgb.g}, ${pRgb.b}, 0.75)`
131
+ const raisedSurface = surfaceStyle === 'opaque'
132
+ ? cfg.customPanelBg
133
+ : `rgba(${pRgb.r}, ${pRgb.g}, ${pRgb.b}, 0.62)`
134
+ document.documentElement.style.setProperty('--bg-surface', panelSurface)
135
+ document.documentElement.style.setProperty('--panel-bg', panelSurface)
136
+ document.documentElement.style.setProperty('--surface-bg', raisedSurface)
124
137
  }
125
138
  return
126
139
  }
@@ -40,6 +40,15 @@ export interface DocumentAttachment {
40
40
  dataUri: string
41
41
  }
42
42
 
43
+ export interface SourceAttachment {
44
+ name: string
45
+ kind: 'image' | 'file' | 'video'
46
+ mimeType: string
47
+ thumbnailDataUri: string | null
48
+ }
49
+ export interface SessionAttachment extends SourceAttachment { id: number; interactionId: number | null; libraryItemId?: string | null; availability?: string | null; trashed?: boolean }
50
+ export interface ConversationSources { attachments: SessionAttachment[]; webSearchProgress: AgentProgress[] }
51
+
43
52
  export interface PlanTaskItem {
44
53
  id: string
45
54
  title: string
@@ -72,13 +81,24 @@ export interface RunTelemetrySummary {
72
81
  retriesCount: number
73
82
  }
74
83
 
84
+ export type ToolStatus = 'success' | 'failed' | 'timed_out' | 'cancelled'
85
+ export interface McpArtifact {
86
+ id: string; name: string; mimeType: string; kind: 'image' | 'file' | 'link'; size: number
87
+ chatId: string; callId: string; server: string; uri?: string
88
+ }
89
+
75
90
  export type AgentProgress =
91
+ | { type: 'ToolDiscovery'; data: { server: string; tool: string; message: string } }
92
+ | { type: 'DeviceState'; data: { callId: string; server: string; tool: string; update: { state: 'accepted' | 'running' | 'verified' | 'failed' | 'unconfirmed'; deviceId?: string | null; operationId?: string | null; target: Record<string, unknown> | null; actual: Record<string, unknown> | null; observationSeq?: number | null; elapsedSecs: number; message: string } } }
93
+ | { type: 'ToolProgress'; data: { callId: string; server: string; tool: string; update: { progress: number; total?: number; message?: string; elapsedSecs: number } } }
94
+ | { type: 'ToolArtifacts'; data: { callId: string; artifacts: McpArtifact[]; warnings: string[] } }
76
95
  | { type: 'Thinking'; data: { elapsed_secs: number; agent_name?: string; model_name?: string } }
96
+ | { type: 'ContextCompaction'; data: { status: 'started' | 'completed' | 'failed'; message: string; subagent?: string } }
77
97
  | { type: 'Thought'; data: { thought: string } }
78
98
  | { type: 'ThinkingDelta'; data: { id: string; delta: string; elapsed_ms: number } }
79
99
  | { type: 'ExtendedThinking'; data: { id?: string; thought: string; elapsed_ms?: number } }
80
- | { type: 'ToolStart'; data: { action: string; input: Record<string, unknown>; subagent?: string } }
81
- | { type: 'ToolEnd'; data: { action: string; input: Record<string, unknown>; result: string; subagent?: string } }
100
+ | { type: 'ToolStart'; data: { action: string; input: Record<string, unknown>; subagent?: string; callId?: string } }
101
+ | { type: 'ToolEnd'; data: { action: string; input: Record<string, unknown>; result: string; subagent?: string; callId?: string; status?: ToolStatus } }
82
102
  | { type: 'PlanUpdated'; data: { plan: ActivePlan } }
83
103
  | { type: 'RunCompleted'; data: { summary: RunTelemetrySummary } }
84
104
 
@@ -146,6 +166,17 @@ export interface PictureEntry {
146
166
  thumbnailUrl?: string
147
167
  }
148
168
 
169
+ export interface LibraryReference { chatId: string; interactionId: number | null }
170
+ export interface LibraryItem {
171
+ id: string; name: string; filename: string; kind: 'image' | 'video' | 'file'; mimeType: string; size: number
172
+ createdAt: string; origin: 'uploaded' | 'generated' | 'legacy'; source: string; message: string
173
+ deletedAt: string | null; thumbnailStatus: 'pending' | 'ready' | 'unavailable'; availability: 'ready' | 'missing'
174
+ references: LibraryReference[]
175
+ }
176
+ export interface LibraryQuery { kind?: 'image' | 'video' | 'file'; search?: string; chatId?: string; trashed?: boolean; cursor?: string | null }
177
+ export interface LibraryPage { items: LibraryItem[]; nextCursor: string | null }
178
+ export interface AttachmentMetadata { requestId: string; imageNames: string[]; videoNames: string[] }
179
+
149
180
  export interface ImageGenRequest {
150
181
  prompt: string
151
182
  negativePrompt?: string
@@ -190,6 +221,7 @@ export interface WorkspaceTreeEntry {
190
221
  }
191
222
  export interface WorkspaceSnapshot { path: string; tree: WorkspaceTreeEntry; git: GitBranchInfo; revision: number }
192
223
  export interface WorkspaceOperation { root: string; relativePath: string; revision: number }
224
+ export interface WorkspaceHistoryEntry { id: string; label: string; path: string; kind: string; destination: string | null; expected: string | null; backup: string | null }
193
225
 
194
226
  export interface VideoGenRequest {
195
227
  prompt: string
@@ -353,3 +385,25 @@ export interface CustomProviderConfig {
353
385
  models: CustomProviderModel[]
354
386
  headers: CustomProviderHeader[]
355
387
  }
388
+
389
+ export type BackgroundJobStatus = 'running' | 'stopping' | 'completed' | 'failed' | 'stopped'
390
+ export interface BackgroundJob {
391
+ id: string
392
+ command: string
393
+ cwd: string
394
+ workspacePath: string
395
+ chatId: string | null
396
+ pid: number | null
397
+ status: BackgroundJobStatus
398
+ exitCode: number | null
399
+ error: string | null
400
+ startedAt: number
401
+ endedAt: number | null
402
+ elapsedSeconds: number
403
+ serverUrl: string | null
404
+ }
405
+ export interface BackgroundJobOutput extends BackgroundJob {
406
+ stdout: string
407
+ stderr: string
408
+ truncated: boolean
409
+ }
@@ -0,0 +1,75 @@
1
+ import { describe, expect, it } from 'vitest'
2
+ import { describeTool, activitiesFrom } from './agentActivity'
3
+ import { viewedImagesFrom } from './viewedImages'
4
+ import { reduceLiveAgentProgress } from '../agentProgress'
5
+ import type { AgentProgress } from '../types'
6
+
7
+ describe('skill reading activity', () => {
8
+ const input = { path: '/repo/.agents/skills/review/SKILL.md', skill_name: 'review' }
9
+ it('shows a reading label while the tool runs', () => {
10
+ expect(describeTool('read_file', input).label).toBe('Reading skill: review')
11
+ })
12
+ it('shows loaded only after a complete successful skill read', () => {
13
+ const view = activitiesFrom([
14
+ { type: 'ToolStart', data: { action: 'read_file', input } },
15
+ { type: 'ToolEnd', data: { action: 'read_file', input, result: '[Loaded skill: review]\nInstructions' } },
16
+ ])
17
+ expect(view.items[0].label).toBe('Loaded skill: review')
18
+ })
19
+ it('does not claim a failed skill read was loaded', () => {
20
+ const view = activitiesFrom([
21
+ { type: 'ToolStart', data: { action: 'read_file', input } },
22
+ { type: 'ToolEnd', data: { action: 'read_file', input, result: 'Error: denied' } },
23
+ ])
24
+ expect(view.items[0].state).toBe('error')
25
+ expect(view.items[0].label).not.toContain('Loaded skill:')
26
+ })
27
+ it('matches parallel completions to the skill that finished', () => {
28
+ const second = { path: '/repo/skills/test/SKILL.md', skill_name: 'test' }
29
+ const view = activitiesFrom([
30
+ { type: 'ToolStart', data: { action: 'read_file', input } },
31
+ { type: 'ToolStart', data: { action: 'read_file', input: second } },
32
+ { type: 'ToolEnd', data: { action: 'read_file', input, result: '[Loaded skill: review]\nInstructions' } },
33
+ ])
34
+ expect(view.items[0].label).toBe('Loaded skill: review')
35
+ expect(view.items[1].label).toBe('Reading skill: test')
36
+ expect(view.timeline?.filter(item => item.kind === 'activity')).toHaveLength(2)
37
+ })
38
+ it('does not mark a line-range preview as a full skill load', () => {
39
+ const view = activitiesFrom([
40
+ { type: 'ToolStart', data: { action: 'read_file', input } },
41
+ { type: 'ToolEnd', data: { action: 'read_file', input, result: '1 | Header only' } },
42
+ ])
43
+ expect(view.items[0].label).toBe('Read skill preview: review')
44
+ })
45
+ })
46
+
47
+ describe('MCP tool outcomes', () => {
48
+ it('uses the explicit failure status even when diagnostic text has no error prefix', () => {
49
+ const input = { server: 'blender', tool: 'render' }
50
+ const view = activitiesFrom([
51
+ { type: 'ToolStart', data: { callId: 'render-1', action: 'mcp_tool', input } },
52
+ { type: 'ToolEnd', data: { callId: 'render-1', action: 'mcp_tool', input, result: 'render failed', status: 'failed' } },
53
+ ] as any)
54
+ expect(view.items[0].state).toBe('error')
55
+ })
56
+ })
57
+
58
+ it('shows a readable view_image result instead of raw image bytes while preserving hook notes', () => {
59
+ const input = { path: '/workspace/screen.png' }
60
+ const view = activitiesFrom([
61
+ { type: 'ToolStart', data: { action: 'view_image', input } },
62
+ { type: 'ToolEnd', data: { action: 'view_image', input, result: 'data:image/png;base64,aGVsbG8=\n\n[Hook] Checked' } },
63
+ ])
64
+ expect(view.items[0].result).not.toContain('data:image/')
65
+ expect(view.items[0].result).toContain('Image displayed below')
66
+ expect(view.items[0].result).toContain('[Hook] Checked')
67
+ })
68
+
69
+ it('keeps viewed image identity stable when earlier text-only activities are trimmed', () => {
70
+ const earlier: AgentProgress[] = Array.from({ length: 10 }, () => ({ type: 'ToolEnd', data: { action: 'read_file', input: {}, result: 'Read' } }))
71
+ const image: AgentProgress = { type: 'ToolEnd', data: { action: 'view_image', input: { path: 'image.png' }, result: 'data:image/png;base64,aGVsbG8=' } }
72
+ const initial = [...earlier, image]
73
+ const later = Array.from({ length: 40 }, () => ({ type: 'ToolEnd' as const, data: { action: 'read_file', input: {}, result: 'Read' } })).reduce(reduceLiveAgentProgress, initial)
74
+ expect(viewedImagesFrom(later).map(item => item.id)).toEqual(viewedImagesFrom(initial).map(item => item.id))
75
+ })
@@ -5,6 +5,7 @@
5
5
  */
6
6
  import type { AgentProgress } from '../types'
7
7
  import { isInternalCot } from '../agentProgress'
8
+ import { viewedImageDataUri } from './viewedImages'
8
9
 
9
10
  export interface AgentActivity {
10
11
  label: string
@@ -12,6 +13,7 @@ export interface AgentActivity {
12
13
  kind: 'file' | 'folder' | 'search' | 'terminal' | 'tool' | 'calc'
13
14
  state: 'active' | 'done' | 'error' | 'retry'
14
15
  action?: string
16
+ callId?: string
15
17
  /** Raw ToolEnd output text, shown when the row is expanded in the UI. */
16
18
  result?: string
17
19
  }
@@ -131,7 +133,8 @@ export function describeTool(action: string, input: Record<string, unknown>): Ag
131
133
 
132
134
  return {
133
135
  // Raw tool/action identifier, matching how the CLI labels activity (e.g. "[web_search]").
134
- label: action,
136
+ label: action === 'read_file' && activityDetail(input, 'skill_name')
137
+ ? `Reading skill: ${activityDetail(input, 'skill_name')}` : action,
135
138
  target: formatActivityTarget(target),
136
139
  kind: activityKind(action, target),
137
140
  state: 'active',
@@ -250,6 +253,16 @@ function finalizeGroup(group: AgentActivityGroup): AgentActivityGroup {
250
253
  }
251
254
 
252
255
  export function activitiesFrom(progress: AgentProgress[]): AgentActivityView {
256
+ const cached = activityCache.get(progress)
257
+ if (cached?.length === progress.length) return cached.view
258
+ const view = deriveActivitiesFrom(progress)
259
+ activityCache.set(progress, { length: progress.length, view })
260
+ return view
261
+ }
262
+
263
+ const activityCache = new WeakMap<AgentProgress[], { length: number; view: AgentActivityView }>()
264
+
265
+ function deriveActivitiesFrom(progress: AgentProgress[]): AgentActivityView {
253
266
  const activities: AgentActivity[] = []
254
267
  const timeline: TimelineItem[] = []
255
268
  let currentGroup: AgentActivityGroup | null = null
@@ -269,8 +282,16 @@ export function activitiesFrom(progress: AgentProgress[]): AgentActivityView {
269
282
  for (const event of progress) {
270
283
  if (event.type === 'ToolStart') {
271
284
  const item = describeTool(event.data.action, event.data.input)
285
+ item.callId = event.data.callId
272
286
  activities.push(item)
273
287
 
288
+ // Keep each skill's lifecycle visible instead of hiding it in a files group.
289
+ if (event.data.action === 'read_file' && activityDetail(event.data.input, 'skill_name')) {
290
+ flushGroup()
291
+ timeline.push({ id: `skill-${nextId++}`, kind: 'activity', activity: item })
292
+ continue
293
+ }
294
+
274
295
  const actionKey = item.action || item.label
275
296
  if (!currentGroup || currentGroup.action !== actionKey) {
276
297
  flushGroup()
@@ -292,10 +313,23 @@ export function activitiesFrom(progress: AgentProgress[]): AgentActivityView {
292
313
  }
293
314
  }
294
315
  } else if (event.type === 'ToolEnd') {
316
+ const finished = describeTool(event.data.action, event.data.input)
295
317
  for (let index = activities.length - 1; index >= 0; index -= 1) {
296
318
  if (activities[index].state !== 'active') continue
297
- activities[index].state = event.data.result.startsWith('Error:') ? 'error' : 'done'
298
- activities[index].result = event.data.result
319
+ if (event.data.callId && activities[index].callId !== event.data.callId) continue
320
+ if (activities[index].action !== finished.action || activities[index].target !== finished.target) continue
321
+ activities[index].state = event.data.status ? (event.data.status === 'success' ? 'done' : 'error') : /^(Error:|Blocked|User denied)/.test(event.data.result) ? 'error' : 'done'
322
+ const viewedImage = event.data.action === 'view_image' ? viewedImageDataUri(event.data.result) : null
323
+ activities[index].result = viewedImage ? event.data.result.replace(viewedImage, '[Image displayed below]') : event.data.result
324
+ if (event.data.action === 'read_file') {
325
+ const loaded = event.data.result.match(/^\[Loaded skill: ([^\n]+)\]\n/)
326
+ if (loaded) activities[index].label = `Loaded skill: ${loaded[1]}`
327
+ else if (activities[index].label.startsWith('Reading skill:')) {
328
+ activities[index].label = activities[index].state === 'error'
329
+ ? activities[index].label.replace('Reading skill:', 'Failed to read skill:')
330
+ : activities[index].label.replace('Reading skill:', 'Read skill preview:')
331
+ }
332
+ }
299
333
  if (activities[index].action === 'ask_user' && event.data.result.startsWith('User answered:')) {
300
334
  const answer = event.data.result.replace('User answered:', '').trim()
301
335
  activities[index].target = `(Answered: "${answer}") ${activities[index].target}`
@@ -309,6 +343,11 @@ export function activitiesFrom(progress: AgentProgress[]): AgentActivityView {
309
343
  const hasRetry = currentGroup.items.some((it) => it.state === 'retry')
310
344
  currentGroup.state = hasActive ? 'active' : hasDone ? 'done' : hasRetry ? 'retry' : hasError ? 'error' : 'done'
311
345
  }
346
+ } else if (event.type === 'ContextCompaction') {
347
+ if (event.data.status !== 'started') {
348
+ flushGroup()
349
+ timeline.push({ id: `context-${nextId++}`, kind: 'thought', thought: event.data.subagent ? `[${event.data.subagent}] ${event.data.message}` : event.data.message })
350
+ }
312
351
  } else if (event.type === 'Thought') {
313
352
  const text = event.data?.thought?.trim()
314
353
  if (text) {
@@ -13,6 +13,12 @@ export interface ApprovalDetails {
13
13
  isDangerous: boolean
14
14
  }
15
15
 
16
+ // Skill changes require a decision for this proposal, including in sessions
17
+ // where ordinary tool requests have already been allowed.
18
+ export function requiresExplicitApproval(approval: Record<string, unknown> | undefined): boolean {
19
+ return !!approval?.SkillWrite
20
+ }
21
+
16
22
  function parseDiffStats(diffText?: string): string {
17
23
  if (!diffText) return ''
18
24
  let additions = 0
@@ -44,6 +50,7 @@ export function renderApprovalDetails(approval: any): ApprovalDetails {
44
50
  const { server, tool, arguments: args } = approval.McpTool
45
51
  return { title: `Run MCP Tool: ${server}/${tool}`, body: typeof args === 'string' ? args : JSON.stringify(args, null, 2), reason: 'Running external MCP tool.', isDangerous: false }
46
52
  }
53
+ if (approval.SkillWrite) return { title: 'Save Skill', body: `Path: ${approval.SkillWrite.path}`, reason: 'This changes instructions used in future tasks. Review the proposed changes before saving.', isDangerous: false }
47
54
  if (approval.UserApproval) return { title: approval.UserApproval.title, body: approval.UserApproval.prompt, reason: 'The agent requested explicit approval.', isDangerous: false }
48
55
  if (approval.AskUser) {
49
56
  const hasOptions = Array.isArray(approval.AskUser.options) && approval.AskUser.options.length > 0
@@ -0,0 +1,80 @@
1
+ import { describe, expect, it, vi } from 'vitest'
2
+ import { installRendererPlatform } from '../platform'
3
+ import * as desktopAdapter from '../../src/tauri'
4
+ import { openArtifactInMintBrowser } from './artifactBrowser'
5
+
6
+ const native = vi.hoisted(() => ({ invoke: vi.fn(async () => undefined) }))
7
+ vi.mock('@tauri-apps/api/core', () => ({ invoke: native.invoke }))
8
+
9
+ const url = 'http://127.0.0.1:12345/site/index.html'
10
+ describe('opening a preview in Mint Browser', () => {
11
+ it('opens an existing served URL through Mint Browser on Desktop', async () => {
12
+ const opened: string[] = []
13
+ await openArtifactInMintBrowser({ path: 'site/index.html', url }, '/projects/Demo', {
14
+ desktop: true,
15
+ startPreview: async () => { throw new Error('An existing URL must be reused') },
16
+ openMintBrowser: async (target) => { opened.push(target) },
17
+ })
18
+ expect(opened).toEqual([url])
19
+ })
20
+ it('serves chat artifacts from their pinned project before opening Mint Browser', async () => {
21
+ const actions: unknown[] = []
22
+ await openArtifactInMintBrowser({ path: 'site/index.html', workspacePath: '/projects/Original' }, '/projects/Other', {
23
+ desktop: true,
24
+ startPreview: async (root, path, mint) => { actions.push([root, path, mint]); return { url, jobId: 'preview-1' } },
25
+ openMintBrowser: async (target) => { actions.push(target) },
26
+ })
27
+ expect(actions).toEqual([['/projects/Original', 'site/index.html', false], url])
28
+ })
29
+ it('opens the controlled browser through the authenticated local backend on Web', async () => {
30
+ const requests: unknown[] = []
31
+ await openArtifactInMintBrowser({ path: 'site/index.html', url, workspacePath: '/projects/Demo' }, undefined, {
32
+ desktop: false,
33
+ startPreview: async (root, path, mint) => { requests.push([root, path, mint]); return { url, jobId: 'preview-1' } },
34
+ openMintBrowser: async () => { throw new Error('Web must not call native IPC') },
35
+ })
36
+ expect(requests).toEqual([['/projects/Demo', 'site/index.html', true]])
37
+ })
38
+ it('reports browser launch failures so the button can show an error', async () => {
39
+ await expect(openArtifactInMintBrowser({ path: 'site/index.html', url }, undefined, {
40
+ desktop: true,
41
+ startPreview: async () => { throw new Error('Unexpected server startup') },
42
+ openMintBrowser: async () => { throw new Error('Chrome unavailable') },
43
+ })).rejects.toThrow('Chrome unavailable')
44
+ })
45
+ it('does not start a server without a source project', async () => {
46
+ await expect(openArtifactInMintBrowser({ path: 'site/index.html' }, undefined, {
47
+ desktop: true,
48
+ startPreview: async () => { throw new Error('Unexpected server startup') },
49
+ openMintBrowser: async () => { throw new Error('Unexpected browser startup') },
50
+ })).rejects.toThrow('Select a project')
51
+ })
52
+ })
53
+
54
+ it('sends the existing open_mint_browser IPC command for the default Desktop action', async () => {
55
+ installRendererPlatform({ ...desktopAdapter, isTauriRuntime: () => true })
56
+ native.invoke.mockClear()
57
+ await openArtifactInMintBrowser({ path: 'site/index.html', url }, undefined)
58
+ expect(native.invoke).toHaveBeenCalledWith('open_mint_browser', { url })
59
+ })
60
+
61
+ it.each([
62
+ ['/projects/Demo', '/projects/Demo/site/index.html', 'site/index.html'],
63
+ ['C:\\Projects\\Demo', 'c:\\projects\\demo\\site\\index.html', 'site/index.html'],
64
+ ])('opens absolute artifact paths relative to their source project %s', async (root, path, relative) => {
65
+ const requests: unknown[] = []
66
+ await openArtifactInMintBrowser({ path, workspacePath: root }, '/projects/Other', {
67
+ desktop: true,
68
+ startPreview: async (workspace, file, mint) => { requests.push([workspace, file, mint]); return { url, jobId: 'preview-1' } },
69
+ openMintBrowser: async () => {},
70
+ })
71
+ expect(requests).toEqual([[root, relative, false]])
72
+ })
73
+
74
+ it('rejects an absolute artifact from a different project without starting a server', async () => {
75
+ await expect(openArtifactInMintBrowser({ path: '/projects/Demo-copy/index.html', workspacePath: '/projects/Demo' }, undefined, {
76
+ desktop: true,
77
+ startPreview: async () => { throw new Error('Unexpected server startup') },
78
+ openMintBrowser: async () => {},
79
+ })).rejects.toThrow('outside its source project')
80
+ })
@@ -0,0 +1,41 @@
1
+ import type { ArtifactFile } from '../components/ArtifactPreviewPanel'
2
+ import { runtimePlatform, workspacePlatform } from '../platform'
3
+
4
+ interface BrowserApi {
5
+ desktop: boolean
6
+ startPreview(root: string, path: string, mintBrowser: boolean): Promise<{ url: string; jobId: string }>
7
+ openMintBrowser(url: string): Promise<void>
8
+ }
9
+
10
+ export async function openArtifactInMintBrowser(
11
+ artifact: ArtifactFile,
12
+ workspace: string | undefined,
13
+ api: BrowserApi = {
14
+ desktop: runtimePlatform.isTauriRuntime(),
15
+ startPreview: (root, path, mint) => workspacePlatform.startHtmlPreview(root, path, mint),
16
+ openMintBrowser: async (url) => {
17
+ const { invoke } = await import('@tauri-apps/api/core')
18
+ await invoke('open_mint_browser', { url })
19
+ },
20
+ },
21
+ ): Promise<void> {
22
+ if (api.desktop && artifact.url) {
23
+ await api.openMintBrowser(artifact.url)
24
+ return
25
+ }
26
+ const root = (artifact.workspacePath ?? workspace)?.trim()
27
+ if (!root) throw new Error('Select a project before opening its preview in Mint Browser')
28
+ let path = artifact.path.replace(/\\/g, '/')
29
+ if (/^(\/|[a-z]:\/)/i.test(path)) {
30
+ const normalizedRoot = root.replace(/\\/g, '/').replace(/\/+$/, '')
31
+ const prefix = `${normalizedRoot}/`
32
+ const windows = /^[a-z]:\//i.test(normalizedRoot) || normalizedRoot.startsWith('//')
33
+ if (!(windows ? path.toLowerCase().startsWith(prefix.toLowerCase()) : path.startsWith(prefix))) {
34
+ throw new Error('This file is outside its source project')
35
+ }
36
+ path = path.slice(prefix.length)
37
+ }
38
+ // The authenticated local Web endpoint launches the same automation browser on the backend.
39
+ const preview = await api.startPreview(root, path, !api.desktop)
40
+ if (api.desktop) await api.openMintBrowser(preview.url)
41
+ }
@@ -0,0 +1,48 @@
1
+ import React from 'react'
2
+ import { renderToStaticMarkup } from 'react-dom/server'
3
+ import { describe, expect, it } from 'vitest'
4
+ import { activeCompactionFrom } from './contextCompaction'
5
+ import { ContextCompactionStatus } from '../components/ContextCompactionStatus'
6
+ import { activitiesFrom } from './agentActivity'
7
+ import type { AgentProgress } from '../types'
8
+
9
+ const started = { type: 'ContextCompaction', data: { status: 'started', message: 'Summarizing earlier steps to continue working' } } as const
10
+ const completed = { type: 'ContextCompaction', data: { status: 'completed', message: 'Context compacted' } } as const
11
+ const failed = { type: 'ContextCompaction', data: { status: 'failed', message: 'Context compaction failed: provider unavailable. Continuing with the original context.' } } as const
12
+
13
+ describe('context compaction progress', () => {
14
+ it('keeps compaction active until its terminal event, then allows normal working status', () => {
15
+ expect(activeCompactionFrom([started, { type: 'Thinking', data: { elapsed_secs: 10 } }])?.message).toContain('Summarizing earlier steps')
16
+ expect(activeCompactionFrom([started, completed])).toBeNull()
17
+ expect(activeCompactionFrom([started, failed])).toBeNull()
18
+ expect(activeCompactionFrom([started, completed, started])).not.toBeNull()
19
+ })
20
+ it('renders the elapsed timer, explanatory text and animated gradient label', () => {
21
+ const html = renderToStaticMarkup(<ContextCompactionStatus elapsedSeconds={12} />)
22
+ expect(html).toContain('Compacting context')
23
+ expect(html).toContain('12s')
24
+ expect(html).toContain('Summarizing earlier steps to continue working')
25
+ expect(html).toContain('thinking-status-label')
26
+ expect(html).toContain('role="status"')
27
+ })
28
+ it('keeps completion and actionable failure visible in activity history, without a completed start row', () => {
29
+ const timeline = activitiesFrom([started, completed, started, failed]).timeline
30
+ expect(timeline?.map(item => 'thought' in item ? item.thought : '')).toEqual([completed.data.message, failed.data.message])
31
+ })
32
+ })
33
+
34
+ it('keeps the collective timer active until all parallel subagents finish', () => {
35
+ const a = { ...started, data: { ...started.data, subagent: 'A' } }
36
+ const b = { ...started, data: { ...started.data, subagent: 'B' } }
37
+ const doneA = { ...completed, data: { ...completed.data, subagent: 'A' } }
38
+ const doneB = { ...completed, data: { ...completed.data, subagent: 'B' } }
39
+ expect(activeCompactionFrom([a, b, doneA])?.index).toBe(0)
40
+ expect(activeCompactionFrom([a, b, doneA, doneB])).toBeNull()
41
+ })
42
+
43
+ it('keeps repeated-name subagents active until every lifecycle finishes', () => {
44
+ const child = { ...started, data: { ...started.data, subagent: 'reviewer' } }
45
+ const done = { ...completed, data: { ...completed.data, subagent: 'reviewer' } }
46
+ expect(activeCompactionFrom([child, child, done])?.index).toBe(0)
47
+ expect(activeCompactionFrom([child, child, done, done])).toBeNull()
48
+ })
@@ -0,0 +1,21 @@
1
+ import type { AgentProgress } from '../types'
2
+
3
+ export function activeCompactionFrom(progress: AgentProgress[]) {
4
+ const pending = new Map<string, { count: number; data: Extract<AgentProgress, { type: 'ContextCompaction' }>['data'] }>()
5
+ let cycleIndex = 0
6
+ for (let index = 0; index < progress.length; index++) {
7
+ const event = progress[index]
8
+ if (event.type !== 'ContextCompaction') continue
9
+ const scope = event.data.subagent ?? ''
10
+ if (event.data.status === 'started') {
11
+ if (pending.size === 0) cycleIndex = index
12
+ pending.set(scope, { count: (pending.get(scope)?.count ?? 0) + 1, data: event.data })
13
+ } else {
14
+ const entry = pending.get(scope)
15
+ if (entry && entry.count > 1) entry.count--
16
+ else pending.delete(scope)
17
+ }
18
+ }
19
+ const active = pending.values().next().value
20
+ return active ? { ...active.data, index: cycleIndex } : null
21
+ }
@@ -0,0 +1,9 @@
1
+ // Each renderer window owns its visibility listener for its lifetime.
2
+ const initialized = new WeakSet<Document>()
3
+ export function initializeEffectVisibility(): void {
4
+ if (typeof document === 'undefined' || !document.addEventListener || initialized.has(document)) return
5
+ initialized.add(document)
6
+ const update = () => document.documentElement.setAttribute('data-effects-hidden', String(document.hidden))
7
+ document.addEventListener('visibilitychange', update)
8
+ update()
9
+ }
@@ -417,13 +417,13 @@ function renderMessageImage(src: string | undefined, alt: string | undefined, so
417
417
  className="chat-media-card chat-media-card--thumbnail"
418
418
  style={{ margin: '6px 0 10px', borderRadius: '10px', overflow: 'hidden', border: '1px solid var(--border, rgba(255,255,255,0.12))', background: 'var(--panel-bg, #141416)', maxWidth: '420px' }}
419
419
  >
420
- <a href={pageUrl} target="_blank" rel="noopener noreferrer" title={sourceUrl ? `Open source page: ${label}` : label} style={{ display: 'block', textDecoration: 'none' }}>
420
+ <a href={pageUrl} target="_blank" rel="noopener noreferrer" title={sourceUrl ? `Open source page: ${label}` : label} style={{ display: 'flex', justifyContent: 'center', textDecoration: 'none' }}>
421
421
  <img
422
422
  src={url}
423
423
  alt={label}
424
424
  loading="lazy"
425
425
  referrerPolicy="no-referrer"
426
- style={{ width: '100%', maxHeight: '200px', objectFit: 'cover', display: 'block' }}
426
+ style={{ width: 'auto', height: 'auto', maxWidth: '100%', maxHeight: '420px', objectFit: 'contain', display: 'block' }}
427
427
  onError={(e) => { const card = e.currentTarget.closest('.chat-media-card') as HTMLElement | null; if (card) card.style.display = 'none' }}
428
428
  />
429
429
  </a>
@@ -700,7 +700,7 @@ function splitVideoSegments(text: string): Segment[] {
700
700
  }
701
701
 
702
702
  export function renderFormattedMessage(text: string, webSources: WebSearchSource[] = []): ReactNode {
703
- const displayText = readableAssistantText(text)
703
+ const displayText = readableAssistantText(text.replace(/\r\n?/g, '\n'))
704
704
  if (!displayText) return null
705
705
 
706
706
  const segments = splitVideoSegments(displayText)