harnery 0.36.0 → 0.38.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.
- package/dist/commander.d.ts +9 -0
- package/dist/commander.d.ts.map +1 -1
- package/dist/commander.js +10 -1
- package/dist/commands/admission.d.ts +21 -0
- package/dist/commands/admission.d.ts.map +1 -0
- package/dist/commands/admission.js +565 -0
- package/dist/commands/agents.d.ts +7 -0
- package/dist/commands/agents.d.ts.map +1 -1
- package/dist/commands/agents.js +148 -47
- package/dist/commands/artifacts.d.ts.map +1 -1
- package/dist/commands/artifacts.js +73 -2
- package/dist/commands/browse-ai.d.ts +2 -2
- package/dist/commands/browse-ai.d.ts.map +1 -1
- package/dist/commands/browse-ai.js +6 -4
- package/dist/commands/browse.d.ts.map +1 -1
- package/dist/commands/browse.js +360 -21
- package/dist/commands/diagnostics.d.ts +4 -0
- package/dist/commands/diagnostics.d.ts.map +1 -0
- package/dist/commands/diagnostics.js +229 -0
- package/dist/commands/fetch.js +1 -0
- package/dist/commands/files.d.ts +12 -0
- package/dist/commands/files.d.ts.map +1 -1
- package/dist/commands/files.js +54 -1
- package/dist/commands/governor.d.ts.map +1 -1
- package/dist/commands/governor.js +4 -0
- package/dist/commands/ledger-v3.d.ts.map +1 -1
- package/dist/commands/ledger-v3.js +71 -2
- package/dist/commands/qa-record.d.ts +144 -0
- package/dist/commands/qa-record.d.ts.map +1 -0
- package/dist/commands/qa-record.js +0 -0
- package/dist/commands/qa-run.d.ts +8 -0
- package/dist/commands/qa-run.d.ts.map +1 -0
- package/dist/commands/qa-run.js +396 -0
- package/dist/commands/qa-status.d.ts +71 -0
- package/dist/commands/qa-status.d.ts.map +1 -0
- package/dist/commands/qa-status.js +490 -0
- package/dist/commands/qa-verify.d.ts +40 -0
- package/dist/commands/qa-verify.d.ts.map +1 -0
- package/dist/commands/qa-verify.js +180 -0
- package/dist/commands/resources.d.ts +4 -0
- package/dist/commands/resources.d.ts.map +1 -0
- package/dist/commands/resources.js +29 -0
- package/dist/commands/review-pack.d.ts +4 -0
- package/dist/commands/review-pack.d.ts.map +1 -0
- package/dist/commands/review-pack.js +1001 -0
- package/dist/commands/supervisor.d.ts +4 -0
- package/dist/commands/supervisor.d.ts.map +1 -0
- package/dist/commands/supervisor.js +101 -0
- package/dist/commands/web.d.ts.map +1 -1
- package/dist/commands/web.js +17 -0
- package/dist/commands/workflow.d.ts.map +1 -1
- package/dist/commands/workflow.js +4 -0
- package/dist/core/agents/cli.js +7 -3
- package/dist/core/agents/health.d.ts +17 -0
- package/dist/core/agents/health.d.ts.map +1 -0
- package/dist/core/agents/health.js +109 -0
- package/dist/core/agents/mailbox.d.ts +92 -0
- package/dist/core/agents/mailbox.d.ts.map +1 -0
- package/dist/core/agents/mailbox.js +325 -0
- package/dist/core/agents/qa-signal.d.ts +111 -0
- package/dist/core/agents/qa-signal.d.ts.map +1 -0
- package/dist/core/agents/qa-signal.js +231 -0
- package/dist/core/agents/reconcile-coordination-v3.d.ts +44 -0
- package/dist/core/agents/reconcile-coordination-v3.d.ts.map +1 -0
- package/dist/core/agents/reconcile-coordination-v3.js +58 -0
- package/dist/core/agents/render/prompt-context.d.ts +5 -0
- package/dist/core/agents/render/prompt-context.d.ts.map +1 -1
- package/dist/core/agents/render/prompt-context.js +34 -13
- package/dist/core/agents/render/session-context.d.ts +8 -0
- package/dist/core/agents/render/session-context.d.ts.map +1 -1
- package/dist/core/agents/render/session-context.js +34 -3
- package/dist/core/agents/rules/commit-conflict.d.ts.map +1 -1
- package/dist/core/agents/rules/commit-conflict.js +50 -1
- package/dist/core/agents/rules/stop-hook.d.ts.map +1 -1
- package/dist/core/agents/rules/stop-hook.js +6 -10
- package/dist/core/agents/session-finalizer-v3.js +4 -1
- package/dist/core/agents/session-name-display.d.ts +20 -5
- package/dist/core/agents/session-name-display.d.ts.map +1 -1
- package/dist/core/agents/session-name-display.js +67 -7
- package/dist/core/agents/state/heartbeat-reader.d.ts +7 -0
- package/dist/core/agents/state/heartbeat-reader.d.ts.map +1 -1
- package/dist/core/agents/state/heartbeat-writer.d.ts +11 -0
- package/dist/core/agents/state/heartbeat-writer.d.ts.map +1 -1
- package/dist/core/agents/state/heartbeat-writer.js +17 -0
- package/dist/core/agents/state/live-coordination-view.d.ts.map +1 -1
- package/dist/core/agents/state/live-coordination-view.js +1 -0
- package/dist/core/agents/state/live-coordination-writer.js +5 -0
- package/dist/core/artifacts/constants.d.ts +1 -1
- package/dist/core/artifacts/constants.js +1 -1
- package/dist/core/artifacts/index.d.ts +82 -6
- package/dist/core/artifacts/index.d.ts.map +1 -1
- package/dist/core/artifacts/index.js +410 -15
- package/dist/core/config.d.ts +20 -0
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +59 -0
- package/dist/core/diagnostics/advice.d.ts +9 -0
- package/dist/core/diagnostics/advice.d.ts.map +1 -0
- package/dist/core/diagnostics/advice.js +112 -0
- package/dist/core/diagnostics/bundle.d.ts +51 -0
- package/dist/core/diagnostics/bundle.d.ts.map +1 -0
- package/dist/core/diagnostics/bundle.js +968 -0
- package/dist/core/diagnostics/comparison.d.ts +5 -0
- package/dist/core/diagnostics/comparison.d.ts.map +1 -0
- package/dist/core/diagnostics/comparison.js +444 -0
- package/dist/core/diagnostics/contract.d.ts +245 -0
- package/dist/core/diagnostics/contract.d.ts.map +1 -0
- package/dist/core/diagnostics/contract.js +18 -0
- package/dist/core/diagnostics/identity.d.ts +3 -0
- package/dist/core/diagnostics/identity.d.ts.map +1 -0
- package/dist/core/diagnostics/identity.js +10 -0
- package/dist/core/diagnostics/index.d.ts +8 -0
- package/dist/core/diagnostics/index.d.ts.map +1 -0
- package/dist/core/diagnostics/index.js +7 -0
- package/dist/core/diagnostics/replay.d.ts +8 -0
- package/dist/core/diagnostics/replay.d.ts.map +1 -0
- package/dist/core/diagnostics/replay.js +213 -0
- package/dist/core/diagnostics/sanitize.d.ts +9 -0
- package/dist/core/diagnostics/sanitize.d.ts.map +1 -0
- package/dist/core/diagnostics/sanitize.js +84 -0
- package/dist/core/events/legacy-storage/compression.d.ts +13 -0
- package/dist/core/events/legacy-storage/compression.d.ts.map +1 -0
- package/dist/core/events/legacy-storage/compression.js +107 -0
- package/dist/core/events/legacy-storage/index.d.ts +1 -0
- package/dist/core/events/legacy-storage/index.d.ts.map +1 -1
- package/dist/core/events/legacy-storage/index.js +1 -0
- package/dist/core/events/v3/archive-retention.d.ts +33 -0
- package/dist/core/events/v3/archive-retention.d.ts.map +1 -0
- package/dist/core/events/v3/archive-retention.js +195 -0
- package/dist/core/events/v3/bootstrap.d.ts.map +1 -1
- package/dist/core/events/v3/bootstrap.js +10 -0
- package/dist/core/events/v3/capabilities.d.ts +1 -1
- package/dist/core/events/v3/capabilities.d.ts.map +1 -1
- package/dist/core/events/v3/capabilities.js +1 -0
- package/dist/core/events/v3/coordination-view.d.ts +3 -0
- package/dist/core/events/v3/coordination-view.d.ts.map +1 -1
- package/dist/core/events/v3/coordination-view.js +69 -8
- package/dist/core/events/v3/index.d.ts +1 -0
- package/dist/core/events/v3/index.d.ts.map +1 -1
- package/dist/core/events/v3/index.js +1 -0
- package/dist/core/events/v3/live-routing.d.ts.map +1 -1
- package/dist/core/events/v3/live-routing.js +1 -0
- package/dist/core/events/v3/producers/hook-base.d.ts +1 -1
- package/dist/core/events/v3/producers/hook-base.d.ts.map +1 -1
- package/dist/core/events/v3/producers/hook-base.js +13 -2
- package/dist/core/events/v3/producers/intake.d.ts.map +1 -1
- package/dist/core/events/v3/producers/intake.js +10 -2
- package/dist/core/events/v3/producers/recorder.d.ts +39 -0
- package/dist/core/events/v3/producers/recorder.d.ts.map +1 -1
- package/dist/core/events/v3/producers/recorder.js +350 -17
- package/dist/core/hooks/adapter/output.d.ts +8 -0
- package/dist/core/hooks/adapter/output.d.ts.map +1 -1
- package/dist/core/hooks/adapter/output.js +11 -1
- package/dist/core/hooks/cli.js +303 -219
- package/dist/core/hooks/health.d.ts +59 -0
- package/dist/core/hooks/health.d.ts.map +1 -0
- package/dist/core/hooks/health.js +84 -0
- package/dist/core/hooks/resolve/transcript.d.ts.map +1 -1
- package/dist/core/hooks/resolve/transcript.js +10 -3
- package/dist/core/hooks/session-name-presence.d.ts.map +1 -1
- package/dist/core/hooks/session-name-presence.js +4 -1
- package/dist/core/qa-artifacts.d.ts +20 -0
- package/dist/core/qa-artifacts.d.ts.map +1 -0
- package/dist/core/qa-artifacts.js +110 -0
- package/dist/core/resources/contract.d.ts +96 -0
- package/dist/core/resources/contract.d.ts.map +1 -0
- package/dist/core/resources/contract.js +2 -0
- package/dist/core/resources/index.d.ts +6 -0
- package/dist/core/resources/index.d.ts.map +1 -0
- package/dist/core/resources/index.js +5 -0
- package/dist/core/resources/sampler.d.ts +34 -0
- package/dist/core/resources/sampler.d.ts.map +1 -0
- package/dist/core/resources/sampler.js +458 -0
- package/dist/core/resources/service-status.d.ts +3 -0
- package/dist/core/resources/service-status.d.ts.map +1 -0
- package/dist/core/resources/service-status.js +48 -0
- package/dist/core/resources/service.d.ts +26 -0
- package/dist/core/resources/service.d.ts.map +1 -0
- package/dist/core/resources/service.js +292 -0
- package/dist/core/resources/storage.d.ts +13 -0
- package/dist/core/resources/storage.d.ts.map +1 -0
- package/dist/core/resources/storage.js +30 -0
- package/dist/core/storage/atomic-json.d.ts +3 -0
- package/dist/core/storage/atomic-json.d.ts.map +1 -0
- package/dist/core/storage/atomic-json.js +15 -0
- package/dist/core/storage/builtins.d.ts.map +1 -1
- package/dist/core/storage/builtins.js +45 -6
- package/dist/core/storage/logger.d.ts +2 -0
- package/dist/core/storage/logger.d.ts.map +1 -1
- package/dist/core/storage/logger.js +2 -0
- package/dist/core/storage/query.d.ts +14 -0
- package/dist/core/storage/query.d.ts.map +1 -1
- package/dist/core/storage/query.js +51 -0
- package/dist/core/supervisor/activity.d.ts +4 -0
- package/dist/core/supervisor/activity.d.ts.map +1 -0
- package/dist/core/supervisor/activity.js +141 -0
- package/dist/core/supervisor/contract.d.ts +268 -0
- package/dist/core/supervisor/contract.d.ts.map +1 -0
- package/dist/core/supervisor/contract.js +35 -0
- package/dist/core/supervisor/explanations.d.ts +4 -0
- package/dist/core/supervisor/explanations.d.ts.map +1 -0
- package/dist/core/supervisor/explanations.js +71 -0
- package/dist/core/supervisor/findings.d.ts +20 -0
- package/dist/core/supervisor/findings.d.ts.map +1 -0
- package/dist/core/supervisor/findings.js +399 -0
- package/dist/core/supervisor/history.d.ts +9 -0
- package/dist/core/supervisor/history.d.ts.map +1 -0
- package/dist/core/supervisor/history.js +46 -0
- package/dist/core/supervisor/hook-health-alerts.d.ts +14 -0
- package/dist/core/supervisor/hook-health-alerts.d.ts.map +1 -0
- package/dist/core/supervisor/hook-health-alerts.js +70 -0
- package/dist/core/supervisor/hook-health-storage.d.ts +5 -0
- package/dist/core/supervisor/hook-health-storage.d.ts.map +1 -0
- package/dist/core/supervisor/hook-health-storage.js +24 -0
- package/dist/core/supervisor/hook-health.d.ts +72 -0
- package/dist/core/supervisor/hook-health.d.ts.map +1 -0
- package/dist/core/supervisor/hook-health.js +203 -0
- package/dist/core/supervisor/hooks.d.ts +10 -0
- package/dist/core/supervisor/hooks.d.ts.map +1 -0
- package/dist/core/supervisor/hooks.js +28 -0
- package/dist/core/supervisor/index.d.ts +15 -0
- package/dist/core/supervisor/index.d.ts.map +1 -0
- package/dist/core/supervisor/index.js +14 -0
- package/dist/core/supervisor/log-feed.d.ts +9 -0
- package/dist/core/supervisor/log-feed.d.ts.map +1 -0
- package/dist/core/supervisor/log-feed.js +103 -0
- package/dist/core/supervisor/service.d.ts +29 -0
- package/dist/core/supervisor/service.d.ts.map +1 -0
- package/dist/core/supervisor/service.js +450 -0
- package/dist/core/supervisor/services.d.ts +11 -0
- package/dist/core/supervisor/services.d.ts.map +1 -0
- package/dist/core/supervisor/services.js +155 -0
- package/dist/core/supervisor/status.d.ts +3 -0
- package/dist/core/supervisor/status.d.ts.map +1 -0
- package/dist/core/supervisor/status.js +48 -0
- package/dist/core/supervisor/storage.d.ts +30 -0
- package/dist/core/supervisor/storage.d.ts.map +1 -0
- package/dist/core/supervisor/storage.js +73 -0
- package/dist/core/supervisor/timeline.d.ts +3 -0
- package/dist/core/supervisor/timeline.d.ts.map +1 -0
- package/dist/core/supervisor/timeline.js +87 -0
- package/dist/core/workflow/admission.d.ts +23 -0
- package/dist/core/workflow/admission.d.ts.map +1 -0
- package/dist/core/workflow/admission.js +136 -0
- package/dist/core/workflow/engine.d.ts.map +1 -1
- package/dist/core/workflow/engine.js +77 -2
- package/dist/core/workflow/index.d.ts +3 -2
- package/dist/core/workflow/index.d.ts.map +1 -1
- package/dist/core/workflow/index.js +2 -1
- package/dist/core/workflow/proof.d.ts +2 -1
- package/dist/core/workflow/proof.d.ts.map +1 -1
- package/dist/core/workflow/proof.js +39 -1
- package/dist/core/workflow/run-state.d.ts +3 -2
- package/dist/core/workflow/run-state.d.ts.map +1 -1
- package/dist/core/workflow/run-state.js +8 -1
- package/dist/core/workflow/types.d.ts +33 -1
- package/dist/core/workflow/types.d.ts.map +1 -1
- package/dist/core/workflow/types.js +2 -1
- package/dist/lib/admission.d.ts +71 -0
- package/dist/lib/admission.d.ts.map +1 -0
- package/dist/lib/admission.js +264 -0
- package/dist/lib/agent-browser/client.d.ts +1 -1
- package/dist/lib/agent-browser/client.d.ts.map +1 -1
- package/dist/lib/agent-browser/client.js +1 -5
- package/dist/lib/browser/capture-fidelity.d.ts +39 -0
- package/dist/lib/browser/capture-fidelity.d.ts.map +1 -0
- package/dist/lib/browser/capture-fidelity.js +84 -0
- package/dist/lib/browser/client.d.ts +46 -1
- package/dist/lib/browser/client.d.ts.map +1 -1
- package/dist/lib/browser/client.js +168 -9
- package/dist/lib/browser/critique.d.ts +38 -1
- package/dist/lib/browser/critique.d.ts.map +1 -1
- package/dist/lib/browser/critique.js +34 -6
- package/dist/lib/browser/index.d.ts +5 -1
- package/dist/lib/browser/index.d.ts.map +1 -1
- package/dist/lib/browser/index.js +4 -0
- package/dist/lib/browser/page-review-judge.d.ts +64 -0
- package/dist/lib/browser/page-review-judge.d.ts.map +1 -0
- package/dist/lib/browser/page-review-judge.js +270 -0
- package/dist/lib/browser/page-review-pack.d.ts +613 -0
- package/dist/lib/browser/page-review-pack.d.ts.map +1 -0
- package/dist/lib/browser/page-review-pack.js +1751 -0
- package/dist/lib/browser/qa-run-contracts.d.ts +377 -0
- package/dist/lib/browser/qa-run-contracts.d.ts.map +1 -0
- package/dist/lib/browser/qa-run-contracts.js +361 -0
- package/dist/lib/browser/qa-run.d.ts +141 -0
- package/dist/lib/browser/qa-run.d.ts.map +1 -0
- package/dist/lib/browser/qa-run.js +1283 -0
- package/dist/lib/browser/request-diagnostics.d.ts +13 -0
- package/dist/lib/browser/request-diagnostics.d.ts.map +1 -0
- package/dist/lib/browser/request-diagnostics.js +18 -0
- package/dist/lib/browser/tiling.d.ts +19 -0
- package/dist/lib/browser/tiling.d.ts.map +1 -1
- package/dist/lib/browser/tiling.js +28 -0
- package/dist/lib/cookies/client.d.ts +9 -0
- package/dist/lib/cookies/client.d.ts.map +1 -1
- package/dist/lib/cookies/client.js +197 -44
- package/dist/lib/cookies/extra.d.ts +18 -0
- package/dist/lib/cookies/extra.d.ts.map +1 -0
- package/dist/lib/cookies/extra.js +14 -0
- package/dist/lib/cookies/index.d.ts +2 -1
- package/dist/lib/cookies/index.d.ts.map +1 -1
- package/dist/lib/cookies/index.js +2 -1
- package/dist/lib/coord-root-id.d.ts +9 -0
- package/dist/lib/coord-root-id.d.ts.map +1 -0
- package/dist/lib/coord-root-id.js +17 -0
- package/dist/lib/durable-job.d.ts +124 -0
- package/dist/lib/durable-job.d.ts.map +1 -0
- package/dist/lib/durable-job.js +296 -0
- package/dist/lib/http/client.d.ts +7 -1
- package/dist/lib/http/client.d.ts.map +1 -1
- package/dist/lib/http/client.js +2 -0
- package/dist/lib/instructions/apply.d.ts +3 -1
- package/dist/lib/instructions/apply.d.ts.map +1 -1
- package/dist/lib/instructions/apply.js +74 -3
- package/dist/lib/instructions/templates.d.ts.map +1 -1
- package/dist/lib/instructions/templates.js +11 -2
- package/package.json +19 -2
- package/src/commander.ts +75 -1
- package/src/commands/admission.ts +699 -0
- package/src/commands/agents.ts +189 -50
- package/src/commands/artifacts.ts +132 -18
- package/src/commands/browse-ai.ts +10 -5
- package/src/commands/browse.ts +496 -20
- package/src/commands/diagnostics.ts +271 -0
- package/src/commands/fetch.ts +1 -0
- package/src/commands/files.ts +102 -2
- package/src/commands/governor.ts +8 -0
- package/src/commands/ledger-v3.ts +82 -0
- package/src/commands/qa-record.ts +682 -0
- package/src/commands/qa-run.ts +503 -0
- package/src/commands/qa-status.ts +608 -0
- package/src/commands/qa-verify.ts +238 -0
- package/src/commands/resources.ts +38 -0
- package/src/commands/review-pack.ts +1281 -0
- package/src/commands/supervisor.ts +141 -0
- package/src/commands/web.ts +19 -0
- package/src/commands/workflow.ts +8 -0
- package/src/core/agents/cli.ts +7 -3
- package/src/core/agents/health.ts +142 -0
- package/src/core/agents/mailbox.ts +373 -0
- package/src/core/agents/qa-signal.ts +261 -0
- package/src/core/agents/reconcile-coordination-v3.ts +77 -0
- package/src/core/agents/render/prompt-context.ts +42 -12
- package/src/core/agents/render/session-context.ts +37 -3
- package/src/core/agents/rules/commit-conflict.ts +58 -1
- package/src/core/agents/rules/stop-hook.ts +6 -12
- package/src/core/agents/session-finalizer-v3.ts +4 -1
- package/src/core/agents/session-name-display.ts +78 -7
- package/src/core/agents/state/heartbeat-reader.ts +7 -0
- package/src/core/agents/state/heartbeat-writer.ts +23 -0
- package/src/core/agents/state/live-coordination-view.ts +1 -0
- package/src/core/agents/state/live-coordination-writer.ts +5 -0
- package/src/core/artifacts/constants.ts +1 -1
- package/src/core/artifacts/index.ts +565 -30
- package/src/core/config.ts +134 -2
- package/src/core/diagnostics/advice.ts +147 -0
- package/src/core/diagnostics/bundle.ts +1250 -0
- package/src/core/diagnostics/comparison.ts +565 -0
- package/src/core/diagnostics/contract.ts +311 -0
- package/src/core/diagnostics/identity.ts +11 -0
- package/src/core/diagnostics/index.ts +7 -0
- package/src/core/diagnostics/replay.ts +314 -0
- package/src/core/diagnostics/sanitize.ts +97 -0
- package/src/core/events/legacy-storage/compression.ts +130 -0
- package/src/core/events/legacy-storage/index.ts +1 -0
- package/src/core/events/v3/archive-retention.ts +251 -0
- package/src/core/events/v3/bootstrap.ts +10 -0
- package/src/core/events/v3/capabilities.ts +2 -0
- package/src/core/events/v3/coordination-view.ts +100 -11
- package/src/core/events/v3/index.ts +9 -0
- package/src/core/events/v3/live-routing.ts +1 -0
- package/src/core/events/v3/producers/hook-base.ts +14 -2
- package/src/core/events/v3/producers/intake.ts +10 -2
- package/src/core/events/v3/producers/recorder.ts +420 -17
- package/src/core/hooks/adapter/output.ts +12 -1
- package/src/core/hooks/cli.ts +332 -247
- package/src/core/hooks/health.ts +146 -0
- package/src/core/hooks/resolve/transcript.ts +10 -3
- package/src/core/hooks/session-name-presence.ts +6 -1
- package/src/core/qa-artifacts.ts +126 -0
- package/src/core/resources/contract.ts +105 -0
- package/src/core/resources/index.ts +5 -0
- package/src/core/resources/sampler.ts +590 -0
- package/src/core/resources/service-status.ts +62 -0
- package/src/core/resources/service.ts +337 -0
- package/src/core/resources/storage.ts +44 -0
- package/src/core/storage/atomic-json.ts +15 -0
- package/src/core/storage/builtins.ts +62 -6
- package/src/core/storage/logger.ts +2 -0
- package/src/core/storage/query.ts +58 -0
- package/src/core/supervisor/activity.ts +193 -0
- package/src/core/supervisor/contract.ts +312 -0
- package/src/core/supervisor/explanations.ts +104 -0
- package/src/core/supervisor/findings.ts +788 -0
- package/src/core/supervisor/history.ts +61 -0
- package/src/core/supervisor/hook-health-alerts.ts +108 -0
- package/src/core/supervisor/hook-health-storage.ts +25 -0
- package/src/core/supervisor/hook-health.ts +301 -0
- package/src/core/supervisor/hooks.ts +35 -0
- package/src/core/supervisor/index.ts +14 -0
- package/src/core/supervisor/log-feed.ts +131 -0
- package/src/core/supervisor/service.ts +511 -0
- package/src/core/supervisor/services.ts +203 -0
- package/src/core/supervisor/status.ts +59 -0
- package/src/core/supervisor/storage.ts +126 -0
- package/src/core/supervisor/timeline.ts +133 -0
- package/src/core/workflow/admission.ts +215 -0
- package/src/core/workflow/engine.ts +93 -1
- package/src/core/workflow/index.ts +10 -0
- package/src/core/workflow/proof.ts +54 -1
- package/src/core/workflow/run-state.ts +13 -1
- package/src/core/workflow/types.ts +39 -1
- package/src/lib/admission.ts +347 -0
- package/src/lib/agent-browser/client.ts +2 -10
- package/src/lib/browser/capture-fidelity.ts +98 -0
- package/src/lib/browser/client.ts +212 -10
- package/src/lib/browser/critique.ts +62 -7
- package/src/lib/browser/index.ts +65 -0
- package/src/lib/browser/page-review-judge.ts +360 -0
- package/src/lib/browser/page-review-pack.ts +2384 -0
- package/src/lib/browser/qa-run-contracts.ts +743 -0
- package/src/lib/browser/qa-run.ts +1462 -0
- package/src/lib/browser/request-diagnostics.ts +27 -0
- package/src/lib/browser/tiling.ts +32 -0
- package/src/lib/cookies/client.ts +228 -42
- package/src/lib/cookies/extra.ts +28 -0
- package/src/lib/cookies/index.ts +2 -0
- package/src/lib/coord-root-id.ts +23 -0
- package/src/lib/durable-job.ts +407 -0
- package/src/lib/http/client.ts +13 -1
- package/src/lib/instructions/apply.ts +81 -2
- package/src/lib/instructions/templates.ts +11 -2
|
@@ -11,8 +11,13 @@ import {
|
|
|
11
11
|
type Cookie as PWCookie,
|
|
12
12
|
type Request,
|
|
13
13
|
} from "playwright";
|
|
14
|
-
import
|
|
14
|
+
import {
|
|
15
|
+
type CookieJar,
|
|
16
|
+
CookieStoreParseError,
|
|
17
|
+
type Cookie as JarCookie,
|
|
18
|
+
} from "../cookies/index.ts";
|
|
15
19
|
import { type AssertResult, type AssertSpec, buildAssertCheck } from "./asserts.js";
|
|
20
|
+
import { stitchPngRows } from "./capture-fidelity.js";
|
|
16
21
|
import {
|
|
17
22
|
buildClearContentAnnotationsScript,
|
|
18
23
|
buildContentAnnotateScript,
|
|
@@ -36,6 +41,7 @@ import {
|
|
|
36
41
|
type OverflowResult,
|
|
37
42
|
type WidthResult,
|
|
38
43
|
} from "./layout.js";
|
|
44
|
+
import { isBenignNextRscAbort } from "./request-diagnostics.js";
|
|
39
45
|
import {
|
|
40
46
|
buildClearRuntsAnnotationsScript,
|
|
41
47
|
buildRuntsAnnotateScript,
|
|
@@ -86,6 +92,17 @@ export interface BrowserOptions {
|
|
|
86
92
|
jar?: CookieJar | null;
|
|
87
93
|
/** Viewport. Default 1280x800. */
|
|
88
94
|
viewport?: { width: number; height: number };
|
|
95
|
+
/**
|
|
96
|
+
* Device scale factor (DPR) for the context. Unset keeps Playwright's
|
|
97
|
+
* default of 1, so screenshots are CSS-pixel sized. A higher value renders
|
|
98
|
+
* every screenshot at that multiple (2 doubles both dimensions).
|
|
99
|
+
*/
|
|
100
|
+
deviceScaleFactor?: number;
|
|
101
|
+
/**
|
|
102
|
+
* Emulated `prefers-color-scheme` for the context. Unset keeps Playwright's
|
|
103
|
+
* default (light), byte-identical to prior behavior.
|
|
104
|
+
*/
|
|
105
|
+
colorScheme?: "light" | "dark";
|
|
89
106
|
/** Default navigation timeout in ms. Default 30000. */
|
|
90
107
|
navigationTimeout?: number;
|
|
91
108
|
/**
|
|
@@ -308,12 +325,18 @@ export class Browser {
|
|
|
308
325
|
* the whole sequence — not just the launch — can be retried as a unit.
|
|
309
326
|
*/
|
|
310
327
|
private async openOnce(): Promise<void> {
|
|
328
|
+
const jarCookies = this.opts.jar?.list() ?? [];
|
|
329
|
+
|
|
311
330
|
// Hold a launch slot only across the spawn itself, not the browser's life.
|
|
312
331
|
await acquireLaunchSlot();
|
|
313
332
|
try {
|
|
314
333
|
this.context = await chromium.launchPersistentContext(this.profileDir, {
|
|
315
334
|
headless: !this.opts.headed,
|
|
316
335
|
viewport: this.opts.viewport ?? { width: 1280, height: 800 },
|
|
336
|
+
...(this.opts.deviceScaleFactor !== undefined
|
|
337
|
+
? { deviceScaleFactor: this.opts.deviceScaleFactor }
|
|
338
|
+
: {}),
|
|
339
|
+
...(this.opts.colorScheme ? { colorScheme: this.opts.colorScheme } : {}),
|
|
317
340
|
...(this.opts.launchTimeout !== undefined ? { timeout: this.opts.launchTimeout } : {}),
|
|
318
341
|
...(this.opts.launchArgs && this.opts.launchArgs.length > 0
|
|
319
342
|
? { args: this.opts.launchArgs }
|
|
@@ -328,11 +351,8 @@ export class Browser {
|
|
|
328
351
|
}
|
|
329
352
|
this.context.setDefaultNavigationTimeout(this.opts.navigationTimeout ?? 30_000);
|
|
330
353
|
|
|
331
|
-
if (
|
|
332
|
-
|
|
333
|
-
if (jarCookies.length > 0) {
|
|
334
|
-
await this.context.addCookies(jarCookies.map(toPWCookie));
|
|
335
|
-
}
|
|
354
|
+
if (jarCookies.length > 0) {
|
|
355
|
+
await this.context.addCookies(jarCookies.map(toPWCookie));
|
|
336
356
|
}
|
|
337
357
|
|
|
338
358
|
// Caller-injected extraHeaders callback (e.g., for Cloudflare-bypass
|
|
@@ -396,6 +416,11 @@ export class Browser {
|
|
|
396
416
|
this.consoleEvents = [];
|
|
397
417
|
this.pageErrors = [];
|
|
398
418
|
this.failedRequests = [];
|
|
419
|
+
if (err instanceof CookieStoreParseError) {
|
|
420
|
+
throw new Error(`Failed to open browser during cookie-store load: ${err.message}`, {
|
|
421
|
+
cause: err,
|
|
422
|
+
});
|
|
423
|
+
}
|
|
399
424
|
if (attempt < maxAttempts) {
|
|
400
425
|
await new Promise((resolve) => setTimeout(resolve, attempt * 250));
|
|
401
426
|
}
|
|
@@ -425,11 +450,15 @@ export class Browser {
|
|
|
425
450
|
this.pageErrors.push({ message: err.message, stack: err.stack });
|
|
426
451
|
});
|
|
427
452
|
page.on("requestfailed", (req: Request) => {
|
|
428
|
-
|
|
453
|
+
const failedRequest = {
|
|
429
454
|
url: req.url(),
|
|
430
455
|
method: req.method(),
|
|
431
456
|
failure: req.failure()?.errorText ?? "unknown",
|
|
432
457
|
resourceType: req.resourceType(),
|
|
458
|
+
};
|
|
459
|
+
if (isBenignNextRscAbort(failedRequest)) return;
|
|
460
|
+
this.failedRequests.push({
|
|
461
|
+
...failedRequest,
|
|
433
462
|
status: null,
|
|
434
463
|
kind: "network",
|
|
435
464
|
});
|
|
@@ -607,6 +636,181 @@ export class Browser {
|
|
|
607
636
|
return buf.toString("base64");
|
|
608
637
|
}
|
|
609
638
|
|
|
639
|
+
/**
|
|
640
|
+
* PNG of a document-space rect captured the way a reader sees it: scroll so
|
|
641
|
+
* the rect's top sits at the top of the viewport, wait for the scroll to
|
|
642
|
+
* settle (instant scroll, then rAF frames until `scrollY` stops moving),
|
|
643
|
+
* and clip the viewport. Restores the scroll position afterwards.
|
|
644
|
+
*
|
|
645
|
+
* Bands are taller than the viewport. Rather than resizing the viewport to
|
|
646
|
+
* the band height (which reflows `vh`-sized layout, moves sticky and fixed
|
|
647
|
+
* elements, and so stops matching what the user sees), the rect is captured
|
|
648
|
+
* in viewport-height pieces at the real viewport and the pieces are
|
|
649
|
+
* stitched with pngjs. The final piece of a multi-piece rect is anchored to
|
|
650
|
+
* the viewport bottom so a fixed header, which sits at the viewport top, is
|
|
651
|
+
* not repeated in the middle of the band. No viewport change is made.
|
|
652
|
+
*
|
|
653
|
+
* Pixels come back at the page's device scale factor, so a rect at DPR 2
|
|
654
|
+
* yields an image twice the rect's CSS size, the same as a full-page
|
|
655
|
+
* screenshot cropped in pixel space would.
|
|
656
|
+
*
|
|
657
|
+
* Parity with the full-page screenshot: a full-page capture renders the
|
|
658
|
+
* whole document as one viewport, so a fixed header or a stuck sticky bar
|
|
659
|
+
* appears once, at its document position. Scrolled, the same element would
|
|
660
|
+
* ride along at the top of every piece and differ from the full-page crop
|
|
661
|
+
* on every band but the first. So while a piece is captured at a non-zero
|
|
662
|
+
* scroll, every `position: fixed`/`sticky` element that has left its
|
|
663
|
+
* scroll-0 document position is given `visibility: hidden` (layout kept,
|
|
664
|
+
* inline style restored afterwards). The result is the region as a
|
|
665
|
+
* full-page screenshot would show it, without the full-page raster.
|
|
666
|
+
*/
|
|
667
|
+
async captureRegionByScroll(rect: {
|
|
668
|
+
x: number;
|
|
669
|
+
y: number;
|
|
670
|
+
width: number;
|
|
671
|
+
height: number;
|
|
672
|
+
}): Promise<Buffer> {
|
|
673
|
+
const page = this.currentPage;
|
|
674
|
+
if (!(rect.width > 0) || !(rect.height > 0)) {
|
|
675
|
+
throw new Error(
|
|
676
|
+
`captureRegionByScroll: rect must have a positive size (got ${rect.width}×${rect.height})`,
|
|
677
|
+
);
|
|
678
|
+
}
|
|
679
|
+
const settle = (top: number) =>
|
|
680
|
+
page.evaluate(async (target: number) => {
|
|
681
|
+
window.scrollTo({ left: window.scrollX, top: target, behavior: "instant" });
|
|
682
|
+
const frame = () => new Promise<void>((r) => requestAnimationFrame(() => r()));
|
|
683
|
+
let last = Number.NaN;
|
|
684
|
+
for (let i = 0; i < 8; i++) {
|
|
685
|
+
await frame();
|
|
686
|
+
const now = window.scrollY;
|
|
687
|
+
if (now === last) break;
|
|
688
|
+
last = now;
|
|
689
|
+
}
|
|
690
|
+
return {
|
|
691
|
+
scrollX: window.scrollX,
|
|
692
|
+
scrollY: window.scrollY,
|
|
693
|
+
innerWidth: window.innerWidth,
|
|
694
|
+
innerHeight: window.innerHeight,
|
|
695
|
+
};
|
|
696
|
+
}, top);
|
|
697
|
+
const original = await page.evaluate(() => ({ x: window.scrollX, y: window.scrollY }));
|
|
698
|
+
const pieces: Buffer[] = [];
|
|
699
|
+
// Viewport-pinned candidates, measured at scroll 0 so each later capture
|
|
700
|
+
// can tell "still where the full page shows it" from "riding along".
|
|
701
|
+
await settle(0);
|
|
702
|
+
// Hiding uses opacity, not visibility: `visibility: hidden` on the pinned
|
|
703
|
+
// element is undone by any descendant that sets `visibility: visible`
|
|
704
|
+
// (a revealed brand label inside a sticky bar did exactly that), while
|
|
705
|
+
// opacity is a group effect no descendant can override. Transitions are
|
|
706
|
+
// switched off inline so the capture never lands mid-fade.
|
|
707
|
+
const pinned = await page.evaluateHandle(() => {
|
|
708
|
+
const out: Array<{
|
|
709
|
+
el: HTMLElement;
|
|
710
|
+
top: number;
|
|
711
|
+
priorOpacity: string;
|
|
712
|
+
priorOpacityPriority: string;
|
|
713
|
+
priorTransition: string;
|
|
714
|
+
priorTransitionPriority: string;
|
|
715
|
+
}> = [];
|
|
716
|
+
const all = document.querySelectorAll<HTMLElement>("body *");
|
|
717
|
+
const limit = Math.min(all.length, 20_000);
|
|
718
|
+
for (let i = 0; i < limit; i++) {
|
|
719
|
+
const el = all[i] as HTMLElement;
|
|
720
|
+
const position = getComputedStyle(el).position;
|
|
721
|
+
if (position !== "fixed" && position !== "sticky") continue;
|
|
722
|
+
out.push({
|
|
723
|
+
el,
|
|
724
|
+
top: el.getBoundingClientRect().top + window.scrollY,
|
|
725
|
+
priorOpacity: el.style.getPropertyValue("opacity"),
|
|
726
|
+
priorOpacityPriority: el.style.getPropertyPriority("opacity"),
|
|
727
|
+
priorTransition: el.style.getPropertyValue("transition"),
|
|
728
|
+
priorTransitionPriority: el.style.getPropertyPriority("transition"),
|
|
729
|
+
});
|
|
730
|
+
}
|
|
731
|
+
return out;
|
|
732
|
+
});
|
|
733
|
+
const syncPinned = (mode: "hide-moved" | "restore") =>
|
|
734
|
+
page.evaluate(
|
|
735
|
+
async ([entries, action]) => {
|
|
736
|
+
for (const entry of entries) {
|
|
737
|
+
const restore = () => {
|
|
738
|
+
entry.el.style.setProperty("opacity", entry.priorOpacity, entry.priorOpacityPriority);
|
|
739
|
+
entry.el.style.setProperty(
|
|
740
|
+
"transition",
|
|
741
|
+
entry.priorTransition,
|
|
742
|
+
entry.priorTransitionPriority,
|
|
743
|
+
);
|
|
744
|
+
};
|
|
745
|
+
if (action === "restore") {
|
|
746
|
+
restore();
|
|
747
|
+
continue;
|
|
748
|
+
}
|
|
749
|
+
const now = entry.el.getBoundingClientRect().top + window.scrollY;
|
|
750
|
+
if (Math.abs(now - entry.top) > 1) {
|
|
751
|
+
entry.el.style.setProperty("transition", "none", "important");
|
|
752
|
+
entry.el.style.setProperty("opacity", "0", "important");
|
|
753
|
+
} else {
|
|
754
|
+
restore();
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
// Let the style change paint before the screenshot is taken.
|
|
758
|
+
await new Promise<void>((r) => requestAnimationFrame(() => r()));
|
|
759
|
+
},
|
|
760
|
+
[pinned, mode] as const,
|
|
761
|
+
);
|
|
762
|
+
try {
|
|
763
|
+
const bottom = rect.y + rect.height;
|
|
764
|
+
let cursor = rect.y;
|
|
765
|
+
let first = true;
|
|
766
|
+
while (cursor < bottom) {
|
|
767
|
+
const remaining = bottom - cursor;
|
|
768
|
+
// Top-align the piece; a final partial piece is then re-anchored to
|
|
769
|
+
// the viewport bottom once the viewport height is known.
|
|
770
|
+
let view = await settle(cursor);
|
|
771
|
+
if (!first && remaining < view.innerHeight) {
|
|
772
|
+
view = await settle(Math.max(0, bottom - view.innerHeight));
|
|
773
|
+
}
|
|
774
|
+
await syncPinned("hide-moved");
|
|
775
|
+
const offset = cursor - view.scrollY;
|
|
776
|
+
if (offset < 0 || offset >= view.innerHeight) {
|
|
777
|
+
throw new Error(
|
|
778
|
+
`captureRegionByScroll: document y ${cursor} is not reachable in the viewport ` +
|
|
779
|
+
`(scrollY ${view.scrollY}, innerHeight ${view.innerHeight})`,
|
|
780
|
+
);
|
|
781
|
+
}
|
|
782
|
+
const pieceHeight = Math.min(remaining, view.innerHeight - offset);
|
|
783
|
+
const clipX = Math.max(0, rect.x - view.scrollX);
|
|
784
|
+
const clipWidth = Math.min(rect.width, view.innerWidth - clipX);
|
|
785
|
+
if (!(clipWidth > 0)) {
|
|
786
|
+
throw new Error(
|
|
787
|
+
`captureRegionByScroll: document x ${rect.x} is outside the viewport (innerWidth ${view.innerWidth})`,
|
|
788
|
+
);
|
|
789
|
+
}
|
|
790
|
+
pieces.push(
|
|
791
|
+
await page.screenshot({
|
|
792
|
+
type: "png",
|
|
793
|
+
clip: { x: clipX, y: offset, width: clipWidth, height: pieceHeight },
|
|
794
|
+
}),
|
|
795
|
+
);
|
|
796
|
+
cursor += pieceHeight;
|
|
797
|
+
first = false;
|
|
798
|
+
}
|
|
799
|
+
} finally {
|
|
800
|
+
try {
|
|
801
|
+
await syncPinned("restore");
|
|
802
|
+
} finally {
|
|
803
|
+
await pinned.dispose();
|
|
804
|
+
await page.evaluate(
|
|
805
|
+
({ x, y }: { x: number; y: number }) =>
|
|
806
|
+
window.scrollTo({ left: x, top: y, behavior: "instant" }),
|
|
807
|
+
original,
|
|
808
|
+
);
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
return stitchPngRows(pieces);
|
|
812
|
+
}
|
|
813
|
+
|
|
610
814
|
/** Document-space rects + labels for each element matching `selector` (semantic tiling). */
|
|
611
815
|
async elementTiles(
|
|
612
816
|
selector: string,
|
|
@@ -1594,9 +1798,7 @@ export class Browser {
|
|
|
1594
1798
|
if (this.opts.jar) {
|
|
1595
1799
|
try {
|
|
1596
1800
|
const live = await this.context.cookies();
|
|
1597
|
-
|
|
1598
|
-
this.opts.jar.set(toJarCookie(c));
|
|
1599
|
-
}
|
|
1801
|
+
this.opts.jar.merge(live.map(toJarCookie));
|
|
1600
1802
|
} catch {
|
|
1601
1803
|
// Cookie persist is best-effort; never block close on it.
|
|
1602
1804
|
}
|
|
@@ -18,7 +18,12 @@
|
|
|
18
18
|
// orchestration live here; the model call lives in the host.
|
|
19
19
|
|
|
20
20
|
import { PNG } from "pngjs";
|
|
21
|
-
import {
|
|
21
|
+
import {
|
|
22
|
+
bandOversizedRect,
|
|
23
|
+
bandsCoveringRects,
|
|
24
|
+
snappedBandRects,
|
|
25
|
+
type VisualAtom,
|
|
26
|
+
} from "./tiling.js";
|
|
22
27
|
|
|
23
28
|
export interface CritiqueTile {
|
|
24
29
|
index: number;
|
|
@@ -42,10 +47,27 @@ export interface CritiqueFinding {
|
|
|
42
47
|
description: string;
|
|
43
48
|
}
|
|
44
49
|
|
|
50
|
+
/**
|
|
51
|
+
* How much of the page the tiles actually cover. The tiler keeps at most
|
|
52
|
+
* `maxTiles` bands and drops the rest, so on a tall page `capped` is true and
|
|
53
|
+
* `reviewed_height_px` stops short of `page_height_px`. Callers that turn a
|
|
54
|
+
* critique into a verdict must read this: a pass over the first 24 bands is
|
|
55
|
+
* not a pass over the page.
|
|
56
|
+
*/
|
|
57
|
+
export interface CritiqueCoverage {
|
|
58
|
+
page_height_px: number;
|
|
59
|
+
reviewed_height_px: number;
|
|
60
|
+
bands_total: number;
|
|
61
|
+
bands_reviewed: number;
|
|
62
|
+
capped: boolean;
|
|
63
|
+
}
|
|
64
|
+
|
|
45
65
|
export interface CritiqueResult {
|
|
46
66
|
rule: "critique";
|
|
47
67
|
/** Number of tiles the page was cut into. */
|
|
48
68
|
tiles: number;
|
|
69
|
+
/** Tile coverage of the page; absent only for results built without tiles. */
|
|
70
|
+
coverage?: CritiqueCoverage;
|
|
49
71
|
/** Whether a provider was available. False → outcome "skipped". */
|
|
50
72
|
provider: boolean;
|
|
51
73
|
findings: CritiqueFinding[];
|
|
@@ -137,6 +159,15 @@ export function bandRects(
|
|
|
137
159
|
* the provider would downscale. Atom coordinates must be in the same pixel
|
|
138
160
|
* space as the screenshot (identical at deviceScaleFactor 1; scale them if
|
|
139
161
|
* the capture DPR differs).
|
|
162
|
+
*
|
|
163
|
+
* `hitRects` (document-space rectangles a deterministic gate already flagged)
|
|
164
|
+
* add bands past the `maxTiles` cap: every full-page band that intersects a
|
|
165
|
+
* hit rect and was dropped by the cap is cut as well, labelled `hit band N`
|
|
166
|
+
* (N is the band's 1-based position in the full band list, and the tile's
|
|
167
|
+
* `index` is that position minus one), and appended after the kept bands.
|
|
168
|
+
* `coverage` stays honest about the kept prefix; `hitBands` counts the
|
|
169
|
+
* extras. Ignored for selector tiling (`elementRects`), which has no cap to
|
|
170
|
+
* look past in that sense.
|
|
140
171
|
*/
|
|
141
172
|
export function tilesFromFullPage(
|
|
142
173
|
fullPageBuffer: Buffer,
|
|
@@ -146,8 +177,11 @@ export function tilesFromFullPage(
|
|
|
146
177
|
overlap?: number;
|
|
147
178
|
maxTiles: number;
|
|
148
179
|
atoms?: VisualAtom[];
|
|
180
|
+
hitRects?: Array<{ x: number; y: number; width: number; height: number }>;
|
|
181
|
+
/** Cap on hit bands appended past `maxTiles` (default 50). */
|
|
182
|
+
maxHitBands?: number;
|
|
149
183
|
},
|
|
150
|
-
): CritiqueTile[] {
|
|
184
|
+
): { tiles: CritiqueTile[]; coverage: CritiqueCoverage; hitBands: number } {
|
|
151
185
|
const png = PNG.sync.read(fullPageBuffer);
|
|
152
186
|
const snapOpts = {
|
|
153
187
|
bandHeight: opts.bandHeight ?? 1400,
|
|
@@ -185,8 +219,7 @@ export function tilesFromFullPage(
|
|
|
185
219
|
height: b.height,
|
|
186
220
|
}));
|
|
187
221
|
}
|
|
188
|
-
const
|
|
189
|
-
for (const rect of rects.slice(0, opts.maxTiles)) {
|
|
222
|
+
const cutTile = (rect: (typeof rects)[number]): CritiqueTile => {
|
|
190
223
|
const sx = Math.max(0, Math.min(Math.round(rect.x), png.width - 1));
|
|
191
224
|
const sy = Math.max(0, Math.min(Math.round(rect.y), png.height - 1));
|
|
192
225
|
const w = Math.max(1, Math.min(Math.round(rect.width), png.width - sx));
|
|
@@ -199,7 +232,7 @@ export function tilesFromFullPage(
|
|
|
199
232
|
const dstStart = row * w * 4;
|
|
200
233
|
png.data.copy(dst.data, dstStart, srcStart, srcStart + w * 4);
|
|
201
234
|
}
|
|
202
|
-
|
|
235
|
+
return {
|
|
203
236
|
index: rect.index,
|
|
204
237
|
label: rect.label,
|
|
205
238
|
scrollY: sy,
|
|
@@ -207,9 +240,31 @@ export function tilesFromFullPage(
|
|
|
207
240
|
width: w,
|
|
208
241
|
height: h,
|
|
209
242
|
pngBase64: PNG.sync.write(dst).toString("base64"),
|
|
210
|
-
}
|
|
243
|
+
};
|
|
244
|
+
};
|
|
245
|
+
const kept = rects.slice(0, opts.maxTiles);
|
|
246
|
+
const tiles: CritiqueTile[] = kept.map(cutTile);
|
|
247
|
+
let hitBands = 0;
|
|
248
|
+
const banding = !(opts.elementRects && opts.elementRects.length > 0);
|
|
249
|
+
if (banding && opts.hitRects && opts.hitRects.length > 0) {
|
|
250
|
+
for (const index of bandsCoveringRects(rects, kept.length, opts.hitRects, opts.maxHitBands)) {
|
|
251
|
+
const band = rects[index];
|
|
252
|
+
if (!band) continue;
|
|
253
|
+
tiles.push(cutTile({ ...band, label: `hit band ${index + 1}` }));
|
|
254
|
+
hitBands++;
|
|
255
|
+
}
|
|
211
256
|
}
|
|
212
|
-
|
|
257
|
+
const coverage: CritiqueCoverage = {
|
|
258
|
+
page_height_px: png.height,
|
|
259
|
+
reviewed_height_px: kept.reduce(
|
|
260
|
+
(max, rect) => Math.max(max, Math.min(png.height, Math.round(rect.y + rect.height))),
|
|
261
|
+
0,
|
|
262
|
+
),
|
|
263
|
+
bands_total: rects.length,
|
|
264
|
+
bands_reviewed: kept.length,
|
|
265
|
+
capped: rects.length > kept.length,
|
|
266
|
+
};
|
|
267
|
+
return { tiles, coverage, hitBands };
|
|
213
268
|
}
|
|
214
269
|
|
|
215
270
|
/**
|
package/src/lib/browser/index.ts
CHANGED
|
@@ -39,6 +39,7 @@ export type {
|
|
|
39
39
|
} from "./content-checks.js";
|
|
40
40
|
export {
|
|
41
41
|
bandRects,
|
|
42
|
+
type CritiqueCoverage,
|
|
42
43
|
type CritiqueFinding,
|
|
43
44
|
type CritiqueProvider,
|
|
44
45
|
type CritiqueResult,
|
|
@@ -85,6 +86,39 @@ export {
|
|
|
85
86
|
serializeNetscapeCookies,
|
|
86
87
|
writeNetscapeCookieFile,
|
|
87
88
|
} from "./netscape-cookies.js";
|
|
89
|
+
export {
|
|
90
|
+
type JudgedContext,
|
|
91
|
+
type JudgePageReviewPackOptions,
|
|
92
|
+
type JudgePageReviewPackResult,
|
|
93
|
+
judgePageReviewPack,
|
|
94
|
+
toCritiqueRecords,
|
|
95
|
+
} from "./page-review-judge.js";
|
|
96
|
+
export {
|
|
97
|
+
buildInspectionPlan,
|
|
98
|
+
type FinalizePageReviewPackInput,
|
|
99
|
+
finalizePageReviewPack,
|
|
100
|
+
findingsSchemaDocument,
|
|
101
|
+
listPackContexts,
|
|
102
|
+
PAGE_REVIEW_FINDINGS_SCHEMA,
|
|
103
|
+
PAGE_REVIEW_PACK_DIRNAME,
|
|
104
|
+
PAGE_REVIEW_PACK_SCHEMA,
|
|
105
|
+
type PageReviewContextCapture,
|
|
106
|
+
type PageReviewContextRecord,
|
|
107
|
+
type PageReviewCritiqueRecord,
|
|
108
|
+
type PageReviewGateRecord,
|
|
109
|
+
type PageReviewInspectionPlan,
|
|
110
|
+
type PageReviewPackManifest,
|
|
111
|
+
type PageReviewTileRecord,
|
|
112
|
+
packPaths,
|
|
113
|
+
readPackContext,
|
|
114
|
+
readPackDom,
|
|
115
|
+
readPackFullPage,
|
|
116
|
+
readPackManifest,
|
|
117
|
+
readPackSignature,
|
|
118
|
+
readPackTiles,
|
|
119
|
+
renderReviewMarkdown,
|
|
120
|
+
writePackContext,
|
|
121
|
+
} from "./page-review-pack.js";
|
|
88
122
|
export {
|
|
89
123
|
type BrowserProxy,
|
|
90
124
|
type BrowserProxyGate,
|
|
@@ -108,6 +142,37 @@ export {
|
|
|
108
142
|
type QaSignature,
|
|
109
143
|
type QaStylesheetSignature,
|
|
110
144
|
} from "./qa-plan.js";
|
|
145
|
+
export {
|
|
146
|
+
defaultQaRunExec,
|
|
147
|
+
QA_RUN_HEADLESS_ONLY_ENV,
|
|
148
|
+
QA_RUN_RESULT_FILENAME,
|
|
149
|
+
type QaRunExec,
|
|
150
|
+
type QaRunExecOptions,
|
|
151
|
+
type QaRunExecResult,
|
|
152
|
+
type QaRunMatrixOptions,
|
|
153
|
+
runQaMatrix,
|
|
154
|
+
} from "./qa-run.js";
|
|
155
|
+
export {
|
|
156
|
+
computeVerdict,
|
|
157
|
+
contextIdFor,
|
|
158
|
+
mergeCoverage,
|
|
159
|
+
QA_RUN_JOB_SCHEMA_VERSION,
|
|
160
|
+
QA_RUN_RESULT_SCHEMA_VERSION,
|
|
161
|
+
type QaRunBlocker,
|
|
162
|
+
type QaRunCheck,
|
|
163
|
+
type QaRunCommandOutcome,
|
|
164
|
+
type QaRunContext,
|
|
165
|
+
type QaRunCritiqueOutcome,
|
|
166
|
+
type QaRunCritiquePool,
|
|
167
|
+
type QaRunInteraction,
|
|
168
|
+
type QaRunJob,
|
|
169
|
+
type QaRunJobValidation,
|
|
170
|
+
type QaRunPolicy,
|
|
171
|
+
type QaRunResult,
|
|
172
|
+
type QaRunReviewPack,
|
|
173
|
+
type QaRunVerdict,
|
|
174
|
+
validateQaRunJob,
|
|
175
|
+
} from "./qa-run-contracts.js";
|
|
111
176
|
export {
|
|
112
177
|
listQaSnapshotTargets,
|
|
113
178
|
loadQaSnapshot,
|