@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
|
@@ -222,37 +222,9 @@ pub(super) fn print_table_block(table_lines: &[String], is_first: &mut bool) {
|
|
|
222
222
|
}
|
|
223
223
|
}
|
|
224
224
|
|
|
225
|
-
pub(super) fn should_show_verification(verification: &str) -> bool {
|
|
226
|
-
let normalized = verification.trim().to_ascii_lowercase();
|
|
227
|
-
if normalized.is_empty() {
|
|
228
|
-
return false;
|
|
229
|
-
}
|
|
230
|
-
if normalized.starts_with("information retrieved from web search")
|
|
231
|
-
|| normalized.starts_with("successfully ran background command")
|
|
232
|
-
|| normalized.starts_with("opened ")
|
|
233
|
-
|| normalized.contains("background command to open")
|
|
234
|
-
|| normalized.contains("web search results")
|
|
235
|
-
{
|
|
236
|
-
return false;
|
|
237
|
-
}
|
|
238
|
-
!matches!(
|
|
239
|
-
normalized.as_str(),
|
|
240
|
-
"not run"
|
|
241
|
-
| "not run."
|
|
242
|
-
| "no checks run"
|
|
243
|
-
| "no checks run."
|
|
244
|
-
| "no technical task requested"
|
|
245
|
-
| "no technical task requested."
|
|
246
|
-
| "no technical task requested, just a greeting."
|
|
247
|
-
| "not required"
|
|
248
|
-
| "not required."
|
|
249
|
-
| "none"
|
|
250
|
-
| "n/a"
|
|
251
|
-
)
|
|
252
|
-
}
|
|
253
|
-
|
|
254
225
|
#[derive(Debug, Default)]
|
|
255
226
|
pub(super) struct LiveStatus {
|
|
227
|
+
pub(super) tui: Option<crate::interactive::TuiHandle>,
|
|
256
228
|
pub(super) thinking: Option<String>,
|
|
257
229
|
/// Context-window usage (0-100) as of the last completed step —
|
|
258
230
|
/// mirrored here (not just built into `thinking`'s label text) so the
|
|
@@ -305,6 +277,9 @@ pub(super) struct LiveStatus {
|
|
|
305
277
|
pub(super) committed_activities: usize,
|
|
306
278
|
pub(super) committed_tasks: usize,
|
|
307
279
|
pub(super) spinner_tick: usize,
|
|
280
|
+
/// When the currently running tool began executing — used to animate an
|
|
281
|
+
/// inline spinner and elapsed timer directly on the active tool line.
|
|
282
|
+
pub(super) active_tool_started: Option<Instant>,
|
|
308
283
|
/// Sources collected from web_search ToolEnd results (title, url)
|
|
309
284
|
pub(super) web_sources: Vec<(String, String)>,
|
|
310
285
|
pub(super) inline_tui: InlineTui,
|
|
@@ -562,13 +537,6 @@ pub(super) fn strip_ansi_escapes(s: &str) -> String {
|
|
|
562
537
|
result
|
|
563
538
|
}
|
|
564
539
|
|
|
565
|
-
pub(super) fn is_thai_combining(c: char) -> bool {
|
|
566
|
-
matches!(c,
|
|
567
|
-
'\u{0e31}' | '\u{0e34}'..='\u{0e37}' | '\u{0e38}'..='\u{0e39}' |
|
|
568
|
-
'\u{0e47}'..='\u{0e4e}'
|
|
569
|
-
)
|
|
570
|
-
}
|
|
571
|
-
|
|
572
540
|
pub(super) fn apply_wave_effect(text: &str, tick: usize) -> String {
|
|
573
541
|
let (label, metadata) = if let Some(idx) = text.rfind(" • Esc to interrupt)") {
|
|
574
542
|
if let Some(open_paren_idx) = text[..idx].rfind('(') {
|
|
@@ -606,33 +574,10 @@ pub(super) fn apply_wave_effect(text: &str, tick: usize) -> String {
|
|
|
606
574
|
let x = (i as f32 * 0.4) - phase;
|
|
607
575
|
let t = (x.sin() + 1.0) / 2.0; // Oscillates in [0.0, 1.0]
|
|
608
576
|
|
|
609
|
-
|
|
610
|
-
let (r, g, b) = if t < 0.3 {
|
|
611
|
-
let local_t = t / 0.3;
|
|
612
|
-
let r = 70.0 + (105.0 - 70.0) * local_t;
|
|
613
|
-
let g = 70.0 + (230.0 - 70.0) * local_t;
|
|
614
|
-
let b = 70.0 + (166.0 - 70.0) * local_t;
|
|
615
|
-
(r, g, b)
|
|
616
|
-
} else if t < 0.7 {
|
|
617
|
-
let local_t = (t - 0.3) / 0.4;
|
|
618
|
-
let r = 105.0 + (78.0 - 105.0) * local_t;
|
|
619
|
-
let g = 230.0 + (201.0 - 230.0) * local_t;
|
|
620
|
-
let b = 166.0 + (216.0 - 166.0) * local_t;
|
|
621
|
-
(r, g, b)
|
|
622
|
-
} else {
|
|
623
|
-
let local_t = (t - 0.7) / 0.3;
|
|
624
|
-
let r = 78.0 + (70.0 - 78.0) * local_t;
|
|
625
|
-
let g = 201.0 + (70.0 - 201.0) * local_t;
|
|
626
|
-
let b = 216.0 + (70.0 - 216.0) * local_t;
|
|
627
|
-
(r, g, b)
|
|
628
|
-
};
|
|
629
|
-
|
|
577
|
+
let emphasis = if t > 0.72 { BOLD } else { "" };
|
|
630
578
|
animated_label.push_str(&format!(
|
|
631
|
-
"
|
|
632
|
-
|
|
633
|
-
g.round() as u8,
|
|
634
|
-
b.round() as u8,
|
|
635
|
-
c
|
|
579
|
+
"{emphasis}{}{c}{RESET}",
|
|
580
|
+
crate::terminal_theme::ANSI_ACCENT
|
|
636
581
|
));
|
|
637
582
|
}
|
|
638
583
|
|
|
@@ -715,7 +660,10 @@ pub(super) fn compose_queue_box(
|
|
|
715
660
|
(lines, cursor_x, cursor_y)
|
|
716
661
|
}
|
|
717
662
|
|
|
718
|
-
|
|
663
|
+
/// Renders the live viewport and reports whether a terminal was available to
|
|
664
|
+
/// draw it. Callers use the result to fall back to plain output when Mint is
|
|
665
|
+
/// run without an interactive terminal.
|
|
666
|
+
pub(super) fn render_live_status(status: &mut LiveStatus) -> bool {
|
|
719
667
|
let mut lines = Vec::new();
|
|
720
668
|
let explored_start = status.committed_explored.min(status.explored.len());
|
|
721
669
|
let activities_start = status.committed_activities.min(status.activities.len());
|
|
@@ -735,6 +683,12 @@ pub(super) fn render_live_status(status: &mut LiveStatus) {
|
|
|
735
683
|
&status.explored[explored_start..],
|
|
736
684
|
true,
|
|
737
685
|
tick,
|
|
686
|
+
status.active_tool_started,
|
|
687
|
+
// The full-screen TUI shows only the last eight live rows. A shell
|
|
688
|
+
// output preview can otherwise push the activity header and command
|
|
689
|
+
// labels out of view while the model is composing its next answer.
|
|
690
|
+
// Keep the preview in `status.tasks` for the committed transcript.
|
|
691
|
+
status.tui.is_none(),
|
|
738
692
|
));
|
|
739
693
|
// Built here (not inline below) so both destinations for it — the old
|
|
740
694
|
// trailing-line spot in `lines`, and the queue box's own pinned row —
|
|
@@ -831,18 +785,23 @@ pub(super) fn render_live_status(status: &mut LiveStatus) {
|
|
|
831
785
|
}
|
|
832
786
|
}
|
|
833
787
|
|
|
788
|
+
if let Some(tui) = &status.tui {
|
|
789
|
+
tui.set_status(lines.iter().map(|line| strip_ansi_escapes(line)).collect());
|
|
790
|
+
return true;
|
|
791
|
+
}
|
|
792
|
+
|
|
834
793
|
if lines.is_empty() && box_lines.is_empty() {
|
|
835
794
|
status.inline_tui.teardown();
|
|
836
|
-
return;
|
|
795
|
+
return false;
|
|
837
796
|
}
|
|
838
797
|
|
|
839
798
|
let Ok(terminal) = status.inline_tui.ensure() else {
|
|
840
|
-
return;
|
|
799
|
+
return false;
|
|
841
800
|
};
|
|
842
801
|
// `draw()` itself only queries the cursor position on the rare path
|
|
843
802
|
// where it detects the terminal window was actually resized since the
|
|
844
803
|
// last frame — bracket it too, defensively, for that case.
|
|
845
|
-
|
|
804
|
+
with_raw_mode_for_cursor_query(|| {
|
|
846
805
|
terminal.draw(|frame| {
|
|
847
806
|
let area = frame.area();
|
|
848
807
|
// The box (the "Ask anything..." input) claims its own rows
|
|
@@ -856,7 +815,7 @@ pub(super) fn render_live_status(status: &mut LiveStatus) {
|
|
|
856
815
|
let box_height = (box_lines.len() as u16).min(area.height);
|
|
857
816
|
let available_for_status = area.height.saturating_sub(box_height);
|
|
858
817
|
|
|
859
|
-
let mut
|
|
818
|
+
let mut status_height: u16 = 0;
|
|
860
819
|
let mut status_paragraph = None;
|
|
861
820
|
if !lines.is_empty()
|
|
862
821
|
&& let Ok(status_text) = lines.join("\n").into_text()
|
|
@@ -874,17 +833,18 @@ pub(super) fn render_live_status(status: &mut LiveStatus) {
|
|
|
874
833
|
// bottom of the frame. (`Paragraph::line_count` would do this
|
|
875
834
|
// exactly, but it's gated behind an unstable ratatui feature.)
|
|
876
835
|
let wrap_width = area.width.max(1);
|
|
877
|
-
status_line_count = status_text
|
|
836
|
+
let status_line_count: u16 = status_text
|
|
878
837
|
.lines
|
|
879
838
|
.iter()
|
|
880
839
|
.map(|line| (line.width().max(1) as u16).div_ceil(wrap_width))
|
|
881
840
|
.sum();
|
|
841
|
+
status_height = status_line_count.min(available_for_status);
|
|
882
842
|
status_paragraph = Some(
|
|
883
843
|
ratatui::widgets::Paragraph::new(status_text)
|
|
884
|
-
.wrap(ratatui::widgets::Wrap { trim: false })
|
|
844
|
+
.wrap(ratatui::widgets::Wrap { trim: false })
|
|
845
|
+
.scroll((status_line_count.saturating_sub(status_height), 0)),
|
|
885
846
|
);
|
|
886
847
|
}
|
|
887
|
-
let status_height = status_line_count.min(available_for_status);
|
|
888
848
|
let status_area = ratatui::layout::Rect {
|
|
889
849
|
height: status_height,
|
|
890
850
|
..area
|
|
@@ -909,13 +869,24 @@ pub(super) fn render_live_status(status: &mut LiveStatus) {
|
|
|
909
869
|
));
|
|
910
870
|
}
|
|
911
871
|
})
|
|
912
|
-
})
|
|
872
|
+
})
|
|
873
|
+
.is_ok()
|
|
913
874
|
}
|
|
914
875
|
|
|
915
876
|
/// Freezes any in-flight activity into scrollback. Returns whether it
|
|
916
877
|
/// actually committed anything — callers that print their own leading blank
|
|
917
878
|
/// line right after (e.g. the final answer) use this to skip it when this
|
|
918
879
|
/// already ended on one, instead of stacking two.
|
|
880
|
+
pub(super) fn commit_activity_snapshot_if_idle(
|
|
881
|
+
status: &mut LiveStatus,
|
|
882
|
+
active_tools: usize,
|
|
883
|
+
) -> bool {
|
|
884
|
+
if active_tools > 0 {
|
|
885
|
+
return false;
|
|
886
|
+
}
|
|
887
|
+
commit_activity_snapshot(status)
|
|
888
|
+
}
|
|
889
|
+
|
|
919
890
|
pub(super) fn commit_activity_snapshot(status: &mut LiveStatus) -> bool {
|
|
920
891
|
let explored_start = status.committed_explored.min(status.explored.len());
|
|
921
892
|
let activities_start = status.committed_activities.min(status.activities.len());
|
|
@@ -927,16 +898,16 @@ pub(super) fn commit_activity_snapshot(status: &mut LiveStatus) -> bool {
|
|
|
927
898
|
&status.explored[explored_start..],
|
|
928
899
|
false,
|
|
929
900
|
0,
|
|
901
|
+
None,
|
|
902
|
+
true,
|
|
930
903
|
);
|
|
931
904
|
if lines.is_empty() {
|
|
932
905
|
return false;
|
|
933
906
|
}
|
|
934
907
|
|
|
935
908
|
let (tw, _) = markdown::terminal_size_or_default();
|
|
936
|
-
let width = tw as usize;
|
|
937
|
-
lines.push(
|
|
938
|
-
lines.push(format!("{DIM}{}{RESET}", "─".repeat(width)));
|
|
939
|
-
lines.push(String::new());
|
|
909
|
+
let width = (tw as usize).saturating_sub(8).max(40);
|
|
910
|
+
lines.push(format!("{DIM} {}{RESET}", "─".repeat(width)));
|
|
940
911
|
insert_permanent_lines(status, &lines);
|
|
941
912
|
|
|
942
913
|
status.committed_explored = status.explored.len();
|
|
@@ -945,19 +916,153 @@ pub(super) fn commit_activity_snapshot(status: &mut LiveStatus) -> bool {
|
|
|
945
916
|
true
|
|
946
917
|
}
|
|
947
918
|
|
|
948
|
-
|
|
919
|
+
#[cfg(test)]
|
|
920
|
+
mod concurrent_activity_tests {
|
|
921
|
+
use super::*;
|
|
922
|
+
|
|
923
|
+
#[test]
|
|
924
|
+
fn unrelated_thought_keeps_in_flight_shell_activity_live() {
|
|
925
|
+
let mut status = LiveStatus::default();
|
|
926
|
+
status.tasks.push(TaskEntry {
|
|
927
|
+
label: "[run_shell] Running command: `sleep 1`...".to_owned(),
|
|
928
|
+
output: Vec::new(),
|
|
929
|
+
});
|
|
930
|
+
|
|
931
|
+
assert!(!commit_activity_snapshot_if_idle(&mut status, 1));
|
|
932
|
+
assert_eq!(status.committed_tasks, 0);
|
|
933
|
+
let live_lines = activity_block_lines(
|
|
934
|
+
&status.tasks[status.committed_tasks..],
|
|
935
|
+
&[],
|
|
936
|
+
&[],
|
|
937
|
+
true,
|
|
938
|
+
0,
|
|
939
|
+
Some(Instant::now()),
|
|
940
|
+
true,
|
|
941
|
+
);
|
|
942
|
+
assert!(
|
|
943
|
+
live_lines
|
|
944
|
+
.iter()
|
|
945
|
+
.any(|line| line.contains("Running 1 shell command"))
|
|
946
|
+
);
|
|
947
|
+
assert!(live_lines.iter().any(|line| line.contains("sleep 1")));
|
|
948
|
+
}
|
|
949
|
+
}
|
|
950
|
+
|
|
951
|
+
#[cfg(test)]
|
|
952
|
+
mod compact_tui_status_tests {
|
|
953
|
+
use super::*;
|
|
954
|
+
|
|
955
|
+
#[test]
|
|
956
|
+
fn completed_shell_output_does_not_push_command_labels_out_of_live_view() {
|
|
957
|
+
let tasks = vec![
|
|
958
|
+
TaskEntry {
|
|
959
|
+
label: "[run_shell] Running command: `time sleep 10`...".into(),
|
|
960
|
+
output: Vec::new(),
|
|
961
|
+
},
|
|
962
|
+
TaskEntry {
|
|
963
|
+
label: "Finished command: `time sleep 10`".into(),
|
|
964
|
+
output: vec![
|
|
965
|
+
"stdout:".into(),
|
|
966
|
+
"stderr:".into(),
|
|
967
|
+
"real 0m10.002s".into(),
|
|
968
|
+
"user 0m0.002s".into(),
|
|
969
|
+
"sys 0m0.002s".into(),
|
|
970
|
+
],
|
|
971
|
+
},
|
|
972
|
+
];
|
|
973
|
+
let mut lines = activity_block_lines(&tasks, &[], &[], true, 0, None, false);
|
|
974
|
+
lines.push(" Herding...".into());
|
|
975
|
+
let visible = &lines[lines.len().saturating_sub(8)..];
|
|
976
|
+
assert!(
|
|
977
|
+
visible
|
|
978
|
+
.iter()
|
|
979
|
+
.any(|line| line.contains("Running 1 shell command"))
|
|
980
|
+
);
|
|
981
|
+
assert!(visible.iter().any(|line| line.contains("[run_shell]")));
|
|
982
|
+
assert!(visible.iter().any(|line| line.contains("Finished command")));
|
|
983
|
+
assert!(!visible.iter().any(|line| line.contains("real 0m10.002s")));
|
|
984
|
+
let committed = activity_block_lines(&tasks, &[], &[], false, 0, None, true);
|
|
985
|
+
assert!(committed.iter().any(|line| line.contains("real 0m10.002s")));
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
pub(super) fn is_internal_cot(text: &str) -> bool {
|
|
990
|
+
mint_core::orchestration::is_internal_cot(text)
|
|
991
|
+
}
|
|
992
|
+
|
|
993
|
+
pub(super) fn print_timeline_note(
|
|
994
|
+
status: &mut LiveStatus,
|
|
995
|
+
thought: &str,
|
|
996
|
+
elapsed: Duration,
|
|
997
|
+
stream_id: Option<&str>,
|
|
998
|
+
) {
|
|
949
999
|
let thought = thought.trim();
|
|
950
1000
|
if thought.is_empty() {
|
|
951
1001
|
return;
|
|
952
1002
|
}
|
|
953
|
-
let
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
1003
|
+
let elapsed_str = crate::interactive::format_thought_elapsed(elapsed);
|
|
1004
|
+
crate::interactive::finish_thought(stream_id, thought, &elapsed_str);
|
|
1005
|
+
|
|
1006
|
+
if is_internal_cot(thought) {
|
|
1007
|
+
let summary = format!(
|
|
1008
|
+
"{muted} • Thought for {elapsed_str}{reset} {muted}(Ctrl+T to view){reset}",
|
|
1009
|
+
muted = crate::terminal_theme::ANSI_MUTED,
|
|
1010
|
+
reset = crate::terminal_theme::ANSI_RESET
|
|
1011
|
+
);
|
|
1012
|
+
insert_permanent_lines(status, &[summary]);
|
|
1013
|
+
} else {
|
|
1014
|
+
let clean_note = thought
|
|
1015
|
+
.strip_prefix("•")
|
|
1016
|
+
.or_else(|| thought.strip_prefix("-"))
|
|
1017
|
+
.unwrap_or(thought)
|
|
1018
|
+
.trim();
|
|
1019
|
+
let clean_note = strip_intermediate_greeting(clean_note);
|
|
1020
|
+
let (tw, _) = markdown::terminal_size_or_default();
|
|
1021
|
+
let width = (tw as usize).saturating_sub(2).max(20);
|
|
1022
|
+
let options = textwrap::Options::new(width)
|
|
1023
|
+
.initial_indent(" ")
|
|
1024
|
+
.subsequent_indent(" ")
|
|
1025
|
+
.break_words(true);
|
|
1026
|
+
let wrapped = textwrap::fill(clean_note, &options);
|
|
1027
|
+
let formatted = format!("{WHITE}{wrapped}{RESET}");
|
|
1028
|
+
insert_permanent_lines(status, &[formatted]);
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
fn strip_intermediate_greeting(text: &str) -> &str {
|
|
1033
|
+
let mut s = text.trim();
|
|
1034
|
+
for prefix in &[
|
|
1035
|
+
"สวัสดีค่ะ",
|
|
1036
|
+
"สวัสดีครับ",
|
|
1037
|
+
"หวัดดีค่ะ",
|
|
1038
|
+
"หวัดดีครับ",
|
|
1039
|
+
"สวัสดี",
|
|
1040
|
+
"Hello",
|
|
1041
|
+
"Hi",
|
|
1042
|
+
"Hey",
|
|
1043
|
+
] {
|
|
1044
|
+
if let Some(rest) = s.strip_prefix(prefix) {
|
|
1045
|
+
s = rest.trim_start();
|
|
1046
|
+
break;
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
if let Some(rest) = s.strip_prefix("พี่") {
|
|
1050
|
+
if let Some(space_idx) = rest.find(' ') {
|
|
1051
|
+
s = rest[space_idx..].trim_start();
|
|
1052
|
+
}
|
|
1053
|
+
} else if let Some(rest) = s.strip_prefix("คุณ") {
|
|
1054
|
+
if let Some(space_idx) = rest.find(' ') {
|
|
1055
|
+
s = rest[space_idx..].trim_start();
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
1058
|
+
for emoji in &["🌿", "🍃", "✨", "🌱"] {
|
|
1059
|
+
if let Some(rest) = s.strip_prefix(emoji) {
|
|
1060
|
+
s = rest.trim_start();
|
|
1061
|
+
}
|
|
1062
|
+
}
|
|
1063
|
+
let trimmed =
|
|
1064
|
+
s.trim_start_matches(|c: char| c == ',' || c == '-' || c == '—' || c == ' ' || c == '•');
|
|
1065
|
+
if trimmed.is_empty() { text } else { trimmed }
|
|
961
1066
|
}
|
|
962
1067
|
|
|
963
1068
|
/// Inserts already ANSI-formatted `lines` as permanent content above the
|
|
@@ -979,6 +1084,10 @@ pub(super) fn print_timeline_note(status: &mut LiveStatus, thought: &str) {
|
|
|
979
1084
|
/// Falls back to plain `println!` if no inline terminal is currently live
|
|
980
1085
|
/// (e.g. committing before anything has rendered yet this turn).
|
|
981
1086
|
pub(super) fn insert_permanent_lines(status: &mut LiveStatus, lines: &[String]) {
|
|
1087
|
+
if let Some(tui) = &status.tui {
|
|
1088
|
+
tui.push_notice(lines.join("\n"));
|
|
1089
|
+
return;
|
|
1090
|
+
}
|
|
982
1091
|
let Some(terminal) = status.inline_tui.terminal.as_mut() else {
|
|
983
1092
|
// Defensive, same reasoning as `approve_cb`/`on_chunk`: this is a
|
|
984
1093
|
// plain `println!`, so it needs cooked mode regardless of whether
|
|
@@ -991,39 +1100,31 @@ pub(super) fn insert_permanent_lines(status: &mut LiveStatus, lines: &[String])
|
|
|
991
1100
|
return;
|
|
992
1101
|
};
|
|
993
1102
|
|
|
994
|
-
let (tw, _) = markdown::terminal_size_or_default();
|
|
995
|
-
let width = tw as usize;
|
|
996
|
-
let mut height: u16 = 0;
|
|
997
|
-
for line in lines {
|
|
998
|
-
let stripped = strip_ansi_escapes(line);
|
|
999
|
-
let line_len = stripped.chars().filter(|&c| !is_thai_combining(c)).count();
|
|
1000
|
-
let physical_lines = if width > 0 {
|
|
1001
|
-
line_len.div_ceil(width)
|
|
1002
|
-
} else {
|
|
1003
|
-
1
|
|
1004
|
-
}
|
|
1005
|
-
.max(1);
|
|
1006
|
-
height = height.saturating_add(physical_lines as u16);
|
|
1007
|
-
}
|
|
1008
|
-
|
|
1009
1103
|
let Ok(text) = lines.join("\n").into_text() else {
|
|
1010
1104
|
return;
|
|
1011
1105
|
};
|
|
1106
|
+
let (width, _) = markdown::terminal_size_or_default();
|
|
1107
|
+
let height = wrapped_text_height(&text, width);
|
|
1012
1108
|
let _ = terminal.insert_before(height, |buf| {
|
|
1013
1109
|
use ratatui::widgets::Widget as _;
|
|
1014
|
-
//
|
|
1015
|
-
//
|
|
1016
|
-
//
|
|
1017
|
-
//
|
|
1018
|
-
// more rows than it painted — leaving stray blank rows behind in
|
|
1019
|
-
// the scrollback. Wrapping keeps what's actually drawn in sync
|
|
1020
|
-
// with what was reserved.
|
|
1110
|
+
// Measure and render with the same Paragraph/Wrap implementation.
|
|
1111
|
+
// Counting Rust chars here under-reserved rows for wide Unicode,
|
|
1112
|
+
// emoji, ANSI-styled spans, and word-boundary wrapping, clipping the
|
|
1113
|
+
// tail of otherwise complete assistant responses in scrollback.
|
|
1021
1114
|
ratatui::widgets::Paragraph::new(text)
|
|
1022
1115
|
.wrap(ratatui::widgets::Wrap { trim: false })
|
|
1023
1116
|
.render(buf.area, buf);
|
|
1024
1117
|
});
|
|
1025
1118
|
}
|
|
1026
1119
|
|
|
1120
|
+
fn wrapped_text_height(text: &ratatui::text::Text<'_>, width: u16) -> u16 {
|
|
1121
|
+
ratatui::widgets::Paragraph::new(text.clone())
|
|
1122
|
+
.wrap(ratatui::widgets::Wrap { trim: false })
|
|
1123
|
+
.line_count(width)
|
|
1124
|
+
.max(1)
|
|
1125
|
+
.min(u16::MAX as usize) as u16
|
|
1126
|
+
}
|
|
1127
|
+
|
|
1027
1128
|
/// Tears down the shared inline `ratatui` terminal (if one is currently
|
|
1028
1129
|
/// live), so whatever prints next — an approval card, a committed activity
|
|
1029
1130
|
/// snapshot, the final AI answer — starts from a clean, un-managed cursor
|
|
@@ -1033,6 +1134,10 @@ pub(super) fn insert_permanent_lines(status: &mut LiveStatus, lines: &[String])
|
|
|
1033
1134
|
/// `render_live_status` call reconstructs it fresh, re-querying the
|
|
1034
1135
|
/// terminal for where the cursor actually is now.
|
|
1035
1136
|
pub(super) fn clear_live_status(status: &mut LiveStatus) {
|
|
1137
|
+
if let Some(tui) = &status.tui {
|
|
1138
|
+
tui.clear_status();
|
|
1139
|
+
return;
|
|
1140
|
+
}
|
|
1036
1141
|
if status.inline_tui.terminal.is_none() {
|
|
1037
1142
|
clear_working_status();
|
|
1038
1143
|
return;
|
|
@@ -1092,7 +1197,46 @@ pub(super) fn activity_summary_line(
|
|
|
1092
1197
|
let web_count = activities.len();
|
|
1093
1198
|
let shell_count = tasks
|
|
1094
1199
|
.iter()
|
|
1095
|
-
.filter(|t|
|
|
1200
|
+
.filter(|t| {
|
|
1201
|
+
t.label.starts_with("[run_shell]")
|
|
1202
|
+
|| t.label.starts_with("[shell_output]")
|
|
1203
|
+
|| t.label.starts_with("[kill_shell]")
|
|
1204
|
+
})
|
|
1205
|
+
.count();
|
|
1206
|
+
let edit_count = tasks
|
|
1207
|
+
.iter()
|
|
1208
|
+
.filter(|t| {
|
|
1209
|
+
t.label.starts_with("[write_file]")
|
|
1210
|
+
|| t.label.starts_with("[apply_patch]")
|
|
1211
|
+
|| t.label.starts_with("[note_write]")
|
|
1212
|
+
})
|
|
1213
|
+
.count();
|
|
1214
|
+
let git_count = tasks
|
|
1215
|
+
.iter()
|
|
1216
|
+
.filter(|t| t.label.starts_with("[git_"))
|
|
1217
|
+
.count();
|
|
1218
|
+
let subagent_count = tasks
|
|
1219
|
+
.iter()
|
|
1220
|
+
.filter(|t| {
|
|
1221
|
+
t.label.contains("[dispatch_subagent]")
|
|
1222
|
+
|| t.label.contains("Subagent dispatched")
|
|
1223
|
+
|| t.label.contains("subagent")
|
|
1224
|
+
})
|
|
1225
|
+
.count();
|
|
1226
|
+
let other_count = tasks
|
|
1227
|
+
.iter()
|
|
1228
|
+
.filter(|t| {
|
|
1229
|
+
!t.label.starts_with("[run_shell]")
|
|
1230
|
+
&& !t.label.starts_with("[shell_output]")
|
|
1231
|
+
&& !t.label.starts_with("[kill_shell]")
|
|
1232
|
+
&& !t.label.starts_with("[write_file]")
|
|
1233
|
+
&& !t.label.starts_with("[apply_patch]")
|
|
1234
|
+
&& !t.label.starts_with("[note_write]")
|
|
1235
|
+
&& !t.label.starts_with("[git_")
|
|
1236
|
+
&& !t.label.contains("[dispatch_subagent]")
|
|
1237
|
+
&& !t.label.contains("Subagent dispatched")
|
|
1238
|
+
&& !t.label.contains("subagent")
|
|
1239
|
+
})
|
|
1096
1240
|
.count();
|
|
1097
1241
|
|
|
1098
1242
|
let mut parts: Vec<String> = Vec::new();
|
|
@@ -1108,6 +1252,12 @@ pub(super) fn activity_summary_line(
|
|
|
1108
1252
|
if file_count == 1 { "" } else { "s" }
|
|
1109
1253
|
));
|
|
1110
1254
|
}
|
|
1255
|
+
if edit_count > 0 {
|
|
1256
|
+
parts.push(format!(
|
|
1257
|
+
"editing {edit_count} file{}",
|
|
1258
|
+
if edit_count == 1 { "" } else { "s" }
|
|
1259
|
+
));
|
|
1260
|
+
}
|
|
1111
1261
|
if dir_count > 0 {
|
|
1112
1262
|
parts.push(format!(
|
|
1113
1263
|
"listing {dir_count} director{}",
|
|
@@ -1132,8 +1282,33 @@ pub(super) fn activity_summary_line(
|
|
|
1132
1282
|
if shell_count == 1 { "" } else { "s" }
|
|
1133
1283
|
));
|
|
1134
1284
|
}
|
|
1285
|
+
if git_count > 0 {
|
|
1286
|
+
parts.push(format!(
|
|
1287
|
+
"checking repository {git_count} time{}",
|
|
1288
|
+
if git_count == 1 { "" } else { "s" }
|
|
1289
|
+
));
|
|
1290
|
+
}
|
|
1291
|
+
if subagent_count > 0 {
|
|
1292
|
+
parts.push(format!(
|
|
1293
|
+
"dispatching {subagent_count} subagent{}",
|
|
1294
|
+
if subagent_count == 1 { "" } else { "s" }
|
|
1295
|
+
));
|
|
1296
|
+
}
|
|
1297
|
+
if other_count > 0 {
|
|
1298
|
+
parts.push(format!(
|
|
1299
|
+
"running {other_count} tool{}",
|
|
1300
|
+
if other_count == 1 { "" } else { "s" }
|
|
1301
|
+
));
|
|
1302
|
+
}
|
|
1135
1303
|
|
|
1136
1304
|
if parts.is_empty() {
|
|
1305
|
+
let total = tasks.len() + activities.len() + explored.len();
|
|
1306
|
+
if total > 0 {
|
|
1307
|
+
return Some(format!(
|
|
1308
|
+
"Running {total} tool{}…",
|
|
1309
|
+
if total == 1 { "" } else { "s" }
|
|
1310
|
+
));
|
|
1311
|
+
}
|
|
1137
1312
|
return None;
|
|
1138
1313
|
}
|
|
1139
1314
|
let sentence = parts.join(", ");
|
|
@@ -1154,20 +1329,68 @@ pub(super) fn activity_block_lines(
|
|
|
1154
1329
|
explored: &[ExploredAction],
|
|
1155
1330
|
animate: bool,
|
|
1156
1331
|
tick: usize,
|
|
1332
|
+
active_tool_started: Option<Instant>,
|
|
1333
|
+
// Whether to render stored command-output preview lines.
|
|
1334
|
+
include_output: bool,
|
|
1157
1335
|
) -> Vec<String> {
|
|
1158
1336
|
if tasks.is_empty() && activities.is_empty() && explored.is_empty() {
|
|
1159
1337
|
return Vec::new();
|
|
1160
1338
|
}
|
|
1161
1339
|
let char_str = bullet_char(animate, tick);
|
|
1162
|
-
let header_text =
|
|
1163
|
-
|
|
1340
|
+
let header_text = activity_summary_line(tasks, activities, explored)
|
|
1341
|
+
.unwrap_or_else(|| "Running tools…".into());
|
|
1164
1342
|
let mut lines = vec![format!(" {BLUE}{char_str}{RESET} {header_text}")];
|
|
1165
|
-
|
|
1166
|
-
lines
|
|
1167
|
-
|
|
1343
|
+
|
|
1344
|
+
// Collect all items with their output lines
|
|
1345
|
+
let mut all_items: Vec<(String, Vec<String>)> = Vec::new();
|
|
1346
|
+
for task in tasks.iter().take(24) {
|
|
1347
|
+
all_items.push((task.label.clone(), task.output.clone()));
|
|
1348
|
+
}
|
|
1349
|
+
for act in activities.iter().take(24) {
|
|
1350
|
+
all_items.push((act.clone(), Vec::new()));
|
|
1351
|
+
}
|
|
1352
|
+
let grouped = grouped_explored_actions(explored);
|
|
1353
|
+
for action in grouped.into_iter().take(24) {
|
|
1354
|
+
all_items.push((action, Vec::new()));
|
|
1355
|
+
}
|
|
1356
|
+
|
|
1357
|
+
let total_items = all_items.len();
|
|
1358
|
+
const SPINNER_FRAMES: &[&str] = &["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
|
|
1359
|
+
let spinner = SPINNER_FRAMES[tick % SPINNER_FRAMES.len()];
|
|
1360
|
+
|
|
1361
|
+
for (idx, (label, output)) in all_items.into_iter().enumerate() {
|
|
1362
|
+
let is_active = animate && active_tool_started.is_some() && idx == total_items - 1;
|
|
1363
|
+
let prefix = if idx == 0 {
|
|
1364
|
+
format!("{DIM} └{RESET}")
|
|
1365
|
+
} else {
|
|
1366
|
+
" ".to_string()
|
|
1367
|
+
};
|
|
1368
|
+
|
|
1369
|
+
if is_active {
|
|
1370
|
+
let elapsed_secs = active_tool_started.unwrap().elapsed().as_secs_f64();
|
|
1371
|
+
let timer_suffix = format!(" ({:.1}s)", elapsed_secs);
|
|
1372
|
+
lines.push(format!(
|
|
1373
|
+
"{prefix} {CYAN}{spinner}{RESET} {WHITE}{label}{RESET}{DIM}{timer_suffix}{RESET}"
|
|
1374
|
+
));
|
|
1375
|
+
} else {
|
|
1376
|
+
lines.push(format!("{prefix} {MINT}✓{RESET} {WHITE}{label}{RESET}"));
|
|
1377
|
+
}
|
|
1378
|
+
|
|
1379
|
+
if include_output {
|
|
1380
|
+
for out_line in &output {
|
|
1381
|
+
lines.push(format!("{DIM} │ {}{RESET}", out_line));
|
|
1382
|
+
}
|
|
1383
|
+
}
|
|
1384
|
+
}
|
|
1385
|
+
|
|
1386
|
+
let raw_total = tasks.len() + activities.len() + explored.len();
|
|
1387
|
+
if raw_total > 24 {
|
|
1388
|
+
lines.push(format!("{DIM} ... {} more{RESET}", raw_total - 24));
|
|
1389
|
+
}
|
|
1168
1390
|
lines
|
|
1169
1391
|
}
|
|
1170
1392
|
|
|
1393
|
+
#[allow(dead_code)]
|
|
1171
1394
|
pub(super) fn explored_lines(actions: &[ExploredAction]) -> Vec<String> {
|
|
1172
1395
|
if actions.is_empty() {
|
|
1173
1396
|
return Vec::new();
|
|
@@ -1178,8 +1401,12 @@ pub(super) fn explored_lines(actions: &[ExploredAction]) -> Vec<String> {
|
|
|
1178
1401
|
.take(24)
|
|
1179
1402
|
.enumerate()
|
|
1180
1403
|
.map(|(index, action)| {
|
|
1181
|
-
|
|
1182
|
-
|
|
1404
|
+
if index == 0 {
|
|
1405
|
+
// └ connector in DIM, tool text in WHITE (plain white)
|
|
1406
|
+
format!("{DIM} └{RESET} {WHITE}{action}{RESET}")
|
|
1407
|
+
} else {
|
|
1408
|
+
format!(" {WHITE}{action}{RESET}")
|
|
1409
|
+
}
|
|
1183
1410
|
})
|
|
1184
1411
|
.collect();
|
|
1185
1412
|
if grouped.len() > 24 {
|
|
@@ -1325,6 +1552,7 @@ pub(super) fn truncate_line(line: &str, max_chars: usize) -> String {
|
|
|
1325
1552
|
format!("{head}…")
|
|
1326
1553
|
}
|
|
1327
1554
|
|
|
1555
|
+
#[allow(dead_code)]
|
|
1328
1556
|
pub(super) fn activities_lines(activities: &[String]) -> Vec<String> {
|
|
1329
1557
|
if activities.is_empty() {
|
|
1330
1558
|
return Vec::new();
|
|
@@ -1334,8 +1562,12 @@ pub(super) fn activities_lines(activities: &[String]) -> Vec<String> {
|
|
|
1334
1562
|
.take(24)
|
|
1335
1563
|
.enumerate()
|
|
1336
1564
|
.map(|(index, act)| {
|
|
1337
|
-
|
|
1338
|
-
|
|
1565
|
+
if index == 0 {
|
|
1566
|
+
// └ connector in DIM, activity text in WHITE (plain white)
|
|
1567
|
+
format!("{DIM} └{RESET} {WHITE}{act}{RESET}")
|
|
1568
|
+
} else {
|
|
1569
|
+
format!(" {WHITE}{act}{RESET}")
|
|
1570
|
+
}
|
|
1339
1571
|
})
|
|
1340
1572
|
.collect();
|
|
1341
1573
|
if activities.len() > 24 {
|
|
@@ -1396,14 +1628,19 @@ pub(super) fn plan_lines(steps: &[String], animate: bool, tick: usize) -> Vec<St
|
|
|
1396
1628
|
lines
|
|
1397
1629
|
}
|
|
1398
1630
|
|
|
1631
|
+
#[allow(dead_code)]
|
|
1399
1632
|
pub(super) fn tasks_lines(tasks: &[TaskEntry]) -> Vec<String> {
|
|
1400
1633
|
if tasks.is_empty() {
|
|
1401
1634
|
return Vec::new();
|
|
1402
1635
|
}
|
|
1403
1636
|
let mut lines = Vec::new();
|
|
1404
1637
|
for (index, task) in tasks.iter().take(24).enumerate() {
|
|
1405
|
-
|
|
1406
|
-
|
|
1638
|
+
if index == 0 {
|
|
1639
|
+
// └ connector in DIM, task label in WHITE (plain white)
|
|
1640
|
+
lines.push(format!("{DIM} └{RESET} {WHITE}{}{RESET}", task.label));
|
|
1641
|
+
} else {
|
|
1642
|
+
lines.push(format!(" {WHITE}{}{RESET}", task.label));
|
|
1643
|
+
}
|
|
1407
1644
|
for out_line in &task.output {
|
|
1408
1645
|
lines.push(format!("{DIM} │ {}{RESET}", out_line));
|
|
1409
1646
|
}
|
|
@@ -1452,6 +1689,18 @@ mod format_token_count_tests {
|
|
|
1452
1689
|
}
|
|
1453
1690
|
}
|
|
1454
1691
|
|
|
1692
|
+
#[cfg(test)]
|
|
1693
|
+
mod scrollback_layout_tests {
|
|
1694
|
+
use super::*;
|
|
1695
|
+
|
|
1696
|
+
#[test]
|
|
1697
|
+
fn scrollback_height_accounts_for_wide_unicode() {
|
|
1698
|
+
let text = ratatui::text::Text::raw("🙂🙂🙂");
|
|
1699
|
+
|
|
1700
|
+
assert_eq!(wrapped_text_height(&text, 4), 2);
|
|
1701
|
+
}
|
|
1702
|
+
}
|
|
1703
|
+
|
|
1455
1704
|
#[cfg(test)]
|
|
1456
1705
|
mod project_tokens_tests {
|
|
1457
1706
|
use super::*;
|