@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.
- package/Cargo.lock +1012 -69
- package/Cargo.toml +5 -2
- package/LICENSE +21 -654
- package/README.md +92 -817
- package/Release_Note.md +53 -560
- package/apps/mint-companion/src-tauri/Cargo.toml +20 -0
- package/apps/mint-companion/src-tauri/build.rs +3 -0
- package/apps/mint-companion/src-tauri/src/main.rs +468 -0
- package/apps/mint-companion/tsconfig.json +20 -0
- package/apps/mint-companion/vite.config.ts +3 -0
- package/components.json +19 -0
- package/crates/mint-cli/Cargo.toml +6 -0
- package/crates/mint-cli/src/agent/live_status.rs +187 -39
- package/crates/mint-cli/src/agent.rs +323 -95
- package/crates/mint-cli/src/commands/agent.rs +69 -55
- package/crates/mint-cli/src/commands/integrations.rs +7 -0
- package/crates/mint-cli/src/commands/knowledge.rs +12 -32
- package/crates/mint-cli/src/commands/mod.rs +44 -0
- package/crates/mint-cli/src/image.rs +31 -33
- package/crates/mint-cli/src/interactive/chat_tui.rs +3594 -483
- package/crates/mint-cli/src/interactive/input_box.rs +56 -6
- package/crates/mint-cli/src/interactive/slash_commands.rs +208 -56
- package/crates/mint-cli/src/interactive/tool_activity.rs +328 -0
- package/crates/mint-cli/src/interactive.rs +64 -40
- package/crates/mint-cli/src/main.rs +13 -7
- package/crates/mint-cli/src/mcp.rs +5 -0
- package/crates/mint-cli/src/mod_host.rs +6 -0
- package/crates/mint-cli/src/mods_cli.rs +62 -0
- package/crates/mint-cli/src/mods_ui.rs +187 -0
- package/crates/mint-cli/src/onboard.rs +5 -31
- package/crates/mint-cli/src/terminal_theme.rs +3 -1
- package/crates/mint-cli/src/updater.rs +56 -2
- package/crates/mint-cli/tests/library_intake.rs +77 -0
- package/crates/mint-cli/tests/mods_testing.rs +133 -0
- package/crates/mint-companion-protocol/Cargo.toml +10 -0
- package/crates/mint-companion-protocol/src/lib.rs +163 -0
- package/crates/mint-core/Cargo.toml +6 -3
- package/crates/mint-core/build.rs +26 -0
- package/crates/mint-core/src/agent/chat.rs +167 -39
- package/crates/mint-core/src/agent/code_tools.rs +15 -0
- package/crates/mint-core/src/agent/memory/sources.rs +240 -0
- package/crates/mint-core/src/agent/memory.rs +147 -13
- package/crates/mint-core/src/agent/skill_inventory.rs +325 -0
- package/crates/mint-core/src/agent/skills.rs +437 -90
- package/crates/mint-core/src/agent.rs +1 -0
- package/crates/mint-core/src/api_server/routes/background_jobs.rs +310 -0
- package/crates/mint-core/src/api_server/routes/chat.rs +216 -199
- package/crates/mint-core/src/api_server/routes/html_preview.rs +77 -0
- package/crates/mint-core/src/api_server/routes/library.rs +97 -0
- package/crates/mint-core/src/api_server/routes/media_gen.rs +10 -57
- package/crates/mint-core/src/api_server/routes/misc.rs +104 -107
- package/crates/mint-core/src/api_server/routes/mod.rs +6 -0
- package/crates/mint-core/src/api_server/routes/mods.rs +31 -0
- package/crates/mint-core/src/api_server/routes/sessions.rs +41 -0
- package/crates/mint-core/src/api_server/routes/skills_subagents.rs +12 -42
- package/crates/mint-core/src/api_server/routes/slash.rs +50 -1
- package/crates/mint-core/src/api_server/routes/sources.rs +101 -0
- package/crates/mint-core/src/api_server.rs +118 -9
- package/crates/mint-core/src/avatar_bridge.rs +11 -2
- package/crates/mint-core/src/browser/session.rs +52 -0
- package/crates/mint-core/src/companion.rs +716 -0
- package/crates/mint-core/src/cron/scheduler.rs +34 -2
- package/crates/mint-core/src/integrations/channels.rs +87 -345
- package/crates/mint-core/src/integrations/mcp.rs +397 -50
- package/crates/mint-core/src/integrations/mcp_calls.rs +823 -0
- package/crates/mint-core/src/integrations/mcp_catalog.rs +267 -0
- package/crates/mint-core/src/integrations/mcp_device.rs +319 -0
- package/crates/mint-core/src/integrations/mcp_result.rs +356 -0
- package/crates/mint-core/src/integrations/webhooks.rs +539 -0
- package/crates/mint-core/src/integrations.rs +2 -0
- package/crates/mint-core/src/lib.rs +85 -26
- package/crates/mint-core/src/media/gemini_live.rs +134 -14
- package/crates/mint-core/src/media/image_models.rs +3 -27
- package/crates/mint-core/src/media/image_workflow.rs +216 -0
- package/crates/mint-core/src/media/library/intake.rs +144 -0
- package/crates/mint-core/src/media/library/migration.rs +56 -0
- package/crates/mint-core/src/media/library/removal.rs +55 -0
- package/crates/mint-core/src/media/library/tests.rs +730 -0
- package/crates/mint-core/src/media/library/thumbnails.rs +72 -0
- package/crates/mint-core/src/media/library.rs +545 -0
- package/crates/mint-core/src/media/model_catalog.rs +375 -0
- package/crates/mint-core/src/media/pictures.rs +79 -222
- package/crates/mint-core/src/media/video_models.rs +3 -22
- package/crates/mint-core/src/media.rs +3 -0
- package/crates/mint-core/src/mods/manager.rs +1124 -0
- package/crates/mint-core/src/mods/mod.rs +569 -0
- package/crates/mint-core/src/mods/operations.rs +204 -0
- package/crates/mint-core/src/mods/session.rs +146 -0
- package/crates/mint-core/src/mods/slash.rs +59 -0
- package/crates/mint-core/src/mods/telemetry.rs +306 -0
- package/crates/mint-core/src/orchestration/approvals.rs +344 -0
- package/crates/mint-core/src/orchestration/context_render.rs +104 -0
- package/crates/mint-core/src/orchestration/mcp_review.rs +153 -0
- package/crates/mint-core/src/orchestration/memory_skill.rs +104 -32
- package/crates/mint-core/src/orchestration/mod.rs +2139 -244
- package/crates/mint-core/src/orchestration/mod_authoring_regressions.rs +209 -0
- package/crates/mint-core/src/orchestration/progress_clock.rs +80 -0
- package/crates/mint-core/src/orchestration/repeated_failures.rs +116 -0
- package/crates/mint-core/src/orchestration/review_regressions.rs +449 -0
- package/crates/mint-core/src/orchestration/run_control.rs +196 -0
- package/crates/mint-core/src/orchestration/tools/files.rs +161 -14
- package/crates/mint-core/src/orchestration/tools/media.rs +37 -41
- package/crates/mint-core/src/orchestration/tools/misc.rs +3 -2
- package/crates/mint-core/src/orchestration/tools/mod.rs +2 -0
- package/crates/mint-core/src/orchestration/tools/mods.rs +161 -0
- package/crates/mint-core/src/orchestration/tools/plugins_mcp.rs +303 -71
- package/crates/mint-core/src/orchestration/tools/shell.rs +95 -2
- package/crates/mint-core/src/orchestration/workspace_helpers.rs +4 -1
- package/crates/mint-core/src/prompts/agent.rs +17 -2
- package/crates/mint-core/src/prompts/tool_catalog.rs +28 -2
- package/crates/mint-core/src/search/knowledge.rs +7 -1
- package/crates/mint-core/src/search/linked_folders/index.rs +177 -13
- package/crates/mint-core/src/search/linked_folders.rs +83 -2
- package/crates/mint-core/src/slash/catalog.rs +1 -1
- package/crates/mint-core/src/slash/mod.rs +174 -11
- package/crates/mint-core/src/slash/mods.rs +155 -0
- package/crates/mint-core/src/system/bg_shell.rs +1129 -95
- package/crates/mint-core/src/system/config.rs +5 -10
- package/crates/mint-core/src/system/html_preview.rs +398 -0
- package/crates/mint-core/src/system/mint_web.rs +164 -0
- package/crates/mint-core/src/system/release_notes.rs +18 -0
- package/crates/mint-core/src/system/shell.rs +21 -6
- package/crates/mint-core/src/system/workspace.rs +72 -8
- package/crates/mint-core/src/system/workspace_history.rs +604 -0
- package/crates/mint-core/src/system.rs +4 -0
- package/crates/mint-core/tests/background_retention.rs +34 -0
- package/crates/mint-core/tests/background_shutdown.rs +24 -0
- package/crates/mint-core/tests/library_http.rs +209 -0
- package/crates/mint-core/tests/mcp_contract.rs +283 -0
- package/crates/mint-core/tests/mcp_stdio.rs +11 -10
- package/crates/mint-core/tests/media_model_catalog_http.rs +403 -0
- package/crates/mint-core/tests/mods_http.rs +215 -0
- package/crates/mint-core/tests/terminal_shutdown.rs +109 -0
- package/crates/mint-mod-runtime/Cargo.toml +18 -0
- package/crates/mint-mod-runtime/src/lib.rs +507 -0
- package/crates/mint-mod-runtime/src/sdk.js +56 -0
- package/crates/mint-mod-runtime/src/test_sdk.js +32 -0
- package/crates/mint-mod-runtime/src/testing.rs +94 -0
- package/crates/mint-mod-runtime/tests/runtime.rs +156 -0
- package/docs/mods/AUTHORING.md +61 -0
- package/docs/mods/README.md +139 -0
- package/docs/mods/TESTING.md +56 -0
- package/docs/mods/mint-mods.d.ts +66 -0
- package/examples/device-mcp/README.md +22 -0
- package/examples/device-mcp/contract.md +49 -0
- package/examples/device-mcp/mock-device.mjs +66 -0
- package/examples/device-mcp/server.mjs +48 -0
- package/examples/device-mcp/server.test.mjs +78 -0
- package/examples/mods/task-checklist/README.md +1 -0
- package/examples/mods/task-checklist/main.ts +17 -0
- package/examples/mods/task-checklist/manifest.json +1 -0
- package/examples/mods/task-checklist/tests/checklist.test.ts +15 -0
- package/examples/mods/token-meter/README.md +1 -0
- package/examples/mods/token-meter/main.ts +8 -0
- package/examples/mods/token-meter/manifest.json +1 -0
- package/examples/mods/tool-guard/README.md +1 -0
- package/examples/mods/tool-guard/main.ts +9 -0
- package/examples/mods/tool-guard/manifest.json +1 -0
- package/out/web/assets/CliSessionsView-CtzUJpK_.css +1 -0
- package/out/web/assets/CliSessionsView-D7hw0Mgj.js +1 -0
- package/out/web/assets/CodeReviewPage-C7bEOJfd.js +4 -0
- package/out/web/assets/CodeReviewPage-Dte9uLiL.css +1 -0
- package/out/web/assets/CommandPalette-0RrF-AOT.js +1 -0
- package/out/web/assets/ImageStudioPanel-CdxkAf_r.js +1 -0
- package/out/web/assets/LibraryPage--Qfisp6D.js +2 -0
- package/out/web/assets/LibraryPage-DAxUTAg7.css +1 -0
- package/out/web/assets/LinkedFoldersView-2nfZbDgN.js +1 -0
- package/out/web/assets/McpRegistryPicker-h9uS8_wT.js +1 -0
- package/out/web/assets/McpServersView-slfQJzNB.js +1 -0
- package/out/web/assets/MintDashboard-BSR5XpXh.js +25 -0
- package/out/web/assets/MintDashboard-CWUcCGhd.css +1 -0
- package/out/web/assets/PluginsView-l7LSm503.js +1 -0
- package/out/web/assets/ScheduledTasksView-CttmLbq1.js +1 -0
- package/out/web/assets/SettingsWindow-BCMLYvEV.js +4 -0
- package/out/web/assets/SettingsWindow-DcMVmU9u.css +1 -0
- package/out/web/assets/SkillsView-rNs1qr_U.js +2 -0
- package/out/web/assets/ToolSurfacePage-B9DzEPWN.js +37 -0
- package/out/web/assets/ToolSurfacePage-CTfgggF2.css +1 -0
- package/out/web/assets/VeoStudioPanel-DiJs_Cg2.js +4 -0
- package/out/web/assets/WorkspaceSelector-B2xIp04D.js +1 -0
- package/out/web/assets/WorkspaceSelector-Ca8uJOsS.css +1 -0
- package/out/web/assets/{abnfDiagram-VCTEODGH-ByMyfanq.js → abnfDiagram-VCTEODGH-CD0CjoGl.js} +1 -1
- package/out/web/assets/{architecture-7GRP2DOG-CLq2kEOB.js → architecture-7GRP2DOG-RKV83OeZ.js} +1 -1
- package/out/web/assets/{architectureDiagram-5GKGNRK7-6PoVSmNG.js → architectureDiagram-5GKGNRK7-nN_HAFct.js} +1 -1
- package/out/web/assets/{blockDiagram-NRAW4CY4-cKw9mAKi.js → blockDiagram-NRAW4CY4-BrrqzHW5.js} +1 -1
- package/out/web/assets/{c4Diagram-UCG6FXSJ-Cqy8N5Ge.js → c4Diagram-UCG6FXSJ-DTdV8_zE.js} +1 -1
- package/out/web/assets/{chunk-75Z2AOVW-3qybijF5.js → chunk-75Z2AOVW-_M0z5olV.js} +1 -1
- package/out/web/assets/chunk-CKBBP62Z-BpQEgeHF.js +2 -0
- package/out/web/assets/{chunk-CLGD4ZFX-CndDQkww.js → chunk-CLGD4ZFX-D54yGvGS.js} +1 -1
- package/out/web/assets/{chunk-DSNCTWBM-Cc4NxvgD.js → chunk-DSNCTWBM-C-gvT2ru.js} +1 -1
- package/out/web/assets/{chunk-DU6HZSFF-drzh6GsU.js → chunk-DU6HZSFF-CnFngIhW.js} +1 -1
- package/out/web/assets/{chunk-F27PBJKO-FiY35l4v.js → chunk-F27PBJKO-BqtWrnEO.js} +1 -1
- package/out/web/assets/{chunk-G27WJ6UU-Bjt9Il4A.js → chunk-G27WJ6UU-Ckoq5mi2.js} +1 -1
- package/out/web/assets/{chunk-GMAD6QVW-Bppi3Ctd.js → chunk-GMAD6QVW-BuhEcgHq.js} +1 -1
- package/out/web/assets/{chunk-JQ64N6SF-DGg5kcEV.js → chunk-JQ64N6SF-CF8T7GiZ.js} +1 -1
- package/out/web/assets/{chunk-LCL6LL3I-CCYcjd7p.js → chunk-LCL6LL3I-BhXV9zyH.js} +1 -1
- package/out/web/assets/{chunk-OBVCFTLP-DJeNil5M.js → chunk-OBVCFTLP-CRIkunUB.js} +1 -1
- package/out/web/assets/{chunk-P2QGCYS3-lRzkRjBB.js → chunk-P2QGCYS3-UFEU6BxZ.js} +1 -1
- package/out/web/assets/{chunk-POPQ4Y6H-DouASMBW.js → chunk-POPQ4Y6H-CQcrNbjr.js} +1 -1
- package/out/web/assets/{chunk-PWAF6VOD-DMmD1vVf.js → chunk-PWAF6VOD-Cc2uVDsG.js} +1 -1
- package/out/web/assets/{chunk-R7TYR2AO-CYLA5UC5.js → chunk-R7TYR2AO-DiCxzdAY.js} +1 -1
- package/out/web/assets/{chunk-RHFEMEQ7-BiXwEcUT.js → chunk-RHFEMEQ7-b7hnPmrR.js} +1 -1
- package/out/web/assets/{chunk-SVP7TREG-BV-zPslF.js → chunk-SVP7TREG-Bu_yYb-V.js} +1 -1
- package/out/web/assets/{chunk-TEH6E4GO-B2RGEohZ.js → chunk-TEH6E4GO-G4Cdlyrt.js} +1 -1
- package/out/web/assets/classDiagram-DTDB5LWJ-RnC2mYO4.js +1 -0
- package/out/web/assets/classDiagram-v2-JRS7N3AN-RnC2mYO4.js +1 -0
- package/out/web/assets/config-CnvCChUM.js +2 -0
- package/out/web/assets/config-DM6oIVO3.css +1 -0
- package/out/web/assets/core-DsKkQ7ig.js +1 -0
- package/out/web/assets/{cynefin-OW5HDTMX-Cas4csHM.js → cynefin-OW5HDTMX-CnzQfOGp.js} +1 -1
- package/out/web/assets/{cynefinDiagram-5FMLGOSQ-Bbpj66Y3.js → cynefinDiagram-5FMLGOSQ-DVtQnfpm.js} +1 -1
- package/out/web/assets/{dagre-3AP2YEHR-B0-2RDEd.js → dagre-3AP2YEHR-DG76_k5_.js} +1 -1
- package/out/web/assets/{diagram-S7CK7UJ4-BdzEjUyH.js → diagram-S7CK7UJ4-CaouUoze.js} +1 -1
- package/out/web/assets/{diagram-UQ7AKVKN-CJDwyPxF.js → diagram-UQ7AKVKN-B4bEc26B.js} +1 -1
- package/out/web/assets/{diagram-VSXAHHWV-BxaG1r_B.js → diagram-VSXAHHWV-BJ86Ov2Y.js} +1 -1
- package/out/web/assets/{diagram-VX7I27RA-BMmUqm8f.js → diagram-VX7I27RA-7hH5IPYf.js} +1 -1
- package/out/web/assets/{diagram-Z3DM3KII-CFtd03eE.js → diagram-Z3DM3KII-CCM4clo8.js} +1 -1
- package/out/web/assets/dist-js-BkYNznHX.js +1 -0
- package/out/web/assets/{ebnfDiagram-PWID7BFC-DwAen1hO.js → ebnfDiagram-PWID7BFC-Da7WAM3k.js} +1 -1
- package/out/web/assets/{erDiagram-SSCWMZ5O-BCZSHACj.js → erDiagram-SSCWMZ5O-CzzmnZWT.js} +1 -1
- package/out/web/assets/{event-ChBVpRy0.js → event-Cdt7Byyj.js} +1 -1
- package/out/web/assets/{eventmodeling-NTZA5JFV-XHStE4E_.js → eventmodeling-NTZA5JFV-xcfsA0XD.js} +1 -1
- package/out/web/assets/flowDiagram-A5DVABFB-JdtH1673.js +1 -0
- package/out/web/assets/{ganttDiagram-EL5Y4UJY-BAEu1Cql.js → ganttDiagram-EL5Y4UJY-B3ClFGmL.js} +1 -1
- package/out/web/assets/{gitGraph-4MIJSDKK-r32Vyper.js → gitGraph-4MIJSDKK-BZ_y_cDU.js} +1 -1
- package/out/web/assets/{gitGraphDiagram-WWUBYQGX-z9o9qt6V.js → gitGraphDiagram-WWUBYQGX-drhRSYm3.js} +1 -1
- package/out/web/assets/index-BZ9xgmMP.css +1 -0
- package/out/web/assets/index-Ca8cCS4h.js +168 -0
- package/out/web/assets/{info-A6RAGUB7-BvLaC2cw.js → info-A6RAGUB7-B7I3K0F1.js} +1 -1
- package/out/web/assets/{infoDiagram-RXCK75RN-Be6WAXXw.js → infoDiagram-RXCK75RN-deX_1MPh.js} +1 -1
- package/out/web/assets/{ishikawaDiagram-5VMMS53U-DZjoHJHC.js → ishikawaDiagram-5VMMS53U-s38yo28y.js} +1 -1
- package/out/web/assets/{journeyDiagram-EYS64GPL-CtVkjkGm.js → journeyDiagram-EYS64GPL-CZn2kB8b.js} +1 -1
- package/out/web/assets/jsx-runtime-DN4NhQUK.js +1 -0
- package/out/web/assets/{kanban-definition-3QL26DDD-CW5FMv1w.js → kanban-definition-3QL26DDD-DodjgySL.js} +1 -1
- package/out/web/assets/markdown-CMhYIcWB.js +39 -0
- package/out/web/assets/{mermaid-parser.core-aUgCqsZ5.js → mermaid-parser.core-Whu2rlJC.js} +3 -3
- package/out/web/assets/{mermaid.core-D57sEiSL.js → mermaid.core-CKyPo8VH.js} +4 -4
- package/out/web/assets/{mindmap-definition-FBJOCRG2-DAmSpM3a.js → mindmap-definition-FBJOCRG2-260WBDxZ.js} +1 -1
- package/out/web/assets/modelManager-CUaGWMWu.js +2 -0
- package/out/web/assets/{oauthManager-9jxicDWJ.js → oauthManager-DlNhXJr6.js} +1 -1
- package/out/web/assets/{packet-AYTQ26CC-DJ27iIoJ.js → packet-AYTQ26CC-CEeIRKRG.js} +1 -1
- package/out/web/assets/{pegDiagram-XKGWAZYB-Bj3ii-gS.js → pegDiagram-XKGWAZYB-BYadI-KO.js} +1 -1
- package/out/web/assets/{pie-WAS4IAKB-DG5mCUbc.js → pie-WAS4IAKB-D8uf4dh5.js} +1 -1
- package/out/web/assets/{pieDiagram-E7YTZNPT-BrJLPnDA.js → pieDiagram-E7YTZNPT-CjSDy4hO.js} +1 -1
- package/out/web/assets/{quadrantDiagram-AXDQQJYC-3x_TmF3j.js → quadrantDiagram-AXDQQJYC-B8D3gU5d.js} +1 -1
- package/out/web/assets/{radar-RG4KPBEZ-CrXaTTuV.js → radar-RG4KPBEZ-DZJxnokY.js} +1 -1
- package/out/web/assets/{railroad-74A4TZTK-BpqMH9BE.js → railroad-74A4TZTK-DBysUiUi.js} +1 -1
- package/out/web/assets/{railroad-abnf-HS5TGJTU-DHI0uLlV.js → railroad-abnf-HS5TGJTU-CHWxoJYg.js} +1 -1
- package/out/web/assets/{railroad-ebnf-LZEXJU2U-CQCb316y.js → railroad-ebnf-LZEXJU2U-DDv7X6bY.js} +1 -1
- package/out/web/assets/{railroad-peg-WCYAUIDC-Ph1giKkH.js → railroad-peg-WCYAUIDC-DpfcYYNJ.js} +1 -1
- package/out/web/assets/{railroadDiagram-O6MQD6OU-BRq6wIxx.js → railroadDiagram-O6MQD6OU-CYtyv0t3.js} +1 -1
- package/out/web/assets/{requirementDiagram-EFPCY7ZU-DIJj6G1g.js → requirementDiagram-EFPCY7ZU-D2X-Ewik.js} +1 -1
- package/out/web/assets/{sankeyDiagram-P5KCCOFB-DZajSryq.js → sankeyDiagram-P5KCCOFB-Bn2x6C4Y.js} +1 -1
- package/out/web/assets/{sequenceDiagram-WJ2MYXX4-DxJCWyZS.js → sequenceDiagram-WJ2MYXX4-BvFLKtPd.js} +1 -1
- package/out/web/assets/{stateDiagram-HBIQ2CUA-k6voi8Vf.js → stateDiagram-HBIQ2CUA-Bx0GWeaY.js} +1 -1
- package/out/web/assets/stateDiagram-v2-4QOOHH4V--hol1yg_.js +1 -0
- package/out/web/assets/{swimlanes-XN3QIQJK-igYhTjXB.js → swimlanes-XN3QIQJK-CCma0T7L.js} +1 -1
- package/out/web/assets/swimlanesDiagram-VK2B7HYN-BkohoVsU.js +8 -0
- package/out/web/assets/{timeline-definition-24CTP7MA-Dke2p93p.js → timeline-definition-24CTP7MA-iCRhhJ7C.js} +1 -1
- package/out/web/assets/{treeView-Q6P3EWNA-hNELnXUs.js → treeView-Q6P3EWNA-DZ-y08qp.js} +1 -1
- package/out/web/assets/{treemap-WGGIJYW6-D2B6wDsx.js → treemap-WGGIJYW6-De0CxzMx.js} +1 -1
- package/out/web/assets/{vennDiagram-4TSXK5OY-CDkW7rUP.js → vennDiagram-4TSXK5OY-w_7aZ6xe.js} +1 -1
- package/out/web/assets/{wardley-WFR3VGLG-BECdXETi.js → wardley-WFR3VGLG-DT0y0xJ4.js} +1 -1
- package/out/web/assets/{wardleyDiagram-VM6X3IG4-B5BycpQ4.js → wardleyDiagram-VM6X3IG4-DAdXELbQ.js} +1 -1
- package/out/web/assets/window-BJCVtyET.js +1 -0
- package/out/web/assets/{xychartDiagram-S5SC5T6Z-CtJS3b--.js → xychartDiagram-S5SC5T6Z-IZIXf3Vo.js} +1 -1
- package/out/web/index-web.html +3 -2
- package/out/web/index.html +3 -2
- package/package.json +71 -22
- package/shared-modules/.github/workflows/ci.yml +120 -0
- package/shared-modules/.github/workflows/update.yaml +28 -0
- package/slash-commands.json +7 -2
- package/src/bin/auto-build.js +66 -0
- package/src/bin/desktop.js +113 -0
- package/src/bin/desktop.test.js +113 -0
- package/src/bin/index.js +18 -25
- package/src/bin/index.test.js +89 -0
- package/src/bin/measure-effects.mjs +53 -0
- package/src/bin/package.test.js +28 -0
- package/src/bin/release-notes.test.js +84 -0
- package/src/bin/styles.test.js +20 -0
- package/src/bin/web.js +5 -0
- package/src/bin/web.test.js +39 -0
- package/src/renderer/index.html +0 -2
- package/src/renderer/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
- package/src/renderer/shared/agentProgress.ts +33 -0
- package/src/renderer/shared/components/AgentActivityDrawer.tsx +3 -2
- package/src/renderer/shared/components/AgentActivityTable.tsx +1 -1
- package/src/renderer/shared/components/ApprovalCard.test.tsx +24 -0
- package/src/renderer/shared/components/ApprovalCard.tsx +10 -3
- package/src/renderer/shared/components/ArtifactPreviewPanel.tsx +88 -37
- package/src/renderer/shared/components/AuthGate.tsx +75 -39
- package/src/renderer/shared/components/BackgroundTerminals.tsx +181 -0
- package/src/renderer/shared/components/ChatCodeBlock.tsx +8 -4
- package/src/renderer/shared/components/ChatMessageItem.test.tsx +68 -0
- package/src/renderer/shared/components/ChatMessageItem.tsx +36 -16
- package/src/renderer/shared/components/ChatPanel.test.tsx +21 -0
- package/src/renderer/shared/components/ChatPanel.tsx +294 -272
- package/src/renderer/shared/components/ChunkErrorBoundary.tsx +4 -102
- package/src/renderer/shared/components/CliSessionsView.test.tsx +125 -0
- package/src/renderer/shared/components/CliSessionsView.tsx +61 -13
- package/src/renderer/shared/components/CodeReviewPage.tsx +111 -8
- package/src/renderer/shared/components/CollapsiblePasteInput.tsx +90 -0
- package/src/renderer/shared/components/ContextCompactionStatus.tsx +17 -0
- package/src/renderer/shared/components/DashboardSidebar.tsx +15 -128
- package/src/renderer/shared/components/DesktopTitlebar.tsx +45 -19
- package/src/renderer/shared/components/ErrorNotice.tsx +29 -0
- package/src/renderer/shared/components/FormattedMessage.tsx +11 -0
- package/src/renderer/shared/components/GeminiLiveOverlay.css +86 -0
- package/src/renderer/shared/components/GeminiLiveOverlay.test.tsx +24 -0
- package/src/renderer/shared/components/GeminiLiveOverlay.tsx +85 -101
- package/src/renderer/shared/components/GlideSelect.css +138 -0
- package/src/renderer/shared/components/GlideSelect.d.ts +31 -0
- package/src/renderer/shared/components/GlideSelect.jsx +266 -0
- package/src/renderer/shared/components/ImageSearchCard.tsx +46 -56
- package/src/renderer/shared/components/ImageStudioPanel.tsx +9 -8
- package/src/renderer/shared/components/LibraryItemCard.tsx +72 -0
- package/src/renderer/shared/components/LibraryPage.tsx +165 -0
- package/src/renderer/shared/components/LibraryPreview.tsx +59 -0
- package/src/renderer/shared/components/McpServersView.tsx +27 -8
- package/src/renderer/shared/components/McpToolAllowlist.tsx +2 -4
- package/src/renderer/shared/components/McpToolResults.tsx +99 -0
- package/src/renderer/shared/components/MintDashboard.tsx +308 -770
- package/src/renderer/shared/components/ModSessionControls.tsx +8 -0
- package/src/renderer/shared/components/ModUi.test.tsx +65 -0
- package/src/renderer/shared/components/ModUi.tsx +26 -0
- package/src/renderer/shared/components/ModelSelectorPopover.tsx +14 -7
- package/src/renderer/shared/components/ModsPanel.tsx +156 -0
- package/src/renderer/shared/components/ProgressActivity.tsx +17 -0
- package/src/renderer/shared/components/ReviewHistory.tsx +42 -0
- package/src/renderer/shared/components/RewindModal.tsx +5 -12
- package/src/renderer/shared/components/RunSummaryDashboard.tsx +6 -12
- package/src/renderer/shared/components/ScheduledTasksView.tsx +7 -6
- package/src/renderer/shared/components/SelectField.test.tsx +27 -0
- package/src/renderer/shared/components/SelectField.tsx +38 -0
- package/src/renderer/shared/components/SessionSources.tsx +48 -0
- package/src/renderer/shared/components/SessionSourcesPopover.tsx +61 -0
- package/src/renderer/shared/components/Settings/AgentsTab.tsx +7 -6
- package/src/renderer/shared/components/Settings/AudioTab.tsx +8 -7
- package/src/renderer/shared/components/Settings/AutomationTab.tsx +2 -2
- package/src/renderer/shared/components/Settings/GeneralTab.tsx +33 -32
- package/src/renderer/shared/components/Settings/MemoryTab.test.tsx +37 -0
- package/src/renderer/shared/components/Settings/MemoryTab.tsx +71 -31
- package/src/renderer/shared/components/Settings/NotificationsTab.test.tsx +15 -0
- package/src/renderer/shared/components/Settings/NotificationsTab.tsx +84 -0
- package/src/renderer/shared/components/Settings/ThemeTab.tsx +19 -11
- package/src/renderer/shared/components/SlashChoicePanel.tsx +88 -0
- package/src/renderer/shared/components/SlashSuggestions.test.tsx +33 -0
- package/src/renderer/shared/components/SlashSuggestions.tsx +38 -10
- package/src/renderer/shared/components/SourcesBlock.tsx +12 -20
- package/src/renderer/shared/components/ToolSurfacePage.test.tsx +32 -0
- package/src/renderer/shared/components/ToolSurfacePage.tsx +59 -11
- package/src/renderer/shared/components/ToolsPanelToggle.tsx +13 -0
- package/src/renderer/shared/components/VeoStudioPanel.tsx +9 -8
- package/src/renderer/shared/components/ViewedImages.tsx +36 -0
- package/src/renderer/shared/components/VirtualChatHistory.tsx +82 -0
- package/src/renderer/shared/components/VoicePill.css +85 -0
- package/src/renderer/shared/components/VoicePill.d.ts +12 -0
- package/src/renderer/shared/components/VoicePill.jsx +190 -0
- package/src/renderer/shared/components/VoicePill.test.tsx +22 -0
- package/src/renderer/shared/components/WorkspaceContextPopover.tsx +20 -15
- package/src/renderer/shared/components/WorkspacePaneResizer.tsx +92 -0
- package/src/renderer/shared/components/WorkspacePreviewActions.test.tsx +44 -0
- package/src/renderer/shared/components/WorkspacePreviewActions.tsx +19 -0
- package/src/renderer/shared/components/WorkspaceSelector.tsx +13 -8
- package/src/renderer/shared/components/background-terminals.css +292 -0
- package/src/renderer/shared/components/ui/README.md +52 -0
- package/src/renderer/shared/components/ui/button.tsx +37 -0
- package/src/renderer/shared/components/ui/demo.tsx +26 -0
- package/src/renderer/shared/components/ui/error-recovery.css +35 -0
- package/src/renderer/shared/components/ui/error-recovery.tsx +35 -0
- package/src/renderer/shared/components/ui/voice-powered-orb.css +6 -0
- package/src/renderer/shared/components/ui/voice-powered-orb.tsx +374 -0
- package/src/renderer/shared/components/workspace-selector.css +248 -0
- package/src/renderer/shared/constants/config.ts +30 -1
- package/src/renderer/shared/constants/slashCommands.ts +1 -1
- package/src/renderer/shared/conversation/lifecycle.test.ts +362 -0
- package/src/renderer/shared/conversation/lifecycle.ts +418 -0
- package/src/renderer/shared/conversation/projectNavigation.test.ts +105 -0
- package/src/renderer/shared/conversation/projectNavigation.ts +39 -0
- package/src/renderer/shared/conversation/sourcesTransport.ts +27 -0
- package/src/renderer/shared/conversation/syncView.test.ts +1 -34
- package/src/renderer/shared/conversation/syncView.ts +0 -37
- package/src/renderer/shared/conversation/transport.test.ts +163 -0
- package/src/renderer/shared/conversation/transport.ts +159 -0
- package/src/renderer/shared/conversation/useConversationCoordinator.ts +30 -72
- package/src/renderer/shared/css/agent-observability.css +20 -21
- package/src/renderer/shared/css/auth-gate.css +112 -13
- package/src/renderer/shared/css/code-review.css +33 -0
- package/src/renderer/shared/css/code-sessions.css +27 -0
- package/src/renderer/shared/css/collapsed-paste.css +35 -0
- package/src/renderer/shared/css/effects.css +15 -0
- package/src/renderer/shared/css/error-notice.css +60 -0
- package/src/renderer/shared/css/library.css +476 -0
- package/src/renderer/shared/css/management-views.css +138 -0
- package/src/renderer/shared/css/mcp-results.css +11 -0
- package/src/renderer/shared/css/model-selector.css +163 -105
- package/src/renderer/shared/css/mods.css +77 -0
- package/src/renderer/shared/css/notification-notice.css +28 -0
- package/src/renderer/shared/css/session-sources-popover.css +9 -0
- package/src/renderer/shared/css/session-sources.css +23 -0
- package/src/renderer/shared/css/settings/memory.css +154 -0
- package/src/renderer/shared/css/settings/notifications.css +11 -0
- package/src/renderer/shared/css/settings/theme.css +5 -0
- package/src/renderer/shared/css/slash-choice.css +95 -0
- package/src/renderer/shared/css/slash-suggestions.css +68 -0
- package/src/renderer/shared/css/sources-block.css +91 -0
- package/src/renderer/shared/css/thinking-status.css +46 -0
- package/src/renderer/shared/css/tools-panel.css +7 -0
- package/src/renderer/shared/css/ui-tailwind.css +19 -0
- package/src/renderer/shared/css/viewed-images.css +15 -0
- package/src/renderer/shared/fonts.css +46 -0
- package/src/renderer/shared/fonts.ts +3 -12
- package/src/renderer/shared/lib/utils.ts +6 -0
- package/src/renderer/shared/library/controller.test.ts +61 -0
- package/src/renderer/shared/library/controller.ts +57 -0
- package/src/renderer/shared/library/transport.test.ts +26 -0
- package/src/renderer/shared/library/transport.ts +60 -0
- package/src/renderer/shared/library/useLibraryFile.ts +38 -0
- package/src/renderer/shared/mods.ts +58 -0
- package/src/renderer/shared/platform.test.ts +57 -1
- package/src/renderer/shared/platform.ts +46 -1
- package/src/renderer/shared/theme/themeManager.test.ts +43 -0
- package/src/renderer/shared/theme/themeManager.ts +17 -4
- package/src/renderer/shared/types.ts +56 -2
- package/src/renderer/shared/utils/agentActivity.test.ts +75 -0
- package/src/renderer/shared/utils/agentActivity.ts +42 -3
- package/src/renderer/shared/utils/approval.tsx +7 -0
- package/src/renderer/shared/utils/artifactBrowser.test.ts +80 -0
- package/src/renderer/shared/utils/artifactBrowser.ts +41 -0
- package/src/renderer/shared/utils/contextCompaction.test.tsx +48 -0
- package/src/renderer/shared/utils/contextCompaction.ts +21 -0
- package/src/renderer/shared/utils/effectVisibility.ts +9 -0
- package/src/renderer/shared/utils/markdown.tsx +3 -3
- package/src/renderer/shared/utils/mcpResults.test.tsx +91 -0
- package/src/renderer/shared/utils/modViewport.ts +7 -0
- package/src/renderer/shared/utils/nativeRecordingSession.test.ts +61 -0
- package/src/renderer/shared/utils/nativeRecordingSession.ts +46 -0
- package/src/renderer/shared/utils/notificationSettings.test.ts +14 -0
- package/src/renderer/shared/utils/notificationSettings.ts +23 -0
- package/src/renderer/shared/utils/notifications.test.ts +51 -0
- package/src/renderer/shared/utils/notifications.ts +54 -0
- package/src/renderer/shared/utils/pastedText.test.ts +20 -0
- package/src/renderer/shared/utils/pastedText.ts +13 -0
- package/src/renderer/shared/utils/progressCache.test.ts +32 -0
- package/src/renderer/shared/utils/sessionSources.test.ts +31 -0
- package/src/renderer/shared/utils/sessionSources.ts +34 -0
- package/src/renderer/shared/utils/slashCommandProcessor.ts +1 -1
- package/src/renderer/shared/utils/sourceAttachments.ts +28 -0
- package/src/renderer/shared/utils/speech.ts +51 -9
- package/src/renderer/shared/utils/syntaxHighlight.test.tsx +22 -0
- package/src/renderer/shared/utils/syntaxHighlight.tsx +26 -0
- package/src/renderer/shared/utils/useGeminiLiveVoice.ts +49 -5
- package/src/renderer/shared/utils/useLatestCallback.ts +9 -0
- package/src/renderer/shared/utils/useNativeVoiceInput.ts +80 -72
- package/src/renderer/shared/utils/useSessionSources.ts +33 -0
- package/src/renderer/shared/utils/viewedImages.ts +26 -0
- package/src/renderer/shared/utils/workspacePane.test.ts +33 -0
- package/src/renderer/shared/utils/workspacePane.ts +20 -0
- package/src/renderer/shared/utils/workspacePreview.test.ts +24 -0
- package/src/renderer/shared/utils/workspacePreview.ts +16 -0
- package/src/renderer/shared/utils/workspaceSnapshot.test.ts +49 -0
- package/src/renderer/shared/utils/workspaceSnapshot.ts +26 -0
- package/src/renderer/shared/utils/workspaces.ts +10 -0
- package/src/renderer/shared/workspaceUndo.ts +88 -0
- package/src/renderer/src/App.tsx +9 -1
- package/src/renderer/src/components/LiveTranslateControls.tsx +65 -0
- package/src/renderer/src/components/PicturesLibrary.tsx +2 -288
- package/src/renderer/src/components/ScreenPicker.css +67 -30
- package/src/renderer/src/components/ScreenPicker.tsx +201 -60
- package/src/renderer/src/components/SettingsWindow.tsx +10 -5
- package/src/renderer/src/components/WorkspacePanel.tsx +222 -32
- package/src/renderer/src/components/browser-shell.css +1 -1
- package/src/renderer/src/components/browser-suggestions-popup.css +1 -1
- package/src/renderer/src/components/liveTranslateFrames.test.ts +26 -5
- package/src/renderer/src/components/liveTranslateFrames.ts +18 -7
- package/src/renderer/src/components/liveTranslateLanguage.ts +6 -0
- package/src/renderer/src/css/app-shell.css +52 -137
- package/src/renderer/src/css/chat.css +21 -495
- package/src/renderer/src/css/desktop-tools.css +199 -1
- package/src/renderer/src/css/misc.css +0 -52
- package/src/renderer/src/css/pictures.css +2 -415
- package/src/renderer/src/css/settings/base.css +50 -47
- package/src/renderer/src/css/sidebar-workspace.css +151 -94
- package/src/renderer/src/css/tool-surfaces.css +65 -9
- package/src/renderer/src/css/widget.css +1 -1
- package/src/renderer/src/env.d.ts +1 -9
- package/src/renderer/src/index.css +1 -1
- package/src/renderer/src/main.tsx +2 -1
- package/src/renderer/src/proactiveSuggestions.ts +29 -0
- package/src/renderer/src/tauri.ts +122 -330
- package/src/renderer/src/voiceInput.ts +2 -1
- package/src/renderer/src-web/components/PicturesLibrary.tsx +2 -285
- package/src/renderer/src-web/components/PullToRefresh.tsx +1 -1
- package/src/renderer/src-web/components/SettingsWindow.tsx +10 -5
- package/src/renderer/src-web/css/app-shell.css +24 -121
- package/src/renderer/src-web/css/chat.css +21 -495
- package/src/renderer/src-web/css/misc.css +0 -52
- package/src/renderer/src-web/css/mobile.css +15 -14
- package/src/renderer/src-web/css/pictures.css +2 -462
- package/src/renderer/src-web/css/settings/base.css +50 -47
- package/src/renderer/src-web/css/sidebar-workspace.css +9 -95
- package/src/renderer/src-web/css/widget.css +1 -1
- package/src/renderer/src-web/env.d.ts +1 -12
- package/src/renderer/src-web/index.css +1 -1
- package/src/renderer/src-web/main.tsx +2 -1
- package/src/renderer/src-web/proactiveSuggestions.ts +3 -0
- package/src/renderer/src-web/tauri.ts +129 -354
- package/src/renderer/tests/backgroundTerminals.browser.html +81 -0
- package/src/renderer/tests/chatPanelFixture.ts +23 -0
- package/src/renderer/tests/chatPerformance.browser.html +71 -0
- package/src/renderer/tests/cliSessions.browser.html +82 -0
- package/src/renderer/tests/collapsedPaste.browser.html +70 -0
- package/src/renderer/tests/composerMenus.browser.html +116 -0
- package/src/renderer/tests/contextCompaction.browser.html +17 -0
- package/src/renderer/tests/conversationLifecycle.browser.html +70 -0
- package/src/renderer/tests/effectsPerformance.browser.html +13 -0
- package/src/renderer/tests/errorRecovery.browser.html +21 -0
- package/src/renderer/tests/glideSelect.browser.html +71 -0
- package/src/renderer/tests/glideSelect.preview.html +27 -0
- package/src/renderer/tests/library.browser.html +1 -0
- package/src/renderer/tests/library.browser.tsx +78 -0
- package/src/renderer/tests/liveOrb.browser.html +49 -0
- package/src/renderer/tests/liveVoice.browser.html +29 -0
- package/src/renderer/tests/modInput.browser.html +22 -0
- package/src/renderer/tests/sessionSources.browser.html +1 -0
- package/src/renderer/tests/sessionSources.browser.tsx +107 -0
- package/src/renderer/tests/skills.browser.html +24 -0
- package/src/renderer/tests/toolsPanel.browser.html +1 -0
- package/src/renderer/tests/toolsPanel.browser.tsx +113 -0
- package/src/renderer/tests/viewedImages.browser.html +1 -0
- package/src/renderer/tests/viewedImages.browser.tsx +93 -0
- package/src/renderer/tests/voicePill.browser.html +80 -0
- package/src/renderer/tests/voicePill.preview.html +34 -0
- package/src/renderer/tests/webSources.browser.html +1 -0
- package/src/renderer/tests/webSources.browser.tsx +98 -0
- package/src/renderer/tests/workspaceUndo.browser.html +92 -0
- package/src-tauri/Cargo.toml +40 -0
- package/src-tauri/build.rs +3 -0
- package/src-tauri/src/app/lifecycle.rs +277 -0
- package/src-tauri/src/app/mod.rs +4 -0
- package/src-tauri/src/app/shortcuts.rs +40 -0
- package/src-tauri/src/app/tray.rs +52 -0
- package/src-tauri/src/background/events.rs +70 -0
- package/src-tauri/src/background/headless.rs +230 -0
- package/src-tauri/src/background/mod.rs +4 -0
- package/src-tauri/src/background/proactive.rs +262 -0
- package/src-tauri/src/commands/approvals.rs +20 -0
- package/src-tauri/src/commands/auth.rs +127 -0
- package/src-tauri/src/commands/conversation.rs +642 -0
- package/src-tauri/src/commands/integrations.rs +157 -0
- package/src-tauri/src/commands/media.rs +179 -0
- package/src-tauri/src/commands/mod.rs +11 -0
- package/src-tauri/src/commands/mods.rs +6 -0
- package/src-tauri/src/commands/settings.rs +141 -0
- package/src-tauri/src/commands/voice.rs +153 -0
- package/src-tauri/src/commands/workspace.rs +501 -0
- package/src-tauri/src/lib.rs +10 -0
- package/src-tauri/src/main.rs +3 -0
- package/src-tauri/src/native/actions.rs +206 -0
- package/src-tauri/src/native/browser.rs +252 -0
- package/src-tauri/src/native/capture.rs +695 -0
- package/src-tauri/src/native/discord_rpc.rs +99 -0
- package/src-tauri/src/native/integrations.rs +126 -0
- package/src-tauri/src/native/mod.rs +12 -0
- package/src-tauri/src/native/notifications.rs +51 -0
- package/src-tauri/src/native/plugins.rs +14 -0
- package/src-tauri/src/native/system.rs +250 -0
- package/src-tauri/src/native/terminal.rs +201 -0
- package/src-tauri/src/native/updater.rs +148 -0
- package/src-tauri/src/native/windows.rs +143 -0
- package/tsconfig.json +2 -0
- package/vite.config.ts +4 -1
- package/vite.config.web.ts +4 -0
- package/.cargo/config.toml +0 -13
- package/.claude/settings.local.json +0 -182
- package/.codex +0 -0
- package/CLAUDE.md +0 -102
- package/ROADMAP.md +0 -30
- package/mint-presentation-demo.mp4 +0 -0
- package/out/web/Live2DCubismCore.js +0 -9
- package/out/web/assets/CliSessionsView-BxUVWEEL.js +0 -1
- package/out/web/assets/CliSessionsView-CBDTXuQv.css +0 -1
- package/out/web/assets/CodeReviewPage-DkMgfcos.css +0 -1
- package/out/web/assets/CodeReviewPage-jKlmLJwT.js +0 -3
- package/out/web/assets/CommandPalette-DnwPA5hy.js +0 -1
- package/out/web/assets/ImageStudioPanel-BR1XFwhR.js +0 -1
- package/out/web/assets/LinkedFoldersView-bi-CWQ-I.js +0 -1
- package/out/web/assets/McpRegistryPicker-D5tEFnyq.js +0 -1
- package/out/web/assets/McpServersView-BGG1dhFM.js +0 -1
- package/out/web/assets/MintDashboard-BIglDEWX.js +0 -20
- package/out/web/assets/MintDashboard-DSMywSgs.css +0 -1
- package/out/web/assets/ModelPanel-CbJ1PFoZ.js +0 -1
- package/out/web/assets/PicturesLibrary-CQP0fLP1.css +0 -1
- package/out/web/assets/PicturesLibrary-DoYN7T1p.js +0 -1
- package/out/web/assets/PluginsView-CU1HWXGk.js +0 -1
- package/out/web/assets/ScheduledTasksView-Bnl36y2N.js +0 -1
- package/out/web/assets/SettingsWindow-DhWLAn9T.css +0 -1
- package/out/web/assets/SettingsWindow-Dw8L01pw.js +0 -2
- package/out/web/assets/SkillsView-cnl8aY5p.js +0 -2
- package/out/web/assets/ToolSurfacePage-CgsQw6l5.css +0 -1
- package/out/web/assets/ToolSurfacePage-Cz2VJAPZ.js +0 -37
- package/out/web/assets/VeoStudioPanel-D4JnERWR.js +0 -4
- package/out/web/assets/chunk-CKBBP62Z-cIrXq6jN.js +0 -2
- package/out/web/assets/classDiagram-DTDB5LWJ-Dq0smRWk.js +0 -1
- package/out/web/assets/classDiagram-v2-JRS7N3AN-Dq0smRWk.js +0 -1
- package/out/web/assets/config-C-ZFtipU.css +0 -1
- package/out/web/assets/config-eEDngJXO.js +0 -1
- package/out/web/assets/core-hQ2VA9Ti.js +0 -1
- package/out/web/assets/dist-js-Bf2bhoku.js +0 -1
- package/out/web/assets/flowDiagram-A5DVABFB-BLg7nEcd.js +0 -1
- package/out/web/assets/index-Btsf4L8M.css +0 -1
- package/out/web/assets/index-D8D9MeRA.js +0 -11
- package/out/web/assets/lucide-react-Ip3L6Jtn.js +0 -1
- package/out/web/assets/markdown-BSeeUbJH.js +0 -38
- package/out/web/assets/modelManager-tMVmJVAW.js +0 -2
- package/out/web/assets/prompt-latin-400-normal-BQ9zjSN8.woff2 +0 -0
- package/out/web/assets/prompt-latin-400-normal-CxU4ec_r.woff +0 -0
- package/out/web/assets/prompt-latin-500-normal-B1edBDQ9.woff +0 -0
- package/out/web/assets/prompt-latin-500-normal-CxzxEHZc.woff2 +0 -0
- package/out/web/assets/prompt-latin-600-normal-CSDDLorv.woff +0 -0
- package/out/web/assets/prompt-latin-600-normal-hKZWXsc1.woff2 +0 -0
- package/out/web/assets/prompt-latin-700-normal-BfbftDSq.woff +0 -0
- package/out/web/assets/prompt-latin-700-normal-I2gc831J.woff2 +0 -0
- package/out/web/assets/prompt-thai-400-normal-BrkKv8cO.woff2 +0 -0
- package/out/web/assets/prompt-thai-400-normal-DJypnfr3.woff +0 -0
- package/out/web/assets/prompt-thai-500-normal-C18pDUoL.woff2 +0 -0
- package/out/web/assets/prompt-thai-500-normal-D7YNqUJD.woff +0 -0
- package/out/web/assets/prompt-thai-600-normal-CYPViXds.woff +0 -0
- package/out/web/assets/prompt-thai-600-normal-MrdfU7zR.woff2 +0 -0
- package/out/web/assets/prompt-thai-700-normal-Cb5ilR-c.woff +0 -0
- package/out/web/assets/prompt-thai-700-normal-Cg4aQ0Nn.woff2 +0 -0
- package/out/web/assets/stateDiagram-v2-4QOOHH4V-DeEc0lGZ.js +0 -1
- package/out/web/assets/swimlanesDiagram-VK2B7HYN-DpVik9v7.js +0 -8
- package/out/web/assets/window-5qYXKoW7.js +0 -1
- package/skills-lock.json +0 -77
- package/src/renderer/public/Live2DCubismCore.js +0 -9
- package/src/renderer/src/companionWidget.ts +0 -95
- package/src/renderer/src/components/Live2DStage.tsx +0 -412
- package/src/renderer/src/components/ModelPanel.tsx +0 -155
- package/src/renderer/src/css/model.css +0 -628
- package/src/renderer/src-web/companionWidget.ts +0 -37
- package/src/renderer/src-web/components/ModelPanel.tsx +0 -12
- package/src/renderer/src-web/css/model.css +0 -628
|
@@ -1,6 +1,298 @@
|
|
|
1
1
|
use std::path::Path;
|
|
2
2
|
|
|
3
3
|
use super::super::*;
|
|
4
|
+
use crate::integrations::mcp_result::{ToolOutcome, ToolStatus, normalize_mcp_result};
|
|
5
|
+
|
|
6
|
+
pub(in crate::orchestration) async fn execute_mcp_outcome(
|
|
7
|
+
action: &str,
|
|
8
|
+
input: &AgentInput,
|
|
9
|
+
config: &MintConfig,
|
|
10
|
+
chat_id: &str,
|
|
11
|
+
call_id: &str,
|
|
12
|
+
approve: &mut (dyn FnMut(&AgentApproval) -> Result<ApprovalOutcome, String> + Send),
|
|
13
|
+
progress: &mut (dyn FnMut(AgentProgress) + Send),
|
|
14
|
+
) -> Result<ToolOutcome, OrchestrationError> {
|
|
15
|
+
execute_reviewed(
|
|
16
|
+
action, input, config, chat_id, call_id, None, approve, progress,
|
|
17
|
+
)
|
|
18
|
+
.await
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
fn authorize(
|
|
22
|
+
cfg: &mut MintConfig,
|
|
23
|
+
server: &str,
|
|
24
|
+
tool: &str,
|
|
25
|
+
arguments: Value,
|
|
26
|
+
approve: &mut (dyn FnMut(&AgentApproval) -> Result<ApprovalOutcome, String> + Send),
|
|
27
|
+
) -> Result<Option<ToolOutcome>, OrchestrationError> {
|
|
28
|
+
super::super::run_control::check()?;
|
|
29
|
+
if crate::mcp::is_mcp_tool_allowed(cfg, server, tool) {
|
|
30
|
+
return Ok(None);
|
|
31
|
+
}
|
|
32
|
+
let approval = approve(&AgentApproval::McpTool {
|
|
33
|
+
server: server.into(),
|
|
34
|
+
tool: tool.into(),
|
|
35
|
+
arguments,
|
|
36
|
+
})
|
|
37
|
+
.map_err(OrchestrationError::Agent)?;
|
|
38
|
+
super::super::run_control::check()?;
|
|
39
|
+
match approval {
|
|
40
|
+
ApprovalOutcome::Approved => {
|
|
41
|
+
crate::mcp::allow_tool_in(cfg, server, tool);
|
|
42
|
+
}
|
|
43
|
+
ApprovalOutcome::Intercepted(answer) if answer == MCP_ALLOW_ALL_SENTINEL => {
|
|
44
|
+
crate::mcp::allow_mcp_tool(server, "*")
|
|
45
|
+
.map_err(|e| OrchestrationError::Agent(e.to_string()))?;
|
|
46
|
+
crate::mcp::allow_tool_in(cfg, server, "*");
|
|
47
|
+
}
|
|
48
|
+
ApprovalOutcome::Denied => {
|
|
49
|
+
return Ok(Some(ToolOutcome::from(format!(
|
|
50
|
+
"User denied MCP tool call: {server} {tool}"
|
|
51
|
+
))));
|
|
52
|
+
}
|
|
53
|
+
ApprovalOutcome::Intercepted(answer) => {
|
|
54
|
+
return Ok(Some(ToolOutcome {
|
|
55
|
+
text: format!(
|
|
56
|
+
"MCP call was not approved; no command was executed. User feedback: {answer}"
|
|
57
|
+
),
|
|
58
|
+
status: ToolStatus::Failed,
|
|
59
|
+
..Default::default()
|
|
60
|
+
}));
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
Ok(None)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
fn failure(error: crate::mcp::McpError) -> ToolOutcome {
|
|
67
|
+
use crate::mcp::McpError;
|
|
68
|
+
let status = match error {
|
|
69
|
+
McpError::Timeout | McpError::TimeoutUndelivered => ToolStatus::TimedOut,
|
|
70
|
+
McpError::Cancelled | McpError::CancelledUndelivered => ToolStatus::Cancelled,
|
|
71
|
+
_ => ToolStatus::Failed,
|
|
72
|
+
};
|
|
73
|
+
let text = if status == ToolStatus::TimedOut {
|
|
74
|
+
format!(
|
|
75
|
+
"Error: {error}; remote completion is unconfirmed. Do not automatically retry this operation."
|
|
76
|
+
)
|
|
77
|
+
} else {
|
|
78
|
+
format!("Error: {error}")
|
|
79
|
+
};
|
|
80
|
+
ToolOutcome {
|
|
81
|
+
text,
|
|
82
|
+
status,
|
|
83
|
+
..Default::default()
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/// Preparation returns an observation, never a command execution record.
|
|
88
|
+
pub(in crate::orchestration) async fn prepare(
|
|
89
|
+
input: &AgentInput,
|
|
90
|
+
config: &MintConfig,
|
|
91
|
+
chat: &str,
|
|
92
|
+
review: &mut mcp_review::McpReview,
|
|
93
|
+
approve: &mut (dyn FnMut(&AgentApproval) -> Result<ApprovalOutcome, String> + Send),
|
|
94
|
+
progress: &mut (dyn FnMut(AgentProgress) + Send),
|
|
95
|
+
) -> Result<Option<ToolOutcome>, OrchestrationError> {
|
|
96
|
+
let server = required(&input.server, "server")?;
|
|
97
|
+
let tool = required(&input.tool, "tool")?;
|
|
98
|
+
// Reading definitions is separately authorized and does not grant execution.
|
|
99
|
+
if !review.discovery_grants.contains(server)
|
|
100
|
+
&& !crate::mcp::is_mcp_tool_allowed(config, server, tool)
|
|
101
|
+
&& !crate::mcp::is_mcp_tool_allowed(config, server, "list_tools")
|
|
102
|
+
{
|
|
103
|
+
let mut cfg = config.clone();
|
|
104
|
+
if let Some(out) = authorize(
|
|
105
|
+
&mut cfg,
|
|
106
|
+
server,
|
|
107
|
+
"list_tools",
|
|
108
|
+
serde_json::json!({}),
|
|
109
|
+
approve,
|
|
110
|
+
)? {
|
|
111
|
+
return Ok(Some(out));
|
|
112
|
+
}
|
|
113
|
+
review.discovery_grants.insert(server.into());
|
|
114
|
+
}
|
|
115
|
+
let definition = match crate::mcp::catalog::describe_tool(config, server, tool, chat).await {
|
|
116
|
+
Ok(d) => d,
|
|
117
|
+
Err(e) => return Ok(Some(failure(e))),
|
|
118
|
+
};
|
|
119
|
+
let mut read = review.knows(server, tool, &definition.fingerprint, &definition.value);
|
|
120
|
+
if let Some(status) = crate::mcp::device::status_tool(&definition)
|
|
121
|
+
.map_err(|e| OrchestrationError::Agent(e.to_string()))?
|
|
122
|
+
{
|
|
123
|
+
let status_definition = crate::mcp::catalog::describe_tool(config, server, &status, chat)
|
|
124
|
+
.await
|
|
125
|
+
.map_err(|e| OrchestrationError::Agent(e.to_string()))?;
|
|
126
|
+
read = review.knows(
|
|
127
|
+
server,
|
|
128
|
+
&status,
|
|
129
|
+
&status_definition.fingerprint,
|
|
130
|
+
&status_definition.value,
|
|
131
|
+
) && read;
|
|
132
|
+
}
|
|
133
|
+
if read {
|
|
134
|
+
return Ok(None);
|
|
135
|
+
}
|
|
136
|
+
let message="Tool definition loaded for the next model request. No tools/call was sent. Read its description and inputSchema, then submit the command with valid arguments.".to_string();
|
|
137
|
+
progress(AgentProgress::ToolDiscovery {
|
|
138
|
+
server: server.into(),
|
|
139
|
+
tool: tool.into(),
|
|
140
|
+
message: "Tool definition ready; preparing the command.".into(),
|
|
141
|
+
});
|
|
142
|
+
Ok(Some(ToolOutcome::from(message)))
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
#[allow(clippy::too_many_arguments)]
|
|
146
|
+
pub(in crate::orchestration) async fn execute_reviewed(
|
|
147
|
+
action: &str,
|
|
148
|
+
input: &AgentInput,
|
|
149
|
+
config: &MintConfig,
|
|
150
|
+
chat_id: &str,
|
|
151
|
+
call_id: &str,
|
|
152
|
+
expected: Option<&mcp_review::McpReview>,
|
|
153
|
+
approve: &mut (dyn FnMut(&AgentApproval) -> Result<ApprovalOutcome, String> + Send),
|
|
154
|
+
progress: &mut (dyn FnMut(AgentProgress) + Send),
|
|
155
|
+
) -> Result<ToolOutcome, OrchestrationError> {
|
|
156
|
+
let server = required(&input.server, "server")?;
|
|
157
|
+
let tool = if action == "mcp_tool" {
|
|
158
|
+
required(&input.tool, "tool")?
|
|
159
|
+
} else {
|
|
160
|
+
"list_tools"
|
|
161
|
+
};
|
|
162
|
+
let mut cfg = config.clone();
|
|
163
|
+
if action == "mcp_list_tools" {
|
|
164
|
+
if let Some(out) = authorize(&mut cfg, server, tool, input.arguments.clone(), approve)? {
|
|
165
|
+
return Ok(out);
|
|
166
|
+
}
|
|
167
|
+
return Ok(
|
|
168
|
+
match crate::mcp::catalog::list_tools(&cfg, server, chat_id).await {
|
|
169
|
+
Ok(v) => ToolOutcome::from(serde_json::to_string_pretty(&v).unwrap_or_default()),
|
|
170
|
+
Err(e) => failure(e),
|
|
171
|
+
},
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
let definition = match crate::mcp::catalog::describe_tool(&cfg, server, tool, chat_id).await {
|
|
175
|
+
Ok(d) => d,
|
|
176
|
+
Err(e) => return Ok(failure(e)),
|
|
177
|
+
};
|
|
178
|
+
if let Err(e) = definition.validate(&input.arguments) {
|
|
179
|
+
return Ok(failure(e));
|
|
180
|
+
}
|
|
181
|
+
if expected
|
|
182
|
+
.is_some_and(|r| r.fingerprint(server, tool) != Some(definition.fingerprint.as_str()))
|
|
183
|
+
{
|
|
184
|
+
return Ok(failure(crate::mcp::McpError::Preflight(
|
|
185
|
+
"Definition changed; read it again before executing".into(),
|
|
186
|
+
)));
|
|
187
|
+
}
|
|
188
|
+
let status_name = match crate::mcp::device::status_tool(&definition) {
|
|
189
|
+
Ok(s) => s,
|
|
190
|
+
Err(e) => return Ok(failure(e)),
|
|
191
|
+
};
|
|
192
|
+
let status_definition = if let Some(name) = &status_name {
|
|
193
|
+
let d = match crate::mcp::catalog::describe_tool(&cfg, server, name, chat_id).await {
|
|
194
|
+
Ok(d) => d,
|
|
195
|
+
Err(e) => return Ok(failure(e)),
|
|
196
|
+
};
|
|
197
|
+
if expected.is_some_and(|r| r.fingerprint(server, name) != Some(d.fingerprint.as_str())) {
|
|
198
|
+
return Ok(failure(crate::mcp::McpError::Preflight(
|
|
199
|
+
"Status definition changed; read it again before executing".into(),
|
|
200
|
+
)));
|
|
201
|
+
}
|
|
202
|
+
let preflight = (|| {
|
|
203
|
+
definition.output_validator()?;
|
|
204
|
+
d.valid_schema()?;
|
|
205
|
+
d.output_validator()?;
|
|
206
|
+
if crate::mcp::device::status_tool(&d)?.is_some() {
|
|
207
|
+
return Err(crate::mcp::McpError::Preflight(
|
|
208
|
+
"statusTool must be a read-only observation tool without command metadata"
|
|
209
|
+
.into(),
|
|
210
|
+
));
|
|
211
|
+
}
|
|
212
|
+
d.validate(&serde_json::json!({"deviceId":input.arguments["deviceId"],"operationId":uuid::Uuid::new_v4().to_string()}))
|
|
213
|
+
})();
|
|
214
|
+
if let Err(e) = preflight {
|
|
215
|
+
return Ok(failure(e));
|
|
216
|
+
}
|
|
217
|
+
Some(d)
|
|
218
|
+
} else {
|
|
219
|
+
None
|
|
220
|
+
};
|
|
221
|
+
if let Some(out) = authorize(&mut cfg, server, tool, input.arguments.clone(), approve)? {
|
|
222
|
+
return Ok(out);
|
|
223
|
+
}
|
|
224
|
+
if let (Some(name), Some(status_definition)) = (status_name, status_definition) {
|
|
225
|
+
if let Some(out) = authorize(
|
|
226
|
+
&mut cfg,
|
|
227
|
+
server,
|
|
228
|
+
&name,
|
|
229
|
+
serde_json::json!({"deviceId":input.arguments["deviceId"],"operationId":"<operationId returned by this command>","scope":"Read status only for this command until its deadline"}),
|
|
230
|
+
approve,
|
|
231
|
+
)? {
|
|
232
|
+
return Ok(out);
|
|
233
|
+
}
|
|
234
|
+
// Both event callbacks share the sink but are invoked sequentially.
|
|
235
|
+
let sink = std::sync::Mutex::new(progress);
|
|
236
|
+
let result = crate::mcp::device::call_verified(
|
|
237
|
+
&cfg,
|
|
238
|
+
server,
|
|
239
|
+
tool,
|
|
240
|
+
input.arguments.clone(),
|
|
241
|
+
chat_id,
|
|
242
|
+
definition,
|
|
243
|
+
&name,
|
|
244
|
+
status_definition,
|
|
245
|
+
|update| {
|
|
246
|
+
sink.lock().unwrap()(AgentProgress::ToolProgress {
|
|
247
|
+
call_id: call_id.into(),
|
|
248
|
+
server: server.into(),
|
|
249
|
+
tool: tool.into(),
|
|
250
|
+
update,
|
|
251
|
+
})
|
|
252
|
+
},
|
|
253
|
+
|update| {
|
|
254
|
+
sink.lock().unwrap()(AgentProgress::DeviceState {
|
|
255
|
+
call_id: call_id.into(),
|
|
256
|
+
server: server.into(),
|
|
257
|
+
tool: tool.into(),
|
|
258
|
+
update,
|
|
259
|
+
})
|
|
260
|
+
},
|
|
261
|
+
)
|
|
262
|
+
.await;
|
|
263
|
+
let mut out = normalize_mcp_result(result.receipt, chat_id, call_id, server);
|
|
264
|
+
out.status = result.status;
|
|
265
|
+
out.completion_unconfirmed = result.completion_unconfirmed;
|
|
266
|
+
out.text.push_str(&format!("\n{}", result.message));
|
|
267
|
+
if out.status != ToolStatus::Success && !out.text.starts_with("Error:") {
|
|
268
|
+
out.text.insert_str(0, "Error: ");
|
|
269
|
+
}
|
|
270
|
+
return Ok(out);
|
|
271
|
+
}
|
|
272
|
+
Ok(
|
|
273
|
+
match crate::mcp::call_mcp_tool_reviewed(
|
|
274
|
+
&cfg,
|
|
275
|
+
server,
|
|
276
|
+
tool,
|
|
277
|
+
input.arguments.clone(),
|
|
278
|
+
chat_id,
|
|
279
|
+
Some(&definition.fingerprint),
|
|
280
|
+
|update| {
|
|
281
|
+
progress(AgentProgress::ToolProgress {
|
|
282
|
+
call_id: call_id.into(),
|
|
283
|
+
server: server.into(),
|
|
284
|
+
tool: tool.into(),
|
|
285
|
+
update,
|
|
286
|
+
})
|
|
287
|
+
},
|
|
288
|
+
)
|
|
289
|
+
.await
|
|
290
|
+
{
|
|
291
|
+
Ok(v) => normalize_mcp_result(v, chat_id, call_id, server),
|
|
292
|
+
Err(e) => failure(e),
|
|
293
|
+
},
|
|
294
|
+
)
|
|
295
|
+
}
|
|
4
296
|
|
|
5
297
|
/// Handles the subset of `execute_tool` actions related to plugins mcp.
|
|
6
298
|
/// Only called for actions `execute_tool` has already routed here, so the
|
|
@@ -37,79 +329,19 @@ pub(in crate::orchestration) async fn execute(
|
|
|
37
329
|
let task = required(&input.instruction, "instruction")?;
|
|
38
330
|
dispatch_one_subagent(root, config, chat_id, name, task, approve_cb, progress).await
|
|
39
331
|
}
|
|
40
|
-
"mcp_tool" =>
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
mcp_approve_then_run(server, tool, &args, config, approve_cb, run)
|
|
52
|
-
}
|
|
53
|
-
"mcp_list_tools" => {
|
|
54
|
-
let server = required(&input.server, "server")?;
|
|
55
|
-
let run = |cfg: &MintConfig| -> Result<String, OrchestrationError> {
|
|
56
|
-
serde_json::to_string_pretty(
|
|
57
|
-
&crate::mcp::list_server_tools(cfg, server)
|
|
58
|
-
.map_err(|e| OrchestrationError::Agent(e.to_string()))?,
|
|
59
|
-
)
|
|
60
|
-
.map_err(|e| OrchestrationError::Agent(e.to_string()))
|
|
61
|
-
};
|
|
62
|
-
mcp_approve_then_run(
|
|
63
|
-
server,
|
|
64
|
-
"list_tools",
|
|
65
|
-
&serde_json::json!({}),
|
|
66
|
-
config,
|
|
67
|
-
approve_cb,
|
|
68
|
-
run,
|
|
69
|
-
)
|
|
70
|
-
}
|
|
332
|
+
"mcp_tool" | "mcp_list_tools" => execute_mcp_outcome(
|
|
333
|
+
action,
|
|
334
|
+
input,
|
|
335
|
+
config,
|
|
336
|
+
chat_id,
|
|
337
|
+
&uuid::Uuid::new_v4().to_string(),
|
|
338
|
+
approve_cb,
|
|
339
|
+
progress,
|
|
340
|
+
)
|
|
341
|
+
.await
|
|
342
|
+
.map(|out| out.text),
|
|
71
343
|
_ => unreachable!(
|
|
72
344
|
"execute_tool routed an unhandled action into tools::plugins_mcp::execute: {action}"
|
|
73
345
|
),
|
|
74
346
|
}
|
|
75
347
|
}
|
|
76
|
-
|
|
77
|
-
/// Shared gate for `mcp_tool` / `mcp_list_tools`:
|
|
78
|
-
/// * a server already trusted via `allowedMcpTools` runs `run` with no prompt;
|
|
79
|
-
/// * otherwise the user is asked. "Allow all (*)" (the
|
|
80
|
-
/// [`MCP_ALLOW_ALL_SENTINEL`] answer) persists `allowedMcpTools[server] =
|
|
81
|
-
/// ["*"]` and then runs against the freshly reloaded config, so the same
|
|
82
|
-
/// server never prompts again;
|
|
83
|
-
/// * a plain approve runs once; deny / free-text feedback is returned as-is.
|
|
84
|
-
fn mcp_approve_then_run(
|
|
85
|
-
server: &str,
|
|
86
|
-
tool: &str,
|
|
87
|
-
arguments: &serde_json::Value,
|
|
88
|
-
config: &MintConfig,
|
|
89
|
-
approve_cb: &mut (dyn FnMut(&AgentApproval) -> Result<ApprovalOutcome, String> + Send),
|
|
90
|
-
run: impl Fn(&MintConfig) -> Result<String, OrchestrationError>,
|
|
91
|
-
) -> Result<String, OrchestrationError> {
|
|
92
|
-
if crate::mcp::is_mcp_tool_allowed(config, server, tool) {
|
|
93
|
-
return run(config);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
let outcome = approve_cb(&AgentApproval::McpTool {
|
|
97
|
-
server: server.to_owned(),
|
|
98
|
-
tool: tool.to_owned(),
|
|
99
|
-
arguments: arguments.clone(),
|
|
100
|
-
})
|
|
101
|
-
.map_err(OrchestrationError::Agent)?;
|
|
102
|
-
|
|
103
|
-
match outcome {
|
|
104
|
-
ApprovalOutcome::Approved => run(config),
|
|
105
|
-
ApprovalOutcome::Intercepted(answer) if answer == MCP_ALLOW_ALL_SENTINEL => {
|
|
106
|
-
crate::mcp::allow_mcp_tool(server, "*")
|
|
107
|
-
.map_err(|e| OrchestrationError::Agent(e.to_string()))?;
|
|
108
|
-
let reloaded =
|
|
109
|
-
crate::load_config().map_err(|e| OrchestrationError::Agent(e.to_string()))?;
|
|
110
|
-
run(&reloaded)
|
|
111
|
-
}
|
|
112
|
-
ApprovalOutcome::Denied => Ok(format!("User denied MCP tool call: {server} {tool}")),
|
|
113
|
-
ApprovalOutcome::Intercepted(obs) => Ok(obs),
|
|
114
|
-
}
|
|
115
|
-
}
|
|
@@ -2,6 +2,40 @@ use std::path::Path;
|
|
|
2
2
|
|
|
3
3
|
use super::super::*;
|
|
4
4
|
|
|
5
|
+
/// Catch ordinary URL launcher commands, not arbitrary shell programs. This is
|
|
6
|
+
/// a workflow guard, not a shell security boundary.
|
|
7
|
+
fn launches_external_url(command: &str) -> bool {
|
|
8
|
+
let Some(tokens) = shlex::split(command) else {
|
|
9
|
+
return false;
|
|
10
|
+
};
|
|
11
|
+
let Some(program) = tokens.first() else {
|
|
12
|
+
return false;
|
|
13
|
+
};
|
|
14
|
+
let program = program.rsplit(['/', '\\']).next().unwrap_or(program);
|
|
15
|
+
let launcher = match program.to_ascii_lowercase().as_str() {
|
|
16
|
+
"xdg-open" | "open" | "wslview" | "sensible-browser" | "start-process" | "start" => true,
|
|
17
|
+
"gio" => tokens.get(1).is_some_and(|arg| arg == "open"),
|
|
18
|
+
_ => false,
|
|
19
|
+
};
|
|
20
|
+
launcher
|
|
21
|
+
&& tokens.iter().skip(1).any(|arg| {
|
|
22
|
+
reqwest::Url::parse(arg).is_ok_and(|url| {
|
|
23
|
+
matches!(url.scheme(), "http" | "https") && url.host_str().is_some()
|
|
24
|
+
})
|
|
25
|
+
})
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
pub(in crate::orchestration) async fn prevent_duplicate_browser_launch(
|
|
29
|
+
command: &str,
|
|
30
|
+
) -> Result<(), OrchestrationError> {
|
|
31
|
+
if launches_external_url(command) && crate::browser::session_finish_evidence().await {
|
|
32
|
+
return Err(OrchestrationError::Agent(
|
|
33
|
+
"External URL launch skipped: this task already uses the automation browser. Use browser_observe/browser_read to inspect its current page, browser_screenshot for visual inspection, or browser_open if navigation is still needed. Do not open the same URL in another browser.".into(),
|
|
34
|
+
));
|
|
35
|
+
}
|
|
36
|
+
Ok(())
|
|
37
|
+
}
|
|
38
|
+
|
|
5
39
|
/// Handles the subset of `execute_tool` actions related to shell.
|
|
6
40
|
/// Only called for actions `execute_tool` has already routed here, so the
|
|
7
41
|
/// fallback arm is unreachable in practice.
|
|
@@ -16,6 +50,7 @@ pub(in crate::orchestration) async fn execute(
|
|
|
16
50
|
match action {
|
|
17
51
|
"run_shell" => {
|
|
18
52
|
let command = required(&input.command, "command")?;
|
|
53
|
+
prevent_duplicate_browser_launch(command).await?;
|
|
19
54
|
let mode = classify_shell_command(command).mode.as_str().to_owned();
|
|
20
55
|
let approved = approve_cb(&AgentApproval::RunShell {
|
|
21
56
|
command: command.to_owned(),
|
|
@@ -26,8 +61,11 @@ pub(in crate::orchestration) async fn execute(
|
|
|
26
61
|
|
|
27
62
|
match approved {
|
|
28
63
|
ApprovalOutcome::Approved if input.background => {
|
|
29
|
-
let started = crate::bg_shell::
|
|
30
|
-
|
|
64
|
+
let started = crate::bg_shell::with_context(
|
|
65
|
+
crate::bg_shell::chat_context(root, chat_id),
|
|
66
|
+
|| crate::bg_shell::start_background(root, config, command),
|
|
67
|
+
)
|
|
68
|
+
.map_err(|e| OrchestrationError::Agent(e.to_string()))?;
|
|
31
69
|
Ok(format!(
|
|
32
70
|
"job_id: {}\npid: {}\nstatus: running\nUse the 'shell_output' tool with this job_id to check on it, and 'kill_shell' to stop it.",
|
|
33
71
|
started.id,
|
|
@@ -43,11 +81,27 @@ pub(in crate::orchestration) async fn execute(
|
|
|
43
81
|
}
|
|
44
82
|
"shell_output" => {
|
|
45
83
|
let job_id = required(&input.job_id, "job_id")?;
|
|
84
|
+
if !crate::bg_shell::accessible(
|
|
85
|
+
job_id,
|
|
86
|
+
&crate::bg_shell::chat_context(root, chat_id).owner,
|
|
87
|
+
) {
|
|
88
|
+
return Err(OrchestrationError::Agent(
|
|
89
|
+
"No accessible background job with that id".into(),
|
|
90
|
+
));
|
|
91
|
+
}
|
|
46
92
|
crate::bg_shell::poll_output(job_id)
|
|
47
93
|
.map_err(|e| OrchestrationError::Agent(e.to_string()))
|
|
48
94
|
}
|
|
49
95
|
"kill_shell" => {
|
|
50
96
|
let job_id = required(&input.job_id, "job_id")?;
|
|
97
|
+
if !crate::bg_shell::accessible(
|
|
98
|
+
job_id,
|
|
99
|
+
&crate::bg_shell::chat_context(root, chat_id).owner,
|
|
100
|
+
) {
|
|
101
|
+
return Err(OrchestrationError::Agent(
|
|
102
|
+
"No accessible background job with that id".into(),
|
|
103
|
+
));
|
|
104
|
+
}
|
|
51
105
|
crate::bg_shell::kill_job(job_id).map_err(|e| OrchestrationError::Agent(e.to_string()))
|
|
52
106
|
}
|
|
53
107
|
"verify" => {
|
|
@@ -163,3 +217,42 @@ pub(in crate::orchestration) async fn execute(
|
|
|
163
217
|
),
|
|
164
218
|
}
|
|
165
219
|
}
|
|
220
|
+
|
|
221
|
+
#[cfg(test)]
|
|
222
|
+
mod tests {
|
|
223
|
+
use super::*;
|
|
224
|
+
|
|
225
|
+
#[test]
|
|
226
|
+
fn external_url_launch_detection_preserves_other_shell_work() {
|
|
227
|
+
for command in [
|
|
228
|
+
"xdg-open 'https://example.com/watch?v=1&list=2'",
|
|
229
|
+
"/usr/bin/xdg-open https://example.com &",
|
|
230
|
+
"open -a Firefox https://example.com",
|
|
231
|
+
"gio open https://example.com",
|
|
232
|
+
"wslview https://example.com",
|
|
233
|
+
"Start-Process https://example.com",
|
|
234
|
+
] {
|
|
235
|
+
assert!(launches_external_url(command), "{command}");
|
|
236
|
+
}
|
|
237
|
+
for command in [
|
|
238
|
+
"xdg-open /tmp/report.pdf",
|
|
239
|
+
"open /tmp",
|
|
240
|
+
"curl https://example.com",
|
|
241
|
+
"echo xdg-open https://example.com",
|
|
242
|
+
"gio info https://example.com",
|
|
243
|
+
"cargo test",
|
|
244
|
+
] {
|
|
245
|
+
assert!(!launches_external_url(command), "{command}");
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
#[tokio::test]
|
|
250
|
+
async fn external_url_launch_allowed_without_browser_use() {
|
|
251
|
+
crate::browser::run_session(async {
|
|
252
|
+
prevent_duplicate_browser_launch("xdg-open https://example.com")
|
|
253
|
+
.await
|
|
254
|
+
.unwrap();
|
|
255
|
+
})
|
|
256
|
+
.await;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
@@ -189,6 +189,7 @@ pub(super) async fn run_shell(
|
|
|
189
189
|
chat_id: &str,
|
|
190
190
|
command: &str,
|
|
191
191
|
) -> Result<String, OrchestrationError> {
|
|
192
|
+
tools::shell::prevent_duplicate_browser_launch(command).await?;
|
|
192
193
|
let root = root.to_path_buf();
|
|
193
194
|
let config = config.clone();
|
|
194
195
|
let chat_id = chat_id.to_owned();
|
|
@@ -196,7 +197,9 @@ pub(super) async fn run_shell(
|
|
|
196
197
|
let output = {
|
|
197
198
|
let command = command.clone();
|
|
198
199
|
tokio::task::spawn_blocking(move || {
|
|
199
|
-
|
|
200
|
+
crate::bg_shell::with_context(crate::bg_shell::chat_context(&root, &chat_id), || {
|
|
201
|
+
run_shell_command(&command, &root, true, &config, Some(&chat_id))
|
|
202
|
+
})
|
|
200
203
|
})
|
|
201
204
|
.await
|
|
202
205
|
.map_err(|e| OrchestrationError::Agent(format!("shell command task panicked: {e}")))?
|
|
@@ -46,6 +46,9 @@ pub(crate) const PLAN_MODE_ALLOWED_ACTIONS: &[&str] = &[
|
|
|
46
46
|
"stock",
|
|
47
47
|
"calculation",
|
|
48
48
|
"memory_recall",
|
|
49
|
+
"mod_help",
|
|
50
|
+
"mod_list",
|
|
51
|
+
"mod_validate",
|
|
49
52
|
"git_status",
|
|
50
53
|
"git_diff",
|
|
51
54
|
"git_log",
|
|
@@ -102,6 +105,10 @@ pub(crate) fn base_allowed_actions() -> Vec<&'static str> {
|
|
|
102
105
|
"stock",
|
|
103
106
|
"calculation",
|
|
104
107
|
"memory_recall",
|
|
108
|
+
"mod_help",
|
|
109
|
+
"mod_list",
|
|
110
|
+
"mod_validate",
|
|
111
|
+
"mod_publish",
|
|
105
112
|
"git_status",
|
|
106
113
|
"git_diff",
|
|
107
114
|
"git_log",
|
|
@@ -185,6 +192,7 @@ pub fn build_system_prompt(
|
|
|
185
192
|
let actions_str = allowed_actions.join("|");
|
|
186
193
|
|
|
187
194
|
let mut input_formats = Vec::new();
|
|
195
|
+
input_formats.push("- mod_help / mod_list: {}. mod_validate / mod_publish: {\"arguments\":{\"manifest\":{...},\"source\":\"export function register(mint) {...}\",\"readme\":\"...\",\"expectedHash\":\"existing hash when replacing\"}}.");
|
|
188
196
|
if allowed_actions.contains(&"list_files") {
|
|
189
197
|
input_formats.push(
|
|
190
198
|
"- list_files: {\"path\":\".\",\"limit\":100} (workspace path, ~/path, or allowed user folder like Downloads)",
|
|
@@ -451,6 +459,9 @@ pub fn build_system_prompt(
|
|
|
451
459
|
let input_formats_str = input_formats.join("\n");
|
|
452
460
|
|
|
453
461
|
let mut rules = Vec::new();
|
|
462
|
+
if allowed_actions.contains(&"mod_help") {
|
|
463
|
+
rules.push("MINT MODS: When asked to create or change a mod, call mod_help and mod_list first. Use the guide to draft the single-file source directly in mod_validate tool arguments, with at most one short progress sentence. Choose reasonable implementation defaults and proceed to validation. After validation succeeds, call mod_publish in execution mode if available; use expectedHash when replacing source. Creation is complete only after the publication result confirms the path in workspace/.mint-mods/<id>/ and activation state. In plan mode, present the draft/plan for approval. Follow the guide's bounded validation retries and report actual diagnostics if blocked.");
|
|
464
|
+
}
|
|
454
465
|
if plan_mode {
|
|
455
466
|
rules.push(
|
|
456
467
|
"0p. PLAN MODE IS ACTIVE: you may only investigate (read files, search, inspect diagnostics, etc.). Mutating tools such as write_file, apply_patch, and most run_shell/mcp_tool/run_plugin calls are unavailable and will be blocked. Once you have a clear implementation plan, call exit_plan_mode with the full plan; the user will approve or reject it. Do not attempt to edit files or run mutating commands before that approval.",
|
|
@@ -492,6 +503,7 @@ pub fn build_system_prompt(
|
|
|
492
503
|
|| allowed_actions.contains(&"apply_patch")
|
|
493
504
|
{
|
|
494
505
|
rules.push("4. Shell commands and file edits require user approval. Mint handles approval after you request the tool.");
|
|
506
|
+
rules.push("4a. SKILL CHANGES: Create or edit reusable skills only when the user asks for that work. Otherwise complete the current task and suggest the skill in your summary. Use write_file or apply_patch for skill files so Mint can show the concrete diff and request approval for each change. A general file or session permission does not authorize changing persistent skill instructions. After approval, report the saved skill path and what changed.");
|
|
495
507
|
}
|
|
496
508
|
if allowed_actions.contains(&"run_shell") {
|
|
497
509
|
rules.push("5. Shell commands are classified as readOnly, test, network, or mutating. Only policy-allowed modes may run after approval. Never request destructive commands such as rm -rf, git reset --hard, git checkout --, or git clean -f.");
|
|
@@ -521,7 +533,7 @@ pub fn build_system_prompt(
|
|
|
521
533
|
rules.push("7v. A Project Avatar is connected. Call avatar_signal when your reply carries an emotional beat the automatic tool-based reactions can't express — greeting, joking, apologizing, thinking something over. Don't call it for routine tool-driven turns (shell, browser, image/video generation); those already react on their own.");
|
|
522
534
|
}
|
|
523
535
|
if allowed_actions.contains(&"browser_open") {
|
|
524
|
-
rules.push("7a. Use browser_open to
|
|
536
|
+
rules.push("7a. Use browser_open to open websites in the automation browser. Inspect the returned page observation, then use browser_observe/browser_read to read the page or browser_screenshot for visual inspection; verify the requested URL/content with browser_wait before finishing. A successful browser_open already opens the website for the user: do not also launch it through run_shell, xdg-open, open, Start-Process, or another browser. Keep website navigation and interaction in the automation browser. If the user explicitly requests an external browser, use that route instead of first opening the website in automation. If automation is unavailable or blocked, report that and ask the user before switching browsers.");
|
|
525
537
|
}
|
|
526
538
|
if allowed_actions.contains(&"browser_click") {
|
|
527
539
|
rules.push("7b. Use browser_click to click elements. Selector can be: CSS selector (button.class, #id, [attr=val]), text=ExactText to find by visible text, contains=PartialText for partial match, or xpath=//expr for XPath. Prefer text= or contains= when the element has visible text but no unique CSS class.");
|
|
@@ -588,11 +600,14 @@ For every JSON-backed card, ensure all properties stay inside their intended obj
|
|
|
588
600
|
- Feature showcases: use fenced ```ui-card with JSON array:\n```ui-card\n[{\"title\": \"...\", \"subtitle\": \"...\", \"icon\": \"file-text\", \"badge\": \"...\", \"details\": {\"Key\": \"Value\"}}]\n```\n\
|
|
589
601
|
- UI Prototypes: use fenced ```ui-mockup with JSON object:\n```ui-mockup\n{\"title\": \"...\", \"subtitle\": \"...\", \"dropzoneText\": \"...\", \"metrics\": {...}}\n```\n\
|
|
590
602
|
- Key insights / alerts: use GitHub callouts (> [!NOTE], > [!TIP], > [!IMPORTANT], > [!WARNING]). Always converse naturally and smoothly; never prefix conversational phrases or greetings with artificial status tags or badge pills. Always put opening and closing ``` fences on their own separate lines.");
|
|
591
|
-
if
|
|
603
|
+
if allowed_actions.contains(&"browser_open") {
|
|
604
|
+
rules.push("12. Shell commands may open local files/folders or launch apps when requested. For websites, follow rule 7a and verify the automation browser's observed page; a shell launch is not evidence that a browser task is complete.");
|
|
605
|
+
} else if native {
|
|
592
606
|
rules.push("12. Commands that open URLs, files, folders, or launch apps (e.g. xdg-open, open) run in the background. Once they succeed (exit: 0), you are done. Use the finish tool immediately.");
|
|
593
607
|
} else {
|
|
594
608
|
rules.push("12. Commands that open URLs, files, folders, or launch apps (e.g. xdg-open, open) run in the background. Once they succeed (exit: 0), you are done. Use the 'finish' action immediately.");
|
|
595
609
|
}
|
|
610
|
+
rules.push("12a. Development servers and watchers must use run_shell with background: true so the tool returns a job_id immediately. For Python use python3 -u -m http.server <port>. Inspect shell_output and verify an HTTP response before claiming a server is ready; a job_id alone only proves it started. Keep existing background jobs alive when finishing a response or cancelling AI work, unless the user asks to stop them. Use kill_shell to stop only the requested job.");
|
|
596
611
|
let mature_rule = format!("13. {}", persona::MATURE_CONTENT_POLICY);
|
|
597
612
|
rules.push(&mature_rule);
|
|
598
613
|
|
|
@@ -136,6 +136,32 @@ fn finish_tool() -> ToolSpec {
|
|
|
136
136
|
|
|
137
137
|
fn all_tools() -> Vec<ToolSpec> {
|
|
138
138
|
vec![
|
|
139
|
+
tool(
|
|
140
|
+
"mod_help",
|
|
141
|
+
"Read the Mint Mods authoring guide. Call before creating or editing a mod from a user prompt.",
|
|
142
|
+
schema(json!({}), &[]),
|
|
143
|
+
),
|
|
144
|
+
tool(
|
|
145
|
+
"mod_list",
|
|
146
|
+
"Inspect workspace mods, sources, hashes, permissions and active revisions.",
|
|
147
|
+
schema(json!({}), &[]),
|
|
148
|
+
),
|
|
149
|
+
tool(
|
|
150
|
+
"mod_validate",
|
|
151
|
+
"Compile and preview a single-file Mint mod without running real tools. Follow mod_help; fix errors before publishing.",
|
|
152
|
+
schema(
|
|
153
|
+
json!({"arguments":{"type":"object","properties":{"manifest":{"type":"object"},"source":{"type":"string"},"readme":{"type":"string"}},"required":["manifest","source"]}}),
|
|
154
|
+
&["arguments"],
|
|
155
|
+
),
|
|
156
|
+
),
|
|
157
|
+
tool(
|
|
158
|
+
"mod_publish",
|
|
159
|
+
"Publish a validated mod in workspace/.mint-mods/<id> and open it in this chat. Use only when the user requests mod creation/editing. Requested special permissions require approval. Existing source requires expectedHash.",
|
|
160
|
+
schema(
|
|
161
|
+
json!({"arguments":{"type":"object","properties":{"manifest":{"type":"object"},"source":{"type":"string"},"readme":{"type":"string"},"expectedHash":{"type":"string"}},"required":["manifest","source"]}}),
|
|
162
|
+
&["arguments"],
|
|
163
|
+
),
|
|
164
|
+
),
|
|
139
165
|
tool(
|
|
140
166
|
"conversation_summary",
|
|
141
167
|
"Internal tool representing a compacted conversation history summary from previous steps.",
|
|
@@ -655,7 +681,7 @@ fn all_tools() -> Vec<ToolSpec> {
|
|
|
655
681
|
tool(
|
|
656
682
|
"run_shell",
|
|
657
683
|
"Run a local shell command. Subject to safety classification and user approval; destructive commands are blocked outright. \
|
|
658
|
-
Set 'background' to true for a long-running command (a dev server, a watcher, ...) so it doesn't \
|
|
684
|
+
Always set 'background' to true for development servers and watchers. For example: {command: 'python3 -u -m http.server 8000', background: true}. Check output and HTTP readiness before claiming the server is ready. Set 'background' to true for a long-running command (a dev server, a watcher, ...) so it doesn't \
|
|
659
685
|
block you — it returns a job_id immediately instead of waiting for the command to exit. Use the \
|
|
660
686
|
'shell_output' tool to check on it later and 'kill_shell' to stop it.",
|
|
661
687
|
schema(
|
|
@@ -750,7 +776,7 @@ fn all_tools() -> Vec<ToolSpec> {
|
|
|
750
776
|
),
|
|
751
777
|
tool(
|
|
752
778
|
"apply_patch",
|
|
753
|
-
"Apply one or more find-and-replace hunks to an existing file. This is the only way to edit existing files (write_file is for new files only). Keep oldText minimal (1-3 exact lines) per hunk; use separate hunks for separate edit locations.",
|
|
779
|
+
"Apply one or more find-and-replace hunks to an existing file. Pass patch as a JSON object, never a JSON-encoded string: {\"patch\":{\"path\":\"style.css\",\"hunks\":[{\"oldText\":\"exact existing text\",\"newText\":\"replacement text\"}]}}. This is the only way to edit existing files (write_file is for new files only). Keep oldText minimal (1-3 exact lines) per hunk; use separate hunks for separate edit locations.",
|
|
754
780
|
schema(
|
|
755
781
|
json!({
|
|
756
782
|
"patch": {
|