@pheem49/mint 1.15.0 → 1.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Cargo.lock +1012 -69
- package/Cargo.toml +5 -2
- package/LICENSE +21 -654
- package/README.md +92 -817
- package/Release_Note.md +53 -560
- package/apps/mint-companion/src-tauri/Cargo.toml +20 -0
- package/apps/mint-companion/src-tauri/build.rs +3 -0
- package/apps/mint-companion/src-tauri/src/main.rs +468 -0
- package/apps/mint-companion/tsconfig.json +20 -0
- package/apps/mint-companion/vite.config.ts +3 -0
- package/components.json +19 -0
- package/crates/mint-cli/Cargo.toml +6 -0
- package/crates/mint-cli/src/agent/live_status.rs +187 -39
- package/crates/mint-cli/src/agent.rs +323 -95
- package/crates/mint-cli/src/commands/agent.rs +69 -55
- package/crates/mint-cli/src/commands/integrations.rs +7 -0
- package/crates/mint-cli/src/commands/knowledge.rs +12 -32
- package/crates/mint-cli/src/commands/mod.rs +44 -0
- package/crates/mint-cli/src/image.rs +31 -33
- package/crates/mint-cli/src/interactive/chat_tui.rs +3594 -483
- package/crates/mint-cli/src/interactive/input_box.rs +56 -6
- package/crates/mint-cli/src/interactive/slash_commands.rs +208 -56
- package/crates/mint-cli/src/interactive/tool_activity.rs +328 -0
- package/crates/mint-cli/src/interactive.rs +64 -40
- package/crates/mint-cli/src/main.rs +13 -7
- package/crates/mint-cli/src/mcp.rs +5 -0
- package/crates/mint-cli/src/mod_host.rs +6 -0
- package/crates/mint-cli/src/mods_cli.rs +62 -0
- package/crates/mint-cli/src/mods_ui.rs +187 -0
- package/crates/mint-cli/src/onboard.rs +5 -31
- package/crates/mint-cli/src/terminal_theme.rs +3 -1
- package/crates/mint-cli/src/updater.rs +56 -2
- package/crates/mint-cli/tests/library_intake.rs +77 -0
- package/crates/mint-cli/tests/mods_testing.rs +133 -0
- package/crates/mint-companion-protocol/Cargo.toml +10 -0
- package/crates/mint-companion-protocol/src/lib.rs +163 -0
- package/crates/mint-core/Cargo.toml +6 -3
- package/crates/mint-core/build.rs +26 -0
- package/crates/mint-core/src/agent/chat.rs +167 -39
- package/crates/mint-core/src/agent/code_tools.rs +15 -0
- package/crates/mint-core/src/agent/memory/sources.rs +240 -0
- package/crates/mint-core/src/agent/memory.rs +147 -13
- package/crates/mint-core/src/agent/skill_inventory.rs +325 -0
- package/crates/mint-core/src/agent/skills.rs +437 -90
- package/crates/mint-core/src/agent.rs +1 -0
- package/crates/mint-core/src/api_server/routes/background_jobs.rs +310 -0
- package/crates/mint-core/src/api_server/routes/chat.rs +216 -199
- package/crates/mint-core/src/api_server/routes/html_preview.rs +77 -0
- package/crates/mint-core/src/api_server/routes/library.rs +97 -0
- package/crates/mint-core/src/api_server/routes/media_gen.rs +10 -57
- package/crates/mint-core/src/api_server/routes/misc.rs +104 -107
- package/crates/mint-core/src/api_server/routes/mod.rs +6 -0
- package/crates/mint-core/src/api_server/routes/mods.rs +31 -0
- package/crates/mint-core/src/api_server/routes/sessions.rs +41 -0
- package/crates/mint-core/src/api_server/routes/skills_subagents.rs +12 -42
- package/crates/mint-core/src/api_server/routes/slash.rs +50 -1
- package/crates/mint-core/src/api_server/routes/sources.rs +101 -0
- package/crates/mint-core/src/api_server.rs +118 -9
- package/crates/mint-core/src/avatar_bridge.rs +11 -2
- package/crates/mint-core/src/browser/session.rs +52 -0
- package/crates/mint-core/src/companion.rs +716 -0
- package/crates/mint-core/src/cron/scheduler.rs +34 -2
- package/crates/mint-core/src/integrations/channels.rs +87 -345
- package/crates/mint-core/src/integrations/mcp.rs +397 -50
- package/crates/mint-core/src/integrations/mcp_calls.rs +823 -0
- package/crates/mint-core/src/integrations/mcp_catalog.rs +267 -0
- package/crates/mint-core/src/integrations/mcp_device.rs +319 -0
- package/crates/mint-core/src/integrations/mcp_result.rs +356 -0
- package/crates/mint-core/src/integrations/webhooks.rs +539 -0
- package/crates/mint-core/src/integrations.rs +2 -0
- package/crates/mint-core/src/lib.rs +85 -26
- package/crates/mint-core/src/media/gemini_live.rs +134 -14
- package/crates/mint-core/src/media/image_models.rs +3 -27
- package/crates/mint-core/src/media/image_workflow.rs +216 -0
- package/crates/mint-core/src/media/library/intake.rs +144 -0
- package/crates/mint-core/src/media/library/migration.rs +56 -0
- package/crates/mint-core/src/media/library/removal.rs +55 -0
- package/crates/mint-core/src/media/library/tests.rs +730 -0
- package/crates/mint-core/src/media/library/thumbnails.rs +72 -0
- package/crates/mint-core/src/media/library.rs +545 -0
- package/crates/mint-core/src/media/model_catalog.rs +375 -0
- package/crates/mint-core/src/media/pictures.rs +79 -222
- package/crates/mint-core/src/media/video_models.rs +3 -22
- package/crates/mint-core/src/media.rs +3 -0
- package/crates/mint-core/src/mods/manager.rs +1124 -0
- package/crates/mint-core/src/mods/mod.rs +569 -0
- package/crates/mint-core/src/mods/operations.rs +204 -0
- package/crates/mint-core/src/mods/session.rs +146 -0
- package/crates/mint-core/src/mods/slash.rs +59 -0
- package/crates/mint-core/src/mods/telemetry.rs +306 -0
- package/crates/mint-core/src/orchestration/approvals.rs +344 -0
- package/crates/mint-core/src/orchestration/context_render.rs +104 -0
- package/crates/mint-core/src/orchestration/mcp_review.rs +153 -0
- package/crates/mint-core/src/orchestration/memory_skill.rs +104 -32
- package/crates/mint-core/src/orchestration/mod.rs +2139 -244
- package/crates/mint-core/src/orchestration/mod_authoring_regressions.rs +209 -0
- package/crates/mint-core/src/orchestration/progress_clock.rs +80 -0
- package/crates/mint-core/src/orchestration/repeated_failures.rs +116 -0
- package/crates/mint-core/src/orchestration/review_regressions.rs +449 -0
- package/crates/mint-core/src/orchestration/run_control.rs +196 -0
- package/crates/mint-core/src/orchestration/tools/files.rs +161 -14
- package/crates/mint-core/src/orchestration/tools/media.rs +37 -41
- package/crates/mint-core/src/orchestration/tools/misc.rs +3 -2
- package/crates/mint-core/src/orchestration/tools/mod.rs +2 -0
- package/crates/mint-core/src/orchestration/tools/mods.rs +161 -0
- package/crates/mint-core/src/orchestration/tools/plugins_mcp.rs +303 -71
- package/crates/mint-core/src/orchestration/tools/shell.rs +95 -2
- package/crates/mint-core/src/orchestration/workspace_helpers.rs +4 -1
- package/crates/mint-core/src/prompts/agent.rs +17 -2
- package/crates/mint-core/src/prompts/tool_catalog.rs +28 -2
- package/crates/mint-core/src/search/knowledge.rs +7 -1
- package/crates/mint-core/src/search/linked_folders/index.rs +177 -13
- package/crates/mint-core/src/search/linked_folders.rs +83 -2
- package/crates/mint-core/src/slash/catalog.rs +1 -1
- package/crates/mint-core/src/slash/mod.rs +174 -11
- package/crates/mint-core/src/slash/mods.rs +155 -0
- package/crates/mint-core/src/system/bg_shell.rs +1129 -95
- package/crates/mint-core/src/system/config.rs +5 -10
- package/crates/mint-core/src/system/html_preview.rs +398 -0
- package/crates/mint-core/src/system/mint_web.rs +164 -0
- package/crates/mint-core/src/system/release_notes.rs +18 -0
- package/crates/mint-core/src/system/shell.rs +21 -6
- package/crates/mint-core/src/system/workspace.rs +72 -8
- package/crates/mint-core/src/system/workspace_history.rs +604 -0
- package/crates/mint-core/src/system.rs +4 -0
- package/crates/mint-core/tests/background_retention.rs +34 -0
- package/crates/mint-core/tests/background_shutdown.rs +24 -0
- package/crates/mint-core/tests/library_http.rs +209 -0
- package/crates/mint-core/tests/mcp_contract.rs +283 -0
- package/crates/mint-core/tests/mcp_stdio.rs +11 -10
- package/crates/mint-core/tests/media_model_catalog_http.rs +403 -0
- package/crates/mint-core/tests/mods_http.rs +215 -0
- package/crates/mint-core/tests/terminal_shutdown.rs +109 -0
- package/crates/mint-mod-runtime/Cargo.toml +18 -0
- package/crates/mint-mod-runtime/src/lib.rs +507 -0
- package/crates/mint-mod-runtime/src/sdk.js +56 -0
- package/crates/mint-mod-runtime/src/test_sdk.js +32 -0
- package/crates/mint-mod-runtime/src/testing.rs +94 -0
- package/crates/mint-mod-runtime/tests/runtime.rs +156 -0
- package/docs/mods/AUTHORING.md +61 -0
- package/docs/mods/README.md +139 -0
- package/docs/mods/TESTING.md +56 -0
- package/docs/mods/mint-mods.d.ts +66 -0
- package/examples/device-mcp/README.md +22 -0
- package/examples/device-mcp/contract.md +49 -0
- package/examples/device-mcp/mock-device.mjs +66 -0
- package/examples/device-mcp/server.mjs +48 -0
- package/examples/device-mcp/server.test.mjs +78 -0
- package/examples/mods/task-checklist/README.md +1 -0
- package/examples/mods/task-checklist/main.ts +17 -0
- package/examples/mods/task-checklist/manifest.json +1 -0
- package/examples/mods/task-checklist/tests/checklist.test.ts +15 -0
- package/examples/mods/token-meter/README.md +1 -0
- package/examples/mods/token-meter/main.ts +8 -0
- package/examples/mods/token-meter/manifest.json +1 -0
- package/examples/mods/tool-guard/README.md +1 -0
- package/examples/mods/tool-guard/main.ts +9 -0
- package/examples/mods/tool-guard/manifest.json +1 -0
- package/out/web/assets/CliSessionsView-CtzUJpK_.css +1 -0
- package/out/web/assets/CliSessionsView-D7hw0Mgj.js +1 -0
- package/out/web/assets/CodeReviewPage-C7bEOJfd.js +4 -0
- package/out/web/assets/CodeReviewPage-Dte9uLiL.css +1 -0
- package/out/web/assets/CommandPalette-0RrF-AOT.js +1 -0
- package/out/web/assets/ImageStudioPanel-CdxkAf_r.js +1 -0
- package/out/web/assets/LibraryPage--Qfisp6D.js +2 -0
- package/out/web/assets/LibraryPage-DAxUTAg7.css +1 -0
- package/out/web/assets/LinkedFoldersView-2nfZbDgN.js +1 -0
- package/out/web/assets/McpRegistryPicker-h9uS8_wT.js +1 -0
- package/out/web/assets/McpServersView-slfQJzNB.js +1 -0
- package/out/web/assets/MintDashboard-BSR5XpXh.js +25 -0
- package/out/web/assets/MintDashboard-CWUcCGhd.css +1 -0
- package/out/web/assets/PluginsView-l7LSm503.js +1 -0
- package/out/web/assets/ScheduledTasksView-CttmLbq1.js +1 -0
- package/out/web/assets/SettingsWindow-BCMLYvEV.js +4 -0
- package/out/web/assets/SettingsWindow-DcMVmU9u.css +1 -0
- package/out/web/assets/SkillsView-rNs1qr_U.js +2 -0
- package/out/web/assets/ToolSurfacePage-B9DzEPWN.js +37 -0
- package/out/web/assets/ToolSurfacePage-CTfgggF2.css +1 -0
- package/out/web/assets/VeoStudioPanel-DiJs_Cg2.js +4 -0
- package/out/web/assets/WorkspaceSelector-B2xIp04D.js +1 -0
- package/out/web/assets/WorkspaceSelector-Ca8uJOsS.css +1 -0
- package/out/web/assets/{abnfDiagram-VCTEODGH-ByMyfanq.js → abnfDiagram-VCTEODGH-CD0CjoGl.js} +1 -1
- package/out/web/assets/{architecture-7GRP2DOG-CLq2kEOB.js → architecture-7GRP2DOG-RKV83OeZ.js} +1 -1
- package/out/web/assets/{architectureDiagram-5GKGNRK7-6PoVSmNG.js → architectureDiagram-5GKGNRK7-nN_HAFct.js} +1 -1
- package/out/web/assets/{blockDiagram-NRAW4CY4-cKw9mAKi.js → blockDiagram-NRAW4CY4-BrrqzHW5.js} +1 -1
- package/out/web/assets/{c4Diagram-UCG6FXSJ-Cqy8N5Ge.js → c4Diagram-UCG6FXSJ-DTdV8_zE.js} +1 -1
- package/out/web/assets/{chunk-75Z2AOVW-3qybijF5.js → chunk-75Z2AOVW-_M0z5olV.js} +1 -1
- package/out/web/assets/chunk-CKBBP62Z-BpQEgeHF.js +2 -0
- package/out/web/assets/{chunk-CLGD4ZFX-CndDQkww.js → chunk-CLGD4ZFX-D54yGvGS.js} +1 -1
- package/out/web/assets/{chunk-DSNCTWBM-Cc4NxvgD.js → chunk-DSNCTWBM-C-gvT2ru.js} +1 -1
- package/out/web/assets/{chunk-DU6HZSFF-drzh6GsU.js → chunk-DU6HZSFF-CnFngIhW.js} +1 -1
- package/out/web/assets/{chunk-F27PBJKO-FiY35l4v.js → chunk-F27PBJKO-BqtWrnEO.js} +1 -1
- package/out/web/assets/{chunk-G27WJ6UU-Bjt9Il4A.js → chunk-G27WJ6UU-Ckoq5mi2.js} +1 -1
- package/out/web/assets/{chunk-GMAD6QVW-Bppi3Ctd.js → chunk-GMAD6QVW-BuhEcgHq.js} +1 -1
- package/out/web/assets/{chunk-JQ64N6SF-DGg5kcEV.js → chunk-JQ64N6SF-CF8T7GiZ.js} +1 -1
- package/out/web/assets/{chunk-LCL6LL3I-CCYcjd7p.js → chunk-LCL6LL3I-BhXV9zyH.js} +1 -1
- package/out/web/assets/{chunk-OBVCFTLP-DJeNil5M.js → chunk-OBVCFTLP-CRIkunUB.js} +1 -1
- package/out/web/assets/{chunk-P2QGCYS3-lRzkRjBB.js → chunk-P2QGCYS3-UFEU6BxZ.js} +1 -1
- package/out/web/assets/{chunk-POPQ4Y6H-DouASMBW.js → chunk-POPQ4Y6H-CQcrNbjr.js} +1 -1
- package/out/web/assets/{chunk-PWAF6VOD-DMmD1vVf.js → chunk-PWAF6VOD-Cc2uVDsG.js} +1 -1
- package/out/web/assets/{chunk-R7TYR2AO-CYLA5UC5.js → chunk-R7TYR2AO-DiCxzdAY.js} +1 -1
- package/out/web/assets/{chunk-RHFEMEQ7-BiXwEcUT.js → chunk-RHFEMEQ7-b7hnPmrR.js} +1 -1
- package/out/web/assets/{chunk-SVP7TREG-BV-zPslF.js → chunk-SVP7TREG-Bu_yYb-V.js} +1 -1
- package/out/web/assets/{chunk-TEH6E4GO-B2RGEohZ.js → chunk-TEH6E4GO-G4Cdlyrt.js} +1 -1
- package/out/web/assets/classDiagram-DTDB5LWJ-RnC2mYO4.js +1 -0
- package/out/web/assets/classDiagram-v2-JRS7N3AN-RnC2mYO4.js +1 -0
- package/out/web/assets/config-CnvCChUM.js +2 -0
- package/out/web/assets/config-DM6oIVO3.css +1 -0
- package/out/web/assets/core-DsKkQ7ig.js +1 -0
- package/out/web/assets/{cynefin-OW5HDTMX-Cas4csHM.js → cynefin-OW5HDTMX-CnzQfOGp.js} +1 -1
- package/out/web/assets/{cynefinDiagram-5FMLGOSQ-Bbpj66Y3.js → cynefinDiagram-5FMLGOSQ-DVtQnfpm.js} +1 -1
- package/out/web/assets/{dagre-3AP2YEHR-B0-2RDEd.js → dagre-3AP2YEHR-DG76_k5_.js} +1 -1
- package/out/web/assets/{diagram-S7CK7UJ4-BdzEjUyH.js → diagram-S7CK7UJ4-CaouUoze.js} +1 -1
- package/out/web/assets/{diagram-UQ7AKVKN-CJDwyPxF.js → diagram-UQ7AKVKN-B4bEc26B.js} +1 -1
- package/out/web/assets/{diagram-VSXAHHWV-BxaG1r_B.js → diagram-VSXAHHWV-BJ86Ov2Y.js} +1 -1
- package/out/web/assets/{diagram-VX7I27RA-BMmUqm8f.js → diagram-VX7I27RA-7hH5IPYf.js} +1 -1
- package/out/web/assets/{diagram-Z3DM3KII-CFtd03eE.js → diagram-Z3DM3KII-CCM4clo8.js} +1 -1
- package/out/web/assets/dist-js-BkYNznHX.js +1 -0
- package/out/web/assets/{ebnfDiagram-PWID7BFC-DwAen1hO.js → ebnfDiagram-PWID7BFC-Da7WAM3k.js} +1 -1
- package/out/web/assets/{erDiagram-SSCWMZ5O-BCZSHACj.js → erDiagram-SSCWMZ5O-CzzmnZWT.js} +1 -1
- package/out/web/assets/{event-ChBVpRy0.js → event-Cdt7Byyj.js} +1 -1
- package/out/web/assets/{eventmodeling-NTZA5JFV-XHStE4E_.js → eventmodeling-NTZA5JFV-xcfsA0XD.js} +1 -1
- package/out/web/assets/flowDiagram-A5DVABFB-JdtH1673.js +1 -0
- package/out/web/assets/{ganttDiagram-EL5Y4UJY-BAEu1Cql.js → ganttDiagram-EL5Y4UJY-B3ClFGmL.js} +1 -1
- package/out/web/assets/{gitGraph-4MIJSDKK-r32Vyper.js → gitGraph-4MIJSDKK-BZ_y_cDU.js} +1 -1
- package/out/web/assets/{gitGraphDiagram-WWUBYQGX-z9o9qt6V.js → gitGraphDiagram-WWUBYQGX-drhRSYm3.js} +1 -1
- package/out/web/assets/index-BZ9xgmMP.css +1 -0
- package/out/web/assets/index-Ca8cCS4h.js +168 -0
- package/out/web/assets/{info-A6RAGUB7-BvLaC2cw.js → info-A6RAGUB7-B7I3K0F1.js} +1 -1
- package/out/web/assets/{infoDiagram-RXCK75RN-Be6WAXXw.js → infoDiagram-RXCK75RN-deX_1MPh.js} +1 -1
- package/out/web/assets/{ishikawaDiagram-5VMMS53U-DZjoHJHC.js → ishikawaDiagram-5VMMS53U-s38yo28y.js} +1 -1
- package/out/web/assets/{journeyDiagram-EYS64GPL-CtVkjkGm.js → journeyDiagram-EYS64GPL-CZn2kB8b.js} +1 -1
- package/out/web/assets/jsx-runtime-DN4NhQUK.js +1 -0
- package/out/web/assets/{kanban-definition-3QL26DDD-CW5FMv1w.js → kanban-definition-3QL26DDD-DodjgySL.js} +1 -1
- package/out/web/assets/markdown-CMhYIcWB.js +39 -0
- package/out/web/assets/{mermaid-parser.core-aUgCqsZ5.js → mermaid-parser.core-Whu2rlJC.js} +3 -3
- package/out/web/assets/{mermaid.core-D57sEiSL.js → mermaid.core-CKyPo8VH.js} +4 -4
- package/out/web/assets/{mindmap-definition-FBJOCRG2-DAmSpM3a.js → mindmap-definition-FBJOCRG2-260WBDxZ.js} +1 -1
- package/out/web/assets/modelManager-CUaGWMWu.js +2 -0
- package/out/web/assets/{oauthManager-9jxicDWJ.js → oauthManager-DlNhXJr6.js} +1 -1
- package/out/web/assets/{packet-AYTQ26CC-DJ27iIoJ.js → packet-AYTQ26CC-CEeIRKRG.js} +1 -1
- package/out/web/assets/{pegDiagram-XKGWAZYB-Bj3ii-gS.js → pegDiagram-XKGWAZYB-BYadI-KO.js} +1 -1
- package/out/web/assets/{pie-WAS4IAKB-DG5mCUbc.js → pie-WAS4IAKB-D8uf4dh5.js} +1 -1
- package/out/web/assets/{pieDiagram-E7YTZNPT-BrJLPnDA.js → pieDiagram-E7YTZNPT-CjSDy4hO.js} +1 -1
- package/out/web/assets/{quadrantDiagram-AXDQQJYC-3x_TmF3j.js → quadrantDiagram-AXDQQJYC-B8D3gU5d.js} +1 -1
- package/out/web/assets/{radar-RG4KPBEZ-CrXaTTuV.js → radar-RG4KPBEZ-DZJxnokY.js} +1 -1
- package/out/web/assets/{railroad-74A4TZTK-BpqMH9BE.js → railroad-74A4TZTK-DBysUiUi.js} +1 -1
- package/out/web/assets/{railroad-abnf-HS5TGJTU-DHI0uLlV.js → railroad-abnf-HS5TGJTU-CHWxoJYg.js} +1 -1
- package/out/web/assets/{railroad-ebnf-LZEXJU2U-CQCb316y.js → railroad-ebnf-LZEXJU2U-DDv7X6bY.js} +1 -1
- package/out/web/assets/{railroad-peg-WCYAUIDC-Ph1giKkH.js → railroad-peg-WCYAUIDC-DpfcYYNJ.js} +1 -1
- package/out/web/assets/{railroadDiagram-O6MQD6OU-BRq6wIxx.js → railroadDiagram-O6MQD6OU-CYtyv0t3.js} +1 -1
- package/out/web/assets/{requirementDiagram-EFPCY7ZU-DIJj6G1g.js → requirementDiagram-EFPCY7ZU-D2X-Ewik.js} +1 -1
- package/out/web/assets/{sankeyDiagram-P5KCCOFB-DZajSryq.js → sankeyDiagram-P5KCCOFB-Bn2x6C4Y.js} +1 -1
- package/out/web/assets/{sequenceDiagram-WJ2MYXX4-DxJCWyZS.js → sequenceDiagram-WJ2MYXX4-BvFLKtPd.js} +1 -1
- package/out/web/assets/{stateDiagram-HBIQ2CUA-k6voi8Vf.js → stateDiagram-HBIQ2CUA-Bx0GWeaY.js} +1 -1
- package/out/web/assets/stateDiagram-v2-4QOOHH4V--hol1yg_.js +1 -0
- package/out/web/assets/{swimlanes-XN3QIQJK-igYhTjXB.js → swimlanes-XN3QIQJK-CCma0T7L.js} +1 -1
- package/out/web/assets/swimlanesDiagram-VK2B7HYN-BkohoVsU.js +8 -0
- package/out/web/assets/{timeline-definition-24CTP7MA-Dke2p93p.js → timeline-definition-24CTP7MA-iCRhhJ7C.js} +1 -1
- package/out/web/assets/{treeView-Q6P3EWNA-hNELnXUs.js → treeView-Q6P3EWNA-DZ-y08qp.js} +1 -1
- package/out/web/assets/{treemap-WGGIJYW6-D2B6wDsx.js → treemap-WGGIJYW6-De0CxzMx.js} +1 -1
- package/out/web/assets/{vennDiagram-4TSXK5OY-CDkW7rUP.js → vennDiagram-4TSXK5OY-w_7aZ6xe.js} +1 -1
- package/out/web/assets/{wardley-WFR3VGLG-BECdXETi.js → wardley-WFR3VGLG-DT0y0xJ4.js} +1 -1
- package/out/web/assets/{wardleyDiagram-VM6X3IG4-B5BycpQ4.js → wardleyDiagram-VM6X3IG4-DAdXELbQ.js} +1 -1
- package/out/web/assets/window-BJCVtyET.js +1 -0
- package/out/web/assets/{xychartDiagram-S5SC5T6Z-CtJS3b--.js → xychartDiagram-S5SC5T6Z-IZIXf3Vo.js} +1 -1
- package/out/web/index-web.html +3 -2
- package/out/web/index.html +3 -2
- package/package.json +71 -22
- package/shared-modules/.github/workflows/ci.yml +120 -0
- package/shared-modules/.github/workflows/update.yaml +28 -0
- package/slash-commands.json +7 -2
- package/src/bin/auto-build.js +66 -0
- package/src/bin/desktop.js +113 -0
- package/src/bin/desktop.test.js +113 -0
- package/src/bin/index.js +18 -25
- package/src/bin/index.test.js +89 -0
- package/src/bin/measure-effects.mjs +53 -0
- package/src/bin/package.test.js +28 -0
- package/src/bin/release-notes.test.js +84 -0
- package/src/bin/styles.test.js +20 -0
- package/src/bin/web.js +5 -0
- package/src/bin/web.test.js +39 -0
- package/src/renderer/index.html +0 -2
- package/src/renderer/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
- package/src/renderer/shared/agentProgress.ts +33 -0
- package/src/renderer/shared/components/AgentActivityDrawer.tsx +3 -2
- package/src/renderer/shared/components/AgentActivityTable.tsx +1 -1
- package/src/renderer/shared/components/ApprovalCard.test.tsx +24 -0
- package/src/renderer/shared/components/ApprovalCard.tsx +10 -3
- package/src/renderer/shared/components/ArtifactPreviewPanel.tsx +88 -37
- package/src/renderer/shared/components/AuthGate.tsx +75 -39
- package/src/renderer/shared/components/BackgroundTerminals.tsx +181 -0
- package/src/renderer/shared/components/ChatCodeBlock.tsx +8 -4
- package/src/renderer/shared/components/ChatMessageItem.test.tsx +68 -0
- package/src/renderer/shared/components/ChatMessageItem.tsx +36 -16
- package/src/renderer/shared/components/ChatPanel.test.tsx +21 -0
- package/src/renderer/shared/components/ChatPanel.tsx +294 -272
- package/src/renderer/shared/components/ChunkErrorBoundary.tsx +4 -102
- package/src/renderer/shared/components/CliSessionsView.test.tsx +125 -0
- package/src/renderer/shared/components/CliSessionsView.tsx +61 -13
- package/src/renderer/shared/components/CodeReviewPage.tsx +111 -8
- package/src/renderer/shared/components/CollapsiblePasteInput.tsx +90 -0
- package/src/renderer/shared/components/ContextCompactionStatus.tsx +17 -0
- package/src/renderer/shared/components/DashboardSidebar.tsx +15 -128
- package/src/renderer/shared/components/DesktopTitlebar.tsx +45 -19
- package/src/renderer/shared/components/ErrorNotice.tsx +29 -0
- package/src/renderer/shared/components/FormattedMessage.tsx +11 -0
- package/src/renderer/shared/components/GeminiLiveOverlay.css +86 -0
- package/src/renderer/shared/components/GeminiLiveOverlay.test.tsx +24 -0
- package/src/renderer/shared/components/GeminiLiveOverlay.tsx +85 -101
- package/src/renderer/shared/components/GlideSelect.css +138 -0
- package/src/renderer/shared/components/GlideSelect.d.ts +31 -0
- package/src/renderer/shared/components/GlideSelect.jsx +266 -0
- package/src/renderer/shared/components/ImageSearchCard.tsx +46 -56
- package/src/renderer/shared/components/ImageStudioPanel.tsx +9 -8
- package/src/renderer/shared/components/LibraryItemCard.tsx +72 -0
- package/src/renderer/shared/components/LibraryPage.tsx +165 -0
- package/src/renderer/shared/components/LibraryPreview.tsx +59 -0
- package/src/renderer/shared/components/McpServersView.tsx +27 -8
- package/src/renderer/shared/components/McpToolAllowlist.tsx +2 -4
- package/src/renderer/shared/components/McpToolResults.tsx +99 -0
- package/src/renderer/shared/components/MintDashboard.tsx +308 -770
- package/src/renderer/shared/components/ModSessionControls.tsx +8 -0
- package/src/renderer/shared/components/ModUi.test.tsx +65 -0
- package/src/renderer/shared/components/ModUi.tsx +26 -0
- package/src/renderer/shared/components/ModelSelectorPopover.tsx +14 -7
- package/src/renderer/shared/components/ModsPanel.tsx +156 -0
- package/src/renderer/shared/components/ProgressActivity.tsx +17 -0
- package/src/renderer/shared/components/ReviewHistory.tsx +42 -0
- package/src/renderer/shared/components/RewindModal.tsx +5 -12
- package/src/renderer/shared/components/RunSummaryDashboard.tsx +6 -12
- package/src/renderer/shared/components/ScheduledTasksView.tsx +7 -6
- package/src/renderer/shared/components/SelectField.test.tsx +27 -0
- package/src/renderer/shared/components/SelectField.tsx +38 -0
- package/src/renderer/shared/components/SessionSources.tsx +48 -0
- package/src/renderer/shared/components/SessionSourcesPopover.tsx +61 -0
- package/src/renderer/shared/components/Settings/AgentsTab.tsx +7 -6
- package/src/renderer/shared/components/Settings/AudioTab.tsx +8 -7
- package/src/renderer/shared/components/Settings/AutomationTab.tsx +2 -2
- package/src/renderer/shared/components/Settings/GeneralTab.tsx +33 -32
- package/src/renderer/shared/components/Settings/MemoryTab.test.tsx +37 -0
- package/src/renderer/shared/components/Settings/MemoryTab.tsx +71 -31
- package/src/renderer/shared/components/Settings/NotificationsTab.test.tsx +15 -0
- package/src/renderer/shared/components/Settings/NotificationsTab.tsx +84 -0
- package/src/renderer/shared/components/Settings/ThemeTab.tsx +19 -11
- package/src/renderer/shared/components/SlashChoicePanel.tsx +88 -0
- package/src/renderer/shared/components/SlashSuggestions.test.tsx +33 -0
- package/src/renderer/shared/components/SlashSuggestions.tsx +38 -10
- package/src/renderer/shared/components/SourcesBlock.tsx +12 -20
- package/src/renderer/shared/components/ToolSurfacePage.test.tsx +32 -0
- package/src/renderer/shared/components/ToolSurfacePage.tsx +59 -11
- package/src/renderer/shared/components/ToolsPanelToggle.tsx +13 -0
- package/src/renderer/shared/components/VeoStudioPanel.tsx +9 -8
- package/src/renderer/shared/components/ViewedImages.tsx +36 -0
- package/src/renderer/shared/components/VirtualChatHistory.tsx +82 -0
- package/src/renderer/shared/components/VoicePill.css +85 -0
- package/src/renderer/shared/components/VoicePill.d.ts +12 -0
- package/src/renderer/shared/components/VoicePill.jsx +190 -0
- package/src/renderer/shared/components/VoicePill.test.tsx +22 -0
- package/src/renderer/shared/components/WorkspaceContextPopover.tsx +20 -15
- package/src/renderer/shared/components/WorkspacePaneResizer.tsx +92 -0
- package/src/renderer/shared/components/WorkspacePreviewActions.test.tsx +44 -0
- package/src/renderer/shared/components/WorkspacePreviewActions.tsx +19 -0
- package/src/renderer/shared/components/WorkspaceSelector.tsx +13 -8
- package/src/renderer/shared/components/background-terminals.css +292 -0
- package/src/renderer/shared/components/ui/README.md +52 -0
- package/src/renderer/shared/components/ui/button.tsx +37 -0
- package/src/renderer/shared/components/ui/demo.tsx +26 -0
- package/src/renderer/shared/components/ui/error-recovery.css +35 -0
- package/src/renderer/shared/components/ui/error-recovery.tsx +35 -0
- package/src/renderer/shared/components/ui/voice-powered-orb.css +6 -0
- package/src/renderer/shared/components/ui/voice-powered-orb.tsx +374 -0
- package/src/renderer/shared/components/workspace-selector.css +248 -0
- package/src/renderer/shared/constants/config.ts +30 -1
- package/src/renderer/shared/constants/slashCommands.ts +1 -1
- package/src/renderer/shared/conversation/lifecycle.test.ts +362 -0
- package/src/renderer/shared/conversation/lifecycle.ts +418 -0
- package/src/renderer/shared/conversation/projectNavigation.test.ts +105 -0
- package/src/renderer/shared/conversation/projectNavigation.ts +39 -0
- package/src/renderer/shared/conversation/sourcesTransport.ts +27 -0
- package/src/renderer/shared/conversation/syncView.test.ts +1 -34
- package/src/renderer/shared/conversation/syncView.ts +0 -37
- package/src/renderer/shared/conversation/transport.test.ts +163 -0
- package/src/renderer/shared/conversation/transport.ts +159 -0
- package/src/renderer/shared/conversation/useConversationCoordinator.ts +30 -72
- package/src/renderer/shared/css/agent-observability.css +20 -21
- package/src/renderer/shared/css/auth-gate.css +112 -13
- package/src/renderer/shared/css/code-review.css +33 -0
- package/src/renderer/shared/css/code-sessions.css +27 -0
- package/src/renderer/shared/css/collapsed-paste.css +35 -0
- package/src/renderer/shared/css/effects.css +15 -0
- package/src/renderer/shared/css/error-notice.css +60 -0
- package/src/renderer/shared/css/library.css +476 -0
- package/src/renderer/shared/css/management-views.css +138 -0
- package/src/renderer/shared/css/mcp-results.css +11 -0
- package/src/renderer/shared/css/model-selector.css +163 -105
- package/src/renderer/shared/css/mods.css +77 -0
- package/src/renderer/shared/css/notification-notice.css +28 -0
- package/src/renderer/shared/css/session-sources-popover.css +9 -0
- package/src/renderer/shared/css/session-sources.css +23 -0
- package/src/renderer/shared/css/settings/memory.css +154 -0
- package/src/renderer/shared/css/settings/notifications.css +11 -0
- package/src/renderer/shared/css/settings/theme.css +5 -0
- package/src/renderer/shared/css/slash-choice.css +95 -0
- package/src/renderer/shared/css/slash-suggestions.css +68 -0
- package/src/renderer/shared/css/sources-block.css +91 -0
- package/src/renderer/shared/css/thinking-status.css +46 -0
- package/src/renderer/shared/css/tools-panel.css +7 -0
- package/src/renderer/shared/css/ui-tailwind.css +19 -0
- package/src/renderer/shared/css/viewed-images.css +15 -0
- package/src/renderer/shared/fonts.css +46 -0
- package/src/renderer/shared/fonts.ts +3 -12
- package/src/renderer/shared/lib/utils.ts +6 -0
- package/src/renderer/shared/library/controller.test.ts +61 -0
- package/src/renderer/shared/library/controller.ts +57 -0
- package/src/renderer/shared/library/transport.test.ts +26 -0
- package/src/renderer/shared/library/transport.ts +60 -0
- package/src/renderer/shared/library/useLibraryFile.ts +38 -0
- package/src/renderer/shared/mods.ts +58 -0
- package/src/renderer/shared/platform.test.ts +57 -1
- package/src/renderer/shared/platform.ts +46 -1
- package/src/renderer/shared/theme/themeManager.test.ts +43 -0
- package/src/renderer/shared/theme/themeManager.ts +17 -4
- package/src/renderer/shared/types.ts +56 -2
- package/src/renderer/shared/utils/agentActivity.test.ts +75 -0
- package/src/renderer/shared/utils/agentActivity.ts +42 -3
- package/src/renderer/shared/utils/approval.tsx +7 -0
- package/src/renderer/shared/utils/artifactBrowser.test.ts +80 -0
- package/src/renderer/shared/utils/artifactBrowser.ts +41 -0
- package/src/renderer/shared/utils/contextCompaction.test.tsx +48 -0
- package/src/renderer/shared/utils/contextCompaction.ts +21 -0
- package/src/renderer/shared/utils/effectVisibility.ts +9 -0
- package/src/renderer/shared/utils/markdown.tsx +3 -3
- package/src/renderer/shared/utils/mcpResults.test.tsx +91 -0
- package/src/renderer/shared/utils/modViewport.ts +7 -0
- package/src/renderer/shared/utils/nativeRecordingSession.test.ts +61 -0
- package/src/renderer/shared/utils/nativeRecordingSession.ts +46 -0
- package/src/renderer/shared/utils/notificationSettings.test.ts +14 -0
- package/src/renderer/shared/utils/notificationSettings.ts +23 -0
- package/src/renderer/shared/utils/notifications.test.ts +51 -0
- package/src/renderer/shared/utils/notifications.ts +54 -0
- package/src/renderer/shared/utils/pastedText.test.ts +20 -0
- package/src/renderer/shared/utils/pastedText.ts +13 -0
- package/src/renderer/shared/utils/progressCache.test.ts +32 -0
- package/src/renderer/shared/utils/sessionSources.test.ts +31 -0
- package/src/renderer/shared/utils/sessionSources.ts +34 -0
- package/src/renderer/shared/utils/slashCommandProcessor.ts +1 -1
- package/src/renderer/shared/utils/sourceAttachments.ts +28 -0
- package/src/renderer/shared/utils/speech.ts +51 -9
- package/src/renderer/shared/utils/syntaxHighlight.test.tsx +22 -0
- package/src/renderer/shared/utils/syntaxHighlight.tsx +26 -0
- package/src/renderer/shared/utils/useGeminiLiveVoice.ts +49 -5
- package/src/renderer/shared/utils/useLatestCallback.ts +9 -0
- package/src/renderer/shared/utils/useNativeVoiceInput.ts +80 -72
- package/src/renderer/shared/utils/useSessionSources.ts +33 -0
- package/src/renderer/shared/utils/viewedImages.ts +26 -0
- package/src/renderer/shared/utils/workspacePane.test.ts +33 -0
- package/src/renderer/shared/utils/workspacePane.ts +20 -0
- package/src/renderer/shared/utils/workspacePreview.test.ts +24 -0
- package/src/renderer/shared/utils/workspacePreview.ts +16 -0
- package/src/renderer/shared/utils/workspaceSnapshot.test.ts +49 -0
- package/src/renderer/shared/utils/workspaceSnapshot.ts +26 -0
- package/src/renderer/shared/utils/workspaces.ts +10 -0
- package/src/renderer/shared/workspaceUndo.ts +88 -0
- package/src/renderer/src/App.tsx +9 -1
- package/src/renderer/src/components/LiveTranslateControls.tsx +65 -0
- package/src/renderer/src/components/PicturesLibrary.tsx +2 -288
- package/src/renderer/src/components/ScreenPicker.css +67 -30
- package/src/renderer/src/components/ScreenPicker.tsx +201 -60
- package/src/renderer/src/components/SettingsWindow.tsx +10 -5
- package/src/renderer/src/components/WorkspacePanel.tsx +222 -32
- package/src/renderer/src/components/browser-shell.css +1 -1
- package/src/renderer/src/components/browser-suggestions-popup.css +1 -1
- package/src/renderer/src/components/liveTranslateFrames.test.ts +26 -5
- package/src/renderer/src/components/liveTranslateFrames.ts +18 -7
- package/src/renderer/src/components/liveTranslateLanguage.ts +6 -0
- package/src/renderer/src/css/app-shell.css +52 -137
- package/src/renderer/src/css/chat.css +21 -495
- package/src/renderer/src/css/desktop-tools.css +199 -1
- package/src/renderer/src/css/misc.css +0 -52
- package/src/renderer/src/css/pictures.css +2 -415
- package/src/renderer/src/css/settings/base.css +50 -47
- package/src/renderer/src/css/sidebar-workspace.css +151 -94
- package/src/renderer/src/css/tool-surfaces.css +65 -9
- package/src/renderer/src/css/widget.css +1 -1
- package/src/renderer/src/env.d.ts +1 -9
- package/src/renderer/src/index.css +1 -1
- package/src/renderer/src/main.tsx +2 -1
- package/src/renderer/src/proactiveSuggestions.ts +29 -0
- package/src/renderer/src/tauri.ts +122 -330
- package/src/renderer/src/voiceInput.ts +2 -1
- package/src/renderer/src-web/components/PicturesLibrary.tsx +2 -285
- package/src/renderer/src-web/components/PullToRefresh.tsx +1 -1
- package/src/renderer/src-web/components/SettingsWindow.tsx +10 -5
- package/src/renderer/src-web/css/app-shell.css +24 -121
- package/src/renderer/src-web/css/chat.css +21 -495
- package/src/renderer/src-web/css/misc.css +0 -52
- package/src/renderer/src-web/css/mobile.css +15 -14
- package/src/renderer/src-web/css/pictures.css +2 -462
- package/src/renderer/src-web/css/settings/base.css +50 -47
- package/src/renderer/src-web/css/sidebar-workspace.css +9 -95
- package/src/renderer/src-web/css/widget.css +1 -1
- package/src/renderer/src-web/env.d.ts +1 -12
- package/src/renderer/src-web/index.css +1 -1
- package/src/renderer/src-web/main.tsx +2 -1
- package/src/renderer/src-web/proactiveSuggestions.ts +3 -0
- package/src/renderer/src-web/tauri.ts +129 -354
- package/src/renderer/tests/backgroundTerminals.browser.html +81 -0
- package/src/renderer/tests/chatPanelFixture.ts +23 -0
- package/src/renderer/tests/chatPerformance.browser.html +71 -0
- package/src/renderer/tests/cliSessions.browser.html +82 -0
- package/src/renderer/tests/collapsedPaste.browser.html +70 -0
- package/src/renderer/tests/composerMenus.browser.html +116 -0
- package/src/renderer/tests/contextCompaction.browser.html +17 -0
- package/src/renderer/tests/conversationLifecycle.browser.html +70 -0
- package/src/renderer/tests/effectsPerformance.browser.html +13 -0
- package/src/renderer/tests/errorRecovery.browser.html +21 -0
- package/src/renderer/tests/glideSelect.browser.html +71 -0
- package/src/renderer/tests/glideSelect.preview.html +27 -0
- package/src/renderer/tests/library.browser.html +1 -0
- package/src/renderer/tests/library.browser.tsx +78 -0
- package/src/renderer/tests/liveOrb.browser.html +49 -0
- package/src/renderer/tests/liveVoice.browser.html +29 -0
- package/src/renderer/tests/modInput.browser.html +22 -0
- package/src/renderer/tests/sessionSources.browser.html +1 -0
- package/src/renderer/tests/sessionSources.browser.tsx +107 -0
- package/src/renderer/tests/skills.browser.html +24 -0
- package/src/renderer/tests/toolsPanel.browser.html +1 -0
- package/src/renderer/tests/toolsPanel.browser.tsx +113 -0
- package/src/renderer/tests/viewedImages.browser.html +1 -0
- package/src/renderer/tests/viewedImages.browser.tsx +93 -0
- package/src/renderer/tests/voicePill.browser.html +80 -0
- package/src/renderer/tests/voicePill.preview.html +34 -0
- package/src/renderer/tests/webSources.browser.html +1 -0
- package/src/renderer/tests/webSources.browser.tsx +98 -0
- package/src/renderer/tests/workspaceUndo.browser.html +92 -0
- package/src-tauri/Cargo.toml +40 -0
- package/src-tauri/build.rs +3 -0
- package/src-tauri/src/app/lifecycle.rs +277 -0
- package/src-tauri/src/app/mod.rs +4 -0
- package/src-tauri/src/app/shortcuts.rs +40 -0
- package/src-tauri/src/app/tray.rs +52 -0
- package/src-tauri/src/background/events.rs +70 -0
- package/src-tauri/src/background/headless.rs +230 -0
- package/src-tauri/src/background/mod.rs +4 -0
- package/src-tauri/src/background/proactive.rs +262 -0
- package/src-tauri/src/commands/approvals.rs +20 -0
- package/src-tauri/src/commands/auth.rs +127 -0
- package/src-tauri/src/commands/conversation.rs +642 -0
- package/src-tauri/src/commands/integrations.rs +157 -0
- package/src-tauri/src/commands/media.rs +179 -0
- package/src-tauri/src/commands/mod.rs +11 -0
- package/src-tauri/src/commands/mods.rs +6 -0
- package/src-tauri/src/commands/settings.rs +141 -0
- package/src-tauri/src/commands/voice.rs +153 -0
- package/src-tauri/src/commands/workspace.rs +501 -0
- package/src-tauri/src/lib.rs +10 -0
- package/src-tauri/src/main.rs +3 -0
- package/src-tauri/src/native/actions.rs +206 -0
- package/src-tauri/src/native/browser.rs +252 -0
- package/src-tauri/src/native/capture.rs +695 -0
- package/src-tauri/src/native/discord_rpc.rs +99 -0
- package/src-tauri/src/native/integrations.rs +126 -0
- package/src-tauri/src/native/mod.rs +12 -0
- package/src-tauri/src/native/notifications.rs +51 -0
- package/src-tauri/src/native/plugins.rs +14 -0
- package/src-tauri/src/native/system.rs +250 -0
- package/src-tauri/src/native/terminal.rs +201 -0
- package/src-tauri/src/native/updater.rs +148 -0
- package/src-tauri/src/native/windows.rs +143 -0
- package/tsconfig.json +2 -0
- package/vite.config.ts +4 -1
- package/vite.config.web.ts +4 -0
- package/.cargo/config.toml +0 -13
- package/.claude/settings.local.json +0 -182
- package/.codex +0 -0
- package/CLAUDE.md +0 -102
- package/ROADMAP.md +0 -30
- package/mint-presentation-demo.mp4 +0 -0
- package/out/web/Live2DCubismCore.js +0 -9
- package/out/web/assets/CliSessionsView-BxUVWEEL.js +0 -1
- package/out/web/assets/CliSessionsView-CBDTXuQv.css +0 -1
- package/out/web/assets/CodeReviewPage-DkMgfcos.css +0 -1
- package/out/web/assets/CodeReviewPage-jKlmLJwT.js +0 -3
- package/out/web/assets/CommandPalette-DnwPA5hy.js +0 -1
- package/out/web/assets/ImageStudioPanel-BR1XFwhR.js +0 -1
- package/out/web/assets/LinkedFoldersView-bi-CWQ-I.js +0 -1
- package/out/web/assets/McpRegistryPicker-D5tEFnyq.js +0 -1
- package/out/web/assets/McpServersView-BGG1dhFM.js +0 -1
- package/out/web/assets/MintDashboard-BIglDEWX.js +0 -20
- package/out/web/assets/MintDashboard-DSMywSgs.css +0 -1
- package/out/web/assets/ModelPanel-CbJ1PFoZ.js +0 -1
- package/out/web/assets/PicturesLibrary-CQP0fLP1.css +0 -1
- package/out/web/assets/PicturesLibrary-DoYN7T1p.js +0 -1
- package/out/web/assets/PluginsView-CU1HWXGk.js +0 -1
- package/out/web/assets/ScheduledTasksView-Bnl36y2N.js +0 -1
- package/out/web/assets/SettingsWindow-DhWLAn9T.css +0 -1
- package/out/web/assets/SettingsWindow-Dw8L01pw.js +0 -2
- package/out/web/assets/SkillsView-cnl8aY5p.js +0 -2
- package/out/web/assets/ToolSurfacePage-CgsQw6l5.css +0 -1
- package/out/web/assets/ToolSurfacePage-Cz2VJAPZ.js +0 -37
- package/out/web/assets/VeoStudioPanel-D4JnERWR.js +0 -4
- package/out/web/assets/chunk-CKBBP62Z-cIrXq6jN.js +0 -2
- package/out/web/assets/classDiagram-DTDB5LWJ-Dq0smRWk.js +0 -1
- package/out/web/assets/classDiagram-v2-JRS7N3AN-Dq0smRWk.js +0 -1
- package/out/web/assets/config-C-ZFtipU.css +0 -1
- package/out/web/assets/config-eEDngJXO.js +0 -1
- package/out/web/assets/core-hQ2VA9Ti.js +0 -1
- package/out/web/assets/dist-js-Bf2bhoku.js +0 -1
- package/out/web/assets/flowDiagram-A5DVABFB-BLg7nEcd.js +0 -1
- package/out/web/assets/index-Btsf4L8M.css +0 -1
- package/out/web/assets/index-D8D9MeRA.js +0 -11
- package/out/web/assets/lucide-react-Ip3L6Jtn.js +0 -1
- package/out/web/assets/markdown-BSeeUbJH.js +0 -38
- package/out/web/assets/modelManager-tMVmJVAW.js +0 -2
- package/out/web/assets/prompt-latin-400-normal-BQ9zjSN8.woff2 +0 -0
- package/out/web/assets/prompt-latin-400-normal-CxU4ec_r.woff +0 -0
- package/out/web/assets/prompt-latin-500-normal-B1edBDQ9.woff +0 -0
- package/out/web/assets/prompt-latin-500-normal-CxzxEHZc.woff2 +0 -0
- package/out/web/assets/prompt-latin-600-normal-CSDDLorv.woff +0 -0
- package/out/web/assets/prompt-latin-600-normal-hKZWXsc1.woff2 +0 -0
- package/out/web/assets/prompt-latin-700-normal-BfbftDSq.woff +0 -0
- package/out/web/assets/prompt-latin-700-normal-I2gc831J.woff2 +0 -0
- package/out/web/assets/prompt-thai-400-normal-BrkKv8cO.woff2 +0 -0
- package/out/web/assets/prompt-thai-400-normal-DJypnfr3.woff +0 -0
- package/out/web/assets/prompt-thai-500-normal-C18pDUoL.woff2 +0 -0
- package/out/web/assets/prompt-thai-500-normal-D7YNqUJD.woff +0 -0
- package/out/web/assets/prompt-thai-600-normal-CYPViXds.woff +0 -0
- package/out/web/assets/prompt-thai-600-normal-MrdfU7zR.woff2 +0 -0
- package/out/web/assets/prompt-thai-700-normal-Cb5ilR-c.woff +0 -0
- package/out/web/assets/prompt-thai-700-normal-Cg4aQ0Nn.woff2 +0 -0
- package/out/web/assets/stateDiagram-v2-4QOOHH4V-DeEc0lGZ.js +0 -1
- package/out/web/assets/swimlanesDiagram-VK2B7HYN-DpVik9v7.js +0 -8
- package/out/web/assets/window-5qYXKoW7.js +0 -1
- package/skills-lock.json +0 -77
- package/src/renderer/public/Live2DCubismCore.js +0 -9
- package/src/renderer/src/companionWidget.ts +0 -95
- package/src/renderer/src/components/Live2DStage.tsx +0 -412
- package/src/renderer/src/components/ModelPanel.tsx +0 -155
- package/src/renderer/src/css/model.css +0 -628
- package/src/renderer/src-web/companionWidget.ts +0 -37
- package/src/renderer/src-web/components/ModelPanel.tsx +0 -12
- package/src/renderer/src-web/css/model.css +0 -628
|
@@ -1,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 { THEME_PRESETS, ACCENT_FLAVORS, ThemePreset, AccentFlavor } from '../../theme/themes'
|
|
@@ -305,6 +306,19 @@ export default function ThemeTab({ config, updateField, updateFields }: ThemeTab
|
|
|
305
306
|
)}
|
|
306
307
|
</div>
|
|
307
308
|
|
|
309
|
+
<div className="toggle-row reduced-effects-row">
|
|
310
|
+
<div>
|
|
311
|
+
<label id="reduced-effects-label" htmlFor="reduced-effects">Reduce effects</label>
|
|
312
|
+
<p className="hint">Keep the background and orb still. Also follows your system’s reduced motion preference.</p>
|
|
313
|
+
</div>
|
|
314
|
+
<label className="settings-toggle-switch">
|
|
315
|
+
<input id="reduced-effects" type="checkbox" role="switch" aria-labelledby="reduced-effects-label"
|
|
316
|
+
checked={config.reducedEffects === true}
|
|
317
|
+
onChange={event => updateField('reducedEffects', event.target.checked)} />
|
|
318
|
+
<span className="settings-toggle-slider" aria-hidden="true" />
|
|
319
|
+
</label>
|
|
320
|
+
</div>
|
|
321
|
+
|
|
308
322
|
{/* Surface style: Opaque vs Glassmorphism */}
|
|
309
323
|
<div className="setting-row stacked">
|
|
310
324
|
<label>Surface style</label>
|
|
@@ -429,18 +443,12 @@ export default function ThemeTab({ config, updateField, updateFields }: ThemeTab
|
|
|
429
443
|
<div className="form-grid">
|
|
430
444
|
<div className="setting-row">
|
|
431
445
|
<label>Font family</label>
|
|
432
|
-
<
|
|
433
|
-
<option value="'
|
|
434
|
-
<option value="'
|
|
435
|
-
<option value="'Inter', sans-serif">
|
|
436
|
-
<option value="'Prompt', sans-serif">Prompt (Modern Thai)</option>
|
|
437
|
-
<option value="'Noto Sans Thai', sans-serif">Noto Sans Thai (clean Thai)</option>
|
|
438
|
-
<option value="'Sarabun', sans-serif">Sarabun (Formal Thai)</option>
|
|
439
|
-
<option value="'Kanit', sans-serif">Kanit (Trendy Thai)</option>
|
|
440
|
-
<option value="'Mitr', sans-serif">Mitr (Friendly Thai)</option>
|
|
441
|
-
<option value="'Mali', cursive">Mali (Cute Thai Font)</option>
|
|
446
|
+
<SelectField aria-label="Font family" value={config.fontFamily} onValueChange={(nextValue) => updateField('fontFamily', nextValue)}>
|
|
447
|
+
<option value="'IBM Plex Sans Thai', 'Noto Sans Thai', 'Inter', ui-sans-serif, system-ui, sans-serif">IBM Plex Sans Thai (Default)</option>
|
|
448
|
+
<option value="'Inter', 'Noto Sans Thai', ui-sans-serif, system-ui, sans-serif">Inter + Noto Sans Thai</option>
|
|
449
|
+
<option value="'Noto Sans Thai', 'Inter', ui-sans-serif, system-ui, sans-serif">Noto Sans Thai</option>
|
|
442
450
|
<option value="'Fira Code', monospace">Fira Code (developer code font)</option>
|
|
443
|
-
</
|
|
451
|
+
</SelectField>
|
|
444
452
|
</div>
|
|
445
453
|
<div className="setting-row">
|
|
446
454
|
<label>Font size</label>
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { useEffect, useRef, useState, type RefObject } from 'react'
|
|
2
|
+
import type { SlashChoice } from '../platform'
|
|
3
|
+
import '../css/slash-choice.css'
|
|
4
|
+
|
|
5
|
+
interface Props {
|
|
6
|
+
choice: { command: string; title: string; options: SlashChoice[] }
|
|
7
|
+
inputRef: RefObject<HTMLTextAreaElement | null>
|
|
8
|
+
onSelect?: (value: string) => void
|
|
9
|
+
onDismiss?: () => void
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export default function SlashChoicePanel({ choice, inputRef, onSelect, onDismiss }: Props) {
|
|
13
|
+
const [selectedIndex, setSelectedIndex] = useState(0)
|
|
14
|
+
const panelRef = useRef<HTMLElement>(null)
|
|
15
|
+
const optionRefs = useRef<Array<HTMLButtonElement | null>>([])
|
|
16
|
+
const selected = Math.min(selectedIndex, Math.max(0, choice.options.length - 1))
|
|
17
|
+
|
|
18
|
+
useEffect(() => {
|
|
19
|
+
setSelectedIndex(0)
|
|
20
|
+
inputRef.current?.focus()
|
|
21
|
+
}, [choice, inputRef])
|
|
22
|
+
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
optionRefs.current[selected]?.scrollIntoView({ block: 'nearest' })
|
|
25
|
+
}, [selected, choice])
|
|
26
|
+
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
const onKeyDown = (event: globalThis.KeyboardEvent) => {
|
|
29
|
+
if (event.isComposing || event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) return
|
|
30
|
+
const target = event.target as Node | null
|
|
31
|
+
const onInput = target === inputRef.current
|
|
32
|
+
const inPanel = target !== null && panelRef.current?.contains(target)
|
|
33
|
+
if (event.key !== 'Escape' && !onInput && !inPanel) return
|
|
34
|
+
// Keep native Enter activation for the dismiss button.
|
|
35
|
+
if (event.key === 'Enter' && !onInput && !optionRefs.current.includes(target as HTMLButtonElement)) return
|
|
36
|
+
if (event.key === 'Escape') {
|
|
37
|
+
event.preventDefault()
|
|
38
|
+
event.stopPropagation()
|
|
39
|
+
onDismiss?.()
|
|
40
|
+
inputRef.current?.focus()
|
|
41
|
+
return
|
|
42
|
+
}
|
|
43
|
+
if (!choice.options.length) return
|
|
44
|
+
if (event.key === 'ArrowUp' || event.key === 'ArrowDown') {
|
|
45
|
+
event.preventDefault()
|
|
46
|
+
event.stopPropagation()
|
|
47
|
+
const next = (selected + (event.key === 'ArrowDown' ? 1 : -1) + choice.options.length) % choice.options.length
|
|
48
|
+
setSelectedIndex(next)
|
|
49
|
+
if (inPanel) optionRefs.current[next]?.focus()
|
|
50
|
+
} else if (event.key === 'Enter') {
|
|
51
|
+
event.preventDefault()
|
|
52
|
+
event.stopPropagation()
|
|
53
|
+
onSelect?.(choice.options[selected].value)
|
|
54
|
+
inputRef.current?.focus()
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
// Capture before the composer's history/submit handlers claim these keys.
|
|
58
|
+
window.addEventListener('keydown', onKeyDown, true)
|
|
59
|
+
return () => window.removeEventListener('keydown', onKeyDown, true)
|
|
60
|
+
}, [choice, inputRef, onDismiss, onSelect, selected])
|
|
61
|
+
|
|
62
|
+
return (
|
|
63
|
+
<section ref={panelRef} className="slash-choice-panel" aria-label={`${choice.command} choices`}>
|
|
64
|
+
<header className="slash-choice-heading">
|
|
65
|
+
<div><span className="slash-choice-command">{choice.command}</span><p>{choice.title}</p></div>
|
|
66
|
+
<button type="button" onClick={onDismiss} aria-label="Dismiss choices">×</button>
|
|
67
|
+
</header>
|
|
68
|
+
<div className="slash-choice-options" role="group" aria-label="Options">
|
|
69
|
+
{choice.options.map((option, index) => (
|
|
70
|
+
<button
|
|
71
|
+
key={option.value}
|
|
72
|
+
ref={(element) => { optionRefs.current[index] = element }}
|
|
73
|
+
type="button"
|
|
74
|
+
aria-pressed={index === selected}
|
|
75
|
+
className={index === selected ? 'active' : undefined}
|
|
76
|
+
onPointerMove={() => setSelectedIndex(index)}
|
|
77
|
+
onFocus={() => setSelectedIndex(index)}
|
|
78
|
+
onClick={() => { onSelect?.(option.value); inputRef.current?.focus() }}
|
|
79
|
+
>
|
|
80
|
+
<span>{index + 1}.</span>{option.label}
|
|
81
|
+
</button>
|
|
82
|
+
))}
|
|
83
|
+
</div>
|
|
84
|
+
<span className="slash-choice-status" role="status">{choice.options[selected]?.label}</span>
|
|
85
|
+
<div className="slash-choice-hint">↑↓ select · Enter choose · Esc dismiss</div>
|
|
86
|
+
</section>
|
|
87
|
+
)
|
|
88
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { renderToStaticMarkup } from 'react-dom/server'
|
|
3
|
+
import { describe, expect, it } from 'vitest'
|
|
4
|
+
import SlashSuggestions from './SlashSuggestions'
|
|
5
|
+
|
|
6
|
+
const render = (message: string, suppressed = false) => renderToStaticMarkup(
|
|
7
|
+
<SlashSuggestions message={message} onComplete={() => {}} anchorRef={{ current: null }} suppressed={suppressed} />,
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
describe('composer command suggestions', () => {
|
|
11
|
+
it('finds a command by its description while retaining its executable token', () => {
|
|
12
|
+
const html = render('/statistics')
|
|
13
|
+
expect(html).toContain('/stats')
|
|
14
|
+
expect(html).toContain('role="option"')
|
|
15
|
+
expect(html).not.toContain('/clear')
|
|
16
|
+
})
|
|
17
|
+
it('shows token-prefix matches before description-only matches', () => {
|
|
18
|
+
const html = render('/st')
|
|
19
|
+
expect(html.indexOf('>/stats<')).toBeLessThan(html.indexOf('>/mods<'))
|
|
20
|
+
})
|
|
21
|
+
it('keeps a command argument as a usage hint instead of unrelated search results', () => {
|
|
22
|
+
const html = render('/remember a durable fact')
|
|
23
|
+
expect(html).toContain('/remember')
|
|
24
|
+
expect(html).not.toContain('role="option"')
|
|
25
|
+
})
|
|
26
|
+
it('keeps CLI-only actions out of the graphical menu and hides it during history browsing', () => {
|
|
27
|
+
const html = render('/')
|
|
28
|
+
expect(html).toContain('/models')
|
|
29
|
+
expect(html).not.toContain('/exit')
|
|
30
|
+
expect(html).not.toContain('/theme')
|
|
31
|
+
expect(render('/', true)).toBe('')
|
|
32
|
+
})
|
|
33
|
+
})
|
|
@@ -8,6 +8,8 @@ import {
|
|
|
8
8
|
type KeyboardEvent,
|
|
9
9
|
type RefObject,
|
|
10
10
|
} from 'react'
|
|
11
|
+
import { Terminal, Brain, Folder, Wrench, BookOpen, AtSign } from 'lucide-react'
|
|
12
|
+
import '../css/slash-suggestions.css'
|
|
11
13
|
import { SLASH_COMMANDS, type SlashCommand } from '../constants/slashCommands'
|
|
12
14
|
import { catalogPlatform } from '../platform'
|
|
13
15
|
import type { LearnedSkill } from '../types'
|
|
@@ -96,8 +98,19 @@ const SlashSuggestions = forwardRef<SlashSuggestionsHandle, Props>(function Slas
|
|
|
96
98
|
const slashMatches = useMemo(() => {
|
|
97
99
|
if (mode !== 'slash') return [] as SlashCommand[]
|
|
98
100
|
const q = raw.toLowerCase()
|
|
99
|
-
const
|
|
100
|
-
|
|
101
|
+
const typingArguments = SLASH_COMMANDS.some((c) => q.startsWith(c.command.toLowerCase() + ' '))
|
|
102
|
+
const words = q.slice(1).trim().split(/\s+/).filter(Boolean)
|
|
103
|
+
const hits = SLASH_COMMANDS.filter((c) =>
|
|
104
|
+
c.command.toLowerCase().startsWith(q) ||
|
|
105
|
+
(!typingArguments && !/\s/.test(q) && words.every((word) => `${c.command} ${c.description}`.toLowerCase().includes(word))),
|
|
106
|
+
)
|
|
107
|
+
const byCategory = (commands: SlashCommand[]) => CATEGORY_ORDER.flatMap((cat) =>
|
|
108
|
+
commands.filter((command) => (command.category ?? 'tools') === cat),
|
|
109
|
+
)
|
|
110
|
+
return [
|
|
111
|
+
...byCategory(hits.filter((command) => command.command.toLowerCase().startsWith(q))),
|
|
112
|
+
...byCategory(hits.filter((command) => !command.command.toLowerCase().startsWith(q))),
|
|
113
|
+
]
|
|
101
114
|
}, [mode, raw])
|
|
102
115
|
|
|
103
116
|
// The command whose arguments are being typed (raw is past its token) — used
|
|
@@ -207,6 +220,16 @@ const SlashSuggestions = forwardRef<SlashSuggestionsHandle, Props>(function Slas
|
|
|
207
220
|
return true
|
|
208
221
|
}
|
|
209
222
|
if ((event.key === 'Enter' || event.key === 'Tab') && !event.shiftKey && !event.nativeEvent.isComposing) {
|
|
223
|
+
// A complete slash command is an invocation, not an autocomplete
|
|
224
|
+
// candidate. Let Enter reach the composer submit handler so commands
|
|
225
|
+
// such as `/models` can open their interactive picker on the first keypress.
|
|
226
|
+
if (
|
|
227
|
+
event.key === 'Enter' &&
|
|
228
|
+
mode === 'slash' &&
|
|
229
|
+
flat.some((item) => (item as SlashCommand).command.toLowerCase() === raw.trim().toLowerCase())
|
|
230
|
+
) {
|
|
231
|
+
return false
|
|
232
|
+
}
|
|
210
233
|
const item = flat[selIndex] ?? flat[0]
|
|
211
234
|
if (!item) return false
|
|
212
235
|
pick(item)
|
|
@@ -248,18 +271,22 @@ const SlashSuggestions = forwardRef<SlashSuggestionsHandle, Props>(function Slas
|
|
|
248
271
|
aria-selected={idx === selIndex}
|
|
249
272
|
data-idx={idx}
|
|
250
273
|
className={`slash-suggestion-item ${idx === selIndex ? 'active' : ''}`}
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
}}
|
|
274
|
+
title={[name, usage, desc].filter(Boolean).join(" · ")}
|
|
275
|
+
onMouseDown={(e) => e.preventDefault()}
|
|
276
|
+
onClick={() => pick(item)}
|
|
255
277
|
onPointerMove={() => setSelIndex(idx)}
|
|
256
278
|
>
|
|
279
|
+
<span className="slash-cmd-icon" aria-hidden="true">
|
|
280
|
+
{mode === 'skill' ? <BookOpen size={15} /> : mode === 'at' ? <AtSign size={15} /> :
|
|
281
|
+
(item as SlashCommand).category === 'models' ? <Brain size={15} /> :
|
|
282
|
+
(item as SlashCommand).category === 'workspace' ? <Folder size={15} /> :
|
|
283
|
+
(item as SlashCommand).category === 'tools' ? <Wrench size={15} /> : <Terminal size={15} />}
|
|
284
|
+
</span>
|
|
257
285
|
<span className="slash-cmd-name">{name}</span>
|
|
258
|
-
{badge && <span className="skill-badge">{badge}</span>}
|
|
259
286
|
<span className="slash-cmd-body">
|
|
260
287
|
<span className="slash-cmd-desc">{desc}</span>
|
|
261
|
-
{usage && <span className="slash-cmd-usage">{usage}</span>}
|
|
262
288
|
</span>
|
|
289
|
+
{badge && <span className="skill-badge">{badge}</span>}
|
|
263
290
|
</button>
|
|
264
291
|
)
|
|
265
292
|
|
|
@@ -269,10 +296,10 @@ const SlashSuggestions = forwardRef<SlashSuggestionsHandle, Props>(function Slas
|
|
|
269
296
|
{mode === 'slash' ? 'Slash Commands' : mode === 'skill' ? 'Learned Skills' : 'Context Mentions'}
|
|
270
297
|
<span className="slash-suggestions-count">{headerLabel}</span>
|
|
271
298
|
</div>
|
|
272
|
-
<div className="slash-suggestions-list" ref={listRef} role="listbox">
|
|
299
|
+
<div className="slash-suggestions-list" ref={listRef} role="listbox" aria-label={mode === 'slash' ? 'Slash commands' : mode === 'skill' ? 'Skills' : 'Context mentions'}>
|
|
273
300
|
{mode === 'slash' &&
|
|
274
301
|
(flat.length > 0
|
|
275
|
-
?
|
|
302
|
+
? [...new Set(slashMatches.map((match) => match.category ?? 'tools'))].map((cat) => {
|
|
276
303
|
const items = slashMatches.filter((m) => (m.category ?? 'tools') === cat)
|
|
277
304
|
if (!items.length) return null
|
|
278
305
|
return (
|
|
@@ -311,6 +338,7 @@ const SlashSuggestions = forwardRef<SlashSuggestionsHandle, Props>(function Slas
|
|
|
311
338
|
row(item, idx, item.label, item.desc, item.kind === 'plugin' ? '[Plugin]' : '[Context]'),
|
|
312
339
|
)}
|
|
313
340
|
</div>
|
|
341
|
+
<div className="slash-suggestions-hint">↑↓ select · Tab complete · Enter send · Esc close</div>
|
|
314
342
|
</div>
|
|
315
343
|
)
|
|
316
344
|
})
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React, { useState, useMemo, useEffect } from 'react'
|
|
2
2
|
import type { WebSearchSource } from '../utils/agentActivity'
|
|
3
3
|
import { resolveMediaUrl } from '../utils/markdown'
|
|
4
|
+
import '../css/sources-block.css'
|
|
4
5
|
|
|
5
6
|
export interface SourcesBlockProps {
|
|
6
7
|
sources: WebSearchSource[]
|
|
@@ -87,7 +88,7 @@ export const SourcesBlock: React.FC<SourcesBlockProps> = React.memo(function Sou
|
|
|
87
88
|
const hiddenGroups = domainGroups.slice(MAX_INITIAL_CARDS)
|
|
88
89
|
|
|
89
90
|
return (
|
|
90
|
-
<div style={{ display: 'flex', flexDirection: 'column', gap: '10px', marginBottom: '12px', marginTop: '4px' }}>
|
|
91
|
+
<div className="sources-block" style={{ display: 'flex', flexDirection: 'column', gap: '10px', marginBottom: '12px', marginTop: '4px' }}>
|
|
91
92
|
{/* Header */}
|
|
92
93
|
<div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
|
|
93
94
|
<svg
|
|
@@ -110,6 +111,7 @@ export const SourcesBlock: React.FC<SourcesBlockProps> = React.memo(function Sou
|
|
|
110
111
|
|
|
111
112
|
{/* Domain Cards Container (wraps to next line if exceeding frame width) */}
|
|
112
113
|
<div
|
|
114
|
+
className="sources-cards"
|
|
113
115
|
style={{
|
|
114
116
|
display: 'flex',
|
|
115
117
|
flexWrap: 'wrap',
|
|
@@ -124,18 +126,11 @@ export const SourcesBlock: React.FC<SourcesBlockProps> = React.memo(function Sou
|
|
|
124
126
|
return (
|
|
125
127
|
<div
|
|
126
128
|
key={group.domain}
|
|
127
|
-
|
|
128
|
-
position: 'relative',
|
|
129
|
-
flex: '1 1 180px',
|
|
130
|
-
maxWidth: '240px',
|
|
131
|
-
minWidth: '160px',
|
|
132
|
-
boxSizing: 'border-box',
|
|
133
|
-
}}
|
|
129
|
+
className="source-card-group"
|
|
134
130
|
>
|
|
135
131
|
<div
|
|
132
|
+
className="source-card"
|
|
136
133
|
style={{
|
|
137
|
-
display: 'flex',
|
|
138
|
-
flexDirection: 'column',
|
|
139
134
|
justifyContent: 'space-between',
|
|
140
135
|
borderRadius: '16px',
|
|
141
136
|
background: 'var(--bg-surface-soft)',
|
|
@@ -143,7 +138,6 @@ export const SourcesBlock: React.FC<SourcesBlockProps> = React.memo(function Sou
|
|
|
143
138
|
transition: 'all 0.15s ease',
|
|
144
139
|
cursor: 'pointer',
|
|
145
140
|
minHeight: '68px',
|
|
146
|
-
height: '100%',
|
|
147
141
|
boxSizing: 'border-box',
|
|
148
142
|
overflow: 'hidden',
|
|
149
143
|
}}
|
|
@@ -173,7 +167,7 @@ export const SourcesBlock: React.FC<SourcesBlockProps> = React.memo(function Sou
|
|
|
173
167
|
>
|
|
174
168
|
{/* Thumbnail (if this source has an associated image) */}
|
|
175
169
|
{primaryItem.imageUrl && (
|
|
176
|
-
<div style={{
|
|
170
|
+
<div className="source-card-thumbnail" style={{ overflow: 'hidden', background: 'var(--bg-surface-raised)', flexShrink: 0 }}>
|
|
177
171
|
<img
|
|
178
172
|
src={resolveMediaUrl(primaryItem.imageUrl)}
|
|
179
173
|
alt={primaryItem.title}
|
|
@@ -185,7 +179,7 @@ export const SourcesBlock: React.FC<SourcesBlockProps> = React.memo(function Sou
|
|
|
185
179
|
</div>
|
|
186
180
|
)}
|
|
187
181
|
|
|
188
|
-
<div style={{ display: 'flex', flexDirection: 'column', flex: 1, padding: '10px 12px' }}>
|
|
182
|
+
<div className="source-card-content" style={{ display: 'flex', flexDirection: 'column', flex: 1, padding: '10px 12px' }}>
|
|
189
183
|
{/* Title */}
|
|
190
184
|
<div
|
|
191
185
|
title={primaryItem.title}
|
|
@@ -280,7 +274,6 @@ export const SourcesBlock: React.FC<SourcesBlockProps> = React.memo(function Sou
|
|
|
280
274
|
position: 'absolute',
|
|
281
275
|
top: '100%',
|
|
282
276
|
left: 0,
|
|
283
|
-
width: '260px',
|
|
284
277
|
marginTop: '6px',
|
|
285
278
|
background: 'var(--bg-overlay)',
|
|
286
279
|
border: '1px solid var(--border-default)',
|
|
@@ -357,7 +350,10 @@ export const SourcesBlock: React.FC<SourcesBlockProps> = React.memo(function Sou
|
|
|
357
350
|
|
|
358
351
|
{/* Overflow "View X more" Card */}
|
|
359
352
|
{!isExpanded && remainingSourcesCount > 0 && (
|
|
360
|
-
<
|
|
353
|
+
<button
|
|
354
|
+
type="button"
|
|
355
|
+
className="sources-more-button"
|
|
356
|
+
aria-expanded={false}
|
|
361
357
|
onClick={() => setIsExpanded(true)}
|
|
362
358
|
style={{
|
|
363
359
|
display: 'flex',
|
|
@@ -369,10 +365,6 @@ export const SourcesBlock: React.FC<SourcesBlockProps> = React.memo(function Sou
|
|
|
369
365
|
border: `1px solid ${isDark ? 'rgba(255,255,255,0.08)' : 'rgba(15,23,42,0.1)'}`,
|
|
370
366
|
cursor: 'pointer',
|
|
371
367
|
transition: 'all 0.15s ease',
|
|
372
|
-
minHeight: '68px',
|
|
373
|
-
height: '100%',
|
|
374
|
-
flex: '1 1 160px',
|
|
375
|
-
maxWidth: '200px',
|
|
376
368
|
boxSizing: 'border-box',
|
|
377
369
|
}}
|
|
378
370
|
onMouseEnter={(e) => {
|
|
@@ -412,7 +404,7 @@ export const SourcesBlock: React.FC<SourcesBlockProps> = React.memo(function Sou
|
|
|
412
404
|
<span style={{ fontSize: '0.78rem', fontWeight: 500, color: '#94a3b8', marginLeft: '8px' }}>
|
|
413
405
|
View {remainingSourcesCount} more
|
|
414
406
|
</span>
|
|
415
|
-
</
|
|
407
|
+
</button>
|
|
416
408
|
)}
|
|
417
409
|
</div>
|
|
418
410
|
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { renderToStaticMarkup } from 'react-dom/server'
|
|
3
|
+
import { describe, expect, it } from 'vitest'
|
|
4
|
+
import ToolSurfacePage from './ToolSurfacePage'
|
|
5
|
+
|
|
6
|
+
const noop = () => {}
|
|
7
|
+
const props = {
|
|
8
|
+
surfaces: [], activeSurfaceId: null, terminalSize: 440,
|
|
9
|
+
onSelect: noop, onClose: noop, onCloseAll: noop, onDuplicate: noop,
|
|
10
|
+
onRename: noop, onCloseOthers: noop, onResizeTerminal: noop, onResizePanel: noop,
|
|
11
|
+
onOpenTerminal: noop, onOpenBrowser: noop, onOpenReview: noop, onOpenFiles: noop,
|
|
12
|
+
onOpenMods: noop, onOpenBackgroundTasks: noop, onClosePanel: noop,
|
|
13
|
+
onModsPanelTarget: noop, onBackgroundPanelTarget: noop,
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
describe('Tools launcher', () => {
|
|
17
|
+
it('makes workspace mods and running background tasks discoverable on its first screen', () => {
|
|
18
|
+
const html = renderToStaticMarkup(<ToolSurfacePage {...props} backgroundTaskCount={2} />)
|
|
19
|
+
expect(html).toMatch(/role="menuitem"[^>]*title="Workspace mods"/)
|
|
20
|
+
expect(html).toMatch(/role="menuitem"[^>]*title="Background tasks"/)
|
|
21
|
+
expect(html).toContain('2 active background tasks')
|
|
22
|
+
expect(html).toContain('Integrated terminal')
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
it('does not offer a native shell or desktop workspace on the web', () => {
|
|
26
|
+
const html = renderToStaticMarkup(<ToolSurfacePage {...props} desktopTools={false} />)
|
|
27
|
+
expect(html).toContain('Workspace mods')
|
|
28
|
+
expect(html).toContain('Background tasks')
|
|
29
|
+
expect(html).not.toContain('Integrated terminal')
|
|
30
|
+
expect(html).not.toContain('Workspace files')
|
|
31
|
+
})
|
|
32
|
+
})
|
|
@@ -6,11 +6,13 @@ import { ArtifactPreviewPanel } from './ArtifactPreviewPanel'
|
|
|
6
6
|
import CodeReviewPage from './CodeReviewPage'
|
|
7
7
|
import TerminalDock from './TerminalDock'
|
|
8
8
|
import type { FileChange } from '../types'
|
|
9
|
+
import { ListTodo, Puzzle } from 'lucide-react'
|
|
9
10
|
|
|
10
11
|
export type ToolSurface =
|
|
11
12
|
| { id: string; kind: 'preview'; title: string; artifact: ArtifactFile }
|
|
12
13
|
| { id: string; kind: 'review'; title: string; reviewTitle: string; changes: FileChange[] }
|
|
13
14
|
| { id: string; kind: 'terminal'; title: string }
|
|
15
|
+
| { id: string; kind: 'mods' | 'background'; title: string }
|
|
14
16
|
|
|
15
17
|
interface Props {
|
|
16
18
|
surfaces: ToolSurface[]
|
|
@@ -31,10 +33,18 @@ interface Props {
|
|
|
31
33
|
onOpenFiles: () => void
|
|
32
34
|
onOpenSideChat?: () => void
|
|
33
35
|
onClosePanel: () => void
|
|
36
|
+
desktopTools?: boolean
|
|
37
|
+
backgroundTaskCount?: number
|
|
38
|
+
onOpenMods: () => void
|
|
39
|
+
onOpenBackgroundTasks: () => void
|
|
40
|
+
onModsPanelTarget: (target: HTMLDivElement | null) => void
|
|
41
|
+
onBackgroundPanelTarget: (target: HTMLDivElement | null) => void
|
|
34
42
|
}
|
|
35
43
|
|
|
36
44
|
|
|
37
45
|
function surfaceIcon(kind: ToolSurface['kind']) {
|
|
46
|
+
if (kind === 'mods') return <Puzzle size={13} aria-hidden="true" />
|
|
47
|
+
if (kind === 'background') return <ListTodo size={13} aria-hidden="true" />
|
|
38
48
|
if (kind === 'terminal') {
|
|
39
49
|
return (
|
|
40
50
|
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true" style={{ verticalAlign: '-1px' }}>
|
|
@@ -80,11 +90,34 @@ export default function ToolSurfacePage({
|
|
|
80
90
|
onOpenFiles,
|
|
81
91
|
onOpenSideChat,
|
|
82
92
|
onClosePanel,
|
|
93
|
+
desktopTools = true,
|
|
94
|
+
backgroundTaskCount = 0,
|
|
95
|
+
onOpenMods,
|
|
96
|
+
onOpenBackgroundTasks,
|
|
97
|
+
onModsPanelTarget,
|
|
98
|
+
onBackgroundPanelTarget,
|
|
83
99
|
}: Props) {
|
|
84
100
|
const active = surfaces.find((surface) => surface.id === activeSurfaceId) ?? surfaces[0] ?? null
|
|
85
101
|
const [switcherOpen, setSwitcherOpen] = useState(false)
|
|
86
102
|
const [tabMenuState, setTabMenuState] = useState<{ id: string; x: number; y: number } | null>(null)
|
|
87
103
|
const [isMaximized, setIsMaximized] = useState(false)
|
|
104
|
+
const panelRef = useRef<HTMLElement>(null)
|
|
105
|
+
|
|
106
|
+
useEffect(() => {
|
|
107
|
+
panelRef.current?.querySelector<HTMLButtonElement>('[role="tab"][aria-selected="true"], [role="menuitem"]')?.focus()
|
|
108
|
+
}, [active?.id])
|
|
109
|
+
|
|
110
|
+
useEffect(() => {
|
|
111
|
+
const dismiss = (event: KeyboardEvent) => {
|
|
112
|
+
if (event.key !== 'Escape' || event.defaultPrevented || !panelRef.current?.contains(event.target as Node)) return
|
|
113
|
+
event.preventDefault()
|
|
114
|
+
if (switcherOpen) { setSwitcherOpen(false); newTabWrapRef.current?.querySelector<HTMLButtonElement>('.tool-surface-dropdown-btn')?.focus() }
|
|
115
|
+
else if (tabMenuState) setTabMenuState(null)
|
|
116
|
+
else onClosePanel()
|
|
117
|
+
}
|
|
118
|
+
document.addEventListener('keydown', dismiss)
|
|
119
|
+
return () => document.removeEventListener('keydown', dismiss)
|
|
120
|
+
}, [onClosePanel, switcherOpen, tabMenuState])
|
|
88
121
|
|
|
89
122
|
const [isEntering, setIsEntering] = useState(true)
|
|
90
123
|
const [isResizing, setIsResizing] = useState(false)
|
|
@@ -193,10 +226,14 @@ export default function ToolSurfacePage({
|
|
|
193
226
|
)
|
|
194
227
|
|
|
195
228
|
const launcherItems = [
|
|
229
|
+
{ label: 'Mods', title: 'Workspace mods', shortcut: '', icon: <Puzzle />, className: 'is-mods', action: onOpenMods },
|
|
230
|
+
{ label: 'Background tasks', title: 'Background tasks', shortcut: '', icon: <ListTodo />, className: 'is-background', action: onOpenBackgroundTasks },
|
|
231
|
+
...(desktopTools ? [
|
|
196
232
|
{ label: 'Review', title: 'Review changes', shortcut: 'Ctrl+Shift+G', icon: <IconReview />, className: 'is-review', action: onOpenReview },
|
|
197
|
-
{ label: 'Terminal', title: 'Integrated terminal', shortcut: 'Ctrl`', icon: <IconTerminal />, className: 'is-terminal', action: onOpenTerminal },
|
|
233
|
+
{ label: 'Terminal', title: 'Integrated terminal', shortcut: 'Ctrl + `', icon: <IconTerminal />, className: 'is-terminal', action: onOpenTerminal },
|
|
198
234
|
{ label: 'Browser', title: 'Browser (Co-browsing with AI)', shortcut: 'Ctrl+T', icon: <IconBrowser />, className: 'is-browser', action: onOpenBrowser },
|
|
199
235
|
{ label: 'Workspace', title: 'Workspace files', shortcut: 'Ctrl+P', icon: <IconFiles />, className: 'is-files', action: onOpenFiles },
|
|
236
|
+
] : []),
|
|
200
237
|
]
|
|
201
238
|
|
|
202
239
|
const renderLauncher = (className = '') => (
|
|
@@ -204,7 +241,9 @@ export default function ToolSurfacePage({
|
|
|
204
241
|
{launcherItems.map((item) => (
|
|
205
242
|
<button type="button" role="menuitem" className="tool-surface-launcher-item" key={item.label} title={item.title} onClick={() => { item.action(); setSwitcherOpen(false) }}>
|
|
206
243
|
<span className={`tool-surface-menu-icon ${item.className}`} aria-hidden="true">{item.icon}</span>
|
|
207
|
-
<span>{item.label}</span
|
|
244
|
+
<span className="tool-surface-menu-copy"><span className="tool-surface-menu-label">{item.label}</span></span>
|
|
245
|
+
{item.className === 'is-background' && backgroundTaskCount > 0 && <span className="tools-task-count" aria-label={`${backgroundTaskCount} active background tasks`}>{backgroundTaskCount}</span>}
|
|
246
|
+
{item.shortcut && <kbd>{item.shortcut}</kbd>}
|
|
208
247
|
</button>
|
|
209
248
|
))}
|
|
210
249
|
</div>
|
|
@@ -218,7 +257,7 @@ export default function ToolSurfacePage({
|
|
|
218
257
|
const next = !open
|
|
219
258
|
if (next && newTabWrapRef.current) {
|
|
220
259
|
const rect = newTabWrapRef.current.getBoundingClientRect()
|
|
221
|
-
setMenuAlignRight(window.innerWidth - rect.left <
|
|
260
|
+
setMenuAlignRight(window.innerWidth - rect.left < 260)
|
|
222
261
|
}
|
|
223
262
|
return next
|
|
224
263
|
})
|
|
@@ -296,6 +335,10 @@ export default function ToolSurfacePage({
|
|
|
296
335
|
}
|
|
297
336
|
|
|
298
337
|
const handleAddNewTab = () => {
|
|
338
|
+
if (active?.kind === 'mods' || active?.kind === 'background') {
|
|
339
|
+
toggleSwitcher()
|
|
340
|
+
return
|
|
341
|
+
}
|
|
299
342
|
if (active?.kind === 'review') {
|
|
300
343
|
onOpenReview()
|
|
301
344
|
} else if (active?.kind === 'preview') {
|
|
@@ -305,7 +348,7 @@ export default function ToolSurfacePage({
|
|
|
305
348
|
}
|
|
306
349
|
}
|
|
307
350
|
|
|
308
|
-
const newTabTooltip = active?.kind === 'review'
|
|
351
|
+
const newTabTooltip = active?.kind === 'mods' || active?.kind === 'background' ? 'Open a tool' : active?.kind === 'review'
|
|
309
352
|
? 'New Review Tab'
|
|
310
353
|
: active?.kind === 'preview'
|
|
311
354
|
? 'Duplicate Preview Tab'
|
|
@@ -313,9 +356,10 @@ export default function ToolSurfacePage({
|
|
|
313
356
|
|
|
314
357
|
return (
|
|
315
358
|
<section
|
|
359
|
+
ref={panelRef}
|
|
316
360
|
className={`tool-surface-page ${isEntering ? 'is-entering' : ''} ${isMaximized ? 'is-maximized' : ''} ${isResizing ? 'is-resizing' : ''}`}
|
|
317
361
|
onAnimationEnd={() => setIsEntering(false)}
|
|
318
|
-
aria-label="
|
|
362
|
+
aria-label="Tools"
|
|
319
363
|
>
|
|
320
364
|
{!isMaximized && (
|
|
321
365
|
<div
|
|
@@ -416,6 +460,7 @@ export default function ToolSurfacePage({
|
|
|
416
460
|
onClick={(e) => { e.stopPropagation(); toggleSwitcher() }}
|
|
417
461
|
title="Switch tool or open page"
|
|
418
462
|
aria-label="Switch tool"
|
|
463
|
+
aria-haspopup="menu"
|
|
419
464
|
aria-expanded={switcherOpen}
|
|
420
465
|
>
|
|
421
466
|
<svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
|
|
@@ -425,8 +470,9 @@ export default function ToolSurfacePage({
|
|
|
425
470
|
{switcherOpen && (
|
|
426
471
|
<div
|
|
427
472
|
className={`tool-surface-switch-menu ${menuAlignRight ? 'is-align-right' : ''}`}
|
|
428
|
-
|
|
473
|
+
aria-label="Tool menu"
|
|
429
474
|
>
|
|
475
|
+
<div className="tool-surface-menu-heading">OPEN TOOL</div>
|
|
430
476
|
{renderLauncher('is-switch-menu')}
|
|
431
477
|
</div>
|
|
432
478
|
)}
|
|
@@ -437,8 +483,8 @@ export default function ToolSurfacePage({
|
|
|
437
483
|
type="button"
|
|
438
484
|
className={`tool-surface-action-btn ${isMaximized ? 'is-active' : ''}`}
|
|
439
485
|
onClick={() => setIsMaximized((prev) => !prev)}
|
|
440
|
-
title={isMaximized ? 'Restore side split' : 'Maximize
|
|
441
|
-
aria-label={isMaximized ? 'Restore side split' : 'Maximize
|
|
486
|
+
title={isMaximized ? 'Restore side split' : 'Maximize tools (⤢)'}
|
|
487
|
+
aria-label={isMaximized ? 'Restore side split' : 'Maximize tools'}
|
|
442
488
|
>
|
|
443
489
|
{isMaximized ? (
|
|
444
490
|
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
|
|
@@ -474,9 +520,9 @@ export default function ToolSurfacePage({
|
|
|
474
520
|
}}
|
|
475
521
|
role="menu"
|
|
476
522
|
>
|
|
477
|
-
<button type="button" role="menuitem" onClick={() => { onDuplicate(tabMenuState.id); setTabMenuState(null) }}>
|
|
523
|
+
{surfaces.find(surface => surface.id === tabMenuState.id)?.kind !== 'mods' && surfaces.find(surface => surface.id === tabMenuState.id)?.kind !== 'background' && <button type="button" role="menuitem" onClick={() => { onDuplicate(tabMenuState.id); setTabMenuState(null) }}>
|
|
478
524
|
Duplicate tab
|
|
479
|
-
</button>
|
|
525
|
+
</button>}
|
|
480
526
|
<button type="button" role="menuitem" onClick={() => { onRename(tabMenuState.id); setTabMenuState(null) }}>
|
|
481
527
|
Rename tab
|
|
482
528
|
</button>
|
|
@@ -493,7 +539,9 @@ export default function ToolSurfacePage({
|
|
|
493
539
|
|
|
494
540
|
<div className={`tool-surface-content${active ? '' : ' is-launcher'}`}>
|
|
495
541
|
{!active && renderLauncher()}
|
|
496
|
-
{active?.kind === '
|
|
542
|
+
{active?.kind === 'mods' && <div key="mods" className="tool-surface-panel-host" ref={onModsPanelTarget} />}
|
|
543
|
+
{active?.kind === 'background' && <div key="background" className="tool-surface-panel-host" ref={onBackgroundPanelTarget} />}
|
|
544
|
+
{active?.kind === 'preview' && <ArtifactPreviewPanel key={active.id} artifact={active.artifact} onClose={() => active && onClose(active.id)} workspacePath={workspacePath || undefined} />}
|
|
497
545
|
{active?.kind === 'review' && (
|
|
498
546
|
<CodeReviewPage
|
|
499
547
|
title={active.reviewTitle}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import '../css/tools-panel.css'
|
|
2
|
+
|
|
3
|
+
export default function ToolsPanelToggle({ open, count = 0, onToggle, className = '' }: {
|
|
4
|
+
open: boolean; count?: number; onToggle: () => void; className?: string
|
|
5
|
+
}) {
|
|
6
|
+
return <button type="button" className={`tools-panel-toggle ${className}${open ? ' is-open' : ''}`}
|
|
7
|
+
aria-label={open ? 'Close tools panel' : 'Open tools panel'} aria-expanded={open}
|
|
8
|
+
title={open ? 'Close tools panel' : 'Open tools panel'} onClick={onToggle}>
|
|
9
|
+
<svg viewBox="0 0 24 24" aria-hidden="true"><rect x="3" y="4" width="18" height="16" rx="2"/><path d="M15 4v16M18 8h1M18 12h1M18 16h1"/></svg>
|
|
10
|
+
<span className="tools-toggle-label">Tools</span>
|
|
11
|
+
{count > 0 && <span className="tools-task-count" aria-label={`${count} active background tasks`}>{count}</span>}
|
|
12
|
+
</button>
|
|
13
|
+
}
|