@pheem49/mint 1.14.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 +1258 -35
- package/Cargo.toml +5 -2
- package/LICENSE +21 -654
- package/README.md +93 -756
- package/Release_Note.md +53 -446
- 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 +9 -1
- package/crates/mint-cli/src/agent/approval_prompts.rs +16 -3
- package/crates/mint-cli/src/agent/live_status.rs +545 -148
- package/crates/mint-cli/src/agent/markdown_render.rs +601 -61
- package/crates/mint-cli/src/agent.rs +723 -258
- package/crates/mint-cli/src/commands/agent.rs +83 -74
- package/crates/mint-cli/src/commands/eval.rs +9 -5
- package/crates/mint-cli/src/commands/git.rs +204 -0
- package/crates/mint-cli/src/commands/integrations.rs +35 -0
- package/crates/mint-cli/src/commands/knowledge.rs +13 -32
- package/crates/mint-cli/src/commands/mod.rs +81 -2
- package/crates/mint-cli/src/commands/tailnet_web.rs +235 -0
- package/crates/mint-cli/src/image.rs +32 -11
- package/crates/mint-cli/src/interactive/chat_tui.rs +7853 -0
- package/crates/mint-cli/src/interactive/command_ui.rs +477 -0
- package/crates/mint-cli/src/interactive/format.rs +8 -0
- package/crates/mint-cli/src/interactive/input_box.rs +94 -8
- package/crates/mint-cli/src/interactive/picker.rs +180 -37
- package/crates/mint-cli/src/interactive/resume_picker.rs +686 -0
- package/crates/mint-cli/src/interactive/slash_commands.rs +1071 -501
- package/crates/mint-cli/src/interactive/thought_viewer.rs +286 -0
- package/crates/mint-cli/src/interactive/tool_activity.rs +328 -0
- package/crates/mint-cli/src/interactive.rs +454 -166
- package/crates/mint-cli/src/main.rs +93 -26
- package/crates/mint-cli/src/markdown.rs +12 -5
- 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 +37 -61
- package/crates/mint-cli/src/plugins_cli.rs +8 -5
- package/crates/mint-cli/src/setup.rs +10 -8
- package/crates/mint-cli/src/terminal_theme.rs +189 -0
- package/crates/mint-cli/src/updater.rs +112 -23
- 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/agent_loop.rs +1 -0
- package/crates/mint-core/src/agent/chat.rs +1003 -209
- package/crates/mint-core/src/agent/code_tools.rs +98 -2
- package/crates/mint-core/src/agent/memory/sources.rs +240 -0
- package/crates/mint-core/src/agent/memory.rs +805 -33
- 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 +233 -190
- 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/linked_folders.rs +118 -3
- package/crates/mint-core/src/api_server/routes/media_gen.rs +10 -57
- package/crates/mint-core/src/api_server/routes/misc.rs +114 -121
- 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 +85 -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 +140 -12
- package/crates/mint-core/src/avatar_bridge.rs +13 -2
- package/crates/mint-core/src/browser/cdp.rs +74 -83
- package/crates/mint-core/src/browser/evidence.rs +260 -0
- package/crates/mint-core/src/browser/input.rs +1 -1
- package/crates/mint-core/src/browser/interact.rs +98 -124
- package/crates/mint-core/src/browser/lifecycle.rs +75 -4
- package/crates/mint-core/src/browser/mod.rs +16 -2
- package/crates/mint-core/src/browser/navigate.rs +27 -19
- package/crates/mint-core/src/browser/observe.js +40 -0
- package/crates/mint-core/src/browser/session.rs +1610 -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/git/branches.rs +348 -0
- package/crates/mint-core/src/git/checkpoint.rs +40 -0
- package/crates/mint-core/src/git/diff.rs +206 -0
- package/crates/mint-core/src/git/mod.rs +10 -2
- package/crates/mint-core/src/integrations/channels.rs +88 -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 +107 -40
- package/crates/mint-core/src/live_sync.rs +28 -9
- package/crates/mint-core/src/media/auto_shorts.rs +1 -0
- package/crates/mint-core/src/media/gemini_live.rs +145 -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/mic_transcribe.rs +1 -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/subtitle.rs +1 -0
- 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 +105 -0
- package/crates/mint-core/src/orchestration/mcp_review.rs +153 -0
- package/crates/mint-core/src/orchestration/memory_skill.rs +110 -33
- package/crates/mint-core/src/orchestration/mod.rs +3129 -481
- 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/browser.rs +16 -139
- 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 +5 -3
- 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/tools/web.rs +1 -1
- package/crates/mint-core/src/orchestration/workspace_helpers.rs +4 -1
- package/crates/mint-core/src/prompts/agent.rs +75 -31
- package/crates/mint-core/src/prompts/chat.rs +1 -1
- package/crates/mint-core/src/prompts/persona.rs +1 -1
- package/crates/mint-core/src/prompts/tool_catalog.rs +121 -27
- package/crates/mint-core/src/search/knowledge.rs +7 -1
- package/crates/mint-core/src/search/linked_folders/index.rs +896 -0
- package/crates/mint-core/src/search/linked_folders.rs +473 -131
- package/crates/mint-core/src/slash/catalog.rs +1 -1
- package/crates/mint-core/src/slash/mod.rs +644 -33
- package/crates/mint-core/src/slash/model_fetcher.rs +12 -3
- package/crates/mint-core/src/slash/models.rs +66 -10
- 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 +235 -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 +292 -0
- package/crates/mint-core/src/system/workspace_history.rs +604 -0
- package/crates/mint-core/src/system.rs +5 -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/memory_persistence.rs +39 -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/ImageStudioPanel-D0lnhQV5.css +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-DOj7_WR3.css +1 -0
- package/out/web/assets/VeoStudioPanel-DiJs_Cg2.js +4 -0
- package/out/web/assets/WorkspacePanel-CbJ1PFoZ.js +1 -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-DAOBA7ZG.js → abnfDiagram-VCTEODGH-CD0CjoGl.js} +1 -1
- package/out/web/assets/{architecture-7GRP2DOG-CgSwQOPQ.js → architecture-7GRP2DOG-RKV83OeZ.js} +1 -1
- package/out/web/assets/{architectureDiagram-5GKGNRK7-CYp3yupP.js → architectureDiagram-5GKGNRK7-nN_HAFct.js} +1 -1
- package/out/web/assets/{blockDiagram-NRAW4CY4-CyWybDWr.js → blockDiagram-NRAW4CY4-BrrqzHW5.js} +1 -1
- package/out/web/assets/{c4Diagram-UCG6FXSJ-BvY3U709.js → c4Diagram-UCG6FXSJ-DTdV8_zE.js} +1 -1
- package/out/web/assets/{chunk-75Z2AOVW-TLXCoZYv.js → chunk-75Z2AOVW-_M0z5olV.js} +1 -1
- package/out/web/assets/chunk-CKBBP62Z-BpQEgeHF.js +2 -0
- package/out/web/assets/{chunk-CLGD4ZFX-xjsKtNS7.js → chunk-CLGD4ZFX-D54yGvGS.js} +1 -1
- package/out/web/assets/chunk-DSNCTWBM-C-gvT2ru.js +2 -0
- package/out/web/assets/chunk-DU6HZSFF-CnFngIhW.js +128 -0
- package/out/web/assets/{chunk-F27PBJKO-BFpgF55A.js → chunk-F27PBJKO-BqtWrnEO.js} +1 -1
- package/out/web/assets/{chunk-G27WJ6UU-DfF7qW-C.js → chunk-G27WJ6UU-Ckoq5mi2.js} +1 -1
- package/out/web/assets/{chunk-GMAD6QVW-C-558kh_.js → chunk-GMAD6QVW-BuhEcgHq.js} +1 -1
- package/out/web/assets/{chunk-JQ64N6SF-wJmeGKAw.js → chunk-JQ64N6SF-CF8T7GiZ.js} +1 -1
- package/out/web/assets/{chunk-LCL6LL3I-C1wHD8Ie.js → chunk-LCL6LL3I-BhXV9zyH.js} +1 -1
- package/out/web/assets/{chunk-OBVCFTLP-BsRTPBqs.js → chunk-OBVCFTLP-CRIkunUB.js} +1 -1
- package/out/web/assets/{chunk-P2QGCYS3-HZIiM7Ni.js → chunk-P2QGCYS3-UFEU6BxZ.js} +1 -1
- package/out/web/assets/{chunk-POPQ4Y6H-Dk9wvVb0.js → chunk-POPQ4Y6H-CQcrNbjr.js} +1 -1
- package/out/web/assets/{chunk-PWAF6VOD-BmjYLNbq.js → chunk-PWAF6VOD-Cc2uVDsG.js} +1 -1
- package/out/web/assets/{chunk-R7TYR2AO-CaHIf-lK.js → chunk-R7TYR2AO-DiCxzdAY.js} +1 -1
- package/out/web/assets/{chunk-RHFEMEQ7-_T561hOU.js → chunk-RHFEMEQ7-b7hnPmrR.js} +1 -1
- package/out/web/assets/{chunk-SVP7TREG-CM-GGYoY.js → chunk-SVP7TREG-Bu_yYb-V.js} +1 -1
- package/out/web/assets/{chunk-TEH6E4GO-K2A8Vg2C.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-ClzaB6cc.js → cynefin-OW5HDTMX-CnzQfOGp.js} +1 -1
- package/out/web/assets/{cynefinDiagram-5FMLGOSQ-D_JzZBzf.js → cynefinDiagram-5FMLGOSQ-DVtQnfpm.js} +1 -1
- package/out/web/assets/{dagre-3AP2YEHR-BDuUeMHj.js → dagre-3AP2YEHR-DG76_k5_.js} +1 -1
- package/out/web/assets/{diagram-S7CK7UJ4-DgtcfE8P.js → diagram-S7CK7UJ4-CaouUoze.js} +1 -1
- package/out/web/assets/{diagram-UQ7AKVKN-DTLoEYti.js → diagram-UQ7AKVKN-B4bEc26B.js} +1 -1
- package/out/web/assets/{diagram-VSXAHHWV-ChGl9pXz.js → diagram-VSXAHHWV-BJ86Ov2Y.js} +1 -1
- package/out/web/assets/{diagram-VX7I27RA-Be8DWz0S.js → diagram-VX7I27RA-7hH5IPYf.js} +1 -1
- package/out/web/assets/{diagram-Z3DM3KII-BMXjRTOF.js → diagram-Z3DM3KII-CCM4clo8.js} +1 -1
- package/out/web/assets/dist-js-BkYNznHX.js +1 -0
- package/out/web/assets/{ebnfDiagram-PWID7BFC-8Q9pl1CJ.js → ebnfDiagram-PWID7BFC-Da7WAM3k.js} +1 -1
- package/out/web/assets/{erDiagram-SSCWMZ5O-DjH8Lnkn.js → erDiagram-SSCWMZ5O-CzzmnZWT.js} +1 -1
- package/out/web/assets/event-Cdt7Byyj.js +1 -0
- package/out/web/assets/{eventmodeling-NTZA5JFV-BKUH_DOp.js → eventmodeling-NTZA5JFV-xcfsA0XD.js} +1 -1
- package/out/web/assets/fira-code-latin-600-normal-BmSSHshu.woff +0 -0
- package/out/web/assets/fira-code-latin-600-normal-CvYZpPHg.woff2 +0 -0
- package/out/web/assets/fira-code-symbols2-600-normal-Dvq6IQE5.woff +0 -0
- package/out/web/assets/flowDiagram-A5DVABFB-JdtH1673.js +1 -0
- package/out/web/assets/{ganttDiagram-EL5Y4UJY-D7fZKJNM.js → ganttDiagram-EL5Y4UJY-B3ClFGmL.js} +1 -1
- package/out/web/assets/{gitGraph-4MIJSDKK-BypWaaBU.js → gitGraph-4MIJSDKK-BZ_y_cDU.js} +1 -1
- package/out/web/assets/{gitGraphDiagram-WWUBYQGX-DWiw_3bq.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-KkAUxT4j.js → info-A6RAGUB7-B7I3K0F1.js} +1 -1
- package/out/web/assets/{infoDiagram-RXCK75RN-BNb6E48y.js → infoDiagram-RXCK75RN-deX_1MPh.js} +1 -1
- package/out/web/assets/{ishikawaDiagram-5VMMS53U-Caa-JoAK.js → ishikawaDiagram-5VMMS53U-s38yo28y.js} +1 -1
- package/out/web/assets/{journeyDiagram-EYS64GPL-DOrmFGz6.js → journeyDiagram-EYS64GPL-CZn2kB8b.js} +1 -1
- package/out/web/assets/jsx-runtime-DN4NhQUK.js +1 -0
- package/out/web/assets/{kanban-definition-3QL26DDD-BOWCYcK0.js → kanban-definition-3QL26DDD-DodjgySL.js} +1 -1
- package/out/web/assets/markdown-CMhYIcWB.js +39 -0
- package/out/web/assets/{mermaid-parser.core-BQqjCkS_.js → mermaid-parser.core-Whu2rlJC.js} +3 -3
- package/out/web/assets/mermaid.core-CKyPo8VH.js +11 -0
- package/out/web/assets/{mindmap-definition-FBJOCRG2-jTceWpr0.js → mindmap-definition-FBJOCRG2-260WBDxZ.js} +1 -1
- package/out/web/assets/modelManager-CUaGWMWu.js +2 -0
- package/out/web/assets/oauthManager-DlNhXJr6.js +1 -0
- package/out/web/assets/{packet-AYTQ26CC-CJ5RXgol.js → packet-AYTQ26CC-CEeIRKRG.js} +1 -1
- package/out/web/assets/{pegDiagram-XKGWAZYB-y8wMtd0y.js → pegDiagram-XKGWAZYB-BYadI-KO.js} +1 -1
- package/out/web/assets/{pie-WAS4IAKB-72fTBbl4.js → pie-WAS4IAKB-D8uf4dh5.js} +1 -1
- package/out/web/assets/{pieDiagram-E7YTZNPT-e0O02qWq.js → pieDiagram-E7YTZNPT-CjSDy4hO.js} +1 -1
- package/out/web/assets/{quadrantDiagram-AXDQQJYC-C9phYLom.js → quadrantDiagram-AXDQQJYC-B8D3gU5d.js} +1 -1
- package/out/web/assets/{radar-RG4KPBEZ-BAU2hzUT.js → radar-RG4KPBEZ-DZJxnokY.js} +1 -1
- package/out/web/assets/{railroad-74A4TZTK-B0bCAVHC.js → railroad-74A4TZTK-DBysUiUi.js} +1 -1
- package/out/web/assets/{railroad-abnf-HS5TGJTU-WhxO7ndE.js → railroad-abnf-HS5TGJTU-CHWxoJYg.js} +1 -1
- package/out/web/assets/{railroad-ebnf-LZEXJU2U-BkA0m7-F.js → railroad-ebnf-LZEXJU2U-DDv7X6bY.js} +1 -1
- package/out/web/assets/{railroad-peg-WCYAUIDC-BsVpHIaj.js → railroad-peg-WCYAUIDC-DpfcYYNJ.js} +1 -1
- package/out/web/assets/{railroadDiagram-O6MQD6OU-CyOLN65Q.js → railroadDiagram-O6MQD6OU-CYtyv0t3.js} +1 -1
- package/out/web/assets/{requirementDiagram-EFPCY7ZU-DQXJ7Dud.js → requirementDiagram-EFPCY7ZU-D2X-Ewik.js} +1 -1
- package/out/web/assets/{sankeyDiagram-P5KCCOFB-B2XLyIIc.js → sankeyDiagram-P5KCCOFB-Bn2x6C4Y.js} +1 -1
- package/out/web/assets/{sequenceDiagram-WJ2MYXX4-DGQY4wwm.js → sequenceDiagram-WJ2MYXX4-BvFLKtPd.js} +1 -1
- package/out/web/assets/{stateDiagram-HBIQ2CUA-DHZpDwNy.js → stateDiagram-HBIQ2CUA-Bx0GWeaY.js} +1 -1
- package/out/web/assets/stateDiagram-v2-4QOOHH4V--hol1yg_.js +1 -0
- package/out/web/assets/studio-B1mk40wD.js +1 -0
- package/out/web/assets/{swimlanes-XN3QIQJK-Bn_jcZz-.js → swimlanes-XN3QIQJK-CCma0T7L.js} +1 -1
- package/out/web/assets/swimlanesDiagram-VK2B7HYN-BkohoVsU.js +8 -0
- package/out/web/assets/{timeline-definition-24CTP7MA-CdTERuJZ.js → timeline-definition-24CTP7MA-iCRhhJ7C.js} +1 -1
- package/out/web/assets/{treeView-Q6P3EWNA-TKBKQG6R.js → treeView-Q6P3EWNA-DZ-y08qp.js} +1 -1
- package/out/web/assets/{treemap-WGGIJYW6-BP7gQoiC.js → treemap-WGGIJYW6-De0CxzMx.js} +1 -1
- package/out/web/assets/{vennDiagram-4TSXK5OY-BHUmxDuK.js → vennDiagram-4TSXK5OY-w_7aZ6xe.js} +1 -1
- package/out/web/assets/{wardley-WFR3VGLG-9bct5AAN.js → wardley-WFR3VGLG-DT0y0xJ4.js} +1 -1
- package/out/web/assets/{wardleyDiagram-VM6X3IG4-BfJwDDso.js → wardleyDiagram-VM6X3IG4-DAdXELbQ.js} +1 -1
- package/out/web/assets/window-BJCVtyET.js +1 -0
- package/out/web/assets/{xychartDiagram-S5SC5T6Z-Dqd9Mvpo.js → xychartDiagram-S5SC5T6Z-IZIXf3Vo.js} +1 -1
- package/out/web/index-web.html +4 -4
- package/out/web/index.html +4 -4
- package/package.json +80 -20
- package/shared-modules/.github/workflows/ci.yml +120 -0
- package/shared-modules/.github/workflows/update.yaml +28 -0
- package/slash-commands.json +16 -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-web.html +1 -0
- package/src/renderer/index.html +1 -2
- package/src/renderer/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
- package/src/renderer/shared/agentProgress.ts +201 -3
- package/src/renderer/shared/components/AgentActivityDrawer.tsx +9 -8
- package/src/renderer/shared/components/AgentActivityTable.tsx +193 -133
- 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 +91 -40
- package/src/renderer/shared/components/AuthGate.tsx +79 -48
- package/src/renderer/shared/components/BackgroundTerminals.tsx +181 -0
- package/src/renderer/shared/components/CalculationCard.tsx +41 -15
- 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 +52 -33
- package/src/renderer/shared/components/ChatPanel.test.tsx +21 -0
- package/src/renderer/shared/components/ChatPanel.tsx +676 -415
- package/src/renderer/shared/components/ChunkErrorBoundary.tsx +115 -64
- package/src/renderer/shared/components/CliSessionsView.test.tsx +125 -0
- package/src/renderer/shared/components/CliSessionsView.tsx +543 -0
- package/src/renderer/shared/components/CodeReviewPage.tsx +668 -0
- package/src/renderer/shared/components/CollapsiblePasteInput.tsx +90 -0
- package/src/renderer/shared/components/CommandPalette.tsx +8 -8
- package/src/renderer/shared/components/ContextCompactionStatus.tsx +17 -0
- package/src/renderer/shared/components/DashboardSidebar.tsx +853 -229
- package/src/renderer/shared/components/DesktopTitlebar.tsx +371 -0
- package/src/renderer/shared/components/DiffReviewModal.tsx +3 -3
- 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/GitBranchSelector.tsx +442 -0
- 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/ImageGenCard.tsx +31 -12
- package/src/renderer/shared/components/ImageSearchCard.tsx +76 -65
- package/src/renderer/shared/components/ImageStudioPanel.tsx +49 -49
- package/src/renderer/shared/components/InlineThoughtNote.tsx +27 -0
- 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/LinkedFoldersView.tsx +365 -46
- package/src/renderer/shared/components/McpRegistryPicker.tsx +1 -1
- package/src/renderer/shared/components/McpServersView.tsx +51 -30
- package/src/renderer/shared/components/McpToolAllowlist.tsx +2 -4
- package/src/renderer/shared/components/McpToolResults.tsx +99 -0
- package/src/renderer/shared/components/MermaidCard.tsx +14 -8
- package/src/renderer/shared/components/MintDashboard.tsx +1002 -831
- 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 +547 -219
- package/src/renderer/shared/components/ModsPanel.tsx +156 -0
- package/src/renderer/shared/components/PlanChecklistWidget.tsx +1 -1
- package/src/renderer/shared/components/PluginsView.tsx +1 -1
- 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 +11 -18
- package/src/renderer/shared/components/RunSummaryDashboard.tsx +8 -14
- package/src/renderer/shared/components/ScheduledTasksView.tsx +11 -10
- package/src/renderer/shared/components/ScreenCaptureDialog.css +221 -0
- package/src/renderer/shared/components/ScreenCaptureDialog.tsx +199 -0
- 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 +41 -45
- package/src/renderer/shared/components/Settings/AudioTab.tsx +16 -15
- package/src/renderer/shared/components/Settings/AutomationTab.tsx +10 -60
- package/src/renderer/shared/components/Settings/AvatarCropModal.tsx +368 -0
- package/src/renderer/shared/components/Settings/GeneralTab.tsx +368 -113
- 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/PluginsTab.tsx +20 -12
- package/src/renderer/shared/components/Settings/ProfileTab.tsx +29 -5
- package/src/renderer/shared/components/Settings/SearchableModelCombobox.tsx +411 -0
- package/src/renderer/shared/components/Settings/ThemeTab.tsx +416 -165
- package/src/renderer/shared/components/SkillsView.tsx +41 -16
- 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 +41 -12
- package/src/renderer/shared/components/SourcesBlock.tsx +55 -51
- package/src/renderer/shared/components/StockCard.tsx +58 -24
- package/src/renderer/shared/components/SubagentDagView.tsx +4 -4
- package/src/renderer/shared/components/TerminalDock.tsx +241 -0
- package/src/renderer/shared/components/ThinkingBlock.tsx +14 -8
- package/src/renderer/shared/components/ToolSurfacePage.test.tsx +32 -0
- package/src/renderer/shared/components/ToolSurfacePage.tsx +568 -0
- package/src/renderer/shared/components/ToolsPanelToggle.tsx +13 -0
- package/src/renderer/shared/components/UiFeatureCard.tsx +267 -0
- package/src/renderer/shared/components/UiGridCard.tsx +188 -0
- package/src/renderer/shared/components/UiMockupWidget.tsx +149 -0
- package/src/renderer/shared/components/VeoStudioPanel.tsx +22 -37
- 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/WeatherCard.tsx +3 -3
- package/src/renderer/shared/components/WorkspaceContextPopover.tsx +138 -0
- 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 +154 -0
- 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 +57 -3
- package/src/renderer/shared/constants/models.ts +189 -2
- package/src/renderer/shared/constants/slashCommands.ts +1 -1
- package/src/renderer/shared/conversation/coordinator.test.ts +27 -0
- package/src/renderer/shared/conversation/coordinator.ts +82 -0
- 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 +13 -0
- package/src/renderer/shared/conversation/syncView.ts +6 -0
- 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 +64 -0
- package/src/renderer/shared/css/agent-observability.css +46 -15
- package/src/renderer/shared/css/auth-gate.css +114 -15
- package/src/renderer/shared/css/chat-ui-cards.css +495 -0
- package/src/renderer/shared/css/code-review.css +856 -0
- package/src/renderer/shared/css/code-sessions.css +479 -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/file-changes.css +132 -0
- package/src/renderer/shared/css/image-studio.css +16 -16
- package/src/renderer/shared/css/library.css +476 -0
- package/src/renderer/shared/css/management-views.css +415 -27
- package/src/renderer/shared/css/mcp-results.css +11 -0
- package/src/renderer/shared/css/model-selector.css +543 -85
- 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/agents.css +1 -1
- package/src/renderer/shared/css/settings/automation.css +13 -13
- package/src/renderer/shared/css/settings/general.css +526 -5
- 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/plugins.css +5 -5
- package/src/renderer/shared/css/settings/profile.css +331 -1
- package/src/renderer/shared/css/settings/theme.css +656 -3
- 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/veo-studio.css +16 -15
- package/src/renderer/shared/css/viewed-images.css +15 -0
- package/src/renderer/shared/fonts.css +46 -0
- package/src/renderer/shared/fonts.ts +10 -37
- 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 +90 -0
- package/src/renderer/shared/platform.ts +219 -7
- package/src/renderer/shared/theme/themeManager.test.ts +43 -0
- package/src/renderer/shared/theme/themeManager.ts +157 -0
- package/src/renderer/shared/theme/themes.ts +116 -0
- package/src/renderer/shared/theme/tokens.css +318 -0
- package/src/renderer/shared/types.ts +137 -2
- package/src/renderer/shared/utils/agentActivity.test.ts +75 -0
- package/src/renderer/shared/utils/agentActivity.ts +168 -8
- 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/cardJson.test.ts +35 -0
- package/src/renderer/shared/utils/cardJson.ts +30 -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/fileIcons.ts +1 -1
- package/src/renderer/shared/utils/markdown.tsx +330 -81
- package/src/renderer/shared/utils/markdown.webImages.test.tsx +40 -0
- 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/providers.ts +8 -3
- package/src/renderer/shared/utils/screenCapture.ts +43 -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 +5 -2
- 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/ui.ts +4 -64
- 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 +16 -1
- package/src/renderer/src/components/BrowserShell.tsx +108 -0
- package/src/renderer/src/components/BrowserSuggestionsPopup.tsx +91 -0
- package/src/renderer/src/components/LiveTranslateControls.tsx +65 -0
- package/src/renderer/src/components/MintDashboard.tsx +4 -2
- package/src/renderer/src/components/PicturesLibrary.tsx +2 -287
- package/src/renderer/src/components/ScreenPicker.css +227 -0
- package/src/renderer/src/components/ScreenPicker.tsx +312 -526
- package/src/renderer/src/components/SettingsWindow.tsx +48 -5
- package/src/renderer/src/components/SpotlightWindow.tsx +1 -0
- package/src/renderer/src/components/WidgetWindow.tsx +27 -3
- package/src/renderer/src/components/WorkspacePanel.tsx +269 -61
- package/src/renderer/src/components/browser-shell.css +185 -0
- package/src/renderer/src/components/browser-suggestions-popup.css +55 -0
- package/src/renderer/src/components/liveTranslateFrames.test.ts +44 -0
- package/src/renderer/src/components/liveTranslateFrames.ts +45 -0
- package/src/renderer/src/components/liveTranslateLanguage.ts +6 -0
- package/src/renderer/src/css/app-shell.css +400 -204
- package/src/renderer/src/css/chat.css +1666 -594
- package/src/renderer/src/css/dashboard.css +11 -0
- package/src/renderer/src/css/desktop-tools.css +928 -0
- package/src/renderer/src/css/misc.css +5 -60
- package/src/renderer/src/css/pictures.css +2 -407
- package/src/renderer/src/css/settings/base.css +394 -157
- package/src/renderer/src/css/sidebar-workspace.css +1072 -376
- package/src/renderer/src/css/spotlight.css +15 -26
- package/src/renderer/src/css/tool-surfaces.css +784 -0
- package/src/renderer/src/css/widget.css +36 -8
- package/src/renderer/src/env.d.ts +4 -9
- package/src/renderer/src/hooks/useProviderModels.ts +2 -9
- package/src/renderer/src/index.css +53 -46
- package/src/renderer/src/main.tsx +12 -0
- package/src/renderer/src/proactiveSuggestions.ts +29 -0
- package/src/renderer/src/tauri.ts +302 -339
- package/src/renderer/src/voiceInput.ts +2 -1
- package/src/renderer/src-web/App.tsx +40 -0
- package/src/renderer/src-web/components/MintDashboard.tsx +4 -2
- package/src/renderer/src-web/components/PicturesLibrary.tsx +2 -284
- package/src/renderer/src-web/components/PullToRefresh.tsx +107 -0
- package/src/renderer/src-web/components/SettingsWindow.tsx +36 -5
- package/src/renderer/src-web/css/app-shell.css +188 -207
- package/src/renderer/src-web/css/chat.css +1236 -507
- package/src/renderer/src-web/css/dashboard.css +11 -0
- package/src/renderer/src-web/css/misc.css +3 -55
- package/src/renderer/src-web/css/mobile.css +679 -0
- package/src/renderer/src-web/css/pictures.css +2 -415
- package/src/renderer/src-web/css/pull-to-refresh.css +54 -0
- package/src/renderer/src-web/css/settings/base.css +353 -134
- package/src/renderer/src-web/css/settings/mobile.css +320 -0
- package/src/renderer/src-web/css/sidebar-workspace.css +546 -187
- package/src/renderer/src-web/css/spotlight.css +9 -26
- package/src/renderer/src-web/css/widget.css +1 -6
- package/src/renderer/src-web/env.d.ts +4 -12
- package/src/renderer/src-web/hooks/useProviderModels.ts +2 -9
- package/src/renderer/src-web/index.css +53 -96
- package/src/renderer/src-web/main.tsx +12 -0
- package/src/renderer/src-web/proactiveSuggestions.ts +3 -0
- package/src/renderer/src-web/tauri.ts +309 -364
- 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 +5 -0
- package/.cargo/config.toml +0 -13
- package/.claude/settings.local.json +0 -182
- package/.codex +0 -0
- package/CLAUDE.md +0 -102
- package/out/web/Live2DCubismCore.js +0 -9
- package/out/web/assets/MintDashboard-DWSqucgb.js +0 -57
- package/out/web/assets/SettingsWindow-DFM2aj5B.js +0 -2
- package/out/web/assets/chunk-CKBBP62Z-nr1uKPj9.js +0 -2
- package/out/web/assets/chunk-DSNCTWBM-Dtj8Rqsd.js +0 -2
- package/out/web/assets/chunk-DU6HZSFF-2tv5K1wT.js +0 -128
- package/out/web/assets/classDiagram-DTDB5LWJ-BdSFArgw.js +0 -1
- package/out/web/assets/classDiagram-v2-JRS7N3AN-BdSFArgw.js +0 -1
- package/out/web/assets/core-DImejIUG.js +0 -1
- package/out/web/assets/dist-js-BxuKEVWM.js +0 -1
- package/out/web/assets/event-BNl8Zahw.js +0 -1
- package/out/web/assets/fira-code-cyrillic-400-normal-UC0NFL4U.woff2 +0 -0
- package/out/web/assets/fira-code-cyrillic-400-normal-dc1q3VD7.woff +0 -0
- package/out/web/assets/fira-code-cyrillic-500-normal-Bu7VCL72.woff +0 -0
- package/out/web/assets/fira-code-cyrillic-500-normal-CX35h3Mg.woff2 +0 -0
- package/out/web/assets/fira-code-cyrillic-ext-400-normal-Buh61xzB.woff +0 -0
- package/out/web/assets/fira-code-cyrillic-ext-400-normal-txZ9Fk_1.woff2 +0 -0
- package/out/web/assets/fira-code-cyrillic-ext-500-normal-CYRspHgm.woff2 +0 -0
- package/out/web/assets/fira-code-cyrillic-ext-500-normal-CwtLmSFD.woff +0 -0
- package/out/web/assets/fira-code-greek-400-normal-B2Gh_Y8s.woff2 +0 -0
- package/out/web/assets/fira-code-greek-400-normal-DobhaxvF.woff +0 -0
- package/out/web/assets/fira-code-greek-500-normal-CVO0IRNt.woff2 +0 -0
- package/out/web/assets/fira-code-greek-500-normal-DEXIWiey.woff +0 -0
- package/out/web/assets/fira-code-greek-ext-400-normal-DR7mBgIM.woff2 +0 -0
- package/out/web/assets/fira-code-greek-ext-400-normal-DSPUheWg.woff +0 -0
- package/out/web/assets/fira-code-greek-ext-500-normal-BO3iq16n.woff2 +0 -0
- package/out/web/assets/fira-code-greek-ext-500-normal-CMiNLXER.woff +0 -0
- package/out/web/assets/fira-code-latin-ext-400-normal-DG73JjOf.woff +0 -0
- package/out/web/assets/fira-code-latin-ext-400-normal-KSMg0QLl.woff2 +0 -0
- package/out/web/assets/fira-code-latin-ext-500-normal-CaANqXjI.woff +0 -0
- package/out/web/assets/fira-code-latin-ext-500-normal-Crd9e_oI.woff2 +0 -0
- package/out/web/assets/flowDiagram-A5DVABFB-BpnHUSU7.js +0 -1
- package/out/web/assets/index-CVRg270z.css +0 -1
- package/out/web/assets/index-DxZQr9yD.js +0 -10
- package/out/web/assets/inter-cyrillic-400-normal-HOLc17fK.woff +0 -0
- package/out/web/assets/inter-cyrillic-400-normal-obahsSVq.woff2 +0 -0
- package/out/web/assets/inter-cyrillic-500-normal-BasfLYem.woff2 +0 -0
- package/out/web/assets/inter-cyrillic-500-normal-CxZf_p3X.woff +0 -0
- package/out/web/assets/inter-cyrillic-600-normal-4D_pXhcN.woff +0 -0
- package/out/web/assets/inter-cyrillic-600-normal-CWCymEST.woff2 +0 -0
- package/out/web/assets/inter-cyrillic-ext-400-normal-BQZuk6qB.woff2 +0 -0
- package/out/web/assets/inter-cyrillic-ext-400-normal-DQukG94-.woff +0 -0
- package/out/web/assets/inter-cyrillic-ext-500-normal-B0yAr1jD.woff2 +0 -0
- package/out/web/assets/inter-cyrillic-ext-500-normal-BmqWE9Dz.woff +0 -0
- package/out/web/assets/inter-cyrillic-ext-600-normal-Bcila6Z-.woff +0 -0
- package/out/web/assets/inter-cyrillic-ext-600-normal-Dfes3d0z.woff2 +0 -0
- package/out/web/assets/inter-greek-400-normal-B4URO6DV.woff2 +0 -0
- package/out/web/assets/inter-greek-400-normal-q2sYcFCs.woff +0 -0
- package/out/web/assets/inter-greek-500-normal-BIZE56-Y.woff2 +0 -0
- package/out/web/assets/inter-greek-500-normal-Xzm54t5V.woff +0 -0
- package/out/web/assets/inter-greek-600-normal-BZpKdvQh.woff +0 -0
- package/out/web/assets/inter-greek-600-normal-plRanbMR.woff2 +0 -0
- package/out/web/assets/inter-greek-ext-400-normal-DGGRlc-M.woff2 +0 -0
- package/out/web/assets/inter-greek-ext-400-normal-KugGGMne.woff +0 -0
- package/out/web/assets/inter-greek-ext-500-normal-2j5mBUwD.woff +0 -0
- package/out/web/assets/inter-greek-ext-500-normal-C4iEst2y.woff2 +0 -0
- package/out/web/assets/inter-greek-ext-600-normal-B8X0CLgF.woff +0 -0
- package/out/web/assets/inter-greek-ext-600-normal-DRtmH8MT.woff2 +0 -0
- package/out/web/assets/inter-latin-400-normal-C38fXH4l.woff2 +0 -0
- package/out/web/assets/inter-latin-400-normal-CyCys3Eg.woff +0 -0
- package/out/web/assets/inter-latin-500-normal-BL9OpVg8.woff +0 -0
- package/out/web/assets/inter-latin-500-normal-Cerq10X2.woff2 +0 -0
- package/out/web/assets/inter-latin-600-normal-CiBQ2DWP.woff +0 -0
- package/out/web/assets/inter-latin-600-normal-LgqL8muc.woff2 +0 -0
- package/out/web/assets/inter-latin-ext-400-normal-77YHD8bZ.woff +0 -0
- package/out/web/assets/inter-latin-ext-400-normal-C1nco2VV.woff2 +0 -0
- package/out/web/assets/inter-latin-ext-500-normal-BxGbmqWO.woff +0 -0
- package/out/web/assets/inter-latin-ext-500-normal-CV4jyFjo.woff2 +0 -0
- package/out/web/assets/inter-latin-ext-600-normal-CIVaiw4L.woff +0 -0
- package/out/web/assets/inter-latin-ext-600-normal-D2bJ5OIk.woff2 +0 -0
- package/out/web/assets/inter-vietnamese-400-normal-Bbgyi5SW.woff +0 -0
- package/out/web/assets/inter-vietnamese-400-normal-DMkecbls.woff2 +0 -0
- package/out/web/assets/inter-vietnamese-500-normal-DOriooB6.woff2 +0 -0
- package/out/web/assets/inter-vietnamese-500-normal-mJboJaSs.woff +0 -0
- package/out/web/assets/inter-vietnamese-600-normal-BuLX-rYi.woff +0 -0
- package/out/web/assets/inter-vietnamese-600-normal-Cc8MFFhd.woff2 +0 -0
- package/out/web/assets/kanit-latin-400-normal-BUlsQXH3.woff2 +0 -0
- package/out/web/assets/kanit-latin-400-normal-HVZWrfev.woff +0 -0
- package/out/web/assets/kanit-latin-500-normal-CX_4XcKi.woff2 +0 -0
- package/out/web/assets/kanit-latin-500-normal-qBha86O4.woff +0 -0
- package/out/web/assets/kanit-latin-600-normal-0lS78yAd.woff2 +0 -0
- package/out/web/assets/kanit-latin-600-normal-DlacpeTg.woff +0 -0
- package/out/web/assets/kanit-latin-ext-400-normal-B2xPf58u.woff2 +0 -0
- package/out/web/assets/kanit-latin-ext-400-normal-CHvNKHHD.woff +0 -0
- package/out/web/assets/kanit-latin-ext-500-normal-BFdWrG22.woff +0 -0
- package/out/web/assets/kanit-latin-ext-500-normal-EHs3suD6.woff2 +0 -0
- package/out/web/assets/kanit-latin-ext-600-normal-BBDzoLaj.woff +0 -0
- package/out/web/assets/kanit-latin-ext-600-normal-DAX3wtuq.woff2 +0 -0
- package/out/web/assets/kanit-thai-400-normal-D2nliXKa.woff +0 -0
- package/out/web/assets/kanit-thai-400-normal-D80Pglro.woff2 +0 -0
- package/out/web/assets/kanit-thai-500-normal-BB8gri04.woff2 +0 -0
- package/out/web/assets/kanit-thai-500-normal-Iy_w0a80.woff +0 -0
- package/out/web/assets/kanit-thai-600-normal-Bj6oiaDc.woff2 +0 -0
- package/out/web/assets/kanit-thai-600-normal-wbTlPO7I.woff +0 -0
- package/out/web/assets/kanit-vietnamese-400-normal-DRI8YWyb.woff2 +0 -0
- package/out/web/assets/kanit-vietnamese-400-normal-dow6Bnto.woff +0 -0
- package/out/web/assets/kanit-vietnamese-500-normal-BzTrpCM3.woff2 +0 -0
- package/out/web/assets/kanit-vietnamese-500-normal-T1ndT7MF.woff +0 -0
- package/out/web/assets/kanit-vietnamese-600-normal-Bi7fw3I4.woff2 +0 -0
- package/out/web/assets/kanit-vietnamese-600-normal-DXCRAa_8.woff +0 -0
- package/out/web/assets/mali-latin-400-normal-ByPcZ8Gx.woff +0 -0
- package/out/web/assets/mali-latin-400-normal-Cuc6Ykl8.woff2 +0 -0
- package/out/web/assets/mali-latin-500-normal-B01M-LP6.woff2 +0 -0
- package/out/web/assets/mali-latin-500-normal-Thgqw_9f.woff +0 -0
- package/out/web/assets/mali-latin-600-normal-B9TiUNpT.woff2 +0 -0
- package/out/web/assets/mali-latin-600-normal-CycpQCwU.woff +0 -0
- package/out/web/assets/mali-latin-ext-400-normal-DUVdJQO4.woff +0 -0
- package/out/web/assets/mali-latin-ext-400-normal-iCG1ALuJ.woff2 +0 -0
- package/out/web/assets/mali-latin-ext-500-normal-BfJE4UMZ.woff2 +0 -0
- package/out/web/assets/mali-latin-ext-500-normal-FoLEyOKS.woff +0 -0
- package/out/web/assets/mali-latin-ext-600-normal-BTvIfiCp.woff2 +0 -0
- package/out/web/assets/mali-latin-ext-600-normal-DAQcLVmD.woff +0 -0
- package/out/web/assets/mali-thai-400-normal-BO7A3bLZ.woff2 +0 -0
- package/out/web/assets/mali-thai-400-normal-CX9VrjTn.woff +0 -0
- package/out/web/assets/mali-thai-500-normal-Cph2qha9.woff +0 -0
- package/out/web/assets/mali-thai-500-normal-D89rMT77.woff2 +0 -0
- package/out/web/assets/mali-thai-600-normal-DPgXT6rZ.woff +0 -0
- package/out/web/assets/mali-thai-600-normal-DlTx3OsB.woff2 +0 -0
- package/out/web/assets/mali-vietnamese-400-normal-DUKxzXaz.woff2 +0 -0
- package/out/web/assets/mali-vietnamese-400-normal-gFDLvsOK.woff +0 -0
- package/out/web/assets/mali-vietnamese-500-normal--OY07q2c.woff +0 -0
- package/out/web/assets/mali-vietnamese-500-normal-KDrNRwfW.woff2 +0 -0
- package/out/web/assets/mali-vietnamese-600-normal-CtTMUU7T.woff +0 -0
- package/out/web/assets/mali-vietnamese-600-normal-DFlJr66u.woff2 +0 -0
- package/out/web/assets/mermaid.core-DYGGlqOf.js +0 -11
- package/out/web/assets/mitr-latin-400-normal-Cb18vPmZ.woff +0 -0
- package/out/web/assets/mitr-latin-400-normal-CwbkLQ4a.woff2 +0 -0
- package/out/web/assets/mitr-latin-500-normal-B4JOhzAi.woff +0 -0
- package/out/web/assets/mitr-latin-500-normal-BmClOow2.woff2 +0 -0
- package/out/web/assets/mitr-latin-ext-400-normal-B3CPG7Yo.woff2 +0 -0
- package/out/web/assets/mitr-latin-ext-400-normal-DTx65hiC.woff +0 -0
- package/out/web/assets/mitr-latin-ext-500-normal-B_Diajz1.woff2 +0 -0
- package/out/web/assets/mitr-latin-ext-500-normal-DYOsVaVT.woff +0 -0
- package/out/web/assets/mitr-thai-400-normal-CS4Do6aM.woff +0 -0
- package/out/web/assets/mitr-thai-400-normal-CXWaAdVj.woff2 +0 -0
- package/out/web/assets/mitr-thai-500-normal-CVdBrEVH.woff2 +0 -0
- package/out/web/assets/mitr-thai-500-normal-CW_B5D-i.woff +0 -0
- package/out/web/assets/mitr-vietnamese-400-normal-CPMGWyoC.woff2 +0 -0
- package/out/web/assets/mitr-vietnamese-400-normal-Z6XhIpdY.woff +0 -0
- package/out/web/assets/mitr-vietnamese-500-normal-CDrv0585.woff2 +0 -0
- package/out/web/assets/mitr-vietnamese-500-normal-CMQWyq-Z.woff +0 -0
- package/out/web/assets/noto-sans-thai-latin-400-normal-BaWBrqFP.woff2 +0 -0
- package/out/web/assets/noto-sans-thai-latin-400-normal-Dh_FJjOB.woff +0 -0
- package/out/web/assets/noto-sans-thai-latin-500-normal-BC04jsmm.woff +0 -0
- package/out/web/assets/noto-sans-thai-latin-500-normal-fyBKClF1.woff2 +0 -0
- package/out/web/assets/noto-sans-thai-latin-600-normal-CemcjnVR.woff2 +0 -0
- package/out/web/assets/noto-sans-thai-latin-600-normal-Dbc-dNO6.woff +0 -0
- package/out/web/assets/noto-sans-thai-latin-ext-400-normal-B-1H0YkH.woff +0 -0
- package/out/web/assets/noto-sans-thai-latin-ext-400-normal-nBP59pVw.woff2 +0 -0
- package/out/web/assets/noto-sans-thai-latin-ext-500-normal-B-ZWb8SZ.woff2 +0 -0
- package/out/web/assets/noto-sans-thai-latin-ext-500-normal-CrEHO7C8.woff +0 -0
- package/out/web/assets/noto-sans-thai-latin-ext-600-normal-PkMZo0xa.woff +0 -0
- package/out/web/assets/noto-sans-thai-latin-ext-600-normal-maHHBsez.woff2 +0 -0
- package/out/web/assets/noto-sans-thai-thai-400-normal-BEOmKAI1.woff2 +0 -0
- package/out/web/assets/noto-sans-thai-thai-400-normal-Dxb_unuU.woff +0 -0
- package/out/web/assets/noto-sans-thai-thai-500-normal-BOGXO2tw.woff +0 -0
- package/out/web/assets/noto-sans-thai-thai-500-normal-CU_X86GQ.woff2 +0 -0
- package/out/web/assets/noto-sans-thai-thai-600-normal-CmgB8_JK.woff +0 -0
- package/out/web/assets/noto-sans-thai-thai-600-normal-Cs73sVjl.woff2 +0 -0
- package/out/web/assets/oauthManager-DNiwM8Rn.js +0 -2
- package/out/web/assets/oauthManager-DuamS1Av.css +0 -1
- package/out/web/assets/outfit-latin-300-normal-AWLfuCom.woff +0 -0
- package/out/web/assets/outfit-latin-300-normal-CRYTwY6m.woff2 +0 -0
- package/out/web/assets/outfit-latin-400-normal-BGsTXAXT.woff2 +0 -0
- package/out/web/assets/outfit-latin-400-normal-DMwTpYkH.woff +0 -0
- package/out/web/assets/outfit-latin-500-normal-ClnHRwRh.woff +0 -0
- package/out/web/assets/outfit-latin-500-normal-DKnIMDSk.woff2 +0 -0
- package/out/web/assets/outfit-latin-600-normal-B7SfZ07L.woff2 +0 -0
- package/out/web/assets/outfit-latin-600-normal-BEfTtDA7.woff +0 -0
- package/out/web/assets/outfit-latin-ext-300-normal-BYS6Dpvq.woff2 +0 -0
- package/out/web/assets/outfit-latin-ext-300-normal-CMIMshEd.woff +0 -0
- package/out/web/assets/outfit-latin-ext-400-normal-5tcqmc2S.woff2 +0 -0
- package/out/web/assets/outfit-latin-ext-400-normal-DHm7mdGe.woff +0 -0
- package/out/web/assets/outfit-latin-ext-500-normal-DrCvqoFD.woff +0 -0
- package/out/web/assets/outfit-latin-ext-500-normal-zeox_O30.woff2 +0 -0
- package/out/web/assets/outfit-latin-ext-600-normal-B85nYjL1.woff2 +0 -0
- package/out/web/assets/outfit-latin-ext-600-normal-CWJcPgd7.woff +0 -0
- package/out/web/assets/preload-helper-D0uHx7FM.js +0 -1
- 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-ext-400-normal-1pHbN9uy.woff +0 -0
- package/out/web/assets/prompt-latin-ext-400-normal-DdSafGZ9.woff2 +0 -0
- package/out/web/assets/prompt-latin-ext-500-normal--EZ1um7s.woff2 +0 -0
- package/out/web/assets/prompt-latin-ext-500-normal-D-lI1EVT.woff +0 -0
- package/out/web/assets/prompt-latin-ext-600-normal-C8b50x67.woff +0 -0
- package/out/web/assets/prompt-latin-ext-600-normal-Cg9L7iJU.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-vietnamese-400-normal-BCPzsgPT.woff2 +0 -0
- package/out/web/assets/prompt-vietnamese-400-normal-D4pLyeNK.woff +0 -0
- package/out/web/assets/prompt-vietnamese-500-normal-DmzxmPwa.woff2 +0 -0
- package/out/web/assets/prompt-vietnamese-500-normal-w_sS_j2F.woff +0 -0
- package/out/web/assets/prompt-vietnamese-600-normal-1dyohtNh.woff +0 -0
- package/out/web/assets/prompt-vietnamese-600-normal-7QWjJBsF.woff2 +0 -0
- package/out/web/assets/sarabun-latin-400-normal-DmguIS-7.woff +0 -0
- package/out/web/assets/sarabun-latin-400-normal-URPBxl-K.woff2 +0 -0
- package/out/web/assets/sarabun-latin-500-normal-BjUTcdxu.woff2 +0 -0
- package/out/web/assets/sarabun-latin-500-normal-CJexTAnl.woff +0 -0
- package/out/web/assets/sarabun-latin-600-normal-9FonlkKx.woff +0 -0
- package/out/web/assets/sarabun-latin-600-normal-DMD3TROr.woff2 +0 -0
- package/out/web/assets/sarabun-latin-ext-400-normal-BbP7GpLL.woff2 +0 -0
- package/out/web/assets/sarabun-latin-ext-400-normal-BsmTn0SS.woff +0 -0
- package/out/web/assets/sarabun-latin-ext-500-normal-Cot16Bd2.woff +0 -0
- package/out/web/assets/sarabun-latin-ext-500-normal-DE1LysqI.woff2 +0 -0
- package/out/web/assets/sarabun-latin-ext-600-normal-0tXu9x_i.woff +0 -0
- package/out/web/assets/sarabun-latin-ext-600-normal-BRxjKUQ6.woff2 +0 -0
- package/out/web/assets/sarabun-thai-400-normal-C2DaJlKK.woff2 +0 -0
- package/out/web/assets/sarabun-thai-400-normal-CH-UbWgg.woff +0 -0
- package/out/web/assets/sarabun-thai-500-normal-BVssjame.woff2 +0 -0
- package/out/web/assets/sarabun-thai-500-normal-C3iDLEzi.woff +0 -0
- package/out/web/assets/sarabun-thai-600-normal-3dIAQ-_s.woff2 +0 -0
- package/out/web/assets/sarabun-thai-600-normal-DWKeTe6a.woff +0 -0
- package/out/web/assets/sarabun-vietnamese-400-normal-DPfkSCMy.woff +0 -0
- package/out/web/assets/sarabun-vietnamese-400-normal-igdrzAGY.woff2 +0 -0
- package/out/web/assets/sarabun-vietnamese-500-normal-CpRVvGRU.woff +0 -0
- package/out/web/assets/sarabun-vietnamese-500-normal-Dpe7Br9m.woff2 +0 -0
- package/out/web/assets/sarabun-vietnamese-600-normal-BMbOgAW-.woff +0 -0
- package/out/web/assets/sarabun-vietnamese-600-normal-DkxrOlLB.woff2 +0 -0
- package/out/web/assets/stateDiagram-v2-4QOOHH4V-s6P9g2_b.js +0 -1
- package/out/web/assets/swimlanesDiagram-VK2B7HYN-CV9fOLrV.js +0 -8
- package/out/web/assets/tauri-CNrHQ2Gb.js +0 -3
- package/out/web/assets/window-DkIhgI7B.js +0 -1
- package/skills-lock.json +0 -41
- package/src/renderer/public/Live2DCubismCore.js +0 -9
- package/src/renderer/src/companionWidget.ts +0 -95
- package/src/renderer/src/components/Live2DStage.tsx +0 -389
- package/src/renderer/src/components/ModelPanel.tsx +0 -154
- package/src/renderer/src/css/model.css +0 -627
- 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
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
const __tests = [];
|
|
2
|
+
function __test(name, run, fixtures = {}) {
|
|
3
|
+
if (typeof name !== 'string' || !name || name.length > 120 || typeof run !== 'function' || __tests.length >= 64 || __tests.some(t => t.name === name)) throw Error('Invalid or duplicate test');
|
|
4
|
+
__tests.push({name, run, fixtures: JSON.parse(JSON.stringify(fixtures))});
|
|
5
|
+
}
|
|
6
|
+
function __normal(value) {
|
|
7
|
+
if (value == null) return null;
|
|
8
|
+
if (Array.isArray(value)) return value.map(__normal);
|
|
9
|
+
if (typeof value === 'object') return Object.fromEntries(Object.keys(value).sort().map(k => [k, __normal(value[k])]));
|
|
10
|
+
return value;
|
|
11
|
+
}
|
|
12
|
+
async function __runTest(index) {
|
|
13
|
+
function checkSnapshot() {
|
|
14
|
+
const response=JSON.parse(__host(JSON.stringify({kind:'test_snapshot', value:__view})));
|
|
15
|
+
if (response.error) throw Error(response.error);
|
|
16
|
+
}
|
|
17
|
+
const context = Object.freeze({
|
|
18
|
+
mint,
|
|
19
|
+
async emit(kind, payload = {}) {
|
|
20
|
+
if (!__events.includes(kind)) throw Error('Invalid test event');
|
|
21
|
+
if (['usage_update','context_compacted','turn_end'].includes(kind)) __host(JSON.stringify({kind:'test_usage', value:payload}));
|
|
22
|
+
const result=await __dispatch(kind, payload); checkSnapshot(); return result;
|
|
23
|
+
},
|
|
24
|
+
async command(name, value) { const result=await __dispatch('action', {action:name, value}); checkSnapshot(); return result; },
|
|
25
|
+
ui(slot) { return JSON.parse(JSON.stringify(__view.ui[slot] ?? null)); },
|
|
26
|
+
state(key) { return JSON.parse(JSON.stringify(__view.state[key] ?? null)); },
|
|
27
|
+
equal(actual, expected, message = 'Values differ') {
|
|
28
|
+
if (JSON.stringify(__normal(actual)) !== JSON.stringify(__normal(expected))) throw Error(`${message}: expected ${JSON.stringify(expected)}, received ${JSON.stringify(actual)}`);
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
await __tests[index].run(context);
|
|
32
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
use super::*;
|
|
2
|
+
use std::sync::Mutex;
|
|
3
|
+
|
|
4
|
+
impl Engine {
|
|
5
|
+
fn load_tests(&self, compiled: &str) -> Result<Vec<Value>, String> {
|
|
6
|
+
*self.deadline.lock().unwrap() = cpu_time::ThreadTime::now().as_duration();
|
|
7
|
+
let metadata = self
|
|
8
|
+
.context
|
|
9
|
+
.with(|ctx| -> rquickjs::Result<String> {
|
|
10
|
+
ctx.eval::<(), _>(include_str!("test_sdk.js"))?;
|
|
11
|
+
let module = Module::declare(ctx.clone(), "tests", compiled)?;
|
|
12
|
+
let (module, promise) = module.eval()?;
|
|
13
|
+
promise.finish::<()>()?;
|
|
14
|
+
let register: Function = module.get("registerTests")?;
|
|
15
|
+
let test: Function = ctx.eval("__test")?;
|
|
16
|
+
let returned: rquickjs::Value = register.call((test,))?;
|
|
17
|
+
if let Some(promise) = returned.as_promise() {
|
|
18
|
+
promise.clone().finish::<()>()?;
|
|
19
|
+
}
|
|
20
|
+
ctx.eval("JSON.stringify(__tests.map(t=>({name:t.name,fixtures:t.fixtures})))")
|
|
21
|
+
})
|
|
22
|
+
.map_err(|e| self.error(e))?;
|
|
23
|
+
serde_json::from_str(&metadata).map_err(|e| e.to_string())
|
|
24
|
+
}
|
|
25
|
+
fn run_test(&self, index: usize) -> Result<(), String> {
|
|
26
|
+
*self.deadline.lock().unwrap() = cpu_time::ThreadTime::now().as_duration();
|
|
27
|
+
self.context
|
|
28
|
+
.with(|ctx| -> rquickjs::Result<()> {
|
|
29
|
+
let promise: Promise = ctx.eval(format!("__runTest({index})"))?;
|
|
30
|
+
promise.finish::<()>()
|
|
31
|
+
})
|
|
32
|
+
.map_err(|e| self.error(e))?;
|
|
33
|
+
self.snapshot()?;
|
|
34
|
+
Ok(())
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
pub fn run_tests(manifest: &Value, source: &str, files: &[(&str, &str)]) -> Result<Value, String> {
|
|
38
|
+
if files.is_empty() || files.len() > 32 {
|
|
39
|
+
return Err("Provide 1–32 .test.ts/.test.js files".into());
|
|
40
|
+
}
|
|
41
|
+
let manifest: Manifest = serde_json::from_value(manifest.clone()).map_err(|e| e.to_string())?;
|
|
42
|
+
let compiled = compile(&manifest, source)?;
|
|
43
|
+
let mut results = vec![];
|
|
44
|
+
for (filename, test_source) in files {
|
|
45
|
+
let test_code = compile(&manifest, test_source)?;
|
|
46
|
+
let registry = Engine::new("export function register(){}", &json!({}), |_| {
|
|
47
|
+
json!({"error":"No host access while registering tests"}).to_string()
|
|
48
|
+
})?;
|
|
49
|
+
let tests = registry.load_tests(&test_code)?;
|
|
50
|
+
if tests.is_empty() {
|
|
51
|
+
return Err(format!("No tests registered in {filename}"));
|
|
52
|
+
}
|
|
53
|
+
for (index, test) in tests.iter().enumerate() {
|
|
54
|
+
let fixtures = test["fixtures"].clone();
|
|
55
|
+
let usage = Arc::new(Mutex::new(
|
|
56
|
+
fixtures
|
|
57
|
+
.get("usage")
|
|
58
|
+
.cloned()
|
|
59
|
+
.unwrap_or_else(unavailable_usage),
|
|
60
|
+
));
|
|
61
|
+
let current = usage.clone();
|
|
62
|
+
let permissions = manifest.permissions.clone();
|
|
63
|
+
let result = (|| -> Result<(), String> {
|
|
64
|
+
let engine = Engine::new(
|
|
65
|
+
&compiled,
|
|
66
|
+
&fixtures.get("state").cloned().unwrap_or_else(|| json!({})),
|
|
67
|
+
move |request| {
|
|
68
|
+
let request: Value = serde_json::from_str(&request).unwrap_or_default();
|
|
69
|
+
match request["kind"].as_str() {
|
|
70
|
+
Some("usage")=>json!({"value":current.lock().unwrap().clone()}),
|
|
71
|
+
Some("viewport")=>json!({"value":fixtures.get("viewport").cloned().unwrap_or_else(unavailable_viewport)}),
|
|
72
|
+
Some("test_usage")=>{*current.lock().unwrap()=request["value"].clone();json!({"value":null})},
|
|
73
|
+
Some("test_snapshot")=>match validate_snapshot(&request["value"]){Ok(())=>json!({"value":null}),Err(error)=>json!({"error":error})},
|
|
74
|
+
Some("read") if permissions.iter().any(|p|p=="workspace.read")=>{
|
|
75
|
+
match request["path"].as_str().and_then(|path|fixtures["files"].get(path)).filter(|v|v.is_string()) {
|
|
76
|
+
Some(value)=>json!({"value":value}),None=>json!({"error":"No file fixture for this path"}),
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
_=>json!({"error":"Test host capability unavailable; external tools and I/O are disabled"}),
|
|
80
|
+
}.to_string()
|
|
81
|
+
},
|
|
82
|
+
)?;
|
|
83
|
+
let registered = engine.load_tests(&test_code)?;
|
|
84
|
+
if registered.get(index).and_then(|t| t["name"].as_str()) != test["name"].as_str() {
|
|
85
|
+
return Err("Test registration must be deterministic".into());
|
|
86
|
+
}
|
|
87
|
+
engine.run_test(index)
|
|
88
|
+
})();
|
|
89
|
+
results.push(json!({"file":filename,"name":test["name"],"passed":result.is_ok(),"error":result.err()}));
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
let passed = results.iter().filter(|t| t["passed"] == true).count();
|
|
93
|
+
Ok(json!({"passed":passed,"failed":results.len()-passed,"tests":results}))
|
|
94
|
+
}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
use mint_mod_runtime::{preview, validate_package};
|
|
2
|
+
use serde_json::{Value, json};
|
|
3
|
+
|
|
4
|
+
fn manifest() -> Value {
|
|
5
|
+
json!({"id":"meter","name":"Token meter","version":"1.0.0","sdkVersion":1,"entry":"main.ts","permissions":[]})
|
|
6
|
+
}
|
|
7
|
+
#[test]
|
|
8
|
+
fn session_and_viewport_getters_work_before_the_first_event() {
|
|
9
|
+
let engine=mint_mod_runtime::Engine::new("export function register(mint){const u=mint.session.usage();const v=mint.ui.viewport();mint.ui.set('above_composer',{type:'text',text:u.context.tokens+' / '+v.columns});mint.on('ui_resize',()=>mint.log('resized'));}",&json!({}),|request| {
|
|
10
|
+
let request:Value=serde_json::from_str(&request).unwrap();
|
|
11
|
+
match request["kind"].as_str() { Some("usage")=>json!({"value":{"context":{"tokens":36100}}}).to_string(), Some("viewport")=>json!({"value":{"columns":80}}).to_string(), _=>panic!("Unexpected host request") }
|
|
12
|
+
}).expect("Basic getters require no filesystem/tool capabilities");
|
|
13
|
+
assert_eq!(
|
|
14
|
+
engine.snapshot().unwrap()["ui"]["above_composer"]["text"],
|
|
15
|
+
"36100 / 80"
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
#[test]
|
|
19
|
+
fn preview_can_use_basic_getters_with_explicit_unavailable_values() {
|
|
20
|
+
let value=preview(&manifest(),"export function register(mint){mint.ui.set('above_composer',{type:'text',text:String(mint.session.usage().context.tokens)+' / '+String(mint.ui.viewport().columns)});}").unwrap();
|
|
21
|
+
assert_eq!(value["ui"]["above_composer"]["text"], "null / null");
|
|
22
|
+
}
|
|
23
|
+
#[test]
|
|
24
|
+
fn mod_test_runner_uses_real_events_fixtures_and_isolates_cases() {
|
|
25
|
+
let source = "export function register(mint){mint.state.set('initial',mint.session.usage().context.tokens);mint.on('usage_update',e=>mint.ui.set('above_composer',{type:'text',text:String(e.context.tokens)}));}";
|
|
26
|
+
let test_source = r#"export function registerTests(test){
|
|
27
|
+
test('updates',async({emit,ui,equal,state})=>{equal(state('initial'),36100);await emit('usage_update',{context:{tokens:134400}});equal(ui('above_composer').text,'134400');},{usage:{context:{tokens:36100}}});
|
|
28
|
+
test('isolated',({ui,equal})=>equal(ui('above_composer'),null));
|
|
29
|
+
test('failure',({equal})=>equal(1,2,'intentional failure'));
|
|
30
|
+
}"#;
|
|
31
|
+
let result =
|
|
32
|
+
mint_mod_runtime::run_tests(&manifest(), source, &[("weather.test.ts", test_source)])
|
|
33
|
+
.unwrap();
|
|
34
|
+
assert_eq!(result["passed"], 2);
|
|
35
|
+
assert_eq!(result["failed"], 1);
|
|
36
|
+
assert!(
|
|
37
|
+
result["tests"][2]["error"]
|
|
38
|
+
.as_str()
|
|
39
|
+
.unwrap()
|
|
40
|
+
.contains("intentional failure")
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
#[test]
|
|
44
|
+
fn mod_test_runner_interrupts_a_loop_and_reports_missing_tests() {
|
|
45
|
+
assert!(mint_mod_runtime::run_tests(&manifest(), "export function register(){}", &[]).is_err());
|
|
46
|
+
let result = mint_mod_runtime::run_tests(
|
|
47
|
+
&manifest(),
|
|
48
|
+
"export function register(){}",
|
|
49
|
+
&[(
|
|
50
|
+
"loop.test.ts",
|
|
51
|
+
"export function registerTests(test){test('loop',()=>{while(true){}});}",
|
|
52
|
+
)],
|
|
53
|
+
)
|
|
54
|
+
.unwrap();
|
|
55
|
+
assert_eq!(result["failed"], 1);
|
|
56
|
+
}
|
|
57
|
+
#[test]
|
|
58
|
+
fn mod_test_runner_rejects_invalid_ui_at_each_dispatch() {
|
|
59
|
+
let source = "export function register(mint){mint.on('usage_update',()=>mint.ui.set('above_composer',{type:'html',html:'bad'}));mint.commands.register('repair',()=>mint.ui.set('above_composer',{type:'text',text:'Ready'}));}";
|
|
60
|
+
let result=mint_mod_runtime::run_tests(&manifest(),source,&[("ui.test.ts","export function registerTests(test){test('invalid update',async({emit,command})=>{await emit('usage_update',{});await command('repair');});}")]).unwrap();
|
|
61
|
+
assert_eq!(result["failed"], 1);
|
|
62
|
+
}
|
|
63
|
+
#[test]
|
|
64
|
+
fn mods_can_subscribe_to_context_compaction() {
|
|
65
|
+
assert!(preview(&manifest(), "export function register(mint){mint.on('context_compacted', e => mint.log(e.contextStatus));}").is_ok());
|
|
66
|
+
}
|
|
67
|
+
#[test]
|
|
68
|
+
fn ui_rejects_unbounded_colors_and_invalid_row_directions() {
|
|
69
|
+
assert!(preview(&manifest(), "export function register(mint){mint.ui.set('above_composer',{type:'text',text:'Weather',color:'url(evil)'});}").is_err());
|
|
70
|
+
assert!(preview(&manifest(), "export function register(mint){mint.ui.set('above_composer',{type:'stack',direction:'diagonal',children:[]});}").is_err());
|
|
71
|
+
}
|
|
72
|
+
#[test]
|
|
73
|
+
fn weather_row_accepts_all_five_named_colors() {
|
|
74
|
+
for color in ["yellow", "cyan", "blue", "magenta", "red"] {
|
|
75
|
+
let source = format!(
|
|
76
|
+
"export function register(mint){{mint.ui.set('above_composer',{{type:'stack',direction:'row',children:[{{type:'text',text:'Weather',color:'{color}'}}]}});}}"
|
|
77
|
+
);
|
|
78
|
+
assert!(
|
|
79
|
+
preview(&manifest(), &source).is_ok(),
|
|
80
|
+
"{color} must be supported"
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
#[test]
|
|
86
|
+
fn typescript_mod_registers_and_renders_without_node() {
|
|
87
|
+
let source = r#"export function register(mint: any) {
|
|
88
|
+
mint.ui.set('above_composer', {type:'text', text:'Usage unavailable'});
|
|
89
|
+
mint.on('usage_update', (event: any) => mint.ui.set('above_composer', {type:'text', text:String(event.totalTokens)}));
|
|
90
|
+
}"#;
|
|
91
|
+
let result = preview(&manifest(), source).expect("valid mod loads");
|
|
92
|
+
assert_eq!(result["ui"]["above_composer"]["text"], "Usage unavailable");
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
#[test]
|
|
96
|
+
fn invalid_ids_and_external_imports_are_rejected() {
|
|
97
|
+
let mut m = manifest();
|
|
98
|
+
m["id"] = json!("../outside");
|
|
99
|
+
assert!(validate_package(&m, "export function register(mint) {}").is_err());
|
|
100
|
+
assert!(
|
|
101
|
+
validate_package(
|
|
102
|
+
&manifest(),
|
|
103
|
+
"import fs from 'node:fs'; export function register() {}"
|
|
104
|
+
)
|
|
105
|
+
.is_err()
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
#[test]
|
|
110
|
+
fn infinite_loop_is_interrupted() {
|
|
111
|
+
let start = std::time::Instant::now();
|
|
112
|
+
assert!(
|
|
113
|
+
preview(
|
|
114
|
+
&manifest(),
|
|
115
|
+
"export function register() { while (true) {} }"
|
|
116
|
+
)
|
|
117
|
+
.is_err()
|
|
118
|
+
);
|
|
119
|
+
assert!(start.elapsed() < std::time::Duration::from_secs(3));
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
#[test]
|
|
123
|
+
fn arbitrary_html_is_not_accepted_as_ui() {
|
|
124
|
+
assert!(preview(&manifest(), "export function register(mint) { mint.ui.set('side_panel', {type:'html', html:'<script>bad</script>'}); }").is_err());
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
#[test]
|
|
128
|
+
fn exported_package_round_trips_only_shareable_source() {
|
|
129
|
+
let bytes = mint_mod_runtime::pack(&manifest(), "export function register(mint) {}", "Example")
|
|
130
|
+
.unwrap();
|
|
131
|
+
let package = mint_mod_runtime::unpack(&bytes).unwrap();
|
|
132
|
+
assert_eq!(package["manifest"]["id"], "meter");
|
|
133
|
+
assert_eq!(package["source"], "export function register(mint) {}");
|
|
134
|
+
assert_eq!(package["readme"], "Example");
|
|
135
|
+
assert!(package.get("permissionsGranted").is_none());
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
#[test]
|
|
139
|
+
fn waiting_for_host_io_does_not_spend_callback_cpu_budget() {
|
|
140
|
+
let code = "export function register(mint) { const text=mint.workspace.read('README.md'); for(let i=0;i<100000;i++){} mint.ui.set('side_panel',{type:'text',text}); }";
|
|
141
|
+
let engine = mint_mod_runtime::Engine::new(code, &json!({}), |_| {
|
|
142
|
+
std::thread::sleep(std::time::Duration::from_millis(350));
|
|
143
|
+
json!({"value":"Read complete"}).to_string()
|
|
144
|
+
})
|
|
145
|
+
.expect("Host wait must not be counted as CPU execution");
|
|
146
|
+
assert_eq!(
|
|
147
|
+
engine.snapshot().unwrap()["ui"]["side_panel"]["text"],
|
|
148
|
+
"Read complete"
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
#[test]
|
|
153
|
+
fn async_registration_finishes_before_preview() {
|
|
154
|
+
let value=preview(&manifest(),"export async function register(mint) { await Promise.resolve(); mint.ui.set('side_panel',{type:'text',text:'Ready'}); }").unwrap();
|
|
155
|
+
assert_eq!(value["ui"]["side_panel"]["text"], "Ready");
|
|
156
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Mint mod authoring
|
|
2
|
+
|
|
3
|
+
Load this guide with `mod_help` when the user asks to create or change a Mint mod.
|
|
4
|
+
|
|
5
|
+
Deliver a working mod through the tools. For a self-contained SDK mod, use the reference below, choose reasonable defaults and send the draft source directly in `mod_validate` arguments. A progress note is at most one short sentence; the source belongs in the tool call. Continue to `mod_publish` after successful validation and report its result. Consult additional workspace files only for a concrete dependency or diagnostic.
|
|
6
|
+
|
|
7
|
+
1. Call `mod_list` to inspect existing source, hashes, permissions and active revisions.
|
|
8
|
+
2. Create one module exporting `register(mint)`. Draft the manifest with sdkVersion 1, a lowercase kebab-case id, name, version, entry `main.ts` or `main.js`, and a permissions array.
|
|
9
|
+
3. Call `mod_validate` with arguments `{manifest, source, readme}`. Mint retains the draft outside the workspace; validation errors include its path. Preview has no filesystem or tools. Defer those calls to commands or event handlers. Fix diagnostics, with at most three validation attempts; then report any remaining error.
|
|
10
|
+
4. Call `mod_publish` with the same arguments. For an existing mod also include `expectedHash` from mod_list. Publishing checks for disk changes, creates new IDs in `.mint-mods/<id>/` (existing legacy IDs are edited in `mint-mods/<id>/`), and opens the validated revision in this chat. Basic capabilities need no extra activation decision; requested permissions are reviewed by the user.
|
|
11
|
+
5. If tests are requested, add `tests/*.test.ts` exporting `registerTests(test)` and run `mint mods test <id>` (or `/mods test <id>`). Follow [TESTING.md](TESTING.md). Report the folder, activation state and validation/test results with tool output as evidence.
|
|
12
|
+
|
|
13
|
+
Use these interfaces:
|
|
14
|
+
- `mint.session.usage()` synchronously reads the latest usage snapshot, including before the first event; no special permission or model request.
|
|
15
|
+
- `mint.ui.viewport()` reads the current band dimensions and surface. Subscribe to `ui_resize` to redraw on resizing or panel placement changes. CLI columns are exact; Desktop/Web columns/rows are estimates, with measured widthPx/heightPx. Unknown values are null.
|
|
16
|
+
- `mint.ui.set('above_composer' | 'side_panel', node)`
|
|
17
|
+
- `mint.on(event, handler)` for session_start/end, turn_start/end, pre_tool_use, post_tool_use, usage_update, context_compacted, ui_resize, tool_result.
|
|
18
|
+
- `mint.commands.register(name, handler, description?)`; UI button/input `action` is a registered command name. Input values arrive as handler arguments. Slash commands are `/mods:<id>:<name>`.
|
|
19
|
+
- `mint.state.get(key)` / `mint.state.set(key, JSON value)`: instance state survives restart and stays separate per chat/workspace.
|
|
20
|
+
- `mint.log(message)` for diagnostics.
|
|
21
|
+
- `mint.workspace.read(relativePath)` synchronously reads up to 256 KiB with `workspace.read` permission.
|
|
22
|
+
- `mint.tools.request(action, input)` returns a request ID with `tools.request` permission. Requests run through Mint's tools and approvals; handle their eventual outcome through `tool_result`, matching `requestId`. Pre-tool hooks cannot request tools.
|
|
23
|
+
|
|
24
|
+
UI node types:
|
|
25
|
+
- text/badge: `{type, text}`
|
|
26
|
+
- stack: `{type:'stack', direction?:'row'|'column', children:[nodes]}`
|
|
27
|
+
- button: `{type:'button', label, action}`
|
|
28
|
+
- input: `{type:'input', label, action, value?}`; Enter submits.
|
|
29
|
+
- progress: `{type:'progress', label, value:number, max:number}`
|
|
30
|
+
- table: `{type:'table', columns:string[], rows:(string|number|null)[][]}`
|
|
31
|
+
|
|
32
|
+
All nodes accept `color: 'default' | 'yellow' | 'cyan' | 'blue' | 'magenta' | 'red'`. Colors inherit from stacks; `default` restores normal text. Use a row stack for a one-line band with separately colored labels and plain metrics. Desktop/Web scroll narrow rows horizontally; CLI truncates at terminal width. Arbitrary CSS, HTML and ANSI escapes are not supported.
|
|
33
|
+
|
|
34
|
+
`usage_update`, `context_compacted` and `turn_end` include:
|
|
35
|
+
- `turnId`, `provider`, `model`, `totalTokens` (accumulated API usage this turn, nullable).
|
|
36
|
+
- `contextUsedTokens` (latest provider-reported input + output), `contextInputTokens`, `contextOutputTokens`, `contextPercent` (all nullable).
|
|
37
|
+
- `contextWindowTokens` (nullable), `contextWindowSource: 'mint_config'`. This window comes from Mint's provider defaults/configuration; it is a planning limit, not discovered model capacity. Never hardcode 200k for every provider.
|
|
38
|
+
- `contextStatus: 'measured' | 'unavailable' | 'compacted'`, `compacted` (whether compaction occurred in this turn).
|
|
39
|
+
- `lastTurnDelta` (signed token change from the prior completed turn; null on the first turn, missing usage, provider/model/window changes, and until turn_end).
|
|
40
|
+
|
|
41
|
+
`usage.context` is `{tokens, window, percent, basis:'input', lastTurnDelta}` and measures the input answered over by the latest response. `usage.contextIncludingOutput` has the same shape with `basis:'input_output'`. The original flat `contextUsedTokens`, `contextPercent` and `lastTurnDelta` retain the input + output definition for compatibility. Use `usage.context` consistently for a Claude-style Token Weather forecast, including its delta; check tokens for null. Both readings use Mint's planning window.
|
|
42
|
+
|
|
43
|
+
Context occupancy is a latest-response snapshot; tool results appended afterwards are reflected in the next provider response. Repeated requests resend history: do not sum their token counts to estimate occupancy. Anthropic input includes uncached, cache-read and cache-created tokens. Successful compaction emits `context_compacted` with cleared occupancy; wait for the next measured response rather than retaining the old value. `turn_end` also includes success/cancelled and the final usage snapshot, including when a mod was published after the latest usage_update. Use it to append exactly one history point per turn; keep the last 12 in mint.state for a weather sparkline. Show unavailable text for null measurements/deltas. Reading current usage at registration/session_start initializes a newly created mod without waiting for another turn. UI changes require mint.ui.set; state.set alone does not redraw. Refer to `mint-mods.d.ts` for types.
|
|
44
|
+
|
|
45
|
+
`pre_tool_use` receives action, input, chatId, workspace and callId; return `{block:'reason'}` to reject, or return nothing to allow. Other observers cannot change tool input. `usage_update.totalTokens` is null when unavailable. `turn_start` resets a per-turn token meter. Use explicit unavailable text rather than inventing usage.
|
|
46
|
+
|
|
47
|
+
Hot reload is opt-in for the live session: `/mods hot-reload on|off`, or the Mods panel toggle. Refresh/events check local active source for changes, validate in a candidate worker, keep state and replace only the current chat's instance. A bad candidate reports reloadError and leaves the old worker active. Changes to any mod with privileged old/new revisions require source-hash review and explicit activation. Global personal copies stay independent of local source. Closing/cancelling the session clears the reload opt-in and session revision override; the original activation revision remains the default for reopening. Invalidate old UI action IDs on reload. Publishing through mod_publish already validates and activates edits; it does not require hot reload to be enabled.
|
|
48
|
+
|
|
49
|
+
Modules run in restricted QuickJS with 64 MiB memory and a 250 ms CPU deadline per callback. Use SDK capabilities instead of OS globals. Source is one file; type imports from `@mint/mods` are supported. The built-in `defineMod` is an identity helper; export `register` directly. UI is declarative and renders in React and Ratatui.
|
|
50
|
+
|
|
51
|
+
Example:
|
|
52
|
+
```ts
|
|
53
|
+
export function register(mint: any) {
|
|
54
|
+
mint.ui.set('above_composer', {type:'text', text:'Usage unavailable'});
|
|
55
|
+
mint.on('usage_update', (event: any) => {
|
|
56
|
+
mint.ui.set('above_composer', {
|
|
57
|
+
type:'text', text:event.totalTokens == null ? 'Usage unavailable' : `${event.totalTokens} tokens`
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
```
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# Mint Mods
|
|
2
|
+
|
|
3
|
+
Mint Mods are single-file TypeScript or JavaScript extensions that add panels,
|
|
4
|
+
status bands, commands and tool guards. Desktop/Web use React; the full-screen
|
|
5
|
+
CLI renders the same UI definitions in Ratatui. No Node.js installation is
|
|
6
|
+
required to compile or execute mods.
|
|
7
|
+
|
|
8
|
+
## Create from a prompt
|
|
9
|
+
|
|
10
|
+
Select a workspace, then ask Mint, for example:
|
|
11
|
+
|
|
12
|
+
> Create a mod showing this turn's token usage above the composer.
|
|
13
|
+
|
|
14
|
+
Mint uses `mod_help`, `mod_list`, `mod_validate` and `mod_publish` to prepare and
|
|
15
|
+
preview the source. Basic mods open in the current chat after successful
|
|
16
|
+
validation. Workspace reads and requests to existing tools require a separate
|
|
17
|
+
permission decision. Drafts are retained beside Mint's configuration under
|
|
18
|
+
`mods/workspaces/<workspace-hash>/drafts/`; validation errors include their path.
|
|
19
|
+
A failed draft never replaces the active revision.
|
|
20
|
+
|
|
21
|
+
Source is stored in `<workspace>/.mint-mods/<id>/` with `manifest.json`, `main.ts`
|
|
22
|
+
(or `main.js`) and `README.md`. This repository ignores workspace-local mods;
|
|
23
|
+
put shareable examples in `examples/mods/` or export a `.mintmod` package.
|
|
24
|
+
Other repositories may choose to track `.mint-mods/` to share source with their
|
|
25
|
+
team. Merely cloning a repository or importing a package does not enable its mods.
|
|
26
|
+
|
|
27
|
+
Compiled source, immutable revisions, activation decisions and per-chat state
|
|
28
|
+
are kept beside Mint's configuration under `mods/`, outside the workspace.
|
|
29
|
+
Activation and state use the canonical workspace identity. A global activation
|
|
30
|
+
installs a personal copy; changes in the original workspace do not silently
|
|
31
|
+
update that copy. Source changes keep the old active revision until validated
|
|
32
|
+
and enabled again, or successfully reloaded in an opted-in session. Special permission decisions belong to the exact source and
|
|
33
|
+
manifest hash.
|
|
34
|
+
|
|
35
|
+
## Source directory compatibility
|
|
36
|
+
|
|
37
|
+
New mods and imports for new IDs are created in `<workspace>/.mint-mods/<id>/`.
|
|
38
|
+
Mint also discovers existing `mint-mods/<id>/` folders during the transition.
|
|
39
|
+
Edits, replacement imports, tests and rollback use the selected mod's existing
|
|
40
|
+
folder; Mint does not move it automatically.
|
|
41
|
+
|
|
42
|
+
If both folders contain the same ID, `.mint-mods` takes precedence and the ID
|
|
43
|
+
appears once. An invalid preferred copy reports an error rather than falling
|
|
44
|
+
back to a legacy copy. To move a legacy mod yourself, move its whole folder
|
|
45
|
+
(including tests) into `.mint-mods`, keeping its ID and source unchanged.
|
|
46
|
+
Activation, approvals and saved state remain tied to the workspace, chat and
|
|
47
|
+
content revision. A changed revision still follows the usual review rules.
|
|
48
|
+
|
|
49
|
+
## Manage
|
|
50
|
+
|
|
51
|
+
Type `/mods` in interactive chat to open the mod manager on Full-Screen TUI,
|
|
52
|
+
Desktop and Web. It shows total and active mod counts. Select a mod with the
|
|
53
|
+
arrow keys and Enter in the TUI, or select the displayed choices on Desktop/Web,
|
|
54
|
+
then choose **Enable for this chat** or **Disable for this chat**. Mods with
|
|
55
|
+
permissions require a separate approval before enabling. After a successful
|
|
56
|
+
change, the menu closes, focus returns to the composer, and chat displays
|
|
57
|
+
`[Mods] Enabled/Disabled <id> for this chat.` Reopen `/mods` to see updated counts,
|
|
58
|
+
or use `/mods list` for a text listing.
|
|
59
|
+
|
|
60
|
+
Use **Mods** above the composer on Desktop/Web to inspect source, diagnostics,
|
|
61
|
+
permissions and revisions; enable for the current chat, workspace or globally;
|
|
62
|
+
export/import `.mintmod` packages; or restore a source revision.
|
|
63
|
+
|
|
64
|
+
```sh
|
|
65
|
+
mint mods list
|
|
66
|
+
mint mods source token-meter
|
|
67
|
+
mint mods validate token-meter
|
|
68
|
+
mint mods test task-checklist
|
|
69
|
+
mint mods --chat <chat-id> usage
|
|
70
|
+
mint mods enable token-meter
|
|
71
|
+
mint mods enable task-checklist workspace
|
|
72
|
+
mint mods enable custom-reader chat --grant-permissions
|
|
73
|
+
mint mods disable token-meter
|
|
74
|
+
mint mods logs token-meter
|
|
75
|
+
mint mods revisions token-meter
|
|
76
|
+
mint mods rollback token-meter <revision-hash>
|
|
77
|
+
mint mods export token-meter token-meter.mintmod
|
|
78
|
+
mint mods import token-meter.mintmod
|
|
79
|
+
mint mods import token-meter.mintmod --replace
|
|
80
|
+
mint mods --chat <chat-id> list
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
In interactive chat use `/mods hot-reload on|off` to watch active basic mods for this session; Desktop/Web offer a Hot reload toggle. Invalid changes keep the working revision and report reload diagnostics. Privileged changes still require review. Closing the session clears the opt-in and temporary revision override.
|
|
84
|
+
|
|
85
|
+
Use `mint mods test <id>` or `/mods test <id>` for runtime tests; Desktop/Web have Run tests with per-case results. Tests never activate mods or perform real filesystem/tool operations. See [TESTING.md](TESTING.md).
|
|
86
|
+
|
|
87
|
+
In interactive chat use `/mods export <id> [file]`,
|
|
88
|
+
`/mods import <file> [--replace]`, and `/mods:<id>:<command> [value]`.
|
|
89
|
+
Quote paths containing spaces. F7 opens the
|
|
90
|
+
terminal panels; Tab/Shift+Tab select a control, Enter activates it, and Escape
|
|
91
|
+
returns to chat. Input controls accept text before Enter. In a narrow terminal
|
|
92
|
+
the panel overlays the transcript while retaining the composer. `/mods run-tools`
|
|
93
|
+
reviews queued tool requests; the standalone equivalent is `mint mods run-tools`.
|
|
94
|
+
|
|
95
|
+
Restore changes source; review and enable the restored revision separately.
|
|
96
|
+
Permission approval is never included in exported packages.
|
|
97
|
+
|
|
98
|
+
## Examples and SDK
|
|
99
|
+
|
|
100
|
+
Copy a folder from `examples/mods/` into your workspace's `.mint-mods/` directory:
|
|
101
|
+
|
|
102
|
+
- `token-meter`: displays actual usage, with explicit unavailable state.
|
|
103
|
+
- `task-checklist`: input, button and table backed by per-chat state.
|
|
104
|
+
- `tool-guard`: blocks recursive `rm` commands as an example guard; it is not a
|
|
105
|
+
comprehensive shell security policy.
|
|
106
|
+
|
|
107
|
+
Read [AUTHORING.md](AUTHORING.md) for the entrypoint, events and workflow, and
|
|
108
|
+
[mint-mods.d.ts](mint-mods.d.ts) for the TypeScript interface.
|
|
109
|
+
|
|
110
|
+
## Runtime and limits
|
|
111
|
+
|
|
112
|
+
Each instance runs in its own process with a restricted QuickJS runtime. The
|
|
113
|
+
SDK grants access through Mint; it does not provide Node.js, direct shell,
|
|
114
|
+
filesystem, network or browser DOM access. The host checks capabilities even
|
|
115
|
+
when a mod bypasses its JavaScript SDK wrappers. This is process separation and
|
|
116
|
+
capability restriction, not an OS sandbox for native-runtime vulnerabilities.
|
|
117
|
+
|
|
118
|
+
The runtime caps memory at 64 MiB and callback execution at 250 ms, with a
|
|
119
|
+
three-second IPC deadline. UI trees are limited to 256 nodes, 12 nesting levels
|
|
120
|
+
and 64 KiB. State/output is limited to 256 KiB; source to 512 KiB. Packages are
|
|
121
|
+
limited to 1 MiB and contain only manifest, entry and optional README. External
|
|
122
|
+
imports, additional package entries and symlinked sources are rejected.
|
|
123
|
+
|
|
124
|
+
Tool requests pass through Mint's existing tools, permissions, disabled-tool
|
|
125
|
+
checks and plan-mode restrictions. A mod never grants itself permissions.
|
|
126
|
+
Pre-tool hooks may observe or block; they cannot request tools or rewrite tool
|
|
127
|
+
inputs. A failed pre-tool hook blocks subsequent calls until the mod is fixed
|
|
128
|
+
or disabled. Other observer errors stop the affected instance.
|
|
129
|
+
|
|
130
|
+
## Packaging
|
|
131
|
+
|
|
132
|
+
The CLI package builds `mint` and `mint-mod-host`. The desktop executable also
|
|
133
|
+
contains an internal host entrypoint, so bundled Desktop installations can
|
|
134
|
+
start isolated workers without an external Node executable or sidecar path.
|
|
135
|
+
The Web server uses the same host launcher on the server machine.
|
|
136
|
+
|
|
137
|
+
Context indicators can read `mint.session.usage()` immediately and consume `usage_update`, `context_compacted`, and `turn_end` with nullable latest context tokens, Mint's planning window, percentage and signed completed-turn delta. UI nodes support five named colors and row stacks in CLI, Desktop and Web. See [authoring contract](AUTHORING.md) and [SDK types](mint-mods.d.ts). Anthropic normalization follows [the provider's prompt-cache usage fields](https://platform.claude.com/docs/en/build-with-claude/prompt-caching).
|
|
138
|
+
|
|
139
|
+
For Claude-style context readings, use `usage.context` (latest input). `usage.contextIncludingOutput` and the existing flat fields include output as well. `mint.ui.viewport()` and `ui_resize` support responsive bands; graphical text dimensions are estimates while pixel dimensions are measured.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Testing Mint mods
|
|
2
|
+
|
|
3
|
+
Keep tests beside the mod in `.mint-mods/<id>/tests/*.test.ts` or `*.test.js`.
|
|
4
|
+
Existing mods in `mint-mods/<id>/` use the same `tests/` layout.
|
|
5
|
+
Export `registerTests(test)`; each named case runs in a fresh QuickJS instance
|
|
6
|
+
using the actual mod source and SDK. Tests never enable a mod or change its
|
|
7
|
+
saved state. Type imports from `@mint/mods` work as in main.ts.
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import type { TestRegistrar } from '@mint/mods'
|
|
11
|
+
|
|
12
|
+
export function registerTests(test: TestRegistrar) {
|
|
13
|
+
test('adds an item', async ({ command, state, equal }) => {
|
|
14
|
+
await command('add', 'Review changes')
|
|
15
|
+
equal(state('task'), 'Review changes')
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
test('usage updates the band', async ({ emit, ui, equal }) => {
|
|
19
|
+
await emit('usage_update', {
|
|
20
|
+
context: { tokens: 134400, window: 200000, percent: 67.2,
|
|
21
|
+
basis: 'input', lastTurnDelta: null },
|
|
22
|
+
})
|
|
23
|
+
equal(ui('above_composer')?.type, 'stack')
|
|
24
|
+
}, {
|
|
25
|
+
usage: { context: { tokens: 36100, window: 200000, percent: 18.05,
|
|
26
|
+
basis: 'input', lastTurnDelta: null } },
|
|
27
|
+
viewport: { surface: 'terminal', columns: 120, rows: 35 },
|
|
28
|
+
})
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Choose assertions that match your mod; the examples assume commands/state/UI
|
|
33
|
+
that the author implements. `emit` dispatches a supported lifecycle event and
|
|
34
|
+
returns its result (including pre-tool block decisions). For usage_update,
|
|
35
|
+
context_compacted and turn_end it first updates what session.usage returns.
|
|
36
|
+
`command` invokes a registered mod command. `ui(slot)` and `state(key)` return
|
|
37
|
+
copies, or null when absent. `equal` checks deep JSON equality and accepts an
|
|
38
|
+
optional failure message.
|
|
39
|
+
|
|
40
|
+
The third test argument supplies initial `usage`, `viewport`, `state` and
|
|
41
|
+
`files` fixtures. File fixtures map relative paths to text and require the
|
|
42
|
+
manifest's workspace.read permission. There is no access to real files,
|
|
43
|
+
network, model calls or tools; simulate tool_result events when needed.
|
|
44
|
+
Include all usage fields your mod reads. Defaults explicitly mark usage and
|
|
45
|
+
viewport as unavailable.
|
|
46
|
+
|
|
47
|
+
Run `mint mods test <id>`, `/mods test <id>`, or Run tests in the Desktop/Web
|
|
48
|
+
Mods panel. CLI returns a nonzero exit status if any case fails. Results name
|
|
49
|
+
each case and file and report assertion/runtime errors. Compilation or missing
|
|
50
|
+
tests are errors rather than successful empty runs. Tests use current workspace
|
|
51
|
+
source, independently of its active revision. Keep tests in the repository;
|
|
52
|
+
the compact .mintmod export format contains only the entry, manifest and README.
|
|
53
|
+
|
|
54
|
+
Limits: 32 test files, 64 uniquely named cases per file, 512 KiB per source,
|
|
55
|
+
64 MiB memory per instance and 250 ms CPU per registration/case. Host fixtures
|
|
56
|
+
perform no external I/O. Infinite loops and invalid UI fail the case.
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
declare module '@mint/mods' {
|
|
2
|
+
export type Slot = 'above_composer' | 'side_panel'
|
|
3
|
+
export type Color = 'default' | 'yellow' | 'cyan' | 'blue' | 'magenta' | 'red'
|
|
4
|
+
export type Node = { type: 'text' | 'stack' | 'badge' | 'button' | 'input' | 'progress' | 'table'; color?: Color; direction?: 'row' | 'column'; text?: string; label?: string; action?: string; value?: string | number; max?: number; columns?: string[]; rows?: (string | number | null)[][]; children?: Node[] }
|
|
5
|
+
export type Event = 'session_start' | 'session_end' | 'turn_start' | 'turn_end' | 'pre_tool_use' | 'post_tool_use' | 'usage_update' | 'context_compacted' | 'ui_resize' | 'tool_result'
|
|
6
|
+
export interface Viewport {
|
|
7
|
+
surface: 'terminal' | 'desktop' | 'web' | null
|
|
8
|
+
/** Exact text columns in CLI; estimated from pixels on graphical surfaces. */
|
|
9
|
+
columns: number | null
|
|
10
|
+
rows: number | null
|
|
11
|
+
widthPx: number | null
|
|
12
|
+
heightPx: number | null
|
|
13
|
+
sidePanelOpen: boolean
|
|
14
|
+
}
|
|
15
|
+
export interface ContextReading {
|
|
16
|
+
tokens: number | null
|
|
17
|
+
window: number | null
|
|
18
|
+
percent: number | null
|
|
19
|
+
basis: 'input' | 'input_output'
|
|
20
|
+
lastTurnDelta: number | null
|
|
21
|
+
}
|
|
22
|
+
export interface UsageEvent {
|
|
23
|
+
turnId: number
|
|
24
|
+
/** Accumulated API usage for this turn, not context occupancy. */
|
|
25
|
+
totalTokens: number | null
|
|
26
|
+
/** Latest provider-reported input + output; null after compaction or missing usage. */
|
|
27
|
+
contextUsedTokens: number | null
|
|
28
|
+
contextInputTokens: number | null
|
|
29
|
+
contextOutputTokens: number | null
|
|
30
|
+
/** Mint's configured/conservative planning window, not a provider capacity discovery. */
|
|
31
|
+
contextWindowTokens: number | null
|
|
32
|
+
contextWindowSource: 'mint_config'
|
|
33
|
+
contextPercent: number | null
|
|
34
|
+
contextStatus: 'measured' | 'unavailable' | 'compacted'
|
|
35
|
+
provider: string
|
|
36
|
+
model: string
|
|
37
|
+
/** Signed difference from previous completed turn; provided only on turn_end. */
|
|
38
|
+
lastTurnDelta: number | null
|
|
39
|
+
compacted: boolean
|
|
40
|
+
/** Last response's input context, matching the Claude-style reading. */
|
|
41
|
+
context: ContextReading & { basis: 'input' }
|
|
42
|
+
contextIncludingOutput: ContextReading & { basis: 'input_output' }
|
|
43
|
+
}
|
|
44
|
+
export type EventPayload<E extends Event> = E extends 'turn_end'
|
|
45
|
+
? UsageEvent & { success: boolean; cancelled: boolean }
|
|
46
|
+
: E extends 'usage_update' | 'context_compacted' ? UsageEvent : E extends 'ui_resize' ? Viewport : any
|
|
47
|
+
export interface Mint {
|
|
48
|
+
session: { usage(): UsageEvent }
|
|
49
|
+
on<E extends Event>(event: E, handler: (event: EventPayload<E>) => void | { block: string } | Promise<void | { block: string }>): void
|
|
50
|
+
ui: { set(slot: Slot, tree: Node): void; viewport(): Viewport }
|
|
51
|
+
commands: { register(name: string, handler: (value?: string) => unknown, description?: string): void }
|
|
52
|
+
state: { get(key: string): any; set(key: string, value: unknown): void }
|
|
53
|
+
workspace: { read(path: string): string }
|
|
54
|
+
tools: { request(action: string, input?: Record<string, unknown>): string }
|
|
55
|
+
log(message: unknown): void
|
|
56
|
+
}
|
|
57
|
+
export interface TestContext {
|
|
58
|
+
mint: Mint
|
|
59
|
+
emit<E extends Event>(event: E, payload?: Partial<EventPayload<E>>): Promise<any>
|
|
60
|
+
command(name: string, value?: unknown): Promise<any>
|
|
61
|
+
ui(slot: Slot): Node | null
|
|
62
|
+
state(key: string): any
|
|
63
|
+
equal(actual: unknown, expected: unknown, message?: string): void
|
|
64
|
+
}
|
|
65
|
+
export type TestRegistrar = (name: string, run: (context: TestContext) => void | Promise<void>, fixtures?: { usage?: Partial<UsageEvent>; viewport?: Partial<Viewport>; files?: Record<string, string>; state?: Record<string, unknown> }) => void
|
|
66
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Mint Device MCP example
|
|
2
|
+
|
|
3
|
+
This stdio MCP server simulates one motor and camera. It requires Node.js 18+ and has no npm dependencies. It never accesses real hardware. `mock-device.mjs` is the adapter seam; `server.mjs` owns MCP framing, tool descriptions, schemas, and results.
|
|
4
|
+
|
|
5
|
+
From the repository root, register its absolute path (replace `/path/to/Mint-CLI`):
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
mint mcp add mock-device node --args /path/to/Mint-CLI/examples/device-mcp/server.mjs
|
|
9
|
+
mint mcp allow mock-device '*'
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
In agent chat, ask: “Set mock-device to 100 RPM and confirm its observed speed”, “Stop mock-device and confirm zero RPM”, or “Capture a photo from mock-device”. The photo is a generated PNG sample. The allow command grants all tools on this example server; omit it to approve calls individually.
|
|
13
|
+
|
|
14
|
+
For the raw CLI, use:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
mint mcp call mock-device set_speed --arguments '{"deviceId":"mock-device","rpm":100}'
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
The raw call returns the MCP receipt after schema validation. Automatic waiting and `DeviceState` events apply to agent chat. Read `get_status` with the receipt's `operationId` when using raw calls; repeated separate CLI processes start fresh mock servers and cannot preserve the simulated operation. An agent chat keeps the MCP session alive.
|
|
21
|
+
|
|
22
|
+
Run the example's protocol tests with `npm run test:device`. See [the Device v1 contract](contract.md) before replacing the mock adapter.
|