@pheem49/mint 1.15.0 → 1.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Cargo.lock +1012 -69
- package/Cargo.toml +5 -2
- package/LICENSE +21 -654
- package/README.md +92 -817
- package/Release_Note.md +71 -579
- 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/compact.rs +69 -0
- package/apps/mint-companion/src-tauri/src/main.rs +675 -0
- package/apps/mint-companion/tsconfig.json +20 -0
- package/apps/mint-companion/vite.config.ts +4 -0
- package/components.json +19 -0
- package/crates/mint-cli/Cargo.toml +6 -0
- package/crates/mint-cli/src/agent/live_status.rs +230 -41
- package/crates/mint-cli/src/agent.rs +476 -108
- package/crates/mint-cli/src/commands/agent.rs +294 -86
- package/crates/mint-cli/src/commands/browser.rs +127 -0
- package/crates/mint-cli/src/commands/config.rs +14 -1
- package/crates/mint-cli/src/commands/integrations.rs +7 -0
- package/crates/mint-cli/src/commands/knowledge.rs +28 -34
- package/crates/mint-cli/src/commands/mod.rs +59 -1
- package/crates/mint-cli/src/commands/tailnet_web.rs +2 -7
- package/crates/mint-cli/src/companion_navigation.rs +268 -0
- package/crates/mint-cli/src/image.rs +31 -33
- package/crates/mint-cli/src/interactive/chat_tui.rs +4977 -864
- package/crates/mint-cli/src/interactive/command_ui.rs +39 -0
- package/crates/mint-cli/src/interactive/input_box.rs +56 -6
- package/crates/mint-cli/src/interactive/slash_commands.rs +321 -61
- package/crates/mint-cli/src/interactive/tool_activity.rs +667 -0
- package/crates/mint-cli/src/interactive.rs +93 -37
- package/crates/mint-cli/src/main.rs +36 -9
- 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 +3492 -1360
- package/crates/mint-cli/src/terminal_theme.rs +3 -1
- package/crates/mint-cli/src/updater.rs +56 -2
- package/crates/mint-cli/tests/library_intake.rs +77 -0
- package/crates/mint-cli/tests/mods_testing.rs +137 -0
- package/crates/mint-companion-protocol/Cargo.toml +10 -0
- package/crates/mint-companion-protocol/src/lib.rs +276 -0
- package/crates/mint-core/Cargo.toml +6 -3
- package/crates/mint-core/build.rs +26 -0
- package/crates/mint-core/src/agent/chat.rs +406 -39
- package/crates/mint-core/src/agent/code_tools.rs +15 -0
- package/crates/mint-core/src/agent/memory/sources.rs +240 -0
- package/crates/mint-core/src/agent/memory.rs +220 -19
- package/crates/mint-core/src/agent/safety.rs +56 -4
- package/crates/mint-core/src/agent/skill_inventory.rs +327 -0
- package/crates/mint-core/src/agent/skills.rs +438 -90
- package/crates/mint-core/src/agent.rs +1 -0
- package/crates/mint-core/src/api_server/routes/auth.rs +1 -4
- package/crates/mint-core/src/api_server/routes/background_jobs.rs +310 -0
- package/crates/mint-core/src/api_server/routes/chat.rs +245 -214
- package/crates/mint-core/src/api_server/routes/html_preview.rs +77 -0
- package/crates/mint-core/src/api_server/routes/library.rs +97 -0
- package/crates/mint-core/src/api_server/routes/media_gen.rs +10 -57
- package/crates/mint-core/src/api_server/routes/misc.rs +220 -107
- package/crates/mint-core/src/api_server/routes/mod.rs +6 -0
- package/crates/mint-core/src/api_server/routes/mods.rs +31 -0
- package/crates/mint-core/src/api_server/routes/profile_oauth.rs +43 -26
- package/crates/mint-core/src/api_server/routes/sessions.rs +127 -69
- package/crates/mint-core/src/api_server/routes/skills_subagents.rs +16 -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/routes/status_health.rs +18 -8
- package/crates/mint-core/src/api_server.rs +327 -72
- package/crates/mint-core/src/avatar_bridge.rs +15 -3
- package/crates/mint-core/src/browser/cdp.rs +82 -26
- package/crates/mint-core/src/browser/lifecycle.rs +143 -43
- package/crates/mint-core/src/browser/mod.rs +5 -4
- package/crates/mint-core/src/browser/navigate.rs +82 -9
- package/crates/mint-core/src/browser/runtime.rs +284 -0
- package/crates/mint-core/src/browser/session.rs +315 -7
- package/crates/mint-core/src/browser/workflow.rs +386 -0
- package/crates/mint-core/src/companion/navigation.rs +115 -0
- package/crates/mint-core/src/companion.rs +824 -0
- package/crates/mint-core/src/cron/scheduler.rs +34 -2
- package/crates/mint-core/src/integrations/channels.rs +87 -345
- package/crates/mint-core/src/integrations/mcp.rs +397 -50
- package/crates/mint-core/src/integrations/mcp_calls.rs +823 -0
- package/crates/mint-core/src/integrations/mcp_catalog.rs +267 -0
- package/crates/mint-core/src/integrations/mcp_device.rs +319 -0
- package/crates/mint-core/src/integrations/mcp_result.rs +401 -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 +95 -32
- package/crates/mint-core/src/media/gemini_live.rs +134 -14
- package/crates/mint-core/src/media/image_models.rs +3 -27
- package/crates/mint-core/src/media/image_proxy.rs +563 -0
- package/crates/mint-core/src/media/image_workflow.rs +216 -0
- package/crates/mint-core/src/media/library/intake.rs +144 -0
- package/crates/mint-core/src/media/library/migration.rs +56 -0
- package/crates/mint-core/src/media/library/removal.rs +55 -0
- package/crates/mint-core/src/media/library/tests.rs +730 -0
- package/crates/mint-core/src/media/library/thumbnails.rs +72 -0
- package/crates/mint-core/src/media/library.rs +545 -0
- package/crates/mint-core/src/media/model_catalog.rs +375 -0
- package/crates/mint-core/src/media/pictures.rs +79 -222
- package/crates/mint-core/src/media/tool_images.rs +196 -0
- package/crates/mint-core/src/media/tts/playback.rs +609 -0
- package/crates/mint-core/src/media/tts.rs +1 -0
- package/crates/mint-core/src/media/video_models.rs +3 -22
- package/crates/mint-core/src/media.rs +5 -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 +553 -32
- package/crates/mint-core/src/orchestration/decision_parsing.rs +5 -23
- package/crates/mint-core/src/orchestration/diagnostics.rs +307 -0
- package/crates/mint-core/src/orchestration/image_regressions.rs +379 -0
- package/crates/mint-core/src/orchestration/loop_guard.rs +334 -0
- package/crates/mint-core/src/orchestration/mcp_review.rs +153 -0
- package/crates/mint-core/src/orchestration/memory_skill.rs +104 -32
- package/crates/mint-core/src/orchestration/mod.rs +3194 -755
- 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/reliability.rs +541 -0
- package/crates/mint-core/src/orchestration/repeated_failures.rs +124 -0
- package/crates/mint-core/src/orchestration/review_regressions.rs +595 -0
- package/crates/mint-core/src/orchestration/run_control.rs +196 -0
- package/crates/mint-core/src/orchestration/tools/files.rs +191 -16
- package/crates/mint-core/src/orchestration/tools/media.rs +37 -41
- package/crates/mint-core/src/orchestration/tools/misc.rs +3 -2
- package/crates/mint-core/src/orchestration/tools/mod.rs +2 -0
- package/crates/mint-core/src/orchestration/tools/mods.rs +161 -0
- package/crates/mint-core/src/orchestration/tools/plugins_mcp.rs +321 -74
- package/crates/mint-core/src/orchestration/tools/project.rs +1 -1
- package/crates/mint-core/src/orchestration/tools/shell.rs +124 -7
- package/crates/mint-core/src/orchestration/tools/web.rs +5 -1
- package/crates/mint-core/src/orchestration/trajectory_schema.rs +353 -0
- package/crates/mint-core/src/orchestration/truncation.rs +211 -0
- package/crates/mint-core/src/orchestration/verification.rs +36 -6
- package/crates/mint-core/src/orchestration/workspace_helpers.rs +57 -23
- package/crates/mint-core/src/prompts/agent.rs +47 -41
- package/crates/mint-core/src/prompts/tool_catalog.rs +158 -38
- package/crates/mint-core/src/search/knowledge.rs +7 -1
- package/crates/mint-core/src/search/linked_folders/index.rs +177 -13
- package/crates/mint-core/src/search/linked_folders.rs +83 -2
- package/crates/mint-core/src/search/web_search.rs +44 -3
- package/crates/mint-core/src/slash/catalog.rs +1 -1
- package/crates/mint-core/src/slash/mod.rs +638 -12
- package/crates/mint-core/src/slash/mods.rs +155 -0
- package/crates/mint-core/src/swarm/batch.rs +643 -0
- package/crates/mint-core/src/swarm/dossier.rs +152 -0
- package/crates/mint-core/src/swarm/labels.rs +100 -0
- package/crates/mint-core/src/swarm/mod.rs +158 -0
- package/crates/mint-core/src/swarm/permissions.rs +167 -0
- package/crates/mint-core/src/system/auth.rs +156 -7
- package/crates/mint-core/src/system/bg_shell.rs +1197 -95
- package/crates/mint-core/src/system/config.rs +97 -13
- package/crates/mint-core/src/system/html_preview.rs +398 -0
- package/crates/mint-core/src/system/mint_web.rs +185 -0
- package/crates/mint-core/src/system/release_notes.rs +18 -0
- package/crates/mint-core/src/system/shell.rs +200 -16
- package/crates/mint-core/src/system/workspace.rs +276 -8
- package/crates/mint-core/src/system/workspace_history.rs +604 -0
- package/crates/mint-core/src/system.rs +4 -0
- package/crates/mint-core/tests/background_retention.rs +34 -0
- package/crates/mint-core/tests/background_shutdown.rs +24 -0
- package/crates/mint-core/tests/library_http.rs +209 -0
- package/crates/mint-core/tests/mcp_contract.rs +283 -0
- package/crates/mint-core/tests/mcp_stdio.rs +11 -10
- package/crates/mint-core/tests/media_model_catalog_http.rs +403 -0
- package/crates/mint-core/tests/memory_persistence.rs +27 -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/ArtifactPreviewPanel-DAT_Y7i0.css +1 -0
- package/out/web/assets/ArtifactPreviewPanel-S0dPfYFx.js +2 -0
- package/out/web/assets/CalculationCard-CRjP3E1j.js +1 -0
- package/out/web/assets/CliSessionsView-C3Br2v5Y.css +1 -0
- package/out/web/assets/CliSessionsView-MI8kXMAb.js +1 -0
- package/out/web/assets/CodeReviewPage-CUJceQme.css +1 -0
- package/out/web/assets/CodeReviewPage-VCUgPla_.js +2 -0
- package/out/web/assets/CommandPalette-BD8SlTE5.js +1 -0
- package/out/web/assets/ImageGenCard-BCXxkVJX.js +1 -0
- package/out/web/assets/ImageSearchCard-N3yQOr8Z.js +1 -0
- package/out/web/assets/ImageStudioPanel-BP7N4rLr.js +1 -0
- package/out/web/assets/LibraryPage-DAxUTAg7.css +1 -0
- package/out/web/assets/LibraryPage-WlviRdR8.js +2 -0
- package/out/web/assets/LinkedFoldersView-CKRgroWK.js +1 -0
- package/out/web/assets/McpRegistryPicker-CoS83vtc.js +1 -0
- package/out/web/assets/McpServersView-D3wHnuHg.js +1 -0
- package/out/web/assets/MermaidCard-NqrHdyJW.js +2 -0
- package/out/web/assets/MintDashboard-B2DJsDDO.css +1 -0
- package/out/web/assets/MintDashboard-COw_xol7.js +63 -0
- package/out/web/assets/PluginsView-jBYmcKh4.js +1 -0
- package/out/web/assets/RewindModal-DempuDod.js +1 -0
- package/out/web/assets/ScheduledTasksView-5uw9-V9H.js +1 -0
- package/out/web/assets/SelectField-DXBQtrUK.js +1 -0
- package/out/web/assets/SelectField-lFEkkWCU.css +1 -0
- package/out/web/assets/SettingsWindow-2YP3yj7s.js +4 -0
- package/out/web/assets/SettingsWindow-Dz8LQVgD.css +1 -0
- package/out/web/assets/SkillsView-C-gp9J7m.js +2 -0
- package/out/web/assets/StockCard-BDMCe7mx.js +1 -0
- package/out/web/assets/ToolSurfacePage-B0J_q0Jl.js +38 -0
- package/out/web/assets/ToolSurfacePage-CRIQ1owD.css +1 -0
- package/out/web/assets/UiFeatureCard-6BwxTOCe.js +1 -0
- package/out/web/assets/UiGridCard-DvZcLNxb.js +1 -0
- package/out/web/assets/UiMockupWidget-DD73QWg1.js +1 -0
- package/out/web/assets/VeoStudioPanel-DfsOJKv0.js +4 -0
- package/out/web/assets/WeatherCard-CPucIfq8.js +1 -0
- package/out/web/assets/WorkspacePanel-BfHKkulU.js +1 -0
- package/out/web/assets/WorkspacePdfPreview-Dx_lkjNu.js +2 -0
- package/out/web/assets/abnfDiagram-VCTEODGH-BOo3Ckng.js +1 -0
- package/out/web/assets/architecture-7GRP2DOG-ZOwheW3n.js +1 -0
- package/out/web/assets/architectureDiagram-5GKGNRK7-DC2FDzVd.js +36 -0
- package/out/web/assets/blockDiagram-I7D4REHJ-BrKFWdAH.js +129 -0
- package/out/web/assets/c4Diagram-7LVT6UL2-BHTHK1Yd.js +38 -0
- package/out/web/assets/chunk-2Q5K7J3B-D2JLPQzF.js +1 -0
- package/out/web/assets/chunk-4HAMMTFA-BYFkZwNj.js +62 -0
- package/out/web/assets/chunk-5VM5RSS4-BZ2oBPYQ.js +15 -0
- package/out/web/assets/chunk-75Z2AOVW-BSKfSKSA.js +2 -0
- package/out/web/assets/chunk-DU6HZSFF-vIhsiW6n.js +128 -0
- package/out/web/assets/chunk-F27PBJKO-BlYpW9xq.js +1 -0
- package/out/web/assets/chunk-FOHPRMQF-JXEeeJ9r.js +161 -0
- package/out/web/assets/chunk-GMAD6QVW-BIBz_Ug5.js +72 -0
- package/out/web/assets/chunk-GVQU2GXP-NPSHxeqC.js +1 -0
- package/out/web/assets/chunk-IMKFNOWR-YlJK8_Fp.js +231 -0
- package/out/web/assets/chunk-JWPE2WC7-BeEMUFDw.js +1 -0
- package/out/web/assets/chunk-L3NEJ4N5-DMYi4-af.js +1 -0
- package/out/web/assets/chunk-OSK3NFVY-Begd3-jA.js +10 -0
- package/out/web/assets/chunk-P2QGCYS3-D1I4xFHN.js +1 -0
- package/out/web/assets/chunk-POPQ4Y6H-CafZZzNE.js +1 -0
- package/out/web/assets/chunk-PWAF6VOD-Dwh6_Lnt.js +1 -0
- package/out/web/assets/chunk-SHT3W25Y-B0XrCSEb.js +168 -0
- package/out/web/assets/chunk-SVP7TREG-CxLsddxC.js +88 -0
- package/out/web/assets/chunk-TICWLB2K-y156QInb.js +206 -0
- package/out/web/assets/chunk-XXDRQBXY-B9YlhOkE.js +1 -0
- package/out/web/assets/chunk-Y2CYZVJY-BxCWjNVG.js +1 -0
- package/out/web/assets/classDiagram-ZZMXUADV-BgJ5WtSp.js +1 -0
- package/out/web/assets/classDiagram-v2-VYDZK3BY-BgJ5WtSp.js +1 -0
- package/out/web/assets/config-CvIO5hkn.js +2 -0
- package/out/web/assets/config-DqXJXeZM.css +1 -0
- package/out/web/assets/core-Mi3s5D4_.js +1 -0
- package/out/web/assets/cose-bilkent-JH36ORCC-qlna31ty.js +1 -0
- package/out/web/assets/cynefin-OW5HDTMX-SMVvrLf-.js +1 -0
- package/out/web/assets/cynefinDiagram-5FMLGOSQ-rZznN24T.js +62 -0
- package/out/web/assets/cytoscape.esm-DWtAUG0r.js +321 -0
- package/out/web/assets/dagre-CnWJJM5f.js +1 -0
- package/out/web/assets/dagre-GXQ25YYZ-BOToydFu.js +4 -0
- package/out/web/assets/diagram-S7CK7UJ4-TMVaGQEJ.js +30 -0
- package/out/web/assets/diagram-UQ7AKVKN-C2JK-GP2.js +41 -0
- package/out/web/assets/diagram-VSXAHHWV-Cw8VSi2K.js +3 -0
- package/out/web/assets/diagram-VX7I27RA-DXp4fKk9.js +24 -0
- package/out/web/assets/diagram-Z3DM3KII-CzSicYiW.js +24 -0
- package/out/web/assets/dist-9ISJ7r-g.js +1 -0
- package/out/web/assets/dist-js-BV3mI7uw.js +1 -0
- package/out/web/assets/ebnfDiagram-PWID7BFC-Dqj-zqPu.js +1 -0
- package/out/web/assets/erDiagram-RLTQ6QDP-DZwFZAuD.js +99 -0
- package/out/web/assets/event-D7D-EBy9.js +1 -0
- package/out/web/assets/eventmodeling-NTZA5JFV-C0O-Lvgp.js +1 -0
- package/out/web/assets/flowDiagram-HODETNUW-uqCHJond.js +1 -0
- package/out/web/assets/ganttDiagram-EL5Y4UJY-Da4ULXTl.js +292 -0
- package/out/web/assets/gitGraph-4MIJSDKK-B9wNFZIP.js +1 -0
- package/out/web/assets/gitGraphDiagram-WWUBYQGX-RjrhB0MP.js +106 -0
- package/out/web/assets/graphlib-Bh9gHply.js +1 -0
- package/out/web/assets/index-BmpulIkg.js +168 -0
- package/out/web/assets/index-CkvBwhX_.css +1 -0
- package/out/web/assets/info-A6RAGUB7-B3dfCpeY.js +1 -0
- package/out/web/assets/infoDiagram-27XIBGKW-QVWkLVx7.js +2 -0
- package/out/web/assets/ishikawaDiagram-5VMMS53U-CLFNIRI9.js +70 -0
- package/out/web/assets/journeyDiagram-3NMN7TZE-fgOQadYF.js +139 -0
- package/out/web/assets/jsx-runtime-DmUwWVTj.js +1 -0
- package/out/web/assets/kanban-definition-UXKFOSKX-G3Q_9g9O.js +89 -0
- package/out/web/assets/katex-MCdQaEAD.js +257 -0
- package/out/web/assets/mermaid-parser.core-v3Jm7nco.js +7 -0
- package/out/web/assets/mermaid.core-DTEjLUA1.js +44 -0
- package/out/web/assets/mindmap-definition-YA3MSWOX-C_D42_fF.js +96 -0
- package/out/web/assets/modelManager-BPLycQrN.js +2 -0
- package/out/web/assets/oauthManager-BUK7ic7q.js +1 -0
- package/out/web/assets/packet-AYTQ26CC-B-R-SHlF.js +1 -0
- package/out/web/assets/pdf-Bcahc2yC.js +56 -0
- package/out/web/assets/pdf.worker.min-Dkey6ZUl.mjs +27 -0
- package/out/web/assets/pegDiagram-XKGWAZYB-Da2q_giz.js +1 -0
- package/out/web/assets/pie-WAS4IAKB-BC8F0N7-.js +1 -0
- package/out/web/assets/pieDiagram-E7YTZNPT-Iy9REJNC.js +39 -0
- package/out/web/assets/quadrantDiagram-AXDQQJYC-ztsiYw7h.js +7 -0
- package/out/web/assets/radar-RG4KPBEZ-B_1P8Z_z.js +1 -0
- package/out/web/assets/railroad-74A4TZTK-DuTqczSo.js +1 -0
- package/out/web/assets/railroad-abnf-HS5TGJTU-Df29WLmp.js +1 -0
- package/out/web/assets/railroad-ebnf-LZEXJU2U-ePFMo-qp.js +1 -0
- package/out/web/assets/railroad-peg-WCYAUIDC-DYXLW4_E.js +1 -0
- package/out/web/assets/railroadDiagram-O6MQD6OU-LStnZf2S.js +1 -0
- package/out/web/assets/requirementDiagram-BXWQKSXE-DmzonMH-.js +84 -0
- package/out/web/assets/rolldown-runtime-CNOWq4Kh.js +1 -0
- package/out/web/assets/rough.esm-CNnFptCR.js +1 -0
- package/out/web/assets/sankeyDiagram-P5KCCOFB-B8vjmUU1.js +40 -0
- package/out/web/assets/sequenceDiagram-WJ2MYXX4-CTnplOAX.js +162 -0
- package/out/web/assets/sizeCapture-INFHLROL-C8Q8DbV5.js +1 -0
- package/out/web/assets/src-CRDfRlHM.js +1 -0
- package/out/web/assets/stateDiagram-D77RDMKH-BFrIaLdI.js +1 -0
- package/out/web/assets/stateDiagram-v2-MP3YSRHH-uf3kdNW4.js +1 -0
- package/out/web/assets/studio-BBZQ_-QK.js +1 -0
- package/out/web/assets/swimlanes-42K2YHIH-BXGngUNU.js +1 -0
- package/out/web/assets/swimlanesDiagram-VR7AAH4N-Y8q5bQce.js +8 -0
- package/out/web/assets/timeline-definition-24CTP7MA-CegH7n43.js +120 -0
- package/out/web/assets/treeView-Q6P3EWNA-DTpJv2Tw.js +1 -0
- package/out/web/assets/treemap-WGGIJYW6-i8M9iJU6.js +1 -0
- package/out/web/assets/vennDiagram-4TSXK5OY-Dpzo1S8U.js +34 -0
- package/out/web/assets/wardley-WFR3VGLG-BrNsgtfw.js +1 -0
- package/out/web/assets/wardleyDiagram-VM6X3IG4-lQ92LFE1.js +78 -0
- package/out/web/assets/window-CkUOP7t0.js +1 -0
- package/out/web/assets/workspaces-SYPrmbgC.js +1 -0
- package/out/web/assets/xychartDiagram-S5SC5T6Z-BaOaEoBd.js +7 -0
- package/out/web/index-web.html +4 -3
- package/out/web/index.html +4 -3
- package/out/web/pdfjs/cmaps/78-EUC-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/78-EUC-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/78-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/78-RKSJ-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/78-RKSJ-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/78-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/78ms-RKSJ-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/78ms-RKSJ-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/83pv-RKSJ-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/90ms-RKSJ-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/90ms-RKSJ-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/90msp-RKSJ-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/90msp-RKSJ-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/90pv-RKSJ-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/90pv-RKSJ-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/Add-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/Add-RKSJ-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/Add-RKSJ-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/Add-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/Adobe-CNS1-0.bcmap +0 -0
- package/out/web/pdfjs/cmaps/Adobe-CNS1-1.bcmap +0 -0
- package/out/web/pdfjs/cmaps/Adobe-CNS1-2.bcmap +0 -0
- package/out/web/pdfjs/cmaps/Adobe-CNS1-3.bcmap +0 -0
- package/out/web/pdfjs/cmaps/Adobe-CNS1-4.bcmap +0 -0
- package/out/web/pdfjs/cmaps/Adobe-CNS1-5.bcmap +0 -0
- package/out/web/pdfjs/cmaps/Adobe-CNS1-6.bcmap +0 -0
- package/out/web/pdfjs/cmaps/Adobe-CNS1-UCS2.bcmap +0 -0
- package/out/web/pdfjs/cmaps/Adobe-GB1-0.bcmap +0 -0
- package/out/web/pdfjs/cmaps/Adobe-GB1-1.bcmap +0 -0
- package/out/web/pdfjs/cmaps/Adobe-GB1-2.bcmap +0 -0
- package/out/web/pdfjs/cmaps/Adobe-GB1-3.bcmap +0 -0
- package/out/web/pdfjs/cmaps/Adobe-GB1-4.bcmap +0 -0
- package/out/web/pdfjs/cmaps/Adobe-GB1-5.bcmap +0 -0
- package/out/web/pdfjs/cmaps/Adobe-GB1-UCS2.bcmap +0 -0
- package/out/web/pdfjs/cmaps/Adobe-Japan1-0.bcmap +0 -0
- package/out/web/pdfjs/cmaps/Adobe-Japan1-1.bcmap +0 -0
- package/out/web/pdfjs/cmaps/Adobe-Japan1-2.bcmap +0 -0
- package/out/web/pdfjs/cmaps/Adobe-Japan1-3.bcmap +0 -0
- package/out/web/pdfjs/cmaps/Adobe-Japan1-4.bcmap +0 -0
- package/out/web/pdfjs/cmaps/Adobe-Japan1-5.bcmap +0 -0
- package/out/web/pdfjs/cmaps/Adobe-Japan1-6.bcmap +0 -0
- package/out/web/pdfjs/cmaps/Adobe-Japan1-UCS2.bcmap +0 -0
- package/out/web/pdfjs/cmaps/Adobe-Korea1-0.bcmap +0 -0
- package/out/web/pdfjs/cmaps/Adobe-Korea1-1.bcmap +0 -0
- package/out/web/pdfjs/cmaps/Adobe-Korea1-2.bcmap +0 -0
- package/out/web/pdfjs/cmaps/Adobe-Korea1-UCS2.bcmap +0 -0
- package/out/web/pdfjs/cmaps/B5-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/B5-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/B5pc-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/B5pc-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/CNS-EUC-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/CNS-EUC-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/CNS1-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/CNS1-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/CNS2-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/CNS2-V.bcmap +3 -0
- package/out/web/pdfjs/cmaps/ETHK-B5-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/ETHK-B5-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/ETen-B5-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/ETen-B5-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/ETenms-B5-H.bcmap +3 -0
- package/out/web/pdfjs/cmaps/ETenms-B5-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/EUC-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/EUC-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/Ext-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/Ext-RKSJ-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/Ext-RKSJ-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/Ext-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/GB-EUC-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/GB-EUC-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/GB-H.bcmap +4 -0
- package/out/web/pdfjs/cmaps/GB-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/GBK-EUC-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/GBK-EUC-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/GBK2K-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/GBK2K-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/GBKp-EUC-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/GBKp-EUC-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/GBT-EUC-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/GBT-EUC-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/GBT-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/GBT-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/GBTpc-EUC-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/GBTpc-EUC-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/GBpc-EUC-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/GBpc-EUC-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/HKdla-B5-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/HKdla-B5-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/HKdlb-B5-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/HKdlb-B5-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/HKgccs-B5-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/HKgccs-B5-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/HKm314-B5-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/HKm314-B5-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/HKm471-B5-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/HKm471-B5-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/HKscs-B5-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/HKscs-B5-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/Hankaku.bcmap +0 -0
- package/out/web/pdfjs/cmaps/Hiragana.bcmap +0 -0
- package/out/web/pdfjs/cmaps/KSC-EUC-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/KSC-EUC-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/KSC-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/KSC-Johab-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/KSC-Johab-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/KSC-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/KSCms-UHC-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/KSCms-UHC-HW-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/KSCms-UHC-HW-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/KSCms-UHC-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/KSCpc-EUC-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/KSCpc-EUC-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/Katakana.bcmap +0 -0
- package/out/web/pdfjs/cmaps/LICENSE +36 -0
- package/out/web/pdfjs/cmaps/NWP-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/NWP-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/RKSJ-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/RKSJ-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/Roman.bcmap +0 -0
- package/out/web/pdfjs/cmaps/UniCNS-UCS2-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/UniCNS-UCS2-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/UniCNS-UTF16-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/UniCNS-UTF16-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/UniCNS-UTF32-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/UniCNS-UTF32-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/UniCNS-UTF8-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/UniCNS-UTF8-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/UniGB-UCS2-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/UniGB-UCS2-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/UniGB-UTF16-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/UniGB-UTF16-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/UniGB-UTF32-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/UniGB-UTF32-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/UniGB-UTF8-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/UniGB-UTF8-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/UniJIS-UCS2-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/UniJIS-UCS2-HW-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/UniJIS-UCS2-HW-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/UniJIS-UCS2-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/UniJIS-UTF16-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/UniJIS-UTF16-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/UniJIS-UTF32-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/UniJIS-UTF32-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/UniJIS-UTF8-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/UniJIS-UTF8-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/UniJIS2004-UTF16-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/UniJIS2004-UTF16-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/UniJIS2004-UTF32-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/UniJIS2004-UTF32-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/UniJIS2004-UTF8-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/UniJIS2004-UTF8-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/UniJISPro-UCS2-HW-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/UniJISPro-UCS2-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/UniJISPro-UTF8-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/UniJISX0213-UTF32-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/UniJISX0213-UTF32-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/UniJISX02132004-UTF32-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/UniJISX02132004-UTF32-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/UniKS-UCS2-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/UniKS-UCS2-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/UniKS-UTF16-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/UniKS-UTF16-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/UniKS-UTF32-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/UniKS-UTF32-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/UniKS-UTF8-H.bcmap +0 -0
- package/out/web/pdfjs/cmaps/UniKS-UTF8-V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/V.bcmap +0 -0
- package/out/web/pdfjs/cmaps/WP-Symbol.bcmap +0 -0
- package/out/web/pdfjs/standard_fonts/FoxitDingbats.pfb +0 -0
- package/out/web/pdfjs/standard_fonts/FoxitFixed.pfb +0 -0
- package/out/web/pdfjs/standard_fonts/FoxitFixedBold.pfb +0 -0
- package/out/web/pdfjs/standard_fonts/FoxitFixedBoldItalic.pfb +0 -0
- package/out/web/pdfjs/standard_fonts/FoxitFixedItalic.pfb +0 -0
- package/out/web/pdfjs/standard_fonts/FoxitSerif.pfb +0 -0
- package/out/web/pdfjs/standard_fonts/FoxitSerifBold.pfb +0 -0
- package/out/web/pdfjs/standard_fonts/FoxitSerifBoldItalic.pfb +0 -0
- package/out/web/pdfjs/standard_fonts/FoxitSerifItalic.pfb +0 -0
- package/out/web/pdfjs/standard_fonts/FoxitSymbol.pfb +0 -0
- package/out/web/pdfjs/standard_fonts/LICENSE_FOXIT +27 -0
- package/out/web/pdfjs/standard_fonts/LICENSE_LIBERATION +363 -0
- package/out/web/pdfjs/standard_fonts/LiberationSans-Bold.ttf +0 -0
- package/out/web/pdfjs/standard_fonts/LiberationSans-BoldItalic.ttf +0 -0
- package/out/web/pdfjs/standard_fonts/LiberationSans-Italic.ttf +0 -0
- package/out/web/pdfjs/standard_fonts/LiberationSans-Regular.ttf +0 -0
- package/out/web/pdfjs/wasm/LICENSE_JBIG2 +196 -0
- package/out/web/pdfjs/wasm/LICENSE_OPENJPEG +39 -0
- package/out/web/pdfjs/wasm/LICENSE_PDFJS_JBIG2 +13 -0
- package/out/web/pdfjs/wasm/LICENSE_PDFJS_OPENJPEG +22 -0
- package/out/web/pdfjs/wasm/LICENSE_PDFJS_QCMS +19 -0
- package/out/web/pdfjs/wasm/LICENSE_QCMS +21 -0
- package/out/web/pdfjs/wasm/jbig2.wasm +0 -0
- package/out/web/pdfjs/wasm/jbig2_nowasm_fallback.js +15 -0
- package/out/web/pdfjs/wasm/openjpeg.wasm +0 -0
- package/out/web/pdfjs/wasm/openjpeg_nowasm_fallback.js +17 -0
- package/out/web/pdfjs/wasm/qcms_bg.wasm +0 -0
- package/out/web/pdfjs/wasm/quickjs-eval.js +16 -0
- package/out/web/pdfjs/wasm/quickjs-eval.wasm +0 -0
- package/package.json +74 -23
- package/shared-modules/.github/workflows/ci.yml +120 -0
- package/shared-modules/.github/workflows/update.yaml +28 -0
- package/slash-commands.json +14 -3
- 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 +21 -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/pdfjs-assets.mjs +31 -0
- package/src/bin/release-notes.test.js +84 -0
- package/src/bin/styles.test.js +20 -0
- package/src/bin/web.js +5 -0
- package/src/bin/web.test.js +39 -0
- package/src/renderer/index.html +0 -2
- package/src/renderer/node_modules/.vite/vitest/CACHEDIR.TAG +3 -0
- package/src/renderer/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
- package/src/renderer/shared/agentProgress.ts +42 -0
- package/src/renderer/shared/components/Settings/AgentsTab.tsx +76 -11
- package/src/renderer/shared/components/Settings/AudioTab.tsx +8 -7
- package/src/renderer/shared/components/Settings/AutomationTab.tsx +59 -2
- package/src/renderer/shared/components/Settings/AvatarCropModal.tsx +18 -12
- package/src/renderer/shared/components/Settings/CustomProviderLogoPicker.test.tsx +65 -0
- package/src/renderer/shared/components/Settings/CustomProviderLogoPicker.tsx +456 -0
- package/src/renderer/shared/components/Settings/GeneralTab.tsx +72 -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 +101 -24
- package/src/renderer/shared/components/Settings/ProfileTab.tsx +1 -1
- package/src/renderer/shared/components/Settings/SettingsWindow.tsx +796 -0
- package/src/renderer/shared/components/Settings/ThemeTab.tsx +31 -11
- package/src/renderer/shared/components/activity/AgentActivityDrawer.tsx +220 -0
- package/src/renderer/shared/components/activity/AgentActivityTable.tsx +340 -0
- package/src/renderer/shared/components/activity/McpToolResults.tsx +118 -0
- package/src/renderer/shared/components/activity/PlanChecklistWidget.tsx +77 -0
- package/src/renderer/shared/components/activity/RunSummaryDashboard.test.tsx +127 -0
- package/src/renderer/shared/components/activity/RunSummaryDashboard.tsx +222 -0
- package/src/renderer/shared/components/activity/SubagentDagView.test.ts +123 -0
- package/src/renderer/shared/components/activity/SubagentDagView.tsx +420 -0
- package/src/renderer/shared/components/activity/SubagentStatusStrip.test.tsx +82 -0
- package/src/renderer/shared/components/activity/SubagentStatusStrip.tsx +107 -0
- package/src/renderer/shared/components/activity/ViewedImages.tsx +140 -0
- package/src/renderer/shared/components/app/AuthGate.tsx +227 -0
- package/src/renderer/shared/components/app/ChunkErrorBoundary.tsx +186 -0
- package/src/renderer/shared/components/app/CommandPalette.tsx +593 -0
- package/src/renderer/shared/components/app/DashboardSidebar.tsx +1230 -0
- package/src/renderer/shared/components/app/DesktopTitlebar.tsx +354 -0
- package/src/renderer/shared/components/app/ErrorNotice.tsx +29 -0
- package/src/renderer/shared/components/app/MintDashboard.tsx +2182 -0
- package/src/renderer/shared/components/app/ModalErrorBoundary.tsx +127 -0
- package/src/renderer/shared/components/cards/CalculationCard.tsx +86 -0
- package/src/renderer/shared/components/cards/ImageGenCard.tsx +146 -0
- package/src/renderer/shared/components/cards/ImageSearchCard.tsx +145 -0
- package/src/renderer/shared/components/cards/MermaidCard.tsx +283 -0
- package/src/renderer/shared/components/cards/StockCard.tsx +152 -0
- package/src/renderer/shared/components/cards/ToolResultCards.tsx +86 -0
- package/src/renderer/shared/components/cards/UiFeatureCard.tsx +267 -0
- package/src/renderer/shared/components/cards/UiGridCard.tsx +188 -0
- package/src/renderer/shared/components/cards/WeatherCard.tsx +224 -0
- package/src/renderer/shared/components/chat/ApprovalCard.test.tsx +24 -0
- package/src/renderer/shared/components/chat/ApprovalCard.tsx +347 -0
- package/src/renderer/shared/components/chat/ChatCodeBlock.tsx +109 -0
- package/src/renderer/shared/components/chat/ChatMessageItem.test.tsx +145 -0
- package/src/renderer/shared/components/chat/ChatMessageItem.tsx +242 -0
- package/src/renderer/shared/components/chat/ChatPanel.test.tsx +31 -0
- package/src/renderer/shared/components/chat/ChatPanel.tsx +1999 -0
- package/src/renderer/shared/components/chat/CollapsiblePasteInput.tsx +90 -0
- package/src/renderer/shared/components/chat/ContextCompactionStatus.tsx +17 -0
- package/src/renderer/shared/components/chat/DiffReviewModal.tsx +565 -0
- package/src/renderer/shared/components/chat/GeminiLiveOverlay.css +86 -0
- package/src/renderer/shared/components/chat/GeminiLiveOverlay.test.tsx +24 -0
- package/src/renderer/shared/components/chat/GeminiLiveOverlay.tsx +112 -0
- package/src/renderer/shared/components/chat/ModelSelectorPopover.tsx +936 -0
- package/src/renderer/shared/components/chat/QueuedMessagesBanner.test.tsx +89 -0
- package/src/renderer/shared/components/chat/QueuedMessagesBanner.tsx +201 -0
- package/src/renderer/shared/components/chat/RewindModal.tsx +414 -0
- package/src/renderer/shared/components/chat/SlashChoicePanel.tsx +88 -0
- package/src/renderer/shared/components/chat/SlashSuggestions.test.tsx +33 -0
- package/src/renderer/shared/components/chat/SlashSuggestions.tsx +346 -0
- package/src/renderer/shared/components/chat/SourcesBlock.tsx +435 -0
- package/src/renderer/shared/components/chat/ThinkingBlock.tsx +102 -0
- package/src/renderer/shared/components/chat/TurnFileChanges.test.tsx +86 -0
- package/src/renderer/shared/components/chat/TurnFileChanges.tsx +430 -0
- package/src/renderer/shared/components/chat/VirtualChatHistory.tsx +82 -0
- package/src/renderer/shared/components/chat/VoicePill.css +85 -0
- package/src/renderer/shared/components/chat/VoicePill.d.ts +12 -0
- package/src/renderer/shared/components/chat/VoicePill.jsx +191 -0
- package/src/renderer/shared/components/chat/VoicePill.test.tsx +22 -0
- package/src/renderer/shared/components/extensions/CliSessionsView.test.tsx +125 -0
- package/src/renderer/shared/components/extensions/CliSessionsView.tsx +545 -0
- package/src/renderer/shared/components/extensions/LinkedFoldersView.tsx +614 -0
- package/src/renderer/shared/components/extensions/McpRegistryPicker.tsx +302 -0
- package/src/renderer/shared/components/extensions/McpServersView.tsx +1040 -0
- package/src/renderer/shared/components/extensions/McpToolAllowlist.tsx +182 -0
- package/src/renderer/shared/components/extensions/ModUi.test.tsx +70 -0
- package/src/renderer/shared/components/extensions/ModsPanel.tsx +208 -0
- package/src/renderer/shared/components/extensions/PluginsView.tsx +325 -0
- package/src/renderer/shared/components/extensions/ScheduledTasksView.tsx +614 -0
- package/src/renderer/shared/components/extensions/SkillsView.test.tsx +31 -0
- package/src/renderer/shared/components/extensions/SkillsView.tsx +363 -0
- package/src/renderer/shared/components/studio/ImageStudioPanel.tsx +740 -0
- package/src/renderer/shared/components/studio/LibraryItemCard.tsx +72 -0
- package/src/renderer/shared/components/studio/LibraryPage.tsx +165 -0
- package/src/renderer/shared/components/studio/LibraryPreview.tsx +59 -0
- package/src/renderer/shared/components/studio/VeoStudioPanel.tsx +708 -0
- package/src/renderer/shared/components/ui/GlideSelect.css +139 -0
- package/src/renderer/shared/components/ui/ProviderBrandIcon.test.tsx +67 -0
- package/src/renderer/shared/components/ui/ProviderBrandIcon.tsx +167 -0
- package/src/renderer/shared/components/ui/README.md +52 -0
- package/src/renderer/shared/components/ui/SelectField.test.tsx +27 -0
- package/src/renderer/shared/components/ui/SelectField.tsx +506 -0
- package/src/renderer/shared/components/ui/button.tsx +37 -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/ArtifactPreviewPanel.tsx +700 -0
- package/src/renderer/shared/components/workspace/BackgroundTerminals.test.tsx +63 -0
- package/src/renderer/shared/components/workspace/BackgroundTerminals.tsx +212 -0
- package/src/renderer/shared/components/workspace/CodeReviewPage.tsx +707 -0
- package/src/renderer/shared/components/workspace/GitBranchSelector.tsx +442 -0
- package/src/renderer/shared/components/workspace/SessionSources.tsx +113 -0
- package/src/renderer/shared/components/workspace/TerminalDock.tsx +244 -0
- package/src/renderer/shared/components/workspace/ToolSurfacePage.test.tsx +68 -0
- package/src/renderer/shared/components/workspace/ToolSurfacePage.tsx +819 -0
- package/src/renderer/shared/components/workspace/ToolsPanelToggle.tsx +13 -0
- package/src/renderer/shared/components/workspace/WorkspaceFileInfo.tsx +28 -0
- package/src/renderer/shared/components/workspace/WorkspaceMediaPreview.tsx +17 -0
- package/src/renderer/shared/components/workspace/WorkspacePaneResizer.tsx +92 -0
- package/src/renderer/shared/components/workspace/WorkspacePdfPreview.tsx +89 -0
- package/src/renderer/shared/components/workspace/WorkspacePreviewActions.test.tsx +89 -0
- package/src/renderer/shared/components/workspace/WorkspacePreviewActions.tsx +19 -0
- package/src/renderer/shared/components/workspace/WorkspaceSelector.tsx +246 -0
- package/src/renderer/shared/components/workspace/background-terminals.css +292 -0
- package/src/renderer/shared/components/workspace/workspace-selector.css +330 -0
- package/src/renderer/shared/constants/config.ts +37 -1
- package/src/renderer/shared/constants/slashCommands.ts +1 -1
- package/src/renderer/shared/conversation/coordinator.test.ts +46 -0
- package/src/renderer/shared/conversation/coordinator.ts +50 -2
- package/src/renderer/shared/conversation/lifecycle.test.ts +524 -0
- package/src/renderer/shared/conversation/lifecycle.ts +575 -0
- package/src/renderer/shared/conversation/projectNavigation.test.ts +123 -0
- package/src/renderer/shared/conversation/projectNavigation.ts +50 -0
- package/src/renderer/shared/conversation/sourcesTransport.ts +27 -0
- package/src/renderer/shared/conversation/syncView.test.ts +1 -34
- package/src/renderer/shared/conversation/syncView.ts +0 -37
- package/src/renderer/shared/conversation/transport.test.ts +183 -0
- package/src/renderer/shared/conversation/transport.ts +201 -0
- package/src/renderer/shared/conversation/useConversationCoordinator.ts +67 -79
- package/src/renderer/shared/css/agent-observability.css +90 -30
- package/src/renderer/shared/css/auth-gate.css +112 -13
- package/src/renderer/shared/css/chat-ui-cards.css +35 -35
- package/src/renderer/shared/css/code-review.css +119 -86
- package/src/renderer/shared/css/code-sessions.css +37 -10
- 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 +167 -5
- package/src/renderer/shared/css/library.css +476 -0
- package/src/renderer/shared/css/management-views.css +216 -37
- package/src/renderer/shared/css/mcp-results.css +54 -0
- package/src/renderer/shared/css/model-selector.css +163 -105
- package/src/renderer/shared/css/mods.css +77 -0
- package/src/renderer/shared/css/notification-notice.css +28 -0
- package/src/renderer/shared/css/queued-messages.css +221 -0
- package/src/renderer/shared/css/session-sources.css +28 -0
- package/src/renderer/shared/css/settings/agents.css +2 -2
- package/src/renderer/shared/css/settings/base.css +1260 -0
- package/src/renderer/shared/css/settings/general.css +384 -92
- 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 +8 -8
- package/src/renderer/shared/css/settings/theme.css +49 -32
- package/src/renderer/shared/css/slash-choice.css +95 -0
- package/src/renderer/shared/css/slash-suggestions.css +68 -0
- package/src/renderer/shared/css/sources-block.css +91 -0
- package/src/renderer/shared/css/thinking-status.css +46 -0
- package/src/renderer/shared/css/tools-panel.css +7 -0
- package/src/renderer/shared/css/ui-tailwind.css +19 -0
- package/src/renderer/shared/css/viewed-images.css +104 -0
- package/src/renderer/shared/css/workspace-file-info.css +12 -0
- package/src/renderer/shared/css/workspace-media-preview.css +13 -0
- package/src/renderer/shared/env.d.ts +9 -0
- package/src/renderer/shared/fonts.css +46 -0
- package/src/renderer/shared/fonts.ts +3 -12
- package/src/renderer/shared/lib/utils.ts +6 -0
- package/src/renderer/shared/library/controller.test.ts +61 -0
- package/src/renderer/shared/library/controller.ts +57 -0
- package/src/renderer/shared/library/transport.test.ts +26 -0
- package/src/renderer/shared/library/transport.ts +60 -0
- package/src/renderer/shared/library/useLibraryFile.ts +38 -0
- package/src/renderer/shared/mods.ts +58 -0
- package/src/renderer/shared/platform.test.ts +200 -1
- package/src/renderer/shared/platform.ts +55 -4
- package/src/renderer/shared/speech/player.ts +160 -0
- package/src/renderer/shared/speech/types.ts +11 -0
- package/src/renderer/shared/theme/themeManager.test.ts +63 -0
- package/src/renderer/shared/theme/themeManager.ts +20 -5
- package/src/renderer/shared/theme/themes.ts +17 -4
- package/src/renderer/shared/theme/tokens.css +448 -51
- package/src/renderer/shared/types.ts +111 -2
- package/src/renderer/shared/utils/agentActivity.test.ts +234 -0
- package/src/renderer/shared/utils/agentActivity.ts +221 -32
- 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/artifacts.ts +55 -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/externalLinks.ts +91 -0
- package/src/renderer/shared/utils/lazyWithRetry.ts +13 -0
- package/src/renderer/shared/utils/markdown.tsx +172 -38
- package/src/renderer/shared/utils/markdown.webImages.test.tsx +124 -2
- package/src/renderer/shared/utils/mcpResults.test.tsx +114 -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/pdfRange.ts +16 -0
- package/src/renderer/shared/utils/previewObjectUrls.ts +20 -0
- package/src/renderer/shared/utils/progressCache.test.ts +32 -0
- package/src/renderer/shared/utils/sessionSources.test.ts +71 -0
- package/src/renderer/shared/utils/sessionSources.ts +36 -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 +65 -9
- package/src/renderer/shared/utils/syntaxHighlight.test.tsx +22 -0
- package/src/renderer/shared/utils/syntaxHighlight.tsx +26 -0
- package/src/renderer/shared/utils/useGeminiLiveVoice.ts +49 -5
- package/src/renderer/shared/utils/useLatestCallback.ts +9 -0
- package/src/renderer/shared/utils/useNativeVoiceInput.ts +95 -73
- package/src/renderer/shared/utils/useSessionSources.ts +37 -0
- package/src/renderer/shared/utils/viewedImages.test.ts +129 -0
- package/src/renderer/shared/utils/viewedImages.ts +97 -0
- package/src/renderer/shared/utils/workspaceDrag.ts +30 -0
- package/src/renderer/shared/utils/workspaceImage.ts +17 -0
- package/src/renderer/shared/utils/workspaceListPreferences.test.ts +64 -0
- package/src/renderer/shared/utils/workspaceListPreferences.ts +54 -0
- package/src/renderer/shared/utils/workspaceMedia.ts +41 -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 +169 -0
- package/src/renderer/shared/utils/workspacePreview.ts +47 -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 +11 -0
- package/src/renderer/shared/workspaceUndo.ts +88 -0
- package/src/renderer/src/App.tsx +15 -9
- package/src/renderer/src/components/ChatPanel.tsx +1 -1
- package/src/renderer/src/components/DashboardSidebar.tsx +2 -2
- package/src/renderer/src/components/ImageStudioPanel.tsx +1 -1
- package/src/renderer/src/components/LiveTranslateControls.tsx +65 -0
- package/src/renderer/src/components/MintDashboard.tsx +1 -1
- package/src/renderer/src/components/ProactiveGlow.tsx +1 -1
- package/src/renderer/src/components/ScreenPicker.css +67 -30
- package/src/renderer/src/components/ScreenPicker.tsx +201 -60
- package/src/renderer/src/components/SettingsWindow.tsx +6 -825
- package/src/renderer/src/components/SpotlightWindow.tsx +4 -32
- package/src/renderer/src/components/VeoStudioPanel.tsx +1 -1
- package/src/renderer/src/components/WorkspacePanel.tsx +261 -38
- package/src/renderer/src/components/browser-shell.css +27 -27
- package/src/renderer/src/components/browser-suggestions-popup.css +9 -9
- package/src/renderer/src/components/liveTranslateFrames.test.ts +26 -5
- package/src/renderer/src/components/liveTranslateFrames.ts +18 -7
- package/src/renderer/src/components/liveTranslateLanguage.ts +6 -0
- package/src/renderer/src/css/app-shell.css +69 -234
- package/src/renderer/src/css/chat.css +207 -494
- package/src/renderer/src/css/desktop-tools.css +6 -139
- package/src/renderer/src/css/misc.css +0 -52
- package/src/renderer/src/css/sidebar-workspace.css +171 -94
- package/src/renderer/src/css/spotlight.css +2 -2
- package/src/renderer/src/css/tool-surfaces.css +387 -61
- package/src/renderer/src/css/widget.css +7 -6
- package/src/renderer/src/env.d.ts +14 -9
- package/src/renderer/src/index.css +16 -64
- package/src/renderer/src/main.tsx +2 -1
- package/src/renderer/src/proactiveSuggestions.ts +29 -0
- package/src/renderer/src/tauri.ts +195 -337
- package/src/renderer/src/voiceInput.ts +5 -2
- package/src/renderer/src-web/App.tsx +6 -8
- package/src/renderer/src-web/components/ChatPanel.tsx +1 -1
- package/src/renderer/src-web/components/DashboardSidebar.tsx +2 -2
- package/src/renderer/src-web/components/ImageStudioPanel.tsx +1 -1
- package/src/renderer/src-web/components/MintDashboard.tsx +1 -1
- package/src/renderer/src-web/components/PullToRefresh.tsx +1 -1
- package/src/renderer/src-web/components/SettingsWindow.tsx +6 -846
- package/src/renderer/src-web/components/VeoStudioPanel.tsx +1 -1
- package/src/renderer/src-web/css/app-shell.css +40 -221
- package/src/renderer/src-web/css/chat.css +207 -494
- package/src/renderer/src-web/css/misc.css +0 -52
- package/src/renderer/src-web/css/mobile.css +15 -14
- package/src/renderer/src-web/css/sidebar-workspace.css +29 -95
- package/src/renderer/src-web/env.d.ts +15 -12
- package/src/renderer/src-web/index.css +16 -64
- package/src/renderer/src-web/main.tsx +2 -1
- package/src/renderer/src-web/proactiveSuggestions.ts +3 -0
- package/src/renderer/src-web/tauri.ts +194 -361
- package/src/renderer/tests/backgroundTerminals.browser.html +81 -0
- package/src/renderer/tests/browserArtifacts.browser.html +1 -0
- package/src/renderer/tests/browserArtifacts.browser.tsx +68 -0
- package/src/renderer/tests/chatEscape.browser.html +1 -0
- package/src/renderer/tests/chatEscape.browser.tsx +25 -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/fixtures/preview.webm +0 -0
- package/src/renderer/tests/glideSelect.browser.html +70 -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/mediaFixtures.ts +32 -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 +168 -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/voiceDictation.browser.html +101 -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 +2 -0
- package/src/renderer/tests/workspaceDrop.browser.html +1 -0
- package/src/renderer/tests/workspaceDrop.browser.tsx +183 -0
- package/src/renderer/tests/workspaceExpansion.browser.html +1 -0
- package/src/renderer/tests/workspaceExpansion.browser.tsx +66 -0
- package/src/renderer/tests/workspaceRemoval.browser.html +66 -0
- package/src/renderer/tests/workspaceUndo.browser.html +100 -0
- package/src-tauri/Cargo.toml +40 -0
- package/src-tauri/build.rs +3 -0
- package/src-tauri/src/app/lifecycle.rs +320 -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 +668 -0
- package/src-tauri/src/commands/integrations.rs +163 -0
- package/src-tauri/src/commands/media.rs +186 -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 +539 -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 +17 -1
- package/vite.config.ts +5 -1
- package/vite.config.web.ts +6 -0
- package/.cargo/config.toml +0 -13
- package/.claude/settings.local.json +0 -182
- package/.codex +0 -0
- package/CLAUDE.md +0 -102
- package/ROADMAP.md +0 -30
- package/mint-presentation-demo.mp4 +0 -0
- package/out/web/Live2DCubismCore.js +0 -9
- package/out/web/assets/CliSessionsView-BxUVWEEL.js +0 -1
- package/out/web/assets/CliSessionsView-CBDTXuQv.css +0 -1
- package/out/web/assets/CodeReviewPage-DkMgfcos.css +0 -1
- package/out/web/assets/CodeReviewPage-jKlmLJwT.js +0 -3
- package/out/web/assets/CommandPalette-DnwPA5hy.js +0 -1
- package/out/web/assets/ImageStudioPanel-BR1XFwhR.js +0 -1
- package/out/web/assets/LinkedFoldersView-bi-CWQ-I.js +0 -1
- package/out/web/assets/McpRegistryPicker-D5tEFnyq.js +0 -1
- package/out/web/assets/McpServersView-BGG1dhFM.js +0 -1
- package/out/web/assets/MintDashboard-BIglDEWX.js +0 -20
- package/out/web/assets/MintDashboard-DSMywSgs.css +0 -1
- package/out/web/assets/ModelPanel-CbJ1PFoZ.js +0 -1
- package/out/web/assets/PicturesLibrary-CQP0fLP1.css +0 -1
- package/out/web/assets/PicturesLibrary-DoYN7T1p.js +0 -1
- package/out/web/assets/PluginsView-CU1HWXGk.js +0 -1
- package/out/web/assets/ScheduledTasksView-Bnl36y2N.js +0 -1
- package/out/web/assets/SettingsWindow-DhWLAn9T.css +0 -1
- package/out/web/assets/SettingsWindow-Dw8L01pw.js +0 -2
- package/out/web/assets/SkillsView-cnl8aY5p.js +0 -2
- package/out/web/assets/ToolSurfacePage-CgsQw6l5.css +0 -1
- package/out/web/assets/ToolSurfacePage-Cz2VJAPZ.js +0 -37
- package/out/web/assets/VeoStudioPanel-D4JnERWR.js +0 -4
- package/out/web/assets/WorkspacePanel-CbJ1PFoZ.js +0 -1
- package/out/web/assets/abnfDiagram-VCTEODGH-ByMyfanq.js +0 -1
- package/out/web/assets/architecture-7GRP2DOG-CLq2kEOB.js +0 -1
- package/out/web/assets/architectureDiagram-5GKGNRK7-6PoVSmNG.js +0 -36
- package/out/web/assets/blockDiagram-NRAW4CY4-cKw9mAKi.js +0 -129
- package/out/web/assets/c4Diagram-UCG6FXSJ-Cqy8N5Ge.js +0 -38
- package/out/web/assets/chunk-2Q5K7J3B-Dmqrq8Tp.js +0 -1
- package/out/web/assets/chunk-5VM5RSS4-BiPuE0io.js +0 -15
- package/out/web/assets/chunk-75Z2AOVW-3qybijF5.js +0 -2
- package/out/web/assets/chunk-CKBBP62Z-cIrXq6jN.js +0 -2
- package/out/web/assets/chunk-CLGD4ZFX-CndDQkww.js +0 -1
- package/out/web/assets/chunk-CacB07dV.js +0 -1
- package/out/web/assets/chunk-DSNCTWBM-Cc4NxvgD.js +0 -2
- package/out/web/assets/chunk-DU6HZSFF-drzh6GsU.js +0 -128
- package/out/web/assets/chunk-F27PBJKO-FiY35l4v.js +0 -1
- package/out/web/assets/chunk-FOHPRMQF-BaVC1uA7.js +0 -161
- package/out/web/assets/chunk-G27WJ6UU-Bjt9Il4A.js +0 -231
- package/out/web/assets/chunk-GMAD6QVW-Bppi3Ctd.js +0 -72
- package/out/web/assets/chunk-JQ64N6SF-DGg5kcEV.js +0 -1
- package/out/web/assets/chunk-JWPE2WC7-BwtYOHqU.js +0 -1
- package/out/web/assets/chunk-LCL6LL3I-CCYcjd7p.js +0 -206
- package/out/web/assets/chunk-LNGE3PJU-AdBoOWw2.js +0 -34
- package/out/web/assets/chunk-OBVCFTLP-DJeNil5M.js +0 -1
- package/out/web/assets/chunk-P2QGCYS3-lRzkRjBB.js +0 -1
- package/out/web/assets/chunk-POPQ4Y6H-DouASMBW.js +0 -1
- package/out/web/assets/chunk-PWAF6VOD-DMmD1vVf.js +0 -1
- package/out/web/assets/chunk-R7TYR2AO-CYLA5UC5.js +0 -10
- package/out/web/assets/chunk-RHFEMEQ7-BiXwEcUT.js +0 -168
- package/out/web/assets/chunk-SVP7TREG-BV-zPslF.js +0 -88
- package/out/web/assets/chunk-TEH6E4GO-B2RGEohZ.js +0 -62
- package/out/web/assets/chunk-XXDRQBXY-DnJkbUaw.js +0 -1
- package/out/web/assets/chunk-Y2CYZVJY-C9o-s6OY.js +0 -1
- package/out/web/assets/classDiagram-DTDB5LWJ-Dq0smRWk.js +0 -1
- package/out/web/assets/classDiagram-v2-JRS7N3AN-Dq0smRWk.js +0 -1
- package/out/web/assets/config-C-ZFtipU.css +0 -1
- package/out/web/assets/config-eEDngJXO.js +0 -1
- package/out/web/assets/core-hQ2VA9Ti.js +0 -1
- package/out/web/assets/cose-bilkent-JH36ORCC--UN4aw5-.js +0 -1
- package/out/web/assets/cynefin-OW5HDTMX-Cas4csHM.js +0 -1
- package/out/web/assets/cynefinDiagram-5FMLGOSQ-Bbpj66Y3.js +0 -62
- package/out/web/assets/cytoscape.esm-Df1UN4Y1.js +0 -321
- package/out/web/assets/dagre-3AP2YEHR-B0-2RDEd.js +0 -4
- package/out/web/assets/dagre-BWadQu2F.js +0 -1
- package/out/web/assets/diagram-S7CK7UJ4-BdzEjUyH.js +0 -30
- package/out/web/assets/diagram-UQ7AKVKN-CJDwyPxF.js +0 -41
- package/out/web/assets/diagram-VSXAHHWV-BxaG1r_B.js +0 -3
- package/out/web/assets/diagram-VX7I27RA-BMmUqm8f.js +0 -24
- package/out/web/assets/diagram-Z3DM3KII-CFtd03eE.js +0 -24
- package/out/web/assets/dist-BoTOASLF.js +0 -1
- package/out/web/assets/dist-js-Bf2bhoku.js +0 -1
- package/out/web/assets/ebnfDiagram-PWID7BFC-DwAen1hO.js +0 -1
- package/out/web/assets/erDiagram-SSCWMZ5O-BCZSHACj.js +0 -99
- package/out/web/assets/event-ChBVpRy0.js +0 -1
- package/out/web/assets/eventmodeling-NTZA5JFV-XHStE4E_.js +0 -1
- package/out/web/assets/flowDiagram-A5DVABFB-BLg7nEcd.js +0 -1
- package/out/web/assets/ganttDiagram-EL5Y4UJY-BAEu1Cql.js +0 -292
- package/out/web/assets/gitGraph-4MIJSDKK-r32Vyper.js +0 -1
- package/out/web/assets/gitGraphDiagram-WWUBYQGX-z9o9qt6V.js +0 -106
- package/out/web/assets/graphlib-CTR5ZhLf.js +0 -1
- package/out/web/assets/index-Btsf4L8M.css +0 -1
- package/out/web/assets/index-D8D9MeRA.js +0 -11
- package/out/web/assets/info-A6RAGUB7-BvLaC2cw.js +0 -1
- package/out/web/assets/infoDiagram-RXCK75RN-Be6WAXXw.js +0 -2
- package/out/web/assets/ishikawaDiagram-5VMMS53U-DZjoHJHC.js +0 -70
- package/out/web/assets/journeyDiagram-EYS64GPL-CtVkjkGm.js +0 -139
- package/out/web/assets/kanban-definition-3QL26DDD-CW5FMv1w.js +0 -89
- package/out/web/assets/katex-O3jvqgnU.js +0 -257
- package/out/web/assets/lucide-react-Ip3L6Jtn.js +0 -1
- package/out/web/assets/markdown-BSeeUbJH.js +0 -38
- package/out/web/assets/mermaid-parser.core-aUgCqsZ5.js +0 -7
- package/out/web/assets/mermaid.core-D57sEiSL.js +0 -11
- package/out/web/assets/mindmap-definition-FBJOCRG2-DAmSpM3a.js +0 -96
- package/out/web/assets/modelManager-tMVmJVAW.js +0 -2
- package/out/web/assets/oauthManager-9jxicDWJ.js +0 -1
- package/out/web/assets/packet-AYTQ26CC-DJ27iIoJ.js +0 -1
- package/out/web/assets/pegDiagram-XKGWAZYB-Bj3ii-gS.js +0 -1
- package/out/web/assets/pie-WAS4IAKB-DG5mCUbc.js +0 -1
- package/out/web/assets/pieDiagram-E7YTZNPT-BrJLPnDA.js +0 -39
- package/out/web/assets/prompt-latin-400-normal-BQ9zjSN8.woff2 +0 -0
- package/out/web/assets/prompt-latin-400-normal-CxU4ec_r.woff +0 -0
- package/out/web/assets/prompt-latin-500-normal-B1edBDQ9.woff +0 -0
- package/out/web/assets/prompt-latin-500-normal-CxzxEHZc.woff2 +0 -0
- package/out/web/assets/prompt-latin-600-normal-CSDDLorv.woff +0 -0
- package/out/web/assets/prompt-latin-600-normal-hKZWXsc1.woff2 +0 -0
- package/out/web/assets/prompt-latin-700-normal-BfbftDSq.woff +0 -0
- package/out/web/assets/prompt-latin-700-normal-I2gc831J.woff2 +0 -0
- package/out/web/assets/prompt-thai-400-normal-BrkKv8cO.woff2 +0 -0
- package/out/web/assets/prompt-thai-400-normal-DJypnfr3.woff +0 -0
- package/out/web/assets/prompt-thai-500-normal-C18pDUoL.woff2 +0 -0
- package/out/web/assets/prompt-thai-500-normal-D7YNqUJD.woff +0 -0
- package/out/web/assets/prompt-thai-600-normal-CYPViXds.woff +0 -0
- package/out/web/assets/prompt-thai-600-normal-MrdfU7zR.woff2 +0 -0
- package/out/web/assets/prompt-thai-700-normal-Cb5ilR-c.woff +0 -0
- package/out/web/assets/prompt-thai-700-normal-Cg4aQ0Nn.woff2 +0 -0
- package/out/web/assets/quadrantDiagram-AXDQQJYC-3x_TmF3j.js +0 -7
- package/out/web/assets/radar-RG4KPBEZ-CrXaTTuV.js +0 -1
- package/out/web/assets/railroad-74A4TZTK-BpqMH9BE.js +0 -1
- package/out/web/assets/railroad-abnf-HS5TGJTU-DHI0uLlV.js +0 -1
- package/out/web/assets/railroad-ebnf-LZEXJU2U-CQCb316y.js +0 -1
- package/out/web/assets/railroad-peg-WCYAUIDC-Ph1giKkH.js +0 -1
- package/out/web/assets/railroadDiagram-O6MQD6OU-BRq6wIxx.js +0 -1
- package/out/web/assets/requirementDiagram-EFPCY7ZU-DIJj6G1g.js +0 -84
- package/out/web/assets/rough.esm-DFbTUy8a.js +0 -1
- package/out/web/assets/sankeyDiagram-P5KCCOFB-DZajSryq.js +0 -40
- package/out/web/assets/sequenceDiagram-WJ2MYXX4-DxJCWyZS.js +0 -162
- package/out/web/assets/sizeCapture-X5ZJPWSS-DKeOCaN2.js +0 -1
- package/out/web/assets/src-DnfeXQPr.js +0 -1
- package/out/web/assets/stateDiagram-HBIQ2CUA-k6voi8Vf.js +0 -1
- package/out/web/assets/stateDiagram-v2-4QOOHH4V-DeEc0lGZ.js +0 -1
- package/out/web/assets/studio-B1mk40wD.js +0 -1
- package/out/web/assets/swimlanes-XN3QIQJK-igYhTjXB.js +0 -1
- package/out/web/assets/swimlanesDiagram-VK2B7HYN-DpVik9v7.js +0 -8
- package/out/web/assets/timeline-definition-24CTP7MA-Dke2p93p.js +0 -120
- package/out/web/assets/treeView-Q6P3EWNA-hNELnXUs.js +0 -1
- package/out/web/assets/treemap-WGGIJYW6-D2B6wDsx.js +0 -1
- package/out/web/assets/vennDiagram-4TSXK5OY-CDkW7rUP.js +0 -34
- package/out/web/assets/wardley-WFR3VGLG-BECdXETi.js +0 -1
- package/out/web/assets/wardleyDiagram-VM6X3IG4-B5BycpQ4.js +0 -78
- package/out/web/assets/window-5qYXKoW7.js +0 -1
- package/out/web/assets/xychartDiagram-S5SC5T6Z-CtJS3b--.js +0 -7
- package/skills-lock.json +0 -77
- package/src/renderer/public/Live2DCubismCore.js +0 -9
- package/src/renderer/shared/components/AgentActivityDrawer.tsx +0 -203
- package/src/renderer/shared/components/AgentActivityTable.tsx +0 -301
- package/src/renderer/shared/components/ApprovalCard.tsx +0 -340
- package/src/renderer/shared/components/ArtifactPreviewPanel.tsx +0 -505
- package/src/renderer/shared/components/AuthGate.tsx +0 -191
- package/src/renderer/shared/components/CalculationCard.tsx +0 -100
- package/src/renderer/shared/components/ChatCodeBlock.tsx +0 -105
- package/src/renderer/shared/components/ChatMessageItem.tsx +0 -306
- package/src/renderer/shared/components/ChatPanel.tsx +0 -2226
- package/src/renderer/shared/components/ChunkErrorBoundary.tsx +0 -284
- package/src/renderer/shared/components/CliSessionsView.tsx +0 -495
- package/src/renderer/shared/components/CodeReviewPage.tsx +0 -565
- package/src/renderer/shared/components/CommandPalette.tsx +0 -593
- package/src/renderer/shared/components/DashboardSidebar.tsx +0 -1341
- package/src/renderer/shared/components/DesktopTitlebar.tsx +0 -345
- package/src/renderer/shared/components/DiffReviewModal.tsx +0 -565
- package/src/renderer/shared/components/GeminiLiveOverlay.tsx +0 -128
- package/src/renderer/shared/components/GitBranchSelector.tsx +0 -442
- package/src/renderer/shared/components/ImageGenCard.tsx +0 -159
- package/src/renderer/shared/components/ImageSearchCard.tsx +0 -168
- package/src/renderer/shared/components/ImageStudioPanel.tsx +0 -739
- package/src/renderer/shared/components/InlineThoughtNote.tsx +0 -27
- package/src/renderer/shared/components/LinkedFoldersView.tsx +0 -614
- package/src/renderer/shared/components/McpRegistryPicker.tsx +0 -302
- package/src/renderer/shared/components/McpServersView.tsx +0 -952
- package/src/renderer/shared/components/McpToolAllowlist.tsx +0 -184
- package/src/renderer/shared/components/MermaidCard.tsx +0 -267
- package/src/renderer/shared/components/MintDashboard.tsx +0 -2665
- package/src/renderer/shared/components/ModalErrorBoundary.tsx +0 -127
- package/src/renderer/shared/components/ModelSelectorPopover.tsx +0 -929
- package/src/renderer/shared/components/PlanChecklistWidget.tsx +0 -77
- package/src/renderer/shared/components/PluginsView.tsx +0 -325
- package/src/renderer/shared/components/RewindModal.tsx +0 -421
- package/src/renderer/shared/components/RunSummaryDashboard.tsx +0 -149
- package/src/renderer/shared/components/ScheduledTasksView.tsx +0 -613
- package/src/renderer/shared/components/SkillsView.tsx +0 -347
- package/src/renderer/shared/components/SlashSuggestions.tsx +0 -318
- package/src/renderer/shared/components/SourcesBlock.tsx +0 -450
- package/src/renderer/shared/components/StockCard.tsx +0 -168
- package/src/renderer/shared/components/SubagentDagView.tsx +0 -366
- package/src/renderer/shared/components/TerminalDock.tsx +0 -241
- package/src/renderer/shared/components/ThinkingBlock.tsx +0 -102
- package/src/renderer/shared/components/ToolSurfacePage.tsx +0 -520
- package/src/renderer/shared/components/UiFeatureCard.tsx +0 -267
- package/src/renderer/shared/components/UiGridCard.tsx +0 -188
- package/src/renderer/shared/components/VeoStudioPanel.tsx +0 -707
- package/src/renderer/shared/components/WeatherCard.tsx +0 -224
- package/src/renderer/shared/components/WorkspaceContextPopover.tsx +0 -133
- package/src/renderer/shared/components/WorkspaceSelector.tsx +0 -149
- package/src/renderer/src/companionWidget.ts +0 -95
- package/src/renderer/src/components/CalculationCard.tsx +0 -3
- package/src/renderer/src/components/ImageGenCard.tsx +0 -2
- package/src/renderer/src/components/ImageSearchCard.tsx +0 -2
- package/src/renderer/src/components/Live2DStage.tsx +0 -412
- package/src/renderer/src/components/MermaidCard.tsx +0 -1
- package/src/renderer/src/components/ModelPanel.tsx +0 -155
- package/src/renderer/src/components/PicturesLibrary.tsx +0 -288
- package/src/renderer/src/components/Settings/AgentsTab.tsx +0 -4
- package/src/renderer/src/components/Settings/AudioTab.tsx +0 -3
- package/src/renderer/src/components/Settings/AutomationTab.tsx +0 -3
- package/src/renderer/src/components/Settings/GeneralTab.tsx +0 -3
- package/src/renderer/src/components/Settings/MemoryTab.tsx +0 -3
- package/src/renderer/src/components/Settings/PluginsTab.tsx +0 -3
- package/src/renderer/src/components/Settings/ProfileTab.tsx +0 -3
- package/src/renderer/src/components/Settings/ShortcutsTab.tsx +0 -3
- package/src/renderer/src/components/Settings/ThemeTab.tsx +0 -3
- package/src/renderer/src/components/StockCard.tsx +0 -3
- package/src/renderer/src/components/WeatherCard.tsx +0 -3
- package/src/renderer/src/css/model.css +0 -628
- package/src/renderer/src/css/pictures.css +0 -415
- package/src/renderer/src/css/settings/base.css +0 -1263
- package/src/renderer/src-web/companionWidget.ts +0 -37
- package/src/renderer/src-web/components/ModelPanel.tsx +0 -12
- package/src/renderer/src-web/components/PicturesLibrary.tsx +0 -285
- package/src/renderer/src-web/components/Settings/AgentsTab.tsx +0 -4
- package/src/renderer/src-web/components/Settings/AudioTab.tsx +0 -3
- package/src/renderer/src-web/components/Settings/AutomationTab.tsx +0 -3
- package/src/renderer/src-web/components/Settings/GeneralTab.tsx +0 -3
- package/src/renderer/src-web/components/Settings/MemoryTab.tsx +0 -3
- package/src/renderer/src-web/components/Settings/PluginsTab.tsx +0 -3
- package/src/renderer/src-web/components/Settings/ProfileTab.tsx +0 -3
- package/src/renderer/src-web/components/Settings/ShortcutsTab.tsx +0 -3
- package/src/renderer/src-web/components/Settings/ThemeTab.tsx +0 -3
- package/src/renderer/src-web/css/model.css +0 -628
- package/src/renderer/src-web/css/pictures.css +0 -462
- package/src/renderer/src-web/css/settings/base.css +0 -1263
- package/src/renderer/src-web/css/spotlight.css +0 -102
- package/src/renderer/src-web/css/widget.css +0 -213
- /package/src/renderer/shared/components/{UiMockupWidget.tsx → cards/UiMockupWidget.tsx} +0 -0
- /package/src/renderer/shared/components/{ScreenCaptureDialog.css → studio/ScreenCaptureDialog.css} +0 -0
- /package/src/renderer/shared/components/{ScreenCaptureDialog.tsx → studio/ScreenCaptureDialog.tsx} +0 -0
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import React, { useState } from 'react'
|
|
2
|
+
import { createRoot } from 'react-dom/client'
|
|
3
|
+
import ToolSurfacePage from '../shared/components/workspace/ToolSurfacePage'
|
|
4
|
+
import ToolsPanelToggle from '../shared/components/workspace/ToolsPanelToggle'
|
|
5
|
+
import { useSessionSources } from '../shared/utils/useSessionSources'
|
|
6
|
+
import SessionSources from '../shared/components/workspace/SessionSources'
|
|
7
|
+
import { installRendererPlatform, installWorkspacePlatform, type RendererAdapter, type WorkspacePlatform } from '../shared/platform'
|
|
8
|
+
import type { ConversationSources } from '../shared/types'
|
|
9
|
+
import { sourceAttachments } from '../shared/utils/sourceAttachments'
|
|
10
|
+
import '../src/css/desktop-tools.css'
|
|
11
|
+
|
|
12
|
+
const canvas = document.createElement('canvas'); canvas.width = 640; canvas.height = 400
|
|
13
|
+
const context = canvas.getContext('2d')!; context.fillStyle = '#256853'; context.fillRect(0, 0, 640, 400); context.fillStyle = '#dcfce7'; context.font = '36px sans-serif'; context.fillText('Test image', 200, 210)
|
|
14
|
+
const originalImage = canvas.toDataURL('image/png')
|
|
15
|
+
const preview = await sourceAttachments({ imageAttachments: [{ name: 'reference.png', dataUri: originalImage }] })
|
|
16
|
+
const data: ConversationSources = {
|
|
17
|
+
attachments: [
|
|
18
|
+
{ ...preview[0], id: 1, interactionId: 2, libraryItemId: 'reference-item' },
|
|
19
|
+
...['Math-Data-Science-Exam.pdf', '01_slr_model_assumptions.md', '02_least_squares_estimation.md', '03_coefficient_accuracy.md', '04_r_squared_rse.md', '05_statistic.md'].map((name, index) => ({ id: index + 2, interactionId: 4 + index, name, kind: 'file' as const, mimeType: name.endsWith('.pdf') ? 'application/pdf' : 'text/markdown', thumbnailDataUri: null })),
|
|
20
|
+
],
|
|
21
|
+
webSearchProgress: [{ type: 'ToolEnd', data: { action: 'web_search', input: { query: 'linear regression' }, result: '1. Linear regression reference\nURL: https://example.com/regression\nReference material\n\n2. Least squares guide\nURL: https://docs.example.com/least-squares\nA guide' } }],
|
|
22
|
+
}
|
|
23
|
+
let fail = false
|
|
24
|
+
let deferA = false
|
|
25
|
+
let resolveA: ((value: ConversationSources) => void) | null = null
|
|
26
|
+
installRendererPlatform({ getConversationSources: async (chatId: string) => {
|
|
27
|
+
if (fail) throw new Error('Offline')
|
|
28
|
+
if (chatId === 'A' && deferA) return new Promise<ConversationSources>(resolve => { resolveA = resolve })
|
|
29
|
+
return chatId === 'A' ? data : { attachments: [], webSearchProgress: [] }
|
|
30
|
+
} } as unknown as RendererAdapter)
|
|
31
|
+
installWorkspacePlatform({ getGitBranchInfo: async () => ({ isRepository: true, currentBranch: 'Rust', isDirty: true, branches: [], remoteBranches: [], detachedHead: null }) } as unknown as WorkspacePlatform)
|
|
32
|
+
|
|
33
|
+
function Fixture() {
|
|
34
|
+
const [chatId, setChatId] = useState('A')
|
|
35
|
+
const [open, setOpen] = useState(false)
|
|
36
|
+
const [selected, setSelected] = useState(false)
|
|
37
|
+
const session = useSessionSources(chatId, [], open)
|
|
38
|
+
const noop = () => {}
|
|
39
|
+
const close = () => { setOpen(false); requestAnimationFrame(() => document.querySelector<HTMLButtonElement>('.tools-panel-toggle')?.focus()) }
|
|
40
|
+
const desktop = location.pathname.includes('sessionSources')
|
|
41
|
+
|
|
42
|
+
return <>
|
|
43
|
+
<style>{`*{box-sizing:border-box}html,body,#root{width:100%;height:100%;overflow:hidden}.assistant-workspace{flex:1;min-width:0}body{margin:0;background:#111113;color:#e8eaed;font-family:Arial,sans-serif;--text-main:#e8eaed;--text-secondary:#c5cad1;--text-muted:#8b939f;--bg-overlay:#111113;--surface-strong:#25262b;--border:#33353b;--accent:#7edbb5;--border-subtle:#27292d;--bg-surface-soft:#1a1b20;--bg-surface-hover:#22242a}.fixture-bar{display:flex;align-items:center;justify-content:flex-end;gap:12px;height:50px;padding:8px 16px;border-bottom:1px solid #33353b}#qa-results{position:fixed;bottom:6px;left:8px;max-width:calc(100vw - 16px);font-size:10px;white-space:pre-wrap;pointer-events:none}`}</style>
|
|
44
|
+
<header className="fixture-bar"><span>Session sources fixture</span><button id="switch-chat" onClick={() => setChatId(id => id === 'A' ? 'B' : 'A')}>Switch session</button><ToolsPanelToggle open={open} count={0} onToggle={() => setOpen(v => !v)} /></header>
|
|
45
|
+
<div className={`app-body ${open ? 'tool-surface-active' : ''}`} style={{ position: 'relative', height: 'calc(100dvh - 50px)', display: 'flex' }}>
|
|
46
|
+
<main className="assistant-workspace"><h1>Conversation</h1><textarea aria-label="Message" defaultValue="Keep my draft" /></main>
|
|
47
|
+
{open && <ToolSurfacePage surfaces={selected ? [{ id: 'sources', kind: 'sources', title: 'Sources' }] : []} activeSurfaceId={selected ? 'sources' : null} terminalSize={440} desktopTools={desktop}
|
|
48
|
+
sourceCount={session.sources.length} onOpenSources={() => setSelected(true)}
|
|
49
|
+
sourcesContent={<SessionSources key={chatId} {...session} onRetry={session.retry} onOpenLibrary={url => { window.history.pushState({}, '', url); window.dispatchEvent(new PopStateEvent('popstate')); close() }} />}
|
|
50
|
+
onSelect={noop} onClose={() => setSelected(false)} onCloseAll={() => setSelected(false)} onDuplicate={noop} onRename={noop} onCloseOthers={noop} onResizeTerminal={noop} onResizePanel={noop}
|
|
51
|
+
onOpenTerminal={noop} onOpenBrowser={noop} onOpenReview={noop} onOpenFiles={noop} onOpenMods={noop} onOpenBackgroundTasks={noop} onModsPanelTarget={noop} onBackgroundPanelTarget={noop} onClosePanel={close} />}
|
|
52
|
+
</div>
|
|
53
|
+
<pre id="qa-results">Running…</pre>
|
|
54
|
+
</>
|
|
55
|
+
}
|
|
56
|
+
createRoot(document.getElementById('root')!).render(<Fixture />)
|
|
57
|
+
const delay = (ms = 50) => new Promise(resolve => setTimeout(resolve, ms))
|
|
58
|
+
async function waitFor(check: () => boolean, name: string) { for (let i = 0; i < 100; i++) { if (check()) return; await delay() } throw new Error(name) }
|
|
59
|
+
const results: string[] = []
|
|
60
|
+
const check = (condition: unknown, name: string) => { if (!condition) throw new Error(name); results.push(`PASS ${name}`) }
|
|
61
|
+
function click(selector: string) { const target = document.querySelector<HTMLElement>(selector); if (!target) throw new Error(`Missing ${selector}`); target.click() }
|
|
62
|
+
async function run() {
|
|
63
|
+
await waitFor(() => Boolean(document.querySelector('.tools-panel-toggle')), 'Tools trigger')
|
|
64
|
+
check(!document.querySelector('.session-sources-toggle'), 'standalone Sources button is removed')
|
|
65
|
+
click('.tools-panel-toggle')
|
|
66
|
+
await waitFor(() => document.querySelector('[aria-label="9 session sources"]'), 'Sources count')
|
|
67
|
+
check(true, 'Tools launcher shows the current session source count')
|
|
68
|
+
click('[title="Session sources"]')
|
|
69
|
+
await waitFor(() => Boolean(document.querySelector('.session-source-row')), 'Saved sources')
|
|
70
|
+
check(document.querySelectorAll('.session-source-row').length === 9, 'all session sources are visible without expanding')
|
|
71
|
+
check(document.querySelector<HTMLAnchorElement>('.session-source-row[href^="/library"]')?.getAttribute('href') === '/library?item=reference-item', 'source image links to its Library original')
|
|
72
|
+
check(document.querySelector('.session-source-icon img'), 'sent image has a thumbnail')
|
|
73
|
+
check(preview[0].name === 'reference.png' && (preview[0].thumbnailDataUri?.length || 0) < 262144, 'thumbnail generation preserves name and bounds payload size')
|
|
74
|
+
check(document.querySelector('.session-sources')?.textContent?.includes('Math-Data-Science-Exam.pdf'), 'sent document appears with filename')
|
|
75
|
+
if (location.search.includes('preview')) { document.getElementById('qa-results')!.textContent = ''; return }
|
|
76
|
+
check(!document.querySelector('.session-sources-more'), 'Sources does not hide items behind Show more')
|
|
77
|
+
check([...document.querySelectorAll('.session-sources-group h3')].map(el => el.textContent).join('|') === 'Images1|Files6|Web searches2', 'group headings show their counts')
|
|
78
|
+
const search = document.querySelector<HTMLInputElement>('[aria-label="Search Sources"]')!
|
|
79
|
+
check(search, 'larger source collections offer search')
|
|
80
|
+
const enterSearch = async (value: string) => {
|
|
81
|
+
Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value')!.set!.call(search, value)
|
|
82
|
+
search.dispatchEvent(new Event('input', { bubbles: true }))
|
|
83
|
+
await delay()
|
|
84
|
+
}
|
|
85
|
+
await enterSearch('LEAST_SQUARES')
|
|
86
|
+
check(document.querySelectorAll('.session-source-row').length === 1 && document.querySelector('.session-source-row')?.textContent?.includes('02_least_squares'), 'search filters names without case sensitivity')
|
|
87
|
+
await enterSearch('docs.example.com')
|
|
88
|
+
check(document.querySelectorAll('.session-source-row').length === 1, 'search filters domains')
|
|
89
|
+
await enterSearch('no-such-source')
|
|
90
|
+
check(document.querySelector('.session-sources-empty')?.textContent?.includes('No sources match'), 'unmatched search explains its empty result')
|
|
91
|
+
await enterSearch('')
|
|
92
|
+
check(document.querySelectorAll('.session-source-row').length === 9, 'clearing search restores every source')
|
|
93
|
+
const titleStyle = getComputedStyle(document.querySelector('.session-source-copy strong')!)
|
|
94
|
+
check(titleStyle.webkitLineClamp === '2' && titleStyle.whiteSpace === 'normal', 'source titles allow two lines')
|
|
95
|
+
check(document.querySelector<HTMLAnchorElement>('.session-source-row[href^="https:"]')?.href === 'https://example.com/regression', 'historical web searches link to source pages')
|
|
96
|
+
document.getAnimations().forEach(animation => animation.finish())
|
|
97
|
+
await delay()
|
|
98
|
+
check(document.documentElement.scrollWidth <= innerWidth, 'Tools does not overflow the page')
|
|
99
|
+
const popover = document.querySelector<HTMLElement>('.tool-surface-sources')!
|
|
100
|
+
check(popover.getBoundingClientRect().right <= innerWidth && popover.getBoundingClientRect().left >= 0, 'Sources tool fits viewport')
|
|
101
|
+
check(getComputedStyle(popover).overflowY === 'auto', 'Sources tool can scroll')
|
|
102
|
+
fail = true; await waitFor(() => Boolean(document.querySelector('.session-sources-error')), 'Error state')
|
|
103
|
+
check(document.querySelectorAll('.session-source-row').length === 9, 'refresh error preserves known sources')
|
|
104
|
+
fail = false; click('.session-sources-error button'); await waitFor(() => !document.querySelector('.session-sources-error'), 'Retry')
|
|
105
|
+
check(true, 'retry recovers')
|
|
106
|
+
deferA = true; click('.tools-panel-toggle'); await delay(); click('.tools-panel-toggle'); await waitFor(() => Boolean(resolveA), 'Pending A request')
|
|
107
|
+
click('#switch-chat'); await waitFor(() => Boolean(document.querySelector('.session-sources-empty')), 'Empty B')
|
|
108
|
+
resolveA!(data); await delay()
|
|
109
|
+
check(document.querySelectorAll('.session-source-row').length === 0, 'late response cannot leak another session sources')
|
|
110
|
+
check(document.querySelector('.session-sources-empty')?.textContent?.includes('Images and files you send'), 'empty session explains what appears here')
|
|
111
|
+
deferA=false;click('#switch-chat')
|
|
112
|
+
await waitFor(()=>Boolean(document.querySelector('.session-source-row[href^="/library"]')),'Sources for internal navigation')
|
|
113
|
+
let navigated=false
|
|
114
|
+
const navigation=()=>{navigated=true}
|
|
115
|
+
window.addEventListener('popstate',navigation)
|
|
116
|
+
const libraryLink=document.querySelector<HTMLAnchorElement>('.session-source-row[href^="/library"]')!
|
|
117
|
+
const clickEvent=new MouseEvent('click',{bubbles:true,cancelable:true,button:0})
|
|
118
|
+
let preventedByComponent=false
|
|
119
|
+
const suppressReload=(event:MouseEvent)=>{preventedByComponent=event.defaultPrevented;event.preventDefault()}
|
|
120
|
+
document.addEventListener('click',suppressReload)
|
|
121
|
+
libraryLink.dispatchEvent(clickEvent)
|
|
122
|
+
document.removeEventListener('click',suppressReload)
|
|
123
|
+
check(preventedByComponent && navigated, 'Library source navigation preserves the live application and composer')
|
|
124
|
+
window.removeEventListener('popstate',navigation)
|
|
125
|
+
await waitFor(()=>!document.querySelector('.tool-surface-page'),'Source navigation closes Tools')
|
|
126
|
+
check(document.querySelector<HTMLTextAreaElement>('textarea')?.value === 'Keep my draft', 'Library navigation preserves the draft')
|
|
127
|
+
click('.tools-panel-toggle'); await waitFor(() => Boolean(document.querySelector('.tool-surface-sources')), 'Sources reopens')
|
|
128
|
+
document.querySelector<HTMLButtonElement>('[role="tab"]')!.focus()
|
|
129
|
+
document.activeElement!.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape', bubbles: true }))
|
|
130
|
+
await waitFor(() => !document.querySelector('.tool-surface-page'), 'Escape closes Sources tool')
|
|
131
|
+
await waitFor(() => document.activeElement === document.querySelector('.tools-panel-toggle'), 'Escape restores focus to Tools')
|
|
132
|
+
check(true, 'Escape restores focus to Tools')
|
|
133
|
+
const iconFixture = document.createElement('div')
|
|
134
|
+
document.body.append(iconFixture)
|
|
135
|
+
const iconRoot = createRoot(iconFixture)
|
|
136
|
+
iconRoot.render(<SessionSources sources={[
|
|
137
|
+
{ id: 'web-good', kind: 'web', name: 'Website with icon', detail: 'example.com', url: 'https://example.com/with-icon', faviconUrl: originalImage },
|
|
138
|
+
{ id: 'web-broken', kind: 'web', name: 'Website without icon', detail: 'other.example', url: 'https://other.example/no-icon', faviconUrl: 'data:image/png;base64,AA==' },
|
|
139
|
+
{ id: 'image-thumbnail', kind: 'image', name: 'reference.png', detail: 'Image', thumbnailDataUri: originalImage },
|
|
140
|
+
]} loading={false} error="" onRetry={() => {}} onOpenLibrary={() => {}} />)
|
|
141
|
+
await waitFor(() => Boolean(iconFixture.querySelector<HTMLImageElement>('.is-web img')?.naturalWidth), 'Website favicon loads')
|
|
142
|
+
const favicon = iconFixture.querySelector<HTMLImageElement>('.is-web img')!
|
|
143
|
+
check(favicon.width === 20 && favicon.height === 20, 'website favicon fits its existing icon slot')
|
|
144
|
+
check(favicon.referrerPolicy === 'no-referrer', 'favicon request omits the chat page referrer')
|
|
145
|
+
await waitFor(() => Boolean(iconFixture.querySelector('[href="https://other.example/no-icon"] .is-web svg')), 'Unavailable favicon falls back')
|
|
146
|
+
check(!iconFixture.querySelector('[href="https://other.example/no-icon"] img'), 'failed favicon uses the globe instead of a broken image')
|
|
147
|
+
check(iconFixture.querySelector<HTMLImageElement>('.is-image img')?.width === 30, 'attachment thumbnails retain their existing size')
|
|
148
|
+
favicon.dispatchEvent(new Event('error'))
|
|
149
|
+
await waitFor(() => Boolean(iconFixture.querySelector('[href="https://example.com/with-icon"] .is-web svg')), 'Late favicon failure falls back')
|
|
150
|
+
check(Boolean(iconFixture.querySelector('[href="https://example.com/with-icon"]')), 'favicon failure preserves the source link')
|
|
151
|
+
iconRoot.unmount(); iconFixture.remove()
|
|
152
|
+
let openedArtifact: any = null
|
|
153
|
+
const artifactFixture = document.createElement('div')
|
|
154
|
+
document.body.append(artifactFixture)
|
|
155
|
+
const artifactRoot = createRoot(artifactFixture)
|
|
156
|
+
artifactRoot.render(<SessionSources sources={[
|
|
157
|
+
{ id: 'img-1', kind: 'image', name: 'photo.png', detail: 'Image', thumbnailDataUri: originalImage },
|
|
158
|
+
]} loading={false} error="" onRetry={() => {}} onOpenLibrary={() => {}} onOpenArtifact={art => { openedArtifact = art }} />)
|
|
159
|
+
await waitFor(() => Boolean(artifactFixture.querySelector('.session-source-row')), 'Image row ready')
|
|
160
|
+
const imgRow = artifactFixture.querySelector<HTMLAnchorElement>('.session-source-row')!
|
|
161
|
+
check(imgRow.getAttribute('title')?.includes('Open image preview in Tools'), 'image source row indicates tool preview')
|
|
162
|
+
imgRow.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true, button: 0 }))
|
|
163
|
+
await waitFor(() => Boolean(openedArtifact), 'Image opens via onOpenArtifact')
|
|
164
|
+
check(openedArtifact?.type === 'image' && openedArtifact?.path === 'sources/img-1/photo.png', 'image opens as artifact preview')
|
|
165
|
+
artifactRoot.unmount(); artifactFixture.remove()
|
|
166
|
+
document.getElementById('qa-results')!.textContent = results.join('\n') + '\nALL PASSED'
|
|
167
|
+
}
|
|
168
|
+
run().catch(error => { document.getElementById('qa-results')!.textContent = results.join('\n') + `\nFAIL ${error.message}` })
|
|
@@ -0,0 +1,24 @@
|
|
|
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:24px;background:#121212;color:#eee;font-family:Arial,sans-serif}pre{white-space:pre-wrap}</style></head>
|
|
4
|
+
<body><div id="root"></div><pre id="result">RUNNING</pre>
|
|
5
|
+
<script type="module">
|
|
6
|
+
import React from 'react';
|
|
7
|
+
import {createRoot} from 'react-dom/client';
|
|
8
|
+
import {AgentActivityTable} from '/shared/components/AgentActivityTable.tsx';
|
|
9
|
+
import {activitiesFrom} from '/shared/utils/agentActivity.ts';
|
|
10
|
+
const root=createRoot(document.getElementById('root'));
|
|
11
|
+
const input={path:'/repo/.agents/skills/review/SKILL.md',skill_name:'review'};
|
|
12
|
+
const start={type:'ToolStart',data:{action:'read_file',input}};
|
|
13
|
+
const end=result=>({type:'ToolEnd',data:{action:'read_file',input,result}});
|
|
14
|
+
async function render(events){root.render(React.createElement(AgentActivityTable,{activityView:activitiesFrom(events)}));await new Promise(resolve=>setTimeout(resolve,50));}
|
|
15
|
+
function check(text){if(!document.getElementById('root').textContent.includes(text))throw Error(`Missing ${text}`)}
|
|
16
|
+
try {
|
|
17
|
+
await render([start]);check('Reading skill: review');
|
|
18
|
+
await render([start,end('[Loaded skill: review]\nReview the changed files.')]);check('Loaded skill: review');
|
|
19
|
+
await render([start,end('Error: denied')]);check('Failed to read skill: review');
|
|
20
|
+
await render([start,end('1 | header only')]);check('Read skill preview: review');
|
|
21
|
+
await render([start,end('[Loaded skill: review]\nReview the changed files.')]);
|
|
22
|
+
document.getElementById('result').textContent='PASS: rendered reading, loaded, failed, and preview states';
|
|
23
|
+
} catch(error){document.getElementById('result').textContent='FAIL: '+error.stack;}
|
|
24
|
+
</script></body></html>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<!doctype html><html><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1"></head><body><div id="root"></div><script type="module" src="./toolsPanel.browser.tsx"></script></body></html>
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import React, { useState } from 'react'
|
|
2
|
+
import { createRoot } from 'react-dom/client'
|
|
3
|
+
import ToolSurfacePage, { type ToolSurface } from '../shared/components/workspace/ToolSurfacePage'
|
|
4
|
+
import ToolsPanelToggle from '../shared/components/workspace/ToolsPanelToggle'
|
|
5
|
+
import { ModsPanel } from '../shared/components/extensions/ModsPanel'
|
|
6
|
+
import { BackgroundTerminals } from '../shared/components/workspace/BackgroundTerminals'
|
|
7
|
+
import { installRendererPlatform, type RendererAdapter } from '../shared/platform'
|
|
8
|
+
import type { BackgroundJob } from '../shared/types'
|
|
9
|
+
|
|
10
|
+
// Isolated browser fixture: only the external runtime boundary is replaced.
|
|
11
|
+
const job: BackgroundJob = { id: 'job-1', command: 'npm run dev', cwd: '/workspace/alpha', workspacePath: '/workspace/alpha', chatId: 'chat-a', pid: 10, status: 'running', exitCode: null, error: null, startedAt: 0, endedAt: null, elapsedSeconds: 12, serverUrl: null }
|
|
12
|
+
const other = { ...job, id: 'job-2', workspacePath: '/workspace/beta', cwd: '/workspace/beta' }
|
|
13
|
+
let jobs = [job, other]
|
|
14
|
+
let failJobs = false
|
|
15
|
+
let modCloses = 0
|
|
16
|
+
let listCalls = 0
|
|
17
|
+
let outputCalls = 0
|
|
18
|
+
let stopCalls = 0
|
|
19
|
+
const enabledMod = { id: 'weather', name: 'Weather', enabled: true, hash: 'rev-1', activeHash: 'rev-1', revisions: ['rev-1'], manifest: { version: '1.0.0', permissions: [] }, snapshot: { ui: { above_composer: { type: 'text', text: 'Weather band' } } } }
|
|
20
|
+
let mods = [enabledMod]
|
|
21
|
+
installRendererPlatform({
|
|
22
|
+
isTauriRuntime: () => false,
|
|
23
|
+
listBackgroundJobs: async (workspace?: string) => { listCalls++; if (failJobs) throw new Error('offline'); return workspace ? jobs.filter(j => j.workspacePath === workspace) : [...jobs] },
|
|
24
|
+
getBackgroundJob: async (id: string) => { outputCalls++; return { ...jobs.find(j => j.id === id), stdout: 'Server ready', stderr: '', truncated: false } },
|
|
25
|
+
stopBackgroundJob: async (id: string) => { stopCalls++; jobs = jobs.map(j => j.id === id ? { ...j, status: 'stopped', exitCode: 0 } : j); return jobs.find(j => j.id === id) },
|
|
26
|
+
deleteBackgroundJob: async (id: string) => { jobs = jobs.filter(j => j.id !== id) },
|
|
27
|
+
modsOperation: async (op: { action: string; workspacePath: string }) => {
|
|
28
|
+
if (op.action === 'close') modCloses++
|
|
29
|
+
return { mods: op.workspacePath.endsWith('alpha') ? mods : [], session: { hotReload: false } }
|
|
30
|
+
},
|
|
31
|
+
} as unknown as RendererAdapter)
|
|
32
|
+
|
|
33
|
+
function Fixture() {
|
|
34
|
+
const [open, setOpen] = useState(false)
|
|
35
|
+
const [surfaces, setSurfaces] = useState<ToolSurface[]>([])
|
|
36
|
+
const [active, setActive] = useState<string | null>(null)
|
|
37
|
+
const [workspace, setWorkspace] = useState('/workspace/alpha')
|
|
38
|
+
const [count, setCount] = useState(0)
|
|
39
|
+
const [modsTarget, setModsTarget] = useState<HTMLDivElement | null>(null)
|
|
40
|
+
const [tasksTarget, setTasksTarget] = useState<HTMLDivElement | null>(null)
|
|
41
|
+
const desktop = new URLSearchParams(location.search).has('desktop')
|
|
42
|
+
const utility = (kind: 'mods' | 'background') => {
|
|
43
|
+
setOpen(true); setActive(kind)
|
|
44
|
+
setSurfaces(previous => previous.some(s => s.id === kind) ? previous : [...previous, { id: kind, kind, title: kind === 'mods' ? 'Mods' : 'Background tasks' }])
|
|
45
|
+
}
|
|
46
|
+
const noop = () => {}
|
|
47
|
+
return <>
|
|
48
|
+
<style>{`*{box-sizing:border-box}body{margin:0;font-family:Arial,sans-serif;--text-main:#e7ece9;--text-muted:#9aa5a0;--bg-surface:#181c1a;--panel-bg:#181c1a;--surface-bg:#222824;--surface-strong:#2c342e;--border:#38413b;--accent:#7edbb5;--accent-subtle:#253e32;background:#111613;color:var(--text-main)}.app-body{position:relative;height:calc(100dvh - 50px);display:flex}.assistant-workspace{flex:1;padding:24px;min-width:0}.fixture-header{height:50px;display:flex;align-items:center;gap:12px;padding:8px 16px}.fixture-composer{margin-top:60px}#qa-results{position:fixed;bottom:0;left:0;z-index:1000;max-width:45vw;font-size:10px;white-space:pre-wrap;pointer-events:none}`}</style>
|
|
49
|
+
<header className="fixture-header"><span>Mint Tools fixture</span><ToolsPanelToggle open={open} count={count} onToggle={() => setOpen(v => !v)} className={desktop ? 'mint-titlebar-icon-button' : ''} /><button id="switch-workspace" onClick={() => setWorkspace(w => w.endsWith('alpha') ? '/workspace/beta' : '/workspace/alpha')}>Switch workspace</button></header>
|
|
50
|
+
<div className={`app-body ${open ? 'tool-surface-active' : ''}`} style={{ '--tool-surface-width': '440px' } as React.CSSProperties}>
|
|
51
|
+
<main className="assistant-workspace"><h1>Conversation</h1><p>{workspace}</p><div className="fixture-composer"><ModsPanel workspacePath={workspace} chatId="chat-a" panelTarget={modsTarget} onOpen={() => utility('mods')} /><textarea aria-label="Message" placeholder="Ask Mint…" /></div></main>
|
|
52
|
+
{open && <ToolSurfacePage surfaces={surfaces} activeSurfaceId={active} workspacePath={workspace} terminalSize={440} desktopTools={desktop} backgroundTaskCount={count}
|
|
53
|
+
onSelect={setActive} onClose={id => { setSurfaces(s => s.filter(v => v.id !== id)); setActive(null) }} onCloseAll={noop} onDuplicate={noop} onRename={noop} onCloseOthers={noop} onResizeTerminal={noop} onResizePanel={noop}
|
|
54
|
+
onOpenSources={noop} onOpenTerminal={noop} onOpenBrowser={noop} onOpenReview={noop} onOpenFiles={noop} onOpenMods={() => utility('mods')} onOpenBackgroundTasks={() => utility('background')} onModsPanelTarget={setModsTarget} onBackgroundPanelTarget={setTasksTarget} onClosePanel={() => setOpen(false)} />}
|
|
55
|
+
<BackgroundTerminals workspacePath={workspace} panelTarget={tasksTarget} onCountChange={setCount} />
|
|
56
|
+
</div>
|
|
57
|
+
<pre id="qa-results">Running…</pre>
|
|
58
|
+
</>
|
|
59
|
+
}
|
|
60
|
+
createRoot(document.getElementById('root')!).render(<Fixture />)
|
|
61
|
+
|
|
62
|
+
const delay = (ms = 50) => new Promise(resolve => setTimeout(resolve, ms))
|
|
63
|
+
async function waitFor(check: () => boolean, label: string) {
|
|
64
|
+
for (let n = 0; n < 100; n++) { if (check()) return; await delay() }
|
|
65
|
+
throw new Error(label)
|
|
66
|
+
}
|
|
67
|
+
function click(selector: string) { const target = document.querySelector<HTMLElement>(selector); if (!target) throw new Error(`Missing ${selector}`); target.click() }
|
|
68
|
+
const results: string[] = []
|
|
69
|
+
const check = (condition: unknown, name: string) => { if (!condition) throw new Error(name); results.push(`PASS ${name}`) }
|
|
70
|
+
async function run() {
|
|
71
|
+
await waitFor(() => Boolean(document.querySelector('.tools-task-count')), 'Initial task count')
|
|
72
|
+
check(document.querySelector('.tools-task-count')?.textContent === '1', 'badge counts current workspace while Tools is closed')
|
|
73
|
+
check(document.body.textContent?.includes('Weather band'), 'mod band renders with Tools closed')
|
|
74
|
+
click('.tools-panel-toggle'); await delay()
|
|
75
|
+
click('[title="Background tasks"]'); await waitFor(() => Boolean(document.querySelector('.background-terminal-job')), 'Tasks panel')
|
|
76
|
+
check(document.querySelector('.tool-surface-page .background-terminal-panel'), 'tasks render inside Tools')
|
|
77
|
+
check(document.querySelectorAll('.background-terminal-job').length === 1, 'workspace filter excludes other jobs')
|
|
78
|
+
click('.background-terminal-actions button'); await waitFor(() => Boolean(document.querySelector('.background-terminal-log')?.textContent?.includes('Server ready')), 'Output')
|
|
79
|
+
check(outputCalls > 0, 'output loads on demand')
|
|
80
|
+
click('.background-terminal-stop'); await waitFor(() => stopCalls === 1 && !document.querySelector('.tools-panel-toggle .tools-task-count'), 'Stop and badge')
|
|
81
|
+
check(document.querySelector('.background-terminal-state')?.textContent === 'stopped', 'Stop updates job status and badge')
|
|
82
|
+
click('[aria-label="Close tools panel"]'); await delay()
|
|
83
|
+
const callsBefore = listCalls; await delay(1100)
|
|
84
|
+
check(listCalls > callsBefore, 'monitor keeps polling while Tools is closed')
|
|
85
|
+
check(modCloses === 0, 'closing Tools keeps mod session alive')
|
|
86
|
+
click('.tools-panel-toggle'); await delay()
|
|
87
|
+
click('[aria-label="Switch tool"]'); await delay(); click('[title="Workspace mods"]')
|
|
88
|
+
await waitFor(() => Boolean(document.querySelector('.mods-panel')), 'Mods panel')
|
|
89
|
+
check(document.querySelector('.tool-surface-page .mods-panel'), 'mods render inside Tools')
|
|
90
|
+
check(document.querySelector('.mods-panel')?.textContent?.includes('Weather'), 'installed mod appears in Tools')
|
|
91
|
+
check(document.body.textContent?.includes('Weather band'), 'mod band survives tab switching')
|
|
92
|
+
click('#switch-workspace'); await waitFor(() => Boolean(document.querySelector('.mods-empty')), 'New workspace mods')
|
|
93
|
+
check(!document.querySelector('.mods-panel')?.textContent?.includes('Weather'), 'workspace switch clears previous mods')
|
|
94
|
+
await waitFor(() => document.querySelector('.tools-panel-toggle .tools-task-count')?.textContent === '1', 'New workspace count')
|
|
95
|
+
check(true, 'workspace switch refreshes badge')
|
|
96
|
+
click('[role="tab"]'); await waitFor(() => Boolean(document.querySelector('.background-terminal-job')), 'Other workspace tasks')
|
|
97
|
+
check(document.querySelector('.background-terminal-job')?.textContent?.includes('job-2'), 'tasks follow workspace switch')
|
|
98
|
+
failJobs = true; await waitFor(() => Boolean(document.querySelector('.background-terminal-error')), 'Error state')
|
|
99
|
+
check(document.querySelector('.background-terminal-stop')?.hasAttribute('disabled'), 'connection failure disables Stop')
|
|
100
|
+
failJobs = false; await delay(1100)
|
|
101
|
+
check(!document.querySelector('.background-terminal-error'), 'polling recovers after connection failure')
|
|
102
|
+
// Measure the resting layout rather than an in-flight entrance transform.
|
|
103
|
+
document.getAnimations().forEach(animation => animation.finish())
|
|
104
|
+
await delay()
|
|
105
|
+
check(document.documentElement.scrollWidth <= innerWidth, 'no page horizontal overflow')
|
|
106
|
+
const filter = document.querySelector<HTMLInputElement>('.background-terminal-filter input')!
|
|
107
|
+
filter.focus()
|
|
108
|
+
filter.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape', bubbles: true }))
|
|
109
|
+
await delay()
|
|
110
|
+
check(!document.querySelector('.tool-surface-page'), 'Escape closes Tools from portalled task content')
|
|
111
|
+
document.getElementById('qa-results')!.textContent = results.join('\n') + '\nALL PASSED'
|
|
112
|
+
}
|
|
113
|
+
if (!location.search.includes('preview')) run().catch(error => { document.getElementById('qa-results')!.textContent = results.join('\n') + `\nFAIL ${error.message}` })
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<!doctype html><html data-theme="dark"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1"></head><body><div id="root"></div><script type="module" src="./viewedImages.browser.tsx"></script></body></html>
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import React, { useState } from 'react'
|
|
2
|
+
import { createRoot } from 'react-dom/client'
|
|
3
|
+
import ChatMessageItem from '../shared/components/chat/ChatMessageItem'
|
|
4
|
+
import { ProgressActivity } from '../shared/components/activity/AgentActivityDrawer'
|
|
5
|
+
import ViewedImages from '../shared/components/activity/ViewedImages'
|
|
6
|
+
import type { AgentProgress } from '../shared/types'
|
|
7
|
+
import { compactAgentProgressForPersistence, reduceLiveAgentProgress } from '../shared/agentProgress'
|
|
8
|
+
import '../shared/theme/tokens.css'
|
|
9
|
+
if (new URLSearchParams(location.search).get('platform') === 'desktop') {
|
|
10
|
+
await import('../src/css/app-shell.css'); await import('../src/css/chat.css')
|
|
11
|
+
} else {
|
|
12
|
+
await import('../src-web/css/app-shell.css'); await import('../src-web/css/chat.css')
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const canvas = document.createElement('canvas'); canvas.width = 960; canvas.height = 600
|
|
16
|
+
const context = canvas.getContext('2d')!
|
|
17
|
+
context.fillStyle = '#1b3534'; context.fillRect(0, 0, 960, 600)
|
|
18
|
+
context.fillStyle = '#8bd8c3'; context.fillRect(56, 56, 848, 100)
|
|
19
|
+
context.fillStyle = '#dce9e4'; context.font = '28px sans-serif'; context.fillText('view_image · screenshot.png', 56, 220)
|
|
20
|
+
context.strokeStyle = '#8bd8c3'; context.lineWidth = 3; context.strokeRect(56, 270, 390, 260); context.strokeRect(480, 270, 424, 260)
|
|
21
|
+
const image = canvas.toDataURL('image/png')
|
|
22
|
+
const svg = `data:image/svg+xml;base64,${btoa('<svg xmlns="http://www.w3.org/2000/svg" width="420" height="260"><rect width="420" height="260" fill="#21343b"/><circle cx="210" cy="130" r="80" fill="#91d6b5"/></svg>')}`
|
|
23
|
+
const input = { path: '/workspace/ภาพตัวอย่างที่มีชื่อไฟล์ยาวเพื่อทดสอบการแสดงผลบนโทรศัพท์มือถือ.png' }
|
|
24
|
+
const start: AgentProgress = { type: 'ToolStart', data: { action: 'view_image', input } }
|
|
25
|
+
const textActivity: AgentProgress = { type: 'ToolEnd', data: { action: 'read_file', input: {}, result: 'Read' } }
|
|
26
|
+
const finished: AgentProgress[] = [textActivity, textActivity, start,
|
|
27
|
+
{ type: 'ToolEnd', data: { action: 'view_image', input, result: `${image}\n\n[Hook] Viewed successfully` } },
|
|
28
|
+
{ type: 'ToolEnd', data: { callId: 'image-2', action: 'view_image', input: { path: '/workspace/diagram.svg' }, result: svg } },
|
|
29
|
+
]
|
|
30
|
+
const noop = () => {}
|
|
31
|
+
let continueRun = noop
|
|
32
|
+
function Fixture() {
|
|
33
|
+
const [done, setDone] = useState(false)
|
|
34
|
+
const [mode, setMode] = useState('live')
|
|
35
|
+
const [open, setOpen] = useState(true)
|
|
36
|
+
const [continued, setContinued] = useState(false)
|
|
37
|
+
continueRun = () => setContinued(true)
|
|
38
|
+
const progress = done ? continued ? Array.from({ length: 40 }, () => ({ ...textActivity })).reduce(reduceLiveAgentProgress, finished) : finished : [start]
|
|
39
|
+
return <>
|
|
40
|
+
<style>{`*{box-sizing:border-box}body{margin:0;padding:16px;background:#101112;color:var(--text-main);font-family:Arial,sans-serif}.fixture-controls{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:20px}.fixture-message{max-width:760px;margin:auto;min-width:0}#qa-results{white-space:pre-wrap;font-size:10px;overflow-wrap:anywhere}.message-bubble{width:100%}`}</style>
|
|
41
|
+
<div className="fixture-controls"><button id="finish" onClick={() => setDone(true)}>Finish view_image</button><button id="history" onClick={() => setMode('history')}>Reload saved history</button><button id="switch" onClick={() => setMode('other')}>Other conversation</button><button id="live" onClick={() => setMode('live')}>Live view</button></div>
|
|
42
|
+
<div className="fixture-message">
|
|
43
|
+
{mode === 'live' ? <><ProgressActivity progress={progress} id="live" isOpen={open} onToggle={() => setOpen(value => !value)} /><div className="message ai-message"><div className="bubble-wrapper"><div className="message-bubble"><ViewedImages progress={progress} /></div></div></div></>
|
|
44
|
+
: <ChatMessageItem interaction={{ id: mode === 'other' ? 8 : 7, status: 'completed', aiText: 'I have inspected the images.', userText: 'ช่วยดูรูปภาพนี้หน่อย', createdAt: '2026-10-16T05:00:00Z', agentActivity: mode === 'other' ? [] : JSON.parse(JSON.stringify(compactAgentProgressForPersistence(finished))) }} copiedId={null} speakingText={null} agentActivitySnapshots={{}} thinkingExpanded={{}} onThinkingExpandedChange={noop} handleCopyMessage={noop} speak={noop} toggleActivity={noop} renderFileChanges={() => null} />}
|
|
45
|
+
</div><pre id="qa-results">Running…</pre>
|
|
46
|
+
</>
|
|
47
|
+
}
|
|
48
|
+
createRoot(document.getElementById('root')!).render(<Fixture />)
|
|
49
|
+
const delay = (ms = 40) => new Promise(resolve => setTimeout(resolve, ms))
|
|
50
|
+
async function waitFor(check: () => boolean, name: string) { for (let i = 0; i < 120; i++) { if (check()) return; await delay() } throw new Error(name) }
|
|
51
|
+
const results: string[] = []
|
|
52
|
+
const check = (value: unknown, name: string) => { if (!value) throw new Error(name); results.push(`PASS ${name}`) }
|
|
53
|
+
const click = (selector: string) => { const element = document.querySelector<HTMLElement>(selector); if (!element) throw new Error(`Missing ${selector}`); element.focus(); element.click() }
|
|
54
|
+
async function run() {
|
|
55
|
+
await waitFor(() => Boolean(document.querySelector('.agent-activity-item')), 'Tool starts')
|
|
56
|
+
check(!document.querySelector('[data-viewed-image]'), 'no image appears before view_image completes')
|
|
57
|
+
click('#finish')
|
|
58
|
+
await waitFor(() => document.querySelectorAll('.viewed-image-button img').length === 2, 'Both results appear')
|
|
59
|
+
await waitFor(() => [...document.querySelectorAll<HTMLImageElement>('.viewed-image-button img')].every(img => img.naturalWidth > 0), 'PNG and SVG load')
|
|
60
|
+
// Capture final layout without depending on headless compositor animation timing.
|
|
61
|
+
document.getAnimations().forEach(animation => { if (animation.effect?.getTiming().iterations !== Infinity) animation.finish() })
|
|
62
|
+
check(getComputedStyle(document.querySelector('.message')!).opacity === '1', 'chat content is visibly rendered')
|
|
63
|
+
check(document.querySelector('.agent-activity-target-text')!.getBoundingClientRect().width > 40, 'view_image row keeps room for the file path')
|
|
64
|
+
check(document.documentElement.scrollWidth <= innerWidth, 'images and long filenames fit viewport')
|
|
65
|
+
click('.agent-activity-item')
|
|
66
|
+
await waitFor(() => Boolean(document.querySelector('.agent-activity-output')), 'Expanded tool output')
|
|
67
|
+
check(!document.querySelector('.agent-activity-output')?.textContent?.includes('data:image/'), 'tool output does not dump base64')
|
|
68
|
+
check(document.querySelector('.agent-activity-output')?.textContent?.includes('[Hook] Viewed successfully'), 'hook notes remain readable')
|
|
69
|
+
if (location.search.includes('preview')) { document.getElementById('qa-results')!.textContent = ''; return }
|
|
70
|
+
const trigger = document.querySelector<HTMLButtonElement>('.viewed-image-button')!
|
|
71
|
+
trigger.focus(); trigger.click()
|
|
72
|
+
await waitFor(() => Boolean(document.querySelector('dialog[open] img')), 'Expanded preview')
|
|
73
|
+
check(document.querySelector<HTMLImageElement>('dialog[open] img')?.naturalWidth === 960, 'expanded preview uses original pixels')
|
|
74
|
+
const rect = document.querySelector('dialog[open]')!.getBoundingClientRect()
|
|
75
|
+
check(rect.left >= 0 && rect.right <= innerWidth && rect.bottom <= innerHeight, 'expanded preview fits viewport')
|
|
76
|
+
const openedDialog = document.querySelector('dialog[open]')
|
|
77
|
+
continueRun(); await delay(100)
|
|
78
|
+
check(document.querySelector('dialog[open]') === openedDialog, 'preview stays open as older activity is trimmed during a run')
|
|
79
|
+
click('dialog[open] button')
|
|
80
|
+
await waitFor(() => !document.querySelector('dialog[open]'), 'Preview closes')
|
|
81
|
+
check(document.activeElement === trigger, 'closing preview restores keyboard focus')
|
|
82
|
+
click('#history')
|
|
83
|
+
await waitFor(() => Boolean(document.querySelector('.agent-activity-history')), 'Saved history mounts')
|
|
84
|
+
check(!document.querySelector('.agent-activity-card-history') && document.querySelectorAll('[data-viewed-image]').length === 2, 'saved images remain visible with Activity collapsed')
|
|
85
|
+
click('#switch'); await waitFor(() => !document.querySelector('[data-viewed-image]'), 'Session switch')
|
|
86
|
+
check(!document.querySelector('[data-viewed-image]'), 'images do not leak into another conversation')
|
|
87
|
+
click('#live'); await waitFor(() => document.querySelectorAll('[data-viewed-image]').length === 2, 'Live view returns')
|
|
88
|
+
document.querySelector('.viewed-image-button img')!.dispatchEvent(new Event('error'))
|
|
89
|
+
await waitFor(() => Boolean(document.querySelector('.viewed-image-error')), 'Image error')
|
|
90
|
+
check(document.querySelectorAll('.viewed-image-button').length === 1, 'a broken image leaves other images available')
|
|
91
|
+
document.getElementById('qa-results')!.textContent = results.join('\n') + '\nALL PASSED'
|
|
92
|
+
}
|
|
93
|
+
run().catch(error => { document.getElementById('qa-results')!.textContent = results.join('\n') + `\nFAIL ${error.message}` })
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
<!doctype html><html><head><meta charset="utf-8"><title>Mint dictation regression checks</title></head>
|
|
2
|
+
<body><div id="root"></div><pre id="result">RUNNING</pre><script type="module">
|
|
3
|
+
import React from 'react'; import {createRoot} from 'react-dom/client';
|
|
4
|
+
import {useSpeechToText} from '../shared/utils/speech';
|
|
5
|
+
import {useNativeVoiceInput} from '../shared/utils/useNativeVoiceInput';
|
|
6
|
+
const wait=()=>new Promise(resolve=>setTimeout(resolve,30));
|
|
7
|
+
const assert=(ok,message)=>{if(!ok)throw Error(message)};
|
|
8
|
+
let root,voice,changeDraft,changeChat,recognition,transcript,finishTranscript;let endDelay=0;
|
|
9
|
+
const writes=[],sends=[],checks=[];
|
|
10
|
+
class Recognition {
|
|
11
|
+
constructor(){recognition=this;this.results=[]}
|
|
12
|
+
start(){setTimeout(()=>this.onstart?.(),0)}
|
|
13
|
+
stop(){setTimeout(()=>this.onend?.(),endDelay)}
|
|
14
|
+
abort(){}
|
|
15
|
+
result(text,final=true,index=this.results.length){
|
|
16
|
+
const result=[{transcript:text}];result.isFinal=final;this.results[index]=result;
|
|
17
|
+
this.onresult?.({resultIndex:index,results:this.results});
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
window.SpeechRecognition=Recognition;
|
|
21
|
+
function Web(){
|
|
22
|
+
const [message,setMessage]=React.useState('Existing');changeDraft=setMessage;const [chatId,setChatId]=React.useState('chat-a');changeChat=setChatId;
|
|
23
|
+
voice=useSpeechToText({chatId,message,sending:false,isSpeaking:false,onSetMessage:text=>{writes.push(text);setMessage(text)},onSendVoiceMessage:async text=>sends.push(text)});
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
function Native(){
|
|
27
|
+
const [message,setMessage]=React.useState('Existing');changeDraft=setMessage;const [chatId,setChatId]=React.useState('chat-a');changeChat=setChatId;
|
|
28
|
+
voice=useNativeVoiceInput({chatId,message,onSetMessage:text=>{writes.push(text);setMessage(text)},onSendVoiceMessage:async text=>sends.push(text),
|
|
29
|
+
startRecording:async()=>{},cancelRecording:async()=>{},stopRecordingAndTranscribe:()=>transcript});
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
async function mount(Component){
|
|
33
|
+
if(root){root.unmount();await wait()}
|
|
34
|
+
writes.length=0;sends.length=0;root=createRoot(document.getElementById('root'));
|
|
35
|
+
root.render(React.createElement(Component));await wait();
|
|
36
|
+
}
|
|
37
|
+
async function check(name,run){try{await run();checks.push('PASS '+name)}catch(error){checks.push('FAIL '+name+': '+error.message)}}
|
|
38
|
+
window.runVoiceDictationChecks=async()=>{
|
|
39
|
+
await check('web retains every final phrase and never sends',async()=>{
|
|
40
|
+
await mount(Web);await voice.startRecognition();await wait();
|
|
41
|
+
recognition.result('First sentence. ');recognition.result('Second sentence.');
|
|
42
|
+
assert(writes.length===0&&sends.length===0,'must wait for stop');
|
|
43
|
+
voice.stopRecognition();await wait();
|
|
44
|
+
assert(writes.join('|')==='Existing First sentence. Second sentence.',JSON.stringify({writes,sends}));
|
|
45
|
+
assert(sends.length===0,'dictation sent a chat message');
|
|
46
|
+
});
|
|
47
|
+
await check('web replaces interim results without duplicating final results',async()=>{
|
|
48
|
+
await mount(Web);await voice.startRecognition();await wait();
|
|
49
|
+
recognition.result('hello ',true);recognition.result('worl',false);
|
|
50
|
+
recognition.result('world',true,1);recognition.result('world',true,1);
|
|
51
|
+
changeDraft('Edited draft');await wait();voice.stopRecognition();await wait();
|
|
52
|
+
assert(writes.join('|')==='Edited draft hello world',JSON.stringify(writes));
|
|
53
|
+
assert(sends.length===0,'dictation sent a chat message');
|
|
54
|
+
});
|
|
55
|
+
await check('web cancel discards all recognized phrases',async()=>{
|
|
56
|
+
await mount(Web);await voice.startRecognition();await wait();recognition.result('discard');
|
|
57
|
+
voice.cancelRecognition();await wait();assert(writes.length===0&&sends.length===0,'canceled text was applied');
|
|
58
|
+
});
|
|
59
|
+
await check('desktop stop appends to latest draft and never sends',async()=>{
|
|
60
|
+
await mount(Native);transcript=new Promise(resolve=>{finishTranscript=resolve});
|
|
61
|
+
await voice.startRecognition();await wait();const stop=voice.stopRecognition();
|
|
62
|
+
changeDraft('Edited while transcribing');await wait();finishTranscript(' Native words ');await stop;await wait();
|
|
63
|
+
assert(writes.join('|')==='Edited while transcribing Native words',JSON.stringify({writes,sends}));
|
|
64
|
+
assert(sends.length===0,'desktop sent a chat message');
|
|
65
|
+
});
|
|
66
|
+
await check('desktop cancellation during transcription leaves draft alone',async()=>{
|
|
67
|
+
await mount(Native);transcript=new Promise(resolve=>{finishTranscript=resolve});
|
|
68
|
+
await voice.startRecognition();await wait();const stop=voice.stopRecognition();
|
|
69
|
+
const cancel=voice.cancelRecognition();finishTranscript('discard');await stop;await cancel;await wait();
|
|
70
|
+
assert(writes.length===0&&sends.length===0,'canceled text was applied');
|
|
71
|
+
});
|
|
72
|
+
await check('desktop empty transcript leaves draft alone',async()=>{
|
|
73
|
+
await mount(Native);transcript=Promise.resolve(' ');await voice.startRecognition();await wait();
|
|
74
|
+
await voice.stopRecognition();await wait();assert(writes.length===0&&sends.length===0,'empty text changed the draft');
|
|
75
|
+
});
|
|
76
|
+
await check('desktop discards delayed transcript after switching chats',async()=>{
|
|
77
|
+
await mount(Native);transcript=new Promise(resolve=>{finishTranscript=resolve});await voice.startRecognition();await wait();
|
|
78
|
+
const stopping=voice.stopRecognition();changeChat('chat-b');changeDraft('Other chat draft');await wait();
|
|
79
|
+
finishTranscript('private words from chat A');await stopping;await wait();
|
|
80
|
+
assert(writes.length===0&&sends.length===0,'old transcript was inserted into the new chat');
|
|
81
|
+
});
|
|
82
|
+
await check('web discards pending recognition after switching chats',async()=>{
|
|
83
|
+
await mount(Web);await voice.startRecognition();await wait();recognition.result('private words from chat A');
|
|
84
|
+
endDelay=80;voice.stopRecognition();changeChat('chat-b');changeDraft('Other chat draft');await wait();await new Promise(resolve=>setTimeout(resolve,100));endDelay=0;
|
|
85
|
+
assert(writes.length===0&&sends.length===0,'old recognition was inserted into the new chat');
|
|
86
|
+
});
|
|
87
|
+
await check('unsupported browser shows popup and leaves draft alone',async()=>{
|
|
88
|
+
await mount(Web);const original=window.SpeechRecognition,webkit=window.webkitSpeechRecognition,alert=window.alert;const popups=[];
|
|
89
|
+
try{
|
|
90
|
+
window.SpeechRecognition=undefined;window.webkitSpeechRecognition=undefined;window.alert=text=>popups.push(text);
|
|
91
|
+
const started=await voice.startRecognition();await wait();
|
|
92
|
+
assert(started===false&&!voice.isRecording&&!voice.voiceMode,'unsupported browser entered recording mode');
|
|
93
|
+
assert(popups.length===1&&popups[0].includes('Chrome or Edge'),'unsupported popup missing');
|
|
94
|
+
assert(writes.length===0&&sends.length===0,'unsupported microphone changed the draft');
|
|
95
|
+
}finally{window.SpeechRecognition=original;window.webkitSpeechRecognition=webkit;window.alert=alert}
|
|
96
|
+
});
|
|
97
|
+
root.unmount();root=null;
|
|
98
|
+
document.getElementById('result').textContent=checks.join('\n');
|
|
99
|
+
return checks;
|
|
100
|
+
}
|
|
101
|
+
</script></body></html>
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
<!doctype html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>Mint VoicePill interaction checks</title></head>
|
|
2
|
+
<body style="background:#18181b;color:#f5f5f5;font-family:system-ui;margin:32px"><h1>Mint VoicePill</h1><div id="root" style="padding:24px 140px"></div><pre id="result">RUNNING</pre>
|
|
3
|
+
<script type="module">
|
|
4
|
+
import React from 'react';import {createRoot} from 'react-dom/client';
|
|
5
|
+
import VoicePill from '../shared/components/chat/VoicePill';
|
|
6
|
+
import {useNativeVoiceInput} from '../shared/utils/useNativeVoiceInput';
|
|
7
|
+
import {useSpeechToText} from '../shared/utils/speech';
|
|
8
|
+
const wait=(ms=60)=>new Promise(done=>setTimeout(done,ms));const lines=[];
|
|
9
|
+
const assert=(ok,line)=>{if(!ok)throw Error(line);lines.push(line)};
|
|
10
|
+
// Drive scheduled component frames deterministically; Chrome virtual-time timers can outrun compositor frames.
|
|
11
|
+
const frames=new Map();let frameId=0;
|
|
12
|
+
window.requestAnimationFrame=callback=>{frames.set(++frameId,callback);return frameId};
|
|
13
|
+
window.cancelAnimationFrame=id=>frames.delete(id);
|
|
14
|
+
const advanceFrames=count=>{const now=performance.now();for(let i=0;i<count;i++){const batch=[...frames.values()];frames.clear();batch.forEach(callback=>callback(now+i*20))}};
|
|
15
|
+
const root=createRoot(document.getElementById('root'));
|
|
16
|
+
const events=[];let setDisabled,unmountPill;
|
|
17
|
+
const button=()=>document.querySelector('.voice-pill');
|
|
18
|
+
const pointer=(type,x=180)=>button().dispatchEvent(new PointerEvent(type,{button:0,pointerId:7,isPrimary:true,clientX:x,bubbles:true,cancelable:true}));
|
|
19
|
+
const tap=async()=>{pointer('pointerdown');await wait(30);pointer('pointerup');await wait()};
|
|
20
|
+
const key=key=>button().dispatchEvent(new KeyboardEvent('keydown',{key,bubbles:true,cancelable:true}));
|
|
21
|
+
try {
|
|
22
|
+
function Fixture(){
|
|
23
|
+
const [disabled,disable]=React.useState(false);setDisabled=disable;
|
|
24
|
+
const [shown,show]=React.useState(true);unmountPill=()=>show(false);
|
|
25
|
+
return shown?React.createElement(VoicePill,{disabled,onStart:e=>events.push(['start',e]),onStop:e=>events.push(['stop',e])}):null;
|
|
26
|
+
}
|
|
27
|
+
root.render(React.createElement(Fixture));await wait(180);
|
|
28
|
+
assert(button().getAttribute('aria-pressed')==='false','idle microphone is not marked recording');
|
|
29
|
+
await tap();assert(button().getAttribute('aria-pressed')==='true','short tap latches recording');
|
|
30
|
+
advanceFrames(64);assert(button().querySelector('.voice-pill__time').textContent!=='0:00','elapsed clock advances');
|
|
31
|
+
const canvas=button().querySelector('canvas');const pixels=canvas.getContext('2d').getImageData(0,0,canvas.width,canvas.height).data;
|
|
32
|
+
assert(pixels.some((v,i)=>i%4===3&&v>0),'authored scrolling waveform renders canvas pixels ('+canvas.width+'x'+canvas.height+')');
|
|
33
|
+
await tap();assert(events.at(-1)[1].reason==='tap'&&button().getAttribute('aria-pressed')==='false','second tap stops latched recording');
|
|
34
|
+
pointer('pointerdown');await wait(360);pointer('pointerup');await wait();assert(events.at(-1)[1].reason==='release','held recording stops on release');
|
|
35
|
+
pointer('pointerdown');await wait();pointer('pointermove',140);await wait();assert(button().dataset.sliding!==undefined,'held left drag reveals cancel affordance');
|
|
36
|
+
pointer('pointermove',110);await wait();const count=events.length;pointer('pointerup',110);await wait();
|
|
37
|
+
assert(events.at(-1)[1].reason==='cancel'&&events.length===count,'crossing cancel distance cancels once without release result');
|
|
38
|
+
pointer('pointerdown');await wait();pointer('pointercancel');await wait();assert(events.at(-1)[1].reason==='cancel','pointer cancellation never submits');
|
|
39
|
+
key('Enter');await wait();assert(button().getAttribute('aria-pressed')==='true','keyboard starts recording');
|
|
40
|
+
key('Escape');await wait();assert(events.at(-1)[1].reason==='escape','Escape cancels keyboard recording');
|
|
41
|
+
await tap();window.dispatchEvent(new Event('blur'));await wait();assert(events.at(-1)[1].reason==='blur','window blur cancels latched recording');
|
|
42
|
+
await tap();setDisabled(true);await wait();assert(events.at(-1)[1].reason==='disabled'&&button().disabled,'disabling cancels microphone');
|
|
43
|
+
setDisabled(false);await wait();await tap();unmountPill();await wait();assert(events.at(-1)[1].reason==='unmount'&&frames.size===0,'unmount stops listening and animation frames');
|
|
44
|
+
const calls=[];let ready;
|
|
45
|
+
function NativeFixture(){
|
|
46
|
+
const voice=useNativeVoiceInput({startRecording:()=>new Promise(resolve=>{calls.push('start');ready=resolve}),
|
|
47
|
+
cancelRecording:async()=>{calls.push('discard')},stopRecordingAndTranscribe:async()=>{calls.push('transcribe');return 'Native words'},message:'Existing',onSetMessage:text=>calls.push('draft:'+text),onSendVoiceMessage:async text=>calls.push('send:'+text)});
|
|
48
|
+
return React.createElement(VoicePill,{active:voice.isRecording,onStart:voice.startRecognition,
|
|
49
|
+
onStop:e=>['tap','release','key'].includes(e.reason)?voice.stopRecognition():voice.cancelRecognition()});
|
|
50
|
+
}
|
|
51
|
+
root.render(React.createElement(NativeFixture));await wait();pointer('pointerdown');await wait();
|
|
52
|
+
assert(button().getAttribute('aria-pressed')==='false'&&button().getAttribute('aria-busy')==='true','actual state waits for native device startup');
|
|
53
|
+
pointer('pointermove',110);pointer('pointerup',110);ready();await wait();
|
|
54
|
+
assert(calls.join(',')==='start,discard'&&button().getAttribute('aria-pressed')==='false','native pending-start cancellation discards without transcription');
|
|
55
|
+
pointer('pointerdown');await wait();ready();await wait();pointer('pointerup');await wait();
|
|
56
|
+
assert(button().getAttribute('aria-pressed')==='true','native success opens listening capsule');
|
|
57
|
+
await tap();await wait();assert(calls.at(-2)==='transcribe'&&calls.at(-1)==='draft:Existing Native words'&&!calls.some(call=>call.startsWith('send:')),'normal native stop appends transcript to composer without sending');
|
|
58
|
+
root.render(React.createElement('div'));await wait();
|
|
59
|
+
const instances=[],messages=[],sends=[];let denied=false;
|
|
60
|
+
class Recognition {
|
|
61
|
+
constructor(){instances.push(this)}
|
|
62
|
+
start(){setTimeout(()=>{if(denied){this.onerror?.({error:'not-allowed'});this.onend?.()}else this.onstart?.()},20)}
|
|
63
|
+
result(text){const result=[{transcript:text}];result.isFinal=true;this.onresult?.({resultIndex:0,results:[result]})}
|
|
64
|
+
stop(){setTimeout(()=>this.onend?.(),20)}
|
|
65
|
+
abort(){this.aborted=true;setTimeout(()=>this.onend?.(),20)}
|
|
66
|
+
}
|
|
67
|
+
window.SpeechRecognition=Recognition;
|
|
68
|
+
function WebFixture(){
|
|
69
|
+
const voice=useSpeechToText({language:'en',message:'Existing',sending:false,isSpeaking:false,onSetMessage:text=>messages.push(text),onSendVoiceMessage:async text=>sends.push(text)});
|
|
70
|
+
return React.createElement(VoicePill,{active:voice.isRecording,onStart:()=>voice.startRecognition(),
|
|
71
|
+
onStop:e=>['tap','release','key'].includes(e.reason)?voice.stopRecognition():voice.cancelRecognition()});
|
|
72
|
+
}
|
|
73
|
+
root.render(React.createElement(WebFixture));await wait();await tap();instances.at(-1).result('cancelled words');
|
|
74
|
+
key('Escape');await wait();assert(instances.at(-1).aborted&&messages.length===0&&sends.length===0,'Web cancellation aborts and discards recognized text');
|
|
75
|
+
await tap();instances.at(-1).result('hello');await tap();await wait();
|
|
76
|
+
assert(messages.join(',')==='Existing hello'&&sends.length===0,'Web normal stop preserves dictation into existing composer');
|
|
77
|
+
denied=true;await tap();await wait();assert(button().getAttribute('aria-pressed')==='false'&&!button().getAttribute('aria-busy'),'permission refusal returns to idle');
|
|
78
|
+
document.getElementById('result').textContent='PASS\n'+lines.join('\n');
|
|
79
|
+
} catch(error){document.getElementById('result').textContent='FAIL: '+error.message+'\n'+lines.join('\n');console.error(error)}
|
|
80
|
+
</script></body></html>
|