@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,32 @@
|
|
|
1
|
+
import { formatRam } from "@/lib/format-bytes";
|
|
2
|
+
import { MetricChartCanvas } from "../metric-chart-canvas";
|
|
3
|
+
|
|
4
|
+
export interface MemCardProps {
|
|
5
|
+
usedMB: number;
|
|
6
|
+
totalMB: number;
|
|
7
|
+
percent: number;
|
|
8
|
+
series: number[];
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function MemCard({ usedMB, totalMB, percent, series }: MemCardProps) {
|
|
12
|
+
return (
|
|
13
|
+
<div
|
|
14
|
+
className="rounded-lg border border-border p-4 space-y-2"
|
|
15
|
+
data-testid="sysmon-card-mem"
|
|
16
|
+
data-mem-percent={percent}
|
|
17
|
+
>
|
|
18
|
+
<div className="flex items-baseline justify-between">
|
|
19
|
+
<h3 className="text-sm font-medium">Memory</h3>
|
|
20
|
+
<span className="text-2xl font-semibold">{percent.toFixed(1)}%</span>
|
|
21
|
+
</div>
|
|
22
|
+
<MetricChartCanvas
|
|
23
|
+
series={[{ data: series, color: "var(--color-primary)" }]}
|
|
24
|
+
height={56}
|
|
25
|
+
maxValue={100}
|
|
26
|
+
/>
|
|
27
|
+
<p className="text-[11px] text-text-subtle">
|
|
28
|
+
{formatRam(usedMB)} / {formatRam(totalMB)}
|
|
29
|
+
</p>
|
|
30
|
+
</div>
|
|
31
|
+
);
|
|
32
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { formatBps } from "@/lib/format-bytes";
|
|
2
|
+
import { MetricChartCanvas } from "../metric-chart-canvas";
|
|
3
|
+
|
|
4
|
+
export interface NetCardProps {
|
|
5
|
+
available: boolean;
|
|
6
|
+
inBps: number;
|
|
7
|
+
outBps: number;
|
|
8
|
+
downSeries: number[];
|
|
9
|
+
upSeries: 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 NetCard({ available, inBps, outBps, downSeries, upSeries, measuring }: NetCardProps) {
|
|
16
|
+
return (
|
|
17
|
+
<div
|
|
18
|
+
className="rounded-lg border border-border p-4 space-y-2"
|
|
19
|
+
data-testid="sysmon-card-net"
|
|
20
|
+
data-available={available}
|
|
21
|
+
>
|
|
22
|
+
<h3 className="text-sm font-medium">Network</h3>
|
|
23
|
+
{available ? (
|
|
24
|
+
<>
|
|
25
|
+
<MetricChartCanvas
|
|
26
|
+
series={[
|
|
27
|
+
{ data: downSeries, color: "var(--color-primary)" },
|
|
28
|
+
{ data: upSeries, color: "var(--color-warning)" },
|
|
29
|
+
]}
|
|
30
|
+
height={56}
|
|
31
|
+
/>
|
|
32
|
+
<p className="text-[11px] text-text-subtle">
|
|
33
|
+
Down {formatBps(inBps)} · Up {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,97 @@
|
|
|
1
|
+
import { useMemo } from "react";
|
|
2
|
+
import type { MetricsHistoryPoint, SystemMetrics } from "../../../types/system-metrics";
|
|
3
|
+
import { CpuCard } from "./overview-cards/cpu-card";
|
|
4
|
+
import { MemCard } from "./overview-cards/mem-card";
|
|
5
|
+
import { DiskCard } from "./overview-cards/disk-card";
|
|
6
|
+
import { NetCard } from "./overview-cards/net-card";
|
|
7
|
+
import { GpuCard } from "./overview-cards/gpu-card";
|
|
8
|
+
|
|
9
|
+
export interface OverviewPanelProps {
|
|
10
|
+
system: SystemMetrics;
|
|
11
|
+
history: MetricsHistoryPoint[];
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const SERIES_POINTS = 200;
|
|
15
|
+
|
|
16
|
+
/** One pass over the recent history window building every card's series together,
|
|
17
|
+
* rather than one `.slice(-200).map(...)` per card. */
|
|
18
|
+
function useOverviewSeries(history: MetricsHistoryPoint[]) {
|
|
19
|
+
return useMemo(() => {
|
|
20
|
+
const recent = history.slice(-SERIES_POINTS);
|
|
21
|
+
const cpu: number[] = [];
|
|
22
|
+
const mem: number[] = [];
|
|
23
|
+
const diskRead: number[] = [];
|
|
24
|
+
const diskWrite: number[] = [];
|
|
25
|
+
const netDown: number[] = [];
|
|
26
|
+
const netUp: number[] = [];
|
|
27
|
+
const gpuUtil: number[][] = [];
|
|
28
|
+
|
|
29
|
+
for (const point of recent) {
|
|
30
|
+
cpu.push(point.system.cpu.total);
|
|
31
|
+
mem.push(point.system.mem.percent);
|
|
32
|
+
diskRead.push(point.system.disk.available ? point.system.disk.inBps : 0);
|
|
33
|
+
diskWrite.push(point.system.disk.available ? point.system.disk.outBps : 0);
|
|
34
|
+
netDown.push(point.system.net.available ? point.system.net.inBps : 0);
|
|
35
|
+
netUp.push(point.system.net.available ? point.system.net.outBps : 0);
|
|
36
|
+
point.system.gpus.forEach((g, i) => {
|
|
37
|
+
(gpuUtil[i] ??= []).push(g.utilPercent);
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return { cpu, mem, diskRead, diskWrite, netDown, netUp, gpuUtil };
|
|
42
|
+
}, [history]);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function OverviewPanel({ system, history }: OverviewPanelProps) {
|
|
46
|
+
const series = useOverviewSeries(history);
|
|
47
|
+
// Disk/net rates need a delta between two samples — `available:false` on the very
|
|
48
|
+
// first frame(s) is the collector doing exactly what it should, not a missing
|
|
49
|
+
// source, so the card says so instead of the flat, indistinguishable "n/a".
|
|
50
|
+
const measuring = history.length <= 1;
|
|
51
|
+
|
|
52
|
+
return (
|
|
53
|
+
<div
|
|
54
|
+
className="p-4 grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4"
|
|
55
|
+
data-testid="sysmon-overview"
|
|
56
|
+
>
|
|
57
|
+
<CpuCard
|
|
58
|
+
total={system.cpu.total}
|
|
59
|
+
cores={system.cpu.cores}
|
|
60
|
+
model={system.cpu.model}
|
|
61
|
+
series={series.cpu}
|
|
62
|
+
/>
|
|
63
|
+
<MemCard
|
|
64
|
+
usedMB={system.mem.usedMB}
|
|
65
|
+
totalMB={system.mem.totalMB}
|
|
66
|
+
percent={system.mem.percent}
|
|
67
|
+
series={series.mem}
|
|
68
|
+
/>
|
|
69
|
+
<DiskCard
|
|
70
|
+
available={system.disk.available}
|
|
71
|
+
inBps={system.disk.inBps}
|
|
72
|
+
outBps={system.disk.outBps}
|
|
73
|
+
readSeries={series.diskRead}
|
|
74
|
+
writeSeries={series.diskWrite}
|
|
75
|
+
measuring={measuring}
|
|
76
|
+
/>
|
|
77
|
+
<NetCard
|
|
78
|
+
available={system.net.available}
|
|
79
|
+
inBps={system.net.inBps}
|
|
80
|
+
outBps={system.net.outBps}
|
|
81
|
+
downSeries={series.netDown}
|
|
82
|
+
upSeries={series.netUp}
|
|
83
|
+
measuring={measuring}
|
|
84
|
+
/>
|
|
85
|
+
{system.gpus.map((gpu, i) => (
|
|
86
|
+
<GpuCard
|
|
87
|
+
key={`${gpu.name}-${i}`}
|
|
88
|
+
name={gpu.name}
|
|
89
|
+
utilPercent={gpu.utilPercent}
|
|
90
|
+
vramUsedMB={gpu.vramUsedMB}
|
|
91
|
+
vramTotalMB={gpu.vramTotalMB}
|
|
92
|
+
series={series.gpuUtil[i] ?? []}
|
|
93
|
+
/>
|
|
94
|
+
))}
|
|
95
|
+
</div>
|
|
96
|
+
);
|
|
97
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/** Pure grid-template builder for the process table. No React, so the visibility
|
|
2
|
+
* rules (which optional columns exist, which one survives below `@lg`) and the
|
|
3
|
+
* user-resized widths are unit-testable without mounting a component.
|
|
4
|
+
*
|
|
5
|
+
* Two responsive templates are computed up front and switched via CSS custom
|
|
6
|
+
* properties + a `@lg:` Tailwind class (see `PROCESS_ROW_GRID_CLASS` below) —
|
|
7
|
+
* Tailwind's arbitrary-value scan only needs the class NAME to be a static
|
|
8
|
+
* string; the var() value itself can vary at runtime. */
|
|
9
|
+
import type { CSSProperties } from "react";
|
|
10
|
+
import type { ProcessColumnAvailability, SortKey } from "../../../types/system-metrics";
|
|
11
|
+
|
|
12
|
+
export type OptionalColumnKey = "disk" | "gpu" | "net";
|
|
13
|
+
/** Every column whose width the user can drag. The name column takes the rest. */
|
|
14
|
+
export type ResizableColumnKey = "cpu" | "ram" | OptionalColumnKey;
|
|
15
|
+
|
|
16
|
+
/** Alias kept local so call sites don't need to know the exact server-contract
|
|
17
|
+
* type name — this module only cares about the three boolean flags. */
|
|
18
|
+
export type ProcessColumnsFlags = ProcessColumnAvailability;
|
|
19
|
+
|
|
20
|
+
/** px overrides from a drag; missing keys fall back to `DEFAULT_COLUMN_WIDTH`. */
|
|
21
|
+
export type ColumnWidths = Partial<Record<ResizableColumnKey, number>>;
|
|
22
|
+
|
|
23
|
+
const OPTIONAL_COLUMN_ORDER: OptionalColumnKey[] = ["disk", "gpu", "net"];
|
|
24
|
+
|
|
25
|
+
/** Disk/Net cells show two values ("↓ read ↑ write"); GPU shows one composite
|
|
26
|
+
* ("12% · 1.1 GB") and fits narrower. */
|
|
27
|
+
export const DEFAULT_COLUMN_WIDTH: Record<ResizableColumnKey, number> = {
|
|
28
|
+
cpu: 64,
|
|
29
|
+
ram: 80,
|
|
30
|
+
disk: 120,
|
|
31
|
+
gpu: 90,
|
|
32
|
+
net: 120,
|
|
33
|
+
};
|
|
34
|
+
/** Drag bounds: below 48px a "1.2 MB/s" no longer fits; above 400px the name
|
|
35
|
+
* column starves in a default-size window. */
|
|
36
|
+
export const MIN_COLUMN_WIDTH = 48;
|
|
37
|
+
export const MAX_COLUMN_WIDTH = 400;
|
|
38
|
+
|
|
39
|
+
const NAME_TRACK = "minmax(0,1fr)";
|
|
40
|
+
const KILL_TRACK = "44px";
|
|
41
|
+
|
|
42
|
+
export interface ProcessGridResult {
|
|
43
|
+
/** Grid template for `@lg` and up: Name/CPU/RAM + every enabled optional column
|
|
44
|
+
* in a fixed order + kill button. */
|
|
45
|
+
wideTemplate: string;
|
|
46
|
+
/** Grid template below `@lg`: Name/CPU/RAM + AT MOST the one optional column
|
|
47
|
+
* currently sorted by (if enabled) + kill button. */
|
|
48
|
+
narrowTemplate: string;
|
|
49
|
+
/** Which optional columns are enabled at all (host can measure them). */
|
|
50
|
+
columns: ProcessColumnsFlags;
|
|
51
|
+
/** The single optional column visible below `@lg`, or null when the current
|
|
52
|
+
* sort isn't on an optional column (or that column isn't enabled). */
|
|
53
|
+
narrowExtra: OptionalColumnKey | null;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function isOptionalColumnKey(key: SortKey): key is OptionalColumnKey {
|
|
57
|
+
return key === "disk" || key === "gpu" || key === "net";
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function clampColumnWidth(px: number): number {
|
|
61
|
+
return Math.round(Math.min(MAX_COLUMN_WIDTH, Math.max(MIN_COLUMN_WIDTH, px)));
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function columnWidthPx(key: ResizableColumnKey, widths: ColumnWidths): number {
|
|
65
|
+
const w = widths[key];
|
|
66
|
+
return typeof w === "number" && Number.isFinite(w) ? clampColumnWidth(w) : DEFAULT_COLUMN_WIDTH[key];
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export function buildProcessGrid(
|
|
70
|
+
columns: ProcessColumnsFlags,
|
|
71
|
+
sortKey: SortKey,
|
|
72
|
+
widths: ColumnWidths = {},
|
|
73
|
+
): ProcessGridResult {
|
|
74
|
+
const enabled = OPTIONAL_COLUMN_ORDER.filter((k) => columns[k]);
|
|
75
|
+
const narrowExtra = isOptionalColumnKey(sortKey) && columns[sortKey] ? sortKey : null;
|
|
76
|
+
const track = (k: ResizableColumnKey) => `${columnWidthPx(k, widths)}px`;
|
|
77
|
+
const base = [NAME_TRACK, track("cpu"), track("ram")];
|
|
78
|
+
|
|
79
|
+
const wideTemplate = [...base, ...enabled.map(track), KILL_TRACK].join(" ");
|
|
80
|
+
const narrowTemplate = [...base, ...(narrowExtra ? [track(narrowExtra)] : []), KILL_TRACK].join(" ");
|
|
81
|
+
|
|
82
|
+
return { wideTemplate, narrowTemplate, columns, narrowExtra };
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/** Static class names (Tailwind can see both arbitrary-value strings at build
|
|
86
|
+
* time); the actual template text is supplied per-render via the two CSS
|
|
87
|
+
* custom properties in `gridCssVars`. */
|
|
88
|
+
export const PROCESS_ROW_GRID_CLASS = "grid-cols-[var(--sysmon-grid-n)] @lg:grid-cols-[var(--sysmon-grid-w)]";
|
|
89
|
+
|
|
90
|
+
export function gridCssVars(grid: ProcessGridResult): CSSProperties {
|
|
91
|
+
return {
|
|
92
|
+
"--sysmon-grid-n": grid.narrowTemplate,
|
|
93
|
+
"--sysmon-grid-w": grid.wideTemplate,
|
|
94
|
+
} as CSSProperties;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/** Visibility className for an optional column's cell: always visible when it is
|
|
98
|
+
* the narrow-mode survivor, otherwise hidden below `@lg` and shown at `@lg`+.
|
|
99
|
+
* Caller must only render the cell at all when `columns[key]` is true — when
|
|
100
|
+
* disabled, the column has no track in either template. */
|
|
101
|
+
export function optionalCellClassName(grid: ProcessGridResult, key: OptionalColumnKey): string {
|
|
102
|
+
return grid.narrowExtra === key ? "block" : "hidden @lg:block";
|
|
103
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { ChevronRight, ChevronDown, X } from "lucide-react";
|
|
2
|
+
import { cn } from "@/lib/utils";
|
|
3
|
+
import { formatRam } from "@/lib/format-bytes";
|
|
4
|
+
import { cpuColor, formatDiskCell, formatGpuCell, formatNetCell, sumOptionalBps } from "./process-row-format";
|
|
5
|
+
import { optionalCellClassName, type ProcessGridResult } from "./process-columns-grid";
|
|
6
|
+
import type { ProcessGroup } from "../../../types/system-metrics";
|
|
7
|
+
|
|
8
|
+
const PROTECTED_GROUP_TOOLTIP = "Protected: this app contains a PPM or OS-critical process — cannot be ended as a whole.";
|
|
9
|
+
|
|
10
|
+
export interface ProcessGroupRowProps {
|
|
11
|
+
group: ProcessGroup;
|
|
12
|
+
expanded: boolean;
|
|
13
|
+
grid: ProcessGridResult;
|
|
14
|
+
/** True when any member is refused by the kill guard — the whole-app button is disabled. */
|
|
15
|
+
killProtected: boolean;
|
|
16
|
+
onToggle: (key: string) => void;
|
|
17
|
+
onKillClick: (group: ProcessGroup) => void;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function ProcessGroupRow({ group, expanded, grid, killProtected, onToggle, onKillClick }: ProcessGroupRowProps) {
|
|
21
|
+
const Chevron = expanded ? ChevronDown : ChevronRight;
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<div
|
|
25
|
+
className="grid items-center gap-1 min-h-11 md:min-h-7 px-3 text-xs cursor-pointer hover:bg-surface-hover transition-colors group/proc grid-cols-[var(--sysmon-grid-n)] @lg:grid-cols-[var(--sysmon-grid-w)]"
|
|
26
|
+
onClick={() => onToggle(group.key)}
|
|
27
|
+
data-testid="sysmon-group-row"
|
|
28
|
+
data-group-key={group.key}
|
|
29
|
+
data-count={group.count}
|
|
30
|
+
data-disk-bps={sumOptionalBps(group.diskReadBps, group.diskWriteBps)}
|
|
31
|
+
data-gpu-pct={group.gpuPct}
|
|
32
|
+
data-net-bps={sumOptionalBps(group.netInBps, group.netOutBps)}
|
|
33
|
+
>
|
|
34
|
+
<div className="flex items-center gap-1.5 min-w-0">
|
|
35
|
+
<button
|
|
36
|
+
type="button"
|
|
37
|
+
onClick={(e) => {
|
|
38
|
+
e.stopPropagation();
|
|
39
|
+
onToggle(group.key);
|
|
40
|
+
}}
|
|
41
|
+
aria-expanded={expanded}
|
|
42
|
+
aria-label={`${expanded ? "Collapse" : "Expand"} ${group.label}`}
|
|
43
|
+
data-testid="sysmon-group-expand"
|
|
44
|
+
className="flex items-center justify-center size-11 md:size-7 -ml-2 shrink-0"
|
|
45
|
+
>
|
|
46
|
+
<Chevron className="size-3.5 text-text-subtle" />
|
|
47
|
+
</button>
|
|
48
|
+
<span className="truncate font-medium">{group.label}</span>
|
|
49
|
+
<span className="text-text-subtle shrink-0">({group.count})</span>
|
|
50
|
+
</div>
|
|
51
|
+
<span className={cn("text-right", cpuColor(group.cpu))}>{group.cpu.toFixed(1)}%</span>
|
|
52
|
+
<span className="text-right text-text-secondary">{formatRam(group.ramMB)}</span>
|
|
53
|
+
{grid.columns.disk && (
|
|
54
|
+
<span className={cn("text-right text-text-secondary tabular-nums truncate", optionalCellClassName(grid, "disk"))}>
|
|
55
|
+
{formatDiskCell(group.diskReadBps, group.diskWriteBps)}
|
|
56
|
+
</span>
|
|
57
|
+
)}
|
|
58
|
+
{grid.columns.gpu && (
|
|
59
|
+
<span className={cn("text-right text-text-secondary tabular-nums truncate", optionalCellClassName(grid, "gpu"))}>
|
|
60
|
+
{formatGpuCell(group.gpuPct, group.gpuMemMB)}
|
|
61
|
+
</span>
|
|
62
|
+
)}
|
|
63
|
+
{grid.columns.net && (
|
|
64
|
+
<span className={cn("text-right text-text-secondary tabular-nums truncate", optionalCellClassName(grid, "net"))}>
|
|
65
|
+
{formatNetCell(group.netInBps, group.netOutBps)}
|
|
66
|
+
</span>
|
|
67
|
+
)}
|
|
68
|
+
{/* Same 44px track as the leaf rows' kill button, so ending a whole app (Notion
|
|
69
|
+
and its 7 helpers) is one click instead of seven. */}
|
|
70
|
+
<div className="flex justify-end">
|
|
71
|
+
<button
|
|
72
|
+
type="button"
|
|
73
|
+
onClick={(e) => {
|
|
74
|
+
e.stopPropagation();
|
|
75
|
+
onKillClick(group);
|
|
76
|
+
}}
|
|
77
|
+
disabled={killProtected}
|
|
78
|
+
aria-label={`End ${group.label} and its ${group.count} processes`}
|
|
79
|
+
title={killProtected ? PROTECTED_GROUP_TOOLTIP : `End ${group.label} (${group.count} processes)`}
|
|
80
|
+
data-testid="sysmon-group-kill-btn"
|
|
81
|
+
className={cn(
|
|
82
|
+
"flex items-center justify-center size-11 md:size-7 rounded transition-all",
|
|
83
|
+
"can-hover:opacity-0 can-hover:group-hover/proc:opacity-100",
|
|
84
|
+
killProtected
|
|
85
|
+
? "opacity-40 cursor-not-allowed"
|
|
86
|
+
: "hover:bg-error/20 hover:text-error active:bg-error/30",
|
|
87
|
+
)}
|
|
88
|
+
>
|
|
89
|
+
<X className="size-3.5" />
|
|
90
|
+
</button>
|
|
91
|
+
</div>
|
|
92
|
+
</div>
|
|
93
|
+
);
|
|
94
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/** Formatting helpers for a single process row, salvaged from the deleted
|
|
2
|
+
* `system-monitor-group-row.tsx` byte-for-byte (same thresholds, same rounding).
|
|
3
|
+
* Grid template logic (which columns exist, the `@lg` trend/age track) now lives
|
|
4
|
+
* in `process-columns-grid.ts` since it grew a runtime dependency (enabled
|
|
5
|
+
* optional columns + active sort key) that no longer fits a static constant. */
|
|
6
|
+
import { formatBps, formatRam } from "@/lib/format-bytes";
|
|
7
|
+
|
|
8
|
+
export function cpuColor(cpu: number): string {
|
|
9
|
+
if (cpu > 80) return "text-error";
|
|
10
|
+
if (cpu > 50) return "text-warning";
|
|
11
|
+
return "text-success";
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function formatAge(startedAt?: number): string {
|
|
15
|
+
if (!startedAt) return "";
|
|
16
|
+
const secs = Math.round((Date.now() - startedAt) / 1000);
|
|
17
|
+
if (secs < 60) return `${secs}s`;
|
|
18
|
+
const mins = Math.floor(secs / 60);
|
|
19
|
+
if (mins < 60) return `${mins}m`;
|
|
20
|
+
const hrs = Math.floor(mins / 60);
|
|
21
|
+
if (hrs < 24) return `${hrs}h ${mins % 60}m`;
|
|
22
|
+
const days = Math.floor(hrs / 24);
|
|
23
|
+
return `${days}d ${hrs % 24}h`;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** `undefined` on both sides means the host cannot measure this metric for this
|
|
27
|
+
* row at all (contract: `undefined` = OS/tier cannot measure) — render an em
|
|
28
|
+
* dash rather than a misleading "0 B/s". A single defined side (e.g. read known,
|
|
29
|
+
* write not) still renders, treating the missing side as 0. */
|
|
30
|
+
export function formatDiskCell(readBps?: number, writeBps?: number): string {
|
|
31
|
+
if (readBps === undefined && writeBps === undefined) return "—";
|
|
32
|
+
return `↓ ${formatBps(readBps ?? 0)} ↑ ${formatBps(writeBps ?? 0)}`;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function formatNetCell(inBps?: number, outBps?: number): string {
|
|
36
|
+
if (inBps === undefined && outBps === undefined) return "—";
|
|
37
|
+
return `↓ ${formatBps(inBps ?? 0)} ↑ ${formatBps(outBps ?? 0)}`;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** GPU % and VRAM are measured independently on some platforms (e.g. NVIDIA
|
|
41
|
+
* consumer drivers on Linux only expose per-process memory, not per-process
|
|
42
|
+
* utilization) — each half renders its own dash when unmeasured. */
|
|
43
|
+
export function formatGpuCell(pct?: number, memMB?: number): string {
|
|
44
|
+
if (pct === undefined && memMB === undefined) return "—";
|
|
45
|
+
const pctText = pct === undefined ? "—" : `${pct.toFixed(0)}%`;
|
|
46
|
+
const memText = memMB === undefined ? "—" : formatRam(memMB);
|
|
47
|
+
return `${pctText} · ${memText}`;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** Row-level `data-*` sort attribute for e2e/debugging: sums a disk or net pair
|
|
51
|
+
* into one comparable number, `undefined` only when NEITHER side is measured —
|
|
52
|
+
* same rule the sort comparator and the cell formatters use. */
|
|
53
|
+
export function sumOptionalBps(a?: number, b?: number): number | undefined {
|
|
54
|
+
if (a === undefined && b === undefined) return undefined;
|
|
55
|
+
return (a ?? 0) + (b ?? 0);
|
|
56
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { X } from "lucide-react";
|
|
2
|
+
import { cn } from "@/lib/utils";
|
|
3
|
+
import { formatRam } from "@/lib/format-bytes";
|
|
4
|
+
import { cpuColor, formatAge, formatDiskCell, formatGpuCell, formatNetCell, sumOptionalBps } from "./process-row-format";
|
|
5
|
+
import { optionalCellClassName, type ProcessGridResult } from "./process-columns-grid";
|
|
6
|
+
import type { ProcessInfo } from "../../../types/system-metrics";
|
|
7
|
+
|
|
8
|
+
const PROTECTED_TOOLTIP = "Protected: PPM or OS-critical process — cannot be ended.";
|
|
9
|
+
|
|
10
|
+
export interface ProcessRowProps {
|
|
11
|
+
proc: ProcessInfo;
|
|
12
|
+
indent: boolean;
|
|
13
|
+
grid: ProcessGridResult;
|
|
14
|
+
onKillClick: (proc: ProcessInfo) => void;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function ProcessRow({ proc, indent, grid, onKillClick }: ProcessRowProps) {
|
|
18
|
+
return (
|
|
19
|
+
<div
|
|
20
|
+
className="grid items-center gap-1 min-h-11 md:min-h-7 px-3 text-xs group/proc hover:bg-surface-hover transition-colors grid-cols-[var(--sysmon-grid-n)] @lg:grid-cols-[var(--sysmon-grid-w)]"
|
|
21
|
+
data-testid="sysmon-process-row"
|
|
22
|
+
data-pid={proc.pid}
|
|
23
|
+
data-ppm={proc.ppm}
|
|
24
|
+
data-protected={proc.protected}
|
|
25
|
+
data-disk-bps={sumOptionalBps(proc.diskReadBps, proc.diskWriteBps)}
|
|
26
|
+
data-gpu-pct={proc.gpuPct}
|
|
27
|
+
data-net-bps={sumOptionalBps(proc.netInBps, proc.netOutBps)}
|
|
28
|
+
>
|
|
29
|
+
{/* Uptime lives in the tooltip: a dedicated column cost 130px for a figure
|
|
30
|
+
that matters only when you are already looking at one row. */}
|
|
31
|
+
<div className={cn("flex items-start gap-1.5 min-w-0", indent && "pl-6")}>
|
|
32
|
+
<span className="text-text-subtle shrink-0">{proc.pid}</span>
|
|
33
|
+
<span
|
|
34
|
+
className="truncate text-text-secondary"
|
|
35
|
+
title={proc.startedAt ? `${proc.command}\nRunning ${formatAge(proc.startedAt)}` : proc.command}
|
|
36
|
+
>
|
|
37
|
+
{proc.command}
|
|
38
|
+
</span>
|
|
39
|
+
</div>
|
|
40
|
+
<span className={cn("text-right", cpuColor(proc.cpu))}>{proc.cpu.toFixed(1)}%</span>
|
|
41
|
+
<span className="text-right text-text-secondary">{formatRam(proc.ramMB)}</span>
|
|
42
|
+
{grid.columns.disk && (
|
|
43
|
+
<span className={cn("text-right text-text-secondary tabular-nums truncate", optionalCellClassName(grid, "disk"))}>
|
|
44
|
+
{formatDiskCell(proc.diskReadBps, proc.diskWriteBps)}
|
|
45
|
+
</span>
|
|
46
|
+
)}
|
|
47
|
+
{grid.columns.gpu && (
|
|
48
|
+
<span className={cn("text-right text-text-secondary tabular-nums truncate", optionalCellClassName(grid, "gpu"))}>
|
|
49
|
+
{formatGpuCell(proc.gpuPct, proc.gpuMemMB)}
|
|
50
|
+
</span>
|
|
51
|
+
)}
|
|
52
|
+
{grid.columns.net && (
|
|
53
|
+
<span className={cn("text-right text-text-secondary tabular-nums truncate", optionalCellClassName(grid, "net"))}>
|
|
54
|
+
{formatNetCell(proc.netInBps, proc.netOutBps)}
|
|
55
|
+
</span>
|
|
56
|
+
)}
|
|
57
|
+
<div className="flex justify-end">
|
|
58
|
+
<button
|
|
59
|
+
type="button"
|
|
60
|
+
onClick={(e) => {
|
|
61
|
+
e.stopPropagation();
|
|
62
|
+
onKillClick(proc);
|
|
63
|
+
}}
|
|
64
|
+
disabled={proc.protected}
|
|
65
|
+
aria-label={`End process ${proc.name} (${proc.pid})`}
|
|
66
|
+
title={proc.protected ? PROTECTED_TOOLTIP : `End process ${proc.name}`}
|
|
67
|
+
data-testid="sysmon-kill-btn"
|
|
68
|
+
className={cn(
|
|
69
|
+
"flex items-center justify-center size-11 md:size-7 rounded transition-all",
|
|
70
|
+
"can-hover:opacity-0 can-hover:group-hover/proc:opacity-100",
|
|
71
|
+
proc.protected
|
|
72
|
+
? "opacity-40 cursor-not-allowed"
|
|
73
|
+
: "hover:bg-error/20 hover:text-error active:bg-error/30",
|
|
74
|
+
)}
|
|
75
|
+
>
|
|
76
|
+
<X className="size-3.5" />
|
|
77
|
+
</button>
|
|
78
|
+
</div>
|
|
79
|
+
</div>
|
|
80
|
+
);
|
|
81
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/** Pure filter/sort/flatten/rollup for the process table. No React, no I/O, so the
|
|
2
|
+
* filter/sort/expand/rollup rules are unit-testable without mounting a component.
|
|
3
|
+
* Sort comparator lives in `process-table-sort.ts`, totals accumulator in
|
|
4
|
+
* `process-table-totals.ts` — both split out to stay under the file-size guideline. */
|
|
5
|
+
import type { ProcessGroup, ProcessInfo, SortDir, SortKey } from "../../../types/system-metrics";
|
|
6
|
+
import { sortByKey, sortFields } from "./process-table-sort";
|
|
7
|
+
import { accumulateTotals, EMPTY_TOTALS, type Totals } from "./process-table-totals";
|
|
8
|
+
|
|
9
|
+
export type { Totals } from "./process-table-totals";
|
|
10
|
+
|
|
11
|
+
export type TableRow =
|
|
12
|
+
| { kind: "group"; group: ProcessGroup; expanded: boolean }
|
|
13
|
+
| { kind: "process"; proc: ProcessInfo; indent: boolean };
|
|
14
|
+
|
|
15
|
+
export interface BuildRowsInput {
|
|
16
|
+
processes: ProcessInfo[];
|
|
17
|
+
groups: ProcessGroup[];
|
|
18
|
+
mode: "grouped" | "flat";
|
|
19
|
+
ppmOnly: boolean;
|
|
20
|
+
query: string;
|
|
21
|
+
sortKey: SortKey;
|
|
22
|
+
sortDir: SortDir;
|
|
23
|
+
expanded: Set<string>;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface BuildRowsResult {
|
|
27
|
+
rows: TableRow[];
|
|
28
|
+
totals: Totals;
|
|
29
|
+
/** Group keys the search auto-expanded (only in grouped mode with a non-empty query). */
|
|
30
|
+
autoExpanded: Set<string>;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function matches(text: string, query: string): boolean {
|
|
34
|
+
return text.toLowerCase().includes(query);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function processMatches(proc: ProcessInfo, query: string): boolean {
|
|
38
|
+
return matches(proc.name, query) || matches(proc.command, query);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** Order fixed: filter (ppmOnly) -> filter (query) -> sort -> flatten (expand). */
|
|
42
|
+
export function buildRows(input: BuildRowsInput): BuildRowsResult {
|
|
43
|
+
const { processes, groups, mode, ppmOnly, query, sortKey, sortDir, expanded } = input;
|
|
44
|
+
const q = query.trim().toLowerCase();
|
|
45
|
+
const byPid = new Map(processes.map((p) => [p.pid, p]));
|
|
46
|
+
|
|
47
|
+
if (mode === "flat") {
|
|
48
|
+
let flat = ppmOnly ? processes.filter((p) => p.ppm) : processes;
|
|
49
|
+
if (q) flat = flat.filter((p) => processMatches(p, q));
|
|
50
|
+
flat = sortByKey(flat, sortKey, sortDir, (p) => sortFields(p, p.name));
|
|
51
|
+
|
|
52
|
+
const totals = flat.reduce((acc, p) => accumulateTotals(acc, p, 1), EMPTY_TOTALS);
|
|
53
|
+
|
|
54
|
+
return {
|
|
55
|
+
rows: flat.map((proc) => ({ kind: "process" as const, proc, indent: false })),
|
|
56
|
+
totals,
|
|
57
|
+
autoExpanded: new Set(),
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Grouped mode.
|
|
62
|
+
let filteredGroups = ppmOnly ? groups.filter((g) => g.ppm) : groups;
|
|
63
|
+
|
|
64
|
+
const autoExpanded = new Set<string>();
|
|
65
|
+
if (q) {
|
|
66
|
+
filteredGroups = filteredGroups.filter((g) => {
|
|
67
|
+
const labelMatch = matches(g.label, q);
|
|
68
|
+
const memberMatch = g.pids.some((pid) => {
|
|
69
|
+
const proc = byPid.get(pid);
|
|
70
|
+
return proc ? processMatches(proc, q) : false;
|
|
71
|
+
});
|
|
72
|
+
const isMatch = labelMatch || memberMatch;
|
|
73
|
+
if (isMatch && memberMatch) autoExpanded.add(g.key);
|
|
74
|
+
return isMatch;
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
filteredGroups = sortByKey(filteredGroups, sortKey, sortDir, (g) => sortFields(g, g.label));
|
|
79
|
+
|
|
80
|
+
const rows: TableRow[] = [];
|
|
81
|
+
for (const group of filteredGroups) {
|
|
82
|
+
const isExpanded = q ? autoExpanded.has(group.key) || expanded.has(group.key) : expanded.has(group.key);
|
|
83
|
+
rows.push({ kind: "group", group, expanded: isExpanded });
|
|
84
|
+
if (!isExpanded) continue;
|
|
85
|
+
|
|
86
|
+
// Skip pids the current snapshot no longer has — a process can exit between the
|
|
87
|
+
// server's tick and the client's render, or the group's own snapshot is already
|
|
88
|
+
// one tick stale. Must not throw.
|
|
89
|
+
let children = group.pids
|
|
90
|
+
.map((pid) => byPid.get(pid))
|
|
91
|
+
.filter((p): p is ProcessInfo => p !== undefined);
|
|
92
|
+
if (q) children = children.filter((p) => processMatches(p, q));
|
|
93
|
+
children = sortByKey(children, sortKey, sortDir, (p) => sortFields(p, p.name));
|
|
94
|
+
for (const proc of children) {
|
|
95
|
+
rows.push({ kind: "process", proc, indent: true });
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const totals = filteredGroups.reduce((acc, g) => accumulateTotals(acc, g, g.count), EMPTY_TOTALS);
|
|
100
|
+
|
|
101
|
+
return { rows, totals, autoExpanded };
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/** Three-state sort toggle: desc -> asc -> off, shared by every sortable column. */
|
|
105
|
+
export function toggleSort(current: SortKey, dir: SortDir, clicked: Exclude<SortKey, null>): [SortKey, SortDir] {
|
|
106
|
+
if (current !== clicked) return [clicked, "desc"];
|
|
107
|
+
if (dir === "desc") return [clicked, "asc"];
|
|
108
|
+
return [null, "desc"];
|
|
109
|
+
}
|