@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,84 @@
1
+ /**
2
+ * Which pids the kill guard must never end: the PPM server, its supervisor (or
3
+ * plain parent), the edge forwarder, the app share tunnel and every per-port
4
+ * preview tunnel PPM spawned.
5
+ *
6
+ * `status.json` is unvalidated disk state — `supervisorPid` is only cleared by
7
+ * a fresh supervisor start, `bun dev:server` has no supervisor at all, and dev
8
+ * and prod share `~/.ppm`. So every candidate is dropped unless it is alive
9
+ * right now, and a cloudflared candidate must also carry the cloudflared image
10
+ * name (a spoofed command line cannot buy protection). A dead or recycled
11
+ * `supervisorPid` therefore counts as absent and the real parent is protected.
12
+ */
13
+ import { readStatus } from "../supervisor-state.ts";
14
+ import { activeTunnels } from "../../server/routes/tunnel-spawn.ts";
15
+
16
+ export interface ProtectedPidsInput {
17
+ status: Record<string, unknown>;
18
+ selfPid: number;
19
+ parentPid: number;
20
+ /** Extra cloudflared pids PPM spawned itself (per-port preview tunnels). */
21
+ portTunnelPids: readonly number[];
22
+ isAlive: (pid: number) => boolean;
23
+ /** Lowercased, extension-free image name for a live pid, or undefined. */
24
+ nameOf: (pid: number) => string | undefined;
25
+ }
26
+
27
+ export interface ProtectedPids {
28
+ /** Everything the kill guard refuses outright. */
29
+ pids: Set<number>;
30
+ /** PPM's own roots: server + supervisor/parent. Grouping boundaries and the
31
+ * seeds of the `ppm` ownership walk. */
32
+ roots: Set<number>;
33
+ /** This server's own pid — lets the UI tell "this server" from another PPM
34
+ * instance on the same machine (dev next to prod). */
35
+ selfPid: number;
36
+ }
37
+
38
+ function pidOf(v: unknown): number | null {
39
+ return typeof v === "number" && Number.isInteger(v) && v > 0 ? v : null;
40
+ }
41
+
42
+ /** Images a PPM supervisor / edge forwarder can run as: the Bun runtime, Node,
43
+ * or the compiled single binary. A live pid with any other image is a
44
+ * recycled `status.json` entry, not PPM. */
45
+ const PPM_IMAGE_NAMES: ReadonlySet<string> = new Set(["bun", "node", "ppm"]);
46
+
47
+ export function resolveProtectedPids(input: ProtectedPidsInput): ProtectedPids {
48
+ const { status, isAlive, nameOf } = input;
49
+ const roots = new Set<number>([input.selfPid]);
50
+ const isPpmImage = (pid: number) => isAlive(pid) && PPM_IMAGE_NAMES.has(nameOf(pid) ?? "");
51
+ const cloudflared = (pid: number) => isAlive(pid) && nameOf(pid) === "cloudflared";
52
+
53
+ const supervisor = pidOf(status.supervisorPid);
54
+ if (supervisor !== null && isPpmImage(supervisor)) roots.add(supervisor);
55
+ else if (input.parentPid > 0 && isAlive(input.parentPid)) roots.add(input.parentPid);
56
+
57
+ const pids = new Set<number>(roots);
58
+
59
+ const edge = pidOf(status.edgePid);
60
+ if (edge !== null && isPpmImage(edge)) pids.add(edge);
61
+
62
+ const tunnel = pidOf(status.tunnelPid);
63
+ if (tunnel !== null && cloudflared(tunnel)) pids.add(tunnel);
64
+ for (const pid of input.portTunnelPids) {
65
+ if (pid > 0 && cloudflared(pid)) pids.add(pid);
66
+ }
67
+
68
+ return { pids, roots, selfPid: input.selfPid };
69
+ }
70
+
71
+ /** Live-state wrapper: reads `status.json` and the preview-tunnel registry. */
72
+ export function resolveProtectedPidsLive(
73
+ isAlive: (pid: number) => boolean,
74
+ nameOf: (pid: number) => string | undefined,
75
+ ): ProtectedPids {
76
+ return resolveProtectedPids({
77
+ status: readStatus(),
78
+ selfPid: process.pid,
79
+ parentPid: process.ppid,
80
+ portTunnelPids: [...activeTunnels.values()].map((t) => t.pid),
81
+ isAlive,
82
+ nameOf,
83
+ });
84
+ }
@@ -0,0 +1,141 @@
1
+ /**
2
+ * macOS process collector via `ps` (cheap there, no leak, no `/proc`).
3
+ *
4
+ * Every tick: `pid ppid etime time rss comm` with `comm` LAST because on macOS
5
+ * it is the full executable path and may contain spaces ("Google Chrome").
6
+ * Every 30 s: `pid args` for command lines, merged by pid — the same slow
7
+ * cadence Windows uses for `CommandLine`, and it keeps the per-tick call to one
8
+ * `ps` whose columns can be parsed unambiguously.
9
+ * UNVERIFIED on real macOS hardware; a parse miss yields a warning, never garbage.
10
+ */
11
+ import type { Runner } from "../host-info/spawn-runner.ts";
12
+ import { defaultRunner } from "../host-info/spawn-runner.ts";
13
+ import type { ProcessCollection, ProcessCollector, RawProcessRow } from "./process-collector-types.ts";
14
+ import { createStickyColumns } from "./process-collector-types.ts";
15
+ import type { ProcessNetCollector } from "./process-net-collector-darwin.ts";
16
+
17
+ export const DARWIN_TICK_ARGV = ["ps", "-Ao", "pid=,ppid=,etime=,time=,rss=,comm="];
18
+ export const DARWIN_ARGS_ARGV = ["ps", "-Ao", "pid=,args="];
19
+ export const DARWIN_ARGS_REFRESH_MS = 30_000;
20
+ const PS_TIMEOUT_MS = 5000;
21
+
22
+ /** `[[dd-]hh:]mm:ss[.cs]` → milliseconds; NaN-free (garbage → 0). */
23
+ export function parsePsCpuTime(text: string): number {
24
+ const m = /^(?:(\d+)-)?(?:(\d+):)?(\d+):(\d+(?:\.\d+)?)$/.exec(text.trim());
25
+ if (!m) return 0;
26
+ const days = Number(m[1] ?? 0);
27
+ const hours = Number(m[2] ?? 0);
28
+ const minutes = Number(m[3]);
29
+ const seconds = Number(m[4]);
30
+ const total = ((days * 24 + hours) * 60 + minutes) * 60 + seconds;
31
+ return Number.isFinite(total) ? Math.round(total * 1000) : 0;
32
+ }
33
+
34
+ const TICK_LINE = /^\s*(\d+)\s+(\d+)\s+(\S+)\s+(\S+)\s+(\d+)\s+(.*)$/;
35
+
36
+ export function parseDarwinPsTick(text: string, now: number): RawProcessRow[] {
37
+ const rows: RawProcessRow[] = [];
38
+ for (const line of text.split("\n")) {
39
+ const m = TICK_LINE.exec(line);
40
+ if (!m) continue;
41
+ const pid = Number(m[1]);
42
+ if (pid <= 0) continue;
43
+ const elapsedMs = parsePsCpuTime(m[3]!);
44
+ const comm = m[6]!.trim();
45
+ rows.push({
46
+ pid,
47
+ ppid: Number(m[2]),
48
+ name: comm.slice(comm.lastIndexOf("/") + 1) || comm || String(pid),
49
+ command: null,
50
+ cpuMs: parsePsCpuTime(m[4]!),
51
+ ramMB: Number(m[5]) / 1024,
52
+ // etime is 1 s resolution: coarse, but enough as an identity guard.
53
+ startedAt: elapsedMs > 0 ? Math.round((now - elapsedMs) / 1000) * 1000 : 0,
54
+ });
55
+ }
56
+ return rows;
57
+ }
58
+
59
+ export function parseDarwinPsArgs(text: string): Map<number, string> {
60
+ const out = new Map<number, string>();
61
+ for (const line of text.split("\n")) {
62
+ const m = /^\s*(\d+)\s+(.+)$/.exec(line);
63
+ if (m) out.set(Number(m[1]), m[2]!.trim());
64
+ }
65
+ return out;
66
+ }
67
+
68
+ /**
69
+ * `etime` ticks in whole seconds while `now` has ms, so `now - etime` jitters by
70
+ * up to a second between ticks. Pin each pid to the first value seen so the CPU
71
+ * delta key `${pid}:${startedAt}` stays stable; a jump beyond the jitter means
72
+ * the pid really was recycled.
73
+ */
74
+ export function stabilizeStartedAt(rows: RawProcessRow[], memo: Map<number, number>): RawProcessRow[] {
75
+ const seen = new Set<number>();
76
+ for (const r of rows) {
77
+ seen.add(r.pid);
78
+ const cached = memo.get(r.pid);
79
+ if (cached !== undefined && Math.abs(cached - r.startedAt) <= 2000) r.startedAt = cached;
80
+ else memo.set(r.pid, r.startedAt);
81
+ }
82
+ for (const pid of memo.keys()) if (!seen.has(pid)) memo.delete(pid);
83
+ return rows;
84
+ }
85
+
86
+ export interface DarwinProcessCollectorOptions {
87
+ /** Omitted or null → no per-process network sample. The production wiring in
88
+ * `system-metrics-platform.ts` injects it, so a unit test never spawns
89
+ * `nettop` by accident. */
90
+ net?: ProcessNetCollector | null;
91
+ }
92
+
93
+ export function createDarwinProcessCollector(
94
+ run: Runner = defaultRunner,
95
+ now: () => number = Date.now,
96
+ opts: DarwinProcessCollectorOptions = {},
97
+ ): ProcessCollector {
98
+ let argsByPid = new Map<number, string>();
99
+ let lastArgsAt = Number.NEGATIVE_INFINITY;
100
+ const startedAtMemo = new Map<number, number>();
101
+ const net = opts.net ?? null;
102
+ const observeColumns = createStickyColumns();
103
+
104
+ return {
105
+ stop: () => {},
106
+ async collect(): Promise<ProcessCollection> {
107
+ const warnings: string[] = [];
108
+ const tick = await run(DARWIN_TICK_ARGV, PS_TIMEOUT_MS);
109
+ if (tick.code !== 0 || tick.timedOut) {
110
+ return {
111
+ rows: [],
112
+ columns: observeColumns({}),
113
+ warnings: [`Process list unavailable: ps exited ${tick.code ?? "on timeout"}`],
114
+ };
115
+ }
116
+ const t = now();
117
+ if (t - lastArgsAt >= DARWIN_ARGS_REFRESH_MS) {
118
+ const args = await run(DARWIN_ARGS_ARGV, PS_TIMEOUT_MS);
119
+ if (args.code === 0 && !args.timedOut) {
120
+ argsByPid = parseDarwinPsArgs(args.stdout);
121
+ lastArgsAt = t;
122
+ } else {
123
+ warnings.push("Command lines unavailable: ps args query failed");
124
+ }
125
+ }
126
+ const netByPid = (await net?.collect()) ?? null;
127
+ const rows = stabilizeStartedAt(parseDarwinPsTick(tick.stdout, t), startedAtMemo)
128
+ .map((r) => ({
129
+ ...r,
130
+ command: argsByPid.get(r.pid) ?? null,
131
+ // nettop lists only processes with sockets, so a missing pid means
132
+ // "measured, no traffic".
133
+ netInBytes: netByPid ? netByPid.get(r.pid)?.inBytes ?? 0 : undefined,
134
+ netOutBytes: netByPid ? netByPid.get(r.pid)?.outBytes ?? 0 : undefined,
135
+ }));
136
+ if (rows.length === 0) warnings.push("Process list unavailable: ps output did not parse");
137
+ // Disk and GPU have no per-process source on macOS without private APIs.
138
+ return { rows, columns: observeColumns({ net: netByPid !== null }), warnings };
139
+ },
140
+ };
141
+ }
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Linux process collector over `/proc` — zero subprocesses for the table and
3
+ * the per-process disk counters. Reuses the repo's `readProcTable()`, which
4
+ * already anchors the `/proc/<pid>/stat` parse on the last `)` so a process
5
+ * name containing spaces cannot shift the fields.
6
+ *
7
+ * Per-process VRAM needs the one `nvidia-smi` call; per-process GPU busy % has
8
+ * no unprivileged source at all, so `gpuPct` stays undefined here.
9
+ */
10
+ import { readProcTable, type ProcEntry } from "../proc-table-linux.ts";
11
+ import type { ProcessCollection, ProcessCollector, RawProcessRow } from "./process-collector-types.ts";
12
+ import { createStickyColumns } from "./process-collector-types.ts";
13
+ import { readProcIoBytes, type ProcIoBytes } from "./process-io-linux.ts";
14
+ import type { ProcessGpuMemoryCollector } from "./gpu-process-memory-nvidia.ts";
15
+
16
+ const KB_PER_MB = 1024;
17
+
18
+ export function procEntriesToRows(entries: readonly ProcEntry[]): RawProcessRow[] {
19
+ const rows: RawProcessRow[] = [];
20
+ for (const e of entries) {
21
+ if (e.pid <= 0) continue;
22
+ rows.push({
23
+ pid: e.pid,
24
+ ppid: e.ppid >= 0 ? e.ppid : -1,
25
+ name: e.comm,
26
+ // Kernel threads have an empty cmdline; the tick falls back to the name.
27
+ command: e.args || null,
28
+ cpuMs: e.cpuMs,
29
+ ramMB: e.rssKB / KB_PER_MB,
30
+ startedAt: Number.isFinite(e.startedAtMs) && e.startedAtMs > 0 ? Math.round(e.startedAtMs) : 0,
31
+ });
32
+ }
33
+ return rows;
34
+ }
35
+
36
+ export interface LinuxProcessCollectorOptions {
37
+ /** Injected so unit tests never touch a real `/proc`. */
38
+ readIo?: (pid: number) => ProcIoBytes | null;
39
+ /** Omitted or null → no per-process VRAM query at all. The production wiring
40
+ * in `system-metrics-platform.ts` injects it; defaulting to a real collector
41
+ * here would make an innocent unit test spawn `nvidia-smi`. */
42
+ gpuMemory?: ProcessGpuMemoryCollector | null;
43
+ }
44
+
45
+ export function createLinuxProcessCollector(
46
+ readTable: () => ProcEntry[] | null = readProcTable,
47
+ opts: LinuxProcessCollectorOptions = {},
48
+ ): ProcessCollector {
49
+ const readIo = opts.readIo ?? readProcIoBytes;
50
+ const gpuMemory = opts.gpuMemory ?? null;
51
+ const observeColumns = createStickyColumns();
52
+
53
+ return {
54
+ stop: () => {},
55
+ async collect(): Promise<ProcessCollection> {
56
+ const table = readTable();
57
+ if (!table) {
58
+ return { rows: [], columns: observeColumns({}), warnings: ["Process list unavailable: /proc is not readable"] };
59
+ }
60
+ const gpuMemByPid = (await gpuMemory?.collect()) ?? null;
61
+
62
+ let anyIo = false;
63
+ const rows = procEntriesToRows(table).map((r) => {
64
+ // EACCES for another user's process is expected, not an error: that row
65
+ // simply has no disk figures.
66
+ const io = readIo(r.pid);
67
+ if (io) anyIo = true;
68
+ return {
69
+ ...r,
70
+ diskReadBytes: io?.readBytes,
71
+ diskWriteBytes: io?.writeBytes,
72
+ // The query lists only processes holding VRAM, so a missing pid means
73
+ // "measured, holding none".
74
+ gpuMemMB: gpuMemByPid ? gpuMemByPid.get(r.pid) ?? 0 : undefined,
75
+ };
76
+ });
77
+
78
+ return {
79
+ rows,
80
+ columns: observeColumns({ disk: anyIo, gpu: gpuMemByPid !== null }),
81
+ warnings: [],
82
+ };
83
+ },
84
+ };
85
+ }
@@ -0,0 +1,80 @@
1
+ /** Shared shapes between the per-OS process collectors and the tick assembler. */
2
+ import type { ProcessColumnAvailability } from "../../types/system-metrics.ts";
3
+ import type { CounterSample } from "./rate-delta.ts";
4
+
5
+ export interface RawProcessRow {
6
+ pid: number;
7
+ /** -1 when unknown. */
8
+ ppid: number;
9
+ /** Executable basename without extension, original case. */
10
+ name: string;
11
+ /** Raw command line, or null when unreadable / not yet fetched. */
12
+ command: string | null;
13
+ /** Cumulative CPU time (user + kernel), milliseconds. */
14
+ cpuMs: number;
15
+ ramMB: number;
16
+ /** Epoch ms UTC; 0 when unknown. */
17
+ startedAt: number;
18
+ /** CUMULATIVE per-process byte counters. The rows builder turns them into
19
+ * bytes/second over the tick's wall interval, exactly like `cpuMs` — a
20
+ * collector must never pre-compute a rate from them. `undefined` = this OS
21
+ * (or this pid, e.g. an access-denied `/proc/<pid>/io`) does not expose it. */
22
+ diskReadBytes?: number;
23
+ diskWriteBytes?: number;
24
+ netInBytes?: number;
25
+ netOutBytes?: number;
26
+ /** ALREADY a rate, 0-100: the GPU busy counters carry their own high-resolution
27
+ * clock, so their delta cannot use the wall interval and is computed by the
28
+ * collector instead. */
29
+ gpuPct?: number;
30
+ gpuMemMB?: number;
31
+ }
32
+
33
+ export interface ProcessCollection {
34
+ rows: RawProcessRow[];
35
+ /** Windows piggybacks the disk/net counters on the same round trip. */
36
+ disk?: CounterSample | null;
37
+ net?: CounterSample | null;
38
+ /** Which optional per-process columns this collector can fill on this host.
39
+ * Absent = none (the platform has no per-process disk/gpu/net source). */
40
+ columns?: ProcessColumnAvailability;
41
+ warnings: string[];
42
+ }
43
+
44
+ export interface ProcessCollector {
45
+ collect(): Promise<ProcessCollection>;
46
+ /** Release any long-lived child. Must be safe to call repeatedly. */
47
+ stop(): void;
48
+ }
49
+
50
+ /** Frozen: it is shared by every light-tier snapshot, so an accidental mutation
51
+ * would rewrite history for all of them. */
52
+ export const NO_PROCESS_COLUMNS: ProcessColumnAvailability = Object.freeze({ disk: false, gpu: false, net: false });
53
+
54
+ /**
55
+ * Sticky column availability. A capability is advertised as soon as it has
56
+ * produced a value ONCE on this host and is never withdrawn: a single tick
57
+ * where the GPU perf provider hiccups (or where every process happens to be
58
+ * idle) must not make the UI drop a whole column and re-add it 2 s later.
59
+ * Machines do not lose hardware mid-session.
60
+ */
61
+ export function createStickyColumns(): (seen: Partial<ProcessColumnAvailability>) => ProcessColumnAvailability {
62
+ const state: ProcessColumnAvailability = { ...NO_PROCESS_COLUMNS };
63
+ return (seen) => {
64
+ state.disk ||= seen.disk === true;
65
+ state.gpu ||= seen.gpu === true;
66
+ state.net ||= seen.net === true;
67
+ return { ...state };
68
+ };
69
+ }
70
+
71
+ /** A collector for platforms without process support: always empty. */
72
+ export const EMPTY_PROCESS_COLLECTOR: ProcessCollector = {
73
+ collect: async () => ({ rows: [], warnings: [] }),
74
+ stop: () => {},
75
+ };
76
+
77
+ /** Windows image names carry an extension (`explorer.exe`); nothing else does. */
78
+ export function stripExecutableExtension(name: string): string {
79
+ return name.replace(/\.(exe|com|scr|bat|cmd)$/i, "");
80
+ }
@@ -0,0 +1,153 @@
1
+ /**
2
+ * Zero-IO parser for the tagged, tab-separated lines one Windows tick returns:
3
+ *
4
+ * P<TAB>pid<TAB>ppid<TAB>Name<TAB>KernelModeTime<TAB>UserModeTime<TAB>WorkingSetSize<TAB>CreationDateUtcTicks<TAB>ReadTransferCount<TAB>WriteTransferCount
5
+ * C<TAB>pid<TAB>CreationDateUtcTicks<TAB>CommandLine (every 30 s only)
6
+ * D… / N… (disk/net counters)
7
+ * G… / M… (per-process GPU)
8
+ * __ERR__ <message> (a failed block)
9
+ *
10
+ * `CommandLine` is always the LAST field and may itself contain tabs, so rows
11
+ * are split with a field limit — a naive `split("\t")` corrupts them.
12
+ *
13
+ * The two transfer counts are appended AFTER the creation ticks so a `P` row
14
+ * from an older shape (or a host where the properties are empty) still parses,
15
+ * it just reports no disk figures.
16
+ */
17
+ import { parsePerfRawDiskNet } from "./disk-net-collector-windows.ts";
18
+ import { parseGpuLines, type ParsedGpuLines } from "./gpu-process-usage-windows.ts";
19
+ import type { CounterSample } from "./rate-delta.ts";
20
+ import { stripExecutableExtension, type RawProcessRow } from "./process-collector-types.ts";
21
+
22
+ export interface WindowsCommandLine {
23
+ pid: number;
24
+ startedAt: number;
25
+ command: string;
26
+ }
27
+
28
+ export interface ParsedWindowsTick {
29
+ /** PID 0 (System Idle Process) is excluded — its kernel time is idle time and
30
+ * inflates a naive CPU roll-up to ~99 %. */
31
+ processes: RawProcessRow[];
32
+ /** Null when the tick carried no `C` section. */
33
+ commands: WindowsCommandLine[] | null;
34
+ disk: CounterSample | null;
35
+ net: CounterSample | null;
36
+ /** Raw per-process GPU samples; the collector turns them into rates. */
37
+ gpu: ParsedGpuLines;
38
+ errors: string[];
39
+ }
40
+
41
+ /** .NET ticks (100 ns since 0001-01-01) → Unix epoch ms. Input MUST already be
42
+ * UTC — the query calls `.ToUniversalTime()` because only .NET on that machine
43
+ * knows the DST rule in force when the process started. BigInt because the
44
+ * tick value exceeds 2^53. */
45
+ export function ticksToEpochMs(ticks: string): number {
46
+ if (!/^\d+$/.test(ticks)) return 0;
47
+ const EPOCH_TICKS = 621355968000000000n;
48
+ const ms = (BigInt(ticks) - EPOCH_TICKS) / 10000n;
49
+ return ms > 0n ? Number(ms) : 0;
50
+ }
51
+
52
+ /** Split into at most `limit` fields; the remainder stays glued to the last one. */
53
+ export function splitLimited(line: string, limit: number): string[] {
54
+ const out: string[] = [];
55
+ let start = 0;
56
+ while (out.length < limit - 1) {
57
+ const i = line.indexOf("\t", start);
58
+ if (i < 0) break;
59
+ out.push(line.slice(start, i));
60
+ start = i + 1;
61
+ }
62
+ out.push(line.slice(start));
63
+ return out;
64
+ }
65
+
66
+ const HUNDRED_NS_PER_MS = 10_000;
67
+ const BYTES_PER_MB = 1024 * 1024;
68
+
69
+ /** An empty (property absent / access denied) or non-numeric counter field is
70
+ * "the OS did not say", which must stay `undefined` rather than become 0. */
71
+ function optionalCount(field: string | undefined): number | undefined {
72
+ const text = (field ?? "").trim();
73
+ if (!/^\d+$/.test(text)) return undefined;
74
+ const n = Number(text);
75
+ return Number.isFinite(n) ? n : undefined;
76
+ }
77
+
78
+ function parseProcessLine(f: string[]): RawProcessRow | null {
79
+ const pid = Number(f[1]);
80
+ const ppid = Number(f[2]);
81
+ const kernel = Number(f[4]);
82
+ const user = Number(f[5]);
83
+ const ws = Number(f[6]);
84
+ if (![pid, ppid, kernel, user, ws].every(Number.isFinite)) return null;
85
+ if (pid === 0) return null;
86
+ return {
87
+ pid,
88
+ ppid: ppid >= 0 ? ppid : -1,
89
+ name: stripExecutableExtension((f[3] ?? "").trim()) || String(pid),
90
+ command: null,
91
+ cpuMs: (kernel + user) / HUNDRED_NS_PER_MS,
92
+ ramMB: ws / BYTES_PER_MB,
93
+ startedAt: ticksToEpochMs((f[7] ?? "").trim()),
94
+ diskReadBytes: optionalCount(f[8]),
95
+ diskWriteBytes: optionalCount(f[9]),
96
+ };
97
+ }
98
+
99
+ /** `CommandLine` arrives base64(UTF-8) because argv is attacker-controlled and
100
+ * the transport is line-framed. Anything that is not valid base64 is dropped —
101
+ * a raw string here means the field was tampered with, not that it is a command. */
102
+ export function decodeCommandLine(b64: string): string {
103
+ if (!b64 || !/^[A-Za-z0-9+/]+={0,2}$/.test(b64)) return "";
104
+ try {
105
+ return Buffer.from(b64, "base64").toString("utf-8").trim();
106
+ } catch {
107
+ return "";
108
+ }
109
+ }
110
+
111
+ export function parseWindowsTick(text: string): ParsedWindowsTick {
112
+ const processes: RawProcessRow[] = [];
113
+ let commands: WindowsCommandLine[] | null = null;
114
+ const counterLines: string[] = [];
115
+ const gpuLines: string[] = [];
116
+ const errors: string[] = [];
117
+
118
+ for (const raw of text.split("\n")) {
119
+ const line = raw.endsWith("\r") ? raw.slice(0, -1) : raw;
120
+ if (!line) continue;
121
+ switch (line.slice(0, 2)) {
122
+ case "P\t": {
123
+ const row = parseProcessLine(splitLimited(line, 10));
124
+ if (row) processes.push(row);
125
+ break;
126
+ }
127
+ case "C\t": {
128
+ const f = splitLimited(line, 4);
129
+ const pid = Number(f[1]);
130
+ // A `C` section that exists but is all-null still counts as fetched.
131
+ commands ??= [];
132
+ if (!Number.isFinite(pid) || f.length < 4) break;
133
+ const command = decodeCommandLine((f[3] ?? "").trim());
134
+ if (command) commands.push({ pid, startedAt: ticksToEpochMs((f[2] ?? "").trim()), command });
135
+ break;
136
+ }
137
+ case "D\t":
138
+ case "N\t":
139
+ counterLines.push(line);
140
+ break;
141
+ case "G\t":
142
+ case "M\t":
143
+ gpuLines.push(line);
144
+ break;
145
+ default:
146
+ if (line.startsWith("__ERR__")) errors.push(line.slice("__ERR__".length).trim());
147
+ break;
148
+ }
149
+ }
150
+
151
+ const { disk, net } = parsePerfRawDiskNet(counterLines);
152
+ return { processes, commands, disk, net, gpu: parseGpuLines(gpuLines), errors };
153
+ }
@@ -0,0 +1,136 @@
1
+ /**
2
+ * Windows process collector: one `Win32_Process` + disk + net round trip per
3
+ * tick through the long-lived PowerShell session (measured 172-206 ms), plus
4
+ * the expensive `CommandLine` pass only every 30 s.
5
+ *
6
+ * `Get-Process` is not used at all: unelevated it silently returns null CPU and
7
+ * start time for ~45 % of rows. `Win32_Process` with this property list has
8
+ * zero nulls. All scripts are static strings — no user input ever reaches them.
9
+ */
10
+ import type { ProcessCollection, ProcessCollector, RawProcessRow } from "./process-collector-types.ts";
11
+ import { createStickyColumns } from "./process-collector-types.ts";
12
+ import { PowerShellSession, PsSessionDisabledError, PS_DISABLED_WARNING } from "./powershell-session.ts";
13
+ import { parseWindowsTick, type WindowsCommandLine } from "./process-collector-windows-parse.ts";
14
+ import { computeGpuPercents, memBytesToMB, type GpuUsageState } from "./gpu-process-usage-windows.ts";
15
+
16
+ /** `.ToUniversalTime()` here, not in JS: only .NET on this machine knows which
17
+ * DST rule applied at the instant each process started. */
18
+ const CREATION_UTC_TICKS = "$($_.CreationDate.ToUniversalTime().Ticks)";
19
+
20
+ export const WINDOWS_TICK_SCRIPT = [
21
+ "Get-CimInstance Win32_Process -Property ProcessId,ParentProcessId,Name,KernelModeTime,UserModeTime,WorkingSetSize,CreationDate,ReadTransferCount,WriteTransferCount | " +
22
+ `ForEach-Object { "P\`t$($_.ProcessId)\`t$($_.ParentProcessId)\`t$($_.Name)\`t$($_.KernelModeTime)\`t$($_.UserModeTime)\`t$($_.WorkingSetSize)\`t${CREATION_UTC_TICKS}\`t$($_.ReadTransferCount)\`t$($_.WriteTransferCount)" }`,
23
+ "Get-CimInstance Win32_PerfRawData_PerfDisk_PhysicalDisk -Filter \"Name='_Total'\" | " +
24
+ 'ForEach-Object { "D`t$($_.DiskReadBytesPerSec)`t$($_.DiskWriteBytesPerSec)`t$($_.Timestamp_PerfTime)`t$($_.Frequency_PerfTime)" }',
25
+ "Get-CimInstance Win32_PerfRawData_Tcpip_NetworkInterface | " +
26
+ 'ForEach-Object { "N`t$($_.Name)`t$($_.BytesReceivedPersec)`t$($_.BytesSentPersec)`t$($_.Timestamp_Sys100NS)" }',
27
+ // 505 engine instances on a dev box, of which ~50 are busy: filtering in
28
+ // PowerShell keeps the reply an order of magnitude smaller than the class.
29
+ "Get-CimInstance Win32_PerfRawData_GPUPerformanceCounters_GPUEngine | Where-Object { $_.UtilizationPercentage -gt 0 } | " +
30
+ 'ForEach-Object { "G`t$($_.Name)`t$($_.UtilizationPercentage)`t$($_.Timestamp_Sys100NS)" }',
31
+ "Get-CimInstance Win32_PerfRawData_GPUPerformanceCounters_GPUProcessMemory | " +
32
+ 'ForEach-Object { "M`t$($_.Name)`t$($_.DedicatedUsage)" }',
33
+ ].join("\n");
34
+
35
+ /** +10 ms and +95 KB per fetch, and ~half the rows are access-denied (null)
36
+ * unelevated — so it runs on its own slow cadence and merges by identity.
37
+ * `CommandLine` is the only attacker-controlled field in the whole round trip
38
+ * (any local process picks its own argv), so it travels base64-encoded: raw,
39
+ * an embedded CR/LF would let it forge a `P` row for another pid or inject an
40
+ * `__END_<id>__` line that truncates the reply. */
41
+ export const WINDOWS_COMMANDLINE_SCRIPT =
42
+ "Get-CimInstance Win32_Process -Property ProcessId,CommandLine,CreationDate | " +
43
+ `ForEach-Object { "C\`t$($_.ProcessId)\`t${CREATION_UTC_TICKS}\`t$([Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes([string]$_.CommandLine)))" }`;
44
+
45
+ export const COMMANDLINE_REFRESH_MS = 30_000;
46
+
47
+ export interface WindowsProcessCollectorOptions {
48
+ session?: PowerShellSession;
49
+ now?: () => number;
50
+ commandRefreshMs?: number;
51
+ /** Seam for the one-shot startup timing line, so tests stay silent. */
52
+ log?: (message: string) => void;
53
+ }
54
+
55
+ export interface WindowsProcessCollector extends ProcessCollector {
56
+ readonly session: PowerShellSession;
57
+ }
58
+
59
+ export function createWindowsProcessCollector(opts: WindowsProcessCollectorOptions = {}): WindowsProcessCollector {
60
+ const session = opts.session ?? new PowerShellSession();
61
+ const now = opts.now ?? Date.now;
62
+ const refreshMs = opts.commandRefreshMs ?? COMMANDLINE_REFRESH_MS;
63
+ const log = opts.log ?? ((m: string) => console.log(m));
64
+ const observeColumns = createStickyColumns();
65
+ let commandByPid = new Map<number, WindowsCommandLine>();
66
+ let lastCommandFetchAt = Number.NEGATIVE_INFINITY;
67
+ let gpuState: GpuUsageState | null = null;
68
+ let logged = false;
69
+
70
+ return {
71
+ session,
72
+ stop: () => session.stop(),
73
+ async collect(): Promise<ProcessCollection> {
74
+ if (session.isDisabled()) return { rows: [], columns: observeColumns({}), warnings: [PS_DISABLED_WARNING] };
75
+
76
+ const wantCommands = now() - lastCommandFetchAt >= refreshMs;
77
+ const script = wantCommands ? `${WINDOWS_TICK_SCRIPT}\n${WINDOWS_COMMANDLINE_SCRIPT}` : WINDOWS_TICK_SCRIPT;
78
+ const startedRequestAt = now();
79
+ let text: string;
80
+ try {
81
+ text = await session.request(script);
82
+ } catch (e) {
83
+ if (e instanceof PsSessionDisabledError) {
84
+ return { rows: [], columns: observeColumns({}), warnings: [PS_DISABLED_WARNING] };
85
+ }
86
+ throw e;
87
+ }
88
+ if (!logged) {
89
+ logged = true;
90
+ // One line, once: the round trip now also carries the two GPU classes,
91
+ // and the 2 s tick budget is the thing that would break first.
92
+ log(`[system-metrics] windows tick round trip (incl. GPU pass): ${now() - startedRequestAt} ms`);
93
+ }
94
+
95
+ const parsed = parseWindowsTick(text);
96
+ if (parsed.commands) {
97
+ commandByPid = new Map(parsed.commands.map((c) => [c.pid, c]));
98
+ lastCommandFetchAt = now();
99
+ }
100
+
101
+ // First row for a pid wins, like the guard maps: a forged duplicate must
102
+ // not decide which start time the GPU delta key is anchored to.
103
+ const startedAtByPid = new Map<number, number>();
104
+ for (const p of parsed.processes) if (!startedAtByPid.has(p.pid)) startedAtByPid.set(p.pid, p.startedAt);
105
+ const gpu = computeGpuPercents(gpuState, parsed.gpu.engines, (pid) => startedAtByPid.get(pid));
106
+ gpuState = gpu.next;
107
+
108
+ const rows: RawProcessRow[] = parsed.processes.map((r) => ({
109
+ ...r,
110
+ command: mergeCommand(r, commandByPid.get(r.pid)),
111
+ // Windows reports GPU per pid for the whole machine, so a pid with no
112
+ // engine instance is measured-and-idle (0), not unmeasurable.
113
+ gpuPct: parsed.gpu.present ? gpu.pctByPid.get(r.pid) ?? 0 : undefined,
114
+ gpuMemMB: parsed.gpu.present ? memBytesToMB(parsed.gpu.memBytesByPid.get(r.pid) ?? 0) : undefined,
115
+ }));
116
+ return {
117
+ rows,
118
+ disk: parsed.disk,
119
+ net: parsed.net,
120
+ columns: observeColumns({
121
+ disk: rows.some((r) => r.diskReadBytes !== undefined),
122
+ gpu: parsed.gpu.present,
123
+ }),
124
+ warnings: parsed.errors.map((e) => `PowerShell: ${e}`),
125
+ };
126
+ },
127
+ };
128
+ }
129
+
130
+ /** A pid new since the last 30 s fetch — or recycled since — has no command
131
+ * yet; the row falls back to its name until the next fetch. */
132
+ export function mergeCommand(row: RawProcessRow, cached: WindowsCommandLine | undefined): string | null {
133
+ if (!cached) return null;
134
+ if (cached.startedAt && row.startedAt && cached.startedAt !== row.startedAt) return null;
135
+ return cached.command;
136
+ }