harnery 0.29.0 → 0.31.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 (512) hide show
  1. package/README.md +4 -4
  2. package/dist/commander.d.ts +8 -0
  3. package/dist/commander.d.ts.map +1 -1
  4. package/dist/commander.js +14 -13
  5. package/dist/commands/adapter.d.ts +12 -0
  6. package/dist/commands/adapter.d.ts.map +1 -0
  7. package/dist/commands/{harness.js → adapter.js} +35 -35
  8. package/dist/commands/agents.d.ts +3 -2
  9. package/dist/commands/agents.d.ts.map +1 -1
  10. package/dist/commands/agents.js +61 -60
  11. package/dist/commands/artifacts.d.ts +4 -0
  12. package/dist/commands/artifacts.d.ts.map +1 -0
  13. package/dist/commands/artifacts.js +143 -0
  14. package/dist/commands/backup.d.ts +1 -1
  15. package/dist/commands/backup.d.ts.map +1 -1
  16. package/dist/commands/backup.js +5 -2
  17. package/dist/commands/browse.d.ts.map +1 -1
  18. package/dist/commands/browse.js +310 -7
  19. package/dist/commands/checkpoint.d.ts +12 -0
  20. package/dist/commands/checkpoint.d.ts.map +1 -0
  21. package/dist/commands/checkpoint.js +162 -0
  22. package/dist/commands/context.d.ts +2 -2
  23. package/dist/commands/context.d.ts.map +1 -1
  24. package/dist/commands/context.js +3 -151
  25. package/dist/commands/decision.d.ts.map +1 -1
  26. package/dist/commands/decision.js +31 -7
  27. package/dist/commands/deinit.d.ts +2 -2
  28. package/dist/commands/deinit.js +15 -15
  29. package/dist/commands/doctor.js +23 -23
  30. package/dist/commands/governor.d.ts +4 -0
  31. package/dist/commands/governor.d.ts.map +1 -0
  32. package/dist/commands/{supervisor.js → governor.js} +133 -108
  33. package/dist/commands/init.d.ts +12 -12
  34. package/dist/commands/init.d.ts.map +1 -1
  35. package/dist/commands/init.js +44 -30
  36. package/dist/commands/{session.d.ts → journal.d.ts} +2 -2
  37. package/dist/commands/journal.d.ts.map +1 -0
  38. package/dist/commands/{scratch.js → journal.js} +47 -47
  39. package/dist/commands/policy.js +1 -1
  40. package/dist/commands/presence.js +2 -2
  41. package/dist/commands/sync.d.ts +1 -1
  42. package/dist/commands/sync.js +3 -3
  43. package/dist/commands/tunnel.d.ts +16 -0
  44. package/dist/commands/tunnel.d.ts.map +1 -1
  45. package/dist/commands/tunnel.js +193 -23
  46. package/dist/commands/web-fetch.js +1 -1
  47. package/dist/commands/web.d.ts +19 -0
  48. package/dist/commands/web.d.ts.map +1 -1
  49. package/dist/commands/web.js +51 -0
  50. package/dist/commands/work.d.ts +2 -1
  51. package/dist/commands/work.d.ts.map +1 -1
  52. package/dist/commands/work.js +55 -25
  53. package/dist/commands/workflow.d.ts.map +1 -1
  54. package/dist/commands/workflow.js +35 -28
  55. package/dist/core/{harnesses → adapters}/attest-projection.d.ts +2 -2
  56. package/dist/core/adapters/attest-projection.d.ts.map +1 -0
  57. package/dist/core/{harnesses → adapters}/attest.d.ts +16 -16
  58. package/dist/core/adapters/attest.d.ts.map +1 -0
  59. package/dist/core/{harnesses → adapters}/attest.js +9 -9
  60. package/dist/core/{harnesses → adapters}/attestation.d.ts +16 -16
  61. package/dist/core/adapters/attestation.d.ts.map +1 -0
  62. package/dist/core/{harnesses → adapters}/attestation.js +20 -20
  63. package/dist/core/{harnesses → adapters}/bench.d.ts +12 -12
  64. package/dist/core/adapters/bench.d.ts.map +1 -0
  65. package/dist/core/{harnesses → adapters}/bench.js +12 -12
  66. package/dist/core/adapters/index.d.ts +13 -0
  67. package/dist/core/adapters/index.d.ts.map +1 -0
  68. package/dist/core/adapters/index.js +6 -0
  69. package/dist/core/{harnesses → adapters}/profiles.d.ts +11 -11
  70. package/dist/core/adapters/profiles.d.ts.map +1 -0
  71. package/dist/core/{harnesses → adapters}/profiles.js +11 -11
  72. package/dist/core/adapters/registry.d.ts +15 -0
  73. package/dist/core/adapters/registry.d.ts.map +1 -0
  74. package/dist/core/{harnesses → adapters}/registry.js +11 -11
  75. package/dist/core/{harnesses → adapters}/types.d.ts +28 -23
  76. package/dist/core/adapters/types.d.ts.map +1 -0
  77. package/dist/core/{harnesses → adapters}/types.js +1 -1
  78. package/dist/core/agents/canonical-emit.d.ts +4 -4
  79. package/dist/core/agents/canonical-emit.js +5 -5
  80. package/dist/core/agents/cli-emit.js +1 -1
  81. package/dist/core/agents/cli.js +30 -26
  82. package/dist/core/agents/codex-replay.d.ts +1 -1
  83. package/dist/core/agents/codex-replay.js +6 -6
  84. package/dist/core/agents/coord-client.d.ts +21 -2
  85. package/dist/core/agents/coord-client.d.ts.map +1 -1
  86. package/dist/core/agents/coord-client.js +122 -27
  87. package/dist/core/agents/events/consume.d.ts +1 -1
  88. package/dist/core/agents/events/emit.d.ts +5 -6
  89. package/dist/core/agents/events/emit.d.ts.map +1 -1
  90. package/dist/core/agents/events/emit.js +2 -2
  91. package/dist/core/agents/render/prompt-context.d.ts +21 -9
  92. package/dist/core/agents/render/prompt-context.d.ts.map +1 -1
  93. package/dist/core/agents/render/prompt-context.js +82 -30
  94. package/dist/core/agents/render/session-context.d.ts +1 -1
  95. package/dist/core/agents/render/session-context.js +5 -5
  96. package/dist/core/agents/rules/claim-conflict.d.ts +2 -6
  97. package/dist/core/agents/rules/claim-conflict.d.ts.map +1 -1
  98. package/dist/core/agents/rules/claim-conflict.js +1 -1
  99. package/dist/core/agents/rules/commit-conflict.js +98 -22
  100. package/dist/core/agents/rules/stop-hook.d.ts +9 -9
  101. package/dist/core/agents/rules/stop-hook.d.ts.map +1 -1
  102. package/dist/core/agents/rules/stop-hook.js +23 -5
  103. package/dist/core/agents/rules/verdict.d.ts +14 -0
  104. package/dist/core/agents/rules/verdict.d.ts.map +1 -0
  105. package/dist/core/agents/rules/verdict.js +1 -0
  106. package/dist/core/agents/session-events.js +3 -3
  107. package/dist/core/agents/state/council.d.ts +1 -1
  108. package/dist/core/agents/state/council.js +1 -1
  109. package/dist/core/agents/state/heartbeat-projector.d.ts +3 -2
  110. package/dist/core/agents/state/heartbeat-projector.d.ts.map +1 -1
  111. package/dist/core/agents/state/heartbeat-projector.js +14 -10
  112. package/dist/core/agents/state/heartbeat-writer.d.ts +1 -1
  113. package/dist/core/agents/state/heartbeat-writer.js +12 -12
  114. package/dist/core/agents/state/{scratch.d.ts → journal.d.ts} +7 -7
  115. package/dist/core/agents/state/{scratch.d.ts.map → journal.d.ts.map} +1 -1
  116. package/dist/core/agents/state/{scratch.js → journal.js} +12 -12
  117. package/dist/core/agents/state/pidmap.d.ts +28 -4
  118. package/dist/core/agents/state/pidmap.d.ts.map +1 -1
  119. package/dist/core/agents/state/pidmap.js +130 -15
  120. package/dist/core/agents/state/proc-start.d.ts +95 -0
  121. package/dist/core/agents/state/proc-start.d.ts.map +1 -0
  122. package/dist/core/agents/state/proc-start.js +199 -0
  123. package/dist/core/agents/state/shell-mutation.d.ts +1 -1
  124. package/dist/core/agents/state/shell-mutation.js +1 -1
  125. package/dist/core/agents/state/stale-sweep.js +7 -7
  126. package/dist/core/artifacts/index.d.ts +86 -0
  127. package/dist/core/artifacts/index.d.ts.map +1 -0
  128. package/dist/core/artifacts/index.js +421 -0
  129. package/dist/core/config.d.ts +9 -2
  130. package/dist/core/config.d.ts.map +1 -1
  131. package/dist/core/config.js +26 -2
  132. package/dist/core/context/index.d.ts +12 -12
  133. package/dist/core/context/index.js +10 -10
  134. package/dist/core/governor/adapter-spread.d.ts +52 -0
  135. package/dist/core/governor/adapter-spread.d.ts.map +1 -0
  136. package/dist/core/governor/adapter-spread.js +52 -0
  137. package/dist/core/governor/index.d.ts +7 -0
  138. package/dist/core/governor/index.d.ts.map +1 -0
  139. package/dist/core/governor/index.js +6 -0
  140. package/dist/core/governor/plan-api.d.ts +38 -0
  141. package/dist/core/governor/plan-api.d.ts.map +1 -0
  142. package/dist/core/governor/plan-api.js +83 -0
  143. package/dist/core/governor/plan-read.d.ts +5 -0
  144. package/dist/core/governor/plan-read.d.ts.map +1 -0
  145. package/dist/core/{supervisor → governor}/plan-read.js +71 -51
  146. package/dist/core/governor/plan-types.d.ts +181 -0
  147. package/dist/core/governor/plan-types.d.ts.map +1 -0
  148. package/dist/core/{supervisor → governor}/plan-types.js +4 -4
  149. package/dist/core/governor/planning.d.ts +48 -0
  150. package/dist/core/governor/planning.d.ts.map +1 -0
  151. package/dist/core/{supervisor → governor}/planning.js +143 -94
  152. package/dist/core/governor/read.d.ts +6 -0
  153. package/dist/core/governor/read.d.ts.map +1 -0
  154. package/dist/core/governor/read.js +4 -0
  155. package/dist/core/governor/runner.d.ts +37 -0
  156. package/dist/core/governor/runner.d.ts.map +1 -0
  157. package/dist/core/{supervisor → governor}/runner.js +15 -15
  158. package/dist/core/governor/service-read.d.ts +6 -0
  159. package/dist/core/governor/service-read.d.ts.map +1 -0
  160. package/dist/core/{supervisor → governor}/service-read.js +12 -12
  161. package/dist/core/governor/service.d.ts +114 -0
  162. package/dist/core/governor/service.d.ts.map +1 -0
  163. package/dist/core/{supervisor → governor}/service.js +57 -57
  164. package/dist/core/governor/state.d.ts +116 -0
  165. package/dist/core/governor/state.d.ts.map +1 -0
  166. package/dist/core/{supervisor → governor}/state.js +290 -116
  167. package/dist/core/hooks/adapter/detect.d.ts +9 -0
  168. package/dist/core/hooks/{harness → adapter}/detect.d.ts.map +1 -1
  169. package/dist/core/hooks/{harness → adapter}/detect.js +8 -8
  170. package/dist/core/hooks/{harness → adapter}/events.d.ts +15 -14
  171. package/dist/core/hooks/adapter/events.d.ts.map +1 -0
  172. package/dist/core/hooks/{harness → adapter}/events.js +5 -5
  173. package/dist/core/hooks/{harness → adapter}/output.d.ts +20 -14
  174. package/dist/core/hooks/adapter/output.d.ts.map +1 -0
  175. package/dist/core/hooks/{harness → adapter}/output.js +30 -22
  176. package/dist/core/hooks/{harness → adapter}/parse.d.ts +5 -5
  177. package/dist/core/hooks/{harness → adapter}/parse.d.ts.map +1 -1
  178. package/dist/core/hooks/{harness → adapter}/parse.js +4 -4
  179. package/dist/core/hooks/{harness → adapter}/wiring.d.ts +15 -15
  180. package/dist/core/hooks/{harness → adapter}/wiring.d.ts.map +1 -1
  181. package/dist/core/hooks/{harness → adapter}/wiring.js +13 -13
  182. package/dist/core/hooks/cli.d.ts +3 -3
  183. package/dist/core/hooks/cli.js +175 -151
  184. package/dist/core/hooks/effects/image-capture.d.ts +5 -5
  185. package/dist/core/hooks/effects/image-capture.d.ts.map +1 -1
  186. package/dist/core/hooks/effects/image-capture.js +3 -3
  187. package/dist/core/hooks/effects/index.d.ts +12 -12
  188. package/dist/core/hooks/effects/index.d.ts.map +1 -1
  189. package/dist/core/hooks/effects/index.js +17 -17
  190. package/dist/core/hooks/events/emit.d.ts +2 -2
  191. package/dist/core/hooks/events/emit.d.ts.map +1 -1
  192. package/dist/core/hooks/events/emit.js +1 -1
  193. package/dist/core/hooks/events/rotate.js +1 -1
  194. package/dist/core/hooks/events/schema.d.ts +13 -5
  195. package/dist/core/hooks/events/schema.d.ts.map +1 -1
  196. package/dist/core/hooks/guard-path.d.ts +2 -2
  197. package/dist/core/hooks/guard-path.js +2 -2
  198. package/dist/core/hooks/index.d.ts +1 -1
  199. package/dist/core/hooks/index.d.ts.map +1 -1
  200. package/dist/core/hooks/resolve/anchor.d.ts +14 -5
  201. package/dist/core/hooks/resolve/anchor.d.ts.map +1 -1
  202. package/dist/core/hooks/resolve/anchor.js +64 -7
  203. package/dist/core/hooks/resolve/coord-root.d.ts +3 -3
  204. package/dist/core/hooks/resolve/coord-root.js +4 -4
  205. package/dist/core/hooks/resolve/intent.js +1 -1
  206. package/dist/core/hooks/resolve/owner.d.ts +1 -1
  207. package/dist/core/hooks/resolve/owner.d.ts.map +1 -1
  208. package/dist/core/hooks/resolve/owner.js +11 -5
  209. package/dist/core/{scratch → journal}/index.d.ts +25 -25
  210. package/dist/core/{scratch → journal}/index.d.ts.map +1 -1
  211. package/dist/core/{scratch → journal}/index.js +38 -38
  212. package/dist/core/policy/evaluate.d.ts +1 -1
  213. package/dist/core/policy/evaluate.d.ts.map +1 -1
  214. package/dist/core/policy/evaluate.js +7 -7
  215. package/dist/core/policy/types.d.ts +3 -3
  216. package/dist/core/policy/types.d.ts.map +1 -1
  217. package/dist/core/work/runner.d.ts.map +1 -1
  218. package/dist/core/work/runner.js +11 -2
  219. package/dist/core/work/state.d.ts +28 -3
  220. package/dist/core/work/state.d.ts.map +1 -1
  221. package/dist/core/work/state.js +148 -16
  222. package/dist/core/workflow/adapters.d.ts +17 -0
  223. package/dist/core/workflow/adapters.d.ts.map +1 -0
  224. package/dist/core/workflow/adapters.js +21 -0
  225. package/dist/core/workflow/approvals.js +6 -6
  226. package/dist/core/workflow/billing.d.ts +9 -9
  227. package/dist/core/workflow/billing.js +9 -9
  228. package/dist/core/workflow/child-env.d.ts +10 -2
  229. package/dist/core/workflow/child-env.d.ts.map +1 -1
  230. package/dist/core/workflow/child-env.js +12 -4
  231. package/dist/core/workflow/engine.d.ts +15 -5
  232. package/dist/core/workflow/engine.d.ts.map +1 -1
  233. package/dist/core/workflow/engine.js +151 -83
  234. package/dist/core/workflow/evidence-preflight.d.ts +24 -0
  235. package/dist/core/workflow/evidence-preflight.d.ts.map +1 -0
  236. package/dist/core/workflow/evidence-preflight.js +134 -0
  237. package/dist/core/workflow/index.d.ts +3 -2
  238. package/dist/core/workflow/index.d.ts.map +1 -1
  239. package/dist/core/workflow/index.js +2 -1
  240. package/dist/core/workflow/proof.d.ts +28 -5
  241. package/dist/core/workflow/proof.d.ts.map +1 -1
  242. package/dist/core/workflow/proof.js +77 -34
  243. package/dist/core/workflow/run-state.d.ts +1 -1
  244. package/dist/core/workflow/run-state.js +7 -7
  245. package/dist/core/workflow/sandbox-projection.d.ts +6 -6
  246. package/dist/core/workflow/sandbox-projection.d.ts.map +1 -1
  247. package/dist/core/workflow/sandbox-projection.js +11 -11
  248. package/dist/core/workflow/spawn-claude.d.ts +3 -3
  249. package/dist/core/workflow/spawn-claude.d.ts.map +1 -1
  250. package/dist/core/workflow/spawn-claude.js +28 -8
  251. package/dist/core/workflow/spawn-codex.d.ts +4 -4
  252. package/dist/core/workflow/spawn-codex.d.ts.map +1 -1
  253. package/dist/core/workflow/spawn-codex.js +26 -8
  254. package/dist/core/workflow/spawn-cursor.d.ts +4 -4
  255. package/dist/core/workflow/spawn-cursor.d.ts.map +1 -1
  256. package/dist/core/workflow/spawn-cursor.js +27 -8
  257. package/dist/core/workflow/spawn-failure.d.ts +15 -1
  258. package/dist/core/workflow/spawn-failure.d.ts.map +1 -1
  259. package/dist/core/workflow/spawn-failure.js +35 -1
  260. package/dist/core/workflow/specialists.js +2 -2
  261. package/dist/core/workflow/{journal.d.ts → transcript.d.ts} +8 -8
  262. package/dist/core/workflow/transcript.d.ts.map +1 -0
  263. package/dist/core/workflow/{journal.js → transcript.js} +14 -14
  264. package/dist/core/workflow/types.d.ts +119 -46
  265. package/dist/core/workflow/types.d.ts.map +1 -1
  266. package/dist/core/workflow/types.js +11 -1
  267. package/dist/core/workflow/validate.d.ts +1 -1
  268. package/dist/core/workflow/validate.js +1 -1
  269. package/dist/core/workflow/workspaces/cancellation.js +2 -2
  270. package/dist/core/workflow/workspaces/cleanup.js +2 -2
  271. package/dist/core/workflow/workspaces/execution.js +6 -6
  272. package/dist/core/workflow/workspaces/inspect.js +9 -9
  273. package/dist/core/workflow/workspaces/integration.js +14 -14
  274. package/dist/core/workflow/workspaces/lifecycle.d.ts +1 -1
  275. package/dist/core/workflow/workspaces/lifecycle.d.ts.map +1 -1
  276. package/dist/core/workflow/workspaces/lifecycle.js +9 -9
  277. package/dist/core/workflow/workspaces/local-git.d.ts.map +1 -1
  278. package/dist/core/workflow/workspaces/local-git.js +39 -5
  279. package/dist/core/workflow/workspaces/recovery.js +3 -3
  280. package/dist/core/workflow/workspaces/state.d.ts +1 -1
  281. package/dist/core/workflow/workspaces/state.d.ts.map +1 -1
  282. package/dist/core/workflow/workspaces/state.js +3 -3
  283. package/dist/core/workflow/workspaces/types.d.ts +1 -1
  284. package/dist/core/workflow/workspaces/types.d.ts.map +1 -1
  285. package/dist/lib/browser/asserts.d.ts +28 -0
  286. package/dist/lib/browser/asserts.d.ts.map +1 -0
  287. package/dist/lib/browser/asserts.js +152 -0
  288. package/dist/lib/browser/client.d.ts +49 -0
  289. package/dist/lib/browser/client.d.ts.map +1 -1
  290. package/dist/lib/browser/client.js +155 -14
  291. package/dist/lib/browser/content-checks.d.ts +108 -0
  292. package/dist/lib/browser/content-checks.d.ts.map +1 -0
  293. package/dist/lib/browser/content-checks.js +474 -0
  294. package/dist/lib/browser/critique.d.ts +91 -0
  295. package/dist/lib/browser/critique.d.ts.map +1 -0
  296. package/dist/lib/browser/critique.js +167 -0
  297. package/dist/lib/browser/geometry.d.ts +32 -0
  298. package/dist/lib/browser/geometry.d.ts.map +1 -1
  299. package/dist/lib/browser/geometry.js +244 -1
  300. package/dist/lib/browser/index.d.ts +4 -1
  301. package/dist/lib/browser/index.d.ts.map +1 -1
  302. package/dist/lib/browser/index.js +2 -0
  303. package/dist/lib/claude-desktop.d.ts.map +1 -1
  304. package/dist/lib/claude-desktop.js +4 -1
  305. package/dist/lib/council/index.d.ts +6 -6
  306. package/dist/lib/council/index.d.ts.map +1 -1
  307. package/dist/lib/council/index.js +8 -8
  308. package/dist/lib/exec.d.ts +7 -0
  309. package/dist/lib/exec.d.ts.map +1 -1
  310. package/dist/lib/exec.js +6 -3
  311. package/dist/lib/identities/assume.d.ts +2 -2
  312. package/dist/lib/identities/assume.js +7 -7
  313. package/dist/lib/instructions/apply.d.ts +3 -3
  314. package/dist/lib/instructions/apply.d.ts.map +1 -1
  315. package/dist/lib/instructions/apply.js +75 -27
  316. package/dist/lib/instructions/host-addendum.d.ts +54 -0
  317. package/dist/lib/instructions/host-addendum.d.ts.map +1 -0
  318. package/dist/lib/instructions/host-addendum.js +107 -0
  319. package/dist/lib/instructions/templates.d.ts +10 -3
  320. package/dist/lib/instructions/templates.d.ts.map +1 -1
  321. package/dist/lib/instructions/templates.js +41 -12
  322. package/dist/lib/machine.d.ts +2 -2
  323. package/dist/lib/machine.js +2 -2
  324. package/package.json +26 -21
  325. package/schemas/config.schema.json +26 -1
  326. package/src/commander.ts +22 -13
  327. package/src/commands/{harness.ts → adapter.ts} +46 -46
  328. package/src/commands/agents.ts +71 -64
  329. package/src/commands/artifacts.ts +168 -0
  330. package/src/commands/backup.ts +47 -33
  331. package/src/commands/browse.ts +438 -2
  332. package/src/commands/checkpoint.ts +196 -0
  333. package/src/commands/context.ts +3 -176
  334. package/src/commands/decision.ts +41 -7
  335. package/src/commands/deinit.ts +16 -16
  336. package/src/commands/doctor.ts +28 -28
  337. package/src/commands/{supervisor.ts → governor.ts} +184 -154
  338. package/src/commands/init.ts +50 -34
  339. package/src/commands/{scratch.ts → journal.ts} +60 -60
  340. package/src/commands/policy.ts +1 -1
  341. package/src/commands/presence.ts +2 -2
  342. package/src/commands/sync.ts +3 -3
  343. package/src/commands/tunnel.ts +237 -34
  344. package/src/commands/web-fetch.ts +1 -1
  345. package/src/commands/web.ts +56 -1
  346. package/src/commands/work.ts +72 -38
  347. package/src/commands/workflow.ts +43 -34
  348. package/src/core/{harnesses → adapters}/attest-projection.ts +2 -2
  349. package/src/core/{harnesses → adapters}/attest.ts +27 -27
  350. package/src/core/{harnesses → adapters}/attestation.ts +41 -41
  351. package/src/core/{harnesses → adapters}/bench.ts +34 -43
  352. package/src/core/adapters/index.ts +56 -0
  353. package/src/core/{harnesses → adapters}/profiles.ts +16 -16
  354. package/src/core/{harnesses → adapters}/registry.ts +23 -23
  355. package/src/core/{harnesses → adapters}/types.ts +28 -23
  356. package/src/core/agents/canonical-emit.ts +6 -6
  357. package/src/core/agents/cli-emit.ts +1 -1
  358. package/src/core/agents/cli.ts +30 -28
  359. package/src/core/agents/codex-replay.ts +6 -6
  360. package/src/core/agents/coord-client.ts +119 -28
  361. package/src/core/agents/events/consume.ts +1 -1
  362. package/src/core/agents/events/emit.ts +7 -6
  363. package/src/core/agents/render/prompt-context.ts +107 -31
  364. package/src/core/agents/render/session-context.ts +6 -6
  365. package/src/core/agents/rules/claim-conflict.ts +4 -7
  366. package/src/core/agents/rules/commit-conflict.ts +103 -22
  367. package/src/core/agents/rules/stop-hook.ts +33 -17
  368. package/src/core/agents/rules/verdict.ts +13 -0
  369. package/src/core/agents/session-events.ts +4 -4
  370. package/src/core/agents/state/council.ts +1 -1
  371. package/src/core/agents/state/heartbeat-projector.ts +16 -12
  372. package/src/core/agents/state/heartbeat-writer.ts +12 -12
  373. package/src/core/agents/state/{scratch.ts → journal.ts} +12 -12
  374. package/src/core/agents/state/pidmap.ts +130 -15
  375. package/src/core/agents/state/proc-start.ts +208 -0
  376. package/src/core/agents/state/shell-mutation.ts +1 -1
  377. package/src/core/agents/state/stale-sweep.ts +7 -7
  378. package/src/core/artifacts/index.ts +557 -0
  379. package/src/core/config.ts +30 -2
  380. package/src/core/context/index.ts +15 -15
  381. package/src/core/governor/adapter-spread.ts +82 -0
  382. package/src/core/governor/index.ts +91 -0
  383. package/src/core/governor/plan-api.ts +115 -0
  384. package/src/core/{supervisor → governor}/plan-read.ts +120 -96
  385. package/src/core/{supervisor → governor}/plan-types.ts +64 -50
  386. package/src/core/{supervisor → governor}/planning.ts +240 -188
  387. package/src/core/governor/read.ts +59 -0
  388. package/src/core/{supervisor → governor}/runner.ts +39 -39
  389. package/src/core/{supervisor → governor}/service-read.ts +22 -22
  390. package/src/core/{supervisor → governor}/service.ts +117 -119
  391. package/src/core/{supervisor → governor}/state.ts +389 -174
  392. package/src/core/hooks/adapter/detect.ts +30 -0
  393. package/src/core/hooks/{harness → adapter}/events.ts +16 -14
  394. package/src/core/hooks/{harness → adapter}/output.ts +31 -23
  395. package/src/core/hooks/{harness → adapter}/parse.ts +5 -5
  396. package/src/core/hooks/{harness → adapter}/wiring.ts +21 -21
  397. package/src/core/hooks/cli.ts +185 -162
  398. package/src/core/hooks/effects/image-capture.ts +6 -6
  399. package/src/core/hooks/effects/index.ts +17 -17
  400. package/src/core/hooks/events/emit.ts +3 -3
  401. package/src/core/hooks/events/rotate.ts +1 -1
  402. package/src/core/hooks/events/schema.ts +15 -7
  403. package/src/core/hooks/guard-path.ts +2 -2
  404. package/src/core/hooks/index.ts +1 -1
  405. package/src/core/hooks/resolve/anchor.ts +63 -8
  406. package/src/core/hooks/resolve/coord-root.ts +4 -4
  407. package/src/core/hooks/resolve/intent.ts +1 -1
  408. package/src/core/hooks/resolve/owner.ts +11 -5
  409. package/src/core/{scratch → journal}/index.ts +53 -53
  410. package/src/core/policy/evaluate.ts +8 -8
  411. package/src/core/policy/types.ts +3 -3
  412. package/src/core/work/runner.ts +11 -2
  413. package/src/core/work/state.ts +185 -21
  414. package/src/core/workflow/adapters.ts +33 -0
  415. package/src/core/workflow/approvals.ts +7 -7
  416. package/src/core/workflow/billing.ts +12 -12
  417. package/src/core/workflow/child-env.ts +13 -4
  418. package/src/core/workflow/engine.ts +166 -90
  419. package/src/core/workflow/evidence-preflight.ts +165 -0
  420. package/src/core/workflow/index.ts +6 -3
  421. package/src/core/workflow/proof.ts +94 -48
  422. package/src/core/workflow/run-state.ts +7 -7
  423. package/src/core/workflow/sandbox-projection.ts +16 -16
  424. package/src/core/workflow/spawn-claude.ts +34 -12
  425. package/src/core/workflow/spawn-codex.ts +30 -12
  426. package/src/core/workflow/spawn-cursor.ts +31 -12
  427. package/src/core/workflow/spawn-failure.ts +41 -1
  428. package/src/core/workflow/specialists.ts +2 -2
  429. package/src/core/workflow/{journal.ts → transcript.ts} +16 -16
  430. package/src/core/workflow/types.ts +130 -46
  431. package/src/core/workflow/validate.ts +1 -1
  432. package/src/core/workflow/workspaces/cancellation.ts +2 -2
  433. package/src/core/workflow/workspaces/cleanup.ts +2 -2
  434. package/src/core/workflow/workspaces/execution.ts +6 -6
  435. package/src/core/workflow/workspaces/inspect.ts +14 -11
  436. package/src/core/workflow/workspaces/integration.ts +18 -14
  437. package/src/core/workflow/workspaces/lifecycle.ts +10 -10
  438. package/src/core/workflow/workspaces/local-git.ts +47 -5
  439. package/src/core/workflow/workspaces/recovery.ts +3 -3
  440. package/src/core/workflow/workspaces/state.ts +4 -3
  441. package/src/core/workflow/workspaces/types.ts +1 -1
  442. package/src/lib/browser/asserts.ts +177 -0
  443. package/src/lib/browser/client.ts +189 -14
  444. package/src/lib/browser/content-checks.ts +571 -0
  445. package/src/lib/browser/critique.ts +231 -0
  446. package/src/lib/browser/geometry.ts +297 -1
  447. package/src/lib/browser/index.ts +34 -0
  448. package/src/lib/claude-desktop.ts +4 -1
  449. package/src/lib/council/index.ts +9 -9
  450. package/src/lib/exec.ts +13 -3
  451. package/src/lib/identities/assume.ts +7 -7
  452. package/src/lib/instructions/apply.ts +87 -25
  453. package/src/lib/instructions/host-addendum.ts +126 -0
  454. package/src/lib/instructions/templates.ts +44 -15
  455. package/src/lib/machine.ts +2 -2
  456. package/dist/commands/harness.d.ts +0 -12
  457. package/dist/commands/harness.d.ts.map +0 -1
  458. package/dist/commands/scratch.d.ts +0 -4
  459. package/dist/commands/scratch.d.ts.map +0 -1
  460. package/dist/commands/session.d.ts.map +0 -1
  461. package/dist/commands/session.js +0 -162
  462. package/dist/commands/supervisor.d.ts +0 -4
  463. package/dist/commands/supervisor.d.ts.map +0 -1
  464. package/dist/core/harnesses/attest-projection.d.ts.map +0 -1
  465. package/dist/core/harnesses/attest.d.ts.map +0 -1
  466. package/dist/core/harnesses/attestation.d.ts.map +0 -1
  467. package/dist/core/harnesses/bench.d.ts.map +0 -1
  468. package/dist/core/harnesses/index.d.ts +0 -13
  469. package/dist/core/harnesses/index.d.ts.map +0 -1
  470. package/dist/core/harnesses/index.js +0 -6
  471. package/dist/core/harnesses/profiles.d.ts.map +0 -1
  472. package/dist/core/harnesses/registry.d.ts +0 -15
  473. package/dist/core/harnesses/registry.d.ts.map +0 -1
  474. package/dist/core/harnesses/types.d.ts.map +0 -1
  475. package/dist/core/hooks/harness/detect.d.ts +0 -9
  476. package/dist/core/hooks/harness/events.d.ts.map +0 -1
  477. package/dist/core/hooks/harness/output.d.ts.map +0 -1
  478. package/dist/core/supervisor/index.d.ts +0 -7
  479. package/dist/core/supervisor/index.d.ts.map +0 -1
  480. package/dist/core/supervisor/index.js +0 -6
  481. package/dist/core/supervisor/plan-api.d.ts +0 -23
  482. package/dist/core/supervisor/plan-api.d.ts.map +0 -1
  483. package/dist/core/supervisor/plan-api.js +0 -50
  484. package/dist/core/supervisor/plan-read.d.ts +0 -5
  485. package/dist/core/supervisor/plan-read.d.ts.map +0 -1
  486. package/dist/core/supervisor/plan-types.d.ts +0 -170
  487. package/dist/core/supervisor/plan-types.d.ts.map +0 -1
  488. package/dist/core/supervisor/planning.d.ts +0 -33
  489. package/dist/core/supervisor/planning.d.ts.map +0 -1
  490. package/dist/core/supervisor/read.d.ts +0 -6
  491. package/dist/core/supervisor/read.d.ts.map +0 -1
  492. package/dist/core/supervisor/read.js +0 -4
  493. package/dist/core/supervisor/runner.d.ts +0 -37
  494. package/dist/core/supervisor/runner.d.ts.map +0 -1
  495. package/dist/core/supervisor/service-read.d.ts +0 -6
  496. package/dist/core/supervisor/service-read.d.ts.map +0 -1
  497. package/dist/core/supervisor/service.d.ts +0 -114
  498. package/dist/core/supervisor/service.d.ts.map +0 -1
  499. package/dist/core/supervisor/state.d.ts +0 -95
  500. package/dist/core/supervisor/state.d.ts.map +0 -1
  501. package/dist/core/workflow/harnesses.d.ts +0 -17
  502. package/dist/core/workflow/harnesses.d.ts.map +0 -1
  503. package/dist/core/workflow/harnesses.js +0 -21
  504. package/dist/core/workflow/journal.d.ts.map +0 -1
  505. package/src/commands/session.ts +0 -187
  506. package/src/core/harnesses/index.ts +0 -56
  507. package/src/core/hooks/harness/detect.ts +0 -30
  508. package/src/core/supervisor/index.ts +0 -89
  509. package/src/core/supervisor/plan-api.ts +0 -73
  510. package/src/core/supervisor/read.ts +0 -59
  511. package/src/core/workflow/harnesses.ts +0 -33
  512. /package/dist/core/{harnesses → adapters}/attest-projection.js +0 -0
@@ -0,0 +1,474 @@
1
+ // Content-level checks for `harn browse` — the failures a human still catches
2
+ // by eye that rendered-geometry checks miss:
3
+ //
4
+ // placeholder Unrendered template tokens / bound-value tells that leaked to
5
+ // the page: `${x}`, `{{x}}`, `[object Object]`, `Invalid Date`,
6
+ // `NaN`, or an element whose whole text is literally
7
+ // "undefined" / "null".
8
+ // image <img> that failed to load (naturalWidth 0), is still loading,
9
+ // or is visibly stretched (rendered aspect ratio far from the
10
+ // intrinsic one, with an object-fit that does not correct it).
11
+ // truncation Text actively cut off by an ellipsis or -webkit-line-clamp —
12
+ // i.e. the author asked to truncate AND the content overflows.
13
+ // contrast Rendered text below the WCAG AA contrast ratio against its
14
+ // effective background. Runs at whatever theme the page is in,
15
+ // so pair it with a theme toggle to cover light + dark.
16
+ //
17
+ // One evaluator runs every requested check in a single page.evaluate so the
18
+ // shared helpers (label, hidden walk, scroll offsets) are defined once. The
19
+ // returned function is serialized into the page by Playwright and cannot reach
20
+ // module-scope closures, which is why the helpers are nested.
21
+ export function buildContentChecks() {
22
+ return (request) => {
23
+ const NODE_CAP = 6000;
24
+ const HIT_CAP = 100;
25
+ const sx = window.scrollX;
26
+ const sy = window.scrollY;
27
+ const labelOf = (element) => {
28
+ const tag = element.tagName.toLowerCase();
29
+ if (element.id)
30
+ return `${tag}#${element.id}`;
31
+ const cls = typeof element.className === "string"
32
+ ? element.className.trim()
33
+ : (element.getAttribute("class") ?? "").trim();
34
+ return cls ? `${tag}.${cls.split(/\s+/).slice(0, 2).join(".")}` : tag;
35
+ };
36
+ const isHidden = (element) => {
37
+ let current = element;
38
+ while (current) {
39
+ const style = getComputedStyle(current);
40
+ const cv = style
41
+ .contentVisibility;
42
+ if (style.display === "none" ||
43
+ style.visibility === "hidden" ||
44
+ style.visibility === "collapse" ||
45
+ Number.parseFloat(style.opacity || "1") === 0 ||
46
+ cv === "hidden") {
47
+ return true;
48
+ }
49
+ current = current.parentElement;
50
+ }
51
+ return false;
52
+ };
53
+ const docRect = (r) => ({
54
+ x: Math.round(r.x + sx),
55
+ y: Math.round(r.y + sy),
56
+ width: Math.round(r.width),
57
+ height: Math.round(r.height),
58
+ });
59
+ const rootOf = (scope) => scope ? document.querySelector(scope) : document.body;
60
+ const snippetOf = (text) => text.replace(/\s+/g, " ").trim().slice(0, 80);
61
+ // ---- placeholder --------------------------------------------------------
62
+ let placeholder;
63
+ if (request.placeholder) {
64
+ const root = rootOf(request.placeholder.scope);
65
+ const hits = [];
66
+ let scanned = 0;
67
+ let truncated = false;
68
+ const EMPTY = new Set(["undefined", "null", "NaN", "[object Object]", "Invalid Date"]);
69
+ // Ordered so the most specific token wins the label for a given match.
70
+ const TOKENS = [
71
+ { re: /\$\{[^}]{1,120}\}/g, kind: "js-template" },
72
+ { re: /\{\{[^}]{1,120}\}\}/g, kind: "mustache" },
73
+ { re: /\[object [A-Z][A-Za-z]+\]/g, kind: "object" },
74
+ { re: /\bInvalid Date\b/g, kind: "invalid-date" },
75
+ { re: /(?<![A-Za-z])NaN(?![A-Za-z])/g, kind: "nan" },
76
+ ];
77
+ const rectForTextNode = (node, index, length) => {
78
+ try {
79
+ const range = document.createRange();
80
+ range.setStart(node, index);
81
+ range.setEnd(node, Math.min(index + length, node.nodeValue?.length ?? index));
82
+ const r = range.getBoundingClientRect();
83
+ if (r.width <= 0 && r.height <= 0)
84
+ return null;
85
+ return docRect(r);
86
+ }
87
+ catch {
88
+ return null;
89
+ }
90
+ };
91
+ if (root && !isHidden(root)) {
92
+ const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT);
93
+ for (let node = walker.nextNode(); node; node = walker.nextNode()) {
94
+ if (scanned >= NODE_CAP) {
95
+ truncated = true;
96
+ break;
97
+ }
98
+ const parent = node.parentElement;
99
+ if (!parent)
100
+ continue;
101
+ if (["SCRIPT", "STYLE", "NOSCRIPT", "TEXTAREA"].includes(parent.tagName))
102
+ continue;
103
+ if (isHidden(parent))
104
+ continue;
105
+ scanned++;
106
+ const value = node.nodeValue ?? "";
107
+ for (const { re, kind } of TOKENS) {
108
+ re.lastIndex = 0;
109
+ for (const m of value.matchAll(re)) {
110
+ if (m.index === undefined)
111
+ continue;
112
+ const rect = rectForTextNode(node, m.index, m[0].length) ?? {
113
+ x: 0,
114
+ y: 0,
115
+ width: 0,
116
+ height: 0,
117
+ };
118
+ hits.push({
119
+ label: labelOf(parent),
120
+ token: m[0],
121
+ kind,
122
+ snippet: snippetOf(value),
123
+ rect,
124
+ });
125
+ if (hits.length >= HIT_CAP)
126
+ break;
127
+ }
128
+ if (hits.length >= HIT_CAP)
129
+ break;
130
+ }
131
+ if (hits.length >= HIT_CAP) {
132
+ truncated = true;
133
+ break;
134
+ }
135
+ }
136
+ // Whole-element-equals sweep for bare undefined/null (prose-safe: only
137
+ // when the trimmed text of a leaf element is exactly the tell).
138
+ if (hits.length < HIT_CAP) {
139
+ const leaves = root.querySelectorAll("*");
140
+ for (let i = 0; i < leaves.length && i < NODE_CAP; i++) {
141
+ const el = leaves[i];
142
+ if (!el || el.children.length > 0)
143
+ continue;
144
+ if (isHidden(el))
145
+ continue;
146
+ const text = (el.textContent ?? "").trim();
147
+ if (!EMPTY.has(text))
148
+ continue;
149
+ const r = el.getBoundingClientRect();
150
+ hits.push({
151
+ label: labelOf(el),
152
+ token: text,
153
+ kind: "empty-binding",
154
+ snippet: text,
155
+ rect: docRect(r),
156
+ });
157
+ if (hits.length >= HIT_CAP) {
158
+ truncated = true;
159
+ break;
160
+ }
161
+ }
162
+ }
163
+ }
164
+ placeholder = {
165
+ rule: "placeholder",
166
+ found: root !== null,
167
+ outcome: root && hits.length === 0 ? "pass" : "fail",
168
+ scanned,
169
+ truncated,
170
+ hits,
171
+ };
172
+ }
173
+ // ---- image health -------------------------------------------------------
174
+ let image;
175
+ if (request.image) {
176
+ const root = rootOf(request.image.scope);
177
+ const tol = request.image.tolerance;
178
+ const issues = [];
179
+ let scanned = 0;
180
+ let truncated = false;
181
+ if (root) {
182
+ const imgs = root.querySelectorAll("img");
183
+ for (let i = 0; i < imgs.length; i++) {
184
+ const img = imgs[i];
185
+ if (!img)
186
+ continue;
187
+ if (isHidden(img))
188
+ continue;
189
+ if (scanned >= NODE_CAP) {
190
+ truncated = true;
191
+ break;
192
+ }
193
+ scanned++;
194
+ const rect = img.getBoundingClientRect();
195
+ const objectFit = getComputedStyle(img).objectFit || "fill";
196
+ let reason = null;
197
+ if (!img.complete) {
198
+ reason = "loading";
199
+ }
200
+ else if (img.naturalWidth === 0 || img.naturalHeight === 0) {
201
+ reason = "missing";
202
+ }
203
+ else if (rect.width > 1 &&
204
+ rect.height > 1 &&
205
+ objectFit !== "cover" &&
206
+ objectFit !== "contain" &&
207
+ objectFit !== "scale-down") {
208
+ const renderedAR = rect.width / rect.height;
209
+ const naturalAR = img.naturalWidth / img.naturalHeight;
210
+ const deviation = Math.abs(renderedAR - naturalAR) / naturalAR;
211
+ if (deviation > tol)
212
+ reason = "stretched";
213
+ }
214
+ if (!reason)
215
+ continue;
216
+ issues.push({
217
+ label: labelOf(img),
218
+ src: img.currentSrc || img.src || "(none)",
219
+ reason,
220
+ naturalWidth: img.naturalWidth,
221
+ naturalHeight: img.naturalHeight,
222
+ renderedWidth: Math.round(rect.width),
223
+ renderedHeight: Math.round(rect.height),
224
+ objectFit,
225
+ rect: docRect(rect),
226
+ });
227
+ if (issues.length >= HIT_CAP) {
228
+ truncated = true;
229
+ break;
230
+ }
231
+ }
232
+ }
233
+ // "loading" alone is not a failure — the capture may have raced the load.
234
+ const failing = issues.some((i) => i.reason !== "loading");
235
+ image = {
236
+ rule: "image",
237
+ found: root !== null,
238
+ outcome: !root || failing ? "fail" : "pass",
239
+ scanned,
240
+ truncated,
241
+ issues,
242
+ };
243
+ }
244
+ // ---- truncation ---------------------------------------------------------
245
+ let truncation;
246
+ if (request.truncation) {
247
+ const root = rootOf(request.truncation.scope);
248
+ const tol = request.truncation.tolerance;
249
+ const hits = [];
250
+ let scanned = 0;
251
+ let truncated = false;
252
+ if (root) {
253
+ const all = root.querySelectorAll("*");
254
+ for (let i = 0; i < all.length; i++) {
255
+ const el = all[i];
256
+ if (!el)
257
+ continue;
258
+ if (scanned >= NODE_CAP) {
259
+ truncated = true;
260
+ break;
261
+ }
262
+ const text = (el.textContent ?? "").trim();
263
+ if (!text)
264
+ continue;
265
+ if (isHidden(el))
266
+ continue;
267
+ scanned++;
268
+ const style = getComputedStyle(el);
269
+ // Horizontal: an active single-line ellipsis.
270
+ if (style.textOverflow === "ellipsis" &&
271
+ (style.overflowX === "hidden" || style.overflowX === "clip") &&
272
+ el.scrollWidth - el.clientWidth > tol) {
273
+ hits.push({
274
+ label: labelOf(el),
275
+ axis: "x",
276
+ how: "ellipsis",
277
+ overflowPx: Math.round(el.scrollWidth - el.clientWidth),
278
+ snippet: snippetOf(text),
279
+ rect: docRect(el.getBoundingClientRect()),
280
+ });
281
+ }
282
+ else {
283
+ // Vertical: an active -webkit-line-clamp.
284
+ const clampRaw = style.getPropertyValue("-webkit-line-clamp");
285
+ const clamp = Number.parseInt(clampRaw, 10);
286
+ if (Number.isFinite(clamp) && clamp > 0 && el.scrollHeight - el.clientHeight > tol) {
287
+ hits.push({
288
+ label: labelOf(el),
289
+ axis: "y",
290
+ how: "line-clamp",
291
+ overflowPx: Math.round(el.scrollHeight - el.clientHeight),
292
+ snippet: snippetOf(text),
293
+ rect: docRect(el.getBoundingClientRect()),
294
+ });
295
+ }
296
+ }
297
+ if (hits.length >= HIT_CAP) {
298
+ truncated = true;
299
+ break;
300
+ }
301
+ }
302
+ }
303
+ truncation = {
304
+ rule: "truncation",
305
+ found: root !== null,
306
+ outcome: !root || hits.length > 0 ? "fail" : "pass",
307
+ scanned,
308
+ truncated,
309
+ hits,
310
+ };
311
+ }
312
+ // ---- contrast -----------------------------------------------------------
313
+ let contrast;
314
+ if (request.contrast) {
315
+ const root = rootOf(request.contrast.scope);
316
+ const hits = [];
317
+ let scanned = 0;
318
+ let truncated = false;
319
+ const parseColor = (value) => {
320
+ const m = value.match(/rgba?\(([^)]+)\)/);
321
+ if (!m?.[1])
322
+ return null;
323
+ const parts = m[1].split(",").map((p) => Number.parseFloat(p.trim()));
324
+ if (parts.length < 3 || parts.some((n) => Number.isNaN(n)))
325
+ return null;
326
+ return { r: parts[0], g: parts[1], b: parts[2], a: parts[3] ?? 1 };
327
+ };
328
+ const lin = (c) => {
329
+ const s = c / 255;
330
+ return s <= 0.03928 ? s / 12.92 : ((s + 0.055) / 1.055) ** 2.4;
331
+ };
332
+ const luminance = (r, g, b) => 0.2126 * lin(r) + 0.7152 * lin(g) + 0.0722 * lin(b);
333
+ const over = (fg, bg) => ({
334
+ r: fg.r * fg.a + bg.r * (1 - fg.a),
335
+ g: fg.g * fg.a + bg.g * (1 - fg.a),
336
+ b: fg.b * fg.a + bg.b * (1 - fg.a),
337
+ });
338
+ const hasDirectText = (el) => {
339
+ for (const node of el.childNodes) {
340
+ if (node.nodeType === Node.TEXT_NODE && (node.nodeValue ?? "").trim().length > 0) {
341
+ return true;
342
+ }
343
+ }
344
+ return false;
345
+ };
346
+ // Effective background: first opaque ancestor background-color. A
347
+ // background-image or gradient anywhere in the chain makes it unknowable.
348
+ const effectiveBg = (el) => {
349
+ let current = el;
350
+ while (current) {
351
+ const style = getComputedStyle(current);
352
+ if (style.backgroundImage && style.backgroundImage !== "none") {
353
+ return { rgb: { r: 255, g: 255, b: 255 }, unknown: true };
354
+ }
355
+ const bg = parseColor(style.backgroundColor);
356
+ if (bg && bg.a >= 0.999)
357
+ return { rgb: { r: bg.r, g: bg.g, b: bg.b }, unknown: false };
358
+ current = current.parentElement;
359
+ }
360
+ // Fell through to the canvas: assume white (the common page default).
361
+ return { rgb: { r: 255, g: 255, b: 255 }, unknown: false };
362
+ };
363
+ if (root) {
364
+ const all = root.querySelectorAll("*");
365
+ for (let i = 0; i < all.length; i++) {
366
+ const el = all[i];
367
+ if (!el)
368
+ continue;
369
+ if (scanned >= NODE_CAP) {
370
+ truncated = true;
371
+ break;
372
+ }
373
+ if (!hasDirectText(el))
374
+ continue;
375
+ if (isHidden(el))
376
+ continue;
377
+ const rect = el.getBoundingClientRect();
378
+ if (rect.width <= 0 || rect.height <= 0)
379
+ continue;
380
+ scanned++;
381
+ const style = getComputedStyle(el);
382
+ const fg = parseColor(style.color);
383
+ if (!fg)
384
+ continue;
385
+ const size = Number.parseFloat(style.fontSize) || 16;
386
+ const weight = Number.parseInt(style.fontWeight, 10) || 400;
387
+ const largeText = size >= 24 || (size >= 18.66 && weight >= 700);
388
+ const required = largeText ? 3 : 4.5;
389
+ const bg = effectiveBg(el);
390
+ const composited = fg.a < 0.999 ? over(fg, bg.rgb) : { r: fg.r, g: fg.g, b: fg.b };
391
+ const lFg = luminance(composited.r, composited.g, composited.b);
392
+ const lBg = luminance(bg.rgb.r, bg.rgb.g, bg.rgb.b);
393
+ const ratio = (Math.max(lFg, lBg) + 0.05) / (Math.min(lFg, lBg) + 0.05);
394
+ const rounded = Math.round(ratio * 100) / 100;
395
+ if (bg.unknown) {
396
+ hits.push({
397
+ label: labelOf(el),
398
+ ratio: rounded,
399
+ required,
400
+ color: style.color,
401
+ background: "(image/gradient)",
402
+ largeText,
403
+ snippet: snippetOf(el.textContent ?? ""),
404
+ outcome: "unknown",
405
+ rect: docRect(rect),
406
+ });
407
+ }
408
+ else if (ratio < required) {
409
+ hits.push({
410
+ label: labelOf(el),
411
+ ratio: rounded,
412
+ required,
413
+ color: style.color,
414
+ background: style.backgroundColor,
415
+ largeText,
416
+ snippet: snippetOf(el.textContent ?? ""),
417
+ outcome: "fail",
418
+ rect: docRect(rect),
419
+ });
420
+ }
421
+ if (hits.length >= HIT_CAP) {
422
+ truncated = true;
423
+ break;
424
+ }
425
+ }
426
+ }
427
+ const anyFail = hits.some((h) => h.outcome === "fail");
428
+ const anyUnknown = hits.some((h) => h.outcome === "unknown");
429
+ contrast = {
430
+ rule: "contrast",
431
+ found: root !== null,
432
+ outcome: !root ? "fail" : anyFail ? "fail" : anyUnknown ? "unknown" : "pass",
433
+ scanned,
434
+ truncated,
435
+ hits,
436
+ };
437
+ }
438
+ const result = {};
439
+ if (placeholder)
440
+ result.placeholder = placeholder;
441
+ if (image)
442
+ result.image = image;
443
+ if (truncation)
444
+ result.truncation = truncation;
445
+ if (contrast)
446
+ result.contrast = contrast;
447
+ return result;
448
+ };
449
+ }
450
+ export function buildContentAnnotateScript() {
451
+ return ({ boxes }) => {
452
+ const ROOT_ID = "__bp-content-check-annotations__";
453
+ document.getElementById(ROOT_ID)?.remove();
454
+ const root = document.createElement("div");
455
+ root.id = ROOT_ID;
456
+ root.style.cssText =
457
+ "position:absolute;top:0;left:0;width:100%;height:0;overflow:visible;pointer-events:none;z-index:2147483646";
458
+ document.body.appendChild(root);
459
+ for (const b of boxes) {
460
+ const node = document.createElement("div");
461
+ node.style.cssText = `position:absolute;left:${b.rect.x - 2}px;top:${b.rect.y - 2}px;width:${Math.max(b.rect.width, 6) + 4}px;height:${Math.max(b.rect.height, 6) + 4}px;border:2px solid ${b.color};box-sizing:border-box;background:${b.color}1a;pointer-events:none`;
462
+ const tag = document.createElement("div");
463
+ tag.textContent = b.label.slice(0, 120);
464
+ tag.style.cssText = `position:absolute;left:0;top:-18px;background:${b.color};color:#fff;font:12px/1.4 system-ui,sans-serif;padding:1px 5px;border-radius:3px;white-space:nowrap`;
465
+ node.appendChild(tag);
466
+ root.appendChild(node);
467
+ }
468
+ };
469
+ }
470
+ export function buildClearContentAnnotationsScript() {
471
+ return () => {
472
+ document.getElementById("__bp-content-check-annotations__")?.remove();
473
+ };
474
+ }
@@ -0,0 +1,91 @@
1
+ export interface CritiqueTile {
2
+ index: number;
3
+ /** Section label or "band N", for locating a finding. */
4
+ label: string;
5
+ /** Document-space Y offset of the tile's top, so findings map to a place. */
6
+ scrollY: number;
7
+ width: number;
8
+ height: number;
9
+ /** Base64 PNG of the tile (no data: prefix). */
10
+ pngBase64: string;
11
+ }
12
+ export interface CritiqueFinding {
13
+ tile: number;
14
+ severity: "high" | "medium" | "low";
15
+ category: string;
16
+ description: string;
17
+ }
18
+ export interface CritiqueResult {
19
+ rule: "critique";
20
+ /** Number of tiles the page was cut into. */
21
+ tiles: number;
22
+ /** Whether a provider was available. False → outcome "skipped". */
23
+ provider: boolean;
24
+ findings: CritiqueFinding[];
25
+ outcome: "pass" | "fail" | "skipped";
26
+ /** Set when skipped or a provider call failed. */
27
+ error?: string;
28
+ }
29
+ /**
30
+ * The host-injected model call. Given one tile and the rubric, return the
31
+ * findings for that tile. Throwing is caught and surfaced as an error finding
32
+ * so one bad tile never sinks the run.
33
+ */
34
+ export type CritiqueProvider = (input: {
35
+ url: string;
36
+ rubric: string;
37
+ tile: CritiqueTile;
38
+ }) => Promise<CritiqueFinding[]>;
39
+ export declare const DEFAULT_CRITIQUE_RUBRIC: string;
40
+ /**
41
+ * Cut a page of height `pageHeight` into overlapping vertical bands. Pure math
42
+ * so the caller (which owns the page) can screenshot each `clip` rect. The
43
+ * overlap keeps a finding that straddles a seam visible in at least one tile.
44
+ */
45
+ export declare function bandRects(pageHeight: number, pageWidth: number, bandHeight: number, overlap: number): Array<{
46
+ index: number;
47
+ x: number;
48
+ y: number;
49
+ width: number;
50
+ height: number;
51
+ }>;
52
+ /**
53
+ * Cut tiles out of ONE full-page screenshot with pngjs. Playwright's own
54
+ * `clip` is viewport-relative, so a band below the fold errors with "clipped
55
+ * area outside the resulting image" — capturing the whole page once and
56
+ * cropping in pixel space sidesteps that and keeps every tile at full
57
+ * resolution. Pass `elementRects` for semantic (per-element) tiling; otherwise
58
+ * the page is banded from the actual image height. Rects are clamped to the
59
+ * image so an off-by-one never throws.
60
+ */
61
+ export declare function tilesFromFullPage(fullPageBuffer: Buffer, opts: {
62
+ elementRects?: Array<{
63
+ label: string;
64
+ x: number;
65
+ y: number;
66
+ width: number;
67
+ height: number;
68
+ }>;
69
+ bandHeight?: number;
70
+ overlap?: number;
71
+ maxTiles: number;
72
+ }): CritiqueTile[];
73
+ /**
74
+ * Validate + normalize a provider's raw output into CritiqueFindings. Tolerant
75
+ * of a model returning a bare array or wrapping it in `{ findings: [...] }`,
76
+ * and drops entries that are not shaped like a finding.
77
+ */
78
+ export declare function normalizeFindings(raw: unknown, tile: number): CritiqueFinding[];
79
+ /**
80
+ * Run the critique over pre-captured tiles with an injected provider. Findings
81
+ * are collected across tiles; a provider throw becomes a `high` error finding
82
+ * for that tile rather than aborting. Outcome is `fail` when any `high` finding
83
+ * survives (the gate escalation lives in the caller).
84
+ */
85
+ export declare function runCritique(args: {
86
+ url: string;
87
+ rubric: string;
88
+ tiles: CritiqueTile[];
89
+ provider: CritiqueProvider | undefined;
90
+ }): Promise<CritiqueResult>;
91
+ //# sourceMappingURL=critique.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"critique.d.ts","sourceRoot":"","sources":["../../../src/lib/browser/critique.ts"],"names":[],"mappings":"AAqBA,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,yDAAyD;IACzD,KAAK,EAAE,MAAM,CAAC;IACd,6EAA6E;IAC7E,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,gDAAgD;IAChD,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,UAAU,CAAC;IACjB,6CAA6C;IAC7C,KAAK,EAAE,MAAM,CAAC;IACd,mEAAmE;IACnE,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IACrC,kDAAkD;IAClD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,KAAK,EAAE;IACrC,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,YAAY,CAAC;CACpB,KAAK,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;AAEjC,eAAO,MAAM,uBAAuB,QAaxB,CAAC;AAEb;;;;GAIG;AACH,wBAAgB,SAAS,CACvB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,GACd,KAAK,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAY/E;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAC/B,cAAc,EAAE,MAAM,EACtB,IAAI,EAAE;IACJ,YAAY,CAAC,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC7F,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB,GACA,YAAY,EAAE,CAqChB;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,eAAe,EAAE,CAyB/E;AAED;;;;;GAKG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE;IACtC,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,QAAQ,EAAE,gBAAgB,GAAG,SAAS,CAAC;CACxC,GAAG,OAAO,CAAC,cAAc,CAAC,CA6B1B"}