@pheem49/mint 1.14.0 → 1.15.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/CLAUDE.md +1 -1
- package/Cargo.lock +291 -11
- package/Cargo.toml +1 -1
- package/README.md +71 -9
- package/ROADMAP.md +30 -0
- package/Release_Note.md +579 -465
- package/crates/mint-cli/Cargo.toml +3 -1
- package/crates/mint-cli/src/agent/approval_prompts.rs +16 -3
- package/crates/mint-cli/src/agent/live_status.rs +367 -118
- package/crates/mint-cli/src/agent/markdown_render.rs +601 -61
- package/crates/mint-cli/src/agent.rs +452 -215
- package/crates/mint-cli/src/commands/agent.rs +16 -21
- package/crates/mint-cli/src/commands/eval.rs +9 -5
- package/crates/mint-cli/src/commands/git.rs +204 -0
- package/crates/mint-cli/src/commands/integrations.rs +28 -0
- package/crates/mint-cli/src/commands/knowledge.rs +1 -0
- package/crates/mint-cli/src/commands/mod.rs +37 -2
- package/crates/mint-cli/src/commands/tailnet_web.rs +235 -0
- package/crates/mint-cli/src/image.rs +26 -3
- package/crates/mint-cli/src/interactive/chat_tui.rs +4742 -0
- package/crates/mint-cli/src/interactive/command_ui.rs +477 -0
- package/crates/mint-cli/src/interactive/format.rs +8 -0
- package/crates/mint-cli/src/interactive/input_box.rs +38 -2
- package/crates/mint-cli/src/interactive/picker.rs +180 -37
- package/crates/mint-cli/src/interactive/resume_picker.rs +686 -0
- package/crates/mint-cli/src/interactive/slash_commands.rs +868 -450
- package/crates/mint-cli/src/interactive/thought_viewer.rs +286 -0
- package/crates/mint-cli/src/interactive.rs +400 -136
- package/crates/mint-cli/src/main.rs +84 -23
- package/crates/mint-cli/src/markdown.rs +12 -5
- package/crates/mint-cli/src/onboard.rs +32 -30
- package/crates/mint-cli/src/plugins_cli.rs +8 -5
- package/crates/mint-cli/src/setup.rs +10 -8
- package/crates/mint-cli/src/terminal_theme.rs +187 -0
- package/crates/mint-cli/src/updater.rs +56 -21
- package/crates/mint-core/src/agent/agent_loop.rs +1 -0
- package/crates/mint-core/src/agent/chat.rs +843 -177
- package/crates/mint-core/src/agent/code_tools.rs +83 -2
- package/crates/mint-core/src/agent/memory.rs +658 -20
- package/crates/mint-core/src/agent/skills.rs +1 -1
- package/crates/mint-core/src/api_server/routes/chat.rs +31 -5
- package/crates/mint-core/src/api_server/routes/linked_folders.rs +118 -3
- package/crates/mint-core/src/api_server/routes/misc.rs +10 -14
- package/crates/mint-core/src/api_server/routes/sessions.rs +44 -0
- package/crates/mint-core/src/api_server.rs +22 -3
- package/crates/mint-core/src/avatar_bridge.rs +2 -0
- package/crates/mint-core/src/browser/cdp.rs +74 -83
- package/crates/mint-core/src/browser/evidence.rs +260 -0
- package/crates/mint-core/src/browser/input.rs +1 -1
- package/crates/mint-core/src/browser/interact.rs +98 -124
- package/crates/mint-core/src/browser/lifecycle.rs +75 -4
- package/crates/mint-core/src/browser/mod.rs +16 -2
- package/crates/mint-core/src/browser/navigate.rs +27 -19
- package/crates/mint-core/src/browser/observe.js +40 -0
- package/crates/mint-core/src/browser/session.rs +1558 -0
- package/crates/mint-core/src/git/branches.rs +348 -0
- package/crates/mint-core/src/git/checkpoint.rs +40 -0
- package/crates/mint-core/src/git/diff.rs +206 -0
- package/crates/mint-core/src/git/mod.rs +10 -2
- package/crates/mint-core/src/integrations/channels.rs +1 -0
- package/crates/mint-core/src/lib.rs +22 -14
- package/crates/mint-core/src/live_sync.rs +28 -9
- package/crates/mint-core/src/media/auto_shorts.rs +1 -0
- package/crates/mint-core/src/media/gemini_live.rs +12 -1
- package/crates/mint-core/src/media/mic_transcribe.rs +1 -0
- package/crates/mint-core/src/media/subtitle.rs +1 -0
- package/crates/mint-core/src/orchestration/context_render.rs +1 -0
- package/crates/mint-core/src/orchestration/memory_skill.rs +6 -1
- package/crates/mint-core/src/orchestration/mod.rs +1024 -271
- package/crates/mint-core/src/orchestration/tools/browser.rs +16 -139
- package/crates/mint-core/src/orchestration/tools/misc.rs +2 -1
- package/crates/mint-core/src/orchestration/tools/web.rs +1 -1
- package/crates/mint-core/src/prompts/agent.rs +58 -29
- package/crates/mint-core/src/prompts/chat.rs +1 -1
- package/crates/mint-core/src/prompts/persona.rs +1 -1
- package/crates/mint-core/src/prompts/tool_catalog.rs +93 -25
- package/crates/mint-core/src/search/linked_folders/index.rs +732 -0
- package/crates/mint-core/src/search/linked_folders.rs +391 -130
- package/crates/mint-core/src/slash/mod.rs +470 -22
- package/crates/mint-core/src/slash/model_fetcher.rs +12 -3
- package/crates/mint-core/src/slash/models.rs +66 -10
- package/crates/mint-core/src/system/config.rs +230 -0
- package/crates/mint-core/src/system/workspace.rs +228 -0
- package/crates/mint-core/src/system.rs +1 -0
- package/crates/mint-core/tests/memory_persistence.rs +39 -0
- package/mint-presentation-demo.mp4 +0 -0
- package/out/web/assets/CliSessionsView-BxUVWEEL.js +1 -0
- package/out/web/assets/CliSessionsView-CBDTXuQv.css +1 -0
- package/out/web/assets/CodeReviewPage-DkMgfcos.css +1 -0
- package/out/web/assets/CodeReviewPage-jKlmLJwT.js +3 -0
- package/out/web/assets/CommandPalette-DnwPA5hy.js +1 -0
- package/out/web/assets/ImageStudioPanel-BR1XFwhR.js +1 -0
- package/out/web/assets/ImageStudioPanel-D0lnhQV5.css +1 -0
- package/out/web/assets/LinkedFoldersView-bi-CWQ-I.js +1 -0
- package/out/web/assets/McpRegistryPicker-D5tEFnyq.js +1 -0
- package/out/web/assets/McpServersView-BGG1dhFM.js +1 -0
- package/out/web/assets/MintDashboard-BIglDEWX.js +20 -0
- package/out/web/assets/MintDashboard-DSMywSgs.css +1 -0
- package/out/web/assets/ModelPanel-CbJ1PFoZ.js +1 -0
- package/out/web/assets/PicturesLibrary-CQP0fLP1.css +1 -0
- package/out/web/assets/PicturesLibrary-DoYN7T1p.js +1 -0
- package/out/web/assets/PluginsView-CU1HWXGk.js +1 -0
- package/out/web/assets/ScheduledTasksView-Bnl36y2N.js +1 -0
- package/out/web/assets/SettingsWindow-DhWLAn9T.css +1 -0
- package/out/web/assets/SettingsWindow-Dw8L01pw.js +2 -0
- package/out/web/assets/SkillsView-cnl8aY5p.js +2 -0
- package/out/web/assets/ToolSurfacePage-CgsQw6l5.css +1 -0
- package/out/web/assets/ToolSurfacePage-Cz2VJAPZ.js +37 -0
- package/out/web/assets/VeoStudioPanel-D4JnERWR.js +4 -0
- package/out/web/assets/VeoStudioPanel-DOj7_WR3.css +1 -0
- package/out/web/assets/WorkspacePanel-CbJ1PFoZ.js +1 -0
- package/out/web/assets/{abnfDiagram-VCTEODGH-DAOBA7ZG.js → abnfDiagram-VCTEODGH-ByMyfanq.js} +1 -1
- package/out/web/assets/{architecture-7GRP2DOG-CgSwQOPQ.js → architecture-7GRP2DOG-CLq2kEOB.js} +1 -1
- package/out/web/assets/{architectureDiagram-5GKGNRK7-CYp3yupP.js → architectureDiagram-5GKGNRK7-6PoVSmNG.js} +1 -1
- package/out/web/assets/{blockDiagram-NRAW4CY4-CyWybDWr.js → blockDiagram-NRAW4CY4-cKw9mAKi.js} +1 -1
- package/out/web/assets/{c4Diagram-UCG6FXSJ-BvY3U709.js → c4Diagram-UCG6FXSJ-Cqy8N5Ge.js} +1 -1
- package/out/web/assets/{chunk-75Z2AOVW-TLXCoZYv.js → chunk-75Z2AOVW-3qybijF5.js} +1 -1
- package/out/web/assets/chunk-CKBBP62Z-cIrXq6jN.js +2 -0
- package/out/web/assets/{chunk-CLGD4ZFX-xjsKtNS7.js → chunk-CLGD4ZFX-CndDQkww.js} +1 -1
- package/out/web/assets/chunk-DSNCTWBM-Cc4NxvgD.js +2 -0
- package/out/web/assets/chunk-DU6HZSFF-drzh6GsU.js +128 -0
- package/out/web/assets/{chunk-F27PBJKO-BFpgF55A.js → chunk-F27PBJKO-FiY35l4v.js} +1 -1
- package/out/web/assets/{chunk-G27WJ6UU-DfF7qW-C.js → chunk-G27WJ6UU-Bjt9Il4A.js} +1 -1
- package/out/web/assets/{chunk-GMAD6QVW-C-558kh_.js → chunk-GMAD6QVW-Bppi3Ctd.js} +1 -1
- package/out/web/assets/{chunk-JQ64N6SF-wJmeGKAw.js → chunk-JQ64N6SF-DGg5kcEV.js} +1 -1
- package/out/web/assets/{chunk-LCL6LL3I-C1wHD8Ie.js → chunk-LCL6LL3I-CCYcjd7p.js} +1 -1
- package/out/web/assets/{chunk-OBVCFTLP-BsRTPBqs.js → chunk-OBVCFTLP-DJeNil5M.js} +1 -1
- package/out/web/assets/{chunk-P2QGCYS3-HZIiM7Ni.js → chunk-P2QGCYS3-lRzkRjBB.js} +1 -1
- package/out/web/assets/{chunk-POPQ4Y6H-Dk9wvVb0.js → chunk-POPQ4Y6H-DouASMBW.js} +1 -1
- package/out/web/assets/{chunk-PWAF6VOD-BmjYLNbq.js → chunk-PWAF6VOD-DMmD1vVf.js} +1 -1
- package/out/web/assets/{chunk-R7TYR2AO-CaHIf-lK.js → chunk-R7TYR2AO-CYLA5UC5.js} +1 -1
- package/out/web/assets/{chunk-RHFEMEQ7-_T561hOU.js → chunk-RHFEMEQ7-BiXwEcUT.js} +1 -1
- package/out/web/assets/{chunk-SVP7TREG-CM-GGYoY.js → chunk-SVP7TREG-BV-zPslF.js} +1 -1
- package/out/web/assets/{chunk-TEH6E4GO-K2A8Vg2C.js → chunk-TEH6E4GO-B2RGEohZ.js} +1 -1
- package/out/web/assets/classDiagram-DTDB5LWJ-Dq0smRWk.js +1 -0
- package/out/web/assets/classDiagram-v2-JRS7N3AN-Dq0smRWk.js +1 -0
- package/out/web/assets/config-C-ZFtipU.css +1 -0
- package/out/web/assets/config-eEDngJXO.js +1 -0
- package/out/web/assets/core-hQ2VA9Ti.js +1 -0
- package/out/web/assets/{cynefin-OW5HDTMX-ClzaB6cc.js → cynefin-OW5HDTMX-Cas4csHM.js} +1 -1
- package/out/web/assets/{cynefinDiagram-5FMLGOSQ-D_JzZBzf.js → cynefinDiagram-5FMLGOSQ-Bbpj66Y3.js} +1 -1
- package/out/web/assets/{dagre-3AP2YEHR-BDuUeMHj.js → dagre-3AP2YEHR-B0-2RDEd.js} +1 -1
- package/out/web/assets/{diagram-S7CK7UJ4-DgtcfE8P.js → diagram-S7CK7UJ4-BdzEjUyH.js} +1 -1
- package/out/web/assets/{diagram-UQ7AKVKN-DTLoEYti.js → diagram-UQ7AKVKN-CJDwyPxF.js} +1 -1
- package/out/web/assets/{diagram-VSXAHHWV-ChGl9pXz.js → diagram-VSXAHHWV-BxaG1r_B.js} +1 -1
- package/out/web/assets/{diagram-VX7I27RA-Be8DWz0S.js → diagram-VX7I27RA-BMmUqm8f.js} +1 -1
- package/out/web/assets/{diagram-Z3DM3KII-BMXjRTOF.js → diagram-Z3DM3KII-CFtd03eE.js} +1 -1
- package/out/web/assets/dist-js-Bf2bhoku.js +1 -0
- package/out/web/assets/{ebnfDiagram-PWID7BFC-8Q9pl1CJ.js → ebnfDiagram-PWID7BFC-DwAen1hO.js} +1 -1
- package/out/web/assets/{erDiagram-SSCWMZ5O-DjH8Lnkn.js → erDiagram-SSCWMZ5O-BCZSHACj.js} +1 -1
- package/out/web/assets/event-ChBVpRy0.js +1 -0
- package/out/web/assets/{eventmodeling-NTZA5JFV-BKUH_DOp.js → eventmodeling-NTZA5JFV-XHStE4E_.js} +1 -1
- package/out/web/assets/fira-code-latin-600-normal-BmSSHshu.woff +0 -0
- package/out/web/assets/fira-code-latin-600-normal-CvYZpPHg.woff2 +0 -0
- package/out/web/assets/fira-code-symbols2-600-normal-Dvq6IQE5.woff +0 -0
- package/out/web/assets/flowDiagram-A5DVABFB-BLg7nEcd.js +1 -0
- package/out/web/assets/{ganttDiagram-EL5Y4UJY-D7fZKJNM.js → ganttDiagram-EL5Y4UJY-BAEu1Cql.js} +1 -1
- package/out/web/assets/{gitGraph-4MIJSDKK-BypWaaBU.js → gitGraph-4MIJSDKK-r32Vyper.js} +1 -1
- package/out/web/assets/{gitGraphDiagram-WWUBYQGX-DWiw_3bq.js → gitGraphDiagram-WWUBYQGX-z9o9qt6V.js} +1 -1
- package/out/web/assets/index-Btsf4L8M.css +1 -0
- package/out/web/assets/index-D8D9MeRA.js +11 -0
- package/out/web/assets/{info-A6RAGUB7-KkAUxT4j.js → info-A6RAGUB7-BvLaC2cw.js} +1 -1
- package/out/web/assets/{infoDiagram-RXCK75RN-BNb6E48y.js → infoDiagram-RXCK75RN-Be6WAXXw.js} +1 -1
- package/out/web/assets/{ishikawaDiagram-5VMMS53U-Caa-JoAK.js → ishikawaDiagram-5VMMS53U-DZjoHJHC.js} +1 -1
- package/out/web/assets/{journeyDiagram-EYS64GPL-DOrmFGz6.js → journeyDiagram-EYS64GPL-CtVkjkGm.js} +1 -1
- package/out/web/assets/{kanban-definition-3QL26DDD-BOWCYcK0.js → kanban-definition-3QL26DDD-CW5FMv1w.js} +1 -1
- package/out/web/assets/lucide-react-Ip3L6Jtn.js +1 -0
- package/out/web/assets/markdown-BSeeUbJH.js +38 -0
- package/out/web/assets/{mermaid-parser.core-BQqjCkS_.js → mermaid-parser.core-aUgCqsZ5.js} +3 -3
- package/out/web/assets/mermaid.core-D57sEiSL.js +11 -0
- package/out/web/assets/{mindmap-definition-FBJOCRG2-jTceWpr0.js → mindmap-definition-FBJOCRG2-DAmSpM3a.js} +1 -1
- package/out/web/assets/modelManager-tMVmJVAW.js +2 -0
- package/out/web/assets/oauthManager-9jxicDWJ.js +1 -0
- package/out/web/assets/{packet-AYTQ26CC-CJ5RXgol.js → packet-AYTQ26CC-DJ27iIoJ.js} +1 -1
- package/out/web/assets/{pegDiagram-XKGWAZYB-y8wMtd0y.js → pegDiagram-XKGWAZYB-Bj3ii-gS.js} +1 -1
- package/out/web/assets/{pie-WAS4IAKB-72fTBbl4.js → pie-WAS4IAKB-DG5mCUbc.js} +1 -1
- package/out/web/assets/{pieDiagram-E7YTZNPT-e0O02qWq.js → pieDiagram-E7YTZNPT-BrJLPnDA.js} +1 -1
- 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-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-C9phYLom.js → quadrantDiagram-AXDQQJYC-3x_TmF3j.js} +1 -1
- package/out/web/assets/{radar-RG4KPBEZ-BAU2hzUT.js → radar-RG4KPBEZ-CrXaTTuV.js} +1 -1
- package/out/web/assets/{railroad-74A4TZTK-B0bCAVHC.js → railroad-74A4TZTK-BpqMH9BE.js} +1 -1
- package/out/web/assets/{railroad-abnf-HS5TGJTU-WhxO7ndE.js → railroad-abnf-HS5TGJTU-DHI0uLlV.js} +1 -1
- package/out/web/assets/{railroad-ebnf-LZEXJU2U-BkA0m7-F.js → railroad-ebnf-LZEXJU2U-CQCb316y.js} +1 -1
- package/out/web/assets/{railroad-peg-WCYAUIDC-BsVpHIaj.js → railroad-peg-WCYAUIDC-Ph1giKkH.js} +1 -1
- package/out/web/assets/{railroadDiagram-O6MQD6OU-CyOLN65Q.js → railroadDiagram-O6MQD6OU-BRq6wIxx.js} +1 -1
- package/out/web/assets/{requirementDiagram-EFPCY7ZU-DQXJ7Dud.js → requirementDiagram-EFPCY7ZU-DIJj6G1g.js} +1 -1
- package/out/web/assets/{sankeyDiagram-P5KCCOFB-B2XLyIIc.js → sankeyDiagram-P5KCCOFB-DZajSryq.js} +1 -1
- package/out/web/assets/{sequenceDiagram-WJ2MYXX4-DGQY4wwm.js → sequenceDiagram-WJ2MYXX4-DxJCWyZS.js} +1 -1
- package/out/web/assets/{stateDiagram-HBIQ2CUA-DHZpDwNy.js → stateDiagram-HBIQ2CUA-k6voi8Vf.js} +1 -1
- package/out/web/assets/stateDiagram-v2-4QOOHH4V-DeEc0lGZ.js +1 -0
- package/out/web/assets/studio-B1mk40wD.js +1 -0
- package/out/web/assets/{swimlanes-XN3QIQJK-Bn_jcZz-.js → swimlanes-XN3QIQJK-igYhTjXB.js} +1 -1
- package/out/web/assets/swimlanesDiagram-VK2B7HYN-DpVik9v7.js +8 -0
- package/out/web/assets/{timeline-definition-24CTP7MA-CdTERuJZ.js → timeline-definition-24CTP7MA-Dke2p93p.js} +1 -1
- package/out/web/assets/{treeView-Q6P3EWNA-TKBKQG6R.js → treeView-Q6P3EWNA-hNELnXUs.js} +1 -1
- package/out/web/assets/{treemap-WGGIJYW6-BP7gQoiC.js → treemap-WGGIJYW6-D2B6wDsx.js} +1 -1
- package/out/web/assets/{vennDiagram-4TSXK5OY-BHUmxDuK.js → vennDiagram-4TSXK5OY-CDkW7rUP.js} +1 -1
- package/out/web/assets/{wardley-WFR3VGLG-9bct5AAN.js → wardley-WFR3VGLG-BECdXETi.js} +1 -1
- package/out/web/assets/{wardleyDiagram-VM6X3IG4-BfJwDDso.js → wardleyDiagram-VM6X3IG4-B5BycpQ4.js} +1 -1
- package/out/web/assets/window-5qYXKoW7.js +1 -0
- package/out/web/assets/{xychartDiagram-S5SC5T6Z-Dqd9Mvpo.js → xychartDiagram-S5SC5T6Z-CtJS3b--.js} +1 -1
- package/out/web/index-web.html +3 -4
- package/out/web/index.html +3 -4
- package/package.json +17 -6
- package/skills-lock.json +36 -0
- package/slash-commands.json +9 -0
- package/src/renderer/index-web.html +1 -0
- package/src/renderer/index.html +1 -0
- package/src/renderer/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
- package/src/renderer/shared/agentProgress.ts +168 -3
- package/src/renderer/shared/components/AgentActivityDrawer.tsx +6 -6
- package/src/renderer/shared/components/AgentActivityTable.tsx +192 -132
- package/src/renderer/shared/components/ArtifactPreviewPanel.tsx +4 -4
- package/src/renderer/shared/components/AuthGate.tsx +4 -9
- package/src/renderer/shared/components/CalculationCard.tsx +41 -15
- package/src/renderer/shared/components/ChatMessageItem.tsx +20 -21
- package/src/renderer/shared/components/ChatPanel.tsx +432 -193
- package/src/renderer/shared/components/ChunkErrorBoundary.tsx +198 -49
- package/src/renderer/shared/components/CliSessionsView.tsx +495 -0
- package/src/renderer/shared/components/CodeReviewPage.tsx +565 -0
- package/src/renderer/shared/components/CommandPalette.tsx +8 -8
- package/src/renderer/shared/components/DashboardSidebar.tsx +862 -125
- package/src/renderer/shared/components/DesktopTitlebar.tsx +345 -0
- package/src/renderer/shared/components/DiffReviewModal.tsx +3 -3
- package/src/renderer/shared/components/GitBranchSelector.tsx +442 -0
- package/src/renderer/shared/components/ImageGenCard.tsx +31 -12
- package/src/renderer/shared/components/ImageSearchCard.tsx +59 -38
- package/src/renderer/shared/components/ImageStudioPanel.tsx +40 -41
- package/src/renderer/shared/components/InlineThoughtNote.tsx +27 -0
- package/src/renderer/shared/components/LinkedFoldersView.tsx +365 -46
- package/src/renderer/shared/components/McpRegistryPicker.tsx +1 -1
- package/src/renderer/shared/components/McpServersView.tsx +24 -22
- package/src/renderer/shared/components/MermaidCard.tsx +14 -8
- package/src/renderer/shared/components/MintDashboard.tsx +1141 -508
- package/src/renderer/shared/components/ModelSelectorPopover.tsx +535 -214
- package/src/renderer/shared/components/PlanChecklistWidget.tsx +1 -1
- package/src/renderer/shared/components/PluginsView.tsx +1 -1
- package/src/renderer/shared/components/RewindModal.tsx +6 -6
- package/src/renderer/shared/components/RunSummaryDashboard.tsx +3 -3
- package/src/renderer/shared/components/ScheduledTasksView.tsx +4 -4
- package/src/renderer/shared/components/ScreenCaptureDialog.css +221 -0
- package/src/renderer/shared/components/ScreenCaptureDialog.tsx +199 -0
- package/src/renderer/shared/components/Settings/AgentsTab.tsx +34 -39
- package/src/renderer/shared/components/Settings/AudioTab.tsx +8 -8
- package/src/renderer/shared/components/Settings/AutomationTab.tsx +8 -58
- package/src/renderer/shared/components/Settings/AvatarCropModal.tsx +368 -0
- package/src/renderer/shared/components/Settings/GeneralTab.tsx +335 -81
- package/src/renderer/shared/components/Settings/MemoryTab.tsx +3 -3
- package/src/renderer/shared/components/Settings/PluginsTab.tsx +20 -12
- package/src/renderer/shared/components/Settings/ProfileTab.tsx +29 -5
- package/src/renderer/shared/components/Settings/SearchableModelCombobox.tsx +411 -0
- package/src/renderer/shared/components/Settings/ThemeTab.tsx +401 -158
- package/src/renderer/shared/components/SkillsView.tsx +41 -16
- package/src/renderer/shared/components/SlashSuggestions.tsx +3 -2
- package/src/renderer/shared/components/SourcesBlock.tsx +44 -32
- package/src/renderer/shared/components/StockCard.tsx +58 -24
- package/src/renderer/shared/components/SubagentDagView.tsx +4 -4
- package/src/renderer/shared/components/TerminalDock.tsx +241 -0
- package/src/renderer/shared/components/ThinkingBlock.tsx +14 -8
- package/src/renderer/shared/components/ToolSurfacePage.tsx +520 -0
- package/src/renderer/shared/components/UiFeatureCard.tsx +267 -0
- package/src/renderer/shared/components/UiGridCard.tsx +188 -0
- package/src/renderer/shared/components/UiMockupWidget.tsx +149 -0
- package/src/renderer/shared/components/VeoStudioPanel.tsx +13 -29
- package/src/renderer/shared/components/WeatherCard.tsx +3 -3
- package/src/renderer/shared/components/WorkspaceContextPopover.tsx +133 -0
- package/src/renderer/shared/components/WorkspaceSelector.tsx +149 -0
- package/src/renderer/shared/constants/config.ts +28 -3
- package/src/renderer/shared/constants/models.ts +189 -2
- package/src/renderer/shared/conversation/coordinator.test.ts +27 -0
- package/src/renderer/shared/conversation/coordinator.ts +82 -0
- package/src/renderer/shared/conversation/syncView.test.ts +46 -0
- package/src/renderer/shared/conversation/syncView.ts +43 -0
- package/src/renderer/shared/conversation/useConversationCoordinator.ts +106 -0
- package/src/renderer/shared/css/agent-observability.css +35 -3
- package/src/renderer/shared/css/auth-gate.css +2 -2
- package/src/renderer/shared/css/chat-ui-cards.css +495 -0
- package/src/renderer/shared/css/code-review.css +823 -0
- package/src/renderer/shared/css/code-sessions.css +452 -0
- package/src/renderer/shared/css/file-changes.css +132 -0
- package/src/renderer/shared/css/image-studio.css +16 -16
- package/src/renderer/shared/css/management-views.css +277 -27
- package/src/renderer/shared/css/model-selector.css +442 -42
- package/src/renderer/shared/css/settings/agents.css +1 -1
- package/src/renderer/shared/css/settings/automation.css +13 -13
- package/src/renderer/shared/css/settings/general.css +526 -5
- package/src/renderer/shared/css/settings/plugins.css +5 -5
- package/src/renderer/shared/css/settings/profile.css +331 -1
- package/src/renderer/shared/css/settings/theme.css +651 -3
- package/src/renderer/shared/css/veo-studio.css +16 -15
- package/src/renderer/shared/fonts.ts +19 -37
- package/src/renderer/shared/platform.test.ts +34 -0
- package/src/renderer/shared/platform.ts +173 -6
- package/src/renderer/shared/theme/themeManager.ts +144 -0
- package/src/renderer/shared/theme/themes.ts +116 -0
- package/src/renderer/shared/theme/tokens.css +318 -0
- package/src/renderer/shared/types.ts +82 -1
- package/src/renderer/shared/utils/agentActivity.ts +126 -5
- package/src/renderer/shared/utils/cardJson.test.ts +35 -0
- package/src/renderer/shared/utils/cardJson.ts +30 -0
- package/src/renderer/shared/utils/fileIcons.ts +1 -1
- package/src/renderer/shared/utils/markdown.tsx +329 -80
- package/src/renderer/shared/utils/markdown.webImages.test.tsx +40 -0
- package/src/renderer/shared/utils/providers.ts +8 -3
- package/src/renderer/shared/utils/screenCapture.ts +43 -0
- package/src/renderer/shared/utils/slashCommandProcessor.ts +4 -1
- package/src/renderer/shared/utils/ui.ts +4 -64
- package/src/renderer/src/App.tsx +7 -0
- package/src/renderer/src/components/BrowserShell.tsx +108 -0
- package/src/renderer/src/components/BrowserSuggestionsPopup.tsx +91 -0
- package/src/renderer/src/components/Live2DStage.tsx +32 -9
- package/src/renderer/src/components/MintDashboard.tsx +4 -2
- package/src/renderer/src/components/ModelPanel.tsx +2 -1
- package/src/renderer/src/components/PicturesLibrary.tsx +3 -2
- package/src/renderer/src/components/ScreenPicker.css +190 -0
- package/src/renderer/src/components/ScreenPicker.tsx +185 -540
- package/src/renderer/src/components/SettingsWindow.tsx +40 -2
- package/src/renderer/src/components/SpotlightWindow.tsx +1 -0
- package/src/renderer/src/components/WidgetWindow.tsx +27 -3
- package/src/renderer/src/components/WorkspacePanel.tsx +61 -43
- package/src/renderer/src/components/browser-shell.css +185 -0
- package/src/renderer/src/components/browser-suggestions-popup.css +55 -0
- package/src/renderer/src/components/liveTranslateFrames.test.ts +23 -0
- package/src/renderer/src/components/liveTranslateFrames.ts +34 -0
- package/src/renderer/src/css/app-shell.css +394 -113
- package/src/renderer/src/css/chat.css +1926 -380
- package/src/renderer/src/css/dashboard.css +11 -0
- package/src/renderer/src/css/desktop-tools.css +730 -0
- package/src/renderer/src/css/misc.css +19 -22
- package/src/renderer/src/css/model.css +49 -48
- package/src/renderer/src/css/pictures.css +144 -136
- package/src/renderer/src/css/settings/base.css +357 -123
- package/src/renderer/src/css/sidebar-workspace.css +930 -291
- package/src/renderer/src/css/spotlight.css +15 -26
- package/src/renderer/src/css/tool-surfaces.css +728 -0
- package/src/renderer/src/css/widget.css +35 -7
- package/src/renderer/src/env.d.ts +3 -0
- package/src/renderer/src/hooks/useProviderModels.ts +2 -9
- package/src/renderer/src/index.css +53 -46
- package/src/renderer/src/main.tsx +11 -0
- package/src/renderer/src/tauri.ts +201 -30
- package/src/renderer/src-web/App.tsx +40 -0
- package/src/renderer/src-web/components/MintDashboard.tsx +4 -2
- package/src/renderer/src-web/components/PicturesLibrary.tsx +3 -2
- package/src/renderer/src-web/components/PullToRefresh.tsx +107 -0
- package/src/renderer/src-web/components/SettingsWindow.tsx +28 -2
- package/src/renderer/src-web/css/app-shell.css +174 -96
- package/src/renderer/src-web/css/chat.css +1519 -316
- package/src/renderer/src-web/css/dashboard.css +11 -0
- package/src/renderer/src-web/css/misc.css +17 -17
- package/src/renderer/src-web/css/mobile.css +678 -0
- package/src/renderer/src-web/css/model.css +46 -46
- package/src/renderer/src-web/css/pictures.css +81 -34
- package/src/renderer/src-web/css/pull-to-refresh.css +54 -0
- package/src/renderer/src-web/css/settings/base.css +316 -100
- package/src/renderer/src-web/css/settings/mobile.css +320 -0
- package/src/renderer/src-web/css/sidebar-workspace.css +545 -100
- package/src/renderer/src-web/css/spotlight.css +9 -26
- package/src/renderer/src-web/css/widget.css +0 -5
- package/src/renderer/src-web/env.d.ts +3 -0
- package/src/renderer/src-web/hooks/useProviderModels.ts +2 -9
- package/src/renderer/src-web/index.css +53 -96
- package/src/renderer/src-web/main.tsx +11 -0
- package/src/renderer/src-web/tauri.ts +200 -30
- package/vite.config.web.ts +1 -0
- package/out/web/assets/MintDashboard-DWSqucgb.js +0 -57
- package/out/web/assets/SettingsWindow-DFM2aj5B.js +0 -2
- package/out/web/assets/chunk-CKBBP62Z-nr1uKPj9.js +0 -2
- package/out/web/assets/chunk-DSNCTWBM-Dtj8Rqsd.js +0 -2
- package/out/web/assets/chunk-DU6HZSFF-2tv5K1wT.js +0 -128
- package/out/web/assets/classDiagram-DTDB5LWJ-BdSFArgw.js +0 -1
- package/out/web/assets/classDiagram-v2-JRS7N3AN-BdSFArgw.js +0 -1
- package/out/web/assets/core-DImejIUG.js +0 -1
- package/out/web/assets/dist-js-BxuKEVWM.js +0 -1
- package/out/web/assets/event-BNl8Zahw.js +0 -1
- package/out/web/assets/fira-code-cyrillic-400-normal-UC0NFL4U.woff2 +0 -0
- package/out/web/assets/fira-code-cyrillic-400-normal-dc1q3VD7.woff +0 -0
- package/out/web/assets/fira-code-cyrillic-500-normal-Bu7VCL72.woff +0 -0
- package/out/web/assets/fira-code-cyrillic-500-normal-CX35h3Mg.woff2 +0 -0
- package/out/web/assets/fira-code-cyrillic-ext-400-normal-Buh61xzB.woff +0 -0
- package/out/web/assets/fira-code-cyrillic-ext-400-normal-txZ9Fk_1.woff2 +0 -0
- package/out/web/assets/fira-code-cyrillic-ext-500-normal-CYRspHgm.woff2 +0 -0
- package/out/web/assets/fira-code-cyrillic-ext-500-normal-CwtLmSFD.woff +0 -0
- package/out/web/assets/fira-code-greek-400-normal-B2Gh_Y8s.woff2 +0 -0
- package/out/web/assets/fira-code-greek-400-normal-DobhaxvF.woff +0 -0
- package/out/web/assets/fira-code-greek-500-normal-CVO0IRNt.woff2 +0 -0
- package/out/web/assets/fira-code-greek-500-normal-DEXIWiey.woff +0 -0
- package/out/web/assets/fira-code-greek-ext-400-normal-DR7mBgIM.woff2 +0 -0
- package/out/web/assets/fira-code-greek-ext-400-normal-DSPUheWg.woff +0 -0
- package/out/web/assets/fira-code-greek-ext-500-normal-BO3iq16n.woff2 +0 -0
- package/out/web/assets/fira-code-greek-ext-500-normal-CMiNLXER.woff +0 -0
- package/out/web/assets/fira-code-latin-ext-400-normal-DG73JjOf.woff +0 -0
- package/out/web/assets/fira-code-latin-ext-400-normal-KSMg0QLl.woff2 +0 -0
- package/out/web/assets/fira-code-latin-ext-500-normal-CaANqXjI.woff +0 -0
- package/out/web/assets/fira-code-latin-ext-500-normal-Crd9e_oI.woff2 +0 -0
- package/out/web/assets/flowDiagram-A5DVABFB-BpnHUSU7.js +0 -1
- package/out/web/assets/index-CVRg270z.css +0 -1
- package/out/web/assets/index-DxZQr9yD.js +0 -10
- package/out/web/assets/inter-cyrillic-400-normal-HOLc17fK.woff +0 -0
- package/out/web/assets/inter-cyrillic-400-normal-obahsSVq.woff2 +0 -0
- package/out/web/assets/inter-cyrillic-500-normal-BasfLYem.woff2 +0 -0
- package/out/web/assets/inter-cyrillic-500-normal-CxZf_p3X.woff +0 -0
- package/out/web/assets/inter-cyrillic-600-normal-4D_pXhcN.woff +0 -0
- package/out/web/assets/inter-cyrillic-600-normal-CWCymEST.woff2 +0 -0
- package/out/web/assets/inter-cyrillic-ext-400-normal-BQZuk6qB.woff2 +0 -0
- package/out/web/assets/inter-cyrillic-ext-400-normal-DQukG94-.woff +0 -0
- package/out/web/assets/inter-cyrillic-ext-500-normal-B0yAr1jD.woff2 +0 -0
- package/out/web/assets/inter-cyrillic-ext-500-normal-BmqWE9Dz.woff +0 -0
- package/out/web/assets/inter-cyrillic-ext-600-normal-Bcila6Z-.woff +0 -0
- package/out/web/assets/inter-cyrillic-ext-600-normal-Dfes3d0z.woff2 +0 -0
- package/out/web/assets/inter-greek-400-normal-B4URO6DV.woff2 +0 -0
- package/out/web/assets/inter-greek-400-normal-q2sYcFCs.woff +0 -0
- package/out/web/assets/inter-greek-500-normal-BIZE56-Y.woff2 +0 -0
- package/out/web/assets/inter-greek-500-normal-Xzm54t5V.woff +0 -0
- package/out/web/assets/inter-greek-600-normal-BZpKdvQh.woff +0 -0
- package/out/web/assets/inter-greek-600-normal-plRanbMR.woff2 +0 -0
- package/out/web/assets/inter-greek-ext-400-normal-DGGRlc-M.woff2 +0 -0
- package/out/web/assets/inter-greek-ext-400-normal-KugGGMne.woff +0 -0
- package/out/web/assets/inter-greek-ext-500-normal-2j5mBUwD.woff +0 -0
- package/out/web/assets/inter-greek-ext-500-normal-C4iEst2y.woff2 +0 -0
- package/out/web/assets/inter-greek-ext-600-normal-B8X0CLgF.woff +0 -0
- package/out/web/assets/inter-greek-ext-600-normal-DRtmH8MT.woff2 +0 -0
- package/out/web/assets/inter-latin-400-normal-C38fXH4l.woff2 +0 -0
- package/out/web/assets/inter-latin-400-normal-CyCys3Eg.woff +0 -0
- package/out/web/assets/inter-latin-500-normal-BL9OpVg8.woff +0 -0
- package/out/web/assets/inter-latin-500-normal-Cerq10X2.woff2 +0 -0
- package/out/web/assets/inter-latin-600-normal-CiBQ2DWP.woff +0 -0
- package/out/web/assets/inter-latin-600-normal-LgqL8muc.woff2 +0 -0
- package/out/web/assets/inter-latin-ext-400-normal-77YHD8bZ.woff +0 -0
- package/out/web/assets/inter-latin-ext-400-normal-C1nco2VV.woff2 +0 -0
- package/out/web/assets/inter-latin-ext-500-normal-BxGbmqWO.woff +0 -0
- package/out/web/assets/inter-latin-ext-500-normal-CV4jyFjo.woff2 +0 -0
- package/out/web/assets/inter-latin-ext-600-normal-CIVaiw4L.woff +0 -0
- package/out/web/assets/inter-latin-ext-600-normal-D2bJ5OIk.woff2 +0 -0
- package/out/web/assets/inter-vietnamese-400-normal-Bbgyi5SW.woff +0 -0
- package/out/web/assets/inter-vietnamese-400-normal-DMkecbls.woff2 +0 -0
- package/out/web/assets/inter-vietnamese-500-normal-DOriooB6.woff2 +0 -0
- package/out/web/assets/inter-vietnamese-500-normal-mJboJaSs.woff +0 -0
- package/out/web/assets/inter-vietnamese-600-normal-BuLX-rYi.woff +0 -0
- package/out/web/assets/inter-vietnamese-600-normal-Cc8MFFhd.woff2 +0 -0
- package/out/web/assets/kanit-latin-400-normal-BUlsQXH3.woff2 +0 -0
- package/out/web/assets/kanit-latin-400-normal-HVZWrfev.woff +0 -0
- package/out/web/assets/kanit-latin-500-normal-CX_4XcKi.woff2 +0 -0
- package/out/web/assets/kanit-latin-500-normal-qBha86O4.woff +0 -0
- package/out/web/assets/kanit-latin-600-normal-0lS78yAd.woff2 +0 -0
- package/out/web/assets/kanit-latin-600-normal-DlacpeTg.woff +0 -0
- package/out/web/assets/kanit-latin-ext-400-normal-B2xPf58u.woff2 +0 -0
- package/out/web/assets/kanit-latin-ext-400-normal-CHvNKHHD.woff +0 -0
- package/out/web/assets/kanit-latin-ext-500-normal-BFdWrG22.woff +0 -0
- package/out/web/assets/kanit-latin-ext-500-normal-EHs3suD6.woff2 +0 -0
- package/out/web/assets/kanit-latin-ext-600-normal-BBDzoLaj.woff +0 -0
- package/out/web/assets/kanit-latin-ext-600-normal-DAX3wtuq.woff2 +0 -0
- package/out/web/assets/kanit-thai-400-normal-D2nliXKa.woff +0 -0
- package/out/web/assets/kanit-thai-400-normal-D80Pglro.woff2 +0 -0
- package/out/web/assets/kanit-thai-500-normal-BB8gri04.woff2 +0 -0
- package/out/web/assets/kanit-thai-500-normal-Iy_w0a80.woff +0 -0
- package/out/web/assets/kanit-thai-600-normal-Bj6oiaDc.woff2 +0 -0
- package/out/web/assets/kanit-thai-600-normal-wbTlPO7I.woff +0 -0
- package/out/web/assets/kanit-vietnamese-400-normal-DRI8YWyb.woff2 +0 -0
- package/out/web/assets/kanit-vietnamese-400-normal-dow6Bnto.woff +0 -0
- package/out/web/assets/kanit-vietnamese-500-normal-BzTrpCM3.woff2 +0 -0
- package/out/web/assets/kanit-vietnamese-500-normal-T1ndT7MF.woff +0 -0
- package/out/web/assets/kanit-vietnamese-600-normal-Bi7fw3I4.woff2 +0 -0
- package/out/web/assets/kanit-vietnamese-600-normal-DXCRAa_8.woff +0 -0
- package/out/web/assets/mali-latin-400-normal-ByPcZ8Gx.woff +0 -0
- package/out/web/assets/mali-latin-400-normal-Cuc6Ykl8.woff2 +0 -0
- package/out/web/assets/mali-latin-500-normal-B01M-LP6.woff2 +0 -0
- package/out/web/assets/mali-latin-500-normal-Thgqw_9f.woff +0 -0
- package/out/web/assets/mali-latin-600-normal-B9TiUNpT.woff2 +0 -0
- package/out/web/assets/mali-latin-600-normal-CycpQCwU.woff +0 -0
- package/out/web/assets/mali-latin-ext-400-normal-DUVdJQO4.woff +0 -0
- package/out/web/assets/mali-latin-ext-400-normal-iCG1ALuJ.woff2 +0 -0
- package/out/web/assets/mali-latin-ext-500-normal-BfJE4UMZ.woff2 +0 -0
- package/out/web/assets/mali-latin-ext-500-normal-FoLEyOKS.woff +0 -0
- package/out/web/assets/mali-latin-ext-600-normal-BTvIfiCp.woff2 +0 -0
- package/out/web/assets/mali-latin-ext-600-normal-DAQcLVmD.woff +0 -0
- package/out/web/assets/mali-thai-400-normal-BO7A3bLZ.woff2 +0 -0
- package/out/web/assets/mali-thai-400-normal-CX9VrjTn.woff +0 -0
- package/out/web/assets/mali-thai-500-normal-Cph2qha9.woff +0 -0
- package/out/web/assets/mali-thai-500-normal-D89rMT77.woff2 +0 -0
- package/out/web/assets/mali-thai-600-normal-DPgXT6rZ.woff +0 -0
- package/out/web/assets/mali-thai-600-normal-DlTx3OsB.woff2 +0 -0
- package/out/web/assets/mali-vietnamese-400-normal-DUKxzXaz.woff2 +0 -0
- package/out/web/assets/mali-vietnamese-400-normal-gFDLvsOK.woff +0 -0
- package/out/web/assets/mali-vietnamese-500-normal--OY07q2c.woff +0 -0
- package/out/web/assets/mali-vietnamese-500-normal-KDrNRwfW.woff2 +0 -0
- package/out/web/assets/mali-vietnamese-600-normal-CtTMUU7T.woff +0 -0
- package/out/web/assets/mali-vietnamese-600-normal-DFlJr66u.woff2 +0 -0
- package/out/web/assets/mermaid.core-DYGGlqOf.js +0 -11
- package/out/web/assets/mitr-latin-400-normal-Cb18vPmZ.woff +0 -0
- package/out/web/assets/mitr-latin-400-normal-CwbkLQ4a.woff2 +0 -0
- package/out/web/assets/mitr-latin-500-normal-B4JOhzAi.woff +0 -0
- package/out/web/assets/mitr-latin-500-normal-BmClOow2.woff2 +0 -0
- package/out/web/assets/mitr-latin-ext-400-normal-B3CPG7Yo.woff2 +0 -0
- package/out/web/assets/mitr-latin-ext-400-normal-DTx65hiC.woff +0 -0
- package/out/web/assets/mitr-latin-ext-500-normal-B_Diajz1.woff2 +0 -0
- package/out/web/assets/mitr-latin-ext-500-normal-DYOsVaVT.woff +0 -0
- package/out/web/assets/mitr-thai-400-normal-CS4Do6aM.woff +0 -0
- package/out/web/assets/mitr-thai-400-normal-CXWaAdVj.woff2 +0 -0
- package/out/web/assets/mitr-thai-500-normal-CVdBrEVH.woff2 +0 -0
- package/out/web/assets/mitr-thai-500-normal-CW_B5D-i.woff +0 -0
- package/out/web/assets/mitr-vietnamese-400-normal-CPMGWyoC.woff2 +0 -0
- package/out/web/assets/mitr-vietnamese-400-normal-Z6XhIpdY.woff +0 -0
- package/out/web/assets/mitr-vietnamese-500-normal-CDrv0585.woff2 +0 -0
- package/out/web/assets/mitr-vietnamese-500-normal-CMQWyq-Z.woff +0 -0
- package/out/web/assets/noto-sans-thai-latin-400-normal-BaWBrqFP.woff2 +0 -0
- package/out/web/assets/noto-sans-thai-latin-400-normal-Dh_FJjOB.woff +0 -0
- package/out/web/assets/noto-sans-thai-latin-500-normal-BC04jsmm.woff +0 -0
- package/out/web/assets/noto-sans-thai-latin-500-normal-fyBKClF1.woff2 +0 -0
- package/out/web/assets/noto-sans-thai-latin-600-normal-CemcjnVR.woff2 +0 -0
- package/out/web/assets/noto-sans-thai-latin-600-normal-Dbc-dNO6.woff +0 -0
- package/out/web/assets/noto-sans-thai-latin-ext-400-normal-B-1H0YkH.woff +0 -0
- package/out/web/assets/noto-sans-thai-latin-ext-400-normal-nBP59pVw.woff2 +0 -0
- package/out/web/assets/noto-sans-thai-latin-ext-500-normal-B-ZWb8SZ.woff2 +0 -0
- package/out/web/assets/noto-sans-thai-latin-ext-500-normal-CrEHO7C8.woff +0 -0
- package/out/web/assets/noto-sans-thai-latin-ext-600-normal-PkMZo0xa.woff +0 -0
- package/out/web/assets/noto-sans-thai-latin-ext-600-normal-maHHBsez.woff2 +0 -0
- package/out/web/assets/noto-sans-thai-thai-400-normal-BEOmKAI1.woff2 +0 -0
- package/out/web/assets/noto-sans-thai-thai-400-normal-Dxb_unuU.woff +0 -0
- package/out/web/assets/noto-sans-thai-thai-500-normal-BOGXO2tw.woff +0 -0
- package/out/web/assets/noto-sans-thai-thai-500-normal-CU_X86GQ.woff2 +0 -0
- package/out/web/assets/noto-sans-thai-thai-600-normal-CmgB8_JK.woff +0 -0
- package/out/web/assets/noto-sans-thai-thai-600-normal-Cs73sVjl.woff2 +0 -0
- package/out/web/assets/oauthManager-DNiwM8Rn.js +0 -2
- package/out/web/assets/oauthManager-DuamS1Av.css +0 -1
- package/out/web/assets/outfit-latin-300-normal-AWLfuCom.woff +0 -0
- package/out/web/assets/outfit-latin-300-normal-CRYTwY6m.woff2 +0 -0
- package/out/web/assets/outfit-latin-400-normal-BGsTXAXT.woff2 +0 -0
- package/out/web/assets/outfit-latin-400-normal-DMwTpYkH.woff +0 -0
- package/out/web/assets/outfit-latin-500-normal-ClnHRwRh.woff +0 -0
- package/out/web/assets/outfit-latin-500-normal-DKnIMDSk.woff2 +0 -0
- package/out/web/assets/outfit-latin-600-normal-B7SfZ07L.woff2 +0 -0
- package/out/web/assets/outfit-latin-600-normal-BEfTtDA7.woff +0 -0
- package/out/web/assets/outfit-latin-ext-300-normal-BYS6Dpvq.woff2 +0 -0
- package/out/web/assets/outfit-latin-ext-300-normal-CMIMshEd.woff +0 -0
- package/out/web/assets/outfit-latin-ext-400-normal-5tcqmc2S.woff2 +0 -0
- package/out/web/assets/outfit-latin-ext-400-normal-DHm7mdGe.woff +0 -0
- package/out/web/assets/outfit-latin-ext-500-normal-DrCvqoFD.woff +0 -0
- package/out/web/assets/outfit-latin-ext-500-normal-zeox_O30.woff2 +0 -0
- package/out/web/assets/outfit-latin-ext-600-normal-B85nYjL1.woff2 +0 -0
- package/out/web/assets/outfit-latin-ext-600-normal-CWJcPgd7.woff +0 -0
- package/out/web/assets/preload-helper-D0uHx7FM.js +0 -1
- package/out/web/assets/prompt-latin-ext-400-normal-1pHbN9uy.woff +0 -0
- package/out/web/assets/prompt-latin-ext-400-normal-DdSafGZ9.woff2 +0 -0
- package/out/web/assets/prompt-latin-ext-500-normal--EZ1um7s.woff2 +0 -0
- package/out/web/assets/prompt-latin-ext-500-normal-D-lI1EVT.woff +0 -0
- package/out/web/assets/prompt-latin-ext-600-normal-C8b50x67.woff +0 -0
- package/out/web/assets/prompt-latin-ext-600-normal-Cg9L7iJU.woff2 +0 -0
- package/out/web/assets/prompt-vietnamese-400-normal-BCPzsgPT.woff2 +0 -0
- package/out/web/assets/prompt-vietnamese-400-normal-D4pLyeNK.woff +0 -0
- package/out/web/assets/prompt-vietnamese-500-normal-DmzxmPwa.woff2 +0 -0
- package/out/web/assets/prompt-vietnamese-500-normal-w_sS_j2F.woff +0 -0
- package/out/web/assets/prompt-vietnamese-600-normal-1dyohtNh.woff +0 -0
- package/out/web/assets/prompt-vietnamese-600-normal-7QWjJBsF.woff2 +0 -0
- package/out/web/assets/sarabun-latin-400-normal-DmguIS-7.woff +0 -0
- package/out/web/assets/sarabun-latin-400-normal-URPBxl-K.woff2 +0 -0
- package/out/web/assets/sarabun-latin-500-normal-BjUTcdxu.woff2 +0 -0
- package/out/web/assets/sarabun-latin-500-normal-CJexTAnl.woff +0 -0
- package/out/web/assets/sarabun-latin-600-normal-9FonlkKx.woff +0 -0
- package/out/web/assets/sarabun-latin-600-normal-DMD3TROr.woff2 +0 -0
- package/out/web/assets/sarabun-latin-ext-400-normal-BbP7GpLL.woff2 +0 -0
- package/out/web/assets/sarabun-latin-ext-400-normal-BsmTn0SS.woff +0 -0
- package/out/web/assets/sarabun-latin-ext-500-normal-Cot16Bd2.woff +0 -0
- package/out/web/assets/sarabun-latin-ext-500-normal-DE1LysqI.woff2 +0 -0
- package/out/web/assets/sarabun-latin-ext-600-normal-0tXu9x_i.woff +0 -0
- package/out/web/assets/sarabun-latin-ext-600-normal-BRxjKUQ6.woff2 +0 -0
- package/out/web/assets/sarabun-thai-400-normal-C2DaJlKK.woff2 +0 -0
- package/out/web/assets/sarabun-thai-400-normal-CH-UbWgg.woff +0 -0
- package/out/web/assets/sarabun-thai-500-normal-BVssjame.woff2 +0 -0
- package/out/web/assets/sarabun-thai-500-normal-C3iDLEzi.woff +0 -0
- package/out/web/assets/sarabun-thai-600-normal-3dIAQ-_s.woff2 +0 -0
- package/out/web/assets/sarabun-thai-600-normal-DWKeTe6a.woff +0 -0
- package/out/web/assets/sarabun-vietnamese-400-normal-DPfkSCMy.woff +0 -0
- package/out/web/assets/sarabun-vietnamese-400-normal-igdrzAGY.woff2 +0 -0
- package/out/web/assets/sarabun-vietnamese-500-normal-CpRVvGRU.woff +0 -0
- package/out/web/assets/sarabun-vietnamese-500-normal-Dpe7Br9m.woff2 +0 -0
- package/out/web/assets/sarabun-vietnamese-600-normal-BMbOgAW-.woff +0 -0
- package/out/web/assets/sarabun-vietnamese-600-normal-DkxrOlLB.woff2 +0 -0
- package/out/web/assets/stateDiagram-v2-4QOOHH4V-s6P9g2_b.js +0 -1
- package/out/web/assets/swimlanesDiagram-VK2B7HYN-CV9fOLrV.js +0 -8
- package/out/web/assets/tauri-CNrHQ2Gb.js +0 -3
- package/out/web/assets/window-DkIhgI7B.js +0 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useEffect, useMemo, useRef, useState, useCallback, Fragment, type ChangeEvent, type ClipboardEvent, type DragEvent, type FormEvent, type KeyboardEvent, type RefObject } from 'react'
|
|
2
|
-
import { hasAgentToolActivity, thoughtsFrom, parseFileChangesFromProgress } from '../agentProgress'
|
|
2
|
+
import { hasAgentToolActivity, thoughtsFrom, extendedThoughtsFrom, mergeFileChanges, parseFileChangesFromProgress } from '../agentProgress'
|
|
3
|
+
import { visibleInteractionsDuringRun } from '../conversation/syncView'
|
|
3
4
|
import {
|
|
4
5
|
GEMINI_MODELS,
|
|
5
6
|
OPENAI_MODELS,
|
|
@@ -25,32 +26,61 @@ import ChatMessageItem from './ChatMessageItem'
|
|
|
25
26
|
import { AgentActivityDrawer } from './AgentActivityDrawer'
|
|
26
27
|
import { ArtifactPreviewPanel, type ArtifactFile } from './ArtifactPreviewPanel'
|
|
27
28
|
import { RewindModal } from './RewindModal'
|
|
28
|
-
import type { DiffHunk, FileChange, GitCheckpoint } from '../types'
|
|
29
|
+
import type { AgentProgress, ChatResponse, DiffHunk, FileChange, GitCheckpoint, RuntimeStatus } from '../types'
|
|
29
30
|
import { numericSetting, shouldShowSessionDivider, formatSessionDividerLabel } from '../utils/ui'
|
|
30
31
|
import { useVoiceInput } from '@/voiceInput'
|
|
31
32
|
import { useGeminiLiveVoice } from '../utils/useGeminiLiveVoice'
|
|
32
33
|
import GeminiLiveOverlay from './GeminiLiveOverlay'
|
|
33
34
|
import { isSupportedDocument, SUPPORTED_DOCUMENT_ACCEPT } from '../utils/documentTypes'
|
|
34
35
|
import ModelSelectorPopover from './ModelSelectorPopover'
|
|
36
|
+
import GitBranchSelector from './GitBranchSelector'
|
|
37
|
+
import WorkspaceSelector from './WorkspaceSelector'
|
|
38
|
+
import CodeReviewPage from './CodeReviewPage'
|
|
39
|
+
import type { ToolSurface } from './ToolSurfacePage'
|
|
35
40
|
|
|
36
|
-
import {
|
|
37
|
-
APP_ICON_PATH,
|
|
38
|
-
type AgentProgress,
|
|
39
|
-
type ChatResponse,
|
|
40
|
-
type RuntimeStatus,
|
|
41
|
-
getTtsUrls,
|
|
42
|
-
startGeminiLiveSession,
|
|
43
|
-
sendGeminiLiveAudioChunk,
|
|
44
|
-
stopGeminiLiveSession,
|
|
45
|
-
listGitCheckpoints,
|
|
46
|
-
rollbackGitCheckpoint,
|
|
47
|
-
undoGitCheckpoint,
|
|
48
|
-
fetchProviderModels,
|
|
49
|
-
} from '@/tauri'
|
|
41
|
+
import { catalogPlatform, conversationPlatform, runtimePlatform } from '../platform'
|
|
50
42
|
|
|
43
|
+
const STREAM_MARKDOWN_UPDATE_MS = 120
|
|
51
44
|
|
|
52
|
-
|
|
45
|
+
function useThrottledValue<T>(value: T, intervalMs: number): T {
|
|
46
|
+
const [throttledValue, setThrottledValue] = useState(value)
|
|
47
|
+
const latestValueRef = useRef(value)
|
|
48
|
+
const lastUpdateRef = useRef(0)
|
|
49
|
+
const timerRef = useRef<ReturnType<typeof window.setTimeout> | null>(null)
|
|
50
|
+
|
|
51
|
+
useEffect(() => {
|
|
52
|
+
latestValueRef.current = value
|
|
53
|
+
if (Object.is(value, throttledValue)) return
|
|
54
|
+
|
|
55
|
+
const flush = () => {
|
|
56
|
+
timerRef.current = null
|
|
57
|
+
lastUpdateRef.current = Date.now()
|
|
58
|
+
setThrottledValue(latestValueRef.current)
|
|
59
|
+
}
|
|
60
|
+
const remaining = intervalMs - (Date.now() - lastUpdateRef.current)
|
|
61
|
+
if (remaining <= 0) flush()
|
|
62
|
+
else if (timerRef.current === null) timerRef.current = window.setTimeout(flush, remaining)
|
|
63
|
+
}, [value, throttledValue, intervalMs])
|
|
64
|
+
|
|
65
|
+
useEffect(() => () => {
|
|
66
|
+
if (timerRef.current !== null) window.clearTimeout(timerRef.current)
|
|
67
|
+
}, [])
|
|
68
|
+
|
|
69
|
+
return throttledValue
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const {
|
|
73
|
+
getTtsUrls, startGeminiLiveSession, sendGeminiLiveAudioChunk, stopGeminiLiveSession,
|
|
74
|
+
listGitCheckpoints, rollbackGitCheckpoint, undoGitCheckpoint,
|
|
75
|
+
} = conversationPlatform
|
|
76
|
+
const { fetchProviderModels } = catalogPlatform
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
interface ChatPanelContract {
|
|
53
80
|
interactions: any[]
|
|
81
|
+
sendingInteractionId?: number | null
|
|
82
|
+
hasOlder?: boolean
|
|
83
|
+
onLoadOlder?: () => Promise<void>
|
|
54
84
|
sending: boolean
|
|
55
85
|
sendingMessage: string
|
|
56
86
|
sendingImageCount: number
|
|
@@ -66,13 +96,13 @@ interface ChatPanelProps {
|
|
|
66
96
|
videoAttachments: Array<{ dataUri: string; name: string }>
|
|
67
97
|
documentName: string
|
|
68
98
|
pendingApproval: any | null
|
|
69
|
-
smartContext: boolean
|
|
70
99
|
agentMode: boolean
|
|
71
100
|
/** Desktop only — plan-mode-approval UI isn't available on web. */
|
|
72
101
|
planMode?: boolean
|
|
73
102
|
status: RuntimeStatus | null
|
|
74
103
|
/** Desktop only — web has no local workspace-folder concept to select from. */
|
|
75
104
|
workspacePath?: string
|
|
105
|
+
chatId: string
|
|
76
106
|
chatEnd: RefObject<HTMLDivElement | null>
|
|
77
107
|
welcomeInteraction: any
|
|
78
108
|
onSubmit: (event: FormEvent<HTMLFormElement>) => void
|
|
@@ -87,15 +117,17 @@ interface ChatPanelProps {
|
|
|
87
117
|
onRemoveDocument: () => void
|
|
88
118
|
onStartWebSearch: () => void
|
|
89
119
|
onCaptureScreen: () => void
|
|
90
|
-
onSetSmartContext: (enabled: boolean) => void
|
|
91
120
|
onSetAgentMode: (enabled: boolean) => void
|
|
92
121
|
/** Desktop only — see `planMode`. */
|
|
93
122
|
onSetPlanMode?: (enabled: boolean) => void
|
|
94
123
|
onSetProvider: (provider: string) => void
|
|
95
124
|
/** Desktop only — see `workspacePath`. */
|
|
96
|
-
onSelectWorkspace?: () => void
|
|
125
|
+
onSelectWorkspace?: (path?: string) => void
|
|
126
|
+
onWorkspaceChanged?: () => void
|
|
127
|
+
recentWorkspacePaths: string[]
|
|
97
128
|
onApproval: (approved: boolean, autoApproveSession?: boolean, answer?: string) => void
|
|
98
129
|
settingsConfig: any
|
|
130
|
+
onUpdateSettings?: (config: any) => void
|
|
99
131
|
onSetModel: (model: string) => void
|
|
100
132
|
onSelectModelAndProvider?: (provider: string, model: string) => void
|
|
101
133
|
onCancelMessage: () => void
|
|
@@ -103,11 +135,40 @@ interface ChatPanelProps {
|
|
|
103
135
|
onSetGeminiLiveVoice: (voice: string) => Promise<void>
|
|
104
136
|
/** Web only — desktop's window has no mobile-width sidebar to toggle. */
|
|
105
137
|
onToggleMobileSidebar?: () => void
|
|
138
|
+
isCliSession?: boolean
|
|
139
|
+
cliSessionId?: string
|
|
140
|
+
onBackToCode?: () => void
|
|
141
|
+
conversationTitle?: string
|
|
142
|
+
onOpenArtifact?: (artifact: ArtifactFile) => void
|
|
143
|
+
onOpenReview?: (review: Extract<ToolSurface, { kind: 'review' }>) => void
|
|
106
144
|
}
|
|
107
145
|
|
|
146
|
+
export type ConversationViewModel = Pick<ChatPanelContract,
|
|
147
|
+
| 'interactions' | 'sending' | 'sendingMessage' | 'sendingImageCount' | 'sendingVideoCount'
|
|
148
|
+
| 'streamedReply' | 'streamedResponse' | 'agentProgress' | 'agentActivitySnapshots'
|
|
149
|
+
| 'thinkingExpanded' | 'message' | 'imageAttachments' | 'videoAttachments' | 'documentName'
|
|
150
|
+
| 'pendingApproval' | 'agentMode' | 'planMode' | 'status' | 'workspacePath' | 'chatId' | 'recentWorkspacePaths'
|
|
151
|
+
| 'chatEnd' | 'welcomeInteraction' | 'settingsConfig' | 'isCliSession' | 'cliSessionId'
|
|
152
|
+
| 'conversationTitle'
|
|
153
|
+
| 'hasOlder'
|
|
154
|
+
| 'sendingInteractionId'
|
|
155
|
+
>
|
|
156
|
+
export type ConversationActions = Omit<ChatPanelContract, keyof ConversationViewModel>
|
|
157
|
+
|
|
158
|
+
interface ChatPanelProps {
|
|
159
|
+
conversation: ConversationViewModel
|
|
160
|
+
actions: ConversationActions
|
|
161
|
+
}
|
|
108
162
|
|
|
109
163
|
export default function ChatPanel({
|
|
164
|
+
conversation,
|
|
165
|
+
actions,
|
|
166
|
+
}: ChatPanelProps) {
|
|
167
|
+
const {
|
|
110
168
|
interactions,
|
|
169
|
+
sendingInteractionId,
|
|
170
|
+
hasOlder,
|
|
171
|
+
onLoadOlder,
|
|
111
172
|
sending,
|
|
112
173
|
sendingMessage,
|
|
113
174
|
sendingImageCount,
|
|
@@ -123,11 +184,12 @@ export default function ChatPanel({
|
|
|
123
184
|
videoAttachments,
|
|
124
185
|
documentName,
|
|
125
186
|
pendingApproval,
|
|
126
|
-
smartContext,
|
|
127
187
|
agentMode,
|
|
128
188
|
planMode,
|
|
129
189
|
status,
|
|
130
190
|
workspacePath,
|
|
191
|
+
chatId,
|
|
192
|
+
recentWorkspacePaths,
|
|
131
193
|
chatEnd,
|
|
132
194
|
welcomeInteraction,
|
|
133
195
|
onSubmit,
|
|
@@ -142,21 +204,71 @@ export default function ChatPanel({
|
|
|
142
204
|
onRemoveDocument,
|
|
143
205
|
onStartWebSearch,
|
|
144
206
|
onCaptureScreen,
|
|
145
|
-
onSetSmartContext,
|
|
146
207
|
onSetAgentMode,
|
|
147
208
|
onSetPlanMode,
|
|
148
209
|
onSetProvider,
|
|
149
210
|
onSelectWorkspace,
|
|
211
|
+
onWorkspaceChanged,
|
|
150
212
|
onApproval,
|
|
151
213
|
settingsConfig,
|
|
214
|
+
onUpdateSettings,
|
|
152
215
|
onSetModel,
|
|
153
216
|
onSelectModelAndProvider,
|
|
154
217
|
onCancelMessage,
|
|
155
218
|
onClearMessages,
|
|
156
219
|
onSetGeminiLiveVoice,
|
|
157
220
|
onToggleMobileSidebar,
|
|
158
|
-
|
|
221
|
+
isCliSession,
|
|
222
|
+
cliSessionId,
|
|
223
|
+
onBackToCode,
|
|
224
|
+
conversationTitle,
|
|
225
|
+
onOpenArtifact,
|
|
226
|
+
onOpenReview,
|
|
227
|
+
} = { ...conversation, ...actions }
|
|
228
|
+
// The initiating surface already renders a live prompt/reply pair below.
|
|
229
|
+
// Hide its matching persisted turn until the local stream settles, while
|
|
230
|
+
// still showing turns submitted from other surfaces during that time.
|
|
231
|
+
const visibleInteractions = useMemo(
|
|
232
|
+
() => visibleInteractionsDuringRun(interactions, sending, sendingInteractionId),
|
|
233
|
+
[interactions, sending, sendingInteractionId],
|
|
234
|
+
)
|
|
159
235
|
const agentActivities = activitiesFrom(agentProgress)
|
|
236
|
+
// Keep the composer summary tied to the active/latest agent run. This is cheap
|
|
237
|
+
// metadata, but memoizing it avoids parsing the activity stream while typing.
|
|
238
|
+
const composerChanges = useMemo(() => parseFileChangesFromProgress(agentProgress), [agentProgress])
|
|
239
|
+
const composerAdditions = useMemo(
|
|
240
|
+
() => composerChanges.reduce((sum, change) => sum + change.additions, 0),
|
|
241
|
+
[composerChanges],
|
|
242
|
+
)
|
|
243
|
+
const composerDeletions = useMemo(
|
|
244
|
+
() => composerChanges.reduce((sum, change) => sum + change.deletions, 0),
|
|
245
|
+
[composerChanges],
|
|
246
|
+
)
|
|
247
|
+
const composerChangeLabel = composerChanges.length === 1
|
|
248
|
+
? '1 file changed'
|
|
249
|
+
: `${composerChanges.length} files changed`
|
|
250
|
+
const conversationChanges = useMemo(() => {
|
|
251
|
+
const historicalGroups = interactions.map((interaction) => {
|
|
252
|
+
const interactionId = String(interaction.id)
|
|
253
|
+
const progress = agentActivitySnapshots[interactionId] ?? interaction.agentActivity ?? []
|
|
254
|
+
return parseFileChangesFromProgress(progress)
|
|
255
|
+
})
|
|
256
|
+
const activeChanges = parseFileChangesFromProgress(agentProgress)
|
|
257
|
+
return mergeFileChanges([...historicalGroups, activeChanges])
|
|
258
|
+
}, [agentActivitySnapshots, agentProgress, interactions])
|
|
259
|
+
|
|
260
|
+
const projectName = useMemo(() => {
|
|
261
|
+
if (!workspacePath) return null
|
|
262
|
+
const clean = workspacePath.replace(/[\\/]+$/, '').trim()
|
|
263
|
+
if (!clean) return null
|
|
264
|
+
const parts = clean.split(/[\\/]/)
|
|
265
|
+
return parts[parts.length - 1] || clean
|
|
266
|
+
}, [workspacePath])
|
|
267
|
+
|
|
268
|
+
// Markdown parsing can be expensive for code, tables, and interactive cards.
|
|
269
|
+
// Limit it to a steady cadence instead of parsing on every stream chunk.
|
|
270
|
+
const throttledStreamedReply = useThrottledValue(streamedReply, STREAM_MARKDOWN_UPDATE_MS)
|
|
271
|
+
const liveWebSources = useMemo(() => parseWebSearchSources(agentProgress), [agentProgress])
|
|
160
272
|
const activeFallbackNotice = fallbackNotice(streamedResponse)
|
|
161
273
|
const lastThinkingProgress = [...agentProgress].reverse().find(p => p.type === 'Thinking')
|
|
162
274
|
let activeAgentName: string | null = null
|
|
@@ -168,11 +280,23 @@ export default function ChatPanel({
|
|
|
168
280
|
const [openActivityIds, setOpenActivityIds] = useState<Record<string, boolean>>({})
|
|
169
281
|
const [openReviewIds, setOpenReviewIds] = useState<Record<string, boolean>>({})
|
|
170
282
|
const [openFileDiffs, setOpenFileDiffs] = useState<Record<string, boolean>>({})
|
|
283
|
+
const [showAllFileChanges, setShowAllFileChanges] = useState<Record<string, boolean>>({})
|
|
284
|
+
const [reviewPage, setReviewPage] = useState<{ title: string; changes: FileChange[] } | null>(null)
|
|
171
285
|
const [activeArtifact, setActiveArtifact] = useState<ArtifactFile | null>(null)
|
|
172
286
|
const [toolMenuOpen, setToolMenuOpen] = useState(false)
|
|
173
287
|
const [elapsedSeconds, setElapsedSeconds] = useState(0)
|
|
174
288
|
const [dynamicOllamaModels, setDynamicOllamaModels] = useState<string[]>(OLLAMA_MODELS)
|
|
175
289
|
|
|
290
|
+
const openArtifact = (artifact: ArtifactFile) => {
|
|
291
|
+
if (onOpenArtifact) onOpenArtifact(artifact)
|
|
292
|
+
else setActiveArtifact(artifact)
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
const openReview = (title: string, changes: FileChange[]) => {
|
|
296
|
+
if (onOpenReview) onOpenReview({ id: `review:${Date.now()}`, kind: 'review', title: 'Review', reviewTitle: title, changes })
|
|
297
|
+
else setReviewPage({ title, changes })
|
|
298
|
+
}
|
|
299
|
+
|
|
176
300
|
useEffect(() => {
|
|
177
301
|
let cancelled = false
|
|
178
302
|
const fetchOllamaModels = async () => {
|
|
@@ -239,7 +363,9 @@ export default function ChatPanel({
|
|
|
239
363
|
|
|
240
364
|
const chatContainerRef = useRef<HTMLDivElement | null>(null)
|
|
241
365
|
const [showScrollToBottom, setShowScrollToBottom] = useState(false)
|
|
366
|
+
const [loadingOlder, setLoadingOlder] = useState(false)
|
|
242
367
|
const isNearBottomRef = useRef(true)
|
|
368
|
+
const scrollFrameRef = useRef<number | null>(null)
|
|
243
369
|
|
|
244
370
|
const handleChatScroll = useCallback(() => {
|
|
245
371
|
const el = chatContainerRef.current
|
|
@@ -250,6 +376,26 @@ export default function ChatPanel({
|
|
|
250
376
|
isNearBottomRef.current = nearBottom
|
|
251
377
|
}, [])
|
|
252
378
|
|
|
379
|
+
const scheduleScrollToLatest = useCallback(() => {
|
|
380
|
+
if (!isNearBottomRef.current || scrollFrameRef.current !== null) return
|
|
381
|
+
scrollFrameRef.current = window.requestAnimationFrame(() => {
|
|
382
|
+
scrollFrameRef.current = null
|
|
383
|
+
const element = chatContainerRef.current
|
|
384
|
+
if (element && isNearBottomRef.current) {
|
|
385
|
+
// Smooth scrolling on every token restarts animations and causes jank.
|
|
386
|
+
element.scrollTop = element.scrollHeight
|
|
387
|
+
}
|
|
388
|
+
})
|
|
389
|
+
}, [])
|
|
390
|
+
|
|
391
|
+
useEffect(() => {
|
|
392
|
+
scheduleScrollToLatest()
|
|
393
|
+
}, [interactions, sending, streamedReply, pendingApproval, agentProgress, scheduleScrollToLatest])
|
|
394
|
+
|
|
395
|
+
useEffect(() => () => {
|
|
396
|
+
if (scrollFrameRef.current !== null) window.cancelAnimationFrame(scrollFrameRef.current)
|
|
397
|
+
}, [])
|
|
398
|
+
|
|
253
399
|
useEffect(() => {
|
|
254
400
|
const el = chatContainerRef.current
|
|
255
401
|
if (!el) return
|
|
@@ -560,6 +706,7 @@ export default function ChatPanel({
|
|
|
560
706
|
const geminiLiveEnabled = settingsConfig?.voiceMode === 'geminiLive'
|
|
561
707
|
const geminiLive = useGeminiLiveVoice({
|
|
562
708
|
workspacePath,
|
|
709
|
+
chatId,
|
|
563
710
|
startSession: startGeminiLiveSession,
|
|
564
711
|
sendAudioChunk: sendGeminiLiveAudioChunk,
|
|
565
712
|
stopSession: stopGeminiLiveSession
|
|
@@ -631,9 +778,6 @@ export default function ChatPanel({
|
|
|
631
778
|
}
|
|
632
779
|
}
|
|
633
780
|
const activeModel = getActiveModel(activeProvider)
|
|
634
|
-
const workspaceName = workspacePath
|
|
635
|
-
? workspacePath.split(/[\\/]/).filter(Boolean).pop() || workspacePath
|
|
636
|
-
: 'Select Project'
|
|
637
781
|
const textareaRef = useRef<HTMLTextAreaElement>(null)
|
|
638
782
|
const slashRef = useRef<SlashSuggestionsHandle>(null)
|
|
639
783
|
|
|
@@ -993,9 +1137,11 @@ export default function ChatPanel({
|
|
|
993
1137
|
}, [agentActivitySnapshots])
|
|
994
1138
|
|
|
995
1139
|
const renderChangesList = (changes: ReturnType<typeof parseFileChangesFromProgress>, idPrefix: string) => {
|
|
1140
|
+
const showAll = Boolean(showAllFileChanges[idPrefix])
|
|
1141
|
+
const visibleChanges = showAll ? changes : changes.slice(0, 3)
|
|
996
1142
|
return (
|
|
997
|
-
<div style={{ display: 'flex', flexDirection: 'column', gap: '6px' }}>
|
|
998
|
-
{
|
|
1143
|
+
<div className="file-changes-list" style={{ display: 'flex', flexDirection: 'column', gap: '6px' }}>
|
|
1144
|
+
{visibleChanges.map((change) => {
|
|
999
1145
|
const fileKey = `${idPrefix}-${change.path}`
|
|
1000
1146
|
const isDiffOpen = Boolean(openFileDiffs[fileKey])
|
|
1001
1147
|
const fileName = change.path.split('/').pop() || change.path
|
|
@@ -1042,7 +1188,7 @@ export default function ChatPanel({
|
|
|
1042
1188
|
change.created && change.hunks.length > 0
|
|
1043
1189
|
? change.hunks.map((h) => h.newText).filter(Boolean).join('\n')
|
|
1044
1190
|
: undefined
|
|
1045
|
-
|
|
1191
|
+
openArtifact({ path: change.path, content: fallbackContent })
|
|
1046
1192
|
}}
|
|
1047
1193
|
title="Open Live Preview Split View"
|
|
1048
1194
|
>
|
|
@@ -1083,6 +1229,17 @@ export default function ChatPanel({
|
|
|
1083
1229
|
</div>
|
|
1084
1230
|
)
|
|
1085
1231
|
})}
|
|
1232
|
+
{changes.length > 3 && (
|
|
1233
|
+
<button
|
|
1234
|
+
type="button"
|
|
1235
|
+
className="file-changes-show-more"
|
|
1236
|
+
aria-expanded={showAll}
|
|
1237
|
+
onClick={() => setShowAllFileChanges((current) => ({ ...current, [idPrefix]: !current[idPrefix] }))}
|
|
1238
|
+
>
|
|
1239
|
+
{showAll ? 'Show fewer files' : `Show ${changes.length - 3} more ${changes.length - 3 === 1 ? 'file' : 'files'}`}
|
|
1240
|
+
<span aria-hidden="true" className={showAll ? 'is-expanded' : ''}>⌄</span>
|
|
1241
|
+
</button>
|
|
1242
|
+
)}
|
|
1086
1243
|
</div>
|
|
1087
1244
|
)
|
|
1088
1245
|
}
|
|
@@ -1097,7 +1254,7 @@ export default function ChatPanel({
|
|
|
1097
1254
|
const totalDeletions = changes.reduce((sum, c) => sum + c.deletions, 0)
|
|
1098
1255
|
const createdCount = changes.filter((c) => c.created).length
|
|
1099
1256
|
const modifiedCount = changes.length - createdCount
|
|
1100
|
-
const isOpen =
|
|
1257
|
+
const isOpen = openReviewIds[interactionId] ?? true
|
|
1101
1258
|
|
|
1102
1259
|
let summaryLabel = ''
|
|
1103
1260
|
if (createdCount > 0 && modifiedCount === 0) {
|
|
@@ -1171,56 +1328,49 @@ export default function ChatPanel({
|
|
|
1171
1328
|
}
|
|
1172
1329
|
|
|
1173
1330
|
return (
|
|
1174
|
-
<div className="file-changes-summary-container"
|
|
1175
|
-
<div
|
|
1176
|
-
<
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
<polyline points="22 4 12 14.01 9 11.01" />
|
|
1185
|
-
</svg>
|
|
1186
|
-
<span>
|
|
1187
|
-
{summaryLabel}
|
|
1188
|
-
{createdCount > 0 && modifiedCount === 0 ? (
|
|
1189
|
-
<span className="file-changes-count-add" style={{ marginLeft: '6px' }}>
|
|
1190
|
-
(+{totalAdditions} {totalAdditions === 1 ? 'line' : 'lines'})
|
|
1331
|
+
<div className="file-changes-summary-container">
|
|
1332
|
+
<div className="agent-activity-card file-changes-card">
|
|
1333
|
+
<div className="file-changes-summary-row">
|
|
1334
|
+
<div className="file-changes-summary">
|
|
1335
|
+
<span className="file-changes-summary-icon" aria-hidden="true">⊞</span>
|
|
1336
|
+
<span className="file-changes-summary-copy">
|
|
1337
|
+
<span className="file-changes-summary-label">{summaryLabel}</span>
|
|
1338
|
+
<span className="file-changes-summary-counts">
|
|
1339
|
+
{totalAdditions > 0 && <span className="file-changes-count-add">+{totalAdditions}</span>}
|
|
1340
|
+
{totalDeletions > 0 && <span className="file-changes-count-del">-{totalDeletions}</span>}
|
|
1191
1341
|
</span>
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
{renderChangesList(changes, interactionId)}
|
|
1342
|
+
</span>
|
|
1343
|
+
</div>
|
|
1344
|
+
<div className="file-changes-summary-actions">
|
|
1345
|
+
<button
|
|
1346
|
+
type="button"
|
|
1347
|
+
className="file-changes-rewind-btn"
|
|
1348
|
+
onClick={handleRewind}
|
|
1349
|
+
title="Rewind workspace to before these file edits (Git Checkpoint)"
|
|
1350
|
+
>
|
|
1351
|
+
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
|
1352
|
+
<polyline points="1 4 7 4 7 10" />
|
|
1353
|
+
<path d="M3 9a9 9 0 1 0 2.13-5.36L1 7" />
|
|
1354
|
+
</svg>
|
|
1355
|
+
Undo
|
|
1356
|
+
</button>
|
|
1357
|
+
<button
|
|
1358
|
+
type="button"
|
|
1359
|
+
className="file-changes-review-btn"
|
|
1360
|
+
title="Review changed code"
|
|
1361
|
+
onClick={() => {
|
|
1362
|
+
openReview('All conversation changes', conversationChanges)
|
|
1363
|
+
}}
|
|
1364
|
+
>
|
|
1365
|
+
Review
|
|
1366
|
+
</button>
|
|
1367
|
+
</div>
|
|
1219
1368
|
</div>
|
|
1220
|
-
|
|
1369
|
+
{isOpen && <div className="file-changes-list-container">{renderChangesList(changes, interactionId)}</div>}
|
|
1370
|
+
</div>
|
|
1221
1371
|
</div>
|
|
1222
1372
|
)
|
|
1223
|
-
}, [agentActivitySnapshots, openReviewIds, openFileDiffs, workspacePath])
|
|
1373
|
+
}, [agentActivitySnapshots, conversationChanges, openReviewIds, openFileDiffs, showAllFileChanges, workspacePath])
|
|
1224
1374
|
|
|
1225
1375
|
const renderActiveFileChanges = () => {
|
|
1226
1376
|
const changes = parseFileChangesFromProgress(agentProgress)
|
|
@@ -1230,49 +1380,45 @@ export default function ChatPanel({
|
|
|
1230
1380
|
const totalDeletions = changes.reduce((sum, c) => sum + c.deletions, 0)
|
|
1231
1381
|
const createdCount = changes.filter((c) => c.created).length
|
|
1232
1382
|
const modifiedCount = changes.length - createdCount
|
|
1233
|
-
const isOpen =
|
|
1383
|
+
const isOpen = openReviewIds['active-run'] ?? true
|
|
1234
1384
|
|
|
1235
1385
|
let summaryLabel = ''
|
|
1236
1386
|
if (createdCount > 0 && modifiedCount === 0) {
|
|
1237
|
-
summaryLabel = `${createdCount} ${createdCount === 1 ? 'file created' : 'files created'}
|
|
1387
|
+
summaryLabel = `${createdCount} ${createdCount === 1 ? 'file created' : 'files created'}`
|
|
1238
1388
|
} else if (createdCount > 0 && modifiedCount > 0) {
|
|
1239
|
-
summaryLabel = `${createdCount} created, ${modifiedCount} modified
|
|
1389
|
+
summaryLabel = `${createdCount} created, ${modifiedCount} modified`
|
|
1240
1390
|
} else {
|
|
1241
|
-
summaryLabel = `${changes.length} ${changes.length === 1 ? 'file changed' : 'files changed'}
|
|
1391
|
+
summaryLabel = `${changes.length} ${changes.length === 1 ? 'file changed' : 'files changed'}`
|
|
1242
1392
|
}
|
|
1243
1393
|
|
|
1244
1394
|
return (
|
|
1245
1395
|
<div className="message ai-message agent-activity-message" style={{ marginTop: '4px', marginBottom: '8px' }}>
|
|
1246
1396
|
<div className="agent-activity-card file-changes-card">
|
|
1247
|
-
<
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
<path d="M22 11.08V12a10 10 0 1 1-5.93-9.14" />
|
|
1256
|
-
<polyline points="22 4 12 14.01 9 11.01" />
|
|
1257
|
-
</svg>
|
|
1258
|
-
<span>
|
|
1259
|
-
{summaryLabel}
|
|
1260
|
-
{createdCount > 0 && modifiedCount === 0 ? (
|
|
1261
|
-
<span className="file-changes-count-add" style={{ marginLeft: '6px' }}>
|
|
1262
|
-
(+{totalAdditions} {totalAdditions === 1 ? 'line' : 'lines'})
|
|
1397
|
+
<div className="file-changes-summary-row">
|
|
1398
|
+
<div className="file-changes-summary">
|
|
1399
|
+
<span className="file-changes-summary-icon" aria-hidden="true">✓</span>
|
|
1400
|
+
<span className="file-changes-summary-copy">
|
|
1401
|
+
<span className="file-changes-summary-label">{summaryLabel}</span>
|
|
1402
|
+
<span className="file-changes-summary-counts">
|
|
1403
|
+
{totalAdditions > 0 && <span className="file-changes-count-add">+{totalAdditions}</span>}
|
|
1404
|
+
{totalDeletions > 0 && <span className="file-changes-count-del">-{totalDeletions}</span>}
|
|
1263
1405
|
</span>
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1406
|
+
</span>
|
|
1407
|
+
</div>
|
|
1408
|
+
<button
|
|
1409
|
+
type="button"
|
|
1410
|
+
className="file-changes-review-btn"
|
|
1411
|
+
title="Review changed code"
|
|
1412
|
+
onClick={() => {
|
|
1413
|
+
openReview('All conversation changes', conversationChanges)
|
|
1414
|
+
}}
|
|
1415
|
+
>
|
|
1416
|
+
Review
|
|
1417
|
+
</button>
|
|
1418
|
+
</div>
|
|
1273
1419
|
|
|
1274
1420
|
{isOpen && (
|
|
1275
|
-
<div style={{ marginTop: '8px' }}>
|
|
1421
|
+
<div className="file-changes-list-container" style={{ marginTop: '8px' }}>
|
|
1276
1422
|
{renderChangesList(changes, 'active')}
|
|
1277
1423
|
</div>
|
|
1278
1424
|
)}
|
|
@@ -1288,7 +1434,7 @@ export default function ChatPanel({
|
|
|
1288
1434
|
onDragOver={handleDragOver}
|
|
1289
1435
|
onDragLeave={handleDragLeave}
|
|
1290
1436
|
onDrop={handleDrop}
|
|
1291
|
-
style={activeArtifact ? { flex: '0 0 calc(100% - var(--preview-width, 50%))', width: 'calc(100% - var(--preview-width, 50%))', minWidth: '320px', maxWidth: 'none', margin: 0, position: 'relative' } : undefined}
|
|
1437
|
+
style={activeArtifact || reviewPage ? { flex: '0 0 calc(100% - var(--preview-width, 50%))', width: 'calc(100% - var(--preview-width, 50%))', minWidth: '320px', maxWidth: 'none', margin: 0, position: 'relative' } : undefined}
|
|
1292
1438
|
>
|
|
1293
1439
|
{isDragging && (
|
|
1294
1440
|
<div
|
|
@@ -1317,7 +1463,7 @@ export default function ChatPanel({
|
|
|
1317
1463
|
pointerEvents: 'auto',
|
|
1318
1464
|
}}
|
|
1319
1465
|
>
|
|
1320
|
-
<div style={{ marginBottom: '16px', color: 'var(--
|
|
1466
|
+
<div style={{ marginBottom: '16px', color: 'var(--interactive-fg)' }}>
|
|
1321
1467
|
<svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
|
1322
1468
|
<rect x="3" y="3" width="18" height="18" rx="2" ry="2" />
|
|
1323
1469
|
<circle cx="8.5" cy="8.5" r="1.5" />
|
|
@@ -1334,9 +1480,9 @@ export default function ChatPanel({
|
|
|
1334
1480
|
className="mobile-menu-btn"
|
|
1335
1481
|
type="button"
|
|
1336
1482
|
onClick={onToggleMobileSidebar}
|
|
1337
|
-
aria-label="
|
|
1483
|
+
aria-label="Open navigation menu"
|
|
1338
1484
|
>
|
|
1339
|
-
<svg width="
|
|
1485
|
+
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
|
|
1340
1486
|
<line x1="3" y1="12" x2="21" y2="12" />
|
|
1341
1487
|
<line x1="3" y1="6" x2="21" y2="6" />
|
|
1342
1488
|
<line x1="3" y1="18" x2="21" y2="18" />
|
|
@@ -1344,35 +1490,79 @@ export default function ChatPanel({
|
|
|
1344
1490
|
</button>
|
|
1345
1491
|
)}
|
|
1346
1492
|
<div className="chat-header-title">
|
|
1347
|
-
|
|
1348
|
-
|
|
1493
|
+
{isCliSession ? (
|
|
1494
|
+
<div className="chat-header-breadcrumb">
|
|
1495
|
+
{onBackToCode && (
|
|
1496
|
+
<button
|
|
1497
|
+
type="button"
|
|
1498
|
+
className="chat-header-back-btn"
|
|
1499
|
+
onClick={onBackToCode}
|
|
1500
|
+
title="Back to Code sessions Hub"
|
|
1501
|
+
>
|
|
1502
|
+
<svg
|
|
1503
|
+
width="12"
|
|
1504
|
+
height="12"
|
|
1505
|
+
viewBox="0 0 24 24"
|
|
1506
|
+
fill="none"
|
|
1507
|
+
stroke="currentColor"
|
|
1508
|
+
strokeWidth="2.5"
|
|
1509
|
+
strokeLinecap="round"
|
|
1510
|
+
strokeLinejoin="round"
|
|
1511
|
+
>
|
|
1512
|
+
<path d="M15 18l-6-6 6-6" />
|
|
1513
|
+
</svg>
|
|
1514
|
+
<span>Code</span>
|
|
1515
|
+
</button>
|
|
1516
|
+
)}
|
|
1517
|
+
<span className="chat-header-sep">/</span>
|
|
1518
|
+
<span className="chat-header-session-tag" title={cliSessionId || 'CLI Session'}>
|
|
1519
|
+
<span>
|
|
1520
|
+
{cliSessionId ? (cliSessionId === 'cli' ? 'cli' : `cli::${cliSessionId.replace(/^cli::/, '').slice(0, 7)}`) : 'cli'}
|
|
1521
|
+
</span>
|
|
1522
|
+
</span>
|
|
1523
|
+
</div>
|
|
1524
|
+
) : (
|
|
1525
|
+
<div className="chat-header-brand-group">
|
|
1526
|
+
<img src={runtimePlatform.appIconPath()} alt="Logo" className="chat-header-logo" />
|
|
1527
|
+
<span
|
|
1528
|
+
className="chat-header-title-text"
|
|
1529
|
+
title={conversationTitle && conversationTitle.trim() && conversationTitle !== 'New chat' ? conversationTitle.trim() : 'Mint Agent'}
|
|
1530
|
+
>
|
|
1531
|
+
{conversationTitle && conversationTitle.trim() && conversationTitle !== 'New chat' ? conversationTitle.trim() : 'Mint Agent'}
|
|
1532
|
+
</span>
|
|
1533
|
+
{projectName && (
|
|
1534
|
+
<span className="chat-header-project-pill" title={`Project: ${workspacePath}`}>
|
|
1535
|
+
<svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round">
|
|
1536
|
+
<path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"></path>
|
|
1537
|
+
</svg>
|
|
1538
|
+
<span>{projectName}</span>
|
|
1539
|
+
</span>
|
|
1540
|
+
)}
|
|
1541
|
+
</div>
|
|
1542
|
+
)}
|
|
1349
1543
|
</div>
|
|
1350
|
-
<div
|
|
1544
|
+
<div className="chat-header-actions">
|
|
1351
1545
|
{activeArtifact && (
|
|
1352
1546
|
<button
|
|
1353
1547
|
type="button"
|
|
1354
|
-
className="chat-header-
|
|
1548
|
+
className="chat-header-pill-btn"
|
|
1355
1549
|
title="Close Live Preview"
|
|
1356
1550
|
onClick={() => setActiveArtifact(null)}
|
|
1357
|
-
style={{
|
|
1358
|
-
color: 'var(--accent)',
|
|
1359
|
-
background: 'color-mix(in srgb, var(--accent) 12%, transparent)',
|
|
1360
|
-
border: '1px solid color-mix(in srgb, var(--accent) 25%, transparent)',
|
|
1361
|
-
padding: '2px 8px',
|
|
1362
|
-
borderRadius: 'var(--radius-xs, 4px)',
|
|
1363
|
-
fontSize: '0.74rem',
|
|
1364
|
-
fontWeight: 600,
|
|
1365
|
-
cursor: 'pointer',
|
|
1366
|
-
display: 'inline-flex',
|
|
1367
|
-
alignItems: 'center',
|
|
1368
|
-
gap: '4px',
|
|
1369
|
-
}}
|
|
1370
1551
|
>
|
|
1371
|
-
<
|
|
1552
|
+
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
|
|
1553
|
+
<line x1="18" y1="6" x2="6" y2="18"></line>
|
|
1554
|
+
<line x1="6" y1="6" x2="18" y2="18"></line>
|
|
1555
|
+
</svg>
|
|
1556
|
+
<span>Close preview</span>
|
|
1372
1557
|
</button>
|
|
1373
1558
|
)}
|
|
1374
|
-
<button
|
|
1375
|
-
|
|
1559
|
+
<button
|
|
1560
|
+
type="button"
|
|
1561
|
+
className="chat-header-action-btn"
|
|
1562
|
+
title="Clear conversation"
|
|
1563
|
+
onClick={onClearMessages}
|
|
1564
|
+
>
|
|
1565
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
|
1376
1566
|
<polyline points="3 6 5 6 21 6"></polyline>
|
|
1377
1567
|
<path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"></path>
|
|
1378
1568
|
<line x1="10" y1="11" x2="10" y2="17"></line>
|
|
@@ -1382,9 +1572,28 @@ export default function ChatPanel({
|
|
|
1382
1572
|
</div>
|
|
1383
1573
|
</div>
|
|
1384
1574
|
<div className="chat-container" ref={chatContainerRef} onScroll={handleChatScroll}>
|
|
1385
|
-
{
|
|
1575
|
+
{hasOlder && onLoadOlder && (
|
|
1576
|
+
<button type="button" className="load-older-messages" disabled={loadingOlder}
|
|
1577
|
+
style={{ display: 'block', margin: '0 auto 20px', padding: '7px 14px', borderRadius: 8,
|
|
1578
|
+
border: '1px solid var(--border-color, #3a3a3a)', background: 'var(--surface, #252525)',
|
|
1579
|
+
color: 'var(--text-secondary, #c0c0c0)', cursor: loadingOlder ? 'default' : 'pointer' }}
|
|
1580
|
+
onClick={async () => {
|
|
1581
|
+
const container = chatContainerRef.current
|
|
1582
|
+
const previousHeight = container?.scrollHeight ?? 0
|
|
1583
|
+
setLoadingOlder(true)
|
|
1584
|
+
try {
|
|
1585
|
+
await onLoadOlder()
|
|
1586
|
+
window.requestAnimationFrame(() => {
|
|
1587
|
+
if (container) container.scrollTop += container.scrollHeight - previousHeight
|
|
1588
|
+
})
|
|
1589
|
+
} finally { setLoadingOlder(false) }
|
|
1590
|
+
}}>
|
|
1591
|
+
{loadingOlder ? 'Loading earlier messages…' : 'Load earlier messages'}
|
|
1592
|
+
</button>
|
|
1593
|
+
)}
|
|
1594
|
+
{visibleInteractions.map((interaction, index) => (
|
|
1386
1595
|
<Fragment key={interaction.id}>
|
|
1387
|
-
{index > 0 && shouldShowSessionDivider(
|
|
1596
|
+
{index > 0 && shouldShowSessionDivider(visibleInteractions[index - 1].createdAt, interaction.createdAt) && (
|
|
1388
1597
|
<div className="system-event-divider">
|
|
1389
1598
|
<div className="system-event-line" />
|
|
1390
1599
|
<div className="system-event-pill">
|
|
@@ -1432,23 +1641,29 @@ export default function ChatPanel({
|
|
|
1432
1641
|
{renderActiveFileChanges()}
|
|
1433
1642
|
<div className="message ai-message thinking-message">
|
|
1434
1643
|
<div className="bubble-wrapper">
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1644
|
+
{!agentMode && extendedThoughtsFrom(agentProgress).length > 0 && (
|
|
1645
|
+
<ThinkingBlock
|
|
1646
|
+
blockKey="live-extended"
|
|
1647
|
+
thoughts={extendedThoughtsFrom(agentProgress)}
|
|
1648
|
+
isLive={true}
|
|
1649
|
+
variant="extended"
|
|
1650
|
+
expanded={thinkingExpanded['live-extended'] ?? true}
|
|
1651
|
+
onExpandedChange={onThinkingExpandedChange}
|
|
1652
|
+
/>
|
|
1653
|
+
)}
|
|
1654
|
+
{!agentMode && thoughtsFrom(agentProgress).length > 0 && extendedThoughtsFrom(agentProgress).length === 0 && (
|
|
1655
|
+
<ThinkingBlock
|
|
1656
|
+
blockKey="live"
|
|
1657
|
+
thoughts={thoughtsFrom(agentProgress)}
|
|
1658
|
+
isLive={true}
|
|
1659
|
+
expanded={thinkingExpanded.live ?? true}
|
|
1660
|
+
onExpandedChange={onThinkingExpandedChange}
|
|
1661
|
+
/>
|
|
1662
|
+
)}
|
|
1448
1663
|
<div className="message-bubble">
|
|
1449
1664
|
<span>
|
|
1450
|
-
{
|
|
1451
|
-
renderFormattedMessage(
|
|
1665
|
+
{throttledStreamedReply ? (
|
|
1666
|
+
renderFormattedMessage(throttledStreamedReply, liveWebSources)
|
|
1452
1667
|
) : (
|
|
1453
1668
|
<div style={{ display: 'flex', alignItems: 'center', gap: '8px', color: 'var(--text-soft, #94a3b8)' }}>
|
|
1454
1669
|
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round" style={{ display: 'inline-block', flexShrink: 0 }}>
|
|
@@ -1483,23 +1698,23 @@ export default function ChatPanel({
|
|
|
1483
1698
|
<span className="provider-chip-model">{streamedResponse.model}</span>
|
|
1484
1699
|
</span>
|
|
1485
1700
|
{activeFallbackNotice && <span className="provider-fallback-notice">{activeFallbackNotice}</span>}
|
|
1486
|
-
{
|
|
1701
|
+
{throttledStreamedReply && (
|
|
1487
1702
|
<div className="message-action-buttons" style={{ display: 'flex', alignItems: 'center', gap: '4px', marginLeft: 'auto' }}>
|
|
1488
1703
|
<button
|
|
1489
1704
|
type="button"
|
|
1490
1705
|
className={`msg-action-btn copy-btn ${copiedId === 'live' ? 'is-copied' : ''}`}
|
|
1491
|
-
onClick={() => handleCopyMessage('live',
|
|
1706
|
+
onClick={() => handleCopyMessage('live', throttledStreamedReply)}
|
|
1492
1707
|
title={copiedId === 'live' ? 'คัดลอกแล้ว (Copied!)' : 'คัดลอกข้อความ (Copy message)'}
|
|
1493
1708
|
>
|
|
1494
1709
|
{renderCopyIcon(copiedId === 'live')}
|
|
1495
1710
|
</button>
|
|
1496
1711
|
<button
|
|
1497
1712
|
type="button"
|
|
1498
|
-
className={`msg-action-btn tts-btn ${speakingText ===
|
|
1499
|
-
onClick={() => speak(
|
|
1500
|
-
title={speakingText ===
|
|
1713
|
+
className={`msg-action-btn tts-btn ${speakingText === throttledStreamedReply ? 'is-speaking' : ''}`}
|
|
1714
|
+
onClick={() => speak(throttledStreamedReply)}
|
|
1715
|
+
title={speakingText === throttledStreamedReply ? 'Stop reading' : 'Read aloud'}
|
|
1501
1716
|
>
|
|
1502
|
-
{renderSpeakerIcon(speakingText ===
|
|
1717
|
+
{renderSpeakerIcon(speakingText === throttledStreamedReply)}
|
|
1503
1718
|
</button>
|
|
1504
1719
|
</div>
|
|
1505
1720
|
)}
|
|
@@ -1535,41 +1750,62 @@ export default function ChatPanel({
|
|
|
1535
1750
|
</div>
|
|
1536
1751
|
|
|
1537
1752
|
<div className={`input-area ${voiceMode ? 'voice-active' : ''}`}>
|
|
1538
|
-
{
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1753
|
+
{composerChanges.length > 0 && (
|
|
1754
|
+
<button
|
|
1755
|
+
type="button"
|
|
1756
|
+
className={`composer-change-status ${sending ? 'is-live' : ''}`}
|
|
1757
|
+
onClick={() => openReview(composerChangeLabel, composerChanges)}
|
|
1758
|
+
title="Review recent agent changes"
|
|
1759
|
+
>
|
|
1760
|
+
<span className="composer-change-status-copy">
|
|
1761
|
+
{sending && <span className="composer-change-status-spinner" aria-hidden="true" />}
|
|
1762
|
+
<span>{sending ? `Editing ${composerChanges.length} ${composerChanges.length === 1 ? 'file' : 'files'}…` : composerChangeLabel}</span>
|
|
1763
|
+
</span>
|
|
1764
|
+
<span className="composer-change-status-counts" aria-label={`${composerAdditions} additions and ${composerDeletions} deletions`}>
|
|
1765
|
+
{composerAdditions > 0 && <strong>+{composerAdditions}</strong>}
|
|
1766
|
+
{composerDeletions > 0 && <em>-{composerDeletions}</em>}
|
|
1545
1767
|
</span>
|
|
1546
|
-
<span>{workspaceName}</span>
|
|
1547
|
-
<span aria-hidden="true">⌄</span>
|
|
1548
1768
|
</button>
|
|
1549
1769
|
)}
|
|
1550
|
-
|
|
1551
|
-
<div className="
|
|
1552
|
-
<
|
|
1553
|
-
|
|
1554
|
-
<
|
|
1555
|
-
|
|
1556
|
-
|
|
1770
|
+
{isEmptyChat && (
|
|
1771
|
+
<div className="empty-chat-prompt-wrap">
|
|
1772
|
+
<div className="empty-chat-prompt">Mint Agent is ready to work</div>
|
|
1773
|
+
{projectName && (
|
|
1774
|
+
<div className="empty-chat-project-badge">
|
|
1775
|
+
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round">
|
|
1776
|
+
<path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"></path>
|
|
1777
|
+
</svg>
|
|
1778
|
+
<span>Working in <strong>{projectName}</strong></span>
|
|
1779
|
+
</div>
|
|
1780
|
+
)}
|
|
1557
1781
|
</div>
|
|
1558
|
-
|
|
1559
|
-
|
|
1782
|
+
)}
|
|
1783
|
+
{onSelectWorkspace && (
|
|
1784
|
+
<div className="project-context-row">
|
|
1785
|
+
<WorkspaceSelector
|
|
1786
|
+
currentPath={workspacePath || ''}
|
|
1787
|
+
recentPaths={recentWorkspacePaths}
|
|
1788
|
+
onSelectWorkspace={onSelectWorkspace}
|
|
1789
|
+
/>
|
|
1790
|
+
{workspacePath && <GitBranchSelector workspacePath={workspacePath} disabled={sending} onBranchChanged={onWorkspaceChanged} />}
|
|
1791
|
+
</div>
|
|
1792
|
+
)}
|
|
1793
|
+
<div className="smart-context-bar">
|
|
1794
|
+
<label className={`smart-context-option ${agentMode ? 'is-active' : ''}`}>
|
|
1795
|
+
<span className="toggle-switch">
|
|
1560
1796
|
<input type="checkbox" checked={agentMode} onChange={(event) => onSetAgentMode(event.target.checked)} />
|
|
1561
1797
|
<span className="slider round" />
|
|
1562
|
-
</
|
|
1563
|
-
<span>Agent
|
|
1564
|
-
</
|
|
1798
|
+
</span>
|
|
1799
|
+
<span className="smart-context-copy"><span className="smart-context-title">Agent mode</span></span>
|
|
1800
|
+
</label>
|
|
1565
1801
|
{onSetPlanMode && (
|
|
1566
|
-
<
|
|
1567
|
-
<
|
|
1802
|
+
<label className={`smart-context-option ${planMode ? 'is-active' : ''}`} title="Investigate read-only and require plan approval before editing files or running commands">
|
|
1803
|
+
<span className="toggle-switch">
|
|
1568
1804
|
<input type="checkbox" checked={Boolean(planMode)} onChange={(event) => onSetPlanMode(event.target.checked)} />
|
|
1569
1805
|
<span className="slider round" />
|
|
1570
|
-
</
|
|
1571
|
-
<span>Plan
|
|
1572
|
-
</
|
|
1806
|
+
</span>
|
|
1807
|
+
<span className="smart-context-copy"><span className="smart-context-title">Plan mode</span></span>
|
|
1808
|
+
</label>
|
|
1573
1809
|
)}
|
|
1574
1810
|
</div>
|
|
1575
1811
|
{voiceMode && (
|
|
@@ -1779,7 +2015,10 @@ export default function ChatPanel({
|
|
|
1779
2015
|
<input id="video-file-input" type="file" accept="video/mp4,video/webm,video/quicktime,video/x-matroska" onChange={onSelectVideo} style={{ display: 'none' }} />
|
|
1780
2016
|
<input id="document-file-input" type="file" accept={SUPPORTED_DOCUMENT_ACCEPT} onChange={onSelectDocument} style={{ display: 'none' }} />
|
|
1781
2017
|
<button id="screen-capture-btn" type="button" onClick={onCaptureScreen} aria-label="Capture screen">
|
|
1782
|
-
<
|
|
2018
|
+
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
|
|
2019
|
+
<rect x="2" y="3" width="20" height="15" rx="2" />
|
|
2020
|
+
<path d="M8 22h8M12 18v4M7 10h10M12 5v10" />
|
|
2021
|
+
</svg>
|
|
1783
2022
|
</button>
|
|
1784
2023
|
<ModelSelectorPopover
|
|
1785
2024
|
activeProvider={status?.activeProvider ?? ''}
|
|
@@ -1795,6 +2034,7 @@ export default function ChatPanel({
|
|
|
1795
2034
|
onSetModel(model)
|
|
1796
2035
|
}
|
|
1797
2036
|
}}
|
|
2037
|
+
onUpdateSettings={onUpdateSettings}
|
|
1798
2038
|
/>
|
|
1799
2039
|
<button
|
|
1800
2040
|
id="mic-btn"
|
|
@@ -1941,19 +2181,13 @@ export default function ChatPanel({
|
|
|
1941
2181
|
return (
|
|
1942
2182
|
<div
|
|
1943
2183
|
ref={wrapperRef}
|
|
1944
|
-
className={`chat-panel-split-wrapper ${activeArtifact ? 'has-preview' : 'no-preview'}`}
|
|
2184
|
+
className={`chat-panel-split-wrapper ${activeArtifact || reviewPage ? 'has-preview' : 'no-preview'}`}
|
|
1945
2185
|
style={{
|
|
1946
|
-
width: '100%',
|
|
1947
|
-
height: '100%',
|
|
1948
|
-
overflow: 'hidden',
|
|
1949
|
-
position: 'relative',
|
|
1950
|
-
gridColumn: '1 / -1',
|
|
1951
|
-
zIndex: 1,
|
|
1952
2186
|
'--preview-width': `${(splitRatio * 100).toFixed(2)}%`,
|
|
1953
2187
|
} as React.CSSProperties}
|
|
1954
2188
|
>
|
|
1955
2189
|
{sectionContent}
|
|
1956
|
-
{activeArtifact && (
|
|
2190
|
+
{(activeArtifact || reviewPage) && (
|
|
1957
2191
|
<>
|
|
1958
2192
|
<div
|
|
1959
2193
|
className="preview-split-resizer"
|
|
@@ -1963,11 +2197,16 @@ export default function ChatPanel({
|
|
|
1963
2197
|
>
|
|
1964
2198
|
<div className="preview-split-resizer-grip" />
|
|
1965
2199
|
</div>
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
2200
|
+
{reviewPage ? (
|
|
2201
|
+
<CodeReviewPage
|
|
2202
|
+
title={reviewPage.title}
|
|
2203
|
+
changes={reviewPage.changes}
|
|
2204
|
+
workspacePath={workspacePath}
|
|
2205
|
+
onBack={() => setReviewPage(null)}
|
|
2206
|
+
/>
|
|
2207
|
+
) : activeArtifact ? (
|
|
2208
|
+
<ArtifactPreviewPanel artifact={activeArtifact} onClose={() => setActiveArtifact(null)} workspacePath={workspacePath} />
|
|
2209
|
+
) : null}
|
|
1971
2210
|
</>
|
|
1972
2211
|
)}
|
|
1973
2212
|
{rewindModalState.isOpen && (
|