@hienlh/ppm 0.18.9 → 0.18.11
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/.spike/cdp-client.ts +116 -0
- package/.spike/cleanup-ppm-workspace.mjs +44 -0
- package/.spike/group-protected-probe.ts +21 -0
- package/.spike/pip-eval.ts +17 -0
- package/.spike/pip-page-helpers.js +119 -0
- package/.spike/pip-results-editor-glue.json +105 -0
- package/.spike/pip-results-editor.json +158 -0
- package/.spike/pip-results-input-isolation.json +28 -0
- package/.spike/pip-results-key-probe.json +58 -0
- package/.spike/pip-results-listener-survival.json +98 -0
- package/.spike/pip-results-listeners.json +36 -0
- package/.spike/pip-results-pagehide.json +92 -0
- package/.spike/pip-results-resize.json +104 -0
- package/.spike/pip-results-terminal-debug.json +99 -0
- package/.spike/pip-results-terminal-v2.json +191 -0
- package/.spike/pip-results-terminal.json +220 -0
- package/.spike/pip-results-xterm-trace.json +73 -0
- package/.spike/pip-spike-common.ts +83 -0
- package/.spike/pip-spike-editor-glue.ts +82 -0
- package/.spike/pip-spike-editor.ts +129 -0
- package/.spike/pip-spike-input-isolation.ts +38 -0
- package/.spike/pip-spike-key-probe.ts +34 -0
- package/.spike/pip-spike-listener-survival.ts +54 -0
- package/.spike/pip-spike-listeners.ts +19 -0
- package/.spike/pip-spike-pagehide.ts +59 -0
- package/.spike/pip-spike-resize.ts +42 -0
- package/.spike/pip-spike-setup.ts +63 -0
- package/.spike/pip-spike-terminal-debug.ts +81 -0
- package/.spike/pip-spike-terminal-v2.ts +139 -0
- package/.spike/pip-spike-terminal.ts +169 -0
- package/.spike/pip-spike-xterm-trace.ts +36 -0
- package/.spike/probe-drag-memo-error.mjs +67 -0
- package/.spike/read-dev-db.ts +15 -0
- package/.spike/scratch-editor-target.ts +7 -0
- package/.spike/smoke-unified-chrome-pip.mjs +353 -0
- package/.spike/tunnel.err +63 -42
- package/.spike/vite-restart.err +663 -0
- package/.spike/w.err +569 -94
- package/CHANGELOG.md +25 -0
- package/assets/skills/ppm/SKILL.md +1 -1
- package/assets/skills/ppm/references/http-api.md +1 -1
- package/dist/web/assets/adaptive-context-menu-DGCKKeTy.js +1 -0
- package/dist/web/assets/ai-resource-editor-BOHHTTe7.js +1 -0
- package/dist/web/assets/ai-settings-section-BigC_nZR.js +1 -0
- package/dist/web/assets/{angular-html-Ctz0zN01.js → angular-html-BYPaydvh.js} +1 -1
- package/dist/web/assets/{angular-ts-QXHpgB1C.js → angular-ts-Bb4AMKlk.js} +1 -1
- package/dist/web/assets/api-client-DTZEgjBQ.js +1 -0
- package/dist/web/assets/{api-settings-kQHV6pYZ.js → api-settings-Bd3M4YpI.js} +1 -1
- package/dist/web/assets/api-settings-kd1j4iR8.js +1 -0
- package/dist/web/assets/{api-themes-CrK0tkW_.js → api-themes-Cpx419SL.js} +1 -1
- package/dist/web/assets/{apl-b9KVk-O4.js → apl-DB2VjFCS.js} +1 -1
- package/dist/web/assets/architecture-PBZL5I3N-8dCMT9r7.js +1 -0
- package/dist/web/assets/{astro-BlFEeGYr.js → astro-BeoJdVpk.js} +1 -1
- package/dist/web/assets/{audio-preview-CZLmhf__.js → audio-preview-BgFuTn-0.js} +1 -1
- package/dist/web/assets/{blade-CGkj2MUI.js → blade-Cf2q1sPf.js} +1 -1
- package/dist/web/assets/{bsl-CVsbb6ap.js → bsl-W1kOaNpu.js} +1 -1
- package/dist/web/assets/{button-BA_fJOtX.js → button-5zTrkEoN.js} +1 -1
- package/dist/web/assets/{cairo-BbIHl2iE.js → cairo-BoAZFcje.js} +1 -1
- package/dist/web/assets/chat-tab-E3bf_V8X.js +15 -0
- package/dist/web/assets/chevron-down-Dp0rpHb8.js +1 -0
- package/dist/web/assets/clipboard-7fw0Shic.js +1 -0
- package/dist/web/assets/{cobol-BWSGjmWb.js → cobol-B0Nm7RXj.js} +1 -1
- package/dist/web/assets/code-editor-BUlM2gXk.js +10 -0
- package/dist/web/assets/{coffee-CWGNOxds.js → coffee-BakMn3on.js} +1 -1
- package/dist/web/assets/{conflict-editor-CdH_h0vD.js → conflict-editor-BUs5k9q_.js} +4 -4
- package/dist/web/assets/context-menu-Bq92km4s.js +1 -0
- package/dist/web/assets/{cpp-DHGV24J2.js → cpp-BRAJQHK2.js} +1 -1
- package/dist/web/assets/{crystal-Vlwf2UMP.js → crystal-kqqO3zkK.js} +1 -1
- package/dist/web/assets/{csv-preview-CY_454vd.js → csv-preview-ByoDgLAZ.js} +1 -1
- package/dist/web/assets/{data-grid-overlay-editor-D9il5DZS.js → data-grid-overlay-editor-Brkf9z41.js} +1 -1
- package/dist/web/assets/database-viewer-Btc3h8Yu.js +1 -0
- package/dist/web/assets/dialog-DwtGlowE.js +1 -0
- package/dist/web/assets/diff-viewer-CZaDnR4w.js +4 -0
- package/dist/web/assets/docx-preview-DAD_vg59.js +12 -0
- package/dist/web/assets/{edge-Bhqk64zS.js → edge-Cq1ZKZuE.js} +1 -1
- package/dist/web/assets/{edit-diff-preview-gq6ALf2B.js → edit-diff-preview-B_VE7ppQ.js} +1 -1
- package/dist/web/assets/{elixir-D466WCFm.js → elixir-BM_JoJRk.js} +1 -1
- package/dist/web/assets/{elm-Bfs2qNPR.js → elm-Dw7oO08Y.js} +1 -1
- package/dist/web/assets/{erb-WI7jUaB6.js → erb-CfKOGAfk.js} +1 -1
- package/dist/web/assets/{erlang-BCBe8nCc.js → erlang-DlDmGVeE.js} +1 -1
- package/dist/web/assets/{esm-CZs9WVDO.js → esm-DGAP0GFh.js} +1 -1
- package/dist/web/assets/explorer-body-9aBmyVpZ.js +2 -0
- package/dist/web/assets/explorer-window-content-DRtqoSPA.js +1 -0
- package/dist/web/assets/extension-store-Cpfh2vMm.js +1 -0
- package/dist/web/assets/{extension-webview-CuOQrHIS.js → extension-webview-B2OnjuCu.js} +2 -2
- package/dist/web/assets/external-link-B8BynhvY.js +1 -0
- package/dist/web/assets/file-store-aOERIEo-.js +1 -0
- package/dist/web/assets/folder-symlink-B8XrtvQK.js +1 -0
- package/dist/web/assets/format-bytes-WVcFxJuT.js +1 -0
- package/dist/web/assets/{fortran-fixed-form-CXLIv8Ox.js → fortran-fixed-form-XnAhQWxS.js} +1 -1
- package/dist/web/assets/{fsharp-CZsYmiw9.js → fsharp-CdNvy0PG.js} +1 -1
- package/dist/web/assets/{gdresource-BGRvoWfC.js → gdresource-DxuG5i8i.js} +1 -1
- package/dist/web/assets/{git-commit-DH6mY3Km.js → git-commit-3lMonsur.js} +1 -1
- package/dist/web/assets/git-log-panel-Co0PBPHC.js +1 -0
- package/dist/web/assets/{git-rebase-C5Gql6Ma.js → git-rebase-N8Z9kIMf.js} +1 -1
- package/dist/web/assets/gitGraph-HDMCJU4V-2e_8dfbs.js +1 -0
- package/dist/web/assets/{glide-data-grid-Cehfgrzc.js → glide-data-grid-C4_zIneN.js} +8 -8
- package/dist/web/assets/{glimmer-js-1-6JMJlj.js → glimmer-js-Dp9OXiib.js} +1 -1
- package/dist/web/assets/{glimmer-ts-C_Njj0nK.js → glimmer-ts-CDVKBcDj.js} +1 -1
- package/dist/web/assets/{glsl-DbkxE1TN.js → glsl-DPJxI4us.js} +1 -1
- package/dist/web/assets/{graphql-BK75fiXl.js → graphql-BrFhaQQl.js} +1 -1
- package/dist/web/assets/group-chat-tab-rOd8J8GC.js +1 -0
- package/dist/web/assets/{hack-DG151vit.js → hack-BzXbDMlA.js} +1 -1
- package/dist/web/assets/{haml-DKeIPQWM.js → haml-CPpkX0s5.js} +1 -1
- package/dist/web/assets/{handlebars-398uCI13.js → handlebars-BqrApy52.js} +1 -1
- package/dist/web/assets/{html-NLWdst5q.js → html-DmjUl-OA.js} +1 -1
- package/dist/web/assets/{html-derivative-CJf_Le2z.js → html-derivative-Cnd6XFR5.js} +1 -1
- package/dist/web/assets/{http-G1K2FozA.js → http-DMLWYun2.js} +1 -1
- package/dist/web/assets/{hurl-WDC6sSBz.js → hurl-CKkCVxbj.js} +1 -1
- package/dist/web/assets/{hxml-Dc3jBXuf.js → hxml-CAx19TtQ.js} +1 -1
- package/dist/web/assets/image-preview-DHUoylQ1.js +1 -0
- package/dist/web/assets/index-BImUaigO.js +52 -0
- package/dist/web/assets/index-CSfi6DSU.css +2 -0
- package/dist/web/assets/info-3K5VOQVL-BZi1Gha1.js +1 -0
- package/dist/web/assets/input-DcEk7mA3.js +1 -0
- package/dist/web/assets/{jinja-CWsQj2y0.js → jinja-BmB9YN9l.js} +1 -1
- package/dist/web/assets/{jison-CciJg2NW.js → jison-BaVsKKpw.js} +1 -1
- package/dist/web/assets/{julia-IOQNJAB7.js → julia-BgVBLveX.js} +1 -1
- package/dist/web/assets/{just-BGdHchwS.js → just-C2ENIbl9.js} +1 -1
- package/dist/web/assets/keybindings-store-BGIyqXHI.js +1 -0
- package/dist/web/assets/keybindings-store-CzV2sPls.js +1 -0
- package/dist/web/assets/{latex-D6TOl-L2.js → latex-BiDIWxKL.js} +1 -1
- package/dist/web/assets/{liquid-CVSvu_Wn.js → liquid-NxpapreE.js} +1 -1
- package/dist/web/assets/loader-circle-gSPVxfvH.js +1 -0
- package/dist/web/assets/lock-Did-87UV.js +1 -0
- package/dist/web/assets/{lua-CcKiU6HW.js → lua-DVepQvwH.js} +1 -1
- package/dist/web/assets/markdown-renderer-CcbR33VG.js +1 -0
- package/dist/web/assets/{markdown-renderer-pVzBdkpl.js → markdown-renderer-DlcDhgrF.js} +3 -3
- package/dist/web/assets/{marko--UOicMGo.js → marko-CJ2606Xl.js} +1 -1
- package/dist/web/assets/{mdc-D690aU2C.js → mdc-D2bjqclE.js} +1 -1
- package/dist/web/assets/{media-url-CylYQld1.js → media-url-H17XJF-I.js} +1 -1
- package/dist/web/assets/mobile-bottom-sheet-g-r2hCFa.js +1 -0
- package/dist/web/assets/mobile-explorer-sheet-SIwQXlwA.js +1 -0
- package/dist/web/assets/monitor-Dv8vn_6O.js +1 -0
- package/dist/web/assets/{nextflow-DR8PhpF8.js → nextflow-BtJwUbfF.js} +1 -1
- package/dist/web/assets/{nginx-Qb9pUk1g.js → nginx-j4gyIhHE.js} +1 -1
- package/dist/web/assets/{nim-DLa8R3NS.js → nim-ClH_gjP5.js} +1 -1
- package/dist/web/assets/notification-store-DV5QtUTg.js +1 -0
- package/dist/web/assets/{number-overlay-editor-D9SkFg1Y.js → number-overlay-editor-C1EqJnWq.js} +1 -1
- package/dist/web/assets/overview-panel-vTeeJYVZ.js +1 -0
- package/dist/web/assets/packet-RMMSAZCW-o5htEcin.js +1 -0
- package/dist/web/assets/panel-store-BSnkjgHt.js +1 -0
- package/dist/web/assets/pdf-preview-CqFGRY0Z.js +1 -0
- package/dist/web/assets/pencil-BlIIg6RH.js +1 -0
- package/dist/web/assets/{perl-AMNGIneF.js → perl-C9H7X7CT.js} +1 -1
- package/dist/web/assets/{php-CDsOOxXn.js → php-Bx2U-cQ_.js} +1 -1
- package/dist/web/assets/pie-UPGHQEXC-BXAIFSAD.js +1 -0
- package/dist/web/assets/play-4MZi1Axp.js +1 -0
- package/dist/web/assets/portal-container-context-Cm5HipFr.js +1 -0
- package/dist/web/assets/{postgres-viewer-CR6VpTrX.js → postgres-viewer-DHwcQucn.js} +3 -3
- package/dist/web/assets/process-table-BGRJNlpn.js +1 -0
- package/dist/web/assets/{project-store-B8BkHXy5.js → project-store--nvQiy75.js} +1 -1
- package/dist/web/assets/{pug-C2kdkhQ6.js → pug-Cw74sKsE.js} +1 -1
- package/dist/web/assets/{qml-DRDkUp75.js → qml-BXD94Eqz.js} +1 -1
- package/dist/web/assets/radar-KQ55EAFF-Dbt2Aebl.js +1 -0
- package/dist/web/assets/{razor-wY_6wUeC.js → razor-DZ0-Ge0S.js} +1 -1
- package/dist/web/assets/refresh-cw-B06yaBrW.js +1 -0
- package/dist/web/assets/resolve-theme-CRt_7wpd.js +1 -0
- package/dist/web/assets/rotate-ccw-COXu_9oj.js +1 -0
- package/dist/web/assets/{rst-BRpofyNs.js → rst-Dtdh0QUj.js} +1 -1
- package/dist/web/assets/{ruby-ieATBhWm.js → ruby-BC51BW2Q.js} +1 -1
- package/dist/web/assets/{run-in-terminal-CyS5Itj-.js → run-in-terminal-Sd3KyjN4.js} +1 -1
- package/dist/web/assets/{sas-CoOOEbOO.js → sas-BN8i4qOU.js} +1 -1
- package/dist/web/assets/scroll-area-0gljZ6lF.js +1 -0
- package/dist/web/assets/{scss-_nWV0bsb.js → scss-H-QtA7Rz.js} +1 -1
- package/dist/web/assets/send-BlyNJAzy.js +1 -0
- package/dist/web/assets/{send-to-chat-BcO39BDR.js → send-to-chat-u6m8l-rH.js} +1 -1
- package/dist/web/assets/{settings-store-C20lqh0G.js → settings-store-CHY6Kzin.js} +2 -2
- package/dist/web/assets/settings-tab-Dic6TKkU.js +1 -0
- package/dist/web/assets/settings-tab-IY6K1MiZ.js +3 -0
- package/dist/web/assets/{shaderlab-XkqfIfO8.js → shaderlab-CalNsj_x.js} +1 -1
- package/dist/web/assets/shallow-DYo6goJ4.js +1 -0
- package/dist/web/assets/{shellsession-BKBIqTlM.js → shellsession-BFrcoR8x.js} +1 -1
- package/dist/web/assets/{soy-oVDnPzzh.js → soy-CNbku7vP.js} +1 -1
- package/dist/web/assets/{sparql-N2VclEsF.js → sparql-BN_orcVp.js} +1 -1
- package/dist/web/assets/{sql-query-editor-BPYsJDsn.js → sql-query-editor-C6pC3I8l.js} +1 -1
- package/dist/web/assets/sqlite-viewer-DTr5PzUb.js +1 -0
- package/dist/web/assets/{stata-BuuClVDg.js → stata-C6a5Ijzq.js} +1 -1
- package/dist/web/assets/{surrealql-DE5_63MS.js → surrealql-ClplI_HY.js} +1 -1
- package/dist/web/assets/{svelte--YWjlOrK.js → svelte-DNm-UNXB.js} +1 -1
- package/dist/web/assets/switch-DKvKya9y.js +1 -0
- package/dist/web/assets/system-monitor-body-iwGiCns9.js +2 -0
- package/dist/web/assets/system-monitor-tab-DdXQhEel.js +1 -0
- package/dist/web/assets/system-monitor-window-content-BUqRsPK2.js +1 -0
- package/dist/web/assets/tab-host-window-content-BnqGPu8a.js +1 -0
- package/dist/web/assets/{tab-store-DAsvpx4t.js → tab-store-CJuJRapl.js} +1 -1
- package/dist/web/assets/team-member-sheet-LkAFSCvb.js +2 -0
- package/dist/web/assets/team-member-window-content-T4Q5JI-G.js +1 -0
- package/dist/web/assets/{templ-MlpvJx4a.js → templ-CSdqVobu.js} +1 -1
- package/dist/web/assets/terminal-tab-Bb2rZegQ.js +3 -0
- package/dist/web/assets/{tex-0loAoXJG.js → tex-DzSJ4kcZ.js} +1 -1
- package/dist/web/assets/text-wrap-CBT4Gxtg.js +1 -0
- package/dist/web/assets/tool-cards-lhqhrDTT.js +8 -0
- package/dist/web/assets/trash-2-Bk4yYlck.js +1 -0
- package/dist/web/assets/treemap-KZPCXAKY-DUbnl9dz.js +1 -0
- package/dist/web/assets/triangle-alert-B8EYecpe.js +1 -0
- package/dist/web/assets/{ts-tags-pt-Ug0hK.js → ts-tags-C28w3bTg.js} +1 -1
- package/dist/web/assets/{twig-DOePpLOL.js → twig-i5jY3QXB.js} +1 -1
- package/dist/web/assets/upload-BNlX8D07.js +1 -0
- package/dist/web/assets/{use-blob-url-BKyVxOZw.js → use-blob-url-Dsq9OjTh.js} +1 -1
- package/dist/web/assets/{use-monaco-theme-CGucu3fb.js → use-monaco-theme-BZvlsoBv.js} +1 -1
- package/dist/web/assets/use-open-team-member-DkiEjFYE.js +1 -0
- package/dist/web/assets/{use-websocket-C-Rxv8JN.js → use-websocket-B8R50f7f.js} +1 -1
- package/dist/web/assets/{vendor-mermaid-DrwG0NYt.js → vendor-mermaid-By4AVvJY.js} +1 -1
- package/dist/web/assets/video-preview-m0-3p7QZ.js +1 -0
- package/dist/web/assets/{vue-D6f-rprj.js → vue-Ceyet_lv.js} +1 -1
- package/dist/web/assets/{vue-html-DEYRkS1V.js → vue-html-GuU7g_hg.js} +1 -1
- package/dist/web/assets/{vue-vine-CxSG2ojf.js → vue-vine-CxXoaJr2.js} +1 -1
- package/dist/web/assets/window-store-CsEW6jiE.js +1 -0
- package/dist/web/assets/{xml-DhrxbATj.js → xml-CbqOVhkP.js} +1 -1
- package/dist/web/assets/{xsl-CU0ZndUO.js → xsl-KfAmCauy.js} +1 -1
- package/dist/web/index.html +56 -27
- package/dist/web/sw.js +1 -1
- package/docs/code-standards.md +8 -0
- package/docs/codebase-summary.md +19 -5
- package/docs/design-guidelines.md +13 -2
- package/docs/project-roadmap.md +9 -0
- package/docs/system-architecture.md +83 -6
- package/package.json +1 -1
- package/src/web/components/chat/file-picker.tsx +5 -2
- package/src/web/components/chat/mode-selector.tsx +5 -2
- package/src/web/components/chat/model-selector.tsx +5 -2
- package/src/web/components/chat/model-thinking-selector.tsx +5 -2
- package/src/web/components/chat/provider-selector.tsx +5 -2
- package/src/web/components/chat/slash-command-picker.tsx +5 -2
- package/src/web/components/editor/code-editor.tsx +13 -3
- package/src/web/components/editor/conflict-editor.tsx +9 -0
- package/src/web/components/editor/diff-viewer.tsx +9 -0
- package/src/web/components/floating-window/floating-window.tsx +23 -15
- package/src/web/components/floating-window/pip/pip-caption-button.tsx +108 -0
- package/src/web/components/floating-window/pip/pip-focus-target.ts +58 -0
- package/src/web/components/floating-window/pip/pip-geometry.ts +46 -0
- package/src/web/components/floating-window/pip/pip-host.ts +156 -0
- package/src/web/components/floating-window/pip/pip-key-forward.ts +59 -0
- package/src/web/components/floating-window/pip/pip-resize-signal.ts +33 -0
- package/src/web/components/floating-window/pip/pip-style-copy.ts +108 -0
- package/src/web/components/floating-window/pip/pip-support.ts +33 -0
- package/src/web/components/floating-window/tab-host-window-content.tsx +80 -0
- package/src/web/components/floating-window/use-window-body-element.ts +67 -0
- package/src/web/components/floating-window/use-window-drag.ts +5 -0
- package/src/web/components/floating-window/use-window-gesture-context.ts +14 -0
- package/src/web/components/floating-window/use-window-resize.ts +5 -0
- package/src/web/components/floating-window/window-content-registry.ts +4 -16
- package/src/web/components/floating-window/window-layer.tsx +1 -2
- package/src/web/components/floating-window/window-persistence.ts +9 -2
- package/src/web/components/floating-window/window-pip-placeholder.tsx +31 -0
- package/src/web/components/floating-window/window-pip-registry.ts +69 -0
- package/src/web/components/floating-window/window-skin-chrome.tsx +21 -0
- package/src/web/components/floating-window/window-store-types.ts +8 -2
- package/src/web/components/layout/reparenting-tab.tsx +136 -0
- package/src/web/components/layout/tab-bar.tsx +2 -0
- package/src/web/components/layout/tab-pool-collect.ts +38 -2
- package/src/web/components/layout/tab-pool-registry.ts +48 -0
- package/src/web/components/layout/tab-pool.tsx +54 -168
- package/src/web/components/layout/tab-pop-out-menu-item.tsx +42 -0
- package/src/web/components/layout/use-window-panel-reconcile.ts +48 -0
- package/src/web/components/os-explorer/skins/macos-window-chrome.tsx +16 -7
- package/src/web/components/os-explorer/skins/windows-window-chrome.tsx +14 -8
- package/src/web/components/system/build-kill-request.ts +28 -1
- package/src/web/components/system/chart-scale.ts +3 -3
- package/src/web/components/system/kill-confirm-dialog.tsx +44 -28
- package/src/web/components/system/metric-chart-canvas.tsx +1 -2
- package/src/web/components/system/process-columns-grid.ts +39 -29
- package/src/web/components/system/process-group-row.tsx +31 -8
- package/src/web/components/system/process-row.tsx +6 -7
- package/src/web/components/system/process-table-model.ts +4 -22
- package/src/web/components/system/process-table-toolbar.tsx +12 -43
- package/src/web/components/system/process-table.tsx +22 -63
- package/src/web/components/system/sortable-header.tsx +33 -8
- package/src/web/components/system/system-monitor-body.tsx +1 -1
- package/src/web/components/system/use-column-widths.ts +91 -0
- package/src/web/components/system/use-process-kill.ts +100 -0
- package/src/web/components/ui/context-menu.tsx +10 -3
- package/src/web/components/ui/dialog.tsx +10 -1
- package/src/web/components/ui/dropdown-menu.tsx +10 -3
- package/src/web/components/ui/mobile-bottom-sheet.tsx +7 -4
- package/src/web/components/ui/portal-container-context.tsx +40 -0
- package/src/web/components/ui/select.tsx +3 -1
- package/src/web/components/ui/tooltip.tsx +3 -1
- package/src/web/hooks/use-terminal.ts +24 -3
- package/src/web/stores/panel-store.ts +72 -7
- package/src/web/stores/panel-utils.ts +36 -0
- package/src/web/stores/window-panel-actions.ts +211 -0
- package/src/web/stores/window-panel-persistence.ts +115 -0
- package/src/web/stores/window-panel-reconcile.ts +97 -0
- package/src/web/styles/globals.css +5 -3
- package/src/web/theme/builtin/aurora.ts +8 -5
- package/dist/web/assets/ai-resource-editor-DFCuNe-P.js +0 -1
- package/dist/web/assets/api-client-CzABTreM.js +0 -1
- package/dist/web/assets/api-settings-nblja3Rk.js +0 -1
- package/dist/web/assets/architecture-PBZL5I3N-C7ra20CE.js +0 -1
- package/dist/web/assets/chat-tab-flMPLoKb.js +0 -15
- package/dist/web/assets/code-editor-C2VQbXzw.js +0 -10
- package/dist/web/assets/context-menu-Cq0u3SK9.js +0 -1
- package/dist/web/assets/database-viewer-BCZOTrPT.js +0 -1
- package/dist/web/assets/diff-viewer-BwfMN-nW.js +0 -4
- package/dist/web/assets/docx-preview-D3Sdh_aT.js +0 -12
- package/dist/web/assets/explorer-body-BKOMM566.js +0 -2
- package/dist/web/assets/explorer-window-content-Bbzijk8t.js +0 -1
- package/dist/web/assets/format-bytes-Dk7B73B7.js +0 -1
- package/dist/web/assets/git-log-panel-DcV7PhqW.js +0 -1
- package/dist/web/assets/gitGraph-HDMCJU4V-D4hYLNJU.js +0 -1
- package/dist/web/assets/group-chat-tab-BVPYxjz-.js +0 -1
- package/dist/web/assets/image-preview-D-Ok10eZ.js +0 -1
- package/dist/web/assets/index-CerSxGdf.js +0 -52
- package/dist/web/assets/index-DRA_OpWY.css +0 -2
- package/dist/web/assets/info-3K5VOQVL-lRlrTlkb.js +0 -1
- package/dist/web/assets/keybindings-store-aIY40k2o.js +0 -1
- package/dist/web/assets/markdown-renderer-I89kyQhe.js +0 -1
- package/dist/web/assets/mobile-bottom-sheet-BUOJgiaZ.js +0 -1
- package/dist/web/assets/mobile-explorer-sheet-5Uj9ZMM9.js +0 -1
- package/dist/web/assets/notification-store-DJ-OtAG3.js +0 -1
- package/dist/web/assets/overview-panel-Cgi3UPY1.js +0 -1
- package/dist/web/assets/packet-RMMSAZCW-BIhk1mvp.js +0 -1
- package/dist/web/assets/panel-store-DCD82zc1.js +0 -1
- package/dist/web/assets/pdf-preview-Di5xHFyT.js +0 -1
- package/dist/web/assets/pie-UPGHQEXC-SLS6i76l.js +0 -1
- package/dist/web/assets/process-table-DL6shbzt.js +0 -1
- package/dist/web/assets/radar-KQ55EAFF-JJ6O1Er_.js +0 -1
- package/dist/web/assets/resolve-theme-IdhSR-gx.js +0 -1
- package/dist/web/assets/settings-tab-jbiQwozX.js +0 -1
- package/dist/web/assets/sqlite-viewer-Bq9ZJA2y.js +0 -1
- package/dist/web/assets/system-monitor-body-CKEYWyN9.js +0 -2
- package/dist/web/assets/system-monitor-tab-WjhFFHyM.js +0 -1
- package/dist/web/assets/system-monitor-window-content-CMiISeoC.js +0 -1
- package/dist/web/assets/team-member-sheet-oY5EkH53.js +0 -2
- package/dist/web/assets/team-member-window-content-yCBeI_5X.js +0 -1
- package/dist/web/assets/terminal-tab-BxHtMR7h.js +0 -3
- package/dist/web/assets/tool-cards-BcGrk1zk.js +0 -8
- package/dist/web/assets/treemap-KZPCXAKY-Be3KNmns.js +0 -1
- package/dist/web/assets/use-open-team-member-DdrRXj-M.js +0 -1
- package/dist/web/assets/video-preview-DYAbbmd0.js +0 -1
- package/src/web/components/floating-window/default-window-chrome.tsx +0 -71
- package/src/web/components/os-explorer/skins/explorer-skin-chrome.tsx +0 -17
- package/src/web/components/system/sparkline-canvas.tsx +0 -63
- /package/dist/web/assets/{abap-MRbmsXOs.js → abap-C6nB04tn.js} +0 -0
- /package/dist/web/assets/{actionscript-3-BDDHKqa4.js → actionscript-3-Vx4rw2sC.js} +0 -0
- /package/dist/web/assets/{ada-DpuV9KwV.js → ada-Ccd8vM20.js} +0 -0
- /package/dist/web/assets/{andromeeda-D6qUCKJo.js → andromeeda-DnBX5xMg.js} +0 -0
- /package/dist/web/assets/{apache-CX1NU_Tl.js → apache-B-9_sx0g.js} +0 -0
- /package/dist/web/assets/{apex-B4-aoQ3K.js → apex-_wPVBYoL.js} +0 -0
- /package/dist/web/assets/{api-client-BSB14J4w.js → api-client-aQb5hHE5.js} +0 -0
- /package/dist/web/assets/{applescript-Dm9NI6KR.js → applescript-CcvD-qr0.js} +0 -0
- /package/dist/web/assets/{apply-theme-BH_d4amk.js → apply-theme-BeLRfsSu.js} +0 -0
- /package/dist/web/assets/{ara-BGN8GAYn.js → ara-C40Ztoms.js} +0 -0
- /package/dist/web/assets/{asciidoc-s_yVuR3t.js → asciidoc-CybYkJV4.js} +0 -0
- /package/dist/web/assets/{asm-BzQdSvTe.js → asm-9eOKwzR0.js} +0 -0
- /package/dist/web/assets/{aurora-x-BJTLETG_.js → aurora-x-B5ZH4t7t.js} +0 -0
- /package/dist/web/assets/{awk-BQEGWxvX.js → awk-Dqilob-2.js} +0 -0
- /package/dist/web/assets/{ayu-dark-CpTORmLc.js → ayu-dark-CPgRhf5r.js} +0 -0
- /package/dist/web/assets/{ayu-light-D8PVj-e6.js → ayu-light-Do06Q52f.js} +0 -0
- /package/dist/web/assets/{ayu-mirage-DyElQHtm.js → ayu-mirage-_BhxcrxY.js} +0 -0
- /package/dist/web/assets/{ballerina-C82NkRtj.js → ballerina-DDwK54QW.js} +0 -0
- /package/dist/web/assets/{bat-0X7DtGI-.js → bat-BGyGlzGk.js} +0 -0
- /package/dist/web/assets/{beancount-Xgvy6YRl.js → beancount-CRWBdapI.js} +0 -0
- /package/dist/web/assets/{berry-CCT2pZcQ.js → berry-DbSFn2gO.js} +0 -0
- /package/dist/web/assets/{bibtex-CpXgZ9M_.js → bibtex-QpsV9gm9.js} +0 -0
- /package/dist/web/assets/{bicep-fkeSA62l.js → bicep-CxS8CUve.js} +0 -0
- /package/dist/web/assets/{bird2-Co7SeAI8.js → bird2-CuZhQzYR.js} +0 -0
- /package/dist/web/assets/{bot-CunPuEdW.js → bot-D6sx11y0.js} +0 -0
- /package/dist/web/assets/{c-BpmrTvJh.js → c-9bnDqE3g.js} +0 -0
- /package/dist/web/assets/{c3-BZ_Z0RrR.js → c3-JMZTrOhA.js} +0 -0
- /package/dist/web/assets/{cadence-B0GBC8OF.js → cadence-DsDNayJS.js} +0 -0
- /package/dist/web/assets/{can-open-in-ppm-omBzUBBq.js → can-open-in-ppm-BJfpynya.js} +0 -0
- /package/dist/web/assets/{catppuccin-frappe-DIt_xR7m.js → catppuccin-frappe-DYIKXXBe.js} +0 -0
- /package/dist/web/assets/{catppuccin-latte-Dw40AcqA.js → catppuccin-latte-IYYOnUJ8.js} +0 -0
- /package/dist/web/assets/{catppuccin-macchiato-BJ7DfVEF.js → catppuccin-macchiato-BrJ_7mfS.js} +0 -0
- /package/dist/web/assets/{catppuccin-mocha-NI2lfXzU.js → catppuccin-mocha-gzSu7v7-.js} +0 -0
- /package/dist/web/assets/{chevron-right-BLOtX8Vy.js → chevron-right-De-Wz5Lz.js} +0 -0
- /package/dist/web/assets/{circle-hjUGru6R.js → circle-BCy0AUCo.js} +0 -0
- /package/dist/web/assets/{clarity-F39L0xMJ.js → clarity-DLzsC0Hb.js} +0 -0
- /package/dist/web/assets/{clock-CvhF4DJP.js → clock-C1CQUQPZ.js} +0 -0
- /package/dist/web/assets/{clojure-DloMkd8K.js → clojure-DS1BvoTt.js} +0 -0
- /package/dist/web/assets/{cmake-CwerJun_.js → cmake-CDvsJwYp.js} +0 -0
- /package/dist/web/assets/{code-DDPoqVri.js → code-DJgYrFzm.js} +0 -0
- /package/dist/web/assets/{codeowners-CQyVz4Qf.js → codeowners-BjsYiflJ.js} +0 -0
- /package/dist/web/assets/{codeql-Bb229zuY.js → codeql-CG-7ARat.js} +0 -0
- /package/dist/web/assets/{common-lisp-KMlIwq5I.js → common-lisp-DSO1Lbh9.js} +0 -0
- /package/dist/web/assets/{copy-DKn11Pye.js → copy-BewHj66E.js} +0 -0
- /package/dist/web/assets/{coq-DHX_3IIo.js → coq-DYdh3oP_.js} +0 -0
- /package/dist/web/assets/{csharp-CEmCZv9Q.js → csharp-DxEBz5s0.js} +0 -0
- /package/dist/web/assets/{css-CqZqBD05.js → css-dal3Q-8C.js} +0 -0
- /package/dist/web/assets/{csv-l1g_V5MV.js → csv-CpqjMGiA.js} +0 -0
- /package/dist/web/assets/{csv-parser-CnS0wqr6.js → csv-parser-3umBA4NY.js} +0 -0
- /package/dist/web/assets/{cue-BrxRmilg.js → cue-DinoJ_5k.js} +0 -0
- /package/dist/web/assets/{cypher-rZkKwqZc.js → cypher-DzxqmkUW.js} +0 -0
- /package/dist/web/assets/{d-BALR-QuP.js → d-BxNwJuEC.js} +0 -0
- /package/dist/web/assets/{dark-plus-Cj7rVwh-.js → dark-plus-Clmv3V-0.js} +0 -0
- /package/dist/web/assets/{dart-CWQcdkXk.js → dart-BWVtXD35.js} +0 -0
- /package/dist/web/assets/{data-grid-types-CYvF-xK5.js → data-grid-types-B4n51Fck.js} +0 -0
- /package/dist/web/assets/{database-BH0urvbs.js → database-Y3ESDK4-.js} +0 -0
- /package/dist/web/assets/{dax-BNHD-QBA.js → dax-DsImuWgJ.js} +0 -0
- /package/dist/web/assets/{desktop-CN0IXPrP.js → desktop-B0jJuG2r.js} +0 -0
- /package/dist/web/assets/{diff-BtOXapES.js → diff-CWqAAxoE.js} +0 -0
- /package/dist/web/assets/{dist-DB1Oaqcc.js → dist-B-EXdSYE.js} +0 -0
- /package/dist/web/assets/{dist-Di6G_5jU.js → dist-C0eNNfbt.js} +0 -0
- /package/dist/web/assets/{docker-DNsAo_qO.js → docker-CYFCJdIL.js} +0 -0
- /package/dist/web/assets/{dotenv-D6Pl6aOU.js → dotenv-CKDUjURg.js} +0 -0
- /package/dist/web/assets/{download-zCATy4x4.js → download-DG3_9xXy.js} +0 -0
- /package/dist/web/assets/{dracula-C3m-w12D.js → dracula-CSoPspHE.js} +0 -0
- /package/dist/web/assets/{dracula-soft-BYqvXm6Z.js → dracula-soft-BuFjw5L1.js} +0 -0
- /package/dist/web/assets/{dream-maker-DZAPbPTi.js → dream-maker-B6PdDRZu.js} +0 -0
- /package/dist/web/assets/{emacs-lisp-Ao5SW8ay.js → emacs-lisp-CMcXvD0G.js} +0 -0
- /package/dist/web/assets/{everforest-dark-uC8QYotQ.js → everforest-dark-cU8-wYzi.js} +0 -0
- /package/dist/web/assets/{everforest-light-CTgsVNMr.js → everforest-light-KhorllqK.js} +0 -0
- /package/dist/web/assets/{fennel-WuBw6IR1.js → fennel-BCELZK87.js} +0 -0
- /package/dist/web/assets/{file-exclamation-point-COAwgNGw.js → file-exclamation-point-CZ4DiR75.js} +0 -0
- /package/dist/web/assets/{fish-Byy9dusu.js → fish-BQc0y_jy.js} +0 -0
- /package/dist/web/assets/{fluent-CDxb_sgw.js → fluent-BTINnwF6.js} +0 -0
- /package/dist/web/assets/{fortran-free-form-DKWSTamT.js → fortran-free-form-BQim9wDz.js} +0 -0
- /package/dist/web/assets/{gdscript-prYHMgtD.js → gdscript-03w5u8un.js} +0 -0
- /package/dist/web/assets/{gdshader-D-RM-SQk.js → gdshader-Dp2daNzU.js} +0 -0
- /package/dist/web/assets/{genie-CowkJhej.js → genie-CoNcjPiD.js} +0 -0
- /package/dist/web/assets/{gherkin-CLFpoVYJ.js → gherkin-NrPOSPQL.js} +0 -0
- /package/dist/web/assets/{github-dark-default-BK_1Qgb8.js → github-dark-default-DOKw-1cI.js} +0 -0
- /package/dist/web/assets/{github-dark-dimmed-Cv9lj6f-.js → github-dark-dimmed-DJRNMkEA.js} +0 -0
- /package/dist/web/assets/{github-dark-high-contrast-CW5ZgIDh.js → github-dark-high-contrast-Bj7jJ_Gs.js} +0 -0
- /package/dist/web/assets/{github-dark-nW2F-RLd.js → github-dark-z4RE9ZqA.js} +0 -0
- /package/dist/web/assets/{github-light-D4PqBHGZ.js → github-light-B4k_yMFu.js} +0 -0
- /package/dist/web/assets/{github-light-default-B-cHtJJV.js → github-light-default-BHc-Uzhs.js} +0 -0
- /package/dist/web/assets/{github-light-high-contrast-Dt0HJq50.js → github-light-high-contrast-CHisIywL.js} +0 -0
- /package/dist/web/assets/{gleam-DwSyXJWP.js → gleam-CfbypZ4q.js} +0 -0
- /package/dist/web/assets/{gn-Cv5WEzHc.js → gn-YoAjyhJa.js} +0 -0
- /package/dist/web/assets/{gnuplot-D7bRdY_M.js → gnuplot-xVkc1f1c.js} +0 -0
- /package/dist/web/assets/{go-DiRVJ22U.js → go-GPCwP3Gu.js} +0 -0
- /package/dist/web/assets/{groovy-BHAgLTeO.js → groovy-Crh4Yww9.js} +0 -0
- /package/dist/web/assets/{gruvbox-dark-hard-C8QZ3gzY.js → gruvbox-dark-hard-BluUFuDS.js} +0 -0
- /package/dist/web/assets/{gruvbox-dark-medium-Dp1eeid2.js → gruvbox-dark-medium-Cxk1FWQp.js} +0 -0
- /package/dist/web/assets/{gruvbox-dark-soft-Cwq0dWVj.js → gruvbox-dark-soft-CHXMiFmj.js} +0 -0
- /package/dist/web/assets/{gruvbox-light-hard-CLQCq2-w.js → gruvbox-light-hard-B6eKPjAD.js} +0 -0
- /package/dist/web/assets/{gruvbox-light-medium-APHsh6Mo.js → gruvbox-light-medium-pDwMm1ut.js} +0 -0
- /package/dist/web/assets/{gruvbox-light-soft-CX-fYc64.js → gruvbox-light-soft-Cxu6kHqK.js} +0 -0
- /package/dist/web/assets/{haskell-C4Tw-TDa.js → haskell-C6JKHjbK.js} +0 -0
- /package/dist/web/assets/{haxe-B7fSduTQ.js → haxe-BuBNdF0a.js} +0 -0
- /package/dist/web/assets/{hcl-Bi3ho6yC.js → hcl-DZpDdGj2.js} +0 -0
- /package/dist/web/assets/{hjson-BXwae2M1.js → hjson-CBkhYRuo.js} +0 -0
- /package/dist/web/assets/{hlsl-CRuQLBSa.js → hlsl-C5nMxnp9.js} +0 -0
- /package/dist/web/assets/{horizon-DtdQ6qjv.js → horizon-VAFvA6R6.js} +0 -0
- /package/dist/web/assets/{horizon-bright-BXSF_uKq.js → horizon-bright-BC0xn7T3.js} +0 -0
- /package/dist/web/assets/{houston-C6ASpUjT.js → houston-BxrUivmz.js} +0 -0
- /package/dist/web/assets/{hy-BrWBHtHY.js → hy-DLtOXoaH.js} +0 -0
- /package/dist/web/assets/{image-gallery-CGvlv8zR.js → image-gallery-Gnf7TdCR.js} +0 -0
- /package/dist/web/assets/{imba-C_JJXckG.js → imba-BdpFXM2W.js} +0 -0
- /package/dist/web/assets/{ini-DEE_vSHQ.js → ini-BInJO_T0.js} +0 -0
- /package/dist/web/assets/{java-CnmpcjcT.js → java-Dxuddnkb.js} +0 -0
- /package/dist/web/assets/{javascript-C-M7sa2e.js → javascript-CVamJfLY.js} +0 -0
- /package/dist/web/assets/{json-BjZ3dAk6.js → json-BLZ0ozYk.js} +0 -0
- /package/dist/web/assets/{json5-BQ2vpqjp.js → json5-BnXzmMKs.js} +0 -0
- /package/dist/web/assets/{jsonc-C5MjoWGx.js → jsonc-CSgkSga7.js} +0 -0
- /package/dist/web/assets/{jsonl-JvhrmQJI.js → jsonl-CY5W2nF2.js} +0 -0
- /package/dist/web/assets/{jsonnet-C5pdZVuo.js → jsonnet-CEJYH3sF.js} +0 -0
- /package/dist/web/assets/{jssm-Db17uybX.js → jssm-CsJc7Uhk.js} +0 -0
- /package/dist/web/assets/{jsx-tJp2Cyqu.js → jsx-jCiRaHU7.js} +0 -0
- /package/dist/web/assets/{kanagawa-dragon-BculT_Y1.js → kanagawa-dragon-DfoA_GxX.js} +0 -0
- /package/dist/web/assets/{kanagawa-lotus-yQgHUGwU.js → kanagawa-lotus-BOLYJpWd.js} +0 -0
- /package/dist/web/assets/{kanagawa-wave-CyGoWN4d.js → kanagawa-wave-DfKlbT1G.js} +0 -0
- /package/dist/web/assets/{kdl-Bn8R1REF.js → kdl-CmssIFTi.js} +0 -0
- /package/dist/web/assets/{kotlin-DWughK73.js → kotlin-BRsNgp6x.js} +0 -0
- /package/dist/web/assets/{kusto--serPb0x.js → kusto-T8X9jUab.js} +0 -0
- /package/dist/web/assets/{laserwave-DfAPJ1tt.js → laserwave-DkJMVJ8Z.js} +0 -0
- /package/dist/web/assets/{lean-UAm1HOKl.js → lean-C65KGVPq.js} +0 -0
- /package/dist/web/assets/{less-Xj6Ka0fF.js → less-exIPdDlf.js} +0 -0
- /package/dist/web/assets/{lib-DgNcCtj3.js → lib-mC1NZfuw.js} +0 -0
- /package/dist/web/assets/{libesm-CPh1Av0r.js → libesm-DSutUtl1.js} +0 -0
- /package/dist/web/assets/{light-plus-BfS7gPcj.js → light-plus-DiHUXAZt.js} +0 -0
- /package/dist/web/assets/{llvm-DvWiVwvU.js → llvm-CJBnEzFM.js} +0 -0
- /package/dist/web/assets/{log-Bo5z9bNz.js → log-DxMyUMuP.js} +0 -0
- /package/dist/web/assets/{logo-CrIjcMZT.js → logo-CC9NKzca.js} +0 -0
- /package/dist/web/assets/{luau-C9TsYwNt.js → luau-Bw10I6zf.js} +0 -0
- /package/dist/web/assets/{make-GYq4qVbx.js → make-C_6M90m6.js} +0 -0
- /package/dist/web/assets/{markdown-p5mNledS.js → markdown-bR9_R-LF.js} +0 -0
- /package/dist/web/assets/{material-theme-CWYOVxsP.js → material-theme-BUx2Qujn.js} +0 -0
- /package/dist/web/assets/{material-theme-darker-BDGty7YH.js → material-theme-darker-CRJrPgKm.js} +0 -0
- /package/dist/web/assets/{material-theme-lighter-JbgOgV3n.js → material-theme-lighter-CUAYppPa.js} +0 -0
- /package/dist/web/assets/{material-theme-ocean-EMOpLpa2.js → material-theme-ocean-DuINF1fg.js} +0 -0
- /package/dist/web/assets/{material-theme-palenight-CY5hgm7h.js → material-theme-palenight-W6_icGCj.js} +0 -0
- /package/dist/web/assets/{matlab-C-He_NTH.js → matlab-rfqn_b3z.js} +0 -0
- /package/dist/web/assets/{mdx-Cr2TR5fj.js → mdx-Bh1B_YOJ.js} +0 -0
- /package/dist/web/assets/{mermaid-BYc0-B0U.js → mermaid-Dxf6Ya2k.js} +0 -0
- /package/dist/web/assets/{min-dark-CMJwqJqB.js → min-dark-CivZ2L0h.js} +0 -0
- /package/dist/web/assets/{min-light-Cx6vFiEX.js → min-light-B1Ykqtma.js} +0 -0
- /package/dist/web/assets/{mipsasm-Bjer5HwK.js → mipsasm-DynHaM0d.js} +0 -0
- /package/dist/web/assets/{mojo-t90PR-Y2.js → mojo-Clw5PbGH.js} +0 -0
- /package/dist/web/assets/{monokai-dci_PdCm.js → monokai-DFIooFZT.js} +0 -0
- /package/dist/web/assets/{moonbit-AAzI-Hd-.js → moonbit-DnBSZWGM.js} +0 -0
- /package/dist/web/assets/{move-kwBhnhrG.js → move-CCcL2PfL.js} +0 -0
- /package/dist/web/assets/{narrat-CXww2YQL.js → narrat-BDarg5Lk.js} +0 -0
- /package/dist/web/assets/{nextflow-groovy-CJXsuXGB.js → nextflow-groovy-DrZOeCNW.js} +0 -0
- /package/dist/web/assets/{night-owl-_GD204Wr.js → night-owl-BnZZCK7v.js} +0 -0
- /package/dist/web/assets/{night-owl-light-DNgkw3kl.js → night-owl-light-CEwBsVHS.js} +0 -0
- /package/dist/web/assets/{nix-BgiorKFd.js → nix-amCzOPMR.js} +0 -0
- /package/dist/web/assets/{nord-CaBmcxFC.js → nord-BIs2BC6q.js} +0 -0
- /package/dist/web/assets/{nushell-DUh4UGx1.js → nushell-Y02fo4yw.js} +0 -0
- /package/dist/web/assets/{objective-c-Cl9KU86S.js → objective-c-7xOZtWW1.js} +0 -0
- /package/dist/web/assets/{objective-cpp-DVkIA8A0.js → objective-cpp-eVtjUvVB.js} +0 -0
- /package/dist/web/assets/{ocaml-vvoHTak0.js → ocaml-Bi6ZwqG4.js} +0 -0
- /package/dist/web/assets/{odin-Cyjw8woZ.js → odin-8xf1Y0S9.js} +0 -0
- /package/dist/web/assets/{one-dark-pro-B1cviILi.js → one-dark-pro-hVv-_y_b.js} +0 -0
- /package/dist/web/assets/{one-light-BPGUJeYI.js → one-light-CJJ3MtHt.js} +0 -0
- /package/dist/web/assets/{openscad-BLMdTUU8.js → openscad-B2HcywLk.js} +0 -0
- /package/dist/web/assets/{pascal-i5niy3e7.js → pascal-C7fllV_7.js} +0 -0
- /package/dist/web/assets/{pkl-CuOV7SsU.js → pkl-qvLC1IWP.js} +0 -0
- /package/dist/web/assets/{plastic-Bf_zE5KL.js → plastic-BT1wHZv2.js} +0 -0
- /package/dist/web/assets/{plsql-cfqEtMD3.js → plsql-1MsmdmJD.js} +0 -0
- /package/dist/web/assets/{plus-BM-Ty0fp.js → plus-BhMZqFsN.js} +0 -0
- /package/dist/web/assets/{po-CFJcWgjr.js → po-BigskytD.js} +0 -0
- /package/dist/web/assets/{poimandres-G5YoaIFf.js → poimandres-DuklniF7.js} +0 -0
- /package/dist/web/assets/{polar-rcjs3i9R.js → polar-e2pjN_sp.js} +0 -0
- /package/dist/web/assets/{postcss-CBKY1FTZ.js → postcss-DtAeYjWw.js} +0 -0
- /package/dist/web/assets/{powerquery-Db7SXLbO.js → powerquery-Cr2PtehI.js} +0 -0
- /package/dist/web/assets/{powershell-LFy3MUTP.js → powershell-BxFTGLJ4.js} +0 -0
- /package/dist/web/assets/{prisma-BE8GR1lH.js → prisma-COWJiwdZ.js} +0 -0
- /package/dist/web/assets/{prolog-DOn5lR1e.js → prolog-DFvGKRx6.js} +0 -0
- /package/dist/web/assets/{proto-wr-TpAK_.js → proto-CcK80lFt.js} +0 -0
- /package/dist/web/assets/{puppet-D2Dkv62u.js → puppet-BF60bZ4F.js} +0 -0
- /package/dist/web/assets/{purescript-DvgJgPdy.js → purescript-zL_69MzU.js} +0 -0
- /package/dist/web/assets/{python-C7TlkHhK.js → python-CIwKhfb_.js} +0 -0
- /package/dist/web/assets/{qmldir-CtZMwhcW.js → qmldir-CXNe04Lo.js} +0 -0
- /package/dist/web/assets/{qss-dNZ2btnl.js → qss-C8lAWe6G.js} +0 -0
- /package/dist/web/assets/{r-BlqnNkHS.js → r-CL5ZVL3_.js} +0 -0
- /package/dist/web/assets/{racket-CzRQrGc4.js → racket-BBfh0uh0.js} +0 -0
- /package/dist/web/assets/{raku-BwutWhBF.js → raku-o6E8R5Q3.js} +0 -0
- /package/dist/web/assets/{react-I_EwPIZi.js → react-CBTnT4sY.js} +0 -0
- /package/dist/web/assets/{red-BMXMywmL.js → red-GomRF2Xp.js} +0 -0
- /package/dist/web/assets/{reg-BqOKrIOw.js → reg-_ffDIvx9.js} +0 -0
- /package/dist/web/assets/{regexp-Bero1BN2.js → regexp-Bl5sF65W.js} +0 -0
- /package/dist/web/assets/{rel-BXKWIElA.js → rel-DgMdqDuj.js} +0 -0
- /package/dist/web/assets/{riscv-BbbBYJBo.js → riscv-8b3-Ye4X.js} +0 -0
- /package/dist/web/assets/{ron-BtVTWW4b.js → ron-DrmU1KHP.js} +0 -0
- /package/dist/web/assets/{rose-pine-hvkvQzvU.js → rose-pine-C_-E2tF1.js} +0 -0
- /package/dist/web/assets/{rose-pine-dawn-D7lwhUei.js → rose-pine-dawn-DEfhNlFH.js} +0 -0
- /package/dist/web/assets/{rose-pine-moon-CoHDmsIw.js → rose-pine-moon-BdvX3gdn.js} +0 -0
- /package/dist/web/assets/{rosmsg-CdaZFgI8.js → rosmsg-B6GhGpd5.js} +0 -0
- /package/dist/web/assets/{rust-Dy2qsphD.js → rust-DmC97M1-.js} +0 -0
- /package/dist/web/assets/{sass-Bz7NVxDb.js → sass-B0tJOHLM.js} +0 -0
- /package/dist/web/assets/{save-C4z1p51e.js → save-CtIGOjmx.js} +0 -0
- /package/dist/web/assets/{scala-sXSwsNyq.js → scala-n8zaFOXv.js} +0 -0
- /package/dist/web/assets/{scheme-DS7TUbN7.js → scheme-BKD9ztBU.js} +0 -0
- /package/dist/web/assets/{sdbl-iISFvIep.js → sdbl-D8gB5-rS.js} +0 -0
- /package/dist/web/assets/{shellscript-BkIl4ApC.js → shellscript-BfXlf_Ao.js} +0 -0
- /package/dist/web/assets/{shield-check-C5laObJv.js → shield-check-B0iGUiOK.js} +0 -0
- /package/dist/web/assets/{shield-off-DULFtyLS.js → shield-off-BNLWBhcq.js} +0 -0
- /package/dist/web/assets/{slack-dark-B1eg0_m2.js → slack-dark-CylEddse.js} +0 -0
- /package/dist/web/assets/{slack-ochin-mdkc1ldu.js → slack-ochin-w8wg8vuC.js} +0 -0
- /package/dist/web/assets/{smalltalk-CORtd03t.js → smalltalk-hiAXA64u.js} +0 -0
- /package/dist/web/assets/{snazzy-light-Bc6Q2G89.js → snazzy-light-BwlV3Xty.js} +0 -0
- /package/dist/web/assets/{solarized-dark-CF83zRXM.js → solarized-dark-vmNGdykz.js} +0 -0
- /package/dist/web/assets/{solarized-light-BoKQZaYU.js → solarized-light-DGv_0JXq.js} +0 -0
- /package/dist/web/assets/{solidity-DOgi1N4w.js → solidity-Y7QSH0B1.js} +0 -0
- /package/dist/web/assets/{sparkles-Dqsf3hq6.js → sparkles-Dh-_J2Rd.js} +0 -0
- /package/dist/web/assets/{splunk-BXfw5ZLy.js → splunk-BtgpLjHi.js} +0 -0
- /package/dist/web/assets/{sql-BcVs-eX4.js → sql-CRHYhOia.js} +0 -0
- /package/dist/web/assets/{ssh-config-CLCtNkkd.js → ssh-config-DOqSs3au.js} +0 -0
- /package/dist/web/assets/{stylus-DdP992aO.js → stylus-crCAEaBT.js} +0 -0
- /package/dist/web/assets/{swift-BnGb6Lgc.js → swift-eE3rT7TC.js} +0 -0
- /package/dist/web/assets/{synthwave-84-cg9264l9.js → synthwave-84-BWy14LBX.js} +0 -0
- /package/dist/web/assets/{system-verilog-GbHpszs3.js → system-verilog-DC0-DZM4.js} +0 -0
- /package/dist/web/assets/{systemd-Dz-bNsDQ.js → systemd-to5p6N8I.js} +0 -0
- /package/dist/web/assets/{table-CHmxuh6M.js → table-Bbc783ko.js} +0 -0
- /package/dist/web/assets/{talonscript-CFIidoBA.js → talonscript-DoTcU8wm.js} +0 -0
- /package/dist/web/assets/{tasl-Cu-TRTKx.js → tasl-cNZvUs95.js} +0 -0
- /package/dist/web/assets/{tcl-DwCHCB1K.js → tcl-mZE8sZH8.js} +0 -0
- /package/dist/web/assets/{terraform-BzZw4T1z.js → terraform-CqHPpIfu.js} +0 -0
- /package/dist/web/assets/{tokyo-night-RKsj2-tv.js → tokyo-night-Tp2rTIZd.js} +0 -0
- /package/dist/web/assets/{toml-CirbOgDP.js → toml-CU_vscgn.js} +0 -0
- /package/dist/web/assets/{tsv-CraRcWdU.js → tsv-ik7iFB9D.js} +0 -0
- /package/dist/web/assets/{tsx-CjFg0lgw.js → tsx-BMvvMKiv.js} +0 -0
- /package/dist/web/assets/{turtle-B-WBIOa6.js → turtle-DBqKCq9o.js} +0 -0
- /package/dist/web/assets/{typescript-MpLarYn1.js → typescript-DXJDmMZZ.js} +0 -0
- /package/dist/web/assets/{typespec-B7QlHMZ_.js → typespec-CBseCMtZ.js} +0 -0
- /package/dist/web/assets/{typst-CcHSKFZj.js → typst-4oY25U9y.js} +0 -0
- /package/dist/web/assets/{use-is-mobile-BXGVvczu.js → use-is-mobile-D1weanbj.js} +0 -0
- /package/dist/web/assets/{utils-DoY4yTP-.js → utils-BNRH507E.js} +0 -0
- /package/dist/web/assets/{v-xTGhWZuD.js → v-BXaZ_1oy.js} +0 -0
- /package/dist/web/assets/{vala-DwebjH3H.js → vala-BImWJE7z.js} +0 -0
- /package/dist/web/assets/{vb-BxJT2RAy.js → vb-CLfj2_sy.js} +0 -0
- /package/dist/web/assets/{vendor-xterm-CU6zIYMB.js → vendor-xterm-_yyu5n32.js} +0 -0
- /package/dist/web/assets/{verilog-CvV6RHPD.js → verilog-BWa8Ed2b.js} +0 -0
- /package/dist/web/assets/{vesper-CY3qd7E_.js → vesper-BGj1cg6m.js} +0 -0
- /package/dist/web/assets/{vhdl-B9ZX-sUL.js → vhdl-mByK7mlx.js} +0 -0
- /package/dist/web/assets/{viml-Y42h_ExQ.js → viml-CugmlW5g.js} +0 -0
- /package/dist/web/assets/{vitesse-black-DkXP6Sv-.js → vitesse-black-vPdpy9TL.js} +0 -0
- /package/dist/web/assets/{vitesse-dark-B9CkIB6r.js → vitesse-dark-BuQK3dUh.js} +0 -0
- /package/dist/web/assets/{vitesse-light-C7DHrJCK.js → vitesse-light-B3nz1XL9.js} +0 -0
- /package/dist/web/assets/{vyper-Cnd9s5j-.js → vyper-DH_GTIHG.js} +0 -0
- /package/dist/web/assets/{wasm-DQE71XTB.js → wasm-C-LF9GjX.js} +0 -0
- /package/dist/web/assets/{wasm-iWe7Fzjc.js → wasm-DfVbVJlW.js} +0 -0
- /package/dist/web/assets/{wenyan-Bc5Pnm9l.js → wenyan-CzQkHyHx.js} +0 -0
- /package/dist/web/assets/{wgsl-D-YUAWkP.js → wgsl-Du_M1DW9.js} +0 -0
- /package/dist/web/assets/{wikitext-DYQDUYf2.js → wikitext-BWN_w5S7.js} +0 -0
- /package/dist/web/assets/{wit-P6u7mfwy.js → wit-BR13v5HD.js} +0 -0
- /package/dist/web/assets/{wolfram-6SXLUqao.js → wolfram-BoXxp_Xl.js} +0 -0
- /package/dist/web/assets/{x-BcqfTY_7.js → x-nhriOX9o.js} +0 -0
- /package/dist/web/assets/{yaml-CQiMLVcZ.js → yaml-DpR_EF-d.js} +0 -0
- /package/dist/web/assets/{zenscript-DFMywo_P.js → zenscript-C-EdUtUd.js} +0 -0
- /package/dist/web/assets/{zig-CtAjaIiF.js → zig-BD4eA5nU.js} +0 -0
|
@@ -29,6 +29,42 @@ export const DOCK_PANEL_ID = "__dock__";
|
|
|
29
29
|
*/
|
|
30
30
|
export const DOCK_ALLOWED_TAB_TYPES = new Set<TabType>(["terminal", "system-monitor"]);
|
|
31
31
|
|
|
32
|
+
// ---------------------------------------------------------------------------
|
|
33
|
+
// Floating-window panels
|
|
34
|
+
// ---------------------------------------------------------------------------
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Prefix of the reserved panel IDs that host tabs detached into a floating window.
|
|
38
|
+
* Like the dock, such a panel lives in the `panels` map but is intentionally excluded
|
|
39
|
+
* from `grid`, so all grid math (MAX_ROWS, split, column count) ignores it. The
|
|
40
|
+
* window id is the suffix, which is what ties the panel to its window.
|
|
41
|
+
*/
|
|
42
|
+
export const WINDOW_PANEL_PREFIX = "__win__:";
|
|
43
|
+
|
|
44
|
+
/** Panel ID hosting the tabs of the floating window `windowId`. */
|
|
45
|
+
export function windowPanelId(windowId: string): string {
|
|
46
|
+
return `${WINDOW_PANEL_PREFIX}${windowId}`;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function isWindowPanelId(panelId: string): boolean {
|
|
50
|
+
return panelId.startsWith(WINDOW_PANEL_PREFIX);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** The window a panel belongs to, or null when it is not a window panel. */
|
|
54
|
+
export function windowIdFromPanelId(panelId: string): string | null {
|
|
55
|
+
return isWindowPanelId(panelId) ? panelId.slice(WINDOW_PANEL_PREFIX.length) || null : null;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** Create the off-grid panel for a floating window, with an empty tab list. */
|
|
59
|
+
export function createWindowPanel(windowId: string): Panel {
|
|
60
|
+
return {
|
|
61
|
+
id: windowPanelId(windowId),
|
|
62
|
+
tabs: [],
|
|
63
|
+
activeTabId: null,
|
|
64
|
+
tabHistory: [],
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
32
68
|
/** Visible/height state for the dock — stored per-project via projectDock map. */
|
|
33
69
|
export interface DockState {
|
|
34
70
|
visible: boolean;
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Action factories for tabs that live in a floating window, for usePanelStore.
|
|
3
|
+
*
|
|
4
|
+
* Extracted to keep panel-store.ts near its size budget, mirroring dock-actions.ts.
|
|
5
|
+
* This module is the ONLY writer of `__win__:` panels, which is what keeps the
|
|
6
|
+
* invariant cheap to check: a window panel exists in the `panels` map and never in
|
|
7
|
+
* `grid`, so no grid math (MAX_ROWS, split, column count) can ever see one.
|
|
8
|
+
*
|
|
9
|
+
* Second invariant, enforced after every move: `focusedPanelId` is never a window
|
|
10
|
+
* panel. `moveTab` focuses its target unconditionally, and `resolvePanel()` sends the
|
|
11
|
+
* next `openTab()` with no explicit panel to the focused one — leaving focus on the
|
|
12
|
+
* window would silently open new tabs inside it.
|
|
13
|
+
*/
|
|
14
|
+
import type { StoreApi } from "zustand";
|
|
15
|
+
import type { Panel } from "./panel-utils";
|
|
16
|
+
import {
|
|
17
|
+
createWindowPanel,
|
|
18
|
+
isWindowPanelId,
|
|
19
|
+
windowIdFromPanelId,
|
|
20
|
+
windowPanelId,
|
|
21
|
+
} from "./panel-utils";
|
|
22
|
+
import { persistDock } from "./dock-actions";
|
|
23
|
+
import { loadWindowPanels, saveWindowPanels } from "./window-panel-persistence";
|
|
24
|
+
import { useWindowStore } from "@/components/floating-window/window-store";
|
|
25
|
+
import { MAX_WINDOWS } from "@/components/floating-window/window-geometry";
|
|
26
|
+
import type { PanelStore } from "./panel-store";
|
|
27
|
+
|
|
28
|
+
type Set = StoreApi<PanelStore>["setState"];
|
|
29
|
+
type Get = StoreApi<PanelStore>["getState"];
|
|
30
|
+
|
|
31
|
+
/** Tab types that never detach — the monitor already owns a window kind of its own. */
|
|
32
|
+
const NON_POPPABLE_TAB_TYPES = new Set(["system-monitor"]);
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* A grid panel to hold focus: the preferred one when it is still in the grid, else the
|
|
36
|
+
* first grid panel. Returns null only for an empty grid (nothing can be focused).
|
|
37
|
+
*/
|
|
38
|
+
function gridFocusTarget(grid: string[][], preferred?: string | null): string | null {
|
|
39
|
+
const flat = grid.flat();
|
|
40
|
+
if (preferred && flat.includes(preferred)) return preferred;
|
|
41
|
+
return flat[0] ?? null;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Persist both halves of a window-panel mutation: the global window-panel blob and the
|
|
46
|
+
* active project's layout (the other side of a move is a grid panel). persistDock writes
|
|
47
|
+
* the whole PanelLayout — grid panels, focus and dock — not just the dock.
|
|
48
|
+
*/
|
|
49
|
+
export function persistWindowPanelChange(get: Get): void {
|
|
50
|
+
saveWindowPanels(get().panels);
|
|
51
|
+
persistDock(get);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Keep a floating window and its panel in lockstep after a tab left the panel: an empty
|
|
56
|
+
* tab-host window has no way back to a tab, so it closes with its panel.
|
|
57
|
+
*
|
|
58
|
+
* Every way a tab can leave — closed, moved to the grid or the dock, dragged out — ends
|
|
59
|
+
* here, so the panel and the window are created and destroyed by the same two functions.
|
|
60
|
+
* Both halves are idempotent: a panel already dropped by the caller and a window already
|
|
61
|
+
* closed are both no-ops.
|
|
62
|
+
*/
|
|
63
|
+
export function syncWindowPanel(set: Set, get: Get, panelId: string): void {
|
|
64
|
+
if (get().panels[panelId]?.tabs.length) {
|
|
65
|
+
saveWindowPanels(get().panels);
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
set((s) => {
|
|
69
|
+
const { [panelId]: _dropped, ...rest } = s.panels;
|
|
70
|
+
return { panels: rest };
|
|
71
|
+
});
|
|
72
|
+
saveWindowPanels(get().panels);
|
|
73
|
+
const windowId = windowIdFromPanelId(panelId);
|
|
74
|
+
if (windowId) useWindowStore.getState().close(windowId);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Merge the persisted window panels into the flat panels map, once per session.
|
|
79
|
+
*
|
|
80
|
+
* They are global, so this runs on the first project load and never again — a later
|
|
81
|
+
* switch must not resurrect a panel the user has since re-docked. Live panels win the
|
|
82
|
+
* merge; a stale persisted twin can only be older than what is in memory.
|
|
83
|
+
*/
|
|
84
|
+
let windowPanelsHydrated = false;
|
|
85
|
+
|
|
86
|
+
export function hydrateWindowPanels(set: Set, get: Get): void {
|
|
87
|
+
if (windowPanelsHydrated) return;
|
|
88
|
+
windowPanelsHydrated = true;
|
|
89
|
+
const loaded = loadWindowPanels();
|
|
90
|
+
if (Object.keys(loaded).length === 0) return;
|
|
91
|
+
set({ panels: { ...loaded, ...get().panels } });
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Detach a tab into a new floating window. Returns the window id, or null when the
|
|
96
|
+
* request is rejected — in which case nothing is mutated and the caller reports it.
|
|
97
|
+
*/
|
|
98
|
+
export function makePopOutTab(set: Set, get: Get) {
|
|
99
|
+
return function popOutTab(tabId: string, fromPanelId: string): string | null {
|
|
100
|
+
// The window layer is desktop-only; on mobile a detached tab would be invisible.
|
|
101
|
+
if (get().isMobile()) return null;
|
|
102
|
+
|
|
103
|
+
const from = get().panels[fromPanelId];
|
|
104
|
+
const tab = from?.tabs.find((t) => t.id === tabId);
|
|
105
|
+
if (!tab || NON_POPPABLE_TAB_TYPES.has(tab.type)) return null;
|
|
106
|
+
|
|
107
|
+
// Pre-check the cap: at the cap `open()` focuses the oldest window and returns ITS
|
|
108
|
+
// id, which would attach this tab to an unrelated window.
|
|
109
|
+
const windowStore = useWindowStore.getState();
|
|
110
|
+
if (Object.keys(windowStore.windows).length >= MAX_WINDOWS) return null;
|
|
111
|
+
|
|
112
|
+
const windowId = windowStore.open("tab-host", { originPanelId: fromPanelId, title: tab.title });
|
|
113
|
+
const panelId = windowPanelId(windowId);
|
|
114
|
+
set((s) => ({ panels: { ...s.panels, [panelId]: createWindowPanel(windowId) } }));
|
|
115
|
+
|
|
116
|
+
get().moveTab(tabId, fromPanelId, panelId);
|
|
117
|
+
|
|
118
|
+
const focus = gridFocusTarget(get().grid, fromPanelId);
|
|
119
|
+
if (focus) set({ focusedPanelId: focus });
|
|
120
|
+
persistWindowPanelChange(get);
|
|
121
|
+
return windowId;
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Send every tab of a window's panel back to the grid and drop the panel.
|
|
127
|
+
*
|
|
128
|
+
* Called from the window body's layout-effect cleanup, so it covers every close path
|
|
129
|
+
* (titlebar ×, keyboard close, a programmatic `close()`), and is a no-op once the panel
|
|
130
|
+
* is gone — closing an emptied window re-enters here and must not resurrect anything.
|
|
131
|
+
*/
|
|
132
|
+
export function makeRedockFromWindow(set: Set, get: Get) {
|
|
133
|
+
return function redockFromWindow(windowId: string, originPanelId?: string | null): void {
|
|
134
|
+
const panelId = windowPanelId(windowId);
|
|
135
|
+
const panel = get().panels[panelId];
|
|
136
|
+
if (!panel) return;
|
|
137
|
+
|
|
138
|
+
const target = redockTarget(get(), originPanelId);
|
|
139
|
+
if (target) {
|
|
140
|
+
for (const tab of [...panel.tabs]) get().moveTab(tab.id, panelId, target);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
set((s) => {
|
|
144
|
+
const { [panelId]: _dropped, ...rest } = s.panels;
|
|
145
|
+
// moveTab focused the target; re-assert it here so the resolved target wins even
|
|
146
|
+
// when the last moveTab picked a different one (or none ran at all).
|
|
147
|
+
const focus = gridFocusTarget(s.grid, target ?? s.focusedPanelId);
|
|
148
|
+
return focus ? { panels: rest, focusedPanelId: focus } : { panels: rest };
|
|
149
|
+
});
|
|
150
|
+
persistWindowPanelChange(get);
|
|
151
|
+
|
|
152
|
+
// The body can unmount without the window closing: the whole desktop window layer is
|
|
153
|
+
// dropped below the `md` breakpoint, which re-docks the tabs but would leave the
|
|
154
|
+
// window entry in `ppm-windows` — restored empty and unfillable on the way back, and
|
|
155
|
+
// burning one of MAX_WINDOWS on every reload. `close()` is a no-op when the window is
|
|
156
|
+
// already gone (the ×/keyboard paths), and re-entry here returns early: the panel is
|
|
157
|
+
// deleted above.
|
|
158
|
+
useWindowStore.getState().close(windowId);
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Where a detached tab goes home to: its origin panel while that still exists, else the
|
|
164
|
+
* focused panel when it is a grid panel, else the first grid panel. The origin may be the
|
|
165
|
+
* dock (a terminal parked there before it was detached) but never another window.
|
|
166
|
+
*/
|
|
167
|
+
function redockTarget(state: PanelStore, originPanelId?: string | null): string | null {
|
|
168
|
+
if (originPanelId && state.panels[originPanelId] && !isWindowPanelId(originPanelId)) {
|
|
169
|
+
return originPanelId;
|
|
170
|
+
}
|
|
171
|
+
return gridFocusTarget(state.grid, state.focusedPanelId);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Drop a project's tabs from every window panel, returning the panels map to commit and
|
|
176
|
+
* the windows whose panel is now empty. Used when a project is reloaded: its grid panels
|
|
177
|
+
* are discarded, and a window still showing one of its tabs would outlive the project.
|
|
178
|
+
*/
|
|
179
|
+
export function stripProjectFromWindowPanels(
|
|
180
|
+
panels: Record<string, Panel>,
|
|
181
|
+
projectName: string,
|
|
182
|
+
): { panels: Record<string, Panel>; windowIdsToClose: string[] } {
|
|
183
|
+
const next: Record<string, Panel> = { ...panels };
|
|
184
|
+
const windowIdsToClose: string[] = [];
|
|
185
|
+
|
|
186
|
+
for (const [id, panel] of Object.entries(panels)) {
|
|
187
|
+
if (!isWindowPanelId(id)) continue;
|
|
188
|
+
const tabs = panel.tabs.filter((t) => t.projectId !== projectName);
|
|
189
|
+
if (tabs.length === panel.tabs.length) continue;
|
|
190
|
+
|
|
191
|
+
const windowId = windowIdFromPanelId(id);
|
|
192
|
+
if (tabs.length === 0) {
|
|
193
|
+
delete next[id];
|
|
194
|
+
if (windowId) windowIdsToClose.push(windowId);
|
|
195
|
+
continue;
|
|
196
|
+
}
|
|
197
|
+
const ids = new Set(tabs.map((t) => t.id));
|
|
198
|
+
const tabHistory = panel.tabHistory.filter((h) => ids.has(h));
|
|
199
|
+
next[id] = {
|
|
200
|
+
...panel,
|
|
201
|
+
tabs,
|
|
202
|
+
tabHistory,
|
|
203
|
+
activeTabId:
|
|
204
|
+
panel.activeTabId && ids.has(panel.activeTabId)
|
|
205
|
+
? panel.activeTabId
|
|
206
|
+
: (tabHistory[tabHistory.length - 1] ?? tabs[tabs.length - 1]!.id),
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return { panels: next, windowIdsToClose };
|
|
211
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* localStorage persistence for the off-grid panels that host detached tabs.
|
|
3
|
+
*
|
|
4
|
+
* Deliberately its own global key instead of a field inside `PanelLayout`: floating
|
|
5
|
+
* windows are global (one `ppm-windows` blob for the whole app) while a PanelLayout is
|
|
6
|
+
* per project. Folding a global panel into a per-project blob is what forced the
|
|
7
|
+
* merge/union machinery the dock needs on every project switch. Consequence, accepted:
|
|
8
|
+
* window panels are not synced to the server workspace — the same limitation the window
|
|
9
|
+
* geometry already has.
|
|
10
|
+
*/
|
|
11
|
+
import type { Panel } from "./panel-utils";
|
|
12
|
+
import { isWindowPanelId } from "./panel-utils";
|
|
13
|
+
import type { Tab, TabType } from "./tab-store";
|
|
14
|
+
|
|
15
|
+
const STORAGE_KEY = "ppm-window-panels";
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Tab types a persisted window panel may bring back. Written as an exhaustive record so
|
|
19
|
+
* adding a TabType is a compile error here rather than a silent gap. `system-monitor` is
|
|
20
|
+
* false because it can never be popped out; everything else a crafted blob names is
|
|
21
|
+
* rejected, so it cannot mount an arbitrary component in the privileged window slot.
|
|
22
|
+
*/
|
|
23
|
+
const POPPABLE_TAB_TYPES: Record<TabType, boolean> = {
|
|
24
|
+
terminal: true,
|
|
25
|
+
chat: true,
|
|
26
|
+
editor: true,
|
|
27
|
+
database: true,
|
|
28
|
+
sqlite: true,
|
|
29
|
+
postgres: true,
|
|
30
|
+
"git-diff": true,
|
|
31
|
+
settings: true,
|
|
32
|
+
extension: true,
|
|
33
|
+
"extension-webview": true,
|
|
34
|
+
"conflict-editor": true,
|
|
35
|
+
"system-monitor": false,
|
|
36
|
+
"git-log": true,
|
|
37
|
+
"ai-resource": true,
|
|
38
|
+
group: true,
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export function isPoppableTabType(type: unknown): type is TabType {
|
|
42
|
+
return typeof type === "string" && POPPABLE_TAB_TYPES[type as TabType] === true;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function isValidTab(value: unknown): value is Tab {
|
|
46
|
+
if (!value || typeof value !== "object") return false;
|
|
47
|
+
const t = value as Record<string, unknown>;
|
|
48
|
+
return typeof t.id === "string" && !!t.id && typeof t.title === "string" && isPoppableTabType(t.type);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** Keep only the window panels out of the full panels map, dropping empty ones. */
|
|
52
|
+
function selectWindowPanels(panels: Record<string, Panel>): Record<string, Panel> {
|
|
53
|
+
const out: Record<string, Panel> = {};
|
|
54
|
+
for (const [id, panel] of Object.entries(panels)) {
|
|
55
|
+
if (!isWindowPanelId(id) || panel.tabs.length === 0) continue;
|
|
56
|
+
out[id] = panel;
|
|
57
|
+
}
|
|
58
|
+
return out;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function saveWindowPanels(panels: Record<string, Panel>): void {
|
|
62
|
+
try {
|
|
63
|
+
const windowPanels = selectWindowPanels(panels);
|
|
64
|
+
if (Object.keys(windowPanels).length === 0) localStorage.removeItem(STORAGE_KEY);
|
|
65
|
+
else localStorage.setItem(STORAGE_KEY, JSON.stringify(windowPanels));
|
|
66
|
+
} catch {
|
|
67
|
+
/* quota exceeded or storage disabled — never block a tab move over persistence */
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** Read persisted window panels, dropping anything malformed or not allowed in a window. */
|
|
72
|
+
export function loadWindowPanels(): Record<string, Panel> {
|
|
73
|
+
let raw: string | null = null;
|
|
74
|
+
try {
|
|
75
|
+
raw = localStorage.getItem(STORAGE_KEY);
|
|
76
|
+
} catch {
|
|
77
|
+
return {};
|
|
78
|
+
}
|
|
79
|
+
if (!raw) return {};
|
|
80
|
+
|
|
81
|
+
let parsed: unknown;
|
|
82
|
+
try {
|
|
83
|
+
parsed = JSON.parse(raw);
|
|
84
|
+
} catch {
|
|
85
|
+
return {};
|
|
86
|
+
}
|
|
87
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return {};
|
|
88
|
+
|
|
89
|
+
const out: Record<string, Panel> = {};
|
|
90
|
+
for (const [id, value] of Object.entries(parsed as Record<string, unknown>)) {
|
|
91
|
+
if (!isWindowPanelId(id) || !value || typeof value !== "object") continue;
|
|
92
|
+
const panel = value as Record<string, unknown>;
|
|
93
|
+
if (!Array.isArray(panel.tabs)) continue;
|
|
94
|
+
const tabs = panel.tabs.filter(isValidTab);
|
|
95
|
+
if (tabs.length === 0) continue;
|
|
96
|
+
const ids = new Set(tabs.map((t) => t.id));
|
|
97
|
+
const tabHistory = Array.isArray(panel.tabHistory)
|
|
98
|
+
? panel.tabHistory.filter((h): h is string => typeof h === "string" && ids.has(h))
|
|
99
|
+
: [];
|
|
100
|
+
const activeTabId =
|
|
101
|
+
typeof panel.activeTabId === "string" && ids.has(panel.activeTabId)
|
|
102
|
+
? panel.activeTabId
|
|
103
|
+
: (tabHistory[tabHistory.length - 1] ?? tabs[tabs.length - 1]!.id);
|
|
104
|
+
out[id] = { id, tabs, activeTabId, tabHistory };
|
|
105
|
+
}
|
|
106
|
+
return out;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export function clearWindowPanels(): void {
|
|
110
|
+
try {
|
|
111
|
+
localStorage.removeItem(STORAGE_KEY);
|
|
112
|
+
} catch {
|
|
113
|
+
/* storage disabled */
|
|
114
|
+
}
|
|
115
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure reconciliation between the off-grid window panels and the windows that are
|
|
3
|
+
* actually alive.
|
|
4
|
+
*
|
|
5
|
+
* The two halves are persisted separately (windows are global geometry, panels hold live
|
|
6
|
+
* tabs), so a reload can land on either side alone: a panel whose window blob was dropped
|
|
7
|
+
* would hide its tabs with no way to reach them, and a window whose panel is gone would
|
|
8
|
+
* float empty. Mobile is the same case by construction — the window layer renders
|
|
9
|
+
* nothing there, so no window is live and every detached tab comes back to the grid.
|
|
10
|
+
*/
|
|
11
|
+
import type { Panel } from "./panel-utils";
|
|
12
|
+
import { isWindowPanelId, windowIdFromPanelId, windowPanelId } from "./panel-utils";
|
|
13
|
+
import type { Tab } from "./tab-store";
|
|
14
|
+
|
|
15
|
+
export interface ReconcileInput {
|
|
16
|
+
panels: Record<string, Panel>;
|
|
17
|
+
grid: string[][];
|
|
18
|
+
focusedPanelId: string;
|
|
19
|
+
/** Ids of the tab-host windows currently in the window store. */
|
|
20
|
+
liveWindowIds: readonly string[];
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface ReconcileResult {
|
|
24
|
+
panels: Record<string, Panel>;
|
|
25
|
+
focusedPanelId: string;
|
|
26
|
+
/** Tab-host windows with no panel behind them — the caller closes these. */
|
|
27
|
+
windowIdsToClose: string[];
|
|
28
|
+
/** True when `panels`/`focusedPanelId` differ from the input and must be committed. */
|
|
29
|
+
changed: boolean;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Identity of one reconcile run, for the caller's once-per-run guard.
|
|
34
|
+
*
|
|
35
|
+
* The viewport class belongs in the key, not just the project: crossing the `md`
|
|
36
|
+
* breakpoint unmounts or remounts the entire window layer, which is precisely the split
|
|
37
|
+
* this reconciles. Keying on the project alone lets the first desktop run suppress the
|
|
38
|
+
* mobile repair that must follow it (and the reverse on the way back).
|
|
39
|
+
*/
|
|
40
|
+
export function reconcileRunKey(project: string, isMobile: boolean): string {
|
|
41
|
+
return `${project}|${isMobile}`;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** Append tabs to a panel without disturbing which tab the user was last looking at. */
|
|
45
|
+
function appendTabs(target: Panel, tabs: Tab[]): Panel {
|
|
46
|
+
const known = new Set(target.tabs.map((t) => t.id));
|
|
47
|
+
const incoming = tabs.filter((t) => !known.has(t.id));
|
|
48
|
+
if (incoming.length === 0) return target;
|
|
49
|
+
const merged = [...target.tabs, ...incoming];
|
|
50
|
+
return {
|
|
51
|
+
...target,
|
|
52
|
+
tabs: merged,
|
|
53
|
+
tabHistory: [...target.tabHistory, ...incoming.map((t) => t.id)],
|
|
54
|
+
activeTabId: target.activeTabId ?? merged[merged.length - 1]!.id,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function reconcileTabHostWindows(input: ReconcileInput): ReconcileResult {
|
|
59
|
+
const { grid, liveWindowIds } = input;
|
|
60
|
+
const live = new Set(liveWindowIds);
|
|
61
|
+
const flat = grid.flat();
|
|
62
|
+
|
|
63
|
+
const panels = { ...input.panels };
|
|
64
|
+
let focusedPanelId = input.focusedPanelId;
|
|
65
|
+
let changed = false;
|
|
66
|
+
|
|
67
|
+
// Panels whose window is gone: move the tabs back into the grid and drop the panel.
|
|
68
|
+
// With no grid panel to receive them the panel is left untouched — losing the tabs
|
|
69
|
+
// would be worse than a panel that reconciles on the next load.
|
|
70
|
+
const target = flat.includes(focusedPanelId) ? focusedPanelId : flat[0];
|
|
71
|
+
for (const [panelId, panel] of Object.entries(input.panels)) {
|
|
72
|
+
if (!isWindowPanelId(panelId)) continue;
|
|
73
|
+
const windowId = windowIdFromPanelId(panelId);
|
|
74
|
+
if (windowId && live.has(windowId)) continue;
|
|
75
|
+
if (!target) continue;
|
|
76
|
+
const receiver = panels[target];
|
|
77
|
+
if (!receiver) continue;
|
|
78
|
+
panels[target] = appendTabs(receiver, panel.tabs);
|
|
79
|
+
delete panels[panelId];
|
|
80
|
+
changed = true;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Windows with no panel: nothing can ever render in them.
|
|
84
|
+
const windowIdsToClose = liveWindowIds.filter((id) => !panels[windowPanelId(id)]);
|
|
85
|
+
|
|
86
|
+
// Focus must sit on a grid panel, or the next tab opened with no explicit panel lands
|
|
87
|
+
// off-grid (inside a window, or nowhere at all once its panel is deleted).
|
|
88
|
+
if (!flat.includes(focusedPanelId)) {
|
|
89
|
+
const fallback = flat[0];
|
|
90
|
+
if (fallback) {
|
|
91
|
+
focusedPanelId = fallback;
|
|
92
|
+
changed = true;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return { panels, focusedPanelId, windowIdsToClose, changed };
|
|
97
|
+
}
|
|
@@ -74,13 +74,15 @@
|
|
|
74
74
|
/*
|
|
75
75
|
* Default token values (Aurora Dark). Present before JS runs so the first
|
|
76
76
|
* paint is correct; apply-theme overrides these on <html> at runtime.
|
|
77
|
+
* Surfaces stay opaque here for the same reason they are in the theme itself:
|
|
78
|
+
* a translucent panel lets content bleed through dropdowns and sheets.
|
|
77
79
|
*/
|
|
78
80
|
:root {
|
|
79
81
|
--bg: radial-gradient(120% 120% at 0% 0%, #0e1626 0%, #0a0e17 55%, #080b12 100%);
|
|
80
82
|
--bg-solid: #0a0e17;
|
|
81
|
-
--rail:
|
|
82
|
-
--panel:
|
|
83
|
-
--panel-2:
|
|
83
|
+
--rail: #141820;
|
|
84
|
+
--panel: #141820;
|
|
85
|
+
--panel-2: #141c2e;
|
|
84
86
|
--border: rgba(255, 255, 255, 0.12);
|
|
85
87
|
--border-soft: rgba(255, 255, 255, 0.06);
|
|
86
88
|
--text: #eaeefb;
|
|
@@ -51,16 +51,19 @@ export const auroraLight: PpmTheme = {
|
|
|
51
51
|
mode: "light",
|
|
52
52
|
swatch: ["#f3f7ff", "#2f6bff", "#7c4dff"],
|
|
53
53
|
syntax: { shikiTheme: "github-light" },
|
|
54
|
+
// Surfaces are opaque on purpose: translucent panels let underlying content
|
|
55
|
+
// bleed through dropdowns, sheets and stacked windows and hurt legibility.
|
|
56
|
+
// Values are the old glass tints pre-blended over bgSolid.
|
|
54
57
|
mobileOverrides: {
|
|
55
|
-
panel: "
|
|
56
|
-
panel2: "
|
|
58
|
+
panel: "#ffffff",
|
|
59
|
+
panel2: "#ffffff",
|
|
57
60
|
},
|
|
58
61
|
tokens: {
|
|
59
62
|
bg: "radial-gradient(120% 120% at 0% 0%, #f3f7ff 0%, #eef2fb 55%, #e8edf7 100%)",
|
|
60
63
|
bgSolid: "#f3f7ff",
|
|
61
|
-
rail: "
|
|
62
|
-
panel: "
|
|
63
|
-
panel2: "
|
|
64
|
+
rail: "#fafcff",
|
|
65
|
+
panel: "#fafcff",
|
|
66
|
+
panel2: "#ffffff",
|
|
64
67
|
border: "rgba(20,30,60,0.12)",
|
|
65
68
|
borderSoft: "rgba(20,30,60,0.07)",
|
|
66
69
|
text: "#0f1a33",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{o as e}from"./rolldown-runtime-FhOqtrmT.js";import{S as t,x as n}from"./vendor-markdown-Ls5AcU91.js";import"./vendor-ui-CaeeFO0B.js";import{t as r}from"./save-C4z1p51e.js";import{s as i}from"./api-client-BSB14J4w.js";import"./vendor-mermaid-DrwG0NYt.js";import"./settings-store-C20lqh0G.js";import{n as a}from"./utils-DoY4yTP-.js";import{$n as o,A as s,M as c,N as l,On as u,Qn as d,j as f,k as p,kn as m,s as h}from"./index-CerSxGdf.js";import{t as g}from"./use-monaco-theme-CGucu3fb.js";var _=e(t(),1),v=n();function y({metadata:e}){let t=e?.filePath,n=e?.name,a=e?.resourceType??`skill`,y=e?.scope??`user`,x=e?.readOnly===!0,S=e?.shadowed===!0,C=e?.shadowedBy,w=e?.project??``,[T,E]=(0,_.useState)(``),[D,O]=(0,_.useState)(``),[k,A]=(0,_.useState)(!0),[j,M]=(0,_.useState)(null),[N,P]=(0,_.useState)(!1),F=g(),I=(0,_.useRef)(``),L=T!==D;(0,_.useEffect)(()=>{let e=!1;return A(!0),M(null),c(t,w).then(t=>{e||(E(t.content),O(t.content),I.current=t.content)}).catch(t=>{e||M(t.message)}).finally(()=>{e||A(!1)}),()=>{e=!0}},[t,w]);let R=(0,_.useCallback)(async()=>{if(x||N)return;let e=I.current;if(e!==D){P(!0);try{await l(t,e,w),O(e),E(e),i.success(`Saved`),f.getState().reload()}catch(e){i.error(e.message)}finally{P(!1)}}},[t,w,D,x,N]);(0,_.useEffect)(()=>{let e=e=>{(e.ctrlKey||e.metaKey)&&e.key.toLowerCase()===`s`&&(e.preventDefault(),R())};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[R]);let z=s[a];return(0,v.jsxs)(`div`,{className:`flex h-full flex-col`,children:[(0,v.jsxs)(`div`,{className:`flex items-center gap-2 border-b border-border px-3 py-2 shrink-0`,children:[(0,v.jsx)(z,{className:`size-4 text-text-subtle`}),(0,v.jsx)(`span`,{className:`text-sm font-semibold`,children:n}),(0,v.jsx)(p,{scope:y}),L&&!x&&(0,v.jsx)(`span`,{className:`size-1.5 rounded-full bg-primary`,title:`Unsaved changes`}),(0,v.jsx)(`div`,{className:`flex-1`}),(0,v.jsxs)(`span`,{className:`hidden sm:block text-[11px] text-text-subtle`,children:[a,` · markdown`]}),!x&&(0,v.jsxs)(v.Fragment,{children:[(0,v.jsxs)(`button`,{onClick:()=>E(D),disabled:!L||N,className:`flex items-center gap-1 rounded px-2 py-1 text-xs text-text-secondary hover:bg-surface-elevated disabled:opacity-40`,children:[(0,v.jsx)(u,{className:`size-3.5`}),` Revert`]}),(0,v.jsxs)(`button`,{onClick:()=>void R(),disabled:!L||N,className:`flex items-center gap-1 rounded bg-primary px-2.5 py-1 text-xs font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-40`,children:[N?(0,v.jsx)(o,{className:`size-3.5 animate-spin`}):(0,v.jsx)(r,{className:`size-3.5`}),` Save`]})]})]}),x&&(0,v.jsx)(b,{icon:d,tone:`muted`,children:`Bundled resource — read-only. Duplicate it (from the AI Resources panel) to make an editable copy.`}),S&&C&&(0,v.jsxs)(b,{icon:m,tone:`warn`,children:[`This `,a,` is overridden by another “`,C.name,`” from a higher-priority source (`,C.source,`). It is currently inactive.`]}),(0,v.jsx)(`div`,{className:`min-h-0 flex-1`,children:k?(0,v.jsx)(`div`,{className:`flex h-full items-center justify-center`,children:(0,v.jsx)(o,{className:`size-5 animate-spin text-primary`})}):j?(0,v.jsx)(`div`,{className:`p-6 text-center text-sm text-destructive`,children:j}):(0,v.jsx)(h,{height:`100%`,language:`markdown`,theme:F,value:T,onChange:e=>{let t=e??``;I.current=t,E(t)},options:{readOnly:x,minimap:{enabled:!1},fontSize:13,wordWrap:`on`,scrollBeyondLastLine:!1,lineNumbers:`on`}})})]})}function b({icon:e,tone:t,children:n}){return(0,v.jsxs)(`div`,{className:a(`flex items-start gap-2 px-3 py-2 text-[12px] shrink-0 border-b border-border`,t===`warn`?`bg-amber-500/10 text-amber-300`:`bg-surface-elevated text-text-secondary`),children:[(0,v.jsx)(e,{className:`mt-0.5 size-3.5 shrink-0`}),(0,v.jsx)(`span`,{children:n})]})}export{y as AiResourceEditor};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import"./vendor-markdown-Ls5AcU91.js";import"./vendor-ui-CaeeFO0B.js";import{i as e,n as t}from"./api-client-BSB14J4w.js";export{t as api,e as projectUrl};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import"./vendor-markdown-Ls5AcU91.js";import"./vendor-ui-CaeeFO0B.js";import"./api-client-BSB14J4w.js";import{v as e}from"./api-settings-kQHV6pYZ.js";export{e as updateDeviceName};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{K as e}from"./vendor-mermaid-DrwG0NYt.js";export{e as createArchitectureServices};
|