@pheem49/mint 1.14.0 → 1.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Cargo.lock +1258 -35
- package/Cargo.toml +5 -2
- package/LICENSE +21 -654
- package/README.md +93 -756
- package/Release_Note.md +53 -446
- package/apps/mint-companion/src-tauri/Cargo.toml +20 -0
- package/apps/mint-companion/src-tauri/build.rs +3 -0
- package/apps/mint-companion/src-tauri/src/main.rs +468 -0
- package/apps/mint-companion/tsconfig.json +20 -0
- package/apps/mint-companion/vite.config.ts +3 -0
- package/components.json +19 -0
- package/crates/mint-cli/Cargo.toml +9 -1
- package/crates/mint-cli/src/agent/approval_prompts.rs +16 -3
- package/crates/mint-cli/src/agent/live_status.rs +545 -148
- package/crates/mint-cli/src/agent/markdown_render.rs +601 -61
- package/crates/mint-cli/src/agent.rs +723 -258
- package/crates/mint-cli/src/commands/agent.rs +83 -74
- package/crates/mint-cli/src/commands/eval.rs +9 -5
- package/crates/mint-cli/src/commands/git.rs +204 -0
- package/crates/mint-cli/src/commands/integrations.rs +35 -0
- package/crates/mint-cli/src/commands/knowledge.rs +13 -32
- package/crates/mint-cli/src/commands/mod.rs +81 -2
- package/crates/mint-cli/src/commands/tailnet_web.rs +235 -0
- package/crates/mint-cli/src/image.rs +32 -11
- package/crates/mint-cli/src/interactive/chat_tui.rs +7853 -0
- package/crates/mint-cli/src/interactive/command_ui.rs +477 -0
- package/crates/mint-cli/src/interactive/format.rs +8 -0
- package/crates/mint-cli/src/interactive/input_box.rs +94 -8
- package/crates/mint-cli/src/interactive/picker.rs +180 -37
- package/crates/mint-cli/src/interactive/resume_picker.rs +686 -0
- package/crates/mint-cli/src/interactive/slash_commands.rs +1071 -501
- package/crates/mint-cli/src/interactive/thought_viewer.rs +286 -0
- package/crates/mint-cli/src/interactive/tool_activity.rs +328 -0
- package/crates/mint-cli/src/interactive.rs +454 -166
- package/crates/mint-cli/src/main.rs +93 -26
- package/crates/mint-cli/src/markdown.rs +12 -5
- package/crates/mint-cli/src/mcp.rs +5 -0
- package/crates/mint-cli/src/mod_host.rs +6 -0
- package/crates/mint-cli/src/mods_cli.rs +62 -0
- package/crates/mint-cli/src/mods_ui.rs +187 -0
- package/crates/mint-cli/src/onboard.rs +37 -61
- package/crates/mint-cli/src/plugins_cli.rs +8 -5
- package/crates/mint-cli/src/setup.rs +10 -8
- package/crates/mint-cli/src/terminal_theme.rs +189 -0
- package/crates/mint-cli/src/updater.rs +112 -23
- package/crates/mint-cli/tests/library_intake.rs +77 -0
- package/crates/mint-cli/tests/mods_testing.rs +133 -0
- package/crates/mint-companion-protocol/Cargo.toml +10 -0
- package/crates/mint-companion-protocol/src/lib.rs +163 -0
- package/crates/mint-core/Cargo.toml +6 -3
- package/crates/mint-core/build.rs +26 -0
- package/crates/mint-core/src/agent/agent_loop.rs +1 -0
- package/crates/mint-core/src/agent/chat.rs +1003 -209
- package/crates/mint-core/src/agent/code_tools.rs +98 -2
- package/crates/mint-core/src/agent/memory/sources.rs +240 -0
- package/crates/mint-core/src/agent/memory.rs +805 -33
- package/crates/mint-core/src/agent/skill_inventory.rs +325 -0
- package/crates/mint-core/src/agent/skills.rs +437 -90
- package/crates/mint-core/src/agent.rs +1 -0
- package/crates/mint-core/src/api_server/routes/background_jobs.rs +310 -0
- package/crates/mint-core/src/api_server/routes/chat.rs +233 -190
- package/crates/mint-core/src/api_server/routes/html_preview.rs +77 -0
- package/crates/mint-core/src/api_server/routes/library.rs +97 -0
- package/crates/mint-core/src/api_server/routes/linked_folders.rs +118 -3
- package/crates/mint-core/src/api_server/routes/media_gen.rs +10 -57
- package/crates/mint-core/src/api_server/routes/misc.rs +114 -121
- package/crates/mint-core/src/api_server/routes/mod.rs +6 -0
- package/crates/mint-core/src/api_server/routes/mods.rs +31 -0
- package/crates/mint-core/src/api_server/routes/sessions.rs +85 -0
- package/crates/mint-core/src/api_server/routes/skills_subagents.rs +12 -42
- package/crates/mint-core/src/api_server/routes/slash.rs +50 -1
- package/crates/mint-core/src/api_server/routes/sources.rs +101 -0
- package/crates/mint-core/src/api_server.rs +140 -12
- package/crates/mint-core/src/avatar_bridge.rs +13 -2
- package/crates/mint-core/src/browser/cdp.rs +74 -83
- package/crates/mint-core/src/browser/evidence.rs +260 -0
- package/crates/mint-core/src/browser/input.rs +1 -1
- package/crates/mint-core/src/browser/interact.rs +98 -124
- package/crates/mint-core/src/browser/lifecycle.rs +75 -4
- package/crates/mint-core/src/browser/mod.rs +16 -2
- package/crates/mint-core/src/browser/navigate.rs +27 -19
- package/crates/mint-core/src/browser/observe.js +40 -0
- package/crates/mint-core/src/browser/session.rs +1610 -0
- package/crates/mint-core/src/companion.rs +716 -0
- package/crates/mint-core/src/cron/scheduler.rs +34 -2
- package/crates/mint-core/src/git/branches.rs +348 -0
- package/crates/mint-core/src/git/checkpoint.rs +40 -0
- package/crates/mint-core/src/git/diff.rs +206 -0
- package/crates/mint-core/src/git/mod.rs +10 -2
- package/crates/mint-core/src/integrations/channels.rs +88 -345
- package/crates/mint-core/src/integrations/mcp.rs +397 -50
- package/crates/mint-core/src/integrations/mcp_calls.rs +823 -0
- package/crates/mint-core/src/integrations/mcp_catalog.rs +267 -0
- package/crates/mint-core/src/integrations/mcp_device.rs +319 -0
- package/crates/mint-core/src/integrations/mcp_result.rs +356 -0
- package/crates/mint-core/src/integrations/webhooks.rs +539 -0
- package/crates/mint-core/src/integrations.rs +2 -0
- package/crates/mint-core/src/lib.rs +107 -40
- package/crates/mint-core/src/live_sync.rs +28 -9
- package/crates/mint-core/src/media/auto_shorts.rs +1 -0
- package/crates/mint-core/src/media/gemini_live.rs +145 -14
- package/crates/mint-core/src/media/image_models.rs +3 -27
- package/crates/mint-core/src/media/image_workflow.rs +216 -0
- package/crates/mint-core/src/media/library/intake.rs +144 -0
- package/crates/mint-core/src/media/library/migration.rs +56 -0
- package/crates/mint-core/src/media/library/removal.rs +55 -0
- package/crates/mint-core/src/media/library/tests.rs +730 -0
- package/crates/mint-core/src/media/library/thumbnails.rs +72 -0
- package/crates/mint-core/src/media/library.rs +545 -0
- package/crates/mint-core/src/media/mic_transcribe.rs +1 -0
- package/crates/mint-core/src/media/model_catalog.rs +375 -0
- package/crates/mint-core/src/media/pictures.rs +79 -222
- package/crates/mint-core/src/media/subtitle.rs +1 -0
- package/crates/mint-core/src/media/video_models.rs +3 -22
- package/crates/mint-core/src/media.rs +3 -0
- package/crates/mint-core/src/mods/manager.rs +1124 -0
- package/crates/mint-core/src/mods/mod.rs +569 -0
- package/crates/mint-core/src/mods/operations.rs +204 -0
- package/crates/mint-core/src/mods/session.rs +146 -0
- package/crates/mint-core/src/mods/slash.rs +59 -0
- package/crates/mint-core/src/mods/telemetry.rs +306 -0
- package/crates/mint-core/src/orchestration/approvals.rs +344 -0
- package/crates/mint-core/src/orchestration/context_render.rs +105 -0
- package/crates/mint-core/src/orchestration/mcp_review.rs +153 -0
- package/crates/mint-core/src/orchestration/memory_skill.rs +110 -33
- package/crates/mint-core/src/orchestration/mod.rs +3129 -481
- package/crates/mint-core/src/orchestration/mod_authoring_regressions.rs +209 -0
- package/crates/mint-core/src/orchestration/progress_clock.rs +80 -0
- package/crates/mint-core/src/orchestration/repeated_failures.rs +116 -0
- package/crates/mint-core/src/orchestration/review_regressions.rs +449 -0
- package/crates/mint-core/src/orchestration/run_control.rs +196 -0
- package/crates/mint-core/src/orchestration/tools/browser.rs +16 -139
- package/crates/mint-core/src/orchestration/tools/files.rs +161 -14
- package/crates/mint-core/src/orchestration/tools/media.rs +37 -41
- package/crates/mint-core/src/orchestration/tools/misc.rs +5 -3
- package/crates/mint-core/src/orchestration/tools/mod.rs +2 -0
- package/crates/mint-core/src/orchestration/tools/mods.rs +161 -0
- package/crates/mint-core/src/orchestration/tools/plugins_mcp.rs +303 -71
- package/crates/mint-core/src/orchestration/tools/shell.rs +95 -2
- package/crates/mint-core/src/orchestration/tools/web.rs +1 -1
- package/crates/mint-core/src/orchestration/workspace_helpers.rs +4 -1
- package/crates/mint-core/src/prompts/agent.rs +75 -31
- package/crates/mint-core/src/prompts/chat.rs +1 -1
- package/crates/mint-core/src/prompts/persona.rs +1 -1
- package/crates/mint-core/src/prompts/tool_catalog.rs +121 -27
- package/crates/mint-core/src/search/knowledge.rs +7 -1
- package/crates/mint-core/src/search/linked_folders/index.rs +896 -0
- package/crates/mint-core/src/search/linked_folders.rs +473 -131
- package/crates/mint-core/src/slash/catalog.rs +1 -1
- package/crates/mint-core/src/slash/mod.rs +644 -33
- package/crates/mint-core/src/slash/model_fetcher.rs +12 -3
- package/crates/mint-core/src/slash/models.rs +66 -10
- package/crates/mint-core/src/slash/mods.rs +155 -0
- package/crates/mint-core/src/system/bg_shell.rs +1129 -95
- package/crates/mint-core/src/system/config.rs +235 -10
- package/crates/mint-core/src/system/html_preview.rs +398 -0
- package/crates/mint-core/src/system/mint_web.rs +164 -0
- package/crates/mint-core/src/system/release_notes.rs +18 -0
- package/crates/mint-core/src/system/shell.rs +21 -6
- package/crates/mint-core/src/system/workspace.rs +292 -0
- package/crates/mint-core/src/system/workspace_history.rs +604 -0
- package/crates/mint-core/src/system.rs +5 -0
- package/crates/mint-core/tests/background_retention.rs +34 -0
- package/crates/mint-core/tests/background_shutdown.rs +24 -0
- package/crates/mint-core/tests/library_http.rs +209 -0
- package/crates/mint-core/tests/mcp_contract.rs +283 -0
- package/crates/mint-core/tests/mcp_stdio.rs +11 -10
- package/crates/mint-core/tests/media_model_catalog_http.rs +403 -0
- package/crates/mint-core/tests/memory_persistence.rs +39 -0
- package/crates/mint-core/tests/mods_http.rs +215 -0
- package/crates/mint-core/tests/terminal_shutdown.rs +109 -0
- package/crates/mint-mod-runtime/Cargo.toml +18 -0
- package/crates/mint-mod-runtime/src/lib.rs +507 -0
- package/crates/mint-mod-runtime/src/sdk.js +56 -0
- package/crates/mint-mod-runtime/src/test_sdk.js +32 -0
- package/crates/mint-mod-runtime/src/testing.rs +94 -0
- package/crates/mint-mod-runtime/tests/runtime.rs +156 -0
- package/docs/mods/AUTHORING.md +61 -0
- package/docs/mods/README.md +139 -0
- package/docs/mods/TESTING.md +56 -0
- package/docs/mods/mint-mods.d.ts +66 -0
- package/examples/device-mcp/README.md +22 -0
- package/examples/device-mcp/contract.md +49 -0
- package/examples/device-mcp/mock-device.mjs +66 -0
- package/examples/device-mcp/server.mjs +48 -0
- package/examples/device-mcp/server.test.mjs +78 -0
- package/examples/mods/task-checklist/README.md +1 -0
- package/examples/mods/task-checklist/main.ts +17 -0
- package/examples/mods/task-checklist/manifest.json +1 -0
- package/examples/mods/task-checklist/tests/checklist.test.ts +15 -0
- package/examples/mods/token-meter/README.md +1 -0
- package/examples/mods/token-meter/main.ts +8 -0
- package/examples/mods/token-meter/manifest.json +1 -0
- package/examples/mods/tool-guard/README.md +1 -0
- package/examples/mods/tool-guard/main.ts +9 -0
- package/examples/mods/tool-guard/manifest.json +1 -0
- package/out/web/assets/CliSessionsView-CtzUJpK_.css +1 -0
- package/out/web/assets/CliSessionsView-D7hw0Mgj.js +1 -0
- package/out/web/assets/CodeReviewPage-C7bEOJfd.js +4 -0
- package/out/web/assets/CodeReviewPage-Dte9uLiL.css +1 -0
- package/out/web/assets/CommandPalette-0RrF-AOT.js +1 -0
- package/out/web/assets/ImageStudioPanel-CdxkAf_r.js +1 -0
- package/out/web/assets/ImageStudioPanel-D0lnhQV5.css +1 -0
- package/out/web/assets/LibraryPage--Qfisp6D.js +2 -0
- package/out/web/assets/LibraryPage-DAxUTAg7.css +1 -0
- package/out/web/assets/LinkedFoldersView-2nfZbDgN.js +1 -0
- package/out/web/assets/McpRegistryPicker-h9uS8_wT.js +1 -0
- package/out/web/assets/McpServersView-slfQJzNB.js +1 -0
- package/out/web/assets/MintDashboard-BSR5XpXh.js +25 -0
- package/out/web/assets/MintDashboard-CWUcCGhd.css +1 -0
- package/out/web/assets/PluginsView-l7LSm503.js +1 -0
- package/out/web/assets/ScheduledTasksView-CttmLbq1.js +1 -0
- package/out/web/assets/SettingsWindow-BCMLYvEV.js +4 -0
- package/out/web/assets/SettingsWindow-DcMVmU9u.css +1 -0
- package/out/web/assets/SkillsView-rNs1qr_U.js +2 -0
- package/out/web/assets/ToolSurfacePage-B9DzEPWN.js +37 -0
- package/out/web/assets/ToolSurfacePage-CTfgggF2.css +1 -0
- package/out/web/assets/VeoStudioPanel-DOj7_WR3.css +1 -0
- package/out/web/assets/VeoStudioPanel-DiJs_Cg2.js +4 -0
- package/out/web/assets/WorkspacePanel-CbJ1PFoZ.js +1 -0
- package/out/web/assets/WorkspaceSelector-B2xIp04D.js +1 -0
- package/out/web/assets/WorkspaceSelector-Ca8uJOsS.css +1 -0
- package/out/web/assets/{abnfDiagram-VCTEODGH-DAOBA7ZG.js → abnfDiagram-VCTEODGH-CD0CjoGl.js} +1 -1
- package/out/web/assets/{architecture-7GRP2DOG-CgSwQOPQ.js → architecture-7GRP2DOG-RKV83OeZ.js} +1 -1
- package/out/web/assets/{architectureDiagram-5GKGNRK7-CYp3yupP.js → architectureDiagram-5GKGNRK7-nN_HAFct.js} +1 -1
- package/out/web/assets/{blockDiagram-NRAW4CY4-CyWybDWr.js → blockDiagram-NRAW4CY4-BrrqzHW5.js} +1 -1
- package/out/web/assets/{c4Diagram-UCG6FXSJ-BvY3U709.js → c4Diagram-UCG6FXSJ-DTdV8_zE.js} +1 -1
- package/out/web/assets/{chunk-75Z2AOVW-TLXCoZYv.js → chunk-75Z2AOVW-_M0z5olV.js} +1 -1
- package/out/web/assets/chunk-CKBBP62Z-BpQEgeHF.js +2 -0
- package/out/web/assets/{chunk-CLGD4ZFX-xjsKtNS7.js → chunk-CLGD4ZFX-D54yGvGS.js} +1 -1
- package/out/web/assets/chunk-DSNCTWBM-C-gvT2ru.js +2 -0
- package/out/web/assets/chunk-DU6HZSFF-CnFngIhW.js +128 -0
- package/out/web/assets/{chunk-F27PBJKO-BFpgF55A.js → chunk-F27PBJKO-BqtWrnEO.js} +1 -1
- package/out/web/assets/{chunk-G27WJ6UU-DfF7qW-C.js → chunk-G27WJ6UU-Ckoq5mi2.js} +1 -1
- package/out/web/assets/{chunk-GMAD6QVW-C-558kh_.js → chunk-GMAD6QVW-BuhEcgHq.js} +1 -1
- package/out/web/assets/{chunk-JQ64N6SF-wJmeGKAw.js → chunk-JQ64N6SF-CF8T7GiZ.js} +1 -1
- package/out/web/assets/{chunk-LCL6LL3I-C1wHD8Ie.js → chunk-LCL6LL3I-BhXV9zyH.js} +1 -1
- package/out/web/assets/{chunk-OBVCFTLP-BsRTPBqs.js → chunk-OBVCFTLP-CRIkunUB.js} +1 -1
- package/out/web/assets/{chunk-P2QGCYS3-HZIiM7Ni.js → chunk-P2QGCYS3-UFEU6BxZ.js} +1 -1
- package/out/web/assets/{chunk-POPQ4Y6H-Dk9wvVb0.js → chunk-POPQ4Y6H-CQcrNbjr.js} +1 -1
- package/out/web/assets/{chunk-PWAF6VOD-BmjYLNbq.js → chunk-PWAF6VOD-Cc2uVDsG.js} +1 -1
- package/out/web/assets/{chunk-R7TYR2AO-CaHIf-lK.js → chunk-R7TYR2AO-DiCxzdAY.js} +1 -1
- package/out/web/assets/{chunk-RHFEMEQ7-_T561hOU.js → chunk-RHFEMEQ7-b7hnPmrR.js} +1 -1
- package/out/web/assets/{chunk-SVP7TREG-CM-GGYoY.js → chunk-SVP7TREG-Bu_yYb-V.js} +1 -1
- package/out/web/assets/{chunk-TEH6E4GO-K2A8Vg2C.js → chunk-TEH6E4GO-G4Cdlyrt.js} +1 -1
- package/out/web/assets/classDiagram-DTDB5LWJ-RnC2mYO4.js +1 -0
- package/out/web/assets/classDiagram-v2-JRS7N3AN-RnC2mYO4.js +1 -0
- package/out/web/assets/config-CnvCChUM.js +2 -0
- package/out/web/assets/config-DM6oIVO3.css +1 -0
- package/out/web/assets/core-DsKkQ7ig.js +1 -0
- package/out/web/assets/{cynefin-OW5HDTMX-ClzaB6cc.js → cynefin-OW5HDTMX-CnzQfOGp.js} +1 -1
- package/out/web/assets/{cynefinDiagram-5FMLGOSQ-D_JzZBzf.js → cynefinDiagram-5FMLGOSQ-DVtQnfpm.js} +1 -1
- package/out/web/assets/{dagre-3AP2YEHR-BDuUeMHj.js → dagre-3AP2YEHR-DG76_k5_.js} +1 -1
- package/out/web/assets/{diagram-S7CK7UJ4-DgtcfE8P.js → diagram-S7CK7UJ4-CaouUoze.js} +1 -1
- package/out/web/assets/{diagram-UQ7AKVKN-DTLoEYti.js → diagram-UQ7AKVKN-B4bEc26B.js} +1 -1
- package/out/web/assets/{diagram-VSXAHHWV-ChGl9pXz.js → diagram-VSXAHHWV-BJ86Ov2Y.js} +1 -1
- package/out/web/assets/{diagram-VX7I27RA-Be8DWz0S.js → diagram-VX7I27RA-7hH5IPYf.js} +1 -1
- package/out/web/assets/{diagram-Z3DM3KII-BMXjRTOF.js → diagram-Z3DM3KII-CCM4clo8.js} +1 -1
- package/out/web/assets/dist-js-BkYNznHX.js +1 -0
- package/out/web/assets/{ebnfDiagram-PWID7BFC-8Q9pl1CJ.js → ebnfDiagram-PWID7BFC-Da7WAM3k.js} +1 -1
- package/out/web/assets/{erDiagram-SSCWMZ5O-DjH8Lnkn.js → erDiagram-SSCWMZ5O-CzzmnZWT.js} +1 -1
- package/out/web/assets/event-Cdt7Byyj.js +1 -0
- package/out/web/assets/{eventmodeling-NTZA5JFV-BKUH_DOp.js → eventmodeling-NTZA5JFV-xcfsA0XD.js} +1 -1
- package/out/web/assets/fira-code-latin-600-normal-BmSSHshu.woff +0 -0
- package/out/web/assets/fira-code-latin-600-normal-CvYZpPHg.woff2 +0 -0
- package/out/web/assets/fira-code-symbols2-600-normal-Dvq6IQE5.woff +0 -0
- package/out/web/assets/flowDiagram-A5DVABFB-JdtH1673.js +1 -0
- package/out/web/assets/{ganttDiagram-EL5Y4UJY-D7fZKJNM.js → ganttDiagram-EL5Y4UJY-B3ClFGmL.js} +1 -1
- package/out/web/assets/{gitGraph-4MIJSDKK-BypWaaBU.js → gitGraph-4MIJSDKK-BZ_y_cDU.js} +1 -1
- package/out/web/assets/{gitGraphDiagram-WWUBYQGX-DWiw_3bq.js → gitGraphDiagram-WWUBYQGX-drhRSYm3.js} +1 -1
- package/out/web/assets/index-BZ9xgmMP.css +1 -0
- package/out/web/assets/index-Ca8cCS4h.js +168 -0
- package/out/web/assets/{info-A6RAGUB7-KkAUxT4j.js → info-A6RAGUB7-B7I3K0F1.js} +1 -1
- package/out/web/assets/{infoDiagram-RXCK75RN-BNb6E48y.js → infoDiagram-RXCK75RN-deX_1MPh.js} +1 -1
- package/out/web/assets/{ishikawaDiagram-5VMMS53U-Caa-JoAK.js → ishikawaDiagram-5VMMS53U-s38yo28y.js} +1 -1
- package/out/web/assets/{journeyDiagram-EYS64GPL-DOrmFGz6.js → journeyDiagram-EYS64GPL-CZn2kB8b.js} +1 -1
- package/out/web/assets/jsx-runtime-DN4NhQUK.js +1 -0
- package/out/web/assets/{kanban-definition-3QL26DDD-BOWCYcK0.js → kanban-definition-3QL26DDD-DodjgySL.js} +1 -1
- package/out/web/assets/markdown-CMhYIcWB.js +39 -0
- package/out/web/assets/{mermaid-parser.core-BQqjCkS_.js → mermaid-parser.core-Whu2rlJC.js} +3 -3
- package/out/web/assets/mermaid.core-CKyPo8VH.js +11 -0
- package/out/web/assets/{mindmap-definition-FBJOCRG2-jTceWpr0.js → mindmap-definition-FBJOCRG2-260WBDxZ.js} +1 -1
- package/out/web/assets/modelManager-CUaGWMWu.js +2 -0
- package/out/web/assets/oauthManager-DlNhXJr6.js +1 -0
- package/out/web/assets/{packet-AYTQ26CC-CJ5RXgol.js → packet-AYTQ26CC-CEeIRKRG.js} +1 -1
- package/out/web/assets/{pegDiagram-XKGWAZYB-y8wMtd0y.js → pegDiagram-XKGWAZYB-BYadI-KO.js} +1 -1
- package/out/web/assets/{pie-WAS4IAKB-72fTBbl4.js → pie-WAS4IAKB-D8uf4dh5.js} +1 -1
- package/out/web/assets/{pieDiagram-E7YTZNPT-e0O02qWq.js → pieDiagram-E7YTZNPT-CjSDy4hO.js} +1 -1
- package/out/web/assets/{quadrantDiagram-AXDQQJYC-C9phYLom.js → quadrantDiagram-AXDQQJYC-B8D3gU5d.js} +1 -1
- package/out/web/assets/{radar-RG4KPBEZ-BAU2hzUT.js → radar-RG4KPBEZ-DZJxnokY.js} +1 -1
- package/out/web/assets/{railroad-74A4TZTK-B0bCAVHC.js → railroad-74A4TZTK-DBysUiUi.js} +1 -1
- package/out/web/assets/{railroad-abnf-HS5TGJTU-WhxO7ndE.js → railroad-abnf-HS5TGJTU-CHWxoJYg.js} +1 -1
- package/out/web/assets/{railroad-ebnf-LZEXJU2U-BkA0m7-F.js → railroad-ebnf-LZEXJU2U-DDv7X6bY.js} +1 -1
- package/out/web/assets/{railroad-peg-WCYAUIDC-BsVpHIaj.js → railroad-peg-WCYAUIDC-DpfcYYNJ.js} +1 -1
- package/out/web/assets/{railroadDiagram-O6MQD6OU-CyOLN65Q.js → railroadDiagram-O6MQD6OU-CYtyv0t3.js} +1 -1
- package/out/web/assets/{requirementDiagram-EFPCY7ZU-DQXJ7Dud.js → requirementDiagram-EFPCY7ZU-D2X-Ewik.js} +1 -1
- package/out/web/assets/{sankeyDiagram-P5KCCOFB-B2XLyIIc.js → sankeyDiagram-P5KCCOFB-Bn2x6C4Y.js} +1 -1
- package/out/web/assets/{sequenceDiagram-WJ2MYXX4-DGQY4wwm.js → sequenceDiagram-WJ2MYXX4-BvFLKtPd.js} +1 -1
- package/out/web/assets/{stateDiagram-HBIQ2CUA-DHZpDwNy.js → stateDiagram-HBIQ2CUA-Bx0GWeaY.js} +1 -1
- package/out/web/assets/stateDiagram-v2-4QOOHH4V--hol1yg_.js +1 -0
- package/out/web/assets/studio-B1mk40wD.js +1 -0
- package/out/web/assets/{swimlanes-XN3QIQJK-Bn_jcZz-.js → swimlanes-XN3QIQJK-CCma0T7L.js} +1 -1
- package/out/web/assets/swimlanesDiagram-VK2B7HYN-BkohoVsU.js +8 -0
- package/out/web/assets/{timeline-definition-24CTP7MA-CdTERuJZ.js → timeline-definition-24CTP7MA-iCRhhJ7C.js} +1 -1
- package/out/web/assets/{treeView-Q6P3EWNA-TKBKQG6R.js → treeView-Q6P3EWNA-DZ-y08qp.js} +1 -1
- package/out/web/assets/{treemap-WGGIJYW6-BP7gQoiC.js → treemap-WGGIJYW6-De0CxzMx.js} +1 -1
- package/out/web/assets/{vennDiagram-4TSXK5OY-BHUmxDuK.js → vennDiagram-4TSXK5OY-w_7aZ6xe.js} +1 -1
- package/out/web/assets/{wardley-WFR3VGLG-9bct5AAN.js → wardley-WFR3VGLG-DT0y0xJ4.js} +1 -1
- package/out/web/assets/{wardleyDiagram-VM6X3IG4-BfJwDDso.js → wardleyDiagram-VM6X3IG4-DAdXELbQ.js} +1 -1
- package/out/web/assets/window-BJCVtyET.js +1 -0
- package/out/web/assets/{xychartDiagram-S5SC5T6Z-Dqd9Mvpo.js → xychartDiagram-S5SC5T6Z-IZIXf3Vo.js} +1 -1
- package/out/web/index-web.html +4 -4
- package/out/web/index.html +4 -4
- package/package.json +80 -20
- package/shared-modules/.github/workflows/ci.yml +120 -0
- package/shared-modules/.github/workflows/update.yaml +28 -0
- package/slash-commands.json +16 -2
- package/src/bin/auto-build.js +66 -0
- package/src/bin/desktop.js +113 -0
- package/src/bin/desktop.test.js +113 -0
- package/src/bin/index.js +18 -25
- package/src/bin/index.test.js +89 -0
- package/src/bin/measure-effects.mjs +53 -0
- package/src/bin/package.test.js +28 -0
- package/src/bin/release-notes.test.js +84 -0
- package/src/bin/styles.test.js +20 -0
- package/src/bin/web.js +5 -0
- package/src/bin/web.test.js +39 -0
- package/src/renderer/index-web.html +1 -0
- package/src/renderer/index.html +1 -2
- package/src/renderer/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
- package/src/renderer/shared/agentProgress.ts +201 -3
- package/src/renderer/shared/components/AgentActivityDrawer.tsx +9 -8
- package/src/renderer/shared/components/AgentActivityTable.tsx +193 -133
- package/src/renderer/shared/components/ApprovalCard.test.tsx +24 -0
- package/src/renderer/shared/components/ApprovalCard.tsx +10 -3
- package/src/renderer/shared/components/ArtifactPreviewPanel.tsx +91 -40
- package/src/renderer/shared/components/AuthGate.tsx +79 -48
- package/src/renderer/shared/components/BackgroundTerminals.tsx +181 -0
- package/src/renderer/shared/components/CalculationCard.tsx +41 -15
- package/src/renderer/shared/components/ChatCodeBlock.tsx +8 -4
- package/src/renderer/shared/components/ChatMessageItem.test.tsx +68 -0
- package/src/renderer/shared/components/ChatMessageItem.tsx +52 -33
- package/src/renderer/shared/components/ChatPanel.test.tsx +21 -0
- package/src/renderer/shared/components/ChatPanel.tsx +676 -415
- package/src/renderer/shared/components/ChunkErrorBoundary.tsx +115 -64
- package/src/renderer/shared/components/CliSessionsView.test.tsx +125 -0
- package/src/renderer/shared/components/CliSessionsView.tsx +543 -0
- package/src/renderer/shared/components/CodeReviewPage.tsx +668 -0
- package/src/renderer/shared/components/CollapsiblePasteInput.tsx +90 -0
- package/src/renderer/shared/components/CommandPalette.tsx +8 -8
- package/src/renderer/shared/components/ContextCompactionStatus.tsx +17 -0
- package/src/renderer/shared/components/DashboardSidebar.tsx +853 -229
- package/src/renderer/shared/components/DesktopTitlebar.tsx +371 -0
- package/src/renderer/shared/components/DiffReviewModal.tsx +3 -3
- package/src/renderer/shared/components/ErrorNotice.tsx +29 -0
- package/src/renderer/shared/components/FormattedMessage.tsx +11 -0
- package/src/renderer/shared/components/GeminiLiveOverlay.css +86 -0
- package/src/renderer/shared/components/GeminiLiveOverlay.test.tsx +24 -0
- package/src/renderer/shared/components/GeminiLiveOverlay.tsx +85 -101
- package/src/renderer/shared/components/GitBranchSelector.tsx +442 -0
- package/src/renderer/shared/components/GlideSelect.css +138 -0
- package/src/renderer/shared/components/GlideSelect.d.ts +31 -0
- package/src/renderer/shared/components/GlideSelect.jsx +266 -0
- package/src/renderer/shared/components/ImageGenCard.tsx +31 -12
- package/src/renderer/shared/components/ImageSearchCard.tsx +76 -65
- package/src/renderer/shared/components/ImageStudioPanel.tsx +49 -49
- package/src/renderer/shared/components/InlineThoughtNote.tsx +27 -0
- package/src/renderer/shared/components/LibraryItemCard.tsx +72 -0
- package/src/renderer/shared/components/LibraryPage.tsx +165 -0
- package/src/renderer/shared/components/LibraryPreview.tsx +59 -0
- package/src/renderer/shared/components/LinkedFoldersView.tsx +365 -46
- package/src/renderer/shared/components/McpRegistryPicker.tsx +1 -1
- package/src/renderer/shared/components/McpServersView.tsx +51 -30
- package/src/renderer/shared/components/McpToolAllowlist.tsx +2 -4
- package/src/renderer/shared/components/McpToolResults.tsx +99 -0
- package/src/renderer/shared/components/MermaidCard.tsx +14 -8
- package/src/renderer/shared/components/MintDashboard.tsx +1002 -831
- package/src/renderer/shared/components/ModSessionControls.tsx +8 -0
- package/src/renderer/shared/components/ModUi.test.tsx +65 -0
- package/src/renderer/shared/components/ModUi.tsx +26 -0
- package/src/renderer/shared/components/ModelSelectorPopover.tsx +547 -219
- package/src/renderer/shared/components/ModsPanel.tsx +156 -0
- package/src/renderer/shared/components/PlanChecklistWidget.tsx +1 -1
- package/src/renderer/shared/components/PluginsView.tsx +1 -1
- package/src/renderer/shared/components/ProgressActivity.tsx +17 -0
- package/src/renderer/shared/components/ReviewHistory.tsx +42 -0
- package/src/renderer/shared/components/RewindModal.tsx +11 -18
- package/src/renderer/shared/components/RunSummaryDashboard.tsx +8 -14
- package/src/renderer/shared/components/ScheduledTasksView.tsx +11 -10
- package/src/renderer/shared/components/ScreenCaptureDialog.css +221 -0
- package/src/renderer/shared/components/ScreenCaptureDialog.tsx +199 -0
- package/src/renderer/shared/components/SelectField.test.tsx +27 -0
- package/src/renderer/shared/components/SelectField.tsx +38 -0
- package/src/renderer/shared/components/SessionSources.tsx +48 -0
- package/src/renderer/shared/components/SessionSourcesPopover.tsx +61 -0
- package/src/renderer/shared/components/Settings/AgentsTab.tsx +41 -45
- package/src/renderer/shared/components/Settings/AudioTab.tsx +16 -15
- package/src/renderer/shared/components/Settings/AutomationTab.tsx +10 -60
- package/src/renderer/shared/components/Settings/AvatarCropModal.tsx +368 -0
- package/src/renderer/shared/components/Settings/GeneralTab.tsx +368 -113
- package/src/renderer/shared/components/Settings/MemoryTab.test.tsx +37 -0
- package/src/renderer/shared/components/Settings/MemoryTab.tsx +71 -31
- package/src/renderer/shared/components/Settings/NotificationsTab.test.tsx +15 -0
- package/src/renderer/shared/components/Settings/NotificationsTab.tsx +84 -0
- package/src/renderer/shared/components/Settings/PluginsTab.tsx +20 -12
- package/src/renderer/shared/components/Settings/ProfileTab.tsx +29 -5
- package/src/renderer/shared/components/Settings/SearchableModelCombobox.tsx +411 -0
- package/src/renderer/shared/components/Settings/ThemeTab.tsx +416 -165
- package/src/renderer/shared/components/SkillsView.tsx +41 -16
- package/src/renderer/shared/components/SlashChoicePanel.tsx +88 -0
- package/src/renderer/shared/components/SlashSuggestions.test.tsx +33 -0
- package/src/renderer/shared/components/SlashSuggestions.tsx +41 -12
- package/src/renderer/shared/components/SourcesBlock.tsx +55 -51
- package/src/renderer/shared/components/StockCard.tsx +58 -24
- package/src/renderer/shared/components/SubagentDagView.tsx +4 -4
- package/src/renderer/shared/components/TerminalDock.tsx +241 -0
- package/src/renderer/shared/components/ThinkingBlock.tsx +14 -8
- package/src/renderer/shared/components/ToolSurfacePage.test.tsx +32 -0
- package/src/renderer/shared/components/ToolSurfacePage.tsx +568 -0
- package/src/renderer/shared/components/ToolsPanelToggle.tsx +13 -0
- package/src/renderer/shared/components/UiFeatureCard.tsx +267 -0
- package/src/renderer/shared/components/UiGridCard.tsx +188 -0
- package/src/renderer/shared/components/UiMockupWidget.tsx +149 -0
- package/src/renderer/shared/components/VeoStudioPanel.tsx +22 -37
- package/src/renderer/shared/components/ViewedImages.tsx +36 -0
- package/src/renderer/shared/components/VirtualChatHistory.tsx +82 -0
- package/src/renderer/shared/components/VoicePill.css +85 -0
- package/src/renderer/shared/components/VoicePill.d.ts +12 -0
- package/src/renderer/shared/components/VoicePill.jsx +190 -0
- package/src/renderer/shared/components/VoicePill.test.tsx +22 -0
- package/src/renderer/shared/components/WeatherCard.tsx +3 -3
- package/src/renderer/shared/components/WorkspaceContextPopover.tsx +138 -0
- package/src/renderer/shared/components/WorkspacePaneResizer.tsx +92 -0
- package/src/renderer/shared/components/WorkspacePreviewActions.test.tsx +44 -0
- package/src/renderer/shared/components/WorkspacePreviewActions.tsx +19 -0
- package/src/renderer/shared/components/WorkspaceSelector.tsx +154 -0
- package/src/renderer/shared/components/background-terminals.css +292 -0
- package/src/renderer/shared/components/ui/README.md +52 -0
- package/src/renderer/shared/components/ui/button.tsx +37 -0
- package/src/renderer/shared/components/ui/demo.tsx +26 -0
- package/src/renderer/shared/components/ui/error-recovery.css +35 -0
- package/src/renderer/shared/components/ui/error-recovery.tsx +35 -0
- package/src/renderer/shared/components/ui/voice-powered-orb.css +6 -0
- package/src/renderer/shared/components/ui/voice-powered-orb.tsx +374 -0
- package/src/renderer/shared/components/workspace-selector.css +248 -0
- package/src/renderer/shared/constants/config.ts +57 -3
- package/src/renderer/shared/constants/models.ts +189 -2
- package/src/renderer/shared/constants/slashCommands.ts +1 -1
- package/src/renderer/shared/conversation/coordinator.test.ts +27 -0
- package/src/renderer/shared/conversation/coordinator.ts +82 -0
- package/src/renderer/shared/conversation/lifecycle.test.ts +362 -0
- package/src/renderer/shared/conversation/lifecycle.ts +418 -0
- package/src/renderer/shared/conversation/projectNavigation.test.ts +105 -0
- package/src/renderer/shared/conversation/projectNavigation.ts +39 -0
- package/src/renderer/shared/conversation/sourcesTransport.ts +27 -0
- package/src/renderer/shared/conversation/syncView.test.ts +13 -0
- package/src/renderer/shared/conversation/syncView.ts +6 -0
- package/src/renderer/shared/conversation/transport.test.ts +163 -0
- package/src/renderer/shared/conversation/transport.ts +159 -0
- package/src/renderer/shared/conversation/useConversationCoordinator.ts +64 -0
- package/src/renderer/shared/css/agent-observability.css +46 -15
- package/src/renderer/shared/css/auth-gate.css +114 -15
- package/src/renderer/shared/css/chat-ui-cards.css +495 -0
- package/src/renderer/shared/css/code-review.css +856 -0
- package/src/renderer/shared/css/code-sessions.css +479 -0
- package/src/renderer/shared/css/collapsed-paste.css +35 -0
- package/src/renderer/shared/css/effects.css +15 -0
- package/src/renderer/shared/css/error-notice.css +60 -0
- package/src/renderer/shared/css/file-changes.css +132 -0
- package/src/renderer/shared/css/image-studio.css +16 -16
- package/src/renderer/shared/css/library.css +476 -0
- package/src/renderer/shared/css/management-views.css +415 -27
- package/src/renderer/shared/css/mcp-results.css +11 -0
- package/src/renderer/shared/css/model-selector.css +543 -85
- package/src/renderer/shared/css/mods.css +77 -0
- package/src/renderer/shared/css/notification-notice.css +28 -0
- package/src/renderer/shared/css/session-sources-popover.css +9 -0
- package/src/renderer/shared/css/session-sources.css +23 -0
- package/src/renderer/shared/css/settings/agents.css +1 -1
- package/src/renderer/shared/css/settings/automation.css +13 -13
- package/src/renderer/shared/css/settings/general.css +526 -5
- package/src/renderer/shared/css/settings/memory.css +154 -0
- package/src/renderer/shared/css/settings/notifications.css +11 -0
- package/src/renderer/shared/css/settings/plugins.css +5 -5
- package/src/renderer/shared/css/settings/profile.css +331 -1
- package/src/renderer/shared/css/settings/theme.css +656 -3
- package/src/renderer/shared/css/slash-choice.css +95 -0
- package/src/renderer/shared/css/slash-suggestions.css +68 -0
- package/src/renderer/shared/css/sources-block.css +91 -0
- package/src/renderer/shared/css/thinking-status.css +46 -0
- package/src/renderer/shared/css/tools-panel.css +7 -0
- package/src/renderer/shared/css/ui-tailwind.css +19 -0
- package/src/renderer/shared/css/veo-studio.css +16 -15
- package/src/renderer/shared/css/viewed-images.css +15 -0
- package/src/renderer/shared/fonts.css +46 -0
- package/src/renderer/shared/fonts.ts +10 -37
- package/src/renderer/shared/lib/utils.ts +6 -0
- package/src/renderer/shared/library/controller.test.ts +61 -0
- package/src/renderer/shared/library/controller.ts +57 -0
- package/src/renderer/shared/library/transport.test.ts +26 -0
- package/src/renderer/shared/library/transport.ts +60 -0
- package/src/renderer/shared/library/useLibraryFile.ts +38 -0
- package/src/renderer/shared/mods.ts +58 -0
- package/src/renderer/shared/platform.test.ts +90 -0
- package/src/renderer/shared/platform.ts +219 -7
- package/src/renderer/shared/theme/themeManager.test.ts +43 -0
- package/src/renderer/shared/theme/themeManager.ts +157 -0
- package/src/renderer/shared/theme/themes.ts +116 -0
- package/src/renderer/shared/theme/tokens.css +318 -0
- package/src/renderer/shared/types.ts +137 -2
- package/src/renderer/shared/utils/agentActivity.test.ts +75 -0
- package/src/renderer/shared/utils/agentActivity.ts +168 -8
- package/src/renderer/shared/utils/approval.tsx +7 -0
- package/src/renderer/shared/utils/artifactBrowser.test.ts +80 -0
- package/src/renderer/shared/utils/artifactBrowser.ts +41 -0
- package/src/renderer/shared/utils/cardJson.test.ts +35 -0
- package/src/renderer/shared/utils/cardJson.ts +30 -0
- package/src/renderer/shared/utils/contextCompaction.test.tsx +48 -0
- package/src/renderer/shared/utils/contextCompaction.ts +21 -0
- package/src/renderer/shared/utils/effectVisibility.ts +9 -0
- package/src/renderer/shared/utils/fileIcons.ts +1 -1
- package/src/renderer/shared/utils/markdown.tsx +330 -81
- package/src/renderer/shared/utils/markdown.webImages.test.tsx +40 -0
- package/src/renderer/shared/utils/mcpResults.test.tsx +91 -0
- package/src/renderer/shared/utils/modViewport.ts +7 -0
- package/src/renderer/shared/utils/nativeRecordingSession.test.ts +61 -0
- package/src/renderer/shared/utils/nativeRecordingSession.ts +46 -0
- package/src/renderer/shared/utils/notificationSettings.test.ts +14 -0
- package/src/renderer/shared/utils/notificationSettings.ts +23 -0
- package/src/renderer/shared/utils/notifications.test.ts +51 -0
- package/src/renderer/shared/utils/notifications.ts +54 -0
- package/src/renderer/shared/utils/pastedText.test.ts +20 -0
- package/src/renderer/shared/utils/pastedText.ts +13 -0
- package/src/renderer/shared/utils/progressCache.test.ts +32 -0
- package/src/renderer/shared/utils/providers.ts +8 -3
- package/src/renderer/shared/utils/screenCapture.ts +43 -0
- package/src/renderer/shared/utils/sessionSources.test.ts +31 -0
- package/src/renderer/shared/utils/sessionSources.ts +34 -0
- package/src/renderer/shared/utils/slashCommandProcessor.ts +5 -2
- package/src/renderer/shared/utils/sourceAttachments.ts +28 -0
- package/src/renderer/shared/utils/speech.ts +51 -9
- package/src/renderer/shared/utils/syntaxHighlight.test.tsx +22 -0
- package/src/renderer/shared/utils/syntaxHighlight.tsx +26 -0
- package/src/renderer/shared/utils/ui.ts +4 -64
- package/src/renderer/shared/utils/useGeminiLiveVoice.ts +49 -5
- package/src/renderer/shared/utils/useLatestCallback.ts +9 -0
- package/src/renderer/shared/utils/useNativeVoiceInput.ts +80 -72
- package/src/renderer/shared/utils/useSessionSources.ts +33 -0
- package/src/renderer/shared/utils/viewedImages.ts +26 -0
- package/src/renderer/shared/utils/workspacePane.test.ts +33 -0
- package/src/renderer/shared/utils/workspacePane.ts +20 -0
- package/src/renderer/shared/utils/workspacePreview.test.ts +24 -0
- package/src/renderer/shared/utils/workspacePreview.ts +16 -0
- package/src/renderer/shared/utils/workspaceSnapshot.test.ts +49 -0
- package/src/renderer/shared/utils/workspaceSnapshot.ts +26 -0
- package/src/renderer/shared/utils/workspaces.ts +10 -0
- package/src/renderer/shared/workspaceUndo.ts +88 -0
- package/src/renderer/src/App.tsx +16 -1
- package/src/renderer/src/components/BrowserShell.tsx +108 -0
- package/src/renderer/src/components/BrowserSuggestionsPopup.tsx +91 -0
- package/src/renderer/src/components/LiveTranslateControls.tsx +65 -0
- package/src/renderer/src/components/MintDashboard.tsx +4 -2
- package/src/renderer/src/components/PicturesLibrary.tsx +2 -287
- package/src/renderer/src/components/ScreenPicker.css +227 -0
- package/src/renderer/src/components/ScreenPicker.tsx +312 -526
- package/src/renderer/src/components/SettingsWindow.tsx +48 -5
- package/src/renderer/src/components/SpotlightWindow.tsx +1 -0
- package/src/renderer/src/components/WidgetWindow.tsx +27 -3
- package/src/renderer/src/components/WorkspacePanel.tsx +269 -61
- package/src/renderer/src/components/browser-shell.css +185 -0
- package/src/renderer/src/components/browser-suggestions-popup.css +55 -0
- package/src/renderer/src/components/liveTranslateFrames.test.ts +44 -0
- package/src/renderer/src/components/liveTranslateFrames.ts +45 -0
- package/src/renderer/src/components/liveTranslateLanguage.ts +6 -0
- package/src/renderer/src/css/app-shell.css +400 -204
- package/src/renderer/src/css/chat.css +1666 -594
- package/src/renderer/src/css/dashboard.css +11 -0
- package/src/renderer/src/css/desktop-tools.css +928 -0
- package/src/renderer/src/css/misc.css +5 -60
- package/src/renderer/src/css/pictures.css +2 -407
- package/src/renderer/src/css/settings/base.css +394 -157
- package/src/renderer/src/css/sidebar-workspace.css +1072 -376
- package/src/renderer/src/css/spotlight.css +15 -26
- package/src/renderer/src/css/tool-surfaces.css +784 -0
- package/src/renderer/src/css/widget.css +36 -8
- package/src/renderer/src/env.d.ts +4 -9
- package/src/renderer/src/hooks/useProviderModels.ts +2 -9
- package/src/renderer/src/index.css +53 -46
- package/src/renderer/src/main.tsx +12 -0
- package/src/renderer/src/proactiveSuggestions.ts +29 -0
- package/src/renderer/src/tauri.ts +302 -339
- package/src/renderer/src/voiceInput.ts +2 -1
- package/src/renderer/src-web/App.tsx +40 -0
- package/src/renderer/src-web/components/MintDashboard.tsx +4 -2
- package/src/renderer/src-web/components/PicturesLibrary.tsx +2 -284
- package/src/renderer/src-web/components/PullToRefresh.tsx +107 -0
- package/src/renderer/src-web/components/SettingsWindow.tsx +36 -5
- package/src/renderer/src-web/css/app-shell.css +188 -207
- package/src/renderer/src-web/css/chat.css +1236 -507
- package/src/renderer/src-web/css/dashboard.css +11 -0
- package/src/renderer/src-web/css/misc.css +3 -55
- package/src/renderer/src-web/css/mobile.css +679 -0
- package/src/renderer/src-web/css/pictures.css +2 -415
- package/src/renderer/src-web/css/pull-to-refresh.css +54 -0
- package/src/renderer/src-web/css/settings/base.css +353 -134
- package/src/renderer/src-web/css/settings/mobile.css +320 -0
- package/src/renderer/src-web/css/sidebar-workspace.css +546 -187
- package/src/renderer/src-web/css/spotlight.css +9 -26
- package/src/renderer/src-web/css/widget.css +1 -6
- package/src/renderer/src-web/env.d.ts +4 -12
- package/src/renderer/src-web/hooks/useProviderModels.ts +2 -9
- package/src/renderer/src-web/index.css +53 -96
- package/src/renderer/src-web/main.tsx +12 -0
- package/src/renderer/src-web/proactiveSuggestions.ts +3 -0
- package/src/renderer/src-web/tauri.ts +309 -364
- package/src/renderer/tests/backgroundTerminals.browser.html +81 -0
- package/src/renderer/tests/chatPanelFixture.ts +23 -0
- package/src/renderer/tests/chatPerformance.browser.html +71 -0
- package/src/renderer/tests/cliSessions.browser.html +82 -0
- package/src/renderer/tests/collapsedPaste.browser.html +70 -0
- package/src/renderer/tests/composerMenus.browser.html +116 -0
- package/src/renderer/tests/contextCompaction.browser.html +17 -0
- package/src/renderer/tests/conversationLifecycle.browser.html +70 -0
- package/src/renderer/tests/effectsPerformance.browser.html +13 -0
- package/src/renderer/tests/errorRecovery.browser.html +21 -0
- package/src/renderer/tests/glideSelect.browser.html +71 -0
- package/src/renderer/tests/glideSelect.preview.html +27 -0
- package/src/renderer/tests/library.browser.html +1 -0
- package/src/renderer/tests/library.browser.tsx +78 -0
- package/src/renderer/tests/liveOrb.browser.html +49 -0
- package/src/renderer/tests/liveVoice.browser.html +29 -0
- package/src/renderer/tests/modInput.browser.html +22 -0
- package/src/renderer/tests/sessionSources.browser.html +1 -0
- package/src/renderer/tests/sessionSources.browser.tsx +107 -0
- package/src/renderer/tests/skills.browser.html +24 -0
- package/src/renderer/tests/toolsPanel.browser.html +1 -0
- package/src/renderer/tests/toolsPanel.browser.tsx +113 -0
- package/src/renderer/tests/viewedImages.browser.html +1 -0
- package/src/renderer/tests/viewedImages.browser.tsx +93 -0
- package/src/renderer/tests/voicePill.browser.html +80 -0
- package/src/renderer/tests/voicePill.preview.html +34 -0
- package/src/renderer/tests/webSources.browser.html +1 -0
- package/src/renderer/tests/webSources.browser.tsx +98 -0
- package/src/renderer/tests/workspaceUndo.browser.html +92 -0
- package/src-tauri/Cargo.toml +40 -0
- package/src-tauri/build.rs +3 -0
- package/src-tauri/src/app/lifecycle.rs +277 -0
- package/src-tauri/src/app/mod.rs +4 -0
- package/src-tauri/src/app/shortcuts.rs +40 -0
- package/src-tauri/src/app/tray.rs +52 -0
- package/src-tauri/src/background/events.rs +70 -0
- package/src-tauri/src/background/headless.rs +230 -0
- package/src-tauri/src/background/mod.rs +4 -0
- package/src-tauri/src/background/proactive.rs +262 -0
- package/src-tauri/src/commands/approvals.rs +20 -0
- package/src-tauri/src/commands/auth.rs +127 -0
- package/src-tauri/src/commands/conversation.rs +642 -0
- package/src-tauri/src/commands/integrations.rs +157 -0
- package/src-tauri/src/commands/media.rs +179 -0
- package/src-tauri/src/commands/mod.rs +11 -0
- package/src-tauri/src/commands/mods.rs +6 -0
- package/src-tauri/src/commands/settings.rs +141 -0
- package/src-tauri/src/commands/voice.rs +153 -0
- package/src-tauri/src/commands/workspace.rs +501 -0
- package/src-tauri/src/lib.rs +10 -0
- package/src-tauri/src/main.rs +3 -0
- package/src-tauri/src/native/actions.rs +206 -0
- package/src-tauri/src/native/browser.rs +252 -0
- package/src-tauri/src/native/capture.rs +695 -0
- package/src-tauri/src/native/discord_rpc.rs +99 -0
- package/src-tauri/src/native/integrations.rs +126 -0
- package/src-tauri/src/native/mod.rs +12 -0
- package/src-tauri/src/native/notifications.rs +51 -0
- package/src-tauri/src/native/plugins.rs +14 -0
- package/src-tauri/src/native/system.rs +250 -0
- package/src-tauri/src/native/terminal.rs +201 -0
- package/src-tauri/src/native/updater.rs +148 -0
- package/src-tauri/src/native/windows.rs +143 -0
- package/tsconfig.json +2 -0
- package/vite.config.ts +4 -1
- package/vite.config.web.ts +5 -0
- package/.cargo/config.toml +0 -13
- package/.claude/settings.local.json +0 -182
- package/.codex +0 -0
- package/CLAUDE.md +0 -102
- package/out/web/Live2DCubismCore.js +0 -9
- package/out/web/assets/MintDashboard-DWSqucgb.js +0 -57
- package/out/web/assets/SettingsWindow-DFM2aj5B.js +0 -2
- package/out/web/assets/chunk-CKBBP62Z-nr1uKPj9.js +0 -2
- package/out/web/assets/chunk-DSNCTWBM-Dtj8Rqsd.js +0 -2
- package/out/web/assets/chunk-DU6HZSFF-2tv5K1wT.js +0 -128
- package/out/web/assets/classDiagram-DTDB5LWJ-BdSFArgw.js +0 -1
- package/out/web/assets/classDiagram-v2-JRS7N3AN-BdSFArgw.js +0 -1
- package/out/web/assets/core-DImejIUG.js +0 -1
- package/out/web/assets/dist-js-BxuKEVWM.js +0 -1
- package/out/web/assets/event-BNl8Zahw.js +0 -1
- package/out/web/assets/fira-code-cyrillic-400-normal-UC0NFL4U.woff2 +0 -0
- package/out/web/assets/fira-code-cyrillic-400-normal-dc1q3VD7.woff +0 -0
- package/out/web/assets/fira-code-cyrillic-500-normal-Bu7VCL72.woff +0 -0
- package/out/web/assets/fira-code-cyrillic-500-normal-CX35h3Mg.woff2 +0 -0
- package/out/web/assets/fira-code-cyrillic-ext-400-normal-Buh61xzB.woff +0 -0
- package/out/web/assets/fira-code-cyrillic-ext-400-normal-txZ9Fk_1.woff2 +0 -0
- package/out/web/assets/fira-code-cyrillic-ext-500-normal-CYRspHgm.woff2 +0 -0
- package/out/web/assets/fira-code-cyrillic-ext-500-normal-CwtLmSFD.woff +0 -0
- package/out/web/assets/fira-code-greek-400-normal-B2Gh_Y8s.woff2 +0 -0
- package/out/web/assets/fira-code-greek-400-normal-DobhaxvF.woff +0 -0
- package/out/web/assets/fira-code-greek-500-normal-CVO0IRNt.woff2 +0 -0
- package/out/web/assets/fira-code-greek-500-normal-DEXIWiey.woff +0 -0
- package/out/web/assets/fira-code-greek-ext-400-normal-DR7mBgIM.woff2 +0 -0
- package/out/web/assets/fira-code-greek-ext-400-normal-DSPUheWg.woff +0 -0
- package/out/web/assets/fira-code-greek-ext-500-normal-BO3iq16n.woff2 +0 -0
- package/out/web/assets/fira-code-greek-ext-500-normal-CMiNLXER.woff +0 -0
- package/out/web/assets/fira-code-latin-ext-400-normal-DG73JjOf.woff +0 -0
- package/out/web/assets/fira-code-latin-ext-400-normal-KSMg0QLl.woff2 +0 -0
- package/out/web/assets/fira-code-latin-ext-500-normal-CaANqXjI.woff +0 -0
- package/out/web/assets/fira-code-latin-ext-500-normal-Crd9e_oI.woff2 +0 -0
- package/out/web/assets/flowDiagram-A5DVABFB-BpnHUSU7.js +0 -1
- package/out/web/assets/index-CVRg270z.css +0 -1
- package/out/web/assets/index-DxZQr9yD.js +0 -10
- package/out/web/assets/inter-cyrillic-400-normal-HOLc17fK.woff +0 -0
- package/out/web/assets/inter-cyrillic-400-normal-obahsSVq.woff2 +0 -0
- package/out/web/assets/inter-cyrillic-500-normal-BasfLYem.woff2 +0 -0
- package/out/web/assets/inter-cyrillic-500-normal-CxZf_p3X.woff +0 -0
- package/out/web/assets/inter-cyrillic-600-normal-4D_pXhcN.woff +0 -0
- package/out/web/assets/inter-cyrillic-600-normal-CWCymEST.woff2 +0 -0
- package/out/web/assets/inter-cyrillic-ext-400-normal-BQZuk6qB.woff2 +0 -0
- package/out/web/assets/inter-cyrillic-ext-400-normal-DQukG94-.woff +0 -0
- package/out/web/assets/inter-cyrillic-ext-500-normal-B0yAr1jD.woff2 +0 -0
- package/out/web/assets/inter-cyrillic-ext-500-normal-BmqWE9Dz.woff +0 -0
- package/out/web/assets/inter-cyrillic-ext-600-normal-Bcila6Z-.woff +0 -0
- package/out/web/assets/inter-cyrillic-ext-600-normal-Dfes3d0z.woff2 +0 -0
- package/out/web/assets/inter-greek-400-normal-B4URO6DV.woff2 +0 -0
- package/out/web/assets/inter-greek-400-normal-q2sYcFCs.woff +0 -0
- package/out/web/assets/inter-greek-500-normal-BIZE56-Y.woff2 +0 -0
- package/out/web/assets/inter-greek-500-normal-Xzm54t5V.woff +0 -0
- package/out/web/assets/inter-greek-600-normal-BZpKdvQh.woff +0 -0
- package/out/web/assets/inter-greek-600-normal-plRanbMR.woff2 +0 -0
- package/out/web/assets/inter-greek-ext-400-normal-DGGRlc-M.woff2 +0 -0
- package/out/web/assets/inter-greek-ext-400-normal-KugGGMne.woff +0 -0
- package/out/web/assets/inter-greek-ext-500-normal-2j5mBUwD.woff +0 -0
- package/out/web/assets/inter-greek-ext-500-normal-C4iEst2y.woff2 +0 -0
- package/out/web/assets/inter-greek-ext-600-normal-B8X0CLgF.woff +0 -0
- package/out/web/assets/inter-greek-ext-600-normal-DRtmH8MT.woff2 +0 -0
- package/out/web/assets/inter-latin-400-normal-C38fXH4l.woff2 +0 -0
- package/out/web/assets/inter-latin-400-normal-CyCys3Eg.woff +0 -0
- package/out/web/assets/inter-latin-500-normal-BL9OpVg8.woff +0 -0
- package/out/web/assets/inter-latin-500-normal-Cerq10X2.woff2 +0 -0
- package/out/web/assets/inter-latin-600-normal-CiBQ2DWP.woff +0 -0
- package/out/web/assets/inter-latin-600-normal-LgqL8muc.woff2 +0 -0
- package/out/web/assets/inter-latin-ext-400-normal-77YHD8bZ.woff +0 -0
- package/out/web/assets/inter-latin-ext-400-normal-C1nco2VV.woff2 +0 -0
- package/out/web/assets/inter-latin-ext-500-normal-BxGbmqWO.woff +0 -0
- package/out/web/assets/inter-latin-ext-500-normal-CV4jyFjo.woff2 +0 -0
- package/out/web/assets/inter-latin-ext-600-normal-CIVaiw4L.woff +0 -0
- package/out/web/assets/inter-latin-ext-600-normal-D2bJ5OIk.woff2 +0 -0
- package/out/web/assets/inter-vietnamese-400-normal-Bbgyi5SW.woff +0 -0
- package/out/web/assets/inter-vietnamese-400-normal-DMkecbls.woff2 +0 -0
- package/out/web/assets/inter-vietnamese-500-normal-DOriooB6.woff2 +0 -0
- package/out/web/assets/inter-vietnamese-500-normal-mJboJaSs.woff +0 -0
- package/out/web/assets/inter-vietnamese-600-normal-BuLX-rYi.woff +0 -0
- package/out/web/assets/inter-vietnamese-600-normal-Cc8MFFhd.woff2 +0 -0
- package/out/web/assets/kanit-latin-400-normal-BUlsQXH3.woff2 +0 -0
- package/out/web/assets/kanit-latin-400-normal-HVZWrfev.woff +0 -0
- package/out/web/assets/kanit-latin-500-normal-CX_4XcKi.woff2 +0 -0
- package/out/web/assets/kanit-latin-500-normal-qBha86O4.woff +0 -0
- package/out/web/assets/kanit-latin-600-normal-0lS78yAd.woff2 +0 -0
- package/out/web/assets/kanit-latin-600-normal-DlacpeTg.woff +0 -0
- package/out/web/assets/kanit-latin-ext-400-normal-B2xPf58u.woff2 +0 -0
- package/out/web/assets/kanit-latin-ext-400-normal-CHvNKHHD.woff +0 -0
- package/out/web/assets/kanit-latin-ext-500-normal-BFdWrG22.woff +0 -0
- package/out/web/assets/kanit-latin-ext-500-normal-EHs3suD6.woff2 +0 -0
- package/out/web/assets/kanit-latin-ext-600-normal-BBDzoLaj.woff +0 -0
- package/out/web/assets/kanit-latin-ext-600-normal-DAX3wtuq.woff2 +0 -0
- package/out/web/assets/kanit-thai-400-normal-D2nliXKa.woff +0 -0
- package/out/web/assets/kanit-thai-400-normal-D80Pglro.woff2 +0 -0
- package/out/web/assets/kanit-thai-500-normal-BB8gri04.woff2 +0 -0
- package/out/web/assets/kanit-thai-500-normal-Iy_w0a80.woff +0 -0
- package/out/web/assets/kanit-thai-600-normal-Bj6oiaDc.woff2 +0 -0
- package/out/web/assets/kanit-thai-600-normal-wbTlPO7I.woff +0 -0
- package/out/web/assets/kanit-vietnamese-400-normal-DRI8YWyb.woff2 +0 -0
- package/out/web/assets/kanit-vietnamese-400-normal-dow6Bnto.woff +0 -0
- package/out/web/assets/kanit-vietnamese-500-normal-BzTrpCM3.woff2 +0 -0
- package/out/web/assets/kanit-vietnamese-500-normal-T1ndT7MF.woff +0 -0
- package/out/web/assets/kanit-vietnamese-600-normal-Bi7fw3I4.woff2 +0 -0
- package/out/web/assets/kanit-vietnamese-600-normal-DXCRAa_8.woff +0 -0
- package/out/web/assets/mali-latin-400-normal-ByPcZ8Gx.woff +0 -0
- package/out/web/assets/mali-latin-400-normal-Cuc6Ykl8.woff2 +0 -0
- package/out/web/assets/mali-latin-500-normal-B01M-LP6.woff2 +0 -0
- package/out/web/assets/mali-latin-500-normal-Thgqw_9f.woff +0 -0
- package/out/web/assets/mali-latin-600-normal-B9TiUNpT.woff2 +0 -0
- package/out/web/assets/mali-latin-600-normal-CycpQCwU.woff +0 -0
- package/out/web/assets/mali-latin-ext-400-normal-DUVdJQO4.woff +0 -0
- package/out/web/assets/mali-latin-ext-400-normal-iCG1ALuJ.woff2 +0 -0
- package/out/web/assets/mali-latin-ext-500-normal-BfJE4UMZ.woff2 +0 -0
- package/out/web/assets/mali-latin-ext-500-normal-FoLEyOKS.woff +0 -0
- package/out/web/assets/mali-latin-ext-600-normal-BTvIfiCp.woff2 +0 -0
- package/out/web/assets/mali-latin-ext-600-normal-DAQcLVmD.woff +0 -0
- package/out/web/assets/mali-thai-400-normal-BO7A3bLZ.woff2 +0 -0
- package/out/web/assets/mali-thai-400-normal-CX9VrjTn.woff +0 -0
- package/out/web/assets/mali-thai-500-normal-Cph2qha9.woff +0 -0
- package/out/web/assets/mali-thai-500-normal-D89rMT77.woff2 +0 -0
- package/out/web/assets/mali-thai-600-normal-DPgXT6rZ.woff +0 -0
- package/out/web/assets/mali-thai-600-normal-DlTx3OsB.woff2 +0 -0
- package/out/web/assets/mali-vietnamese-400-normal-DUKxzXaz.woff2 +0 -0
- package/out/web/assets/mali-vietnamese-400-normal-gFDLvsOK.woff +0 -0
- package/out/web/assets/mali-vietnamese-500-normal--OY07q2c.woff +0 -0
- package/out/web/assets/mali-vietnamese-500-normal-KDrNRwfW.woff2 +0 -0
- package/out/web/assets/mali-vietnamese-600-normal-CtTMUU7T.woff +0 -0
- package/out/web/assets/mali-vietnamese-600-normal-DFlJr66u.woff2 +0 -0
- package/out/web/assets/mermaid.core-DYGGlqOf.js +0 -11
- package/out/web/assets/mitr-latin-400-normal-Cb18vPmZ.woff +0 -0
- package/out/web/assets/mitr-latin-400-normal-CwbkLQ4a.woff2 +0 -0
- package/out/web/assets/mitr-latin-500-normal-B4JOhzAi.woff +0 -0
- package/out/web/assets/mitr-latin-500-normal-BmClOow2.woff2 +0 -0
- package/out/web/assets/mitr-latin-ext-400-normal-B3CPG7Yo.woff2 +0 -0
- package/out/web/assets/mitr-latin-ext-400-normal-DTx65hiC.woff +0 -0
- package/out/web/assets/mitr-latin-ext-500-normal-B_Diajz1.woff2 +0 -0
- package/out/web/assets/mitr-latin-ext-500-normal-DYOsVaVT.woff +0 -0
- package/out/web/assets/mitr-thai-400-normal-CS4Do6aM.woff +0 -0
- package/out/web/assets/mitr-thai-400-normal-CXWaAdVj.woff2 +0 -0
- package/out/web/assets/mitr-thai-500-normal-CVdBrEVH.woff2 +0 -0
- package/out/web/assets/mitr-thai-500-normal-CW_B5D-i.woff +0 -0
- package/out/web/assets/mitr-vietnamese-400-normal-CPMGWyoC.woff2 +0 -0
- package/out/web/assets/mitr-vietnamese-400-normal-Z6XhIpdY.woff +0 -0
- package/out/web/assets/mitr-vietnamese-500-normal-CDrv0585.woff2 +0 -0
- package/out/web/assets/mitr-vietnamese-500-normal-CMQWyq-Z.woff +0 -0
- package/out/web/assets/noto-sans-thai-latin-400-normal-BaWBrqFP.woff2 +0 -0
- package/out/web/assets/noto-sans-thai-latin-400-normal-Dh_FJjOB.woff +0 -0
- package/out/web/assets/noto-sans-thai-latin-500-normal-BC04jsmm.woff +0 -0
- package/out/web/assets/noto-sans-thai-latin-500-normal-fyBKClF1.woff2 +0 -0
- package/out/web/assets/noto-sans-thai-latin-600-normal-CemcjnVR.woff2 +0 -0
- package/out/web/assets/noto-sans-thai-latin-600-normal-Dbc-dNO6.woff +0 -0
- package/out/web/assets/noto-sans-thai-latin-ext-400-normal-B-1H0YkH.woff +0 -0
- package/out/web/assets/noto-sans-thai-latin-ext-400-normal-nBP59pVw.woff2 +0 -0
- package/out/web/assets/noto-sans-thai-latin-ext-500-normal-B-ZWb8SZ.woff2 +0 -0
- package/out/web/assets/noto-sans-thai-latin-ext-500-normal-CrEHO7C8.woff +0 -0
- package/out/web/assets/noto-sans-thai-latin-ext-600-normal-PkMZo0xa.woff +0 -0
- package/out/web/assets/noto-sans-thai-latin-ext-600-normal-maHHBsez.woff2 +0 -0
- package/out/web/assets/noto-sans-thai-thai-400-normal-BEOmKAI1.woff2 +0 -0
- package/out/web/assets/noto-sans-thai-thai-400-normal-Dxb_unuU.woff +0 -0
- package/out/web/assets/noto-sans-thai-thai-500-normal-BOGXO2tw.woff +0 -0
- package/out/web/assets/noto-sans-thai-thai-500-normal-CU_X86GQ.woff2 +0 -0
- package/out/web/assets/noto-sans-thai-thai-600-normal-CmgB8_JK.woff +0 -0
- package/out/web/assets/noto-sans-thai-thai-600-normal-Cs73sVjl.woff2 +0 -0
- package/out/web/assets/oauthManager-DNiwM8Rn.js +0 -2
- package/out/web/assets/oauthManager-DuamS1Av.css +0 -1
- package/out/web/assets/outfit-latin-300-normal-AWLfuCom.woff +0 -0
- package/out/web/assets/outfit-latin-300-normal-CRYTwY6m.woff2 +0 -0
- package/out/web/assets/outfit-latin-400-normal-BGsTXAXT.woff2 +0 -0
- package/out/web/assets/outfit-latin-400-normal-DMwTpYkH.woff +0 -0
- package/out/web/assets/outfit-latin-500-normal-ClnHRwRh.woff +0 -0
- package/out/web/assets/outfit-latin-500-normal-DKnIMDSk.woff2 +0 -0
- package/out/web/assets/outfit-latin-600-normal-B7SfZ07L.woff2 +0 -0
- package/out/web/assets/outfit-latin-600-normal-BEfTtDA7.woff +0 -0
- package/out/web/assets/outfit-latin-ext-300-normal-BYS6Dpvq.woff2 +0 -0
- package/out/web/assets/outfit-latin-ext-300-normal-CMIMshEd.woff +0 -0
- package/out/web/assets/outfit-latin-ext-400-normal-5tcqmc2S.woff2 +0 -0
- package/out/web/assets/outfit-latin-ext-400-normal-DHm7mdGe.woff +0 -0
- package/out/web/assets/outfit-latin-ext-500-normal-DrCvqoFD.woff +0 -0
- package/out/web/assets/outfit-latin-ext-500-normal-zeox_O30.woff2 +0 -0
- package/out/web/assets/outfit-latin-ext-600-normal-B85nYjL1.woff2 +0 -0
- package/out/web/assets/outfit-latin-ext-600-normal-CWJcPgd7.woff +0 -0
- package/out/web/assets/preload-helper-D0uHx7FM.js +0 -1
- package/out/web/assets/prompt-latin-400-normal-BQ9zjSN8.woff2 +0 -0
- package/out/web/assets/prompt-latin-400-normal-CxU4ec_r.woff +0 -0
- package/out/web/assets/prompt-latin-500-normal-B1edBDQ9.woff +0 -0
- package/out/web/assets/prompt-latin-500-normal-CxzxEHZc.woff2 +0 -0
- package/out/web/assets/prompt-latin-600-normal-CSDDLorv.woff +0 -0
- package/out/web/assets/prompt-latin-600-normal-hKZWXsc1.woff2 +0 -0
- package/out/web/assets/prompt-latin-ext-400-normal-1pHbN9uy.woff +0 -0
- package/out/web/assets/prompt-latin-ext-400-normal-DdSafGZ9.woff2 +0 -0
- package/out/web/assets/prompt-latin-ext-500-normal--EZ1um7s.woff2 +0 -0
- package/out/web/assets/prompt-latin-ext-500-normal-D-lI1EVT.woff +0 -0
- package/out/web/assets/prompt-latin-ext-600-normal-C8b50x67.woff +0 -0
- package/out/web/assets/prompt-latin-ext-600-normal-Cg9L7iJU.woff2 +0 -0
- package/out/web/assets/prompt-thai-400-normal-BrkKv8cO.woff2 +0 -0
- package/out/web/assets/prompt-thai-400-normal-DJypnfr3.woff +0 -0
- package/out/web/assets/prompt-thai-500-normal-C18pDUoL.woff2 +0 -0
- package/out/web/assets/prompt-thai-500-normal-D7YNqUJD.woff +0 -0
- package/out/web/assets/prompt-thai-600-normal-CYPViXds.woff +0 -0
- package/out/web/assets/prompt-thai-600-normal-MrdfU7zR.woff2 +0 -0
- package/out/web/assets/prompt-vietnamese-400-normal-BCPzsgPT.woff2 +0 -0
- package/out/web/assets/prompt-vietnamese-400-normal-D4pLyeNK.woff +0 -0
- package/out/web/assets/prompt-vietnamese-500-normal-DmzxmPwa.woff2 +0 -0
- package/out/web/assets/prompt-vietnamese-500-normal-w_sS_j2F.woff +0 -0
- package/out/web/assets/prompt-vietnamese-600-normal-1dyohtNh.woff +0 -0
- package/out/web/assets/prompt-vietnamese-600-normal-7QWjJBsF.woff2 +0 -0
- package/out/web/assets/sarabun-latin-400-normal-DmguIS-7.woff +0 -0
- package/out/web/assets/sarabun-latin-400-normal-URPBxl-K.woff2 +0 -0
- package/out/web/assets/sarabun-latin-500-normal-BjUTcdxu.woff2 +0 -0
- package/out/web/assets/sarabun-latin-500-normal-CJexTAnl.woff +0 -0
- package/out/web/assets/sarabun-latin-600-normal-9FonlkKx.woff +0 -0
- package/out/web/assets/sarabun-latin-600-normal-DMD3TROr.woff2 +0 -0
- package/out/web/assets/sarabun-latin-ext-400-normal-BbP7GpLL.woff2 +0 -0
- package/out/web/assets/sarabun-latin-ext-400-normal-BsmTn0SS.woff +0 -0
- package/out/web/assets/sarabun-latin-ext-500-normal-Cot16Bd2.woff +0 -0
- package/out/web/assets/sarabun-latin-ext-500-normal-DE1LysqI.woff2 +0 -0
- package/out/web/assets/sarabun-latin-ext-600-normal-0tXu9x_i.woff +0 -0
- package/out/web/assets/sarabun-latin-ext-600-normal-BRxjKUQ6.woff2 +0 -0
- package/out/web/assets/sarabun-thai-400-normal-C2DaJlKK.woff2 +0 -0
- package/out/web/assets/sarabun-thai-400-normal-CH-UbWgg.woff +0 -0
- package/out/web/assets/sarabun-thai-500-normal-BVssjame.woff2 +0 -0
- package/out/web/assets/sarabun-thai-500-normal-C3iDLEzi.woff +0 -0
- package/out/web/assets/sarabun-thai-600-normal-3dIAQ-_s.woff2 +0 -0
- package/out/web/assets/sarabun-thai-600-normal-DWKeTe6a.woff +0 -0
- package/out/web/assets/sarabun-vietnamese-400-normal-DPfkSCMy.woff +0 -0
- package/out/web/assets/sarabun-vietnamese-400-normal-igdrzAGY.woff2 +0 -0
- package/out/web/assets/sarabun-vietnamese-500-normal-CpRVvGRU.woff +0 -0
- package/out/web/assets/sarabun-vietnamese-500-normal-Dpe7Br9m.woff2 +0 -0
- package/out/web/assets/sarabun-vietnamese-600-normal-BMbOgAW-.woff +0 -0
- package/out/web/assets/sarabun-vietnamese-600-normal-DkxrOlLB.woff2 +0 -0
- package/out/web/assets/stateDiagram-v2-4QOOHH4V-s6P9g2_b.js +0 -1
- package/out/web/assets/swimlanesDiagram-VK2B7HYN-CV9fOLrV.js +0 -8
- package/out/web/assets/tauri-CNrHQ2Gb.js +0 -3
- package/out/web/assets/window-DkIhgI7B.js +0 -1
- package/skills-lock.json +0 -41
- package/src/renderer/public/Live2DCubismCore.js +0 -9
- package/src/renderer/src/companionWidget.ts +0 -95
- package/src/renderer/src/components/Live2DStage.tsx +0 -389
- package/src/renderer/src/components/ModelPanel.tsx +0 -154
- package/src/renderer/src/css/model.css +0 -627
- package/src/renderer/src-web/companionWidget.ts +0 -37
- package/src/renderer/src-web/components/ModelPanel.tsx +0 -12
- package/src/renderer/src-web/css/model.css +0 -628
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en" data-theme="dark"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"></head>
|
|
3
|
+
<body><div id="root"></div><pre id="result" style="position:fixed;top:0;left:0;z-index:500;font-size:12px">RUNNING</pre>
|
|
4
|
+
<script type="module">
|
|
5
|
+
import React from 'react';
|
|
6
|
+
import { createRoot } from 'react-dom/client';
|
|
7
|
+
import { BackgroundTerminals } from '/shared/components/BackgroundTerminals.tsx';
|
|
8
|
+
import { installRendererPlatform } from '/shared/platform.ts';
|
|
9
|
+
const web = location.search.includes('web');
|
|
10
|
+
const compact = location.search.includes('compact');
|
|
11
|
+
for (const file of ['index.css','css/dashboard.css', ...(web ? ['css/mobile.css'] : [])]) {
|
|
12
|
+
const link=document.createElement('link'); link.rel='stylesheet'; link.href=`/${web?'src-web':'src'}/${file}`; document.head.append(link);
|
|
13
|
+
}
|
|
14
|
+
const makeJob = (id,workspacePath) => ({id,workspacePath,cwd:workspacePath,command:id==='bg-first'?'python3 -m http.server 8000':'npm run dev',chatId:'chat',pid:1,status:'running',exitCode:null,error:null,startedAt:Date.now(),endedAt:null,elapsedSeconds:12,serverUrl:null});
|
|
15
|
+
const initialJobs=[makeJob('bg-first','/Demo'),makeJob('bg-second','/Demo'),makeJob('bg-other','/Other')];
|
|
16
|
+
let jobs=[], disconnected=false, stopCalls=[], outputCalls=0;
|
|
17
|
+
installRendererPlatform(new Proxy({
|
|
18
|
+
isTauriRuntime:()=>!web,
|
|
19
|
+
listBackgroundJobs:async(workspace)=>{if(disconnected)throw new Error('offline');return jobs.filter(j=>!workspace||j.workspacePath===workspace).map(j=>({...j}));},
|
|
20
|
+
getBackgroundJob:async(id)=>{outputCalls++;if(disconnected)throw new Error('offline');const job=jobs.find(j=>j.id===id);return {...job,stdout:'hello\n'+'line\n'.repeat(100),stderr:'',truncated:true};},
|
|
21
|
+
stopBackgroundJob:async(id)=>{stopCalls.push(id);jobs=jobs.map(j=>j.id===id?{...j,status:'stopping'}:j);return jobs.find(j=>j.id===id);},
|
|
22
|
+
},{get:(target,key)=>target[key]||(()=>{})}));
|
|
23
|
+
const root=createRoot(document.getElementById('root'));
|
|
24
|
+
function render(workspace='/Demo') { root.render(React.createElement('div',{className:'input-area',style:{position:'fixed',bottom:16,left:16,right:compact?'auto':16,width:compact?320:undefined,padding:8}},React.createElement('div',{className:'smart-context-bar'},React.createElement('button',null,'Agent mode'),React.createElement('button',null,'Plan mode'),React.createElement(BackgroundTerminals,{workspacePath:workspace})),React.createElement('textarea',{id:'composer',style:{width:'100%',height:80},'aria-label':'Chat message'}),React.createElement('button',{id:'send'},'Send'))); }
|
|
25
|
+
render();
|
|
26
|
+
const sleep=ms=>new Promise(r=>setTimeout(r,ms));
|
|
27
|
+
async function waitFor(test) {const deadline=Date.now()+5000;while(!test()){if(Date.now()>deadline)throw new Error('timed out');await sleep(25);}}
|
|
28
|
+
const results=[];
|
|
29
|
+
const check=(condition,label)=>{if(!condition)throw new Error(label);results.push(label);};
|
|
30
|
+
const trigger=()=>document.querySelector('.background-terminal-trigger');
|
|
31
|
+
try {
|
|
32
|
+
await waitFor(()=>trigger()?.textContent.trim()==='▸ Terminals ▾');
|
|
33
|
+
check(true,'zero jobs keeps Terminals accessible');
|
|
34
|
+
jobs=[initialJobs[0]];
|
|
35
|
+
await waitFor(()=>trigger()?.textContent.includes('1 background terminal'));
|
|
36
|
+
check(true,'one running job uses singular count');
|
|
37
|
+
jobs=initialJobs;
|
|
38
|
+
await waitFor(()=>trigger()?.textContent.includes('2 background terminals'));
|
|
39
|
+
check(true,'workspace count excludes other workspace');
|
|
40
|
+
trigger().click(); await waitFor(()=>document.querySelector('.background-terminal-panel'));
|
|
41
|
+
check(document.querySelectorAll('.background-terminal-job').length===2,'panel lists workspace jobs');
|
|
42
|
+
const input=document.getElementById('composer'), bounds=input.getBoundingClientRect();
|
|
43
|
+
check(document.elementFromPoint(bounds.left+20,bounds.top+20)===input,'composer remains clickable with panel open');
|
|
44
|
+
const panel=document.querySelector('.background-terminal-panel').getBoundingClientRect();
|
|
45
|
+
check(panel.left>=0&&panel.right<=innerWidth&&panel.top>=0&&panel.bottom<=bounds.top,'panel fits viewport above composer');
|
|
46
|
+
check(panel.left>=bounds.left-1&&panel.right<=bounds.right+1,'panel fits the composer column');
|
|
47
|
+
document.querySelector('.background-terminal-filter input').click(); await sleep(25);
|
|
48
|
+
check(document.querySelectorAll('.background-terminal-job').length===3,'all workspaces exposes other job');
|
|
49
|
+
const view=[...document.querySelectorAll('button')].find(b=>b.textContent==='View output');view.click();
|
|
50
|
+
await waitFor(()=>document.querySelector('.background-terminal-log pre'));
|
|
51
|
+
check(document.querySelector('.background-terminal-output').textContent.includes('Older output was truncated.'),'output shows truncation');
|
|
52
|
+
check(outputCalls>0,'output uses snapshot API');
|
|
53
|
+
const follow=document.querySelector('.background-terminal-output input');
|
|
54
|
+
document.querySelector('.background-terminal-log').dispatchEvent(new WheelEvent('wheel',{deltaY:-100,bubbles:true}));await sleep(25);
|
|
55
|
+
check(!follow.checked,'scrolling up pauses follow');
|
|
56
|
+
const stop=document.querySelector('.background-terminal-stop');stop.click();
|
|
57
|
+
await waitFor(()=>stopCalls.length===1);
|
|
58
|
+
check(stopCalls.length===1,'stop targets one job');
|
|
59
|
+
jobs=jobs.map(j=>j.id==='bg-first'?{...j,status:'completed',exitCode:0,endedAt:Date.now()}:j);
|
|
60
|
+
await waitFor(()=>trigger()?.textContent.includes('1 background terminal'));
|
|
61
|
+
check(true,'completed job reduces active count');
|
|
62
|
+
jobs=jobs.map(j=>({...j,status:'completed',exitCode:0,endedAt:Date.now()}));
|
|
63
|
+
await waitFor(()=>trigger().textContent.trim()==='▸ Terminals ▾');
|
|
64
|
+
check(document.querySelectorAll('.background-terminal-job').length===3,'finished output remains accessible');
|
|
65
|
+
await waitFor(()=>document.querySelector('[role=status]'));
|
|
66
|
+
check(document.querySelector('[role=status]').textContent.includes('completed'),'completion notice is nonblocking');
|
|
67
|
+
disconnected=true;await waitFor(()=>trigger().textContent.includes('Status unavailable'));
|
|
68
|
+
check(document.querySelectorAll('.background-terminal-job').length===3,'connection loss keeps last known list');
|
|
69
|
+
disconnected=false;await waitFor(()=>trigger().textContent.includes('Terminals'));
|
|
70
|
+
document.querySelector('.background-terminal-panel').dispatchEvent(new KeyboardEvent('keydown',{key:'Escape',bubbles:true}));await sleep(25);
|
|
71
|
+
check(!document.querySelector('.background-terminal-panel')&&document.activeElement===trigger(),'Escape closes panel and restores focus');
|
|
72
|
+
render('/Other');await sleep(50);trigger().click();await sleep(50);
|
|
73
|
+
check(document.querySelectorAll('.background-terminal-job').length===1,'workspace switch changes list without stopping jobs');
|
|
74
|
+
check(stopCalls.length===1,'switching workspace does not stop jobs');
|
|
75
|
+
document.documentElement.dataset.theme='light';await sleep(50);
|
|
76
|
+
const color=getComputedStyle(document.querySelector('.background-terminal-panel')).backgroundColor;
|
|
77
|
+
check(color==='rgb(255, 255, 255)','panel follows light theme');
|
|
78
|
+
document.getElementById('result').textContent='PASS '+results.length+'\n'+results.join('\n');
|
|
79
|
+
document.documentElement.dataset.result='pass';
|
|
80
|
+
} catch(error) {document.getElementById('result').textContent='FAIL '+error.message+'\n'+results.join('\n');document.documentElement.dataset.result='fail';}
|
|
81
|
+
</script></body></html>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { DEFAULT_CONFIG } from '../shared/constants/config'
|
|
2
|
+
|
|
3
|
+
const noop = () => {}
|
|
4
|
+
export function chatPanelFixture() {
|
|
5
|
+
return {
|
|
6
|
+
conversation: {
|
|
7
|
+
interactions: [], sending: false, sendingMessage: '', sendingImageCount: 0,
|
|
8
|
+
streamedReply: '', streamedResponse: null, agentProgress: [], agentActivitySnapshots: {},
|
|
9
|
+
thinkingExpanded: {}, message: '', imageAttachments: [], videoAttachments: [], documentName: '',
|
|
10
|
+
pendingApproval: null, agentMode: false, status: null, chatId: 'A', recentWorkspacePaths: [],
|
|
11
|
+
chatEnd: { current: null }, welcomeInteraction: null, settingsConfig: DEFAULT_CONFIG,
|
|
12
|
+
conversationTitle: 'Session sources example',
|
|
13
|
+
},
|
|
14
|
+
actions: Object.fromEntries([
|
|
15
|
+
'onSubmit', 'onSelectImage', 'onSelectVideo', 'onSelectDocument', 'onPasteImage', 'onSetMessage',
|
|
16
|
+
'onSendVoiceMessage', 'onRemoveImage', 'onRemoveVideo', 'onRemoveDocument', 'onStartWebSearch',
|
|
17
|
+
'onCaptureScreen', 'onSetAgentMode', 'onSetProvider', 'onApproval', 'onSetModel',
|
|
18
|
+
'onCancelMessage', 'onClearMessages', 'onSetGeminiLiveVoice', 'onThinkingExpandedChange',
|
|
19
|
+
'onToggleMobileSidebar',
|
|
20
|
+
].map(name => [name, noop])),
|
|
21
|
+
tools: { modsPanelTarget: null, onOpenMods: noop, onToggle: noop, open: false, backgroundTaskCount: 0 },
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
<!doctype html><html><head><meta charset="utf-8"><title>Virtual chat regression</title></head>
|
|
2
|
+
<body><div id="root"></div><pre id="result">RUNNING</pre><script type="module">
|
|
3
|
+
import React, { useRef, useState } from 'react';
|
|
4
|
+
import { createRoot } from 'react-dom/client';
|
|
5
|
+
import { VirtualChatHistory } from '../shared/components/VirtualChatHistory';
|
|
6
|
+
const h = React.createElement;
|
|
7
|
+
const runtimeErrors = [];
|
|
8
|
+
window.addEventListener('error', event => runtimeErrors.push(event.message));
|
|
9
|
+
let update, setOlder, switchChat, setLive;
|
|
10
|
+
function App() {
|
|
11
|
+
const scroll = useRef(null);
|
|
12
|
+
const [items, setItems] = useState(Array.from({length:1000}, (_, i) => ({id:i, height:80 + i % 3 * 40})));
|
|
13
|
+
const [older, changeOlder] = useState(true);
|
|
14
|
+
const [chat, changeChat] = useState('first');
|
|
15
|
+
const [live, changeLive] = useState(false);
|
|
16
|
+
update = setItems;
|
|
17
|
+
setOlder = changeOlder; switchChat = changeChat; setLive = changeLive;
|
|
18
|
+
return h('div', {ref:scroll, id:'scroll', style:{height:400,width:700,overflow:'auto',position:'relative',overflowAnchor:'none',display:'flex',flexDirection:'column',gap:10,padding:16,boxSizing:'border-box'}},
|
|
19
|
+
older && h('button', {style:{height:40,flexShrink:0,marginBottom:20}}, 'Load older'),
|
|
20
|
+
h(VirtualChatHistory, {key:chat,items, scrollRef:scroll,hasOlder:older,tail:live ? h('div', {style:{minHeight:200}}, h('input', {id:'approval-answer'})) : null, renderRow:index => h('div', {'data-message':items[index].id, style:{minHeight:items[index].height}}, 'Message ' + items[index].id)}));
|
|
21
|
+
}
|
|
22
|
+
const sleep = ms => new Promise(resolve => setTimeout(resolve,ms));
|
|
23
|
+
const assert = (ok, message) => { if (!ok) throw Error(message); };
|
|
24
|
+
createRoot(document.getElementById('root')).render(h(App));
|
|
25
|
+
try {
|
|
26
|
+
await sleep(500);
|
|
27
|
+
const scroll = document.getElementById('scroll');
|
|
28
|
+
assert(document.querySelectorAll('[data-message]').length < 40, 'bounded mounted rows');
|
|
29
|
+
assert(document.querySelector('[data-message="999"]'), 'starts at latest: ' + JSON.stringify({offset:scroll.scrollTop,height:scroll.scrollHeight,rows:[...document.querySelectorAll('[data-message]')].map(node=>node.dataset.message)}));
|
|
30
|
+
scroll.scrollTop = 30000;
|
|
31
|
+
await sleep(300);
|
|
32
|
+
const anchor = () => [...document.querySelectorAll('[data-message]')].find(node => node.getBoundingClientRect().bottom > scroll.getBoundingClientRect().top);
|
|
33
|
+
const before = anchor(); const id = before.dataset.message; const top = before.getBoundingClientRect().top;
|
|
34
|
+
update(items => [{id:-2,height:190},{id:-1,height:270},...items]);
|
|
35
|
+
await sleep(400);
|
|
36
|
+
const retained = document.querySelector(`[data-message="${id}"]`);
|
|
37
|
+
assert(retained && Math.abs(retained.getBoundingClientRect().top - top) < 3, 'prepend preserves reading anchor');
|
|
38
|
+
const headerAnchor = anchor(); const headerId = headerAnchor.dataset.message; const headerTop = headerAnchor.getBoundingClientRect().top;
|
|
39
|
+
setOlder(false);
|
|
40
|
+
await sleep(400);
|
|
41
|
+
const newHeaderTop = document.querySelector(`[data-message="${headerId}"]`)?.getBoundingClientRect().top;
|
|
42
|
+
assert(Math.abs(newHeaderTop - headerTop) < 3, 'removing load-older header preserves anchor: ' + JSON.stringify({headerId,headerTop,newHeaderTop,offset:scroll.scrollTop}));
|
|
43
|
+
const offset = scroll.scrollTop;
|
|
44
|
+
update(items => [...items, {id:1000,height:200}]);
|
|
45
|
+
await sleep(300);
|
|
46
|
+
assert(Math.abs(scroll.scrollTop - offset) < 3, 'append does not pull reader to bottom');
|
|
47
|
+
scroll.scrollTop = scroll.scrollHeight;
|
|
48
|
+
await sleep(300);
|
|
49
|
+
update(items => [...items, {id:1001,height:300}]);
|
|
50
|
+
await sleep(400);
|
|
51
|
+
assert(scroll.scrollHeight - scroll.scrollTop - scroll.clientHeight < 3, 'append follows when pinned');
|
|
52
|
+
update(items => items.map(item => item.id === 1001 ? {...item,height:700} : item));
|
|
53
|
+
await sleep(400);
|
|
54
|
+
assert(scroll.scrollHeight - scroll.scrollTop - scroll.clientHeight < 3, 'dynamic height follows when pinned');
|
|
55
|
+
scroll.style.width = '350px';
|
|
56
|
+
await sleep(300);
|
|
57
|
+
assert(document.querySelectorAll('[data-message]').length < 40, 'resize retains bounded DOM');
|
|
58
|
+
setLive(true);
|
|
59
|
+
await sleep(300);
|
|
60
|
+
document.getElementById('approval-answer').value = 'draft approval answer';
|
|
61
|
+
scroll.scrollTop = 20000;
|
|
62
|
+
await sleep(300);
|
|
63
|
+
assert(document.getElementById('approval-answer')?.value === 'draft approval answer', 'active approval draft survives scrolling into history');
|
|
64
|
+
setLive(false);
|
|
65
|
+
update([{id:5000,height:120},{id:5001,height:600}]); switchChat('second');
|
|
66
|
+
await sleep(400);
|
|
67
|
+
assert(document.querySelector('[data-message="5001"]') && scroll.scrollHeight - scroll.scrollTop - scroll.clientHeight < 3, 'session switch opens latest');
|
|
68
|
+
assert(runtimeErrors.length === 0, 'no runtime/ResizeObserver errors: ' + runtimeErrors.join('; '));
|
|
69
|
+
document.getElementById('result').textContent = 'PASS: bounded DOM, latest, prepend/header anchor, append policy, dynamic height, resize, approval draft, session switch';
|
|
70
|
+
} catch(error) { document.getElementById('result').textContent = 'FAIL: ' + error.message; }
|
|
71
|
+
</script></body></html>
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">
|
|
3
|
+
<style>*{box-sizing:border-box}body{margin:0;background:#0b0b0c;color:#eee;font-family:Arial,sans-serif}pre{white-space:pre-wrap;overflow-wrap:anywhere}</style></head>
|
|
4
|
+
<body><div id="root"></div><pre id="result">RUNNING</pre>
|
|
5
|
+
<script type="module">
|
|
6
|
+
import React from 'react';
|
|
7
|
+
import '/shared/theme/tokens.css';
|
|
8
|
+
import { createRoot } from 'react-dom/client';
|
|
9
|
+
import WorkspaceSelector from '/shared/components/WorkspaceSelector.tsx';
|
|
10
|
+
import CliSessionsView from '/shared/components/CliSessionsView.tsx';
|
|
11
|
+
const demo='/projects/Demo', mint='/projects/Mint-CLI';
|
|
12
|
+
const makeSession=(id,kind,workspacePath)=>({id,kind,workspacePath,title:`Task ${id}`,createdAt:'2026-10-05T15:10:24Z',messageCount:1});
|
|
13
|
+
const sessions=[makeSession('app-demo','conversation',demo), ...Array.from({length:37},(_,i)=>makeSession(`cli::${i}`,'cli',mint))];
|
|
14
|
+
const chatHost=document.createElement('div');document.body.append(chatHost);
|
|
15
|
+
createRoot(chatHost).render(React.createElement(WorkspaceSelector,{currentPath:mint,recentPaths:[demo,mint,'/projects/Empty'],onSelectWorkspace:()=>{}}));
|
|
16
|
+
const root=createRoot(document.getElementById('root'));
|
|
17
|
+
const sleep=ms=>new Promise(resolve=>setTimeout(resolve,ms));
|
|
18
|
+
const checks=[];
|
|
19
|
+
let folderResult='/projects/Picked', folderCalls=0;
|
|
20
|
+
let toast='';
|
|
21
|
+
function check(condition,message){if(!condition)throw Error(message);checks.push(message)}
|
|
22
|
+
async function waitFor(predicate){for(let i=0;i<100;i++){if(predicate())return;await sleep(20)}throw Error('Timed out waiting for UI')}
|
|
23
|
+
function render(workspace=demo){root.render(React.createElement(CliSessionsView,{chatSessions:sessions,workspacePath:workspace,recentWorkspacePaths:[demo,mint,'/projects/Empty'],activeConversationId:'app-demo',onSelectSession:()=>{},onDeleteSession:()=>{},onRenameSession:()=>{},onSelectFolder:async()=>{folderCalls++;return folderResult},onShowToast:message=>{toast=message}}))}
|
|
24
|
+
function trigger(){return document.querySelector('.code-header-controls .workspace-select-btn')}
|
|
25
|
+
async function choose(path){
|
|
26
|
+
trigger().click();await waitFor(()=>document.querySelector('.workspace-select-menu'));
|
|
27
|
+
const option=[...document.querySelectorAll('.workspace-select-option')].find(item=>item.title===path);
|
|
28
|
+
check(!!option,`workspace available: ${path}`);option.click();
|
|
29
|
+
await waitFor(()=>!document.querySelector('.workspace-select-menu'));
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function button(text){return [...document.querySelectorAll('button')].find(b=>b.textContent.trim()===text)}
|
|
33
|
+
function search(text){const input=document.querySelector('.code-search-input');Object.getOwnPropertyDescriptor(HTMLInputElement.prototype,'value').set.call(input,text);input.dispatchEvent(new Event('input',{bubbles:true}))}
|
|
34
|
+
try {
|
|
35
|
+
render();await waitFor(()=>button('Show all sessions'));
|
|
36
|
+
const chatTrigger=chatHost.querySelector('.workspace-select-btn');chatTrigger.click();await waitFor(()=>chatHost.querySelector('.workspace-select-menu'));
|
|
37
|
+
const chatPaths=[...chatHost.querySelectorAll('.workspace-select-option')].map(item=>item.title);
|
|
38
|
+
window.dispatchEvent(new KeyboardEvent('keydown',{key:'Escape',bubbles:true}));await waitFor(()=>!chatHost.querySelector('.workspace-select-menu'));
|
|
39
|
+
trigger().click();await waitFor(()=>document.querySelector('.code-header-controls .workspace-select-menu'));
|
|
40
|
+
const codePaths=[...document.querySelectorAll('.code-header-controls .workspace-select-option')].map(item=>item.title);
|
|
41
|
+
check(JSON.stringify(chatPaths)===JSON.stringify(codePaths),'chat and Code hub show the same workspace paths in the same order');
|
|
42
|
+
window.dispatchEvent(new KeyboardEvent('keydown',{key:'Escape',bubbles:true}));await waitFor(()=>!document.querySelector('.workspace-select-menu'));
|
|
43
|
+
check(document.querySelector('.code-terminal-text').textContent.includes('37 CLI sessions outside this project'),'empty project explains real outside count');
|
|
44
|
+
button('Show all sessions').click();await waitFor(()=>document.querySelectorAll('.code-session-row').length===37);
|
|
45
|
+
check(!document.querySelector('.code-sessions-list').textContent.includes('Task app-demo'),'show all keeps app conversations excluded');
|
|
46
|
+
await choose(mint);await waitFor(()=>button('Current Project').classList.contains('active'));
|
|
47
|
+
check(document.querySelector('.code-header-subtitle').textContent.includes('Mint-CLI'),'selector changes project scope');
|
|
48
|
+
await choose(demo);await waitFor(()=>button('Show all sessions'));
|
|
49
|
+
await choose('/projects/Empty');await waitFor(()=>document.querySelector('.code-header-subtitle').textContent.includes('Empty'));
|
|
50
|
+
check(!!button('Show all sessions'),'recent project without sessions is selectable');
|
|
51
|
+
await choose(mint);await waitFor(()=>document.querySelectorAll('.code-session-row').length===37);
|
|
52
|
+
search('missing-task');await waitFor(()=>document.querySelector('.code-empty-terminal'));
|
|
53
|
+
check(!button('Show all sessions'),'search miss does not claim the project is empty');
|
|
54
|
+
search('');await waitFor(()=>document.querySelectorAll('.code-session-row').length===37);
|
|
55
|
+
render();await sleep(50);
|
|
56
|
+
check(trigger().title===mint,'refresh does not reset local project selection');
|
|
57
|
+
render('/projects/Empty');await waitFor(()=>trigger().title==='/projects/Empty');
|
|
58
|
+
check(true,'workspace prop changes update the initial scope');
|
|
59
|
+
check(document.documentElement.scrollWidth<=innerWidth,'controls fit viewport without horizontal page overflow');
|
|
60
|
+
await choose(mint);await waitFor(()=>document.querySelectorAll('.code-session-row').length===37);
|
|
61
|
+
trigger().click();await waitFor(()=>document.querySelector('.workspace-select-menu'));
|
|
62
|
+
check(document.activeElement===document.querySelector('[aria-label="Search workspaces"]'),'opening focuses workspace search');
|
|
63
|
+
const menu=document.querySelector('.workspace-select-menu');
|
|
64
|
+
check(menu.getBoundingClientRect().top>=trigger().getBoundingClientRect().bottom,'Code hub menu opens below its trigger');
|
|
65
|
+
check(menu.getBoundingClientRect().right<=innerWidth,'workspace menu fits viewport');
|
|
66
|
+
const input=document.querySelector('[aria-label="Search workspaces"]');
|
|
67
|
+
Object.getOwnPropertyDescriptor(HTMLInputElement.prototype,'value').set.call(input,'Empty');input.dispatchEvent(new Event('input',{bubbles:true}));
|
|
68
|
+
await waitFor(()=>document.querySelectorAll('.workspace-select-option').length===1);
|
|
69
|
+
check(document.querySelector('.workspace-select-option').title==='/projects/Empty','workspace search filters paths');
|
|
70
|
+
window.dispatchEvent(new KeyboardEvent('keydown',{key:'Escape',bubbles:true}));
|
|
71
|
+
await waitFor(()=>!document.querySelector('.workspace-select-menu'));
|
|
72
|
+
check(document.activeElement===trigger(),'Escape closes and restores trigger focus');
|
|
73
|
+
trigger().click();await waitFor(()=>button('Open folder…'));button('Open folder…').click();
|
|
74
|
+
await waitFor(()=>trigger().title==='/projects/Picked');
|
|
75
|
+
check(folderCalls===1,'Open folder selects returned directory');
|
|
76
|
+
folderResult=null;trigger().click();await waitFor(()=>button('Open folder…'));button('Open folder…').click();await sleep(30);
|
|
77
|
+
check(trigger().title==='/projects/Picked','cancelled folder dialog preserves selection');
|
|
78
|
+
await choose(mint);await waitFor(()=>document.querySelectorAll('.code-session-row').length===37);
|
|
79
|
+
if(new URLSearchParams(location.search).has('preview')){trigger().click();await waitFor(()=>document.querySelector('.workspace-select-menu'))}
|
|
80
|
+
document.getElementById('result').textContent='PASS\n'+checks.join('\n');
|
|
81
|
+
} catch(error){document.getElementById('result').textContent='FAIL\n'+error.stack;}
|
|
82
|
+
</script></body></html>
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
<!doctype html><html><head><meta charset="utf-8"><title>Collapsed paste input</title></head><body><div id="root"></div><pre id="result">RUNNING</pre><script type="module">
|
|
2
|
+
import React, { useRef, useState } from 'react';
|
|
3
|
+
import { createRoot } from 'react-dom/client';
|
|
4
|
+
import { CollapsiblePasteInput } from '../shared/components/CollapsiblePasteInput';
|
|
5
|
+
const desktop = new URLSearchParams(location.search).get('surface') === 'desktop';
|
|
6
|
+
if (desktop) await import('../src/css/chat.css'); else await import('../src-web/css/chat.css');
|
|
7
|
+
const submitted = [];
|
|
8
|
+
let reset;
|
|
9
|
+
let setAttachment;
|
|
10
|
+
function App() {
|
|
11
|
+
const [value, setValue] = useState('');
|
|
12
|
+
const [attached, setAttached] = useState(false);
|
|
13
|
+
setAttachment = setAttached;
|
|
14
|
+
const inputRef = useRef(null);
|
|
15
|
+
reset = setValue;
|
|
16
|
+
return React.createElement('form', { id: 'chat-form', style: { width: '600px' }, onSubmit: event => { event.preventDefault(); submitted.push(value); setValue(''); } },
|
|
17
|
+
attached && React.createElement('div', { className: 'mint-attachment', style: { height: '30px' } }, 'Image attachment'),
|
|
18
|
+
React.createElement(CollapsiblePasteInput, { id: 'chat-input', value, inputRef, onValueChange: setValue, onChange: event => setValue(event.target.value), onResizeInput: input => { input.style.height = 'auto'; input.style.height = Math.min(input.scrollHeight, 120) + 'px'; } }),
|
|
19
|
+
React.createElement('button', { id: 'send-btn', type: 'submit' }, 'Send'));
|
|
20
|
+
}
|
|
21
|
+
createRoot(document.getElementById('root')).render(React.createElement(App));
|
|
22
|
+
const pause = () => new Promise(resolve => setTimeout(resolve, 70));
|
|
23
|
+
const check = (ok, message) => { if (!ok) throw Error(message); };
|
|
24
|
+
const input = () => document.getElementById('chat-input');
|
|
25
|
+
const paste = text => {
|
|
26
|
+
const data = new DataTransfer(); data.setData('text/plain', text);
|
|
27
|
+
input().dispatchEvent(new ClipboardEvent('paste', { clipboardData: data, bubbles: true, cancelable: true }));
|
|
28
|
+
};
|
|
29
|
+
const edit = value => {
|
|
30
|
+
Object.getOwnPropertyDescriptor(HTMLTextAreaElement.prototype, 'value').set.call(input(), value);
|
|
31
|
+
input().dispatchEvent(new Event('input', { bubbles: true }));
|
|
32
|
+
};
|
|
33
|
+
await pause();
|
|
34
|
+
try {
|
|
35
|
+
paste('a\rb\rc\rd\re\rf\rg'); await pause();
|
|
36
|
+
let badge = document.querySelector('.chat-pasted-content');
|
|
37
|
+
check(badge?.textContent.includes('[Pasted Content 13 chars]'), 'Missing long-paste badge');
|
|
38
|
+
check(badge.getBoundingClientRect().width > 400, 'Paste badge did not span the composer columns');
|
|
39
|
+
check(getComputedStyle(input()).display === 'none', 'Full paste still occupies the composer');
|
|
40
|
+
input().style.height = '0px';
|
|
41
|
+
badge.click(); await pause();
|
|
42
|
+
check(input().clientHeight >= 60, 'Opening did not restore the editable textarea height');
|
|
43
|
+
check(input().value === 'a\nb\nc\nd\ne\nf\ng', 'Opening lost full paste text');
|
|
44
|
+
check(input().selectionStart === 0, 'Opening did not reveal the first line');
|
|
45
|
+
edit('a edited\nb\nc\nd\ne\nf\ng'); await pause();
|
|
46
|
+
input().dispatchEvent(new KeyboardEvent('keydown', { key: 'F2', bubbles: true, cancelable: true })); await pause();
|
|
47
|
+
badge = document.querySelector('.chat-pasted-content');
|
|
48
|
+
check(badge?.textContent.includes('[Pasted Content 20 chars]'), 'F2 did not refold the edited paste with its new character count');
|
|
49
|
+
badge.dispatchEvent(new KeyboardEvent('keydown', { key: 'F2', bubbles: true, cancelable: true })); await pause();
|
|
50
|
+
check(input().value === 'a edited\nb\nc\nd\ne\nf\ng', 'Reopening lost the edits');
|
|
51
|
+
input().dispatchEvent(new KeyboardEvent('keydown', { key: 'F2', bubbles: true, cancelable: true })); await pause();
|
|
52
|
+
document.querySelector('.chat-pasted-content').dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', bubbles: true, cancelable: true })); await pause();
|
|
53
|
+
check(submitted[0] === 'a edited\nb\nc\nd\ne\nf\ng', 'Edited content did not reach submit');
|
|
54
|
+
paste('1\n2\n3\n4\n5\n6\n7'); await pause();
|
|
55
|
+
document.querySelector('.chat-pasted-content').dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', bubbles: true, cancelable: true })); await pause();
|
|
56
|
+
check(submitted[1] === '1\n2\n3\n4\n5\n6\n7', 'Collapsed submit sent a badge instead of full text');
|
|
57
|
+
check(!document.querySelector('.chat-pasted-content'), 'Submitted paste remained attached');
|
|
58
|
+
reset('before selection after'); await pause();
|
|
59
|
+
input().setSelectionRange(7, 16); paste('a\rb\rc\rd\re\rf\rg'); await pause();
|
|
60
|
+
badge = document.querySelector('.chat-pasted-content');
|
|
61
|
+
badge.dispatchEvent(new KeyboardEvent('keydown', { key: 'F2', bubbles: true })); await pause();
|
|
62
|
+
check(input().value === 'before a\nb\nc\nd\ne\nf\ng after', 'Paste replaced surrounding instructions');
|
|
63
|
+
reset(''); await pause(); paste('a\r\nb\rc\nd\ne\nf\r\n'); await pause();
|
|
64
|
+
check(!document.querySelector('.chat-pasted-content') && input().value === 'a\nb\nc\nd\ne\nf\n', 'Six-line paste should stay inline and retain its trailing newline');
|
|
65
|
+
reset(''); setAttachment(true); await pause(); paste('1\n2\n3\n4\n5\n6\n7'); await pause();
|
|
66
|
+
badge = document.querySelector('.chat-pasted-content');
|
|
67
|
+
check(badge.getBoundingClientRect().top >= document.querySelector('.mint-attachment').getBoundingClientRect().bottom, 'Paste badge overlapped image attachments');
|
|
68
|
+
document.getElementById('result').textContent = 'PASS (' + (desktop ? 'Desktop' : 'Web') + '): repeated F2 open/collapse, edits, full Enter submit, reset, selection, six-line boundary and attachment layout';
|
|
69
|
+
} catch (error) { document.getElementById('result').textContent = 'FAIL: ' + error.message; }
|
|
70
|
+
</script></body></html>
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
<!doctype html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>Composer command and model menus</title></head>
|
|
2
|
+
<body><div id="menu-fixture"></div><pre id="result">RUNNING</pre><script type="module">
|
|
3
|
+
import React, { useRef, useState } from 'react';
|
|
4
|
+
import { createRoot } from 'react-dom/client';
|
|
5
|
+
import SlashSuggestions from '../shared/components/SlashSuggestions';
|
|
6
|
+
import SlashChoicePanel from '../shared/components/SlashChoicePanel';
|
|
7
|
+
import ModelSelectorPopover from '../shared/components/ModelSelectorPopover';
|
|
8
|
+
const params = new URLSearchParams(location.search);
|
|
9
|
+
const desktop = params.get('surface') === 'desktop';
|
|
10
|
+
await import('../shared/theme/tokens.css');
|
|
11
|
+
if (desktop) await import('../src/css/dashboard.css'); else await import('../src-web/css/dashboard.css');
|
|
12
|
+
await import('../shared/css/slash-choice.css');
|
|
13
|
+
const style = document.createElement('style');
|
|
14
|
+
style.textContent = 'body{margin:0;background:var(--bg-base,#181818);color:var(--text-main);font-family:Inter,system-ui,sans-serif}#menu-fixture{height:auto!important;position:absolute;bottom:36px;left:50%;transform:translateX(-50%);width:min(736px,calc(100% - 32px))}#result{font-size:11px;position:absolute;top:0;left:8px;white-space:pre-wrap}';
|
|
15
|
+
document.head.append(style);
|
|
16
|
+
let setMessage, setAttached, setChoice;
|
|
17
|
+
const choiceValues=[];
|
|
18
|
+
const selected = [], sent = [];
|
|
19
|
+
function App() {
|
|
20
|
+
const [message, update] = useState('/'); setMessage = update;
|
|
21
|
+
const [attached, attach] = useState(false); setAttached = attach;
|
|
22
|
+
const [choice, updateChoice] = useState(null); setChoice=updateChoice;
|
|
23
|
+
const [model, updateModel] = useState('qwen3');
|
|
24
|
+
const inputRef = useRef(null), slashRef = useRef(null);
|
|
25
|
+
return React.createElement('form', {id:'chat-form', onSubmit:e=>{e.preventDefault();sent.push(message)}},
|
|
26
|
+
choice && React.createElement(SlashChoicePanel,{choice,inputRef,onSelect:value=>{choiceValues.push(value);updateChoice(null)},onDismiss:()=>updateChoice(null)}),
|
|
27
|
+
attached && React.createElement('div',{className:'mint-attachment'},'Image attachment'),
|
|
28
|
+
React.createElement('textarea',{id:'chat-input',ref:inputRef,value:message,onChange:e=>update(e.target.value),onKeyDown:e=>{
|
|
29
|
+
if(slashRef.current?.handleKeyDown(e)) return;
|
|
30
|
+
if(e.key==='Enter') { e.preventDefault();sent.push(message); }
|
|
31
|
+
}}),
|
|
32
|
+
React.createElement(SlashSuggestions,{ref:slashRef,message,onComplete:update,anchorRef:inputRef,suppressed:Boolean(choice)}),
|
|
33
|
+
React.createElement('div',{className:'chat-tool-menu-wrap'},React.createElement('button',{type:'button',id:'chat-tool-btn'},'+')),
|
|
34
|
+
React.createElement(ModelSelectorPopover,{activeProvider:'ollama',activeModel:model,availableProviders:['ollama'],dynamicOllamaModels:['qwen3','deepseek-r1','llama3.3'],settingsConfig:{thinkingEnabled:true,thinkingEffort:'medium'},onSelect:(provider,id)=>{selected.push([provider,id]);updateModel(id)}}),
|
|
35
|
+
React.createElement('button',{type:'submit',id:'send-btn'},'↑'));
|
|
36
|
+
}
|
|
37
|
+
createRoot(document.getElementById('menu-fixture')).render(React.createElement(App));
|
|
38
|
+
const pause=()=>new Promise(r=>setTimeout(r,150));
|
|
39
|
+
const check=(value,message)=>{if(!value) throw Error(message)};
|
|
40
|
+
const input=()=>document.getElementById('chat-input');
|
|
41
|
+
const bounds=selector=>document.querySelector(selector).getBoundingClientRect();
|
|
42
|
+
function checkMenu(selector) {
|
|
43
|
+
const menu=bounds(selector), form=bounds('#chat-form');
|
|
44
|
+
check(menu.bottom<=form.top-4,'Menu must sit above composer');
|
|
45
|
+
check(Math.abs(menu.left-form.left)<=2 && Math.abs(menu.width-form.width)<=2,'Menu must align with composer width');
|
|
46
|
+
check(menu.top>=0 && menu.left>=0 && menu.right<=innerWidth,selector+' must stay within viewport: '+JSON.stringify({top:menu.top,left:menu.left,right:menu.right,width:innerWidth,height:innerHeight}));
|
|
47
|
+
}
|
|
48
|
+
try {
|
|
49
|
+
await pause();
|
|
50
|
+
if(params.get('preview')==='model') {setMessage('');await pause();document.querySelector('.model-selector-trigger').click();await pause();document.getElementById('result').textContent='Model menu preview';}
|
|
51
|
+
else if(params.has('preview')) {document.getElementById('result').textContent='Command menu preview';}
|
|
52
|
+
else {
|
|
53
|
+
const height=bounds('#chat-form').height;
|
|
54
|
+
checkMenu('.slash-suggestions-popup');
|
|
55
|
+
setAttached(true);await pause();checkMenu('.slash-suggestions-popup');
|
|
56
|
+
setAttached(false);setMessage('/statistics');await pause();
|
|
57
|
+
check(document.querySelector('[role="option"]').textContent.includes('/stats'),'Description search should find executable stats command');
|
|
58
|
+
document.querySelector('[role="option"]').click();await pause();
|
|
59
|
+
check(input().value==='/stats ','Click should complete command');
|
|
60
|
+
check(!document.querySelector('.slash-suggestions-popup'),'Completion should dismiss menu');
|
|
61
|
+
setMessage('/models');await pause();
|
|
62
|
+
input().dispatchEvent(new KeyboardEvent('keydown',{key:'Enter',bubbles:true}));await pause();
|
|
63
|
+
check(sent.at(-1)==='/models','Fully typed commands should submit on first Enter');
|
|
64
|
+
setMessage('/');await pause();
|
|
65
|
+
input().dispatchEvent(new KeyboardEvent('keydown',{key:'Escape',bubbles:true}));await pause();
|
|
66
|
+
check(!document.querySelector('.slash-suggestions-popup'),'Escape should close suggestions');
|
|
67
|
+
input().dispatchEvent(new KeyboardEvent('keydown',{key:'ArrowDown',bubbles:true}));await pause();
|
|
68
|
+
check(Boolean(document.querySelector('.slash-suggestions-popup')),'Arrow should reopen suggestions');
|
|
69
|
+
setMessage('');await pause();
|
|
70
|
+
check(Math.abs(bounds('#chat-form').height-height)<2,'Suggestions must not enlarge composer');
|
|
71
|
+
document.querySelector('.model-selector-trigger').click();await pause();checkMenu('.model-spotlight-popover');
|
|
72
|
+
const leftPane=document.querySelector('.model-spotlight-left-pane');
|
|
73
|
+
const rightPane=document.querySelector('.model-spotlight-right-pane');
|
|
74
|
+
if(innerWidth>760) {
|
|
75
|
+
check(getComputedStyle(rightPane).display!=='none','Desktop model menu must show Options beside Models');
|
|
76
|
+
check(Math.abs(bounds('.model-spotlight-left-pane').width-bounds('.model-spotlight-right-pane').width)<3,'Desktop Models and Options must each take half the menu');
|
|
77
|
+
} else {
|
|
78
|
+
check(getComputedStyle(rightPane).display==='none','Narrow model menu starts with Models');
|
|
79
|
+
const optionsTab=document.querySelectorAll('[role="tab"]')[1];
|
|
80
|
+
const tabEnter=new KeyboardEvent('keydown',{key:'Enter',bubbles:true,cancelable:true});
|
|
81
|
+
optionsTab.dispatchEvent(tabEnter);await pause();
|
|
82
|
+
check(selected.length===0 && !tabEnter.defaultPrevented,'Enter on a tab must not select a model');
|
|
83
|
+
optionsTab.click();await pause();
|
|
84
|
+
check(getComputedStyle(rightPane).display!=='none','Thinking options must remain accessible');
|
|
85
|
+
document.querySelectorAll('[role="tab"]')[0].click();await pause();
|
|
86
|
+
}
|
|
87
|
+
document.querySelectorAll('.model-spotlight-item')[1].click();await pause();
|
|
88
|
+
check(selected.at(-1)?.[1]==='deepseek-r1','Mouse selection should choose model');
|
|
89
|
+
check(!document.querySelector('.model-spotlight-popover'),'Model selection should dismiss menu');
|
|
90
|
+
setAttached(true);await pause();document.querySelector('.model-selector-trigger').click();await pause();checkMenu('.model-spotlight-popover');
|
|
91
|
+
document.querySelector('.model-spotlight-input').dispatchEvent(new KeyboardEvent('keydown',{key:'Escape',bubbles:true}));await pause();
|
|
92
|
+
check(!document.querySelector('.model-spotlight-popover'),'Escape should dismiss model list');
|
|
93
|
+
const providerChoice={command:'/models',title:'Select AI provider',options:[{label:'OpenRouter',value:'openrouter'},{label:'DeepSeek',value:'deepseek'},{label:'Gemini',value:'gemini'}]};
|
|
94
|
+
setChoice(providerChoice);await pause();input().focus();
|
|
95
|
+
const sendsBefore=sent.length;
|
|
96
|
+
const press=async key=>{input().dispatchEvent(new KeyboardEvent('keydown',{key,bubbles:true,cancelable:true}));await pause()};
|
|
97
|
+
await press('ArrowDown');
|
|
98
|
+
check(document.querySelector('.slash-choice-options button[aria-pressed="true"]')?.textContent.includes('DeepSeek'),'ArrowDown should highlight next provider');
|
|
99
|
+
await press('Enter');
|
|
100
|
+
check(choiceValues.at(-1)==='deepseek','Enter should choose highlighted provider');
|
|
101
|
+
check(sent.length===sendsBefore,'Choice Enter must not submit composer');
|
|
102
|
+
setChoice({...providerChoice,title:'Select model',options:[{label:'Model A',value:'a'},{label:'Model B',value:'b'}]});await pause();
|
|
103
|
+
await press('ArrowUp');await press('Enter');
|
|
104
|
+
check(choiceValues.at(-1)==='b','New choice should reset selection and ArrowUp should wrap');
|
|
105
|
+
setChoice({...providerChoice,title:'Long model list',options:Array.from({length:40},(_,i)=>({label:'Model '+i,value:String(i)}))});await pause();
|
|
106
|
+
await press('ArrowUp');
|
|
107
|
+
const activeChoice=document.querySelector('.slash-choice-options button[aria-pressed="true"]').getBoundingClientRect();
|
|
108
|
+
const panelBounds=bounds('.slash-choice-panel');
|
|
109
|
+
check(activeChoice.top>=panelBounds.top && activeChoice.bottom<=panelBounds.bottom,'Arrow navigation should scroll highlighted option into view');
|
|
110
|
+
await press('Enter');check(choiceValues.at(-1)==='39','Enter should choose last option after wrapping');
|
|
111
|
+
setChoice(providerChoice);await pause();await press('Escape');
|
|
112
|
+
check(!document.querySelector('.slash-choice-panel'),'Escape should dismiss choices');
|
|
113
|
+
document.getElementById('result').textContent='PASS: '+(desktop?'Desktop':'Web')+' '+innerWidth+'px — menu placement, attachment layout, search, completion, Enter, Escape, reopen, model selection thinking options and slash choice keyboard navigation';
|
|
114
|
+
}
|
|
115
|
+
} catch(error) {document.getElementById('result').textContent='FAIL: '+error.message;}
|
|
116
|
+
</script></body></html>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<!doctype html><html><head><meta charset="utf-8"><title>Context compaction status</title></head><body style="background:#111;color:#eee;font-family:system-ui"><div id="root"></div><pre id="result">RUNNING</pre><script type="module">
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { createRoot } from 'react-dom/client';
|
|
4
|
+
import { ContextCompactionStatus } from '../shared/components/ContextCompactionStatus';
|
|
5
|
+
import '../shared/css/thinking-status.css';
|
|
6
|
+
document.documentElement.style.setProperty('--text-main','#eeeeee');
|
|
7
|
+
document.documentElement.style.setProperty('--text-muted','#71717a');
|
|
8
|
+
document.documentElement.style.setProperty('--text-soft','#a1a1aa');
|
|
9
|
+
createRoot(document.getElementById('root')).render(React.createElement(ContextCompactionStatus));
|
|
10
|
+
setTimeout(() => {
|
|
11
|
+
const label=document.querySelector('.thinking-status-label');
|
|
12
|
+
const meta=document.querySelector('.thinking-status-meta');
|
|
13
|
+
const style=getComputedStyle(label);
|
|
14
|
+
const ok=document.body.textContent.includes('Summarizing earlier steps to continue working') && /[2-9]s/.test(meta.textContent) && style.backgroundImage.includes('linear-gradient') && style.animationName==='thinkingStatusSweep';
|
|
15
|
+
document.getElementById('result').textContent=ok?'PASS: timer, message and gradient':'FAIL: '+meta.textContent+' '+style.backgroundImage+' '+style.animationName;
|
|
16
|
+
},2800);
|
|
17
|
+
</script></body></html>
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
<!-- Browser regression: real shared React hook, isolated transport and draft keys. -->
|
|
2
|
+
<!doctype html><html><body><div id="root"></div><pre id="result">RUNNING</pre>
|
|
3
|
+
<script type="module">
|
|
4
|
+
import React, { StrictMode } from 'react';
|
|
5
|
+
import { createRoot } from 'react-dom/client';
|
|
6
|
+
import { useConversationCoordinator } from '/shared/conversation/useConversationCoordinator.ts';
|
|
7
|
+
const prefix = 'mint:lifecycle-browser-test:';
|
|
8
|
+
const workspaceKey = prefix + 'workspace';
|
|
9
|
+
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
|
|
10
|
+
const assert = (condition, message) => { if (!condition) throw new Error(message); };
|
|
11
|
+
async function until(check) {
|
|
12
|
+
for (let i = 0; i < 200; i++) { if (check()) return; await sleep(50); }
|
|
13
|
+
throw new Error('Timed out waiting for React/persistence');
|
|
14
|
+
}
|
|
15
|
+
let current, actions, reply, callbacks, errors = [];
|
|
16
|
+
const transport = {
|
|
17
|
+
getConversationSnapshot: async () => ({ interactions: [], cursor: 0, hasOlder: false }),
|
|
18
|
+
getConversationChanges: async () => ({ changes: [], cursor: 0, hasMore: false }),
|
|
19
|
+
listChatSessions: async () => [], cancelChatMessage: async () => {}, clearChatHistory: async () => 0,
|
|
20
|
+
saveInteractionAgentActivity: async () => {}, submitToolApproval: async () => {},
|
|
21
|
+
streamChatMessage: (...args) => { callbacks = args; return new Promise(resolve => reply = resolve); },
|
|
22
|
+
};
|
|
23
|
+
function Harness() {
|
|
24
|
+
const result = useConversationCoordinator({ message: 'draft A', workspacePath: '/A' }, {
|
|
25
|
+
conversationId: 'A', draftKeyPrefix: prefix, workspaceStorageKey: workspaceKey,
|
|
26
|
+
historyVisible: false, onError: error => errors.push(error),
|
|
27
|
+
}, transport);
|
|
28
|
+
current = result.conversation; actions = result.actions;
|
|
29
|
+
return React.createElement('div', null,
|
|
30
|
+
React.createElement('span', {id:'active'}, current.conversationId),
|
|
31
|
+
React.createElement('textarea', {id:'composer', value:current.message, onChange:event=>actions.compose(event.target.value)}),
|
|
32
|
+
React.createElement('span', {id:'sending'}, String(current.sending)),
|
|
33
|
+
React.createElement('span', {id:'approval'}, current.pendingApprovals[current.conversationId]?.token ?? 'none'));
|
|
34
|
+
}
|
|
35
|
+
const root = createRoot(document.getElementById('root'));
|
|
36
|
+
try {
|
|
37
|
+
root.render(React.createElement(StrictMode, null, React.createElement(Harness)));
|
|
38
|
+
await until(() => localStorage.getItem(prefix+'A') === 'draft A');
|
|
39
|
+
assert(localStorage.getItem(prefix+'A') === 'draft A', 'initial draft is persisted under A');
|
|
40
|
+
actions.activate('B', 'draft B');
|
|
41
|
+
await until(() => document.querySelector('#active')?.textContent === 'B' && localStorage.getItem(prefix+'B') === 'draft B');
|
|
42
|
+
assert(document.querySelector('#active').textContent === 'B', 'shared hook displays the selected conversation');
|
|
43
|
+
assert(document.querySelector('#composer').value === 'draft B', 'selected draft appears without an intermediate stale A state');
|
|
44
|
+
assert(localStorage.getItem(prefix+'A') === 'draft A', 'switching never writes the B draft to A');
|
|
45
|
+
assert(localStorage.getItem(prefix+'B') === 'draft B', 'selected draft is persisted under B');
|
|
46
|
+
actions.selectWorkspace('/B');
|
|
47
|
+
const run = actions.sendPrompt('work', {clearComposer:true});
|
|
48
|
+
await until(() => document.querySelector('#sending')?.textContent === 'true');
|
|
49
|
+
callbacks[13]({token:'approve-B', approval:{RunShell:{command:'pwd'}}});
|
|
50
|
+
await until(() => document.querySelector('#approval')?.textContent === 'approve-B');
|
|
51
|
+
assert(document.querySelector('#sending').textContent === 'true', 'React observes run startup through the lifecycle interface');
|
|
52
|
+
assert(document.querySelector('#approval').textContent === 'approve-B', 'React observes pending approval');
|
|
53
|
+
await actions.resolveApproval(true);
|
|
54
|
+
reply({provider:'system', model:'test', text:'done'});
|
|
55
|
+
await run;
|
|
56
|
+
await until(() => document.querySelector('#sending')?.textContent === 'false' && localStorage.getItem(prefix+'B') === null);
|
|
57
|
+
assert(document.querySelector('#sending').textContent === 'false', 'React observes run completion');
|
|
58
|
+
assert(document.querySelector('#approval').textContent === 'none', 'resolved approval is removed');
|
|
59
|
+
assert(localStorage.getItem(prefix+'B') === null, 'clearing composer removes only B draft');
|
|
60
|
+
assert(localStorage.getItem(workspaceKey) === '/B', 'workspace persistence follows lifecycle state');
|
|
61
|
+
assert(errors.length === 0, 'no lifecycle errors in StrictMode');
|
|
62
|
+
root.unmount();
|
|
63
|
+
document.getElementById('result').textContent = 'PASS: StrictMode subscription, conversation drafts, workspace persistence, run and approval rendering';
|
|
64
|
+
} catch(error) {
|
|
65
|
+
root.unmount();
|
|
66
|
+
document.getElementById('result').textContent = 'FAIL: '+error.stack;
|
|
67
|
+
} finally {
|
|
68
|
+
for (const key of [prefix+'A', prefix+'B', workspaceKey]) localStorage.removeItem(key);
|
|
69
|
+
}
|
|
70
|
+
</script></body></html>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html><head><meta name="viewport" content="width=device-width, initial-scale=1"><title>Mint effects measurement</title></head>
|
|
3
|
+
<body style="margin:0;background:#0f172a">
|
|
4
|
+
<div class="assistant-workspace chat-only" style="position:fixed;inset:0"><div id="root" style="width:300px;height:300px;margin:100px auto"></div></div>
|
|
5
|
+
<script type="module">
|
|
6
|
+
import React from 'react';
|
|
7
|
+
import {createRoot} from 'react-dom/client';
|
|
8
|
+
import {VoicePoweredOrb} from '../shared/components/ui/voice-powered-orb';
|
|
9
|
+
import '../src-web/css/app-shell.css';
|
|
10
|
+
const root=createRoot(document.getElementById('root'));
|
|
11
|
+
window.setOrb=(props={})=>root.render(React.createElement(VoicePoweredOrb,{enableVoiceControl:false,...props}));
|
|
12
|
+
window.setOrb();
|
|
13
|
+
</script></body></html>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<!doctype html><html><head><meta name="viewport" content="width=device-width, initial-scale=1"><title>Error recovery regression</title></head><body style="margin:0"><div id="root"></div><pre id="result">RUNNING</pre><script type="module">
|
|
2
|
+
import React from 'react';import {createRoot} from 'react-dom/client';import ChunkErrorBoundary from '../shared/components/ChunkErrorBoundary';
|
|
3
|
+
const wait=ms=>new Promise(r=>setTimeout(r,ms)),results=[];const assert=(ok,msg)=>{if(!ok)throw Error(msg);results.push(msg)};
|
|
4
|
+
let fail=true,micRequests=0;Object.defineProperty(navigator,'mediaDevices',{configurable:true,value:{getUserMedia:async()=>{micRequests++;throw Error('Error page must not request microphone')}}});
|
|
5
|
+
function BrokenRoute(){if(fail)throw Error('Fixture route failed to render');return React.createElement('h1',null,'Recovered chat')}
|
|
6
|
+
const root=createRoot(document.getElementById('root'));root.render(React.createElement(ChunkErrorBoundary,null,React.createElement(BrokenRoute)));
|
|
7
|
+
const frames=new Map();let id=0;window.requestAnimationFrame=cb=>{frames.set(++id,cb);return id};window.cancelAnimationFrame=id=>frames.delete(id);
|
|
8
|
+
try{
|
|
9
|
+
await wait(400);for(let i=0;i<20;i++){const batch=[...frames.values()];frames.clear();batch.forEach(cb=>cb(performance.now()+i*20));}
|
|
10
|
+
const canvas=document.querySelector('.voice-powered-orb canvas');assert(canvas,'full application error renders the supplied orb');
|
|
11
|
+
assert(micRequests===0,'error page never requests microphone access');
|
|
12
|
+
assert(document.body.textContent.includes('Mint needs to refresh'),'recovery guidance is retained');
|
|
13
|
+
const gl=canvas.getContext('webgl2')||canvas.getContext('webgl');const px=new Uint8Array(canvas.width*canvas.height*4);gl.readPixels(0,0,canvas.width,canvas.height,gl.RGBA,gl.UNSIGNED_BYTE,px);assert(px.some((v,i)=>i%4!==3&&v>40),'error orb shader renders visible pixels');
|
|
14
|
+
const refresh=[...document.querySelectorAll('button')].find(b=>b.textContent.includes('Refresh'));assert(refresh,'refresh action remains available');
|
|
15
|
+
const rect=refresh.getBoundingClientRect();assert(rect.left>=0&&rect.right<=innerWidth&&rect.top>=0&&rect.bottom<=innerHeight,'recovery actions fit viewport');
|
|
16
|
+
if(!location.search.includes('preview')){
|
|
17
|
+
fail=false;[...document.querySelectorAll('button')].find(b=>b.textContent.includes('Back to Chat')).click();await wait(100);assert(document.body.textContent.includes('Recovered chat'),'Back to Chat retries the route');assert(location.hash==='#/','Back to Chat resets navigation');assert(frames.size===0,'recovering releases the orb animation frame');root.unmount();
|
|
18
|
+
}else document.getElementById('result').style.display='none';
|
|
19
|
+
document.getElementById('result').textContent='PASS\n'+results.join('\n');
|
|
20
|
+
}catch(e){document.getElementById('result').textContent='FAIL: '+e.message+'\n'+results.join('\n');}
|
|
21
|
+
</script></body></html>
|