@hienlh/ppm 0.17.16 → 0.17.18
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/CHANGELOG.md +19 -0
- package/assets/skills/ppm/SKILL.md +1 -1
- package/assets/skills/ppm/references/cli-reference.md +4 -4
- package/assets/skills/ppm/references/http-api.md +5 -1
- package/dist/web/assets/{ai-resource-editor-CsossqDO.js → ai-resource-editor-BgWg-ty8.js} +1 -1
- package/dist/web/assets/{angular-html-CkxY2iBQ.js → angular-html-2g8YGiJY.js} +1 -1
- package/dist/web/assets/{angular-ts-BePeGkkC.js → angular-ts-BwSmoLfh.js} +1 -1
- package/dist/web/assets/{api-settings-DAk7D-NP.js → api-settings-BJTjIG4U.js} +1 -1
- package/dist/web/assets/{api-themes-84MT-XqR.js → api-themes-DuLpbQFV.js} +1 -1
- package/dist/web/assets/{apl-DBS7PWvB.js → apl-B44SMKHp.js} +1 -1
- package/dist/web/assets/architecture-PBZL5I3N-gLlhsjM9.js +1 -0
- package/dist/web/assets/{astro-Clbk1k4h.js → astro-E5620wek.js} +1 -1
- package/dist/web/assets/{audio-preview-DIkokvPM.js → audio-preview-CLn1LTxc.js} +1 -1
- package/dist/web/assets/{blade-BeBsBuGS.js → blade-D-VQWAHB.js} +1 -1
- package/dist/web/assets/{bsl-DYigT3JZ.js → bsl-Bq5qFzpU.js} +1 -1
- package/dist/web/assets/{cairo-BjpO78wI.js → cairo-Cn9-ZKRa.js} +1 -1
- package/dist/web/assets/chat-tab-tTUVo4G3.js +13 -0
- package/dist/web/assets/{cobol-CpuUx69s.js → cobol-IM3E3iCH.js} +1 -1
- package/dist/web/assets/code-editor-DMfUjdk5.js +10 -0
- package/dist/web/assets/{coffee-FoFd2Cxo.js → coffee-24wG7ekn.js} +1 -1
- package/dist/web/assets/{conflict-editor-Dqm1bkyL.js → conflict-editor-BosR4PW3.js} +3 -3
- package/dist/web/assets/{cpp-CO_nPfdr.js → cpp-DH9Cqt4g.js} +1 -1
- package/dist/web/assets/{crystal-D-UygAAF.js → crystal-4nZYHhdi.js} +1 -1
- package/dist/web/assets/{csv-preview-CvP4xzug.js → csv-preview-BqszurHp.js} +1 -1
- package/dist/web/assets/data-grid-overlay-editor-DxdOKRAY.js +1 -0
- package/dist/web/assets/data-grid-types-CzEQU9PJ.js +1 -0
- package/dist/web/assets/database-viewer-CiomoOU6.js +1 -0
- package/dist/web/assets/dialog-BpkAWOy8.js +1 -0
- package/dist/web/assets/{diff-viewer-BfWixe_z.js → diff-viewer-aOrOaGWx.js} +1 -1
- package/dist/web/assets/dist-Bn3E6I4R.js +11 -0
- package/dist/web/assets/{docx-preview-CguUoTKe.js → docx-preview-BAzpJdua.js} +1 -1
- package/dist/web/assets/{edge-BSzxzX11.js → edge-DTI9d2Qi.js} +1 -1
- package/dist/web/assets/{elixir-DH1-Mrep.js → elixir-Ys0wioho.js} +1 -1
- package/dist/web/assets/{elm-B0ln5J70.js → elm-Cihc9TAz.js} +1 -1
- package/dist/web/assets/{erb-GIz6NnlZ.js → erb-BwYBWK2-.js} +1 -1
- package/dist/web/assets/{erlang-B8MgYhib.js → erlang-CzlD_Joo.js} +1 -1
- package/dist/web/assets/esm-JLkfN0k-.js +2 -0
- package/dist/web/assets/{extension-webview-DTpFt1eL.js → extension-webview-CKUUvgOr.js} +1 -1
- package/dist/web/assets/{fortran-fixed-form-D_-TrK6U.js → fortran-fixed-form-CT90EtSp.js} +1 -1
- package/dist/web/assets/{fsharp-C9cLCk2b.js → fsharp-LasxezlU.js} +1 -1
- package/dist/web/assets/{gdresource-CsZ3lXwY.js → gdresource-XqgPdfiE.js} +1 -1
- package/dist/web/assets/{git-commit-xmq0KqrA.js → git-commit-CZBgPolw.js} +1 -1
- package/dist/web/assets/{git-log-panel-DUX7N5tN.js → git-log-panel-B6GFWhj4.js} +1 -1
- package/dist/web/assets/{git-rebase-D3O-jsSX.js → git-rebase-C2VzKDB1.js} +1 -1
- package/dist/web/assets/gitGraph-HDMCJU4V-BKGq--Jw.js +1 -0
- package/dist/web/assets/glide-data-grid-z9FPvRBG.js +138 -0
- package/dist/web/assets/{glimmer-js-g74gESrC.js → glimmer-js-DfjWcOLD.js} +1 -1
- package/dist/web/assets/{glimmer-ts-DF4aDWHT.js → glimmer-ts-DBldQATc.js} +1 -1
- package/dist/web/assets/{glsl-D5LmfW7l.js → glsl-CzNv1NPP.js} +1 -1
- package/dist/web/assets/{graphql-_KI4RuXL.js → graphql-DDyLtQb4.js} +1 -1
- package/dist/web/assets/group-chat-tab-Bu31mwmF.js +1 -0
- package/dist/web/assets/{hack-B1NaTC39.js → hack-CtoYNYkC.js} +1 -1
- package/dist/web/assets/{haml-DDFXadZ4.js → haml-CnBVap7G.js} +1 -1
- package/dist/web/assets/{handlebars-Bp-Jq3K9.js → handlebars-Dg51esUH.js} +1 -1
- package/dist/web/assets/{html-DyB9_5Tj.js → html-Ec2_evSy.js} +1 -1
- package/dist/web/assets/{html-derivative-CC60wi-3.js → html-derivative-Cy-F7ZqL.js} +1 -1
- package/dist/web/assets/{http-C-9qngH4.js → http-C236v8Tg.js} +1 -1
- package/dist/web/assets/{hurl-BtxgpNDs.js → hurl-0rMD2gPU.js} +1 -1
- package/dist/web/assets/{hxml-DOoOS9op.js → hxml-e5uS5jTD.js} +1 -1
- package/dist/web/assets/{image-preview-CZg6FQ3w.js → image-preview-CaX4gpN6.js} +1 -1
- package/dist/web/assets/index-4M24PSHW.js +50 -0
- package/dist/web/assets/index-BYFXiFsa.css +2 -0
- package/dist/web/assets/info-3K5VOQVL-BOhGriBF.js +1 -0
- package/dist/web/assets/{jinja-cN-150ao.js → jinja-DybFmhfq.js} +1 -1
- package/dist/web/assets/{jison-CqjsqPq5.js → jison-hkHbixdZ.js} +1 -1
- package/dist/web/assets/{julia-C-I5m8W4.js → julia-QnxY6sRE.js} +1 -1
- package/dist/web/assets/{just-CgsSW9zs.js → just-1Rs-nm8g.js} +1 -1
- package/dist/web/assets/keybindings-store-Cv-U85V6.js +1 -0
- package/dist/web/assets/{latex-BFzR9N2d.js → latex-jEBQqA7u.js} +1 -1
- package/dist/web/assets/{liquid-BWfr-_iC.js → liquid-DfJaZpxG.js} +1 -1
- package/dist/web/assets/{lua-DsXVun6g.js → lua-ti0Jr6-C.js} +1 -1
- package/dist/web/assets/{markdown-renderer-CiQkvWP_.js → markdown-renderer-BNXJygz9.js} +3 -3
- package/dist/web/assets/markdown-renderer-DCsEEdo7.js +1 -0
- package/dist/web/assets/{marko-DWBbo09n.js → marko-DNj4AhPg.js} +1 -1
- package/dist/web/assets/{mdc-CUMe9LOG.js → mdc-DPFwQFe4.js} +1 -1
- package/dist/web/assets/mobile-bottom-sheet--5_YEewV.js +1 -0
- package/dist/web/assets/{nextflow-CoYbADOm.js → nextflow-BUrFV5aB.js} +1 -1
- package/dist/web/assets/{nginx-z-JRZREw.js → nginx-BrW9NdOb.js} +1 -1
- package/dist/web/assets/{nim-Ci4LHyBm.js → nim-DS_6PF2p.js} +1 -1
- package/dist/web/assets/notification-store-DADt1gJH.js +1 -0
- package/dist/web/assets/{number-overlay-editor-lnnuUpPI.js → number-overlay-editor-CReXWiQ1.js} +1 -1
- package/dist/web/assets/packet-RMMSAZCW-CdLFnL8a.js +1 -0
- package/dist/web/assets/{panel-store-D6RV_ztx.js → panel-store-DnbT1c8L.js} +1 -1
- package/dist/web/assets/{pdf-preview-B6ZqANpw.js → pdf-preview-DZzbm9A4.js} +1 -1
- package/dist/web/assets/{perl-pbDimKOO.js → perl-ytm9vKO_.js} +1 -1
- package/dist/web/assets/{php-B003E5v7.js → php-DWTD1Usw.js} +1 -1
- package/dist/web/assets/pie-UPGHQEXC-COC-h0zz.js +1 -0
- package/dist/web/assets/{trash-2-CbbD5QF1.js → plus-DcuJuDC3.js} +1 -1
- package/dist/web/assets/postgres-viewer-BxpeiVkt.js +3 -0
- package/dist/web/assets/{project-store-Cekcjcom.js → project-store-Sbnqc41N.js} +1 -1
- package/dist/web/assets/{pug-AoueAWJo.js → pug-Bt7KL3_r.js} +1 -1
- package/dist/web/assets/{qml-CepxioQA.js → qml-Dexdon5J.js} +1 -1
- package/dist/web/assets/radar-KQ55EAFF-CiCfdJNL.js +1 -0
- package/dist/web/assets/{razor-lIvU-Gu-.js → razor-DnYCSl0G.js} +1 -1
- package/dist/web/assets/{rst-Dn-dwElE.js → rst-BEFYzwF8.js} +1 -1
- package/dist/web/assets/{ruby-DmsD1Iz5.js → ruby-BPaXFEjN.js} +1 -1
- package/dist/web/assets/{sas-6IM2P4YP.js → sas-CywiNBp8.js} +1 -1
- package/dist/web/assets/{scss-RgYEZQqh.js → scss-CGk0L6hN.js} +1 -1
- package/dist/web/assets/{settings-store-BkSf4SPQ.js → settings-store-DkRZhj-g.js} +2 -2
- package/dist/web/assets/settings-tab-DJOhpW09.js +1 -0
- package/dist/web/assets/{shaderlab-B0MNEwt4.js → shaderlab-Byjk0kH7.js} +1 -1
- package/dist/web/assets/{shellsession-F8S4LrQI.js → shellsession-DbA70QB6.js} +1 -1
- package/dist/web/assets/{soy-DDlMbX7u.js → soy-Bm97kWiA.js} +1 -1
- package/dist/web/assets/sparkles-B3DmG8PJ.js +1 -0
- package/dist/web/assets/{sparql-kthmGAAe.js → sparql-CawLnniT.js} +1 -1
- package/dist/web/assets/{sql-query-editor-BYNM0RRl.js → sql-query-editor-9TwIPvRj.js} +1 -1
- package/dist/web/assets/sqlite-viewer-D-3i_x28.js +1 -0
- package/dist/web/assets/{stata-Tfbew8La.js → stata-RifEDtNO.js} +1 -1
- package/dist/web/assets/{surrealql-C0LIGqRx.js → surrealql-DGRQa5Lm.js} +1 -1
- package/dist/web/assets/{svelte-CfTy8CGF.js → svelte-w9Hb12aM.js} +1 -1
- package/dist/web/assets/system-monitor-tab-CuVVp2wt.js +1 -0
- package/dist/web/assets/{tab-store-CcLQfu8H.js → tab-store-vn0viMOP.js} +1 -1
- package/dist/web/assets/{templ-V5H1Sbfy.js → templ-BpUwjJXV.js} +1 -1
- package/dist/web/assets/{terminal-tab-CK3lX-0Y.js → terminal-tab-DrSqSrdX.js} +2 -2
- package/dist/web/assets/{tex-C3H3uMZf.js → tex-DJFSsuTD.js} +1 -1
- package/dist/web/assets/tool-cards-CtE_JnF-.js +7 -0
- package/dist/web/assets/treemap-KZPCXAKY-CZwuSCtA.js +1 -0
- package/dist/web/assets/{ts-tags-7AXgG5YS.js → ts-tags-vp9Qvx2O.js} +1 -1
- package/dist/web/assets/{twig-BSyS38T3.js → twig-CoazxjRB.js} +1 -1
- package/dist/web/assets/{use-blob-url-CpyRr7Cx.js → use-blob-url-DdXgVqfz.js} +1 -1
- package/dist/web/assets/use-is-mobile-CE6AamG6.js +1 -0
- package/dist/web/assets/{use-monaco-theme-Jj2OxkAE.js → use-monaco-theme-BvzqffqR.js} +1 -1
- package/dist/web/assets/{vendor-mermaid-DGOXKrJC.js → vendor-mermaid-DPpYkrMf.js} +193 -193
- package/dist/web/assets/{video-preview-BOHxkwKG.js → video-preview-DxdyVATR.js} +1 -1
- package/dist/web/assets/{vue-C4d_br9u.js → vue-CnshsiXd.js} +1 -1
- package/dist/web/assets/{vue-html-CGdoz4vW.js → vue-html-CZshynFp.js} +1 -1
- package/dist/web/assets/{vue-vine-CqNolQlN.js → vue-vine-C5gtp_T1.js} +1 -1
- package/dist/web/assets/{xml-UmCmu-Od.js → xml-BEGJasgj.js} +1 -1
- package/dist/web/assets/{xsl-DJG6USGh.js → xsl-DXpRLjYk.js} +1 -1
- package/dist/web/index.html +22 -20
- package/dist/web/monacoeditorwork/css.worker.bundle.js +122 -122
- package/dist/web/monacoeditorwork/editor.worker.bundle.js +78 -78
- package/dist/web/monacoeditorwork/html.worker.bundle.js +110 -110
- package/dist/web/monacoeditorwork/json.worker.bundle.js +108 -108
- package/dist/web/monacoeditorwork/ts.worker.bundle.js +81 -81
- package/dist/web/sw.js +1 -1
- package/docs/journal/binary-self-upgrade-260724.md +66 -0
- package/nul/docs/claude-agent-sdk-reference.md +780 -0
- package/nul/docs/code-standards.md +1080 -0
- package/nul/docs/codebase-summary.md +916 -0
- package/nul/docs/deployment-guide.md +702 -0
- package/nul/docs/design-guidelines.md +767 -0
- package/nul/docs/extension-development-guide.md +629 -0
- package/nul/docs/journals/260414-1400-ext-git-graph-port-complete.md +147 -0
- package/nul/docs/journals/260414-1452-git-graph-faithful-port.md +144 -0
- package/nul/docs/journals/260414-1810-git-graph-ui-improvements-complete.md +261 -0
- package/nul/docs/journals/260414-2001-bundled-extensions.md +219 -0
- package/nul/docs/journals/260415-frontend-memory-optimization.md +73 -0
- package/nul/docs/lessons-learned.md +70 -0
- package/nul/docs/project-changelog.md +574 -0
- package/nul/docs/project-overview-pdr.md +205 -0
- package/nul/docs/project-roadmap.md +222 -0
- package/nul/docs/system-architecture.md +1961 -0
- package/package.json +1 -1
- package/packages/vscode-compat/node_modules/.bin/tsc.bunx +0 -0
- package/packages/vscode-compat/node_modules/.bin/tsc.exe +0 -0
- package/packages/vscode-compat/node_modules/.bin/tsserver.bunx +0 -0
- package/packages/vscode-compat/node_modules/.bin/tsserver.exe +0 -0
- package/spike-group-channel.mjs +156 -0
- package/spike-group-chat.mjs +181 -0
- package/src/server/routes/group-chat.ts +118 -9
- package/src/services/group-chat/agent-runner.ts +15 -2
- package/src/services/group-chat/context-window.ts +15 -0
- package/src/services/group-chat/group-chat.service.ts +178 -79
- package/src/services/group-chat/group-chat.store.ts +30 -0
- package/src/services/group-chat/responder-router.ts +110 -0
- package/src/services/group-chat/transcript-archive.ts +18 -0
- package/src/services/group-chat/turn-engine.ts +183 -105
- package/src/services/jsonl-transcript-parser.ts +36 -0
- package/src/types/group-chat-ws.ts +2 -2
- package/src/types/group-chat.ts +33 -4
- package/src/web/components/group-chat/group-chat-tab.tsx +109 -14
- package/src/web/components/group-chat/group-create-dialog.tsx +10 -3
- package/src/web/components/group-chat/group-full-transcript-view.tsx +9 -8
- package/src/web/components/group-chat/group-member-edit-dialog.tsx +108 -0
- package/src/web/components/group-chat/group-member-roster.tsx +51 -23
- package/src/web/components/group-chat/group-message-item.tsx +45 -26
- package/src/web/components/group-chat/group-transcript-messages.tsx +126 -0
- package/src/web/components/layout/cloud-share-popover.tsx +10 -2
- package/src/web/components/layout/mobile-drawer-tab-bar.tsx +10 -0
- package/src/web/components/layout/mobile-drawer.tsx +26 -9
- package/src/web/components/layout/nav-section-rail.tsx +8 -2
- package/src/web/components/layout/upgrade-button.tsx +33 -11
- package/src/web/hooks/use-group-chat.ts +8 -1
- package/src/web/lib/api-group-chat.ts +47 -4
- package/src/web/lib/sidebar-tabs/tab-registry.ts +3 -1
- package/dist/web/assets/architecture-PBZL5I3N-NAS99xy0.js +0 -1
- package/dist/web/assets/chat-tab-Bh6l253v.js +0 -18
- package/dist/web/assets/click-outside-container-DXZVmhaX.js +0 -1
- package/dist/web/assets/code-editor-B7F-d4DK.js +0 -10
- package/dist/web/assets/data-grid-overlay-editor-CUlFsD-D.js +0 -1
- package/dist/web/assets/database-viewer-5oNTPgjF.js +0 -1
- package/dist/web/assets/dist-BsziT-tR.js +0 -11
- package/dist/web/assets/esm-CjVeOTNQ.js +0 -2
- package/dist/web/assets/gitGraph-HDMCJU4V-B4I3L4Sf.js +0 -1
- package/dist/web/assets/glide-data-grid-7vB1SNne.js +0 -138
- package/dist/web/assets/group-chat-tab-CNECY-zg.js +0 -1
- package/dist/web/assets/index-D2G6kmTs.js +0 -50
- package/dist/web/assets/index-DCmrZnq0.css +0 -2
- package/dist/web/assets/info-3K5VOQVL-CBbbOe3C.js +0 -1
- package/dist/web/assets/input-24Nf_edC.js +0 -1
- package/dist/web/assets/keybindings-store-D8Cppv4w.js +0 -1
- package/dist/web/assets/notification-store-DOGxkWih.js +0 -1
- package/dist/web/assets/packet-RMMSAZCW-fr8-QSTF.js +0 -1
- package/dist/web/assets/pie-UPGHQEXC-Biu7_Pbb.js +0 -1
- package/dist/web/assets/postgres-viewer-B23xTCSs.js +0 -3
- package/dist/web/assets/radar-KQ55EAFF-CMtNRpK6.js +0 -1
- package/dist/web/assets/settings-tab-D5hAA1bY.js +0 -1
- package/dist/web/assets/sparkles-2ii4lR7b.js +0 -1
- package/dist/web/assets/sqlite-viewer-DW9f2Hqj.js +0 -1
- package/dist/web/assets/system-monitor-tab-B5f4pgdX.js +0 -1
- package/dist/web/assets/treemap-KZPCXAKY-ZYVFjoaN.js +0 -1
- package/dist/web/assets/use-websocket-DrDBgIWU.js +0 -1
- /package/dist/web/assets/{abap-BZ3J5hF3.js → abap-wT6fgqwv.js} +0 -0
- /package/dist/web/assets/{actionscript-3-CkyGfT-8.js → actionscript-3-CqcHpPYj.js} +0 -0
- /package/dist/web/assets/{ada-CxNLBoe7.js → ada-DWE3Hn4E.js} +0 -0
- /package/dist/web/assets/{andromeeda-BPN5rsDz.js → andromeeda-DpQ-y-Jt.js} +0 -0
- /package/dist/web/assets/{apache-C1F5wHL6.js → apache-LRTUP4r3.js} +0 -0
- /package/dist/web/assets/{apex-BaNixdO-.js → apex-DwVeH5_h.js} +0 -0
- /package/dist/web/assets/{api-client-Dvzcc_EO.js → api-client-BK4NPNoY.js} +0 -0
- /package/dist/web/assets/{applescript-Cl_pdcch.js → applescript-DyQiO9JU.js} +0 -0
- /package/dist/web/assets/{apply-theme-ORrEdHKT.js → apply-theme-DxKsrDLA.js} +0 -0
- /package/dist/web/assets/{ara-B6UAE7M2.js → ara-Cf-OWd2S.js} +0 -0
- /package/dist/web/assets/{asciidoc-D9c9Twki.js → asciidoc-gocbKcVK.js} +0 -0
- /package/dist/web/assets/{asm-CNmtv7Y9.js → asm-C3meb5HY.js} +0 -0
- /package/dist/web/assets/{aurora-x-C9z-NyzR.js → aurora-x-BYcXaCIg.js} +0 -0
- /package/dist/web/assets/{awk-BfLHEnKa.js → awk-BcT6nIdN.js} +0 -0
- /package/dist/web/assets/{ayu-dark-Bn7trkt_.js → ayu-dark-CLZPoccg.js} +0 -0
- /package/dist/web/assets/{ayu-light-Dpya9hPf.js → ayu-light-CTyRQdS2.js} +0 -0
- /package/dist/web/assets/{ayu-mirage-Cc0jfABD.js → ayu-mirage-DjqfqZdo.js} +0 -0
- /package/dist/web/assets/{ballerina-BtiCmN7T.js → ballerina-BCARR-zK.js} +0 -0
- /package/dist/web/assets/{bat-tmFM76zR.js → bat-_yaRjWOb.js} +0 -0
- /package/dist/web/assets/{beancount-BjPqRrcH.js → beancount-BPESBMS9.js} +0 -0
- /package/dist/web/assets/{berry-D0SQBxN2.js → berry-BSLE-Sf8.js} +0 -0
- /package/dist/web/assets/{bibtex-CkjRWQKr.js → bibtex-CvUWWCVx.js} +0 -0
- /package/dist/web/assets/{bicep-Bhq28Cxc.js → bicep--vcqqALZ.js} +0 -0
- /package/dist/web/assets/{bird2-DFGInYb3.js → bird2-Clclqgh6.js} +0 -0
- /package/dist/web/assets/{c-CP8cB4k_.js → c-CSC2LwTp.js} +0 -0
- /package/dist/web/assets/{c3-oRytyeWo.js → c3-Cl1_jUnm.js} +0 -0
- /package/dist/web/assets/{cadence-Inf1rGb7.js → cadence-BwAD7vSC.js} +0 -0
- /package/dist/web/assets/{catppuccin-frappe-DAzribQo.js → catppuccin-frappe-hr0HKoFX.js} +0 -0
- /package/dist/web/assets/{catppuccin-latte-B6Y_mCCQ.js → catppuccin-latte-DXEIYlFO.js} +0 -0
- /package/dist/web/assets/{catppuccin-macchiato-COLbYqVL.js → catppuccin-macchiato-B2zST7sA.js} +0 -0
- /package/dist/web/assets/{catppuccin-mocha-DKWaML1B.js → catppuccin-mocha-CvrdnYv9.js} +0 -0
- /package/dist/web/assets/{chevron-right-BBc6ATtm.js → chevron-right-DeUue2aK.js} +0 -0
- /package/dist/web/assets/{circle-question-mark-CveWaCux.js → circle-question-mark-PaJgx-3d.js} +0 -0
- /package/dist/web/assets/{clarity-_ZLLrrsX.js → clarity-BeQd5TQD.js} +0 -0
- /package/dist/web/assets/{clojure-DWGVCg_P.js → clojure-Csdo0vb_.js} +0 -0
- /package/dist/web/assets/{cmake-Cwh3mug7.js → cmake-Cf0q7ddg.js} +0 -0
- /package/dist/web/assets/{code-7ZAlTvsm.js → code-TekEnDFM.js} +0 -0
- /package/dist/web/assets/{codeowners-BdV6CFYi.js → codeowners-CUEzlC7R.js} +0 -0
- /package/dist/web/assets/{codeql-NvupDIDf.js → codeql-DxHyogQt.js} +0 -0
- /package/dist/web/assets/{common-lisp-B-vtBh5k.js → common-lisp-WLb-tAda.js} +0 -0
- /package/dist/web/assets/{coq-M8-FTfiZ.js → coq-DFtMD6Wn.js} +0 -0
- /package/dist/web/assets/{csharp-B7Ugdtd-.js → csharp-DEnvXVjs.js} +0 -0
- /package/dist/web/assets/{css-86k3Z-YA.js → css-DMPpCfkZ.js} +0 -0
- /package/dist/web/assets/{csv-BX5XYhfH.js → csv-DTSgNSaP.js} +0 -0
- /package/dist/web/assets/{csv-parser-d56Fzpwc.js → csv-parser-B_xNn07y.js} +0 -0
- /package/dist/web/assets/{cue-B7099gQa.js → cue-BEmVIZmd.js} +0 -0
- /package/dist/web/assets/{cypher-D99mWVIu.js → cypher-CncQVhvU.js} +0 -0
- /package/dist/web/assets/{d-CFE8oQwh.js → d-BzUSBVex.js} +0 -0
- /package/dist/web/assets/{dark-plus-BEeeDwdg.js → dark-plus-mysFNRq2.js} +0 -0
- /package/dist/web/assets/{dart-HVSWGnI5.js → dart-BBu3nkcE.js} +0 -0
- /package/dist/web/assets/{database-BLht7BVM.js → database-COYAMZaw.js} +0 -0
- /package/dist/web/assets/{dax-DjDgSJkh.js → dax-DcLVz9_9.js} +0 -0
- /package/dist/web/assets/{desktop-B5A3i7J1.js → desktop-DS2PdvoU.js} +0 -0
- /package/dist/web/assets/{diff-CpTrlaE9.js → diff-aUYk5Qys.js} +0 -0
- /package/dist/web/assets/{dist-BSCgJs-V.js → dist-Dxl3dqhC.js} +0 -0
- /package/dist/web/assets/{docker-xBhmJeHj.js → docker-12Lj1QUD.js} +0 -0
- /package/dist/web/assets/{dotenv-DKKhLEv5.js → dotenv-D-P4bzvl.js} +0 -0
- /package/dist/web/assets/{dracula-CVwQuzra.js → dracula-C-eRNn4o.js} +0 -0
- /package/dist/web/assets/{dracula-soft-CG6mB-lf.js → dracula-soft-CBB1BI7O.js} +0 -0
- /package/dist/web/assets/{dream-maker-SC-IdYY3.js → dream-maker-C_j5A0r7.js} +0 -0
- /package/dist/web/assets/{edit-diff-preview-C50i1H63.js → edit-diff-preview-CRMu-6r1.js} +0 -0
- /package/dist/web/assets/{emacs-lisp-CIBFq6W8.js → emacs-lisp-W54LT7rh.js} +0 -0
- /package/dist/web/assets/{everforest-dark-odRT_lec.js → everforest-dark-B_ISUDeh.js} +0 -0
- /package/dist/web/assets/{everforest-light-or1Voqjl.js → everforest-light-CNUYa354.js} +0 -0
- /package/dist/web/assets/{fennel-tQd1z3iu.js → fennel-DK82-oso.js} +0 -0
- /package/dist/web/assets/{file-exclamation-point-C-lL0g_E.js → file-exclamation-point-DBEC-Kst.js} +0 -0
- /package/dist/web/assets/{fish-DSuZQG0k.js → fish-CbJVJzQj.js} +0 -0
- /package/dist/web/assets/{fluent-D7xI8a8e.js → fluent-Cug5cOL1.js} +0 -0
- /package/dist/web/assets/{fortran-free-form-BlAtcPd3.js → fortran-free-form-amHz32Zw.js} +0 -0
- /package/dist/web/assets/{gdscript-VsEQXBPm.js → gdscript-t_G6VYpv.js} +0 -0
- /package/dist/web/assets/{gdshader-iqHMOdwW.js → gdshader-DqZaHh4E.js} +0 -0
- /package/dist/web/assets/{genie-C4XU4g1a.js → genie-CIJtFlZK.js} +0 -0
- /package/dist/web/assets/{gherkin-C4nfQzAB.js → gherkin-CalidqLY.js} +0 -0
- /package/dist/web/assets/{github-dark-B_pbG3CC.js → github-dark-BG2xX0wa.js} +0 -0
- /package/dist/web/assets/{github-dark-default-kFbx7C95.js → github-dark-default-tDp_EOBs.js} +0 -0
- /package/dist/web/assets/{github-dark-dimmed-CpVfQEqs.js → github-dark-dimmed-DlSfPwW2.js} +0 -0
- /package/dist/web/assets/{github-dark-high-contrast-DYKqQwZh.js → github-dark-high-contrast-qZM7j5KB.js} +0 -0
- /package/dist/web/assets/{github-light-gEYBmKaj.js → github-light-CnvWTiyb.js} +0 -0
- /package/dist/web/assets/{github-light-default-DVHfMPQ2.js → github-light-default-Dy6OAt2Q.js} +0 -0
- /package/dist/web/assets/{github-light-high-contrast-ClVJDu-q.js → github-light-high-contrast-1BHQCOPl.js} +0 -0
- /package/dist/web/assets/{gleam-BLaPu7ft.js → gleam-D-2cpXVX.js} +0 -0
- /package/dist/web/assets/{gn-BKgerUyI.js → gn-C1cC4xLc.js} +0 -0
- /package/dist/web/assets/{gnuplot-cqJuEFb-.js → gnuplot-2Gp459mV.js} +0 -0
- /package/dist/web/assets/{go-B2EHdyD8.js → go-BA1q0q8h.js} +0 -0
- /package/dist/web/assets/{groovy-DdImoj8s.js → groovy-BlIa-VfI.js} +0 -0
- /package/dist/web/assets/{gruvbox-dark-hard-DlwstAds.js → gruvbox-dark-hard-BMIwVwaJ.js} +0 -0
- /package/dist/web/assets/{gruvbox-dark-medium-CiYEd1vd.js → gruvbox-dark-medium-DxfuBW3n.js} +0 -0
- /package/dist/web/assets/{gruvbox-dark-soft-C-wEa4h4.js → gruvbox-dark-soft-_NSslDDi.js} +0 -0
- /package/dist/web/assets/{gruvbox-light-hard-BqYmfna-.js → gruvbox-light-hard-CP5MIsL9.js} +0 -0
- /package/dist/web/assets/{gruvbox-light-medium-CxmfalT2.js → gruvbox-light-medium-BTMursH0.js} +0 -0
- /package/dist/web/assets/{gruvbox-light-soft-DGWXXMCB.js → gruvbox-light-soft-Bv6zFoVX.js} +0 -0
- /package/dist/web/assets/{haskell-H_C_IuVb.js → haskell-Da8UeSv-.js} +0 -0
- /package/dist/web/assets/{haxe-CGNSMpeZ.js → haxe-mcKlcxBa.js} +0 -0
- /package/dist/web/assets/{hcl-B7bSTSQf.js → hcl-BdZcx5JX.js} +0 -0
- /package/dist/web/assets/{hjson-DlJ-glQZ.js → hjson-pFXYbN4t.js} +0 -0
- /package/dist/web/assets/{hlsl-CehW5SJN.js → hlsl-Z0II0KR8.js} +0 -0
- /package/dist/web/assets/{horizon-Beabcz2d.js → horizon-CufN8DyP.js} +0 -0
- /package/dist/web/assets/{horizon-bright-BC87RXPa.js → horizon-bright-5qoQVyIY.js} +0 -0
- /package/dist/web/assets/{houston-Da7RFwUy.js → houston-DOFkQwep.js} +0 -0
- /package/dist/web/assets/{hy-m1H70w19.js → hy-BVbDMDcG.js} +0 -0
- /package/dist/web/assets/{imba-MExFsdAA.js → imba-DRM6LLS5.js} +0 -0
- /package/dist/web/assets/{ini-CJy_zmwy.js → ini-2KCnNvmz.js} +0 -0
- /package/dist/web/assets/{java-DqDFvJBH.js → java-BmvH-Ou1.js} +0 -0
- /package/dist/web/assets/{javascript-C3Wyv22X.js → javascript-B7VhU1Yc.js} +0 -0
- /package/dist/web/assets/{json-DnGBw_DZ.js → json-X1pNk0n7.js} +0 -0
- /package/dist/web/assets/{json5-CRN-zoN4.js → json5-CJeEJPTg.js} +0 -0
- /package/dist/web/assets/{jsonc-CKRUZNRo.js → jsonc-C1haTBsf.js} +0 -0
- /package/dist/web/assets/{jsonl-CGfD6FrH.js → jsonl-wQ8-AJgs.js} +0 -0
- /package/dist/web/assets/{jsonnet-nbFuDj0o.js → jsonnet-BrEjY3Xh.js} +0 -0
- /package/dist/web/assets/{jssm-D0ShzIqD.js → jssm-C6LgYbOs.js} +0 -0
- /package/dist/web/assets/{jsx-D27hbRbs.js → jsx-B2cfD_Fb.js} +0 -0
- /package/dist/web/assets/{kanagawa-dragon-Ov3f8K0T.js → kanagawa-dragon-6UCcJpLw.js} +0 -0
- /package/dist/web/assets/{kanagawa-lotus-CLyOqh-g.js → kanagawa-lotus-DOmfpsRg.js} +0 -0
- /package/dist/web/assets/{kanagawa-wave-Kj3dzabH.js → kanagawa-wave-CpxmPE7N.js} +0 -0
- /package/dist/web/assets/{kdl-DFF58Gu4.js → kdl-BrLEivmb.js} +0 -0
- /package/dist/web/assets/{kotlin-BM4PKaB4.js → kotlin-BO2FUnDB.js} +0 -0
- /package/dist/web/assets/{kusto-DrvHLCv5.js → kusto-Cev1yiq9.js} +0 -0
- /package/dist/web/assets/{laserwave-Db6i6ZkO.js → laserwave-BlEkf-eH.js} +0 -0
- /package/dist/web/assets/{lean-D0hEjzwk.js → lean-BLS3Xk2w.js} +0 -0
- /package/dist/web/assets/{less-BEj4npGG.js → less-BXmcsqcq.js} +0 -0
- /package/dist/web/assets/{lib-CBdlQ75W.js → lib-CxSBdrd7.js} +0 -0
- /package/dist/web/assets/{light-plus-DLIIbDea.js → light-plus-DS6zriYl.js} +0 -0
- /package/dist/web/assets/{llvm-DMt6umsO.js → llvm-C_wLnJgX.js} +0 -0
- /package/dist/web/assets/{log-BopvdtPW.js → log-Cg8pvmWi.js} +0 -0
- /package/dist/web/assets/{logo-CYSUFPFR.js → logo-C9-kEvPW.js} +0 -0
- /package/dist/web/assets/{luau-XC611HNO.js → luau-NwaGugfZ.js} +0 -0
- /package/dist/web/assets/{make-BMYZIfBj.js → make-DBpJE-Z8.js} +0 -0
- /package/dist/web/assets/{markdown-BLza5nvF.js → markdown-B7ZTAu7B.js} +0 -0
- /package/dist/web/assets/{material-theme-Uw27UfJW.js → material-theme-BsXH-Mss.js} +0 -0
- /package/dist/web/assets/{material-theme-darker-dfqt8XBY.js → material-theme-darker-CW9OlIeY.js} +0 -0
- /package/dist/web/assets/{material-theme-lighter-CPtBTblV.js → material-theme-lighter-D2PAh0Kw.js} +0 -0
- /package/dist/web/assets/{material-theme-ocean-BfZgVqC-.js → material-theme-ocean-Vz6DBVi3.js} +0 -0
- /package/dist/web/assets/{material-theme-palenight-DAZoVYg8.js → material-theme-palenight-D-GleP3G.js} +0 -0
- /package/dist/web/assets/{matlab-cSzmquiW.js → matlab-C7MYlMSn.js} +0 -0
- /package/dist/web/assets/{mdx-Dq0kW5VM.js → mdx-FkOOX3Dq.js} +0 -0
- /package/dist/web/assets/{mermaid-DoIKF0yS.js → mermaid-C_9qw5it.js} +0 -0
- /package/dist/web/assets/{min-dark-DyraimDU.js → min-dark-BowNvxk2.js} +0 -0
- /package/dist/web/assets/{min-light-Co9cbcUv.js → min-light-x8oWUmbL.js} +0 -0
- /package/dist/web/assets/{mipsasm-ph6cKgHn.js → mipsasm-Dmi1AZOT.js} +0 -0
- /package/dist/web/assets/{mojo-BBT0XwmY.js → mojo-C6z7mry2.js} +0 -0
- /package/dist/web/assets/{monokai-IP0T5Rtg.js → monokai-BQ4e_Hn0.js} +0 -0
- /package/dist/web/assets/{moonbit-B8cogNXl.js → moonbit-CEeNIoB4.js} +0 -0
- /package/dist/web/assets/{move-DkY26NtM.js → move-bALfKUa7.js} +0 -0
- /package/dist/web/assets/{narrat-rBs3byG0.js → narrat-DX4JlAWT.js} +0 -0
- /package/dist/web/assets/{nextflow-groovy-DkO9wMLP.js → nextflow-groovy-CKQWtRkO.js} +0 -0
- /package/dist/web/assets/{night-owl-jVR4lFji.js → night-owl-D4PQd726.js} +0 -0
- /package/dist/web/assets/{night-owl-light-fBYJ7s3U.js → night-owl-light-BQo_YHll.js} +0 -0
- /package/dist/web/assets/{nix-WX9oavu6.js → nix-B1jThkGj.js} +0 -0
- /package/dist/web/assets/{nord-Cf7G21Pu.js → nord-35quHUKo.js} +0 -0
- /package/dist/web/assets/{nushell-DQdzcJ1H.js → nushell-L6DbJTuL.js} +0 -0
- /package/dist/web/assets/{objective-c-JSO2uvZ-.js → objective-c-CTZ4bR2U.js} +0 -0
- /package/dist/web/assets/{objective-cpp-CZMGJ9Fb.js → objective-cpp-Dm1YDIdA.js} +0 -0
- /package/dist/web/assets/{ocaml-C4S4NSDo.js → ocaml-B3n__LGy.js} +0 -0
- /package/dist/web/assets/{odin-Y2jXCgVq.js → odin-DmqZ8n3i.js} +0 -0
- /package/dist/web/assets/{one-dark-pro-dVIxuoJY.js → one-dark-pro-16_UaUig.js} +0 -0
- /package/dist/web/assets/{one-light-BQ1IKfD1.js → one-light-B-GGjWn5.js} +0 -0
- /package/dist/web/assets/{openscad-Bddw4I3z.js → openscad-DTFB9Sj6.js} +0 -0
- /package/dist/web/assets/{pascal-BKVXrzC1.js → pascal-RcT1dQYN.js} +0 -0
- /package/dist/web/assets/{pkl-BTd-YRsO.js → pkl-Dr4yLQ_o.js} +0 -0
- /package/dist/web/assets/{plastic-eiGvBIxV.js → plastic-hp2Nry0R.js} +0 -0
- /package/dist/web/assets/{plsql-C290tieP.js → plsql-pFcO4WZ0.js} +0 -0
- /package/dist/web/assets/{po-DyDwh0tx.js → po-BkZ0_HvY.js} +0 -0
- /package/dist/web/assets/{poimandres-B87zc_g-.js → poimandres-BcTrxj7f.js} +0 -0
- /package/dist/web/assets/{polar-Cdub1YMT.js → polar-DHK3q8FF.js} +0 -0
- /package/dist/web/assets/{postcss-BcI_3K0v.js → postcss-Bv7WzijA.js} +0 -0
- /package/dist/web/assets/{powerquery-OdMrkJSe.js → powerquery-DpaU_hW9.js} +0 -0
- /package/dist/web/assets/{powershell-C8auT6xg.js → powershell-_Rqc0MGP.js} +0 -0
- /package/dist/web/assets/{prisma-DIbVv8PA.js → prisma-wyegE8us.js} +0 -0
- /package/dist/web/assets/{prolog-DbTOH3Ld.js → prolog-DspHCURv.js} +0 -0
- /package/dist/web/assets/{proto-C4Cq2dCD.js → proto-BOBiNGf5.js} +0 -0
- /package/dist/web/assets/{puppet-DJp3uqum.js → puppet-DfLvV8h2.js} +0 -0
- /package/dist/web/assets/{purescript-CLsV4rPU.js → purescript-BY5ZSOZy.js} +0 -0
- /package/dist/web/assets/{python-2gBtEza2.js → python-B758mMeg.js} +0 -0
- /package/dist/web/assets/{qmldir-DfhULcua.js → qmldir-C75bpHvy.js} +0 -0
- /package/dist/web/assets/{qss-DK--VTTV.js → qss-DcLTlbLd.js} +0 -0
- /package/dist/web/assets/{r-BArBO2Sa.js → r-D0G_Y1P5.js} +0 -0
- /package/dist/web/assets/{racket-5mijHsVy.js → racket-DTye_5qn.js} +0 -0
- /package/dist/web/assets/{raku-ir0suElk.js → raku-uJXBXkV0.js} +0 -0
- /package/dist/web/assets/{react-J9g6e3Rq.js → react-CorNPdie.js} +0 -0
- /package/dist/web/assets/{red-DSecpIOT.js → red-rs3HE3re.js} +0 -0
- /package/dist/web/assets/{reg-Dp30FusS.js → reg-DkTIaX7a.js} +0 -0
- /package/dist/web/assets/{regexp-DXJnEM_6.js → regexp-4TLSs4_m.js} +0 -0
- /package/dist/web/assets/{rel-Dr483ozj.js → rel-B0jumCjt.js} +0 -0
- /package/dist/web/assets/{resolve-theme-DJORYzKu.js → resolve-theme-CCoakF2E.js} +0 -0
- /package/dist/web/assets/{riscv-ZfBy5IA1.js → riscv-DtaWMlo0.js} +0 -0
- /package/dist/web/assets/{ron-ZJ_CljGP.js → ron-BCPxwJD6.js} +0 -0
- /package/dist/web/assets/{rose-pine-CcW_eJ6G.js → rose-pine-CNryoqGi.js} +0 -0
- /package/dist/web/assets/{rose-pine-dawn-v2l_UF-j.js → rose-pine-dawn-C-gJOQVP.js} +0 -0
- /package/dist/web/assets/{rose-pine-moon-CNXkwf3D.js → rose-pine-moon-BdXSXpZh.js} +0 -0
- /package/dist/web/assets/{rosmsg-BMYMVW84.js → rosmsg-CPG8X-D5.js} +0 -0
- /package/dist/web/assets/{rust-BR-zJh5q.js → rust-CxfW3ePx.js} +0 -0
- /package/dist/web/assets/{sass-BukPOBFz.js → sass-D-7bxo_L.js} +0 -0
- /package/dist/web/assets/{save-DO5xjW95.js → save-BM4p9_9n.js} +0 -0
- /package/dist/web/assets/{scala-DUFY7D6D.js → scala-DyUsfHNc.js} +0 -0
- /package/dist/web/assets/{scheme-Dl-dNNxQ.js → scheme-ROgrwiO-.js} +0 -0
- /package/dist/web/assets/{sdbl-DdmlQhia.js → sdbl-B1EAQWpp.js} +0 -0
- /package/dist/web/assets/{shellscript-UyhrvGcd.js → shellscript-HhmB_Ufy.js} +0 -0
- /package/dist/web/assets/{shield-check-m2QzZTuZ.js → shield-check-C3qYSU8a.js} +0 -0
- /package/dist/web/assets/{shield-off-DNn7VzJe.js → shield-off-D5tU7gQT.js} +0 -0
- /package/dist/web/assets/{slack-dark-Cv6Szr-q.js → slack-dark-DnmSY72G.js} +0 -0
- /package/dist/web/assets/{slack-ochin-V6Ii3lAm.js → slack-ochin-q97gHjcd.js} +0 -0
- /package/dist/web/assets/{smalltalk-BUCv5G91.js → smalltalk-B-1waXvA.js} +0 -0
- /package/dist/web/assets/{snazzy-light-B67a78qi.js → snazzy-light-C8yWDN2g.js} +0 -0
- /package/dist/web/assets/{solarized-dark-ccWnfYyA.js → solarized-dark-ClVDEMJZ.js} +0 -0
- /package/dist/web/assets/{solarized-light-C3WyRO5I.js → solarized-light-Bts6CUIP.js} +0 -0
- /package/dist/web/assets/{solidity-BFbRPNi_.js → solidity-DYxwp0om.js} +0 -0
- /package/dist/web/assets/{splunk-zdpwCJLE.js → splunk-jK6-Sr06.js} +0 -0
- /package/dist/web/assets/{sql-B2IPUsfz.js → sql-DPpd8aUS.js} +0 -0
- /package/dist/web/assets/{ssh-config-Co4cXifq.js → ssh-config-Bimb9LVr.js} +0 -0
- /package/dist/web/assets/{stylus-CmI75XY8.js → stylus-B2DgJRJw.js} +0 -0
- /package/dist/web/assets/{swift-Dfks9YQI.js → swift-ChEH2nFL.js} +0 -0
- /package/dist/web/assets/{synthwave-84-B3LERzNS.js → synthwave-84-DwSLbgAm.js} +0 -0
- /package/dist/web/assets/{system-verilog-BFvldiwl.js → system-verilog-DoVBMhJ8.js} +0 -0
- /package/dist/web/assets/{systemd-Cu4Vvgbu.js → systemd--Ux4VAYD.js} +0 -0
- /package/dist/web/assets/{table-CAVmgQMT.js → table-Di8pv2Y_.js} +0 -0
- /package/dist/web/assets/{talonscript-Bnq32pUB.js → talonscript-DQNx9nak.js} +0 -0
- /package/dist/web/assets/{tasl-Nwe2K3J1.js → tasl-Bwy_Y9uD.js} +0 -0
- /package/dist/web/assets/{tcl-zOnpywrl.js → tcl-Drea-2jA.js} +0 -0
- /package/dist/web/assets/{terraform-Bc9Vj-n3.js → terraform-4rS5HoFk.js} +0 -0
- /package/dist/web/assets/{tokyo-night-9_KyM8M2.js → tokyo-night-C9MqaxIn.js} +0 -0
- /package/dist/web/assets/{toml-ByH-fxOY.js → toml-tSgOSv42.js} +0 -0
- /package/dist/web/assets/{tsv-DrCnDClP.js → tsv-BmL4O1Zx.js} +0 -0
- /package/dist/web/assets/{tsx-B8LafSYr.js → tsx-BwzeA880.js} +0 -0
- /package/dist/web/assets/{turtle-DuyP_QCJ.js → turtle-2DYvssFL.js} +0 -0
- /package/dist/web/assets/{typescript-BTBJb5RD.js → typescript-ZC-vonSh.js} +0 -0
- /package/dist/web/assets/{typespec-DdOFo7M5.js → typespec-DkCEO45F.js} +0 -0
- /package/dist/web/assets/{typst-LYvnBWQu.js → typst-DAZdb2n6.js} +0 -0
- /package/dist/web/assets/{utils-CTg5uAYR.js → utils-CSCvNZxE.js} +0 -0
- /package/dist/web/assets/{v-BuBYA1_x.js → v-B_wsb4C1.js} +0 -0
- /package/dist/web/assets/{vala-vRIBYYe3.js → vala-BDBNS784.js} +0 -0
- /package/dist/web/assets/{vb-DwGi-IYM.js → vb-CuOoJSSa.js} +0 -0
- /package/dist/web/assets/{vendor-xterm-i6SHFTfU.js → vendor-xterm-CImj6i6Z.js} +0 -0
- /package/dist/web/assets/{verilog-6B1X4G2-.js → verilog-BCcOvOcc.js} +0 -0
- /package/dist/web/assets/{vesper-Dw1y_Ae7.js → vesper-vN8CREK5.js} +0 -0
- /package/dist/web/assets/{vhdl-DK8JwBzJ.js → vhdl-CI8PoqeM.js} +0 -0
- /package/dist/web/assets/{viml-BTKIEIqm.js → viml-B66dNP1B.js} +0 -0
- /package/dist/web/assets/{vitesse-black-BqqolhEg.js → vitesse-black-0bGIaCfD.js} +0 -0
- /package/dist/web/assets/{vitesse-dark-B9JL5WQA.js → vitesse-dark-Dk-RSXq-.js} +0 -0
- /package/dist/web/assets/{vitesse-light-DYJKj2se.js → vitesse-light-BUsA5RhG.js} +0 -0
- /package/dist/web/assets/{vyper-D-jDI3WH.js → vyper-dNodzEa8.js} +0 -0
- /package/dist/web/assets/{wasm-1-GlNdpk.js → wasm-BDxaNPCj.js} +0 -0
- /package/dist/web/assets/{wasm-BBW4WmT2.js → wasm-d6SE2_qm.js} +0 -0
- /package/dist/web/assets/{wenyan-B6cM7sDO.js → wenyan-D0h8Uz55.js} +0 -0
- /package/dist/web/assets/{wgsl-FaHGQgko.js → wgsl-vKs_vsvQ.js} +0 -0
- /package/dist/web/assets/{wikitext-DtIyPUrk.js → wikitext-BIWsPJit.js} +0 -0
- /package/dist/web/assets/{wit-BMVRif5Y.js → wit-6vmKi2H3.js} +0 -0
- /package/dist/web/assets/{wolfram-DQsCGohn.js → wolfram-zoNg6F1a.js} +0 -0
- /package/dist/web/assets/{x-C2VSAp7O.js → x-BsFLg-T8.js} +0 -0
- /package/dist/web/assets/{yaml-C-Va56Gt.js → yaml-W95qP6-B.js} +0 -0
- /package/dist/web/assets/{zenscript-DdobKGI-.js → zenscript-BxircxDx.js} +0 -0
- /package/dist/web/assets/{zig-vqDFwj6q.js → zig-DD79WQtz.js} +0 -0
|
@@ -35,6 +35,7 @@ export function GroupCreateDialog({
|
|
|
35
35
|
}: GroupCreateDialogProps) {
|
|
36
36
|
const isMobile = useIsMobile();
|
|
37
37
|
const [name, setName] = useState("");
|
|
38
|
+
const [cap, setCap] = useState(10); // reply-burst cap (max AI turns per message)
|
|
38
39
|
const [leaderName, setLeaderName] = useState("Leader");
|
|
39
40
|
const [leaderPersona, setLeaderPersona] = useState("");
|
|
40
41
|
const [leaderModel, setLeaderModel] = useState<string | null>(null);
|
|
@@ -43,7 +44,7 @@ export function GroupCreateDialog({
|
|
|
43
44
|
const [error, setError] = useState<string | null>(null);
|
|
44
45
|
|
|
45
46
|
const reset = useCallback(() => {
|
|
46
|
-
setName(""); setLeaderName("Leader"); setLeaderPersona(""); setLeaderModel(null);
|
|
47
|
+
setName(""); setCap(10); setLeaderName("Leader"); setLeaderPersona(""); setLeaderModel(null);
|
|
47
48
|
setMembers([newMember()]); setError(null); setSubmitting(false);
|
|
48
49
|
}, []);
|
|
49
50
|
|
|
@@ -79,14 +80,14 @@ export function GroupCreateDialog({
|
|
|
79
80
|
setSubmitting(true);
|
|
80
81
|
setError(null);
|
|
81
82
|
try {
|
|
82
|
-
const group = await createGroup({ projectName, projectPath, name: gName, members: roster });
|
|
83
|
+
const group = await createGroup({ projectName, projectPath, name: gName, maxTurns: cap, members: roster });
|
|
83
84
|
onCreated(group);
|
|
84
85
|
close();
|
|
85
86
|
} catch (e) {
|
|
86
87
|
setError(e instanceof Error ? e.message : "Failed to create group");
|
|
87
88
|
setSubmitting(false);
|
|
88
89
|
}
|
|
89
|
-
}, [name, leaderName, leaderPersona, leaderModel, members, projectName, projectPath, onCreated, close]);
|
|
90
|
+
}, [name, cap, leaderName, leaderPersona, leaderModel, members, projectName, projectPath, onCreated, close]);
|
|
90
91
|
|
|
91
92
|
const inputCls =
|
|
92
93
|
"w-full min-h-[40px] rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground placeholder:text-text-subtle focus:outline-none focus:ring-1 focus:ring-primary";
|
|
@@ -99,6 +100,12 @@ export function GroupCreateDialog({
|
|
|
99
100
|
placeholder="e.g. Design Review" autoFocus />
|
|
100
101
|
</div>
|
|
101
102
|
|
|
103
|
+
<div>
|
|
104
|
+
<label className="mb-1 block text-xs font-medium text-text-secondary">Reply cap (max AI turns per message, 1–50)</label>
|
|
105
|
+
<input type="number" min={1} max={50} className={inputCls} value={cap}
|
|
106
|
+
onChange={(e) => setCap(Math.max(1, Math.min(50, Number(e.target.value) || 1)))} />
|
|
107
|
+
</div>
|
|
108
|
+
|
|
102
109
|
<div className="rounded-lg border border-border p-3">
|
|
103
110
|
<p className="mb-2 text-xs font-semibold uppercase tracking-wide text-primary">Leader</p>
|
|
104
111
|
<div className="flex flex-col gap-2">
|
|
@@ -3,7 +3,8 @@ import { Loader2 } from "lucide-react";
|
|
|
3
3
|
import { useIsMobile } from "@/hooks/use-is-mobile";
|
|
4
4
|
import { BottomSheet } from "@/components/ui/mobile-bottom-sheet";
|
|
5
5
|
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog";
|
|
6
|
-
import { getTranscript } from "@/lib/api-group-chat";
|
|
6
|
+
import { getTranscript, type TranscriptResult } from "@/lib/api-group-chat";
|
|
7
|
+
import { GroupTranscriptMessages } from "./group-transcript-messages";
|
|
7
8
|
import type { GroupMessage } from "../../../types/group-chat";
|
|
8
9
|
|
|
9
10
|
interface GroupFullTranscriptViewProps {
|
|
@@ -16,7 +17,7 @@ interface GroupFullTranscriptViewProps {
|
|
|
16
17
|
* Adaptive: centered dialog on desktop, bottom sheet on mobile. */
|
|
17
18
|
export function GroupFullTranscriptView({ groupId, message, onClose }: GroupFullTranscriptViewProps) {
|
|
18
19
|
const isMobile = useIsMobile();
|
|
19
|
-
const [
|
|
20
|
+
const [data, setData] = useState<TranscriptResult | null>(null);
|
|
20
21
|
const [loading, setLoading] = useState(false);
|
|
21
22
|
const [error, setError] = useState<string | null>(null);
|
|
22
23
|
|
|
@@ -25,11 +26,11 @@ export function GroupFullTranscriptView({ groupId, message, onClose }: GroupFull
|
|
|
25
26
|
useEffect(() => {
|
|
26
27
|
if (!message || !sessionRef) return;
|
|
27
28
|
let cancelled = false;
|
|
28
|
-
|
|
29
|
+
setData(null);
|
|
29
30
|
setError(null);
|
|
30
31
|
setLoading(true);
|
|
31
32
|
getTranscript(groupId, sessionRef)
|
|
32
|
-
.then((res) => { if (!cancelled)
|
|
33
|
+
.then((res) => { if (!cancelled) setData(res); })
|
|
33
34
|
.catch((e) => { if (!cancelled) setError(e instanceof Error ? e.message : "Failed to load transcript"); })
|
|
34
35
|
.finally(() => { if (!cancelled) setLoading(false); });
|
|
35
36
|
return () => { cancelled = true; };
|
|
@@ -55,10 +56,10 @@ export function GroupFullTranscriptView({ groupId, message, onClose }: GroupFull
|
|
|
55
56
|
)}
|
|
56
57
|
</div>
|
|
57
58
|
)}
|
|
58
|
-
{!loading && !error &&
|
|
59
|
-
<
|
|
60
|
-
{
|
|
61
|
-
</
|
|
59
|
+
{!loading && !error && data != null && (
|
|
60
|
+
<div className="px-1 py-1">
|
|
61
|
+
<GroupTranscriptMessages messages={data.messages} config={data.config} />
|
|
62
|
+
</div>
|
|
62
63
|
)}
|
|
63
64
|
</div>
|
|
64
65
|
);
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { useState, useCallback } from "react";
|
|
2
|
+
import { Loader2 } from "lucide-react";
|
|
3
|
+
import { useIsMobile } from "@/hooks/use-is-mobile";
|
|
4
|
+
import { BottomSheet } from "@/components/ui/mobile-bottom-sheet";
|
|
5
|
+
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog";
|
|
6
|
+
import { Button } from "@/components/ui/button";
|
|
7
|
+
import { ModelSelector } from "@/components/chat/model-selector";
|
|
8
|
+
import type { GroupMember, MemberRole } from "../../../types/group-chat";
|
|
9
|
+
|
|
10
|
+
export interface MemberFormValues {
|
|
11
|
+
name: string;
|
|
12
|
+
persona: string | null;
|
|
13
|
+
model: string | null;
|
|
14
|
+
role: MemberRole;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
interface Props {
|
|
18
|
+
open: boolean;
|
|
19
|
+
/** Editing an existing member, or null when adding a new one. */
|
|
20
|
+
member: GroupMember | null;
|
|
21
|
+
projectName: string;
|
|
22
|
+
providerId?: string;
|
|
23
|
+
onSubmit: (values: MemberFormValues) => Promise<void>;
|
|
24
|
+
onClose: () => void;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const inputCls =
|
|
28
|
+
"w-full min-h-[40px] rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground placeholder:text-text-subtle focus:outline-none focus:ring-1 focus:ring-primary";
|
|
29
|
+
|
|
30
|
+
export function GroupMemberEditDialog({ open, member, projectName, providerId = "claude", onSubmit, onClose }: Props) {
|
|
31
|
+
const isMobile = useIsMobile();
|
|
32
|
+
const [name, setName] = useState(member?.name ?? "");
|
|
33
|
+
const [persona, setPersona] = useState(member?.persona ?? "");
|
|
34
|
+
const [model, setModel] = useState<string | null>(member?.model ?? null);
|
|
35
|
+
const [isLeader, setIsLeader] = useState(member?.role === "leader");
|
|
36
|
+
const [submitting, setSubmitting] = useState(false);
|
|
37
|
+
const [error, setError] = useState<string | null>(null);
|
|
38
|
+
|
|
39
|
+
const handleSubmit = useCallback(async () => {
|
|
40
|
+
const n = name.trim();
|
|
41
|
+
if (!n) { setError("Name is required"); return; }
|
|
42
|
+
setSubmitting(true);
|
|
43
|
+
setError(null);
|
|
44
|
+
try {
|
|
45
|
+
await onSubmit({ name: n, persona: persona.trim() || null, model, role: isLeader ? "leader" : "member" });
|
|
46
|
+
onClose();
|
|
47
|
+
} catch (e) {
|
|
48
|
+
setError(e instanceof Error ? e.message : "Failed to save member");
|
|
49
|
+
setSubmitting(false);
|
|
50
|
+
}
|
|
51
|
+
}, [name, persona, model, isLeader, onSubmit, onClose]);
|
|
52
|
+
|
|
53
|
+
const alreadyLeader = member?.role === "leader";
|
|
54
|
+
|
|
55
|
+
const form = (
|
|
56
|
+
<div className="flex flex-col gap-3 px-1 py-1">
|
|
57
|
+
<input className={inputCls} value={name} onChange={(e) => setName(e.target.value)} placeholder="Member name" autoFocus />
|
|
58
|
+
<input className={inputCls} value={persona} onChange={(e) => setPersona(e.target.value)} placeholder="Persona (optional)" />
|
|
59
|
+
<ModelSelector value={model} onChange={setModel} projectName={projectName} providerId={providerId} />
|
|
60
|
+
<label className={cnLeader(alreadyLeader)}>
|
|
61
|
+
<input
|
|
62
|
+
type="checkbox"
|
|
63
|
+
className="size-4 accent-[var(--color-primary)]"
|
|
64
|
+
checked={isLeader}
|
|
65
|
+
disabled={alreadyLeader}
|
|
66
|
+
onChange={(e) => setIsLeader(e.target.checked)}
|
|
67
|
+
/>
|
|
68
|
+
<span>{alreadyLeader ? "Leader (reassign from another member)" : "Set as leader"}</span>
|
|
69
|
+
</label>
|
|
70
|
+
{error && <p className="text-xs text-destructive">{error}</p>}
|
|
71
|
+
<div className="flex justify-end gap-2 pt-1">
|
|
72
|
+
<Button variant="outline" onClick={onClose} disabled={submitting}>Cancel</Button>
|
|
73
|
+
<Button onClick={handleSubmit} disabled={submitting}>
|
|
74
|
+
{submitting && <Loader2 className="mr-1.5 size-4 animate-spin" />}
|
|
75
|
+
{member ? "Save" : "Add member"}
|
|
76
|
+
</Button>
|
|
77
|
+
</div>
|
|
78
|
+
</div>
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
if (!open) return null;
|
|
82
|
+
const title = member ? "Edit member" : "Add member";
|
|
83
|
+
|
|
84
|
+
if (isMobile) {
|
|
85
|
+
return (
|
|
86
|
+
<BottomSheet open onClose={onClose} className="flex max-h-[90vh] flex-col">
|
|
87
|
+
<div className="flex min-h-0 flex-col px-4 pb-2">
|
|
88
|
+
<h2 className="mb-2 text-base font-semibold text-foreground">{title}</h2>
|
|
89
|
+
{form}
|
|
90
|
+
</div>
|
|
91
|
+
</BottomSheet>
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return (
|
|
96
|
+
<Dialog open onOpenChange={(o) => { if (!o) onClose(); }}>
|
|
97
|
+
<DialogContent className="flex flex-col sm:max-w-md">
|
|
98
|
+
<DialogHeader><DialogTitle>{title}</DialogTitle></DialogHeader>
|
|
99
|
+
{form}
|
|
100
|
+
</DialogContent>
|
|
101
|
+
</Dialog>
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** Label styling for the leader checkbox row (dimmed when already leader). */
|
|
106
|
+
function cnLeader(disabled: boolean): string {
|
|
107
|
+
return `flex items-center gap-2 text-sm text-text-secondary ${disabled ? "opacity-60" : ""}`;
|
|
108
|
+
}
|
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
import { memo } from "react";
|
|
2
|
+
import { Pencil, Trash2, UserPlus } from "lucide-react";
|
|
2
3
|
import { cn } from "@/lib/utils";
|
|
3
|
-
import type { MemberStatus } from "../../../types/group-chat";
|
|
4
|
-
import type { RosterMember } from "@/hooks/use-group-chat";
|
|
4
|
+
import type { GroupMember, MemberStatus } from "../../../types/group-chat";
|
|
5
5
|
|
|
6
6
|
interface GroupMemberRosterProps {
|
|
7
|
-
members:
|
|
7
|
+
members: GroupMember[];
|
|
8
|
+
/** memberId → live status (working/done/error) from the running burst. */
|
|
9
|
+
liveStatus: Map<string, MemberStatus>;
|
|
8
10
|
/** Member name → true when composing a turn. */
|
|
9
11
|
typing: Record<string, boolean>;
|
|
12
|
+
/** Disables actions while a mutation is in flight. */
|
|
13
|
+
busy?: boolean;
|
|
14
|
+
onAdd: () => void;
|
|
15
|
+
onEdit: (member: GroupMember) => void;
|
|
16
|
+
onRemove: (member: GroupMember) => void;
|
|
10
17
|
}
|
|
11
18
|
|
|
12
19
|
const STATUS_DOT: Record<MemberStatus, string> = {
|
|
@@ -23,26 +30,17 @@ const STATUS_LABEL: Record<MemberStatus, string> = {
|
|
|
23
30
|
error: "Error",
|
|
24
31
|
};
|
|
25
32
|
|
|
26
|
-
/**
|
|
33
|
+
/** Editable roster: avatar + name + role/persona + live status; add/edit/remove. */
|
|
27
34
|
export const GroupMemberRoster = memo(function GroupMemberRoster({
|
|
28
|
-
members,
|
|
29
|
-
typing,
|
|
35
|
+
members, liveStatus, typing, busy, onAdd, onEdit, onRemove,
|
|
30
36
|
}: GroupMemberRosterProps) {
|
|
31
|
-
if (members.length === 0) {
|
|
32
|
-
return (
|
|
33
|
-
<div className="p-3 text-xs text-text-subtle">No members yet.</div>
|
|
34
|
-
);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
37
|
return (
|
|
38
|
-
<
|
|
38
|
+
<div className="flex flex-col gap-0.5 p-2">
|
|
39
39
|
{members.map((m) => {
|
|
40
40
|
const isTyping = typing[m.name];
|
|
41
|
+
const status = liveStatus.get(m.id) ?? m.status;
|
|
41
42
|
return (
|
|
42
|
-
<
|
|
43
|
-
key={m.id}
|
|
44
|
-
className="flex items-center gap-2 rounded-md px-2 py-1.5"
|
|
45
|
-
>
|
|
43
|
+
<div key={m.id} className="group flex items-center gap-2 rounded-md px-2 py-1.5">
|
|
46
44
|
<span
|
|
47
45
|
className="flex size-6 shrink-0 items-center justify-center rounded-full text-[10px] font-semibold text-white ring-2 ring-background"
|
|
48
46
|
style={{ backgroundColor: m.color ?? "var(--accent)" }}
|
|
@@ -59,18 +57,48 @@ export const GroupMemberRoster = memo(function GroupMemberRoster({
|
|
|
59
57
|
</span>
|
|
60
58
|
)}
|
|
61
59
|
</div>
|
|
62
|
-
<span className="text-[10px] text-text-subtle">
|
|
63
|
-
{isTyping ? "typing…" : STATUS_LABEL[
|
|
60
|
+
<span className="block truncate text-[10px] text-text-subtle">
|
|
61
|
+
{isTyping ? "typing…" : (m.persona || STATUS_LABEL[status])}
|
|
64
62
|
</span>
|
|
65
63
|
</div>
|
|
64
|
+
{/* Actions — always visible on touch; hover-reveal on pointer devices. */}
|
|
65
|
+
<div className="flex shrink-0 items-center gap-0.5 can-hover:opacity-0 can-hover:group-hover:opacity-100">
|
|
66
|
+
<button
|
|
67
|
+
type="button"
|
|
68
|
+
onClick={() => onEdit(m)}
|
|
69
|
+
disabled={busy}
|
|
70
|
+
aria-label={`Edit ${m.name}`}
|
|
71
|
+
className="flex size-8 items-center justify-center rounded-md text-text-subtle hover:bg-surface-elevated hover:text-foreground active:bg-surface-elevated disabled:opacity-40"
|
|
72
|
+
>
|
|
73
|
+
<Pencil className="size-3.5" />
|
|
74
|
+
</button>
|
|
75
|
+
<button
|
|
76
|
+
type="button"
|
|
77
|
+
onClick={() => onRemove(m)}
|
|
78
|
+
disabled={busy}
|
|
79
|
+
aria-label={`Remove ${m.name}`}
|
|
80
|
+
className="flex size-8 items-center justify-center rounded-md text-text-subtle hover:bg-surface-elevated hover:text-destructive active:bg-surface-elevated disabled:opacity-40"
|
|
81
|
+
>
|
|
82
|
+
<Trash2 className="size-3.5" />
|
|
83
|
+
</button>
|
|
84
|
+
</div>
|
|
66
85
|
<span
|
|
67
|
-
className={cn("size-2 shrink-0 rounded-full", STATUS_DOT[
|
|
68
|
-
title={STATUS_LABEL[
|
|
86
|
+
className={cn("size-2 shrink-0 rounded-full", STATUS_DOT[status])}
|
|
87
|
+
title={STATUS_LABEL[status]}
|
|
69
88
|
aria-hidden
|
|
70
89
|
/>
|
|
71
|
-
</
|
|
90
|
+
</div>
|
|
72
91
|
);
|
|
73
92
|
})}
|
|
74
|
-
|
|
93
|
+
|
|
94
|
+
<button
|
|
95
|
+
type="button"
|
|
96
|
+
onClick={onAdd}
|
|
97
|
+
disabled={busy}
|
|
98
|
+
className="mt-1 flex items-center gap-2 rounded-md px-2 py-2 text-xs font-medium text-primary hover:bg-surface-elevated active:bg-surface-elevated disabled:opacity-40"
|
|
99
|
+
>
|
|
100
|
+
<UserPlus className="size-4" /> Add member
|
|
101
|
+
</button>
|
|
102
|
+
</div>
|
|
75
103
|
);
|
|
76
104
|
});
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import { memo, type ReactNode } from "react";
|
|
2
|
+
import { ScrollText } from "lucide-react";
|
|
2
3
|
import { cn } from "@/lib/utils";
|
|
4
|
+
import {
|
|
5
|
+
ContextMenu,
|
|
6
|
+
ContextMenuTrigger,
|
|
7
|
+
ContextMenuContent,
|
|
8
|
+
ContextMenuItem,
|
|
9
|
+
} from "@/components/ui/adaptive-context-menu";
|
|
3
10
|
import type { GroupMessage } from "../../../types/group-chat";
|
|
4
11
|
|
|
5
12
|
interface GroupMessageItemProps {
|
|
@@ -21,7 +28,10 @@ function initials(name: string): string {
|
|
|
21
28
|
|
|
22
29
|
function formatTime(ts: number): string {
|
|
23
30
|
try {
|
|
24
|
-
|
|
31
|
+
// The bus stores created_at in SECONDS (SQLite unixepoch()); Date expects ms.
|
|
32
|
+
// Normalize second-scale values so timestamps don't all collapse to one minute.
|
|
33
|
+
const ms = ts < 1e12 ? ts * 1000 : ts;
|
|
34
|
+
return new Date(ms).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
|
|
25
35
|
} catch {
|
|
26
36
|
return "";
|
|
27
37
|
}
|
|
@@ -30,7 +40,7 @@ function formatTime(ts: number): string {
|
|
|
30
40
|
/** Render body text with @mentions tinted in the mentioned member's color
|
|
31
41
|
* (falls back to the primary accent) so it's obvious who is being addressed. */
|
|
32
42
|
function withMentions(text: string, colorFor: (n: string) => string | null): ReactNode[] {
|
|
33
|
-
return text.split(/(
|
|
43
|
+
return text.split(/(@[\p{L}\p{N}_]+)/gu).map((part, i) => {
|
|
34
44
|
if (part.startsWith("@") && part.length > 1) {
|
|
35
45
|
const c = colorFor(part.slice(1));
|
|
36
46
|
return (
|
|
@@ -44,7 +54,7 @@ function withMentions(text: string, colorFor: (n: string) => string | null): Rea
|
|
|
44
54
|
}
|
|
45
55
|
|
|
46
56
|
/** Slack-style feed row: colored avatar + name accent per speaker, left color
|
|
47
|
-
* bar, "You" for the user, leader badge, highlighted @mentions
|
|
57
|
+
* bar, "You" for the user, leader badge, highlighted @mentions. */
|
|
48
58
|
export const GroupMessageItem = memo(function GroupMessageItem({
|
|
49
59
|
message,
|
|
50
60
|
colorFor,
|
|
@@ -55,18 +65,30 @@ export const GroupMessageItem = memo(function GroupMessageItem({
|
|
|
55
65
|
const displayName = isUser ? "You" : message.fromMember;
|
|
56
66
|
const accent = isUser ? "var(--color-primary)" : (colorFor(message.fromMember) ?? "var(--accent)");
|
|
57
67
|
const leader = !isUser && isLeader(message.fromMember);
|
|
58
|
-
const isFinal = message.kind === "final";
|
|
59
68
|
const summary = message.summary ?? "";
|
|
60
69
|
const target = message.toMember && message.toMember !== "all" ? message.toMember : null;
|
|
61
70
|
|
|
62
|
-
|
|
71
|
+
const row = (
|
|
63
72
|
<div
|
|
64
73
|
className={cn(
|
|
65
|
-
"flex gap-2.5 px-3 py-2 transition-colors hover:bg-surface-elevated/50",
|
|
74
|
+
"group relative flex gap-2.5 px-3 py-2 transition-colors hover:bg-surface-elevated/50",
|
|
66
75
|
isUser && "bg-primary/5",
|
|
67
76
|
)}
|
|
68
77
|
style={{ boxShadow: `inset 3px 0 0 0 ${accent}` }}
|
|
69
78
|
>
|
|
79
|
+
{/* Transcript (AI raw thinking / debug) — top-right icon, POINTER DEVICES ONLY,
|
|
80
|
+
revealed on hover. On touch it's hidden; use long-press → context menu instead. */}
|
|
81
|
+
{message.fullSessionRef && (
|
|
82
|
+
<button
|
|
83
|
+
type="button"
|
|
84
|
+
onClick={() => onViewFull(message)}
|
|
85
|
+
title="View full transcript (AI's raw thinking / debug)"
|
|
86
|
+
aria-label="View full transcript"
|
|
87
|
+
className="absolute right-1.5 top-1.5 hidden items-center rounded p-1 text-text-subtle/60 hover:bg-surface-elevated hover:text-text-secondary can-hover:group-hover:inline-flex"
|
|
88
|
+
>
|
|
89
|
+
<ScrollText className="size-3.5" />
|
|
90
|
+
</button>
|
|
91
|
+
)}
|
|
70
92
|
<div
|
|
71
93
|
className="mt-0.5 flex size-8 shrink-0 items-center justify-center rounded-full text-[11px] font-semibold text-white ring-2 ring-background"
|
|
72
94
|
style={{ backgroundColor: accent }}
|
|
@@ -75,7 +97,7 @@ export const GroupMessageItem = memo(function GroupMessageItem({
|
|
|
75
97
|
{initials(displayName)}
|
|
76
98
|
</div>
|
|
77
99
|
|
|
78
|
-
<div className="min-w-0 flex-1">
|
|
100
|
+
<div className="min-w-0 flex-1 can-hover:pr-6">
|
|
79
101
|
<div className="flex flex-wrap items-center gap-x-2 gap-y-0.5">
|
|
80
102
|
<span
|
|
81
103
|
className="text-sm font-semibold"
|
|
@@ -91,31 +113,28 @@ export const GroupMessageItem = memo(function GroupMessageItem({
|
|
|
91
113
|
{target && (
|
|
92
114
|
<span className="text-[11px] text-text-subtle">→ {target}</span>
|
|
93
115
|
)}
|
|
94
|
-
{isFinal && (
|
|
95
|
-
<span className="rounded-full bg-accent-wash px-1.5 py-px text-[10px] font-medium text-primary">
|
|
96
|
-
final
|
|
97
|
-
</span>
|
|
98
|
-
)}
|
|
99
116
|
<span className="text-[11px] text-text-subtle">{formatTime(message.createdAt)}</span>
|
|
100
117
|
</div>
|
|
101
118
|
|
|
102
|
-
<div className=
|
|
103
|
-
"mt-0.5 whitespace-pre-wrap break-words text-sm leading-relaxed text-text-secondary",
|
|
104
|
-
isFinal && "mt-1.5 rounded-md border border-accent-wash bg-accent-wash/40 px-3 py-2 text-foreground",
|
|
105
|
-
)}>
|
|
119
|
+
<div className="mt-0.5 whitespace-pre-wrap break-words text-sm leading-relaxed text-text-secondary">
|
|
106
120
|
{withMentions(summary, colorFor)}
|
|
107
121
|
</div>
|
|
108
|
-
|
|
109
|
-
{message.fullSessionRef && (
|
|
110
|
-
<button
|
|
111
|
-
type="button"
|
|
112
|
-
onClick={() => onViewFull(message)}
|
|
113
|
-
className="mt-1 inline-flex min-h-[44px] items-center text-xs font-medium text-primary hover:underline md:min-h-[32px]"
|
|
114
|
-
>
|
|
115
|
-
View full transcript
|
|
116
|
-
</button>
|
|
117
|
-
)}
|
|
118
122
|
</div>
|
|
119
123
|
</div>
|
|
120
124
|
);
|
|
125
|
+
|
|
126
|
+
// No transcript → plain row. Otherwise wrap so long-press (mobile) / right-click
|
|
127
|
+
// (desktop) opens a menu with the transcript action; the hover icon covers pointer.
|
|
128
|
+
if (!message.fullSessionRef) return row;
|
|
129
|
+
|
|
130
|
+
return (
|
|
131
|
+
<ContextMenu>
|
|
132
|
+
<ContextMenuTrigger asChild>{row}</ContextMenuTrigger>
|
|
133
|
+
<ContextMenuContent>
|
|
134
|
+
<ContextMenuItem onClick={() => onViewFull(message)}>
|
|
135
|
+
<ScrollText className="size-4" /> View full transcript
|
|
136
|
+
</ContextMenuItem>
|
|
137
|
+
</ContextMenuContent>
|
|
138
|
+
</ContextMenu>
|
|
139
|
+
);
|
|
121
140
|
});
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { useState } from "react";
|
|
2
|
+
import { ChevronRight, Brain, Settings2 } from "lucide-react";
|
|
3
|
+
import { MarkdownRenderer } from "@/components/shared/markdown-renderer";
|
|
4
|
+
import { ToolCard } from "@/components/chat/tool-cards";
|
|
5
|
+
import { cn } from "@/lib/utils";
|
|
6
|
+
import type { ChatMessage, ChatEvent } from "../../../types/chat";
|
|
7
|
+
import type { TranscriptConfig } from "@/lib/api-group-chat";
|
|
8
|
+
|
|
9
|
+
interface Props {
|
|
10
|
+
messages: ChatMessage[];
|
|
11
|
+
config: TranscriptConfig | null;
|
|
12
|
+
projectName?: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/** Read-only, chat-style render of an archived member transcript: text (markdown),
|
|
16
|
+
* collapsible thinking, tool calls with inputs + outputs, and the session input config.
|
|
17
|
+
* Deliberately minimal — no approvals / fork / version affordances. */
|
|
18
|
+
export function GroupTranscriptMessages({ messages, config, projectName }: Props) {
|
|
19
|
+
return (
|
|
20
|
+
<div className="flex flex-col gap-3">
|
|
21
|
+
{config && <ConfigBlock config={config} />}
|
|
22
|
+
{messages.map((m) => (
|
|
23
|
+
<div key={m.id} className="flex flex-col gap-1.5">
|
|
24
|
+
<span className="text-[10px] font-semibold uppercase tracking-wide text-text-subtle">
|
|
25
|
+
{m.role === "user" ? "User" : m.role === "assistant" ? "Assistant" : m.role}
|
|
26
|
+
</span>
|
|
27
|
+
<MessageBody message={m} projectName={projectName} />
|
|
28
|
+
</div>
|
|
29
|
+
))}
|
|
30
|
+
{messages.length === 0 && (
|
|
31
|
+
<p className="py-6 text-center text-sm text-text-subtle">Transcript is empty.</p>
|
|
32
|
+
)}
|
|
33
|
+
</div>
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function MessageBody({ message, projectName }: { message: ChatMessage; projectName?: string }) {
|
|
38
|
+
const events = message.events ?? [];
|
|
39
|
+
if (events.length === 0) {
|
|
40
|
+
return message.content.trim()
|
|
41
|
+
? <MarkdownRenderer content={message.content} />
|
|
42
|
+
: null;
|
|
43
|
+
}
|
|
44
|
+
// Match tool_result events to their tool_use by id (rendered inside the ToolCard).
|
|
45
|
+
const resultById = new Map<string, ChatEvent>();
|
|
46
|
+
for (const ev of events) {
|
|
47
|
+
if (ev.type === "tool_result" && ev.toolUseId) resultById.set(ev.toolUseId, ev);
|
|
48
|
+
}
|
|
49
|
+
return (
|
|
50
|
+
<div className="flex flex-col gap-2">
|
|
51
|
+
{events.map((ev, i) => {
|
|
52
|
+
if (ev.type === "text") {
|
|
53
|
+
return ev.content.trim() ? <MarkdownRenderer key={i} content={ev.content} /> : null;
|
|
54
|
+
}
|
|
55
|
+
if (ev.type === "thinking") {
|
|
56
|
+
return <ThinkingBlock key={i} content={ev.content} />;
|
|
57
|
+
}
|
|
58
|
+
if (ev.type === "tool_use") {
|
|
59
|
+
const result = ev.toolUseId ? resultById.get(ev.toolUseId) : undefined;
|
|
60
|
+
return <ToolCard key={i} tool={ev} result={result} completed={!!result} projectName={projectName} />;
|
|
61
|
+
}
|
|
62
|
+
return null; // tool_result rendered via its tool_use
|
|
63
|
+
})}
|
|
64
|
+
</div>
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** Collapsible reasoning block (collapsed by default). */
|
|
69
|
+
function ThinkingBlock({ content }: { content: string }) {
|
|
70
|
+
const [open, setOpen] = useState(false);
|
|
71
|
+
return (
|
|
72
|
+
<div className="rounded-md border border-border bg-surface-elevated/40">
|
|
73
|
+
<button
|
|
74
|
+
type="button"
|
|
75
|
+
onClick={() => setOpen((v) => !v)}
|
|
76
|
+
className="flex w-full items-center gap-1.5 px-2.5 py-1.5 text-xs text-text-subtle hover:text-text-secondary"
|
|
77
|
+
>
|
|
78
|
+
<ChevronRight className={cn("size-3.5 transition-transform", open && "rotate-90")} />
|
|
79
|
+
<Brain className="size-3.5" />
|
|
80
|
+
<span>Thinking</span>
|
|
81
|
+
</button>
|
|
82
|
+
{open && (
|
|
83
|
+
<div className="border-t border-border px-3 py-2 text-xs leading-relaxed text-text-secondary">
|
|
84
|
+
<MarkdownRenderer content={content} />
|
|
85
|
+
</div>
|
|
86
|
+
)}
|
|
87
|
+
</div>
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/** Collapsible input-config summary (model / cwd / branch / version / permission mode). */
|
|
92
|
+
function ConfigBlock({ config }: { config: TranscriptConfig }) {
|
|
93
|
+
const [open, setOpen] = useState(false);
|
|
94
|
+
const rows: Array<[string, string | undefined]> = [
|
|
95
|
+
["Model", config.model],
|
|
96
|
+
["Permission", config.permissionMode],
|
|
97
|
+
["CWD", config.cwd],
|
|
98
|
+
["Git branch", config.gitBranch],
|
|
99
|
+
["CLI version", config.version],
|
|
100
|
+
];
|
|
101
|
+
const shown = rows.filter(([, v]) => v);
|
|
102
|
+
if (shown.length === 0) return null;
|
|
103
|
+
return (
|
|
104
|
+
<div className="rounded-md border border-border bg-surface-elevated/40">
|
|
105
|
+
<button
|
|
106
|
+
type="button"
|
|
107
|
+
onClick={() => setOpen((v) => !v)}
|
|
108
|
+
className="flex w-full items-center gap-1.5 px-2.5 py-1.5 text-xs font-medium text-text-secondary hover:text-foreground"
|
|
109
|
+
>
|
|
110
|
+
<ChevronRight className={cn("size-3.5 transition-transform", open && "rotate-90")} />
|
|
111
|
+
<Settings2 className="size-3.5" />
|
|
112
|
+
<span>Input config</span>
|
|
113
|
+
</button>
|
|
114
|
+
{open && (
|
|
115
|
+
<dl className="grid grid-cols-[auto_1fr] gap-x-3 gap-y-1 border-t border-border px-3 py-2 text-xs">
|
|
116
|
+
{shown.map(([k, v]) => (
|
|
117
|
+
<div key={k} className="contents">
|
|
118
|
+
<dt className="text-text-subtle">{k}</dt>
|
|
119
|
+
<dd className="break-all font-mono text-text-secondary">{v}</dd>
|
|
120
|
+
</div>
|
|
121
|
+
))}
|
|
122
|
+
</dl>
|
|
123
|
+
)}
|
|
124
|
+
</div>
|
|
125
|
+
);
|
|
126
|
+
}
|
|
@@ -22,9 +22,11 @@ interface TunnelStatus {
|
|
|
22
22
|
|
|
23
23
|
interface Props {
|
|
24
24
|
onClose: () => void;
|
|
25
|
+
/** "popover" = self-contained card (desktop rail); "sheet" = fills a bottom sheet on mobile. */
|
|
26
|
+
variant?: "popover" | "sheet";
|
|
25
27
|
}
|
|
26
28
|
|
|
27
|
-
export function CloudSharePopover({ onClose }: Props) {
|
|
29
|
+
export function CloudSharePopover({ onClose, variant = "popover" }: Props) {
|
|
28
30
|
const [cloud, setCloud] = useState<CloudStatus | null>(null);
|
|
29
31
|
const [tunnel, setTunnel] = useState<TunnelStatus | null>(null);
|
|
30
32
|
const [loading, setLoading] = useState(true);
|
|
@@ -184,7 +186,13 @@ export function CloudSharePopover({ onClose }: Props) {
|
|
|
184
186
|
const shareUrl = tunnel?.url || cloud?.tunnel_url;
|
|
185
187
|
|
|
186
188
|
return (
|
|
187
|
-
<div
|
|
189
|
+
<div
|
|
190
|
+
className={
|
|
191
|
+
variant === "sheet"
|
|
192
|
+
? "w-full p-3 space-y-3"
|
|
193
|
+
: "w-72 bg-background border border-border rounded-lg shadow-lg p-3 space-y-3"
|
|
194
|
+
}
|
|
195
|
+
>
|
|
188
196
|
{/* Header */}
|
|
189
197
|
<div className="flex items-center justify-between">
|
|
190
198
|
<div className="flex items-center gap-1.5">
|
|
@@ -134,6 +134,11 @@ export function MobileDrawerTabBar({ tabs, activeId, onSelect, onReorder }: Prop
|
|
|
134
134
|
>
|
|
135
135
|
<Icon className="size-4" />
|
|
136
136
|
<span>{tab.shortLabel ?? tab.label}</span>
|
|
137
|
+
{tab.beta && (
|
|
138
|
+
<span className="absolute top-1 right-2 rounded-full bg-accent-wash px-1 text-[7px] font-bold uppercase leading-[1.4] tracking-wide text-primary">
|
|
139
|
+
beta
|
|
140
|
+
</span>
|
|
141
|
+
)}
|
|
137
142
|
</button>
|
|
138
143
|
);
|
|
139
144
|
})}
|
|
@@ -168,6 +173,11 @@ export function MobileDrawerTabBar({ tabs, activeId, onSelect, onReorder }: Prop
|
|
|
168
173
|
>
|
|
169
174
|
<Icon className="size-4 shrink-0" />
|
|
170
175
|
<span>{tab.label}</span>
|
|
176
|
+
{tab.beta && (
|
|
177
|
+
<span className="rounded-full bg-accent-wash px-1.5 py-px text-[9px] font-semibold uppercase tracking-wide text-primary">
|
|
178
|
+
beta
|
|
179
|
+
</span>
|
|
180
|
+
)}
|
|
171
181
|
</button>
|
|
172
182
|
);
|
|
173
183
|
})}
|