@hienlh/ppm 0.18.12 → 0.18.14
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 +27 -0
- package/CLAUDE.md +3 -0
- package/README.md +6 -6
- 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 +19 -1
- package/dist/web/assets/{adaptive-context-menu-DGCKKeTy.js → adaptive-context-menu-DCZtgOL7.js} +1 -1
- package/dist/web/assets/{ai-resource-editor-BOHHTTe7.js → ai-resource-editor-D5CPBg06.js} +1 -1
- package/dist/web/assets/{ai-settings-section-BigC_nZR.js → ai-settings-section-DY-t1bK8.js} +1 -1
- package/dist/web/assets/{angular-html-BYPaydvh.js → angular-html-CTvM4ulF.js} +1 -1
- package/dist/web/assets/{angular-ts-Bb4AMKlk.js → angular-ts-B_vSkjco.js} +1 -1
- package/dist/web/assets/api-client-BogqsFna.js +1 -0
- package/dist/web/assets/{api-settings-Bd3M4YpI.js → api-settings-B2iNXQ0c.js} +1 -1
- package/dist/web/assets/api-settings-DRF9oYkn.js +1 -0
- package/dist/web/assets/{api-themes-Cpx419SL.js → api-themes-DrWnJbhs.js} +1 -1
- package/dist/web/assets/{apl-DB2VjFCS.js → apl-DywzTry0.js} +1 -1
- package/dist/web/assets/architecture-PBZL5I3N-nw5-j_I_.js +1 -0
- package/dist/web/assets/{astro-BeoJdVpk.js → astro-1JaRgaSb.js} +1 -1
- package/dist/web/assets/{audio-preview-BgFuTn-0.js → audio-preview-DAuGvOiK.js} +1 -1
- package/dist/web/assets/{blade-Cf2q1sPf.js → blade-CDeeJWBb.js} +1 -1
- package/dist/web/assets/{bsl-W1kOaNpu.js → bsl-BfgoPVYR.js} +1 -1
- package/dist/web/assets/{button-5zTrkEoN.js → button-tNy0ba3y.js} +1 -1
- package/dist/web/assets/{cairo-BoAZFcje.js → cairo-C26gNwWW.js} +1 -1
- package/dist/web/assets/chat-tab-IcnU3nqQ.js +15 -0
- package/dist/web/assets/{cobol-B0Nm7RXj.js → cobol-D92nBnON.js} +1 -1
- package/dist/web/assets/code-editor-Dno5Srkm.js +10 -0
- package/dist/web/assets/{coffee-BakMn3on.js → coffee-CIWH40R1.js} +1 -1
- package/dist/web/assets/{conflict-editor-BUs5k9q_.js → conflict-editor-CDp0I3mD.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-DOrBqXCn.js} +1 -1
- package/dist/web/assets/{crystal-kqqO3zkK.js → crystal-BNKqmHux.js} +1 -1
- package/dist/web/assets/{csv-preview-ByoDgLAZ.js → csv-preview-D4svNDAq.js} +1 -1
- package/dist/web/assets/{data-grid-overlay-editor-Brkf9z41.js → data-grid-overlay-editor-BqV0AxZg.js} +1 -1
- package/dist/web/assets/{database-viewer-Btc3h8Yu.js → database-viewer-BCvv_Bwf.js} +1 -1
- package/dist/web/assets/{dialog-DwtGlowE.js → dialog-DcLGDwaX.js} +1 -1
- package/dist/web/assets/diff-viewer-D41fCFAi.js +4 -0
- package/dist/web/assets/{docx-preview-DAD_vg59.js → docx-preview-DfaQn9v7.js} +1 -1
- package/dist/web/assets/{edge-Cq1ZKZuE.js → edge-Dbjp42Pt.js} +1 -1
- package/dist/web/assets/{edit-diff-preview-B_VE7ppQ.js → edit-diff-preview-BqcUuFCc.js} +1 -1
- package/dist/web/assets/{elixir-BM_JoJRk.js → elixir-na3b1pYy.js} +1 -1
- package/dist/web/assets/{elm-Dw7oO08Y.js → elm-_Nalil1R.js} +1 -1
- package/dist/web/assets/{erb-CfKOGAfk.js → erb-CW_7dubf.js} +1 -1
- package/dist/web/assets/{erlang-DlDmGVeE.js → erlang-DmZ7Zzb0.js} +1 -1
- package/dist/web/assets/{esm-DGAP0GFh.js → esm-CwyBetO1.js} +1 -1
- package/dist/web/assets/explorer-body-DB1L30pa.js +2 -0
- package/dist/web/assets/explorer-window-content-Cwlt3C3I.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-BW_mccb3.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-DB2A8L4-.js} +1 -1
- package/dist/web/assets/{fsharp-CdNvy0PG.js → fsharp-BYHrti7z.js} +1 -1
- package/dist/web/assets/{gdresource-DxuG5i8i.js → gdresource-D5GBin40.js} +1 -1
- package/dist/web/assets/{git-commit-3lMonsur.js → git-commit-CUiOBoIL.js} +1 -1
- package/dist/web/assets/{git-log-panel-Co0PBPHC.js → git-log-panel-C1QDkmgl.js} +1 -1
- package/dist/web/assets/{git-rebase-N8Z9kIMf.js → git-rebase-DOxGnpdw.js} +1 -1
- package/dist/web/assets/gitGraph-HDMCJU4V-C1xf87gN.js +1 -0
- package/dist/web/assets/glide-data-grid-Dz8lx6n2.js +138 -0
- package/dist/web/assets/{glimmer-js-Dp9OXiib.js → glimmer-js-Begy4UT7.js} +1 -1
- package/dist/web/assets/{glimmer-ts-CDVKBcDj.js → glimmer-ts-rPApRY8N.js} +1 -1
- package/dist/web/assets/{glsl-DPJxI4us.js → glsl-wrbPvrBL.js} +1 -1
- package/dist/web/assets/{graphql-BrFhaQQl.js → graphql-Cu4-NR__.js} +1 -1
- package/dist/web/assets/group-chat-tab-DFwr-pig.js +1 -0
- package/dist/web/assets/{hack-BzXbDMlA.js → hack-Ddo93XKD.js} +1 -1
- package/dist/web/assets/{haml-CPpkX0s5.js → haml-BFX_1i8j.js} +1 -1
- package/dist/web/assets/{handlebars-BqrApy52.js → handlebars-5gFKA4H5.js} +1 -1
- package/dist/web/assets/{html-DmjUl-OA.js → html-C06I-zeO.js} +1 -1
- package/dist/web/assets/{html-derivative-Cnd6XFR5.js → html-derivative-e5JLAFZF.js} +1 -1
- package/dist/web/assets/{http-DMLWYun2.js → http-CrAAhSU7.js} +1 -1
- package/dist/web/assets/{hurl-CKkCVxbj.js → hurl-T1V3SX9T.js} +1 -1
- package/dist/web/assets/{hxml-CAx19TtQ.js → hxml-B056LLKN.js} +1 -1
- package/dist/web/assets/{image-preview-DHUoylQ1.js → image-preview-DWyuCYT3.js} +1 -1
- package/dist/web/assets/index-DWpNR3nB.css +2 -0
- package/dist/web/assets/index-oUKV5nIA.js +52 -0
- package/dist/web/assets/info-3K5VOQVL-C2z7FTDe.js +1 -0
- package/dist/web/assets/{input-DcEk7mA3.js → input-DouJ9Zvt.js} +1 -1
- package/dist/web/assets/{jinja-BmB9YN9l.js → jinja-DGdtRh43.js} +1 -1
- package/dist/web/assets/{jison-BaVsKKpw.js → jison-Ah6QobPS.js} +1 -1
- package/dist/web/assets/{julia-BgVBLveX.js → julia-BJeGOK0K.js} +1 -1
- package/dist/web/assets/{just-C2ENIbl9.js → just-iw9oRs7j.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-DHjj5hyN.js} +1 -1
- package/dist/web/assets/{liquid-NxpapreE.js → liquid-B-FFecDc.js} +1 -1
- package/dist/web/assets/{lua-DVepQvwH.js → lua-DDianJp_.js} +1 -1
- package/dist/web/assets/{markdown-renderer-DlcDhgrF.js → markdown-renderer-BHiUhQN8.js} +3 -3
- package/dist/web/assets/markdown-renderer-CnE36_gd.js +1 -0
- package/dist/web/assets/{marko-CJ2606Xl.js → marko-BW5SBVng.js} +1 -1
- package/dist/web/assets/{mdc-D2bjqclE.js → mdc-B9gL9bjl.js} +1 -1
- package/dist/web/assets/{media-url-H17XJF-I.js → media-url-DUK-k0bB.js} +1 -1
- package/dist/web/assets/{mobile-bottom-sheet-g-r2hCFa.js → mobile-bottom-sheet-CJ7ApOkI.js} +1 -1
- package/dist/web/assets/mobile-explorer-sheet-BzjlS1Xn.js +1 -0
- package/dist/web/assets/{nextflow-BtJwUbfF.js → nextflow-dTluY6qy.js} +1 -1
- package/dist/web/assets/{nginx-j4gyIhHE.js → nginx-DlwghGI-.js} +1 -1
- package/dist/web/assets/{nim-ClH_gjP5.js → nim-N9jddb5D.js} +1 -1
- package/dist/web/assets/notification-store-C7UBqxYP.js +1 -0
- package/dist/web/assets/{number-overlay-editor-C1EqJnWq.js → number-overlay-editor-BVXM7aAs.js} +1 -1
- package/dist/web/assets/{overview-panel-vTeeJYVZ.js → overview-panel-DCCDmtCQ.js} +1 -1
- package/dist/web/assets/packet-RMMSAZCW-DQUxN0wU.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-D7yLmAZW.js} +1 -1
- package/dist/web/assets/{perl-C9H7X7CT.js → perl-CkmpYKa_.js} +1 -1
- package/dist/web/assets/{php-Bx2U-cQ_.js → php-BwZ3KDPo.js} +1 -1
- package/dist/web/assets/pie-UPGHQEXC-BOr9ek4Q.js +1 -0
- package/dist/web/assets/{postgres-viewer-DHwcQucn.js → postgres-viewer--CRN1fvO.js} +3 -3
- package/dist/web/assets/{process-table-BGRJNlpn.js → process-table-CXC10GSy.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-B3rBPqQo.js} +1 -1
- package/dist/web/assets/{qml-BXD94Eqz.js → qml-BfDbWFmg.js} +1 -1
- package/dist/web/assets/radar-KQ55EAFF-DSErxZFb.js +1 -0
- package/dist/web/assets/{razor-DZ0-Ge0S.js → razor-B1ww1r38.js} +1 -1
- package/dist/web/assets/{rst-Dtdh0QUj.js → rst-C0MSq6m-.js} +1 -1
- package/dist/web/assets/{ruby-BC51BW2Q.js → ruby-ClIZ1wb3.js} +1 -1
- package/dist/web/assets/{run-in-terminal-Sd3KyjN4.js → run-in-terminal-4efbW2Xv.js} +1 -1
- package/dist/web/assets/{sas-BN8i4qOU.js → sas-DR0j3o4_.js} +1 -1
- package/dist/web/assets/{scroll-area-0gljZ6lF.js → scroll-area-ZP8wcwTI.js} +1 -1
- package/dist/web/assets/{scss-H-QtA7Rz.js → scss-Vh3JLayR.js} +1 -1
- package/dist/web/assets/{send-to-chat-u6m8l-rH.js → send-to-chat-BNrEpAyC.js} +1 -1
- package/dist/web/assets/{settings-store-CHY6Kzin.js → settings-store-OLJE7dPH.js} +2 -2
- package/dist/web/assets/{settings-tab-IY6K1MiZ.js → settings-tab-B1rvHFc6.js} +1 -1
- package/dist/web/assets/settings-tab-BUlmPJ2w.js +1 -0
- package/dist/web/assets/{shaderlab-CalNsj_x.js → shaderlab-0rHRnQ18.js} +1 -1
- package/dist/web/assets/{shellsession-BFrcoR8x.js → shellsession-Dxdw6D8c.js} +1 -1
- package/dist/web/assets/{soy-CNbku7vP.js → soy-BHlSNj1y.js} +1 -1
- package/dist/web/assets/{sparql-BN_orcVp.js → sparql-B2QaPpni.js} +1 -1
- package/dist/web/assets/{sql-query-editor-C6pC3I8l.js → sql-query-editor-R_iKjPP9.js} +1 -1
- package/dist/web/assets/{sqlite-viewer-DTr5PzUb.js → sqlite-viewer-b2onA0SP.js} +1 -1
- package/dist/web/assets/{stata-C6a5Ijzq.js → stata-CwIxjsEJ.js} +1 -1
- package/dist/web/assets/{surrealql-ClplI_HY.js → surrealql-C6vo-rp-.js} +1 -1
- package/dist/web/assets/{svelte-DNm-UNXB.js → svelte-LLdJ6rlH.js} +1 -1
- package/dist/web/assets/{switch-DKvKya9y.js → switch-DV-BDjyk.js} +1 -1
- package/dist/web/assets/system-monitor-body-DPYQlBEt.js +2 -0
- package/dist/web/assets/system-monitor-tab-CPQdWv27.js +1 -0
- package/dist/web/assets/{system-monitor-window-content-BUqRsPK2.js → system-monitor-window-content-BPif0azo.js} +1 -1
- package/dist/web/assets/tab-host-window-content-BnAN6m4K.js +1 -0
- package/dist/web/assets/{tab-store-CJuJRapl.js → tab-store-tFnyPmm4.js} +1 -1
- package/dist/web/assets/team-member-sheet-Bu2wG1sm.js +2 -0
- package/dist/web/assets/{team-member-window-content-T4Q5JI-G.js → team-member-window-content-BSyU-5Uc.js} +1 -1
- package/dist/web/assets/{templ-CSdqVobu.js → templ-CJGvhEP5.js} +1 -1
- package/dist/web/assets/{terminal-tab-Bb2rZegQ.js → terminal-tab-Ncor0Rfu.js} +3 -3
- package/dist/web/assets/{tex-DzSJ4kcZ.js → tex-psXWhc4t.js} +1 -1
- package/dist/web/assets/{tool-cards-lhqhrDTT.js → tool-cards-DdVP1wrD.js} +4 -4
- package/dist/web/assets/treemap-KZPCXAKY-C17p0LQw.js +1 -0
- package/dist/web/assets/{ts-tags-C28w3bTg.js → ts-tags-D5Ar_ZCO.js} +1 -1
- package/dist/web/assets/{twig-i5jY3QXB.js → twig-vJgGC-qY.js} +1 -1
- package/dist/web/assets/{use-blob-url-Dsq9OjTh.js → use-blob-url-BOVGWg9F.js} +1 -1
- package/dist/web/assets/use-coarse-long-press-BmI_GVW5.js +1 -0
- package/dist/web/assets/use-monaco-theme-BshnLXoY.js +1 -0
- package/dist/web/assets/{use-open-team-member-DkiEjFYE.js → use-open-team-member-CY3wOdWL.js} +1 -1
- package/dist/web/assets/{use-websocket-B8R50f7f.js → use-websocket-B7xjNsyD.js} +1 -1
- package/dist/web/assets/{vendor-mermaid-By4AVvJY.js → vendor-mermaid-999ksD45.js} +1 -1
- package/dist/web/assets/video-preview-7F72sRwf.js +1 -0
- package/dist/web/assets/{vue-Ceyet_lv.js → vue-BWngFyav.js} +1 -1
- package/dist/web/assets/{vue-html-GuU7g_hg.js → vue-html-BN5ZLu-H.js} +1 -1
- package/dist/web/assets/{vue-vine-CxXoaJr2.js → vue-vine-BZHnO8yV.js} +1 -1
- package/dist/web/assets/window-pip-registry-BnYU83LE.js +1 -0
- package/dist/web/assets/{window-store-CsEW6jiE.js → window-store-CQ1lghvv.js} +1 -1
- package/dist/web/assets/{xml-CbqOVhkP.js → xml-DS2beZHp.js} +1 -1
- package/dist/web/assets/{xsl-KfAmCauy.js → xsl-Ciiku1Bq.js} +1 -1
- package/dist/web/index.html +47 -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 +399 -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 +4 -3
- 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/edge-forwarder.ts +191 -191
- 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/services/windows-process-tree.ts +351 -351
- 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/floating-window/floating-window.tsx +8 -1
- package/src/web/components/floating-window/open-tab-in-pip.ts +78 -0
- package/src/web/components/floating-window/window-pip-registry.ts +46 -0
- 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/layout/tab-pop-out-menu-item.tsx +25 -2
- 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/diff-viewer-CZaDnR4w.js +0 -4
- 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/group-chat-tab-rOd8J8GC.js +0 -1
- 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/tab-host-window-content-BnqGPu8a.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/use-monaco-theme-BZvlsoBv.js +0 -1
- package/dist/web/assets/video-preview-m0-3p7QZ.js +0 -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/dist/web/assets/{abap-C6nB04tn.js → abap-CjzrhAS2.js} +0 -0
- /package/dist/web/assets/{actionscript-3-Vx4rw2sC.js → actionscript-3-B59Kbl-9.js} +0 -0
- /package/dist/web/assets/{ada-Ccd8vM20.js → ada-B7gItKAE.js} +0 -0
- /package/dist/web/assets/{andromeeda-DnBX5xMg.js → andromeeda-Dy5zcy0Q.js} +0 -0
- /package/dist/web/assets/{apache-B-9_sx0g.js → apache-B6T9jrc0.js} +0 -0
- /package/dist/web/assets/{apex-_wPVBYoL.js → apex-CTsIxDQw.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-DuycKmmb.js} +0 -0
- /package/dist/web/assets/{apply-theme-BeLRfsSu.js → apply-theme-r8tKDrCR.js} +0 -0
- /package/dist/web/assets/{ara-C40Ztoms.js → ara-CISL3599.js} +0 -0
- /package/dist/web/assets/{asciidoc-CybYkJV4.js → asciidoc-BXyE2Lpr.js} +0 -0
- /package/dist/web/assets/{asm-9eOKwzR0.js → asm-y258phtP.js} +0 -0
- /package/dist/web/assets/{aurora-x-B5ZH4t7t.js → aurora-x-Dq3Jc78M.js} +0 -0
- /package/dist/web/assets/{awk-Dqilob-2.js → awk-DxL6XSJv.js} +0 -0
- /package/dist/web/assets/{ayu-dark-CPgRhf5r.js → ayu-dark-DjoK6Evo.js} +0 -0
- /package/dist/web/assets/{ayu-light-Do06Q52f.js → ayu-light-CKKXBLMI.js} +0 -0
- /package/dist/web/assets/{ayu-mirage-_BhxcrxY.js → ayu-mirage-DGXSrrXB.js} +0 -0
- /package/dist/web/assets/{ballerina-DDwK54QW.js → ballerina-DZSXFmUf.js} +0 -0
- /package/dist/web/assets/{bat-BGyGlzGk.js → bat-BNsZk6nY.js} +0 -0
- /package/dist/web/assets/{beancount-CRWBdapI.js → beancount-cPl4gJct.js} +0 -0
- /package/dist/web/assets/{berry-DbSFn2gO.js → berry-DGAodERk.js} +0 -0
- /package/dist/web/assets/{bibtex-QpsV9gm9.js → bibtex-DftVoRif.js} +0 -0
- /package/dist/web/assets/{bicep-CxS8CUve.js → bicep-Suioyyzh.js} +0 -0
- /package/dist/web/assets/{bird2-CuZhQzYR.js → bird2-DjU24I2P.js} +0 -0
- /package/dist/web/assets/{c-9bnDqE3g.js → c-DFi8Y_nN.js} +0 -0
- /package/dist/web/assets/{c3-JMZTrOhA.js → c3-1eSHnH5V.js} +0 -0
- /package/dist/web/assets/{cadence-DsDNayJS.js → cadence-DLLsFwQP.js} +0 -0
- /package/dist/web/assets/{can-open-in-ppm-BJfpynya.js → can-open-in-ppm-in727eFQ.js} +0 -0
- /package/dist/web/assets/{catppuccin-frappe-DYIKXXBe.js → catppuccin-frappe-DDj0JEiY.js} +0 -0
- /package/dist/web/assets/{catppuccin-latte-IYYOnUJ8.js → catppuccin-latte-DPyANHyR.js} +0 -0
- /package/dist/web/assets/{catppuccin-macchiato-BrJ_7mfS.js → catppuccin-macchiato-CO-h8VTT.js} +0 -0
- /package/dist/web/assets/{catppuccin-mocha-gzSu7v7-.js → catppuccin-mocha-BCmbN2IZ.js} +0 -0
- /package/dist/web/assets/{clarity-DLzsC0Hb.js → clarity-C0pYsZjs.js} +0 -0
- /package/dist/web/assets/{clipboard-7fw0Shic.js → clipboard-DBLGKMrH.js} +0 -0
- /package/dist/web/assets/{clojure-DS1BvoTt.js → clojure-JFr6s8iZ.js} +0 -0
- /package/dist/web/assets/{cmake-CDvsJwYp.js → cmake-EEcLEgVy.js} +0 -0
- /package/dist/web/assets/{codeowners-BjsYiflJ.js → codeowners-Deh3Lx0u.js} +0 -0
- /package/dist/web/assets/{codeql-CG-7ARat.js → codeql-C317igT5.js} +0 -0
- /package/dist/web/assets/{common-lisp-DSO1Lbh9.js → common-lisp-DepbATZs.js} +0 -0
- /package/dist/web/assets/{coq-DYdh3oP_.js → coq-MxgxU5ya.js} +0 -0
- /package/dist/web/assets/{csharp-DxEBz5s0.js → csharp-eEFXdsAq.js} +0 -0
- /package/dist/web/assets/{css-dal3Q-8C.js → css-Db-syWW9.js} +0 -0
- /package/dist/web/assets/{csv-CpqjMGiA.js → csv-DHeYcbaq.js} +0 -0
- /package/dist/web/assets/{csv-parser-3umBA4NY.js → csv-parser-_JWMLGl3.js} +0 -0
- /package/dist/web/assets/{cue-DinoJ_5k.js → cue-BmUNowrt.js} +0 -0
- /package/dist/web/assets/{cypher-DzxqmkUW.js → cypher-XjXHgCNS.js} +0 -0
- /package/dist/web/assets/{d-BxNwJuEC.js → d-BWJnZtig.js} +0 -0
- /package/dist/web/assets/{dark-plus-Clmv3V-0.js → dark-plus-Db7umas1.js} +0 -0
- /package/dist/web/assets/{dart-BWVtXD35.js → dart-DSI4HYh1.js} +0 -0
- /package/dist/web/assets/{data-grid-types-B4n51Fck.js → data-grid-types-CfVHh9gv.js} +0 -0
- /package/dist/web/assets/{dax-DsImuWgJ.js → dax-yw1JsAni.js} +0 -0
- /package/dist/web/assets/{desktop-B0jJuG2r.js → desktop-C2QO4RvD.js} +0 -0
- /package/dist/web/assets/{diff-CWqAAxoE.js → diff-Drt8aEyp.js} +0 -0
- /package/dist/web/assets/{dist-B-EXdSYE.js → dist-DNRvhVdz.js} +0 -0
- /package/dist/web/assets/{dist-C0eNNfbt.js → dist-VBxOHLmN.js} +0 -0
- /package/dist/web/assets/{docker-CYFCJdIL.js → docker-ByDKbmLl.js} +0 -0
- /package/dist/web/assets/{dotenv-CKDUjURg.js → dotenv-BkfOLytR.js} +0 -0
- /package/dist/web/assets/{dracula-CSoPspHE.js → dracula-DAmrm-Un.js} +0 -0
- /package/dist/web/assets/{dracula-soft-BuFjw5L1.js → dracula-soft-BUOEnKqR.js} +0 -0
- /package/dist/web/assets/{dream-maker-B6PdDRZu.js → dream-maker-DQBIfSiO.js} +0 -0
- /package/dist/web/assets/{emacs-lisp-CMcXvD0G.js → emacs-lisp-Blh5kBD3.js} +0 -0
- /package/dist/web/assets/{everforest-dark-cU8-wYzi.js → everforest-dark-CEzhDxHq.js} +0 -0
- /package/dist/web/assets/{everforest-light-KhorllqK.js → everforest-light-CPk_5Khm.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-B1MT_EBZ.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-C_HGcewt.js} +0 -0
- /package/dist/web/assets/{fluent-BTINnwF6.js → fluent-Dp1Iclmx.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-53WBtyi2.js} +0 -0
- /package/dist/web/assets/{fortran-free-form-BQim9wDz.js → fortran-free-form-B_-UA4XC.js} +0 -0
- /package/dist/web/assets/{gdscript-03w5u8un.js → gdscript-Bm_JpjS_.js} +0 -0
- /package/dist/web/assets/{gdshader-Dp2daNzU.js → gdshader-C_PNmfYU.js} +0 -0
- /package/dist/web/assets/{genie-CoNcjPiD.js → genie-B5rmR2TF.js} +0 -0
- /package/dist/web/assets/{gherkin-NrPOSPQL.js → gherkin-BTJ34TJ9.js} +0 -0
- /package/dist/web/assets/{github-dark-z4RE9ZqA.js → github-dark-DOkNVj9H.js} +0 -0
- /package/dist/web/assets/{github-dark-default-DOKw-1cI.js → github-dark-default-DTsmiyVo.js} +0 -0
- /package/dist/web/assets/{github-dark-dimmed-DJRNMkEA.js → github-dark-dimmed-CjbxAe9s.js} +0 -0
- /package/dist/web/assets/{github-dark-high-contrast-Bj7jJ_Gs.js → github-dark-high-contrast-r_M8F_k7.js} +0 -0
- /package/dist/web/assets/{github-light-B4k_yMFu.js → github-light-BzfxyMyb.js} +0 -0
- /package/dist/web/assets/{github-light-default-BHc-Uzhs.js → github-light-default-BOqiBIy5.js} +0 -0
- /package/dist/web/assets/{github-light-high-contrast-CHisIywL.js → github-light-high-contrast-DQzBrDM4.js} +0 -0
- /package/dist/web/assets/{gleam-CfbypZ4q.js → gleam-BWmuAtD8.js} +0 -0
- /package/dist/web/assets/{gn-YoAjyhJa.js → gn-CNQPjiZW.js} +0 -0
- /package/dist/web/assets/{gnuplot-xVkc1f1c.js → gnuplot-BlHjcPMe.js} +0 -0
- /package/dist/web/assets/{go-GPCwP3Gu.js → go-Bn8Ba9uz.js} +0 -0
- /package/dist/web/assets/{groovy-Crh4Yww9.js → groovy-C1Y1_F4V.js} +0 -0
- /package/dist/web/assets/{gruvbox-dark-hard-BluUFuDS.js → gruvbox-dark-hard-DueOsHav.js} +0 -0
- /package/dist/web/assets/{gruvbox-dark-medium-Cxk1FWQp.js → gruvbox-dark-medium-DaQjD538.js} +0 -0
- /package/dist/web/assets/{gruvbox-dark-soft-CHXMiFmj.js → gruvbox-dark-soft-CbbX2WOm.js} +0 -0
- /package/dist/web/assets/{gruvbox-light-hard-B6eKPjAD.js → gruvbox-light-hard-E2M70ljZ.js} +0 -0
- /package/dist/web/assets/{gruvbox-light-medium-pDwMm1ut.js → gruvbox-light-medium-B_DDLY6h.js} +0 -0
- /package/dist/web/assets/{gruvbox-light-soft-Cxu6kHqK.js → gruvbox-light-soft-2SZmyC1F.js} +0 -0
- /package/dist/web/assets/{haskell-C6JKHjbK.js → haskell-D8DeoXtG.js} +0 -0
- /package/dist/web/assets/{haxe-BuBNdF0a.js → haxe-BmZm7B0W.js} +0 -0
- /package/dist/web/assets/{hcl-DZpDdGj2.js → hcl-CKnBM3ng.js} +0 -0
- /package/dist/web/assets/{hjson-CBkhYRuo.js → hjson-Ct9t4-ci.js} +0 -0
- /package/dist/web/assets/{hlsl-C5nMxnp9.js → hlsl-BZSASBqS.js} +0 -0
- /package/dist/web/assets/{horizon-VAFvA6R6.js → horizon-CzX1AZ08.js} +0 -0
- /package/dist/web/assets/{horizon-bright-BC0xn7T3.js → horizon-bright-CCVNeRIP.js} +0 -0
- /package/dist/web/assets/{houston-BxrUivmz.js → houston-DBlJN7xc.js} +0 -0
- /package/dist/web/assets/{hy-DLtOXoaH.js → hy-Dyc6h6Xb.js} +0 -0
- /package/dist/web/assets/{image-gallery-Gnf7TdCR.js → image-gallery-DujlrjOC.js} +0 -0
- /package/dist/web/assets/{imba-BdpFXM2W.js → imba-Bauru7s2.js} +0 -0
- /package/dist/web/assets/{ini-BInJO_T0.js → ini-SjdwtaTp.js} +0 -0
- /package/dist/web/assets/{java-Dxuddnkb.js → java-D2r0ocpf.js} +0 -0
- /package/dist/web/assets/{javascript-CVamJfLY.js → javascript-y-lof7iP.js} +0 -0
- /package/dist/web/assets/{json-BLZ0ozYk.js → json-DO4LSx5A.js} +0 -0
- /package/dist/web/assets/{json5-BnXzmMKs.js → json5-BEwWf-W3.js} +0 -0
- /package/dist/web/assets/{jsonc-CSgkSga7.js → jsonc-OBEFv7gP.js} +0 -0
- /package/dist/web/assets/{jsonl-CY5W2nF2.js → jsonl-DOyW4Mg3.js} +0 -0
- /package/dist/web/assets/{jsonnet-CEJYH3sF.js → jsonnet-BL5R2CpP.js} +0 -0
- /package/dist/web/assets/{jssm-CsJc7Uhk.js → jssm-ksPusAyg.js} +0 -0
- /package/dist/web/assets/{jsx-jCiRaHU7.js → jsx-B6XEu6O-.js} +0 -0
- /package/dist/web/assets/{kanagawa-dragon-DfoA_GxX.js → kanagawa-dragon-JBVe_ji_.js} +0 -0
- /package/dist/web/assets/{kanagawa-lotus-BOLYJpWd.js → kanagawa-lotus-ChprO68_.js} +0 -0
- /package/dist/web/assets/{kanagawa-wave-DfKlbT1G.js → kanagawa-wave-D_uB_R0Q.js} +0 -0
- /package/dist/web/assets/{kdl-CmssIFTi.js → kdl-pf5B8N_m.js} +0 -0
- /package/dist/web/assets/{kotlin-BRsNgp6x.js → kotlin-BdF0METC.js} +0 -0
- /package/dist/web/assets/{kusto-T8X9jUab.js → kusto-BneVP-OU.js} +0 -0
- /package/dist/web/assets/{laserwave-DkJMVJ8Z.js → laserwave-C4-UPIyG.js} +0 -0
- /package/dist/web/assets/{lean-C65KGVPq.js → lean-BN6Jdymq.js} +0 -0
- /package/dist/web/assets/{less-exIPdDlf.js → less-Cx-fdlDC.js} +0 -0
- /package/dist/web/assets/{lib-mC1NZfuw.js → lib-CMuBa85c.js} +0 -0
- /package/dist/web/assets/{libesm-DSutUtl1.js → libesm-BB74PRsH.js} +0 -0
- /package/dist/web/assets/{light-plus-DiHUXAZt.js → light-plus-DFnnn_iL.js} +0 -0
- /package/dist/web/assets/{llvm-CJBnEzFM.js → llvm-BGxtW0Nw.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-kQb4eJnj.js} +0 -0
- /package/dist/web/assets/{logo-CC9NKzca.js → logo-DqAzaq7s.js} +0 -0
- /package/dist/web/assets/{luau-Bw10I6zf.js → luau-Dc2cp-zS.js} +0 -0
- /package/dist/web/assets/{make-C_6M90m6.js → make-DYg9dwaJ.js} +0 -0
- /package/dist/web/assets/{markdown-bR9_R-LF.js → markdown-O4EPpS3K.js} +0 -0
- /package/dist/web/assets/{material-theme-BUx2Qujn.js → material-theme-ClP8yfQ2.js} +0 -0
- /package/dist/web/assets/{material-theme-darker-CRJrPgKm.js → material-theme-darker-LOK55hGu.js} +0 -0
- /package/dist/web/assets/{material-theme-lighter-CUAYppPa.js → material-theme-lighter-j72tzZqi.js} +0 -0
- /package/dist/web/assets/{material-theme-ocean-DuINF1fg.js → material-theme-ocean-C19LKClA.js} +0 -0
- /package/dist/web/assets/{material-theme-palenight-W6_icGCj.js → material-theme-palenight-DJ5tN2ax.js} +0 -0
- /package/dist/web/assets/{matlab-rfqn_b3z.js → matlab-DQNZ_NU8.js} +0 -0
- /package/dist/web/assets/{mdx-Bh1B_YOJ.js → mdx-CJayB7XK.js} +0 -0
- /package/dist/web/assets/{mermaid-Dxf6Ya2k.js → mermaid-Cb0TRX92.js} +0 -0
- /package/dist/web/assets/{min-dark-CivZ2L0h.js → min-dark-CWM8Bo-m.js} +0 -0
- /package/dist/web/assets/{min-light-B1Ykqtma.js → min-light-BBR1sjS2.js} +0 -0
- /package/dist/web/assets/{mipsasm-DynHaM0d.js → mipsasm-Jc7u7YSS.js} +0 -0
- /package/dist/web/assets/{mojo-Clw5PbGH.js → mojo-CTB0cutd.js} +0 -0
- /package/dist/web/assets/{monitor-Dv8vn_6O.js → monitor-4vWfqzuN.js} +0 -0
- /package/dist/web/assets/{monokai-DFIooFZT.js → monokai-CvM_YNKx.js} +0 -0
- /package/dist/web/assets/{moonbit-DnBSZWGM.js → moonbit-CbFEfYYM.js} +0 -0
- /package/dist/web/assets/{move-CCcL2PfL.js → move-BT38p0kT.js} +0 -0
- /package/dist/web/assets/{narrat-BDarg5Lk.js → narrat-55QZ_kOG.js} +0 -0
- /package/dist/web/assets/{nextflow-groovy-DrZOeCNW.js → nextflow-groovy-Bg8peyqg.js} +0 -0
- /package/dist/web/assets/{night-owl-BnZZCK7v.js → night-owl-DzS77iPK.js} +0 -0
- /package/dist/web/assets/{night-owl-light-CEwBsVHS.js → night-owl-light-DER7fGnx.js} +0 -0
- /package/dist/web/assets/{nix-amCzOPMR.js → nix-BSI8YesN.js} +0 -0
- /package/dist/web/assets/{nord-BIs2BC6q.js → nord-9bn7iNWo.js} +0 -0
- /package/dist/web/assets/{nushell-Y02fo4yw.js → nushell-qDVZn_lw.js} +0 -0
- /package/dist/web/assets/{objective-c-7xOZtWW1.js → objective-c-Blf-ATos.js} +0 -0
- /package/dist/web/assets/{objective-cpp-eVtjUvVB.js → objective-cpp-Bz8bAq47.js} +0 -0
- /package/dist/web/assets/{ocaml-Bi6ZwqG4.js → ocaml-B9heAsc3.js} +0 -0
- /package/dist/web/assets/{odin-8xf1Y0S9.js → odin-BaFYnOwO.js} +0 -0
- /package/dist/web/assets/{one-dark-pro-hVv-_y_b.js → one-dark-pro-D6B_hSe-.js} +0 -0
- /package/dist/web/assets/{one-light-CJJ3MtHt.js → one-light-Ba-f0wyk.js} +0 -0
- /package/dist/web/assets/{openscad-B2HcywLk.js → openscad-UvYyL2MK.js} +0 -0
- /package/dist/web/assets/{pascal-C7fllV_7.js → pascal-B4-qvEoG.js} +0 -0
- /package/dist/web/assets/{pkl-qvLC1IWP.js → pkl-B146nqGx.js} +0 -0
- /package/dist/web/assets/{plastic-BT1wHZv2.js → plastic-L38t-Id3.js} +0 -0
- /package/dist/web/assets/{play-4MZi1Axp.js → play-CpCAoQRZ.js} +0 -0
- /package/dist/web/assets/{plsql-1MsmdmJD.js → plsql-ItOG5Cca.js} +0 -0
- /package/dist/web/assets/{plus-BhMZqFsN.js → plus-BR0qewJI.js} +0 -0
- /package/dist/web/assets/{po-BigskytD.js → po-imiCTaNX.js} +0 -0
- /package/dist/web/assets/{poimandres-DuklniF7.js → poimandres-Bu6sIba9.js} +0 -0
- /package/dist/web/assets/{polar-e2pjN_sp.js → polar-CTeGoFxV.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-jvFe6GNE.js} +0 -0
- /package/dist/web/assets/{powerquery-Cr2PtehI.js → powerquery-D9Dw1hJp.js} +0 -0
- /package/dist/web/assets/{powershell-BxFTGLJ4.js → powershell-CZqvYQtg.js} +0 -0
- /package/dist/web/assets/{prisma-COWJiwdZ.js → prisma-B4D2nO_7.js} +0 -0
- /package/dist/web/assets/{prolog-DFvGKRx6.js → prolog-CQbyUcCF.js} +0 -0
- /package/dist/web/assets/{proto-CcK80lFt.js → proto-Cwpo0cW1.js} +0 -0
- /package/dist/web/assets/{puppet-BF60bZ4F.js → puppet-CKxCwBod.js} +0 -0
- /package/dist/web/assets/{purescript-zL_69MzU.js → purescript-B-MyXMMp.js} +0 -0
- /package/dist/web/assets/{python-CIwKhfb_.js → python-D6QbSR2S.js} +0 -0
- /package/dist/web/assets/{qmldir-CXNe04Lo.js → qmldir-BpTSVcw_.js} +0 -0
- /package/dist/web/assets/{qss-C8lAWe6G.js → qss-DBc4gbpe.js} +0 -0
- /package/dist/web/assets/{r-CL5ZVL3_.js → r-i9jMMi0s.js} +0 -0
- /package/dist/web/assets/{racket-BBfh0uh0.js → racket-BWNaxU7C.js} +0 -0
- /package/dist/web/assets/{raku-o6E8R5Q3.js → raku-fqTZLn7L.js} +0 -0
- /package/dist/web/assets/{react-CBTnT4sY.js → react-X4jUntEf.js} +0 -0
- /package/dist/web/assets/{red-GomRF2Xp.js → red-D-JEcuzA.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-BbirlU1S.js} +0 -0
- /package/dist/web/assets/{regexp-Bl5sF65W.js → regexp-D8VTFrtg.js} +0 -0
- /package/dist/web/assets/{rel-DgMdqDuj.js → rel-ByQGKiNM.js} +0 -0
- /package/dist/web/assets/{resolve-theme-CRt_7wpd.js → resolve-theme-Cqb9zWYc.js} +0 -0
- /package/dist/web/assets/{riscv-8b3-Ye4X.js → riscv-B5nqCfLE.js} +0 -0
- /package/dist/web/assets/{ron-DrmU1KHP.js → ron-DOVh_iZR.js} +0 -0
- /package/dist/web/assets/{rose-pine-dawn-DEfhNlFH.js → rose-pine-dawn-B7hkmmWy.js} +0 -0
- /package/dist/web/assets/{rose-pine-C_-E2tF1.js → rose-pine-jp51ZUzi.js} +0 -0
- /package/dist/web/assets/{rose-pine-moon-BdvX3gdn.js → rose-pine-moon-Ff063yLj.js} +0 -0
- /package/dist/web/assets/{rosmsg-B6GhGpd5.js → rosmsg-Cyk7Il8z.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-DRNM5epF.js} +0 -0
- /package/dist/web/assets/{sass-B0tJOHLM.js → sass-D_cB0-M1.js} +0 -0
- /package/dist/web/assets/{save-CtIGOjmx.js → save-DxonD4y1.js} +0 -0
- /package/dist/web/assets/{scala-n8zaFOXv.js → scala-Crl-1kKS.js} +0 -0
- /package/dist/web/assets/{scheme-BKD9ztBU.js → scheme-DCaWyEJ0.js} +0 -0
- /package/dist/web/assets/{sdbl-D8gB5-rS.js → sdbl-BbXNqwtX.js} +0 -0
- /package/dist/web/assets/{send-BlyNJAzy.js → send-B-t5Mz26.js} +0 -0
- /package/dist/web/assets/{shallow-DYo6goJ4.js → shallow-4zAfs2KW.js} +0 -0
- /package/dist/web/assets/{shellscript-BfXlf_Ao.js → shellscript-BAgksBhW.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-GB-ElUW_.js} +0 -0
- /package/dist/web/assets/{slack-ochin-w8wg8vuC.js → slack-ochin-tU6CFD3S.js} +0 -0
- /package/dist/web/assets/{smalltalk-hiAXA64u.js → smalltalk-DSVGUbtL.js} +0 -0
- /package/dist/web/assets/{snazzy-light-BwlV3Xty.js → snazzy-light-DZhi3PoS.js} +0 -0
- /package/dist/web/assets/{solarized-dark-vmNGdykz.js → solarized-dark-D6AMCco7.js} +0 -0
- /package/dist/web/assets/{solarized-light-DGv_0JXq.js → solarized-light-DepuTWSE.js} +0 -0
- /package/dist/web/assets/{solidity-Y7QSH0B1.js → solidity-CsxN618l.js} +0 -0
- /package/dist/web/assets/{splunk-BtgpLjHi.js → splunk-CF1m0Kkv.js} +0 -0
- /package/dist/web/assets/{sql-CRHYhOia.js → sql-DvyMDgrB.js} +0 -0
- /package/dist/web/assets/{ssh-config-DOqSs3au.js → ssh-config-a8sDo-Q8.js} +0 -0
- /package/dist/web/assets/{stylus-crCAEaBT.js → stylus-DCJ-6AjT.js} +0 -0
- /package/dist/web/assets/{swift-eE3rT7TC.js → swift-c-ZFxyPP.js} +0 -0
- /package/dist/web/assets/{synthwave-84-BWy14LBX.js → synthwave-84-9NPgBcuv.js} +0 -0
- /package/dist/web/assets/{system-verilog-DC0-DZM4.js → system-verilog-DPD02IOo.js} +0 -0
- /package/dist/web/assets/{systemd-to5p6N8I.js → systemd-BUr5HRtU.js} +0 -0
- /package/dist/web/assets/{table-Bbc783ko.js → table-FLU8ei8b.js} +0 -0
- /package/dist/web/assets/{talonscript-DoTcU8wm.js → talonscript-BNBQV5YJ.js} +0 -0
- /package/dist/web/assets/{tasl-cNZvUs95.js → tasl-BETjpSyu.js} +0 -0
- /package/dist/web/assets/{tcl-mZE8sZH8.js → tcl-Clp_AZiC.js} +0 -0
- /package/dist/web/assets/{terraform-CqHPpIfu.js → terraform-B0kZ0lim.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-oOJ0a7Dk.js} +0 -0
- /package/dist/web/assets/{toml-CU_vscgn.js → toml-DOPCSumy.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-D6qUGf84.js} +0 -0
- /package/dist/web/assets/{tsx-BMvvMKiv.js → tsx-B6qYhT6O.js} +0 -0
- /package/dist/web/assets/{turtle-DBqKCq9o.js → turtle-C0Rjzw73.js} +0 -0
- /package/dist/web/assets/{typescript-DXJDmMZZ.js → typescript-BiydShEu.js} +0 -0
- /package/dist/web/assets/{typespec-CBseCMtZ.js → typespec-DjmF6Aww.js} +0 -0
- /package/dist/web/assets/{typst-4oY25U9y.js → typst-CPuscfcL.js} +0 -0
- /package/dist/web/assets/{use-is-mobile-D1weanbj.js → use-is-mobile-b94q8RvF.js} +0 -0
- /package/dist/web/assets/{utils-BNRH507E.js → utils-C9OjCrou.js} +0 -0
- /package/dist/web/assets/{v-BXaZ_1oy.js → v-DE4vpLLQ.js} +0 -0
- /package/dist/web/assets/{vala-BImWJE7z.js → vala-CmUF2pS5.js} +0 -0
- /package/dist/web/assets/{vb-CLfj2_sy.js → vb-BvcRoX4b.js} +0 -0
- /package/dist/web/assets/{vendor-xterm-_yyu5n32.js → vendor-xterm-K8kpLxdb.js} +0 -0
- /package/dist/web/assets/{verilog-BWa8Ed2b.js → verilog-BGIzyH3R.js} +0 -0
- /package/dist/web/assets/{vesper-BGj1cg6m.js → vesper-CG7IrHQQ.js} +0 -0
- /package/dist/web/assets/{vhdl-mByK7mlx.js → vhdl-DMSumomw.js} +0 -0
- /package/dist/web/assets/{viml-CugmlW5g.js → viml-Drt7AEmU.js} +0 -0
- /package/dist/web/assets/{vitesse-black-vPdpy9TL.js → vitesse-black-DmsjfN0b.js} +0 -0
- /package/dist/web/assets/{vitesse-dark-BuQK3dUh.js → vitesse-dark-Dl55_WeJ.js} +0 -0
- /package/dist/web/assets/{vitesse-light-B3nz1XL9.js → vitesse-light-Crbv9aGg.js} +0 -0
- /package/dist/web/assets/{vyper-DH_GTIHG.js → vyper-CB7psEJj.js} +0 -0
- /package/dist/web/assets/{wasm-DfVbVJlW.js → wasm-BY1tuM5m.js} +0 -0
- /package/dist/web/assets/{wasm-C-LF9GjX.js → wasm-Dck8KPgP.js} +0 -0
- /package/dist/web/assets/{wenyan-CzQkHyHx.js → wenyan-DhewQ68b.js} +0 -0
- /package/dist/web/assets/{wgsl-Du_M1DW9.js → wgsl-DlmiP456.js} +0 -0
- /package/dist/web/assets/{wikitext-BWN_w5S7.js → wikitext-cQCnqNgE.js} +0 -0
- /package/dist/web/assets/{wit-BR13v5HD.js → wit-S5MaCngB.js} +0 -0
- /package/dist/web/assets/{wolfram-BoXxp_Xl.js → wolfram-Bh8n_9zr.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-BoK_17l9.js} +0 -0
- /package/dist/web/assets/{zenscript-C-EdUtUd.js → zenscript-DB3ZFwNJ.js} +0 -0
- /package/dist/web/assets/{zig-BD4eA5nU.js → zig-Bv1BWmfT.js} +0 -0
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
|
}
|
|
@@ -19,6 +19,7 @@ import { PortalContainerProvider } from "@/components/ui/portal-container-contex
|
|
|
19
19
|
import { TITLEBAR_HEIGHT } from "./window-chrome-contract";
|
|
20
20
|
import { useWindowBodyElement } from "./use-window-body-element";
|
|
21
21
|
import { WindowPipPlaceholder } from "./window-pip-placeholder";
|
|
22
|
+
import { isPipOnlyWindow } from "./window-pip-registry";
|
|
22
23
|
import { WindowSkinChrome } from "./window-skin-chrome";
|
|
23
24
|
import { windowZIndex, type Bounds, type Rect } from "./window-geometry";
|
|
24
25
|
import { useWindowStore, type WindowRuntimeState } from "./window-store";
|
|
@@ -120,6 +121,8 @@ export function FloatingWindow({
|
|
|
120
121
|
movable: !maximized,
|
|
121
122
|
});
|
|
122
123
|
|
|
124
|
+
const hiddenHost = Boolean(pip) && isPipOnlyWindow(win.id);
|
|
125
|
+
|
|
123
126
|
return (
|
|
124
127
|
<div
|
|
125
128
|
ref={rootRef}
|
|
@@ -135,6 +138,10 @@ export function FloatingWindow({
|
|
|
135
138
|
focused ? "shadow-2xl shadow-black/40" : "shadow-lg shadow-black/20",
|
|
136
139
|
// Transitions are for maximize/restore only; during a gesture they would lag the pointer.
|
|
137
140
|
gesturing ? "transition-none" : "transition-[transform,width,height] duration-150 motion-reduce:transition-none",
|
|
141
|
+
// A window opened only to carry a tab into PiP is never shown: the user asked for a
|
|
142
|
+
// PiP, not a window. `hidden` and not an unmount — the body must stay connected, or
|
|
143
|
+
// the PiP host has nowhere to put the tab back.
|
|
144
|
+
hiddenHost && "hidden",
|
|
138
145
|
)}
|
|
139
146
|
>
|
|
140
147
|
<WindowSkinChrome
|
|
@@ -158,7 +165,7 @@ export function FloatingWindow({
|
|
|
158
165
|
onClose={close}
|
|
159
166
|
/>
|
|
160
167
|
|
|
161
|
-
{pip && <WindowPipPlaceholder pip={pip} minimized={minimized} />}
|
|
168
|
+
{pip && !hiddenHost && <WindowPipPlaceholder pip={pip} minimized={minimized} />}
|
|
162
169
|
|
|
163
170
|
{!maximized && !minimized && (
|
|
164
171
|
<WindowResizeHandles bind={(handle) => bindResize(handle) as Record<string, unknown>} />
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Send a tab straight into picture-in-picture, without the user ever seeing a window.
|
|
3
|
+
*
|
|
4
|
+
* A PiP window can only adopt an element that is already in the page, and it needs somewhere
|
|
5
|
+
* to put it back. The floating window is that element and that home — so one still opens
|
|
6
|
+
* here, it is simply never shown: the frame keeps a pip-only window off screen, and closing
|
|
7
|
+
* PiP closes it, which re-docks the tab into the panel it came from.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { usePanelStore } from "@/stores/panel-store";
|
|
11
|
+
import { focusPipDocument } from "./pip/pip-focus-target";
|
|
12
|
+
import { attachPipHost } from "./pip/pip-host";
|
|
13
|
+
import { TITLEBAR_HEIGHT } from "./window-chrome-contract";
|
|
14
|
+
import {
|
|
15
|
+
clearPipOnlyWindow,
|
|
16
|
+
markPipOnlyWindow,
|
|
17
|
+
setWindowPip,
|
|
18
|
+
whenWindowSlot,
|
|
19
|
+
} from "./window-pip-registry";
|
|
20
|
+
import { useWindowStore } from "./window-store";
|
|
21
|
+
|
|
22
|
+
export type OpenTabInPipResult = "opened" | "window-cap" | "cancelled";
|
|
23
|
+
|
|
24
|
+
/** Drop the host window; its own teardown hands the tab back to the panel it came from. */
|
|
25
|
+
function discard(windowId: string): void {
|
|
26
|
+
clearPipOnlyWindow(windowId);
|
|
27
|
+
useWindowStore.getState().close(windowId);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Detach a tab into a hidden window and adopt it into a PiP window.
|
|
32
|
+
*
|
|
33
|
+
* Rejects when the browser refuses the request (no support, or the click's activation was
|
|
34
|
+
* already spent); the caller reports that. Call it from a click handler with nothing awaited
|
|
35
|
+
* before it — the one await inside is a React commit, which leaves the activation valid.
|
|
36
|
+
*/
|
|
37
|
+
export async function openTabInPip(tabId: string, panelId: string): Promise<OpenTabInPipResult> {
|
|
38
|
+
const windowId = usePanelStore.getState().popOutTab(tabId, panelId);
|
|
39
|
+
if (!windowId) return "window-cap";
|
|
40
|
+
markPipOnlyWindow(windowId);
|
|
41
|
+
|
|
42
|
+
// The window exists in the store, but its body is created by the frame's layout effect —
|
|
43
|
+
// one commit away.
|
|
44
|
+
const slot = await whenWindowSlot(windowId);
|
|
45
|
+
if (!slot) {
|
|
46
|
+
discard(windowId);
|
|
47
|
+
return "cancelled";
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const rect = useWindowStore.getState().windows[windowId]?.rect;
|
|
51
|
+
let handle;
|
|
52
|
+
try {
|
|
53
|
+
handle = await attachPipHost(slot, {
|
|
54
|
+
// A zero falls through to the host's minimum size rather than a magic default.
|
|
55
|
+
width: rect?.w ?? 0,
|
|
56
|
+
height: rect ? rect.h - TITLEBAR_HEIGHT : 0,
|
|
57
|
+
onDetach: () => {
|
|
58
|
+
setWindowPip(windowId, null);
|
|
59
|
+
// Closing PiP means "done with this tab out here", not "give me a window instead":
|
|
60
|
+
// the tab goes back to its strip.
|
|
61
|
+
discard(windowId);
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
} catch (err) {
|
|
65
|
+
discard(windowId);
|
|
66
|
+
throw err;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Null means the window went away while the request was in flight; the host already
|
|
70
|
+
// restored what it had and called onDetach.
|
|
71
|
+
if (!handle) return "cancelled";
|
|
72
|
+
|
|
73
|
+
setWindowPip(windowId, handle);
|
|
74
|
+
// A DOM move carries no focus with it: without this the tab is visible in PiP but swallows
|
|
75
|
+
// nothing until the user clicks it.
|
|
76
|
+
focusPipDocument(handle.pipWindow.document);
|
|
77
|
+
return "opened";
|
|
78
|
+
}
|
|
@@ -24,6 +24,52 @@ const listeners = new Set<() => void>();
|
|
|
24
24
|
export function publishWindowSlot(windowId: string, el: HTMLElement | null): void {
|
|
25
25
|
if (el) slots.set(windowId, el);
|
|
26
26
|
else slots.delete(windowId);
|
|
27
|
+
for (const notify of listeners) notify();
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Resolve once a window has published its body, or `null` if it never does.
|
|
32
|
+
*
|
|
33
|
+
* A window opened to host a picture-in-picture request exists in the store before React has
|
|
34
|
+
* mounted its frame, so the element the PiP host needs does not exist yet in the click
|
|
35
|
+
* handler that created it. Waiting is safe: transient activation survives a commit, it is
|
|
36
|
+
* consuming it twice that the browser refuses.
|
|
37
|
+
*/
|
|
38
|
+
export function whenWindowSlot(windowId: string, timeoutMs = 2000): Promise<HTMLElement | null> {
|
|
39
|
+
const existing = windowSlot(windowId);
|
|
40
|
+
if (existing) return Promise.resolve(existing);
|
|
41
|
+
return new Promise((resolve) => {
|
|
42
|
+
const settle = (el: HTMLElement | null) => {
|
|
43
|
+
listeners.delete(check);
|
|
44
|
+
clearTimeout(timer);
|
|
45
|
+
resolve(el);
|
|
46
|
+
};
|
|
47
|
+
const check = () => {
|
|
48
|
+
const el = windowSlot(windowId);
|
|
49
|
+
if (el) settle(el);
|
|
50
|
+
};
|
|
51
|
+
const timer = setTimeout(() => settle(null), timeoutMs);
|
|
52
|
+
listeners.add(check);
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Windows that exist only to carry a tab into picture-in-picture: the frame keeps them off
|
|
58
|
+
* screen while PiP is up, and closing PiP closes the window, so the tab goes straight back
|
|
59
|
+
* to its tab strip instead of stranding an empty window the user never asked for.
|
|
60
|
+
*/
|
|
61
|
+
const pipOnly = new Set<string>();
|
|
62
|
+
|
|
63
|
+
export function markPipOnlyWindow(windowId: string): void {
|
|
64
|
+
pipOnly.add(windowId);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export function isPipOnlyWindow(windowId: string): boolean {
|
|
68
|
+
return pipOnly.has(windowId);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function clearPipOnlyWindow(windowId: string): void {
|
|
72
|
+
pipOnly.delete(windowId);
|
|
27
73
|
}
|
|
28
74
|
|
|
29
75
|
/** The body element of a mounted window, or null. */
|