@hienlh/ppm 0.18.12 → 0.18.13
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/AGENTS.md +17 -5
- package/CHANGELOG.md +22 -0
- package/CLAUDE.md +3 -0
- package/README.md +6 -6
- package/assets/skills/ppm/SKILL.md +1 -1
- package/assets/skills/ppm/references/http-api.md +19 -1
- package/dist/web/assets/{adaptive-context-menu-DGCKKeTy.js → adaptive-context-menu-CbgPYQmj.js} +1 -1
- package/dist/web/assets/{ai-resource-editor-BOHHTTe7.js → ai-resource-editor-unM2HNmg.js} +1 -1
- package/dist/web/assets/{ai-settings-section-BigC_nZR.js → ai-settings-section-CdktdrwF.js} +1 -1
- package/dist/web/assets/{angular-html-BYPaydvh.js → angular-html-DcpbdcNG.js} +1 -1
- package/dist/web/assets/{angular-ts-Bb4AMKlk.js → angular-ts-Bv_WIk34.js} +1 -1
- package/dist/web/assets/api-client-BogqsFna.js +1 -0
- package/dist/web/assets/{api-settings-Bd3M4YpI.js → api-settings-BdCtex9i.js} +1 -1
- package/dist/web/assets/api-settings-DfXViPKz.js +1 -0
- package/dist/web/assets/{api-themes-Cpx419SL.js → api-themes-pRRoLvgD.js} +1 -1
- package/dist/web/assets/{apl-DB2VjFCS.js → apl-D5_lLszu.js} +1 -1
- package/dist/web/assets/architecture-PBZL5I3N-BzFm9ELu.js +1 -0
- package/dist/web/assets/{astro-BeoJdVpk.js → astro-CBHwddYL.js} +1 -1
- package/dist/web/assets/{audio-preview-BgFuTn-0.js → audio-preview-BD1iDovf.js} +1 -1
- package/dist/web/assets/{blade-Cf2q1sPf.js → blade-DGe1d2Pq.js} +1 -1
- package/dist/web/assets/{bsl-W1kOaNpu.js → bsl-2lyAzRJA.js} +1 -1
- package/dist/web/assets/{button-5zTrkEoN.js → button-2WCAS8dI.js} +1 -1
- package/dist/web/assets/{cairo-BoAZFcje.js → cairo-DjzZeJrq.js} +1 -1
- package/dist/web/assets/chat-tab-DzK8LGti.js +15 -0
- package/dist/web/assets/{cobol-B0Nm7RXj.js → cobol-cC3XIuAJ.js} +1 -1
- package/dist/web/assets/code-editor-CuMfPN9X.js +10 -0
- package/dist/web/assets/{coffee-BakMn3on.js → coffee-4eGboVoU.js} +1 -1
- package/dist/web/assets/{conflict-editor-BUs5k9q_.js → conflict-editor-DdJag4QK.js} +1 -1
- package/dist/web/assets/{context-menu-Bq92km4s.js → context-menu-BO1c9jKy.js} +1 -1
- package/dist/web/assets/{cpp-BRAJQHK2.js → cpp-DF9_G-OU.js} +1 -1
- package/dist/web/assets/{crystal-kqqO3zkK.js → crystal-OavZlzcm.js} +1 -1
- package/dist/web/assets/{csv-preview-ByoDgLAZ.js → csv-preview-DnXwouF3.js} +1 -1
- package/dist/web/assets/{data-grid-overlay-editor-Brkf9z41.js → data-grid-overlay-editor-B9Gpjm3l.js} +1 -1
- package/dist/web/assets/{database-viewer-Btc3h8Yu.js → database-viewer-Dk8oGyZx.js} +1 -1
- package/dist/web/assets/{dialog-DwtGlowE.js → dialog-B-l2ZxVm.js} +1 -1
- package/dist/web/assets/{diff-viewer-CZaDnR4w.js → diff-viewer-eaUBjLCH.js} +1 -1
- package/dist/web/assets/{docx-preview-DAD_vg59.js → docx-preview-DAdHPlhZ.js} +1 -1
- package/dist/web/assets/{edge-Cq1ZKZuE.js → edge-TzYh8OlN.js} +1 -1
- package/dist/web/assets/{edit-diff-preview-B_VE7ppQ.js → edit-diff-preview-DlwP3UIU.js} +1 -1
- package/dist/web/assets/{elixir-BM_JoJRk.js → elixir-Cy3RhKKH.js} +1 -1
- package/dist/web/assets/{elm-Dw7oO08Y.js → elm-BTBZdweK.js} +1 -1
- package/dist/web/assets/{erb-CfKOGAfk.js → erb-dv1mI0y4.js} +1 -1
- package/dist/web/assets/{erlang-DlDmGVeE.js → erlang-DjeiDrkl.js} +1 -1
- package/dist/web/assets/{esm-DGAP0GFh.js → esm-FRwvcesu.js} +1 -1
- package/dist/web/assets/explorer-body-DkCkSVrN.js +2 -0
- package/dist/web/assets/explorer-window-content-MsnTVngu.js +1 -0
- package/dist/web/assets/{extension-store-Cpfh2vMm.js → extension-store-DUaZINyC.js} +1 -1
- package/dist/web/assets/{extension-webview-B2OnjuCu.js → extension-webview-W0qRfaAU.js} +1 -1
- package/dist/web/assets/{file-store-aOERIEo-.js → file-store-yReVbR8q.js} +1 -1
- package/dist/web/assets/{fortran-fixed-form-XnAhQWxS.js → fortran-fixed-form-BCH9DAIJ.js} +1 -1
- package/dist/web/assets/{fsharp-CdNvy0PG.js → fsharp-C93NYKYD.js} +1 -1
- package/dist/web/assets/{gdresource-DxuG5i8i.js → gdresource-BcIEE2eX.js} +1 -1
- package/dist/web/assets/{git-commit-3lMonsur.js → git-commit-BVjlXEy8.js} +1 -1
- package/dist/web/assets/{git-log-panel-Co0PBPHC.js → git-log-panel-2_4HuP47.js} +1 -1
- package/dist/web/assets/{git-rebase-N8Z9kIMf.js → git-rebase-Bj_21B1V.js} +1 -1
- package/dist/web/assets/gitGraph-HDMCJU4V-B72vcb2r.js +1 -0
- package/dist/web/assets/glide-data-grid-B0IY6n_Q.js +138 -0
- package/dist/web/assets/{glimmer-js-Dp9OXiib.js → glimmer-js-C20yj4Zv.js} +1 -1
- package/dist/web/assets/{glimmer-ts-CDVKBcDj.js → glimmer-ts-ipbYC7kh.js} +1 -1
- package/dist/web/assets/{glsl-DPJxI4us.js → glsl-Dovazu3t.js} +1 -1
- package/dist/web/assets/{graphql-BrFhaQQl.js → graphql-DpMlM7hC.js} +1 -1
- package/dist/web/assets/{group-chat-tab-rOd8J8GC.js → group-chat-tab-DRLDHOp6.js} +1 -1
- package/dist/web/assets/{hack-BzXbDMlA.js → hack-gc7LCBuV.js} +1 -1
- package/dist/web/assets/{haml-CPpkX0s5.js → haml-vtlFm9gm.js} +1 -1
- package/dist/web/assets/{handlebars-BqrApy52.js → handlebars-DGKhpCji.js} +1 -1
- package/dist/web/assets/{html-DmjUl-OA.js → html-DvfhQbXb.js} +1 -1
- package/dist/web/assets/{html-derivative-Cnd6XFR5.js → html-derivative-C3oTSSCN.js} +1 -1
- package/dist/web/assets/{http-DMLWYun2.js → http-SG6zLTo7.js} +1 -1
- package/dist/web/assets/{hurl-CKkCVxbj.js → hurl-BWXsYlqW.js} +1 -1
- package/dist/web/assets/{hxml-CAx19TtQ.js → hxml-DUdMzaoh.js} +1 -1
- package/dist/web/assets/{image-preview-DHUoylQ1.js → image-preview-DxgFOV1T.js} +1 -1
- package/dist/web/assets/index-CBn4SOoT.js +52 -0
- package/dist/web/assets/index-DWpNR3nB.css +2 -0
- package/dist/web/assets/info-3K5VOQVL-3irPxRK_.js +1 -0
- package/dist/web/assets/{input-DcEk7mA3.js → input-DuAF-Stj.js} +1 -1
- package/dist/web/assets/{jinja-BmB9YN9l.js → jinja-955w9RKM.js} +1 -1
- package/dist/web/assets/{jison-BaVsKKpw.js → jison-WWfqPo50.js} +1 -1
- package/dist/web/assets/{julia-BgVBLveX.js → julia-BFrfnaNl.js} +1 -1
- package/dist/web/assets/{just-C2ENIbl9.js → just-BrZdyR_I.js} +1 -1
- package/dist/web/assets/{keybindings-store-BGIyqXHI.js → keybindings-store-0Wqfa7Qp.js} +1 -1
- package/dist/web/assets/keybindings-store-d54pv2NK.js +1 -0
- package/dist/web/assets/{latex-BiDIWxKL.js → latex-CwtPPASD.js} +1 -1
- package/dist/web/assets/{liquid-NxpapreE.js → liquid-CYZuvDDd.js} +1 -1
- package/dist/web/assets/{lua-DVepQvwH.js → lua-BV095ZyY.js} +1 -1
- package/dist/web/assets/markdown-renderer-BTS8ifdu.js +1 -0
- package/dist/web/assets/{markdown-renderer-DlcDhgrF.js → markdown-renderer-CnRcKK3d.js} +3 -3
- package/dist/web/assets/{marko-CJ2606Xl.js → marko-CNeljZ1C.js} +1 -1
- package/dist/web/assets/{mdc-D2bjqclE.js → mdc-JfGapShy.js} +1 -1
- package/dist/web/assets/{media-url-H17XJF-I.js → media-url-Bm4PsduE.js} +1 -1
- package/dist/web/assets/{mobile-bottom-sheet-g-r2hCFa.js → mobile-bottom-sheet-M5iZDX7y.js} +1 -1
- package/dist/web/assets/mobile-explorer-sheet-BqK2-WuN.js +1 -0
- package/dist/web/assets/{nextflow-BtJwUbfF.js → nextflow-DD5C8nqX.js} +1 -1
- package/dist/web/assets/{nginx-j4gyIhHE.js → nginx-Ca7B__x_.js} +1 -1
- package/dist/web/assets/{nim-ClH_gjP5.js → nim-B8FogsDw.js} +1 -1
- package/dist/web/assets/notification-store-Yvy1I8gd.js +1 -0
- package/dist/web/assets/{number-overlay-editor-C1EqJnWq.js → number-overlay-editor-DG9xJwEG.js} +1 -1
- package/dist/web/assets/{overview-panel-vTeeJYVZ.js → overview-panel-s53bnl0q.js} +1 -1
- package/dist/web/assets/packet-RMMSAZCW-Z5jWjFCV.js +1 -0
- package/dist/web/assets/{panel-store-BSnkjgHt.js → panel-store-B4rijFKN.js} +1 -1
- package/dist/web/assets/{pdf-preview-CqFGRY0Z.js → pdf-preview-DYt3aBzM.js} +1 -1
- package/dist/web/assets/{perl-C9H7X7CT.js → perl-BR78hS8R.js} +1 -1
- package/dist/web/assets/{php-Bx2U-cQ_.js → php-DXBOMC9z.js} +1 -1
- package/dist/web/assets/pie-UPGHQEXC-Bq7UMi8P.js +1 -0
- package/dist/web/assets/{postgres-viewer-DHwcQucn.js → postgres-viewer-BvoWSuoZ.js} +3 -3
- package/dist/web/assets/{process-table-BGRJNlpn.js → process-table-BYwKigiD.js} +1 -1
- package/dist/web/assets/{project-store--nvQiy75.js → project-store-BuY7rxn_.js} +1 -1
- package/dist/web/assets/{pug-Cw74sKsE.js → pug-CvTwVVKV.js} +1 -1
- package/dist/web/assets/{qml-BXD94Eqz.js → qml-CPSoZ1-B.js} +1 -1
- package/dist/web/assets/radar-KQ55EAFF-BLo4BOTD.js +1 -0
- package/dist/web/assets/{razor-DZ0-Ge0S.js → razor-BUA1YKtF.js} +1 -1
- package/dist/web/assets/{rst-Dtdh0QUj.js → rst-BJsq7ISz.js} +1 -1
- package/dist/web/assets/{ruby-BC51BW2Q.js → ruby-DSDMeYf5.js} +1 -1
- package/dist/web/assets/{run-in-terminal-Sd3KyjN4.js → run-in-terminal-C9xpskFn.js} +1 -1
- package/dist/web/assets/{sas-BN8i4qOU.js → sas-B1nJOjbN.js} +1 -1
- package/dist/web/assets/{scroll-area-0gljZ6lF.js → scroll-area-DBcG1fQo.js} +1 -1
- package/dist/web/assets/{scss-H-QtA7Rz.js → scss-BZFyRiQn.js} +1 -1
- package/dist/web/assets/{send-to-chat-u6m8l-rH.js → send-to-chat-BIg70MUZ.js} +1 -1
- package/dist/web/assets/{settings-store-CHY6Kzin.js → settings-store-GV5pkkke.js} +2 -2
- package/dist/web/assets/{settings-tab-IY6K1MiZ.js → settings-tab-BePvIcjd.js} +1 -1
- package/dist/web/assets/settings-tab-Br-lJSPa.js +1 -0
- package/dist/web/assets/{shaderlab-CalNsj_x.js → shaderlab-laINRXBo.js} +1 -1
- package/dist/web/assets/{shellsession-BFrcoR8x.js → shellsession-BpOOvWVR.js} +1 -1
- package/dist/web/assets/{soy-CNbku7vP.js → soy-BW4d91Sa.js} +1 -1
- package/dist/web/assets/{sparql-BN_orcVp.js → sparql-BsvvyoHn.js} +1 -1
- package/dist/web/assets/{sql-query-editor-C6pC3I8l.js → sql-query-editor-qQce5QJ6.js} +1 -1
- package/dist/web/assets/{sqlite-viewer-DTr5PzUb.js → sqlite-viewer-yhc0YNvu.js} +1 -1
- package/dist/web/assets/{stata-C6a5Ijzq.js → stata-K-dZInUt.js} +1 -1
- package/dist/web/assets/{surrealql-ClplI_HY.js → surrealql-CpNp2sgf.js} +1 -1
- package/dist/web/assets/{svelte-DNm-UNXB.js → svelte-BG6iBA8R.js} +1 -1
- package/dist/web/assets/{switch-DKvKya9y.js → switch-_NcrktLe.js} +1 -1
- package/dist/web/assets/system-monitor-body-D8Z5QXBB.js +2 -0
- package/dist/web/assets/system-monitor-tab-BclYXFTe.js +1 -0
- package/dist/web/assets/{system-monitor-window-content-BUqRsPK2.js → system-monitor-window-content-CaOhD0AU.js} +1 -1
- package/dist/web/assets/{tab-host-window-content-BnqGPu8a.js → tab-host-window-content-f_Rc5rJK.js} +1 -1
- package/dist/web/assets/{tab-store-CJuJRapl.js → tab-store-tFnyPmm4.js} +1 -1
- package/dist/web/assets/team-member-sheet-QDHoYCs0.js +2 -0
- package/dist/web/assets/{team-member-window-content-T4Q5JI-G.js → team-member-window-content-B1jkKkDi.js} +1 -1
- package/dist/web/assets/{templ-CSdqVobu.js → templ-gxNKXmt3.js} +1 -1
- package/dist/web/assets/{terminal-tab-Bb2rZegQ.js → terminal-tab-UvwM0sty.js} +3 -3
- package/dist/web/assets/{tex-DzSJ4kcZ.js → tex-C0ON27g5.js} +1 -1
- package/dist/web/assets/{tool-cards-lhqhrDTT.js → tool-cards-jB7GT-wj.js} +4 -4
- package/dist/web/assets/treemap-KZPCXAKY-dyrE6SW2.js +1 -0
- package/dist/web/assets/{ts-tags-C28w3bTg.js → ts-tags-BX_CTVgQ.js} +1 -1
- package/dist/web/assets/{twig-i5jY3QXB.js → twig-CwL7XnU0.js} +1 -1
- package/dist/web/assets/{use-blob-url-Dsq9OjTh.js → use-blob-url-DcRcjNTE.js} +1 -1
- package/dist/web/assets/use-coarse-long-press-BmI_GVW5.js +1 -0
- package/dist/web/assets/{use-monaco-theme-BZvlsoBv.js → use-monaco-theme--9tOOkDA.js} +1 -1
- package/dist/web/assets/{use-open-team-member-DkiEjFYE.js → use-open-team-member-1hRsHLKg.js} +1 -1
- package/dist/web/assets/{use-websocket-B8R50f7f.js → use-websocket-rxJLbFqy.js} +1 -1
- package/dist/web/assets/{vendor-mermaid-By4AVvJY.js → vendor-mermaid-CHTa6D69.js} +1 -1
- package/dist/web/assets/video-preview-DMhnf2Gi.js +1 -0
- package/dist/web/assets/{vue-Ceyet_lv.js → vue-Bykm6wSS.js} +1 -1
- package/dist/web/assets/{vue-html-GuU7g_hg.js → vue-html-CETdK_iV.js} +1 -1
- package/dist/web/assets/{vue-vine-CxXoaJr2.js → vue-vine-DiJb6fO5.js} +1 -1
- package/dist/web/assets/{window-store-CsEW6jiE.js → window-store-CQ1lghvv.js} +1 -1
- package/dist/web/assets/{xml-CbqOVhkP.js → xml-BNw8J5YW.js} +1 -1
- package/dist/web/assets/{xsl-KfAmCauy.js → xsl-CsG9L31b.js} +1 -1
- package/dist/web/index.html +46 -45
- package/dist/web/sw.js +1 -1
- package/docs/architecture/ai-chat-and-providers.md +309 -0
- package/docs/architecture/data-and-storage.md +356 -0
- package/docs/architecture/extensions.md +496 -0
- package/docs/architecture/integrations.md +214 -0
- package/docs/architecture/workspace-and-ui.md +391 -0
- package/docs/claude-agent-sdk-reference.md +1 -1
- package/docs/code-patterns.md +361 -0
- package/docs/code-standards.md +8 -358
- package/docs/codebase-subsystems.md +364 -0
- package/docs/codebase-summary.md +34 -379
- package/docs/deployment-guide.md +280 -490
- package/docs/design-guidelines.md +1 -1
- package/docs/lessons-learned.md +27 -10
- package/docs/project-changelog.md +18 -806
- package/docs/project-overview-pdr.md +117 -111
- package/docs/project-roadmap.md +89 -133
- package/docs/system-architecture.md +77 -1826
- package/package.json +2 -2
- package/src/cli/commands/autostart.ts +2 -2
- package/src/cli/commands/config-cmd.ts +12 -3
- package/src/cli/commands/status.ts +3 -2
- package/src/cli/commands/stop.ts +32 -4
- package/src/server/index.ts +17 -3
- package/src/server/routes/chat-unread.ts +36 -0
- package/src/server/routes/named-tunnel.ts +132 -0
- package/src/server/routes/tunnel.ts +13 -0
- package/src/server/ws/chat.ts +5 -2
- package/src/services/autostart-register.ts +47 -29
- package/src/services/cloud.service.ts +26 -1
- package/src/services/config-secret-keys.ts +48 -0
- package/src/services/config.service.ts +1 -1
- package/src/services/db.service.ts +62 -12
- package/src/services/extension-rpc-handlers.ts +9 -1
- package/src/services/file-watcher/watch-tree.ts +67 -33
- package/src/services/file-watcher.service.ts +28 -10
- package/src/services/fs-credential-path-guard.ts +103 -0
- package/src/services/fs-path-guard.service.ts +14 -66
- package/src/services/named-tunnel/cloudflare-dns-api.ts +40 -0
- package/src/services/named-tunnel/cloudflare-zone-api.ts +28 -0
- package/src/services/named-tunnel/cloudflared-cert.ts +95 -0
- package/src/services/named-tunnel/cloudflared-exec.ts +50 -0
- package/src/services/named-tunnel/cloudflared-login-helpers.ts +98 -0
- package/src/services/named-tunnel/cloudflared-login.service.ts +182 -0
- package/src/services/named-tunnel/hostname-rules.ts +58 -0
- package/src/services/named-tunnel/login-output-parser.ts +36 -0
- package/src/services/named-tunnel/named-tunnel-args.ts +110 -0
- package/src/services/named-tunnel/named-tunnel-config.ts +67 -0
- package/src/services/named-tunnel/named-tunnel-probe-state.ts +95 -0
- package/src/services/named-tunnel/named-tunnel-readiness.ts +59 -0
- package/src/services/named-tunnel/named-tunnel-runtime.ts +42 -0
- package/src/services/named-tunnel/named-tunnel-setup-confirm.ts +98 -0
- package/src/services/named-tunnel/named-tunnel-setup.service.ts +191 -0
- package/src/services/supervisor-state.ts +67 -2
- package/src/services/supervisor.ts +454 -157
- package/src/services/tunnel-registry-parse.ts +27 -0
- package/src/services/tunnel-registry.service.ts +2 -15
- package/src/services/tunnel.service.ts +12 -3
- package/src/types/config.ts +31 -0
- package/src/web/app.tsx +5 -0
- package/src/web/components/chat/chat-history-bar.tsx +95 -98
- package/src/web/components/chat/chat-toolbar-overflow-menu.tsx +57 -0
- package/src/web/components/chat/session-debug-dialog.tsx +35 -27
- package/src/web/components/layout/cloud-share-named-tunnel-row.tsx +111 -0
- package/src/web/components/layout/cloud-share-popover.tsx +56 -14
- package/src/web/components/shared/connection-lost-overlay.tsx +44 -5
- package/src/web/components/tunnels/named-tunnel/hostname-validation.ts +14 -0
- package/src/web/components/tunnels/named-tunnel/named-tunnel-copy.ts +96 -0
- package/src/web/components/tunnels/named-tunnel/named-tunnel-hostname-field.tsx +51 -0
- package/src/web/components/tunnels/named-tunnel/named-tunnel-login-step.tsx +105 -0
- package/src/web/components/tunnels/named-tunnel/named-tunnel-section.tsx +159 -0
- package/src/web/components/tunnels/named-tunnel/named-tunnel-setup-content.tsx +197 -0
- package/src/web/components/tunnels/named-tunnel/named-tunnel-setup-popup.tsx +57 -0
- package/src/web/components/tunnels/named-tunnel/named-tunnel-step-reducer.ts +191 -0
- package/src/web/components/tunnels/named-tunnel/use-named-tunnel-setup.ts +212 -0
- package/src/web/components/tunnels/tunnel-manager-tab.tsx +4 -0
- package/src/web/hooks/use-global-events.ts +3 -1
- package/src/web/lib/api-named-tunnel.ts +54 -0
- package/src/web/lib/last-known-local-url.ts +23 -0
- package/src/web/stores/notification-store.ts +20 -1
- package/dist/web/assets/api-client-DTZEgjBQ.js +0 -1
- package/dist/web/assets/api-settings-kd1j4iR8.js +0 -1
- package/dist/web/assets/architecture-PBZL5I3N-8dCMT9r7.js +0 -1
- package/dist/web/assets/chat-tab-E3bf_V8X.js +0 -15
- package/dist/web/assets/code-editor-BUlM2gXk.js +0 -10
- package/dist/web/assets/explorer-body-9aBmyVpZ.js +0 -2
- package/dist/web/assets/explorer-window-content-DRtqoSPA.js +0 -1
- package/dist/web/assets/gitGraph-HDMCJU4V-2e_8dfbs.js +0 -1
- package/dist/web/assets/glide-data-grid-C4_zIneN.js +0 -138
- package/dist/web/assets/index-BImUaigO.js +0 -52
- package/dist/web/assets/index-CSfi6DSU.css +0 -2
- package/dist/web/assets/info-3K5VOQVL-BZi1Gha1.js +0 -1
- package/dist/web/assets/keybindings-store-CzV2sPls.js +0 -1
- package/dist/web/assets/markdown-renderer-CcbR33VG.js +0 -1
- package/dist/web/assets/mobile-explorer-sheet-SIwQXlwA.js +0 -1
- package/dist/web/assets/notification-store-DV5QtUTg.js +0 -1
- package/dist/web/assets/packet-RMMSAZCW-o5htEcin.js +0 -1
- package/dist/web/assets/pie-UPGHQEXC-BXAIFSAD.js +0 -1
- package/dist/web/assets/radar-KQ55EAFF-Dbt2Aebl.js +0 -1
- package/dist/web/assets/settings-tab-Dic6TKkU.js +0 -1
- package/dist/web/assets/system-monitor-body-iwGiCns9.js +0 -2
- package/dist/web/assets/system-monitor-tab-DdXQhEel.js +0 -1
- package/dist/web/assets/team-member-sheet-LkAFSCvb.js +0 -2
- package/dist/web/assets/treemap-KZPCXAKY-DUbnl9dz.js +0 -1
- package/dist/web/assets/video-preview-m0-3p7QZ.js +0 -1
- /package/dist/web/assets/{abap-C6nB04tn.js → abap-DGlrX_8G.js} +0 -0
- /package/dist/web/assets/{actionscript-3-Vx4rw2sC.js → actionscript-3-CUqRtUJE.js} +0 -0
- /package/dist/web/assets/{ada-Ccd8vM20.js → ada-CY3Spa33.js} +0 -0
- /package/dist/web/assets/{andromeeda-DnBX5xMg.js → andromeeda-Lxs2TJn7.js} +0 -0
- /package/dist/web/assets/{apache-B-9_sx0g.js → apache-DfxgGdgM.js} +0 -0
- /package/dist/web/assets/{apex-_wPVBYoL.js → apex-QVDF1dnI.js} +0 -0
- /package/dist/web/assets/{api-client-aQb5hHE5.js → api-client-oY1tC3tM.js} +0 -0
- /package/dist/web/assets/{applescript-CcvD-qr0.js → applescript-pwJ8QXh-.js} +0 -0
- /package/dist/web/assets/{apply-theme-BeLRfsSu.js → apply-theme-B_bMVL6a.js} +0 -0
- /package/dist/web/assets/{ara-C40Ztoms.js → ara-mPjeX5YX.js} +0 -0
- /package/dist/web/assets/{asciidoc-CybYkJV4.js → asciidoc-Bf7LsDkI.js} +0 -0
- /package/dist/web/assets/{asm-9eOKwzR0.js → asm-rRKC1OUx.js} +0 -0
- /package/dist/web/assets/{aurora-x-B5ZH4t7t.js → aurora-x-DwQr0DkG.js} +0 -0
- /package/dist/web/assets/{awk-Dqilob-2.js → awk-Bpt768fN.js} +0 -0
- /package/dist/web/assets/{ayu-dark-CPgRhf5r.js → ayu-dark-D9lwQHMs.js} +0 -0
- /package/dist/web/assets/{ayu-light-Do06Q52f.js → ayu-light-B4-ptrU5.js} +0 -0
- /package/dist/web/assets/{ayu-mirage-_BhxcrxY.js → ayu-mirage-DAyRzH5Q.js} +0 -0
- /package/dist/web/assets/{ballerina-DDwK54QW.js → ballerina-Cgdpj1HC.js} +0 -0
- /package/dist/web/assets/{bat-BGyGlzGk.js → bat-4FrN36S2.js} +0 -0
- /package/dist/web/assets/{beancount-CRWBdapI.js → beancount-DkcxQER3.js} +0 -0
- /package/dist/web/assets/{berry-DbSFn2gO.js → berry-Dnuut-Ml.js} +0 -0
- /package/dist/web/assets/{bibtex-QpsV9gm9.js → bibtex-CCDwmbuA.js} +0 -0
- /package/dist/web/assets/{bicep-CxS8CUve.js → bicep-BC0ryoGM.js} +0 -0
- /package/dist/web/assets/{bird2-CuZhQzYR.js → bird2-C50V_A-0.js} +0 -0
- /package/dist/web/assets/{c-9bnDqE3g.js → c-Ddorhq0U.js} +0 -0
- /package/dist/web/assets/{c3-JMZTrOhA.js → c3-DdIf5r9E.js} +0 -0
- /package/dist/web/assets/{cadence-DsDNayJS.js → cadence-s9pd1Wng.js} +0 -0
- /package/dist/web/assets/{can-open-in-ppm-BJfpynya.js → can-open-in-ppm-C6hZV1OP.js} +0 -0
- /package/dist/web/assets/{catppuccin-frappe-DYIKXXBe.js → catppuccin-frappe-CzJNTyu-.js} +0 -0
- /package/dist/web/assets/{catppuccin-latte-IYYOnUJ8.js → catppuccin-latte-BNpt-m7s.js} +0 -0
- /package/dist/web/assets/{catppuccin-macchiato-BrJ_7mfS.js → catppuccin-macchiato-FYGkfsJ5.js} +0 -0
- /package/dist/web/assets/{catppuccin-mocha-gzSu7v7-.js → catppuccin-mocha-it2g5D1q.js} +0 -0
- /package/dist/web/assets/{clarity-DLzsC0Hb.js → clarity-BVFBTjMe.js} +0 -0
- /package/dist/web/assets/{clipboard-7fw0Shic.js → clipboard-BWznymz7.js} +0 -0
- /package/dist/web/assets/{clojure-DS1BvoTt.js → clojure-BSYvXMI8.js} +0 -0
- /package/dist/web/assets/{cmake-CDvsJwYp.js → cmake-DGEqH-Np.js} +0 -0
- /package/dist/web/assets/{codeowners-BjsYiflJ.js → codeowners-D8FCOxWg.js} +0 -0
- /package/dist/web/assets/{codeql-CG-7ARat.js → codeql-COV0eluG.js} +0 -0
- /package/dist/web/assets/{common-lisp-DSO1Lbh9.js → common-lisp-xHnZUlgt.js} +0 -0
- /package/dist/web/assets/{coq-DYdh3oP_.js → coq-Cs_2i3Xg.js} +0 -0
- /package/dist/web/assets/{csharp-DxEBz5s0.js → csharp-B1ONB4PT.js} +0 -0
- /package/dist/web/assets/{css-dal3Q-8C.js → css-BgGQbvrZ.js} +0 -0
- /package/dist/web/assets/{csv-CpqjMGiA.js → csv-CNHmQBzs.js} +0 -0
- /package/dist/web/assets/{csv-parser-3umBA4NY.js → csv-parser-DWR24J17.js} +0 -0
- /package/dist/web/assets/{cue-DinoJ_5k.js → cue-ZXAKzwIy.js} +0 -0
- /package/dist/web/assets/{cypher-DzxqmkUW.js → cypher-4PL5bmT5.js} +0 -0
- /package/dist/web/assets/{d-BxNwJuEC.js → d-CEsV3RT2.js} +0 -0
- /package/dist/web/assets/{dark-plus-Clmv3V-0.js → dark-plus-NtFnYSDz.js} +0 -0
- /package/dist/web/assets/{dart-BWVtXD35.js → dart-CKHn4mDf.js} +0 -0
- /package/dist/web/assets/{data-grid-types-B4n51Fck.js → data-grid-types-CxU8oo-j.js} +0 -0
- /package/dist/web/assets/{dax-DsImuWgJ.js → dax-Cmkj1I_M.js} +0 -0
- /package/dist/web/assets/{desktop-B0jJuG2r.js → desktop-DJLalvPQ.js} +0 -0
- /package/dist/web/assets/{diff-CWqAAxoE.js → diff-BnS2wpj6.js} +0 -0
- /package/dist/web/assets/{dist-C0eNNfbt.js → dist-CuIdRyUB.js} +0 -0
- /package/dist/web/assets/{dist-B-EXdSYE.js → dist-uYjs3Wv6.js} +0 -0
- /package/dist/web/assets/{docker-CYFCJdIL.js → docker-CovNy7ml.js} +0 -0
- /package/dist/web/assets/{dotenv-CKDUjURg.js → dotenv-Gh4w3I6B.js} +0 -0
- /package/dist/web/assets/{dracula-CSoPspHE.js → dracula-NF0tAHXl.js} +0 -0
- /package/dist/web/assets/{dracula-soft-BuFjw5L1.js → dracula-soft-Cj_qBurK.js} +0 -0
- /package/dist/web/assets/{dream-maker-B6PdDRZu.js → dream-maker-CRuZPcl7.js} +0 -0
- /package/dist/web/assets/{emacs-lisp-CMcXvD0G.js → emacs-lisp-BACmC9qj.js} +0 -0
- /package/dist/web/assets/{everforest-dark-cU8-wYzi.js → everforest-dark-Dd9av4QG.js} +0 -0
- /package/dist/web/assets/{everforest-light-KhorllqK.js → everforest-light-C-jsss-B.js} +0 -0
- /package/dist/web/assets/{external-link-B8BynhvY.js → external-link-B6Hl0U4X.js} +0 -0
- /package/dist/web/assets/{fennel-BCELZK87.js → fennel-BJA9XnL8.js} +0 -0
- /package/dist/web/assets/{file-exclamation-point-CZ4DiR75.js → file-exclamation-point-JzhTU2TX.js} +0 -0
- /package/dist/web/assets/{fish-BQc0y_jy.js → fish-CKlhNSc2.js} +0 -0
- /package/dist/web/assets/{fluent-BTINnwF6.js → fluent-wfglRk5D.js} +0 -0
- /package/dist/web/assets/{folder-symlink-B8XrtvQK.js → folder-symlink-Dx1hOk8X.js} +0 -0
- /package/dist/web/assets/{format-bytes-WVcFxJuT.js → format-bytes-utwHMTry.js} +0 -0
- /package/dist/web/assets/{fortran-free-form-BQim9wDz.js → fortran-free-form-BlXCdid3.js} +0 -0
- /package/dist/web/assets/{gdscript-03w5u8un.js → gdscript-BwAVG6Et.js} +0 -0
- /package/dist/web/assets/{gdshader-Dp2daNzU.js → gdshader-DPc_T7ib.js} +0 -0
- /package/dist/web/assets/{genie-CoNcjPiD.js → genie-B-zZSLCX.js} +0 -0
- /package/dist/web/assets/{gherkin-NrPOSPQL.js → gherkin-CJ0ajpGs.js} +0 -0
- /package/dist/web/assets/{github-dark-z4RE9ZqA.js → github-dark-Dz8ZkzSP.js} +0 -0
- /package/dist/web/assets/{github-dark-default-DOKw-1cI.js → github-dark-default-CNUYo_kp.js} +0 -0
- /package/dist/web/assets/{github-dark-dimmed-DJRNMkEA.js → github-dark-dimmed-241z_Ycx.js} +0 -0
- /package/dist/web/assets/{github-dark-high-contrast-Bj7jJ_Gs.js → github-dark-high-contrast-7r6yZZYH.js} +0 -0
- /package/dist/web/assets/{github-light-B4k_yMFu.js → github-light-C8gmZn-D.js} +0 -0
- /package/dist/web/assets/{github-light-default-BHc-Uzhs.js → github-light-default-GAEgq1eA.js} +0 -0
- /package/dist/web/assets/{github-light-high-contrast-CHisIywL.js → github-light-high-contrast-3z91352E.js} +0 -0
- /package/dist/web/assets/{gleam-CfbypZ4q.js → gleam-C7vxW5zd.js} +0 -0
- /package/dist/web/assets/{gn-YoAjyhJa.js → gn-CyJIXwHP.js} +0 -0
- /package/dist/web/assets/{gnuplot-xVkc1f1c.js → gnuplot-CqLbGgPd.js} +0 -0
- /package/dist/web/assets/{go-GPCwP3Gu.js → go-DdDcK9aX.js} +0 -0
- /package/dist/web/assets/{groovy-Crh4Yww9.js → groovy-UYHggEqH.js} +0 -0
- /package/dist/web/assets/{gruvbox-dark-hard-BluUFuDS.js → gruvbox-dark-hard-B4ierkJn.js} +0 -0
- /package/dist/web/assets/{gruvbox-dark-medium-Cxk1FWQp.js → gruvbox-dark-medium-DYwkDSZ6.js} +0 -0
- /package/dist/web/assets/{gruvbox-dark-soft-CHXMiFmj.js → gruvbox-dark-soft-CVL4P-Lz.js} +0 -0
- /package/dist/web/assets/{gruvbox-light-hard-B6eKPjAD.js → gruvbox-light-hard-BJ0LewUZ.js} +0 -0
- /package/dist/web/assets/{gruvbox-light-medium-pDwMm1ut.js → gruvbox-light-medium-CaqqjeGJ.js} +0 -0
- /package/dist/web/assets/{gruvbox-light-soft-Cxu6kHqK.js → gruvbox-light-soft-ByKMoVNr.js} +0 -0
- /package/dist/web/assets/{haskell-C6JKHjbK.js → haskell-BilYRVPp.js} +0 -0
- /package/dist/web/assets/{haxe-BuBNdF0a.js → haxe-Brs9Bj1s.js} +0 -0
- /package/dist/web/assets/{hcl-DZpDdGj2.js → hcl-ClrZpol-.js} +0 -0
- /package/dist/web/assets/{hjson-CBkhYRuo.js → hjson-9PvHnYMX.js} +0 -0
- /package/dist/web/assets/{hlsl-C5nMxnp9.js → hlsl-BbBk4vqV.js} +0 -0
- /package/dist/web/assets/{horizon-VAFvA6R6.js → horizon-E5Py0cny.js} +0 -0
- /package/dist/web/assets/{horizon-bright-BC0xn7T3.js → horizon-bright-DVCsNGEk.js} +0 -0
- /package/dist/web/assets/{houston-BxrUivmz.js → houston-JdFEax9Y.js} +0 -0
- /package/dist/web/assets/{hy-DLtOXoaH.js → hy-W_W3tLKT.js} +0 -0
- /package/dist/web/assets/{image-gallery-Gnf7TdCR.js → image-gallery-5IURd6db.js} +0 -0
- /package/dist/web/assets/{imba-BdpFXM2W.js → imba-CfAqJz7T.js} +0 -0
- /package/dist/web/assets/{ini-BInJO_T0.js → ini-C_3gvKWs.js} +0 -0
- /package/dist/web/assets/{java-Dxuddnkb.js → java-CKqtXZ-j.js} +0 -0
- /package/dist/web/assets/{javascript-CVamJfLY.js → javascript-C7gSEfae.js} +0 -0
- /package/dist/web/assets/{json-BLZ0ozYk.js → json-BoN6e11T.js} +0 -0
- /package/dist/web/assets/{json5-BnXzmMKs.js → json5-CgE7C8HW.js} +0 -0
- /package/dist/web/assets/{jsonc-CSgkSga7.js → jsonc-DjyoattY.js} +0 -0
- /package/dist/web/assets/{jsonl-CY5W2nF2.js → jsonl-lI82wGSw.js} +0 -0
- /package/dist/web/assets/{jsonnet-CEJYH3sF.js → jsonnet-CszEI8va.js} +0 -0
- /package/dist/web/assets/{jssm-CsJc7Uhk.js → jssm-CZXDlszb.js} +0 -0
- /package/dist/web/assets/{jsx-jCiRaHU7.js → jsx-BeRz0eEz.js} +0 -0
- /package/dist/web/assets/{kanagawa-dragon-DfoA_GxX.js → kanagawa-dragon-BOmnUiyd.js} +0 -0
- /package/dist/web/assets/{kanagawa-lotus-BOLYJpWd.js → kanagawa-lotus-ffU_P5w-.js} +0 -0
- /package/dist/web/assets/{kanagawa-wave-DfKlbT1G.js → kanagawa-wave-DKTJZrMu.js} +0 -0
- /package/dist/web/assets/{kdl-CmssIFTi.js → kdl-BWECJveH.js} +0 -0
- /package/dist/web/assets/{kotlin-BRsNgp6x.js → kotlin-DpVwBCSt.js} +0 -0
- /package/dist/web/assets/{kusto-T8X9jUab.js → kusto-BgVqjUZA.js} +0 -0
- /package/dist/web/assets/{laserwave-DkJMVJ8Z.js → laserwave-CEVCi8em.js} +0 -0
- /package/dist/web/assets/{lean-C65KGVPq.js → lean-CGyfRhLJ.js} +0 -0
- /package/dist/web/assets/{less-exIPdDlf.js → less-B0_H10Ku.js} +0 -0
- /package/dist/web/assets/{lib-mC1NZfuw.js → lib-hrC3bruJ.js} +0 -0
- /package/dist/web/assets/{libesm-DSutUtl1.js → libesm-DVpFmwJu.js} +0 -0
- /package/dist/web/assets/{light-plus-DiHUXAZt.js → light-plus-DqzMqPID.js} +0 -0
- /package/dist/web/assets/{llvm-CJBnEzFM.js → llvm-9ucnfNiF.js} +0 -0
- /package/dist/web/assets/{loader-circle-gSPVxfvH.js → loader-circle-Dpqcv0eS.js} +0 -0
- /package/dist/web/assets/{lock-Did-87UV.js → lock-DldbT31x.js} +0 -0
- /package/dist/web/assets/{log-DxMyUMuP.js → log-m6A2dOSj.js} +0 -0
- /package/dist/web/assets/{logo-CC9NKzca.js → logo-ByPcsC9P.js} +0 -0
- /package/dist/web/assets/{luau-Bw10I6zf.js → luau-DFCo8nBn.js} +0 -0
- /package/dist/web/assets/{make-C_6M90m6.js → make-C90w3MeA.js} +0 -0
- /package/dist/web/assets/{markdown-bR9_R-LF.js → markdown-DT0uywZG.js} +0 -0
- /package/dist/web/assets/{material-theme-BUx2Qujn.js → material-theme-BVUO93tJ.js} +0 -0
- /package/dist/web/assets/{material-theme-darker-CRJrPgKm.js → material-theme-darker-xXgGDwnF.js} +0 -0
- /package/dist/web/assets/{material-theme-lighter-CUAYppPa.js → material-theme-lighter-BjStPzWB.js} +0 -0
- /package/dist/web/assets/{material-theme-ocean-DuINF1fg.js → material-theme-ocean-wFmSiKjy.js} +0 -0
- /package/dist/web/assets/{material-theme-palenight-W6_icGCj.js → material-theme-palenight-e-0CtRoe.js} +0 -0
- /package/dist/web/assets/{matlab-rfqn_b3z.js → matlab-BNaNQAUH.js} +0 -0
- /package/dist/web/assets/{mdx-Bh1B_YOJ.js → mdx-DfpVWAqO.js} +0 -0
- /package/dist/web/assets/{mermaid-Dxf6Ya2k.js → mermaid-Bpq7wFCP.js} +0 -0
- /package/dist/web/assets/{min-dark-CivZ2L0h.js → min-dark-CL2Y0WH6.js} +0 -0
- /package/dist/web/assets/{min-light-B1Ykqtma.js → min-light-DOgr_IdP.js} +0 -0
- /package/dist/web/assets/{mipsasm-DynHaM0d.js → mipsasm-C9ie2zlB.js} +0 -0
- /package/dist/web/assets/{mojo-Clw5PbGH.js → mojo-Md2A2sJy.js} +0 -0
- /package/dist/web/assets/{monitor-Dv8vn_6O.js → monitor-4vWfqzuN.js} +0 -0
- /package/dist/web/assets/{monokai-DFIooFZT.js → monokai-nbXIEySB.js} +0 -0
- /package/dist/web/assets/{moonbit-DnBSZWGM.js → moonbit-CJ-T-s4A.js} +0 -0
- /package/dist/web/assets/{move-CCcL2PfL.js → move-DwEehLIK.js} +0 -0
- /package/dist/web/assets/{narrat-BDarg5Lk.js → narrat-CuF4sIKr.js} +0 -0
- /package/dist/web/assets/{nextflow-groovy-DrZOeCNW.js → nextflow-groovy-1dYhfPfq.js} +0 -0
- /package/dist/web/assets/{night-owl-BnZZCK7v.js → night-owl-gZS5mfzY.js} +0 -0
- /package/dist/web/assets/{night-owl-light-CEwBsVHS.js → night-owl-light-DDAster5.js} +0 -0
- /package/dist/web/assets/{nix-amCzOPMR.js → nix-BlbEYs2c.js} +0 -0
- /package/dist/web/assets/{nord-BIs2BC6q.js → nord-BRiPb8Vy.js} +0 -0
- /package/dist/web/assets/{nushell-Y02fo4yw.js → nushell-DgWicB1i.js} +0 -0
- /package/dist/web/assets/{objective-c-7xOZtWW1.js → objective-c-D8mPZ42Y.js} +0 -0
- /package/dist/web/assets/{objective-cpp-eVtjUvVB.js → objective-cpp-B0pNXzuj.js} +0 -0
- /package/dist/web/assets/{ocaml-Bi6ZwqG4.js → ocaml-lQd7aK5d.js} +0 -0
- /package/dist/web/assets/{odin-8xf1Y0S9.js → odin-CxtIOBjm.js} +0 -0
- /package/dist/web/assets/{one-dark-pro-hVv-_y_b.js → one-dark-pro-T_UFnWfe.js} +0 -0
- /package/dist/web/assets/{one-light-CJJ3MtHt.js → one-light-LBVqwyV-.js} +0 -0
- /package/dist/web/assets/{openscad-B2HcywLk.js → openscad-C5dnS6J7.js} +0 -0
- /package/dist/web/assets/{pascal-C7fllV_7.js → pascal-CmWCWQML.js} +0 -0
- /package/dist/web/assets/{pkl-qvLC1IWP.js → pkl-BWWOtDQk.js} +0 -0
- /package/dist/web/assets/{plastic-BT1wHZv2.js → plastic-ekhupckF.js} +0 -0
- /package/dist/web/assets/{play-4MZi1Axp.js → play-CpCAoQRZ.js} +0 -0
- /package/dist/web/assets/{plsql-1MsmdmJD.js → plsql-BPsDHXx4.js} +0 -0
- /package/dist/web/assets/{plus-BhMZqFsN.js → plus-BR0qewJI.js} +0 -0
- /package/dist/web/assets/{po-BigskytD.js → po-BX2FiuW2.js} +0 -0
- /package/dist/web/assets/{poimandres-DuklniF7.js → poimandres-DzXOdZcN.js} +0 -0
- /package/dist/web/assets/{polar-e2pjN_sp.js → polar-DDRXgJzG.js} +0 -0
- /package/dist/web/assets/{portal-container-context-Cm5HipFr.js → portal-container-context-a399Hd9F.js} +0 -0
- /package/dist/web/assets/{postcss-DtAeYjWw.js → postcss-BHW6XBhx.js} +0 -0
- /package/dist/web/assets/{powerquery-Cr2PtehI.js → powerquery-B89c2NBb.js} +0 -0
- /package/dist/web/assets/{powershell-BxFTGLJ4.js → powershell-Dvxrd3Tu.js} +0 -0
- /package/dist/web/assets/{prisma-COWJiwdZ.js → prisma-lMK8EFLU.js} +0 -0
- /package/dist/web/assets/{prolog-DFvGKRx6.js → prolog-D0YrtMG4.js} +0 -0
- /package/dist/web/assets/{proto-CcK80lFt.js → proto-J0mM25aw.js} +0 -0
- /package/dist/web/assets/{puppet-BF60bZ4F.js → puppet-CUT0xkhh.js} +0 -0
- /package/dist/web/assets/{purescript-zL_69MzU.js → purescript-CoJWSGRp.js} +0 -0
- /package/dist/web/assets/{python-CIwKhfb_.js → python-BBrmuz6P.js} +0 -0
- /package/dist/web/assets/{qmldir-CXNe04Lo.js → qmldir-CUtzs4Q7.js} +0 -0
- /package/dist/web/assets/{qss-C8lAWe6G.js → qss-Dm1RZ8aL.js} +0 -0
- /package/dist/web/assets/{r-CL5ZVL3_.js → r-BGP7qZTe.js} +0 -0
- /package/dist/web/assets/{racket-BBfh0uh0.js → racket-K_6U1lqJ.js} +0 -0
- /package/dist/web/assets/{raku-o6E8R5Q3.js → raku-bNSiZeW_.js} +0 -0
- /package/dist/web/assets/{react-CBTnT4sY.js → react-X4jUntEf.js} +0 -0
- /package/dist/web/assets/{red-GomRF2Xp.js → red-uVeIEF0f.js} +0 -0
- /package/dist/web/assets/{refresh-cw-B06yaBrW.js → refresh-cw-B9iv7csb.js} +0 -0
- /package/dist/web/assets/{reg-_ffDIvx9.js → reg-DSm9GWjh.js} +0 -0
- /package/dist/web/assets/{regexp-Bl5sF65W.js → regexp-CljRm_j_.js} +0 -0
- /package/dist/web/assets/{rel-DgMdqDuj.js → rel-d3JcopZg.js} +0 -0
- /package/dist/web/assets/{resolve-theme-CRt_7wpd.js → resolve-theme-DLKmm-lE.js} +0 -0
- /package/dist/web/assets/{riscv-8b3-Ye4X.js → riscv-CJmaELjT.js} +0 -0
- /package/dist/web/assets/{ron-DrmU1KHP.js → ron-D0g9B1rW.js} +0 -0
- /package/dist/web/assets/{rose-pine-C_-E2tF1.js → rose-pine-DOrD2BSH.js} +0 -0
- /package/dist/web/assets/{rose-pine-dawn-DEfhNlFH.js → rose-pine-dawn-CzZQ-LCF.js} +0 -0
- /package/dist/web/assets/{rose-pine-moon-BdvX3gdn.js → rose-pine-moon-CdmsYp7C.js} +0 -0
- /package/dist/web/assets/{rosmsg-B6GhGpd5.js → rosmsg-CmDth6pO.js} +0 -0
- /package/dist/web/assets/{rotate-ccw-COXu_9oj.js → rotate-ccw-DnuPzJRE.js} +0 -0
- /package/dist/web/assets/{rust-DmC97M1-.js → rust-DGdP6jiR.js} +0 -0
- /package/dist/web/assets/{sass-B0tJOHLM.js → sass-Dkgt2FKZ.js} +0 -0
- /package/dist/web/assets/{save-CtIGOjmx.js → save-DxonD4y1.js} +0 -0
- /package/dist/web/assets/{scala-n8zaFOXv.js → scala-BQLTON6C.js} +0 -0
- /package/dist/web/assets/{scheme-BKD9ztBU.js → scheme-DKlxUGCi.js} +0 -0
- /package/dist/web/assets/{sdbl-D8gB5-rS.js → sdbl-C3iZJQeZ.js} +0 -0
- /package/dist/web/assets/{send-BlyNJAzy.js → send-B-t5Mz26.js} +0 -0
- /package/dist/web/assets/{shallow-DYo6goJ4.js → shallow-jwPzEunk.js} +0 -0
- /package/dist/web/assets/{shellscript-BfXlf_Ao.js → shellscript-BRu-ZQAx.js} +0 -0
- /package/dist/web/assets/{shield-check-B0iGUiOK.js → shield-check-CdTiK1j2.js} +0 -0
- /package/dist/web/assets/{shield-off-BNLWBhcq.js → shield-off-DuetkXKM.js} +0 -0
- /package/dist/web/assets/{slack-dark-CylEddse.js → slack-dark-qkm_u2zz.js} +0 -0
- /package/dist/web/assets/{slack-ochin-w8wg8vuC.js → slack-ochin-BP8_8e4m.js} +0 -0
- /package/dist/web/assets/{smalltalk-hiAXA64u.js → smalltalk-Bnz4gt07.js} +0 -0
- /package/dist/web/assets/{snazzy-light-BwlV3Xty.js → snazzy-light-fbPZg5io.js} +0 -0
- /package/dist/web/assets/{solarized-dark-vmNGdykz.js → solarized-dark-CM0vTRoi.js} +0 -0
- /package/dist/web/assets/{solarized-light-DGv_0JXq.js → solarized-light-C4_W9mvs.js} +0 -0
- /package/dist/web/assets/{solidity-Y7QSH0B1.js → solidity-Bz6v1PoD.js} +0 -0
- /package/dist/web/assets/{splunk-BtgpLjHi.js → splunk-DyNxu-0i.js} +0 -0
- /package/dist/web/assets/{sql-CRHYhOia.js → sql-DXRL1gw1.js} +0 -0
- /package/dist/web/assets/{ssh-config-DOqSs3au.js → ssh-config-2z1QHuOG.js} +0 -0
- /package/dist/web/assets/{stylus-crCAEaBT.js → stylus-D4I-VaeY.js} +0 -0
- /package/dist/web/assets/{swift-eE3rT7TC.js → swift-C_2G-tIc.js} +0 -0
- /package/dist/web/assets/{synthwave-84-BWy14LBX.js → synthwave-84-osBjChRP.js} +0 -0
- /package/dist/web/assets/{system-verilog-DC0-DZM4.js → system-verilog-zQP2qPNU.js} +0 -0
- /package/dist/web/assets/{systemd-to5p6N8I.js → systemd-UGfjRSBM.js} +0 -0
- /package/dist/web/assets/{table-Bbc783ko.js → table-FLU8ei8b.js} +0 -0
- /package/dist/web/assets/{talonscript-DoTcU8wm.js → talonscript-C1XrFPwo.js} +0 -0
- /package/dist/web/assets/{tasl-cNZvUs95.js → tasl-B5raVn43.js} +0 -0
- /package/dist/web/assets/{tcl-mZE8sZH8.js → tcl-3-vbeMIc.js} +0 -0
- /package/dist/web/assets/{terraform-CqHPpIfu.js → terraform-a8VXZDm9.js} +0 -0
- /package/dist/web/assets/{text-wrap-CBT4Gxtg.js → text-wrap-B05VGRa-.js} +0 -0
- /package/dist/web/assets/{tokyo-night-Tp2rTIZd.js → tokyo-night-4SRhf-Hz.js} +0 -0
- /package/dist/web/assets/{toml-CU_vscgn.js → toml-B4N0i8wT.js} +0 -0
- /package/dist/web/assets/{trash-2-Bk4yYlck.js → trash-2-CTXlTflF.js} +0 -0
- /package/dist/web/assets/{triangle-alert-B8EYecpe.js → triangle-alert-BRq0VAfd.js} +0 -0
- /package/dist/web/assets/{tsv-ik7iFB9D.js → tsv-DA5k9Lvw.js} +0 -0
- /package/dist/web/assets/{tsx-BMvvMKiv.js → tsx-D9SZ8owC.js} +0 -0
- /package/dist/web/assets/{turtle-DBqKCq9o.js → turtle-BTHTvyY_.js} +0 -0
- /package/dist/web/assets/{typescript-DXJDmMZZ.js → typescript-DYzV9p5L.js} +0 -0
- /package/dist/web/assets/{typespec-CBseCMtZ.js → typespec-BC15eh7F.js} +0 -0
- /package/dist/web/assets/{typst-4oY25U9y.js → typst-BJUqzA6D.js} +0 -0
- /package/dist/web/assets/{use-is-mobile-D1weanbj.js → use-is-mobile-DFWViA4S.js} +0 -0
- /package/dist/web/assets/{utils-BNRH507E.js → utils-C9OjCrou.js} +0 -0
- /package/dist/web/assets/{v-BXaZ_1oy.js → v-50Lps6oA.js} +0 -0
- /package/dist/web/assets/{vala-BImWJE7z.js → vala-8wiUvvrD.js} +0 -0
- /package/dist/web/assets/{vb-CLfj2_sy.js → vb-BlgPLt6B.js} +0 -0
- /package/dist/web/assets/{vendor-xterm-_yyu5n32.js → vendor-xterm-BZOrwF_F.js} +0 -0
- /package/dist/web/assets/{verilog-BWa8Ed2b.js → verilog-CD9pVW5p.js} +0 -0
- /package/dist/web/assets/{vesper-BGj1cg6m.js → vesper-BrivW4PT.js} +0 -0
- /package/dist/web/assets/{vhdl-mByK7mlx.js → vhdl-Bunxfa7N.js} +0 -0
- /package/dist/web/assets/{viml-CugmlW5g.js → viml-DndUb2qM.js} +0 -0
- /package/dist/web/assets/{vitesse-black-vPdpy9TL.js → vitesse-black-BurZSkxW.js} +0 -0
- /package/dist/web/assets/{vitesse-dark-BuQK3dUh.js → vitesse-dark-8UShspzC.js} +0 -0
- /package/dist/web/assets/{vitesse-light-B3nz1XL9.js → vitesse-light-DghCAZ90.js} +0 -0
- /package/dist/web/assets/{vyper-DH_GTIHG.js → vyper-b-Clr-8u.js} +0 -0
- /package/dist/web/assets/{wasm-DfVbVJlW.js → wasm-C5v2T06Y.js} +0 -0
- /package/dist/web/assets/{wasm-C-LF9GjX.js → wasm-CpcKStkw.js} +0 -0
- /package/dist/web/assets/{wenyan-CzQkHyHx.js → wenyan-Dz2srLZR.js} +0 -0
- /package/dist/web/assets/{wgsl-Du_M1DW9.js → wgsl-CeD1-dRb.js} +0 -0
- /package/dist/web/assets/{wikitext-BWN_w5S7.js → wikitext-CyeS-9FH.js} +0 -0
- /package/dist/web/assets/{wit-BR13v5HD.js → wit-Kr-q-qBQ.js} +0 -0
- /package/dist/web/assets/{wolfram-BoXxp_Xl.js → wolfram-BKm8bmln.js} +0 -0
- /package/dist/web/assets/{x-nhriOX9o.js → x-YDu4m2Iq.js} +0 -0
- /package/dist/web/assets/{yaml-DpR_EF-d.js → yaml-2XSxomjM.js} +0 -0
- /package/dist/web/assets/{zenscript-C-EdUtUd.js → zenscript-CKIS34vf.js} +0 -0
- /package/dist/web/assets/{zig-BD4eA5nU.js → zig-DdHGNllX.js} +0 -0
|
@@ -125,6 +125,33 @@ const SOURCE_RANK: Record<TunnelSource, number> = { external: 0, ppm: 1, app: 2
|
|
|
125
125
|
* source/protected flag, while url/port/identity are filled from whichever
|
|
126
126
|
* entry has them (higher precedence preferred).
|
|
127
127
|
*/
|
|
128
|
+
/** Identity of the supervisor-managed app tunnel, read from status.json + config. */
|
|
129
|
+
export interface AppShare {
|
|
130
|
+
shareUrl: string | null;
|
|
131
|
+
tunnelPid: number | null;
|
|
132
|
+
serverPort: number | null;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Does this cloudflared entry belong to the app/supervisor tunnel? Such a
|
|
137
|
+
* tunnel is display-only: stopping it from the panel would take the whole app
|
|
138
|
+
* offline, and the supervisor would just respawn it.
|
|
139
|
+
*
|
|
140
|
+
* Matching is protect-by-default (PID, public URL, then the PPM port as a
|
|
141
|
+
* fallback for a stale `tunnelPid`) with one deliberate exception: a tunnel
|
|
142
|
+
* this server spawned itself. Running a second, temporary tunnel onto the same
|
|
143
|
+
* public port is a supported thing to do — sharing a one-off link without
|
|
144
|
+
* handing out the permanent hostname — and it must stay stoppable from the UI
|
|
145
|
+
* that created it.
|
|
146
|
+
*/
|
|
147
|
+
export function isAppTunnel(entry: TunnelEntry, app: AppShare): boolean {
|
|
148
|
+
if (app.tunnelPid != null && entry.pid === app.tunnelPid) return true;
|
|
149
|
+
if (app.shareUrl && entry.url && entry.url === app.shareUrl) return true;
|
|
150
|
+
if (entry.source === "ppm") return false;
|
|
151
|
+
if (app.serverPort != null && entry.port === app.serverPort) return true;
|
|
152
|
+
return false;
|
|
153
|
+
}
|
|
154
|
+
|
|
128
155
|
export function mergeTunnelSources(sources: {
|
|
129
156
|
external: TunnelEntry[];
|
|
130
157
|
ppm: TunnelEntry[];
|
|
@@ -21,6 +21,8 @@ import {
|
|
|
21
21
|
extractMetricsPort,
|
|
22
22
|
parseQuickTunnelResponse,
|
|
23
23
|
mergeTunnelSources,
|
|
24
|
+
isAppTunnel,
|
|
25
|
+
type AppShare,
|
|
24
26
|
type TunnelEntry,
|
|
25
27
|
} from "./tunnel-registry-parse.ts";
|
|
26
28
|
|
|
@@ -159,12 +161,6 @@ async function recoverUrl(pid: number, metricsAddr: string | null): Promise<stri
|
|
|
159
161
|
// App/supervisor tunnel identification (protection)
|
|
160
162
|
// ---------------------------------------------------------------------------
|
|
161
163
|
|
|
162
|
-
interface AppShare {
|
|
163
|
-
shareUrl: string | null;
|
|
164
|
-
tunnelPid: number | null;
|
|
165
|
-
serverPort: number | null;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
164
|
/** Read the app-share tunnel fresh from status.json each call (guards stale PID). */
|
|
169
165
|
function readAppShare(): AppShare {
|
|
170
166
|
let shareUrl: string | null = null;
|
|
@@ -181,15 +177,6 @@ function readAppShare(): AppShare {
|
|
|
181
177
|
return { shareUrl, tunnelPid, serverPort };
|
|
182
178
|
}
|
|
183
179
|
|
|
184
|
-
/** A cloudflared entry belongs to the app/supervisor tunnel if it matches by
|
|
185
|
-
* PID, public URL, or targets the PPM server port. Protect-by-default. */
|
|
186
|
-
function isAppTunnel(entry: TunnelEntry, app: AppShare): boolean {
|
|
187
|
-
if (app.tunnelPid != null && entry.pid === app.tunnelPid) return true;
|
|
188
|
-
if (app.shareUrl && entry.url && entry.url === app.shareUrl) return true;
|
|
189
|
-
if (app.serverPort != null && entry.port === app.serverPort) return true;
|
|
190
|
-
return false;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
180
|
// ---------------------------------------------------------------------------
|
|
194
181
|
// Image verification (safe-kill guard, used by the route layer)
|
|
195
182
|
// ---------------------------------------------------------------------------
|
|
@@ -125,22 +125,31 @@ class TunnelService {
|
|
|
125
125
|
/** Get current tunnel URL (null if not running).
|
|
126
126
|
* Falls back to status.json if the supervisor set the URL after this process started. */
|
|
127
127
|
getTunnelUrl(): string | null {
|
|
128
|
-
|
|
129
|
-
//
|
|
128
|
+
// A tunnel this process spawned can only change through this class, so its
|
|
129
|
+
// URL is safe to cache. A supervisor-managed one is not: the supervisor
|
|
130
|
+
// rewrites shareUrl on its own (quick-URL regeneration, switching to or
|
|
131
|
+
// from a named hostname) and the server would otherwise keep handing out
|
|
132
|
+
// the first URL it ever saw — the share popover and the cloud heartbeat
|
|
133
|
+
// both showed a dead temporary URL minutes after the hostname went live.
|
|
134
|
+
if (this.childProcess && this.url) return this.url;
|
|
130
135
|
this.syncFromStatusFile();
|
|
131
136
|
return this.url;
|
|
132
137
|
}
|
|
133
138
|
|
|
134
139
|
/** Re-read tunnel state from status.json (supervisor may have updated it after server started) */
|
|
135
140
|
private syncFromStatusFile(): void {
|
|
136
|
-
if (this.
|
|
141
|
+
if (this.childProcess) return; // we own this tunnel; status.json mirrors us, not the other way round
|
|
137
142
|
try {
|
|
138
143
|
const statusFile = resolve(getPpmDir(), "status.json");
|
|
139
144
|
const status = JSON.parse(readFileSync(statusFile, "utf-8"));
|
|
140
145
|
if (status.shareUrl) {
|
|
146
|
+
const changed = status.shareUrl !== this.url;
|
|
141
147
|
this.url = status.shareUrl;
|
|
142
148
|
this.supervisorManaged = true;
|
|
143
149
|
if (status.tunnelPid) this.externalPid = status.tunnelPid;
|
|
150
|
+
// A new public URL must reach PPM Cloud too, or the permanent link
|
|
151
|
+
// keeps redirecting to the retired one.
|
|
152
|
+
if (changed) this.syncToCloud();
|
|
144
153
|
}
|
|
145
154
|
} catch {}
|
|
146
155
|
}
|
package/src/types/config.ts
CHANGED
|
@@ -35,6 +35,23 @@ export interface PpmConfig {
|
|
|
35
35
|
clawbot?: PPMBotConfig;
|
|
36
36
|
cloud_url?: string;
|
|
37
37
|
query_audit: QueryAuditConfig;
|
|
38
|
+
tunnel: TunnelConfig;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Persisted named-tunnel state. `namedTunnelToken` is secret-by-contract —
|
|
43
|
+
* guarded by the config-key denylist and never returned unmasked by any route.
|
|
44
|
+
* `zoneID`/`accountID` are pinned at setup and re-checked on every reuse.
|
|
45
|
+
*/
|
|
46
|
+
export interface TunnelConfig {
|
|
47
|
+
mode: "quick" | "named";
|
|
48
|
+
namedTunnelName?: string;
|
|
49
|
+
namedTunnelHostname?: string;
|
|
50
|
+
namedTunnelToken?: string;
|
|
51
|
+
zoneID?: string;
|
|
52
|
+
accountID?: string;
|
|
53
|
+
/** User answered "no domain" — popup must never nag again. */
|
|
54
|
+
dismissed?: boolean;
|
|
38
55
|
}
|
|
39
56
|
|
|
40
57
|
export interface QueryAuditConfig {
|
|
@@ -131,6 +148,9 @@ export const DEFAULT_CONFIG: PpmConfig = {
|
|
|
131
148
|
permission_mode: "bypassPermissions",
|
|
132
149
|
debounce_ms: 2000,
|
|
133
150
|
},
|
|
151
|
+
tunnel: {
|
|
152
|
+
mode: "quick",
|
|
153
|
+
},
|
|
134
154
|
};
|
|
135
155
|
|
|
136
156
|
const VALID_TYPES = ["agent-sdk", "cli", "mock"] as const;
|
|
@@ -264,5 +284,16 @@ export function sanitizeConfig(config: PpmConfig): boolean {
|
|
|
264
284
|
}
|
|
265
285
|
}
|
|
266
286
|
|
|
287
|
+
// Only repair `tunnel` when storage itself is malformed (wrong type / bad enum).
|
|
288
|
+
// Never strip namedTunnel*/zoneID/accountID just because mode is "quick" or the
|
|
289
|
+
// combination looks "incomplete" — that degrade-to-quick judgment belongs to
|
|
290
|
+
// the runtime resolver (resolveTunnelConfig), or /disable's "keep the config so
|
|
291
|
+
// Retry works" contract silently breaks.
|
|
292
|
+
if (typeof config.tunnel !== "object" || config.tunnel === null ||
|
|
293
|
+
(config.tunnel.mode !== "quick" && config.tunnel.mode !== "named")) {
|
|
294
|
+
config.tunnel = structuredClone(DEFAULT_CONFIG.tunnel);
|
|
295
|
+
dirty = true;
|
|
296
|
+
}
|
|
297
|
+
|
|
267
298
|
return dirty;
|
|
268
299
|
}
|
package/src/web/app.tsx
CHANGED
|
@@ -27,6 +27,7 @@ import { useServerReload } from "@/hooks/use-server-reload";
|
|
|
27
27
|
import { CommandPalette } from "@/components/layout/command-palette";
|
|
28
28
|
import { ComparePicker } from "@/components/editor/compare-picker";
|
|
29
29
|
import { BugReportPopup } from "@/components/shared/bug-report-popup";
|
|
30
|
+
import { NamedTunnelSetupPopup } from "@/components/tunnels/named-tunnel/named-tunnel-setup-popup";
|
|
30
31
|
import { ImageOverlay } from "@/components/shared/image-overlay";
|
|
31
32
|
import { DiagramOverlay } from "@/components/shared/diagram-overlay";
|
|
32
33
|
import { BackgroundOutputPanel } from "@/components/chat/background-output-panel";
|
|
@@ -359,6 +360,10 @@ export function App() {
|
|
|
359
360
|
{/* Global bug report popup */}
|
|
360
361
|
<BugReportPopup />
|
|
361
362
|
|
|
363
|
+
{/* Named-tunnel first-run setup popup — hidden unless auth is on, mode is
|
|
364
|
+
still quick and the user has not dismissed it (or a cert needs renewal) */}
|
|
365
|
+
<NamedTunnelSetupPopup />
|
|
366
|
+
|
|
362
367
|
{/* Global image lightbox */}
|
|
363
368
|
<ImageOverlay />
|
|
364
369
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useState, useEffect, useCallback, useRef, type MouseEvent } from "react";
|
|
2
|
-
import { History, Settings2, Loader2, MessageSquare, RefreshCw, Search, Pencil, Check, X,
|
|
2
|
+
import { History, Settings2, Loader2, MessageSquare, RefreshCw, Search, Pencil, Check, X, Pin, PinOff, Trash2, Users, Bot, Tags, CalendarX2 } from "lucide-react";
|
|
3
3
|
import { Activity } from "lucide-react";
|
|
4
4
|
import { api, projectUrl } from "@/lib/api-client";
|
|
5
5
|
import { useTabStore } from "@/stores/tab-store";
|
|
@@ -8,7 +8,8 @@ import { cn } from "@/lib/utils";
|
|
|
8
8
|
import { AISettingsSection } from "@/components/settings/ai-settings-section";
|
|
9
9
|
import { TagSettingsSection } from "@/components/settings/tag-settings-section";
|
|
10
10
|
import { SessionContextMenu } from "./session-context-menu";
|
|
11
|
-
import {
|
|
11
|
+
import { SessionDebugDialog } from "./session-debug-dialog";
|
|
12
|
+
import { ChatToolbarOverflowMenu } from "./chat-toolbar-overflow-menu";
|
|
12
13
|
import { UsageDetailPanel } from "./usage-badge";
|
|
13
14
|
import { CodexUsagePanel } from "./codex-usage-panel";
|
|
14
15
|
import { TeamActivityPanel } from "./team-activity-panel";
|
|
@@ -82,6 +83,7 @@ export function ChatHistoryBar({
|
|
|
82
83
|
const [selectedTagId, setSelectedTagId] = useState<number | null>(null);
|
|
83
84
|
const [tagCounts, setTagCounts] = useState<Record<number, number>>({});
|
|
84
85
|
const [showTagSettings, setShowTagSettings] = useState(false);
|
|
86
|
+
const [debugOpen, setDebugOpen] = useState(false);
|
|
85
87
|
const editInputRef = useRef<HTMLInputElement>(null);
|
|
86
88
|
const openTab = useTabStore((s) => s.openTab);
|
|
87
89
|
const PAGE_SIZE = 50;
|
|
@@ -273,112 +275,88 @@ export function ChatHistoryBar({
|
|
|
273
275
|
|
|
274
276
|
return (
|
|
275
277
|
<div className="border-b border-border/50">
|
|
276
|
-
{/* Toolbar row —
|
|
278
|
+
{/* Toolbar row — status chips scroll on the left, controls stay pinned right.
|
|
279
|
+
A narrow chat pane must never push the connection indicator out of view. */}
|
|
277
280
|
<div className="flex items-center gap-1 px-2 py-1">
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
onClick={() => togglePanel("history")}
|
|
281
|
-
className={`flex items-center gap-1 px-1.5 py-0.5 rounded text-[11px] transition-colors ${
|
|
282
|
-
activePanel === "history" ? "text-primary bg-primary/10" : "text-text-secondary hover:text-foreground hover:bg-surface-elevated"
|
|
283
|
-
}`}
|
|
284
|
-
>
|
|
285
|
-
<History className="size-3" />
|
|
286
|
-
<span>History</span>
|
|
287
|
-
</button>
|
|
288
|
-
|
|
289
|
-
{/* Active provider + AI Settings (combined) */}
|
|
290
|
-
{sessionId && providerId && providerId !== "mock" ? (
|
|
281
|
+
<div className="flex min-w-0 flex-1 items-center gap-1 overflow-x-auto scrollbar-none">
|
|
282
|
+
{/* History */}
|
|
291
283
|
<button
|
|
292
|
-
onClick={() => togglePanel("
|
|
293
|
-
className={`flex items-center gap-1 px-1.5 py-0.5 rounded text-[11px] transition-colors ${
|
|
294
|
-
activePanel === "
|
|
284
|
+
onClick={() => togglePanel("history")}
|
|
285
|
+
className={`shrink-0 flex items-center gap-1 px-1.5 py-0.5 rounded text-[11px] transition-colors ${
|
|
286
|
+
activePanel === "history" ? "text-primary bg-primary/10" : "text-text-secondary hover:text-foreground hover:bg-surface-elevated"
|
|
295
287
|
}`}
|
|
296
|
-
title="AI Settings"
|
|
297
288
|
>
|
|
298
|
-
<
|
|
299
|
-
<span
|
|
289
|
+
<History className="size-3" />
|
|
290
|
+
<span>History</span>
|
|
300
291
|
</button>
|
|
301
|
-
) : (
|
|
302
|
-
<button
|
|
303
|
-
onClick={() => togglePanel("config")}
|
|
304
|
-
className={`p-1 rounded transition-colors ${
|
|
305
|
-
activePanel === "config" ? "text-primary bg-primary/10" : "text-text-subtle hover:text-text-secondary hover:bg-surface-elevated"
|
|
306
|
-
}`}
|
|
307
|
-
title="AI Settings"
|
|
308
|
-
>
|
|
309
|
-
<Settings2 className="size-3" />
|
|
310
|
-
</button>
|
|
311
|
-
)}
|
|
312
|
-
|
|
313
|
-
{/* Usage & Accounts — Claude and Codex both surface usage + account mgmt here */}
|
|
314
|
-
{(isClaudeProvider || isCodexProvider) ? (
|
|
315
|
-
<button
|
|
316
|
-
onClick={() => togglePanel("usage")}
|
|
317
|
-
className={`flex items-center gap-1 px-1.5 py-0.5 rounded text-[11px] font-medium tabular-nums transition-colors hover:bg-surface-elevated ${
|
|
318
|
-
activePanel === "usage" ? "bg-primary/10" : ""
|
|
319
|
-
} ${usageColor}`}
|
|
320
|
-
title="Usage limits"
|
|
321
|
-
>
|
|
322
|
-
<Activity className="size-3" />
|
|
323
|
-
{usageInfo.activeAccountLabel && (
|
|
324
|
-
<span className="text-text-secondary font-normal truncate max-w-[60px]">[{usageInfo.activeAccountLabel}]</span>
|
|
325
|
-
)}
|
|
326
|
-
<span>5h:{fiveHourPct != null ? `${fiveHourPct}%` : "--%"}</span>
|
|
327
|
-
<span className="text-text-subtle">·</span>
|
|
328
|
-
<span>Wk:{sevenDayPct != null ? `${sevenDayPct}%` : "--%"}</span>
|
|
329
|
-
</button>
|
|
330
|
-
) : null}
|
|
331
|
-
|
|
332
|
-
{/* Team activity */}
|
|
333
|
-
{teamActivity?.hasTeams && (
|
|
334
|
-
<button
|
|
335
|
-
onClick={() => {
|
|
336
|
-
togglePanel("team");
|
|
337
|
-
onTeamOpen?.();
|
|
338
|
-
}}
|
|
339
|
-
className={`relative flex items-center gap-1 px-1.5 py-0.5 rounded text-[11px] transition-colors ${
|
|
340
|
-
activePanel === "team" ? "text-primary bg-primary/10" : "text-text-secondary hover:text-foreground hover:bg-surface-elevated"
|
|
341
|
-
}`}
|
|
342
|
-
title="Team activity"
|
|
343
|
-
>
|
|
344
|
-
<Users className="size-3" />
|
|
345
|
-
<span>Team</span>
|
|
346
|
-
{(teamActivity.unreadCount ?? 0) > 0 && (
|
|
347
|
-
<span className="absolute -top-0.5 -right-0.5 size-2 bg-primary rounded-full animate-pulse" />
|
|
348
|
-
)}
|
|
349
|
-
</button>
|
|
350
|
-
)}
|
|
351
292
|
|
|
352
|
-
|
|
353
|
-
|
|
293
|
+
{/* Active provider + AI Settings (combined) */}
|
|
294
|
+
{sessionId && providerId && providerId !== "mock" ? (
|
|
295
|
+
<button
|
|
296
|
+
onClick={() => togglePanel("config")}
|
|
297
|
+
className={`shrink-0 flex items-center gap-1 px-1.5 py-0.5 rounded text-[11px] transition-colors ${
|
|
298
|
+
activePanel === "config" ? "text-primary bg-primary/10" : "text-text-secondary hover:text-foreground hover:bg-surface-elevated"
|
|
299
|
+
}`}
|
|
300
|
+
title="AI Settings"
|
|
301
|
+
>
|
|
302
|
+
<ProviderBadge providerId={providerId} />
|
|
303
|
+
<span className="capitalize">{providerId}</span>
|
|
304
|
+
</button>
|
|
305
|
+
) : (
|
|
306
|
+
<button
|
|
307
|
+
onClick={() => togglePanel("config")}
|
|
308
|
+
className={`shrink-0 p-1 rounded transition-colors ${
|
|
309
|
+
activePanel === "config" ? "text-primary bg-primary/10" : "text-text-subtle hover:text-text-secondary hover:bg-surface-elevated"
|
|
310
|
+
}`}
|
|
311
|
+
title="AI Settings"
|
|
312
|
+
>
|
|
313
|
+
<Settings2 className="size-3" />
|
|
314
|
+
</button>
|
|
315
|
+
)}
|
|
354
316
|
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
317
|
+
{/* Usage & Accounts — Claude and Codex both surface usage + account mgmt here */}
|
|
318
|
+
{(isClaudeProvider || isCodexProvider) ? (
|
|
319
|
+
<button
|
|
320
|
+
onClick={() => togglePanel("usage")}
|
|
321
|
+
className={`shrink-0 flex items-center gap-1 px-1.5 py-0.5 rounded text-[11px] font-medium tabular-nums transition-colors hover:bg-surface-elevated ${
|
|
322
|
+
activePanel === "usage" ? "bg-primary/10" : ""
|
|
323
|
+
} ${usageColor}`}
|
|
324
|
+
title="Usage limits"
|
|
325
|
+
>
|
|
326
|
+
<Activity className="size-3" />
|
|
327
|
+
{usageInfo.activeAccountLabel && (
|
|
328
|
+
<span className="text-text-secondary font-normal truncate max-w-[60px]">[{usageInfo.activeAccountLabel}]</span>
|
|
329
|
+
)}
|
|
330
|
+
<span>5h:{fiveHourPct != null ? `${fiveHourPct}%` : "--%"}</span>
|
|
331
|
+
<span className="text-text-subtle">·</span>
|
|
332
|
+
<span>Wk:{sevenDayPct != null ? `${sevenDayPct}%` : "--%"}</span>
|
|
333
|
+
</button>
|
|
334
|
+
) : null}
|
|
365
335
|
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
336
|
+
{/* Team activity */}
|
|
337
|
+
{teamActivity?.hasTeams && (
|
|
338
|
+
<button
|
|
339
|
+
onClick={() => {
|
|
340
|
+
togglePanel("team");
|
|
341
|
+
onTeamOpen?.();
|
|
342
|
+
}}
|
|
343
|
+
className={`shrink-0 relative flex items-center gap-1 px-1.5 py-0.5 rounded text-[11px] transition-colors ${
|
|
344
|
+
activePanel === "team" ? "text-primary bg-primary/10" : "text-text-secondary hover:text-foreground hover:bg-surface-elevated"
|
|
345
|
+
}`}
|
|
346
|
+
title="Team activity"
|
|
347
|
+
>
|
|
348
|
+
<Users className="size-3" />
|
|
349
|
+
<span>Team</span>
|
|
350
|
+
{(teamActivity.unreadCount ?? 0) > 0 && (
|
|
351
|
+
<span className="absolute -top-0.5 -right-0.5 size-2 bg-primary rounded-full animate-pulse" />
|
|
352
|
+
)}
|
|
353
|
+
</button>
|
|
354
|
+
)}
|
|
376
355
|
|
|
377
|
-
|
|
378
|
-
{sessionId && (
|
|
379
|
-
<SessionDebugButton sessionId={sessionId} projectName={projectName} />
|
|
380
|
-
)}
|
|
356
|
+
</div>
|
|
381
357
|
|
|
358
|
+
{/* Pinned controls — always visible, never scrolled away */}
|
|
359
|
+
<div className="flex shrink-0 items-center gap-1 pl-1">
|
|
382
360
|
{/* Reload messages + connection status */}
|
|
383
361
|
{onReload && (
|
|
384
362
|
<button
|
|
@@ -397,8 +375,27 @@ export function ChatHistoryBar({
|
|
|
397
375
|
<span className={`absolute -top-0.5 -right-0.5 size-1.5 rounded-full ${isConnected ? "bg-success" : "bg-error animate-pulse"}`} />
|
|
398
376
|
</button>
|
|
399
377
|
)}
|
|
378
|
+
|
|
379
|
+
{/* Overflow menu — session actions, and the home for future toolbar actions */}
|
|
380
|
+
{sessionId && (
|
|
381
|
+
<ChatToolbarOverflowMenu
|
|
382
|
+
hasUnread={hasUnread}
|
|
383
|
+
onToggleUnread={() => hasUnread ? clearForSession(sessionId) : markUnread(sessionId, projectName)}
|
|
384
|
+
onOpenDebug={() => setDebugOpen(true)}
|
|
385
|
+
/>
|
|
386
|
+
)}
|
|
387
|
+
</div>
|
|
400
388
|
</div>
|
|
401
389
|
|
|
390
|
+
{sessionId && (
|
|
391
|
+
<SessionDebugDialog
|
|
392
|
+
sessionId={sessionId}
|
|
393
|
+
projectName={projectName}
|
|
394
|
+
open={debugOpen}
|
|
395
|
+
onOpenChange={setDebugOpen}
|
|
396
|
+
/>
|
|
397
|
+
)}
|
|
398
|
+
|
|
402
399
|
{/* Panels — only one visible at a time */}
|
|
403
400
|
|
|
404
401
|
{/* History panel */}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { BellOff, Bug, Circle, MoreHorizontal } from "lucide-react";
|
|
2
|
+
import {
|
|
3
|
+
DropdownMenu,
|
|
4
|
+
DropdownMenuContent,
|
|
5
|
+
DropdownMenuItem,
|
|
6
|
+
DropdownMenuTrigger,
|
|
7
|
+
} from "@/components/ui/dropdown-menu";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Session actions that do not earn permanent space in the chat toolbar.
|
|
11
|
+
*
|
|
12
|
+
* The toolbar's left zone scrolls once the chat panel gets narrow, so every
|
|
13
|
+
* control pinned on the right competes for the handful of pixels that stay
|
|
14
|
+
* visible. Only the connection indicator earns that spot; infrequent actions
|
|
15
|
+
* live behind this trigger, which is also where future toolbar actions belong.
|
|
16
|
+
*/
|
|
17
|
+
export function ChatToolbarOverflowMenu({
|
|
18
|
+
hasUnread,
|
|
19
|
+
onToggleUnread,
|
|
20
|
+
onOpenDebug,
|
|
21
|
+
}: {
|
|
22
|
+
hasUnread: boolean;
|
|
23
|
+
onToggleUnread: () => void;
|
|
24
|
+
onOpenDebug: () => void;
|
|
25
|
+
}) {
|
|
26
|
+
return (
|
|
27
|
+
<DropdownMenu>
|
|
28
|
+
<DropdownMenuTrigger asChild>
|
|
29
|
+
<button
|
|
30
|
+
type="button"
|
|
31
|
+
className="flex items-center justify-center size-5 rounded text-text-subtle hover:text-text-secondary hover:bg-surface-elevated transition-colors"
|
|
32
|
+
title="More actions"
|
|
33
|
+
aria-label="More actions"
|
|
34
|
+
>
|
|
35
|
+
<MoreHorizontal className="size-3.5" />
|
|
36
|
+
</button>
|
|
37
|
+
</DropdownMenuTrigger>
|
|
38
|
+
{/* Anchored above: this toolbar sits at the bottom of the chat pane. */}
|
|
39
|
+
<DropdownMenuContent align="end" side="top" className="min-w-[190px]">
|
|
40
|
+
<DropdownMenuItem onClick={onToggleUnread} className="max-md:py-3">
|
|
41
|
+
{hasUnread ? (
|
|
42
|
+
<>
|
|
43
|
+
<BellOff className="size-3.5 text-warning" /> Mark as read
|
|
44
|
+
</>
|
|
45
|
+
) : (
|
|
46
|
+
<>
|
|
47
|
+
<Circle className="size-3.5 fill-current text-primary" /> Mark as unread
|
|
48
|
+
</>
|
|
49
|
+
)}
|
|
50
|
+
</DropdownMenuItem>
|
|
51
|
+
<DropdownMenuItem onClick={onOpenDebug} className="max-md:py-3">
|
|
52
|
+
<Bug className="size-3.5" /> Session debug info
|
|
53
|
+
</DropdownMenuItem>
|
|
54
|
+
</DropdownMenuContent>
|
|
55
|
+
</DropdownMenu>
|
|
56
|
+
);
|
|
57
|
+
}
|
|
@@ -308,15 +308,30 @@ function TurnUsageHistory({ sessionId, projectName }: { sessionId: string; proje
|
|
|
308
308
|
);
|
|
309
309
|
}
|
|
310
310
|
|
|
311
|
-
/**
|
|
312
|
-
|
|
313
|
-
|
|
311
|
+
/**
|
|
312
|
+
* Session debug facts and transcript maintenance.
|
|
313
|
+
*
|
|
314
|
+
* Controlled by the caller so the trigger can live anywhere — including inside a
|
|
315
|
+
* dropdown menu, which unmounts its own items on select and would take an
|
|
316
|
+
* internally-owned dialog down with them.
|
|
317
|
+
*/
|
|
318
|
+
export function SessionDebugDialog({
|
|
319
|
+
sessionId,
|
|
320
|
+
projectName,
|
|
321
|
+
open,
|
|
322
|
+
onOpenChange,
|
|
323
|
+
}: {
|
|
324
|
+
sessionId: string;
|
|
325
|
+
projectName: string;
|
|
326
|
+
open: boolean;
|
|
327
|
+
onOpenChange: (open: boolean) => void;
|
|
328
|
+
}) {
|
|
314
329
|
const [info, setInfo] = useState<string | null>(null);
|
|
315
330
|
const [copied, setCopied] = useState(false);
|
|
316
331
|
const isMobile = useIsMobile();
|
|
317
332
|
|
|
318
|
-
|
|
319
|
-
|
|
333
|
+
useEffect(() => {
|
|
334
|
+
if (!open) return;
|
|
320
335
|
setCopied(false);
|
|
321
336
|
setInfo(null);
|
|
322
337
|
api.get<DebugInfo>(
|
|
@@ -333,7 +348,7 @@ export function SessionDebugButton({ sessionId, projectName }: { sessionId: stri
|
|
|
333
348
|
...gatherRenderStats(),
|
|
334
349
|
].filter(Boolean).join("\n"));
|
|
335
350
|
}).catch(() => setInfo("Failed to load debug info"));
|
|
336
|
-
};
|
|
351
|
+
}, [open, sessionId, projectName]);
|
|
337
352
|
|
|
338
353
|
const copy = () => {
|
|
339
354
|
if (!info) return;
|
|
@@ -365,27 +380,20 @@ export function SessionDebugButton({ sessionId, projectName }: { sessionId: stri
|
|
|
365
380
|
</div>
|
|
366
381
|
);
|
|
367
382
|
|
|
383
|
+
if (isMobile) {
|
|
384
|
+
return (
|
|
385
|
+
<BottomSheet open={open} onClose={() => onOpenChange(false)} className="popover-solid">
|
|
386
|
+
<div className="max-h-[85vh] overflow-y-auto px-4 pb-4 pt-1">{body}</div>
|
|
387
|
+
</BottomSheet>
|
|
388
|
+
);
|
|
389
|
+
}
|
|
390
|
+
|
|
368
391
|
return (
|
|
369
|
-
|
|
370
|
-
<
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
<Bug className="size-3" />
|
|
376
|
-
</button>
|
|
377
|
-
{isMobile ? (
|
|
378
|
-
<BottomSheet open={open} onClose={() => setOpen(false)} className="popover-solid">
|
|
379
|
-
<div className="max-h-[85vh] overflow-y-auto px-4 pb-4 pt-1">{body}</div>
|
|
380
|
-
</BottomSheet>
|
|
381
|
-
) : (
|
|
382
|
-
<Dialog open={open} onOpenChange={setOpen}>
|
|
383
|
-
<DialogContent className="sm:max-w-lg">
|
|
384
|
-
<DialogTitle className="sr-only">Session debug info</DialogTitle>
|
|
385
|
-
{body}
|
|
386
|
-
</DialogContent>
|
|
387
|
-
</Dialog>
|
|
388
|
-
)}
|
|
389
|
-
</>
|
|
392
|
+
<Dialog open={open} onOpenChange={onOpenChange}>
|
|
393
|
+
<DialogContent className="sm:max-w-lg">
|
|
394
|
+
<DialogTitle className="sr-only">Session debug info</DialogTitle>
|
|
395
|
+
{body}
|
|
396
|
+
</DialogContent>
|
|
397
|
+
</Dialog>
|
|
390
398
|
);
|
|
391
399
|
}
|