harnery 0.38.0 → 0.40.0

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 (378) hide show
  1. package/dist/commands/agents.d.ts.map +1 -1
  2. package/dist/commands/agents.js +32 -8
  3. package/dist/commands/artifacts.d.ts.map +1 -1
  4. package/dist/commands/artifacts.js +97 -6
  5. package/dist/commands/backup.d.ts +16 -0
  6. package/dist/commands/backup.d.ts.map +1 -1
  7. package/dist/commands/backup.js +239 -33
  8. package/dist/commands/browse.d.ts +8 -0
  9. package/dist/commands/browse.d.ts.map +1 -1
  10. package/dist/commands/browse.js +466 -231
  11. package/dist/commands/diagnostics.d.ts.map +1 -1
  12. package/dist/commands/diagnostics.js +6 -3
  13. package/dist/commands/ledger-v3.d.ts.map +1 -1
  14. package/dist/commands/ledger-v3.js +20 -4
  15. package/dist/commands/qa-run.d.ts.map +1 -1
  16. package/dist/commands/qa-run.js +26 -3
  17. package/dist/commands/qa-status.d.ts.map +1 -1
  18. package/dist/commands/qa-status.js +7 -2
  19. package/dist/commands/resources.d.ts.map +1 -1
  20. package/dist/commands/resources.js +23 -3
  21. package/dist/commands/review-pack.d.ts.map +1 -1
  22. package/dist/commands/review-pack.js +98 -23
  23. package/dist/commands/tunnel.d.ts.map +1 -1
  24. package/dist/commands/tunnel.js +2 -2
  25. package/dist/core/adapters/profiles.d.ts +1 -1
  26. package/dist/core/agents/canonical-emit.d.ts +3 -2
  27. package/dist/core/agents/canonical-emit.d.ts.map +1 -1
  28. package/dist/core/agents/canonical-emit.js +2 -0
  29. package/dist/core/agents/cli.js +13 -6
  30. package/dist/core/agents/live-authority-v3.d.ts.map +1 -1
  31. package/dist/core/agents/live-authority-v3.js +5 -3
  32. package/dist/core/agents/live-lifecycle-v3.d.ts +2 -2
  33. package/dist/core/agents/live-lifecycle-v3.d.ts.map +1 -1
  34. package/dist/core/agents/render/prompt-context.d.ts +7 -5
  35. package/dist/core/agents/render/prompt-context.d.ts.map +1 -1
  36. package/dist/core/agents/render/prompt-context.js +63 -8
  37. package/dist/core/agents/session-finalizer-v3.d.ts +2 -2
  38. package/dist/core/agents/session-finalizer-v3.d.ts.map +1 -1
  39. package/dist/core/agents/state/live-coordination-view.d.ts +3 -3
  40. package/dist/core/agents/state/live-coordination-view.d.ts.map +1 -1
  41. package/dist/core/agents/state/live-coordination-view.js +2 -1
  42. package/dist/core/agents/state/names.d.ts +35 -2
  43. package/dist/core/agents/state/names.d.ts.map +1 -1
  44. package/dist/core/agents/state/names.js +80 -5
  45. package/dist/core/agents/state/stale-sweep.d.ts +2 -1
  46. package/dist/core/agents/state/stale-sweep.d.ts.map +1 -1
  47. package/dist/core/agents/state/stale-sweep.js +23 -6
  48. package/dist/core/agents/turn-elapsed.d.ts +51 -0
  49. package/dist/core/agents/turn-elapsed.d.ts.map +1 -0
  50. package/dist/core/agents/turn-elapsed.js +91 -0
  51. package/dist/core/artifacts/activity.d.ts +14 -0
  52. package/dist/core/artifacts/activity.d.ts.map +1 -0
  53. package/dist/core/artifacts/activity.js +52 -0
  54. package/dist/core/artifacts/delivery-card.d.ts +39 -0
  55. package/dist/core/artifacts/delivery-card.d.ts.map +1 -0
  56. package/dist/core/artifacts/delivery-card.js +282 -0
  57. package/dist/core/artifacts/index.d.ts +42 -7
  58. package/dist/core/artifacts/index.d.ts.map +1 -1
  59. package/dist/core/artifacts/index.js +288 -76
  60. package/dist/core/artifacts/mutation-lock.d.ts +2 -0
  61. package/dist/core/artifacts/mutation-lock.d.ts.map +1 -0
  62. package/dist/core/artifacts/mutation-lock.js +91 -0
  63. package/dist/core/backup/host-snapshot.d.ts +18 -0
  64. package/dist/core/backup/host-snapshot.d.ts.map +1 -0
  65. package/dist/core/backup/host-snapshot.js +64 -0
  66. package/dist/core/config.d.ts +20 -5
  67. package/dist/core/config.d.ts.map +1 -1
  68. package/dist/core/config.js +44 -10
  69. package/dist/core/diagnostics/advice.d.ts +38 -3
  70. package/dist/core/diagnostics/advice.d.ts.map +1 -1
  71. package/dist/core/diagnostics/advice.js +103 -99
  72. package/dist/core/diagnostics/bundle.d.ts.map +1 -1
  73. package/dist/core/diagnostics/bundle.js +111 -47
  74. package/dist/core/diagnostics/comparison.d.ts.map +1 -1
  75. package/dist/core/diagnostics/comparison.js +3 -2
  76. package/dist/core/diagnostics/contract.d.ts +15 -31
  77. package/dist/core/diagnostics/contract.d.ts.map +1 -1
  78. package/dist/core/diagnostics/contract.js +2 -5
  79. package/dist/core/diagnostics/index.d.ts +2 -0
  80. package/dist/core/diagnostics/index.d.ts.map +1 -1
  81. package/dist/core/diagnostics/index.js +2 -0
  82. package/dist/core/diagnostics/pressure-contract.d.ts +260 -0
  83. package/dist/core/diagnostics/pressure-contract.d.ts.map +1 -0
  84. package/dist/core/diagnostics/pressure-contract.js +70 -0
  85. package/dist/core/diagnostics/pressure.d.ts +25 -0
  86. package/dist/core/diagnostics/pressure.d.ts.map +1 -0
  87. package/dist/core/diagnostics/pressure.js +1138 -0
  88. package/dist/core/diagnostics/replay.d.ts.map +1 -1
  89. package/dist/core/diagnostics/replay.js +90 -10
  90. package/dist/core/events/v3/adapter-id.d.ts +6 -0
  91. package/dist/core/events/v3/adapter-id.d.ts.map +1 -0
  92. package/dist/core/events/v3/adapter-id.js +7 -0
  93. package/dist/core/events/v3/archive-retention.d.ts.map +1 -1
  94. package/dist/core/events/v3/archive-retention.js +3 -2
  95. package/dist/core/events/v3/bootstrap.d.ts +41 -4
  96. package/dist/core/events/v3/bootstrap.d.ts.map +1 -1
  97. package/dist/core/events/v3/bootstrap.js +120 -17
  98. package/dist/core/events/v3/capabilities.d.ts +16 -9
  99. package/dist/core/events/v3/capabilities.d.ts.map +1 -1
  100. package/dist/core/events/v3/capabilities.js +37 -2
  101. package/dist/core/events/v3/capability-drift.d.ts +2 -2
  102. package/dist/core/events/v3/capability-drift.d.ts.map +1 -1
  103. package/dist/core/events/v3/control-witness.d.ts +48 -5
  104. package/dist/core/events/v3/control-witness.d.ts.map +1 -1
  105. package/dist/core/events/v3/control-witness.js +91 -36
  106. package/dist/core/events/v3/control.d.ts.map +1 -1
  107. package/dist/core/events/v3/control.js +22 -2
  108. package/dist/core/events/v3/index.d.ts +2 -1
  109. package/dist/core/events/v3/index.d.ts.map +1 -1
  110. package/dist/core/events/v3/index.js +2 -1
  111. package/dist/core/events/v3/live-feed.d.ts +7 -1
  112. package/dist/core/events/v3/live-feed.d.ts.map +1 -1
  113. package/dist/core/events/v3/live-feed.js +21 -3
  114. package/dist/core/events/v3/live-routing.d.ts.map +1 -1
  115. package/dist/core/events/v3/live-routing.js +10 -2
  116. package/dist/core/events/v3/producers/command-recorder.d.ts +2 -2
  117. package/dist/core/events/v3/producers/command-recorder.d.ts.map +1 -1
  118. package/dist/core/events/v3/producers/command-recorder.js +2 -1
  119. package/dist/core/events/v3/producers/coordination-recorder.d.ts +2 -2
  120. package/dist/core/events/v3/producers/coordination-recorder.d.ts.map +1 -1
  121. package/dist/core/events/v3/producers/coordination-recorder.js +2 -1
  122. package/dist/core/events/v3/producers/hook-base.d.ts +2 -2
  123. package/dist/core/events/v3/producers/hook-base.d.ts.map +1 -1
  124. package/dist/core/events/v3/producers/hook-base.js +15 -5
  125. package/dist/core/events/v3/producers/hook.d.ts.map +1 -1
  126. package/dist/core/events/v3/producers/hook.js +17 -4
  127. package/dist/core/events/v3/producers/intake.d.ts +4 -4
  128. package/dist/core/events/v3/producers/intake.d.ts.map +1 -1
  129. package/dist/core/events/v3/producers/intake.js +3 -2
  130. package/dist/core/events/v3/producers/producer-state-observer.d.ts.map +1 -1
  131. package/dist/core/events/v3/producers/producer-state-observer.js +2 -1
  132. package/dist/core/events/v3/producers/recorder.d.ts +16 -5
  133. package/dist/core/events/v3/producers/recorder.d.ts.map +1 -1
  134. package/dist/core/events/v3/producers/recorder.js +31 -9
  135. package/dist/core/events/v3/reader.d.ts.map +1 -1
  136. package/dist/core/events/v3/reader.js +10 -13
  137. package/dist/core/events/v3/runtime-build.d.ts.map +1 -1
  138. package/dist/core/events/v3/runtime-build.js +3 -2
  139. package/dist/core/events/v3/runtime-telemetry-capabilities.d.ts +2 -2
  140. package/dist/core/events/v3/runtime-telemetry-capabilities.d.ts.map +1 -1
  141. package/dist/core/events/v3/turn-telemetry.d.ts +2 -2
  142. package/dist/core/events/v3/turn-telemetry.d.ts.map +1 -1
  143. package/dist/core/hooks/adapter/output.d.ts +16 -14
  144. package/dist/core/hooks/adapter/output.d.ts.map +1 -1
  145. package/dist/core/hooks/adapter/output.js +36 -38
  146. package/dist/core/hooks/backup-schedule.d.ts +34 -0
  147. package/dist/core/hooks/backup-schedule.d.ts.map +1 -0
  148. package/dist/core/hooks/backup-schedule.js +114 -0
  149. package/dist/core/hooks/cli.js +61 -18
  150. package/dist/core/hooks/codex-wsl-bridge.d.ts +2 -0
  151. package/dist/core/hooks/codex-wsl-bridge.d.ts.map +1 -1
  152. package/dist/core/hooks/codex-wsl-bridge.js +18 -4
  153. package/dist/core/hooks/index.d.ts +1 -0
  154. package/dist/core/hooks/index.d.ts.map +1 -1
  155. package/dist/core/hooks/index.js +1 -0
  156. package/dist/core/hooks/prompt-context/contract.d.ts +61 -0
  157. package/dist/core/hooks/prompt-context/contract.d.ts.map +1 -0
  158. package/dist/core/hooks/prompt-context/contract.js +102 -0
  159. package/dist/core/hooks/prompt-context/index.d.ts +5 -0
  160. package/dist/core/hooks/prompt-context/index.d.ts.map +1 -0
  161. package/dist/core/hooks/prompt-context/index.js +2 -0
  162. package/dist/core/hooks/prompt-context/runner.d.ts +24 -0
  163. package/dist/core/hooks/prompt-context/runner.d.ts.map +1 -0
  164. package/dist/core/hooks/prompt-context/runner.js +249 -0
  165. package/dist/core/qa-artifacts.d.ts +3 -0
  166. package/dist/core/qa-artifacts.d.ts.map +1 -1
  167. package/dist/core/qa-artifacts.js +25 -3
  168. package/dist/core/resources/contract.d.ts +69 -3
  169. package/dist/core/resources/contract.d.ts.map +1 -1
  170. package/dist/core/resources/contract.js +1 -1
  171. package/dist/core/resources/index.d.ts +1 -0
  172. package/dist/core/resources/index.d.ts.map +1 -1
  173. package/dist/core/resources/index.js +1 -0
  174. package/dist/core/resources/native.d.ts +36 -0
  175. package/dist/core/resources/native.d.ts.map +1 -0
  176. package/dist/core/resources/native.js +418 -0
  177. package/dist/core/resources/sampler.d.ts +2 -0
  178. package/dist/core/resources/sampler.d.ts.map +1 -1
  179. package/dist/core/resources/sampler.js +31 -1
  180. package/dist/core/resources/status.d.ts +61 -0
  181. package/dist/core/resources/status.d.ts.map +1 -0
  182. package/dist/core/resources/status.js +536 -0
  183. package/dist/core/resources/system.d.ts +27 -0
  184. package/dist/core/resources/system.d.ts.map +1 -0
  185. package/dist/core/resources/system.js +439 -0
  186. package/dist/core/semantic/contract.d.ts +13 -13
  187. package/dist/core/semantic/service.d.ts +2 -0
  188. package/dist/core/semantic/service.d.ts.map +1 -1
  189. package/dist/core/semantic/service.js +27 -4
  190. package/dist/core/storage/builtins.js +41 -0
  191. package/dist/core/supervisor/contract.d.ts +41 -3
  192. package/dist/core/supervisor/contract.d.ts.map +1 -1
  193. package/dist/core/supervisor/contract.js +3 -2
  194. package/dist/core/supervisor/findings.d.ts +3 -0
  195. package/dist/core/supervisor/findings.d.ts.map +1 -1
  196. package/dist/core/supervisor/findings.js +88 -0
  197. package/dist/core/supervisor/history.d.ts.map +1 -1
  198. package/dist/core/supervisor/history.js +14 -0
  199. package/dist/core/supervisor/ledger-state.d.ts +55 -0
  200. package/dist/core/supervisor/ledger-state.d.ts.map +1 -0
  201. package/dist/core/supervisor/ledger-state.js +0 -0
  202. package/dist/core/supervisor/service.d.ts.map +1 -1
  203. package/dist/core/supervisor/service.js +120 -7
  204. package/dist/core/supervisor/storage.d.ts +3 -1
  205. package/dist/core/supervisor/storage.d.ts.map +1 -1
  206. package/dist/core/supervisor/storage.js +4 -0
  207. package/dist/core/workflow/admission.d.ts +3 -0
  208. package/dist/core/workflow/admission.d.ts.map +1 -1
  209. package/dist/core/workflow/admission.js +28 -16
  210. package/dist/core/workflow/engine.js +2 -2
  211. package/dist/core/workflow/live-session-v3.d.ts.map +1 -1
  212. package/dist/core/workflow/live-session-v3.js +6 -1
  213. package/dist/core/workflow/proof.d.ts.map +1 -1
  214. package/dist/core/workflow/proof.js +4 -3
  215. package/dist/lib/browser/capture-fidelity.d.ts +7 -0
  216. package/dist/lib/browser/capture-fidelity.d.ts.map +1 -1
  217. package/dist/lib/browser/capture-fidelity.js +17 -0
  218. package/dist/lib/browser/client.d.ts +9 -0
  219. package/dist/lib/browser/client.d.ts.map +1 -1
  220. package/dist/lib/browser/client.js +85 -37
  221. package/dist/lib/browser/index.d.ts +3 -1
  222. package/dist/lib/browser/index.d.ts.map +1 -1
  223. package/dist/lib/browser/index.js +2 -1
  224. package/dist/lib/browser/page-review-budget.d.ts +13 -0
  225. package/dist/lib/browser/page-review-budget.d.ts.map +1 -0
  226. package/dist/lib/browser/page-review-budget.js +251 -0
  227. package/dist/lib/browser/page-review-contracts.d.ts +127 -0
  228. package/dist/lib/browser/page-review-contracts.d.ts.map +1 -0
  229. package/dist/lib/browser/page-review-contracts.js +5 -0
  230. package/dist/lib/browser/page-review-evidence.d.ts +48 -0
  231. package/dist/lib/browser/page-review-evidence.d.ts.map +1 -0
  232. package/dist/lib/browser/page-review-evidence.js +340 -0
  233. package/dist/lib/browser/page-review-judge.d.ts +1 -1
  234. package/dist/lib/browser/page-review-judge.d.ts.map +1 -1
  235. package/dist/lib/browser/page-review-judge.js +46 -38
  236. package/dist/lib/browser/page-review-pack.d.ts +44 -22
  237. package/dist/lib/browser/page-review-pack.d.ts.map +1 -1
  238. package/dist/lib/browser/page-review-pack.js +116 -36
  239. package/dist/lib/browser/page-review-source.d.ts +12 -0
  240. package/dist/lib/browser/page-review-source.d.ts.map +1 -0
  241. package/dist/lib/browser/page-review-source.js +22 -0
  242. package/dist/lib/browser/qa-run-contracts.d.ts +35 -9
  243. package/dist/lib/browser/qa-run-contracts.d.ts.map +1 -1
  244. package/dist/lib/browser/qa-run-contracts.js +48 -14
  245. package/dist/lib/browser/qa-run.d.ts.map +1 -1
  246. package/dist/lib/browser/qa-run.js +215 -68
  247. package/dist/lib/browser/qa-snapshot.d.ts +6 -0
  248. package/dist/lib/browser/qa-snapshot.d.ts.map +1 -1
  249. package/dist/lib/browser/qa-snapshot.js +259 -48
  250. package/dist/lib/browser/review-capture-transaction.d.ts +13 -0
  251. package/dist/lib/browser/review-capture-transaction.d.ts.map +1 -0
  252. package/dist/lib/browser/review-capture-transaction.js +79 -0
  253. package/dist/lib/browser/standalone-html.d.ts.map +1 -1
  254. package/dist/lib/browser/standalone-html.js +4 -2
  255. package/dist/lib/browser/thumbnail-association.d.ts +34 -0
  256. package/dist/lib/browser/thumbnail-association.d.ts.map +1 -0
  257. package/dist/lib/browser/thumbnail-association.js +158 -0
  258. package/dist/lib/browser/tiling.d.ts +30 -0
  259. package/dist/lib/browser/tiling.d.ts.map +1 -1
  260. package/dist/lib/browser/tiling.js +38 -0
  261. package/dist/lib/docs-metadata-managed.d.ts.map +1 -1
  262. package/dist/lib/docs-metadata-managed.js +4 -1
  263. package/dist/lib/identities/assume.d.ts.map +1 -1
  264. package/dist/lib/identities/assume.js +7 -1
  265. package/dist/lib/instructions/templates.d.ts.map +1 -1
  266. package/dist/lib/instructions/templates.js +1 -0
  267. package/dist/lib/local-file-url.d.ts +12 -0
  268. package/dist/lib/local-file-url.d.ts.map +1 -1
  269. package/dist/lib/local-file-url.js +16 -2
  270. package/dist/lib/tunnel/state.d.ts +19 -4
  271. package/dist/lib/tunnel/state.d.ts.map +1 -1
  272. package/dist/lib/tunnel/state.js +53 -13
  273. package/package.json +7 -4
  274. package/schemas/config.schema.json +69 -2
  275. package/src/commands/agents.ts +42 -9
  276. package/src/commands/artifacts.ts +130 -6
  277. package/src/commands/backup.ts +287 -34
  278. package/src/commands/browse.ts +564 -267
  279. package/src/commands/diagnostics.ts +6 -3
  280. package/src/commands/ledger-v3.ts +20 -3
  281. package/src/commands/qa-run.ts +37 -3
  282. package/src/commands/qa-status.ts +11 -2
  283. package/src/commands/resources.ts +23 -3
  284. package/src/commands/review-pack.ts +165 -62
  285. package/src/commands/tunnel.ts +2 -1
  286. package/src/core/agents/canonical-emit.ts +4 -2
  287. package/src/core/agents/cli.ts +14 -6
  288. package/src/core/agents/live-authority-v3.ts +7 -3
  289. package/src/core/agents/live-lifecycle-v3.ts +2 -2
  290. package/src/core/agents/render/prompt-context.ts +68 -14
  291. package/src/core/agents/session-finalizer-v3.ts +2 -2
  292. package/src/core/agents/state/live-coordination-view.ts +4 -4
  293. package/src/core/agents/state/names.ts +92 -7
  294. package/src/core/agents/state/stale-sweep.ts +22 -8
  295. package/src/core/agents/turn-elapsed.ts +135 -0
  296. package/src/core/artifacts/activity.ts +71 -0
  297. package/src/core/artifacts/delivery-card.ts +375 -0
  298. package/src/core/artifacts/index.ts +385 -91
  299. package/src/core/artifacts/mutation-lock.ts +106 -0
  300. package/src/core/backup/host-snapshot.ts +76 -0
  301. package/src/core/config.ts +66 -13
  302. package/src/core/diagnostics/advice.ts +148 -120
  303. package/src/core/diagnostics/bundle.ts +138 -52
  304. package/src/core/diagnostics/comparison.ts +6 -2
  305. package/src/core/diagnostics/contract.ts +39 -42
  306. package/src/core/diagnostics/index.ts +2 -0
  307. package/src/core/diagnostics/pressure-contract.ts +294 -0
  308. package/src/core/diagnostics/pressure.ts +1361 -0
  309. package/src/core/diagnostics/replay.ts +116 -11
  310. package/src/core/events/v3/adapter-id.ts +12 -0
  311. package/src/core/events/v3/archive-retention.ts +3 -6
  312. package/src/core/events/v3/bootstrap.ts +163 -16
  313. package/src/core/events/v3/capabilities.ts +75 -25
  314. package/src/core/events/v3/capability-drift.ts +2 -2
  315. package/src/core/events/v3/control-witness.ts +172 -41
  316. package/src/core/events/v3/control.ts +34 -2
  317. package/src/core/events/v3/index.ts +3 -0
  318. package/src/core/events/v3/live-feed.ts +23 -5
  319. package/src/core/events/v3/live-routing.ts +14 -2
  320. package/src/core/events/v3/producers/command-recorder.ts +4 -4
  321. package/src/core/events/v3/producers/coordination-recorder.ts +4 -4
  322. package/src/core/events/v3/producers/hook-base.ts +21 -16
  323. package/src/core/events/v3/producers/hook.ts +21 -4
  324. package/src/core/events/v3/producers/intake.ts +6 -6
  325. package/src/core/events/v3/producers/producer-state-observer.ts +2 -1
  326. package/src/core/events/v3/producers/recorder.ts +50 -21
  327. package/src/core/events/v3/reader.ts +14 -13
  328. package/src/core/events/v3/runtime-build.ts +3 -2
  329. package/src/core/events/v3/runtime-telemetry-capabilities.ts +3 -3
  330. package/src/core/events/v3/turn-telemetry.ts +4 -4
  331. package/src/core/hooks/adapter/output.ts +50 -36
  332. package/src/core/hooks/backup-schedule.ts +147 -0
  333. package/src/core/hooks/cli.ts +65 -14
  334. package/src/core/hooks/codex-wsl-bridge.ts +21 -5
  335. package/src/core/hooks/index.ts +1 -0
  336. package/src/core/hooks/prompt-context/contract.ts +177 -0
  337. package/src/core/hooks/prompt-context/index.ts +22 -0
  338. package/src/core/hooks/prompt-context/runner.ts +303 -0
  339. package/src/core/qa-artifacts.ts +29 -3
  340. package/src/core/resources/contract.ts +76 -3
  341. package/src/core/resources/index.ts +1 -0
  342. package/src/core/resources/native.ts +481 -0
  343. package/src/core/resources/sampler.ts +46 -1
  344. package/src/core/resources/status.ts +717 -0
  345. package/src/core/resources/system.ts +530 -0
  346. package/src/core/semantic/service.ts +37 -3
  347. package/src/core/storage/builtins.ts +41 -0
  348. package/src/core/supervisor/contract.ts +45 -3
  349. package/src/core/supervisor/findings.ts +159 -0
  350. package/src/core/supervisor/history.ts +15 -0
  351. package/src/core/supervisor/ledger-state.ts +0 -0
  352. package/src/core/supervisor/service.ts +133 -5
  353. package/src/core/supervisor/storage.ts +7 -0
  354. package/src/core/workflow/admission.ts +33 -17
  355. package/src/core/workflow/engine.ts +2 -2
  356. package/src/core/workflow/live-session-v3.ts +6 -8
  357. package/src/core/workflow/proof.ts +4 -3
  358. package/src/lib/browser/capture-fidelity.ts +23 -0
  359. package/src/lib/browser/client.ts +96 -44
  360. package/src/lib/browser/index.ts +15 -1
  361. package/src/lib/browser/page-review-budget.ts +309 -0
  362. package/src/lib/browser/page-review-contracts.ts +129 -0
  363. package/src/lib/browser/page-review-evidence.ts +465 -0
  364. package/src/lib/browser/page-review-judge.ts +56 -40
  365. package/src/lib/browser/page-review-pack.ts +181 -43
  366. package/src/lib/browser/page-review-source.ts +30 -0
  367. package/src/lib/browser/qa-run-contracts.ts +62 -18
  368. package/src/lib/browser/qa-run.ts +259 -71
  369. package/src/lib/browser/qa-snapshot.ts +289 -48
  370. package/src/lib/browser/review-capture-transaction.ts +106 -0
  371. package/src/lib/browser/standalone-html.ts +4 -2
  372. package/src/lib/browser/thumbnail-association.ts +190 -0
  373. package/src/lib/browser/tiling.ts +63 -0
  374. package/src/lib/docs-metadata-managed.ts +4 -1
  375. package/src/lib/identities/assume.ts +12 -4
  376. package/src/lib/instructions/templates.ts +1 -0
  377. package/src/lib/local-file-url.ts +17 -2
  378. package/src/lib/tunnel/state.ts +70 -13
@@ -0,0 +1,536 @@
1
+ import { closeSync, fstatSync, openSync, readSync, statSync } from "node:fs";
2
+ import { unknownPressureAssessment } from "../diagnostics/advice.js";
3
+ import { PRESSURE_ASSESSMENT_SCHEMA_VERSION, PRESSURE_POLICY, } from "../diagnostics/contract.js";
4
+ import { SUPERVISOR_PRESSURE_SCHEMA_VERSION, } from "../supervisor/contract.js";
5
+ import { readSupervisorStatus } from "../supervisor/status.js";
6
+ import { supervisorPaths } from "../supervisor/storage.js";
7
+ import { RESOURCE_SNAPSHOT_SCHEMA_VERSION, } from "./contract.js";
8
+ import { resourcePaths } from "./storage.js";
9
+ export const RESOURCE_STATUS_STALE_MS = 15_000;
10
+ export const RESOURCE_STATUS_MAX_BYTES = 4 * 1024 * 1024;
11
+ export const RESOURCE_STATUS_PROCESS_LIMIT = 20;
12
+ export const RESOURCE_HOST_STATUS_STALE_MS = 30_000;
13
+ const FUTURE_TOLERANCE_MS = 1_000;
14
+ /** A bounded cache-only read. Never samples the OS or starts the writer. */
15
+ export function readResourceStatus(coordRoot, options = {}) {
16
+ const nowMs = options.nowMs ?? Date.now();
17
+ const writerState = readWriterState(coordRoot, nowMs);
18
+ const published = readPublishedPressure(coordRoot, nowMs, writerState);
19
+ const result = {
20
+ schema_version: 2,
21
+ state: "unavailable",
22
+ reason: "snapshot_missing",
23
+ sampled_at: null,
24
+ sample_age_ms: null,
25
+ stale_after_ms: RESOURCE_STATUS_STALE_MS,
26
+ platform: null,
27
+ namespace: "unknown",
28
+ support: null,
29
+ writer: writerState,
30
+ assessment: published.assessment,
31
+ prior_hysteresis: published.prior_hysteresis,
32
+ assessment_capability: published.capability,
33
+ machine: null,
34
+ disks: [],
35
+ pressure: null,
36
+ oom: null,
37
+ io: null,
38
+ host: null,
39
+ };
40
+ let value;
41
+ try {
42
+ value = readBoundedJson(resourcePaths(coordRoot).snapshot);
43
+ }
44
+ catch (error) {
45
+ result.reason =
46
+ error.code === "ENOENT"
47
+ ? "snapshot_missing"
48
+ : error instanceof Error && error.message === "snapshot_too_large"
49
+ ? "snapshot_too_large"
50
+ : "snapshot_invalid";
51
+ return result;
52
+ }
53
+ if (!validSnapshot(value))
54
+ return { ...result, reason: "snapshot_invalid" };
55
+ const sampleMs = Date.parse(value.sampled_at);
56
+ if (!Number.isFinite(sampleMs) || sampleMs - nowMs > FUTURE_TOLERANCE_MS) {
57
+ return { ...result, reason: "snapshot_clock_invalid" };
58
+ }
59
+ result.sampled_at = value.sampled_at;
60
+ result.sample_age_ms = Math.max(0, nowMs - sampleMs);
61
+ result.platform = value.platform;
62
+ result.namespace = value.namespace;
63
+ result.support = {
64
+ state: value.support.state,
65
+ sampler: value.support.sampler,
66
+ ...reason(value.support.reason),
67
+ };
68
+ if (result.sample_age_ms > RESOURCE_STATUS_STALE_MS) {
69
+ return { ...result, state: "stale", reason: "snapshot_stale" };
70
+ }
71
+ if (value.support.state === "error" || value.support.state === "unsupported") {
72
+ return { ...result, reason: `sampler_${value.support.state}` };
73
+ }
74
+ result.state = "fresh";
75
+ result.reason = null;
76
+ result.machine = projectMachine(value.machine);
77
+ result.disks = (value.disks ?? []).map(projectDisk);
78
+ result.pressure = value.pressure
79
+ ? {
80
+ state: value.pressure.state,
81
+ ...reason(value.pressure.reason),
82
+ cpu: projectWindow(value.pressure.cpu),
83
+ memory: projectWindow(value.pressure.memory),
84
+ io: projectWindow(value.pressure.io),
85
+ memory_full: projectWindow(value.pressure.memory_full),
86
+ io_full: projectWindow(value.pressure.io_full),
87
+ }
88
+ : null;
89
+ result.oom = value.oom
90
+ ? {
91
+ state: value.oom.state,
92
+ total_kills: value.oom.total_kills,
93
+ kills_since_last_sample: value.oom.kills_since_last_sample,
94
+ last_kill_age_ms: value.oom.last_kill_age_ms,
95
+ ...reason(value.oom.reason),
96
+ }
97
+ : null;
98
+ result.io = value.io
99
+ ? {
100
+ state: value.io.state,
101
+ read_bytes_per_second: value.io.read_bytes_per_second,
102
+ write_bytes_per_second: value.io.write_bytes_per_second,
103
+ ...reason(value.io.reason),
104
+ }
105
+ : null;
106
+ if (value.host) {
107
+ const hostAge = nowMs - Date.parse(value.host.sampled_at);
108
+ result.host =
109
+ hostAge > RESOURCE_HOST_STATUS_STALE_MS || hostAge < -FUTURE_TOLERANCE_MS
110
+ ? {
111
+ platform: "win32",
112
+ sampled_at: value.host.sampled_at,
113
+ state: "error",
114
+ machine: null,
115
+ disks: [],
116
+ reason: "host_snapshot_stale",
117
+ }
118
+ : {
119
+ platform: "win32",
120
+ sampled_at: value.host.sampled_at,
121
+ state: value.host.state,
122
+ machine: value.host.machine ? projectMachine(value.host.machine) : null,
123
+ disks: value.host.disks.map(projectDisk),
124
+ ...reason(value.host.reason),
125
+ };
126
+ }
127
+ if (options.includeProcesses) {
128
+ result.processes = [...value.processes]
129
+ .sort((a, b) => b.rss_bytes - a.rss_bytes)
130
+ .slice(0, RESOURCE_STATUS_PROCESS_LIMIT)
131
+ .map((p) => ({
132
+ pid: p.pid,
133
+ name: text(p.name),
134
+ cpu_percent: p.cpu_percent,
135
+ rss_bytes: p.rss_bytes,
136
+ owner_kind: p.owner_kind,
137
+ owner_id: p.owner_id === null ? null : text(p.owner_id),
138
+ }));
139
+ result.processes_omitted =
140
+ value.omitted_process_count + value.processes.length - result.processes.length;
141
+ }
142
+ return result;
143
+ }
144
+ export function formatResourceSummary(status) {
145
+ const lead = status.assessment.summary;
146
+ if (status.state !== "fresh" || !status.machine) {
147
+ const age = status.sample_age_ms === null ? "" : ` (${Math.round(status.sample_age_ms / 1_000)}s old)`;
148
+ return `${lead} Measurements are ${status.state}${age}: ${status.reason?.replaceAll("_", " ") ?? "no measurements"}.`;
149
+ }
150
+ const m = status.machine;
151
+ const disk = status.disks
152
+ .filter((d) => d.available_bytes !== null)
153
+ .reduce((least, d) => !least || (d.available_bytes ?? Infinity) < (least.available_bytes ?? Infinity) ? d : least, null);
154
+ const cpu = m.cpu_percent === null ? "warming up" : `${Math.round(m.cpu_percent)}%`;
155
+ const ram = m.memory_available_bytes === null
156
+ ? "unknown"
157
+ : `${formatBytes(m.memory_available_bytes)} available`;
158
+ const diskText = disk ? `${formatBytes(disk.available_bytes)} available` : "unknown";
159
+ return `${lead} ${status.namespace}/${status.platform}: CPU ${cpu}, RAM ${ram}, disk ${diskText}; ${Math.round((status.sample_age_ms ?? 0) / 1_000)}s old${status.support?.state === "partial" ? "; partial" : ""}${!status.writer.running ? "; writer stopped" : ""}.`;
160
+ }
161
+ export function formatResourceStatus(status, bin) {
162
+ const a = status.assessment;
163
+ const lines = [formatResourceSummary(status)];
164
+ lines.push(`Assessment: ${a.state} at ${a.scope} scope; limiting resource ${a.limiting_resource}; trend ${a.trend}; evidence ${a.evidence_state}; recommended action ${a.recommended_action}.`);
165
+ lines.push(`Evidence age: ${a.sample_age_ms === null ? "unknown" : `${Math.round(a.sample_age_ms / 1_000)}s`}; assessment source ${status.assessment_capability.state}${status.assessment_capability.reason_code ? ` (${status.assessment_capability.reason_code})` : ""}.`);
166
+ for (const item of a.reasons)
167
+ lines.push(`Reason ${item.code}: ${item.summary}`);
168
+ for (const item of a.guidance)
169
+ lines.push(`Guidance for ${item.workload_class} work: ${item.summary}`);
170
+ if (a.contributors.length) {
171
+ lines.push("Contributors (who is using the resource, never the machine state):");
172
+ for (const item of a.contributors)
173
+ lines.push(` ${formatContributor(item)}`);
174
+ if (a.omitted_contributor_count)
175
+ lines.push(` ${a.omitted_contributor_count} other contributors omitted.`);
176
+ }
177
+ if (a.unattributed_memory_percent !== null)
178
+ lines.push(`Unattributed memory: ${Math.round(a.unattributed_memory_percent)}% of machine memory has no validated owner.`);
179
+ if (status.state !== "fresh" || !status.writer.running)
180
+ lines.push(`Start or inspect the writer with ${bin} supervisor start --keep-alive and ${bin} supervisor status.`);
181
+ if (status.host)
182
+ lines.push(`Windows host: ${status.host.state}${status.host.machine ? `; CPU ${status.host.machine.cpu_percent === null ? "warming up" : `${Math.round(status.host.machine.cpu_percent)}%`}, RAM ${status.host.machine.memory_available_bytes === null ? "unknown" : `${formatBytes(status.host.machine.memory_available_bytes)} available`}` : `; ${status.host.reason ?? "unavailable"}`}`);
183
+ for (const disk of status.disks)
184
+ lines.push(`Disk ${disk.path}: ${disk.available_bytes === null ? (disk.reason ?? disk.state) : `${formatBytes(disk.available_bytes)} available (${disk.used_percent === null ? "unknown" : `${Math.round(disk.used_percent)}%`} used)`}`);
185
+ if (status.pressure)
186
+ lines.push(`Pressure: ${status.pressure.state}${status.pressure.reason ? ` (${status.pressure.reason})` : ""}`);
187
+ for (const [name, window] of [
188
+ ["memory", status.pressure?.memory_full],
189
+ ["I/O", status.pressure?.io_full],
190
+ ]) {
191
+ if (!window)
192
+ continue;
193
+ const direction = window.avg10 > window.avg60 ? "rising" : window.avg10 < window.avg60 ? "falling" : "steady";
194
+ lines.push(`Full ${name} stalls: ${window.avg10}% / ${window.avg60}% / ${window.avg300}% (10s / 60s / 300s; ${direction}).`);
195
+ }
196
+ if (status.oom) {
197
+ const oom = status.oom;
198
+ lines.push(`OOM kills: ${oom.total_kills ?? "unknown"} total; ${oom.kills_since_last_sample ?? "unknown"} since previous sample${oom.last_kill_age_ms === null ? "" : `; last increase ${Math.round(oom.last_kill_age_ms / 1000)}s ago`}${oom.reason ? ` (${oom.reason})` : ""}.`);
199
+ }
200
+ if (status.io)
201
+ lines.push(`Disk I/O: ${status.io.state}; read ${status.io.read_bytes_per_second === null ? "unknown" : `${formatBytes(status.io.read_bytes_per_second)}/s`}, write ${status.io.write_bytes_per_second === null ? "unknown" : `${formatBytes(status.io.write_bytes_per_second)}/s`}`);
202
+ if (status.processes) {
203
+ lines.push("Processes (largest memory first):");
204
+ for (const p of status.processes)
205
+ lines.push(` ${p.pid} ${p.name}: ${formatBytes(p.rss_bytes)}, CPU ${p.cpu_percent === null ? "unknown" : `${Math.round(p.cpu_percent)}%`}, ${p.owner_kind}${p.owner_id ? ` ${p.owner_id}` : ""}`);
206
+ if (status.processes_omitted)
207
+ lines.push(` ${status.processes_omitted} other processes omitted.`);
208
+ }
209
+ return lines.join("\n");
210
+ }
211
+ /** Ownership is stated only when attribution is exact. */
212
+ function formatContributor(item) {
213
+ const owner = item.attribution_confidence === "exact" && item.owner_id
214
+ ? `${item.owner_kind ?? "owner"} ${item.owner_id}`
215
+ : item.attribution_state === "unattributed"
216
+ ? "no validated owner"
217
+ : "owner not confirmed";
218
+ return `${item.finding_kind} ${item.scope_kind}:${item.scope_id} (${owner}): ${item.summary}`;
219
+ }
220
+ export const PRESSURE_RECORD_MAX_BYTES = 256 * 1024;
221
+ /**
222
+ * Read the assessment the observer published. Bounded, cache only, and never a
223
+ * computation: a missing, stale, or malformed record yields `unknown` with the
224
+ * reason stated, because a gap in the evidence is not a measurement of health.
225
+ */
226
+ export function readPublishedPressure(coordRoot, nowMs = Date.now(), writer) {
227
+ const sourceKind = "supervisor.pressure";
228
+ const observedAt = new Date(nowMs).toISOString();
229
+ const gap = (state, reasonCode, summary, stale = false) => ({
230
+ assessment: unknownPressureAssessment({
231
+ observedAt,
232
+ reasonCode: stale ? "snapshot_stale" : "evidence_unavailable",
233
+ summary,
234
+ }),
235
+ prior_hysteresis: null,
236
+ capability: { source_kind: sourceKind, state, reason_code: reasonCode },
237
+ record: null,
238
+ });
239
+ // A record can only be trusted while its writer is alive. Every surface makes
240
+ // the same check here so none of them reports a state the others do not.
241
+ if (!(writer ?? readWriterState(coordRoot, nowMs)).running) {
242
+ return gap("expired", "pressure_observer_not_running", "Local resource pressure cannot be determined because the resource observer is not running.");
243
+ }
244
+ const path = supervisorPaths(coordRoot).pressure;
245
+ let record;
246
+ try {
247
+ const age = nowMs - statSync(path).mtimeMs;
248
+ if (age > PRESSURE_POLICY.sample_staleness_ms || age < -FUTURE_TOLERANCE_MS) {
249
+ return gap("expired", "pressure_record_stale", `Local resource pressure cannot be determined because the published assessment is ${Math.round(Math.abs(age) / 1_000)} seconds old.`, true);
250
+ }
251
+ record = readBoundedJson(path, PRESSURE_RECORD_MAX_BYTES);
252
+ }
253
+ catch (error) {
254
+ if (error.code === "ENOENT") {
255
+ return gap("unsupported", "pressure_record_missing", "Local resource pressure cannot be determined because the observer has not published an assessment yet.");
256
+ }
257
+ if (error instanceof Error && error.message === "snapshot_too_large") {
258
+ return gap("error", "pressure_record_too_large", "Local resource pressure cannot be determined because the published assessment is larger than the read limit.");
259
+ }
260
+ return gap("malformed", "pressure_record_malformed", "Local resource pressure cannot be determined because the published assessment could not be parsed.");
261
+ }
262
+ if (!validPressureRecord(record)) {
263
+ return gap("malformed", "pressure_record_malformed", "Local resource pressure cannot be determined because the published assessment did not match the expected shape.");
264
+ }
265
+ return {
266
+ assessment: record.assessment,
267
+ prior_hysteresis: record.prior_hysteresis,
268
+ capability: { source_kind: sourceKind, state: "supported" },
269
+ record,
270
+ };
271
+ }
272
+ /** Whether the observer that writes both the snapshot and the record is alive. */
273
+ function readWriterState(coordRoot, nowMs) {
274
+ try {
275
+ // Keep malformed service metadata from making the read expensive. The shared
276
+ // status reader retains ownership of PID/start-token liveness checks.
277
+ if (statSync(supervisorPaths(coordRoot).service).size > 65_536) {
278
+ return { running: false, stale: false };
279
+ }
280
+ const writer = readSupervisorStatus(coordRoot, nowMs);
281
+ const futureHeartbeat = writer.record && Date.parse(writer.record.heartbeat_at) > nowMs + FUTURE_TOLERANCE_MS;
282
+ return {
283
+ running: writer.running && !futureHeartbeat,
284
+ stale: writer.stale || !!futureHeartbeat,
285
+ };
286
+ }
287
+ catch {
288
+ // A missing writer must not break normal coordination.
289
+ return { running: false, stale: false };
290
+ }
291
+ }
292
+ function validPressureRecord(v) {
293
+ if (!object(v) ||
294
+ v.schema_version !== SUPERVISOR_PRESSURE_SCHEMA_VERSION ||
295
+ !string(v.published_at) ||
296
+ !string(v.observer_generation) ||
297
+ !validAssessment(v.assessment) ||
298
+ !(v.prior_hysteresis === null || validHysteresis(v.prior_hysteresis)))
299
+ return false;
300
+ return true;
301
+ }
302
+ function validAssessment(v) {
303
+ if (!object(v) ||
304
+ v.schema_version !== PRESSURE_ASSESSMENT_SCHEMA_VERSION ||
305
+ v.observer_only !== true ||
306
+ !["normal", "elevated", "critical", "unknown"].includes(v.state) ||
307
+ !["guest", "native", "windows-host"].includes(v.scope) ||
308
+ !["memory", "cpu", "io", "storage", "none", "unknown"].includes(v.limiting_resource) ||
309
+ !["rising", "steady", "falling", "unknown"].includes(v.trend) ||
310
+ !string(v.observed_at) ||
311
+ !nullable(v.sample_age_ms) ||
312
+ !["complete", "partial", "unavailable"].includes(v.evidence_state) ||
313
+ !boundedArray(v.evidence, PRESSURE_POLICY.limits.max_evidence) ||
314
+ !boundedArray(v.reasons, PRESSURE_POLICY.limits.max_reasons) ||
315
+ !boundedArray(v.contributors, PRESSURE_POLICY.limits.max_contributors) ||
316
+ !number(v.omitted_contributor_count) ||
317
+ !percent(v.unattributed_memory_percent) ||
318
+ !["proceed", "limit-heavy-work", "avoid-new-heavy-work", "unknown"].includes(v.recommended_action) ||
319
+ !string(v.summary) ||
320
+ !boundedArray(v.guidance, 8) ||
321
+ !validHysteresis(v.hysteresis) ||
322
+ !number(v.policy_version))
323
+ return false;
324
+ return (v.reasons.every((row) => object(row) && string(row.code) && string(row.summary)) &&
325
+ v.guidance.every((row) => object(row) && string(row.workload_class) && string(row.summary)) &&
326
+ v.contributors.every((row) => object(row) &&
327
+ string(row.finding_id) &&
328
+ string(row.finding_kind) &&
329
+ string(row.summary) &&
330
+ ["exact", "none"].includes(row.attribution_confidence)));
331
+ }
332
+ function validHysteresis(v) {
333
+ return (object(v) &&
334
+ ["normal", "elevated", "critical", "unknown"].includes(v.state) &&
335
+ string(v.state_since) &&
336
+ number(v.consecutive_clear_samples) &&
337
+ object(v.dimension_streaks) &&
338
+ (v.oom_baseline_total_kills === null || number(v.oom_baseline_total_kills)) &&
339
+ (v.oom_hold_until === null || string(v.oom_hold_until)) &&
340
+ (v.observer_generation === null || string(v.observer_generation)));
341
+ }
342
+ function boundedArray(v, max) {
343
+ return Array.isArray(v) && v.length <= max;
344
+ }
345
+ function readBoundedJson(path, maxBytes = RESOURCE_STATUS_MAX_BYTES) {
346
+ const fd = openSync(path, "r");
347
+ try {
348
+ const size = fstatSync(fd).size;
349
+ if (size > maxBytes)
350
+ throw new Error("snapshot_too_large");
351
+ const buffer = Buffer.alloc(Math.min(maxBytes + 1, size + 1));
352
+ const length = readSync(fd, buffer, 0, buffer.length, 0);
353
+ if (length > maxBytes)
354
+ throw new Error("snapshot_too_large");
355
+ return JSON.parse(buffer.subarray(0, length).toString("utf8"));
356
+ }
357
+ finally {
358
+ closeSync(fd);
359
+ }
360
+ }
361
+ function object(v) {
362
+ return v !== null && typeof v === "object" && !Array.isArray(v);
363
+ }
364
+ function number(v) {
365
+ return typeof v === "number" && Number.isFinite(v) && v >= 0;
366
+ }
367
+ function nullable(v) {
368
+ return v === null || number(v);
369
+ }
370
+ function percent(v) {
371
+ return v === null || (number(v) && v <= 100);
372
+ }
373
+ function support(v) {
374
+ return ["supported", "partial", "unsupported", "error"].includes(v);
375
+ }
376
+ function string(v) {
377
+ return typeof v === "string" && v.length <= 4096;
378
+ }
379
+ function validMachine(v) {
380
+ return (object(v) &&
381
+ percent(v.cpu_percent) &&
382
+ number(v.cpu_logical_count) &&
383
+ (v.cpu_available_parallelism === undefined || number(v.cpu_available_parallelism)) &&
384
+ (v.load_average === null ||
385
+ (Array.isArray(v.load_average) &&
386
+ v.load_average.length === 3 &&
387
+ v.load_average.every(number))) &&
388
+ [
389
+ "memory_total_bytes",
390
+ "memory_available_bytes",
391
+ "memory_used_bytes",
392
+ "swap_total_bytes",
393
+ "swap_used_bytes",
394
+ ].every((k) => nullable(v[k])) &&
395
+ percent(v.memory_percent) &&
396
+ nullable(v.process_count) &&
397
+ !(number(v.memory_total_bytes) &&
398
+ number(v.memory_available_bytes) &&
399
+ v.memory_available_bytes > v.memory_total_bytes));
400
+ }
401
+ function validDisk(v) {
402
+ return (object(v) &&
403
+ string(v.path) &&
404
+ support(v.state) &&
405
+ nullable(v.total_bytes) &&
406
+ nullable(v.available_bytes) &&
407
+ percent(v.used_percent) &&
408
+ (v.reason === undefined || string(v.reason)) &&
409
+ !(number(v.total_bytes) && number(v.available_bytes) && v.available_bytes > v.total_bytes));
410
+ }
411
+ function validWindow(v) {
412
+ return (v === null ||
413
+ (object(v) && ["avg10", "avg60", "avg300"].every((k) => number(v[k]) && v[k] <= 100)));
414
+ }
415
+ function validSnapshot(v) {
416
+ if (!object(v) ||
417
+ v.schema_version !== RESOURCE_SNAPSHOT_SCHEMA_VERSION ||
418
+ !string(v.sampled_at) ||
419
+ ![
420
+ "aix",
421
+ "android",
422
+ "darwin",
423
+ "freebsd",
424
+ "haiku",
425
+ "linux",
426
+ "openbsd",
427
+ "sunos",
428
+ "win32",
429
+ "cygwin",
430
+ "netbsd",
431
+ ].includes(v.platform) ||
432
+ !["host", "wsl", "unknown"].includes(v.namespace) ||
433
+ !object(v.support) ||
434
+ !support(v.support.state) ||
435
+ !["procfs", "darwin", "win32", "unsupported"].includes(v.support.sampler) ||
436
+ (v.support.reason !== undefined && !string(v.support.reason)) ||
437
+ !validMachine(v.machine) ||
438
+ !nullable(v.interval_ms) ||
439
+ !number(v.sample_duration_ms) ||
440
+ !number(v.collector_cpu_ms) ||
441
+ !number(v.omitted_process_count) ||
442
+ !Array.isArray(v.processes) ||
443
+ v.processes.length > 10000)
444
+ return false;
445
+ if (v.disks !== undefined &&
446
+ (!Array.isArray(v.disks) || v.disks.length > 64 || !v.disks.every(validDisk)))
447
+ return false;
448
+ if (v.pressure !== undefined &&
449
+ (!object(v.pressure) ||
450
+ !support(v.pressure.state) ||
451
+ !validWindow(v.pressure.cpu) ||
452
+ !validWindow(v.pressure.memory) ||
453
+ !validWindow(v.pressure.io) ||
454
+ !validWindow(v.pressure.memory_full) ||
455
+ !validWindow(v.pressure.io_full) ||
456
+ (v.pressure.reason !== undefined && !string(v.pressure.reason))))
457
+ return false;
458
+ if (v.oom !== undefined &&
459
+ (!object(v.oom) ||
460
+ !support(v.oom.state) ||
461
+ !["total_kills", "kills_since_last_sample"].every((key) => v.oom !== null &&
462
+ object(v.oom) &&
463
+ (v.oom[key] === null || (number(v.oom[key]) && Number.isSafeInteger(v.oom[key])))) ||
464
+ !nullable(v.oom.last_kill_age_ms) ||
465
+ (v.oom.reason !== undefined && !string(v.oom.reason))))
466
+ return false;
467
+ if (v.io !== undefined &&
468
+ (!object(v.io) ||
469
+ !support(v.io.state) ||
470
+ !nullable(v.io.read_bytes_per_second) ||
471
+ !nullable(v.io.write_bytes_per_second) ||
472
+ (v.io.reason !== undefined && !string(v.io.reason))))
473
+ return false;
474
+ if (v.host !== undefined &&
475
+ (!object(v.host) ||
476
+ v.host.platform !== "win32" ||
477
+ !support(v.host.state) ||
478
+ !string(v.host.sampled_at) ||
479
+ !Number.isFinite(Date.parse(v.host.sampled_at)) ||
480
+ (v.host.machine !== null && !validMachine(v.host.machine)) ||
481
+ !Array.isArray(v.host.disks) ||
482
+ v.host.disks.length > 64 ||
483
+ !v.host.disks.every(validDisk) ||
484
+ (v.host.reason !== undefined && !string(v.host.reason))))
485
+ return false;
486
+ return v.processes.every((p) => object(p) &&
487
+ Number.isSafeInteger(p.pid) &&
488
+ number(p.pid) &&
489
+ string(p.name) &&
490
+ nullable(p.cpu_percent) &&
491
+ number(p.rss_bytes) &&
492
+ ["agent", "service", "unattributed"].includes(p.owner_kind) &&
493
+ (p.owner_id === null || string(p.owner_id)));
494
+ }
495
+ function projectMachine(m) {
496
+ return {
497
+ cpu_percent: m.cpu_percent,
498
+ cpu_logical_count: m.cpu_logical_count,
499
+ ...(m.cpu_available_parallelism === undefined
500
+ ? {}
501
+ : { cpu_available_parallelism: m.cpu_available_parallelism }),
502
+ load_average: m.load_average,
503
+ memory_total_bytes: m.memory_total_bytes,
504
+ memory_available_bytes: m.memory_available_bytes,
505
+ memory_used_bytes: m.memory_used_bytes,
506
+ memory_percent: m.memory_percent,
507
+ swap_total_bytes: m.swap_total_bytes,
508
+ swap_used_bytes: m.swap_used_bytes,
509
+ process_count: m.process_count,
510
+ };
511
+ }
512
+ function projectDisk(d) {
513
+ return {
514
+ path: text(d.path),
515
+ state: d.state,
516
+ total_bytes: d.total_bytes,
517
+ available_bytes: d.available_bytes,
518
+ used_percent: d.used_percent,
519
+ ...reason(d.reason),
520
+ };
521
+ }
522
+ function projectWindow(v) {
523
+ return v ? { avg10: v.avg10, avg60: v.avg60, avg300: v.avg300 } : null;
524
+ }
525
+ function text(s) {
526
+ // biome-ignore lint/suspicious/noControlCharactersInRegex: Cache strings must not inject terminal control sequences.
527
+ return s.replace(/[\x00-\x1f\x7f]/g, " ").slice(0, 240);
528
+ }
529
+ function reason(s) {
530
+ return s === undefined ? {} : { reason: text(s) };
531
+ }
532
+ function formatBytes(bytes) {
533
+ return bytes >= 1024 ** 3
534
+ ? `${(bytes / 1024 ** 3).toFixed(1)} GiB`
535
+ : `${Math.round(bytes / 1024 ** 2)} MiB`;
536
+ }
@@ -0,0 +1,27 @@
1
+ import type { ResourceDiskSample, ResourceIoSample, ResourceOomSample, ResourcePressureSample, ResourceVmstatSample } from "./contract.js";
2
+ interface FileSystemCapacity {
3
+ bsize: number | bigint;
4
+ blocks: number | bigint;
5
+ bavail: number | bigint;
6
+ bfree: number | bigint;
7
+ }
8
+ export interface SystemResourceOptions {
9
+ platform?: NodeJS.Platform;
10
+ procRoot?: string;
11
+ sysRoot?: string;
12
+ nowMs?: number;
13
+ namespace?: string;
14
+ tmpPath?: string;
15
+ statfs?: (path: string) => FileSystemCapacity;
16
+ filesystemId?: (path: string) => string | number | bigint;
17
+ }
18
+ /** Collect only the workspace and temporary volume; never walk their contents. */
19
+ export declare function collectSystemResources(coordRoot: string, options?: SystemResourceOptions): {
20
+ disks: ResourceDiskSample[];
21
+ pressure: ResourcePressureSample;
22
+ io: ResourceIoSample;
23
+ oom: ResourceOomSample;
24
+ vmstat: ResourceVmstatSample;
25
+ };
26
+ export {};
27
+ //# sourceMappingURL=system.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"system.d.ts","sourceRoot":"","sources":["../../../src/core/resources/system.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,EACjB,sBAAsB,EAGtB,oBAAoB,EACrB,MAAM,eAAe,CAAC;AAEvB,UAAU,kBAAkB;IAC1B,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,kBAAkB,CAAC;IAC9C,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;CAC3D;AAwCD,kFAAkF;AAClF,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,qBAA0B,GAClC;IACD,KAAK,EAAE,kBAAkB,EAAE,CAAC;IAC5B,QAAQ,EAAE,sBAAsB,CAAC;IACjC,EAAE,EAAE,gBAAgB,CAAC;IACrB,GAAG,EAAE,iBAAiB,CAAC;IACvB,MAAM,EAAE,oBAAoB,CAAC;CAC9B,CA6CA"}