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
@@ -19,9 +19,36 @@
19
19
  */
20
20
  import { spawnSync } from "node:child_process";
21
21
  import { randomBytes } from "node:crypto";
22
- import { existsSync, mkdirSync, writeFileSync } from "node:fs";
22
+ import { existsSync, lstatSync, mkdirSync, readdirSync, readFileSync, rmSync, writeFileSync, } from "node:fs";
23
+ import { hostname } from "node:os";
23
24
  import path from "node:path";
25
+ import { newestSnapshotTime, parseBackupDuration, recordHostSnapshot, } from "../core/backup/host-snapshot.js";
24
26
  import { backupConfig } from "../core/config.js";
27
+ import { createStorageCatalog } from "../core/storage/catalog.js";
28
+ export { hostSnapshotCachePath, newestSnapshotTime, parseBackupDuration, readHostSnapshotCache, } from "../core/backup/host-snapshot.js";
29
+ export const DEFAULT_BACKUP_MAX_BYTES = 50 * 1_024 * 1_024;
30
+ export const DEFAULT_BACKUP_CLASSES = new Set([
31
+ "canonical-authority",
32
+ "durable-object-history",
33
+ "recovery-state",
34
+ ]);
35
+ export const DEFAULT_BACKUP_EXCLUDED_CLASSES = new Set([
36
+ "debug-log",
37
+ "managed-artifact",
38
+ "operational-log",
39
+ "repairable-cache",
40
+ ]);
41
+ export const DEFAULT_BACKUP_EXCLUDED_FAMILY_IDS = new Set([
42
+ "event-v3-canonical-active",
43
+ "event-v3-canonical-archives",
44
+ "event-v3-support-active",
45
+ "event-v3-support-archives",
46
+ "event-v3-recovery-records",
47
+ "legacy-canonical-ledgers",
48
+ "managed-artifacts",
49
+ "captured-images",
50
+ "storage-exports",
51
+ ]);
25
52
  function defaultRepo() {
26
53
  return backupConfig().repo;
27
54
  }
@@ -48,6 +75,145 @@ function ensurePasswordFile(file) {
48
75
  const pw = randomBytes(24).toString("base64");
49
76
  writeFileSync(file, `${pw}\n`, { encoding: "utf-8", mode: 0o600 });
50
77
  }
78
+ function isFilesystemRepository(repo) {
79
+ if (/^[a-zA-Z]:[\\/]/.test(repo))
80
+ return true;
81
+ return !/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(repo);
82
+ }
83
+ function inside(base, candidate) {
84
+ const relative = path.relative(base, candidate);
85
+ return relative === "" || (!relative.startsWith("..") && !path.isAbsolute(relative));
86
+ }
87
+ function configPath(harneryDir, value) {
88
+ if (path.isAbsolute(value))
89
+ return null;
90
+ const normalized = value.replaceAll("\\", "/").replace(/^\.harnery\//, "");
91
+ if (!normalized || normalized.split("/").some((part) => part === ".." || part === "")) {
92
+ return null;
93
+ }
94
+ const resolved = path.resolve(harneryDir, normalized);
95
+ return inside(harneryDir, resolved) ? resolved : null;
96
+ }
97
+ export function resolveBackupSelection(projectRoot, config = backupConfig(projectRoot), includeArtifacts = false) {
98
+ const root = path.resolve(projectRoot);
99
+ const harneryDir = path.join(root, ".harnery");
100
+ const catalog = createStorageCatalog({ coord_root: root, project_root: root });
101
+ const knownFamilyIds = new Set(catalog.families.map((family) => family.id));
102
+ const configuredFamilyExclusions = new Set(config.exclude.filter((entry) => knownFamilyIds.has(entry)));
103
+ const configuredPathExclusions = config.exclude
104
+ .filter((entry) => !knownFamilyIds.has(entry))
105
+ .map((entry) => configPath(harneryDir, entry))
106
+ .filter((entry) => entry !== null);
107
+ const selectedFamilies = catalog.families.filter((family) => DEFAULT_BACKUP_CLASSES.has(family.storage_class) &&
108
+ !DEFAULT_BACKUP_EXCLUDED_FAMILY_IDS.has(family.id) &&
109
+ !configuredFamilyExclusions.has(family.id));
110
+ const excludedByPath = (candidate) => configuredPathExclusions.some((excluded) => candidate === excluded || inside(excluded, candidate));
111
+ const targets = selectedFamilies
112
+ .flatMap((family) => family.resolved_roots.map((storageRoot) => storageRoot.path))
113
+ .filter((candidate) => inside(harneryDir, candidate))
114
+ .filter((candidate) => !excludedByPath(candidate));
115
+ for (const entry of config.include) {
116
+ const candidate = configPath(harneryDir, entry);
117
+ if (candidate && !excludedByPath(candidate))
118
+ targets.push(candidate);
119
+ }
120
+ if (includeArtifacts)
121
+ targets.push(path.join(harneryDir, "artifacts"));
122
+ return {
123
+ targets: [...new Set(targets)].filter(existsSync).sort(),
124
+ familyIds: selectedFamilies.map((family) => family.id).sort(),
125
+ };
126
+ }
127
+ export function backupCatalogCoverage(projectRoot) {
128
+ const root = path.resolve(projectRoot);
129
+ const harneryDir = path.join(root, ".harnery");
130
+ const catalog = createStorageCatalog({ coord_root: root, project_root: root });
131
+ const uncovered = catalog.families
132
+ .filter((family) => {
133
+ const selected = DEFAULT_BACKUP_CLASSES.has(family.storage_class) &&
134
+ !DEFAULT_BACKUP_EXCLUDED_FAMILY_IDS.has(family.id);
135
+ const excluded = DEFAULT_BACKUP_EXCLUDED_CLASSES.has(family.storage_class) ||
136
+ DEFAULT_BACKUP_EXCLUDED_FAMILY_IDS.has(family.id);
137
+ const externalOnly = family.resolved_roots.length === 0 ||
138
+ family.resolved_roots.every((storageRoot) => !inside(harneryDir, storageRoot.path));
139
+ return !selected && !excluded && !externalOnly;
140
+ })
141
+ .map((family) => family.id);
142
+ return { uncovered };
143
+ }
144
+ export function selectedLogicalBytes(targets) {
145
+ const visited = new Set();
146
+ const measure = (candidate) => {
147
+ let stat;
148
+ try {
149
+ stat = lstatSync(candidate);
150
+ }
151
+ catch {
152
+ return 0;
153
+ }
154
+ const identity = `${stat.dev}:${stat.ino}`;
155
+ if (visited.has(identity))
156
+ return 0;
157
+ visited.add(identity);
158
+ if (stat.isSymbolicLink())
159
+ return 0;
160
+ if (stat.isFile())
161
+ return stat.size;
162
+ if (!stat.isDirectory())
163
+ return 0;
164
+ return readdirSync(candidate).reduce((total, entry) => total + measure(path.join(candidate, entry)), 0);
165
+ };
166
+ return targets.reduce((total, target) => total + measure(target), 0);
167
+ }
168
+ function lockOwnerIsAlive(lockDir) {
169
+ try {
170
+ const owner = JSON.parse(readFileSync(path.join(lockDir, "owner.json"), "utf8"));
171
+ if (typeof owner.pid === "number" && owner.pid > 0) {
172
+ try {
173
+ process.kill(owner.pid, 0);
174
+ return true;
175
+ }
176
+ catch {
177
+ // The owner is gone; the directory is reclaimable.
178
+ }
179
+ }
180
+ const createdAt = typeof owner.created_at === "string" ? Date.parse(owner.created_at) : 0;
181
+ return Number.isFinite(createdAt) && Date.now() - createdAt < 60 * 60 * 1_000;
182
+ }
183
+ catch {
184
+ return false;
185
+ }
186
+ }
187
+ function acquireSnapshotLock(harneryDir) {
188
+ const locksDir = path.join(harneryDir, "locks");
189
+ const lockDir = path.join(locksDir, "backup-snapshot.lock");
190
+ mkdirSync(locksDir, { recursive: true });
191
+ const create = () => {
192
+ try {
193
+ mkdirSync(lockDir);
194
+ writeFileSync(path.join(lockDir, "owner.json"), `${JSON.stringify({ pid: process.pid, created_at: new Date().toISOString() })}\n`, "utf8");
195
+ return true;
196
+ }
197
+ catch (error) {
198
+ if (error.code !== "EEXIST")
199
+ throw error;
200
+ return false;
201
+ }
202
+ };
203
+ if (!create()) {
204
+ if (lockOwnerIsAlive(lockDir))
205
+ return { acquired: false, release() { } };
206
+ rmSync(lockDir, { recursive: true, force: true });
207
+ if (!create())
208
+ return { acquired: false, release() { } };
209
+ }
210
+ return {
211
+ acquired: true,
212
+ release() {
213
+ rmSync(lockDir, { recursive: true, force: true });
214
+ },
215
+ };
216
+ }
51
217
  function runRestic(args, opts = {}) {
52
218
  const repo = opts.repo ?? defaultRepo();
53
219
  const pwFile = opts.passwordFile ?? defaultPasswordFile();
@@ -96,7 +262,8 @@ export function registerBackupCommand(program, emit) {
96
262
  const repo = opts.repo ?? defaultRepo();
97
263
  const pwFile = opts.passwordFile ?? defaultPasswordFile();
98
264
  ensurePasswordFile(pwFile);
99
- mkdirSync(path.dirname(repo), { recursive: true });
265
+ if (isFilesystemRepository(repo))
266
+ mkdirSync(path.dirname(repo), { recursive: true });
100
267
  const r = runRestic(["init"], { repo, passwordFile: pwFile, stdio: "inherit" });
101
268
  if (r.exitCode === 0) {
102
269
  emit.text(`restic repo initialized at ${repo}\npassword file: ${pwFile}`);
@@ -113,13 +280,15 @@ export function registerBackupCommand(program, emit) {
113
280
  .option("--repo <path>", "Repository path")
114
281
  .option("--password-file <path>", "Password file")
115
282
  .option("--include-artifacts", "Include managed working artifacts (default: excluded; potentially large + ephemeral)")
283
+ .option("--allow-large", "Permit a selected set larger than backup.max_bytes")
284
+ .option("--if-stale <duration>", "Skip when this host has a newer snapshot (for example 24h)")
116
285
  .action((opts) => {
117
286
  if (!checkRestic(emit)) {
118
287
  emit.setExitCode(1);
119
288
  return;
120
289
  }
121
- const harnery = findHarneryDir();
122
- if (!harnery) {
290
+ const harneryDir = findHarneryDir();
291
+ if (!harneryDir) {
123
292
  emit.error({
124
293
  code: "target_missing",
125
294
  message: "No .harnery/ found above cwd; run from an initialized project",
@@ -127,40 +296,77 @@ export function registerBackupCommand(program, emit) {
127
296
  emit.setExitCode(1);
128
297
  return;
129
298
  }
130
- const passThrough = [];
131
- for (const t of opts.tag) {
132
- passThrough.push("--tag", t);
133
- }
134
- const safeTargets = [
135
- "ledgers",
136
- "councils",
137
- "journal",
138
- "work",
139
- "workflows",
140
- "decisions",
141
- "config.jsonc",
142
- ".name-history",
143
- ]
144
- .map((entry) => path.join(harnery, entry))
145
- .filter(existsSync);
146
- if (opts.includeArtifacts && existsSync(path.join(harnery, "artifacts"))) {
147
- safeTargets.push(path.join(harnery, "artifacts"));
148
- }
149
- if (safeTargets.length === 0) {
299
+ const staleMs = opts.ifStale ? parseBackupDuration(opts.ifStale) : null;
300
+ if (opts.ifStale && staleMs === null) {
150
301
  emit.error({
151
- code: "backup_empty",
152
- message: "No durable V3 state is available to back up",
302
+ code: "backup_invalid_duration",
303
+ message: `Invalid --if-stale duration: ${opts.ifStale}`,
304
+ hint: "Use an integer duration such as 30m, 24h, or 7d",
153
305
  });
154
306
  emit.setExitCode(1);
155
307
  return;
156
308
  }
157
- const r = runRestic(["backup", ...safeTargets], {
158
- repo: opts.repo,
159
- passwordFile: opts.passwordFile,
160
- stdio: "inherit",
161
- passThrough,
162
- });
163
- emit.setExitCode(r.exitCode);
309
+ const lock = acquireSnapshotLock(harneryDir);
310
+ if (!lock.acquired) {
311
+ emit.text("backup snapshot already running; skipped");
312
+ return;
313
+ }
314
+ try {
315
+ if (staleMs !== null) {
316
+ const latest = runRestic(["snapshots", "--json", "--host", hostname()], {
317
+ repo: opts.repo,
318
+ passwordFile: opts.passwordFile,
319
+ stdio: "pipe",
320
+ });
321
+ if (latest.exitCode !== 0) {
322
+ emit.error({ code: "backup_snapshot_list_failed", message: latest.stdout.trim() });
323
+ emit.setExitCode(latest.exitCode);
324
+ return;
325
+ }
326
+ const newest = newestSnapshotTime(latest.stdout);
327
+ if (newest !== null && Date.now() - newest < staleMs) {
328
+ recordHostSnapshot(harneryDir, newest);
329
+ emit.text(`latest snapshot for ${hostname()} is newer than ${opts.ifStale}; skipped`);
330
+ return;
331
+ }
332
+ }
333
+ const config = backupConfig(path.dirname(harneryDir));
334
+ const selection = resolveBackupSelection(path.dirname(harneryDir), config, opts.includeArtifacts);
335
+ if (selection.targets.length === 0) {
336
+ emit.error({
337
+ code: "backup_empty",
338
+ message: "No durable Harnery state is available to back up",
339
+ });
340
+ emit.setExitCode(1);
341
+ return;
342
+ }
343
+ const logicalBytes = selectedLogicalBytes(selection.targets);
344
+ if (!opts.allowLarge && logicalBytes > config.maxBytes) {
345
+ emit.error({
346
+ code: "backup_too_large",
347
+ message: `Selected backup is ${logicalBytes} bytes; limit is ${config.maxBytes} bytes`,
348
+ hint: "Review backup.include/exclude or pass --allow-large for this snapshot",
349
+ });
350
+ emit.setExitCode(1);
351
+ return;
352
+ }
353
+ const passThrough = [];
354
+ for (const tag of opts.tag)
355
+ passThrough.push("--tag", tag);
356
+ const startedAt = Date.now();
357
+ const result = runRestic(["backup", ...selection.targets], {
358
+ repo: opts.repo,
359
+ passwordFile: opts.passwordFile,
360
+ stdio: "inherit",
361
+ passThrough,
362
+ });
363
+ if (result.exitCode === 0)
364
+ recordHostSnapshot(harneryDir, startedAt);
365
+ emit.setExitCode(result.exitCode);
366
+ }
367
+ finally {
368
+ lock.release();
369
+ }
164
370
  });
165
371
  // -- list --
166
372
  backup
@@ -1,4 +1,12 @@
1
1
  import type { Command } from "commander";
2
2
  import type { EmitContext, HarneryProgramContext } from "../commander.js";
3
3
  export declare function registerBrowseCommand(program: Command, emitParam: EmitContext, context?: HarneryProgramContext, binName?: string): void;
4
+ /**
5
+ * Capture this render into a page review pack: one full-page screenshot,
6
+ * budgeted native tiles, one candidate set per
7
+ * --review-pack-scope selector, the serialized DOM, and the QA signature —
8
+ * all written to disk, with no vision call. The judge stage reads them back
9
+ * once the browser is gone.
10
+ */
11
+ export declare const REVIEW_CAPTURE_RECIPE = "native-full-page-scroll-probe/v2";
4
12
  //# sourceMappingURL=browse.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"browse.d.ts","sourceRoot":"","sources":["../../src/commands/browse.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AA8P1E,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,WAAW,EACtB,OAAO,CAAC,EAAE,qBAAqB,EAC/B,OAAO,SAAmB,GACzB,IAAI,CA+fN"}
1
+ {"version":3,"file":"browse.d.ts","sourceRoot":"","sources":["../../src/commands/browse.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAkS1E,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,WAAW,EACtB,OAAO,CAAC,EAAE,qBAAqB,EAC/B,OAAO,SAAmB,GACzB,IAAI,CAugBN;AAuzDD;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB,qCAAqC,CAAC"}