@hienlh/ppm 0.18.8 → 0.18.10
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/group-protected-probe.ts +21 -0
- package/.spike/s.err +63 -0
- package/.spike/tunnel.err +22 -0
- package/.spike/w.err +28 -0
- package/CHANGELOG.md +21 -0
- package/CLAUDE.md +1 -0
- package/assets/skills/ppm/SKILL.md +1 -1
- package/assets/skills/ppm/references/cli-reference.md +4 -4
- package/assets/skills/ppm/references/http-api.md +4 -3
- package/dist/web/assets/{ai-resource-editor-BydGrxjb.js → ai-resource-editor-mdDKG-rw.js} +1 -1
- package/dist/web/assets/{angular-html-jfMqUuRd.js → angular-html-Ctz0zN01.js} +1 -1
- package/dist/web/assets/{angular-ts-wytn9PMm.js → angular-ts-QXHpgB1C.js} +1 -1
- package/dist/web/assets/{api-settings-DlcoR5QT.js → api-settings-nblja3Rk.js} +1 -1
- package/dist/web/assets/{apl-i-ahKx6O.js → apl-b9KVk-O4.js} +1 -1
- package/dist/web/assets/architecture-PBZL5I3N-C7ra20CE.js +1 -0
- package/dist/web/assets/{astro-DVBCJfG6.js → astro-BlFEeGYr.js} +1 -1
- package/dist/web/assets/{audio-preview-DzBGq9Lk.js → audio-preview-CZLmhf__.js} +1 -1
- package/dist/web/assets/{blade-BHlL8SqU.js → blade-CGkj2MUI.js} +1 -1
- package/dist/web/assets/{bsl-D-UOfR1F.js → bsl-CVsbb6ap.js} +1 -1
- package/dist/web/assets/button-BA_fJOtX.js +1 -0
- package/dist/web/assets/{cairo-Bn6rucli.js → cairo-BbIHl2iE.js} +1 -1
- package/dist/web/assets/chat-tab-C060A94y.js +15 -0
- package/dist/web/assets/circle-hjUGru6R.js +1 -0
- package/dist/web/assets/circle-question-mark-CzR7YRc-.js +1 -0
- package/dist/web/assets/{cobol-Byn9FYKu.js → cobol-BWSGjmWb.js} +1 -1
- package/dist/web/assets/code-editor-WELegzdp.js +10 -0
- package/dist/web/assets/{coffee-DjBl4gm-.js → coffee-CWGNOxds.js} +1 -1
- package/dist/web/assets/{conflict-editor-CRConSGG.js → conflict-editor-fRTU3f1o.js} +3 -3
- package/dist/web/assets/{context-menu-DkQdt6YA.js → context-menu-Cq0u3SK9.js} +1 -1
- package/dist/web/assets/{cpp-CKzic-3E.js → cpp-DHGV24J2.js} +1 -1
- package/dist/web/assets/{crystal-Bkg-Ly_g.js → crystal-Vlwf2UMP.js} +1 -1
- package/dist/web/assets/{csv-preview-BtCGfmrq.js → csv-preview-D1d0cxOJ.js} +1 -1
- package/dist/web/assets/{data-grid-overlay-editor-B1mTl3KS.js → data-grid-overlay-editor-D9il5DZS.js} +1 -1
- package/dist/web/assets/{database-viewer-2M5sKRqb.js → database-viewer-DevnWTV4.js} +1 -1
- package/dist/web/assets/{diff-viewer-BMr7vOvZ.js → diff-viewer-DGxVg1pD.js} +1 -1
- package/dist/web/assets/{docx-preview-BpG2kr_-.js → docx-preview-Cx-zLwAw.js} +1 -1
- package/dist/web/assets/{edge-DVbZnd3Y.js → edge-Bhqk64zS.js} +1 -1
- package/dist/web/assets/{edit-diff-preview-BivQwZMD.js → edit-diff-preview-gq6ALf2B.js} +1 -1
- package/dist/web/assets/{elixir-Dwi8Wu7W.js → elixir-D466WCFm.js} +1 -1
- package/dist/web/assets/{elm-DtIv-HXJ.js → elm-Bfs2qNPR.js} +1 -1
- package/dist/web/assets/{erb-D3HEDz1x.js → erb-WI7jUaB6.js} +1 -1
- package/dist/web/assets/{erlang-2MjTCzGz.js → erlang-BCBe8nCc.js} +1 -1
- package/dist/web/assets/{esm-CZ8B8Ba2.js → esm-CZs9WVDO.js} +1 -1
- package/dist/web/assets/{explorer-body-DXufyj-9.js → explorer-body-j_4hVc34.js} +2 -2
- package/dist/web/assets/{explorer-window-content-B3krk4G1.js → explorer-window-content-DdrGwk3w.js} +1 -1
- package/dist/web/assets/{extension-webview-12M45CGq.js → extension-webview-BH_mWYMe.js} +1 -1
- package/dist/web/assets/format-bytes-BE_W3UBg.js +1 -0
- package/dist/web/assets/{fortran-fixed-form-BLyAtyPM.js → fortran-fixed-form-CXLIv8Ox.js} +1 -1
- package/dist/web/assets/{fsharp-Bxbn_gbr.js → fsharp-CZsYmiw9.js} +1 -1
- package/dist/web/assets/{gdresource-sFMY4D2Q.js → gdresource-BGRvoWfC.js} +1 -1
- package/dist/web/assets/{git-commit-BzB9Lio5.js → git-commit-DH6mY3Km.js} +1 -1
- package/dist/web/assets/{git-log-panel-Cp4k3tX_.js → git-log-panel-CfpXRJcP.js} +1 -1
- package/dist/web/assets/{git-rebase-CKSVd848.js → git-rebase-C5Gql6Ma.js} +1 -1
- package/dist/web/assets/gitGraph-HDMCJU4V-D4hYLNJU.js +1 -0
- package/dist/web/assets/{glide-data-grid-B0BB0VDl.js → glide-data-grid-n4ox_uev.js} +7 -7
- package/dist/web/assets/{glimmer-js-BY8aExAJ.js → glimmer-js-1-6JMJlj.js} +1 -1
- package/dist/web/assets/{glimmer-ts-Bak54dBX.js → glimmer-ts-C_Njj0nK.js} +1 -1
- package/dist/web/assets/{glsl-nR2eaJQe.js → glsl-DbkxE1TN.js} +1 -1
- package/dist/web/assets/{graphql-CGPPFAU6.js → graphql-BK75fiXl.js} +1 -1
- package/dist/web/assets/group-chat-tab-dYuuknLN.js +1 -0
- package/dist/web/assets/{hack-CXIMX-Ol.js → hack-DG151vit.js} +1 -1
- package/dist/web/assets/{haml-tPY-9Pfm.js → haml-DKeIPQWM.js} +1 -1
- package/dist/web/assets/{handlebars-BuW1LT7T.js → handlebars-398uCI13.js} +1 -1
- package/dist/web/assets/{html-bgVcwZ-t.js → html-NLWdst5q.js} +1 -1
- package/dist/web/assets/{html-derivative-D6-IxTgn.js → html-derivative-CJf_Le2z.js} +1 -1
- package/dist/web/assets/{http-CJ1zyB-h.js → http-G1K2FozA.js} +1 -1
- package/dist/web/assets/{hurl-CmoT7l3T.js → hurl-WDC6sSBz.js} +1 -1
- package/dist/web/assets/{hxml-CztOsL8o.js → hxml-Dc3jBXuf.js} +1 -1
- package/dist/web/assets/{image-preview-3HfuxA0N.js → image-preview-Ss38ex8g.js} +1 -1
- package/dist/web/assets/index-BiTiXgBZ.css +2 -0
- package/dist/web/assets/index-Ch8l9de-.js +52 -0
- package/dist/web/assets/info-3K5VOQVL-lRlrTlkb.js +1 -0
- package/dist/web/assets/{jinja-B1pq3jJq.js → jinja-CWsQj2y0.js} +1 -1
- package/dist/web/assets/{jison-D8B5pCwA.js → jison-CciJg2NW.js} +1 -1
- package/dist/web/assets/{julia-D0K3bwpU.js → julia-IOQNJAB7.js} +1 -1
- package/dist/web/assets/{just-B9Jlddu-.js → just-BGdHchwS.js} +1 -1
- package/dist/web/assets/{keybindings-store-oMJmtpH4.js → keybindings-store-CDfTjwZX.js} +1 -1
- package/dist/web/assets/{latex-BPJSSE6j.js → latex-D6TOl-L2.js} +1 -1
- package/dist/web/assets/{liquid-lv10fo4U.js → liquid-CVSvu_Wn.js} +1 -1
- package/dist/web/assets/{lua-PNuaIBEF.js → lua-CcKiU6HW.js} +1 -1
- package/dist/web/assets/{markdown-renderer-DPcoPjmO.js → markdown-renderer-B317vEys.js} +3 -3
- package/dist/web/assets/markdown-renderer-CpRlpLHw.js +1 -0
- package/dist/web/assets/{marko-Du3frD6X.js → marko--UOicMGo.js} +1 -1
- package/dist/web/assets/{mdc-BeDVcFRl.js → mdc-D690aU2C.js} +1 -1
- package/dist/web/assets/{mobile-explorer-sheet-CEVcU964.js → mobile-explorer-sheet-D1Bv9UCT.js} +1 -1
- package/dist/web/assets/{nextflow-DkcXP71s.js → nextflow-DR8PhpF8.js} +1 -1
- package/dist/web/assets/{nginx-C5n8N_bt.js → nginx-Qb9pUk1g.js} +1 -1
- package/dist/web/assets/{nim-CIhyfs-A.js → nim-DLa8R3NS.js} +1 -1
- package/dist/web/assets/{notification-store-B8AqxwRT.js → notification-store-KwTAZT8b.js} +1 -1
- package/dist/web/assets/{number-overlay-editor-NgOsWJ7x.js → number-overlay-editor-D9SkFg1Y.js} +1 -1
- package/dist/web/assets/overview-panel-BxDohIEa.js +1 -0
- package/dist/web/assets/packet-RMMSAZCW-BIhk1mvp.js +1 -0
- package/dist/web/assets/{pdf-preview-BslNoDFw.js → pdf-preview-dwRe54ht.js} +1 -1
- package/dist/web/assets/{perl-Cf31sZYE.js → perl-AMNGIneF.js} +1 -1
- package/dist/web/assets/{php-Dzl_MDIW.js → php-CDsOOxXn.js} +1 -1
- package/dist/web/assets/pie-UPGHQEXC-SLS6i76l.js +1 -0
- package/dist/web/assets/{postgres-viewer-BtSXQ3S4.js → postgres-viewer-BWZLW7kI.js} +3 -3
- package/dist/web/assets/process-table-CI-fnVsy.js +1 -0
- package/dist/web/assets/{pug-CxSYHrB3.js → pug-C2kdkhQ6.js} +1 -1
- package/dist/web/assets/{qml-DlEjGhwN.js → qml-DRDkUp75.js} +1 -1
- package/dist/web/assets/radar-KQ55EAFF-JJ6O1Er_.js +1 -0
- package/dist/web/assets/{razor-KVt5uW14.js → razor-wY_6wUeC.js} +1 -1
- package/dist/web/assets/resolve-theme-B9ABAH_3.js +1 -0
- package/dist/web/assets/{rst-D5BwNTnw.js → rst-BRpofyNs.js} +1 -1
- package/dist/web/assets/{ruby-D5fejQwd.js → ruby-ieATBhWm.js} +1 -1
- package/dist/web/assets/{sas-Bj7B1CB2.js → sas-CoOOEbOO.js} +1 -1
- package/dist/web/assets/{scss-BB0CUoCL.js → scss-_nWV0bsb.js} +1 -1
- package/dist/web/assets/{settings-store-C9YT1Hir.js → settings-store-C20lqh0G.js} +2 -2
- package/dist/web/assets/settings-tab-mPxrKkfm.js +1 -0
- package/dist/web/assets/{shaderlab-BdjEZUMc.js → shaderlab-XkqfIfO8.js} +1 -1
- package/dist/web/assets/{shellsession-Bp1OA1rR.js → shellsession-BKBIqTlM.js} +1 -1
- package/dist/web/assets/{soy-DlYz3wsC.js → soy-oVDnPzzh.js} +1 -1
- package/dist/web/assets/{sparql-CdfII5Jd.js → sparql-N2VclEsF.js} +1 -1
- package/dist/web/assets/{sql-query-editor-CkvpmXyA.js → sql-query-editor-BwPjEaP9.js} +1 -1
- package/dist/web/assets/{sqlite-viewer-CJbP6ruh.js → sqlite-viewer-Cs-_D942.js} +1 -1
- package/dist/web/assets/{stata-BvUA6GUW.js → stata-BuuClVDg.js} +1 -1
- package/dist/web/assets/{surrealql--DLNbTyI.js → surrealql-DE5_63MS.js} +1 -1
- package/dist/web/assets/{svelte-CBfSsG4n.js → svelte--YWjlOrK.js} +1 -1
- package/dist/web/assets/system-monitor-body-CV7-0hZG.js +2 -0
- package/dist/web/assets/system-monitor-tab-Ce-8Axhh.js +1 -0
- package/dist/web/assets/system-monitor-window-content-CetwYOQy.js +1 -0
- package/dist/web/assets/team-member-sheet-CjgaQjsZ.js +2 -0
- package/dist/web/assets/{team-member-window-content-Cxh-HF2V.js → team-member-window-content-DNJiYWS7.js} +1 -1
- package/dist/web/assets/{templ-Dv8zpKZW.js → templ-MlpvJx4a.js} +1 -1
- package/dist/web/assets/{terminal-tab-gQCs_fyx.js → terminal-tab-DF7521sT.js} +3 -3
- package/dist/web/assets/{tex-CsrOiqh1.js → tex-0loAoXJG.js} +1 -1
- package/dist/web/assets/{tool-cards-BG2fz83z.js → tool-cards-DCAXGDJI.js} +5 -5
- package/dist/web/assets/treemap-KZPCXAKY-Be3KNmns.js +1 -0
- package/dist/web/assets/{ts-tags-3T98k4EJ.js → ts-tags-pt-Ug0hK.js} +1 -1
- package/dist/web/assets/{twig-u6QZ45FH.js → twig-DOePpLOL.js} +1 -1
- package/dist/web/assets/{use-monaco-theme-DaqI7O-a.js → use-monaco-theme-DSCdlrjO.js} +1 -1
- package/dist/web/assets/{use-open-team-member-DKpstvLS.js → use-open-team-member-H4k74HnV.js} +1 -1
- package/dist/web/assets/{use-websocket-KVhDtbwK.js → use-websocket-iJfc7EbK.js} +1 -1
- package/dist/web/assets/{vendor-mermaid-Bg4vE8QA.js → vendor-mermaid-DrwG0NYt.js} +1 -1
- package/dist/web/assets/{video-preview-CVEUDZBj.js → video-preview-B0ZWpX0F.js} +1 -1
- package/dist/web/assets/{vue-CxIsxtwn.js → vue-D6f-rprj.js} +1 -1
- package/dist/web/assets/{vue-html-BGL5qnuH.js → vue-html-DEYRkS1V.js} +1 -1
- package/dist/web/assets/{vue-vine-DHPh_gMr.js → vue-vine-CxSG2ojf.js} +1 -1
- package/dist/web/assets/{xml-C-vM2m7J.js → xml-DhrxbATj.js} +1 -1
- package/dist/web/assets/{xsl-DvTXNwuO.js → xsl-CU0ZndUO.js} +1 -1
- package/dist/web/index.html +18 -17
- package/dist/web/sw.js +1 -1
- package/docs/system-architecture.md +2 -2
- package/package.json +1 -1
- package/packages/vscode-compat/node_modules/.bin/tsc.bunx +0 -0
- package/packages/vscode-compat/node_modules/.bin/tsc.exe +0 -0
- package/packages/vscode-compat/node_modules/.bin/tsserver.bunx +0 -0
- package/packages/vscode-compat/node_modules/.bin/tsserver.exe +0 -0
- package/src/server/index.ts +2 -8
- package/src/server/routes/resources.ts +119 -73
- package/src/services/autostart-generator.ts +79 -7
- package/src/services/autostart-register.ts +15 -2
- package/src/services/edge-forwarder.ts +191 -191
- package/src/services/proc-table-linux.ts +4 -0
- package/src/services/redact-secrets.ts +33 -0
- package/src/services/system-metrics/cpu-memory-collector.ts +101 -0
- package/src/services/system-metrics/disk-net-collector-darwin.ts +75 -0
- package/src/services/system-metrics/disk-net-collector-linux.ts +88 -0
- package/src/services/system-metrics/disk-net-collector-windows.ts +57 -0
- package/src/services/system-metrics/gpu-collector-nvidia.ts +78 -0
- package/src/services/system-metrics/gpu-process-memory-nvidia.ts +66 -0
- package/src/services/system-metrics/gpu-process-usage-windows.ts +138 -0
- package/src/services/system-metrics/kill-executor.ts +85 -0
- package/src/services/system-metrics/kill-guard.ts +124 -0
- package/src/services/system-metrics/kill-identity-resolver.ts +72 -0
- package/src/services/system-metrics/kill-request-handler.ts +79 -0
- package/src/services/system-metrics/metrics-collector-lock.ts +36 -0
- package/src/services/system-metrics/metrics-poll-scheduler.ts +83 -0
- package/src/services/system-metrics/metrics-subscriber-registry.ts +85 -0
- package/src/services/system-metrics/powershell-session-bootstrap.ts +48 -0
- package/src/services/system-metrics/powershell-session.ts +182 -0
- package/src/services/system-metrics/ppm-process-ownership.ts +34 -0
- package/src/services/system-metrics/ppm-protected-pids.ts +84 -0
- package/src/services/system-metrics/process-collector-darwin.ts +141 -0
- package/src/services/system-metrics/process-collector-linux.ts +85 -0
- package/src/services/system-metrics/process-collector-types.ts +80 -0
- package/src/services/system-metrics/process-collector-windows-parse.ts +153 -0
- package/src/services/system-metrics/process-collector-windows.ts +136 -0
- package/src/services/system-metrics/process-cpu-delta.ts +61 -0
- package/src/services/system-metrics/process-grouping.ts +142 -0
- package/src/services/system-metrics/process-io-delta.ts +84 -0
- package/src/services/system-metrics/process-io-linux.ts +46 -0
- package/src/services/system-metrics/process-net-collector-darwin.ts +103 -0
- package/src/services/system-metrics/process-rows-builder.ts +111 -0
- package/src/services/system-metrics/rate-delta.ts +47 -0
- package/src/services/system-metrics/system-metrics-platform.ts +51 -0
- package/src/services/system-metrics/system-metrics-tick.ts +178 -0
- package/src/services/system-metrics/system-metrics.service.ts +212 -0
- package/src/services/windows-process-tree.ts +351 -351
- package/src/types/system-metrics.ts +199 -0
- package/src/web/components/floating-window/window-content-registry.ts +2 -0
- package/src/web/components/floating-window/window-persistence.ts +1 -1
- package/src/web/components/floating-window/window-store-types.ts +1 -1
- package/src/web/components/system/build-kill-request.ts +36 -0
- package/src/web/components/system/chart-scale.ts +28 -0
- package/src/web/components/system/cpu-core-bars.tsx +33 -0
- package/src/web/components/system/kill-confirm-dialog.tsx +105 -0
- package/src/web/components/system/metric-chart-canvas.tsx +107 -0
- package/src/web/components/system/overview-cards/cpu-card.tsx +39 -0
- package/src/web/components/system/overview-cards/disk-card.tsx +41 -0
- package/src/web/components/system/overview-cards/gpu-card.tsx +33 -0
- package/src/web/components/system/overview-cards/mem-card.tsx +32 -0
- package/src/web/components/system/overview-cards/net-card.tsx +41 -0
- package/src/web/components/system/overview-panel.tsx +97 -0
- package/src/web/components/system/process-columns-grid.ts +103 -0
- package/src/web/components/system/process-group-row.tsx +94 -0
- package/src/web/components/system/process-row-format.ts +56 -0
- package/src/web/components/system/process-row.tsx +81 -0
- package/src/web/components/system/process-table-model.ts +109 -0
- package/src/web/components/system/process-table-sort.ts +90 -0
- package/src/web/components/system/process-table-toolbar.tsx +159 -0
- package/src/web/components/system/process-table-totals.ts +49 -0
- package/src/web/components/system/process-table.tsx +146 -0
- package/src/web/components/system/resolve-open-system-monitor-action.ts +29 -0
- package/src/web/components/system/resource-status-bar.tsx +17 -16
- package/src/web/components/system/sortable-header.tsx +90 -0
- package/src/web/components/system/system-monitor-body.tsx +146 -0
- package/src/web/components/system/system-monitor-tab.tsx +2 -185
- package/src/web/components/system/system-monitor-window-content.tsx +18 -0
- package/src/web/components/system/use-column-widths.ts +91 -0
- package/src/web/components/system/use-open-system-monitor.ts +34 -0
- package/src/web/components/system/use-process-kill.ts +100 -0
- package/src/web/hooks/resource-monitor-lease.ts +55 -0
- package/src/web/hooks/use-element-width.ts +27 -0
- package/src/web/hooks/use-resource-monitor.ts +113 -35
- package/src/web/lib/format-bytes.ts +16 -0
- package/src/web/styles/globals.css +5 -3
- package/src/web/theme/builtin/aurora.ts +8 -5
- package/dist/web/assets/architecture-PBZL5I3N-Bs7wzj-W.js +0 -1
- package/dist/web/assets/arrow-right-DubGFkN8.js +0 -1
- package/dist/web/assets/button-B4MWPjWj.js +0 -1
- package/dist/web/assets/chat-tab-pBGQ9SCY.js +0 -15
- package/dist/web/assets/circle-question-mark-CENpx4oA.js +0 -1
- package/dist/web/assets/code-editor-XviNXdzi.js +0 -10
- package/dist/web/assets/gitGraph-HDMCJU4V-D7i54kbM.js +0 -1
- package/dist/web/assets/group-chat-tab-CcG_NXIS.js +0 -1
- package/dist/web/assets/index-BAVBuKmT.js +0 -52
- package/dist/web/assets/index-oxsyfDa0.css +0 -2
- package/dist/web/assets/info-3K5VOQVL-BV41AzR9.js +0 -1
- package/dist/web/assets/markdown-renderer-Dg5HE9Zq.js +0 -1
- package/dist/web/assets/packet-RMMSAZCW-CaJoP44m.js +0 -1
- package/dist/web/assets/pie-UPGHQEXC-DSGZmNw2.js +0 -1
- package/dist/web/assets/radar-KQ55EAFF-Be4VUTs0.js +0 -1
- package/dist/web/assets/resolve-theme-CJvkL8hU.js +0 -1
- package/dist/web/assets/settings-tab-COSUzGl8.js +0 -1
- package/dist/web/assets/system-monitor-tab-DThAFSd_.js +0 -1
- package/dist/web/assets/team-member-sheet-M83B4znI.js +0 -2
- package/dist/web/assets/treemap-KZPCXAKY-Cu2zgbxU.js +0 -1
- package/src/services/resource-monitor-utils.ts +0 -141
- package/src/services/resource-monitor.service.ts +0 -147
- package/src/web/components/system/sparkline-canvas.tsx +0 -64
- package/src/web/components/system/system-monitor-group-row.tsx +0 -153
- /package/dist/web/assets/{abap-C1K0-wzc.js → abap-MRbmsXOs.js} +0 -0
- /package/dist/web/assets/{actionscript-3-CJhQVjLA.js → actionscript-3-BDDHKqa4.js} +0 -0
- /package/dist/web/assets/{ada-Bt8r9fME.js → ada-DpuV9KwV.js} +0 -0
- /package/dist/web/assets/{andromeeda-DF1I8qi3.js → andromeeda-D6qUCKJo.js} +0 -0
- /package/dist/web/assets/{apache-CnlleE6P.js → apache-CX1NU_Tl.js} +0 -0
- /package/dist/web/assets/{apex-j0C6Xmk6.js → apex-B4-aoQ3K.js} +0 -0
- /package/dist/web/assets/{api-settings-DfNRPr1q.js → api-settings-kQHV6pYZ.js} +0 -0
- /package/dist/web/assets/{api-themes-8WTH6KpV.js → api-themes-CrK0tkW_.js} +0 -0
- /package/dist/web/assets/{applescript-DO7AnO8U.js → applescript-Dm9NI6KR.js} +0 -0
- /package/dist/web/assets/{apply-theme-CNj1iA-v.js → apply-theme-BH_d4amk.js} +0 -0
- /package/dist/web/assets/{ara-i83AydZj.js → ara-BGN8GAYn.js} +0 -0
- /package/dist/web/assets/{asciidoc-DbBA6-sF.js → asciidoc-s_yVuR3t.js} +0 -0
- /package/dist/web/assets/{asm-B5S47Rgr.js → asm-BzQdSvTe.js} +0 -0
- /package/dist/web/assets/{aurora-x-De_IaSKw.js → aurora-x-BJTLETG_.js} +0 -0
- /package/dist/web/assets/{awk-CfyLHXqS.js → awk-BQEGWxvX.js} +0 -0
- /package/dist/web/assets/{ayu-dark-DTLdZ1Si.js → ayu-dark-CpTORmLc.js} +0 -0
- /package/dist/web/assets/{ayu-light-DTOfkzhu.js → ayu-light-D8PVj-e6.js} +0 -0
- /package/dist/web/assets/{ayu-mirage-DsAECCMv.js → ayu-mirage-DyElQHtm.js} +0 -0
- /package/dist/web/assets/{ballerina-CumGp9A7.js → ballerina-C82NkRtj.js} +0 -0
- /package/dist/web/assets/{bat-Ca2SBbYN.js → bat-0X7DtGI-.js} +0 -0
- /package/dist/web/assets/{beancount-CqyXBwwF.js → beancount-Xgvy6YRl.js} +0 -0
- /package/dist/web/assets/{berry-yl-kJr_H.js → berry-CCT2pZcQ.js} +0 -0
- /package/dist/web/assets/{bibtex-DoFFszjV.js → bibtex-CpXgZ9M_.js} +0 -0
- /package/dist/web/assets/{bicep-CWPi4nfK.js → bicep-fkeSA62l.js} +0 -0
- /package/dist/web/assets/{bird2-DXew-ut0.js → bird2-Co7SeAI8.js} +0 -0
- /package/dist/web/assets/{c-clbySDvd.js → c-BpmrTvJh.js} +0 -0
- /package/dist/web/assets/{c3-B65jvSM1.js → c3-BZ_Z0RrR.js} +0 -0
- /package/dist/web/assets/{cadence-Cm8tQTHN.js → cadence-B0GBC8OF.js} +0 -0
- /package/dist/web/assets/{can-open-in-ppm-DXGOSUQc.js → can-open-in-ppm-omBzUBBq.js} +0 -0
- /package/dist/web/assets/{catppuccin-frappe-DLeGslh_.js → catppuccin-frappe-DIt_xR7m.js} +0 -0
- /package/dist/web/assets/{catppuccin-latte-CR5GeHws.js → catppuccin-latte-Dw40AcqA.js} +0 -0
- /package/dist/web/assets/{catppuccin-macchiato-p-XgjxhP.js → catppuccin-macchiato-BJ7DfVEF.js} +0 -0
- /package/dist/web/assets/{catppuccin-mocha-B8QOAZLl.js → catppuccin-mocha-NI2lfXzU.js} +0 -0
- /package/dist/web/assets/{clarity-DPulbvKH.js → clarity-F39L0xMJ.js} +0 -0
- /package/dist/web/assets/{clock-D493FU_D.js → clock-CvhF4DJP.js} +0 -0
- /package/dist/web/assets/{clojure-DFuWS20u.js → clojure-DloMkd8K.js} +0 -0
- /package/dist/web/assets/{cmake-DejCqcu4.js → cmake-CwerJun_.js} +0 -0
- /package/dist/web/assets/{code-CLF5x7KK.js → code-DDPoqVri.js} +0 -0
- /package/dist/web/assets/{codeowners-BwAyqWIH.js → codeowners-CQyVz4Qf.js} +0 -0
- /package/dist/web/assets/{codeql-DgSwFjqI.js → codeql-Bb229zuY.js} +0 -0
- /package/dist/web/assets/{common-lisp-CxIVJCtf.js → common-lisp-KMlIwq5I.js} +0 -0
- /package/dist/web/assets/{copy-BApI9v7Z.js → copy-DKn11Pye.js} +0 -0
- /package/dist/web/assets/{coq-DLSjSnmf.js → coq-DHX_3IIo.js} +0 -0
- /package/dist/web/assets/{csharp-C1HHzXBp.js → csharp-CEmCZv9Q.js} +0 -0
- /package/dist/web/assets/{css-VXsMY--y.js → css-CqZqBD05.js} +0 -0
- /package/dist/web/assets/{csv-BEbcJdHz.js → csv-l1g_V5MV.js} +0 -0
- /package/dist/web/assets/{csv-parser-BRtnJCfv.js → csv-parser-CnS0wqr6.js} +0 -0
- /package/dist/web/assets/{cue-BkDnFqUD.js → cue-BrxRmilg.js} +0 -0
- /package/dist/web/assets/{cypher-1cMqojSQ.js → cypher-rZkKwqZc.js} +0 -0
- /package/dist/web/assets/{d-BnYjRXtH.js → d-BALR-QuP.js} +0 -0
- /package/dist/web/assets/{dark-plus-XfbaH7kZ.js → dark-plus-Cj7rVwh-.js} +0 -0
- /package/dist/web/assets/{dart-Ca7s-8hK.js → dart-CWQcdkXk.js} +0 -0
- /package/dist/web/assets/{data-grid-types-BXwlFMzs.js → data-grid-types-CYvF-xK5.js} +0 -0
- /package/dist/web/assets/{database-B9okYLx6.js → database-BH0urvbs.js} +0 -0
- /package/dist/web/assets/{dax-CmuOw-mY.js → dax-BNHD-QBA.js} +0 -0
- /package/dist/web/assets/{desktop-C2gJ6Ovb.js → desktop-CN0IXPrP.js} +0 -0
- /package/dist/web/assets/{diff-BCEo1Ej7.js → diff-BtOXapES.js} +0 -0
- /package/dist/web/assets/{dist-CUPbqNnL.js → dist-DB1Oaqcc.js} +0 -0
- /package/dist/web/assets/{dist-DOlBnxFX.js → dist-Di6G_5jU.js} +0 -0
- /package/dist/web/assets/{docker-DN2jlyAh.js → docker-DNsAo_qO.js} +0 -0
- /package/dist/web/assets/{dotenv-NExMY2kS.js → dotenv-D6Pl6aOU.js} +0 -0
- /package/dist/web/assets/{download-D9UYwY0-.js → download-zCATy4x4.js} +0 -0
- /package/dist/web/assets/{dracula-B9lbE01y.js → dracula-C3m-w12D.js} +0 -0
- /package/dist/web/assets/{dracula-soft-CMBBfKF_.js → dracula-soft-BYqvXm6Z.js} +0 -0
- /package/dist/web/assets/{dream-maker-DEyDwFsd.js → dream-maker-DZAPbPTi.js} +0 -0
- /package/dist/web/assets/{emacs-lisp-D_qP2zS6.js → emacs-lisp-Ao5SW8ay.js} +0 -0
- /package/dist/web/assets/{everforest-dark-DbHa2U-p.js → everforest-dark-uC8QYotQ.js} +0 -0
- /package/dist/web/assets/{everforest-light-BISkJchP.js → everforest-light-CTgsVNMr.js} +0 -0
- /package/dist/web/assets/{fennel-6B22SfJR.js → fennel-WuBw6IR1.js} +0 -0
- /package/dist/web/assets/{file-exclamation-point-a8f3_w7a.js → file-exclamation-point-COAwgNGw.js} +0 -0
- /package/dist/web/assets/{fish-CubIIvJD.js → fish-Byy9dusu.js} +0 -0
- /package/dist/web/assets/{fluent-DF55zQ09.js → fluent-CDxb_sgw.js} +0 -0
- /package/dist/web/assets/{fortran-free-form-DvOu8jAt.js → fortran-free-form-DKWSTamT.js} +0 -0
- /package/dist/web/assets/{gdscript-DCPxdLpq.js → gdscript-prYHMgtD.js} +0 -0
- /package/dist/web/assets/{gdshader-CTZ381FO.js → gdshader-D-RM-SQk.js} +0 -0
- /package/dist/web/assets/{genie-C_QDtvgU.js → genie-CowkJhej.js} +0 -0
- /package/dist/web/assets/{gherkin-BcvK42tF.js → gherkin-CLFpoVYJ.js} +0 -0
- /package/dist/web/assets/{github-dark-default-CKGVrl3Z.js → github-dark-default-BK_1Qgb8.js} +0 -0
- /package/dist/web/assets/{github-dark-dimmed-C3dQZ_LC.js → github-dark-dimmed-Cv9lj6f-.js} +0 -0
- /package/dist/web/assets/{github-dark-high-contrast-DW78QukY.js → github-dark-high-contrast-CW5ZgIDh.js} +0 -0
- /package/dist/web/assets/{github-dark-C9afs_4w.js → github-dark-nW2F-RLd.js} +0 -0
- /package/dist/web/assets/{github-light-BnP2dznS.js → github-light-D4PqBHGZ.js} +0 -0
- /package/dist/web/assets/{github-light-default-C2fPZzPG.js → github-light-default-B-cHtJJV.js} +0 -0
- /package/dist/web/assets/{github-light-high-contrast-BzIuUFR2.js → github-light-high-contrast-Dt0HJq50.js} +0 -0
- /package/dist/web/assets/{gleam-BpeKwEIO.js → gleam-DwSyXJWP.js} +0 -0
- /package/dist/web/assets/{gn-nUb_Mit0.js → gn-Cv5WEzHc.js} +0 -0
- /package/dist/web/assets/{gnuplot-D7I0v20p.js → gnuplot-D7bRdY_M.js} +0 -0
- /package/dist/web/assets/{go-D7Qqska7.js → go-DiRVJ22U.js} +0 -0
- /package/dist/web/assets/{groovy-DS-pne5-.js → groovy-BHAgLTeO.js} +0 -0
- /package/dist/web/assets/{gruvbox-dark-hard-C0W01fsq.js → gruvbox-dark-hard-C8QZ3gzY.js} +0 -0
- /package/dist/web/assets/{gruvbox-dark-medium-Bqo6fQbg.js → gruvbox-dark-medium-Dp1eeid2.js} +0 -0
- /package/dist/web/assets/{gruvbox-dark-soft-D-XSM_fu.js → gruvbox-dark-soft-Cwq0dWVj.js} +0 -0
- /package/dist/web/assets/{gruvbox-light-hard-IVAwMJRl.js → gruvbox-light-hard-CLQCq2-w.js} +0 -0
- /package/dist/web/assets/{gruvbox-light-medium-38ATiG7i.js → gruvbox-light-medium-APHsh6Mo.js} +0 -0
- /package/dist/web/assets/{gruvbox-light-soft-DnZr3c_0.js → gruvbox-light-soft-CX-fYc64.js} +0 -0
- /package/dist/web/assets/{haskell-uQcywkDH.js → haskell-C4Tw-TDa.js} +0 -0
- /package/dist/web/assets/{haxe-c6bI4_GT.js → haxe-B7fSduTQ.js} +0 -0
- /package/dist/web/assets/{hcl-CQXTiEXq.js → hcl-Bi3ho6yC.js} +0 -0
- /package/dist/web/assets/{hjson-ChETf2bz.js → hjson-BXwae2M1.js} +0 -0
- /package/dist/web/assets/{hlsl-BMC4JGoE.js → hlsl-CRuQLBSa.js} +0 -0
- /package/dist/web/assets/{horizon-BusFlhLW.js → horizon-DtdQ6qjv.js} +0 -0
- /package/dist/web/assets/{horizon-bright-2oD0Mz7W.js → horizon-bright-BXSF_uKq.js} +0 -0
- /package/dist/web/assets/{houston-DdbbjqFg.js → houston-C6ASpUjT.js} +0 -0
- /package/dist/web/assets/{hy-D_SOuqw9.js → hy-BrWBHtHY.js} +0 -0
- /package/dist/web/assets/{image-gallery-CrM5fHKy.js → image-gallery-CGvlv8zR.js} +0 -0
- /package/dist/web/assets/{imba-BxLOHO5I.js → imba-C_JJXckG.js} +0 -0
- /package/dist/web/assets/{ini-ox-CFcg0.js → ini-DEE_vSHQ.js} +0 -0
- /package/dist/web/assets/{java-Bzo8yIal.js → java-CnmpcjcT.js} +0 -0
- /package/dist/web/assets/{javascript-DHuz9VXn.js → javascript-C-M7sa2e.js} +0 -0
- /package/dist/web/assets/{json-0_y80FD5.js → json-BjZ3dAk6.js} +0 -0
- /package/dist/web/assets/{json5-CEQ50pGM.js → json5-BQ2vpqjp.js} +0 -0
- /package/dist/web/assets/{jsonc-CfrLEAKA.js → jsonc-C5MjoWGx.js} +0 -0
- /package/dist/web/assets/{jsonl-fKbrANC2.js → jsonl-JvhrmQJI.js} +0 -0
- /package/dist/web/assets/{jsonnet-DKbkPaQ2.js → jsonnet-C5pdZVuo.js} +0 -0
- /package/dist/web/assets/{jssm-Dxxx1Hqu.js → jssm-Db17uybX.js} +0 -0
- /package/dist/web/assets/{jsx-DlJL-Oj3.js → jsx-tJp2Cyqu.js} +0 -0
- /package/dist/web/assets/{kanagawa-dragon-CwN4SV1c.js → kanagawa-dragon-BculT_Y1.js} +0 -0
- /package/dist/web/assets/{kanagawa-lotus-BHltayiE.js → kanagawa-lotus-yQgHUGwU.js} +0 -0
- /package/dist/web/assets/{kanagawa-wave-D-KXPjw6.js → kanagawa-wave-CyGoWN4d.js} +0 -0
- /package/dist/web/assets/{kdl-DvtoJdFo.js → kdl-Bn8R1REF.js} +0 -0
- /package/dist/web/assets/{kotlin-CTS4MLcx.js → kotlin-DWughK73.js} +0 -0
- /package/dist/web/assets/{kusto-HtSE_sKm.js → kusto--serPb0x.js} +0 -0
- /package/dist/web/assets/{laserwave-DaXZG9ge.js → laserwave-DfAPJ1tt.js} +0 -0
- /package/dist/web/assets/{lean-BYtGUfWx.js → lean-UAm1HOKl.js} +0 -0
- /package/dist/web/assets/{less-BoxmU_Mk.js → less-Xj6Ka0fF.js} +0 -0
- /package/dist/web/assets/{lib-B1clP4ai.js → lib-DgNcCtj3.js} +0 -0
- /package/dist/web/assets/{libesm-ah-mr-sh.js → libesm-CPh1Av0r.js} +0 -0
- /package/dist/web/assets/{light-plus-Bt5CyUuo.js → light-plus-BfS7gPcj.js} +0 -0
- /package/dist/web/assets/{llvm-CSdk9q9V.js → llvm-DvWiVwvU.js} +0 -0
- /package/dist/web/assets/{log-B-kp_3CL.js → log-Bo5z9bNz.js} +0 -0
- /package/dist/web/assets/{logo-DdIsXFDO.js → logo-CrIjcMZT.js} +0 -0
- /package/dist/web/assets/{luau-DUBpLlzQ.js → luau-C9TsYwNt.js} +0 -0
- /package/dist/web/assets/{make-B3JVjoW_.js → make-GYq4qVbx.js} +0 -0
- /package/dist/web/assets/{markdown-Seon0vHs.js → markdown-p5mNledS.js} +0 -0
- /package/dist/web/assets/{material-theme-Nq-ChX1P.js → material-theme-CWYOVxsP.js} +0 -0
- /package/dist/web/assets/{material-theme-darker-CPV4ayXJ.js → material-theme-darker-BDGty7YH.js} +0 -0
- /package/dist/web/assets/{material-theme-lighter-0kyjYqEd.js → material-theme-lighter-JbgOgV3n.js} +0 -0
- /package/dist/web/assets/{material-theme-ocean-DGpAp5co.js → material-theme-ocean-EMOpLpa2.js} +0 -0
- /package/dist/web/assets/{material-theme-palenight-B0AUn0NG.js → material-theme-palenight-CY5hgm7h.js} +0 -0
- /package/dist/web/assets/{matlab-C2waytxs.js → matlab-C-He_NTH.js} +0 -0
- /package/dist/web/assets/{mdx-DAis6R6I.js → mdx-Cr2TR5fj.js} +0 -0
- /package/dist/web/assets/{media-url-DlYsHq0S.js → media-url-CylYQld1.js} +0 -0
- /package/dist/web/assets/{mermaid-_rnT2YGD.js → mermaid-BYc0-B0U.js} +0 -0
- /package/dist/web/assets/{min-dark-BSSjchUB.js → min-dark-CMJwqJqB.js} +0 -0
- /package/dist/web/assets/{min-light-DomAFQsa.js → min-light-Cx6vFiEX.js} +0 -0
- /package/dist/web/assets/{mipsasm-bBgtvPyG.js → mipsasm-Bjer5HwK.js} +0 -0
- /package/dist/web/assets/{mobile-bottom-sheet-CS3XMwFw.js → mobile-bottom-sheet-BUOJgiaZ.js} +0 -0
- /package/dist/web/assets/{mojo-Cp9BayW0.js → mojo-t90PR-Y2.js} +0 -0
- /package/dist/web/assets/{monokai-CL_9gbmn.js → monokai-dci_PdCm.js} +0 -0
- /package/dist/web/assets/{moonbit-BS_fcr-P.js → moonbit-AAzI-Hd-.js} +0 -0
- /package/dist/web/assets/{move-C79AH45U.js → move-kwBhnhrG.js} +0 -0
- /package/dist/web/assets/{narrat-CJ5s3BDf.js → narrat-CXww2YQL.js} +0 -0
- /package/dist/web/assets/{nextflow-groovy-ZHa4JrPJ.js → nextflow-groovy-CJXsuXGB.js} +0 -0
- /package/dist/web/assets/{night-owl-Jkf9zFQK.js → night-owl-_GD204Wr.js} +0 -0
- /package/dist/web/assets/{night-owl-light-DRPeaG5J.js → night-owl-light-DNgkw3kl.js} +0 -0
- /package/dist/web/assets/{nix-D2Jet9DN.js → nix-BgiorKFd.js} +0 -0
- /package/dist/web/assets/{nord-CREVs22j.js → nord-CaBmcxFC.js} +0 -0
- /package/dist/web/assets/{nushell-CAiDi_mR.js → nushell-DUh4UGx1.js} +0 -0
- /package/dist/web/assets/{objective-c-CVkmJkC1.js → objective-c-Cl9KU86S.js} +0 -0
- /package/dist/web/assets/{objective-cpp-DIKDO1Ly.js → objective-cpp-DVkIA8A0.js} +0 -0
- /package/dist/web/assets/{ocaml-R9qtGQhs.js → ocaml-vvoHTak0.js} +0 -0
- /package/dist/web/assets/{odin-DTYNQqVr.js → odin-Cyjw8woZ.js} +0 -0
- /package/dist/web/assets/{one-dark-pro-BSLWUJn5.js → one-dark-pro-B1cviILi.js} +0 -0
- /package/dist/web/assets/{one-light-DbkRXG3t.js → one-light-BPGUJeYI.js} +0 -0
- /package/dist/web/assets/{openscad-BlPcSnmT.js → openscad-BLMdTUU8.js} +0 -0
- /package/dist/web/assets/{pascal-B1Y46ZZB.js → pascal-i5niy3e7.js} +0 -0
- /package/dist/web/assets/{pkl-BhJSJbFv.js → pkl-CuOV7SsU.js} +0 -0
- /package/dist/web/assets/{plastic-BzxsCTpi.js → plastic-Bf_zE5KL.js} +0 -0
- /package/dist/web/assets/{plsql-DBba7dyP.js → plsql-cfqEtMD3.js} +0 -0
- /package/dist/web/assets/{plus-DmjC2iRB.js → plus-BM-Ty0fp.js} +0 -0
- /package/dist/web/assets/{po-BvgLlnNo.js → po-CFJcWgjr.js} +0 -0
- /package/dist/web/assets/{poimandres-DUaI_1JP.js → poimandres-G5YoaIFf.js} +0 -0
- /package/dist/web/assets/{polar-C7uILwJn.js → polar-rcjs3i9R.js} +0 -0
- /package/dist/web/assets/{postcss-BgJlpFdw.js → postcss-CBKY1FTZ.js} +0 -0
- /package/dist/web/assets/{powerquery-Dn1MIpZu.js → powerquery-Db7SXLbO.js} +0 -0
- /package/dist/web/assets/{powershell-Bo-DYzOS.js → powershell-LFy3MUTP.js} +0 -0
- /package/dist/web/assets/{prisma-CTLs5IdT.js → prisma-BE8GR1lH.js} +0 -0
- /package/dist/web/assets/{prolog-QRGun3eG.js → prolog-DOn5lR1e.js} +0 -0
- /package/dist/web/assets/{proto-B7PI7apn.js → proto-wr-TpAK_.js} +0 -0
- /package/dist/web/assets/{puppet-CBq0tLrP.js → puppet-D2Dkv62u.js} +0 -0
- /package/dist/web/assets/{purescript-DFewOQb2.js → purescript-DvgJgPdy.js} +0 -0
- /package/dist/web/assets/{python-iWuxKXvT.js → python-C7TlkHhK.js} +0 -0
- /package/dist/web/assets/{qmldir-cXiW3AsF.js → qmldir-CtZMwhcW.js} +0 -0
- /package/dist/web/assets/{qss-DASwAbBL.js → qss-dNZ2btnl.js} +0 -0
- /package/dist/web/assets/{r-TU2eaIPw.js → r-BlqnNkHS.js} +0 -0
- /package/dist/web/assets/{racket-SkRKqrLY.js → racket-CzRQrGc4.js} +0 -0
- /package/dist/web/assets/{raku-D31lthkZ.js → raku-BwutWhBF.js} +0 -0
- /package/dist/web/assets/{red-CTcQZevb.js → red-BMXMywmL.js} +0 -0
- /package/dist/web/assets/{reg-D8YAsTGf.js → reg-BqOKrIOw.js} +0 -0
- /package/dist/web/assets/{regexp-CD2uvAWx.js → regexp-Bero1BN2.js} +0 -0
- /package/dist/web/assets/{rel-CAaI-1fg.js → rel-BXKWIElA.js} +0 -0
- /package/dist/web/assets/{riscv-DR-hJVIj.js → riscv-BbbBYJBo.js} +0 -0
- /package/dist/web/assets/{ron-CuUCJ0n4.js → ron-BtVTWW4b.js} +0 -0
- /package/dist/web/assets/{rose-pine-dawn-Bqz2sBRY.js → rose-pine-dawn-D7lwhUei.js} +0 -0
- /package/dist/web/assets/{rose-pine-aFHxW48i.js → rose-pine-hvkvQzvU.js} +0 -0
- /package/dist/web/assets/{rose-pine-moon-wqyh0an4.js → rose-pine-moon-CoHDmsIw.js} +0 -0
- /package/dist/web/assets/{rosmsg-CI1ywimO.js → rosmsg-CdaZFgI8.js} +0 -0
- /package/dist/web/assets/{run-in-terminal-CGW6o37_.js → run-in-terminal-CyS5Itj-.js} +0 -0
- /package/dist/web/assets/{rust-p7Imk4G_.js → rust-Dy2qsphD.js} +0 -0
- /package/dist/web/assets/{sass-C8JfaqCV.js → sass-Bz7NVxDb.js} +0 -0
- /package/dist/web/assets/{save-DRPrDfTt.js → save-C4z1p51e.js} +0 -0
- /package/dist/web/assets/{scala-DNxCW1By.js → scala-sXSwsNyq.js} +0 -0
- /package/dist/web/assets/{scheme-BYuUPJoL.js → scheme-DS7TUbN7.js} +0 -0
- /package/dist/web/assets/{sdbl-DbPeJPUr.js → sdbl-iISFvIep.js} +0 -0
- /package/dist/web/assets/{send-to-chat-YXHdAyLG.js → send-to-chat-BcO39BDR.js} +0 -0
- /package/dist/web/assets/{shellscript-DMiHlR3q.js → shellscript-BkIl4ApC.js} +0 -0
- /package/dist/web/assets/{shield-check-8GObuUAn.js → shield-check-C5laObJv.js} +0 -0
- /package/dist/web/assets/{shield-off-egKAZEwR.js → shield-off-DULFtyLS.js} +0 -0
- /package/dist/web/assets/{slack-dark-C4xGcQXI.js → slack-dark-B1eg0_m2.js} +0 -0
- /package/dist/web/assets/{slack-ochin-BzgRt_wm.js → slack-ochin-mdkc1ldu.js} +0 -0
- /package/dist/web/assets/{smalltalk-LDeL9PYH.js → smalltalk-CORtd03t.js} +0 -0
- /package/dist/web/assets/{snazzy-light-CXE7a5j_.js → snazzy-light-Bc6Q2G89.js} +0 -0
- /package/dist/web/assets/{solarized-dark-DgUhY74x.js → solarized-dark-CF83zRXM.js} +0 -0
- /package/dist/web/assets/{solarized-light-DD9C-H-9.js → solarized-light-BoKQZaYU.js} +0 -0
- /package/dist/web/assets/{solidity-CAbDB4D4.js → solidity-DOgi1N4w.js} +0 -0
- /package/dist/web/assets/{sparkles-n1hzh65o.js → sparkles-Dqsf3hq6.js} +0 -0
- /package/dist/web/assets/{splunk-kQREPfIc.js → splunk-BXfw5ZLy.js} +0 -0
- /package/dist/web/assets/{sql-CBzeNAD8.js → sql-BcVs-eX4.js} +0 -0
- /package/dist/web/assets/{ssh-config-L1euxrsM.js → ssh-config-CLCtNkkd.js} +0 -0
- /package/dist/web/assets/{stylus-DvBnYniP.js → stylus-DdP992aO.js} +0 -0
- /package/dist/web/assets/{swift-DF5NDQp6.js → swift-BnGb6Lgc.js} +0 -0
- /package/dist/web/assets/{synthwave-84-DbBhB_Hq.js → synthwave-84-cg9264l9.js} +0 -0
- /package/dist/web/assets/{system-verilog-D8s2ZW_k.js → system-verilog-GbHpszs3.js} +0 -0
- /package/dist/web/assets/{systemd-a5-XZJsG.js → systemd-Dz-bNsDQ.js} +0 -0
- /package/dist/web/assets/{table-BX2ZrJfM.js → table-CHmxuh6M.js} +0 -0
- /package/dist/web/assets/{talonscript-BLa0URTW.js → talonscript-CFIidoBA.js} +0 -0
- /package/dist/web/assets/{tasl-DIoV4XcC.js → tasl-Cu-TRTKx.js} +0 -0
- /package/dist/web/assets/{tcl-ztYAdXfQ.js → tcl-DwCHCB1K.js} +0 -0
- /package/dist/web/assets/{terraform-DvpCCiOZ.js → terraform-BzZw4T1z.js} +0 -0
- /package/dist/web/assets/{tokyo-night-BkHlYUv0.js → tokyo-night-RKsj2-tv.js} +0 -0
- /package/dist/web/assets/{toml-acIrxos6.js → toml-CirbOgDP.js} +0 -0
- /package/dist/web/assets/{tsv-BJB5EVCT.js → tsv-CraRcWdU.js} +0 -0
- /package/dist/web/assets/{tsx-B1MmXGT3.js → tsx-CjFg0lgw.js} +0 -0
- /package/dist/web/assets/{turtle-DFceTiqd.js → turtle-B-WBIOa6.js} +0 -0
- /package/dist/web/assets/{typescript-Dz9wU5Y1.js → typescript-MpLarYn1.js} +0 -0
- /package/dist/web/assets/{typespec-CPuYZijj.js → typespec-B7QlHMZ_.js} +0 -0
- /package/dist/web/assets/{typst-CfsCIYv8.js → typst-CcHSKFZj.js} +0 -0
- /package/dist/web/assets/{use-blob-url-BmlYYZ8L.js → use-blob-url-BKyVxOZw.js} +0 -0
- /package/dist/web/assets/{use-is-mobile-B8FA4kQf.js → use-is-mobile-BXGVvczu.js} +0 -0
- /package/dist/web/assets/{v-CGo0jcXA.js → v-xTGhWZuD.js} +0 -0
- /package/dist/web/assets/{vala-AsSR0hrb.js → vala-DwebjH3H.js} +0 -0
- /package/dist/web/assets/{vb-C7tvbXv1.js → vb-BxJT2RAy.js} +0 -0
- /package/dist/web/assets/{vendor-xterm-C1diXHJl.js → vendor-xterm-CU6zIYMB.js} +0 -0
- /package/dist/web/assets/{verilog--a33ND-p.js → verilog-CvV6RHPD.js} +0 -0
- /package/dist/web/assets/{vesper-B_Z0h4pn.js → vesper-CY3qd7E_.js} +0 -0
- /package/dist/web/assets/{vhdl-CWL5dZPN.js → vhdl-B9ZX-sUL.js} +0 -0
- /package/dist/web/assets/{viml-BglmT14Y.js → viml-Y42h_ExQ.js} +0 -0
- /package/dist/web/assets/{vitesse-black-RKFsSqQI.js → vitesse-black-DkXP6Sv-.js} +0 -0
- /package/dist/web/assets/{vitesse-dark-D7zDWNmc.js → vitesse-dark-B9CkIB6r.js} +0 -0
- /package/dist/web/assets/{vitesse-light-MAp87W5b.js → vitesse-light-C7DHrJCK.js} +0 -0
- /package/dist/web/assets/{vyper-CgCBYg1G.js → vyper-Cnd9s5j-.js} +0 -0
- /package/dist/web/assets/{wasm-Bwl4txwp.js → wasm-DQE71XTB.js} +0 -0
- /package/dist/web/assets/{wasm-BOG7ZeTT.js → wasm-iWe7Fzjc.js} +0 -0
- /package/dist/web/assets/{wenyan-DpShPKXZ.js → wenyan-Bc5Pnm9l.js} +0 -0
- /package/dist/web/assets/{wgsl-BakcCblK.js → wgsl-D-YUAWkP.js} +0 -0
- /package/dist/web/assets/{wikitext-NroRWVAO.js → wikitext-DYQDUYf2.js} +0 -0
- /package/dist/web/assets/{wit-B5CM2pg6.js → wit-P6u7mfwy.js} +0 -0
- /package/dist/web/assets/{wolfram-7MTFBJpR.js → wolfram-6SXLUqao.js} +0 -0
- /package/dist/web/assets/{yaml-Bwr01G2K.js → yaml-CQiMLVcZ.js} +0 -0
- /package/dist/web/assets/{zenscript-Dj8GATvi.js → zenscript-DFMywo_P.js} +0 -0
- /package/dist/web/assets/{zig-LAE-fbS-.js → zig-CtAjaIiF.js} +0 -0
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
/** Whole-machine metrics contract shared by the collectors, the REST/SSE routes
|
|
2
|
+
* and the web client. Types + constants only, no imports, so both bundles can
|
|
3
|
+
* take it. Import RELATIVELY — the "@" alias points at src/web, not src. */
|
|
4
|
+
|
|
5
|
+
export type MetricsPlatform = "win32" | "darwin" | "linux";
|
|
6
|
+
|
|
7
|
+
/** `light` = node:os only, no child processes, status-bar cadence.
|
|
8
|
+
* `full` = every collector, process rows, groups. */
|
|
9
|
+
export type MetricsTier = "light" | "full";
|
|
10
|
+
|
|
11
|
+
/** Aggregate + per-core busy percentage over the last tick (0-100, 1 decimal). */
|
|
12
|
+
export interface CpuMetrics {
|
|
13
|
+
total: number;
|
|
14
|
+
/** Index matches `os.cpus()` order. Core count is `cores.length`. */
|
|
15
|
+
cores: number[];
|
|
16
|
+
model: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface MemoryMetrics {
|
|
20
|
+
totalMB: number;
|
|
21
|
+
usedMB: number;
|
|
22
|
+
availableMB: number;
|
|
23
|
+
/** usedMB / totalMB × 100. */
|
|
24
|
+
percent: number;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** Whole-machine throughput, bytes/second over the last tick. */
|
|
28
|
+
export interface RateMetrics {
|
|
29
|
+
/** Disk: read. Net: received/down. */
|
|
30
|
+
inBps: number;
|
|
31
|
+
/** Disk: write. Net: sent/up. */
|
|
32
|
+
outBps: number;
|
|
33
|
+
/** False in the light tier, on a missing OS source, and on the first tick
|
|
34
|
+
* (no baseline). The UI must render "n/a", never 0 B/s. */
|
|
35
|
+
available: boolean;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface GpuMetrics {
|
|
39
|
+
name: string;
|
|
40
|
+
/** 0-100. */
|
|
41
|
+
utilPercent: number;
|
|
42
|
+
vramUsedMB: number;
|
|
43
|
+
vramTotalMB: number;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface SystemMetrics {
|
|
47
|
+
cpu: CpuMetrics;
|
|
48
|
+
mem: MemoryMetrics;
|
|
49
|
+
/** light tier: available:false. */
|
|
50
|
+
disk: RateMetrics;
|
|
51
|
+
/** light tier: available:false. */
|
|
52
|
+
net: RateMetrics;
|
|
53
|
+
/** light tier: []. Empty also when no NVIDIA GPU — the UI hides the card. */
|
|
54
|
+
gpus: GpuMetrics[];
|
|
55
|
+
/** light tier: 0. Processes the collector could see this tick. */
|
|
56
|
+
processCount: number;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export interface ProcessInfo {
|
|
60
|
+
pid: number;
|
|
61
|
+
/** -1 when the parent is unknown. */
|
|
62
|
+
ppid: number;
|
|
63
|
+
/** Executable basename WITHOUT extension, lowercased for comparison by the
|
|
64
|
+
* guard: "explorer", "node", "chrome". Never "explorer.exe". */
|
|
65
|
+
name: string;
|
|
66
|
+
/** Command line, secrets redacted then truncated to 160 chars. Falls back to
|
|
67
|
+
* `name` when unreadable (Windows: ~53% of rows are unreadable unelevated). */
|
|
68
|
+
command: string;
|
|
69
|
+
/** Instantaneous machine-normalised CPU%: deltaCpuMs / (wallMs × coreCount) × 100.
|
|
70
|
+
* Always 0 on a process's first observed tick. */
|
|
71
|
+
cpu: number;
|
|
72
|
+
ramMB: number;
|
|
73
|
+
/** Epoch ms UTC; 0 when unknown. Identity guard for CPU deltas, grouping and kill. */
|
|
74
|
+
startedAt: number;
|
|
75
|
+
/** PPM server, supervisor, edge forwarder, their descendants, PPM-managed
|
|
76
|
+
* cloudflared. Drives the "PPM only" filter — NOT a safety mechanism. */
|
|
77
|
+
ppm: boolean;
|
|
78
|
+
/** The server will refuse to kill it. Produced by the same guard the route
|
|
79
|
+
* enforces, so the disabled button and the 403 cannot disagree. */
|
|
80
|
+
protected: boolean;
|
|
81
|
+
/** Per-process throughput/GPU. `undefined` means this OS or tier cannot
|
|
82
|
+
* measure it — the UI must render "—", never 0. All are omitted from the
|
|
83
|
+
* JSON frame when undefined, so an unsupported host pays nothing.
|
|
84
|
+
*
|
|
85
|
+
* Bytes/second, delta of a cumulative OS counter over the tick's wall
|
|
86
|
+
* interval; 0 on a process's first observed tick, like `cpu`. */
|
|
87
|
+
diskReadBps?: number;
|
|
88
|
+
diskWriteBps?: number;
|
|
89
|
+
/** Sum of this pid's GPU engine busy percentages (3D + Copy + Video + …),
|
|
90
|
+
* clamped 0-100. Rate over the counter's OWN clock, not the wall tick. */
|
|
91
|
+
gpuPct?: number;
|
|
92
|
+
/** Dedicated (on-card) VRAM in MB attributed to this pid. */
|
|
93
|
+
gpuMemMB?: number;
|
|
94
|
+
/** macOS only: per-process network has no supported source on Windows (ETW
|
|
95
|
+
* only) or Linux (packet capture). */
|
|
96
|
+
netInBps?: number;
|
|
97
|
+
netOutBps?: number;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export interface ProcessGroup {
|
|
101
|
+
/** Stable across ticks: "root:<pid>" for an ancestor roll-up, "exe:<name>" for
|
|
102
|
+
* the orphan bucket. React key and history-series key. */
|
|
103
|
+
key: string;
|
|
104
|
+
label: string;
|
|
105
|
+
/** Roll-up root pid; null for an "exe:" bucket. */
|
|
106
|
+
rootPid: number | null;
|
|
107
|
+
cpu: number;
|
|
108
|
+
ramMB: number;
|
|
109
|
+
count: number;
|
|
110
|
+
/** True when any member is PPM-owned. */
|
|
111
|
+
ppm: boolean;
|
|
112
|
+
/** Member pids, CPU-desc. Full rows are in `MetricsSnapshot.processes`. */
|
|
113
|
+
pids: number[];
|
|
114
|
+
/** Roll-ups of the optional per-process columns, with the same optionality:
|
|
115
|
+
* the sum over the members that HAVE a value, and `undefined` when no member
|
|
116
|
+
* has one — so "nothing measurable" never renders as a hard 0. */
|
|
117
|
+
diskReadBps?: number;
|
|
118
|
+
diskWriteBps?: number;
|
|
119
|
+
/** Summed engine busy across members, clamped 0-100. */
|
|
120
|
+
gpuPct?: number;
|
|
121
|
+
gpuMemMB?: number;
|
|
122
|
+
netInBps?: number;
|
|
123
|
+
netOutBps?: number;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/** Per-host availability of the optional process columns. A column is offered
|
|
127
|
+
* once the collector has actually produced a value for it on this host. */
|
|
128
|
+
export interface ProcessColumnAvailability {
|
|
129
|
+
disk: boolean;
|
|
130
|
+
gpu: boolean;
|
|
131
|
+
net: boolean;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/** CLIENT-SIDE history element: aggregates only. There is no server ring. */
|
|
135
|
+
export interface MetricsHistoryPoint {
|
|
136
|
+
ts: number;
|
|
137
|
+
system: SystemMetrics;
|
|
138
|
+
/** group.key → roll-up, so group sparklines survive across ticks. */
|
|
139
|
+
groups: Record<string, { cpu: number; ramMB: number }>;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export interface MetricsSnapshot {
|
|
143
|
+
ts: number;
|
|
144
|
+
platform: MetricsPlatform;
|
|
145
|
+
tier: MetricsTier;
|
|
146
|
+
/** Poll cadence in ms for THIS tier, so the client can label chart axes. */
|
|
147
|
+
intervalMs: number;
|
|
148
|
+
system: SystemMetrics;
|
|
149
|
+
/** Empty in the light tier. */
|
|
150
|
+
groups: ProcessGroup[];
|
|
151
|
+
/** Empty in the light tier. Latest snapshot only — never retained. */
|
|
152
|
+
processes: ProcessInfo[];
|
|
153
|
+
/** Which optional process columns THIS host can actually fill, so the UI can
|
|
154
|
+
* hide the unavailable ones instead of showing a wall of "—". All false in
|
|
155
|
+
* the light tier (no process rows at all). */
|
|
156
|
+
processColumns: ProcessColumnAvailability;
|
|
157
|
+
/** DEPRECATED, remove one release after this ships. Mirrors cpu/mem/count so a
|
|
158
|
+
* PWA-cached old bundle's `resource-status-bar.tsx:41` destructure of
|
|
159
|
+
* `latest.total` does not TypeError on every page. */
|
|
160
|
+
total: { cpu: number; ramMB: number; processCount: number };
|
|
161
|
+
/** Non-fatal collector failures, human readable. Rendered in the UI. */
|
|
162
|
+
warnings: string[];
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export interface KillProcessRequest {
|
|
166
|
+
pid: number;
|
|
167
|
+
/** Identity guard: the `startedAt` the client saw. The server re-queries the
|
|
168
|
+
* live process and returns 409 on mismatch, so a recycled pid cannot be
|
|
169
|
+
* killed against a stale name. */
|
|
170
|
+
startedAt: number;
|
|
171
|
+
/** Kill descendants too (`taskkill /T` on Windows, collected tree on POSIX). */
|
|
172
|
+
tree?: boolean;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
export interface KillProcessResult {
|
|
176
|
+
pid: number;
|
|
177
|
+
tree: boolean;
|
|
178
|
+
method: "taskkill" | "signal";
|
|
179
|
+
/** Pids actually signalled. On win32 with tree:true this is always `[pid]` —
|
|
180
|
+
* `taskkill /T` walks and kills the tree inside the OS and reports no member
|
|
181
|
+
* list, so the real count is unknowable from here. */
|
|
182
|
+
killed: number[];
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/** Sort columns offered by the process table. `disk` sorts by read + write,
|
|
186
|
+
* `net` by in + out; rows without a value sort last. */
|
|
187
|
+
export type SortKey = "cpu" | "ram" | "disk" | "gpu" | "gpuMem" | "net" | "name" | null;
|
|
188
|
+
export type SortDir = "asc" | "desc";
|
|
189
|
+
|
|
190
|
+
/** Full-tier poll cadence. A Windows tick (one CIM round trip) costs ~175-200 ms,
|
|
191
|
+
* so 2 s leaves an order of magnitude of headroom before ticks would overlap. */
|
|
192
|
+
export const METRICS_INTERVAL_MS = 2000;
|
|
193
|
+
/** Light-tier poll cadence — node:os only, costs <0.1 ms. */
|
|
194
|
+
export const METRICS_LIGHT_INTERVAL_MS = 5000;
|
|
195
|
+
/** Client history cap: 30 min at METRICS_INTERVAL_MS. */
|
|
196
|
+
export const METRICS_HISTORY_MAX = 900;
|
|
197
|
+
/** Subscriber lease: client pings every 10 s, server reaps after 30 s silence. */
|
|
198
|
+
export const METRICS_PING_INTERVAL_MS = 10_000;
|
|
199
|
+
export const METRICS_LEASE_TIMEOUT_MS = 30_000;
|
|
@@ -22,6 +22,7 @@ export interface WindowContentProps {
|
|
|
22
22
|
export const WINDOW_CONTENT: Record<WindowKind, LazyExoticComponent<ComponentType<WindowContentProps>>> = {
|
|
23
23
|
explorer: lazy(() => import("@/components/os-explorer/explorer-window-content")),
|
|
24
24
|
"team-member": lazy(() => import("@/components/chat/team-member-window-content")),
|
|
25
|
+
"system-monitor": lazy(() => import("@/components/system/system-monitor-window-content")),
|
|
25
26
|
};
|
|
26
27
|
|
|
27
28
|
/**
|
|
@@ -46,6 +47,7 @@ export function windowTitle(kind: WindowKind, payload?: Record<string, unknown>)
|
|
|
46
47
|
const member = payload?.memberName;
|
|
47
48
|
return typeof member === "string" && member ? `Session — ${member}` : "Team member";
|
|
48
49
|
}
|
|
50
|
+
if (kind === "system-monitor") return "System Monitor";
|
|
49
51
|
const path = payload?.path;
|
|
50
52
|
if (kind === "explorer" && typeof path === "string" && path) {
|
|
51
53
|
const segments = path.split(/[\\/]/).filter(Boolean);
|
|
@@ -20,7 +20,7 @@ export interface PersistedWindow {
|
|
|
20
20
|
payload?: Record<string, unknown>;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
const KINDS: WindowKind[] = ["explorer"];
|
|
23
|
+
const KINDS: WindowKind[] = ["explorer", "system-monitor"];
|
|
24
24
|
const STATES: WindowVisualState[] = ["normal", "maximized", "minimized"];
|
|
25
25
|
|
|
26
26
|
function isRect(v: unknown): v is Rect {
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import type { Rect } from "./window-geometry";
|
|
4
4
|
|
|
5
5
|
/** Content families the layer can host. The registry maps each kind to its body component. */
|
|
6
|
-
export type WindowKind = "explorer" | "team-member";
|
|
6
|
+
export type WindowKind = "explorer" | "team-member" | "system-monitor";
|
|
7
7
|
|
|
8
8
|
export type WindowVisualState = "normal" | "maximized" | "minimized";
|
|
9
9
|
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { KillProcessRequest, ProcessGroup, ProcessInfo } from "../../../types/system-metrics";
|
|
2
|
+
|
|
3
|
+
/** What the confirm dialog is about to end: one row, or a whole app group. */
|
|
4
|
+
export type KillTarget =
|
|
5
|
+
| { kind: "process"; proc: ProcessInfo }
|
|
6
|
+
| { kind: "group"; group: ProcessGroup; members: ProcessInfo[] };
|
|
7
|
+
|
|
8
|
+
/** Builds the kill request body from a process row's own identity fields — pulled out
|
|
9
|
+
* of the dialog's confirm handler so the payload shape is unit-testable without
|
|
10
|
+
* mounting the dialog. `startedAt` travels unchanged so the server can 409 a pid the
|
|
11
|
+
* OS recycled between the snapshot and the click. */
|
|
12
|
+
export function buildKillRequest(proc: ProcessInfo, tree: boolean): KillProcessRequest {
|
|
13
|
+
return { pid: proc.pid, startedAt: proc.startedAt, tree };
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Requests that end every member of a group.
|
|
18
|
+
*
|
|
19
|
+
* An ancestor roll-up ("root:<pid>") is ended with ONE tree kill on its root — the
|
|
20
|
+
* server walks the same descendant set it grouped by, so this is atomic on Windows
|
|
21
|
+
* (`taskkill /T`) and cannot miss a child that forked between snapshot and click.
|
|
22
|
+
* An orphan bucket ("exe:<name>") has no common ancestor, so each member is a
|
|
23
|
+
* separate single-process kill. Protected members are never included: the caller
|
|
24
|
+
* disables the button when any exist, and the server would 403 anyway.
|
|
25
|
+
*/
|
|
26
|
+
export function buildGroupKillRequests(group: ProcessGroup, members: ProcessInfo[]): KillProcessRequest[] {
|
|
27
|
+
const root = group.rootPid !== null ? members.find((m) => m.pid === group.rootPid) : undefined;
|
|
28
|
+
if (root) return [buildKillRequest(root, true)];
|
|
29
|
+
return members.map((m) => buildKillRequest(m, false));
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** A group can be ended only when none of its members is refused by the guard —
|
|
33
|
+
* the PPM instance and system groups stay un-endable as a whole. */
|
|
34
|
+
export function isGroupProtected(members: ProcessInfo[]): boolean {
|
|
35
|
+
return members.some((m) => m.protected);
|
|
36
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/** Shared scale resolution for the canvas charts: a fixed ceiling (percentage axes)
|
|
2
|
+
* or autoscale to the max of the visible window (byte-rate axes) — pulled out of
|
|
3
|
+
* `metric-chart-canvas.tsx` so it is unit-testable without a canvas context. A
|
|
4
|
+
* percentage axis must be pinned to 100, otherwise a 3% CPU reading autoscales to a
|
|
5
|
+
* full-height line. */
|
|
6
|
+
export function resolveScaleMax(data: number[], maxValue?: number): number {
|
|
7
|
+
if (maxValue !== undefined) return maxValue;
|
|
8
|
+
return Math.max(...data, 1);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/** The minimal surface of `CSSStyleDeclaration` this needs — lets a test pass a plain
|
|
12
|
+
* fake object instead of a real computed style. */
|
|
13
|
+
export interface ComputedColorSource {
|
|
14
|
+
getPropertyValue(property: string): string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** Canvas 2D's `strokeStyle`/`fillStyle` parse as a standalone CSS `<color>` — `var(...)`
|
|
18
|
+
* is not resolvable without an element context, so assigning `"var(--color-primary)"`
|
|
19
|
+
* directly is silently ignored and the shape draws black. Resolve once per draw call
|
|
20
|
+
* against the canvas's own computed style (custom properties inherit from the
|
|
21
|
+
* document, so any element's computed style works) and fall back to the original
|
|
22
|
+
* string when it is not a `var(...)` reference or resolves to nothing. */
|
|
23
|
+
export function resolveCssColor(color: string, styles: ComputedColorSource): string {
|
|
24
|
+
const match = /^var\((--[\w-]+)\)$/.exec(color.trim());
|
|
25
|
+
if (!match) return color;
|
|
26
|
+
const resolved = styles.getPropertyValue(match[1]!).trim();
|
|
27
|
+
return resolved || color;
|
|
28
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { cn } from "@/lib/utils";
|
|
2
|
+
|
|
3
|
+
function loadColor(pct: number): string {
|
|
4
|
+
if (pct > 80) return "bg-error";
|
|
5
|
+
if (pct > 50) return "bg-warning";
|
|
6
|
+
return "bg-success";
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/** One vertical bar per core, tooltip shows the exact percentage. `min-h-11` keeps the
|
|
10
|
+
* strip out of sub-44px touch-row territory even though nothing here is clickable —
|
|
11
|
+
* a future click-to-isolate-core affordance should not need a layout change. */
|
|
12
|
+
export function CpuCoreBars({ cores }: { cores: number[] }) {
|
|
13
|
+
return (
|
|
14
|
+
<div
|
|
15
|
+
className="flex items-end gap-0.5 min-h-11 w-full"
|
|
16
|
+
data-testid="sysmon-core-bars"
|
|
17
|
+
data-core-count={cores.length}
|
|
18
|
+
>
|
|
19
|
+
{cores.map((pct, i) => (
|
|
20
|
+
<div
|
|
21
|
+
key={i}
|
|
22
|
+
className="flex-1 h-11 flex items-end rounded-sm overflow-hidden bg-surface-hover"
|
|
23
|
+
title={`Core ${i}: ${pct.toFixed(0)}%`}
|
|
24
|
+
>
|
|
25
|
+
<div
|
|
26
|
+
className={cn("w-full transition-[height]", loadColor(pct))}
|
|
27
|
+
style={{ height: `${Math.max(2, Math.min(100, pct))}%` }}
|
|
28
|
+
/>
|
|
29
|
+
</div>
|
|
30
|
+
))}
|
|
31
|
+
</div>
|
|
32
|
+
);
|
|
33
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog";
|
|
3
|
+
import { BottomSheet } from "@/components/ui/mobile-bottom-sheet";
|
|
4
|
+
import { Button } from "@/components/ui/button";
|
|
5
|
+
import { Switch } from "@/components/ui/switch";
|
|
6
|
+
import { useIsMobile } from "@/hooks/use-is-mobile";
|
|
7
|
+
import { formatRam } from "@/lib/format-bytes";
|
|
8
|
+
import type { KillTarget } from "./build-kill-request";
|
|
9
|
+
|
|
10
|
+
export interface KillConfirmDialogProps {
|
|
11
|
+
target: KillTarget | null;
|
|
12
|
+
/** `tree` is only meaningful for a single process; a group is always ended whole. */
|
|
13
|
+
onConfirm: (target: KillTarget, tree: boolean) => void;
|
|
14
|
+
onCancel: () => void;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** Confirm dialog for ending a process or a whole app group. Bottom sheet below
|
|
18
|
+
* `md`, centered dialog at `md`+. The "end child processes" toggle defaults off and
|
|
19
|
+
* the destructive action is never the default focus — Escape/backdrop cancels either
|
|
20
|
+
* way. */
|
|
21
|
+
export function KillConfirmDialog({ target, onConfirm, onCancel }: KillConfirmDialogProps) {
|
|
22
|
+
const isMobile = useIsMobile();
|
|
23
|
+
const [tree, setTree] = useState(false);
|
|
24
|
+
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
if (!target) setTree(false);
|
|
27
|
+
}, [target]);
|
|
28
|
+
|
|
29
|
+
if (!target) return null;
|
|
30
|
+
|
|
31
|
+
const isGroup = target.kind === "group";
|
|
32
|
+
const title = isGroup ? "End app" : "End process";
|
|
33
|
+
const cpu = isGroup ? target.group.cpu : target.proc.cpu;
|
|
34
|
+
const ramMB = isGroup ? target.group.ramMB : target.proc.ramMB;
|
|
35
|
+
|
|
36
|
+
const body = (
|
|
37
|
+
<div className="space-y-4" data-testid="sysmon-kill-confirm" data-kill-kind={target.kind}>
|
|
38
|
+
{isGroup ? (
|
|
39
|
+
<p className="text-sm">
|
|
40
|
+
End <span className="font-medium">{target.group.label}</span> and all its{" "}
|
|
41
|
+
<span className="font-medium">{target.members.length}</span> processes?
|
|
42
|
+
</p>
|
|
43
|
+
) : (
|
|
44
|
+
<p className="text-sm">
|
|
45
|
+
End <span className="font-medium">{target.proc.name}</span> (pid {target.proc.pid})?
|
|
46
|
+
</p>
|
|
47
|
+
)}
|
|
48
|
+
<p className="text-xs text-text-subtle">
|
|
49
|
+
CPU {cpu.toFixed(1)}% · RAM {formatRam(ramMB)}
|
|
50
|
+
</p>
|
|
51
|
+
{!isGroup && (
|
|
52
|
+
<label className="flex items-center justify-between gap-3 min-h-11 py-1">
|
|
53
|
+
<span className="text-sm">Also end child processes</span>
|
|
54
|
+
<Switch
|
|
55
|
+
checked={tree}
|
|
56
|
+
onCheckedChange={setTree}
|
|
57
|
+
data-testid="sysmon-kill-tree"
|
|
58
|
+
aria-label="Also end child processes"
|
|
59
|
+
/>
|
|
60
|
+
</label>
|
|
61
|
+
)}
|
|
62
|
+
<div className="flex flex-col-reverse md:flex-row gap-2 md:justify-end pt-2">
|
|
63
|
+
<Button
|
|
64
|
+
variant="outline"
|
|
65
|
+
onClick={onCancel}
|
|
66
|
+
data-testid="sysmon-kill-confirm-cancel"
|
|
67
|
+
className="min-h-11"
|
|
68
|
+
>
|
|
69
|
+
Cancel
|
|
70
|
+
</Button>
|
|
71
|
+
<Button
|
|
72
|
+
variant="destructive"
|
|
73
|
+
autoFocus={false}
|
|
74
|
+
onClick={() => onConfirm(target, tree)}
|
|
75
|
+
data-testid="sysmon-kill-confirm-ok"
|
|
76
|
+
className="min-h-11"
|
|
77
|
+
>
|
|
78
|
+
{isGroup ? `End ${target.members.length} processes` : "End process"}
|
|
79
|
+
</Button>
|
|
80
|
+
</div>
|
|
81
|
+
</div>
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
if (isMobile) {
|
|
85
|
+
return (
|
|
86
|
+
<BottomSheet open onClose={onCancel}>
|
|
87
|
+
<div className="px-4 pb-4">
|
|
88
|
+
<h2 className="text-base font-semibold mb-3">{title}</h2>
|
|
89
|
+
{body}
|
|
90
|
+
</div>
|
|
91
|
+
</BottomSheet>
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return (
|
|
96
|
+
<Dialog open onOpenChange={(open) => !open && onCancel()}>
|
|
97
|
+
<DialogContent>
|
|
98
|
+
<DialogHeader>
|
|
99
|
+
<DialogTitle>{title}</DialogTitle>
|
|
100
|
+
</DialogHeader>
|
|
101
|
+
{body}
|
|
102
|
+
</DialogContent>
|
|
103
|
+
</Dialog>
|
|
104
|
+
);
|
|
105
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { useRef, useEffect, memo } from "react";
|
|
2
|
+
import { useElementWidth } from "@/hooks/use-element-width";
|
|
3
|
+
import { resolveScaleMax, resolveCssColor } from "./chart-scale";
|
|
4
|
+
|
|
5
|
+
export interface MetricSeries {
|
|
6
|
+
data: number[];
|
|
7
|
+
color: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
interface MetricChartCanvasProps {
|
|
11
|
+
/** 1-2 series drawn on the same axis. */
|
|
12
|
+
series: MetricSeries[];
|
|
13
|
+
height: number;
|
|
14
|
+
/** Fixed scale ceiling (e.g. 100 for a percentage axis). Omitted = autoscale to
|
|
15
|
+
* the max across all series in the visible window. */
|
|
16
|
+
maxValue?: number;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** Generalised, filled, multi-series canvas chart for the Overview cards. Fills the
|
|
20
|
+
* width of its parent — the cards live in a resizable floating window, so a fixed
|
|
21
|
+
* pixel width overflows the card as soon as the window is narrower than designed.
|
|
22
|
+
* No redraw throttle — one draw per prop change, which at a 2s tick cadence is
|
|
23
|
+
* nowhere near a frame budget. */
|
|
24
|
+
export const MetricChartCanvas = memo(function MetricChartCanvas({
|
|
25
|
+
series,
|
|
26
|
+
height,
|
|
27
|
+
maxValue,
|
|
28
|
+
}: MetricChartCanvasProps) {
|
|
29
|
+
const wrapperRef = useRef<HTMLDivElement>(null);
|
|
30
|
+
const canvasRef = useRef<HTMLCanvasElement>(null);
|
|
31
|
+
const width = useElementWidth(wrapperRef);
|
|
32
|
+
|
|
33
|
+
useEffect(() => {
|
|
34
|
+
const canvas = canvasRef.current;
|
|
35
|
+
if (!canvas || width === 0) return;
|
|
36
|
+
const ctx = canvas.getContext("2d");
|
|
37
|
+
if (!ctx) return;
|
|
38
|
+
|
|
39
|
+
const dpr = window.devicePixelRatio || 1;
|
|
40
|
+
canvas.width = width * dpr;
|
|
41
|
+
canvas.height = height * dpr;
|
|
42
|
+
ctx.scale(dpr, dpr);
|
|
43
|
+
ctx.clearRect(0, 0, width, height);
|
|
44
|
+
|
|
45
|
+
// Resolved once per draw, not per point — `var(...)` is not a canvas-resolvable
|
|
46
|
+
// color, so every strokeStyle/fillStyle assignment below must go through this.
|
|
47
|
+
const style = getComputedStyle(canvas);
|
|
48
|
+
const colorOf = (c: string) => resolveCssColor(c, style);
|
|
49
|
+
|
|
50
|
+
const padding = 2;
|
|
51
|
+
const drawH = height - padding * 2;
|
|
52
|
+
const longest = Math.max(1, ...series.map((s) => s.data.length));
|
|
53
|
+
|
|
54
|
+
// A flat baseline when there isn't enough data yet to draw a meaningful line —
|
|
55
|
+
// a freshly-opened window otherwise shows nothing at all for the first tick.
|
|
56
|
+
if (longest < 2) {
|
|
57
|
+
ctx.beginPath();
|
|
58
|
+
ctx.strokeStyle = colorOf("var(--color-border)");
|
|
59
|
+
ctx.lineWidth = 1;
|
|
60
|
+
ctx.moveTo(0, height - padding);
|
|
61
|
+
ctx.lineTo(width, height - padding);
|
|
62
|
+
ctx.stroke();
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const scaleMax = resolveScaleMax(series.flatMap((s) => s.data), maxValue);
|
|
67
|
+
|
|
68
|
+
for (const s of series) {
|
|
69
|
+
if (s.data.length < 2) continue;
|
|
70
|
+
const localStepX = width / (s.data.length - 1);
|
|
71
|
+
|
|
72
|
+
// Filled area under the line.
|
|
73
|
+
ctx.beginPath();
|
|
74
|
+
ctx.moveTo(0, height - padding);
|
|
75
|
+
for (let i = 0; i < s.data.length; i++) {
|
|
76
|
+
const x = i * localStepX;
|
|
77
|
+
const y = padding + drawH - (s.data[i]! / scaleMax) * drawH;
|
|
78
|
+
ctx.lineTo(x, y);
|
|
79
|
+
}
|
|
80
|
+
ctx.lineTo((s.data.length - 1) * localStepX, height - padding);
|
|
81
|
+
ctx.closePath();
|
|
82
|
+
ctx.fillStyle = colorOf(s.color);
|
|
83
|
+
ctx.globalAlpha = 0.12;
|
|
84
|
+
ctx.fill();
|
|
85
|
+
ctx.globalAlpha = 1;
|
|
86
|
+
|
|
87
|
+
// Line on top.
|
|
88
|
+
ctx.beginPath();
|
|
89
|
+
ctx.strokeStyle = colorOf(s.color);
|
|
90
|
+
ctx.lineWidth = 1.5;
|
|
91
|
+
ctx.lineJoin = "round";
|
|
92
|
+
for (let i = 0; i < s.data.length; i++) {
|
|
93
|
+
const x = i * localStepX;
|
|
94
|
+
const y = padding + drawH - (s.data[i]! / scaleMax) * drawH;
|
|
95
|
+
if (i === 0) ctx.moveTo(x, y);
|
|
96
|
+
else ctx.lineTo(x, y);
|
|
97
|
+
}
|
|
98
|
+
ctx.stroke();
|
|
99
|
+
}
|
|
100
|
+
}, [series, width, height, maxValue]);
|
|
101
|
+
|
|
102
|
+
return (
|
|
103
|
+
<div ref={wrapperRef} className="w-full min-w-0 overflow-hidden" style={{ height }}>
|
|
104
|
+
<canvas ref={canvasRef} style={{ width: width || "100%", height }} className="block" />
|
|
105
|
+
</div>
|
|
106
|
+
);
|
|
107
|
+
});
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { MetricChartCanvas } from "../metric-chart-canvas";
|
|
2
|
+
import { CpuCoreBars } from "../cpu-core-bars";
|
|
3
|
+
|
|
4
|
+
export interface CpuCardProps {
|
|
5
|
+
total: number;
|
|
6
|
+
cores: number[];
|
|
7
|
+
model: string;
|
|
8
|
+
series: number[];
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function cpuColor(pct: number): string {
|
|
12
|
+
if (pct > 80) return "text-error";
|
|
13
|
+
if (pct > 50) return "text-warning";
|
|
14
|
+
return "text-success";
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function CpuCard({ total, cores, model, series }: CpuCardProps) {
|
|
18
|
+
return (
|
|
19
|
+
<div
|
|
20
|
+
className="rounded-lg border border-border p-4 space-y-2"
|
|
21
|
+
data-testid="sysmon-card-cpu"
|
|
22
|
+
data-cpu-total={total}
|
|
23
|
+
>
|
|
24
|
+
<div className="flex items-baseline justify-between">
|
|
25
|
+
<h3 className="text-sm font-medium">CPU</h3>
|
|
26
|
+
<span className={`text-2xl font-semibold ${cpuColor(total)}`}>{total.toFixed(1)}%</span>
|
|
27
|
+
</div>
|
|
28
|
+
<MetricChartCanvas
|
|
29
|
+
series={[{ data: series, color: "var(--color-primary)" }]}
|
|
30
|
+
height={56}
|
|
31
|
+
maxValue={100}
|
|
32
|
+
/>
|
|
33
|
+
<CpuCoreBars cores={cores} />
|
|
34
|
+
<p className="text-[11px] text-text-subtle truncate" title={model}>
|
|
35
|
+
{model}
|
|
36
|
+
</p>
|
|
37
|
+
</div>
|
|
38
|
+
);
|
|
39
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { formatBps } from "@/lib/format-bytes";
|
|
2
|
+
import { MetricChartCanvas } from "../metric-chart-canvas";
|
|
3
|
+
|
|
4
|
+
export interface DiskCardProps {
|
|
5
|
+
available: boolean;
|
|
6
|
+
inBps: number;
|
|
7
|
+
outBps: number;
|
|
8
|
+
readSeries: number[];
|
|
9
|
+
writeSeries: number[];
|
|
10
|
+
/** True while the stream has not yet delivered a second tick — a rate needs two
|
|
11
|
+
* samples, so `available:false` here is expected, not a missing collector. */
|
|
12
|
+
measuring?: boolean;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function DiskCard({ available, inBps, outBps, readSeries, writeSeries, measuring }: DiskCardProps) {
|
|
16
|
+
return (
|
|
17
|
+
<div
|
|
18
|
+
className="rounded-lg border border-border p-4 space-y-2"
|
|
19
|
+
data-testid="sysmon-card-disk"
|
|
20
|
+
data-available={available}
|
|
21
|
+
>
|
|
22
|
+
<h3 className="text-sm font-medium">Disk</h3>
|
|
23
|
+
{available ? (
|
|
24
|
+
<>
|
|
25
|
+
<MetricChartCanvas
|
|
26
|
+
series={[
|
|
27
|
+
{ data: readSeries, color: "var(--color-primary)" },
|
|
28
|
+
{ data: writeSeries, color: "var(--color-warning)" },
|
|
29
|
+
]}
|
|
30
|
+
height={56}
|
|
31
|
+
/>
|
|
32
|
+
<p className="text-[11px] text-text-subtle">
|
|
33
|
+
Read {formatBps(inBps)} · Write {formatBps(outBps)}
|
|
34
|
+
</p>
|
|
35
|
+
</>
|
|
36
|
+
) : (
|
|
37
|
+
<p className="text-[11px] text-text-subtle">{measuring ? "measuring…" : "n/a"}</p>
|
|
38
|
+
)}
|
|
39
|
+
</div>
|
|
40
|
+
);
|
|
41
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { formatRam } from "@/lib/format-bytes";
|
|
2
|
+
import { MetricChartCanvas } from "../metric-chart-canvas";
|
|
3
|
+
|
|
4
|
+
export interface GpuCardProps {
|
|
5
|
+
name: string;
|
|
6
|
+
utilPercent: number;
|
|
7
|
+
vramUsedMB: number;
|
|
8
|
+
vramTotalMB: number;
|
|
9
|
+
series: number[];
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/** One card per GPU. The caller (`overview-panel.tsx`) renders zero of these when
|
|
13
|
+
* `system.gpus` is empty — hide, never a disabled placeholder card. */
|
|
14
|
+
export function GpuCard({ name, utilPercent, vramUsedMB, vramTotalMB, series }: GpuCardProps) {
|
|
15
|
+
return (
|
|
16
|
+
<div className="rounded-lg border border-border p-4 space-y-2" data-testid="sysmon-card-gpu">
|
|
17
|
+
<div className="flex items-baseline justify-between gap-2">
|
|
18
|
+
<h3 className="text-sm font-medium truncate" title={name}>
|
|
19
|
+
{name}
|
|
20
|
+
</h3>
|
|
21
|
+
<span className="text-2xl font-semibold shrink-0">{utilPercent.toFixed(0)}%</span>
|
|
22
|
+
</div>
|
|
23
|
+
<MetricChartCanvas
|
|
24
|
+
series={[{ data: series, color: "var(--color-primary)" }]}
|
|
25
|
+
height={56}
|
|
26
|
+
maxValue={100}
|
|
27
|
+
/>
|
|
28
|
+
<p className="text-[11px] text-text-subtle">
|
|
29
|
+
VRAM {formatRam(vramUsedMB)} / {formatRam(vramTotalMB)}
|
|
30
|
+
</p>
|
|
31
|
+
</div>
|
|
32
|
+
);
|
|
33
|
+
}
|