@hienlh/ppm 0.18.7 → 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 (510) 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 +16 -0
  5. package/CLAUDE.md +1 -0
  6. package/assets/skills/ppm/SKILL.md +1 -1
  7. package/assets/skills/ppm/references/http-api.md +5 -3
  8. package/dist/web/assets/{ai-resource-editor-DZQUyrsU.js → ai-resource-editor-DFCuNe-P.js} +1 -1
  9. package/dist/web/assets/{angular-html-jfMqUuRd.js → angular-html-Ctz0zN01.js} +1 -1
  10. package/dist/web/assets/{angular-ts-wytn9PMm.js → angular-ts-QXHpgB1C.js} +1 -1
  11. package/dist/web/assets/{api-settings-DlcoR5QT.js → api-settings-nblja3Rk.js} +1 -1
  12. package/dist/web/assets/{apl-i-ahKx6O.js → apl-b9KVk-O4.js} +1 -1
  13. package/dist/web/assets/architecture-PBZL5I3N-C7ra20CE.js +1 -0
  14. package/dist/web/assets/{astro-DVBCJfG6.js → astro-BlFEeGYr.js} +1 -1
  15. package/dist/web/assets/{audio-preview-GGksv6U8.js → audio-preview-CZLmhf__.js} +1 -1
  16. package/dist/web/assets/{blade-BHlL8SqU.js → blade-CGkj2MUI.js} +1 -1
  17. package/dist/web/assets/{bsl-D-UOfR1F.js → bsl-CVsbb6ap.js} +1 -1
  18. package/dist/web/assets/button-BA_fJOtX.js +1 -0
  19. package/dist/web/assets/{cairo-Bn6rucli.js → cairo-BbIHl2iE.js} +1 -1
  20. package/dist/web/assets/chat-tab-flMPLoKb.js +15 -0
  21. package/dist/web/assets/circle-hjUGru6R.js +1 -0
  22. package/dist/web/assets/circle-question-mark-CzR7YRc-.js +1 -0
  23. package/dist/web/assets/{cobol-Byn9FYKu.js → cobol-BWSGjmWb.js} +1 -1
  24. package/dist/web/assets/code-editor-C2VQbXzw.js +10 -0
  25. package/dist/web/assets/{coffee-DjBl4gm-.js → coffee-CWGNOxds.js} +1 -1
  26. package/dist/web/assets/{conflict-editor-Dg_JIcKq.js → conflict-editor-CdH_h0vD.js} +3 -3
  27. package/dist/web/assets/{context-menu-DkQdt6YA.js → context-menu-Cq0u3SK9.js} +1 -1
  28. package/dist/web/assets/{cpp-CKzic-3E.js → cpp-DHGV24J2.js} +1 -1
  29. package/dist/web/assets/{crystal-Bkg-Ly_g.js → crystal-Vlwf2UMP.js} +1 -1
  30. package/dist/web/assets/{csv-preview-DsJ_a2Op.js → csv-preview-CY_454vd.js} +1 -1
  31. package/dist/web/assets/{data-grid-overlay-editor-B1mTl3KS.js → data-grid-overlay-editor-D9il5DZS.js} +1 -1
  32. package/dist/web/assets/{database-viewer-CzjnrnMz.js → database-viewer-BCZOTrPT.js} +1 -1
  33. package/dist/web/assets/{diff-viewer-DUNkO-ll.js → diff-viewer-BwfMN-nW.js} +1 -1
  34. package/dist/web/assets/{docx-preview-DujpUDkE.js → docx-preview-D3Sdh_aT.js} +1 -1
  35. package/dist/web/assets/{edge-DVbZnd3Y.js → edge-Bhqk64zS.js} +1 -1
  36. package/dist/web/assets/{edit-diff-preview-BivQwZMD.js → edit-diff-preview-gq6ALf2B.js} +1 -1
  37. package/dist/web/assets/{elixir-Dwi8Wu7W.js → elixir-D466WCFm.js} +1 -1
  38. package/dist/web/assets/{elm-DtIv-HXJ.js → elm-Bfs2qNPR.js} +1 -1
  39. package/dist/web/assets/{erb-D3HEDz1x.js → erb-WI7jUaB6.js} +1 -1
  40. package/dist/web/assets/{erlang-2MjTCzGz.js → erlang-BCBe8nCc.js} +1 -1
  41. package/dist/web/assets/{esm-CZ8B8Ba2.js → esm-CZs9WVDO.js} +1 -1
  42. package/dist/web/assets/{explorer-body-DSDJUQs7.js → explorer-body-BKOMM566.js} +2 -2
  43. package/dist/web/assets/{explorer-window-content-CWYBapkj.js → explorer-window-content-Bbzijk8t.js} +1 -1
  44. package/dist/web/assets/{extension-webview-DBTFznQp.js → extension-webview-CuOQrHIS.js} +1 -1
  45. package/dist/web/assets/format-bytes-Dk7B73B7.js +1 -0
  46. package/dist/web/assets/{fortran-fixed-form-BLyAtyPM.js → fortran-fixed-form-CXLIv8Ox.js} +1 -1
  47. package/dist/web/assets/{fsharp-Bxbn_gbr.js → fsharp-CZsYmiw9.js} +1 -1
  48. package/dist/web/assets/{gdresource-sFMY4D2Q.js → gdresource-BGRvoWfC.js} +1 -1
  49. package/dist/web/assets/{git-commit-BzB9Lio5.js → git-commit-DH6mY3Km.js} +1 -1
  50. package/dist/web/assets/{git-log-panel-D8ZQdoYl.js → git-log-panel-DcV7PhqW.js} +1 -1
  51. package/dist/web/assets/{git-rebase-CKSVd848.js → git-rebase-C5Gql6Ma.js} +1 -1
  52. package/dist/web/assets/gitGraph-HDMCJU4V-D4hYLNJU.js +1 -0
  53. package/dist/web/assets/{glide-data-grid-uIjdTT7c.js → glide-data-grid-Cehfgrzc.js} +7 -7
  54. package/dist/web/assets/{glimmer-js-BY8aExAJ.js → glimmer-js-1-6JMJlj.js} +1 -1
  55. package/dist/web/assets/{glimmer-ts-Bak54dBX.js → glimmer-ts-C_Njj0nK.js} +1 -1
  56. package/dist/web/assets/{glsl-nR2eaJQe.js → glsl-DbkxE1TN.js} +1 -1
  57. package/dist/web/assets/{graphql-CGPPFAU6.js → graphql-BK75fiXl.js} +1 -1
  58. package/dist/web/assets/group-chat-tab-BVPYxjz-.js +1 -0
  59. package/dist/web/assets/{hack-CXIMX-Ol.js → hack-DG151vit.js} +1 -1
  60. package/dist/web/assets/{haml-tPY-9Pfm.js → haml-DKeIPQWM.js} +1 -1
  61. package/dist/web/assets/{handlebars-BuW1LT7T.js → handlebars-398uCI13.js} +1 -1
  62. package/dist/web/assets/{html-bgVcwZ-t.js → html-NLWdst5q.js} +1 -1
  63. package/dist/web/assets/{html-derivative-D6-IxTgn.js → html-derivative-CJf_Le2z.js} +1 -1
  64. package/dist/web/assets/{http-CJ1zyB-h.js → http-G1K2FozA.js} +1 -1
  65. package/dist/web/assets/{hurl-CmoT7l3T.js → hurl-WDC6sSBz.js} +1 -1
  66. package/dist/web/assets/{hxml-CztOsL8o.js → hxml-Dc3jBXuf.js} +1 -1
  67. package/dist/web/assets/{image-preview-B0VXSpYu.js → image-preview-D-Ok10eZ.js} +1 -1
  68. package/dist/web/assets/index-CerSxGdf.js +52 -0
  69. package/dist/web/assets/index-DRA_OpWY.css +2 -0
  70. package/dist/web/assets/info-3K5VOQVL-lRlrTlkb.js +1 -0
  71. package/dist/web/assets/{jinja-B1pq3jJq.js → jinja-CWsQj2y0.js} +1 -1
  72. package/dist/web/assets/{jison-D8B5pCwA.js → jison-CciJg2NW.js} +1 -1
  73. package/dist/web/assets/{julia-D0K3bwpU.js → julia-IOQNJAB7.js} +1 -1
  74. package/dist/web/assets/{just-B9Jlddu-.js → just-BGdHchwS.js} +1 -1
  75. package/dist/web/assets/{keybindings-store-FyolpNND.js → keybindings-store-aIY40k2o.js} +1 -1
  76. package/dist/web/assets/{latex-BPJSSE6j.js → latex-D6TOl-L2.js} +1 -1
  77. package/dist/web/assets/{liquid-lv10fo4U.js → liquid-CVSvu_Wn.js} +1 -1
  78. package/dist/web/assets/{lua-PNuaIBEF.js → lua-CcKiU6HW.js} +1 -1
  79. package/dist/web/assets/markdown-renderer-I89kyQhe.js +1 -0
  80. package/dist/web/assets/{markdown-renderer-BaBQ6Wm6.js → markdown-renderer-pVzBdkpl.js} +3 -3
  81. package/dist/web/assets/{marko-Du3frD6X.js → marko--UOicMGo.js} +1 -1
  82. package/dist/web/assets/{mdc-BeDVcFRl.js → mdc-D690aU2C.js} +1 -1
  83. package/dist/web/assets/media-url-CylYQld1.js +1 -0
  84. package/dist/web/assets/{mobile-explorer-sheet-Zxjl-e4c.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-DnGpxgkF.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-xzAA4-kD.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-Dkec6GyK.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-Bz1XrUqI.js → sql-query-editor-BPYsJDsn.js} +1 -1
  113. package/dist/web/assets/{sqlite-viewer-D5-NZw6b.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-DSpZ2zhL.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-DXazqejW.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-Bgp8iceS.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-CpF3A7JL.js → use-monaco-theme-CGucu3fb.js} +1 -1
  130. package/dist/web/assets/{use-open-team-member-CUvV02fA.js → use-open-team-member-DdrRXj-M.js} +1 -1
  131. package/dist/web/assets/{use-websocket-TnL2I1io.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-DYAbbmd0.js +1 -0
  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/src/server/helpers/media-route-handlers.ts +22 -3
  144. package/src/server/index.ts +2 -8
  145. package/src/server/routes/files.ts +5 -2
  146. package/src/server/routes/fs-browse.ts +5 -2
  147. package/src/server/routes/resources.ts +119 -73
  148. package/src/services/autostart-generator.ts +79 -7
  149. package/src/services/autostart-register.ts +15 -2
  150. package/src/services/fs-path-guard.service.ts +17 -1
  151. package/src/services/media-transcode/transcode-stream.ts +27 -5
  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/types/system-metrics.ts +199 -0
  188. package/src/web/components/editor/video-player/video-player.tsx +54 -22
  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/src/web/lib/media-url.ts +30 -4
  225. package/.release-run.sh +0 -5
  226. package/dist/web/assets/architecture-PBZL5I3N-Bs7wzj-W.js +0 -1
  227. package/dist/web/assets/arrow-right-DubGFkN8.js +0 -1
  228. package/dist/web/assets/button-B4MWPjWj.js +0 -1
  229. package/dist/web/assets/chat-tab-Xd2WMjdX.js +0 -15
  230. package/dist/web/assets/circle-question-mark-CENpx4oA.js +0 -1
  231. package/dist/web/assets/code-editor-DqXYJWAB.js +0 -10
  232. package/dist/web/assets/gitGraph-HDMCJU4V-D7i54kbM.js +0 -1
  233. package/dist/web/assets/group-chat-tab-B3sryFdA.js +0 -1
  234. package/dist/web/assets/index-DgbOF3xa.js +0 -52
  235. package/dist/web/assets/index-oxsyfDa0.css +0 -2
  236. package/dist/web/assets/info-3K5VOQVL-BV41AzR9.js +0 -1
  237. package/dist/web/assets/markdown-renderer-feiuhJ9n.js +0 -1
  238. package/dist/web/assets/media-url-CUpN5vI1.js +0 -1
  239. package/dist/web/assets/packet-RMMSAZCW-CaJoP44m.js +0 -1
  240. package/dist/web/assets/pie-UPGHQEXC-DSGZmNw2.js +0 -1
  241. package/dist/web/assets/radar-KQ55EAFF-Be4VUTs0.js +0 -1
  242. package/dist/web/assets/settings-tab-Bd8e6iqY.js +0 -1
  243. package/dist/web/assets/system-monitor-tab-A0jvt5Qw.js +0 -1
  244. package/dist/web/assets/team-member-sheet-5Oaqm8I_.js +0 -2
  245. package/dist/web/assets/treemap-KZPCXAKY-Cu2zgbxU.js +0 -1
  246. package/dist/web/assets/video-preview-CwtLPELG.js +0 -1
  247. package/src/services/resource-monitor-utils.ts +0 -141
  248. package/src/services/resource-monitor.service.ts +0 -147
  249. package/src/web/components/system/system-monitor-group-row.tsx +0 -153
  250. /package/dist/web/assets/{abap-C1K0-wzc.js → abap-MRbmsXOs.js} +0 -0
  251. /package/dist/web/assets/{actionscript-3-CJhQVjLA.js → actionscript-3-BDDHKqa4.js} +0 -0
  252. /package/dist/web/assets/{ada-Bt8r9fME.js → ada-DpuV9KwV.js} +0 -0
  253. /package/dist/web/assets/{andromeeda-DF1I8qi3.js → andromeeda-D6qUCKJo.js} +0 -0
  254. /package/dist/web/assets/{apache-CnlleE6P.js → apache-CX1NU_Tl.js} +0 -0
  255. /package/dist/web/assets/{apex-j0C6Xmk6.js → apex-B4-aoQ3K.js} +0 -0
  256. /package/dist/web/assets/{api-settings-DfNRPr1q.js → api-settings-kQHV6pYZ.js} +0 -0
  257. /package/dist/web/assets/{api-themes-8WTH6KpV.js → api-themes-CrK0tkW_.js} +0 -0
  258. /package/dist/web/assets/{applescript-DO7AnO8U.js → applescript-Dm9NI6KR.js} +0 -0
  259. /package/dist/web/assets/{apply-theme-CNj1iA-v.js → apply-theme-BH_d4amk.js} +0 -0
  260. /package/dist/web/assets/{ara-i83AydZj.js → ara-BGN8GAYn.js} +0 -0
  261. /package/dist/web/assets/{asciidoc-DbBA6-sF.js → asciidoc-s_yVuR3t.js} +0 -0
  262. /package/dist/web/assets/{asm-B5S47Rgr.js → asm-BzQdSvTe.js} +0 -0
  263. /package/dist/web/assets/{aurora-x-De_IaSKw.js → aurora-x-BJTLETG_.js} +0 -0
  264. /package/dist/web/assets/{awk-CfyLHXqS.js → awk-BQEGWxvX.js} +0 -0
  265. /package/dist/web/assets/{ayu-dark-DTLdZ1Si.js → ayu-dark-CpTORmLc.js} +0 -0
  266. /package/dist/web/assets/{ayu-light-DTOfkzhu.js → ayu-light-D8PVj-e6.js} +0 -0
  267. /package/dist/web/assets/{ayu-mirage-DsAECCMv.js → ayu-mirage-DyElQHtm.js} +0 -0
  268. /package/dist/web/assets/{ballerina-CumGp9A7.js → ballerina-C82NkRtj.js} +0 -0
  269. /package/dist/web/assets/{bat-Ca2SBbYN.js → bat-0X7DtGI-.js} +0 -0
  270. /package/dist/web/assets/{beancount-CqyXBwwF.js → beancount-Xgvy6YRl.js} +0 -0
  271. /package/dist/web/assets/{berry-yl-kJr_H.js → berry-CCT2pZcQ.js} +0 -0
  272. /package/dist/web/assets/{bibtex-DoFFszjV.js → bibtex-CpXgZ9M_.js} +0 -0
  273. /package/dist/web/assets/{bicep-CWPi4nfK.js → bicep-fkeSA62l.js} +0 -0
  274. /package/dist/web/assets/{bird2-DXew-ut0.js → bird2-Co7SeAI8.js} +0 -0
  275. /package/dist/web/assets/{c-clbySDvd.js → c-BpmrTvJh.js} +0 -0
  276. /package/dist/web/assets/{c3-B65jvSM1.js → c3-BZ_Z0RrR.js} +0 -0
  277. /package/dist/web/assets/{cadence-Cm8tQTHN.js → cadence-B0GBC8OF.js} +0 -0
  278. /package/dist/web/assets/{can-open-in-ppm-DXGOSUQc.js → can-open-in-ppm-omBzUBBq.js} +0 -0
  279. /package/dist/web/assets/{catppuccin-frappe-DLeGslh_.js → catppuccin-frappe-DIt_xR7m.js} +0 -0
  280. /package/dist/web/assets/{catppuccin-latte-CR5GeHws.js → catppuccin-latte-Dw40AcqA.js} +0 -0
  281. /package/dist/web/assets/{catppuccin-macchiato-p-XgjxhP.js → catppuccin-macchiato-BJ7DfVEF.js} +0 -0
  282. /package/dist/web/assets/{catppuccin-mocha-B8QOAZLl.js → catppuccin-mocha-NI2lfXzU.js} +0 -0
  283. /package/dist/web/assets/{clarity-DPulbvKH.js → clarity-F39L0xMJ.js} +0 -0
  284. /package/dist/web/assets/{clock-D493FU_D.js → clock-CvhF4DJP.js} +0 -0
  285. /package/dist/web/assets/{clojure-DFuWS20u.js → clojure-DloMkd8K.js} +0 -0
  286. /package/dist/web/assets/{cmake-DejCqcu4.js → cmake-CwerJun_.js} +0 -0
  287. /package/dist/web/assets/{code-CLF5x7KK.js → code-DDPoqVri.js} +0 -0
  288. /package/dist/web/assets/{codeowners-BwAyqWIH.js → codeowners-CQyVz4Qf.js} +0 -0
  289. /package/dist/web/assets/{codeql-DgSwFjqI.js → codeql-Bb229zuY.js} +0 -0
  290. /package/dist/web/assets/{common-lisp-CxIVJCtf.js → common-lisp-KMlIwq5I.js} +0 -0
  291. /package/dist/web/assets/{copy-BApI9v7Z.js → copy-DKn11Pye.js} +0 -0
  292. /package/dist/web/assets/{coq-DLSjSnmf.js → coq-DHX_3IIo.js} +0 -0
  293. /package/dist/web/assets/{csharp-C1HHzXBp.js → csharp-CEmCZv9Q.js} +0 -0
  294. /package/dist/web/assets/{css-VXsMY--y.js → css-CqZqBD05.js} +0 -0
  295. /package/dist/web/assets/{csv-BEbcJdHz.js → csv-l1g_V5MV.js} +0 -0
  296. /package/dist/web/assets/{csv-parser-BRtnJCfv.js → csv-parser-CnS0wqr6.js} +0 -0
  297. /package/dist/web/assets/{cue-BkDnFqUD.js → cue-BrxRmilg.js} +0 -0
  298. /package/dist/web/assets/{cypher-1cMqojSQ.js → cypher-rZkKwqZc.js} +0 -0
  299. /package/dist/web/assets/{d-BnYjRXtH.js → d-BALR-QuP.js} +0 -0
  300. /package/dist/web/assets/{dark-plus-XfbaH7kZ.js → dark-plus-Cj7rVwh-.js} +0 -0
  301. /package/dist/web/assets/{dart-Ca7s-8hK.js → dart-CWQcdkXk.js} +0 -0
  302. /package/dist/web/assets/{data-grid-types-BXwlFMzs.js → data-grid-types-CYvF-xK5.js} +0 -0
  303. /package/dist/web/assets/{database-B9okYLx6.js → database-BH0urvbs.js} +0 -0
  304. /package/dist/web/assets/{dax-CmuOw-mY.js → dax-BNHD-QBA.js} +0 -0
  305. /package/dist/web/assets/{desktop-C2gJ6Ovb.js → desktop-CN0IXPrP.js} +0 -0
  306. /package/dist/web/assets/{diff-BCEo1Ej7.js → diff-BtOXapES.js} +0 -0
  307. /package/dist/web/assets/{dist-CUPbqNnL.js → dist-DB1Oaqcc.js} +0 -0
  308. /package/dist/web/assets/{dist-DOlBnxFX.js → dist-Di6G_5jU.js} +0 -0
  309. /package/dist/web/assets/{docker-DN2jlyAh.js → docker-DNsAo_qO.js} +0 -0
  310. /package/dist/web/assets/{dotenv-NExMY2kS.js → dotenv-D6Pl6aOU.js} +0 -0
  311. /package/dist/web/assets/{download-D9UYwY0-.js → download-zCATy4x4.js} +0 -0
  312. /package/dist/web/assets/{dracula-B9lbE01y.js → dracula-C3m-w12D.js} +0 -0
  313. /package/dist/web/assets/{dracula-soft-CMBBfKF_.js → dracula-soft-BYqvXm6Z.js} +0 -0
  314. /package/dist/web/assets/{dream-maker-DEyDwFsd.js → dream-maker-DZAPbPTi.js} +0 -0
  315. /package/dist/web/assets/{emacs-lisp-D_qP2zS6.js → emacs-lisp-Ao5SW8ay.js} +0 -0
  316. /package/dist/web/assets/{everforest-dark-DbHa2U-p.js → everforest-dark-uC8QYotQ.js} +0 -0
  317. /package/dist/web/assets/{everforest-light-BISkJchP.js → everforest-light-CTgsVNMr.js} +0 -0
  318. /package/dist/web/assets/{fennel-6B22SfJR.js → fennel-WuBw6IR1.js} +0 -0
  319. /package/dist/web/assets/{file-exclamation-point-a8f3_w7a.js → file-exclamation-point-COAwgNGw.js} +0 -0
  320. /package/dist/web/assets/{fish-CubIIvJD.js → fish-Byy9dusu.js} +0 -0
  321. /package/dist/web/assets/{fluent-DF55zQ09.js → fluent-CDxb_sgw.js} +0 -0
  322. /package/dist/web/assets/{fortran-free-form-DvOu8jAt.js → fortran-free-form-DKWSTamT.js} +0 -0
  323. /package/dist/web/assets/{gdscript-DCPxdLpq.js → gdscript-prYHMgtD.js} +0 -0
  324. /package/dist/web/assets/{gdshader-CTZ381FO.js → gdshader-D-RM-SQk.js} +0 -0
  325. /package/dist/web/assets/{genie-C_QDtvgU.js → genie-CowkJhej.js} +0 -0
  326. /package/dist/web/assets/{gherkin-BcvK42tF.js → gherkin-CLFpoVYJ.js} +0 -0
  327. /package/dist/web/assets/{github-dark-default-CKGVrl3Z.js → github-dark-default-BK_1Qgb8.js} +0 -0
  328. /package/dist/web/assets/{github-dark-dimmed-C3dQZ_LC.js → github-dark-dimmed-Cv9lj6f-.js} +0 -0
  329. /package/dist/web/assets/{github-dark-high-contrast-DW78QukY.js → github-dark-high-contrast-CW5ZgIDh.js} +0 -0
  330. /package/dist/web/assets/{github-dark-C9afs_4w.js → github-dark-nW2F-RLd.js} +0 -0
  331. /package/dist/web/assets/{github-light-BnP2dznS.js → github-light-D4PqBHGZ.js} +0 -0
  332. /package/dist/web/assets/{github-light-default-C2fPZzPG.js → github-light-default-B-cHtJJV.js} +0 -0
  333. /package/dist/web/assets/{github-light-high-contrast-BzIuUFR2.js → github-light-high-contrast-Dt0HJq50.js} +0 -0
  334. /package/dist/web/assets/{gleam-BpeKwEIO.js → gleam-DwSyXJWP.js} +0 -0
  335. /package/dist/web/assets/{gn-nUb_Mit0.js → gn-Cv5WEzHc.js} +0 -0
  336. /package/dist/web/assets/{gnuplot-D7I0v20p.js → gnuplot-D7bRdY_M.js} +0 -0
  337. /package/dist/web/assets/{go-D7Qqska7.js → go-DiRVJ22U.js} +0 -0
  338. /package/dist/web/assets/{groovy-DS-pne5-.js → groovy-BHAgLTeO.js} +0 -0
  339. /package/dist/web/assets/{gruvbox-dark-hard-C0W01fsq.js → gruvbox-dark-hard-C8QZ3gzY.js} +0 -0
  340. /package/dist/web/assets/{gruvbox-dark-medium-Bqo6fQbg.js → gruvbox-dark-medium-Dp1eeid2.js} +0 -0
  341. /package/dist/web/assets/{gruvbox-dark-soft-D-XSM_fu.js → gruvbox-dark-soft-Cwq0dWVj.js} +0 -0
  342. /package/dist/web/assets/{gruvbox-light-hard-IVAwMJRl.js → gruvbox-light-hard-CLQCq2-w.js} +0 -0
  343. /package/dist/web/assets/{gruvbox-light-medium-38ATiG7i.js → gruvbox-light-medium-APHsh6Mo.js} +0 -0
  344. /package/dist/web/assets/{gruvbox-light-soft-DnZr3c_0.js → gruvbox-light-soft-CX-fYc64.js} +0 -0
  345. /package/dist/web/assets/{haskell-uQcywkDH.js → haskell-C4Tw-TDa.js} +0 -0
  346. /package/dist/web/assets/{haxe-c6bI4_GT.js → haxe-B7fSduTQ.js} +0 -0
  347. /package/dist/web/assets/{hcl-CQXTiEXq.js → hcl-Bi3ho6yC.js} +0 -0
  348. /package/dist/web/assets/{hjson-ChETf2bz.js → hjson-BXwae2M1.js} +0 -0
  349. /package/dist/web/assets/{hlsl-BMC4JGoE.js → hlsl-CRuQLBSa.js} +0 -0
  350. /package/dist/web/assets/{horizon-BusFlhLW.js → horizon-DtdQ6qjv.js} +0 -0
  351. /package/dist/web/assets/{horizon-bright-2oD0Mz7W.js → horizon-bright-BXSF_uKq.js} +0 -0
  352. /package/dist/web/assets/{houston-DdbbjqFg.js → houston-C6ASpUjT.js} +0 -0
  353. /package/dist/web/assets/{hy-D_SOuqw9.js → hy-BrWBHtHY.js} +0 -0
  354. /package/dist/web/assets/{image-gallery-CrM5fHKy.js → image-gallery-CGvlv8zR.js} +0 -0
  355. /package/dist/web/assets/{imba-BxLOHO5I.js → imba-C_JJXckG.js} +0 -0
  356. /package/dist/web/assets/{ini-ox-CFcg0.js → ini-DEE_vSHQ.js} +0 -0
  357. /package/dist/web/assets/{java-Bzo8yIal.js → java-CnmpcjcT.js} +0 -0
  358. /package/dist/web/assets/{javascript-DHuz9VXn.js → javascript-C-M7sa2e.js} +0 -0
  359. /package/dist/web/assets/{json-0_y80FD5.js → json-BjZ3dAk6.js} +0 -0
  360. /package/dist/web/assets/{json5-CEQ50pGM.js → json5-BQ2vpqjp.js} +0 -0
  361. /package/dist/web/assets/{jsonc-CfrLEAKA.js → jsonc-C5MjoWGx.js} +0 -0
  362. /package/dist/web/assets/{jsonl-fKbrANC2.js → jsonl-JvhrmQJI.js} +0 -0
  363. /package/dist/web/assets/{jsonnet-DKbkPaQ2.js → jsonnet-C5pdZVuo.js} +0 -0
  364. /package/dist/web/assets/{jssm-Dxxx1Hqu.js → jssm-Db17uybX.js} +0 -0
  365. /package/dist/web/assets/{jsx-DlJL-Oj3.js → jsx-tJp2Cyqu.js} +0 -0
  366. /package/dist/web/assets/{kanagawa-dragon-CwN4SV1c.js → kanagawa-dragon-BculT_Y1.js} +0 -0
  367. /package/dist/web/assets/{kanagawa-lotus-BHltayiE.js → kanagawa-lotus-yQgHUGwU.js} +0 -0
  368. /package/dist/web/assets/{kanagawa-wave-D-KXPjw6.js → kanagawa-wave-CyGoWN4d.js} +0 -0
  369. /package/dist/web/assets/{kdl-DvtoJdFo.js → kdl-Bn8R1REF.js} +0 -0
  370. /package/dist/web/assets/{kotlin-CTS4MLcx.js → kotlin-DWughK73.js} +0 -0
  371. /package/dist/web/assets/{kusto-HtSE_sKm.js → kusto--serPb0x.js} +0 -0
  372. /package/dist/web/assets/{laserwave-DaXZG9ge.js → laserwave-DfAPJ1tt.js} +0 -0
  373. /package/dist/web/assets/{lean-BYtGUfWx.js → lean-UAm1HOKl.js} +0 -0
  374. /package/dist/web/assets/{less-BoxmU_Mk.js → less-Xj6Ka0fF.js} +0 -0
  375. /package/dist/web/assets/{lib-B1clP4ai.js → lib-DgNcCtj3.js} +0 -0
  376. /package/dist/web/assets/{libesm-ah-mr-sh.js → libesm-CPh1Av0r.js} +0 -0
  377. /package/dist/web/assets/{light-plus-Bt5CyUuo.js → light-plus-BfS7gPcj.js} +0 -0
  378. /package/dist/web/assets/{llvm-CSdk9q9V.js → llvm-DvWiVwvU.js} +0 -0
  379. /package/dist/web/assets/{log-B-kp_3CL.js → log-Bo5z9bNz.js} +0 -0
  380. /package/dist/web/assets/{logo-DdIsXFDO.js → logo-CrIjcMZT.js} +0 -0
  381. /package/dist/web/assets/{luau-DUBpLlzQ.js → luau-C9TsYwNt.js} +0 -0
  382. /package/dist/web/assets/{make-B3JVjoW_.js → make-GYq4qVbx.js} +0 -0
  383. /package/dist/web/assets/{markdown-Seon0vHs.js → markdown-p5mNledS.js} +0 -0
  384. /package/dist/web/assets/{material-theme-Nq-ChX1P.js → material-theme-CWYOVxsP.js} +0 -0
  385. /package/dist/web/assets/{material-theme-darker-CPV4ayXJ.js → material-theme-darker-BDGty7YH.js} +0 -0
  386. /package/dist/web/assets/{material-theme-lighter-0kyjYqEd.js → material-theme-lighter-JbgOgV3n.js} +0 -0
  387. /package/dist/web/assets/{material-theme-ocean-DGpAp5co.js → material-theme-ocean-EMOpLpa2.js} +0 -0
  388. /package/dist/web/assets/{material-theme-palenight-B0AUn0NG.js → material-theme-palenight-CY5hgm7h.js} +0 -0
  389. /package/dist/web/assets/{matlab-C2waytxs.js → matlab-C-He_NTH.js} +0 -0
  390. /package/dist/web/assets/{mdx-DAis6R6I.js → mdx-Cr2TR5fj.js} +0 -0
  391. /package/dist/web/assets/{mermaid-_rnT2YGD.js → mermaid-BYc0-B0U.js} +0 -0
  392. /package/dist/web/assets/{min-dark-BSSjchUB.js → min-dark-CMJwqJqB.js} +0 -0
  393. /package/dist/web/assets/{min-light-DomAFQsa.js → min-light-Cx6vFiEX.js} +0 -0
  394. /package/dist/web/assets/{mipsasm-bBgtvPyG.js → mipsasm-Bjer5HwK.js} +0 -0
  395. /package/dist/web/assets/{mobile-bottom-sheet-CS3XMwFw.js → mobile-bottom-sheet-BUOJgiaZ.js} +0 -0
  396. /package/dist/web/assets/{mojo-Cp9BayW0.js → mojo-t90PR-Y2.js} +0 -0
  397. /package/dist/web/assets/{monokai-CL_9gbmn.js → monokai-dci_PdCm.js} +0 -0
  398. /package/dist/web/assets/{moonbit-BS_fcr-P.js → moonbit-AAzI-Hd-.js} +0 -0
  399. /package/dist/web/assets/{move-C79AH45U.js → move-kwBhnhrG.js} +0 -0
  400. /package/dist/web/assets/{narrat-CJ5s3BDf.js → narrat-CXww2YQL.js} +0 -0
  401. /package/dist/web/assets/{nextflow-groovy-ZHa4JrPJ.js → nextflow-groovy-CJXsuXGB.js} +0 -0
  402. /package/dist/web/assets/{night-owl-Jkf9zFQK.js → night-owl-_GD204Wr.js} +0 -0
  403. /package/dist/web/assets/{night-owl-light-DRPeaG5J.js → night-owl-light-DNgkw3kl.js} +0 -0
  404. /package/dist/web/assets/{nix-D2Jet9DN.js → nix-BgiorKFd.js} +0 -0
  405. /package/dist/web/assets/{nord-CREVs22j.js → nord-CaBmcxFC.js} +0 -0
  406. /package/dist/web/assets/{nushell-CAiDi_mR.js → nushell-DUh4UGx1.js} +0 -0
  407. /package/dist/web/assets/{objective-c-CVkmJkC1.js → objective-c-Cl9KU86S.js} +0 -0
  408. /package/dist/web/assets/{objective-cpp-DIKDO1Ly.js → objective-cpp-DVkIA8A0.js} +0 -0
  409. /package/dist/web/assets/{ocaml-R9qtGQhs.js → ocaml-vvoHTak0.js} +0 -0
  410. /package/dist/web/assets/{odin-DTYNQqVr.js → odin-Cyjw8woZ.js} +0 -0
  411. /package/dist/web/assets/{one-dark-pro-BSLWUJn5.js → one-dark-pro-B1cviILi.js} +0 -0
  412. /package/dist/web/assets/{one-light-DbkRXG3t.js → one-light-BPGUJeYI.js} +0 -0
  413. /package/dist/web/assets/{openscad-BlPcSnmT.js → openscad-BLMdTUU8.js} +0 -0
  414. /package/dist/web/assets/{pascal-B1Y46ZZB.js → pascal-i5niy3e7.js} +0 -0
  415. /package/dist/web/assets/{pkl-BhJSJbFv.js → pkl-CuOV7SsU.js} +0 -0
  416. /package/dist/web/assets/{plastic-BzxsCTpi.js → plastic-Bf_zE5KL.js} +0 -0
  417. /package/dist/web/assets/{plsql-DBba7dyP.js → plsql-cfqEtMD3.js} +0 -0
  418. /package/dist/web/assets/{plus-DmjC2iRB.js → plus-BM-Ty0fp.js} +0 -0
  419. /package/dist/web/assets/{po-BvgLlnNo.js → po-CFJcWgjr.js} +0 -0
  420. /package/dist/web/assets/{poimandres-DUaI_1JP.js → poimandres-G5YoaIFf.js} +0 -0
  421. /package/dist/web/assets/{polar-C7uILwJn.js → polar-rcjs3i9R.js} +0 -0
  422. /package/dist/web/assets/{postcss-BgJlpFdw.js → postcss-CBKY1FTZ.js} +0 -0
  423. /package/dist/web/assets/{powerquery-Dn1MIpZu.js → powerquery-Db7SXLbO.js} +0 -0
  424. /package/dist/web/assets/{powershell-Bo-DYzOS.js → powershell-LFy3MUTP.js} +0 -0
  425. /package/dist/web/assets/{prisma-CTLs5IdT.js → prisma-BE8GR1lH.js} +0 -0
  426. /package/dist/web/assets/{prolog-QRGun3eG.js → prolog-DOn5lR1e.js} +0 -0
  427. /package/dist/web/assets/{proto-B7PI7apn.js → proto-wr-TpAK_.js} +0 -0
  428. /package/dist/web/assets/{puppet-CBq0tLrP.js → puppet-D2Dkv62u.js} +0 -0
  429. /package/dist/web/assets/{purescript-DFewOQb2.js → purescript-DvgJgPdy.js} +0 -0
  430. /package/dist/web/assets/{python-iWuxKXvT.js → python-C7TlkHhK.js} +0 -0
  431. /package/dist/web/assets/{qmldir-cXiW3AsF.js → qmldir-CtZMwhcW.js} +0 -0
  432. /package/dist/web/assets/{qss-DASwAbBL.js → qss-dNZ2btnl.js} +0 -0
  433. /package/dist/web/assets/{r-TU2eaIPw.js → r-BlqnNkHS.js} +0 -0
  434. /package/dist/web/assets/{racket-SkRKqrLY.js → racket-CzRQrGc4.js} +0 -0
  435. /package/dist/web/assets/{raku-D31lthkZ.js → raku-BwutWhBF.js} +0 -0
  436. /package/dist/web/assets/{red-CTcQZevb.js → red-BMXMywmL.js} +0 -0
  437. /package/dist/web/assets/{reg-D8YAsTGf.js → reg-BqOKrIOw.js} +0 -0
  438. /package/dist/web/assets/{regexp-CD2uvAWx.js → regexp-Bero1BN2.js} +0 -0
  439. /package/dist/web/assets/{rel-CAaI-1fg.js → rel-BXKWIElA.js} +0 -0
  440. /package/dist/web/assets/{resolve-theme-CJvkL8hU.js → resolve-theme-IdhSR-gx.js} +0 -0
  441. /package/dist/web/assets/{riscv-DR-hJVIj.js → riscv-BbbBYJBo.js} +0 -0
  442. /package/dist/web/assets/{ron-CuUCJ0n4.js → ron-BtVTWW4b.js} +0 -0
  443. /package/dist/web/assets/{rose-pine-dawn-Bqz2sBRY.js → rose-pine-dawn-D7lwhUei.js} +0 -0
  444. /package/dist/web/assets/{rose-pine-aFHxW48i.js → rose-pine-hvkvQzvU.js} +0 -0
  445. /package/dist/web/assets/{rose-pine-moon-wqyh0an4.js → rose-pine-moon-CoHDmsIw.js} +0 -0
  446. /package/dist/web/assets/{rosmsg-CI1ywimO.js → rosmsg-CdaZFgI8.js} +0 -0
  447. /package/dist/web/assets/{run-in-terminal-CGW6o37_.js → run-in-terminal-CyS5Itj-.js} +0 -0
  448. /package/dist/web/assets/{rust-p7Imk4G_.js → rust-Dy2qsphD.js} +0 -0
  449. /package/dist/web/assets/{sass-C8JfaqCV.js → sass-Bz7NVxDb.js} +0 -0
  450. /package/dist/web/assets/{save-DRPrDfTt.js → save-C4z1p51e.js} +0 -0
  451. /package/dist/web/assets/{scala-DNxCW1By.js → scala-sXSwsNyq.js} +0 -0
  452. /package/dist/web/assets/{scheme-BYuUPJoL.js → scheme-DS7TUbN7.js} +0 -0
  453. /package/dist/web/assets/{sdbl-DbPeJPUr.js → sdbl-iISFvIep.js} +0 -0
  454. /package/dist/web/assets/{send-to-chat-YXHdAyLG.js → send-to-chat-BcO39BDR.js} +0 -0
  455. /package/dist/web/assets/{shellscript-DMiHlR3q.js → shellscript-BkIl4ApC.js} +0 -0
  456. /package/dist/web/assets/{shield-check-8GObuUAn.js → shield-check-C5laObJv.js} +0 -0
  457. /package/dist/web/assets/{shield-off-egKAZEwR.js → shield-off-DULFtyLS.js} +0 -0
  458. /package/dist/web/assets/{slack-dark-C4xGcQXI.js → slack-dark-B1eg0_m2.js} +0 -0
  459. /package/dist/web/assets/{slack-ochin-BzgRt_wm.js → slack-ochin-mdkc1ldu.js} +0 -0
  460. /package/dist/web/assets/{smalltalk-LDeL9PYH.js → smalltalk-CORtd03t.js} +0 -0
  461. /package/dist/web/assets/{snazzy-light-CXE7a5j_.js → snazzy-light-Bc6Q2G89.js} +0 -0
  462. /package/dist/web/assets/{solarized-dark-DgUhY74x.js → solarized-dark-CF83zRXM.js} +0 -0
  463. /package/dist/web/assets/{solarized-light-DD9C-H-9.js → solarized-light-BoKQZaYU.js} +0 -0
  464. /package/dist/web/assets/{solidity-CAbDB4D4.js → solidity-DOgi1N4w.js} +0 -0
  465. /package/dist/web/assets/{sparkles-n1hzh65o.js → sparkles-Dqsf3hq6.js} +0 -0
  466. /package/dist/web/assets/{splunk-kQREPfIc.js → splunk-BXfw5ZLy.js} +0 -0
  467. /package/dist/web/assets/{sql-CBzeNAD8.js → sql-BcVs-eX4.js} +0 -0
  468. /package/dist/web/assets/{ssh-config-L1euxrsM.js → ssh-config-CLCtNkkd.js} +0 -0
  469. /package/dist/web/assets/{stylus-DvBnYniP.js → stylus-DdP992aO.js} +0 -0
  470. /package/dist/web/assets/{swift-DF5NDQp6.js → swift-BnGb6Lgc.js} +0 -0
  471. /package/dist/web/assets/{synthwave-84-DbBhB_Hq.js → synthwave-84-cg9264l9.js} +0 -0
  472. /package/dist/web/assets/{system-verilog-D8s2ZW_k.js → system-verilog-GbHpszs3.js} +0 -0
  473. /package/dist/web/assets/{systemd-a5-XZJsG.js → systemd-Dz-bNsDQ.js} +0 -0
  474. /package/dist/web/assets/{table-BX2ZrJfM.js → table-CHmxuh6M.js} +0 -0
  475. /package/dist/web/assets/{talonscript-BLa0URTW.js → talonscript-CFIidoBA.js} +0 -0
  476. /package/dist/web/assets/{tasl-DIoV4XcC.js → tasl-Cu-TRTKx.js} +0 -0
  477. /package/dist/web/assets/{tcl-ztYAdXfQ.js → tcl-DwCHCB1K.js} +0 -0
  478. /package/dist/web/assets/{terraform-DvpCCiOZ.js → terraform-BzZw4T1z.js} +0 -0
  479. /package/dist/web/assets/{tokyo-night-BkHlYUv0.js → tokyo-night-RKsj2-tv.js} +0 -0
  480. /package/dist/web/assets/{toml-acIrxos6.js → toml-CirbOgDP.js} +0 -0
  481. /package/dist/web/assets/{tsv-BJB5EVCT.js → tsv-CraRcWdU.js} +0 -0
  482. /package/dist/web/assets/{tsx-B1MmXGT3.js → tsx-CjFg0lgw.js} +0 -0
  483. /package/dist/web/assets/{turtle-DFceTiqd.js → turtle-B-WBIOa6.js} +0 -0
  484. /package/dist/web/assets/{typescript-Dz9wU5Y1.js → typescript-MpLarYn1.js} +0 -0
  485. /package/dist/web/assets/{typespec-CPuYZijj.js → typespec-B7QlHMZ_.js} +0 -0
  486. /package/dist/web/assets/{typst-CfsCIYv8.js → typst-CcHSKFZj.js} +0 -0
  487. /package/dist/web/assets/{use-blob-url-BmlYYZ8L.js → use-blob-url-BKyVxOZw.js} +0 -0
  488. /package/dist/web/assets/{use-is-mobile-B8FA4kQf.js → use-is-mobile-BXGVvczu.js} +0 -0
  489. /package/dist/web/assets/{v-CGo0jcXA.js → v-xTGhWZuD.js} +0 -0
  490. /package/dist/web/assets/{vala-AsSR0hrb.js → vala-DwebjH3H.js} +0 -0
  491. /package/dist/web/assets/{vb-C7tvbXv1.js → vb-BxJT2RAy.js} +0 -0
  492. /package/dist/web/assets/{vendor-xterm-C1diXHJl.js → vendor-xterm-CU6zIYMB.js} +0 -0
  493. /package/dist/web/assets/{verilog--a33ND-p.js → verilog-CvV6RHPD.js} +0 -0
  494. /package/dist/web/assets/{vesper-B_Z0h4pn.js → vesper-CY3qd7E_.js} +0 -0
  495. /package/dist/web/assets/{vhdl-CWL5dZPN.js → vhdl-B9ZX-sUL.js} +0 -0
  496. /package/dist/web/assets/{viml-BglmT14Y.js → viml-Y42h_ExQ.js} +0 -0
  497. /package/dist/web/assets/{vitesse-black-RKFsSqQI.js → vitesse-black-DkXP6Sv-.js} +0 -0
  498. /package/dist/web/assets/{vitesse-dark-D7zDWNmc.js → vitesse-dark-B9CkIB6r.js} +0 -0
  499. /package/dist/web/assets/{vitesse-light-MAp87W5b.js → vitesse-light-C7DHrJCK.js} +0 -0
  500. /package/dist/web/assets/{vyper-CgCBYg1G.js → vyper-Cnd9s5j-.js} +0 -0
  501. /package/dist/web/assets/{wasm-Bwl4txwp.js → wasm-DQE71XTB.js} +0 -0
  502. /package/dist/web/assets/{wasm-BOG7ZeTT.js → wasm-iWe7Fzjc.js} +0 -0
  503. /package/dist/web/assets/{wenyan-DpShPKXZ.js → wenyan-Bc5Pnm9l.js} +0 -0
  504. /package/dist/web/assets/{wgsl-BakcCblK.js → wgsl-D-YUAWkP.js} +0 -0
  505. /package/dist/web/assets/{wikitext-NroRWVAO.js → wikitext-DYQDUYf2.js} +0 -0
  506. /package/dist/web/assets/{wit-B5CM2pg6.js → wit-P6u7mfwy.js} +0 -0
  507. /package/dist/web/assets/{wolfram-7MTFBJpR.js → wolfram-6SXLUqao.js} +0 -0
  508. /package/dist/web/assets/{yaml-Bwr01G2K.js → yaml-CQiMLVcZ.js} +0 -0
  509. /package/dist/web/assets/{zenscript-Dj8GATvi.js → zenscript-DFMywo_P.js} +0 -0
  510. /package/dist/web/assets/{zig-LAE-fbS-.js → zig-CtAjaIiF.js} +0 -0
@@ -0,0 +1,182 @@
1
+ /**
2
+ * ONE long-lived PowerShell child for the polling lifetime.
3
+ *
4
+ * Why not spawn per tick: every `powershell.exe` spawn costs a 32 MiB allocator
5
+ * segment Bun never returns to the OS (see windows-process-tree.ts) and ~400 ms
6
+ * versus ~140 ms in-session. Requests are serialised, time-limited, and a
7
+ * failed child may be restarted only a fixed number of times for the server's
8
+ * whole life — a refilling budget would re-arm against a permanently wedged
9
+ * CIM provider and spawn hundreds of times a day.
10
+ */
11
+ import { defaultPsSpawner, encodeRequestLine, type PsChild, type PsSpawner } from "./powershell-session-bootstrap.ts";
12
+
13
+ export { POWERSHELL_BOOTSTRAP, defaultPsSpawner, type PsChild, type PsSpawner } from "./powershell-session-bootstrap.ts";
14
+
15
+ export interface PowerShellSessionOptions {
16
+ spawn?: PsSpawner;
17
+ /** Measured p95 real tick is 206 ms; 5 s only fires on a wedged CIM provider. */
18
+ requestTimeoutMs?: number;
19
+ /** Absolute cap for the server's lifetime — a refilling budget would re-arm
20
+ * against a permanently wedged provider and spawn hundreds of times a day. */
21
+ maxRestarts?: number;
22
+ /** Child working set creeps over hours; a scheduled recycle is free of the budget. */
23
+ recycleAfterMs?: number;
24
+ now?: () => number;
25
+ }
26
+
27
+ export const PS_DISABLED_WARNING = "Windows process collection disabled after repeated PowerShell failures";
28
+
29
+ export class PsSessionBusyError extends Error { constructor() { super("PowerShell request already in flight"); } }
30
+ export class PsSessionDisabledError extends Error { constructor() { super(PS_DISABLED_WARNING); } }
31
+
32
+ interface Pending { id: string; resolve: (s: string) => void; reject: (e: Error) => void; timer: ReturnType<typeof setTimeout> }
33
+
34
+ /** Anything larger than this without an end marker is not a reply we want. */
35
+ const MAX_BUFFER_CHARS = 8 * 1024 * 1024;
36
+
37
+ export class PowerShellSession {
38
+ private readonly spawn: PsSpawner;
39
+ private readonly requestTimeoutMs: number;
40
+ private readonly maxRestarts: number;
41
+ private readonly recycleAfterMs: number;
42
+ private readonly now: () => number;
43
+
44
+ private child: PsChild | null = null;
45
+ private generation = 0;
46
+ private spawnedAt = 0;
47
+ private restarts = 0;
48
+ private everStarted = false;
49
+ private previousDiedAbnormally = false;
50
+ private disabled = false;
51
+ private buffer = "";
52
+ private pending: Pending | null = null;
53
+ private nextId = 1;
54
+
55
+ constructor(opts: PowerShellSessionOptions = {}) {
56
+ this.spawn = opts.spawn ?? defaultPsSpawner;
57
+ this.requestTimeoutMs = opts.requestTimeoutMs ?? 5000;
58
+ this.maxRestarts = opts.maxRestarts ?? 5;
59
+ this.recycleAfterMs = opts.recycleAfterMs ?? 6 * 60 * 60 * 1000;
60
+ this.now = opts.now ?? Date.now;
61
+ }
62
+
63
+ isHealthy(): boolean { return this.child !== null && !this.disabled; }
64
+ isDisabled(): boolean { return this.disabled; }
65
+ isBusy(): boolean { return this.pending !== null; }
66
+ restartCount(): number { return this.restarts; }
67
+ childPid(): number | null { return this.child?.pid ?? null; }
68
+
69
+ request(script: string): Promise<string> {
70
+ if (this.disabled) return Promise.reject(new PsSessionDisabledError());
71
+ if (this.pending) return Promise.reject(new PsSessionBusyError());
72
+ if (this.child && this.now() - this.spawnedAt >= this.recycleAfterMs) this.stop();
73
+ if (!this.child) {
74
+ try { this.start(); } catch (e) { return Promise.reject(e as Error); }
75
+ }
76
+ const child = this.child!;
77
+ const id = String(this.nextId++);
78
+ return new Promise<string>((resolve, reject) => {
79
+ const timer = setTimeout(() => this.onFailure(`PowerShell request timed out after ${this.requestTimeoutMs} ms`), this.requestTimeoutMs);
80
+ this.pending = { id, resolve, reject, timer };
81
+ try {
82
+ child.stdin.write(encodeRequestLine(id, script));
83
+ child.stdin.flush?.();
84
+ } catch (e) {
85
+ this.onFailure(`PowerShell stdin write failed: ${(e as Error).message}`);
86
+ }
87
+ });
88
+ }
89
+
90
+ /** Write nothing, kill, clear. Safe to call repeatedly. No subscribers must mean no child. */
91
+ stop(): void {
92
+ this.teardown(new Error("PowerShell session stopped"));
93
+ }
94
+
95
+ private teardown(pendingError: Error): void {
96
+ const child = this.child;
97
+ this.child = null;
98
+ this.generation++;
99
+ this.buffer = "";
100
+ this.failPending(pendingError);
101
+ if (child) { try { child.kill(); } catch { /* already gone */ } }
102
+ }
103
+
104
+ private start(): void {
105
+ if (this.everStarted && this.previousDiedAbnormally) {
106
+ if (this.restarts >= this.maxRestarts) {
107
+ this.disabled = true;
108
+ throw new PsSessionDisabledError();
109
+ }
110
+ this.restarts++;
111
+ }
112
+ this.everStarted = true;
113
+ this.previousDiedAbnormally = false;
114
+ const gen = ++this.generation;
115
+ const child = this.spawn();
116
+ this.child = child;
117
+ this.spawnedAt = this.now();
118
+ this.buffer = "";
119
+ void this.pump(child, gen);
120
+ void drain(child.stderr);
121
+ child.exited.then(
122
+ () => { if (gen === this.generation) this.onFailure("PowerShell exited unexpectedly"); },
123
+ () => { if (gen === this.generation) this.onFailure("PowerShell exited unexpectedly"); },
124
+ );
125
+ }
126
+
127
+ private async pump(child: PsChild, gen: number): Promise<void> {
128
+ const reader = child.stdout.getReader();
129
+ const decoder = new TextDecoder();
130
+ try {
131
+ while (true) {
132
+ const { done, value } = await reader.read();
133
+ if (done || gen !== this.generation) break;
134
+ this.buffer += decoder.decode(value, { stream: true });
135
+ this.scan();
136
+ }
137
+ } catch { /* stream torn down with the child */ }
138
+ if (gen === this.generation) this.onFailure("PowerShell stdout closed");
139
+ }
140
+
141
+ /** Resolve the pending request on ITS marker; discard any stale marker's output. */
142
+ private scan(): void {
143
+ while (true) {
144
+ const m = /__END_(\d+)__/.exec(this.buffer);
145
+ if (!m) {
146
+ if (this.buffer.length > MAX_BUFFER_CHARS) this.buffer = "";
147
+ return;
148
+ }
149
+ const reply = this.buffer.slice(0, m.index);
150
+ this.buffer = this.buffer.slice(m.index + m[0].length).replace(/^\r?\n/, "");
151
+ const p = this.pending;
152
+ if (p && p.id === m[1]) {
153
+ this.pending = null;
154
+ clearTimeout(p.timer);
155
+ p.resolve(reply);
156
+ }
157
+ }
158
+ }
159
+
160
+ /** Timeout, exit or write failure: kill, mark for a counted restart, reject. */
161
+ private onFailure(reason: string): void {
162
+ this.previousDiedAbnormally = true;
163
+ this.teardown(new Error(reason));
164
+ }
165
+
166
+ private failPending(error: Error): void {
167
+ const p = this.pending;
168
+ if (!p) return;
169
+ this.pending = null;
170
+ clearTimeout(p.timer);
171
+ p.reject(error);
172
+ }
173
+ }
174
+
175
+ /** A full stderr pipe would block the child; read and discard it. */
176
+ async function drain(stream: ReadableStream<Uint8Array> | null | undefined): Promise<void> {
177
+ if (!stream) return;
178
+ try {
179
+ const reader = stream.getReader();
180
+ while (!(await reader.read()).done) { /* discard */ }
181
+ } catch { /* closed with the child */ }
182
+ }
@@ -0,0 +1,34 @@
1
+ /**
2
+ * The cosmetic `ppm` flag: PPM's roots (server + supervisor/parent), every
3
+ * descendant of those roots, and the app share tunnel. Drives the "PPM only"
4
+ * filter in the UI. It is NOT a safety mechanism — the kill guard walks the
5
+ * ppid maps itself and never keys off this flag.
6
+ */
7
+ import { collectDescendants } from "./kill-guard.ts";
8
+
9
+ export interface PpmOwnershipInput {
10
+ roots: ReadonlySet<number>;
11
+ /** Extra pids owned outright (the share tunnel, preview tunnels). */
12
+ extraPids: readonly number[];
13
+ ppidOf: ReadonlyMap<number, number>;
14
+ startedAtOf: ReadonlyMap<number, number>;
15
+ }
16
+
17
+ /**
18
+ * Descendants follow ppid links only while the parent started no later than
19
+ * the child — Windows never clears a dead parent's ppid reference, so an
20
+ * unguarded walk would adopt whatever unrelated process later reused that pid.
21
+ */
22
+ export function computePpmPids(input: PpmOwnershipInput): Set<number> {
23
+ const out = new Set<number>();
24
+ const ctx = { ppidOf: input.ppidOf, startedAtOf: input.startedAtOf };
25
+ for (const root of input.roots) {
26
+ if (!input.ppidOf.has(root)) continue;
27
+ out.add(root);
28
+ for (const pid of collectDescendants(root, ctx)) out.add(pid);
29
+ }
30
+ for (const pid of input.extraPids) {
31
+ if (input.ppidOf.has(pid)) out.add(pid);
32
+ }
33
+ return out;
34
+ }
@@ -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
+ }