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,177 @@
1
+ import type { Adapter } from "../../adapter.ts";
2
+
3
+ export const PROMPT_CONTEXT_REQUEST_SCHEMA = "harnery.prompt-context-request/v1" as const;
4
+ export const PROMPT_CONTEXT_RESULT_SCHEMA = "harnery.prompt-context-result/v1" as const;
5
+
6
+ export const DEFAULT_PROMPT_CONTEXT_TIMEOUT_MS = 15_000;
7
+ export const DEFAULT_PROMPT_CONTEXT_MAX_OUTPUT_BYTES = 65_536;
8
+ export const MAX_PROMPT_CONTEXT_TIMEOUT_MS = 120_000;
9
+ export const MAX_PROMPT_CONTEXT_OUTPUT_BYTES = 4 * 1024 * 1024;
10
+
11
+ const MAX_PROVIDER_ID_CHARS = 100;
12
+ const MAX_REASON_CODES = 32;
13
+ const MAX_REASON_CODE_CHARS = 80;
14
+
15
+ export type PromptContextDelivery = "direct" | "unsupported";
16
+
17
+ export interface PromptContextConfig {
18
+ enabled: boolean;
19
+ timeoutMs: number;
20
+ maxOutputBytes: number;
21
+ }
22
+
23
+ export interface PromptContextRequestV1 {
24
+ schema: typeof PROMPT_CONTEXT_REQUEST_SCHEMA;
25
+ event: "user_prompt_submit";
26
+ adapter: Adapter;
27
+ session_id: string;
28
+ turn_id: string;
29
+ cwd: string;
30
+ prompt: string;
31
+ }
32
+
33
+ export interface PromptContextResultV1 {
34
+ schema: typeof PROMPT_CONTEXT_RESULT_SCHEMA;
35
+ provider_id: string;
36
+ context: string;
37
+ matched: number;
38
+ succeeded: number;
39
+ failed: number;
40
+ reason_codes: string[];
41
+ }
42
+
43
+ export interface PromptContextAuditV1 {
44
+ provider_id?: string;
45
+ status:
46
+ | "disabled"
47
+ | "no_prompt"
48
+ | "missing_extension"
49
+ | "timeout"
50
+ | "signal"
51
+ | "nonzero_exit"
52
+ | "invalid_result"
53
+ | "oversized_result"
54
+ | "empty"
55
+ | "delivered";
56
+ delivery: PromptContextDelivery;
57
+ elapsed_ms: number;
58
+ matched?: number;
59
+ succeeded?: number;
60
+ failed?: number;
61
+ reason_codes?: string[];
62
+ output_bytes?: number;
63
+ context_fingerprint?: string;
64
+ }
65
+
66
+ export type PromptContextResultValidation =
67
+ | { ok: true; value: PromptContextResultV1 }
68
+ | { ok: false; reason: string };
69
+
70
+ const DELIVERY_BY_ADAPTER: Readonly<Record<Adapter, PromptContextDelivery>> = {
71
+ "claude-code": "direct",
72
+ codex: "direct",
73
+ cursor: "direct",
74
+ };
75
+
76
+ export function promptContextDelivery(adapter: Adapter): PromptContextDelivery {
77
+ return DELIVERY_BY_ADAPTER[adapter] ?? "unsupported";
78
+ }
79
+
80
+ export function parsePromptContextConfig(value: unknown): PromptContextConfig | null {
81
+ if (value === undefined) {
82
+ return {
83
+ enabled: false,
84
+ timeoutMs: DEFAULT_PROMPT_CONTEXT_TIMEOUT_MS,
85
+ maxOutputBytes: DEFAULT_PROMPT_CONTEXT_MAX_OUTPUT_BYTES,
86
+ };
87
+ }
88
+ if (!isRecord(value) || typeof value.enabled !== "boolean") return null;
89
+
90
+ const timeoutMs = value.timeoutMs ?? DEFAULT_PROMPT_CONTEXT_TIMEOUT_MS;
91
+ const maxOutputBytes = value.maxOutputBytes ?? DEFAULT_PROMPT_CONTEXT_MAX_OUTPUT_BYTES;
92
+ if (!isBoundedInteger(timeoutMs, 1, MAX_PROMPT_CONTEXT_TIMEOUT_MS)) return null;
93
+ if (!isBoundedInteger(maxOutputBytes, 1, MAX_PROMPT_CONTEXT_OUTPUT_BYTES)) return null;
94
+
95
+ return { enabled: value.enabled, timeoutMs, maxOutputBytes };
96
+ }
97
+
98
+ export function buildPromptContextRequest(input: {
99
+ adapter: Adapter;
100
+ sessionId: string;
101
+ turnId: string;
102
+ cwd: string;
103
+ prompt: string;
104
+ }): PromptContextRequestV1 {
105
+ return {
106
+ schema: PROMPT_CONTEXT_REQUEST_SCHEMA,
107
+ event: "user_prompt_submit",
108
+ adapter: input.adapter,
109
+ session_id: input.sessionId,
110
+ turn_id: input.turnId,
111
+ cwd: input.cwd,
112
+ prompt: input.prompt,
113
+ };
114
+ }
115
+
116
+ export function validatePromptContextResult(value: unknown): PromptContextResultValidation {
117
+ if (!isRecord(value)) return invalid("result_not_object");
118
+ if (value.schema !== PROMPT_CONTEXT_RESULT_SCHEMA) return invalid("unsupported_schema");
119
+ if (
120
+ typeof value.provider_id !== "string" ||
121
+ value.provider_id.length === 0 ||
122
+ value.provider_id.length > MAX_PROVIDER_ID_CHARS ||
123
+ !/^[a-z0-9][a-z0-9._-]*$/.test(value.provider_id)
124
+ ) {
125
+ return invalid("invalid_provider_id");
126
+ }
127
+ if (typeof value.context !== "string") return invalid("invalid_context");
128
+ if (!isCount(value.matched) || !isCount(value.succeeded) || !isCount(value.failed)) {
129
+ return invalid("invalid_counts");
130
+ }
131
+ if (value.succeeded + value.failed !== value.matched) return invalid("count_mismatch");
132
+ if (value.succeeded === 0 && value.context.length > 0) return invalid("context_without_success");
133
+ if (value.succeeded > 0 && value.context.length === 0) return invalid("success_without_context");
134
+ if (!Array.isArray(value.reason_codes) || value.reason_codes.length > MAX_REASON_CODES) {
135
+ return invalid("invalid_reason_codes");
136
+ }
137
+ if (
138
+ value.reason_codes.some(
139
+ (code) =>
140
+ typeof code !== "string" ||
141
+ code.length === 0 ||
142
+ code.length > MAX_REASON_CODE_CHARS ||
143
+ !/^[a-z0-9][a-z0-9._-]*$/.test(code),
144
+ )
145
+ ) {
146
+ return invalid("invalid_reason_code");
147
+ }
148
+
149
+ return {
150
+ ok: true,
151
+ value: {
152
+ schema: PROMPT_CONTEXT_RESULT_SCHEMA,
153
+ provider_id: value.provider_id,
154
+ context: value.context,
155
+ matched: value.matched,
156
+ succeeded: value.succeeded,
157
+ failed: value.failed,
158
+ reason_codes: [...value.reason_codes],
159
+ },
160
+ };
161
+ }
162
+
163
+ function invalid(reason: string): PromptContextResultValidation {
164
+ return { ok: false, reason };
165
+ }
166
+
167
+ function isRecord(value: unknown): value is Record<string, unknown> {
168
+ return typeof value === "object" && value !== null && !Array.isArray(value);
169
+ }
170
+
171
+ function isBoundedInteger(value: unknown, min: number, max: number): value is number {
172
+ return Number.isInteger(value) && (value as number) >= min && (value as number) <= max;
173
+ }
174
+
175
+ function isCount(value: unknown): value is number {
176
+ return Number.isSafeInteger(value) && (value as number) >= 0;
177
+ }
@@ -0,0 +1,22 @@
1
+ export type {
2
+ PromptContextAuditV1,
3
+ PromptContextConfig,
4
+ PromptContextDelivery,
5
+ PromptContextRequestV1,
6
+ PromptContextResultV1,
7
+ PromptContextResultValidation,
8
+ } from "./contract.ts";
9
+ export {
10
+ buildPromptContextRequest,
11
+ DEFAULT_PROMPT_CONTEXT_MAX_OUTPUT_BYTES,
12
+ DEFAULT_PROMPT_CONTEXT_TIMEOUT_MS,
13
+ MAX_PROMPT_CONTEXT_OUTPUT_BYTES,
14
+ MAX_PROMPT_CONTEXT_TIMEOUT_MS,
15
+ PROMPT_CONTEXT_REQUEST_SCHEMA,
16
+ PROMPT_CONTEXT_RESULT_SCHEMA,
17
+ parsePromptContextConfig,
18
+ promptContextDelivery,
19
+ validatePromptContextResult,
20
+ } from "./contract.ts";
21
+ export type { PromptContextRunResult, RunPromptContextInput } from "./runner.ts";
22
+ export { runPromptContext } from "./runner.ts";
@@ -0,0 +1,303 @@
1
+ import { type ChildProcess, spawn } from "node:child_process";
2
+ import { createHmac } from "node:crypto";
3
+ import { existsSync, realpathSync, statSync } from "node:fs";
4
+ import { join, resolve } from "node:path";
5
+ import type { Adapter } from "../../adapter.ts";
6
+ import { hostPromptContextConfig } from "../../config.ts";
7
+ import { loadOrCreateFingerprintKeyStoreV3 } from "../../events/v3/fingerprint-keys.ts";
8
+ import { codexWslWorkspaceLinuxPath } from "../codex-wsl-bridge.ts";
9
+ import {
10
+ buildPromptContextRequest,
11
+ type PromptContextAuditV1,
12
+ type PromptContextDelivery,
13
+ type PromptContextResultV1,
14
+ promptContextDelivery,
15
+ validatePromptContextResult,
16
+ } from "./contract.ts";
17
+
18
+ const EXTENSION_RELATIVE_PATH = [
19
+ "scripts",
20
+ "hooks",
21
+ "harness",
22
+ "extensions",
23
+ "prompt-context",
24
+ ] as const;
25
+
26
+ const PROVIDER_ENV_ALLOWLIST = [
27
+ "COLORTERM",
28
+ "COMSPEC",
29
+ "HOME",
30
+ "LANG",
31
+ "LC_ALL",
32
+ "LC_CTYPE",
33
+ "LOGNAME",
34
+ "NO_COLOR",
35
+ "PATH",
36
+ "PATHEXT",
37
+ "SHELL",
38
+ "SYSTEMROOT",
39
+ "SystemRoot",
40
+ "TEMP",
41
+ "TERM",
42
+ "TMP",
43
+ "TMPDIR",
44
+ "TZ",
45
+ "USER",
46
+ "USERPROFILE",
47
+ "WINDIR",
48
+ "XDG_CACHE_HOME",
49
+ "XDG_CONFIG_HOME",
50
+ "XDG_DATA_HOME",
51
+ ] as const;
52
+
53
+ const RESULT_KEYS = [
54
+ "context",
55
+ "failed",
56
+ "matched",
57
+ "provider_id",
58
+ "reason_codes",
59
+ "schema",
60
+ "succeeded",
61
+ ] as const;
62
+
63
+ export interface RunPromptContextInput {
64
+ coordRoot: string;
65
+ adapter: Adapter;
66
+ sessionId: string;
67
+ turnId: string;
68
+ cwd: string;
69
+ prompt: string;
70
+ /** Test and embedding seam. Production callers should omit this. */
71
+ sourceEnv?: NodeJS.ProcessEnv;
72
+ }
73
+
74
+ export interface PromptContextRunResult {
75
+ context: string | null;
76
+ delivery: PromptContextDelivery;
77
+ audit: PromptContextAuditV1;
78
+ }
79
+
80
+ interface ChildResult {
81
+ kind: "closed" | "error" | "oversized" | "timeout";
82
+ stdout?: Buffer;
83
+ code?: number | null;
84
+ signal?: NodeJS.Signals | null;
85
+ }
86
+
87
+ /**
88
+ * Run one project-owned prompt-context provider behind Harnery's normalized
89
+ * prompt hook. Every provider failure returns metadata instead of throwing so
90
+ * optional context can never make the user's turn unusable.
91
+ */
92
+ export async function runPromptContext(
93
+ input: RunPromptContextInput,
94
+ ): Promise<PromptContextRunResult> {
95
+ const startedAt = Date.now();
96
+ const delivery = promptContextDelivery(input.adapter);
97
+ const finish = (
98
+ status: PromptContextAuditV1["status"],
99
+ fields: Omit<PromptContextAuditV1, "status" | "delivery" | "elapsed_ms"> = {},
100
+ context: string | null = null,
101
+ ): PromptContextRunResult => ({
102
+ context,
103
+ delivery,
104
+ audit: {
105
+ status,
106
+ delivery,
107
+ elapsed_ms: Math.max(0, Date.now() - startedAt),
108
+ ...fields,
109
+ },
110
+ });
111
+
112
+ try {
113
+ const coordRoot = realDirectory(input.coordRoot);
114
+ const config = hostPromptContextConfig(coordRoot);
115
+ if (!config?.enabled) return finish("disabled");
116
+ if (!input.prompt.trim()) return finish("no_prompt");
117
+
118
+ const executable = join(coordRoot, ...EXTENSION_RELATIVE_PATH);
119
+ if (!isRegularFile(executable)) return finish("missing_extension");
120
+
121
+ const reportedCwd =
122
+ input.adapter === "codex"
123
+ ? (codexWslWorkspaceLinuxPath(coordRoot, input.cwd) ?? input.cwd)
124
+ : input.cwd;
125
+ const cwd = realDirectory(reportedCwd);
126
+ const request = buildPromptContextRequest({
127
+ adapter: input.adapter,
128
+ sessionId: input.sessionId,
129
+ turnId: input.turnId,
130
+ cwd,
131
+ prompt: input.prompt,
132
+ });
133
+ const child = await runExtension({
134
+ executable,
135
+ cwd,
136
+ stdin: `${JSON.stringify(request)}\n`,
137
+ env: providerEnvironment(input.sourceEnv ?? process.env),
138
+ timeoutMs: config.timeoutMs,
139
+ maxOutputBytes: config.maxOutputBytes,
140
+ });
141
+
142
+ if (child.kind === "timeout") return finish("timeout");
143
+ if (child.kind === "oversized") return finish("oversized_result");
144
+ if (child.kind === "error") return finish("missing_extension");
145
+ if (child.signal) return finish("signal");
146
+ if (child.code !== 0) return finish("nonzero_exit");
147
+
148
+ const stdout = child.stdout ?? Buffer.alloc(0);
149
+ const outputBytes = stdout.byteLength;
150
+ let parsed: unknown;
151
+ try {
152
+ parsed = JSON.parse(stdout.toString("utf8"));
153
+ } catch {
154
+ return finish("invalid_result", { output_bytes: outputBytes });
155
+ }
156
+ if (!hasExactResultKeys(parsed)) {
157
+ return finish("invalid_result", { output_bytes: outputBytes });
158
+ }
159
+ const validated = validatePromptContextResult(parsed);
160
+ if (!validated.ok) return finish("invalid_result", { output_bytes: outputBytes });
161
+
162
+ const auditFields = providerAudit(validated.value, outputBytes);
163
+ if (!validated.value.context) return finish("empty", auditFields);
164
+
165
+ const contextFingerprint = fingerprintContext(coordRoot, validated.value.context);
166
+ return finish(
167
+ "delivered",
168
+ { ...auditFields, context_fingerprint: contextFingerprint },
169
+ validated.value.context,
170
+ );
171
+ } catch {
172
+ return finish("invalid_result");
173
+ }
174
+ }
175
+
176
+ function providerAudit(
177
+ result: PromptContextResultV1,
178
+ outputBytes: number,
179
+ ): Omit<PromptContextAuditV1, "status" | "delivery" | "elapsed_ms"> {
180
+ return {
181
+ provider_id: result.provider_id,
182
+ matched: result.matched,
183
+ succeeded: result.succeeded,
184
+ failed: result.failed,
185
+ reason_codes: [...result.reason_codes],
186
+ output_bytes: outputBytes,
187
+ };
188
+ }
189
+
190
+ function fingerprintContext(coordRoot: string, context: string): string {
191
+ const store = loadOrCreateFingerprintKeyStoreV3(coordRoot);
192
+ const epoch = store.epochs.find((candidate) => candidate.epoch_id === store.active_epoch_id);
193
+ if (!epoch) throw new Error("active fingerprint key is unavailable");
194
+ const key = Buffer.from(epoch.key_base64url, "base64url");
195
+ const digest = createHmac("sha256", key)
196
+ .update("harnery:prompt-context:v1\0", "utf8")
197
+ .update(context.normalize("NFC"), "utf8")
198
+ .digest("hex");
199
+ return `hmac-sha256:${digest}`;
200
+ }
201
+
202
+ function providerEnvironment(source: NodeJS.ProcessEnv): NodeJS.ProcessEnv {
203
+ const env: NodeJS.ProcessEnv = {};
204
+ for (const name of PROVIDER_ENV_ALLOWLIST) {
205
+ const value = source[name];
206
+ if (value !== undefined) env[name] = value;
207
+ }
208
+ return env;
209
+ }
210
+
211
+ function hasExactResultKeys(value: unknown): value is Record<string, unknown> {
212
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
213
+ const keys = Object.keys(value).sort();
214
+ return (
215
+ keys.length === RESULT_KEYS.length && keys.every((key, index) => key === RESULT_KEYS[index])
216
+ );
217
+ }
218
+
219
+ function realDirectory(path: string): string {
220
+ const real = realpathSync(resolve(path));
221
+ if (!statSync(real).isDirectory()) throw new Error("workspace is not a directory");
222
+ return real;
223
+ }
224
+
225
+ function isRegularFile(path: string): boolean {
226
+ if (!existsSync(path)) return false;
227
+ try {
228
+ return statSync(path).isFile();
229
+ } catch {
230
+ return false;
231
+ }
232
+ }
233
+
234
+ function runExtension(options: {
235
+ executable: string;
236
+ cwd: string;
237
+ stdin: string;
238
+ env: NodeJS.ProcessEnv;
239
+ timeoutMs: number;
240
+ maxOutputBytes: number;
241
+ }): Promise<ChildResult> {
242
+ return new Promise((resolveResult) => {
243
+ let settled = false;
244
+ let timedOut = false;
245
+ let oversized = false;
246
+ let stdoutBytes = 0;
247
+ const stdout: Buffer[] = [];
248
+
249
+ const finish = (result: ChildResult): void => {
250
+ if (settled) return;
251
+ settled = true;
252
+ clearTimeout(timer);
253
+ resolveResult(result);
254
+ };
255
+ const child = spawn(options.executable, [], {
256
+ cwd: options.cwd,
257
+ detached: process.platform !== "win32",
258
+ env: options.env,
259
+ shell: false,
260
+ stdio: ["pipe", "pipe", "ignore"],
261
+ windowsHide: true,
262
+ });
263
+ const timer = setTimeout(() => {
264
+ timedOut = true;
265
+ killExtension(child);
266
+ }, options.timeoutMs);
267
+
268
+ child.stdout.on("data", (chunk: Buffer | string) => {
269
+ const bytes = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
270
+ stdoutBytes += bytes.byteLength;
271
+ if (stdoutBytes > options.maxOutputBytes) {
272
+ oversized = true;
273
+ killExtension(child);
274
+ return;
275
+ }
276
+ stdout.push(bytes);
277
+ });
278
+ child.stdin.on("error", () => {
279
+ // The process outcome below remains authoritative. Broken input is
280
+ // represented as a nonzero exit, signal, or invalid empty result.
281
+ });
282
+ child.on("error", () => finish({ kind: "error" }));
283
+ child.on("close", (code, signal) => {
284
+ if (timedOut) return finish({ kind: "timeout" });
285
+ if (oversized) return finish({ kind: "oversized" });
286
+ return finish({ kind: "closed", stdout: Buffer.concat(stdout), code, signal });
287
+ });
288
+ child.stdin.end(options.stdin);
289
+ });
290
+ }
291
+
292
+ function killExtension(child: ChildProcess): void {
293
+ if (process.platform !== "win32" && child.pid) {
294
+ try {
295
+ process.kill(-child.pid, "SIGKILL");
296
+ return;
297
+ } catch {
298
+ // The process may have exited between the output/timeout boundary and
299
+ // this signal. Fall through to the ordinary child handle.
300
+ }
301
+ }
302
+ child.kill("SIGKILL");
303
+ }
@@ -6,14 +6,16 @@
6
6
  * full control of that explicit destination.
7
7
  */
8
8
 
9
- import { existsSync, readdirSync, readFileSync } from "node:fs";
10
- import { join, resolve } from "node:path";
9
+ import { existsSync, lstatSync, readdirSync, readFileSync } from "node:fs";
10
+ import { dirname, join, resolve } from "node:path";
11
11
  import type { HarneryProgramContext } from "../commander.ts";
12
12
  import { monorepoRoot } from "./agents/index.ts";
13
13
  import {
14
14
  ARTIFACT_MANIFEST,
15
15
  type ArtifactManifestV2,
16
+ artifactReviewGuidance,
16
17
  artifactsRoot,
18
+ autoCleanArtifacts,
17
19
  configuredArtifactRetentionDays,
18
20
  createArtifact,
19
21
  parseArtifactManifest,
@@ -21,6 +23,23 @@ import {
21
23
 
22
24
  export type QaArtifactKind = "qa-run" | "qa-record" | "review-pack";
23
25
 
26
+ /** Recognize managed outputs even when a detached child receives an explicit path. */
27
+ export function managedQaReviewGuidance(repoRoot: string, outParent: string): string | undefined {
28
+ const path = resolve(outParent);
29
+ if (dirname(path) !== artifactsRoot(repoRoot)) return undefined;
30
+ try {
31
+ if (
32
+ lstatSync(path).isSymbolicLink() ||
33
+ lstatSync(join(path, ARTIFACT_MANIFEST)).isSymbolicLink()
34
+ )
35
+ return undefined;
36
+ const manifest = readQaManifest(join(path, ARTIFACT_MANIFEST));
37
+ return manifest ? artifactReviewGuidance(repoRoot, manifest.artifact_id) : undefined;
38
+ } catch {
39
+ return undefined;
40
+ }
41
+ }
42
+
24
43
  export function resolveQaRepoRoot(context?: HarneryProgramContext): string {
25
44
  return resolve(context?.repoRoot ?? monorepoRoot() ?? process.cwd());
26
45
  }
@@ -28,8 +47,15 @@ export function resolveQaRepoRoot(context?: HarneryProgramContext): string {
28
47
  export function createManagedQaOutParent(
29
48
  repoRoot: string,
30
49
  kind: QaArtifactKind,
31
- opts: { retentionMinutes?: number } = {},
50
+ opts: { retentionMinutes?: number; onCleanupWarning?: (message: string) => void } = {},
32
51
  ): string {
52
+ try {
53
+ autoCleanArtifacts(repoRoot);
54
+ } catch (error) {
55
+ opts.onCleanupWarning?.(
56
+ `artifact cleanup skipped: ${error instanceof Error ? error.message : String(error)}`,
57
+ );
58
+ }
33
59
  return createArtifact(repoRoot, {
34
60
  slug: kind,
35
61
  purpose:
@@ -1,4 +1,4 @@
1
- export const RESOURCE_SNAPSHOT_SCHEMA_VERSION = 1;
1
+ export const RESOURCE_SNAPSHOT_SCHEMA_VERSION = 2;
2
2
  export const RESOURCE_SERVICE_STATUS_SCHEMA_VERSION = 1;
3
3
 
4
4
  export type ResourceSupportState = "supported" | "partial" | "unsupported" | "error";
@@ -29,6 +29,7 @@ export interface ResourceProcessGroup {
29
29
  }
30
30
 
31
31
  export interface ResourceMachineSample {
32
+ cpu_available_parallelism?: number;
32
33
  cpu_percent: number | null;
33
34
  cpu_logical_count: number;
34
35
  load_average: [number, number, number] | null;
@@ -38,7 +39,7 @@ export interface ResourceMachineSample {
38
39
  memory_percent: number | null;
39
40
  swap_total_bytes: number | null;
40
41
  swap_used_bytes: number | null;
41
- process_count: number;
42
+ process_count: number | null;
42
43
  }
43
44
 
44
45
  export interface ResourceSnapshot {
@@ -51,10 +52,16 @@ export interface ResourceSnapshot {
51
52
  namespace: "host" | "wsl" | "unknown";
52
53
  support: {
53
54
  state: ResourceSupportState;
54
- sampler: "procfs" | "unsupported";
55
+ sampler: "procfs" | "darwin" | "win32" | "unsupported";
55
56
  reason?: string;
56
57
  };
57
58
  machine: ResourceMachineSample;
59
+ disks?: ResourceDiskSample[];
60
+ pressure?: ResourcePressureSample;
61
+ oom?: ResourceOomSample;
62
+ vmstat?: ResourceVmstatSample;
63
+ io?: ResourceIoSample;
64
+ host?: ResourceHostSample;
58
65
  groups: ResourceProcessGroup[];
59
66
  processes: ResourceProcessSample[];
60
67
  visible_process_count: number;
@@ -62,6 +69,72 @@ export interface ResourceSnapshot {
62
69
  unattributed_process_count: number;
63
70
  }
64
71
 
72
+ export interface ResourceDiskSample {
73
+ path: string;
74
+ state: ResourceSupportState;
75
+ total_bytes: number | null;
76
+ available_bytes: number | null;
77
+ used_percent: number | null;
78
+ reason?: string;
79
+ }
80
+
81
+ export interface ResourcePressureWindow {
82
+ avg10: number;
83
+ avg60: number;
84
+ avg300: number;
85
+ }
86
+
87
+ export interface ResourcePressureSample {
88
+ state: ResourceSupportState;
89
+ /** The CPU, memory, and I/O fields contain the kernel's some-stall averages. */
90
+ cpu: ResourcePressureWindow | null;
91
+ memory: ResourcePressureWindow | null;
92
+ io: ResourcePressureWindow | null;
93
+ memory_full: ResourcePressureWindow | null;
94
+ io_full: ResourcePressureWindow | null;
95
+ reason?: string;
96
+ }
97
+
98
+ export interface ResourceOomSample {
99
+ state: ResourceSupportState;
100
+ total_kills: number | null;
101
+ kills_since_last_sample: number | null;
102
+ last_kill_age_ms: number | null;
103
+ reason?: string;
104
+ }
105
+
106
+ /**
107
+ * Kernel memory-reclaim activity as per-second rates, from one bounded
108
+ * `/proc/vmstat` read. Rates need two consecutive samples: the first sample
109
+ * after a start, an observer restart, or a counter reset reports
110
+ * `counters_reset` with null rates rather than inventing a baseline.
111
+ */
112
+ export interface ResourceVmstatSample {
113
+ state: ResourceSupportState;
114
+ swap_in_bytes_per_second: number | null;
115
+ swap_out_bytes_per_second: number | null;
116
+ direct_reclaim_pages_per_second: number | null;
117
+ major_faults_per_second: number | null;
118
+ counters_reset: boolean;
119
+ reason?: string;
120
+ }
121
+
122
+ export interface ResourceIoSample {
123
+ state: ResourceSupportState;
124
+ read_bytes_per_second: number | null;
125
+ write_bytes_per_second: number | null;
126
+ reason?: string;
127
+ }
128
+
129
+ export interface ResourceHostSample {
130
+ platform: "win32";
131
+ sampled_at: string;
132
+ state: ResourceSupportState;
133
+ machine: ResourceMachineSample | null;
134
+ disks: ResourceDiskSample[];
135
+ reason?: string;
136
+ }
137
+
65
138
  export interface ResourceServiceStatusRecord {
66
139
  schema_version: typeof RESOURCE_SERVICE_STATUS_SCHEMA_VERSION;
67
140
  pid: number;
@@ -2,4 +2,5 @@ export * from "./contract.ts";
2
2
  export * from "./sampler.ts";
3
3
  export * from "./service.ts";
4
4
  export * from "./service-status.ts";
5
+ export * from "./status.ts";
5
6
  export * from "./storage.ts";