@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.
Files changed (513) hide show
  1. package/.spike/group-protected-probe.ts +21 -0
  2. package/.spike/s.err +63 -0
  3. package/.spike/tunnel.err +22 -0
  4. package/.spike/w.err +28 -0
  5. package/CHANGELOG.md +21 -0
  6. package/CLAUDE.md +1 -0
  7. package/assets/skills/ppm/SKILL.md +1 -1
  8. package/assets/skills/ppm/references/cli-reference.md +4 -4
  9. package/assets/skills/ppm/references/http-api.md +4 -3
  10. package/dist/web/assets/{ai-resource-editor-BydGrxjb.js → ai-resource-editor-mdDKG-rw.js} +1 -1
  11. package/dist/web/assets/{angular-html-jfMqUuRd.js → angular-html-Ctz0zN01.js} +1 -1
  12. package/dist/web/assets/{angular-ts-wytn9PMm.js → angular-ts-QXHpgB1C.js} +1 -1
  13. package/dist/web/assets/{api-settings-DlcoR5QT.js → api-settings-nblja3Rk.js} +1 -1
  14. package/dist/web/assets/{apl-i-ahKx6O.js → apl-b9KVk-O4.js} +1 -1
  15. package/dist/web/assets/architecture-PBZL5I3N-C7ra20CE.js +1 -0
  16. package/dist/web/assets/{astro-DVBCJfG6.js → astro-BlFEeGYr.js} +1 -1
  17. package/dist/web/assets/{audio-preview-DzBGq9Lk.js → audio-preview-CZLmhf__.js} +1 -1
  18. package/dist/web/assets/{blade-BHlL8SqU.js → blade-CGkj2MUI.js} +1 -1
  19. package/dist/web/assets/{bsl-D-UOfR1F.js → bsl-CVsbb6ap.js} +1 -1
  20. package/dist/web/assets/button-BA_fJOtX.js +1 -0
  21. package/dist/web/assets/{cairo-Bn6rucli.js → cairo-BbIHl2iE.js} +1 -1
  22. package/dist/web/assets/chat-tab-C060A94y.js +15 -0
  23. package/dist/web/assets/circle-hjUGru6R.js +1 -0
  24. package/dist/web/assets/circle-question-mark-CzR7YRc-.js +1 -0
  25. package/dist/web/assets/{cobol-Byn9FYKu.js → cobol-BWSGjmWb.js} +1 -1
  26. package/dist/web/assets/code-editor-WELegzdp.js +10 -0
  27. package/dist/web/assets/{coffee-DjBl4gm-.js → coffee-CWGNOxds.js} +1 -1
  28. package/dist/web/assets/{conflict-editor-CRConSGG.js → conflict-editor-fRTU3f1o.js} +3 -3
  29. package/dist/web/assets/{context-menu-DkQdt6YA.js → context-menu-Cq0u3SK9.js} +1 -1
  30. package/dist/web/assets/{cpp-CKzic-3E.js → cpp-DHGV24J2.js} +1 -1
  31. package/dist/web/assets/{crystal-Bkg-Ly_g.js → crystal-Vlwf2UMP.js} +1 -1
  32. package/dist/web/assets/{csv-preview-BtCGfmrq.js → csv-preview-D1d0cxOJ.js} +1 -1
  33. package/dist/web/assets/{data-grid-overlay-editor-B1mTl3KS.js → data-grid-overlay-editor-D9il5DZS.js} +1 -1
  34. package/dist/web/assets/{database-viewer-2M5sKRqb.js → database-viewer-DevnWTV4.js} +1 -1
  35. package/dist/web/assets/{diff-viewer-BMr7vOvZ.js → diff-viewer-DGxVg1pD.js} +1 -1
  36. package/dist/web/assets/{docx-preview-BpG2kr_-.js → docx-preview-Cx-zLwAw.js} +1 -1
  37. package/dist/web/assets/{edge-DVbZnd3Y.js → edge-Bhqk64zS.js} +1 -1
  38. package/dist/web/assets/{edit-diff-preview-BivQwZMD.js → edit-diff-preview-gq6ALf2B.js} +1 -1
  39. package/dist/web/assets/{elixir-Dwi8Wu7W.js → elixir-D466WCFm.js} +1 -1
  40. package/dist/web/assets/{elm-DtIv-HXJ.js → elm-Bfs2qNPR.js} +1 -1
  41. package/dist/web/assets/{erb-D3HEDz1x.js → erb-WI7jUaB6.js} +1 -1
  42. package/dist/web/assets/{erlang-2MjTCzGz.js → erlang-BCBe8nCc.js} +1 -1
  43. package/dist/web/assets/{esm-CZ8B8Ba2.js → esm-CZs9WVDO.js} +1 -1
  44. package/dist/web/assets/{explorer-body-DXufyj-9.js → explorer-body-j_4hVc34.js} +2 -2
  45. package/dist/web/assets/{explorer-window-content-B3krk4G1.js → explorer-window-content-DdrGwk3w.js} +1 -1
  46. package/dist/web/assets/{extension-webview-12M45CGq.js → extension-webview-BH_mWYMe.js} +1 -1
  47. package/dist/web/assets/format-bytes-BE_W3UBg.js +1 -0
  48. package/dist/web/assets/{fortran-fixed-form-BLyAtyPM.js → fortran-fixed-form-CXLIv8Ox.js} +1 -1
  49. package/dist/web/assets/{fsharp-Bxbn_gbr.js → fsharp-CZsYmiw9.js} +1 -1
  50. package/dist/web/assets/{gdresource-sFMY4D2Q.js → gdresource-BGRvoWfC.js} +1 -1
  51. package/dist/web/assets/{git-commit-BzB9Lio5.js → git-commit-DH6mY3Km.js} +1 -1
  52. package/dist/web/assets/{git-log-panel-Cp4k3tX_.js → git-log-panel-CfpXRJcP.js} +1 -1
  53. package/dist/web/assets/{git-rebase-CKSVd848.js → git-rebase-C5Gql6Ma.js} +1 -1
  54. package/dist/web/assets/gitGraph-HDMCJU4V-D4hYLNJU.js +1 -0
  55. package/dist/web/assets/{glide-data-grid-B0BB0VDl.js → glide-data-grid-n4ox_uev.js} +7 -7
  56. package/dist/web/assets/{glimmer-js-BY8aExAJ.js → glimmer-js-1-6JMJlj.js} +1 -1
  57. package/dist/web/assets/{glimmer-ts-Bak54dBX.js → glimmer-ts-C_Njj0nK.js} +1 -1
  58. package/dist/web/assets/{glsl-nR2eaJQe.js → glsl-DbkxE1TN.js} +1 -1
  59. package/dist/web/assets/{graphql-CGPPFAU6.js → graphql-BK75fiXl.js} +1 -1
  60. package/dist/web/assets/group-chat-tab-dYuuknLN.js +1 -0
  61. package/dist/web/assets/{hack-CXIMX-Ol.js → hack-DG151vit.js} +1 -1
  62. package/dist/web/assets/{haml-tPY-9Pfm.js → haml-DKeIPQWM.js} +1 -1
  63. package/dist/web/assets/{handlebars-BuW1LT7T.js → handlebars-398uCI13.js} +1 -1
  64. package/dist/web/assets/{html-bgVcwZ-t.js → html-NLWdst5q.js} +1 -1
  65. package/dist/web/assets/{html-derivative-D6-IxTgn.js → html-derivative-CJf_Le2z.js} +1 -1
  66. package/dist/web/assets/{http-CJ1zyB-h.js → http-G1K2FozA.js} +1 -1
  67. package/dist/web/assets/{hurl-CmoT7l3T.js → hurl-WDC6sSBz.js} +1 -1
  68. package/dist/web/assets/{hxml-CztOsL8o.js → hxml-Dc3jBXuf.js} +1 -1
  69. package/dist/web/assets/{image-preview-3HfuxA0N.js → image-preview-Ss38ex8g.js} +1 -1
  70. package/dist/web/assets/index-BiTiXgBZ.css +2 -0
  71. package/dist/web/assets/index-Ch8l9de-.js +52 -0
  72. package/dist/web/assets/info-3K5VOQVL-lRlrTlkb.js +1 -0
  73. package/dist/web/assets/{jinja-B1pq3jJq.js → jinja-CWsQj2y0.js} +1 -1
  74. package/dist/web/assets/{jison-D8B5pCwA.js → jison-CciJg2NW.js} +1 -1
  75. package/dist/web/assets/{julia-D0K3bwpU.js → julia-IOQNJAB7.js} +1 -1
  76. package/dist/web/assets/{just-B9Jlddu-.js → just-BGdHchwS.js} +1 -1
  77. package/dist/web/assets/{keybindings-store-oMJmtpH4.js → keybindings-store-CDfTjwZX.js} +1 -1
  78. package/dist/web/assets/{latex-BPJSSE6j.js → latex-D6TOl-L2.js} +1 -1
  79. package/dist/web/assets/{liquid-lv10fo4U.js → liquid-CVSvu_Wn.js} +1 -1
  80. package/dist/web/assets/{lua-PNuaIBEF.js → lua-CcKiU6HW.js} +1 -1
  81. package/dist/web/assets/{markdown-renderer-DPcoPjmO.js → markdown-renderer-B317vEys.js} +3 -3
  82. package/dist/web/assets/markdown-renderer-CpRlpLHw.js +1 -0
  83. package/dist/web/assets/{marko-Du3frD6X.js → marko--UOicMGo.js} +1 -1
  84. package/dist/web/assets/{mdc-BeDVcFRl.js → mdc-D690aU2C.js} +1 -1
  85. package/dist/web/assets/{mobile-explorer-sheet-CEVcU964.js → mobile-explorer-sheet-D1Bv9UCT.js} +1 -1
  86. package/dist/web/assets/{nextflow-DkcXP71s.js → nextflow-DR8PhpF8.js} +1 -1
  87. package/dist/web/assets/{nginx-C5n8N_bt.js → nginx-Qb9pUk1g.js} +1 -1
  88. package/dist/web/assets/{nim-CIhyfs-A.js → nim-DLa8R3NS.js} +1 -1
  89. package/dist/web/assets/{notification-store-B8AqxwRT.js → notification-store-KwTAZT8b.js} +1 -1
  90. package/dist/web/assets/{number-overlay-editor-NgOsWJ7x.js → number-overlay-editor-D9SkFg1Y.js} +1 -1
  91. package/dist/web/assets/overview-panel-BxDohIEa.js +1 -0
  92. package/dist/web/assets/packet-RMMSAZCW-BIhk1mvp.js +1 -0
  93. package/dist/web/assets/{pdf-preview-BslNoDFw.js → pdf-preview-dwRe54ht.js} +1 -1
  94. package/dist/web/assets/{perl-Cf31sZYE.js → perl-AMNGIneF.js} +1 -1
  95. package/dist/web/assets/{php-Dzl_MDIW.js → php-CDsOOxXn.js} +1 -1
  96. package/dist/web/assets/pie-UPGHQEXC-SLS6i76l.js +1 -0
  97. package/dist/web/assets/{postgres-viewer-BtSXQ3S4.js → postgres-viewer-BWZLW7kI.js} +3 -3
  98. package/dist/web/assets/process-table-CI-fnVsy.js +1 -0
  99. package/dist/web/assets/{pug-CxSYHrB3.js → pug-C2kdkhQ6.js} +1 -1
  100. package/dist/web/assets/{qml-DlEjGhwN.js → qml-DRDkUp75.js} +1 -1
  101. package/dist/web/assets/radar-KQ55EAFF-JJ6O1Er_.js +1 -0
  102. package/dist/web/assets/{razor-KVt5uW14.js → razor-wY_6wUeC.js} +1 -1
  103. package/dist/web/assets/resolve-theme-B9ABAH_3.js +1 -0
  104. package/dist/web/assets/{rst-D5BwNTnw.js → rst-BRpofyNs.js} +1 -1
  105. package/dist/web/assets/{ruby-D5fejQwd.js → ruby-ieATBhWm.js} +1 -1
  106. package/dist/web/assets/{sas-Bj7B1CB2.js → sas-CoOOEbOO.js} +1 -1
  107. package/dist/web/assets/{scss-BB0CUoCL.js → scss-_nWV0bsb.js} +1 -1
  108. package/dist/web/assets/{settings-store-C9YT1Hir.js → settings-store-C20lqh0G.js} +2 -2
  109. package/dist/web/assets/settings-tab-mPxrKkfm.js +1 -0
  110. package/dist/web/assets/{shaderlab-BdjEZUMc.js → shaderlab-XkqfIfO8.js} +1 -1
  111. package/dist/web/assets/{shellsession-Bp1OA1rR.js → shellsession-BKBIqTlM.js} +1 -1
  112. package/dist/web/assets/{soy-DlYz3wsC.js → soy-oVDnPzzh.js} +1 -1
  113. package/dist/web/assets/{sparql-CdfII5Jd.js → sparql-N2VclEsF.js} +1 -1
  114. package/dist/web/assets/{sql-query-editor-CkvpmXyA.js → sql-query-editor-BwPjEaP9.js} +1 -1
  115. package/dist/web/assets/{sqlite-viewer-CJbP6ruh.js → sqlite-viewer-Cs-_D942.js} +1 -1
  116. package/dist/web/assets/{stata-BvUA6GUW.js → stata-BuuClVDg.js} +1 -1
  117. package/dist/web/assets/{surrealql--DLNbTyI.js → surrealql-DE5_63MS.js} +1 -1
  118. package/dist/web/assets/{svelte-CBfSsG4n.js → svelte--YWjlOrK.js} +1 -1
  119. package/dist/web/assets/system-monitor-body-CV7-0hZG.js +2 -0
  120. package/dist/web/assets/system-monitor-tab-Ce-8Axhh.js +1 -0
  121. package/dist/web/assets/system-monitor-window-content-CetwYOQy.js +1 -0
  122. package/dist/web/assets/team-member-sheet-CjgaQjsZ.js +2 -0
  123. package/dist/web/assets/{team-member-window-content-Cxh-HF2V.js → team-member-window-content-DNJiYWS7.js} +1 -1
  124. package/dist/web/assets/{templ-Dv8zpKZW.js → templ-MlpvJx4a.js} +1 -1
  125. package/dist/web/assets/{terminal-tab-gQCs_fyx.js → terminal-tab-DF7521sT.js} +3 -3
  126. package/dist/web/assets/{tex-CsrOiqh1.js → tex-0loAoXJG.js} +1 -1
  127. package/dist/web/assets/{tool-cards-BG2fz83z.js → tool-cards-DCAXGDJI.js} +5 -5
  128. package/dist/web/assets/treemap-KZPCXAKY-Be3KNmns.js +1 -0
  129. package/dist/web/assets/{ts-tags-3T98k4EJ.js → ts-tags-pt-Ug0hK.js} +1 -1
  130. package/dist/web/assets/{twig-u6QZ45FH.js → twig-DOePpLOL.js} +1 -1
  131. package/dist/web/assets/{use-monaco-theme-DaqI7O-a.js → use-monaco-theme-DSCdlrjO.js} +1 -1
  132. package/dist/web/assets/{use-open-team-member-DKpstvLS.js → use-open-team-member-H4k74HnV.js} +1 -1
  133. package/dist/web/assets/{use-websocket-KVhDtbwK.js → use-websocket-iJfc7EbK.js} +1 -1
  134. package/dist/web/assets/{vendor-mermaid-Bg4vE8QA.js → vendor-mermaid-DrwG0NYt.js} +1 -1
  135. package/dist/web/assets/{video-preview-CVEUDZBj.js → video-preview-B0ZWpX0F.js} +1 -1
  136. package/dist/web/assets/{vue-CxIsxtwn.js → vue-D6f-rprj.js} +1 -1
  137. package/dist/web/assets/{vue-html-BGL5qnuH.js → vue-html-DEYRkS1V.js} +1 -1
  138. package/dist/web/assets/{vue-vine-DHPh_gMr.js → vue-vine-CxSG2ojf.js} +1 -1
  139. package/dist/web/assets/{xml-C-vM2m7J.js → xml-DhrxbATj.js} +1 -1
  140. package/dist/web/assets/{xsl-DvTXNwuO.js → xsl-CU0ZndUO.js} +1 -1
  141. package/dist/web/index.html +18 -17
  142. package/dist/web/sw.js +1 -1
  143. package/docs/system-architecture.md +2 -2
  144. package/package.json +1 -1
  145. package/packages/vscode-compat/node_modules/.bin/tsc.bunx +0 -0
  146. package/packages/vscode-compat/node_modules/.bin/tsc.exe +0 -0
  147. package/packages/vscode-compat/node_modules/.bin/tsserver.bunx +0 -0
  148. package/packages/vscode-compat/node_modules/.bin/tsserver.exe +0 -0
  149. package/src/server/index.ts +2 -8
  150. package/src/server/routes/resources.ts +119 -73
  151. package/src/services/autostart-generator.ts +79 -7
  152. package/src/services/autostart-register.ts +15 -2
  153. package/src/services/edge-forwarder.ts +191 -191
  154. package/src/services/proc-table-linux.ts +4 -0
  155. package/src/services/redact-secrets.ts +33 -0
  156. package/src/services/system-metrics/cpu-memory-collector.ts +101 -0
  157. package/src/services/system-metrics/disk-net-collector-darwin.ts +75 -0
  158. package/src/services/system-metrics/disk-net-collector-linux.ts +88 -0
  159. package/src/services/system-metrics/disk-net-collector-windows.ts +57 -0
  160. package/src/services/system-metrics/gpu-collector-nvidia.ts +78 -0
  161. package/src/services/system-metrics/gpu-process-memory-nvidia.ts +66 -0
  162. package/src/services/system-metrics/gpu-process-usage-windows.ts +138 -0
  163. package/src/services/system-metrics/kill-executor.ts +85 -0
  164. package/src/services/system-metrics/kill-guard.ts +124 -0
  165. package/src/services/system-metrics/kill-identity-resolver.ts +72 -0
  166. package/src/services/system-metrics/kill-request-handler.ts +79 -0
  167. package/src/services/system-metrics/metrics-collector-lock.ts +36 -0
  168. package/src/services/system-metrics/metrics-poll-scheduler.ts +83 -0
  169. package/src/services/system-metrics/metrics-subscriber-registry.ts +85 -0
  170. package/src/services/system-metrics/powershell-session-bootstrap.ts +48 -0
  171. package/src/services/system-metrics/powershell-session.ts +182 -0
  172. package/src/services/system-metrics/ppm-process-ownership.ts +34 -0
  173. package/src/services/system-metrics/ppm-protected-pids.ts +84 -0
  174. package/src/services/system-metrics/process-collector-darwin.ts +141 -0
  175. package/src/services/system-metrics/process-collector-linux.ts +85 -0
  176. package/src/services/system-metrics/process-collector-types.ts +80 -0
  177. package/src/services/system-metrics/process-collector-windows-parse.ts +153 -0
  178. package/src/services/system-metrics/process-collector-windows.ts +136 -0
  179. package/src/services/system-metrics/process-cpu-delta.ts +61 -0
  180. package/src/services/system-metrics/process-grouping.ts +142 -0
  181. package/src/services/system-metrics/process-io-delta.ts +84 -0
  182. package/src/services/system-metrics/process-io-linux.ts +46 -0
  183. package/src/services/system-metrics/process-net-collector-darwin.ts +103 -0
  184. package/src/services/system-metrics/process-rows-builder.ts +111 -0
  185. package/src/services/system-metrics/rate-delta.ts +47 -0
  186. package/src/services/system-metrics/system-metrics-platform.ts +51 -0
  187. package/src/services/system-metrics/system-metrics-tick.ts +178 -0
  188. package/src/services/system-metrics/system-metrics.service.ts +212 -0
  189. package/src/services/windows-process-tree.ts +351 -351
  190. package/src/types/system-metrics.ts +199 -0
  191. package/src/web/components/floating-window/window-content-registry.ts +2 -0
  192. package/src/web/components/floating-window/window-persistence.ts +1 -1
  193. package/src/web/components/floating-window/window-store-types.ts +1 -1
  194. package/src/web/components/system/build-kill-request.ts +36 -0
  195. package/src/web/components/system/chart-scale.ts +28 -0
  196. package/src/web/components/system/cpu-core-bars.tsx +33 -0
  197. package/src/web/components/system/kill-confirm-dialog.tsx +105 -0
  198. package/src/web/components/system/metric-chart-canvas.tsx +107 -0
  199. package/src/web/components/system/overview-cards/cpu-card.tsx +39 -0
  200. package/src/web/components/system/overview-cards/disk-card.tsx +41 -0
  201. package/src/web/components/system/overview-cards/gpu-card.tsx +33 -0
  202. package/src/web/components/system/overview-cards/mem-card.tsx +32 -0
  203. package/src/web/components/system/overview-cards/net-card.tsx +41 -0
  204. package/src/web/components/system/overview-panel.tsx +97 -0
  205. package/src/web/components/system/process-columns-grid.ts +103 -0
  206. package/src/web/components/system/process-group-row.tsx +94 -0
  207. package/src/web/components/system/process-row-format.ts +56 -0
  208. package/src/web/components/system/process-row.tsx +81 -0
  209. package/src/web/components/system/process-table-model.ts +109 -0
  210. package/src/web/components/system/process-table-sort.ts +90 -0
  211. package/src/web/components/system/process-table-toolbar.tsx +159 -0
  212. package/src/web/components/system/process-table-totals.ts +49 -0
  213. package/src/web/components/system/process-table.tsx +146 -0
  214. package/src/web/components/system/resolve-open-system-monitor-action.ts +29 -0
  215. package/src/web/components/system/resource-status-bar.tsx +17 -16
  216. package/src/web/components/system/sortable-header.tsx +90 -0
  217. package/src/web/components/system/system-monitor-body.tsx +146 -0
  218. package/src/web/components/system/system-monitor-tab.tsx +2 -185
  219. package/src/web/components/system/system-monitor-window-content.tsx +18 -0
  220. package/src/web/components/system/use-column-widths.ts +91 -0
  221. package/src/web/components/system/use-open-system-monitor.ts +34 -0
  222. package/src/web/components/system/use-process-kill.ts +100 -0
  223. package/src/web/hooks/resource-monitor-lease.ts +55 -0
  224. package/src/web/hooks/use-element-width.ts +27 -0
  225. package/src/web/hooks/use-resource-monitor.ts +113 -35
  226. package/src/web/lib/format-bytes.ts +16 -0
  227. package/src/web/styles/globals.css +5 -3
  228. package/src/web/theme/builtin/aurora.ts +8 -5
  229. package/dist/web/assets/architecture-PBZL5I3N-Bs7wzj-W.js +0 -1
  230. package/dist/web/assets/arrow-right-DubGFkN8.js +0 -1
  231. package/dist/web/assets/button-B4MWPjWj.js +0 -1
  232. package/dist/web/assets/chat-tab-pBGQ9SCY.js +0 -15
  233. package/dist/web/assets/circle-question-mark-CENpx4oA.js +0 -1
  234. package/dist/web/assets/code-editor-XviNXdzi.js +0 -10
  235. package/dist/web/assets/gitGraph-HDMCJU4V-D7i54kbM.js +0 -1
  236. package/dist/web/assets/group-chat-tab-CcG_NXIS.js +0 -1
  237. package/dist/web/assets/index-BAVBuKmT.js +0 -52
  238. package/dist/web/assets/index-oxsyfDa0.css +0 -2
  239. package/dist/web/assets/info-3K5VOQVL-BV41AzR9.js +0 -1
  240. package/dist/web/assets/markdown-renderer-Dg5HE9Zq.js +0 -1
  241. package/dist/web/assets/packet-RMMSAZCW-CaJoP44m.js +0 -1
  242. package/dist/web/assets/pie-UPGHQEXC-DSGZmNw2.js +0 -1
  243. package/dist/web/assets/radar-KQ55EAFF-Be4VUTs0.js +0 -1
  244. package/dist/web/assets/resolve-theme-CJvkL8hU.js +0 -1
  245. package/dist/web/assets/settings-tab-COSUzGl8.js +0 -1
  246. package/dist/web/assets/system-monitor-tab-DThAFSd_.js +0 -1
  247. package/dist/web/assets/team-member-sheet-M83B4znI.js +0 -2
  248. package/dist/web/assets/treemap-KZPCXAKY-Cu2zgbxU.js +0 -1
  249. package/src/services/resource-monitor-utils.ts +0 -141
  250. package/src/services/resource-monitor.service.ts +0 -147
  251. package/src/web/components/system/sparkline-canvas.tsx +0 -64
  252. package/src/web/components/system/system-monitor-group-row.tsx +0 -153
  253. /package/dist/web/assets/{abap-C1K0-wzc.js → abap-MRbmsXOs.js} +0 -0
  254. /package/dist/web/assets/{actionscript-3-CJhQVjLA.js → actionscript-3-BDDHKqa4.js} +0 -0
  255. /package/dist/web/assets/{ada-Bt8r9fME.js → ada-DpuV9KwV.js} +0 -0
  256. /package/dist/web/assets/{andromeeda-DF1I8qi3.js → andromeeda-D6qUCKJo.js} +0 -0
  257. /package/dist/web/assets/{apache-CnlleE6P.js → apache-CX1NU_Tl.js} +0 -0
  258. /package/dist/web/assets/{apex-j0C6Xmk6.js → apex-B4-aoQ3K.js} +0 -0
  259. /package/dist/web/assets/{api-settings-DfNRPr1q.js → api-settings-kQHV6pYZ.js} +0 -0
  260. /package/dist/web/assets/{api-themes-8WTH6KpV.js → api-themes-CrK0tkW_.js} +0 -0
  261. /package/dist/web/assets/{applescript-DO7AnO8U.js → applescript-Dm9NI6KR.js} +0 -0
  262. /package/dist/web/assets/{apply-theme-CNj1iA-v.js → apply-theme-BH_d4amk.js} +0 -0
  263. /package/dist/web/assets/{ara-i83AydZj.js → ara-BGN8GAYn.js} +0 -0
  264. /package/dist/web/assets/{asciidoc-DbBA6-sF.js → asciidoc-s_yVuR3t.js} +0 -0
  265. /package/dist/web/assets/{asm-B5S47Rgr.js → asm-BzQdSvTe.js} +0 -0
  266. /package/dist/web/assets/{aurora-x-De_IaSKw.js → aurora-x-BJTLETG_.js} +0 -0
  267. /package/dist/web/assets/{awk-CfyLHXqS.js → awk-BQEGWxvX.js} +0 -0
  268. /package/dist/web/assets/{ayu-dark-DTLdZ1Si.js → ayu-dark-CpTORmLc.js} +0 -0
  269. /package/dist/web/assets/{ayu-light-DTOfkzhu.js → ayu-light-D8PVj-e6.js} +0 -0
  270. /package/dist/web/assets/{ayu-mirage-DsAECCMv.js → ayu-mirage-DyElQHtm.js} +0 -0
  271. /package/dist/web/assets/{ballerina-CumGp9A7.js → ballerina-C82NkRtj.js} +0 -0
  272. /package/dist/web/assets/{bat-Ca2SBbYN.js → bat-0X7DtGI-.js} +0 -0
  273. /package/dist/web/assets/{beancount-CqyXBwwF.js → beancount-Xgvy6YRl.js} +0 -0
  274. /package/dist/web/assets/{berry-yl-kJr_H.js → berry-CCT2pZcQ.js} +0 -0
  275. /package/dist/web/assets/{bibtex-DoFFszjV.js → bibtex-CpXgZ9M_.js} +0 -0
  276. /package/dist/web/assets/{bicep-CWPi4nfK.js → bicep-fkeSA62l.js} +0 -0
  277. /package/dist/web/assets/{bird2-DXew-ut0.js → bird2-Co7SeAI8.js} +0 -0
  278. /package/dist/web/assets/{c-clbySDvd.js → c-BpmrTvJh.js} +0 -0
  279. /package/dist/web/assets/{c3-B65jvSM1.js → c3-BZ_Z0RrR.js} +0 -0
  280. /package/dist/web/assets/{cadence-Cm8tQTHN.js → cadence-B0GBC8OF.js} +0 -0
  281. /package/dist/web/assets/{can-open-in-ppm-DXGOSUQc.js → can-open-in-ppm-omBzUBBq.js} +0 -0
  282. /package/dist/web/assets/{catppuccin-frappe-DLeGslh_.js → catppuccin-frappe-DIt_xR7m.js} +0 -0
  283. /package/dist/web/assets/{catppuccin-latte-CR5GeHws.js → catppuccin-latte-Dw40AcqA.js} +0 -0
  284. /package/dist/web/assets/{catppuccin-macchiato-p-XgjxhP.js → catppuccin-macchiato-BJ7DfVEF.js} +0 -0
  285. /package/dist/web/assets/{catppuccin-mocha-B8QOAZLl.js → catppuccin-mocha-NI2lfXzU.js} +0 -0
  286. /package/dist/web/assets/{clarity-DPulbvKH.js → clarity-F39L0xMJ.js} +0 -0
  287. /package/dist/web/assets/{clock-D493FU_D.js → clock-CvhF4DJP.js} +0 -0
  288. /package/dist/web/assets/{clojure-DFuWS20u.js → clojure-DloMkd8K.js} +0 -0
  289. /package/dist/web/assets/{cmake-DejCqcu4.js → cmake-CwerJun_.js} +0 -0
  290. /package/dist/web/assets/{code-CLF5x7KK.js → code-DDPoqVri.js} +0 -0
  291. /package/dist/web/assets/{codeowners-BwAyqWIH.js → codeowners-CQyVz4Qf.js} +0 -0
  292. /package/dist/web/assets/{codeql-DgSwFjqI.js → codeql-Bb229zuY.js} +0 -0
  293. /package/dist/web/assets/{common-lisp-CxIVJCtf.js → common-lisp-KMlIwq5I.js} +0 -0
  294. /package/dist/web/assets/{copy-BApI9v7Z.js → copy-DKn11Pye.js} +0 -0
  295. /package/dist/web/assets/{coq-DLSjSnmf.js → coq-DHX_3IIo.js} +0 -0
  296. /package/dist/web/assets/{csharp-C1HHzXBp.js → csharp-CEmCZv9Q.js} +0 -0
  297. /package/dist/web/assets/{css-VXsMY--y.js → css-CqZqBD05.js} +0 -0
  298. /package/dist/web/assets/{csv-BEbcJdHz.js → csv-l1g_V5MV.js} +0 -0
  299. /package/dist/web/assets/{csv-parser-BRtnJCfv.js → csv-parser-CnS0wqr6.js} +0 -0
  300. /package/dist/web/assets/{cue-BkDnFqUD.js → cue-BrxRmilg.js} +0 -0
  301. /package/dist/web/assets/{cypher-1cMqojSQ.js → cypher-rZkKwqZc.js} +0 -0
  302. /package/dist/web/assets/{d-BnYjRXtH.js → d-BALR-QuP.js} +0 -0
  303. /package/dist/web/assets/{dark-plus-XfbaH7kZ.js → dark-plus-Cj7rVwh-.js} +0 -0
  304. /package/dist/web/assets/{dart-Ca7s-8hK.js → dart-CWQcdkXk.js} +0 -0
  305. /package/dist/web/assets/{data-grid-types-BXwlFMzs.js → data-grid-types-CYvF-xK5.js} +0 -0
  306. /package/dist/web/assets/{database-B9okYLx6.js → database-BH0urvbs.js} +0 -0
  307. /package/dist/web/assets/{dax-CmuOw-mY.js → dax-BNHD-QBA.js} +0 -0
  308. /package/dist/web/assets/{desktop-C2gJ6Ovb.js → desktop-CN0IXPrP.js} +0 -0
  309. /package/dist/web/assets/{diff-BCEo1Ej7.js → diff-BtOXapES.js} +0 -0
  310. /package/dist/web/assets/{dist-CUPbqNnL.js → dist-DB1Oaqcc.js} +0 -0
  311. /package/dist/web/assets/{dist-DOlBnxFX.js → dist-Di6G_5jU.js} +0 -0
  312. /package/dist/web/assets/{docker-DN2jlyAh.js → docker-DNsAo_qO.js} +0 -0
  313. /package/dist/web/assets/{dotenv-NExMY2kS.js → dotenv-D6Pl6aOU.js} +0 -0
  314. /package/dist/web/assets/{download-D9UYwY0-.js → download-zCATy4x4.js} +0 -0
  315. /package/dist/web/assets/{dracula-B9lbE01y.js → dracula-C3m-w12D.js} +0 -0
  316. /package/dist/web/assets/{dracula-soft-CMBBfKF_.js → dracula-soft-BYqvXm6Z.js} +0 -0
  317. /package/dist/web/assets/{dream-maker-DEyDwFsd.js → dream-maker-DZAPbPTi.js} +0 -0
  318. /package/dist/web/assets/{emacs-lisp-D_qP2zS6.js → emacs-lisp-Ao5SW8ay.js} +0 -0
  319. /package/dist/web/assets/{everforest-dark-DbHa2U-p.js → everforest-dark-uC8QYotQ.js} +0 -0
  320. /package/dist/web/assets/{everforest-light-BISkJchP.js → everforest-light-CTgsVNMr.js} +0 -0
  321. /package/dist/web/assets/{fennel-6B22SfJR.js → fennel-WuBw6IR1.js} +0 -0
  322. /package/dist/web/assets/{file-exclamation-point-a8f3_w7a.js → file-exclamation-point-COAwgNGw.js} +0 -0
  323. /package/dist/web/assets/{fish-CubIIvJD.js → fish-Byy9dusu.js} +0 -0
  324. /package/dist/web/assets/{fluent-DF55zQ09.js → fluent-CDxb_sgw.js} +0 -0
  325. /package/dist/web/assets/{fortran-free-form-DvOu8jAt.js → fortran-free-form-DKWSTamT.js} +0 -0
  326. /package/dist/web/assets/{gdscript-DCPxdLpq.js → gdscript-prYHMgtD.js} +0 -0
  327. /package/dist/web/assets/{gdshader-CTZ381FO.js → gdshader-D-RM-SQk.js} +0 -0
  328. /package/dist/web/assets/{genie-C_QDtvgU.js → genie-CowkJhej.js} +0 -0
  329. /package/dist/web/assets/{gherkin-BcvK42tF.js → gherkin-CLFpoVYJ.js} +0 -0
  330. /package/dist/web/assets/{github-dark-default-CKGVrl3Z.js → github-dark-default-BK_1Qgb8.js} +0 -0
  331. /package/dist/web/assets/{github-dark-dimmed-C3dQZ_LC.js → github-dark-dimmed-Cv9lj6f-.js} +0 -0
  332. /package/dist/web/assets/{github-dark-high-contrast-DW78QukY.js → github-dark-high-contrast-CW5ZgIDh.js} +0 -0
  333. /package/dist/web/assets/{github-dark-C9afs_4w.js → github-dark-nW2F-RLd.js} +0 -0
  334. /package/dist/web/assets/{github-light-BnP2dznS.js → github-light-D4PqBHGZ.js} +0 -0
  335. /package/dist/web/assets/{github-light-default-C2fPZzPG.js → github-light-default-B-cHtJJV.js} +0 -0
  336. /package/dist/web/assets/{github-light-high-contrast-BzIuUFR2.js → github-light-high-contrast-Dt0HJq50.js} +0 -0
  337. /package/dist/web/assets/{gleam-BpeKwEIO.js → gleam-DwSyXJWP.js} +0 -0
  338. /package/dist/web/assets/{gn-nUb_Mit0.js → gn-Cv5WEzHc.js} +0 -0
  339. /package/dist/web/assets/{gnuplot-D7I0v20p.js → gnuplot-D7bRdY_M.js} +0 -0
  340. /package/dist/web/assets/{go-D7Qqska7.js → go-DiRVJ22U.js} +0 -0
  341. /package/dist/web/assets/{groovy-DS-pne5-.js → groovy-BHAgLTeO.js} +0 -0
  342. /package/dist/web/assets/{gruvbox-dark-hard-C0W01fsq.js → gruvbox-dark-hard-C8QZ3gzY.js} +0 -0
  343. /package/dist/web/assets/{gruvbox-dark-medium-Bqo6fQbg.js → gruvbox-dark-medium-Dp1eeid2.js} +0 -0
  344. /package/dist/web/assets/{gruvbox-dark-soft-D-XSM_fu.js → gruvbox-dark-soft-Cwq0dWVj.js} +0 -0
  345. /package/dist/web/assets/{gruvbox-light-hard-IVAwMJRl.js → gruvbox-light-hard-CLQCq2-w.js} +0 -0
  346. /package/dist/web/assets/{gruvbox-light-medium-38ATiG7i.js → gruvbox-light-medium-APHsh6Mo.js} +0 -0
  347. /package/dist/web/assets/{gruvbox-light-soft-DnZr3c_0.js → gruvbox-light-soft-CX-fYc64.js} +0 -0
  348. /package/dist/web/assets/{haskell-uQcywkDH.js → haskell-C4Tw-TDa.js} +0 -0
  349. /package/dist/web/assets/{haxe-c6bI4_GT.js → haxe-B7fSduTQ.js} +0 -0
  350. /package/dist/web/assets/{hcl-CQXTiEXq.js → hcl-Bi3ho6yC.js} +0 -0
  351. /package/dist/web/assets/{hjson-ChETf2bz.js → hjson-BXwae2M1.js} +0 -0
  352. /package/dist/web/assets/{hlsl-BMC4JGoE.js → hlsl-CRuQLBSa.js} +0 -0
  353. /package/dist/web/assets/{horizon-BusFlhLW.js → horizon-DtdQ6qjv.js} +0 -0
  354. /package/dist/web/assets/{horizon-bright-2oD0Mz7W.js → horizon-bright-BXSF_uKq.js} +0 -0
  355. /package/dist/web/assets/{houston-DdbbjqFg.js → houston-C6ASpUjT.js} +0 -0
  356. /package/dist/web/assets/{hy-D_SOuqw9.js → hy-BrWBHtHY.js} +0 -0
  357. /package/dist/web/assets/{image-gallery-CrM5fHKy.js → image-gallery-CGvlv8zR.js} +0 -0
  358. /package/dist/web/assets/{imba-BxLOHO5I.js → imba-C_JJXckG.js} +0 -0
  359. /package/dist/web/assets/{ini-ox-CFcg0.js → ini-DEE_vSHQ.js} +0 -0
  360. /package/dist/web/assets/{java-Bzo8yIal.js → java-CnmpcjcT.js} +0 -0
  361. /package/dist/web/assets/{javascript-DHuz9VXn.js → javascript-C-M7sa2e.js} +0 -0
  362. /package/dist/web/assets/{json-0_y80FD5.js → json-BjZ3dAk6.js} +0 -0
  363. /package/dist/web/assets/{json5-CEQ50pGM.js → json5-BQ2vpqjp.js} +0 -0
  364. /package/dist/web/assets/{jsonc-CfrLEAKA.js → jsonc-C5MjoWGx.js} +0 -0
  365. /package/dist/web/assets/{jsonl-fKbrANC2.js → jsonl-JvhrmQJI.js} +0 -0
  366. /package/dist/web/assets/{jsonnet-DKbkPaQ2.js → jsonnet-C5pdZVuo.js} +0 -0
  367. /package/dist/web/assets/{jssm-Dxxx1Hqu.js → jssm-Db17uybX.js} +0 -0
  368. /package/dist/web/assets/{jsx-DlJL-Oj3.js → jsx-tJp2Cyqu.js} +0 -0
  369. /package/dist/web/assets/{kanagawa-dragon-CwN4SV1c.js → kanagawa-dragon-BculT_Y1.js} +0 -0
  370. /package/dist/web/assets/{kanagawa-lotus-BHltayiE.js → kanagawa-lotus-yQgHUGwU.js} +0 -0
  371. /package/dist/web/assets/{kanagawa-wave-D-KXPjw6.js → kanagawa-wave-CyGoWN4d.js} +0 -0
  372. /package/dist/web/assets/{kdl-DvtoJdFo.js → kdl-Bn8R1REF.js} +0 -0
  373. /package/dist/web/assets/{kotlin-CTS4MLcx.js → kotlin-DWughK73.js} +0 -0
  374. /package/dist/web/assets/{kusto-HtSE_sKm.js → kusto--serPb0x.js} +0 -0
  375. /package/dist/web/assets/{laserwave-DaXZG9ge.js → laserwave-DfAPJ1tt.js} +0 -0
  376. /package/dist/web/assets/{lean-BYtGUfWx.js → lean-UAm1HOKl.js} +0 -0
  377. /package/dist/web/assets/{less-BoxmU_Mk.js → less-Xj6Ka0fF.js} +0 -0
  378. /package/dist/web/assets/{lib-B1clP4ai.js → lib-DgNcCtj3.js} +0 -0
  379. /package/dist/web/assets/{libesm-ah-mr-sh.js → libesm-CPh1Av0r.js} +0 -0
  380. /package/dist/web/assets/{light-plus-Bt5CyUuo.js → light-plus-BfS7gPcj.js} +0 -0
  381. /package/dist/web/assets/{llvm-CSdk9q9V.js → llvm-DvWiVwvU.js} +0 -0
  382. /package/dist/web/assets/{log-B-kp_3CL.js → log-Bo5z9bNz.js} +0 -0
  383. /package/dist/web/assets/{logo-DdIsXFDO.js → logo-CrIjcMZT.js} +0 -0
  384. /package/dist/web/assets/{luau-DUBpLlzQ.js → luau-C9TsYwNt.js} +0 -0
  385. /package/dist/web/assets/{make-B3JVjoW_.js → make-GYq4qVbx.js} +0 -0
  386. /package/dist/web/assets/{markdown-Seon0vHs.js → markdown-p5mNledS.js} +0 -0
  387. /package/dist/web/assets/{material-theme-Nq-ChX1P.js → material-theme-CWYOVxsP.js} +0 -0
  388. /package/dist/web/assets/{material-theme-darker-CPV4ayXJ.js → material-theme-darker-BDGty7YH.js} +0 -0
  389. /package/dist/web/assets/{material-theme-lighter-0kyjYqEd.js → material-theme-lighter-JbgOgV3n.js} +0 -0
  390. /package/dist/web/assets/{material-theme-ocean-DGpAp5co.js → material-theme-ocean-EMOpLpa2.js} +0 -0
  391. /package/dist/web/assets/{material-theme-palenight-B0AUn0NG.js → material-theme-palenight-CY5hgm7h.js} +0 -0
  392. /package/dist/web/assets/{matlab-C2waytxs.js → matlab-C-He_NTH.js} +0 -0
  393. /package/dist/web/assets/{mdx-DAis6R6I.js → mdx-Cr2TR5fj.js} +0 -0
  394. /package/dist/web/assets/{media-url-DlYsHq0S.js → media-url-CylYQld1.js} +0 -0
  395. /package/dist/web/assets/{mermaid-_rnT2YGD.js → mermaid-BYc0-B0U.js} +0 -0
  396. /package/dist/web/assets/{min-dark-BSSjchUB.js → min-dark-CMJwqJqB.js} +0 -0
  397. /package/dist/web/assets/{min-light-DomAFQsa.js → min-light-Cx6vFiEX.js} +0 -0
  398. /package/dist/web/assets/{mipsasm-bBgtvPyG.js → mipsasm-Bjer5HwK.js} +0 -0
  399. /package/dist/web/assets/{mobile-bottom-sheet-CS3XMwFw.js → mobile-bottom-sheet-BUOJgiaZ.js} +0 -0
  400. /package/dist/web/assets/{mojo-Cp9BayW0.js → mojo-t90PR-Y2.js} +0 -0
  401. /package/dist/web/assets/{monokai-CL_9gbmn.js → monokai-dci_PdCm.js} +0 -0
  402. /package/dist/web/assets/{moonbit-BS_fcr-P.js → moonbit-AAzI-Hd-.js} +0 -0
  403. /package/dist/web/assets/{move-C79AH45U.js → move-kwBhnhrG.js} +0 -0
  404. /package/dist/web/assets/{narrat-CJ5s3BDf.js → narrat-CXww2YQL.js} +0 -0
  405. /package/dist/web/assets/{nextflow-groovy-ZHa4JrPJ.js → nextflow-groovy-CJXsuXGB.js} +0 -0
  406. /package/dist/web/assets/{night-owl-Jkf9zFQK.js → night-owl-_GD204Wr.js} +0 -0
  407. /package/dist/web/assets/{night-owl-light-DRPeaG5J.js → night-owl-light-DNgkw3kl.js} +0 -0
  408. /package/dist/web/assets/{nix-D2Jet9DN.js → nix-BgiorKFd.js} +0 -0
  409. /package/dist/web/assets/{nord-CREVs22j.js → nord-CaBmcxFC.js} +0 -0
  410. /package/dist/web/assets/{nushell-CAiDi_mR.js → nushell-DUh4UGx1.js} +0 -0
  411. /package/dist/web/assets/{objective-c-CVkmJkC1.js → objective-c-Cl9KU86S.js} +0 -0
  412. /package/dist/web/assets/{objective-cpp-DIKDO1Ly.js → objective-cpp-DVkIA8A0.js} +0 -0
  413. /package/dist/web/assets/{ocaml-R9qtGQhs.js → ocaml-vvoHTak0.js} +0 -0
  414. /package/dist/web/assets/{odin-DTYNQqVr.js → odin-Cyjw8woZ.js} +0 -0
  415. /package/dist/web/assets/{one-dark-pro-BSLWUJn5.js → one-dark-pro-B1cviILi.js} +0 -0
  416. /package/dist/web/assets/{one-light-DbkRXG3t.js → one-light-BPGUJeYI.js} +0 -0
  417. /package/dist/web/assets/{openscad-BlPcSnmT.js → openscad-BLMdTUU8.js} +0 -0
  418. /package/dist/web/assets/{pascal-B1Y46ZZB.js → pascal-i5niy3e7.js} +0 -0
  419. /package/dist/web/assets/{pkl-BhJSJbFv.js → pkl-CuOV7SsU.js} +0 -0
  420. /package/dist/web/assets/{plastic-BzxsCTpi.js → plastic-Bf_zE5KL.js} +0 -0
  421. /package/dist/web/assets/{plsql-DBba7dyP.js → plsql-cfqEtMD3.js} +0 -0
  422. /package/dist/web/assets/{plus-DmjC2iRB.js → plus-BM-Ty0fp.js} +0 -0
  423. /package/dist/web/assets/{po-BvgLlnNo.js → po-CFJcWgjr.js} +0 -0
  424. /package/dist/web/assets/{poimandres-DUaI_1JP.js → poimandres-G5YoaIFf.js} +0 -0
  425. /package/dist/web/assets/{polar-C7uILwJn.js → polar-rcjs3i9R.js} +0 -0
  426. /package/dist/web/assets/{postcss-BgJlpFdw.js → postcss-CBKY1FTZ.js} +0 -0
  427. /package/dist/web/assets/{powerquery-Dn1MIpZu.js → powerquery-Db7SXLbO.js} +0 -0
  428. /package/dist/web/assets/{powershell-Bo-DYzOS.js → powershell-LFy3MUTP.js} +0 -0
  429. /package/dist/web/assets/{prisma-CTLs5IdT.js → prisma-BE8GR1lH.js} +0 -0
  430. /package/dist/web/assets/{prolog-QRGun3eG.js → prolog-DOn5lR1e.js} +0 -0
  431. /package/dist/web/assets/{proto-B7PI7apn.js → proto-wr-TpAK_.js} +0 -0
  432. /package/dist/web/assets/{puppet-CBq0tLrP.js → puppet-D2Dkv62u.js} +0 -0
  433. /package/dist/web/assets/{purescript-DFewOQb2.js → purescript-DvgJgPdy.js} +0 -0
  434. /package/dist/web/assets/{python-iWuxKXvT.js → python-C7TlkHhK.js} +0 -0
  435. /package/dist/web/assets/{qmldir-cXiW3AsF.js → qmldir-CtZMwhcW.js} +0 -0
  436. /package/dist/web/assets/{qss-DASwAbBL.js → qss-dNZ2btnl.js} +0 -0
  437. /package/dist/web/assets/{r-TU2eaIPw.js → r-BlqnNkHS.js} +0 -0
  438. /package/dist/web/assets/{racket-SkRKqrLY.js → racket-CzRQrGc4.js} +0 -0
  439. /package/dist/web/assets/{raku-D31lthkZ.js → raku-BwutWhBF.js} +0 -0
  440. /package/dist/web/assets/{red-CTcQZevb.js → red-BMXMywmL.js} +0 -0
  441. /package/dist/web/assets/{reg-D8YAsTGf.js → reg-BqOKrIOw.js} +0 -0
  442. /package/dist/web/assets/{regexp-CD2uvAWx.js → regexp-Bero1BN2.js} +0 -0
  443. /package/dist/web/assets/{rel-CAaI-1fg.js → rel-BXKWIElA.js} +0 -0
  444. /package/dist/web/assets/{riscv-DR-hJVIj.js → riscv-BbbBYJBo.js} +0 -0
  445. /package/dist/web/assets/{ron-CuUCJ0n4.js → ron-BtVTWW4b.js} +0 -0
  446. /package/dist/web/assets/{rose-pine-dawn-Bqz2sBRY.js → rose-pine-dawn-D7lwhUei.js} +0 -0
  447. /package/dist/web/assets/{rose-pine-aFHxW48i.js → rose-pine-hvkvQzvU.js} +0 -0
  448. /package/dist/web/assets/{rose-pine-moon-wqyh0an4.js → rose-pine-moon-CoHDmsIw.js} +0 -0
  449. /package/dist/web/assets/{rosmsg-CI1ywimO.js → rosmsg-CdaZFgI8.js} +0 -0
  450. /package/dist/web/assets/{run-in-terminal-CGW6o37_.js → run-in-terminal-CyS5Itj-.js} +0 -0
  451. /package/dist/web/assets/{rust-p7Imk4G_.js → rust-Dy2qsphD.js} +0 -0
  452. /package/dist/web/assets/{sass-C8JfaqCV.js → sass-Bz7NVxDb.js} +0 -0
  453. /package/dist/web/assets/{save-DRPrDfTt.js → save-C4z1p51e.js} +0 -0
  454. /package/dist/web/assets/{scala-DNxCW1By.js → scala-sXSwsNyq.js} +0 -0
  455. /package/dist/web/assets/{scheme-BYuUPJoL.js → scheme-DS7TUbN7.js} +0 -0
  456. /package/dist/web/assets/{sdbl-DbPeJPUr.js → sdbl-iISFvIep.js} +0 -0
  457. /package/dist/web/assets/{send-to-chat-YXHdAyLG.js → send-to-chat-BcO39BDR.js} +0 -0
  458. /package/dist/web/assets/{shellscript-DMiHlR3q.js → shellscript-BkIl4ApC.js} +0 -0
  459. /package/dist/web/assets/{shield-check-8GObuUAn.js → shield-check-C5laObJv.js} +0 -0
  460. /package/dist/web/assets/{shield-off-egKAZEwR.js → shield-off-DULFtyLS.js} +0 -0
  461. /package/dist/web/assets/{slack-dark-C4xGcQXI.js → slack-dark-B1eg0_m2.js} +0 -0
  462. /package/dist/web/assets/{slack-ochin-BzgRt_wm.js → slack-ochin-mdkc1ldu.js} +0 -0
  463. /package/dist/web/assets/{smalltalk-LDeL9PYH.js → smalltalk-CORtd03t.js} +0 -0
  464. /package/dist/web/assets/{snazzy-light-CXE7a5j_.js → snazzy-light-Bc6Q2G89.js} +0 -0
  465. /package/dist/web/assets/{solarized-dark-DgUhY74x.js → solarized-dark-CF83zRXM.js} +0 -0
  466. /package/dist/web/assets/{solarized-light-DD9C-H-9.js → solarized-light-BoKQZaYU.js} +0 -0
  467. /package/dist/web/assets/{solidity-CAbDB4D4.js → solidity-DOgi1N4w.js} +0 -0
  468. /package/dist/web/assets/{sparkles-n1hzh65o.js → sparkles-Dqsf3hq6.js} +0 -0
  469. /package/dist/web/assets/{splunk-kQREPfIc.js → splunk-BXfw5ZLy.js} +0 -0
  470. /package/dist/web/assets/{sql-CBzeNAD8.js → sql-BcVs-eX4.js} +0 -0
  471. /package/dist/web/assets/{ssh-config-L1euxrsM.js → ssh-config-CLCtNkkd.js} +0 -0
  472. /package/dist/web/assets/{stylus-DvBnYniP.js → stylus-DdP992aO.js} +0 -0
  473. /package/dist/web/assets/{swift-DF5NDQp6.js → swift-BnGb6Lgc.js} +0 -0
  474. /package/dist/web/assets/{synthwave-84-DbBhB_Hq.js → synthwave-84-cg9264l9.js} +0 -0
  475. /package/dist/web/assets/{system-verilog-D8s2ZW_k.js → system-verilog-GbHpszs3.js} +0 -0
  476. /package/dist/web/assets/{systemd-a5-XZJsG.js → systemd-Dz-bNsDQ.js} +0 -0
  477. /package/dist/web/assets/{table-BX2ZrJfM.js → table-CHmxuh6M.js} +0 -0
  478. /package/dist/web/assets/{talonscript-BLa0URTW.js → talonscript-CFIidoBA.js} +0 -0
  479. /package/dist/web/assets/{tasl-DIoV4XcC.js → tasl-Cu-TRTKx.js} +0 -0
  480. /package/dist/web/assets/{tcl-ztYAdXfQ.js → tcl-DwCHCB1K.js} +0 -0
  481. /package/dist/web/assets/{terraform-DvpCCiOZ.js → terraform-BzZw4T1z.js} +0 -0
  482. /package/dist/web/assets/{tokyo-night-BkHlYUv0.js → tokyo-night-RKsj2-tv.js} +0 -0
  483. /package/dist/web/assets/{toml-acIrxos6.js → toml-CirbOgDP.js} +0 -0
  484. /package/dist/web/assets/{tsv-BJB5EVCT.js → tsv-CraRcWdU.js} +0 -0
  485. /package/dist/web/assets/{tsx-B1MmXGT3.js → tsx-CjFg0lgw.js} +0 -0
  486. /package/dist/web/assets/{turtle-DFceTiqd.js → turtle-B-WBIOa6.js} +0 -0
  487. /package/dist/web/assets/{typescript-Dz9wU5Y1.js → typescript-MpLarYn1.js} +0 -0
  488. /package/dist/web/assets/{typespec-CPuYZijj.js → typespec-B7QlHMZ_.js} +0 -0
  489. /package/dist/web/assets/{typst-CfsCIYv8.js → typst-CcHSKFZj.js} +0 -0
  490. /package/dist/web/assets/{use-blob-url-BmlYYZ8L.js → use-blob-url-BKyVxOZw.js} +0 -0
  491. /package/dist/web/assets/{use-is-mobile-B8FA4kQf.js → use-is-mobile-BXGVvczu.js} +0 -0
  492. /package/dist/web/assets/{v-CGo0jcXA.js → v-xTGhWZuD.js} +0 -0
  493. /package/dist/web/assets/{vala-AsSR0hrb.js → vala-DwebjH3H.js} +0 -0
  494. /package/dist/web/assets/{vb-C7tvbXv1.js → vb-BxJT2RAy.js} +0 -0
  495. /package/dist/web/assets/{vendor-xterm-C1diXHJl.js → vendor-xterm-CU6zIYMB.js} +0 -0
  496. /package/dist/web/assets/{verilog--a33ND-p.js → verilog-CvV6RHPD.js} +0 -0
  497. /package/dist/web/assets/{vesper-B_Z0h4pn.js → vesper-CY3qd7E_.js} +0 -0
  498. /package/dist/web/assets/{vhdl-CWL5dZPN.js → vhdl-B9ZX-sUL.js} +0 -0
  499. /package/dist/web/assets/{viml-BglmT14Y.js → viml-Y42h_ExQ.js} +0 -0
  500. /package/dist/web/assets/{vitesse-black-RKFsSqQI.js → vitesse-black-DkXP6Sv-.js} +0 -0
  501. /package/dist/web/assets/{vitesse-dark-D7zDWNmc.js → vitesse-dark-B9CkIB6r.js} +0 -0
  502. /package/dist/web/assets/{vitesse-light-MAp87W5b.js → vitesse-light-C7DHrJCK.js} +0 -0
  503. /package/dist/web/assets/{vyper-CgCBYg1G.js → vyper-Cnd9s5j-.js} +0 -0
  504. /package/dist/web/assets/{wasm-Bwl4txwp.js → wasm-DQE71XTB.js} +0 -0
  505. /package/dist/web/assets/{wasm-BOG7ZeTT.js → wasm-iWe7Fzjc.js} +0 -0
  506. /package/dist/web/assets/{wenyan-DpShPKXZ.js → wenyan-Bc5Pnm9l.js} +0 -0
  507. /package/dist/web/assets/{wgsl-BakcCblK.js → wgsl-D-YUAWkP.js} +0 -0
  508. /package/dist/web/assets/{wikitext-NroRWVAO.js → wikitext-DYQDUYf2.js} +0 -0
  509. /package/dist/web/assets/{wit-B5CM2pg6.js → wit-P6u7mfwy.js} +0 -0
  510. /package/dist/web/assets/{wolfram-7MTFBJpR.js → wolfram-6SXLUqao.js} +0 -0
  511. /package/dist/web/assets/{yaml-Bwr01G2K.js → yaml-CQiMLVcZ.js} +0 -0
  512. /package/dist/web/assets/{zenscript-Dj8GATvi.js → zenscript-DFMywo_P.js} +0 -0
  513. /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
+ }