harnery 0.30.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.
- package/README.md +4 -4
- package/dist/commander.d.ts +8 -0
- package/dist/commander.d.ts.map +1 -1
- package/dist/commander.js +14 -13
- package/dist/commands/adapter.d.ts +12 -0
- package/dist/commands/adapter.d.ts.map +1 -0
- package/dist/commands/{harness.js → adapter.js} +35 -35
- package/dist/commands/agents.d.ts +3 -2
- package/dist/commands/agents.d.ts.map +1 -1
- package/dist/commands/agents.js +61 -60
- package/dist/commands/artifacts.d.ts +4 -0
- package/dist/commands/artifacts.d.ts.map +1 -0
- package/dist/commands/artifacts.js +143 -0
- package/dist/commands/backup.d.ts +1 -1
- package/dist/commands/backup.d.ts.map +1 -1
- package/dist/commands/backup.js +5 -2
- package/dist/commands/browse.d.ts.map +1 -1
- package/dist/commands/browse.js +310 -7
- package/dist/commands/checkpoint.d.ts +12 -0
- package/dist/commands/checkpoint.d.ts.map +1 -0
- package/dist/commands/checkpoint.js +162 -0
- package/dist/commands/context.d.ts +2 -2
- package/dist/commands/context.d.ts.map +1 -1
- package/dist/commands/context.js +3 -151
- package/dist/commands/decision.d.ts.map +1 -1
- package/dist/commands/decision.js +31 -7
- package/dist/commands/deinit.d.ts +2 -2
- package/dist/commands/deinit.js +15 -15
- package/dist/commands/doctor.js +23 -23
- package/dist/commands/governor.d.ts +4 -0
- package/dist/commands/governor.d.ts.map +1 -0
- package/dist/commands/{supervisor.js → governor.js} +133 -108
- package/dist/commands/init.d.ts +12 -12
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +44 -30
- package/dist/commands/{session.d.ts → journal.d.ts} +2 -2
- package/dist/commands/journal.d.ts.map +1 -0
- package/dist/commands/{scratch.js → journal.js} +47 -47
- package/dist/commands/policy.js +1 -1
- package/dist/commands/presence.js +2 -2
- package/dist/commands/sync.d.ts +1 -1
- package/dist/commands/sync.js +3 -3
- package/dist/commands/tunnel.d.ts +16 -0
- package/dist/commands/tunnel.d.ts.map +1 -1
- package/dist/commands/tunnel.js +193 -23
- package/dist/commands/web-fetch.js +1 -1
- package/dist/commands/web.d.ts +19 -0
- package/dist/commands/web.d.ts.map +1 -1
- package/dist/commands/web.js +51 -0
- package/dist/commands/work.d.ts.map +1 -1
- package/dist/commands/work.js +38 -22
- package/dist/commands/workflow.d.ts.map +1 -1
- package/dist/commands/workflow.js +35 -28
- package/dist/core/{harnesses → adapters}/attest-projection.d.ts +2 -2
- package/dist/core/adapters/attest-projection.d.ts.map +1 -0
- package/dist/core/{harnesses → adapters}/attest.d.ts +16 -16
- package/dist/core/adapters/attest.d.ts.map +1 -0
- package/dist/core/{harnesses → adapters}/attest.js +9 -9
- package/dist/core/{harnesses → adapters}/attestation.d.ts +16 -16
- package/dist/core/adapters/attestation.d.ts.map +1 -0
- package/dist/core/{harnesses → adapters}/attestation.js +20 -20
- package/dist/core/{harnesses → adapters}/bench.d.ts +12 -12
- package/dist/core/adapters/bench.d.ts.map +1 -0
- package/dist/core/{harnesses → adapters}/bench.js +12 -12
- package/dist/core/adapters/index.d.ts +13 -0
- package/dist/core/adapters/index.d.ts.map +1 -0
- package/dist/core/adapters/index.js +6 -0
- package/dist/core/{harnesses → adapters}/profiles.d.ts +11 -11
- package/dist/core/adapters/profiles.d.ts.map +1 -0
- package/dist/core/{harnesses → adapters}/profiles.js +11 -11
- package/dist/core/adapters/registry.d.ts +15 -0
- package/dist/core/adapters/registry.d.ts.map +1 -0
- package/dist/core/{harnesses → adapters}/registry.js +11 -11
- package/dist/core/{harnesses → adapters}/types.d.ts +23 -23
- package/dist/core/adapters/types.d.ts.map +1 -0
- package/dist/core/{harnesses → adapters}/types.js +1 -1
- package/dist/core/agents/canonical-emit.d.ts +4 -4
- package/dist/core/agents/canonical-emit.js +5 -5
- package/dist/core/agents/cli-emit.js +1 -1
- package/dist/core/agents/cli.js +30 -26
- package/dist/core/agents/codex-replay.d.ts +1 -1
- package/dist/core/agents/codex-replay.js +6 -6
- package/dist/core/agents/coord-client.d.ts +21 -2
- package/dist/core/agents/coord-client.d.ts.map +1 -1
- package/dist/core/agents/coord-client.js +122 -27
- package/dist/core/agents/events/consume.d.ts +1 -1
- package/dist/core/agents/events/emit.d.ts +5 -6
- package/dist/core/agents/events/emit.d.ts.map +1 -1
- package/dist/core/agents/events/emit.js +2 -2
- package/dist/core/agents/render/prompt-context.d.ts +21 -9
- package/dist/core/agents/render/prompt-context.d.ts.map +1 -1
- package/dist/core/agents/render/prompt-context.js +82 -30
- package/dist/core/agents/render/session-context.d.ts +1 -1
- package/dist/core/agents/render/session-context.js +5 -5
- package/dist/core/agents/rules/claim-conflict.d.ts +2 -6
- package/dist/core/agents/rules/claim-conflict.d.ts.map +1 -1
- package/dist/core/agents/rules/claim-conflict.js +1 -1
- package/dist/core/agents/rules/commit-conflict.js +98 -22
- package/dist/core/agents/rules/stop-hook.d.ts +9 -9
- package/dist/core/agents/rules/stop-hook.d.ts.map +1 -1
- package/dist/core/agents/rules/stop-hook.js +23 -5
- package/dist/core/agents/rules/verdict.d.ts +14 -0
- package/dist/core/agents/rules/verdict.d.ts.map +1 -0
- package/dist/core/agents/rules/verdict.js +1 -0
- package/dist/core/agents/session-events.js +3 -3
- package/dist/core/agents/state/council.d.ts +1 -1
- package/dist/core/agents/state/council.js +1 -1
- package/dist/core/agents/state/heartbeat-projector.d.ts +3 -2
- package/dist/core/agents/state/heartbeat-projector.d.ts.map +1 -1
- package/dist/core/agents/state/heartbeat-projector.js +14 -10
- package/dist/core/agents/state/heartbeat-writer.d.ts +1 -1
- package/dist/core/agents/state/heartbeat-writer.js +12 -12
- package/dist/core/agents/state/{scratch.d.ts → journal.d.ts} +7 -7
- package/dist/core/agents/state/{scratch.d.ts.map → journal.d.ts.map} +1 -1
- package/dist/core/agents/state/{scratch.js → journal.js} +12 -12
- package/dist/core/agents/state/pidmap.d.ts +28 -4
- package/dist/core/agents/state/pidmap.d.ts.map +1 -1
- package/dist/core/agents/state/pidmap.js +130 -15
- package/dist/core/agents/state/proc-start.d.ts +95 -0
- package/dist/core/agents/state/proc-start.d.ts.map +1 -0
- package/dist/core/agents/state/proc-start.js +199 -0
- package/dist/core/agents/state/shell-mutation.d.ts +1 -1
- package/dist/core/agents/state/shell-mutation.js +1 -1
- package/dist/core/agents/state/stale-sweep.js +7 -7
- package/dist/core/artifacts/index.d.ts +86 -0
- package/dist/core/artifacts/index.d.ts.map +1 -0
- package/dist/core/artifacts/index.js +421 -0
- package/dist/core/config.d.ts +9 -2
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +26 -2
- package/dist/core/context/index.d.ts +12 -12
- package/dist/core/context/index.js +10 -10
- package/dist/core/governor/adapter-spread.d.ts +52 -0
- package/dist/core/governor/adapter-spread.d.ts.map +1 -0
- package/dist/core/governor/adapter-spread.js +52 -0
- package/dist/core/governor/index.d.ts +7 -0
- package/dist/core/governor/index.d.ts.map +1 -0
- package/dist/core/governor/index.js +6 -0
- package/dist/core/governor/plan-api.d.ts +38 -0
- package/dist/core/governor/plan-api.d.ts.map +1 -0
- package/dist/core/governor/plan-api.js +83 -0
- package/dist/core/governor/plan-read.d.ts +5 -0
- package/dist/core/governor/plan-read.d.ts.map +1 -0
- package/dist/core/{supervisor → governor}/plan-read.js +66 -52
- package/dist/core/{supervisor → governor}/plan-types.d.ts +57 -56
- package/dist/core/governor/plan-types.d.ts.map +1 -0
- package/dist/core/{supervisor → governor}/plan-types.js +4 -4
- package/dist/core/governor/planning.d.ts +48 -0
- package/dist/core/governor/planning.d.ts.map +1 -0
- package/dist/core/{supervisor → governor}/planning.js +125 -94
- package/dist/core/governor/read.d.ts +6 -0
- package/dist/core/governor/read.d.ts.map +1 -0
- package/dist/core/governor/read.js +4 -0
- package/dist/core/governor/runner.d.ts +37 -0
- package/dist/core/governor/runner.d.ts.map +1 -0
- package/dist/core/{supervisor → governor}/runner.js +15 -15
- package/dist/core/governor/service-read.d.ts +6 -0
- package/dist/core/governor/service-read.d.ts.map +1 -0
- package/dist/core/{supervisor → governor}/service-read.js +12 -12
- package/dist/core/governor/service.d.ts +114 -0
- package/dist/core/governor/service.d.ts.map +1 -0
- package/dist/core/{supervisor → governor}/service.js +57 -57
- package/dist/core/governor/state.d.ts +116 -0
- package/dist/core/governor/state.d.ts.map +1 -0
- package/dist/core/{supervisor → governor}/state.js +228 -108
- package/dist/core/hooks/adapter/detect.d.ts +9 -0
- package/dist/core/hooks/{harness → adapter}/detect.d.ts.map +1 -1
- package/dist/core/hooks/{harness → adapter}/detect.js +8 -8
- package/dist/core/hooks/{harness → adapter}/events.d.ts +15 -14
- package/dist/core/hooks/adapter/events.d.ts.map +1 -0
- package/dist/core/hooks/{harness → adapter}/events.js +5 -5
- package/dist/core/hooks/{harness → adapter}/output.d.ts +20 -14
- package/dist/core/hooks/adapter/output.d.ts.map +1 -0
- package/dist/core/hooks/{harness → adapter}/output.js +30 -22
- package/dist/core/hooks/{harness → adapter}/parse.d.ts +5 -5
- package/dist/core/hooks/{harness → adapter}/parse.d.ts.map +1 -1
- package/dist/core/hooks/{harness → adapter}/parse.js +4 -4
- package/dist/core/hooks/{harness → adapter}/wiring.d.ts +15 -15
- package/dist/core/hooks/{harness → adapter}/wiring.d.ts.map +1 -1
- package/dist/core/hooks/{harness → adapter}/wiring.js +13 -13
- package/dist/core/hooks/cli.d.ts +3 -3
- package/dist/core/hooks/cli.js +175 -151
- package/dist/core/hooks/effects/image-capture.d.ts +5 -5
- package/dist/core/hooks/effects/image-capture.d.ts.map +1 -1
- package/dist/core/hooks/effects/image-capture.js +3 -3
- package/dist/core/hooks/effects/index.d.ts +12 -12
- package/dist/core/hooks/effects/index.d.ts.map +1 -1
- package/dist/core/hooks/effects/index.js +17 -17
- package/dist/core/hooks/events/emit.d.ts +2 -2
- package/dist/core/hooks/events/emit.d.ts.map +1 -1
- package/dist/core/hooks/events/emit.js +1 -1
- package/dist/core/hooks/events/rotate.js +1 -1
- package/dist/core/hooks/events/schema.d.ts +13 -5
- package/dist/core/hooks/events/schema.d.ts.map +1 -1
- package/dist/core/hooks/guard-path.d.ts +2 -2
- package/dist/core/hooks/guard-path.js +2 -2
- package/dist/core/hooks/index.d.ts +1 -1
- package/dist/core/hooks/index.d.ts.map +1 -1
- package/dist/core/hooks/resolve/anchor.d.ts +14 -5
- package/dist/core/hooks/resolve/anchor.d.ts.map +1 -1
- package/dist/core/hooks/resolve/anchor.js +64 -7
- package/dist/core/hooks/resolve/coord-root.d.ts +3 -3
- package/dist/core/hooks/resolve/coord-root.js +4 -4
- package/dist/core/hooks/resolve/intent.js +1 -1
- package/dist/core/hooks/resolve/owner.d.ts +1 -1
- package/dist/core/hooks/resolve/owner.d.ts.map +1 -1
- package/dist/core/hooks/resolve/owner.js +11 -5
- package/dist/core/{scratch → journal}/index.d.ts +25 -25
- package/dist/core/{scratch → journal}/index.d.ts.map +1 -1
- package/dist/core/{scratch → journal}/index.js +38 -38
- package/dist/core/policy/evaluate.d.ts +1 -1
- package/dist/core/policy/evaluate.d.ts.map +1 -1
- package/dist/core/policy/evaluate.js +7 -7
- package/dist/core/policy/types.d.ts +3 -3
- package/dist/core/policy/types.d.ts.map +1 -1
- package/dist/core/work/state.d.ts +12 -4
- package/dist/core/work/state.d.ts.map +1 -1
- package/dist/core/work/state.js +50 -17
- package/dist/core/workflow/adapters.d.ts +17 -0
- package/dist/core/workflow/adapters.d.ts.map +1 -0
- package/dist/core/workflow/adapters.js +21 -0
- package/dist/core/workflow/approvals.js +6 -6
- package/dist/core/workflow/billing.d.ts +9 -9
- package/dist/core/workflow/billing.js +9 -9
- package/dist/core/workflow/child-env.d.ts +10 -2
- package/dist/core/workflow/child-env.d.ts.map +1 -1
- package/dist/core/workflow/child-env.js +12 -4
- package/dist/core/workflow/engine.d.ts +15 -5
- package/dist/core/workflow/engine.d.ts.map +1 -1
- package/dist/core/workflow/engine.js +138 -83
- package/dist/core/workflow/evidence-preflight.d.ts +24 -0
- package/dist/core/workflow/evidence-preflight.d.ts.map +1 -0
- package/dist/core/workflow/evidence-preflight.js +134 -0
- package/dist/core/workflow/index.d.ts +1 -1
- package/dist/core/workflow/index.d.ts.map +1 -1
- package/dist/core/workflow/proof.d.ts +11 -5
- package/dist/core/workflow/proof.d.ts.map +1 -1
- package/dist/core/workflow/proof.js +45 -36
- package/dist/core/workflow/run-state.d.ts +1 -1
- package/dist/core/workflow/run-state.js +7 -7
- package/dist/core/workflow/sandbox-projection.d.ts +6 -6
- package/dist/core/workflow/sandbox-projection.d.ts.map +1 -1
- package/dist/core/workflow/sandbox-projection.js +11 -11
- package/dist/core/workflow/spawn-claude.d.ts +3 -3
- package/dist/core/workflow/spawn-claude.d.ts.map +1 -1
- package/dist/core/workflow/spawn-claude.js +9 -6
- package/dist/core/workflow/spawn-codex.d.ts +4 -4
- package/dist/core/workflow/spawn-codex.d.ts.map +1 -1
- package/dist/core/workflow/spawn-codex.js +9 -6
- package/dist/core/workflow/spawn-cursor.d.ts +4 -4
- package/dist/core/workflow/spawn-cursor.d.ts.map +1 -1
- package/dist/core/workflow/spawn-cursor.js +9 -6
- package/dist/core/workflow/spawn-failure.d.ts +1 -1
- package/dist/core/workflow/spawn-failure.js +1 -1
- package/dist/core/workflow/specialists.js +2 -2
- package/dist/core/workflow/{journal.d.ts → transcript.d.ts} +8 -8
- package/dist/core/workflow/transcript.d.ts.map +1 -0
- package/dist/core/workflow/{journal.js → transcript.js} +14 -14
- package/dist/core/workflow/types.d.ts +98 -51
- package/dist/core/workflow/types.d.ts.map +1 -1
- package/dist/core/workflow/types.js +11 -1
- package/dist/core/workflow/validate.d.ts +1 -1
- package/dist/core/workflow/validate.js +1 -1
- package/dist/core/workflow/workspaces/cancellation.js +2 -2
- package/dist/core/workflow/workspaces/cleanup.js +2 -2
- package/dist/core/workflow/workspaces/execution.js +6 -6
- package/dist/core/workflow/workspaces/inspect.js +9 -9
- package/dist/core/workflow/workspaces/integration.js +14 -14
- package/dist/core/workflow/workspaces/lifecycle.d.ts +1 -1
- package/dist/core/workflow/workspaces/lifecycle.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/lifecycle.js +9 -9
- package/dist/core/workflow/workspaces/local-git.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/local-git.js +39 -5
- package/dist/core/workflow/workspaces/recovery.js +3 -3
- package/dist/core/workflow/workspaces/state.d.ts +1 -1
- package/dist/core/workflow/workspaces/state.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/state.js +3 -3
- package/dist/core/workflow/workspaces/types.d.ts +1 -1
- package/dist/core/workflow/workspaces/types.d.ts.map +1 -1
- package/dist/lib/browser/asserts.d.ts +28 -0
- package/dist/lib/browser/asserts.d.ts.map +1 -0
- package/dist/lib/browser/asserts.js +152 -0
- package/dist/lib/browser/client.d.ts +49 -0
- package/dist/lib/browser/client.d.ts.map +1 -1
- package/dist/lib/browser/client.js +155 -14
- package/dist/lib/browser/content-checks.d.ts +108 -0
- package/dist/lib/browser/content-checks.d.ts.map +1 -0
- package/dist/lib/browser/content-checks.js +474 -0
- package/dist/lib/browser/critique.d.ts +91 -0
- package/dist/lib/browser/critique.d.ts.map +1 -0
- package/dist/lib/browser/critique.js +167 -0
- package/dist/lib/browser/geometry.d.ts +32 -0
- package/dist/lib/browser/geometry.d.ts.map +1 -1
- package/dist/lib/browser/geometry.js +244 -1
- package/dist/lib/browser/index.d.ts +4 -1
- package/dist/lib/browser/index.d.ts.map +1 -1
- package/dist/lib/browser/index.js +2 -0
- package/dist/lib/claude-desktop.d.ts.map +1 -1
- package/dist/lib/claude-desktop.js +4 -1
- package/dist/lib/council/index.d.ts +6 -6
- package/dist/lib/council/index.d.ts.map +1 -1
- package/dist/lib/council/index.js +8 -8
- package/dist/lib/identities/assume.d.ts +2 -2
- package/dist/lib/identities/assume.js +7 -7
- package/dist/lib/instructions/apply.d.ts +3 -3
- package/dist/lib/instructions/apply.d.ts.map +1 -1
- package/dist/lib/instructions/apply.js +75 -27
- package/dist/lib/instructions/host-addendum.d.ts +54 -0
- package/dist/lib/instructions/host-addendum.d.ts.map +1 -0
- package/dist/lib/instructions/host-addendum.js +107 -0
- package/dist/lib/instructions/templates.d.ts +10 -3
- package/dist/lib/instructions/templates.d.ts.map +1 -1
- package/dist/lib/instructions/templates.js +41 -12
- package/dist/lib/machine.d.ts +2 -2
- package/dist/lib/machine.js +2 -2
- package/package.json +26 -21
- package/schemas/config.schema.json +26 -1
- package/src/commander.ts +22 -13
- package/src/commands/{harness.ts → adapter.ts} +46 -46
- package/src/commands/agents.ts +71 -64
- package/src/commands/artifacts.ts +168 -0
- package/src/commands/backup.ts +47 -33
- package/src/commands/browse.ts +438 -2
- package/src/commands/checkpoint.ts +196 -0
- package/src/commands/context.ts +3 -176
- package/src/commands/decision.ts +41 -7
- package/src/commands/deinit.ts +16 -16
- package/src/commands/doctor.ts +28 -28
- package/src/commands/{supervisor.ts → governor.ts} +184 -154
- package/src/commands/init.ts +50 -34
- package/src/commands/{scratch.ts → journal.ts} +60 -60
- package/src/commands/policy.ts +1 -1
- package/src/commands/presence.ts +2 -2
- package/src/commands/sync.ts +3 -3
- package/src/commands/tunnel.ts +237 -34
- package/src/commands/web-fetch.ts +1 -1
- package/src/commands/web.ts +56 -1
- package/src/commands/work.ts +50 -35
- package/src/commands/workflow.ts +43 -34
- package/src/core/{harnesses → adapters}/attest-projection.ts +2 -2
- package/src/core/{harnesses → adapters}/attest.ts +27 -27
- package/src/core/{harnesses → adapters}/attestation.ts +41 -41
- package/src/core/{harnesses → adapters}/bench.ts +34 -43
- package/src/core/adapters/index.ts +56 -0
- package/src/core/{harnesses → adapters}/profiles.ts +16 -16
- package/src/core/{harnesses → adapters}/registry.ts +23 -23
- package/src/core/{harnesses → adapters}/types.ts +23 -23
- package/src/core/agents/canonical-emit.ts +6 -6
- package/src/core/agents/cli-emit.ts +1 -1
- package/src/core/agents/cli.ts +30 -28
- package/src/core/agents/codex-replay.ts +6 -6
- package/src/core/agents/coord-client.ts +119 -28
- package/src/core/agents/events/consume.ts +1 -1
- package/src/core/agents/events/emit.ts +7 -6
- package/src/core/agents/render/prompt-context.ts +107 -31
- package/src/core/agents/render/session-context.ts +6 -6
- package/src/core/agents/rules/claim-conflict.ts +4 -7
- package/src/core/agents/rules/commit-conflict.ts +103 -22
- package/src/core/agents/rules/stop-hook.ts +33 -17
- package/src/core/agents/rules/verdict.ts +13 -0
- package/src/core/agents/session-events.ts +4 -4
- package/src/core/agents/state/council.ts +1 -1
- package/src/core/agents/state/heartbeat-projector.ts +16 -12
- package/src/core/agents/state/heartbeat-writer.ts +12 -12
- package/src/core/agents/state/{scratch.ts → journal.ts} +12 -12
- package/src/core/agents/state/pidmap.ts +130 -15
- package/src/core/agents/state/proc-start.ts +208 -0
- package/src/core/agents/state/shell-mutation.ts +1 -1
- package/src/core/agents/state/stale-sweep.ts +7 -7
- package/src/core/artifacts/index.ts +557 -0
- package/src/core/config.ts +30 -2
- package/src/core/context/index.ts +15 -15
- package/src/core/governor/adapter-spread.ts +82 -0
- package/src/core/governor/index.ts +91 -0
- package/src/core/governor/plan-api.ts +115 -0
- package/src/core/{supervisor → governor}/plan-read.ts +112 -97
- package/src/core/{supervisor → governor}/plan-types.ts +59 -56
- package/src/core/{supervisor → governor}/planning.ts +223 -192
- package/src/core/governor/read.ts +59 -0
- package/src/core/{supervisor → governor}/runner.ts +39 -39
- package/src/core/{supervisor → governor}/service-read.ts +22 -22
- package/src/core/{supervisor → governor}/service.ts +117 -119
- package/src/core/{supervisor → governor}/state.ts +325 -167
- package/src/core/hooks/adapter/detect.ts +30 -0
- package/src/core/hooks/{harness → adapter}/events.ts +16 -14
- package/src/core/hooks/{harness → adapter}/output.ts +31 -23
- package/src/core/hooks/{harness → adapter}/parse.ts +5 -5
- package/src/core/hooks/{harness → adapter}/wiring.ts +21 -21
- package/src/core/hooks/cli.ts +185 -162
- package/src/core/hooks/effects/image-capture.ts +6 -6
- package/src/core/hooks/effects/index.ts +17 -17
- package/src/core/hooks/events/emit.ts +3 -3
- package/src/core/hooks/events/rotate.ts +1 -1
- package/src/core/hooks/events/schema.ts +15 -7
- package/src/core/hooks/guard-path.ts +2 -2
- package/src/core/hooks/index.ts +1 -1
- package/src/core/hooks/resolve/anchor.ts +63 -8
- package/src/core/hooks/resolve/coord-root.ts +4 -4
- package/src/core/hooks/resolve/intent.ts +1 -1
- package/src/core/hooks/resolve/owner.ts +11 -5
- package/src/core/{scratch → journal}/index.ts +53 -53
- package/src/core/policy/evaluate.ts +8 -8
- package/src/core/policy/types.ts +3 -3
- package/src/core/work/state.ts +65 -23
- package/src/core/workflow/adapters.ts +33 -0
- package/src/core/workflow/approvals.ts +7 -7
- package/src/core/workflow/billing.ts +12 -12
- package/src/core/workflow/child-env.ts +13 -4
- package/src/core/workflow/engine.ts +155 -90
- package/src/core/workflow/evidence-preflight.ts +165 -0
- package/src/core/workflow/index.ts +3 -3
- package/src/core/workflow/proof.ts +60 -50
- package/src/core/workflow/run-state.ts +7 -7
- package/src/core/workflow/sandbox-projection.ts +16 -16
- package/src/core/workflow/spawn-claude.ts +13 -10
- package/src/core/workflow/spawn-codex.ts +13 -10
- package/src/core/workflow/spawn-cursor.ts +13 -10
- package/src/core/workflow/spawn-failure.ts +1 -1
- package/src/core/workflow/specialists.ts +2 -2
- package/src/core/workflow/{journal.ts → transcript.ts} +16 -16
- package/src/core/workflow/types.ts +108 -51
- package/src/core/workflow/validate.ts +1 -1
- package/src/core/workflow/workspaces/cancellation.ts +2 -2
- package/src/core/workflow/workspaces/cleanup.ts +2 -2
- package/src/core/workflow/workspaces/execution.ts +6 -6
- package/src/core/workflow/workspaces/inspect.ts +14 -11
- package/src/core/workflow/workspaces/integration.ts +18 -14
- package/src/core/workflow/workspaces/lifecycle.ts +10 -10
- package/src/core/workflow/workspaces/local-git.ts +47 -5
- package/src/core/workflow/workspaces/recovery.ts +3 -3
- package/src/core/workflow/workspaces/state.ts +4 -3
- package/src/core/workflow/workspaces/types.ts +1 -1
- package/src/lib/browser/asserts.ts +177 -0
- package/src/lib/browser/client.ts +189 -14
- package/src/lib/browser/content-checks.ts +571 -0
- package/src/lib/browser/critique.ts +231 -0
- package/src/lib/browser/geometry.ts +297 -1
- package/src/lib/browser/index.ts +34 -0
- package/src/lib/claude-desktop.ts +4 -1
- package/src/lib/council/index.ts +9 -9
- package/src/lib/identities/assume.ts +7 -7
- package/src/lib/instructions/apply.ts +87 -25
- package/src/lib/instructions/host-addendum.ts +126 -0
- package/src/lib/instructions/templates.ts +44 -15
- package/src/lib/machine.ts +2 -2
- package/dist/commands/harness.d.ts +0 -12
- package/dist/commands/harness.d.ts.map +0 -1
- package/dist/commands/scratch.d.ts +0 -4
- package/dist/commands/scratch.d.ts.map +0 -1
- package/dist/commands/session.d.ts.map +0 -1
- package/dist/commands/session.js +0 -162
- package/dist/commands/supervisor.d.ts +0 -4
- package/dist/commands/supervisor.d.ts.map +0 -1
- package/dist/core/harnesses/attest-projection.d.ts.map +0 -1
- package/dist/core/harnesses/attest.d.ts.map +0 -1
- package/dist/core/harnesses/attestation.d.ts.map +0 -1
- package/dist/core/harnesses/bench.d.ts.map +0 -1
- package/dist/core/harnesses/index.d.ts +0 -13
- package/dist/core/harnesses/index.d.ts.map +0 -1
- package/dist/core/harnesses/index.js +0 -6
- package/dist/core/harnesses/profiles.d.ts.map +0 -1
- package/dist/core/harnesses/registry.d.ts +0 -15
- package/dist/core/harnesses/registry.d.ts.map +0 -1
- package/dist/core/harnesses/types.d.ts.map +0 -1
- package/dist/core/hooks/harness/detect.d.ts +0 -9
- package/dist/core/hooks/harness/events.d.ts.map +0 -1
- package/dist/core/hooks/harness/output.d.ts.map +0 -1
- package/dist/core/supervisor/index.d.ts +0 -7
- package/dist/core/supervisor/index.d.ts.map +0 -1
- package/dist/core/supervisor/index.js +0 -6
- package/dist/core/supervisor/plan-api.d.ts +0 -23
- package/dist/core/supervisor/plan-api.d.ts.map +0 -1
- package/dist/core/supervisor/plan-api.js +0 -50
- package/dist/core/supervisor/plan-read.d.ts +0 -5
- package/dist/core/supervisor/plan-read.d.ts.map +0 -1
- package/dist/core/supervisor/plan-types.d.ts.map +0 -1
- package/dist/core/supervisor/planning.d.ts +0 -33
- package/dist/core/supervisor/planning.d.ts.map +0 -1
- package/dist/core/supervisor/read.d.ts +0 -6
- package/dist/core/supervisor/read.d.ts.map +0 -1
- package/dist/core/supervisor/read.js +0 -4
- package/dist/core/supervisor/runner.d.ts +0 -37
- package/dist/core/supervisor/runner.d.ts.map +0 -1
- package/dist/core/supervisor/service-read.d.ts +0 -6
- package/dist/core/supervisor/service-read.d.ts.map +0 -1
- package/dist/core/supervisor/service.d.ts +0 -114
- package/dist/core/supervisor/service.d.ts.map +0 -1
- package/dist/core/supervisor/state.d.ts +0 -95
- package/dist/core/supervisor/state.d.ts.map +0 -1
- package/dist/core/workflow/harnesses.d.ts +0 -17
- package/dist/core/workflow/harnesses.d.ts.map +0 -1
- package/dist/core/workflow/harnesses.js +0 -21
- package/dist/core/workflow/journal.d.ts.map +0 -1
- package/src/commands/session.ts +0 -187
- package/src/core/harnesses/index.ts +0 -56
- package/src/core/hooks/harness/detect.ts +0 -30
- package/src/core/supervisor/index.ts +0 -89
- package/src/core/supervisor/plan-api.ts +0 -73
- package/src/core/supervisor/read.ts +0 -59
- package/src/core/workflow/harnesses.ts +0 -33
- /package/dist/core/{harnesses → adapters}/attest-projection.js +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Workflow engine: loads a workflow script (plain JS, `export default
|
|
3
|
-
* async (ctx) => …`), injects the ctx API, enforces the caps,
|
|
4
|
-
* step to `.harnery/workflows/<run-id>/
|
|
3
|
+
* async (ctx) => …`), injects the ctx API, enforces the caps, transcripts every
|
|
4
|
+
* step to `.harnery/workflows/<run-id>/transcript.jsonl`, and returns a RunReport.
|
|
5
5
|
*
|
|
6
6
|
* Guarantees the engine makes (the pitch, in code):
|
|
7
7
|
* - **Bounded**: hard total-agent ceiling + bounded parallel() concurrency.
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* validate; failures re-prompt with the validation errors appended, up to
|
|
14
14
|
* `maxAttempts`, then throw. Routing decisions read validated fields, so
|
|
15
15
|
* the deterministic script — not a model — decides what runs next.
|
|
16
|
-
* - **
|
|
16
|
+
* - **Transcripted**: every stage/agent start+end lands in the run transcript with
|
|
17
17
|
* cost, duration, and child session id (the resume + web-UI substrate).
|
|
18
18
|
*/
|
|
19
19
|
var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
|
|
@@ -34,11 +34,12 @@ import { assertWorkflowRunId, createWorkflowApproval } from "./approvals.js";
|
|
|
34
34
|
import { freezeWorkflowAttemptContext } from "./attempt-context.js";
|
|
35
35
|
import { probeBilling } from "./billing.js";
|
|
36
36
|
import { stableDigest } from "./durable-record.js";
|
|
37
|
-
import {
|
|
37
|
+
import { evidencePreflightError } from "./evidence-preflight.js";
|
|
38
38
|
import { buildWorkflowProof, createEvidenceRecord, digestResult, normalizeWorkflowMeta, writeWorkflowProof, } from "./proof.js";
|
|
39
39
|
import { acquireWorkflowResumeLease, assertWorkflowRunResumable, assertWorkflowScriptUnchanged, workflowScriptDigest, writeWorkflowRunManifest, } from "./run-state.js";
|
|
40
40
|
import { assertProjectionWithinWorkspace, resolveGitGrantRoots } from "./sandbox-projection.js";
|
|
41
41
|
import { normalizeWorkflowSpecialists, resolveSpecialistAssignment } from "./specialists.js";
|
|
42
|
+
import { appendWorkflowTranscriptEvent } from "./transcript.js";
|
|
42
43
|
import { parseStageOutput, validateAgainstSchema } from "./validate.js";
|
|
43
44
|
import { freezeWorkflowWorkContext } from "./work-context.js";
|
|
44
45
|
import { attestTerminal, attestWorkspaceFailure, resolveWorkspaceBinding, } from "./workspaces/execution.js";
|
|
@@ -75,13 +76,30 @@ export class WorkflowRunError extends Error {
|
|
|
75
76
|
export class WorkflowParkedError extends Error {
|
|
76
77
|
runId;
|
|
77
78
|
approvalId;
|
|
78
|
-
|
|
79
|
-
constructor(message, runId, approvalId,
|
|
79
|
+
transcriptPath;
|
|
80
|
+
constructor(message, runId, approvalId, transcriptPath) {
|
|
80
81
|
super(message);
|
|
81
82
|
this.name = "WorkflowParkedError";
|
|
82
83
|
this.runId = runId;
|
|
83
84
|
this.approvalId = approvalId;
|
|
84
|
-
this.
|
|
85
|
+
this.transcriptPath = transcriptPath;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/** Thrown by ctx.blocked(). Carries the run out of the script and into the
|
|
89
|
+
* failure path, where its presence — not its message — is what stamps the proof
|
|
90
|
+
* with class "decision". A script cannot fake this by throwing an ordinary
|
|
91
|
+
* Error with a suggestive message, which is the point: the class has to mean
|
|
92
|
+
* "the script deliberately declared this", not "the text looked like it". */
|
|
93
|
+
export class WorkflowBlockedError extends Error {
|
|
94
|
+
reason;
|
|
95
|
+
decisionId;
|
|
96
|
+
constructor(reason, decisionId) {
|
|
97
|
+
super(decisionId
|
|
98
|
+
? `blocked on decision ${decisionId}: ${reason}`
|
|
99
|
+
: `blocked pending a human decision: ${reason}`);
|
|
100
|
+
this.name = "WorkflowBlockedError";
|
|
101
|
+
this.reason = reason;
|
|
102
|
+
this.decisionId = decisionId;
|
|
85
103
|
}
|
|
86
104
|
}
|
|
87
105
|
export async function runWorkflow(scriptPath, opts) {
|
|
@@ -151,9 +169,28 @@ export async function runWorkflow(scriptPath, opts) {
|
|
|
151
169
|
releaseResumeLease?.();
|
|
152
170
|
}
|
|
153
171
|
}
|
|
172
|
+
/** Throws when the script names an evidence kind the proof layer will refuse.
|
|
173
|
+
* Silent when the file cannot be read: the import a moment later will produce a
|
|
174
|
+
* better error than a guess from here would. */
|
|
175
|
+
function assertEvidenceKindsAreUsable(scriptPath, absScript) {
|
|
176
|
+
let source;
|
|
177
|
+
try {
|
|
178
|
+
source = readFileSync(absScript, "utf8");
|
|
179
|
+
}
|
|
180
|
+
catch {
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
const message = evidencePreflightError(source, scriptPath);
|
|
184
|
+
if (message)
|
|
185
|
+
throw new Error(message);
|
|
186
|
+
}
|
|
154
187
|
async function executeWorkflow(scriptPath, absScript, opts, resumeState, workContext, attemptContext) {
|
|
155
188
|
const frozen = resumeState?.manifest.execution;
|
|
156
189
|
const isolation = frozen?.isolation ?? opts.isolation ?? "shared";
|
|
190
|
+
// Before anything is spawned, and before either import path below: an evidence
|
|
191
|
+
// kind the proof will reject is fatal at the END of a workflow, which is the
|
|
192
|
+
// most expensive place to learn it. Reading the file is the cheapest moment.
|
|
193
|
+
assertEvidenceKindsAreUsable(scriptPath, absScript);
|
|
157
194
|
let sharedWorkflow;
|
|
158
195
|
let sharedMeta;
|
|
159
196
|
if (isolation === "shared") {
|
|
@@ -170,7 +207,7 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
170
207
|
`wf-${new Date().toISOString().replace(/[:.]/g, "-")}-${randomBytes(3).toString("hex")}`;
|
|
171
208
|
const runDir = join(opts.coordRoot, ".harnery", "workflows", runId);
|
|
172
209
|
mkdirSync(runDir, { recursive: true });
|
|
173
|
-
const
|
|
210
|
+
const transcriptPath = join(runDir, "transcript.jsonl");
|
|
174
211
|
const proofPath = join(runDir, "proof.json");
|
|
175
212
|
const maxAgents = frozen?.max_agents ?? opts.maxAgents ?? DEFAULT_MAX_AGENTS;
|
|
176
213
|
const concurrency = frozen?.concurrency ?? opts.concurrency ?? DEFAULT_CONCURRENCY;
|
|
@@ -178,7 +215,7 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
178
215
|
assertPositiveWorkflowBound(concurrency, "concurrency");
|
|
179
216
|
const cwd = frozen?.cwd ?? opts.cwd ?? opts.coordRoot;
|
|
180
217
|
const log = opts.onLog ?? ((line) => process.stderr.write(`${line}\n`));
|
|
181
|
-
const
|
|
218
|
+
const defaultAdapter = frozen?.default_adapter ?? opts.defaultAdapter ?? "claude-code";
|
|
182
219
|
const specialists = frozen?.specialists ?? (resumeState ? {} : normalizeWorkflowSpecialists(opts.specialists));
|
|
183
220
|
const networkAccess = frozen?.network_access ?? opts.networkAccess ?? "unknown";
|
|
184
221
|
const policy = frozen?.policy ?? (opts.policy ? normalizePolicy(opts.policy, { baseDir: cwd }) : undefined);
|
|
@@ -220,19 +257,19 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
220
257
|
const endedAt = new Date().toISOString();
|
|
221
258
|
const durationMs = Date.now() - t0;
|
|
222
259
|
const failedAttestation = await attestWorkspaceFailure(workspaceProvider, frozenBinding, error);
|
|
223
|
-
|
|
260
|
+
appendWorkflowTranscriptEvent(opts.coordRoot, runId, "run.resume", {
|
|
224
261
|
approval_id: resumeState.approvalId,
|
|
225
262
|
script: absScript,
|
|
226
263
|
resumed_at: new Date().toISOString(),
|
|
227
264
|
});
|
|
228
|
-
|
|
265
|
+
appendWorkflowTranscriptEvent(opts.coordRoot, runId, "workspace.reattach.failed", {
|
|
229
266
|
binding_id: frozenBinding.binding_id,
|
|
230
267
|
provider_id: frozenBinding.provider.id,
|
|
231
268
|
status: failedAttestation.status,
|
|
232
269
|
reason: failure.message,
|
|
233
270
|
attestation_sha256: stableDigest(failedAttestation),
|
|
234
271
|
});
|
|
235
|
-
|
|
272
|
+
appendWorkflowTranscriptEvent(opts.coordRoot, runId, "run.end", {
|
|
236
273
|
ok: false,
|
|
237
274
|
error: failure.message,
|
|
238
275
|
agents: 0,
|
|
@@ -251,13 +288,13 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
251
288
|
startedAt,
|
|
252
289
|
endedAt,
|
|
253
290
|
durationMs,
|
|
254
|
-
|
|
291
|
+
transcriptPath,
|
|
255
292
|
before: resumeState.manifest.repository_before,
|
|
256
293
|
after: resumeState.manifest.repository_before,
|
|
257
294
|
agents: [],
|
|
258
295
|
evidence: [],
|
|
259
|
-
|
|
260
|
-
|
|
296
|
+
adapterEvidence: opts.adapterEvidence,
|
|
297
|
+
adapterAttestations: opts.adapterAttestations,
|
|
261
298
|
sandboxProjection: sandboxProjectionEvidence(opts.filesystemPolicy, opts.gitWrite ?? "none"),
|
|
262
299
|
policy: policy
|
|
263
300
|
? {
|
|
@@ -320,7 +357,7 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
320
357
|
repository_before: executionRepoBefore,
|
|
321
358
|
execution: {
|
|
322
359
|
cwd: executionCwd,
|
|
323
|
-
|
|
360
|
+
default_adapter: defaultAdapter,
|
|
324
361
|
max_agents: maxAgents,
|
|
325
362
|
concurrency,
|
|
326
363
|
subscription_only: subscriptionOnly,
|
|
@@ -363,7 +400,7 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
363
400
|
: undefined;
|
|
364
401
|
throw new Error("workspace authority changed during workflow module initialization");
|
|
365
402
|
}
|
|
366
|
-
|
|
403
|
+
appendWorkflowTranscriptEvent(opts.coordRoot, runId, "workspace.reattach.module_initialized", {
|
|
367
404
|
binding_id: workspaceBinding.binding_id,
|
|
368
405
|
provider_id: workspaceBinding.provider.id,
|
|
369
406
|
attestation_sha256: stableDigest(postImport),
|
|
@@ -377,7 +414,7 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
377
414
|
cause: reattachmentError,
|
|
378
415
|
})
|
|
379
416
|
: reattachmentError;
|
|
380
|
-
|
|
417
|
+
appendWorkflowTranscriptEvent(opts.coordRoot, runId, "workspace.reattach.module_initialization_failed", {
|
|
381
418
|
binding_id: workspaceBinding.binding_id,
|
|
382
419
|
provider_id: workspaceBinding.provider.id,
|
|
383
420
|
status: initializationAttestation.status,
|
|
@@ -396,12 +433,12 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
396
433
|
log(`[context] each child cache-writes ~${Math.round(contextTokensPerChildEstimate / 1000)}K tokens of repo ` +
|
|
397
434
|
`instructions from ${executionCwd}; a fan-out multiplies this per agent`);
|
|
398
435
|
}
|
|
399
|
-
// Resume:
|
|
436
|
+
// Resume: transcripted results of a prior run, keyed by agent-call identity.
|
|
400
437
|
const resumeSource = opts.resumeRunId ?? opts.resumeFrom;
|
|
401
438
|
const resumeCache = resumeSource
|
|
402
439
|
? loadResumeCache(opts.coordRoot, resumeSource)
|
|
403
440
|
: new Map();
|
|
404
|
-
const history = opts.resumeRunId ? loadRunHistory(
|
|
441
|
+
const history = opts.resumeRunId ? loadRunHistory(transcriptPath) : undefined;
|
|
405
442
|
let agentsSpawned = history?.agentsSpawned ?? 0;
|
|
406
443
|
let agentsCached = 0;
|
|
407
444
|
let costUsd = history?.costUsd ?? 0;
|
|
@@ -415,14 +452,14 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
415
452
|
const evidenceRecords = [];
|
|
416
453
|
const policyDecisions = new Map(history?.policyDecisions.map((decision) => [decision.id, decision]));
|
|
417
454
|
const acceptanceIds = new Set(meta.acceptance.map((criterion) => criterion.id));
|
|
418
|
-
const
|
|
419
|
-
|
|
455
|
+
const transcript = (event, data) => {
|
|
456
|
+
appendWorkflowTranscriptEvent(opts.coordRoot, runId, event, { stage: currentStage, ...data });
|
|
420
457
|
};
|
|
421
|
-
const
|
|
458
|
+
const transcriptAgentEnd = (data, resultKind, result) => {
|
|
422
459
|
// The writer shrinks an oversized record itself and names what it dropped,
|
|
423
460
|
// so no per-call fallback is needed here. A digest rides along regardless so
|
|
424
461
|
// a shrunk record can still be tied back to the exact result.
|
|
425
|
-
|
|
462
|
+
transcript("agent.end", {
|
|
426
463
|
...data,
|
|
427
464
|
result_kind: resultKind,
|
|
428
465
|
result_digest: digestResult(result, resultKind),
|
|
@@ -475,7 +512,7 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
475
512
|
const evaluation = evaluatePolicy(policy, request);
|
|
476
513
|
const id = `p${++policySeq}`;
|
|
477
514
|
const checkedAt = new Date().toISOString();
|
|
478
|
-
|
|
515
|
+
transcript("policy.check", {
|
|
479
516
|
id,
|
|
480
517
|
policy: policy.name,
|
|
481
518
|
policy_sha256: policyDigest(policy),
|
|
@@ -521,25 +558,25 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
521
558
|
});
|
|
522
559
|
if (stored.approval.status === "pending") {
|
|
523
560
|
if (stored.created) {
|
|
524
|
-
|
|
561
|
+
transcript("approval.requested", {
|
|
525
562
|
approval_id: stored.approval.request.id,
|
|
526
563
|
decision_id: id,
|
|
527
564
|
addressed_to: stored.approval.request.addressed_to,
|
|
528
565
|
request_sha256: stored.approval.request.request_sha256,
|
|
529
566
|
});
|
|
530
567
|
}
|
|
531
|
-
|
|
568
|
+
transcript("run.parked", {
|
|
532
569
|
approval_id: stored.approval.request.id,
|
|
533
570
|
decision_id: id,
|
|
534
571
|
phase: request.phase,
|
|
535
572
|
action: request.action,
|
|
536
573
|
});
|
|
537
|
-
throw new WorkflowParkedError(`workflow parked for approval ${stored.approval.request.id}: ${evaluation.reason}`, runId, stored.approval.request.id,
|
|
574
|
+
throw new WorkflowParkedError(`workflow parked for approval ${stored.approval.request.id}: ${evaluation.reason}`, runId, stored.approval.request.id, transcriptPath);
|
|
538
575
|
}
|
|
539
576
|
verdict = stored.approval.decision.verdict;
|
|
540
577
|
resolvedBy = "approval";
|
|
541
578
|
reason = boundedPolicyReason(stored.approval.decision.reason ?? evaluation.reason);
|
|
542
|
-
|
|
579
|
+
transcript("approval.consumed", {
|
|
543
580
|
approval_id: stored.approval.request.id,
|
|
544
581
|
decision_id: id,
|
|
545
582
|
verdict,
|
|
@@ -561,7 +598,7 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
561
598
|
request,
|
|
562
599
|
};
|
|
563
600
|
policyDecisions.set(decision.id, decision);
|
|
564
|
-
|
|
601
|
+
transcript("policy.resolve", { ...decision });
|
|
565
602
|
if (decision.verdict === "deny") {
|
|
566
603
|
throw new PolicyDeniedError(`policy ${JSON.stringify(policy.name)} denied ${request.phase} ${JSON.stringify(request.action)}: ${decision.reason}`, decision.id);
|
|
567
604
|
}
|
|
@@ -576,10 +613,10 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
576
613
|
: assignmentPrompt;
|
|
577
614
|
let reservedForDispatch = 0;
|
|
578
615
|
let spawnCountClaimed = false;
|
|
579
|
-
const
|
|
580
|
-
const spawner = opts.spawners[
|
|
616
|
+
const adapter = agentOpts.adapter ?? defaultAdapter;
|
|
617
|
+
const spawner = opts.spawners[adapter];
|
|
581
618
|
if (!spawner) {
|
|
582
|
-
throw new Error(`no spawner registered for
|
|
619
|
+
throw new Error(`no spawner registered for adapter "${adapter}" (registered: ${Object.keys(opts.spawners).join(", ") || "none"})`);
|
|
583
620
|
}
|
|
584
621
|
const id = `a${++agentSeq}`;
|
|
585
622
|
const label = agentOpts.label ?? `${prompt.slice(0, 60).replace(/\s+/g, " ")}…`;
|
|
@@ -590,16 +627,16 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
590
627
|
label: proofLabel,
|
|
591
628
|
stage: currentStage || undefined,
|
|
592
629
|
specialist: agentOpts.specialist,
|
|
593
|
-
|
|
630
|
+
adapter,
|
|
594
631
|
model: agentOpts.model,
|
|
595
632
|
status: "failed",
|
|
596
633
|
attempts: 0,
|
|
597
634
|
duration_ms: 0,
|
|
598
635
|
};
|
|
599
636
|
agentProofs.set(id, agentProof);
|
|
600
|
-
// Call identity for resume: same stage +
|
|
637
|
+
// Call identity for resume: same stage + adapter + model + effort + turns + schema
|
|
601
638
|
// + ORIGINAL prompt → same key. Retry-mutated prompts never enter the key.
|
|
602
|
-
const key = agentCallKey(currentStage,
|
|
639
|
+
const key = agentCallKey(currentStage, adapter, agentOpts, assignmentPrompt);
|
|
603
640
|
const cached = resumeCache.get(key);
|
|
604
641
|
if (cached) {
|
|
605
642
|
// Exact-run replay skips dispatch authorization because no dispatch
|
|
@@ -610,11 +647,11 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
610
647
|
agentsCached++;
|
|
611
648
|
agentProof.status = "cached";
|
|
612
649
|
agentProof.result = digestResult(cached.value, cached.kind);
|
|
613
|
-
|
|
650
|
+
transcript("agent.cached", {
|
|
614
651
|
id,
|
|
615
652
|
label,
|
|
616
653
|
key,
|
|
617
|
-
|
|
654
|
+
adapter,
|
|
618
655
|
specialist: agentOpts.specialist ?? null,
|
|
619
656
|
model: agentOpts.model ?? null,
|
|
620
657
|
kind: cached.kind,
|
|
@@ -627,7 +664,7 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
627
664
|
phase: "dispatch",
|
|
628
665
|
action: "spawn agent",
|
|
629
666
|
path: executionCwd,
|
|
630
|
-
|
|
667
|
+
adapter,
|
|
631
668
|
model: agentOpts.model,
|
|
632
669
|
effort: agentOpts.effort,
|
|
633
670
|
max_attempts: maxAttempts,
|
|
@@ -649,8 +686,8 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
649
686
|
projectedCost = candidate;
|
|
650
687
|
}
|
|
651
688
|
catch (error) {
|
|
652
|
-
|
|
653
|
-
|
|
689
|
+
transcript("policy.cost_estimate_failed", {
|
|
690
|
+
adapter,
|
|
654
691
|
model: agentOpts.model ?? null,
|
|
655
692
|
error: boundedPolicyReason(error.message),
|
|
656
693
|
});
|
|
@@ -688,17 +725,17 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
688
725
|
throw error;
|
|
689
726
|
}
|
|
690
727
|
}
|
|
691
|
-
// Billing safeguard: on a
|
|
728
|
+
// Billing safeguard: on a adapter's FIRST spawn this run, classify which
|
|
692
729
|
// auth its children will use and refuse the silent-override state (an
|
|
693
730
|
// exported API key shadowing a stored subscription login) unless the
|
|
694
731
|
// caller explicitly opted into API billing. Cached agents never reach
|
|
695
732
|
// this — no spawn, no billing.
|
|
696
733
|
try {
|
|
697
|
-
if (!billingProbed.has(
|
|
698
|
-
const probe = (opts.probeBilling ?? probeBilling)(
|
|
699
|
-
billingProbed.set(
|
|
700
|
-
|
|
701
|
-
|
|
734
|
+
if (!billingProbed.has(adapter)) {
|
|
735
|
+
const probe = (opts.probeBilling ?? probeBilling)(adapter);
|
|
736
|
+
billingProbed.set(adapter, probe);
|
|
737
|
+
transcript("billing.probe", {
|
|
738
|
+
adapter,
|
|
702
739
|
mode: subscriptionOnly ? "subscription" : probe.mode,
|
|
703
740
|
api_key_source: probe.apiKeySource,
|
|
704
741
|
login: probe.login,
|
|
@@ -706,26 +743,26 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
706
743
|
});
|
|
707
744
|
if (subscriptionOnly) {
|
|
708
745
|
if (probe.login === "absent") {
|
|
709
|
-
throw new Error(`subscription-only: no stored login detected for ${
|
|
710
|
-
`log the
|
|
746
|
+
throw new Error(`subscription-only: no stored login detected for ${adapter}; ` +
|
|
747
|
+
`log the adapter CLI in (or drop --subscription-only for a key-only host)`);
|
|
711
748
|
}
|
|
712
|
-
log(`[billing] ${
|
|
749
|
+
log(`[billing] ${adapter}: subscription-only (API-key vars scrubbed from child env)`);
|
|
713
750
|
}
|
|
714
751
|
else if (probe.mode === "api-key-override" && !allowApiBilling) {
|
|
715
|
-
throw new Error(`${probe.apiKeySource} is set AND a stored ${
|
|
752
|
+
throw new Error(`${probe.apiKeySource} is set AND a stored ${adapter} login exists — the key silently ` +
|
|
716
753
|
`overrides your subscription auth, so children would bill per-token API rates. ` +
|
|
717
754
|
`Either unset ${probe.apiKeySource}, run with --subscription-only to scrub it from ` +
|
|
718
755
|
`child envs, or pass --allow-api-billing if API billing is intended`);
|
|
719
756
|
}
|
|
720
757
|
else if (probe.mode === "api-key") {
|
|
721
|
-
log(`[billing] ${
|
|
758
|
+
log(`[billing] ${adapter}: API-key billing (${probe.apiKeySource}; no stored login detected) — ` +
|
|
722
759
|
`children bill per-token rates`);
|
|
723
760
|
}
|
|
724
761
|
else if (probe.mode === "api-key-override") {
|
|
725
|
-
log(`[billing] ${
|
|
762
|
+
log(`[billing] ${adapter}: API-key billing (--allow-api-billing; key overrides stored login)`);
|
|
726
763
|
}
|
|
727
764
|
else {
|
|
728
|
-
log(`[billing] ${
|
|
765
|
+
log(`[billing] ${adapter}: subscription login`);
|
|
729
766
|
}
|
|
730
767
|
}
|
|
731
768
|
}
|
|
@@ -743,16 +780,16 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
743
780
|
agentsSpawned++;
|
|
744
781
|
await acquire();
|
|
745
782
|
try {
|
|
746
|
-
|
|
783
|
+
transcript("agent.start", {
|
|
747
784
|
id,
|
|
748
785
|
label,
|
|
749
786
|
key,
|
|
750
|
-
|
|
787
|
+
adapter,
|
|
751
788
|
specialist: agentOpts.specialist ?? null,
|
|
752
789
|
model: agentOpts.model ?? null,
|
|
753
790
|
effort: agentOpts.effort ?? null,
|
|
754
791
|
});
|
|
755
|
-
log(`[${name}] ${currentStage || "(no stage)"} → ${id} [${
|
|
792
|
+
log(`[${name}] ${currentStage || "(no stage)"} → ${id} [${adapter}] ${label}`);
|
|
756
793
|
let attemptPrompt = dispatchPrompt;
|
|
757
794
|
let last = null;
|
|
758
795
|
let agentCostUsd = 0;
|
|
@@ -765,6 +802,7 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
765
802
|
maxTurns: agentOpts.maxTurns ?? DEFAULT_MAX_TURNS,
|
|
766
803
|
cwd: executionCwd,
|
|
767
804
|
runId,
|
|
805
|
+
agentId: id,
|
|
768
806
|
subscriptionOnly,
|
|
769
807
|
filesystemPolicy,
|
|
770
808
|
});
|
|
@@ -773,7 +811,7 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
773
811
|
agentCostUsd += last.costUsd ?? 0;
|
|
774
812
|
costUsd += last.costUsd ?? 0;
|
|
775
813
|
if (!last.ok) {
|
|
776
|
-
|
|
814
|
+
transcript("agent.attempt_failed", { id, attempt, error: last.error });
|
|
777
815
|
// ADR 0046: an environment failure (the binary was absent) cannot be
|
|
778
816
|
// helped by retrying an unchanged environment, so stop the in-agent
|
|
779
817
|
// retry too — not just the outer attempt/replan budget. An upstream
|
|
@@ -788,7 +826,7 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
788
826
|
agentCostUsd > 0 || last.costUsd !== undefined ? agentCostUsd : undefined;
|
|
789
827
|
agentProof.session_id = last.sessionId;
|
|
790
828
|
agentProof.result = digestResult(last.text, "text");
|
|
791
|
-
|
|
829
|
+
transcriptAgentEnd({
|
|
792
830
|
id,
|
|
793
831
|
key,
|
|
794
832
|
attempts: attempt,
|
|
@@ -809,7 +847,7 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
809
847
|
agentCostUsd > 0 || last.costUsd !== undefined ? agentCostUsd : undefined;
|
|
810
848
|
agentProof.session_id = last.sessionId;
|
|
811
849
|
agentProof.result = digestResult(parsed.value, "json");
|
|
812
|
-
|
|
850
|
+
transcriptAgentEnd({
|
|
813
851
|
id,
|
|
814
852
|
key,
|
|
815
853
|
attempts: attempt,
|
|
@@ -820,7 +858,7 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
820
858
|
}, "json", parsed.value);
|
|
821
859
|
return parsed.value;
|
|
822
860
|
}
|
|
823
|
-
|
|
861
|
+
transcript("agent.schema_retry", { id, attempt, problems });
|
|
824
862
|
// Keep the original cache identity while making the actual output
|
|
825
863
|
// contract explicit. A full bounded copy of the rejected value lets the
|
|
826
864
|
// child repair omissions instead of reconstructing an unseen object.
|
|
@@ -846,7 +884,7 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
846
884
|
// above, so this only fires when the agent genuinely failed.
|
|
847
885
|
if (last && !last.ok && last.class)
|
|
848
886
|
agentProof.class = last.class;
|
|
849
|
-
|
|
887
|
+
transcript("agent.failed", { id, error: reason });
|
|
850
888
|
throw new Error(`agent ${proofLabel}: ${reason}`);
|
|
851
889
|
}
|
|
852
890
|
catch (error) {
|
|
@@ -863,13 +901,13 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
863
901
|
// concurrency. A rejected thunk lands as null so one bad item can't kill
|
|
864
902
|
// the batch — the script filters and routes.
|
|
865
903
|
return Promise.all(thunks.map((t) => t().catch((err) => {
|
|
866
|
-
|
|
904
|
+
transcript("parallel.item_failed", { error: err.message });
|
|
867
905
|
return null;
|
|
868
906
|
})));
|
|
869
907
|
};
|
|
870
908
|
const stage = (title) => {
|
|
871
909
|
currentStage = title;
|
|
872
|
-
|
|
910
|
+
transcript("stage.start", { title });
|
|
873
911
|
log(`[${name}] ── stage: ${title}`);
|
|
874
912
|
};
|
|
875
913
|
const evidence = (input) => {
|
|
@@ -881,7 +919,7 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
881
919
|
});
|
|
882
920
|
evidenceSeq++;
|
|
883
921
|
evidenceRecords.push(record);
|
|
884
|
-
|
|
922
|
+
transcript("evidence.recorded", { ...record });
|
|
885
923
|
return record.id;
|
|
886
924
|
};
|
|
887
925
|
const authorize = async (input) => {
|
|
@@ -899,6 +937,16 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
899
937
|
current_cost_usd: round4(costUsd),
|
|
900
938
|
});
|
|
901
939
|
};
|
|
940
|
+
const blocked = (input) => {
|
|
941
|
+
const reason = input.reason.trim();
|
|
942
|
+
if (!reason)
|
|
943
|
+
throw new Error("ctx.blocked() requires a reason");
|
|
944
|
+
transcript("run.blocked", {
|
|
945
|
+
reason,
|
|
946
|
+
...(input.decision ? { decision_id: input.decision } : {}),
|
|
947
|
+
});
|
|
948
|
+
throw new WorkflowBlockedError(reason, input.decision);
|
|
949
|
+
};
|
|
902
950
|
const ctx = {
|
|
903
951
|
work: workContext,
|
|
904
952
|
attempt: attemptContext,
|
|
@@ -908,17 +956,18 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
908
956
|
log,
|
|
909
957
|
evidence,
|
|
910
958
|
authorize,
|
|
959
|
+
blocked,
|
|
911
960
|
};
|
|
912
961
|
try {
|
|
913
962
|
if (resumeState) {
|
|
914
|
-
|
|
963
|
+
transcript("run.resume", {
|
|
915
964
|
approval_id: resumeState.approvalId,
|
|
916
965
|
script: absScript,
|
|
917
966
|
resumed_at: new Date().toISOString(),
|
|
918
967
|
});
|
|
919
968
|
}
|
|
920
969
|
else {
|
|
921
|
-
|
|
970
|
+
transcript("run.start", {
|
|
922
971
|
name,
|
|
923
972
|
work_item_id: opts.workItemId ?? null,
|
|
924
973
|
work_context: workContext ?? null,
|
|
@@ -951,7 +1000,7 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
951
1000
|
if (workspaceAttestation && workspaceAttestation.status !== "ok") {
|
|
952
1001
|
throw new Error(`terminal workspace attestation ${workspaceAttestation.status}: ${workspaceAttestation.provider_drift.join("; ") || "provider could not prove the workspace"}`);
|
|
953
1002
|
}
|
|
954
|
-
|
|
1003
|
+
transcript("run.end", {
|
|
955
1004
|
ok: true,
|
|
956
1005
|
agents: agentsSpawned,
|
|
957
1006
|
cached: agentsCached,
|
|
@@ -970,13 +1019,13 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
970
1019
|
startedAt,
|
|
971
1020
|
endedAt,
|
|
972
1021
|
durationMs,
|
|
973
|
-
|
|
1022
|
+
transcriptPath,
|
|
974
1023
|
before: executionRepoBefore,
|
|
975
1024
|
after: snapshotRepo(executionCwd),
|
|
976
1025
|
agents: Array.from(agentProofs.values()),
|
|
977
1026
|
evidence: evidenceRecords,
|
|
978
|
-
|
|
979
|
-
|
|
1027
|
+
adapterEvidence: opts.adapterEvidence,
|
|
1028
|
+
adapterAttestations: opts.adapterAttestations,
|
|
980
1029
|
sandboxProjection: sandboxProjectionEvidence(filesystemPolicy, gitWrite),
|
|
981
1030
|
policy: policy
|
|
982
1031
|
? {
|
|
@@ -1005,12 +1054,12 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
1005
1054
|
agentsCached,
|
|
1006
1055
|
costUsd: round4(costUsd),
|
|
1007
1056
|
durationMs,
|
|
1008
|
-
|
|
1057
|
+
transcriptPath,
|
|
1009
1058
|
proofPath,
|
|
1010
1059
|
acceptance: proof.acceptance.summary,
|
|
1011
1060
|
contextTokensPerChildEstimate,
|
|
1012
1061
|
billing: Array.from(billingProbed.values()).map((p) => ({
|
|
1013
|
-
|
|
1062
|
+
adapter: p.adapter,
|
|
1014
1063
|
mode: subscriptionOnly ? "subscription" : p.mode,
|
|
1015
1064
|
})),
|
|
1016
1065
|
policy: proof.policy?.summary,
|
|
@@ -1026,7 +1075,7 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
1026
1075
|
throw err;
|
|
1027
1076
|
const endedAt = new Date().toISOString();
|
|
1028
1077
|
const durationMs = Date.now() - t0;
|
|
1029
|
-
|
|
1078
|
+
transcript("run.end", {
|
|
1030
1079
|
ok: false,
|
|
1031
1080
|
error: err.message,
|
|
1032
1081
|
agents: agentsSpawned,
|
|
@@ -1049,13 +1098,13 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
1049
1098
|
startedAt,
|
|
1050
1099
|
endedAt,
|
|
1051
1100
|
durationMs,
|
|
1052
|
-
|
|
1101
|
+
transcriptPath,
|
|
1053
1102
|
before: executionRepoBefore,
|
|
1054
1103
|
after: snapshotRepo(executionCwd),
|
|
1055
1104
|
agents: Array.from(agentProofs.values()),
|
|
1056
1105
|
evidence: evidenceRecords,
|
|
1057
|
-
|
|
1058
|
-
|
|
1106
|
+
adapterEvidence: opts.adapterEvidence,
|
|
1107
|
+
adapterAttestations: opts.adapterAttestations,
|
|
1059
1108
|
sandboxProjection: sandboxProjectionEvidence(filesystemPolicy, gitWrite),
|
|
1060
1109
|
policy: policy
|
|
1061
1110
|
? {
|
|
@@ -1069,6 +1118,12 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
1069
1118
|
workspaceAttestation,
|
|
1070
1119
|
workspaceFallback,
|
|
1071
1120
|
error: err.message,
|
|
1121
|
+
// A deliberate stop-on-human, not a work failure. Overrides whatever the
|
|
1122
|
+
// agents' own classes would have derived: the script's determination is
|
|
1123
|
+
// the more specific fact about why this run ended.
|
|
1124
|
+
blocked: err instanceof WorkflowBlockedError
|
|
1125
|
+
? { reason: err.reason, decisionId: err.decisionId }
|
|
1126
|
+
: undefined,
|
|
1072
1127
|
});
|
|
1073
1128
|
writeWorkflowProof(proofPath, proof);
|
|
1074
1129
|
}
|
|
@@ -1091,10 +1146,10 @@ function boundedSchemaReply(value) {
|
|
|
1091
1146
|
}
|
|
1092
1147
|
/** Stable identity for one agent() call, for the resume cache. The ORIGINAL
|
|
1093
1148
|
* prompt (never a retry-mutated one) plus everything that changes behavior. */
|
|
1094
|
-
function agentCallKey(stage,
|
|
1149
|
+
function agentCallKey(stage, adapter, agentOpts, prompt) {
|
|
1095
1150
|
const parts = [
|
|
1096
1151
|
stage,
|
|
1097
|
-
|
|
1152
|
+
adapter,
|
|
1098
1153
|
agentOpts.model ?? null,
|
|
1099
1154
|
agentOpts.effort ?? null,
|
|
1100
1155
|
agentOpts.maxTurns ?? DEFAULT_MAX_TURNS,
|
|
@@ -1123,14 +1178,14 @@ function estimateInstructionTokens(cwd) {
|
|
|
1123
1178
|
}
|
|
1124
1179
|
return 0;
|
|
1125
1180
|
}
|
|
1126
|
-
/** Load a prior run's
|
|
1181
|
+
/** Load a prior run's transcript into a key → result map. Only `agent.end`
|
|
1127
1182
|
* entries (completed, validated) are resumable; failed or retried-out agents
|
|
1128
|
-
* re-run live. Unreadable
|
|
1183
|
+
* re-run live. Unreadable transcript → error (a typo'd run id should fail loud,
|
|
1129
1184
|
* not silently run everything fresh). */
|
|
1130
1185
|
function loadResumeCache(coordRoot, resumeFrom) {
|
|
1131
|
-
const path = join(coordRoot, ".harnery", "workflows", resumeFrom, "
|
|
1186
|
+
const path = join(coordRoot, ".harnery", "workflows", resumeFrom, "transcript.jsonl");
|
|
1132
1187
|
if (!existsSync(path)) {
|
|
1133
|
-
throw new Error(`--resume-from ${resumeFrom}: no
|
|
1188
|
+
throw new Error(`--resume-from ${resumeFrom}: no transcript at ${path}`);
|
|
1134
1189
|
}
|
|
1135
1190
|
const cache = new Map();
|
|
1136
1191
|
for (const line of readFileSync(path, "utf8").split("\n")) {
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reject an unusable evidence kind before the first agent is spawned.
|
|
3
|
+
*
|
|
4
|
+
* `evidence()` is by construction near the end of a workflow, so an invalid
|
|
5
|
+
* kind throws after every agent has finished. Measured: a fifty-minute run with
|
|
6
|
+
* three completed agents died at its final line on `kind: "design"`, reported
|
|
7
|
+
* `work_failed`, and burned an attempt. The work survived only because it had
|
|
8
|
+
* already been written to the tree; nothing in the proof could recover it.
|
|
9
|
+
*
|
|
10
|
+
* A workflow's evidence kinds are usually written literally, and a literal is
|
|
11
|
+
* checkable by reading the file. Where a kind is computed the scan says nothing
|
|
12
|
+
* and the existing runtime validation still applies — a partial check that
|
|
13
|
+
* costs one file read is worth more than a complete one nobody can implement.
|
|
14
|
+
*/
|
|
15
|
+
export interface EvidencePreflightProblem {
|
|
16
|
+
kind: string;
|
|
17
|
+
line: number;
|
|
18
|
+
}
|
|
19
|
+
/** Every literal `evidence({ kind: … })` in this source whose kind is not in the
|
|
20
|
+
* vocabulary. Computed kinds are invisible here, by design. */
|
|
21
|
+
export declare function findInvalidEvidenceKinds(source: string): EvidencePreflightProblem[];
|
|
22
|
+
/** The thrown message, or undefined when the script is clean or unreadable. */
|
|
23
|
+
export declare function evidencePreflightError(source: string, scriptPath: string): string | undefined;
|
|
24
|
+
//# sourceMappingURL=evidence-preflight.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evidence-preflight.d.ts","sourceRoot":"","sources":["../../../src/core/workflow/evidence-preflight.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;GAaG;AAEH,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED;+DAC+D;AAC/D,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,GAAG,wBAAwB,EAAE,CAsBnF;AAED,+EAA+E;AAC/E,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAW7F"}
|