@pheem49/mint 1.15.0 → 1.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Cargo.lock +1012 -69
- package/Cargo.toml +5 -2
- package/LICENSE +21 -654
- package/README.md +92 -817
- package/Release_Note.md +53 -560
- package/apps/mint-companion/src-tauri/Cargo.toml +20 -0
- package/apps/mint-companion/src-tauri/build.rs +3 -0
- package/apps/mint-companion/src-tauri/src/main.rs +468 -0
- package/apps/mint-companion/tsconfig.json +20 -0
- package/apps/mint-companion/vite.config.ts +3 -0
- package/components.json +19 -0
- package/crates/mint-cli/Cargo.toml +6 -0
- package/crates/mint-cli/src/agent/live_status.rs +187 -39
- package/crates/mint-cli/src/agent.rs +323 -95
- package/crates/mint-cli/src/commands/agent.rs +69 -55
- package/crates/mint-cli/src/commands/integrations.rs +7 -0
- package/crates/mint-cli/src/commands/knowledge.rs +12 -32
- package/crates/mint-cli/src/commands/mod.rs +44 -0
- package/crates/mint-cli/src/image.rs +31 -33
- package/crates/mint-cli/src/interactive/chat_tui.rs +3594 -483
- package/crates/mint-cli/src/interactive/input_box.rs +56 -6
- package/crates/mint-cli/src/interactive/slash_commands.rs +208 -56
- package/crates/mint-cli/src/interactive/tool_activity.rs +328 -0
- package/crates/mint-cli/src/interactive.rs +64 -40
- package/crates/mint-cli/src/main.rs +13 -7
- package/crates/mint-cli/src/mcp.rs +5 -0
- package/crates/mint-cli/src/mod_host.rs +6 -0
- package/crates/mint-cli/src/mods_cli.rs +62 -0
- package/crates/mint-cli/src/mods_ui.rs +187 -0
- package/crates/mint-cli/src/onboard.rs +5 -31
- package/crates/mint-cli/src/terminal_theme.rs +3 -1
- package/crates/mint-cli/src/updater.rs +56 -2
- package/crates/mint-cli/tests/library_intake.rs +77 -0
- package/crates/mint-cli/tests/mods_testing.rs +133 -0
- package/crates/mint-companion-protocol/Cargo.toml +10 -0
- package/crates/mint-companion-protocol/src/lib.rs +163 -0
- package/crates/mint-core/Cargo.toml +6 -3
- package/crates/mint-core/build.rs +26 -0
- package/crates/mint-core/src/agent/chat.rs +167 -39
- package/crates/mint-core/src/agent/code_tools.rs +15 -0
- package/crates/mint-core/src/agent/memory/sources.rs +240 -0
- package/crates/mint-core/src/agent/memory.rs +147 -13
- package/crates/mint-core/src/agent/skill_inventory.rs +325 -0
- package/crates/mint-core/src/agent/skills.rs +437 -90
- package/crates/mint-core/src/agent.rs +1 -0
- package/crates/mint-core/src/api_server/routes/background_jobs.rs +310 -0
- package/crates/mint-core/src/api_server/routes/chat.rs +216 -199
- package/crates/mint-core/src/api_server/routes/html_preview.rs +77 -0
- package/crates/mint-core/src/api_server/routes/library.rs +97 -0
- package/crates/mint-core/src/api_server/routes/media_gen.rs +10 -57
- package/crates/mint-core/src/api_server/routes/misc.rs +104 -107
- package/crates/mint-core/src/api_server/routes/mod.rs +6 -0
- package/crates/mint-core/src/api_server/routes/mods.rs +31 -0
- package/crates/mint-core/src/api_server/routes/sessions.rs +41 -0
- package/crates/mint-core/src/api_server/routes/skills_subagents.rs +12 -42
- package/crates/mint-core/src/api_server/routes/slash.rs +50 -1
- package/crates/mint-core/src/api_server/routes/sources.rs +101 -0
- package/crates/mint-core/src/api_server.rs +118 -9
- package/crates/mint-core/src/avatar_bridge.rs +11 -2
- package/crates/mint-core/src/browser/session.rs +52 -0
- package/crates/mint-core/src/companion.rs +716 -0
- package/crates/mint-core/src/cron/scheduler.rs +34 -2
- package/crates/mint-core/src/integrations/channels.rs +87 -345
- package/crates/mint-core/src/integrations/mcp.rs +397 -50
- package/crates/mint-core/src/integrations/mcp_calls.rs +823 -0
- package/crates/mint-core/src/integrations/mcp_catalog.rs +267 -0
- package/crates/mint-core/src/integrations/mcp_device.rs +319 -0
- package/crates/mint-core/src/integrations/mcp_result.rs +356 -0
- package/crates/mint-core/src/integrations/webhooks.rs +539 -0
- package/crates/mint-core/src/integrations.rs +2 -0
- package/crates/mint-core/src/lib.rs +85 -26
- package/crates/mint-core/src/media/gemini_live.rs +134 -14
- package/crates/mint-core/src/media/image_models.rs +3 -27
- package/crates/mint-core/src/media/image_workflow.rs +216 -0
- package/crates/mint-core/src/media/library/intake.rs +144 -0
- package/crates/mint-core/src/media/library/migration.rs +56 -0
- package/crates/mint-core/src/media/library/removal.rs +55 -0
- package/crates/mint-core/src/media/library/tests.rs +730 -0
- package/crates/mint-core/src/media/library/thumbnails.rs +72 -0
- package/crates/mint-core/src/media/library.rs +545 -0
- package/crates/mint-core/src/media/model_catalog.rs +375 -0
- package/crates/mint-core/src/media/pictures.rs +79 -222
- package/crates/mint-core/src/media/video_models.rs +3 -22
- package/crates/mint-core/src/media.rs +3 -0
- package/crates/mint-core/src/mods/manager.rs +1124 -0
- package/crates/mint-core/src/mods/mod.rs +569 -0
- package/crates/mint-core/src/mods/operations.rs +204 -0
- package/crates/mint-core/src/mods/session.rs +146 -0
- package/crates/mint-core/src/mods/slash.rs +59 -0
- package/crates/mint-core/src/mods/telemetry.rs +306 -0
- package/crates/mint-core/src/orchestration/approvals.rs +344 -0
- package/crates/mint-core/src/orchestration/context_render.rs +104 -0
- package/crates/mint-core/src/orchestration/mcp_review.rs +153 -0
- package/crates/mint-core/src/orchestration/memory_skill.rs +104 -32
- package/crates/mint-core/src/orchestration/mod.rs +2139 -244
- package/crates/mint-core/src/orchestration/mod_authoring_regressions.rs +209 -0
- package/crates/mint-core/src/orchestration/progress_clock.rs +80 -0
- package/crates/mint-core/src/orchestration/repeated_failures.rs +116 -0
- package/crates/mint-core/src/orchestration/review_regressions.rs +449 -0
- package/crates/mint-core/src/orchestration/run_control.rs +196 -0
- package/crates/mint-core/src/orchestration/tools/files.rs +161 -14
- package/crates/mint-core/src/orchestration/tools/media.rs +37 -41
- package/crates/mint-core/src/orchestration/tools/misc.rs +3 -2
- package/crates/mint-core/src/orchestration/tools/mod.rs +2 -0
- package/crates/mint-core/src/orchestration/tools/mods.rs +161 -0
- package/crates/mint-core/src/orchestration/tools/plugins_mcp.rs +303 -71
- package/crates/mint-core/src/orchestration/tools/shell.rs +95 -2
- package/crates/mint-core/src/orchestration/workspace_helpers.rs +4 -1
- package/crates/mint-core/src/prompts/agent.rs +17 -2
- package/crates/mint-core/src/prompts/tool_catalog.rs +28 -2
- package/crates/mint-core/src/search/knowledge.rs +7 -1
- package/crates/mint-core/src/search/linked_folders/index.rs +177 -13
- package/crates/mint-core/src/search/linked_folders.rs +83 -2
- package/crates/mint-core/src/slash/catalog.rs +1 -1
- package/crates/mint-core/src/slash/mod.rs +174 -11
- package/crates/mint-core/src/slash/mods.rs +155 -0
- package/crates/mint-core/src/system/bg_shell.rs +1129 -95
- package/crates/mint-core/src/system/config.rs +5 -10
- package/crates/mint-core/src/system/html_preview.rs +398 -0
- package/crates/mint-core/src/system/mint_web.rs +164 -0
- package/crates/mint-core/src/system/release_notes.rs +18 -0
- package/crates/mint-core/src/system/shell.rs +21 -6
- package/crates/mint-core/src/system/workspace.rs +72 -8
- package/crates/mint-core/src/system/workspace_history.rs +604 -0
- package/crates/mint-core/src/system.rs +4 -0
- package/crates/mint-core/tests/background_retention.rs +34 -0
- package/crates/mint-core/tests/background_shutdown.rs +24 -0
- package/crates/mint-core/tests/library_http.rs +209 -0
- package/crates/mint-core/tests/mcp_contract.rs +283 -0
- package/crates/mint-core/tests/mcp_stdio.rs +11 -10
- package/crates/mint-core/tests/media_model_catalog_http.rs +403 -0
- package/crates/mint-core/tests/mods_http.rs +215 -0
- package/crates/mint-core/tests/terminal_shutdown.rs +109 -0
- package/crates/mint-mod-runtime/Cargo.toml +18 -0
- package/crates/mint-mod-runtime/src/lib.rs +507 -0
- package/crates/mint-mod-runtime/src/sdk.js +56 -0
- package/crates/mint-mod-runtime/src/test_sdk.js +32 -0
- package/crates/mint-mod-runtime/src/testing.rs +94 -0
- package/crates/mint-mod-runtime/tests/runtime.rs +156 -0
- package/docs/mods/AUTHORING.md +61 -0
- package/docs/mods/README.md +139 -0
- package/docs/mods/TESTING.md +56 -0
- package/docs/mods/mint-mods.d.ts +66 -0
- package/examples/device-mcp/README.md +22 -0
- package/examples/device-mcp/contract.md +49 -0
- package/examples/device-mcp/mock-device.mjs +66 -0
- package/examples/device-mcp/server.mjs +48 -0
- package/examples/device-mcp/server.test.mjs +78 -0
- package/examples/mods/task-checklist/README.md +1 -0
- package/examples/mods/task-checklist/main.ts +17 -0
- package/examples/mods/task-checklist/manifest.json +1 -0
- package/examples/mods/task-checklist/tests/checklist.test.ts +15 -0
- package/examples/mods/token-meter/README.md +1 -0
- package/examples/mods/token-meter/main.ts +8 -0
- package/examples/mods/token-meter/manifest.json +1 -0
- package/examples/mods/tool-guard/README.md +1 -0
- package/examples/mods/tool-guard/main.ts +9 -0
- package/examples/mods/tool-guard/manifest.json +1 -0
- package/out/web/assets/CliSessionsView-CtzUJpK_.css +1 -0
- package/out/web/assets/CliSessionsView-D7hw0Mgj.js +1 -0
- package/out/web/assets/CodeReviewPage-C7bEOJfd.js +4 -0
- package/out/web/assets/CodeReviewPage-Dte9uLiL.css +1 -0
- package/out/web/assets/CommandPalette-0RrF-AOT.js +1 -0
- package/out/web/assets/ImageStudioPanel-CdxkAf_r.js +1 -0
- package/out/web/assets/LibraryPage--Qfisp6D.js +2 -0
- package/out/web/assets/LibraryPage-DAxUTAg7.css +1 -0
- package/out/web/assets/LinkedFoldersView-2nfZbDgN.js +1 -0
- package/out/web/assets/McpRegistryPicker-h9uS8_wT.js +1 -0
- package/out/web/assets/McpServersView-slfQJzNB.js +1 -0
- package/out/web/assets/MintDashboard-BSR5XpXh.js +25 -0
- package/out/web/assets/MintDashboard-CWUcCGhd.css +1 -0
- package/out/web/assets/PluginsView-l7LSm503.js +1 -0
- package/out/web/assets/ScheduledTasksView-CttmLbq1.js +1 -0
- package/out/web/assets/SettingsWindow-BCMLYvEV.js +4 -0
- package/out/web/assets/SettingsWindow-DcMVmU9u.css +1 -0
- package/out/web/assets/SkillsView-rNs1qr_U.js +2 -0
- package/out/web/assets/ToolSurfacePage-B9DzEPWN.js +37 -0
- package/out/web/assets/ToolSurfacePage-CTfgggF2.css +1 -0
- package/out/web/assets/VeoStudioPanel-DiJs_Cg2.js +4 -0
- package/out/web/assets/WorkspaceSelector-B2xIp04D.js +1 -0
- package/out/web/assets/WorkspaceSelector-Ca8uJOsS.css +1 -0
- package/out/web/assets/{abnfDiagram-VCTEODGH-ByMyfanq.js → abnfDiagram-VCTEODGH-CD0CjoGl.js} +1 -1
- package/out/web/assets/{architecture-7GRP2DOG-CLq2kEOB.js → architecture-7GRP2DOG-RKV83OeZ.js} +1 -1
- package/out/web/assets/{architectureDiagram-5GKGNRK7-6PoVSmNG.js → architectureDiagram-5GKGNRK7-nN_HAFct.js} +1 -1
- package/out/web/assets/{blockDiagram-NRAW4CY4-cKw9mAKi.js → blockDiagram-NRAW4CY4-BrrqzHW5.js} +1 -1
- package/out/web/assets/{c4Diagram-UCG6FXSJ-Cqy8N5Ge.js → c4Diagram-UCG6FXSJ-DTdV8_zE.js} +1 -1
- package/out/web/assets/{chunk-75Z2AOVW-3qybijF5.js → chunk-75Z2AOVW-_M0z5olV.js} +1 -1
- package/out/web/assets/chunk-CKBBP62Z-BpQEgeHF.js +2 -0
- package/out/web/assets/{chunk-CLGD4ZFX-CndDQkww.js → chunk-CLGD4ZFX-D54yGvGS.js} +1 -1
- package/out/web/assets/{chunk-DSNCTWBM-Cc4NxvgD.js → chunk-DSNCTWBM-C-gvT2ru.js} +1 -1
- package/out/web/assets/{chunk-DU6HZSFF-drzh6GsU.js → chunk-DU6HZSFF-CnFngIhW.js} +1 -1
- package/out/web/assets/{chunk-F27PBJKO-FiY35l4v.js → chunk-F27PBJKO-BqtWrnEO.js} +1 -1
- package/out/web/assets/{chunk-G27WJ6UU-Bjt9Il4A.js → chunk-G27WJ6UU-Ckoq5mi2.js} +1 -1
- package/out/web/assets/{chunk-GMAD6QVW-Bppi3Ctd.js → chunk-GMAD6QVW-BuhEcgHq.js} +1 -1
- package/out/web/assets/{chunk-JQ64N6SF-DGg5kcEV.js → chunk-JQ64N6SF-CF8T7GiZ.js} +1 -1
- package/out/web/assets/{chunk-LCL6LL3I-CCYcjd7p.js → chunk-LCL6LL3I-BhXV9zyH.js} +1 -1
- package/out/web/assets/{chunk-OBVCFTLP-DJeNil5M.js → chunk-OBVCFTLP-CRIkunUB.js} +1 -1
- package/out/web/assets/{chunk-P2QGCYS3-lRzkRjBB.js → chunk-P2QGCYS3-UFEU6BxZ.js} +1 -1
- package/out/web/assets/{chunk-POPQ4Y6H-DouASMBW.js → chunk-POPQ4Y6H-CQcrNbjr.js} +1 -1
- package/out/web/assets/{chunk-PWAF6VOD-DMmD1vVf.js → chunk-PWAF6VOD-Cc2uVDsG.js} +1 -1
- package/out/web/assets/{chunk-R7TYR2AO-CYLA5UC5.js → chunk-R7TYR2AO-DiCxzdAY.js} +1 -1
- package/out/web/assets/{chunk-RHFEMEQ7-BiXwEcUT.js → chunk-RHFEMEQ7-b7hnPmrR.js} +1 -1
- package/out/web/assets/{chunk-SVP7TREG-BV-zPslF.js → chunk-SVP7TREG-Bu_yYb-V.js} +1 -1
- package/out/web/assets/{chunk-TEH6E4GO-B2RGEohZ.js → chunk-TEH6E4GO-G4Cdlyrt.js} +1 -1
- package/out/web/assets/classDiagram-DTDB5LWJ-RnC2mYO4.js +1 -0
- package/out/web/assets/classDiagram-v2-JRS7N3AN-RnC2mYO4.js +1 -0
- package/out/web/assets/config-CnvCChUM.js +2 -0
- package/out/web/assets/config-DM6oIVO3.css +1 -0
- package/out/web/assets/core-DsKkQ7ig.js +1 -0
- package/out/web/assets/{cynefin-OW5HDTMX-Cas4csHM.js → cynefin-OW5HDTMX-CnzQfOGp.js} +1 -1
- package/out/web/assets/{cynefinDiagram-5FMLGOSQ-Bbpj66Y3.js → cynefinDiagram-5FMLGOSQ-DVtQnfpm.js} +1 -1
- package/out/web/assets/{dagre-3AP2YEHR-B0-2RDEd.js → dagre-3AP2YEHR-DG76_k5_.js} +1 -1
- package/out/web/assets/{diagram-S7CK7UJ4-BdzEjUyH.js → diagram-S7CK7UJ4-CaouUoze.js} +1 -1
- package/out/web/assets/{diagram-UQ7AKVKN-CJDwyPxF.js → diagram-UQ7AKVKN-B4bEc26B.js} +1 -1
- package/out/web/assets/{diagram-VSXAHHWV-BxaG1r_B.js → diagram-VSXAHHWV-BJ86Ov2Y.js} +1 -1
- package/out/web/assets/{diagram-VX7I27RA-BMmUqm8f.js → diagram-VX7I27RA-7hH5IPYf.js} +1 -1
- package/out/web/assets/{diagram-Z3DM3KII-CFtd03eE.js → diagram-Z3DM3KII-CCM4clo8.js} +1 -1
- package/out/web/assets/dist-js-BkYNznHX.js +1 -0
- package/out/web/assets/{ebnfDiagram-PWID7BFC-DwAen1hO.js → ebnfDiagram-PWID7BFC-Da7WAM3k.js} +1 -1
- package/out/web/assets/{erDiagram-SSCWMZ5O-BCZSHACj.js → erDiagram-SSCWMZ5O-CzzmnZWT.js} +1 -1
- package/out/web/assets/{event-ChBVpRy0.js → event-Cdt7Byyj.js} +1 -1
- package/out/web/assets/{eventmodeling-NTZA5JFV-XHStE4E_.js → eventmodeling-NTZA5JFV-xcfsA0XD.js} +1 -1
- package/out/web/assets/flowDiagram-A5DVABFB-JdtH1673.js +1 -0
- package/out/web/assets/{ganttDiagram-EL5Y4UJY-BAEu1Cql.js → ganttDiagram-EL5Y4UJY-B3ClFGmL.js} +1 -1
- package/out/web/assets/{gitGraph-4MIJSDKK-r32Vyper.js → gitGraph-4MIJSDKK-BZ_y_cDU.js} +1 -1
- package/out/web/assets/{gitGraphDiagram-WWUBYQGX-z9o9qt6V.js → gitGraphDiagram-WWUBYQGX-drhRSYm3.js} +1 -1
- package/out/web/assets/index-BZ9xgmMP.css +1 -0
- package/out/web/assets/index-Ca8cCS4h.js +168 -0
- package/out/web/assets/{info-A6RAGUB7-BvLaC2cw.js → info-A6RAGUB7-B7I3K0F1.js} +1 -1
- package/out/web/assets/{infoDiagram-RXCK75RN-Be6WAXXw.js → infoDiagram-RXCK75RN-deX_1MPh.js} +1 -1
- package/out/web/assets/{ishikawaDiagram-5VMMS53U-DZjoHJHC.js → ishikawaDiagram-5VMMS53U-s38yo28y.js} +1 -1
- package/out/web/assets/{journeyDiagram-EYS64GPL-CtVkjkGm.js → journeyDiagram-EYS64GPL-CZn2kB8b.js} +1 -1
- package/out/web/assets/jsx-runtime-DN4NhQUK.js +1 -0
- package/out/web/assets/{kanban-definition-3QL26DDD-CW5FMv1w.js → kanban-definition-3QL26DDD-DodjgySL.js} +1 -1
- package/out/web/assets/markdown-CMhYIcWB.js +39 -0
- package/out/web/assets/{mermaid-parser.core-aUgCqsZ5.js → mermaid-parser.core-Whu2rlJC.js} +3 -3
- package/out/web/assets/{mermaid.core-D57sEiSL.js → mermaid.core-CKyPo8VH.js} +4 -4
- package/out/web/assets/{mindmap-definition-FBJOCRG2-DAmSpM3a.js → mindmap-definition-FBJOCRG2-260WBDxZ.js} +1 -1
- package/out/web/assets/modelManager-CUaGWMWu.js +2 -0
- package/out/web/assets/{oauthManager-9jxicDWJ.js → oauthManager-DlNhXJr6.js} +1 -1
- package/out/web/assets/{packet-AYTQ26CC-DJ27iIoJ.js → packet-AYTQ26CC-CEeIRKRG.js} +1 -1
- package/out/web/assets/{pegDiagram-XKGWAZYB-Bj3ii-gS.js → pegDiagram-XKGWAZYB-BYadI-KO.js} +1 -1
- package/out/web/assets/{pie-WAS4IAKB-DG5mCUbc.js → pie-WAS4IAKB-D8uf4dh5.js} +1 -1
- package/out/web/assets/{pieDiagram-E7YTZNPT-BrJLPnDA.js → pieDiagram-E7YTZNPT-CjSDy4hO.js} +1 -1
- package/out/web/assets/{quadrantDiagram-AXDQQJYC-3x_TmF3j.js → quadrantDiagram-AXDQQJYC-B8D3gU5d.js} +1 -1
- package/out/web/assets/{radar-RG4KPBEZ-CrXaTTuV.js → radar-RG4KPBEZ-DZJxnokY.js} +1 -1
- package/out/web/assets/{railroad-74A4TZTK-BpqMH9BE.js → railroad-74A4TZTK-DBysUiUi.js} +1 -1
- package/out/web/assets/{railroad-abnf-HS5TGJTU-DHI0uLlV.js → railroad-abnf-HS5TGJTU-CHWxoJYg.js} +1 -1
- package/out/web/assets/{railroad-ebnf-LZEXJU2U-CQCb316y.js → railroad-ebnf-LZEXJU2U-DDv7X6bY.js} +1 -1
- package/out/web/assets/{railroad-peg-WCYAUIDC-Ph1giKkH.js → railroad-peg-WCYAUIDC-DpfcYYNJ.js} +1 -1
- package/out/web/assets/{railroadDiagram-O6MQD6OU-BRq6wIxx.js → railroadDiagram-O6MQD6OU-CYtyv0t3.js} +1 -1
- package/out/web/assets/{requirementDiagram-EFPCY7ZU-DIJj6G1g.js → requirementDiagram-EFPCY7ZU-D2X-Ewik.js} +1 -1
- package/out/web/assets/{sankeyDiagram-P5KCCOFB-DZajSryq.js → sankeyDiagram-P5KCCOFB-Bn2x6C4Y.js} +1 -1
- package/out/web/assets/{sequenceDiagram-WJ2MYXX4-DxJCWyZS.js → sequenceDiagram-WJ2MYXX4-BvFLKtPd.js} +1 -1
- package/out/web/assets/{stateDiagram-HBIQ2CUA-k6voi8Vf.js → stateDiagram-HBIQ2CUA-Bx0GWeaY.js} +1 -1
- package/out/web/assets/stateDiagram-v2-4QOOHH4V--hol1yg_.js +1 -0
- package/out/web/assets/{swimlanes-XN3QIQJK-igYhTjXB.js → swimlanes-XN3QIQJK-CCma0T7L.js} +1 -1
- package/out/web/assets/swimlanesDiagram-VK2B7HYN-BkohoVsU.js +8 -0
- package/out/web/assets/{timeline-definition-24CTP7MA-Dke2p93p.js → timeline-definition-24CTP7MA-iCRhhJ7C.js} +1 -1
- package/out/web/assets/{treeView-Q6P3EWNA-hNELnXUs.js → treeView-Q6P3EWNA-DZ-y08qp.js} +1 -1
- package/out/web/assets/{treemap-WGGIJYW6-D2B6wDsx.js → treemap-WGGIJYW6-De0CxzMx.js} +1 -1
- package/out/web/assets/{vennDiagram-4TSXK5OY-CDkW7rUP.js → vennDiagram-4TSXK5OY-w_7aZ6xe.js} +1 -1
- package/out/web/assets/{wardley-WFR3VGLG-BECdXETi.js → wardley-WFR3VGLG-DT0y0xJ4.js} +1 -1
- package/out/web/assets/{wardleyDiagram-VM6X3IG4-B5BycpQ4.js → wardleyDiagram-VM6X3IG4-DAdXELbQ.js} +1 -1
- package/out/web/assets/window-BJCVtyET.js +1 -0
- package/out/web/assets/{xychartDiagram-S5SC5T6Z-CtJS3b--.js → xychartDiagram-S5SC5T6Z-IZIXf3Vo.js} +1 -1
- package/out/web/index-web.html +3 -2
- package/out/web/index.html +3 -2
- package/package.json +71 -22
- package/shared-modules/.github/workflows/ci.yml +120 -0
- package/shared-modules/.github/workflows/update.yaml +28 -0
- package/slash-commands.json +7 -2
- package/src/bin/auto-build.js +66 -0
- package/src/bin/desktop.js +113 -0
- package/src/bin/desktop.test.js +113 -0
- package/src/bin/index.js +18 -25
- package/src/bin/index.test.js +89 -0
- package/src/bin/measure-effects.mjs +53 -0
- package/src/bin/package.test.js +28 -0
- package/src/bin/release-notes.test.js +84 -0
- package/src/bin/styles.test.js +20 -0
- package/src/bin/web.js +5 -0
- package/src/bin/web.test.js +39 -0
- package/src/renderer/index.html +0 -2
- package/src/renderer/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
- package/src/renderer/shared/agentProgress.ts +33 -0
- package/src/renderer/shared/components/AgentActivityDrawer.tsx +3 -2
- package/src/renderer/shared/components/AgentActivityTable.tsx +1 -1
- package/src/renderer/shared/components/ApprovalCard.test.tsx +24 -0
- package/src/renderer/shared/components/ApprovalCard.tsx +10 -3
- package/src/renderer/shared/components/ArtifactPreviewPanel.tsx +88 -37
- package/src/renderer/shared/components/AuthGate.tsx +75 -39
- package/src/renderer/shared/components/BackgroundTerminals.tsx +181 -0
- package/src/renderer/shared/components/ChatCodeBlock.tsx +8 -4
- package/src/renderer/shared/components/ChatMessageItem.test.tsx +68 -0
- package/src/renderer/shared/components/ChatMessageItem.tsx +36 -16
- package/src/renderer/shared/components/ChatPanel.test.tsx +21 -0
- package/src/renderer/shared/components/ChatPanel.tsx +294 -272
- package/src/renderer/shared/components/ChunkErrorBoundary.tsx +4 -102
- package/src/renderer/shared/components/CliSessionsView.test.tsx +125 -0
- package/src/renderer/shared/components/CliSessionsView.tsx +61 -13
- package/src/renderer/shared/components/CodeReviewPage.tsx +111 -8
- package/src/renderer/shared/components/CollapsiblePasteInput.tsx +90 -0
- package/src/renderer/shared/components/ContextCompactionStatus.tsx +17 -0
- package/src/renderer/shared/components/DashboardSidebar.tsx +15 -128
- package/src/renderer/shared/components/DesktopTitlebar.tsx +45 -19
- package/src/renderer/shared/components/ErrorNotice.tsx +29 -0
- package/src/renderer/shared/components/FormattedMessage.tsx +11 -0
- package/src/renderer/shared/components/GeminiLiveOverlay.css +86 -0
- package/src/renderer/shared/components/GeminiLiveOverlay.test.tsx +24 -0
- package/src/renderer/shared/components/GeminiLiveOverlay.tsx +85 -101
- package/src/renderer/shared/components/GlideSelect.css +138 -0
- package/src/renderer/shared/components/GlideSelect.d.ts +31 -0
- package/src/renderer/shared/components/GlideSelect.jsx +266 -0
- package/src/renderer/shared/components/ImageSearchCard.tsx +46 -56
- package/src/renderer/shared/components/ImageStudioPanel.tsx +9 -8
- package/src/renderer/shared/components/LibraryItemCard.tsx +72 -0
- package/src/renderer/shared/components/LibraryPage.tsx +165 -0
- package/src/renderer/shared/components/LibraryPreview.tsx +59 -0
- package/src/renderer/shared/components/McpServersView.tsx +27 -8
- package/src/renderer/shared/components/McpToolAllowlist.tsx +2 -4
- package/src/renderer/shared/components/McpToolResults.tsx +99 -0
- package/src/renderer/shared/components/MintDashboard.tsx +308 -770
- package/src/renderer/shared/components/ModSessionControls.tsx +8 -0
- package/src/renderer/shared/components/ModUi.test.tsx +65 -0
- package/src/renderer/shared/components/ModUi.tsx +26 -0
- package/src/renderer/shared/components/ModelSelectorPopover.tsx +14 -7
- package/src/renderer/shared/components/ModsPanel.tsx +156 -0
- package/src/renderer/shared/components/ProgressActivity.tsx +17 -0
- package/src/renderer/shared/components/ReviewHistory.tsx +42 -0
- package/src/renderer/shared/components/RewindModal.tsx +5 -12
- package/src/renderer/shared/components/RunSummaryDashboard.tsx +6 -12
- package/src/renderer/shared/components/ScheduledTasksView.tsx +7 -6
- package/src/renderer/shared/components/SelectField.test.tsx +27 -0
- package/src/renderer/shared/components/SelectField.tsx +38 -0
- package/src/renderer/shared/components/SessionSources.tsx +48 -0
- package/src/renderer/shared/components/SessionSourcesPopover.tsx +61 -0
- package/src/renderer/shared/components/Settings/AgentsTab.tsx +7 -6
- package/src/renderer/shared/components/Settings/AudioTab.tsx +8 -7
- package/src/renderer/shared/components/Settings/AutomationTab.tsx +2 -2
- package/src/renderer/shared/components/Settings/GeneralTab.tsx +33 -32
- package/src/renderer/shared/components/Settings/MemoryTab.test.tsx +37 -0
- package/src/renderer/shared/components/Settings/MemoryTab.tsx +71 -31
- package/src/renderer/shared/components/Settings/NotificationsTab.test.tsx +15 -0
- package/src/renderer/shared/components/Settings/NotificationsTab.tsx +84 -0
- package/src/renderer/shared/components/Settings/ThemeTab.tsx +19 -11
- package/src/renderer/shared/components/SlashChoicePanel.tsx +88 -0
- package/src/renderer/shared/components/SlashSuggestions.test.tsx +33 -0
- package/src/renderer/shared/components/SlashSuggestions.tsx +38 -10
- package/src/renderer/shared/components/SourcesBlock.tsx +12 -20
- package/src/renderer/shared/components/ToolSurfacePage.test.tsx +32 -0
- package/src/renderer/shared/components/ToolSurfacePage.tsx +59 -11
- package/src/renderer/shared/components/ToolsPanelToggle.tsx +13 -0
- package/src/renderer/shared/components/VeoStudioPanel.tsx +9 -8
- package/src/renderer/shared/components/ViewedImages.tsx +36 -0
- package/src/renderer/shared/components/VirtualChatHistory.tsx +82 -0
- package/src/renderer/shared/components/VoicePill.css +85 -0
- package/src/renderer/shared/components/VoicePill.d.ts +12 -0
- package/src/renderer/shared/components/VoicePill.jsx +190 -0
- package/src/renderer/shared/components/VoicePill.test.tsx +22 -0
- package/src/renderer/shared/components/WorkspaceContextPopover.tsx +20 -15
- package/src/renderer/shared/components/WorkspacePaneResizer.tsx +92 -0
- package/src/renderer/shared/components/WorkspacePreviewActions.test.tsx +44 -0
- package/src/renderer/shared/components/WorkspacePreviewActions.tsx +19 -0
- package/src/renderer/shared/components/WorkspaceSelector.tsx +13 -8
- package/src/renderer/shared/components/background-terminals.css +292 -0
- package/src/renderer/shared/components/ui/README.md +52 -0
- package/src/renderer/shared/components/ui/button.tsx +37 -0
- package/src/renderer/shared/components/ui/demo.tsx +26 -0
- package/src/renderer/shared/components/ui/error-recovery.css +35 -0
- package/src/renderer/shared/components/ui/error-recovery.tsx +35 -0
- package/src/renderer/shared/components/ui/voice-powered-orb.css +6 -0
- package/src/renderer/shared/components/ui/voice-powered-orb.tsx +374 -0
- package/src/renderer/shared/components/workspace-selector.css +248 -0
- package/src/renderer/shared/constants/config.ts +30 -1
- package/src/renderer/shared/constants/slashCommands.ts +1 -1
- package/src/renderer/shared/conversation/lifecycle.test.ts +362 -0
- package/src/renderer/shared/conversation/lifecycle.ts +418 -0
- package/src/renderer/shared/conversation/projectNavigation.test.ts +105 -0
- package/src/renderer/shared/conversation/projectNavigation.ts +39 -0
- package/src/renderer/shared/conversation/sourcesTransport.ts +27 -0
- package/src/renderer/shared/conversation/syncView.test.ts +1 -34
- package/src/renderer/shared/conversation/syncView.ts +0 -37
- package/src/renderer/shared/conversation/transport.test.ts +163 -0
- package/src/renderer/shared/conversation/transport.ts +159 -0
- package/src/renderer/shared/conversation/useConversationCoordinator.ts +30 -72
- package/src/renderer/shared/css/agent-observability.css +20 -21
- package/src/renderer/shared/css/auth-gate.css +112 -13
- package/src/renderer/shared/css/code-review.css +33 -0
- package/src/renderer/shared/css/code-sessions.css +27 -0
- package/src/renderer/shared/css/collapsed-paste.css +35 -0
- package/src/renderer/shared/css/effects.css +15 -0
- package/src/renderer/shared/css/error-notice.css +60 -0
- package/src/renderer/shared/css/library.css +476 -0
- package/src/renderer/shared/css/management-views.css +138 -0
- package/src/renderer/shared/css/mcp-results.css +11 -0
- package/src/renderer/shared/css/model-selector.css +163 -105
- package/src/renderer/shared/css/mods.css +77 -0
- package/src/renderer/shared/css/notification-notice.css +28 -0
- package/src/renderer/shared/css/session-sources-popover.css +9 -0
- package/src/renderer/shared/css/session-sources.css +23 -0
- package/src/renderer/shared/css/settings/memory.css +154 -0
- package/src/renderer/shared/css/settings/notifications.css +11 -0
- package/src/renderer/shared/css/settings/theme.css +5 -0
- package/src/renderer/shared/css/slash-choice.css +95 -0
- package/src/renderer/shared/css/slash-suggestions.css +68 -0
- package/src/renderer/shared/css/sources-block.css +91 -0
- package/src/renderer/shared/css/thinking-status.css +46 -0
- package/src/renderer/shared/css/tools-panel.css +7 -0
- package/src/renderer/shared/css/ui-tailwind.css +19 -0
- package/src/renderer/shared/css/viewed-images.css +15 -0
- package/src/renderer/shared/fonts.css +46 -0
- package/src/renderer/shared/fonts.ts +3 -12
- package/src/renderer/shared/lib/utils.ts +6 -0
- package/src/renderer/shared/library/controller.test.ts +61 -0
- package/src/renderer/shared/library/controller.ts +57 -0
- package/src/renderer/shared/library/transport.test.ts +26 -0
- package/src/renderer/shared/library/transport.ts +60 -0
- package/src/renderer/shared/library/useLibraryFile.ts +38 -0
- package/src/renderer/shared/mods.ts +58 -0
- package/src/renderer/shared/platform.test.ts +57 -1
- package/src/renderer/shared/platform.ts +46 -1
- package/src/renderer/shared/theme/themeManager.test.ts +43 -0
- package/src/renderer/shared/theme/themeManager.ts +17 -4
- package/src/renderer/shared/types.ts +56 -2
- package/src/renderer/shared/utils/agentActivity.test.ts +75 -0
- package/src/renderer/shared/utils/agentActivity.ts +42 -3
- package/src/renderer/shared/utils/approval.tsx +7 -0
- package/src/renderer/shared/utils/artifactBrowser.test.ts +80 -0
- package/src/renderer/shared/utils/artifactBrowser.ts +41 -0
- package/src/renderer/shared/utils/contextCompaction.test.tsx +48 -0
- package/src/renderer/shared/utils/contextCompaction.ts +21 -0
- package/src/renderer/shared/utils/effectVisibility.ts +9 -0
- package/src/renderer/shared/utils/markdown.tsx +3 -3
- package/src/renderer/shared/utils/mcpResults.test.tsx +91 -0
- package/src/renderer/shared/utils/modViewport.ts +7 -0
- package/src/renderer/shared/utils/nativeRecordingSession.test.ts +61 -0
- package/src/renderer/shared/utils/nativeRecordingSession.ts +46 -0
- package/src/renderer/shared/utils/notificationSettings.test.ts +14 -0
- package/src/renderer/shared/utils/notificationSettings.ts +23 -0
- package/src/renderer/shared/utils/notifications.test.ts +51 -0
- package/src/renderer/shared/utils/notifications.ts +54 -0
- package/src/renderer/shared/utils/pastedText.test.ts +20 -0
- package/src/renderer/shared/utils/pastedText.ts +13 -0
- package/src/renderer/shared/utils/progressCache.test.ts +32 -0
- package/src/renderer/shared/utils/sessionSources.test.ts +31 -0
- package/src/renderer/shared/utils/sessionSources.ts +34 -0
- package/src/renderer/shared/utils/slashCommandProcessor.ts +1 -1
- package/src/renderer/shared/utils/sourceAttachments.ts +28 -0
- package/src/renderer/shared/utils/speech.ts +51 -9
- package/src/renderer/shared/utils/syntaxHighlight.test.tsx +22 -0
- package/src/renderer/shared/utils/syntaxHighlight.tsx +26 -0
- package/src/renderer/shared/utils/useGeminiLiveVoice.ts +49 -5
- package/src/renderer/shared/utils/useLatestCallback.ts +9 -0
- package/src/renderer/shared/utils/useNativeVoiceInput.ts +80 -72
- package/src/renderer/shared/utils/useSessionSources.ts +33 -0
- package/src/renderer/shared/utils/viewedImages.ts +26 -0
- package/src/renderer/shared/utils/workspacePane.test.ts +33 -0
- package/src/renderer/shared/utils/workspacePane.ts +20 -0
- package/src/renderer/shared/utils/workspacePreview.test.ts +24 -0
- package/src/renderer/shared/utils/workspacePreview.ts +16 -0
- package/src/renderer/shared/utils/workspaceSnapshot.test.ts +49 -0
- package/src/renderer/shared/utils/workspaceSnapshot.ts +26 -0
- package/src/renderer/shared/utils/workspaces.ts +10 -0
- package/src/renderer/shared/workspaceUndo.ts +88 -0
- package/src/renderer/src/App.tsx +9 -1
- package/src/renderer/src/components/LiveTranslateControls.tsx +65 -0
- package/src/renderer/src/components/PicturesLibrary.tsx +2 -288
- package/src/renderer/src/components/ScreenPicker.css +67 -30
- package/src/renderer/src/components/ScreenPicker.tsx +201 -60
- package/src/renderer/src/components/SettingsWindow.tsx +10 -5
- package/src/renderer/src/components/WorkspacePanel.tsx +222 -32
- package/src/renderer/src/components/browser-shell.css +1 -1
- package/src/renderer/src/components/browser-suggestions-popup.css +1 -1
- package/src/renderer/src/components/liveTranslateFrames.test.ts +26 -5
- package/src/renderer/src/components/liveTranslateFrames.ts +18 -7
- package/src/renderer/src/components/liveTranslateLanguage.ts +6 -0
- package/src/renderer/src/css/app-shell.css +52 -137
- package/src/renderer/src/css/chat.css +21 -495
- package/src/renderer/src/css/desktop-tools.css +199 -1
- package/src/renderer/src/css/misc.css +0 -52
- package/src/renderer/src/css/pictures.css +2 -415
- package/src/renderer/src/css/settings/base.css +50 -47
- package/src/renderer/src/css/sidebar-workspace.css +151 -94
- package/src/renderer/src/css/tool-surfaces.css +65 -9
- package/src/renderer/src/css/widget.css +1 -1
- package/src/renderer/src/env.d.ts +1 -9
- package/src/renderer/src/index.css +1 -1
- package/src/renderer/src/main.tsx +2 -1
- package/src/renderer/src/proactiveSuggestions.ts +29 -0
- package/src/renderer/src/tauri.ts +122 -330
- package/src/renderer/src/voiceInput.ts +2 -1
- package/src/renderer/src-web/components/PicturesLibrary.tsx +2 -285
- package/src/renderer/src-web/components/PullToRefresh.tsx +1 -1
- package/src/renderer/src-web/components/SettingsWindow.tsx +10 -5
- package/src/renderer/src-web/css/app-shell.css +24 -121
- package/src/renderer/src-web/css/chat.css +21 -495
- package/src/renderer/src-web/css/misc.css +0 -52
- package/src/renderer/src-web/css/mobile.css +15 -14
- package/src/renderer/src-web/css/pictures.css +2 -462
- package/src/renderer/src-web/css/settings/base.css +50 -47
- package/src/renderer/src-web/css/sidebar-workspace.css +9 -95
- package/src/renderer/src-web/css/widget.css +1 -1
- package/src/renderer/src-web/env.d.ts +1 -12
- package/src/renderer/src-web/index.css +1 -1
- package/src/renderer/src-web/main.tsx +2 -1
- package/src/renderer/src-web/proactiveSuggestions.ts +3 -0
- package/src/renderer/src-web/tauri.ts +129 -354
- package/src/renderer/tests/backgroundTerminals.browser.html +81 -0
- package/src/renderer/tests/chatPanelFixture.ts +23 -0
- package/src/renderer/tests/chatPerformance.browser.html +71 -0
- package/src/renderer/tests/cliSessions.browser.html +82 -0
- package/src/renderer/tests/collapsedPaste.browser.html +70 -0
- package/src/renderer/tests/composerMenus.browser.html +116 -0
- package/src/renderer/tests/contextCompaction.browser.html +17 -0
- package/src/renderer/tests/conversationLifecycle.browser.html +70 -0
- package/src/renderer/tests/effectsPerformance.browser.html +13 -0
- package/src/renderer/tests/errorRecovery.browser.html +21 -0
- package/src/renderer/tests/glideSelect.browser.html +71 -0
- package/src/renderer/tests/glideSelect.preview.html +27 -0
- package/src/renderer/tests/library.browser.html +1 -0
- package/src/renderer/tests/library.browser.tsx +78 -0
- package/src/renderer/tests/liveOrb.browser.html +49 -0
- package/src/renderer/tests/liveVoice.browser.html +29 -0
- package/src/renderer/tests/modInput.browser.html +22 -0
- package/src/renderer/tests/sessionSources.browser.html +1 -0
- package/src/renderer/tests/sessionSources.browser.tsx +107 -0
- package/src/renderer/tests/skills.browser.html +24 -0
- package/src/renderer/tests/toolsPanel.browser.html +1 -0
- package/src/renderer/tests/toolsPanel.browser.tsx +113 -0
- package/src/renderer/tests/viewedImages.browser.html +1 -0
- package/src/renderer/tests/viewedImages.browser.tsx +93 -0
- package/src/renderer/tests/voicePill.browser.html +80 -0
- package/src/renderer/tests/voicePill.preview.html +34 -0
- package/src/renderer/tests/webSources.browser.html +1 -0
- package/src/renderer/tests/webSources.browser.tsx +98 -0
- package/src/renderer/tests/workspaceUndo.browser.html +92 -0
- package/src-tauri/Cargo.toml +40 -0
- package/src-tauri/build.rs +3 -0
- package/src-tauri/src/app/lifecycle.rs +277 -0
- package/src-tauri/src/app/mod.rs +4 -0
- package/src-tauri/src/app/shortcuts.rs +40 -0
- package/src-tauri/src/app/tray.rs +52 -0
- package/src-tauri/src/background/events.rs +70 -0
- package/src-tauri/src/background/headless.rs +230 -0
- package/src-tauri/src/background/mod.rs +4 -0
- package/src-tauri/src/background/proactive.rs +262 -0
- package/src-tauri/src/commands/approvals.rs +20 -0
- package/src-tauri/src/commands/auth.rs +127 -0
- package/src-tauri/src/commands/conversation.rs +642 -0
- package/src-tauri/src/commands/integrations.rs +157 -0
- package/src-tauri/src/commands/media.rs +179 -0
- package/src-tauri/src/commands/mod.rs +11 -0
- package/src-tauri/src/commands/mods.rs +6 -0
- package/src-tauri/src/commands/settings.rs +141 -0
- package/src-tauri/src/commands/voice.rs +153 -0
- package/src-tauri/src/commands/workspace.rs +501 -0
- package/src-tauri/src/lib.rs +10 -0
- package/src-tauri/src/main.rs +3 -0
- package/src-tauri/src/native/actions.rs +206 -0
- package/src-tauri/src/native/browser.rs +252 -0
- package/src-tauri/src/native/capture.rs +695 -0
- package/src-tauri/src/native/discord_rpc.rs +99 -0
- package/src-tauri/src/native/integrations.rs +126 -0
- package/src-tauri/src/native/mod.rs +12 -0
- package/src-tauri/src/native/notifications.rs +51 -0
- package/src-tauri/src/native/plugins.rs +14 -0
- package/src-tauri/src/native/system.rs +250 -0
- package/src-tauri/src/native/terminal.rs +201 -0
- package/src-tauri/src/native/updater.rs +148 -0
- package/src-tauri/src/native/windows.rs +143 -0
- package/tsconfig.json +2 -0
- package/vite.config.ts +4 -1
- package/vite.config.web.ts +4 -0
- package/.cargo/config.toml +0 -13
- package/.claude/settings.local.json +0 -182
- package/.codex +0 -0
- package/CLAUDE.md +0 -102
- package/ROADMAP.md +0 -30
- package/mint-presentation-demo.mp4 +0 -0
- package/out/web/Live2DCubismCore.js +0 -9
- package/out/web/assets/CliSessionsView-BxUVWEEL.js +0 -1
- package/out/web/assets/CliSessionsView-CBDTXuQv.css +0 -1
- package/out/web/assets/CodeReviewPage-DkMgfcos.css +0 -1
- package/out/web/assets/CodeReviewPage-jKlmLJwT.js +0 -3
- package/out/web/assets/CommandPalette-DnwPA5hy.js +0 -1
- package/out/web/assets/ImageStudioPanel-BR1XFwhR.js +0 -1
- package/out/web/assets/LinkedFoldersView-bi-CWQ-I.js +0 -1
- package/out/web/assets/McpRegistryPicker-D5tEFnyq.js +0 -1
- package/out/web/assets/McpServersView-BGG1dhFM.js +0 -1
- package/out/web/assets/MintDashboard-BIglDEWX.js +0 -20
- package/out/web/assets/MintDashboard-DSMywSgs.css +0 -1
- package/out/web/assets/ModelPanel-CbJ1PFoZ.js +0 -1
- package/out/web/assets/PicturesLibrary-CQP0fLP1.css +0 -1
- package/out/web/assets/PicturesLibrary-DoYN7T1p.js +0 -1
- package/out/web/assets/PluginsView-CU1HWXGk.js +0 -1
- package/out/web/assets/ScheduledTasksView-Bnl36y2N.js +0 -1
- package/out/web/assets/SettingsWindow-DhWLAn9T.css +0 -1
- package/out/web/assets/SettingsWindow-Dw8L01pw.js +0 -2
- package/out/web/assets/SkillsView-cnl8aY5p.js +0 -2
- package/out/web/assets/ToolSurfacePage-CgsQw6l5.css +0 -1
- package/out/web/assets/ToolSurfacePage-Cz2VJAPZ.js +0 -37
- package/out/web/assets/VeoStudioPanel-D4JnERWR.js +0 -4
- package/out/web/assets/chunk-CKBBP62Z-cIrXq6jN.js +0 -2
- package/out/web/assets/classDiagram-DTDB5LWJ-Dq0smRWk.js +0 -1
- package/out/web/assets/classDiagram-v2-JRS7N3AN-Dq0smRWk.js +0 -1
- package/out/web/assets/config-C-ZFtipU.css +0 -1
- package/out/web/assets/config-eEDngJXO.js +0 -1
- package/out/web/assets/core-hQ2VA9Ti.js +0 -1
- package/out/web/assets/dist-js-Bf2bhoku.js +0 -1
- package/out/web/assets/flowDiagram-A5DVABFB-BLg7nEcd.js +0 -1
- package/out/web/assets/index-Btsf4L8M.css +0 -1
- package/out/web/assets/index-D8D9MeRA.js +0 -11
- package/out/web/assets/lucide-react-Ip3L6Jtn.js +0 -1
- package/out/web/assets/markdown-BSeeUbJH.js +0 -38
- package/out/web/assets/modelManager-tMVmJVAW.js +0 -2
- package/out/web/assets/prompt-latin-400-normal-BQ9zjSN8.woff2 +0 -0
- package/out/web/assets/prompt-latin-400-normal-CxU4ec_r.woff +0 -0
- package/out/web/assets/prompt-latin-500-normal-B1edBDQ9.woff +0 -0
- package/out/web/assets/prompt-latin-500-normal-CxzxEHZc.woff2 +0 -0
- package/out/web/assets/prompt-latin-600-normal-CSDDLorv.woff +0 -0
- package/out/web/assets/prompt-latin-600-normal-hKZWXsc1.woff2 +0 -0
- package/out/web/assets/prompt-latin-700-normal-BfbftDSq.woff +0 -0
- package/out/web/assets/prompt-latin-700-normal-I2gc831J.woff2 +0 -0
- package/out/web/assets/prompt-thai-400-normal-BrkKv8cO.woff2 +0 -0
- package/out/web/assets/prompt-thai-400-normal-DJypnfr3.woff +0 -0
- package/out/web/assets/prompt-thai-500-normal-C18pDUoL.woff2 +0 -0
- package/out/web/assets/prompt-thai-500-normal-D7YNqUJD.woff +0 -0
- package/out/web/assets/prompt-thai-600-normal-CYPViXds.woff +0 -0
- package/out/web/assets/prompt-thai-600-normal-MrdfU7zR.woff2 +0 -0
- package/out/web/assets/prompt-thai-700-normal-Cb5ilR-c.woff +0 -0
- package/out/web/assets/prompt-thai-700-normal-Cg4aQ0Nn.woff2 +0 -0
- package/out/web/assets/stateDiagram-v2-4QOOHH4V-DeEc0lGZ.js +0 -1
- package/out/web/assets/swimlanesDiagram-VK2B7HYN-DpVik9v7.js +0 -8
- package/out/web/assets/window-5qYXKoW7.js +0 -1
- package/skills-lock.json +0 -77
- package/src/renderer/public/Live2DCubismCore.js +0 -9
- package/src/renderer/src/companionWidget.ts +0 -95
- package/src/renderer/src/components/Live2DStage.tsx +0 -412
- package/src/renderer/src/components/ModelPanel.tsx +0 -155
- package/src/renderer/src/css/model.css +0 -628
- package/src/renderer/src-web/companionWidget.ts +0 -37
- package/src/renderer/src-web/components/ModelPanel.tsx +0 -12
- package/src/renderer/src-web/css/model.css +0 -628
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { useCallback, useEffect, useId, useRef, useState } from 'react'
|
|
2
|
+
import { createPortal } from 'react-dom'
|
|
3
|
+
import { Paperclip, X } from 'lucide-react'
|
|
4
|
+
import type { AgentProgress } from '../types'
|
|
5
|
+
import { useSessionSources } from '../utils/useSessionSources'
|
|
6
|
+
import SessionSources from './SessionSources'
|
|
7
|
+
import '../css/session-sources-popover.css'
|
|
8
|
+
|
|
9
|
+
export default function SessionSourcesPopover({ chatId, liveProgress, open, onOpenChange }: {
|
|
10
|
+
chatId: string; liveProgress: AgentProgress[]; open: boolean; onOpenChange: (open: boolean) => void
|
|
11
|
+
}) {
|
|
12
|
+
const [position, setPosition] = useState({ left: 12, top: 64, maxHeight: 400 })
|
|
13
|
+
const trigger = useRef<HTMLButtonElement>(null)
|
|
14
|
+
const panel = useRef<HTMLElement>(null)
|
|
15
|
+
const closeButton = useRef<HTMLButtonElement>(null)
|
|
16
|
+
const id = useId()
|
|
17
|
+
const { sources, loading, error, retry } = useSessionSources(chatId, liveProgress, open)
|
|
18
|
+
const close = useCallback((restoreFocus = false) => {
|
|
19
|
+
onOpenChange(false)
|
|
20
|
+
if (restoreFocus) trigger.current?.focus()
|
|
21
|
+
}, [onOpenChange])
|
|
22
|
+
const reposition = useCallback(() => {
|
|
23
|
+
const bounds = trigger.current?.getBoundingClientRect()
|
|
24
|
+
if (!bounds) return
|
|
25
|
+
const width = Math.min(360, window.innerWidth - 24)
|
|
26
|
+
const top = bounds.bottom + 8
|
|
27
|
+
setPosition({ left: Math.max(12, Math.min(bounds.right - width, window.innerWidth - width - 12)), top, maxHeight: Math.max(0, window.innerHeight - top - 12) })
|
|
28
|
+
}, [])
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
if (!open) return
|
|
31
|
+
reposition()
|
|
32
|
+
closeButton.current?.focus()
|
|
33
|
+
const outside = (event: MouseEvent) => {
|
|
34
|
+
if (!trigger.current?.contains(event.target as Node) && !panel.current?.contains(event.target as Node)) close()
|
|
35
|
+
}
|
|
36
|
+
const key = (event: KeyboardEvent) => { if (event.key === 'Escape') { event.preventDefault(); close(true) } }
|
|
37
|
+
document.addEventListener('mousedown', outside)
|
|
38
|
+
window.addEventListener('keydown', key)
|
|
39
|
+
window.addEventListener('resize', reposition)
|
|
40
|
+
window.addEventListener('scroll', reposition, true)
|
|
41
|
+
return () => {
|
|
42
|
+
document.removeEventListener('mousedown', outside)
|
|
43
|
+
window.removeEventListener('keydown', key)
|
|
44
|
+
window.removeEventListener('resize', reposition)
|
|
45
|
+
window.removeEventListener('scroll', reposition, true)
|
|
46
|
+
}
|
|
47
|
+
}, [open, close, reposition])
|
|
48
|
+
return <>
|
|
49
|
+
<button ref={trigger} type="button" className={`session-sources-toggle${open ? ' is-open' : ''}`} aria-label="Open session sources" aria-haspopup="dialog" aria-expanded={open} aria-controls={open ? id : undefined} title="Sources for this session" onClick={() => { reposition(); onOpenChange(!open) }}>
|
|
50
|
+
<Paperclip size={15} aria-hidden="true" /><span>Sources</span>
|
|
51
|
+
</button>
|
|
52
|
+
{open && createPortal(<section ref={panel} id={id} className="session-sources-popover" role="dialog" aria-label="Session sources" style={position}>
|
|
53
|
+
<button ref={closeButton} type="button" className="session-sources-close" aria-label="Close session sources" onClick={() => close(true)}><X size={16} aria-hidden="true" /></button>
|
|
54
|
+
<SessionSources key={chatId} sources={sources} loading={loading} error={error} onRetry={retry} onOpenLibrary={url => {
|
|
55
|
+
window.history.pushState({}, '', url)
|
|
56
|
+
window.dispatchEvent(new PopStateEvent('popstate'))
|
|
57
|
+
close()
|
|
58
|
+
}} />
|
|
59
|
+
</section>, document.body)}
|
|
60
|
+
</>
|
|
61
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import SelectField from '../SelectField'
|
|
1
2
|
import React, { useEffect, useState } from 'react'
|
|
2
3
|
import { DEFAULT_CONFIG } from '../../constants/config'
|
|
3
4
|
import { HF_MODELS } from '../../constants/models'
|
|
@@ -260,19 +261,19 @@ export default function AgentsTab({ config, updateField, dynamicOllamaModels = [
|
|
|
260
261
|
|
|
261
262
|
<div className="setting-row">
|
|
262
263
|
<label>AI provider</label>
|
|
263
|
-
<
|
|
264
|
+
<SelectField aria-label="AI provider" value={provider} onValueChange={(nextValue) => handleProviderChange(nextValue)}>
|
|
264
265
|
{availableProviders.map(p => (
|
|
265
266
|
<option key={p.value} value={p.value}>{p.label}</option>
|
|
266
267
|
))}
|
|
267
|
-
</
|
|
268
|
+
</SelectField>
|
|
268
269
|
</div>
|
|
269
270
|
|
|
270
271
|
<div className="setting-row">
|
|
271
272
|
<label>Model name</label>
|
|
272
|
-
<
|
|
273
|
+
<SelectField aria-label="Model name"
|
|
273
274
|
value={isCustomModel ? 'custom' : model}
|
|
274
|
-
|
|
275
|
-
const val =
|
|
275
|
+
onValueChange={(nextValue) => {
|
|
276
|
+
const val = nextValue
|
|
276
277
|
if (val === 'custom') {
|
|
277
278
|
setModel('')
|
|
278
279
|
} else {
|
|
@@ -284,7 +285,7 @@ export default function AgentsTab({ config, updateField, dynamicOllamaModels = [
|
|
|
284
285
|
<option key={m} value={m}>{m}</option>
|
|
285
286
|
))}
|
|
286
287
|
<option value="custom">Custom...</option>
|
|
287
|
-
</
|
|
288
|
+
</SelectField>
|
|
288
289
|
</div>
|
|
289
290
|
|
|
290
291
|
{isCustomModel && (
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import SelectField from '../SelectField'
|
|
1
2
|
import React, { useState } from 'react'
|
|
2
3
|
import { DEFAULT_CONFIG } from '../../constants/config'
|
|
3
4
|
import { GEMINI_LIVE_VOICES } from '../../constants/models'
|
|
@@ -84,14 +85,14 @@ export default function AudioTab({ config, updateField, apiKey }: AudioTabProps)
|
|
|
84
85
|
<div className="form-grid single">
|
|
85
86
|
<div className="setting-row">
|
|
86
87
|
<label>Real-time model{liveLoading && <span style={{ marginLeft: 6, opacity: 0.5, fontSize: '0.8em' }}>loading…</span>}</label>
|
|
87
|
-
<
|
|
88
|
+
<SelectField aria-label="Real-time model"
|
|
88
89
|
value={isCustomLiveModel ? 'custom' : config.geminiLiveModel}
|
|
89
|
-
|
|
90
|
-
if (
|
|
90
|
+
onValueChange={(nextValue) => {
|
|
91
|
+
if (nextValue === 'custom') {
|
|
91
92
|
setCustomLiveModel(true)
|
|
92
93
|
} else {
|
|
93
94
|
setCustomLiveModel(false)
|
|
94
|
-
updateField('geminiLiveModel',
|
|
95
|
+
updateField('geminiLiveModel', nextValue)
|
|
95
96
|
}
|
|
96
97
|
}}
|
|
97
98
|
>
|
|
@@ -99,7 +100,7 @@ export default function AudioTab({ config, updateField, apiKey }: AudioTabProps)
|
|
|
99
100
|
<option key={model} value={model}>{model}</option>
|
|
100
101
|
))}
|
|
101
102
|
<option value="custom">Custom...</option>
|
|
102
|
-
</
|
|
103
|
+
</SelectField>
|
|
103
104
|
<p className="hint">
|
|
104
105
|
The model Gemini Live uses for realtime voice conversations.
|
|
105
106
|
"gemini-3.1-flash-live-preview" requires requesting allowlist access from Google first — if it
|
|
@@ -119,11 +120,11 @@ export default function AudioTab({ config, updateField, apiKey }: AudioTabProps)
|
|
|
119
120
|
)}
|
|
120
121
|
<div className="setting-row">
|
|
121
122
|
<label>Live voice</label>
|
|
122
|
-
<
|
|
123
|
+
<SelectField aria-label="Live voice" value={config.geminiLiveVoice} onValueChange={(nextValue) => updateField('geminiLiveVoice', nextValue)}>
|
|
123
124
|
{GEMINI_LIVE_VOICES.map((voiceName) => (
|
|
124
125
|
<option key={voiceName} value={voiceName}>{voiceName}</option>
|
|
125
126
|
))}
|
|
126
|
-
</
|
|
127
|
+
</SelectField>
|
|
127
128
|
<p className="hint">
|
|
128
129
|
The voice Gemini Live speaks with. Can also be changed mid-call from the Live overlay itself.
|
|
129
130
|
</p>
|
|
@@ -86,8 +86,8 @@ export default function AutomationTab({
|
|
|
86
86
|
</div>
|
|
87
87
|
<div className="toggle-row">
|
|
88
88
|
<div>
|
|
89
|
-
<label>
|
|
90
|
-
<p className="hint">
|
|
89
|
+
<label>Suggest a skill after finishing a hard task</label>
|
|
90
|
+
<p className="hint">Proposes reusable instructions after a multi-step task. Review and approve each change before it is saved.</p>
|
|
91
91
|
</div>
|
|
92
92
|
<label className="settings-toggle-switch">
|
|
93
93
|
<input
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import SelectField from '../SelectField'
|
|
1
2
|
import React from 'react'
|
|
2
3
|
import { DEFAULT_CONFIG } from '../../constants/config'
|
|
3
4
|
import {
|
|
@@ -369,11 +370,11 @@ export default function GeneralTab({
|
|
|
369
370
|
return (
|
|
370
371
|
<div className="setting-row wide">
|
|
371
372
|
<label>Active model</label>
|
|
372
|
-
<
|
|
373
|
+
<SelectField aria-label="Active model"
|
|
373
374
|
value={currentModel}
|
|
374
|
-
|
|
375
|
+
onValueChange={(nextValue) => updateField('customModelSelections', {
|
|
375
376
|
...(config.customModelSelections ?? {}),
|
|
376
|
-
[activeId]:
|
|
377
|
+
[activeId]: nextValue
|
|
377
378
|
})}
|
|
378
379
|
>
|
|
379
380
|
{cp.models.map(m => (
|
|
@@ -381,7 +382,7 @@ export default function GeneralTab({
|
|
|
381
382
|
{m.displayName || m.modelId}
|
|
382
383
|
</option>
|
|
383
384
|
))}
|
|
384
|
-
</
|
|
385
|
+
</SelectField>
|
|
385
386
|
</div>
|
|
386
387
|
)
|
|
387
388
|
})()}
|
|
@@ -724,15 +725,15 @@ export default function GeneralTab({
|
|
|
724
725
|
<div className="provider-card-body">
|
|
725
726
|
<div className="setting-row">
|
|
726
727
|
<label>Gemini model</label>
|
|
727
|
-
<
|
|
728
|
+
<SelectField aria-label="Gemini model"
|
|
728
729
|
value={dynamicGeminiModels.includes(config.geminiModel) ? config.geminiModel : 'custom'}
|
|
729
|
-
|
|
730
|
+
onValueChange={(nextValue) => updateField('geminiModel', nextValue)}
|
|
730
731
|
>
|
|
731
732
|
{dynamicGeminiModels.map(model => (
|
|
732
733
|
<option key={model} value={model}>{model}</option>
|
|
733
734
|
))}
|
|
734
735
|
<option value="custom">Custom...</option>
|
|
735
|
-
</
|
|
736
|
+
</SelectField>
|
|
736
737
|
</div>
|
|
737
738
|
{(!dynamicGeminiModels.includes(config.geminiModel) || config.geminiModel === 'custom') && (
|
|
738
739
|
<div className="setting-row">
|
|
@@ -776,15 +777,15 @@ export default function GeneralTab({
|
|
|
776
777
|
<div className="provider-card-body">
|
|
777
778
|
<div className="setting-row">
|
|
778
779
|
<label>Anthropic model</label>
|
|
779
|
-
<
|
|
780
|
+
<SelectField aria-label="Anthropic model"
|
|
780
781
|
value={dynamicAnthropicModels.includes(config.anthropicModel) ? config.anthropicModel : 'custom'}
|
|
781
|
-
|
|
782
|
+
onValueChange={(nextValue) => updateField('anthropicModel', nextValue)}
|
|
782
783
|
>
|
|
783
784
|
{dynamicAnthropicModels.map(model => (
|
|
784
785
|
<option key={model} value={model}>{model}</option>
|
|
785
786
|
))}
|
|
786
787
|
<option value="custom">Custom...</option>
|
|
787
|
-
</
|
|
788
|
+
</SelectField>
|
|
788
789
|
</div>
|
|
789
790
|
{(!dynamicAnthropicModels.includes(config.anthropicModel) || config.anthropicModel === 'custom') && (
|
|
790
791
|
<div className="setting-row">
|
|
@@ -828,15 +829,15 @@ export default function GeneralTab({
|
|
|
828
829
|
<div className="provider-card-body">
|
|
829
830
|
<div className="setting-row">
|
|
830
831
|
<label>OpenAI Model</label>
|
|
831
|
-
<
|
|
832
|
+
<SelectField aria-label="OpenAI Model"
|
|
832
833
|
value={dynamicOpenAIModels.includes(config.openaiModel) ? config.openaiModel : 'custom'}
|
|
833
|
-
|
|
834
|
+
onValueChange={(nextValue) => updateField('openaiModel', nextValue)}
|
|
834
835
|
>
|
|
835
836
|
{dynamicOpenAIModels.map(model => (
|
|
836
837
|
<option key={model} value={model}>{model}</option>
|
|
837
838
|
))}
|
|
838
839
|
<option value="custom">Custom...</option>
|
|
839
|
-
</
|
|
840
|
+
</SelectField>
|
|
840
841
|
</div>
|
|
841
842
|
{(!dynamicOpenAIModels.includes(config.openaiModel) || config.openaiModel === 'custom') && (
|
|
842
843
|
<div className="setting-row">
|
|
@@ -934,15 +935,15 @@ export default function GeneralTab({
|
|
|
934
935
|
<div className="provider-card-body">
|
|
935
936
|
<div className="setting-row">
|
|
936
937
|
<label>DeepSeek Model</label>
|
|
937
|
-
<
|
|
938
|
+
<SelectField aria-label="DeepSeek Model"
|
|
938
939
|
value={dynamicDeepSeekModels.includes(config.deepseekModel) ? config.deepseekModel : 'custom'}
|
|
939
|
-
|
|
940
|
+
onValueChange={(nextValue) => updateField('deepseekModel', nextValue)}
|
|
940
941
|
>
|
|
941
942
|
{dynamicDeepSeekModels.map(model => (
|
|
942
943
|
<option key={model} value={model}>{model}</option>
|
|
943
944
|
))}
|
|
944
945
|
<option value="custom">Custom...</option>
|
|
945
|
-
</
|
|
946
|
+
</SelectField>
|
|
946
947
|
</div>
|
|
947
948
|
{(!dynamicDeepSeekModels.includes(config.deepseekModel) || config.deepseekModel === 'custom') && (
|
|
948
949
|
<div className="setting-row">
|
|
@@ -986,15 +987,15 @@ export default function GeneralTab({
|
|
|
986
987
|
<div className="provider-card-body">
|
|
987
988
|
<div className="setting-row">
|
|
988
989
|
<label>Hugging Face model</label>
|
|
989
|
-
<
|
|
990
|
+
<SelectField aria-label="Hugging Face model"
|
|
990
991
|
value={(HF_MODELS as readonly string[]).includes(config.hfModel) ? config.hfModel : 'custom'}
|
|
991
|
-
|
|
992
|
+
onValueChange={(nextValue) => updateField('hfModel', nextValue)}
|
|
992
993
|
>
|
|
993
994
|
{HF_MODELS.map(model => (
|
|
994
995
|
<option key={model} value={model}>{model}</option>
|
|
995
996
|
))}
|
|
996
997
|
<option value="custom">Custom...</option>
|
|
997
|
-
</
|
|
998
|
+
</SelectField>
|
|
998
999
|
</div>
|
|
999
1000
|
{(!(HF_MODELS as readonly string[]).includes(config.hfModel) || config.hfModel === 'custom') && (
|
|
1000
1001
|
<div className="setting-row">
|
|
@@ -1038,15 +1039,15 @@ export default function GeneralTab({
|
|
|
1038
1039
|
<div className="provider-card-body">
|
|
1039
1040
|
<div className="setting-row">
|
|
1040
1041
|
<label>LM Studio Model</label>
|
|
1041
|
-
<
|
|
1042
|
+
<SelectField aria-label="LM Studio Model"
|
|
1042
1043
|
value={dynamicLocalModels.includes(config.localModelName) ? config.localModelName : 'custom'}
|
|
1043
|
-
|
|
1044
|
+
onValueChange={(nextValue) => updateField('localModelName', nextValue)}
|
|
1044
1045
|
>
|
|
1045
1046
|
{dynamicLocalModels.map(model => (
|
|
1046
1047
|
<option key={model} value={model}>{model}</option>
|
|
1047
1048
|
))}
|
|
1048
1049
|
<option value="custom">Custom...</option>
|
|
1049
|
-
</
|
|
1050
|
+
</SelectField>
|
|
1050
1051
|
</div>
|
|
1051
1052
|
{(!dynamicLocalModels.includes(config.localModelName) || config.localModelName === 'custom') && (
|
|
1052
1053
|
<div className="setting-row">
|
|
@@ -1091,9 +1092,9 @@ export default function GeneralTab({
|
|
|
1091
1092
|
<div className="provider-card-body">
|
|
1092
1093
|
<div className="setting-row">
|
|
1093
1094
|
<label>Ollama model</label>
|
|
1094
|
-
<
|
|
1095
|
+
<SelectField aria-label="Ollama model"
|
|
1095
1096
|
value={dynamicOllamaModels.includes(config.ollamaModel) ? config.ollamaModel : 'custom'}
|
|
1096
|
-
|
|
1097
|
+
onValueChange={(nextValue) => updateField('ollamaModel', nextValue)}
|
|
1097
1098
|
>
|
|
1098
1099
|
{dynamicOllamaModels.map(model => (
|
|
1099
1100
|
<option key={model} value={model}>{model}</option>
|
|
@@ -1102,7 +1103,7 @@ export default function GeneralTab({
|
|
|
1102
1103
|
<option value={config.ollamaModel}>{config.ollamaModel}</option>
|
|
1103
1104
|
)}
|
|
1104
1105
|
<option value="custom">Custom...</option>
|
|
1105
|
-
</
|
|
1106
|
+
</SelectField>
|
|
1106
1107
|
</div>
|
|
1107
1108
|
{(!dynamicOllamaModels.includes(config.ollamaModel) || config.ollamaModel === 'custom') && (
|
|
1108
1109
|
<div className="setting-row">
|
|
@@ -1308,14 +1309,14 @@ export default function GeneralTab({
|
|
|
1308
1309
|
{modelField && opts.length > 0 && (
|
|
1309
1310
|
<div className="setting-row">
|
|
1310
1311
|
<label>{prov.label} Model</label>
|
|
1311
|
-
<
|
|
1312
|
+
<SelectField aria-label="Model" value={currentModel} onValueChange={(nextValue) => updateField(modelField, nextValue)}>
|
|
1312
1313
|
{opts.map(m => (
|
|
1313
1314
|
<option key={m.value} value={m.value}>{m.label}</option>
|
|
1314
1315
|
))}
|
|
1315
1316
|
{currentModel && !opts.some(m => m.value === currentModel) && (
|
|
1316
1317
|
<option key={currentModel} value={currentModel}>{currentModel}</option>
|
|
1317
1318
|
)}
|
|
1318
|
-
</
|
|
1319
|
+
</SelectField>
|
|
1319
1320
|
</div>
|
|
1320
1321
|
)}
|
|
1321
1322
|
{prov.keyField ? (
|
|
@@ -1374,11 +1375,11 @@ export default function GeneralTab({
|
|
|
1374
1375
|
const veoOpts = dynamicVideoModels?.veo || VEO_STUDIO_MODELS.veo || []
|
|
1375
1376
|
const currentVeoModel = config.veoModel || 'veo-3.1-generate-preview'
|
|
1376
1377
|
return (
|
|
1377
|
-
<
|
|
1378
|
+
<SelectField aria-label="Default Veo model"
|
|
1378
1379
|
value={currentVeoModel}
|
|
1379
|
-
|
|
1380
|
-
updateField('veoModel',
|
|
1381
|
-
setActiveModel('veoModel',
|
|
1380
|
+
onValueChange={(nextValue) => {
|
|
1381
|
+
updateField('veoModel', nextValue)
|
|
1382
|
+
setActiveModel('veoModel', nextValue, 'video')
|
|
1382
1383
|
}}
|
|
1383
1384
|
>
|
|
1384
1385
|
{veoOpts.map((m) => (
|
|
@@ -1387,7 +1388,7 @@ export default function GeneralTab({
|
|
|
1387
1388
|
{currentVeoModel && !veoOpts.some((m) => m.value === currentVeoModel) && (
|
|
1388
1389
|
<option key={currentVeoModel} value={currentVeoModel}>{currentVeoModel}</option>
|
|
1389
1390
|
)}
|
|
1390
|
-
</
|
|
1391
|
+
</SelectField>
|
|
1391
1392
|
)
|
|
1392
1393
|
})()}
|
|
1393
1394
|
</div>
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { renderToStaticMarkup } from 'react-dom/server'
|
|
3
|
+
import { describe, expect, it } from 'vitest'
|
|
4
|
+
import MemoryTab from './MemoryTab'
|
|
5
|
+
|
|
6
|
+
const render = (preferences: string) => renderToStaticMarkup(<MemoryTab
|
|
7
|
+
userName="Pheem"
|
|
8
|
+
setUserName={() => { throw new Error('Rendering must not rewrite the name') }}
|
|
9
|
+
userPreferences={preferences}
|
|
10
|
+
setUserPreferences={() => { throw new Error('Rendering must not rewrite preferences') }}
|
|
11
|
+
/>)
|
|
12
|
+
|
|
13
|
+
describe('Memory & Profile reading view', () => {
|
|
14
|
+
it('preserves the original text and line breaks in a continuous reading view', () => {
|
|
15
|
+
const preferences = 'Talk in Thai; Keep explanations concise;\nPrefer TypeScript.'
|
|
16
|
+
const html = render(preferences)
|
|
17
|
+
expect(html).toContain(preferences)
|
|
18
|
+
expect(html).not.toContain('<li')
|
|
19
|
+
expect(html).toContain('Edit instructions')
|
|
20
|
+
expect(html).not.toContain('<textarea')
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
it('offers an explicit way to add instructions when memory is empty', () => {
|
|
24
|
+
const html = render(' ')
|
|
25
|
+
expect(html).toContain('Add instructions')
|
|
26
|
+
expect(html).not.toContain('<li')
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
it('associates the editable name with a label and explains its scope', () => {
|
|
30
|
+
const html = render('Keep it short.')
|
|
31
|
+
expect(html).toMatch(/<label[^>]* for="([^"]+)"[^>]*>What should Mint call you\?<\/label>/)
|
|
32
|
+
const id = html.match(/<label[^>]* for="([^"]+)"/)![1]
|
|
33
|
+
expect(html).toContain(`id="${id}"`)
|
|
34
|
+
expect(html).toContain('value="Pheem"')
|
|
35
|
+
expect(html).toContain('Across all sessions and projects')
|
|
36
|
+
})
|
|
37
|
+
})
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import React from 'react'
|
|
1
|
+
import React, { useId, useRef, useState } from 'react'
|
|
2
|
+
import '../../css/settings/memory.css'
|
|
2
3
|
|
|
3
4
|
interface MemoryTabProps {
|
|
4
5
|
userName: string
|
|
@@ -13,45 +14,84 @@ export default function MemoryTab({
|
|
|
13
14
|
userPreferences,
|
|
14
15
|
setUserPreferences
|
|
15
16
|
}: MemoryTabProps) {
|
|
17
|
+
const id = useId()
|
|
18
|
+
const [editing, setEditing] = useState(false)
|
|
19
|
+
const modeButton = useRef<HTMLButtonElement>(null)
|
|
20
|
+
const hasPreferences = Boolean(userPreferences.trim())
|
|
21
|
+
|
|
16
22
|
return (
|
|
17
|
-
<div className="tab-pane active
|
|
18
|
-
<
|
|
19
|
-
<
|
|
23
|
+
<div className="tab-pane active memory-tab">
|
|
24
|
+
<header className="memory-intro">
|
|
25
|
+
<p className="section-kicker">Across all sessions and projects</p>
|
|
26
|
+
<h2>What Mint remembers about you</h2>
|
|
27
|
+
<p>Your name and response preferences follow you in CLI, Web, and Desktop.</p>
|
|
28
|
+
</header>
|
|
29
|
+
|
|
30
|
+
<section className="memory-name-section" aria-labelledby={`${id}-name-label`}>
|
|
31
|
+
<label id={`${id}-name-label`} htmlFor={`${id}-name`}>What should Mint call you?</label>
|
|
32
|
+
<input
|
|
33
|
+
id={`${id}-name`}
|
|
34
|
+
type="text"
|
|
35
|
+
autoComplete="nickname"
|
|
36
|
+
value={userName}
|
|
37
|
+
onChange={(e) => setUserName(e.target.value)}
|
|
38
|
+
placeholder="Your name or nickname"
|
|
39
|
+
aria-describedby={`${id}-name-hint`}
|
|
40
|
+
/>
|
|
41
|
+
<p id={`${id}-name-hint`} className="memory-helper">The name Mint uses when talking with you.</p>
|
|
42
|
+
</section>
|
|
43
|
+
|
|
44
|
+
<section className="memory-instructions-section" aria-labelledby={`${id}-instructions-heading`}>
|
|
45
|
+
<div className="memory-section-heading">
|
|
20
46
|
<div>
|
|
21
|
-
<
|
|
22
|
-
<
|
|
47
|
+
<h3 id={`${id}-instructions-heading`}>How Mint should respond</h3>
|
|
48
|
+
<p className="memory-helper">Your preferred language, tone, and everyday instructions.</p>
|
|
23
49
|
</div>
|
|
50
|
+
<button
|
|
51
|
+
ref={modeButton}
|
|
52
|
+
type="button"
|
|
53
|
+
className="btn-secondary memory-mode-button"
|
|
54
|
+
aria-controls={`${id}-instructions`}
|
|
55
|
+
onClick={() => {
|
|
56
|
+
setEditing(!editing)
|
|
57
|
+
if (editing) modeButton.current?.focus()
|
|
58
|
+
}}
|
|
59
|
+
>
|
|
60
|
+
{editing ? 'Reading view' : hasPreferences ? 'Edit instructions' : 'Add instructions'}
|
|
61
|
+
</button>
|
|
24
62
|
</div>
|
|
25
63
|
|
|
26
|
-
<div className="
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
<
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
64
|
+
<div id={`${id}-instructions`} className="memory-instructions-content">
|
|
65
|
+
{editing ? (
|
|
66
|
+
<>
|
|
67
|
+
<label className="memory-editor-label" htmlFor={`${id}-editor`}>Response preferences & instructions</label>
|
|
68
|
+
<textarea
|
|
69
|
+
id={`${id}-editor`}
|
|
70
|
+
className="memory-editor"
|
|
71
|
+
autoFocus
|
|
72
|
+
rows={10}
|
|
73
|
+
value={userPreferences}
|
|
74
|
+
onChange={(e) => setUserPreferences(e.target.value)}
|
|
75
|
+
placeholder={'Talk in Thai.\nKeep explanations concise.\nExplain coding concepts step by step.'}
|
|
76
|
+
aria-describedby={`${id}-edit-hint`}
|
|
35
77
|
/>
|
|
36
|
-
<p className="
|
|
78
|
+
<p id={`${id}-edit-hint`} className="memory-helper">Write one instruction per line for easier reading. Select Save Settings to save your changes.</p>
|
|
79
|
+
</>
|
|
80
|
+
) : hasPreferences ? (
|
|
81
|
+
<div className="memory-reading-frame" tabIndex={0} role="region" aria-label="Response preferences and instructions">{userPreferences}</div>
|
|
82
|
+
) : (
|
|
83
|
+
<div className="memory-empty">
|
|
84
|
+
<p>No response preferences added yet.</p>
|
|
85
|
+
<p className="memory-helper">Add the language, tone, or habits you want Mint to remember.</p>
|
|
37
86
|
</div>
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
<div className="setting-row">
|
|
41
|
-
<label>Custom instructions & preferences</label>
|
|
42
|
-
<div className="memory-field-container">
|
|
43
|
-
<textarea
|
|
44
|
-
value={userPreferences}
|
|
45
|
-
onChange={(e) => setUserPreferences(e.target.value)}
|
|
46
|
-
placeholder="e.g. Explain coding concepts step-by-step. Prefer TypeScript. Talk in Thai. Keep explanations concise."
|
|
47
|
-
style={{ minHeight: '120px', resize: 'vertical' }}
|
|
48
|
-
/>
|
|
49
|
-
<p className="hint">Preferences, guidelines, or persona instructions for the assistant.</p>
|
|
50
|
-
</div>
|
|
51
|
-
</div>
|
|
87
|
+
)}
|
|
52
88
|
</div>
|
|
53
89
|
</section>
|
|
90
|
+
|
|
91
|
+
<aside className="memory-scope-note" aria-label="About this memory">
|
|
92
|
+
<strong>About this memory</strong>
|
|
93
|
+
<p>This page contains your shared profile and preferences. Saved facts, project memory, and conversation history are stored separately.</p>
|
|
94
|
+
</aside>
|
|
54
95
|
</div>
|
|
55
96
|
)
|
|
56
97
|
}
|
|
57
|
-
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { renderToStaticMarkup } from 'react-dom/server'
|
|
3
|
+
import { expect, it } from 'vitest'
|
|
4
|
+
import NotificationsTab from './NotificationsTab'
|
|
5
|
+
|
|
6
|
+
it('shows notification categories with accessible switches and permission controls', () => {
|
|
7
|
+
const html = renderToStaticMarkup(<NotificationsTab settings={{ enabled: false }} onChange={() => {}} />)
|
|
8
|
+
expect(html).toContain('AI replies')
|
|
9
|
+
expect(html).toContain('Approval requests')
|
|
10
|
+
expect(html).toContain('System & background tasks')
|
|
11
|
+
expect(html).toContain('aria-label="Enable notifications"')
|
|
12
|
+
expect(html).toContain('disabled=""')
|
|
13
|
+
expect(html).toContain('Check permission')
|
|
14
|
+
expect(html).toContain('Send test notification')
|
|
15
|
+
})
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import React, { useEffect, useState } from 'react'
|
|
2
|
+
import { notificationPermission, readNotificationSettings, type NotificationSettings } from '../../utils/notificationSettings'
|
|
3
|
+
import '../../css/settings/notifications.css'
|
|
4
|
+
|
|
5
|
+
export default function NotificationsTab({ settings, onChange }: {
|
|
6
|
+
settings: unknown; onChange: (settings: NotificationSettings) => void
|
|
7
|
+
}) {
|
|
8
|
+
const preferences = readNotificationSettings(settings)
|
|
9
|
+
const [permission, setPermission] = useState<string>('Checking…')
|
|
10
|
+
const [busy, setBusy] = useState(false)
|
|
11
|
+
const [message, setMessage] = useState('')
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
let disposed = false
|
|
14
|
+
const refresh = () => {
|
|
15
|
+
notificationPermission().then(value => { if (!disposed) setPermission(value) })
|
|
16
|
+
.catch(() => { if (!disposed) setPermission('Could not check permission') })
|
|
17
|
+
}
|
|
18
|
+
refresh()
|
|
19
|
+
window.addEventListener('focus', refresh)
|
|
20
|
+
return () => { disposed = true; window.removeEventListener('focus', refresh) }
|
|
21
|
+
}, [])
|
|
22
|
+
const run = async (test: boolean) => {
|
|
23
|
+
setBusy(true)
|
|
24
|
+
setMessage('')
|
|
25
|
+
try {
|
|
26
|
+
const granted = await notificationPermission(true)
|
|
27
|
+
setPermission(granted)
|
|
28
|
+
if (granted !== 'granted') {
|
|
29
|
+
setMessage(granted === 'unsupported' ? 'Notifications are unavailable in this browser.' : 'Allow notifications in your browser or system settings, then check permission again.')
|
|
30
|
+
} else if (test) {
|
|
31
|
+
await window.api.notifyAiResponse('Your Mint notifications are working.')
|
|
32
|
+
setMessage('Test notification sent. If it does not appear, check your system’s Do Not Disturb setting.')
|
|
33
|
+
}
|
|
34
|
+
} catch (error) {
|
|
35
|
+
setMessage(error instanceof Error ? error.message : String(error))
|
|
36
|
+
} finally { setBusy(false) }
|
|
37
|
+
}
|
|
38
|
+
const toggle = (key: keyof NotificationSettings, title: string, description: string) => (
|
|
39
|
+
<div className="toggle-row" key={key}>
|
|
40
|
+
<div><label htmlFor={'notifications-' + key}>{title}</label><p className="hint">{description}</p></div>
|
|
41
|
+
<label className="settings-toggle-switch">
|
|
42
|
+
<input id={'notifications-' + key} type="checkbox" aria-label={title}
|
|
43
|
+
checked={preferences[key]} disabled={key !== 'enabled' && !preferences.enabled}
|
|
44
|
+
onChange={event => onChange({ ...preferences, [key]: event.target.checked })} />
|
|
45
|
+
<span className="settings-toggle-slider" />
|
|
46
|
+
</label>
|
|
47
|
+
</div>
|
|
48
|
+
)
|
|
49
|
+
return (
|
|
50
|
+
<div className="tab-pane active notifications-tab">
|
|
51
|
+
<section className="setting-section">
|
|
52
|
+
<div className="section-heading"><div><p className="section-kicker">Stay informed</p><h2 className="section-title">Notifications</h2></div></div>
|
|
53
|
+
<p className="hint">Choose what Mint shows in Desktop and Web. Select Save Settings to apply your changes.</p>
|
|
54
|
+
<div className="toggle-card">{toggle('enabled', 'Enable notifications', 'Turn Mint notifications on or off.')}</div>
|
|
55
|
+
</section>
|
|
56
|
+
<section className="setting-section">
|
|
57
|
+
<h3>Notification types</h3>
|
|
58
|
+
<div className="toggle-card">
|
|
59
|
+
{toggle('replies', 'AI replies', 'Notify when a response finishes while Mint is in the background.')}
|
|
60
|
+
{toggle('approvals', 'Approval requests', 'Notify when Mint needs your approval or an answer while in the background.')}
|
|
61
|
+
{toggle('system', 'System & background tasks', 'Battery, connection changes, and queued task updates on Desktop.')}
|
|
62
|
+
</div>
|
|
63
|
+
</section>
|
|
64
|
+
<section className="setting-section">
|
|
65
|
+
<h3>Where notifications appear</h3>
|
|
66
|
+
<div className="toggle-card">
|
|
67
|
+
{toggle('os', 'System notifications', 'Show an operating system popup while Mint is in the background.')}
|
|
68
|
+
{toggle('inApp', 'In-app notices', 'Show system and background task updates inside Mint.')}
|
|
69
|
+
</div>
|
|
70
|
+
</section>
|
|
71
|
+
<section className="setting-section notifications-permission">
|
|
72
|
+
<h3>Notification permission</h3>
|
|
73
|
+
<p className="hint">Permission is specific to this browser or Desktop installation.</p>
|
|
74
|
+
<p className="notifications-permission-state" role="status">Status: <strong>{permission}</strong></p>
|
|
75
|
+
{permission === 'denied' && <p className="hint">Notifications are blocked. Allow them in your browser or system settings.</p>}
|
|
76
|
+
<div className="notifications-actions">
|
|
77
|
+
<button type="button" className="btn-secondary" disabled={busy || permission === 'unsupported'} onClick={() => void run(false)}>Check permission</button>
|
|
78
|
+
<button type="button" className="btn-secondary" disabled={busy || !preferences.enabled || !preferences.os || permission === 'unsupported'} onClick={() => void run(true)}>Send test notification</button>
|
|
79
|
+
</div>
|
|
80
|
+
{message && <p className="notifications-feedback" role="status">{message}</p>}
|
|
81
|
+
</section>
|
|
82
|
+
</div>
|
|
83
|
+
)
|
|
84
|
+
}
|