@hienlh/ppm 0.18.8 → 0.18.9

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 (507) hide show
  1. package/.spike/s.err +63 -0
  2. package/.spike/tunnel.err +42 -0
  3. package/.spike/w.err +96 -0
  4. package/CHANGELOG.md +9 -0
  5. package/CLAUDE.md +1 -0
  6. package/assets/skills/ppm/SKILL.md +1 -1
  7. package/assets/skills/ppm/references/cli-reference.md +4 -4
  8. package/assets/skills/ppm/references/http-api.md +4 -3
  9. package/dist/web/assets/{ai-resource-editor-BydGrxjb.js → ai-resource-editor-DFCuNe-P.js} +1 -1
  10. package/dist/web/assets/{angular-html-jfMqUuRd.js → angular-html-Ctz0zN01.js} +1 -1
  11. package/dist/web/assets/{angular-ts-wytn9PMm.js → angular-ts-QXHpgB1C.js} +1 -1
  12. package/dist/web/assets/{api-settings-DlcoR5QT.js → api-settings-nblja3Rk.js} +1 -1
  13. package/dist/web/assets/{apl-i-ahKx6O.js → apl-b9KVk-O4.js} +1 -1
  14. package/dist/web/assets/architecture-PBZL5I3N-C7ra20CE.js +1 -0
  15. package/dist/web/assets/{astro-DVBCJfG6.js → astro-BlFEeGYr.js} +1 -1
  16. package/dist/web/assets/{audio-preview-DzBGq9Lk.js → audio-preview-CZLmhf__.js} +1 -1
  17. package/dist/web/assets/{blade-BHlL8SqU.js → blade-CGkj2MUI.js} +1 -1
  18. package/dist/web/assets/{bsl-D-UOfR1F.js → bsl-CVsbb6ap.js} +1 -1
  19. package/dist/web/assets/button-BA_fJOtX.js +1 -0
  20. package/dist/web/assets/{cairo-Bn6rucli.js → cairo-BbIHl2iE.js} +1 -1
  21. package/dist/web/assets/chat-tab-flMPLoKb.js +15 -0
  22. package/dist/web/assets/circle-hjUGru6R.js +1 -0
  23. package/dist/web/assets/circle-question-mark-CzR7YRc-.js +1 -0
  24. package/dist/web/assets/{cobol-Byn9FYKu.js → cobol-BWSGjmWb.js} +1 -1
  25. package/dist/web/assets/code-editor-C2VQbXzw.js +10 -0
  26. package/dist/web/assets/{coffee-DjBl4gm-.js → coffee-CWGNOxds.js} +1 -1
  27. package/dist/web/assets/{conflict-editor-CRConSGG.js → conflict-editor-CdH_h0vD.js} +3 -3
  28. package/dist/web/assets/{context-menu-DkQdt6YA.js → context-menu-Cq0u3SK9.js} +1 -1
  29. package/dist/web/assets/{cpp-CKzic-3E.js → cpp-DHGV24J2.js} +1 -1
  30. package/dist/web/assets/{crystal-Bkg-Ly_g.js → crystal-Vlwf2UMP.js} +1 -1
  31. package/dist/web/assets/{csv-preview-BtCGfmrq.js → csv-preview-CY_454vd.js} +1 -1
  32. package/dist/web/assets/{data-grid-overlay-editor-B1mTl3KS.js → data-grid-overlay-editor-D9il5DZS.js} +1 -1
  33. package/dist/web/assets/{database-viewer-2M5sKRqb.js → database-viewer-BCZOTrPT.js} +1 -1
  34. package/dist/web/assets/{diff-viewer-BMr7vOvZ.js → diff-viewer-BwfMN-nW.js} +1 -1
  35. package/dist/web/assets/{docx-preview-BpG2kr_-.js → docx-preview-D3Sdh_aT.js} +1 -1
  36. package/dist/web/assets/{edge-DVbZnd3Y.js → edge-Bhqk64zS.js} +1 -1
  37. package/dist/web/assets/{edit-diff-preview-BivQwZMD.js → edit-diff-preview-gq6ALf2B.js} +1 -1
  38. package/dist/web/assets/{elixir-Dwi8Wu7W.js → elixir-D466WCFm.js} +1 -1
  39. package/dist/web/assets/{elm-DtIv-HXJ.js → elm-Bfs2qNPR.js} +1 -1
  40. package/dist/web/assets/{erb-D3HEDz1x.js → erb-WI7jUaB6.js} +1 -1
  41. package/dist/web/assets/{erlang-2MjTCzGz.js → erlang-BCBe8nCc.js} +1 -1
  42. package/dist/web/assets/{esm-CZ8B8Ba2.js → esm-CZs9WVDO.js} +1 -1
  43. package/dist/web/assets/{explorer-body-DXufyj-9.js → explorer-body-BKOMM566.js} +2 -2
  44. package/dist/web/assets/{explorer-window-content-B3krk4G1.js → explorer-window-content-Bbzijk8t.js} +1 -1
  45. package/dist/web/assets/{extension-webview-12M45CGq.js → extension-webview-CuOQrHIS.js} +1 -1
  46. package/dist/web/assets/format-bytes-Dk7B73B7.js +1 -0
  47. package/dist/web/assets/{fortran-fixed-form-BLyAtyPM.js → fortran-fixed-form-CXLIv8Ox.js} +1 -1
  48. package/dist/web/assets/{fsharp-Bxbn_gbr.js → fsharp-CZsYmiw9.js} +1 -1
  49. package/dist/web/assets/{gdresource-sFMY4D2Q.js → gdresource-BGRvoWfC.js} +1 -1
  50. package/dist/web/assets/{git-commit-BzB9Lio5.js → git-commit-DH6mY3Km.js} +1 -1
  51. package/dist/web/assets/{git-log-panel-Cp4k3tX_.js → git-log-panel-DcV7PhqW.js} +1 -1
  52. package/dist/web/assets/{git-rebase-CKSVd848.js → git-rebase-C5Gql6Ma.js} +1 -1
  53. package/dist/web/assets/gitGraph-HDMCJU4V-D4hYLNJU.js +1 -0
  54. package/dist/web/assets/{glide-data-grid-B0BB0VDl.js → glide-data-grid-Cehfgrzc.js} +7 -7
  55. package/dist/web/assets/{glimmer-js-BY8aExAJ.js → glimmer-js-1-6JMJlj.js} +1 -1
  56. package/dist/web/assets/{glimmer-ts-Bak54dBX.js → glimmer-ts-C_Njj0nK.js} +1 -1
  57. package/dist/web/assets/{glsl-nR2eaJQe.js → glsl-DbkxE1TN.js} +1 -1
  58. package/dist/web/assets/{graphql-CGPPFAU6.js → graphql-BK75fiXl.js} +1 -1
  59. package/dist/web/assets/group-chat-tab-BVPYxjz-.js +1 -0
  60. package/dist/web/assets/{hack-CXIMX-Ol.js → hack-DG151vit.js} +1 -1
  61. package/dist/web/assets/{haml-tPY-9Pfm.js → haml-DKeIPQWM.js} +1 -1
  62. package/dist/web/assets/{handlebars-BuW1LT7T.js → handlebars-398uCI13.js} +1 -1
  63. package/dist/web/assets/{html-bgVcwZ-t.js → html-NLWdst5q.js} +1 -1
  64. package/dist/web/assets/{html-derivative-D6-IxTgn.js → html-derivative-CJf_Le2z.js} +1 -1
  65. package/dist/web/assets/{http-CJ1zyB-h.js → http-G1K2FozA.js} +1 -1
  66. package/dist/web/assets/{hurl-CmoT7l3T.js → hurl-WDC6sSBz.js} +1 -1
  67. package/dist/web/assets/{hxml-CztOsL8o.js → hxml-Dc3jBXuf.js} +1 -1
  68. package/dist/web/assets/{image-preview-3HfuxA0N.js → image-preview-D-Ok10eZ.js} +1 -1
  69. package/dist/web/assets/index-CerSxGdf.js +52 -0
  70. package/dist/web/assets/index-DRA_OpWY.css +2 -0
  71. package/dist/web/assets/info-3K5VOQVL-lRlrTlkb.js +1 -0
  72. package/dist/web/assets/{jinja-B1pq3jJq.js → jinja-CWsQj2y0.js} +1 -1
  73. package/dist/web/assets/{jison-D8B5pCwA.js → jison-CciJg2NW.js} +1 -1
  74. package/dist/web/assets/{julia-D0K3bwpU.js → julia-IOQNJAB7.js} +1 -1
  75. package/dist/web/assets/{just-B9Jlddu-.js → just-BGdHchwS.js} +1 -1
  76. package/dist/web/assets/{keybindings-store-oMJmtpH4.js → keybindings-store-aIY40k2o.js} +1 -1
  77. package/dist/web/assets/{latex-BPJSSE6j.js → latex-D6TOl-L2.js} +1 -1
  78. package/dist/web/assets/{liquid-lv10fo4U.js → liquid-CVSvu_Wn.js} +1 -1
  79. package/dist/web/assets/{lua-PNuaIBEF.js → lua-CcKiU6HW.js} +1 -1
  80. package/dist/web/assets/markdown-renderer-I89kyQhe.js +1 -0
  81. package/dist/web/assets/{markdown-renderer-DPcoPjmO.js → markdown-renderer-pVzBdkpl.js} +3 -3
  82. package/dist/web/assets/{marko-Du3frD6X.js → marko--UOicMGo.js} +1 -1
  83. package/dist/web/assets/{mdc-BeDVcFRl.js → mdc-D690aU2C.js} +1 -1
  84. package/dist/web/assets/{mobile-explorer-sheet-CEVcU964.js → mobile-explorer-sheet-5Uj9ZMM9.js} +1 -1
  85. package/dist/web/assets/{nextflow-DkcXP71s.js → nextflow-DR8PhpF8.js} +1 -1
  86. package/dist/web/assets/{nginx-C5n8N_bt.js → nginx-Qb9pUk1g.js} +1 -1
  87. package/dist/web/assets/{nim-CIhyfs-A.js → nim-DLa8R3NS.js} +1 -1
  88. package/dist/web/assets/{notification-store-B8AqxwRT.js → notification-store-DJ-OtAG3.js} +1 -1
  89. package/dist/web/assets/{number-overlay-editor-NgOsWJ7x.js → number-overlay-editor-D9SkFg1Y.js} +1 -1
  90. package/dist/web/assets/overview-panel-Cgi3UPY1.js +1 -0
  91. package/dist/web/assets/packet-RMMSAZCW-BIhk1mvp.js +1 -0
  92. package/dist/web/assets/{pdf-preview-BslNoDFw.js → pdf-preview-Di5xHFyT.js} +1 -1
  93. package/dist/web/assets/{perl-Cf31sZYE.js → perl-AMNGIneF.js} +1 -1
  94. package/dist/web/assets/{php-Dzl_MDIW.js → php-CDsOOxXn.js} +1 -1
  95. package/dist/web/assets/pie-UPGHQEXC-SLS6i76l.js +1 -0
  96. package/dist/web/assets/{postgres-viewer-BtSXQ3S4.js → postgres-viewer-CR6VpTrX.js} +3 -3
  97. package/dist/web/assets/process-table-DL6shbzt.js +1 -0
  98. package/dist/web/assets/{pug-CxSYHrB3.js → pug-C2kdkhQ6.js} +1 -1
  99. package/dist/web/assets/{qml-DlEjGhwN.js → qml-DRDkUp75.js} +1 -1
  100. package/dist/web/assets/radar-KQ55EAFF-JJ6O1Er_.js +1 -0
  101. package/dist/web/assets/{razor-KVt5uW14.js → razor-wY_6wUeC.js} +1 -1
  102. package/dist/web/assets/{rst-D5BwNTnw.js → rst-BRpofyNs.js} +1 -1
  103. package/dist/web/assets/{ruby-D5fejQwd.js → ruby-ieATBhWm.js} +1 -1
  104. package/dist/web/assets/{sas-Bj7B1CB2.js → sas-CoOOEbOO.js} +1 -1
  105. package/dist/web/assets/{scss-BB0CUoCL.js → scss-_nWV0bsb.js} +1 -1
  106. package/dist/web/assets/{settings-store-C9YT1Hir.js → settings-store-C20lqh0G.js} +2 -2
  107. package/dist/web/assets/settings-tab-jbiQwozX.js +1 -0
  108. package/dist/web/assets/{shaderlab-BdjEZUMc.js → shaderlab-XkqfIfO8.js} +1 -1
  109. package/dist/web/assets/{shellsession-Bp1OA1rR.js → shellsession-BKBIqTlM.js} +1 -1
  110. package/dist/web/assets/{soy-DlYz3wsC.js → soy-oVDnPzzh.js} +1 -1
  111. package/dist/web/assets/{sparql-CdfII5Jd.js → sparql-N2VclEsF.js} +1 -1
  112. package/dist/web/assets/{sql-query-editor-CkvpmXyA.js → sql-query-editor-BPYsJDsn.js} +1 -1
  113. package/dist/web/assets/{sqlite-viewer-CJbP6ruh.js → sqlite-viewer-Bq9ZJA2y.js} +1 -1
  114. package/dist/web/assets/{stata-BvUA6GUW.js → stata-BuuClVDg.js} +1 -1
  115. package/dist/web/assets/{surrealql--DLNbTyI.js → surrealql-DE5_63MS.js} +1 -1
  116. package/dist/web/assets/{svelte-CBfSsG4n.js → svelte--YWjlOrK.js} +1 -1
  117. package/dist/web/assets/system-monitor-body-CKEYWyN9.js +2 -0
  118. package/dist/web/assets/system-monitor-tab-WjhFFHyM.js +1 -0
  119. package/dist/web/assets/system-monitor-window-content-CMiISeoC.js +1 -0
  120. package/dist/web/assets/team-member-sheet-oY5EkH53.js +2 -0
  121. package/dist/web/assets/{team-member-window-content-Cxh-HF2V.js → team-member-window-content-yCBeI_5X.js} +1 -1
  122. package/dist/web/assets/{templ-Dv8zpKZW.js → templ-MlpvJx4a.js} +1 -1
  123. package/dist/web/assets/{terminal-tab-gQCs_fyx.js → terminal-tab-BxHtMR7h.js} +3 -3
  124. package/dist/web/assets/{tex-CsrOiqh1.js → tex-0loAoXJG.js} +1 -1
  125. package/dist/web/assets/{tool-cards-BG2fz83z.js → tool-cards-BcGrk1zk.js} +5 -5
  126. package/dist/web/assets/treemap-KZPCXAKY-Be3KNmns.js +1 -0
  127. package/dist/web/assets/{ts-tags-3T98k4EJ.js → ts-tags-pt-Ug0hK.js} +1 -1
  128. package/dist/web/assets/{twig-u6QZ45FH.js → twig-DOePpLOL.js} +1 -1
  129. package/dist/web/assets/{use-monaco-theme-DaqI7O-a.js → use-monaco-theme-CGucu3fb.js} +1 -1
  130. package/dist/web/assets/{use-open-team-member-DKpstvLS.js → use-open-team-member-DdrRXj-M.js} +1 -1
  131. package/dist/web/assets/{use-websocket-KVhDtbwK.js → use-websocket-C-Rxv8JN.js} +1 -1
  132. package/dist/web/assets/{vendor-mermaid-Bg4vE8QA.js → vendor-mermaid-DrwG0NYt.js} +1 -1
  133. package/dist/web/assets/{video-preview-CVEUDZBj.js → video-preview-DYAbbmd0.js} +1 -1
  134. package/dist/web/assets/{vue-CxIsxtwn.js → vue-D6f-rprj.js} +1 -1
  135. package/dist/web/assets/{vue-html-BGL5qnuH.js → vue-html-DEYRkS1V.js} +1 -1
  136. package/dist/web/assets/{vue-vine-DHPh_gMr.js → vue-vine-CxSG2ojf.js} +1 -1
  137. package/dist/web/assets/{xml-C-vM2m7J.js → xml-DhrxbATj.js} +1 -1
  138. package/dist/web/assets/{xsl-DvTXNwuO.js → xsl-CU0ZndUO.js} +1 -1
  139. package/dist/web/index.html +18 -17
  140. package/dist/web/sw.js +1 -1
  141. package/docs/system-architecture.md +2 -2
  142. package/package.json +1 -1
  143. package/packages/vscode-compat/node_modules/.bin/tsc.bunx +0 -0
  144. package/packages/vscode-compat/node_modules/.bin/tsc.exe +0 -0
  145. package/packages/vscode-compat/node_modules/.bin/tsserver.bunx +0 -0
  146. package/packages/vscode-compat/node_modules/.bin/tsserver.exe +0 -0
  147. package/src/server/index.ts +2 -8
  148. package/src/server/routes/resources.ts +119 -73
  149. package/src/services/autostart-generator.ts +79 -7
  150. package/src/services/autostart-register.ts +15 -2
  151. package/src/services/edge-forwarder.ts +191 -191
  152. package/src/services/proc-table-linux.ts +4 -0
  153. package/src/services/redact-secrets.ts +33 -0
  154. package/src/services/system-metrics/cpu-memory-collector.ts +101 -0
  155. package/src/services/system-metrics/disk-net-collector-darwin.ts +75 -0
  156. package/src/services/system-metrics/disk-net-collector-linux.ts +88 -0
  157. package/src/services/system-metrics/disk-net-collector-windows.ts +57 -0
  158. package/src/services/system-metrics/gpu-collector-nvidia.ts +78 -0
  159. package/src/services/system-metrics/gpu-process-memory-nvidia.ts +66 -0
  160. package/src/services/system-metrics/gpu-process-usage-windows.ts +138 -0
  161. package/src/services/system-metrics/kill-executor.ts +85 -0
  162. package/src/services/system-metrics/kill-guard.ts +124 -0
  163. package/src/services/system-metrics/kill-identity-resolver.ts +72 -0
  164. package/src/services/system-metrics/kill-request-handler.ts +79 -0
  165. package/src/services/system-metrics/metrics-collector-lock.ts +36 -0
  166. package/src/services/system-metrics/metrics-poll-scheduler.ts +83 -0
  167. package/src/services/system-metrics/metrics-subscriber-registry.ts +85 -0
  168. package/src/services/system-metrics/powershell-session-bootstrap.ts +48 -0
  169. package/src/services/system-metrics/powershell-session.ts +182 -0
  170. package/src/services/system-metrics/ppm-process-ownership.ts +34 -0
  171. package/src/services/system-metrics/ppm-protected-pids.ts +84 -0
  172. package/src/services/system-metrics/process-collector-darwin.ts +141 -0
  173. package/src/services/system-metrics/process-collector-linux.ts +85 -0
  174. package/src/services/system-metrics/process-collector-types.ts +80 -0
  175. package/src/services/system-metrics/process-collector-windows-parse.ts +153 -0
  176. package/src/services/system-metrics/process-collector-windows.ts +136 -0
  177. package/src/services/system-metrics/process-cpu-delta.ts +61 -0
  178. package/src/services/system-metrics/process-grouping.ts +142 -0
  179. package/src/services/system-metrics/process-io-delta.ts +84 -0
  180. package/src/services/system-metrics/process-io-linux.ts +46 -0
  181. package/src/services/system-metrics/process-net-collector-darwin.ts +103 -0
  182. package/src/services/system-metrics/process-rows-builder.ts +111 -0
  183. package/src/services/system-metrics/rate-delta.ts +47 -0
  184. package/src/services/system-metrics/system-metrics-platform.ts +51 -0
  185. package/src/services/system-metrics/system-metrics-tick.ts +178 -0
  186. package/src/services/system-metrics/system-metrics.service.ts +212 -0
  187. package/src/services/windows-process-tree.ts +351 -351
  188. package/src/types/system-metrics.ts +199 -0
  189. package/src/web/components/floating-window/window-content-registry.ts +2 -0
  190. package/src/web/components/floating-window/window-persistence.ts +1 -1
  191. package/src/web/components/floating-window/window-store-types.ts +1 -1
  192. package/src/web/components/system/build-kill-request.ts +9 -0
  193. package/src/web/components/system/chart-scale.ts +28 -0
  194. package/src/web/components/system/cpu-core-bars.tsx +33 -0
  195. package/src/web/components/system/kill-confirm-dialog.tsx +89 -0
  196. package/src/web/components/system/metric-chart-canvas.tsx +108 -0
  197. package/src/web/components/system/overview-cards/cpu-card.tsx +39 -0
  198. package/src/web/components/system/overview-cards/disk-card.tsx +41 -0
  199. package/src/web/components/system/overview-cards/gpu-card.tsx +33 -0
  200. package/src/web/components/system/overview-cards/mem-card.tsx +32 -0
  201. package/src/web/components/system/overview-cards/net-card.tsx +41 -0
  202. package/src/web/components/system/overview-panel.tsx +97 -0
  203. package/src/web/components/system/process-columns-grid.ts +93 -0
  204. package/src/web/components/system/process-group-row.tsx +71 -0
  205. package/src/web/components/system/process-row-format.ts +56 -0
  206. package/src/web/components/system/process-row.tsx +82 -0
  207. package/src/web/components/system/process-table-model.ts +127 -0
  208. package/src/web/components/system/process-table-sort.ts +90 -0
  209. package/src/web/components/system/process-table-toolbar.tsx +190 -0
  210. package/src/web/components/system/process-table-totals.ts +49 -0
  211. package/src/web/components/system/process-table.tsx +187 -0
  212. package/src/web/components/system/resolve-open-system-monitor-action.ts +29 -0
  213. package/src/web/components/system/resource-status-bar.tsx +17 -16
  214. package/src/web/components/system/sortable-header.tsx +65 -0
  215. package/src/web/components/system/sparkline-canvas.tsx +8 -9
  216. package/src/web/components/system/system-monitor-body.tsx +146 -0
  217. package/src/web/components/system/system-monitor-tab.tsx +2 -185
  218. package/src/web/components/system/system-monitor-window-content.tsx +18 -0
  219. package/src/web/components/system/use-open-system-monitor.ts +34 -0
  220. package/src/web/hooks/resource-monitor-lease.ts +55 -0
  221. package/src/web/hooks/use-element-width.ts +27 -0
  222. package/src/web/hooks/use-resource-monitor.ts +113 -35
  223. package/src/web/lib/format-bytes.ts +16 -0
  224. package/dist/web/assets/architecture-PBZL5I3N-Bs7wzj-W.js +0 -1
  225. package/dist/web/assets/arrow-right-DubGFkN8.js +0 -1
  226. package/dist/web/assets/button-B4MWPjWj.js +0 -1
  227. package/dist/web/assets/chat-tab-pBGQ9SCY.js +0 -15
  228. package/dist/web/assets/circle-question-mark-CENpx4oA.js +0 -1
  229. package/dist/web/assets/code-editor-XviNXdzi.js +0 -10
  230. package/dist/web/assets/gitGraph-HDMCJU4V-D7i54kbM.js +0 -1
  231. package/dist/web/assets/group-chat-tab-CcG_NXIS.js +0 -1
  232. package/dist/web/assets/index-BAVBuKmT.js +0 -52
  233. package/dist/web/assets/index-oxsyfDa0.css +0 -2
  234. package/dist/web/assets/info-3K5VOQVL-BV41AzR9.js +0 -1
  235. package/dist/web/assets/markdown-renderer-Dg5HE9Zq.js +0 -1
  236. package/dist/web/assets/packet-RMMSAZCW-CaJoP44m.js +0 -1
  237. package/dist/web/assets/pie-UPGHQEXC-DSGZmNw2.js +0 -1
  238. package/dist/web/assets/radar-KQ55EAFF-Be4VUTs0.js +0 -1
  239. package/dist/web/assets/settings-tab-COSUzGl8.js +0 -1
  240. package/dist/web/assets/system-monitor-tab-DThAFSd_.js +0 -1
  241. package/dist/web/assets/team-member-sheet-M83B4znI.js +0 -2
  242. package/dist/web/assets/treemap-KZPCXAKY-Cu2zgbxU.js +0 -1
  243. package/src/services/resource-monitor-utils.ts +0 -141
  244. package/src/services/resource-monitor.service.ts +0 -147
  245. package/src/web/components/system/system-monitor-group-row.tsx +0 -153
  246. /package/dist/web/assets/{abap-C1K0-wzc.js → abap-MRbmsXOs.js} +0 -0
  247. /package/dist/web/assets/{actionscript-3-CJhQVjLA.js → actionscript-3-BDDHKqa4.js} +0 -0
  248. /package/dist/web/assets/{ada-Bt8r9fME.js → ada-DpuV9KwV.js} +0 -0
  249. /package/dist/web/assets/{andromeeda-DF1I8qi3.js → andromeeda-D6qUCKJo.js} +0 -0
  250. /package/dist/web/assets/{apache-CnlleE6P.js → apache-CX1NU_Tl.js} +0 -0
  251. /package/dist/web/assets/{apex-j0C6Xmk6.js → apex-B4-aoQ3K.js} +0 -0
  252. /package/dist/web/assets/{api-settings-DfNRPr1q.js → api-settings-kQHV6pYZ.js} +0 -0
  253. /package/dist/web/assets/{api-themes-8WTH6KpV.js → api-themes-CrK0tkW_.js} +0 -0
  254. /package/dist/web/assets/{applescript-DO7AnO8U.js → applescript-Dm9NI6KR.js} +0 -0
  255. /package/dist/web/assets/{apply-theme-CNj1iA-v.js → apply-theme-BH_d4amk.js} +0 -0
  256. /package/dist/web/assets/{ara-i83AydZj.js → ara-BGN8GAYn.js} +0 -0
  257. /package/dist/web/assets/{asciidoc-DbBA6-sF.js → asciidoc-s_yVuR3t.js} +0 -0
  258. /package/dist/web/assets/{asm-B5S47Rgr.js → asm-BzQdSvTe.js} +0 -0
  259. /package/dist/web/assets/{aurora-x-De_IaSKw.js → aurora-x-BJTLETG_.js} +0 -0
  260. /package/dist/web/assets/{awk-CfyLHXqS.js → awk-BQEGWxvX.js} +0 -0
  261. /package/dist/web/assets/{ayu-dark-DTLdZ1Si.js → ayu-dark-CpTORmLc.js} +0 -0
  262. /package/dist/web/assets/{ayu-light-DTOfkzhu.js → ayu-light-D8PVj-e6.js} +0 -0
  263. /package/dist/web/assets/{ayu-mirage-DsAECCMv.js → ayu-mirage-DyElQHtm.js} +0 -0
  264. /package/dist/web/assets/{ballerina-CumGp9A7.js → ballerina-C82NkRtj.js} +0 -0
  265. /package/dist/web/assets/{bat-Ca2SBbYN.js → bat-0X7DtGI-.js} +0 -0
  266. /package/dist/web/assets/{beancount-CqyXBwwF.js → beancount-Xgvy6YRl.js} +0 -0
  267. /package/dist/web/assets/{berry-yl-kJr_H.js → berry-CCT2pZcQ.js} +0 -0
  268. /package/dist/web/assets/{bibtex-DoFFszjV.js → bibtex-CpXgZ9M_.js} +0 -0
  269. /package/dist/web/assets/{bicep-CWPi4nfK.js → bicep-fkeSA62l.js} +0 -0
  270. /package/dist/web/assets/{bird2-DXew-ut0.js → bird2-Co7SeAI8.js} +0 -0
  271. /package/dist/web/assets/{c-clbySDvd.js → c-BpmrTvJh.js} +0 -0
  272. /package/dist/web/assets/{c3-B65jvSM1.js → c3-BZ_Z0RrR.js} +0 -0
  273. /package/dist/web/assets/{cadence-Cm8tQTHN.js → cadence-B0GBC8OF.js} +0 -0
  274. /package/dist/web/assets/{can-open-in-ppm-DXGOSUQc.js → can-open-in-ppm-omBzUBBq.js} +0 -0
  275. /package/dist/web/assets/{catppuccin-frappe-DLeGslh_.js → catppuccin-frappe-DIt_xR7m.js} +0 -0
  276. /package/dist/web/assets/{catppuccin-latte-CR5GeHws.js → catppuccin-latte-Dw40AcqA.js} +0 -0
  277. /package/dist/web/assets/{catppuccin-macchiato-p-XgjxhP.js → catppuccin-macchiato-BJ7DfVEF.js} +0 -0
  278. /package/dist/web/assets/{catppuccin-mocha-B8QOAZLl.js → catppuccin-mocha-NI2lfXzU.js} +0 -0
  279. /package/dist/web/assets/{clarity-DPulbvKH.js → clarity-F39L0xMJ.js} +0 -0
  280. /package/dist/web/assets/{clock-D493FU_D.js → clock-CvhF4DJP.js} +0 -0
  281. /package/dist/web/assets/{clojure-DFuWS20u.js → clojure-DloMkd8K.js} +0 -0
  282. /package/dist/web/assets/{cmake-DejCqcu4.js → cmake-CwerJun_.js} +0 -0
  283. /package/dist/web/assets/{code-CLF5x7KK.js → code-DDPoqVri.js} +0 -0
  284. /package/dist/web/assets/{codeowners-BwAyqWIH.js → codeowners-CQyVz4Qf.js} +0 -0
  285. /package/dist/web/assets/{codeql-DgSwFjqI.js → codeql-Bb229zuY.js} +0 -0
  286. /package/dist/web/assets/{common-lisp-CxIVJCtf.js → common-lisp-KMlIwq5I.js} +0 -0
  287. /package/dist/web/assets/{copy-BApI9v7Z.js → copy-DKn11Pye.js} +0 -0
  288. /package/dist/web/assets/{coq-DLSjSnmf.js → coq-DHX_3IIo.js} +0 -0
  289. /package/dist/web/assets/{csharp-C1HHzXBp.js → csharp-CEmCZv9Q.js} +0 -0
  290. /package/dist/web/assets/{css-VXsMY--y.js → css-CqZqBD05.js} +0 -0
  291. /package/dist/web/assets/{csv-BEbcJdHz.js → csv-l1g_V5MV.js} +0 -0
  292. /package/dist/web/assets/{csv-parser-BRtnJCfv.js → csv-parser-CnS0wqr6.js} +0 -0
  293. /package/dist/web/assets/{cue-BkDnFqUD.js → cue-BrxRmilg.js} +0 -0
  294. /package/dist/web/assets/{cypher-1cMqojSQ.js → cypher-rZkKwqZc.js} +0 -0
  295. /package/dist/web/assets/{d-BnYjRXtH.js → d-BALR-QuP.js} +0 -0
  296. /package/dist/web/assets/{dark-plus-XfbaH7kZ.js → dark-plus-Cj7rVwh-.js} +0 -0
  297. /package/dist/web/assets/{dart-Ca7s-8hK.js → dart-CWQcdkXk.js} +0 -0
  298. /package/dist/web/assets/{data-grid-types-BXwlFMzs.js → data-grid-types-CYvF-xK5.js} +0 -0
  299. /package/dist/web/assets/{database-B9okYLx6.js → database-BH0urvbs.js} +0 -0
  300. /package/dist/web/assets/{dax-CmuOw-mY.js → dax-BNHD-QBA.js} +0 -0
  301. /package/dist/web/assets/{desktop-C2gJ6Ovb.js → desktop-CN0IXPrP.js} +0 -0
  302. /package/dist/web/assets/{diff-BCEo1Ej7.js → diff-BtOXapES.js} +0 -0
  303. /package/dist/web/assets/{dist-CUPbqNnL.js → dist-DB1Oaqcc.js} +0 -0
  304. /package/dist/web/assets/{dist-DOlBnxFX.js → dist-Di6G_5jU.js} +0 -0
  305. /package/dist/web/assets/{docker-DN2jlyAh.js → docker-DNsAo_qO.js} +0 -0
  306. /package/dist/web/assets/{dotenv-NExMY2kS.js → dotenv-D6Pl6aOU.js} +0 -0
  307. /package/dist/web/assets/{download-D9UYwY0-.js → download-zCATy4x4.js} +0 -0
  308. /package/dist/web/assets/{dracula-B9lbE01y.js → dracula-C3m-w12D.js} +0 -0
  309. /package/dist/web/assets/{dracula-soft-CMBBfKF_.js → dracula-soft-BYqvXm6Z.js} +0 -0
  310. /package/dist/web/assets/{dream-maker-DEyDwFsd.js → dream-maker-DZAPbPTi.js} +0 -0
  311. /package/dist/web/assets/{emacs-lisp-D_qP2zS6.js → emacs-lisp-Ao5SW8ay.js} +0 -0
  312. /package/dist/web/assets/{everforest-dark-DbHa2U-p.js → everforest-dark-uC8QYotQ.js} +0 -0
  313. /package/dist/web/assets/{everforest-light-BISkJchP.js → everforest-light-CTgsVNMr.js} +0 -0
  314. /package/dist/web/assets/{fennel-6B22SfJR.js → fennel-WuBw6IR1.js} +0 -0
  315. /package/dist/web/assets/{file-exclamation-point-a8f3_w7a.js → file-exclamation-point-COAwgNGw.js} +0 -0
  316. /package/dist/web/assets/{fish-CubIIvJD.js → fish-Byy9dusu.js} +0 -0
  317. /package/dist/web/assets/{fluent-DF55zQ09.js → fluent-CDxb_sgw.js} +0 -0
  318. /package/dist/web/assets/{fortran-free-form-DvOu8jAt.js → fortran-free-form-DKWSTamT.js} +0 -0
  319. /package/dist/web/assets/{gdscript-DCPxdLpq.js → gdscript-prYHMgtD.js} +0 -0
  320. /package/dist/web/assets/{gdshader-CTZ381FO.js → gdshader-D-RM-SQk.js} +0 -0
  321. /package/dist/web/assets/{genie-C_QDtvgU.js → genie-CowkJhej.js} +0 -0
  322. /package/dist/web/assets/{gherkin-BcvK42tF.js → gherkin-CLFpoVYJ.js} +0 -0
  323. /package/dist/web/assets/{github-dark-default-CKGVrl3Z.js → github-dark-default-BK_1Qgb8.js} +0 -0
  324. /package/dist/web/assets/{github-dark-dimmed-C3dQZ_LC.js → github-dark-dimmed-Cv9lj6f-.js} +0 -0
  325. /package/dist/web/assets/{github-dark-high-contrast-DW78QukY.js → github-dark-high-contrast-CW5ZgIDh.js} +0 -0
  326. /package/dist/web/assets/{github-dark-C9afs_4w.js → github-dark-nW2F-RLd.js} +0 -0
  327. /package/dist/web/assets/{github-light-BnP2dznS.js → github-light-D4PqBHGZ.js} +0 -0
  328. /package/dist/web/assets/{github-light-default-C2fPZzPG.js → github-light-default-B-cHtJJV.js} +0 -0
  329. /package/dist/web/assets/{github-light-high-contrast-BzIuUFR2.js → github-light-high-contrast-Dt0HJq50.js} +0 -0
  330. /package/dist/web/assets/{gleam-BpeKwEIO.js → gleam-DwSyXJWP.js} +0 -0
  331. /package/dist/web/assets/{gn-nUb_Mit0.js → gn-Cv5WEzHc.js} +0 -0
  332. /package/dist/web/assets/{gnuplot-D7I0v20p.js → gnuplot-D7bRdY_M.js} +0 -0
  333. /package/dist/web/assets/{go-D7Qqska7.js → go-DiRVJ22U.js} +0 -0
  334. /package/dist/web/assets/{groovy-DS-pne5-.js → groovy-BHAgLTeO.js} +0 -0
  335. /package/dist/web/assets/{gruvbox-dark-hard-C0W01fsq.js → gruvbox-dark-hard-C8QZ3gzY.js} +0 -0
  336. /package/dist/web/assets/{gruvbox-dark-medium-Bqo6fQbg.js → gruvbox-dark-medium-Dp1eeid2.js} +0 -0
  337. /package/dist/web/assets/{gruvbox-dark-soft-D-XSM_fu.js → gruvbox-dark-soft-Cwq0dWVj.js} +0 -0
  338. /package/dist/web/assets/{gruvbox-light-hard-IVAwMJRl.js → gruvbox-light-hard-CLQCq2-w.js} +0 -0
  339. /package/dist/web/assets/{gruvbox-light-medium-38ATiG7i.js → gruvbox-light-medium-APHsh6Mo.js} +0 -0
  340. /package/dist/web/assets/{gruvbox-light-soft-DnZr3c_0.js → gruvbox-light-soft-CX-fYc64.js} +0 -0
  341. /package/dist/web/assets/{haskell-uQcywkDH.js → haskell-C4Tw-TDa.js} +0 -0
  342. /package/dist/web/assets/{haxe-c6bI4_GT.js → haxe-B7fSduTQ.js} +0 -0
  343. /package/dist/web/assets/{hcl-CQXTiEXq.js → hcl-Bi3ho6yC.js} +0 -0
  344. /package/dist/web/assets/{hjson-ChETf2bz.js → hjson-BXwae2M1.js} +0 -0
  345. /package/dist/web/assets/{hlsl-BMC4JGoE.js → hlsl-CRuQLBSa.js} +0 -0
  346. /package/dist/web/assets/{horizon-BusFlhLW.js → horizon-DtdQ6qjv.js} +0 -0
  347. /package/dist/web/assets/{horizon-bright-2oD0Mz7W.js → horizon-bright-BXSF_uKq.js} +0 -0
  348. /package/dist/web/assets/{houston-DdbbjqFg.js → houston-C6ASpUjT.js} +0 -0
  349. /package/dist/web/assets/{hy-D_SOuqw9.js → hy-BrWBHtHY.js} +0 -0
  350. /package/dist/web/assets/{image-gallery-CrM5fHKy.js → image-gallery-CGvlv8zR.js} +0 -0
  351. /package/dist/web/assets/{imba-BxLOHO5I.js → imba-C_JJXckG.js} +0 -0
  352. /package/dist/web/assets/{ini-ox-CFcg0.js → ini-DEE_vSHQ.js} +0 -0
  353. /package/dist/web/assets/{java-Bzo8yIal.js → java-CnmpcjcT.js} +0 -0
  354. /package/dist/web/assets/{javascript-DHuz9VXn.js → javascript-C-M7sa2e.js} +0 -0
  355. /package/dist/web/assets/{json-0_y80FD5.js → json-BjZ3dAk6.js} +0 -0
  356. /package/dist/web/assets/{json5-CEQ50pGM.js → json5-BQ2vpqjp.js} +0 -0
  357. /package/dist/web/assets/{jsonc-CfrLEAKA.js → jsonc-C5MjoWGx.js} +0 -0
  358. /package/dist/web/assets/{jsonl-fKbrANC2.js → jsonl-JvhrmQJI.js} +0 -0
  359. /package/dist/web/assets/{jsonnet-DKbkPaQ2.js → jsonnet-C5pdZVuo.js} +0 -0
  360. /package/dist/web/assets/{jssm-Dxxx1Hqu.js → jssm-Db17uybX.js} +0 -0
  361. /package/dist/web/assets/{jsx-DlJL-Oj3.js → jsx-tJp2Cyqu.js} +0 -0
  362. /package/dist/web/assets/{kanagawa-dragon-CwN4SV1c.js → kanagawa-dragon-BculT_Y1.js} +0 -0
  363. /package/dist/web/assets/{kanagawa-lotus-BHltayiE.js → kanagawa-lotus-yQgHUGwU.js} +0 -0
  364. /package/dist/web/assets/{kanagawa-wave-D-KXPjw6.js → kanagawa-wave-CyGoWN4d.js} +0 -0
  365. /package/dist/web/assets/{kdl-DvtoJdFo.js → kdl-Bn8R1REF.js} +0 -0
  366. /package/dist/web/assets/{kotlin-CTS4MLcx.js → kotlin-DWughK73.js} +0 -0
  367. /package/dist/web/assets/{kusto-HtSE_sKm.js → kusto--serPb0x.js} +0 -0
  368. /package/dist/web/assets/{laserwave-DaXZG9ge.js → laserwave-DfAPJ1tt.js} +0 -0
  369. /package/dist/web/assets/{lean-BYtGUfWx.js → lean-UAm1HOKl.js} +0 -0
  370. /package/dist/web/assets/{less-BoxmU_Mk.js → less-Xj6Ka0fF.js} +0 -0
  371. /package/dist/web/assets/{lib-B1clP4ai.js → lib-DgNcCtj3.js} +0 -0
  372. /package/dist/web/assets/{libesm-ah-mr-sh.js → libesm-CPh1Av0r.js} +0 -0
  373. /package/dist/web/assets/{light-plus-Bt5CyUuo.js → light-plus-BfS7gPcj.js} +0 -0
  374. /package/dist/web/assets/{llvm-CSdk9q9V.js → llvm-DvWiVwvU.js} +0 -0
  375. /package/dist/web/assets/{log-B-kp_3CL.js → log-Bo5z9bNz.js} +0 -0
  376. /package/dist/web/assets/{logo-DdIsXFDO.js → logo-CrIjcMZT.js} +0 -0
  377. /package/dist/web/assets/{luau-DUBpLlzQ.js → luau-C9TsYwNt.js} +0 -0
  378. /package/dist/web/assets/{make-B3JVjoW_.js → make-GYq4qVbx.js} +0 -0
  379. /package/dist/web/assets/{markdown-Seon0vHs.js → markdown-p5mNledS.js} +0 -0
  380. /package/dist/web/assets/{material-theme-Nq-ChX1P.js → material-theme-CWYOVxsP.js} +0 -0
  381. /package/dist/web/assets/{material-theme-darker-CPV4ayXJ.js → material-theme-darker-BDGty7YH.js} +0 -0
  382. /package/dist/web/assets/{material-theme-lighter-0kyjYqEd.js → material-theme-lighter-JbgOgV3n.js} +0 -0
  383. /package/dist/web/assets/{material-theme-ocean-DGpAp5co.js → material-theme-ocean-EMOpLpa2.js} +0 -0
  384. /package/dist/web/assets/{material-theme-palenight-B0AUn0NG.js → material-theme-palenight-CY5hgm7h.js} +0 -0
  385. /package/dist/web/assets/{matlab-C2waytxs.js → matlab-C-He_NTH.js} +0 -0
  386. /package/dist/web/assets/{mdx-DAis6R6I.js → mdx-Cr2TR5fj.js} +0 -0
  387. /package/dist/web/assets/{media-url-DlYsHq0S.js → media-url-CylYQld1.js} +0 -0
  388. /package/dist/web/assets/{mermaid-_rnT2YGD.js → mermaid-BYc0-B0U.js} +0 -0
  389. /package/dist/web/assets/{min-dark-BSSjchUB.js → min-dark-CMJwqJqB.js} +0 -0
  390. /package/dist/web/assets/{min-light-DomAFQsa.js → min-light-Cx6vFiEX.js} +0 -0
  391. /package/dist/web/assets/{mipsasm-bBgtvPyG.js → mipsasm-Bjer5HwK.js} +0 -0
  392. /package/dist/web/assets/{mobile-bottom-sheet-CS3XMwFw.js → mobile-bottom-sheet-BUOJgiaZ.js} +0 -0
  393. /package/dist/web/assets/{mojo-Cp9BayW0.js → mojo-t90PR-Y2.js} +0 -0
  394. /package/dist/web/assets/{monokai-CL_9gbmn.js → monokai-dci_PdCm.js} +0 -0
  395. /package/dist/web/assets/{moonbit-BS_fcr-P.js → moonbit-AAzI-Hd-.js} +0 -0
  396. /package/dist/web/assets/{move-C79AH45U.js → move-kwBhnhrG.js} +0 -0
  397. /package/dist/web/assets/{narrat-CJ5s3BDf.js → narrat-CXww2YQL.js} +0 -0
  398. /package/dist/web/assets/{nextflow-groovy-ZHa4JrPJ.js → nextflow-groovy-CJXsuXGB.js} +0 -0
  399. /package/dist/web/assets/{night-owl-Jkf9zFQK.js → night-owl-_GD204Wr.js} +0 -0
  400. /package/dist/web/assets/{night-owl-light-DRPeaG5J.js → night-owl-light-DNgkw3kl.js} +0 -0
  401. /package/dist/web/assets/{nix-D2Jet9DN.js → nix-BgiorKFd.js} +0 -0
  402. /package/dist/web/assets/{nord-CREVs22j.js → nord-CaBmcxFC.js} +0 -0
  403. /package/dist/web/assets/{nushell-CAiDi_mR.js → nushell-DUh4UGx1.js} +0 -0
  404. /package/dist/web/assets/{objective-c-CVkmJkC1.js → objective-c-Cl9KU86S.js} +0 -0
  405. /package/dist/web/assets/{objective-cpp-DIKDO1Ly.js → objective-cpp-DVkIA8A0.js} +0 -0
  406. /package/dist/web/assets/{ocaml-R9qtGQhs.js → ocaml-vvoHTak0.js} +0 -0
  407. /package/dist/web/assets/{odin-DTYNQqVr.js → odin-Cyjw8woZ.js} +0 -0
  408. /package/dist/web/assets/{one-dark-pro-BSLWUJn5.js → one-dark-pro-B1cviILi.js} +0 -0
  409. /package/dist/web/assets/{one-light-DbkRXG3t.js → one-light-BPGUJeYI.js} +0 -0
  410. /package/dist/web/assets/{openscad-BlPcSnmT.js → openscad-BLMdTUU8.js} +0 -0
  411. /package/dist/web/assets/{pascal-B1Y46ZZB.js → pascal-i5niy3e7.js} +0 -0
  412. /package/dist/web/assets/{pkl-BhJSJbFv.js → pkl-CuOV7SsU.js} +0 -0
  413. /package/dist/web/assets/{plastic-BzxsCTpi.js → plastic-Bf_zE5KL.js} +0 -0
  414. /package/dist/web/assets/{plsql-DBba7dyP.js → plsql-cfqEtMD3.js} +0 -0
  415. /package/dist/web/assets/{plus-DmjC2iRB.js → plus-BM-Ty0fp.js} +0 -0
  416. /package/dist/web/assets/{po-BvgLlnNo.js → po-CFJcWgjr.js} +0 -0
  417. /package/dist/web/assets/{poimandres-DUaI_1JP.js → poimandres-G5YoaIFf.js} +0 -0
  418. /package/dist/web/assets/{polar-C7uILwJn.js → polar-rcjs3i9R.js} +0 -0
  419. /package/dist/web/assets/{postcss-BgJlpFdw.js → postcss-CBKY1FTZ.js} +0 -0
  420. /package/dist/web/assets/{powerquery-Dn1MIpZu.js → powerquery-Db7SXLbO.js} +0 -0
  421. /package/dist/web/assets/{powershell-Bo-DYzOS.js → powershell-LFy3MUTP.js} +0 -0
  422. /package/dist/web/assets/{prisma-CTLs5IdT.js → prisma-BE8GR1lH.js} +0 -0
  423. /package/dist/web/assets/{prolog-QRGun3eG.js → prolog-DOn5lR1e.js} +0 -0
  424. /package/dist/web/assets/{proto-B7PI7apn.js → proto-wr-TpAK_.js} +0 -0
  425. /package/dist/web/assets/{puppet-CBq0tLrP.js → puppet-D2Dkv62u.js} +0 -0
  426. /package/dist/web/assets/{purescript-DFewOQb2.js → purescript-DvgJgPdy.js} +0 -0
  427. /package/dist/web/assets/{python-iWuxKXvT.js → python-C7TlkHhK.js} +0 -0
  428. /package/dist/web/assets/{qmldir-cXiW3AsF.js → qmldir-CtZMwhcW.js} +0 -0
  429. /package/dist/web/assets/{qss-DASwAbBL.js → qss-dNZ2btnl.js} +0 -0
  430. /package/dist/web/assets/{r-TU2eaIPw.js → r-BlqnNkHS.js} +0 -0
  431. /package/dist/web/assets/{racket-SkRKqrLY.js → racket-CzRQrGc4.js} +0 -0
  432. /package/dist/web/assets/{raku-D31lthkZ.js → raku-BwutWhBF.js} +0 -0
  433. /package/dist/web/assets/{red-CTcQZevb.js → red-BMXMywmL.js} +0 -0
  434. /package/dist/web/assets/{reg-D8YAsTGf.js → reg-BqOKrIOw.js} +0 -0
  435. /package/dist/web/assets/{regexp-CD2uvAWx.js → regexp-Bero1BN2.js} +0 -0
  436. /package/dist/web/assets/{rel-CAaI-1fg.js → rel-BXKWIElA.js} +0 -0
  437. /package/dist/web/assets/{resolve-theme-CJvkL8hU.js → resolve-theme-IdhSR-gx.js} +0 -0
  438. /package/dist/web/assets/{riscv-DR-hJVIj.js → riscv-BbbBYJBo.js} +0 -0
  439. /package/dist/web/assets/{ron-CuUCJ0n4.js → ron-BtVTWW4b.js} +0 -0
  440. /package/dist/web/assets/{rose-pine-dawn-Bqz2sBRY.js → rose-pine-dawn-D7lwhUei.js} +0 -0
  441. /package/dist/web/assets/{rose-pine-aFHxW48i.js → rose-pine-hvkvQzvU.js} +0 -0
  442. /package/dist/web/assets/{rose-pine-moon-wqyh0an4.js → rose-pine-moon-CoHDmsIw.js} +0 -0
  443. /package/dist/web/assets/{rosmsg-CI1ywimO.js → rosmsg-CdaZFgI8.js} +0 -0
  444. /package/dist/web/assets/{run-in-terminal-CGW6o37_.js → run-in-terminal-CyS5Itj-.js} +0 -0
  445. /package/dist/web/assets/{rust-p7Imk4G_.js → rust-Dy2qsphD.js} +0 -0
  446. /package/dist/web/assets/{sass-C8JfaqCV.js → sass-Bz7NVxDb.js} +0 -0
  447. /package/dist/web/assets/{save-DRPrDfTt.js → save-C4z1p51e.js} +0 -0
  448. /package/dist/web/assets/{scala-DNxCW1By.js → scala-sXSwsNyq.js} +0 -0
  449. /package/dist/web/assets/{scheme-BYuUPJoL.js → scheme-DS7TUbN7.js} +0 -0
  450. /package/dist/web/assets/{sdbl-DbPeJPUr.js → sdbl-iISFvIep.js} +0 -0
  451. /package/dist/web/assets/{send-to-chat-YXHdAyLG.js → send-to-chat-BcO39BDR.js} +0 -0
  452. /package/dist/web/assets/{shellscript-DMiHlR3q.js → shellscript-BkIl4ApC.js} +0 -0
  453. /package/dist/web/assets/{shield-check-8GObuUAn.js → shield-check-C5laObJv.js} +0 -0
  454. /package/dist/web/assets/{shield-off-egKAZEwR.js → shield-off-DULFtyLS.js} +0 -0
  455. /package/dist/web/assets/{slack-dark-C4xGcQXI.js → slack-dark-B1eg0_m2.js} +0 -0
  456. /package/dist/web/assets/{slack-ochin-BzgRt_wm.js → slack-ochin-mdkc1ldu.js} +0 -0
  457. /package/dist/web/assets/{smalltalk-LDeL9PYH.js → smalltalk-CORtd03t.js} +0 -0
  458. /package/dist/web/assets/{snazzy-light-CXE7a5j_.js → snazzy-light-Bc6Q2G89.js} +0 -0
  459. /package/dist/web/assets/{solarized-dark-DgUhY74x.js → solarized-dark-CF83zRXM.js} +0 -0
  460. /package/dist/web/assets/{solarized-light-DD9C-H-9.js → solarized-light-BoKQZaYU.js} +0 -0
  461. /package/dist/web/assets/{solidity-CAbDB4D4.js → solidity-DOgi1N4w.js} +0 -0
  462. /package/dist/web/assets/{sparkles-n1hzh65o.js → sparkles-Dqsf3hq6.js} +0 -0
  463. /package/dist/web/assets/{splunk-kQREPfIc.js → splunk-BXfw5ZLy.js} +0 -0
  464. /package/dist/web/assets/{sql-CBzeNAD8.js → sql-BcVs-eX4.js} +0 -0
  465. /package/dist/web/assets/{ssh-config-L1euxrsM.js → ssh-config-CLCtNkkd.js} +0 -0
  466. /package/dist/web/assets/{stylus-DvBnYniP.js → stylus-DdP992aO.js} +0 -0
  467. /package/dist/web/assets/{swift-DF5NDQp6.js → swift-BnGb6Lgc.js} +0 -0
  468. /package/dist/web/assets/{synthwave-84-DbBhB_Hq.js → synthwave-84-cg9264l9.js} +0 -0
  469. /package/dist/web/assets/{system-verilog-D8s2ZW_k.js → system-verilog-GbHpszs3.js} +0 -0
  470. /package/dist/web/assets/{systemd-a5-XZJsG.js → systemd-Dz-bNsDQ.js} +0 -0
  471. /package/dist/web/assets/{table-BX2ZrJfM.js → table-CHmxuh6M.js} +0 -0
  472. /package/dist/web/assets/{talonscript-BLa0URTW.js → talonscript-CFIidoBA.js} +0 -0
  473. /package/dist/web/assets/{tasl-DIoV4XcC.js → tasl-Cu-TRTKx.js} +0 -0
  474. /package/dist/web/assets/{tcl-ztYAdXfQ.js → tcl-DwCHCB1K.js} +0 -0
  475. /package/dist/web/assets/{terraform-DvpCCiOZ.js → terraform-BzZw4T1z.js} +0 -0
  476. /package/dist/web/assets/{tokyo-night-BkHlYUv0.js → tokyo-night-RKsj2-tv.js} +0 -0
  477. /package/dist/web/assets/{toml-acIrxos6.js → toml-CirbOgDP.js} +0 -0
  478. /package/dist/web/assets/{tsv-BJB5EVCT.js → tsv-CraRcWdU.js} +0 -0
  479. /package/dist/web/assets/{tsx-B1MmXGT3.js → tsx-CjFg0lgw.js} +0 -0
  480. /package/dist/web/assets/{turtle-DFceTiqd.js → turtle-B-WBIOa6.js} +0 -0
  481. /package/dist/web/assets/{typescript-Dz9wU5Y1.js → typescript-MpLarYn1.js} +0 -0
  482. /package/dist/web/assets/{typespec-CPuYZijj.js → typespec-B7QlHMZ_.js} +0 -0
  483. /package/dist/web/assets/{typst-CfsCIYv8.js → typst-CcHSKFZj.js} +0 -0
  484. /package/dist/web/assets/{use-blob-url-BmlYYZ8L.js → use-blob-url-BKyVxOZw.js} +0 -0
  485. /package/dist/web/assets/{use-is-mobile-B8FA4kQf.js → use-is-mobile-BXGVvczu.js} +0 -0
  486. /package/dist/web/assets/{v-CGo0jcXA.js → v-xTGhWZuD.js} +0 -0
  487. /package/dist/web/assets/{vala-AsSR0hrb.js → vala-DwebjH3H.js} +0 -0
  488. /package/dist/web/assets/{vb-C7tvbXv1.js → vb-BxJT2RAy.js} +0 -0
  489. /package/dist/web/assets/{vendor-xterm-C1diXHJl.js → vendor-xterm-CU6zIYMB.js} +0 -0
  490. /package/dist/web/assets/{verilog--a33ND-p.js → verilog-CvV6RHPD.js} +0 -0
  491. /package/dist/web/assets/{vesper-B_Z0h4pn.js → vesper-CY3qd7E_.js} +0 -0
  492. /package/dist/web/assets/{vhdl-CWL5dZPN.js → vhdl-B9ZX-sUL.js} +0 -0
  493. /package/dist/web/assets/{viml-BglmT14Y.js → viml-Y42h_ExQ.js} +0 -0
  494. /package/dist/web/assets/{vitesse-black-RKFsSqQI.js → vitesse-black-DkXP6Sv-.js} +0 -0
  495. /package/dist/web/assets/{vitesse-dark-D7zDWNmc.js → vitesse-dark-B9CkIB6r.js} +0 -0
  496. /package/dist/web/assets/{vitesse-light-MAp87W5b.js → vitesse-light-C7DHrJCK.js} +0 -0
  497. /package/dist/web/assets/{vyper-CgCBYg1G.js → vyper-Cnd9s5j-.js} +0 -0
  498. /package/dist/web/assets/{wasm-Bwl4txwp.js → wasm-DQE71XTB.js} +0 -0
  499. /package/dist/web/assets/{wasm-BOG7ZeTT.js → wasm-iWe7Fzjc.js} +0 -0
  500. /package/dist/web/assets/{wenyan-DpShPKXZ.js → wenyan-Bc5Pnm9l.js} +0 -0
  501. /package/dist/web/assets/{wgsl-BakcCblK.js → wgsl-D-YUAWkP.js} +0 -0
  502. /package/dist/web/assets/{wikitext-NroRWVAO.js → wikitext-DYQDUYf2.js} +0 -0
  503. /package/dist/web/assets/{wit-B5CM2pg6.js → wit-P6u7mfwy.js} +0 -0
  504. /package/dist/web/assets/{wolfram-7MTFBJpR.js → wolfram-6SXLUqao.js} +0 -0
  505. /package/dist/web/assets/{yaml-Bwr01G2K.js → yaml-CQiMLVcZ.js} +0 -0
  506. /package/dist/web/assets/{zenscript-Dj8GATvi.js → zenscript-DFMywo_P.js} +0 -0
  507. /package/dist/web/assets/{zig-LAE-fbS-.js → zig-CtAjaIiF.js} +0 -0
@@ -0,0 +1,190 @@
1
+ import { useEffect, useRef, useState } from "react";
2
+ import { Search } from "lucide-react";
3
+ import { cn } from "@/lib/utils";
4
+ import { formatRam } from "@/lib/format-bytes";
5
+ import { cpuColor, formatDiskCell, formatGpuCell, formatNetCell } from "./process-row-format";
6
+ import { optionalCellClassName, PROCESS_ROW_GRID_CLASS, type ProcessGridResult } from "./process-columns-grid";
7
+ import type { Totals } from "./process-table-totals";
8
+ import { SortableHeader } from "./sortable-header";
9
+ import type { SortDir, SortKey } from "../../../types/system-metrics";
10
+
11
+ const SEARCH_DEBOUNCE_MS = 150;
12
+
13
+ export interface ProcessTableToolbarProps {
14
+ mode: "grouped" | "flat";
15
+ onModeChange: (mode: "grouped" | "flat") => void;
16
+ ppmOnly: boolean;
17
+ onPpmOnlyChange: (v: boolean) => void;
18
+ onQueryChange: (query: string) => void;
19
+ }
20
+
21
+ /** Search/mode/PPM controls. Debounces the query locally so typing does not rebuild
22
+ * up to 1000 rows on every keystroke. */
23
+ export function ProcessTableToolbar({
24
+ mode,
25
+ onModeChange,
26
+ ppmOnly,
27
+ onPpmOnlyChange,
28
+ onQueryChange,
29
+ }: ProcessTableToolbarProps) {
30
+ const [draft, setDraft] = useState("");
31
+ const timer = useRef<ReturnType<typeof setTimeout> | null>(null);
32
+
33
+ useEffect(() => {
34
+ if (timer.current) clearTimeout(timer.current);
35
+ timer.current = setTimeout(() => onQueryChange(draft), SEARCH_DEBOUNCE_MS);
36
+ return () => {
37
+ if (timer.current) clearTimeout(timer.current);
38
+ };
39
+ // eslint-disable-next-line react-hooks/exhaustive-deps -- onQueryChange identity may churn; only `draft` should retrigger
40
+ }, [draft]);
41
+
42
+ return (
43
+ <div className="flex flex-wrap items-center gap-2 p-2 border-b border-border shrink-0">
44
+ <div className="relative flex-1 min-w-[140px]">
45
+ <Search className="absolute left-2 top-1/2 -translate-y-1/2 size-3.5 text-text-subtle" />
46
+ <input
47
+ type="text"
48
+ value={draft}
49
+ onChange={(e) => setDraft(e.target.value)}
50
+ placeholder="Search processes"
51
+ aria-label="Search processes"
52
+ data-testid="sysmon-process-search"
53
+ className="w-full min-h-11 md:min-h-8 pl-7 pr-2 text-sm rounded-md border border-border bg-transparent focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
54
+ />
55
+ </div>
56
+ <button
57
+ type="button"
58
+ onClick={() => onModeChange(mode === "grouped" ? "flat" : "grouped")}
59
+ aria-pressed={mode === "flat"}
60
+ data-testid="sysmon-toggle-flat"
61
+ className="min-h-11 md:min-h-8 px-3 text-xs rounded-md border border-border hover:bg-surface-hover transition-colors"
62
+ >
63
+ {mode === "flat" ? "Flat" : "Grouped"}
64
+ </button>
65
+ <button
66
+ type="button"
67
+ onClick={() => onPpmOnlyChange(!ppmOnly)}
68
+ aria-pressed={ppmOnly}
69
+ data-testid="sysmon-filter-ppm"
70
+ className={cn(
71
+ "min-h-11 md:min-h-8 px-3 text-xs rounded-md border transition-colors",
72
+ ppmOnly ? "border-primary bg-primary/10 text-primary" : "border-border hover:bg-surface-hover",
73
+ )}
74
+ >
75
+ PPM only
76
+ </button>
77
+ </div>
78
+ );
79
+ }
80
+
81
+ export interface ProcessTableHeaderProps {
82
+ sortKey: SortKey;
83
+ sortDir: SortDir;
84
+ grid: ProcessGridResult;
85
+ onSort: (field: Exclude<SortKey, null>) => void;
86
+ }
87
+
88
+ /** Sticky column header row, grid-aligned with the rows below it. Disk/GPU/Net
89
+ * headers only render when the host reported that column as measurable
90
+ * (`grid.columns.<x>`); below `@lg` only the one currently sorted survives. */
91
+ export function ProcessTableHeader({ sortKey, sortDir, grid, onSort }: ProcessTableHeaderProps) {
92
+ return (
93
+ <div
94
+ role="row"
95
+ className={cn(
96
+ "grid gap-1 px-3 py-1.5 text-[11px] text-text-subtle border-b border-border sticky top-0 bg-background z-10",
97
+ PROCESS_ROW_GRID_CLASS,
98
+ )}
99
+ >
100
+ <SortableHeader
101
+ label="Process"
102
+ field="name"
103
+ activeKey={sortKey}
104
+ activeDir={sortDir}
105
+ onClick={onSort}
106
+ align="left"
107
+ testId="sysmon-sort-name"
108
+ />
109
+ <SortableHeader label="CPU" field="cpu" activeKey={sortKey} activeDir={sortDir} onClick={onSort} testId="sysmon-sort-cpu" />
110
+ <SortableHeader label="RAM" field="ram" activeKey={sortKey} activeDir={sortDir} onClick={onSort} testId="sysmon-sort-ram" />
111
+ {grid.columns.disk && (
112
+ <SortableHeader
113
+ label="Disk"
114
+ field="disk"
115
+ activeKey={sortKey}
116
+ activeDir={sortDir}
117
+ onClick={onSort}
118
+ testId="sysmon-col-disk"
119
+ className={optionalCellClassName(grid, "disk")}
120
+ />
121
+ )}
122
+ {grid.columns.gpu && (
123
+ <SortableHeader
124
+ label="GPU"
125
+ field="gpu"
126
+ activeKey={sortKey}
127
+ activeDir={sortDir}
128
+ onClick={onSort}
129
+ testId="sysmon-col-gpu"
130
+ className={optionalCellClassName(grid, "gpu")}
131
+ />
132
+ )}
133
+ {grid.columns.net && (
134
+ <SortableHeader
135
+ label="Net"
136
+ field="net"
137
+ activeKey={sortKey}
138
+ activeDir={sortDir}
139
+ onClick={onSort}
140
+ testId="sysmon-col-net"
141
+ className={optionalCellClassName(grid, "net")}
142
+ />
143
+ )}
144
+ <span className="text-right hidden @lg:block">Trend</span>
145
+ <span />
146
+ </div>
147
+ );
148
+ }
149
+
150
+ export interface ProcessTableFooterProps {
151
+ totals: Totals;
152
+ grid: ProcessGridResult;
153
+ /** `system.gpus[0]?.utilPercent` — a whole-machine reading, not a sum of the
154
+ * visible rows' `gpuPct` (per-process GPU% can double-count shared engines). */
155
+ gpuUtilPercent?: number;
156
+ }
157
+
158
+ export function ProcessTableFooter({ totals, grid, gpuUtilPercent }: ProcessTableFooterProps) {
159
+ return (
160
+ <div
161
+ className={cn(
162
+ "grid gap-1 px-3 py-1.5 text-xs font-medium border-t border-border shrink-0",
163
+ PROCESS_ROW_GRID_CLASS,
164
+ )}
165
+ data-testid="sysmon-total"
166
+ data-process-count={totals.count}
167
+ >
168
+ <span className="truncate">Total ({totals.count} processes)</span>
169
+ <span className={cn("text-right", cpuColor(totals.cpu))}>{totals.cpu.toFixed(1)}%</span>
170
+ <span className="text-right text-text-secondary">{formatRam(totals.ramMB)}</span>
171
+ {grid.columns.disk && (
172
+ <span className={cn("text-right text-text-secondary tabular-nums truncate", optionalCellClassName(grid, "disk"))}>
173
+ {formatDiskCell(totals.diskReadBps, totals.diskWriteBps)}
174
+ </span>
175
+ )}
176
+ {grid.columns.gpu && (
177
+ <span className={cn("text-right text-text-secondary tabular-nums truncate", optionalCellClassName(grid, "gpu"))}>
178
+ {formatGpuCell(gpuUtilPercent, totals.gpuMemMB)}
179
+ </span>
180
+ )}
181
+ {grid.columns.net && (
182
+ <span className={cn("text-right text-text-secondary tabular-nums truncate", optionalCellClassName(grid, "net"))}>
183
+ {formatNetCell(totals.netInBps, totals.netOutBps)}
184
+ </span>
185
+ )}
186
+ <span className="hidden @lg:block" />
187
+ <span />
188
+ </div>
189
+ );
190
+ }
@@ -0,0 +1,49 @@
1
+ /** Footer totals accumulator, split out of `process-table-model.ts` to keep
2
+ * that file under the repo's 200-line guideline. Pure, no React/I/O. */
3
+
4
+ export interface Totals {
5
+ cpu: number;
6
+ ramMB: number;
7
+ count: number;
8
+ /** Sums over rows with a defined value; `undefined` when NO visible row measured
9
+ * that metric — mirrors the "undefined = host can't measure" rule on ProcessInfo. */
10
+ diskReadBps?: number;
11
+ diskWriteBps?: number;
12
+ gpuMemMB?: number;
13
+ netInBps?: number;
14
+ netOutBps?: number;
15
+ }
16
+
17
+ export const EMPTY_TOTALS: Totals = { cpu: 0, ramMB: 0, count: 0 };
18
+
19
+ /** Adds an optional metric into a running total; stays `undefined` until at
20
+ * least one contributor has a defined value (mirrors the roll-up rule). */
21
+ function addOptional(sum: number | undefined, value: number | undefined): number | undefined {
22
+ if (value === undefined) return sum;
23
+ return (sum ?? 0) + value;
24
+ }
25
+
26
+ export function accumulateTotals(
27
+ acc: Totals,
28
+ item: {
29
+ cpu: number;
30
+ ramMB: number;
31
+ diskReadBps?: number;
32
+ diskWriteBps?: number;
33
+ gpuMemMB?: number;
34
+ netInBps?: number;
35
+ netOutBps?: number;
36
+ },
37
+ countDelta: number,
38
+ ): Totals {
39
+ return {
40
+ cpu: acc.cpu + item.cpu,
41
+ ramMB: acc.ramMB + item.ramMB,
42
+ count: acc.count + countDelta,
43
+ diskReadBps: addOptional(acc.diskReadBps, item.diskReadBps),
44
+ diskWriteBps: addOptional(acc.diskWriteBps, item.diskWriteBps),
45
+ gpuMemMB: addOptional(acc.gpuMemMB, item.gpuMemMB),
46
+ netInBps: addOptional(acc.netInBps, item.netInBps),
47
+ netOutBps: addOptional(acc.netOutBps, item.netOutBps),
48
+ };
49
+ }
@@ -0,0 +1,187 @@
1
+ import { useCallback, useMemo, useRef, useState } from "react";
2
+ import { useVirtualizer } from "@tanstack/react-virtual";
3
+ import { toast } from "sonner";
4
+ import { getAuthToken } from "@/lib/api-client";
5
+ import { useIsMobile } from "@/hooks/use-is-mobile";
6
+ import { buildRows, toggleSort } from "./process-table-model";
7
+ import { buildKillRequest } from "./build-kill-request";
8
+ import { buildProcessGrid, gridCssVars } from "./process-columns-grid";
9
+ import { ProcessTableToolbar, ProcessTableHeader, ProcessTableFooter } from "./process-table-toolbar";
10
+ import { ProcessGroupRow } from "./process-group-row";
11
+ import { ProcessRow } from "./process-row";
12
+ import { KillConfirmDialog } from "./kill-confirm-dialog";
13
+ import type {
14
+ KillProcessRequest,
15
+ KillProcessResult,
16
+ MetricsHistoryPoint,
17
+ MetricsSnapshot,
18
+ ProcessInfo,
19
+ SortDir,
20
+ SortKey,
21
+ } from "../../../types/system-metrics";
22
+
23
+ /** Older cached bundles/snapshots (mid-rollout) predate `processColumns` — default
24
+ * every optional column off rather than let a missing field throw. */
25
+ const NO_OPTIONAL_COLUMNS = { disk: false, gpu: false, net: false };
26
+
27
+ export interface ProcessTableProps {
28
+ snapshot: MetricsSnapshot;
29
+ history: MetricsHistoryPoint[];
30
+ }
31
+
32
+ /** `api.post` (src/web/lib/api-client.ts) has no way to add a bespoke header, and the
33
+ * kill route requires `X-PPM-Request: 1` — CSRF hardening, since a cross-origin HTML
34
+ * form cannot set a custom header, so a preflight becomes mandatory. A raw fetch here
35
+ * mirrors `handleResponse`'s single-Error-on-any-failure contract exactly, so the
36
+ * caller still has exactly one catch path. */
37
+ async function killProcess(request: KillProcessRequest): Promise<KillProcessResult> {
38
+ const token = getAuthToken();
39
+ const headers: Record<string, string> = {
40
+ "Content-Type": "application/json",
41
+ "X-PPM-Request": "1",
42
+ };
43
+ if (token) headers.Authorization = `Bearer ${token}`;
44
+
45
+ const res = await fetch("/api/system/resources/kill", {
46
+ method: "POST",
47
+ headers,
48
+ body: JSON.stringify(request),
49
+ });
50
+
51
+ let json: { ok: boolean; data?: KillProcessResult; error?: string };
52
+ try {
53
+ json = await res.json();
54
+ } catch {
55
+ throw new Error(res.ok ? "Empty response from server" : `Server error (HTTP ${res.status})`);
56
+ }
57
+ if (json.ok === false) throw new Error(json.error ?? `HTTP ${res.status}`);
58
+ return json.data as KillProcessResult;
59
+ }
60
+
61
+ export function ProcessTable({ snapshot, history }: ProcessTableProps) {
62
+ const isMobile = useIsMobile();
63
+ const parentRef = useRef<HTMLDivElement>(null);
64
+
65
+ const [mode, setMode] = useState<"grouped" | "flat">("grouped");
66
+ const [ppmOnly, setPpmOnly] = useState(false);
67
+ const [query, setQuery] = useState("");
68
+ const [sortKey, setSortKey] = useState<SortKey>(null);
69
+ const [sortDir, setSortDir] = useState<SortDir>("desc");
70
+ const [expanded, setExpanded] = useState<Set<string>>(() => new Set());
71
+ const [pendingKill, setPendingKill] = useState<ProcessInfo | null>(null);
72
+
73
+ const { rows, totals } = useMemo(
74
+ () =>
75
+ buildRows({
76
+ processes: snapshot.processes,
77
+ groups: snapshot.groups,
78
+ history,
79
+ mode,
80
+ ppmOnly,
81
+ query,
82
+ sortKey,
83
+ sortDir,
84
+ expanded,
85
+ }),
86
+ [snapshot.processes, snapshot.groups, history, mode, ppmOnly, query, sortKey, sortDir, expanded],
87
+ );
88
+
89
+ const columns = snapshot.processColumns ?? NO_OPTIONAL_COLUMNS;
90
+ const grid = useMemo(() => buildProcessGrid(columns, sortKey), [columns, sortKey]);
91
+ const gpuUtilPercent = snapshot.system.gpus[0]?.utilPercent;
92
+
93
+ const virtualizer = useVirtualizer({
94
+ count: rows.length,
95
+ getScrollElement: () => parentRef.current,
96
+ estimateSize: () => (isMobile ? 44 : 28),
97
+ overscan: 12,
98
+ });
99
+
100
+ const handleSort = useCallback(
101
+ (field: Exclude<SortKey, null>) => {
102
+ const [nextKey, nextDir] = toggleSort(sortKey, sortDir, field);
103
+ setSortKey(nextKey);
104
+ setSortDir(nextDir);
105
+ },
106
+ [sortKey, sortDir],
107
+ );
108
+
109
+ const handleToggleGroup = useCallback((key: string) => {
110
+ setExpanded((prev) => {
111
+ const next = new Set(prev);
112
+ if (next.has(key)) next.delete(key);
113
+ else next.add(key);
114
+ return next;
115
+ });
116
+ }, []);
117
+
118
+ const handleConfirmKill = useCallback(async (proc: ProcessInfo, tree: boolean) => {
119
+ setPendingKill(null);
120
+ try {
121
+ await killProcess(buildKillRequest(proc, tree));
122
+ toast.success(`Ended ${proc.name} (${proc.pid})`);
123
+ } catch (e) {
124
+ toast.error(e instanceof Error ? e.message : `Failed to end ${proc.name}`);
125
+ }
126
+ }, []);
127
+
128
+ // `@container`: the trend/age track is toggled on the table's own width, not the
129
+ // viewport — a floating window is routinely narrower than the screen it sits on.
130
+ // `gridCssVars` sets `--sysmon-grid-n`/`--sysmon-grid-w` once here; CSS custom
131
+ // properties inherit to every row/header/footer below without re-passing style.
132
+ return (
133
+ <div
134
+ className="h-full flex flex-col min-h-0 @container"
135
+ style={gridCssVars(grid)}
136
+ data-testid="sysmon-processes"
137
+ data-row-count={rows.length}
138
+ >
139
+ <ProcessTableToolbar
140
+ mode={mode}
141
+ onModeChange={setMode}
142
+ ppmOnly={ppmOnly}
143
+ onPpmOnlyChange={setPpmOnly}
144
+ onQueryChange={setQuery}
145
+ />
146
+ <ProcessTableHeader sortKey={sortKey} sortDir={sortDir} grid={grid} onSort={handleSort} />
147
+ <div ref={parentRef} className="flex-1 min-h-0 overflow-y-auto">
148
+ <div style={{ height: virtualizer.getTotalSize(), position: "relative" }}>
149
+ {virtualizer.getVirtualItems().map((item) => {
150
+ const row = rows[item.index];
151
+ if (!row) return null;
152
+ return (
153
+ <div
154
+ key={row.kind === "group" ? row.group.key : `p:${row.proc.pid}`}
155
+ style={{
156
+ position: "absolute",
157
+ top: 0,
158
+ left: 0,
159
+ right: 0,
160
+ transform: `translateY(${item.start}px)`,
161
+ }}
162
+ >
163
+ {row.kind === "group" ? (
164
+ <ProcessGroupRow
165
+ group={row.group}
166
+ expanded={row.expanded}
167
+ spark={row.spark}
168
+ grid={grid}
169
+ onToggle={handleToggleGroup}
170
+ />
171
+ ) : (
172
+ <ProcessRow proc={row.proc} indent={row.indent} grid={grid} onKillClick={setPendingKill} />
173
+ )}
174
+ </div>
175
+ );
176
+ })}
177
+ </div>
178
+ </div>
179
+ <ProcessTableFooter totals={totals} grid={grid} gpuUtilPercent={gpuUtilPercent} />
180
+ <KillConfirmDialog
181
+ process={pendingKill}
182
+ onConfirm={handleConfirmKill}
183
+ onCancel={() => setPendingKill(null)}
184
+ />
185
+ </div>
186
+ );
187
+ }
@@ -0,0 +1,29 @@
1
+ /** Pure viewport-routing decision for the System Monitor open-hook — split out from
2
+ * `use-open-system-monitor.ts` so it has zero runtime imports (only a type-only one,
3
+ * fully erased) and is unit-testable without mounting zustand stores. */
4
+ import type { Tab } from "@/stores/tab-store";
5
+
6
+ export type OpenSystemMonitorAction =
7
+ | { kind: "tab"; tab: Omit<Tab, "id"> }
8
+ | { kind: "window" }
9
+ | { kind: "focus"; id: string };
10
+
11
+ /**
12
+ * There is exactly one machine, so unlike `"explorer"`/`"team-member"` (legitimately
13
+ * multi-instance — different payload, different folder/teammate), a second
14
+ * `"system-monitor"` window is never a distinct instance, only a duplicate. When one
15
+ * is already open, focus it instead of spawning another.
16
+ */
17
+ export function resolveOpenSystemMonitorAction(
18
+ isMobile: boolean,
19
+ existingWindowId: string | null,
20
+ ): OpenSystemMonitorAction {
21
+ if (isMobile) {
22
+ return {
23
+ kind: "tab",
24
+ tab: { type: "system-monitor", title: "System Monitor", projectId: null, closable: true },
25
+ };
26
+ }
27
+ if (existingWindowId) return { kind: "focus", id: existingWindowId };
28
+ return { kind: "window" };
29
+ }
@@ -1,9 +1,9 @@
1
1
  import { memo } from "react";
2
2
  import { Cpu } from "lucide-react";
3
3
  import { useResourceMonitor } from "@/hooks/use-resource-monitor";
4
- import { useTabStore } from "@/stores/tab-store";
5
4
  import { useIsMobile } from "@/hooks/use-is-mobile";
6
5
  import { cn } from "@/lib/utils";
6
+ import { useOpenSystemMonitor } from "./use-open-system-monitor";
7
7
 
8
8
  function cpuColor(cpu: number) {
9
9
  if (cpu > 80) return "text-error";
@@ -11,26 +11,21 @@ function cpuColor(cpu: number) {
11
11
  return "text-success";
12
12
  }
13
13
 
14
- /** `compact` renders inline for the 22px status bar (no full-width button, CPU+MEM only). */
14
+ /** `compact` renders inline for the 22px status bar (no full-width button, CPU+MEM only).
15
+ * Stays on the light SSE tier — never opts into `{processes:true}` — so it never pays
16
+ * for the full collector just to render two numbers. */
15
17
  export const ResourceStatusBar = memo(function ResourceStatusBar({ compact = false }: { compact?: boolean }) {
16
18
  const { latest, isConnected } = useResourceMonitor();
17
- const openTab = useTabStore((s) => s.openTab);
19
+ const openSystemMonitor = useOpenSystemMonitor();
18
20
  const isMobile = useIsMobile();
19
21
 
20
- const handleClick = () => {
21
- openTab({
22
- type: "system-monitor",
23
- title: "System Monitor",
24
- projectId: null,
25
- closable: true,
26
- });
27
- };
28
-
29
22
  if (!isConnected || !latest) {
30
23
  if (compact) return null; // stay silent in the status bar until connected
31
24
  return (
32
25
  <button
33
- onClick={handleClick}
26
+ onClick={openSystemMonitor}
27
+ data-testid="status-bar-resources"
28
+ aria-label="Open System Monitor"
34
29
  className="flex items-center gap-1.5 px-2 py-1 text-[10px] text-text-subtle hover:text-text-secondary transition-colors w-full"
35
30
  >
36
31
  <Cpu className="size-3 opacity-50" />
@@ -39,14 +34,18 @@ export const ResourceStatusBar = memo(function ResourceStatusBar({ compact = fal
39
34
  );
40
35
  }
41
36
 
42
- const { cpu, ramMB, processCount } = latest.total;
37
+ const cpu = latest.system.cpu.total;
38
+ const ramMB = latest.system.mem.usedMB;
39
+ const processCount = latest.system.processCount;
43
40
  const mem = ramMB < 1024 ? `${ramMB.toFixed(0)}M` : `${(ramMB / 1024).toFixed(1)}G`;
44
41
 
45
42
  if (compact) {
46
43
  // Inline segment for the 22px status bar: CPU % · MEM (handoff B2 right cluster).
47
44
  return (
48
45
  <button
49
- onClick={handleClick}
46
+ onClick={openSystemMonitor}
47
+ data-testid="status-bar-resources"
48
+ aria-label="Open System Monitor"
50
49
  className="flex items-center gap-2 px-1 rounded-sm hover:bg-accent/15 transition-colors cursor-pointer"
51
50
  title="Open System Monitor"
52
51
  >
@@ -58,7 +57,9 @@ export const ResourceStatusBar = memo(function ResourceStatusBar({ compact = fal
58
57
 
59
58
  return (
60
59
  <button
61
- onClick={handleClick}
60
+ onClick={openSystemMonitor}
61
+ data-testid="status-bar-resources"
62
+ aria-label="Open System Monitor"
62
63
  className="flex items-center gap-1.5 px-2 py-1 text-[10px] hover:bg-surface-hover transition-colors w-full cursor-pointer"
63
64
  title="Open System Monitor"
64
65
  >
@@ -0,0 +1,65 @@
1
+ import { ArrowUp, ArrowDown } from "lucide-react";
2
+ import { cn } from "@/lib/utils";
3
+ import type { SortDir, SortKey } from "../../../types/system-metrics";
4
+
5
+ /** Sortable column header shared by the process table toolbar, salvaged from
6
+ * the deleted `system-monitor-group-row.tsx`. Renders as a `columnheader` `<div>`,
7
+ * not a `<th>` — the parent row is a CSS-grid `<div role="row">`, and a `<th>`
8
+ * inside a non-table ancestor both triggers React's DOM-nesting warning and makes
9
+ * `aria-sort` meaningless to assistive tech outside an actual table. */
10
+ export function SortableHeader({
11
+ label,
12
+ field,
13
+ activeKey,
14
+ activeDir,
15
+ onClick,
16
+ align = "right",
17
+ testId,
18
+ className,
19
+ }: {
20
+ label: string;
21
+ field: Exclude<SortKey, null>;
22
+ activeKey: SortKey;
23
+ activeDir: SortDir;
24
+ onClick: (field: Exclude<SortKey, null>) => void;
25
+ /** Text/justify alignment — the "Process" column is left-aligned over the name
26
+ * cell, every numeric column stays right-aligned. */
27
+ align?: "left" | "right";
28
+ testId?: string;
29
+ /** Extra classes on the outer `columnheader` — e.g. the `hidden @lg:block`
30
+ * visibility rule an optional (Disk/GPU/Net) column needs below `@lg`. */
31
+ className?: string;
32
+ }) {
33
+ const isActive = activeKey === field;
34
+ const Arrow = isActive ? (activeDir === "asc" ? ArrowUp : ArrowDown) : null;
35
+ const ariaSort = isActive ? (activeDir === "asc" ? "ascending" : "descending") : "none";
36
+
37
+ return (
38
+ <div
39
+ role="columnheader"
40
+ aria-sort={ariaSort}
41
+ className={cn(
42
+ "py-1.5 px-2 font-medium select-none",
43
+ align === "left" ? "text-left" : "text-right",
44
+ className,
45
+ )}
46
+ >
47
+ {/* The test id sits on the interactive element: a synthetic `click()` on the
48
+ wrapper never reaches the button (events bubble up, not down), so a harness
49
+ targeting the div would silently not sort. */}
50
+ <button
51
+ type="button"
52
+ data-testid={testId}
53
+ onClick={() => onClick(field)}
54
+ className={cn(
55
+ "flex items-center gap-0.5 w-full min-h-11 md:min-h-0 cursor-pointer hover:text-text-primary transition-colors",
56
+ align === "left" ? "justify-start" : "justify-end",
57
+ isActive && "text-text-primary",
58
+ )}
59
+ >
60
+ <span>{label}</span>
61
+ {Arrow && <Arrow className="size-3" />}
62
+ </button>
63
+ </div>
64
+ );
65
+ }
@@ -1,10 +1,14 @@
1
1
  import { useRef, useEffect, memo } from "react";
2
+ import { resolveScaleMax, resolveCssColor } from "./chart-scale";
2
3
 
3
4
  interface SparklineCanvasProps {
4
5
  data: number[];
5
6
  width?: number;
6
7
  height?: number;
7
8
  color?: string;
9
+ /** Fixed scale ceiling (e.g. 100 for a percentage axis). Omitted = autoscale to
10
+ * the max of the visible window, same as before. */
11
+ maxValue?: number;
8
12
  }
9
13
 
10
14
  export const SparklineCanvas = memo(function SparklineCanvas({
@@ -12,16 +16,11 @@ export const SparklineCanvas = memo(function SparklineCanvas({
12
16
  width = 120,
13
17
  height = 24,
14
18
  color = "var(--color-primary)",
19
+ maxValue,
15
20
  }: SparklineCanvasProps) {
16
21
  const canvasRef = useRef<HTMLCanvasElement>(null);
17
- const lastDrawRef = useRef(0);
18
22
 
19
23
  useEffect(() => {
20
- const now = Date.now();
21
- // Throttle redraws to 1fps
22
- if (now - lastDrawRef.current < 1000) return;
23
- lastDrawRef.current = now;
24
-
25
24
  const canvas = canvasRef.current;
26
25
  if (!canvas || data.length < 2) return;
27
26
 
@@ -35,13 +34,13 @@ export const SparklineCanvas = memo(function SparklineCanvas({
35
34
 
36
35
  ctx.clearRect(0, 0, width, height);
37
36
 
38
- const max = Math.max(...data, 1);
37
+ const max = resolveScaleMax(data, maxValue);
39
38
  const stepX = width / (data.length - 1);
40
39
  const padding = 2;
41
40
  const drawH = height - padding * 2;
42
41
 
43
42
  ctx.beginPath();
44
- ctx.strokeStyle = color;
43
+ ctx.strokeStyle = resolveCssColor(color, getComputedStyle(canvas));
45
44
  ctx.lineWidth = 1.5;
46
45
  ctx.lineJoin = "round";
47
46
 
@@ -52,7 +51,7 @@ export const SparklineCanvas = memo(function SparklineCanvas({
52
51
  else ctx.lineTo(x, y);
53
52
  }
54
53
  ctx.stroke();
55
- }, [data, width, height, color]);
54
+ }, [data, width, height, color, maxValue]);
56
55
 
57
56
  return (
58
57
  <canvas