@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,20 +1,11 @@
1
1
  import React from 'react'
2
+ import { ErrorRecovery } from './ui/error-recovery'
2
3
 
3
4
  interface State {
4
5
  hasError: boolean
5
6
  }
6
7
 
7
- /**
8
- * Catches errors from lazy-loaded route chunks (e.g. a stale cached page
9
- * trying to fetch a hashed JS file that no longer exists after a rebuild)
10
- * and offers a reload instead of leaving the app permanently blank.
11
- *
12
- * Deliberately styled with plain inline styles instead of the app's themed
13
- * CSS: this screen exists for the case where something in the app's own
14
- * loading chain already failed, so it shouldn't gamble on `--bg-color` /
15
- * `--accent` etc. having made it in — a fixed white background reads
16
- * correctly no matter what broke.
17
- */
8
+ /** Catches failed route chunks and keeps recovery/window controls available. */
18
9
  type Props = { children: React.ReactNode }
19
10
 
20
11
  export default class ChunkErrorBoundary extends React.Component<Props, State> {
@@ -91,7 +82,7 @@ export default class ChunkErrorBoundary extends React.Component<Props, State> {
91
82
  width: '100vw',
92
83
  background: '#09090b',
93
84
  color: '#e4e4e7',
94
- fontFamily: 'Outfit, Inter, ui-sans-serif, system-ui, sans-serif',
85
+ fontFamily: "'IBM Plex Sans Thai', 'Noto Sans Thai', 'Inter', ui-sans-serif, system-ui, sans-serif",
95
86
  boxSizing: 'border-box',
96
87
  overflow: 'hidden',
97
88
  }}
@@ -186,96 +177,7 @@ export default class ChunkErrorBoundary extends React.Component<Props, State> {
186
177
  </div>
187
178
  </div>
188
179
 
189
- <div
190
- style={{
191
- flex: 1,
192
- display: 'flex',
193
- flexDirection: 'column',
194
- alignItems: 'center',
195
- justifyContent: 'center',
196
- padding: 24,
197
- boxSizing: 'border-box',
198
- }}
199
- >
200
- <div
201
- style={{
202
- display: 'flex',
203
- flexDirection: 'column',
204
- alignItems: 'center',
205
- maxWidth: 420,
206
- textAlign: 'center',
207
- padding: '32px 28px',
208
- borderRadius: 20,
209
- background: '#18181b',
210
- border: '1px solid rgba(255, 255, 255, 0.08)',
211
- boxShadow: '0 20px 40px rgba(0, 0, 0, 0.6)',
212
- gap: 16,
213
- }}
214
- >
215
- <div
216
- style={{
217
- width: 48,
218
- height: 48,
219
- borderRadius: 14,
220
- background: 'rgba(16, 185, 129, 0.12)',
221
- border: '1px solid rgba(16, 185, 129, 0.25)',
222
- display: 'flex',
223
- alignItems: 'center',
224
- justifyContent: 'center',
225
- color: '#10b981',
226
- fontSize: '1.4rem',
227
- fontWeight: 700,
228
- }}
229
- >
230
- ✦
231
- </div>
232
- <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
233
- <h2 style={{ margin: 0, fontSize: '1.15rem', fontWeight: 650, color: '#f4f4f5' }}>
234
- Mint needs to refresh
235
- </h2>
236
- <span style={{ fontSize: '0.88rem', color: '#a1a1aa', lineHeight: 1.5 }}>
237
- An asset failed to load or a new version was deployed. Refreshing will load the latest version.
238
- </span>
239
- </div>
240
- <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginTop: 8 }}>
241
- <button
242
- type="button"
243
- onClick={this.handleReset}
244
- style={{
245
- padding: '10px 18px',
246
- borderRadius: 12,
247
- border: '1px solid rgba(255, 255, 255, 0.12)',
248
- background: 'rgba(255, 255, 255, 0.06)',
249
- color: '#e4e4e7',
250
- fontWeight: 600,
251
- fontSize: '0.88rem',
252
- cursor: 'pointer',
253
- transition: 'background 0.15s ease',
254
- }}
255
- >
256
- Back to Chat
257
- </button>
258
- <button
259
- type="button"
260
- onClick={this.handleReload}
261
- style={{
262
- padding: '10px 22px',
263
- borderRadius: 12,
264
- border: 'none',
265
- background: '#10b981',
266
- color: '#06120c',
267
- fontWeight: 650,
268
- fontSize: '0.88rem',
269
- cursor: 'pointer',
270
- boxShadow: '0 4px 14px rgba(16, 185, 129, 0.25)',
271
- transition: 'background 0.15s ease, transform 0.1s ease',
272
- }}
273
- >
274
- Refresh &amp; Update
275
- </button>
276
- </div>
277
- </div>
278
- </div>
180
+ <ErrorRecovery onBackToChat={this.handleReset} onRefresh={this.handleReload} />
279
181
  </div>
280
182
  )
281
183
  }
@@ -0,0 +1,125 @@
1
+ import React from 'react'
2
+ import { renderToStaticMarkup } from 'react-dom/server'
3
+ import { describe, expect, it } from 'vitest'
4
+ import CliSessionsView from './CliSessionsView'
5
+ import { workspacePaths } from '../utils/workspaces'
6
+ import type { ChatSession } from '../types'
7
+
8
+ const demo = '/home/pheem49/vscode/Project/Demo'
9
+ const mint = '/home/pheem49/vscode/Project/Mint-CLI'
10
+ const session = (id: string, kind: string, workspacePath?: string): ChatSession => ({
11
+ id, kind, workspacePath, title: `Task ${id}`,
12
+ createdAt: '2026-10-05T15:10:24Z', updatedAt: '2026-10-05T15:10:24Z',
13
+ messageCount: 1, totalBytes: 100,
14
+ })
15
+
16
+ function render(chatSessions: ChatSession[], workspacePath?: string, recentWorkspacePaths?: string[]) {
17
+ return renderToStaticMarkup(<CliSessionsView
18
+ chatSessions={chatSessions}
19
+ workspacePath={workspacePath}
20
+ recentWorkspacePaths={recentWorkspacePaths}
21
+ activeConversationId="conversation-demo"
22
+ onSelectSession={() => {}}
23
+ onDeleteSession={() => {}}
24
+ onRenameSession={() => {}}
25
+ />)
26
+ }
27
+
28
+ describe('Code hub Current Project', () => {
29
+ it('shows only CLI sessions in the selected project and counts the visible scope', () => {
30
+ const html = render([
31
+ session('conversation-demo', 'conversation', demo),
32
+ session('cli::demo', 'cli', demo),
33
+ session('cli::mint', 'cli', mint),
34
+ session('conversation-mint', 'conversation', mint),
35
+ ], demo)
36
+ expect(html).not.toContain('Task conversation-demo')
37
+ expect(html).toContain('Task cli::demo')
38
+ expect(html).not.toContain('Task cli::mint')
39
+ expect(html).not.toContain('Task conversation-mint')
40
+ expect(html).toMatch(/code-header-count[^>]*>1 session</)
41
+ expect(html).not.toContain('mint --resume conversation-demo')
42
+ })
43
+
44
+ it('identifies a project without CLI sessions even when other repositories have sessions', () => {
45
+ const html = render([
46
+ session('conversation-demo', 'conversation', demo),
47
+ session('cli::mint', 'cli', mint),
48
+ ], demo)
49
+ expect(html).toMatch(/code-header-count[^>]*>0 sessions</)
50
+ expect(html).toContain('No CLI sessions found in Demo.')
51
+ expect(html).toContain(`title="${demo}"`)
52
+ })
53
+
54
+ it('uses the searchable workspace dialog trigger in Code hub', () => {
55
+ const html = render([session('cli::mint', 'cli', mint)], mint)
56
+ expect(html).toContain('aria-label="Change workspace: Mint-CLI"')
57
+ expect(html).toContain('aria-haspopup="dialog"')
58
+ expect(html).toContain(`title="${mint}"`)
59
+ })
60
+
61
+ it('counts CLI sessions outside an empty project and offers to show them all', () => {
62
+ const html = render([
63
+ session('conversation-demo', 'conversation', demo),
64
+ ...Array.from({ length: 37 }, (_, i) => session(`cli::mint-${i}`, 'cli', mint)),
65
+ ], demo)
66
+ expect(html).toContain('37 CLI sessions outside this project')
67
+ expect(html).toMatch(/>Show all sessions<\/button>/)
68
+ })
69
+
70
+ it('does not offer a show-all empty-state action when no CLI sessions exist', () => {
71
+ const html = render([session('conversation-demo', 'conversation', demo)], demo)
72
+ expect(html).not.toMatch(/>Show all sessions<\/button>/)
73
+ expect(html).not.toContain('CLI sessions outside this project')
74
+ })
75
+
76
+ it('does not mix unassigned sessions into a selected project', () => {
77
+ const html = render([
78
+ session('cli::global', 'cli'),
79
+ session('conversation-global', 'conversation'),
80
+ session('cli::demo', 'cli', demo),
81
+ ], demo)
82
+ expect(html).toContain('Task cli::demo')
83
+ expect(html).not.toContain('Task cli::global')
84
+ expect(html).not.toContain('Task conversation-global')
85
+ })
86
+
87
+ it.each([
88
+ [demo, ` ${demo}/ `],
89
+ ['C:\\Projects\\Demo', 'C:/Projects/Demo/'],
90
+ ])('matches equivalent workspace spellings: %s', (stored, selected) => {
91
+ expect(render([session('cli::demo', 'cli', stored)], selected)).toContain('Task cli::demo')
92
+ })
93
+
94
+ it('keeps distinct directories and Linux case differences separate', () => {
95
+ const html = render([
96
+ session('cli::prefix', 'cli', `${demo}-other`),
97
+ session('cli::case', 'cli', demo.toLowerCase()),
98
+ ], demo)
99
+ expect(html).not.toContain('Task cli::prefix')
100
+ expect(html).not.toContain('Task cli::case')
101
+ })
102
+
103
+ it('requests a project selection instead of showing every session when no workspace is selected', () => {
104
+ const html = render([session('cli::demo', 'cli', demo)])
105
+ expect(html).not.toContain('Task cli::demo')
106
+ expect(html).toContain('Select a project')
107
+ })
108
+ })
109
+
110
+
111
+ describe('shared workspace catalog', () => {
112
+ it('includes session-only projects without changing the recent-folder order', () => {
113
+ expect(workspacePaths([mint, demo], mint, ['/home/pheem49', '/projects/FableMint', demo]))
114
+ .toEqual([mint, demo, '/home/pheem49', '/projects/FableMint'])
115
+ })
116
+ it('deduplicates equivalent paths and retains distinct folders with the same name', () => {
117
+ expect(workspacePaths([` ${mint}/ `, mint, '/another/Mint-CLI'], '', [undefined, 'C:\\Projects\\Demo', 'C:/Projects/Demo/']))
118
+ .toEqual([mint, '/another/Mint-CLI', 'C:/Projects/Demo'])
119
+ })
120
+ })
121
+
122
+ it('preserves absolute Windows drive roots when deduplicating workspace folders', () => {
123
+ expect(workspacePaths(['C:\\', 'C:/', '/'], 'C:/', ['C:/Projects/Demo/']))
124
+ .toEqual(['C:/', '/', 'C:/Projects/Demo'])
125
+ })
@@ -1,15 +1,20 @@
1
+ import SelectField from './SelectField'
1
2
  import React, { useState, useMemo, useEffect, useRef } from 'react'
2
3
  import type { ChatSession } from '../types'
3
4
  import { parseUtcDate } from '../utils/ui'
5
+ import { normalizeWorkspacePath, workspacePaths } from '../utils/workspaces'
6
+ import WorkspaceSelector from './WorkspaceSelector'
4
7
  import '../css/code-sessions.css'
5
8
 
6
9
  export interface CliSessionsViewProps {
7
10
  chatSessions: ChatSession[]
8
11
  activeConversationId: string
9
12
  workspacePath?: string
13
+ recentWorkspacePaths?: string[]
10
14
  onSelectSession: (id: string) => void
11
15
  onDeleteSession: (id: string) => void
12
16
  onRenameSession: (id: string, newTitle: string) => void
17
+ onSelectFolder?: () => Promise<string | null>
13
18
  onRefreshSessions?: () => void
14
19
  onShowToast?: (message: string) => void
15
20
  }
@@ -40,13 +45,16 @@ function getFolderBasename(path?: string | null): string {
40
45
  return parts[parts.length - 1] || path
41
46
  }
42
47
 
48
+
43
49
  export const CliSessionsView: React.FC<CliSessionsViewProps> = React.memo(function CliSessionsView({
44
50
  chatSessions,
45
51
  activeConversationId,
46
52
  workspacePath,
53
+ recentWorkspacePaths,
47
54
  onSelectSession,
48
55
  onDeleteSession,
49
56
  onRenameSession,
57
+ onSelectFolder,
50
58
  onRefreshSessions,
51
59
  onShowToast,
52
60
  }) {
@@ -55,6 +63,14 @@ export const CliSessionsView: React.FC<CliSessionsViewProps> = React.memo(functi
55
63
  const [sortBy, setSortBy] = useState<'recent' | 'messages' | 'oldest'>('recent')
56
64
  const [editingSessionId, setEditingSessionId] = useState<string | null>(null)
57
65
  const [editTitleValue, setEditTitleValue] = useState('')
66
+ const [selectedWorkspace, setSelectedWorkspace] = useState(() => normalizeWorkspacePath(workspacePath))
67
+ useEffect(() => {
68
+ setSelectedWorkspace(normalizeWorkspacePath(workspacePath))
69
+ }, [workspacePath])
70
+ const currentWorkspace = selectedWorkspace
71
+ const projectName = getFolderBasename(currentWorkspace)
72
+ const projectPaths = useMemo(() => workspacePaths(recentWorkspacePaths || [], selectedWorkspace),
73
+ [recentWorkspacePaths, selectedWorkspace])
58
74
 
59
75
  const onRefreshRef = useRef(onRefreshSessions)
60
76
  useEffect(() => {
@@ -74,12 +90,17 @@ export const CliSessionsView: React.FC<CliSessionsViewProps> = React.memo(functi
74
90
  const allCliSessions = useMemo(() => {
75
91
  return chatSessions.filter((s) => s.kind === 'cli' || s.id.startsWith('cli'))
76
92
  }, [chatSessions])
93
+ const projectSessionCount = allCliSessions.filter((session) =>
94
+ currentWorkspace && normalizeWorkspacePath(session.workspacePath) === currentWorkspace).length
95
+ const otherSessionCount = allCliSessions.length - projectSessionCount
96
+ const showOtherSessions = scopeFilter === 'workspace' && !searchQuery.trim()
97
+ && projectSessionCount === 0 && otherSessionCount > 0
77
98
 
78
99
  const filteredSessions = useMemo(() => {
79
100
  return allCliSessions
80
101
  .filter((s) => {
81
- if (scopeFilter === 'workspace' && workspacePath && s.workspacePath) {
82
- if (s.workspacePath !== workspacePath) return false
102
+ if (scopeFilter === 'workspace') {
103
+ if (!currentWorkspace || normalizeWorkspacePath(s.workspacePath) !== currentWorkspace) return false
83
104
  }
84
105
 
85
106
  if (!searchQuery.trim()) return true
@@ -103,7 +124,7 @@ export const CliSessionsView: React.FC<CliSessionsViewProps> = React.memo(functi
103
124
  }
104
125
  return timeB - timeA
105
126
  })
106
- }, [allCliSessions, scopeFilter, workspacePath, searchQuery, sortBy])
127
+ }, [allCliSessions, scopeFilter, currentWorkspace, searchQuery, sortBy])
107
128
 
108
129
  const handleCopyResumeCommand = (e: React.MouseEvent, sessionId: string) => {
109
130
  e.stopPropagation()
@@ -162,22 +183,42 @@ export const CliSessionsView: React.FC<CliSessionsViewProps> = React.memo(functi
162
183
  <span>Code sessions</span>
163
184
  </h1>
164
185
  <span className="code-header-count">
165
- {allCliSessions.length} {allCliSessions.length === 1 ? 'session' : 'sessions'}
186
+ {filteredSessions.length} {filteredSessions.length === 1 ? 'session' : 'sessions'}
166
187
  </span>
167
188
  </div>
168
189
  <p className="code-header-subtitle">
169
- Terminal conversations and agent runs from your active repositories.
190
+ {scopeFilter === 'workspace'
191
+ ? currentWorkspace
192
+ ? <>CLI sessions in <strong title={currentWorkspace}>{projectName}</strong>.</>
193
+ : 'Select a project above to view its CLI sessions.'
194
+ : 'CLI sessions across all repositories.'}
170
195
  </p>
171
196
  </div>
172
197
 
173
198
  {/* Right side controls: Scope switch & refresh */}
174
- <div style={{ display: 'flex', alignItems: 'center', gap: '8px', flexWrap: 'wrap' }}>
199
+ <div className="code-header-controls">
200
+ <WorkspaceSelector
201
+ currentPath={currentWorkspace}
202
+ recentPaths={projectPaths}
203
+ placement="below"
204
+ onSelectWorkspace={async (path) => {
205
+ try {
206
+ const selected = path || await onSelectFolder?.()
207
+ if (selected) {
208
+ setSelectedWorkspace(normalizeWorkspacePath(selected))
209
+ setScopeFilter('workspace')
210
+ }
211
+ } catch (error) {
212
+ onShowToast?.(`Could not open folder: ${error instanceof Error ? error.message : String(error)}`)
213
+ }
214
+ }}
215
+ />
175
216
  <div className="code-segmented-toggle">
176
217
  <button
177
218
  type="button"
178
219
  className={`code-segmented-btn ${scopeFilter === 'workspace' ? 'active' : ''}`}
179
220
  onClick={() => setScopeFilter('workspace')}
180
- title="Show sessions from current workspace"
221
+ title="Show sessions from the selected project"
181
222
  >
182
223
  Current Project
183
224
  </button>
@@ -191,16 +232,16 @@ export const CliSessionsView: React.FC<CliSessionsViewProps> = React.memo(functi
191
232
  </button>
192
233
  </div>
193
234
 
194
- <select
235
+ <SelectField fullWidth={false} aria-label="Sort sessions"
195
236
  className="code-sort-select"
196
237
  value={sortBy}
197
- onChange={(e) => setSortBy(e.target.value as any)}
238
+ onValueChange={(nextValue) => setSortBy(nextValue as any)}
198
239
  title="Sort sessions"
199
240
  >
200
241
  <option value="recent">Recently active</option>
201
242
  <option value="messages">Most turns</option>
202
243
  <option value="oldest">Oldest first</option>
203
- </select>
244
+ </SelectField>
204
245
 
205
246
  {onRefreshSessions && (
206
247
  <button
@@ -265,12 +306,19 @@ export const CliSessionsView: React.FC<CliSessionsViewProps> = React.memo(functi
265
306
  </div>
266
307
  <div className="code-terminal-body">
267
308
  <p className="code-terminal-text">
268
- {searchQuery
309
+ {searchQuery.trim()
269
310
  ? 'No terminal sessions match your query.'
270
- : scopeFilter === 'workspace' && allCliSessions.length > 0
271
- ? 'No sessions found in this project. Switch to "All Repositories" or start one in this directory:'
311
+ : scopeFilter === 'workspace'
312
+ ? currentWorkspace
313
+ ? `No CLI sessions found in ${projectName}.${otherSessionCount > 0 ? ` ${otherSessionCount} CLI ${otherSessionCount === 1 ? 'session' : 'sessions'} outside this project.` : ' Run Mint in this project directory to begin:'}`
314
+ : 'Select a project above, or switch to "All Repositories" to view your CLI sessions.'
272
315
  : 'No terminal sessions recorded yet. Launch Mint in any repository to begin:'}
273
316
  </p>
317
+ {showOtherSessions && (
318
+ <button type="button" className="code-segmented-btn active code-show-all-btn"
319
+ onClick={() => { setSearchQuery(''); setScopeFilter('all') }}
320
+ >Show all sessions</button>
321
+ )}
274
322
  <div className="code-terminal-codeblock">
275
323
  <span>$ mint</span>
276
324
  <button
@@ -1,7 +1,10 @@
1
+ import SelectField from './SelectField'
1
2
  import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
2
3
  import type { PointerEvent as ReactPointerEvent } from 'react'
3
- import type { FileChange, GitBranchInfo } from '../types'
4
+ import type { FileChange, GitBranchInfo, WorkspaceHistoryEntry } from '../types'
4
5
  import { workspacePlatform } from '../platform'
6
+ import { useWorkspaceUndo } from '../workspaceUndo'
7
+ import { HistoryDetails, UndoConfirmation } from './ReviewHistory'
5
8
  import GitBranchSelector from './GitBranchSelector'
6
9
  import {
7
10
  materialFolderIcon,
@@ -26,6 +29,31 @@ function diffLines(text: string) {
26
29
  return text.replace(/\n$/, '').split('\n')
27
30
  }
28
31
 
32
+ /** Display paths inside the selected workspace, with a boundary-safe prefix. */
33
+ function workspaceRelativePath(path: string, workspace?: string | null): string | null {
34
+ const normalized = path.replace(/\\/g, '/')
35
+ const root = workspace?.replace(/\\/g, '/').replace(/\/+$/, '')
36
+ const isAbsolute = /^(\/|[a-z]:\/)/i.test(normalized)
37
+ let relative = normalized
38
+ if (root && isAbsolute) {
39
+ const windows = /^[a-z]:\//i.test(root) || root.startsWith('//')
40
+ const prefix = `${root}/`
41
+ if (!(windows ? normalized.toLowerCase().startsWith(prefix.toLowerCase()) : normalized.startsWith(prefix))) return null
42
+ relative = normalized.slice(prefix.length)
43
+ } else if (!root && isAbsolute) {
44
+ return normalized
45
+ }
46
+ const parts: string[] = []
47
+ for (const part of relative.split('/')) {
48
+ if (!part || part === '.') continue
49
+ if (part === '..') {
50
+ if (!parts.length) return null
51
+ parts.pop()
52
+ } else parts.push(part)
53
+ }
54
+ return parts.length ? parts.join('/') : null
55
+ }
56
+
29
57
  interface TreeNode {
30
58
  name: string
31
59
  path: string
@@ -84,10 +112,23 @@ export default function CodeReviewPage({
84
112
  onBack,
85
113
  onOpenFiles,
86
114
  }: Props) {
115
+ const workspaceRef = useRef(workspacePath)
116
+ workspaceRef.current = workspacePath
117
+ const diffRequest = useRef(0)
118
+ const [tab, setTab] = useState<'changes' | 'history'>('changes')
119
+ const [historyRevision, setHistoryRevision] = useState(0)
120
+ const [historySelection, setHistorySelection] = useState('')
121
+ const [confirmation, setConfirmation] = useState<{ root: string; entry: WorkspaceHistoryEntry } | null>(null)
122
+ const [undoNotice, setUndoNotice] = useState('')
123
+ const [undonePaths, setUndonePaths] = useState<Set<string>>(new Set())
87
124
  const [workspaceDiffs, setWorkspaceDiffs] = useState<FileChange[]>([])
88
125
  const [isLoadingDiff, setIsLoadingDiff] = useState(false)
89
126
  const [gitInfo, setGitInfo] = useState<GitBranchInfo | null>(null)
90
- const hasAgentChanges = Boolean(changes && changes.length > 0)
127
+ const agentChanges = useMemo(() => (changes || []).flatMap(change => {
128
+ const path = workspaceRelativePath(change.path, workspacePath)
129
+ return path ? [{ ...change, path }] : []
130
+ }), [changes, workspacePath])
131
+ const hasAgentChanges = agentChanges.length > 0
91
132
 
92
133
  const [diffScope, setDiffScope] = useState<'workspace' | 'agent'>(
93
134
  hasAgentChanges ? 'agent' : 'workspace'
@@ -98,18 +139,24 @@ export default function CodeReviewPage({
98
139
  // Fetch real Git diff and branch info from workspace
99
140
  const loadWorkspaceDiff = useCallback(async () => {
100
141
  if (!workspacePath) return
142
+ const request = ++diffRequest.current
143
+ setHistoryRevision(value => value + 1)
101
144
  setIsLoadingDiff(true)
102
145
  try {
103
146
  const [diffs, branch] = await Promise.all([
104
147
  workspacePlatform.getWorkspaceGitDiff(workspacePath),
105
148
  workspacePlatform.getGitBranchInfo(workspacePath).catch(() => null),
106
149
  ])
107
- setWorkspaceDiffs(diffs || [])
150
+ if (workspaceRef.current !== workspacePath || request !== diffRequest.current) return
151
+ setWorkspaceDiffs((diffs || []).flatMap(change => {
152
+ const path = workspaceRelativePath(change.path, workspacePath)
153
+ return path ? [{ ...change, path }] : []
154
+ }))
108
155
  if (branch) setGitInfo(branch)
109
156
  } catch (e) {
110
157
  console.error('Failed to load workspace git diff:', e)
111
158
  } finally {
112
- setIsLoadingDiff(false)
159
+ if (workspaceRef.current === workspacePath && request === diffRequest.current) setIsLoadingDiff(false)
113
160
  }
114
161
  }, [workspacePath])
115
162
 
@@ -117,18 +164,41 @@ export default function CodeReviewPage({
117
164
  loadWorkspaceDiff()
118
165
  }, [loadWorkspaceDiff])
119
166
 
167
+ const history = useWorkspaceUndo(workspacePath || '', historyRevision, () => { void loadWorkspaceDiff() })
168
+ useEffect(() => {
169
+ setConfirmation(null)
170
+ setHistorySelection('')
171
+ setUndoNotice('')
172
+ setUndonePaths(new Set())
173
+ setWorkspaceDiffs([])
174
+ }, [workspacePath])
175
+ const undoConfirmed = async () => {
176
+ if (!confirmation || confirmation.root !== workspacePath) return
177
+ if (await history.undo(confirmation.entry.id)) {
178
+ if (workspaceRef.current !== confirmation.root) return
179
+ setUndonePaths(previous => new Set([...previous,
180
+ workspaceRelativePath(confirmation.entry.path, confirmation.root) || '',
181
+ workspaceRelativePath(confirmation.entry.destination || '', confirmation.root) || '',
182
+ ]))
183
+ setDiffScope('workspace')
184
+ setUndoNotice(`Undone: ${confirmation.entry.label.replace(/^Undo /, '')}`)
185
+ setConfirmation(null)
186
+ void loadWorkspaceDiff()
187
+ }
188
+ }
189
+
120
190
  const activeChanges = useMemo(() => {
121
191
  if (diffScope === 'agent' && hasAgentChanges) {
122
- return changes!
192
+ return agentChanges.filter(change => !undonePaths.has(change.path))
123
193
  }
124
194
  if (workspaceDiffs.length > 0) {
125
195
  return workspaceDiffs
126
196
  }
127
197
  if (hasAgentChanges) {
128
- return changes!
198
+ return agentChanges.filter(change => !undonePaths.has(change.path))
129
199
  }
130
200
  return []
131
- }, [diffScope, hasAgentChanges, changes, workspaceDiffs])
201
+ }, [diffScope, hasAgentChanges, agentChanges, workspaceDiffs, undonePaths])
132
202
 
133
203
  const filteredChanges = useMemo(() => {
134
204
  if (!filterQuery.trim()) return activeChanges
@@ -147,6 +217,15 @@ export default function CodeReviewPage({
147
217
  const currentIndex = Math.max(0, filteredChanges.findIndex((c) => c.path === selectedPath))
148
218
  const selectedChange = filteredChanges[currentIndex] || filteredChanges[0]
149
219
 
220
+ const selectedHistory = history.entries.find(entry => entry.id === historySelection) || history.entries[0]
221
+ const selectedFileHistory = selectedChange && history.entries.find(entry =>
222
+ workspaceRelativePath(entry.path, workspacePath) === selectedChange.path ||
223
+ workspaceRelativePath(entry.destination || '', workspacePath) === selectedChange.path)
224
+ const canUndoFile = Boolean(selectedFileHistory && selectedFileHistory.id === history.entries[0]?.id)
225
+ const requestUndo = (entry: WorkspaceHistoryEntry) => {
226
+ if (workspacePath) setConfirmation({ root: workspacePath, entry })
227
+ }
228
+
150
229
  const totalAdditions = activeChanges.reduce((sum, change) => sum + change.additions, 0)
151
230
  const totalDeletions = activeChanges.reduce((sum, change) => sum + change.deletions, 0)
152
231
 
@@ -374,6 +453,27 @@ export default function CodeReviewPage({
374
453
  </div>
375
454
  </header>
376
455
 
456
+ <div className="review-tabs" role="tablist" aria-label="Review views">
457
+ <button type="button" role="tab" id="review-changes-tab" aria-selected={tab === 'changes'} aria-controls="review-changes" onClick={() => setTab('changes')}>Changes</button>
458
+ <button type="button" role="tab" id="review-history-tab" aria-selected={tab === 'history'} aria-controls="review-history" onClick={() => setTab('history')}>File history ({history.entries.length})</button>
459
+ </div>
460
+ {history.error && <p className="review-feedback" role="alert">{history.error}</p>}
461
+ {undoNotice && <p className="review-feedback" role="status">{undoNotice}</p>}
462
+ {tab === 'history' && <section id="review-history" role="tabpanel" aria-labelledby="review-history-tab" className="review-history-panel">
463
+ {!workspacePath ? <p>Select a workspace to view file history.</p> : history.loading && history.entries.length === 0 ? <p>Loading file history…</p> : history.entries.length === 0 ? <p>No saved file history in this workspace.</p> : <>
464
+ <label className="review-history-picker">Saved action
465
+ <SelectField aria-label="Saved action" value={selectedHistory?.id || ''} onValueChange={(nextValue) => setHistorySelection(nextValue)}>
466
+ {history.entries.map((entry, index) => <option key={entry.id} value={entry.id}>{index === 0 ? 'Latest · ' : ''}{entry.label.replace(/^Undo /, '')}</option>)}
467
+ </SelectField>
468
+ </label>
469
+ {selectedHistory && <>
470
+ <HistoryDetails entry={selectedHistory} />
471
+ <button type="button" className="review-undo-button" disabled={history.busy || selectedHistory.id !== history.entries[0]?.id} onClick={() => requestUndo(selectedHistory)}>Undo action…</button>
472
+ {selectedHistory.id !== history.entries[0]?.id && <p>Undo newer actions first. History is restored in reverse order.</p>}
473
+ </>}
474
+ </>}
475
+ </section>}
476
+ {tab === 'changes' && <div id="review-changes" role="tabpanel" aria-labelledby="review-changes-tab" className="review-changes-panel">
377
477
  {/* Large diff / status banner */}
378
478
  <div className="code-review-banner">
379
479
  <div className="code-review-banner-left">
@@ -396,7 +496,7 @@ export default function CodeReviewPage({
396
496
  className={`code-review-scope-btn ${diffScope === 'agent' ? 'is-active' : ''}`}
397
497
  onClick={() => setDiffScope('agent')}
398
498
  >
399
- AI Edits ({changes?.length || 0})
499
+ AI Edits ({agentChanges.length})
400
500
  </button>
401
501
  </div>
402
502
  ) : (
@@ -455,6 +555,7 @@ export default function CodeReviewPage({
455
555
  <span className="code-review-file-bar-path" title={selectedChange.path}>
456
556
  {selectedChange.path}
457
557
  </span>
558
+ <button type="button" className="review-undo-button" disabled={!canUndoFile || history.busy} title={canUndoFile ? selectedFileHistory?.label : selectedFileHistory ? 'Undo newer workspace actions first in File history.' : 'No saved undo action for this file.'} onClick={() => selectedFileHistory && requestUndo(selectedFileHistory)}>Undo edit…</button>
458
559
  <span className="code-review-file-bar-stat-add">+{selectedChange.additions}</span>
459
560
  <span className="code-review-file-bar-stat-del">-{selectedChange.deletions}</span>
460
561
  </div>
@@ -560,6 +661,8 @@ export default function CodeReviewPage({
560
661
  </aside>
561
662
  )}
562
663
  </div>
664
+ </div>}
665
+ {confirmation && confirmation.root === workspacePath && <UndoConfirmation entry={confirmation.entry} busy={history.busy} error={history.error} onCancel={() => setConfirmation(null)} onConfirm={() => { void undoConfirmed() }} />}
563
666
  </main>
564
667
  )
565
668
  }