harnery 0.32.0 → 0.34.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 +2 -0
- package/dist/commander.d.ts.map +1 -1
- package/dist/commander.js +7 -1
- package/dist/commands/adapter.js +2 -2
- package/dist/commands/agents.d.ts +144 -1
- package/dist/commands/agents.d.ts.map +1 -1
- package/dist/commands/agents.js +1408 -565
- package/dist/commands/artifacts.d.ts.map +1 -1
- package/dist/commands/artifacts.js +7 -6
- package/dist/commands/backup.d.ts +1 -1
- package/dist/commands/backup.d.ts.map +1 -1
- package/dist/commands/backup.js +29 -16
- package/dist/commands/browse.d.ts.map +1 -1
- package/dist/commands/browse.js +234 -12
- package/dist/commands/checkpoint.d.ts.map +1 -1
- package/dist/commands/checkpoint.js +3 -2
- package/dist/commands/claude-desktop.d.ts +2 -2
- package/dist/commands/claude-desktop.d.ts.map +1 -1
- package/dist/commands/claude-desktop.js +2 -2
- package/dist/commands/context.js +1 -6
- package/dist/commands/decision.d.ts.map +1 -1
- package/dist/commands/decision.js +22 -38
- package/dist/commands/docs.d.ts.map +1 -1
- package/dist/commands/docs.js +91 -28
- package/dist/commands/doctor.d.ts +4 -2
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +55 -7
- package/dist/commands/events.d.ts +5 -0
- package/dist/commands/events.d.ts.map +1 -0
- package/dist/commands/events.js +189 -0
- package/dist/commands/governor.d.ts.map +1 -1
- package/dist/commands/governor.js +13 -4
- package/dist/commands/init.d.ts +10 -2
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +233 -51
- package/dist/commands/instructions.d.ts +4 -0
- package/dist/commands/instructions.d.ts.map +1 -0
- package/dist/commands/instructions.js +100 -0
- package/dist/commands/journal.d.ts.map +1 -1
- package/dist/commands/journal.js +4 -13
- package/dist/commands/ledger-v3.d.ts +5 -0
- package/dist/commands/ledger-v3.d.ts.map +1 -0
- package/dist/commands/ledger-v3.js +91 -0
- package/dist/commands/presence.d.ts.map +1 -1
- package/dist/commands/presence.js +15 -6
- package/dist/commands/sync.d.ts +1 -1
- package/dist/commands/sync.js +1 -1
- package/dist/commands/web.d.ts +6 -0
- package/dist/commands/web.d.ts.map +1 -1
- package/dist/commands/web.js +67 -7
- package/dist/commands/work.d.ts.map +1 -1
- package/dist/commands/work.js +22 -5
- package/dist/core/adapter.d.ts +5 -0
- package/dist/core/adapter.d.ts.map +1 -0
- package/dist/core/adapter.js +1 -0
- package/dist/core/adapters/attest.d.ts +5 -2
- package/dist/core/adapters/attest.d.ts.map +1 -1
- package/dist/core/adapters/attest.js +8 -3
- package/dist/core/adapters/profiles.d.ts +6 -6
- package/dist/core/adapters/profiles.d.ts.map +1 -1
- package/dist/core/adapters/profiles.js +4 -4
- package/dist/core/agents/canonical-emit.d.ts +17 -15
- package/dist/core/agents/canonical-emit.d.ts.map +1 -1
- package/dist/core/agents/canonical-emit.js +27 -25
- package/dist/core/agents/cli.js +212 -235
- package/dist/core/agents/codex-archive-v3.d.ts +14 -0
- package/dist/core/agents/codex-archive-v3.d.ts.map +1 -0
- package/dist/core/agents/codex-archive-v3.js +110 -0
- package/dist/core/agents/coord-client.d.ts +19 -70
- package/dist/core/agents/coord-client.d.ts.map +1 -1
- package/dist/core/agents/coord-client.js +65 -155
- package/dist/core/agents/finalization.d.ts +4 -1
- package/dist/core/agents/finalization.d.ts.map +1 -1
- package/dist/core/agents/finalization.js +89 -32
- package/dist/core/agents/index.d.ts +5 -5
- package/dist/core/agents/index.d.ts.map +1 -1
- package/dist/core/agents/index.js +5 -5
- package/dist/core/agents/live-authority-v3.d.ts +59 -0
- package/dist/core/agents/live-authority-v3.d.ts.map +1 -0
- package/dist/core/agents/live-authority-v3.js +233 -0
- package/dist/core/agents/live-lifecycle-v3.d.ts +20 -0
- package/dist/core/agents/live-lifecycle-v3.d.ts.map +1 -0
- package/dist/core/agents/live-lifecycle-v3.js +91 -0
- package/dist/core/agents/live-observation-v3.d.ts +25 -0
- package/dist/core/agents/live-observation-v3.d.ts.map +1 -0
- package/dist/core/agents/live-observation-v3.js +157 -0
- package/dist/core/agents/render/prompt-context.d.ts +10 -4
- package/dist/core/agents/render/prompt-context.d.ts.map +1 -1
- package/dist/core/agents/render/prompt-context.js +61 -55
- package/dist/core/agents/render/session-context.d.ts +1 -1
- package/dist/core/agents/render/session-context.d.ts.map +1 -1
- package/dist/core/agents/render/session-context.js +15 -33
- package/dist/core/agents/rules/claim-conflict.d.ts +3 -3
- package/dist/core/agents/rules/claim-conflict.d.ts.map +1 -1
- package/dist/core/agents/rules/claim-conflict.js +79 -127
- package/dist/core/agents/rules/commit-conflict.d.ts.map +1 -1
- package/dist/core/agents/rules/commit-conflict.js +3 -18
- package/dist/core/agents/rules/stop-hook.d.ts +9 -50
- package/dist/core/agents/rules/stop-hook.d.ts.map +1 -1
- package/dist/core/agents/rules/stop-hook.js +193 -236
- package/dist/core/agents/session-events.d.ts +5 -7
- package/dist/core/agents/session-events.d.ts.map +1 -1
- package/dist/core/agents/session-events.js +127 -95
- package/dist/core/agents/session-finalization-state-v3.d.ts +30 -0
- package/dist/core/agents/session-finalization-state-v3.d.ts.map +1 -0
- package/dist/core/agents/session-finalization-state-v3.js +40 -0
- package/dist/core/agents/session-finalizer-v3.d.ts +107 -0
- package/dist/core/agents/session-finalizer-v3.d.ts.map +1 -0
- package/dist/core/agents/session-finalizer-v3.js +734 -0
- package/dist/core/agents/session-name-display.d.ts +40 -0
- package/dist/core/agents/session-name-display.d.ts.map +1 -0
- package/dist/core/agents/session-name-display.js +119 -0
- package/dist/core/agents/state/activity-log.d.ts +3 -3
- package/dist/core/agents/state/activity-log.d.ts.map +1 -1
- package/dist/core/agents/state/activity-log.js +7 -16
- package/dist/core/agents/state/heartbeat-writer.d.ts +29 -46
- package/dist/core/agents/state/heartbeat-writer.d.ts.map +1 -1
- package/dist/core/agents/state/heartbeat-writer.js +59 -199
- package/dist/core/agents/state/live-coordination-view.d.ts +31 -0
- package/dist/core/agents/state/live-coordination-view.d.ts.map +1 -0
- package/dist/core/agents/state/live-coordination-view.js +209 -0
- package/dist/core/agents/state/session-state.d.ts +45 -0
- package/dist/core/agents/state/session-state.d.ts.map +1 -0
- package/dist/core/agents/state/session-state.js +90 -0
- package/dist/core/agents/state/stale-sweep.d.ts +1 -1
- package/dist/core/agents/state/stale-sweep.d.ts.map +1 -1
- package/dist/core/agents/state/stale-sweep.js +26 -15
- package/dist/core/artifacts/index.d.ts.map +1 -1
- package/dist/core/artifacts/index.js +5 -7
- package/dist/core/config.d.ts +33 -2
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +98 -2
- package/dist/core/context/index.d.ts +1 -4
- package/dist/core/context/index.d.ts.map +1 -1
- package/dist/core/context/index.js +9 -9
- package/dist/core/events/span-parent.d.ts +15 -0
- package/dist/core/events/span-parent.d.ts.map +1 -0
- package/dist/core/events/span-parent.js +34 -0
- package/dist/core/events/v3/advance.d.ts +14 -0
- package/dist/core/events/v3/advance.d.ts.map +1 -0
- package/dist/core/events/v3/advance.js +134 -0
- package/dist/core/events/v3/authority-outbox.d.ts +78 -0
- package/dist/core/events/v3/authority-outbox.d.ts.map +1 -0
- package/dist/core/events/v3/authority-outbox.js +399 -0
- package/dist/core/events/v3/base-builder.d.ts +20 -0
- package/dist/core/events/v3/base-builder.d.ts.map +1 -0
- package/dist/core/events/v3/base-builder.js +29 -0
- package/dist/core/events/v3/base-contract.d.ts +7576 -0
- package/dist/core/events/v3/base-contract.d.ts.map +1 -0
- package/dist/core/events/v3/base-contract.js +647 -0
- package/dist/core/events/v3/bootstrap.d.ts +34 -0
- package/dist/core/events/v3/bootstrap.d.ts.map +1 -0
- package/dist/core/events/v3/bootstrap.js +175 -0
- package/dist/core/events/v3/builder.d.ts +20 -0
- package/dist/core/events/v3/builder.d.ts.map +1 -0
- package/dist/core/events/v3/builder.js +28 -0
- package/dist/core/events/v3/canonical.d.ts +31 -0
- package/dist/core/events/v3/canonical.d.ts.map +1 -0
- package/dist/core/events/v3/canonical.js +100 -0
- package/dist/core/events/v3/capabilities.d.ts +31 -0
- package/dist/core/events/v3/capabilities.d.ts.map +1 -0
- package/dist/core/events/v3/capabilities.js +107 -0
- package/dist/core/events/v3/capability-drift.d.ts +22 -0
- package/dist/core/events/v3/capability-drift.d.ts.map +1 -0
- package/dist/core/events/v3/capability-drift.js +134 -0
- package/dist/core/events/v3/catalog.d.ts +38 -0
- package/dist/core/events/v3/catalog.d.ts.map +1 -0
- package/dist/core/events/v3/catalog.js +135 -0
- package/dist/core/events/v3/clock-order.d.ts +34 -0
- package/dist/core/events/v3/clock-order.d.ts.map +1 -0
- package/dist/core/events/v3/clock-order.js +35 -0
- package/dist/core/events/v3/contract.d.ts +171 -0
- package/dist/core/events/v3/contract.d.ts.map +1 -0
- package/dist/core/events/v3/contract.js +180 -0
- package/dist/core/events/v3/control.d.ts +111 -0
- package/dist/core/events/v3/control.d.ts.map +1 -0
- package/dist/core/events/v3/control.js +419 -0
- package/dist/core/events/v3/coordination-view.d.ts +69 -0
- package/dist/core/events/v3/coordination-view.d.ts.map +1 -0
- package/dist/core/events/v3/coordination-view.js +119 -0
- package/dist/core/events/v3/economics.d.ts +77 -0
- package/dist/core/events/v3/economics.d.ts.map +1 -0
- package/dist/core/events/v3/economics.js +274 -0
- package/dist/core/events/v3/finalization-view.d.ts +26 -0
- package/dist/core/events/v3/finalization-view.d.ts.map +1 -0
- package/dist/core/events/v3/finalization-view.js +37 -0
- package/dist/core/events/v3/fingerprint-keys.d.ts +25 -0
- package/dist/core/events/v3/fingerprint-keys.d.ts.map +1 -0
- package/dist/core/events/v3/fingerprint-keys.js +217 -0
- package/dist/core/events/v3/generated.d.ts +4 -0
- package/dist/core/events/v3/generated.d.ts.map +1 -0
- package/dist/core/events/v3/generated.js +47 -0
- package/dist/core/events/v3/ids.d.ts +9 -0
- package/dist/core/events/v3/ids.d.ts.map +1 -0
- package/dist/core/events/v3/ids.js +25 -0
- package/dist/core/events/v3/index.d.ts +35 -0
- package/dist/core/events/v3/index.d.ts.map +1 -0
- package/dist/core/events/v3/index.js +33 -0
- package/dist/core/events/v3/latency.d.ts +63 -0
- package/dist/core/events/v3/latency.d.ts.map +1 -0
- package/dist/core/events/v3/latency.js +412 -0
- package/dist/core/events/v3/live-feed.d.ts +45 -0
- package/dist/core/events/v3/live-feed.d.ts.map +1 -0
- package/dist/core/events/v3/live-feed.js +246 -0
- package/dist/core/events/v3/live-observation.d.ts +35 -0
- package/dist/core/events/v3/live-observation.d.ts.map +1 -0
- package/dist/core/events/v3/live-observation.js +1 -0
- package/dist/core/events/v3/live-routing.d.ts +57 -0
- package/dist/core/events/v3/live-routing.d.ts.map +1 -0
- package/dist/core/events/v3/live-routing.js +107 -0
- package/dist/core/events/v3/producers/command-recorder.d.ts +67 -0
- package/dist/core/events/v3/producers/command-recorder.d.ts.map +1 -0
- package/dist/core/events/v3/producers/command-recorder.js +477 -0
- package/dist/core/events/v3/producers/command.d.ts +50 -0
- package/dist/core/events/v3/producers/command.d.ts.map +1 -0
- package/dist/core/events/v3/producers/command.js +135 -0
- package/dist/core/events/v3/producers/coordination-recorder.d.ts +53 -0
- package/dist/core/events/v3/producers/coordination-recorder.d.ts.map +1 -0
- package/dist/core/events/v3/producers/coordination-recorder.js +376 -0
- package/dist/core/events/v3/producers/coordination.d.ts +90 -0
- package/dist/core/events/v3/producers/coordination.d.ts.map +1 -0
- package/dist/core/events/v3/producers/coordination.js +229 -0
- package/dist/core/events/v3/producers/hook-base.d.ts +54 -0
- package/dist/core/events/v3/producers/hook-base.d.ts.map +1 -0
- package/dist/core/events/v3/producers/hook-base.js +424 -0
- package/dist/core/events/v3/producers/hook.d.ts +29 -0
- package/dist/core/events/v3/producers/hook.d.ts.map +1 -0
- package/dist/core/events/v3/producers/hook.js +71 -0
- package/dist/core/events/v3/producers/intake.d.ts +65 -0
- package/dist/core/events/v3/producers/intake.d.ts.map +1 -0
- package/dist/core/events/v3/producers/intake.js +244 -0
- package/dist/core/events/v3/producers/recorder.d.ts +240 -0
- package/dist/core/events/v3/producers/recorder.d.ts.map +1 -0
- package/dist/core/events/v3/producers/recorder.js +2176 -0
- package/dist/core/events/v3/projection.d.ts +101 -0
- package/dist/core/events/v3/projection.d.ts.map +1 -0
- package/dist/core/events/v3/projection.js +479 -0
- package/dist/core/events/v3/reader.d.ts +75 -0
- package/dist/core/events/v3/reader.d.ts.map +1 -0
- package/dist/core/events/v3/reader.js +778 -0
- package/dist/core/events/v3/recovery-record.d.ts +47 -0
- package/dist/core/events/v3/recovery-record.d.ts.map +1 -0
- package/dist/core/events/v3/recovery-record.js +167 -0
- package/dist/core/events/v3/recovery.d.ts +22 -0
- package/dist/core/events/v3/recovery.d.ts.map +1 -0
- package/dist/core/events/v3/recovery.js +227 -0
- package/dist/core/events/v3/span-state.d.ts +52 -0
- package/dist/core/events/v3/span-state.d.ts.map +1 -0
- package/dist/core/events/v3/span-state.js +142 -0
- package/dist/core/events/v3/targets.d.ts +23 -0
- package/dist/core/events/v3/targets.d.ts.map +1 -0
- package/dist/core/events/v3/targets.js +134 -0
- package/dist/core/events/v3/turn-telemetry.d.ts +41 -0
- package/dist/core/events/v3/turn-telemetry.d.ts.map +1 -0
- package/dist/core/events/v3/turn-telemetry.js +168 -0
- package/dist/core/events/v3/validate.d.ts +9 -0
- package/dist/core/events/v3/validate.d.ts.map +1 -0
- package/dist/core/events/v3/validate.js +281 -0
- package/dist/core/events/v3/writer.d.ts +56 -0
- package/dist/core/events/v3/writer.d.ts.map +1 -0
- package/dist/core/events/v3/writer.js +335 -0
- package/dist/core/governor/index.d.ts +1 -1
- package/dist/core/governor/index.d.ts.map +1 -1
- package/dist/core/governor/index.js +1 -1
- package/dist/core/governor/plan-api.d.ts +2 -1
- package/dist/core/governor/plan-api.d.ts.map +1 -1
- package/dist/core/governor/plan-api.js +6 -3
- package/dist/core/governor/read.d.ts +1 -1
- package/dist/core/governor/read.d.ts.map +1 -1
- package/dist/core/governor/read.js +1 -1
- package/dist/core/governor/state.d.ts +9 -0
- package/dist/core/governor/state.d.ts.map +1 -1
- package/dist/core/governor/state.js +40 -3
- package/dist/core/guard/config.d.ts +5 -0
- package/dist/core/guard/config.d.ts.map +1 -0
- package/dist/core/guard/config.js +157 -0
- package/dist/core/guard/coordinator.d.ts +14 -0
- package/dist/core/guard/coordinator.d.ts.map +1 -0
- package/dist/core/guard/coordinator.js +173 -0
- package/dist/core/guard/evaluator.d.ts +4 -0
- package/dist/core/guard/evaluator.d.ts.map +1 -0
- package/dist/core/guard/evaluator.js +242 -0
- package/dist/core/guard/evidence-v3.d.ts +15 -0
- package/dist/core/guard/evidence-v3.d.ts.map +1 -0
- package/dist/core/guard/evidence-v3.js +171 -0
- package/dist/core/guard/index.d.ts +10 -0
- package/dist/core/guard/index.d.ts.map +1 -0
- package/dist/core/guard/index.js +6 -0
- package/dist/core/guard/live-source-v3.d.ts +40 -0
- package/dist/core/guard/live-source-v3.d.ts.map +1 -0
- package/dist/core/guard/live-source-v3.js +128 -0
- package/dist/core/guard/storage.d.ts +27 -0
- package/dist/core/guard/storage.d.ts.map +1 -0
- package/dist/core/guard/storage.js +140 -0
- package/dist/core/guard/types.d.ts +119 -0
- package/dist/core/guard/types.d.ts.map +1 -0
- package/dist/core/guard/types.js +1 -0
- package/dist/core/hooks/adapter/detect.d.ts +18 -1
- package/dist/core/hooks/adapter/detect.d.ts.map +1 -1
- package/dist/core/hooks/adapter/detect.js +29 -0
- package/dist/core/hooks/adapter/events.d.ts +7 -4
- package/dist/core/hooks/adapter/events.d.ts.map +1 -1
- package/dist/core/hooks/adapter/events.js +13 -4
- package/dist/core/hooks/adapter/output.d.ts +2 -2
- package/dist/core/hooks/adapter/output.d.ts.map +1 -1
- package/dist/core/hooks/adapter/parse.d.ts +7 -4
- package/dist/core/hooks/adapter/parse.d.ts.map +1 -1
- package/dist/core/hooks/adapter/parse.js +64 -24
- package/dist/core/hooks/adapter/wiring.d.ts +30 -4
- package/dist/core/hooks/adapter/wiring.d.ts.map +1 -1
- package/dist/core/hooks/adapter/wiring.js +89 -11
- package/dist/core/hooks/cli.d.ts +1 -1
- package/dist/core/hooks/cli.js +345 -400
- package/dist/core/hooks/codex-authorization.d.ts +30 -0
- package/dist/core/hooks/codex-authorization.d.ts.map +1 -0
- package/dist/core/hooks/codex-authorization.js +199 -0
- package/dist/core/hooks/effects/image-capture.d.ts +20 -34
- package/dist/core/hooks/effects/image-capture.d.ts.map +1 -1
- package/dist/core/hooks/effects/image-capture.js +212 -221
- package/dist/core/hooks/effects/index.d.ts +1 -9
- package/dist/core/hooks/effects/index.d.ts.map +1 -1
- package/dist/core/hooks/effects/index.js +1 -24
- package/dist/core/hooks/events/input-hash.d.ts +7 -0
- package/dist/core/hooks/events/input-hash.d.ts.map +1 -0
- package/dist/core/hooks/events/input-hash.js +43 -0
- package/dist/core/hooks/index.d.ts +4 -3
- package/dist/core/hooks/index.d.ts.map +1 -1
- package/dist/core/hooks/index.js +2 -3
- package/dist/core/hooks/resolve/coord-root.d.ts +1 -1
- package/dist/core/hooks/resolve/coord-root.js +1 -1
- package/dist/core/hooks/resolve/owner.d.ts +16 -15
- package/dist/core/hooks/resolve/owner.d.ts.map +1 -1
- package/dist/core/hooks/resolve/owner.js +51 -42
- package/dist/core/hooks/resolve/transcript.d.ts +33 -3
- package/dist/core/hooks/resolve/transcript.d.ts.map +1 -1
- package/dist/core/hooks/resolve/transcript.js +155 -14
- package/dist/core/hooks/session-name-presence.d.ts +9 -10
- package/dist/core/hooks/session-name-presence.d.ts.map +1 -1
- package/dist/core/hooks/session-name-presence.js +15 -15
- package/dist/core/hooks/unsafe-cross-shell.d.ts +1 -1
- package/dist/core/hooks/unsafe-cross-shell.d.ts.map +1 -1
- package/dist/core/journal/index.d.ts +2 -2
- package/dist/core/journal/index.d.ts.map +1 -1
- package/dist/core/journal/index.js +9 -22
- package/dist/core/presence/blob.d.ts +8 -3
- package/dist/core/presence/blob.d.ts.map +1 -1
- package/dist/core/presence/blob.js +54 -41
- package/dist/core/presence/codec-digest.d.ts +29 -0
- package/dist/core/presence/codec-digest.d.ts.map +1 -0
- package/dist/core/presence/codec-digest.js +170 -0
- package/dist/core/presence/index.js +15 -1
- package/dist/core/presence/relay-client.d.ts +1 -1
- package/dist/core/presence/relay-client.d.ts.map +1 -1
- package/dist/core/presence/relay-client.js +5 -5
- package/dist/core/work/index.d.ts +1 -1
- package/dist/core/work/index.d.ts.map +1 -1
- package/dist/core/work/index.js +1 -1
- package/dist/core/work/read.d.ts +1 -1
- package/dist/core/work/read.d.ts.map +1 -1
- package/dist/core/work/read.js +1 -1
- package/dist/core/work/runner.d.ts.map +1 -1
- package/dist/core/work/runner.js +6 -0
- package/dist/core/work/state.d.ts +9 -0
- package/dist/core/work/state.d.ts.map +1 -1
- package/dist/core/work/state.js +17 -3
- package/dist/core/workflow/engine.js +24 -25
- package/dist/core/workflow/live-session-v3.d.ts +19 -0
- package/dist/core/workflow/live-session-v3.d.ts.map +1 -0
- package/dist/core/workflow/live-session-v3.js +86 -0
- package/dist/core/workflow/scope-id.d.ts +3 -0
- package/dist/core/workflow/scope-id.d.ts.map +1 -0
- package/dist/core/workflow/scope-id.js +5 -0
- package/dist/core/workflow/workspaces/leases.d.ts +4 -0
- package/dist/core/workflow/workspaces/leases.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/leases.js +53 -19
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/lib/browser/client.d.ts +41 -0
- package/dist/lib/browser/client.d.ts.map +1 -1
- package/dist/lib/browser/client.js +203 -0
- package/dist/lib/browser/critique.d.ts +28 -2
- package/dist/lib/browser/critique.d.ts.map +1 -1
- package/dist/lib/browser/critique.js +74 -18
- package/dist/lib/browser/geometry.d.ts +1 -1
- package/dist/lib/browser/geometry.d.ts.map +1 -1
- package/dist/lib/browser/geometry.js +130 -6
- package/dist/lib/browser/index.d.ts +3 -0
- package/dist/lib/browser/index.d.ts.map +1 -1
- package/dist/lib/browser/index.js +3 -0
- package/dist/lib/browser/qa-plan.d.ts +174 -0
- package/dist/lib/browser/qa-plan.d.ts.map +1 -0
- package/dist/lib/browser/qa-plan.js +321 -0
- package/dist/lib/browser/qa-reuse.d.ts +99 -0
- package/dist/lib/browser/qa-reuse.d.ts.map +1 -0
- package/dist/lib/browser/qa-reuse.js +222 -0
- package/dist/lib/browser/qa-snapshot.d.ts +64 -0
- package/dist/lib/browser/qa-snapshot.d.ts.map +1 -0
- package/dist/lib/browser/qa-snapshot.js +171 -0
- package/dist/lib/browser/runts.d.ts.map +1 -1
- package/dist/lib/browser/runts.js +22 -1
- package/dist/lib/browser/tiling.d.ts +71 -0
- package/dist/lib/browser/tiling.d.ts.map +1 -0
- package/dist/lib/browser/tiling.js +118 -0
- package/dist/lib/context/index.d.ts +0 -3
- package/dist/lib/context/index.d.ts.map +1 -1
- package/dist/lib/context/index.js +20 -42
- package/dist/lib/council/index.d.ts +2 -2
- package/dist/lib/council/index.d.ts.map +1 -1
- package/dist/lib/council/index.js +9 -20
- package/dist/lib/docs-frontmatter.d.ts +1 -6
- package/dist/lib/docs-frontmatter.d.ts.map +1 -1
- package/dist/lib/docs-frontmatter.js +12 -78
- package/dist/lib/docs-index.d.ts +9 -0
- package/dist/lib/docs-index.d.ts.map +1 -1
- package/dist/lib/docs-index.js +32 -3
- package/dist/lib/docs-lint.d.ts.map +1 -1
- package/dist/lib/docs-lint.js +14 -30
- package/dist/lib/docs-metadata-audit.d.ts +19 -0
- package/dist/lib/docs-metadata-audit.d.ts.map +1 -0
- package/dist/lib/docs-metadata-audit.js +132 -0
- package/dist/lib/docs-metadata-managed.d.ts +23 -0
- package/dist/lib/docs-metadata-managed.d.ts.map +1 -0
- package/dist/lib/docs-metadata-managed.js +78 -0
- package/dist/lib/docs-metadata-sync.d.ts +20 -0
- package/dist/lib/docs-metadata-sync.d.ts.map +1 -0
- package/dist/lib/docs-metadata-sync.js +222 -0
- package/dist/lib/docs-metadata-v2-schema.d.ts +273 -0
- package/dist/lib/docs-metadata-v2-schema.d.ts.map +1 -0
- package/dist/lib/docs-metadata-v2-schema.js +134 -0
- package/dist/lib/docs-metadata-v2.d.ts +21 -0
- package/dist/lib/docs-metadata-v2.d.ts.map +1 -0
- package/dist/lib/docs-metadata-v2.js +424 -0
- package/dist/lib/docs-new.d.ts +11 -0
- package/dist/lib/docs-new.d.ts.map +1 -0
- package/dist/lib/docs-new.js +52 -0
- package/dist/lib/docs-sweep.d.ts.map +1 -1
- package/dist/lib/docs-sweep.js +45 -29
- package/dist/lib/headless/index.d.ts +98 -0
- package/dist/lib/headless/index.d.ts.map +1 -0
- package/dist/lib/headless/index.js +211 -0
- package/dist/lib/identities/assume.d.ts +4 -4
- package/dist/lib/identities/assume.d.ts.map +1 -1
- package/dist/lib/identities/assume.js +52 -68
- package/dist/lib/instructions/apply.d.ts +5 -4
- package/dist/lib/instructions/apply.d.ts.map +1 -1
- package/dist/lib/instructions/apply.js +32 -20
- package/dist/lib/instructions/bundle.d.ts +33 -0
- package/dist/lib/instructions/bundle.d.ts.map +1 -0
- package/dist/lib/instructions/bundle.js +149 -0
- package/dist/lib/instructions/splice.d.ts +0 -1
- package/dist/lib/instructions/splice.d.ts.map +1 -1
- package/dist/lib/instructions/splice.js +22 -6
- package/dist/lib/instructions/templates.d.ts +7 -5
- package/dist/lib/instructions/templates.d.ts.map +1 -1
- package/dist/lib/instructions/templates.js +79 -9
- package/package.json +27 -6
- package/schemas/config.schema.json +120 -2
- package/schemas/docs-metadata-v2.schema.json +441 -0
- package/schemas/event-v3.schema.json +24472 -0
- package/src/commander.ts +7 -1
- package/src/commands/adapter.ts +2 -2
- package/src/commands/agents.ts +1737 -570
- package/src/commands/artifacts.ts +7 -6
- package/src/commands/backup.ts +29 -21
- package/src/commands/browse.ts +349 -8
- package/src/commands/checkpoint.ts +4 -3
- package/src/commands/claude-desktop.ts +7 -5
- package/src/commands/context.ts +1 -6
- package/src/commands/decision.ts +27 -44
- package/src/commands/docs.ts +100 -33
- package/src/commands/doctor.ts +73 -8
- package/src/commands/events.ts +256 -0
- package/src/commands/governor.ts +18 -4
- package/src/commands/init.ts +264 -57
- package/src/commands/instructions.ts +129 -0
- package/src/commands/journal.ts +4 -13
- package/src/commands/ledger-v3.ts +111 -0
- package/src/commands/presence.ts +18 -11
- package/src/commands/sync.ts +1 -1
- package/src/commands/web.ts +67 -8
- package/src/commands/work.ts +28 -5
- package/src/core/adapter.ts +5 -0
- package/src/core/adapters/attest.ts +8 -3
- package/src/core/adapters/profiles.ts +4 -6
- package/src/core/agents/canonical-emit.ts +39 -28
- package/src/core/agents/cli.ts +242 -263
- package/src/core/agents/codex-archive-v3.ts +138 -0
- package/src/core/agents/coord-client.ts +75 -177
- package/src/core/agents/finalization.ts +120 -38
- package/src/core/agents/index.ts +5 -5
- package/src/core/agents/live-authority-v3.ts +375 -0
- package/src/core/agents/live-lifecycle-v3.ts +140 -0
- package/src/core/agents/live-observation-v3.ts +216 -0
- package/src/core/agents/render/prompt-context.ts +89 -55
- package/src/core/agents/render/session-context.ts +23 -32
- package/src/core/agents/rules/claim-conflict.ts +85 -126
- package/src/core/agents/rules/commit-conflict.ts +3 -14
- package/src/core/agents/rules/stop-hook.ts +239 -293
- package/src/core/agents/session-events.ts +137 -104
- package/src/core/agents/session-finalization-state-v3.ts +90 -0
- package/src/core/agents/session-finalizer-v3.ts +953 -0
- package/src/core/agents/session-name-display.ts +149 -0
- package/src/core/agents/state/activity-log.ts +6 -14
- package/src/core/agents/state/heartbeat-writer.ts +98 -242
- package/src/core/agents/state/live-coordination-view.ts +290 -0
- package/src/core/agents/state/session-state.ts +143 -0
- package/src/core/agents/state/stale-sweep.ts +40 -17
- package/src/core/artifacts/index.ts +4 -5
- package/src/core/config.ts +148 -3
- package/src/core/context/index.ts +9 -17
- package/src/core/events/span-parent.ts +46 -0
- package/src/core/events/v3/advance.ts +168 -0
- package/src/core/events/v3/authority-outbox.ts +548 -0
- package/src/core/events/v3/base-builder.ts +60 -0
- package/src/core/events/v3/base-contract.ts +882 -0
- package/src/core/events/v3/bootstrap.ts +226 -0
- package/src/core/events/v3/builder.ts +59 -0
- package/src/core/events/v3/canonical.ts +153 -0
- package/src/core/events/v3/capabilities.ts +171 -0
- package/src/core/events/v3/capability-drift.ts +177 -0
- package/src/core/events/v3/catalog.ts +202 -0
- package/src/core/events/v3/clock-order.ts +41 -0
- package/src/core/events/v3/contract.ts +365 -0
- package/src/core/events/v3/control.ts +576 -0
- package/src/core/events/v3/coordination-view.ts +193 -0
- package/src/core/events/v3/economics.ts +384 -0
- package/src/core/events/v3/finalization-view.ts +67 -0
- package/src/core/events/v3/fingerprint-keys.ts +260 -0
- package/src/core/events/v3/generated.ts +48 -0
- package/src/core/events/v3/ids.ts +33 -0
- package/src/core/events/v3/index.ts +322 -0
- package/src/core/events/v3/latency.ts +551 -0
- package/src/core/events/v3/live-feed.ts +319 -0
- package/src/core/events/v3/live-observation.ts +39 -0
- package/src/core/events/v3/live-routing.ts +135 -0
- package/src/core/events/v3/producers/command-recorder.ts +631 -0
- package/src/core/events/v3/producers/command.ts +201 -0
- package/src/core/events/v3/producers/coordination-recorder.ts +538 -0
- package/src/core/events/v3/producers/coordination.ts +355 -0
- package/src/core/events/v3/producers/hook-base.ts +578 -0
- package/src/core/events/v3/producers/hook.ts +119 -0
- package/src/core/events/v3/producers/intake.ts +319 -0
- package/src/core/events/v3/producers/recorder.ts +2805 -0
- package/src/core/events/v3/projection.ts +653 -0
- package/src/core/events/v3/reader.ts +1127 -0
- package/src/core/events/v3/recovery-record.ts +244 -0
- package/src/core/events/v3/recovery.ts +271 -0
- package/src/core/events/v3/span-state.ts +187 -0
- package/src/core/events/v3/targets.ts +182 -0
- package/src/core/events/v3/turn-telemetry.ts +259 -0
- package/src/core/events/v3/validate.ts +361 -0
- package/src/core/events/v3/writer.ts +419 -0
- package/src/core/governor/index.ts +3 -0
- package/src/core/governor/plan-api.ts +10 -2
- package/src/core/governor/read.ts +3 -0
- package/src/core/governor/state.ts +52 -5
- package/src/core/guard/config.ts +206 -0
- package/src/core/guard/coordinator.ts +227 -0
- package/src/core/guard/evaluator.ts +343 -0
- package/src/core/guard/evidence-v3.ts +227 -0
- package/src/core/guard/index.ts +35 -0
- package/src/core/guard/live-source-v3.ts +204 -0
- package/src/core/guard/storage.ts +188 -0
- package/src/core/guard/types.ts +152 -0
- package/src/core/hooks/adapter/detect.ts +28 -1
- package/src/core/hooks/adapter/events.ts +15 -6
- package/src/core/hooks/adapter/output.ts +7 -2
- package/src/core/hooks/adapter/parse.ts +81 -36
- package/src/core/hooks/adapter/wiring.ts +119 -13
- package/src/core/hooks/cli.ts +398 -422
- package/src/core/hooks/codex-authorization.ts +253 -0
- package/src/core/hooks/effects/image-capture.ts +228 -238
- package/src/core/hooks/effects/index.ts +1 -36
- package/src/core/hooks/events/input-hash.ts +47 -0
- package/src/core/hooks/index.ts +4 -11
- package/src/core/hooks/resolve/coord-root.ts +1 -1
- package/src/core/hooks/resolve/owner.ts +52 -45
- package/src/core/hooks/resolve/transcript.ts +165 -14
- package/src/core/hooks/session-name-presence.ts +14 -15
- package/src/core/hooks/unsafe-cross-shell.ts +1 -1
- package/src/core/journal/index.ts +15 -22
- package/src/core/presence/blob.ts +63 -38
- package/src/core/presence/codec-digest.ts +215 -0
- package/src/core/presence/index.ts +18 -1
- package/src/core/presence/relay-client.ts +5 -5
- package/src/core/work/index.ts +3 -0
- package/src/core/work/read.ts +3 -0
- package/src/core/work/runner.ts +6 -0
- package/src/core/work/state.ts +27 -3
- package/src/core/workflow/engine.ts +24 -24
- package/src/core/workflow/live-session-v3.ts +126 -0
- package/src/core/workflow/scope-id.ts +6 -0
- package/src/core/workflow/workspaces/leases.ts +56 -19
- package/src/index.ts +1 -1
- package/src/lib/browser/client.ts +230 -0
- package/src/lib/browser/critique.ts +104 -27
- package/src/lib/browser/geometry.ts +143 -14
- package/src/lib/browser/index.ts +34 -0
- package/src/lib/browser/qa-plan.ts +501 -0
- package/src/lib/browser/qa-reuse.ts +306 -0
- package/src/lib/browser/qa-snapshot.ts +223 -0
- package/src/lib/browser/runts.ts +27 -2
- package/src/lib/browser/tiling.ts +164 -0
- package/src/lib/context/index.ts +22 -46
- package/src/lib/council/index.ts +9 -21
- package/src/lib/docs-frontmatter.ts +8 -79
- package/src/lib/docs-index.ts +33 -3
- package/src/lib/docs-lint.ts +15 -29
- package/src/lib/docs-metadata-audit.ts +166 -0
- package/src/lib/docs-metadata-managed.ts +83 -0
- package/src/lib/docs-metadata-sync.ts +262 -0
- package/src/lib/docs-metadata-v2-schema.ts +138 -0
- package/src/lib/docs-metadata-v2.ts +646 -0
- package/src/lib/docs-new.ts +63 -0
- package/src/lib/docs-sweep.ts +42 -28
- package/src/lib/headless/index.ts +287 -0
- package/src/lib/identities/assume.ts +67 -86
- package/src/lib/instructions/apply.ts +33 -20
- package/src/lib/instructions/bundle.ts +199 -0
- package/src/lib/instructions/splice.ts +21 -7
- package/src/lib/instructions/templates.ts +85 -13
- package/dist/core/agents/cli-emit.d.ts +0 -27
- package/dist/core/agents/cli-emit.d.ts.map +0 -1
- package/dist/core/agents/cli-emit.js +0 -57
- package/dist/core/agents/codex-replay.d.ts +0 -29
- package/dist/core/agents/codex-replay.d.ts.map +0 -1
- package/dist/core/agents/codex-replay.js +0 -138
- package/dist/core/agents/events/consume.d.ts +0 -82
- package/dist/core/agents/events/consume.d.ts.map +0 -1
- package/dist/core/agents/events/consume.js +0 -195
- package/dist/core/agents/events/emit.d.ts +0 -42
- package/dist/core/agents/events/emit.d.ts.map +0 -1
- package/dist/core/agents/events/emit.js +0 -75
- package/dist/core/agents/events/ulid.d.ts +0 -11
- package/dist/core/agents/events/ulid.d.ts.map +0 -1
- package/dist/core/agents/events/ulid.js +0 -47
- package/dist/core/agents/state/heartbeat-projector.d.ts +0 -65
- package/dist/core/agents/state/heartbeat-projector.d.ts.map +0 -1
- package/dist/core/agents/state/heartbeat-projector.js +0 -527
- package/dist/core/hooks/events/emit.d.ts +0 -31
- package/dist/core/hooks/events/emit.d.ts.map +0 -1
- package/dist/core/hooks/events/emit.js +0 -93
- package/dist/core/hooks/events/rotate.d.ts +0 -43
- package/dist/core/hooks/events/rotate.d.ts.map +0 -1
- package/dist/core/hooks/events/rotate.js +0 -142
- package/dist/core/hooks/events/schema.d.ts +0 -312
- package/dist/core/hooks/events/schema.d.ts.map +0 -1
- package/dist/core/hooks/events/schema.js +0 -12
- package/dist/core/hooks/events/ulid.d.ts +0 -10
- package/dist/core/hooks/events/ulid.d.ts.map +0 -1
- package/dist/core/hooks/events/ulid.js +0 -47
- package/dist/lib/docs-frontmatter-migrate.d.ts +0 -33
- package/dist/lib/docs-frontmatter-migrate.d.ts.map +0 -1
- package/dist/lib/docs-frontmatter-migrate.js +0 -364
- package/src/core/agents/cli-emit.ts +0 -64
- package/src/core/agents/codex-replay.ts +0 -163
- package/src/core/agents/events/consume.ts +0 -254
- package/src/core/agents/events/emit.ts +0 -115
- package/src/core/agents/events/ulid.ts +0 -51
- package/src/core/agents/state/heartbeat-projector.ts +0 -582
- package/src/core/hooks/events/emit.ts +0 -125
- package/src/core/hooks/events/rotate.ts +0 -151
- package/src/core/hooks/events/schema.ts +0 -538
- package/src/core/hooks/events/ulid.ts +0 -51
- package/src/lib/docs-frontmatter-migrate.ts +0 -427
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Headless harness calling — run a one-shot prompt (optionally with images)
|
|
3
|
+
* through a locally installed AI coding harness CLI and return its reply.
|
|
4
|
+
*
|
|
5
|
+
* Backends, in default preference order (subscription seats an embedding
|
|
6
|
+
* host already pays for, before any metered API a host might add on top):
|
|
7
|
+
*
|
|
8
|
+
* 1. claude-code `claude -p` JSON envelope on stdout
|
|
9
|
+
* 2. codex `codex exec` last message written to a file
|
|
10
|
+
* 3. cursor `cursor-agent -p` plain text on stdout
|
|
11
|
+
*
|
|
12
|
+
* Design rules, each learned from a live failure:
|
|
13
|
+
*
|
|
14
|
+
* - Every call runs from a NEUTRAL temp cwd holding only the staged images,
|
|
15
|
+
* so the nested session loads no repo instructions, hooks, or coordination
|
|
16
|
+
* rituals from the caller's checkout.
|
|
17
|
+
* - The child's stdin is CLOSED immediately. execFile leaves it open as a
|
|
18
|
+
* pipe, and codex interprets that as "more prompt coming" and blocks on
|
|
19
|
+
* it, then exits with no output.
|
|
20
|
+
* - An empty reply THROWS instead of returning "": a one-shot call that
|
|
21
|
+
* produced nothing was inconclusive, and callers gating on the result must
|
|
22
|
+
* fail closed rather than read silence as success.
|
|
23
|
+
* - `runHeadless` walks the backend chain PER CALL: a backend that is
|
|
24
|
+
* installed but errors (rate limit, timeout, transient exec failure) hands
|
|
25
|
+
* the same request to the next backend instead of failing the call. "On
|
|
26
|
+
* PATH" is not "working", and under parallel load the first backend can
|
|
27
|
+
* flake on a fraction of calls while the second runs clean.
|
|
28
|
+
*
|
|
29
|
+
* Env knobs (read through coordEnv, so the HARNERY_ prefix stays in one
|
|
30
|
+
* place): HARNERY_HEADLESS_BACKEND forces one backend and disables the
|
|
31
|
+
* fallback walk; HARNERY_HEADLESS_MODEL overrides the model passed to
|
|
32
|
+
* whichever backend runs.
|
|
33
|
+
*/
|
|
34
|
+
/** Names accepted by `runHeadlessOn`, `runHeadless({backends})`, and the
|
|
35
|
+
* HARNERY_HEADLESS_BACKEND env knob. */
|
|
36
|
+
export type HeadlessBackendName = "claude-code" | "codex" | "cursor";
|
|
37
|
+
/** An image to stage into the call's neutral cwd. `data` is the PNG bytes
|
|
38
|
+
* (Buffer) or their base64 encoding (string). */
|
|
39
|
+
export interface HeadlessImage {
|
|
40
|
+
data: Buffer | string;
|
|
41
|
+
/** Staged filename inside the neutral dir (default `image-<n>.png`). */
|
|
42
|
+
name?: string;
|
|
43
|
+
}
|
|
44
|
+
export interface HeadlessRequest {
|
|
45
|
+
/**
|
|
46
|
+
* The prompt, or a builder receiving the staged image paths. Backends that
|
|
47
|
+
* cannot attach an image natively (claude-code, cursor) rely on the prompt
|
|
48
|
+
* naming the staged paths so the harness reads them with its own tools;
|
|
49
|
+
* codex additionally attaches every image via `-i`.
|
|
50
|
+
*/
|
|
51
|
+
prompt: string | ((ctx: {
|
|
52
|
+
imagePaths: string[];
|
|
53
|
+
}) => string);
|
|
54
|
+
images?: HeadlessImage[];
|
|
55
|
+
/** Model override for this call; HARNERY_HEADLESS_MODEL wins over it. */
|
|
56
|
+
model?: string;
|
|
57
|
+
/** Kill the child after this long (default 240_000 ms). */
|
|
58
|
+
timeoutMs?: number;
|
|
59
|
+
/** Agentic turn budget where the backend supports one (default 4). */
|
|
60
|
+
maxTurns?: number;
|
|
61
|
+
}
|
|
62
|
+
export interface HeadlessResult {
|
|
63
|
+
/** The harness's final reply text, never empty (empty replies throw). */
|
|
64
|
+
text: string;
|
|
65
|
+
/** Which backend produced it. */
|
|
66
|
+
backend: HeadlessBackendName;
|
|
67
|
+
}
|
|
68
|
+
export interface RunHeadlessOptions {
|
|
69
|
+
/** Preference order (default: HEADLESS_BACKENDS order). */
|
|
70
|
+
backends?: HeadlessBackendName[];
|
|
71
|
+
/** Walk the chain past a failing backend (default true). Forcing a backend
|
|
72
|
+
* via HARNERY_HEADLESS_BACKEND implies false. */
|
|
73
|
+
fallback?: boolean;
|
|
74
|
+
}
|
|
75
|
+
/** Cross-runtime `which`: walk PATH (and PATHEXT on Windows) for an
|
|
76
|
+
* executable. Node has no built-in and Bun.which only exists under Bun. */
|
|
77
|
+
export declare function whichBin(bin: string): string | undefined;
|
|
78
|
+
/** The backend registry in default preference order. */
|
|
79
|
+
export declare const HEADLESS_BACKENDS: ReadonlyArray<{
|
|
80
|
+
name: HeadlessBackendName;
|
|
81
|
+
bin: string;
|
|
82
|
+
}>;
|
|
83
|
+
/** Backends whose binary is on PATH right now, in preference order. Being
|
|
84
|
+
* listed means installed, not proven working — that is what the per-call
|
|
85
|
+
* fallback in `runHeadless` is for. */
|
|
86
|
+
export declare function availableHeadlessBackends(): HeadlessBackendName[];
|
|
87
|
+
/** Run the request on exactly one named backend. Throws when the backend is
|
|
88
|
+
* not installed or the call fails. */
|
|
89
|
+
export declare function runHeadlessOn(name: HeadlessBackendName, req: HeadlessRequest): Promise<HeadlessResult>;
|
|
90
|
+
/**
|
|
91
|
+
* Run the request on the first backend that succeeds, walking the preference
|
|
92
|
+
* order past installed-but-failing backends (unless fallback is disabled or a
|
|
93
|
+
* backend is forced via HARNERY_HEADLESS_BACKEND). Throws when no backend is
|
|
94
|
+
* installed, or every attempted backend failed — the error message carries
|
|
95
|
+
* each backend's failure so a flaky chain is diagnosable.
|
|
96
|
+
*/
|
|
97
|
+
export declare function runHeadless(req: HeadlessRequest, opts?: RunHeadlessOptions): Promise<HeadlessResult>;
|
|
98
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/headless/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAoBH;wCACwC;AACxC,MAAM,MAAM,mBAAmB,GAAG,aAAa,GAAG,OAAO,GAAG,QAAQ,CAAC;AAErE;iDACiD;AACjD,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,wEAAwE;IACxE,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,eAAe;IAC9B;;;;;OAKG;IACH,MAAM,EAAE,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE;QAAE,UAAU,EAAE,MAAM,EAAE,CAAA;KAAE,KAAK,MAAM,CAAC,CAAC;IAC7D,MAAM,CAAC,EAAE,aAAa,EAAE,CAAC;IACzB,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2DAA2D;IAC3D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sEAAsE;IACtE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,yEAAyE;IACzE,IAAI,EAAE,MAAM,CAAC;IACb,iCAAiC;IACjC,OAAO,EAAE,mBAAmB,CAAC;CAC9B;AAED,MAAM,WAAW,kBAAkB;IACjC,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,mBAAmB,EAAE,CAAC;IACjC;qDACiD;IACjD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAMD;2EAC2E;AAC3E,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAgBxD;AA6FD,wDAAwD;AACxD,eAAO,MAAM,iBAAiB,EAAE,aAAa,CAAC;IAAE,IAAI,EAAE,mBAAmB,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAIvF,CAAC;AAaF;;uCAEuC;AACvC,wBAAgB,yBAAyB,IAAI,mBAAmB,EAAE,CAEjE;AAED;sCACsC;AACtC,wBAAsB,aAAa,CACjC,IAAI,EAAE,mBAAmB,EACzB,GAAG,EAAE,eAAe,GACnB,OAAO,CAAC,cAAc,CAAC,CASzB;AAED;;;;;;GAMG;AACH,wBAAsB,WAAW,CAC/B,GAAG,EAAE,eAAe,EACpB,IAAI,GAAE,kBAAuB,GAC5B,OAAO,CAAC,cAAc,CAAC,CAwBzB"}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Headless harness calling — run a one-shot prompt (optionally with images)
|
|
3
|
+
* through a locally installed AI coding harness CLI and return its reply.
|
|
4
|
+
*
|
|
5
|
+
* Backends, in default preference order (subscription seats an embedding
|
|
6
|
+
* host already pays for, before any metered API a host might add on top):
|
|
7
|
+
*
|
|
8
|
+
* 1. claude-code `claude -p` JSON envelope on stdout
|
|
9
|
+
* 2. codex `codex exec` last message written to a file
|
|
10
|
+
* 3. cursor `cursor-agent -p` plain text on stdout
|
|
11
|
+
*
|
|
12
|
+
* Design rules, each learned from a live failure:
|
|
13
|
+
*
|
|
14
|
+
* - Every call runs from a NEUTRAL temp cwd holding only the staged images,
|
|
15
|
+
* so the nested session loads no repo instructions, hooks, or coordination
|
|
16
|
+
* rituals from the caller's checkout.
|
|
17
|
+
* - The child's stdin is CLOSED immediately. execFile leaves it open as a
|
|
18
|
+
* pipe, and codex interprets that as "more prompt coming" and blocks on
|
|
19
|
+
* it, then exits with no output.
|
|
20
|
+
* - An empty reply THROWS instead of returning "": a one-shot call that
|
|
21
|
+
* produced nothing was inconclusive, and callers gating on the result must
|
|
22
|
+
* fail closed rather than read silence as success.
|
|
23
|
+
* - `runHeadless` walks the backend chain PER CALL: a backend that is
|
|
24
|
+
* installed but errors (rate limit, timeout, transient exec failure) hands
|
|
25
|
+
* the same request to the next backend instead of failing the call. "On
|
|
26
|
+
* PATH" is not "working", and under parallel load the first backend can
|
|
27
|
+
* flake on a fraction of calls while the second runs clean.
|
|
28
|
+
*
|
|
29
|
+
* Env knobs (read through coordEnv, so the HARNERY_ prefix stays in one
|
|
30
|
+
* place): HARNERY_HEADLESS_BACKEND forces one backend and disables the
|
|
31
|
+
* fallback walk; HARNERY_HEADLESS_MODEL overrides the model passed to
|
|
32
|
+
* whichever backend runs.
|
|
33
|
+
*/
|
|
34
|
+
import { execFile } from "node:child_process";
|
|
35
|
+
import { accessSync, constants, existsSync, mkdtempSync, readFileSync, rmSync, statSync, writeFileSync, } from "node:fs";
|
|
36
|
+
import { tmpdir } from "node:os";
|
|
37
|
+
import { delimiter, isAbsolute, join } from "node:path";
|
|
38
|
+
import { promisify } from "node:util";
|
|
39
|
+
import { coordEnv } from "../env.js";
|
|
40
|
+
const execFileAsync = promisify(execFile);
|
|
41
|
+
const MAX_BUFFER = 32 * 1024 * 1024;
|
|
42
|
+
const DEFAULT_TIMEOUT_MS = 240_000;
|
|
43
|
+
const DEFAULT_MAX_TURNS = 4;
|
|
44
|
+
/** Cross-runtime `which`: walk PATH (and PATHEXT on Windows) for an
|
|
45
|
+
* executable. Node has no built-in and Bun.which only exists under Bun. */
|
|
46
|
+
export function whichBin(bin) {
|
|
47
|
+
if (isAbsolute(bin))
|
|
48
|
+
return isExecutable(bin) ? bin : undefined;
|
|
49
|
+
const paths = (process.env.PATH ?? "").split(delimiter).filter(Boolean);
|
|
50
|
+
const exts = process.platform === "win32" ? (process.env.PATHEXT ?? ".EXE;.CMD;.BAT;.COM").split(";") : [""];
|
|
51
|
+
for (const dir of paths) {
|
|
52
|
+
for (const ext of exts) {
|
|
53
|
+
const candidate = join(dir, bin + ext.toLowerCase());
|
|
54
|
+
if (isExecutable(candidate))
|
|
55
|
+
return candidate;
|
|
56
|
+
if (ext) {
|
|
57
|
+
const upper = join(dir, bin + ext);
|
|
58
|
+
if (isExecutable(upper))
|
|
59
|
+
return upper;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
|
65
|
+
function isExecutable(path) {
|
|
66
|
+
try {
|
|
67
|
+
if (!statSync(path).isFile())
|
|
68
|
+
return false;
|
|
69
|
+
accessSync(path, constants.X_OK);
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/** Write the request's images into a fresh neutral dir and resolve the
|
|
77
|
+
* prompt against their staged paths. Caller must clean the dir up. */
|
|
78
|
+
function stageCall(req) {
|
|
79
|
+
const dir = mkdtempSync(join(tmpdir(), "harnery-headless-"));
|
|
80
|
+
const imagePaths = (req.images ?? []).map((img, i) => {
|
|
81
|
+
const path = join(dir, img.name ?? `image-${i + 1}.png`);
|
|
82
|
+
writeFileSync(path, typeof img.data === "string" ? Buffer.from(img.data, "base64") : img.data);
|
|
83
|
+
return path;
|
|
84
|
+
});
|
|
85
|
+
const prompt = typeof req.prompt === "function" ? req.prompt({ imagePaths }) : req.prompt;
|
|
86
|
+
return {
|
|
87
|
+
dir,
|
|
88
|
+
imagePaths,
|
|
89
|
+
prompt,
|
|
90
|
+
model: coordEnv("HEADLESS_MODEL") ?? req.model,
|
|
91
|
+
timeoutMs: req.timeoutMs ?? DEFAULT_TIMEOUT_MS,
|
|
92
|
+
maxTurns: req.maxTurns ?? DEFAULT_MAX_TURNS,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
/** Run a harness CLI from the neutral dir with stdin CLOSED (see module
|
|
96
|
+
* comment: an open stdin pipe deadlocks codex). */
|
|
97
|
+
function execHarness(bin, args, call) {
|
|
98
|
+
const pending = execFileAsync(bin, args, {
|
|
99
|
+
cwd: call.dir,
|
|
100
|
+
timeout: call.timeoutMs,
|
|
101
|
+
maxBuffer: MAX_BUFFER,
|
|
102
|
+
});
|
|
103
|
+
pending.child.stdin?.end();
|
|
104
|
+
return pending;
|
|
105
|
+
}
|
|
106
|
+
function assertReply(text, backend) {
|
|
107
|
+
if (!text.trim())
|
|
108
|
+
throw new Error(`${backend}: empty reply (inconclusive; failing closed)`);
|
|
109
|
+
return { text, backend };
|
|
110
|
+
}
|
|
111
|
+
async function runClaudeCode(bin, call) {
|
|
112
|
+
const args = ["-p", call.prompt, "--output-format", "json", "--max-turns", String(call.maxTurns)];
|
|
113
|
+
if (call.imagePaths.length)
|
|
114
|
+
args.push("--allowedTools", "Read");
|
|
115
|
+
if (call.model)
|
|
116
|
+
args.push("--model", call.model);
|
|
117
|
+
const { stdout } = await execHarness(bin, args, call);
|
|
118
|
+
const envelope = JSON.parse(stdout);
|
|
119
|
+
if (envelope.is_error) {
|
|
120
|
+
throw new Error(typeof envelope.result === "string" ? envelope.result : "claude-code: headless error");
|
|
121
|
+
}
|
|
122
|
+
return assertReply(typeof envelope.result === "string" ? envelope.result : "", "claude-code");
|
|
123
|
+
}
|
|
124
|
+
async function runCodex(bin, call) {
|
|
125
|
+
const outPath = join(call.dir, "last-message.txt");
|
|
126
|
+
const args = ["exec", "--skip-git-repo-check"];
|
|
127
|
+
for (const png of call.imagePaths)
|
|
128
|
+
args.push("-i", png);
|
|
129
|
+
args.push("--output-last-message", outPath);
|
|
130
|
+
if (call.model)
|
|
131
|
+
args.push("-m", call.model);
|
|
132
|
+
args.push(call.prompt);
|
|
133
|
+
await execHarness(bin, args, call);
|
|
134
|
+
return assertReply(existsSync(outPath) ? readFileSync(outPath, "utf-8") : "", "codex");
|
|
135
|
+
}
|
|
136
|
+
/** `-f` trusts the neutral dir so cursor's read tool runs without a prompt. */
|
|
137
|
+
async function runCursor(bin, call) {
|
|
138
|
+
const args = ["-p", call.prompt, "--output-format", "text", "-f"];
|
|
139
|
+
if (call.model)
|
|
140
|
+
args.push("--model", call.model);
|
|
141
|
+
const { stdout } = await execHarness(bin, args, call);
|
|
142
|
+
return assertReply(stdout, "cursor");
|
|
143
|
+
}
|
|
144
|
+
/** The backend registry in default preference order. */
|
|
145
|
+
export const HEADLESS_BACKENDS = [
|
|
146
|
+
{ name: "claude-code", bin: "claude" },
|
|
147
|
+
{ name: "codex", bin: "codex" },
|
|
148
|
+
{ name: "cursor", bin: "cursor-agent" },
|
|
149
|
+
];
|
|
150
|
+
const RUNNERS = {
|
|
151
|
+
"claude-code": runClaudeCode,
|
|
152
|
+
codex: runCodex,
|
|
153
|
+
cursor: runCursor,
|
|
154
|
+
};
|
|
155
|
+
function backendBin(name) {
|
|
156
|
+
const entry = HEADLESS_BACKENDS.find((b) => b.name === name);
|
|
157
|
+
return entry ? whichBin(entry.bin) : undefined;
|
|
158
|
+
}
|
|
159
|
+
/** Backends whose binary is on PATH right now, in preference order. Being
|
|
160
|
+
* listed means installed, not proven working — that is what the per-call
|
|
161
|
+
* fallback in `runHeadless` is for. */
|
|
162
|
+
export function availableHeadlessBackends() {
|
|
163
|
+
return HEADLESS_BACKENDS.filter((b) => whichBin(b.bin)).map((b) => b.name);
|
|
164
|
+
}
|
|
165
|
+
/** Run the request on exactly one named backend. Throws when the backend is
|
|
166
|
+
* not installed or the call fails. */
|
|
167
|
+
export async function runHeadlessOn(name, req) {
|
|
168
|
+
const bin = backendBin(name);
|
|
169
|
+
if (!bin)
|
|
170
|
+
throw new Error(`headless backend not installed: ${name}`);
|
|
171
|
+
const call = stageCall(req);
|
|
172
|
+
try {
|
|
173
|
+
return await RUNNERS[name](bin, call);
|
|
174
|
+
}
|
|
175
|
+
finally {
|
|
176
|
+
rmSync(call.dir, { recursive: true, force: true });
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Run the request on the first backend that succeeds, walking the preference
|
|
181
|
+
* order past installed-but-failing backends (unless fallback is disabled or a
|
|
182
|
+
* backend is forced via HARNERY_HEADLESS_BACKEND). Throws when no backend is
|
|
183
|
+
* installed, or every attempted backend failed — the error message carries
|
|
184
|
+
* each backend's failure so a flaky chain is diagnosable.
|
|
185
|
+
*/
|
|
186
|
+
export async function runHeadless(req, opts = {}) {
|
|
187
|
+
const forced = coordEnv("HEADLESS_BACKEND");
|
|
188
|
+
if (forced && !opts.backends) {
|
|
189
|
+
if (!HEADLESS_BACKENDS.some((b) => b.name === forced)) {
|
|
190
|
+
throw new Error(`unknown HARNERY_HEADLESS_BACKEND: ${forced}`);
|
|
191
|
+
}
|
|
192
|
+
return runHeadlessOn(forced, req);
|
|
193
|
+
}
|
|
194
|
+
const order = opts.backends ?? HEADLESS_BACKENDS.map((b) => b.name);
|
|
195
|
+
const installed = order.filter((name) => backendBin(name));
|
|
196
|
+
if (!installed.length) {
|
|
197
|
+
throw new Error(`no headless backend installed (looked for: ${order.join(", ")})`);
|
|
198
|
+
}
|
|
199
|
+
const fallback = opts.fallback ?? true;
|
|
200
|
+
const attempts = fallback ? installed : installed.slice(0, 1);
|
|
201
|
+
const failures = [];
|
|
202
|
+
for (const name of attempts) {
|
|
203
|
+
try {
|
|
204
|
+
return await runHeadlessOn(name, req);
|
|
205
|
+
}
|
|
206
|
+
catch (err) {
|
|
207
|
+
failures.push(`${name}: ${err instanceof Error ? err.message : String(err)}`);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
throw new Error(`every headless backend failed:\n ${failures.join("\n ")}`);
|
|
211
|
+
}
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
*
|
|
4
4
|
* The operation is serialized because "is this name live?" and "claim it"
|
|
5
5
|
* must be one critical section. Authoritative state is written twice on
|
|
6
|
-
* purpose: `.name-history`
|
|
7
|
-
* `
|
|
6
|
+
* purpose: `.name-history` supplies display metadata, while the canonical
|
|
7
|
+
* `coord.identity_attested` event makes replay and derived readers converge.
|
|
8
8
|
*
|
|
9
9
|
* Local collision policy: a fresh heartbeat alone is not enough to block.
|
|
10
10
|
* If the namesake has no live pid-map process (crashed session, healed
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* Refuse only when another process is still alive, or when cached remote
|
|
13
13
|
* presence reports the name.
|
|
14
14
|
*/
|
|
15
|
-
export type IdentityAssumeErrorCode = "identity_busy" | "identity_in_use" | "identity_is_ancestor" | "identity_not_found" | "invalid_identity" | "
|
|
15
|
+
export type IdentityAssumeErrorCode = "identity_busy" | "identity_in_use" | "identity_is_ancestor" | "identity_not_found" | "invalid_identity" | "no_live_generation" | "not_session" | "projection_failed";
|
|
16
16
|
export declare class IdentityAssumeError extends Error {
|
|
17
17
|
readonly code: IdentityAssumeErrorCode;
|
|
18
18
|
constructor(code: IdentityAssumeErrorCode, message: string);
|
|
@@ -38,7 +38,7 @@ export interface IdentityAssumeResult {
|
|
|
38
38
|
}
|
|
39
39
|
/** Best-effort collision read across local heartbeats and cached remote
|
|
40
40
|
* presence. No network call occurs; absent presence degrades to local-only. */
|
|
41
|
-
export declare function findIdentityConflict(coordRoot: string, instanceId: string, name: string, nowMs?: number): IdentityConflict | null;
|
|
41
|
+
export declare function findIdentityConflict(coordRoot: string, instanceId: string, name: string, nowMs?: number, excludedInstanceIds?: ReadonlySet<string>): IdentityConflict | null;
|
|
42
42
|
/**
|
|
43
43
|
* Drop a local namesake whose adapter process is gone. Fresh heartbeats can
|
|
44
44
|
* linger after a crash (or after heartbeat heal without a live pid-map), and
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assume.d.ts","sourceRoot":"","sources":["../../../src/lib/identities/assume.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;
|
|
1
|
+
{"version":3,"file":"assume.d.ts","sourceRoot":"","sources":["../../../src/lib/identities/assume.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAuBH,MAAM,MAAM,uBAAuB,GAC/B,eAAe,GACf,iBAAiB,GACjB,sBAAsB,GACtB,oBAAoB,GACpB,kBAAkB,GAClB,oBAAoB,GACpB,aAAa,GACb,mBAAmB,CAAC;AAExB,qBAAa,mBAAoB,SAAQ,KAAK;aAE1B,IAAI,EAAE,uBAAuB;gBAA7B,IAAI,EAAE,uBAAuB,EAC7C,OAAO,EAAE,MAAM;CAKlB;AAED,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,OAAO,GAAG,QAAQ,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,+DAA+D;IAC/D,qBAAqB,EAAE,MAAM,GAAG,IAAI,CAAC;CACtC;AAOD;+EAC+E;AAC/E,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EACZ,KAAK,SAAa,EAClB,mBAAmB,GAAE,WAAW,CAAC,MAAM,CAAa,GACnD,gBAAgB,GAAG,IAAI,CA6BzB;AAED;;;;;GAKG;AACH,wBAAgB,6BAA6B,CAC3C,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,gBAAgB,GACzB,OAAO,CAyCT;AAyED,gEAAgE;AAChE,wBAAgB,cAAc,CAC5B,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EACd,IAAI,CAAC,EAAE;IAAE,aAAa,CAAC,EAAE,OAAO,CAAA;CAAE,GACjC,oBAAoB,CAkHtB"}
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
*
|
|
4
4
|
* The operation is serialized because "is this name live?" and "claim it"
|
|
5
5
|
* must be one critical section. Authoritative state is written twice on
|
|
6
|
-
* purpose: `.name-history`
|
|
7
|
-
* `
|
|
6
|
+
* purpose: `.name-history` supplies display metadata, while the canonical
|
|
7
|
+
* `coord.identity_attested` event makes replay and derived readers converge.
|
|
8
8
|
*
|
|
9
9
|
* Local collision policy: a fresh heartbeat alone is not enough to block.
|
|
10
10
|
* If the namesake has no live pid-map process (crashed session, healed
|
|
@@ -13,12 +13,12 @@
|
|
|
13
13
|
* presence reports the name.
|
|
14
14
|
*/
|
|
15
15
|
import { randomUUID } from "node:crypto";
|
|
16
|
-
import { existsSync, mkdirSync,
|
|
16
|
+
import { existsSync, mkdirSync, readFileSync, statSync, unlinkSync, writeFileSync } from "node:fs";
|
|
17
17
|
import { join } from "node:path";
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
18
|
+
import { recordLiveIdentityChangeV3 } from "../../core/agents/live-authority-v3.js";
|
|
19
|
+
import { recordLiveSweepObservationV3 } from "../../core/agents/live-lifecycle-v3.js";
|
|
20
|
+
import { readLiveCoordinationRow, readLiveCoordinationRows, } from "../../core/agents/state/live-coordination-view.js";
|
|
21
|
+
import { resolveForkAncestry } from "../../core/agents/state/names.js";
|
|
22
22
|
import { instanceHasLivePid, removePidmapRowsForInstance } from "../../core/agents/state/pidmap.js";
|
|
23
23
|
import { coordFreshnessSeconds } from "../../core/config.js";
|
|
24
24
|
import { readRemoteMachines } from "../../core/presence/index.js";
|
|
@@ -40,25 +40,16 @@ function heartbeatIsFresh(hb, cutoffMs) {
|
|
|
40
40
|
}
|
|
41
41
|
/** Best-effort collision read across local heartbeats and cached remote
|
|
42
42
|
* presence. No network call occurs; absent presence degrades to local-only. */
|
|
43
|
-
export function findIdentityConflict(coordRoot, instanceId, name, nowMs = Date.now()) {
|
|
43
|
+
export function findIdentityConflict(coordRoot, instanceId, name, nowMs = Date.now(), excludedInstanceIds = new Set()) {
|
|
44
44
|
const wanted = name.toLowerCase();
|
|
45
45
|
const cutoffMs = nowMs - coordFreshnessSeconds(coordRoot) * 1000;
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
if (hb.instance_id === instanceId || !heartbeatIsFresh(hb, cutoffMs))
|
|
54
|
-
continue;
|
|
55
|
-
if ((hb.name ?? "").toLowerCase() === wanted) {
|
|
56
|
-
return { instance_id: hb.instance_id, name: hb.name ?? name, scope: "local" };
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
catch {
|
|
60
|
-
// Malformed heartbeats are handled by stale sweep, not this command.
|
|
61
|
-
}
|
|
46
|
+
for (const row of readLiveCoordinationRows(coordRoot)) {
|
|
47
|
+
if (row.instance_id === instanceId ||
|
|
48
|
+
excludedInstanceIds.has(row.instance_id) ||
|
|
49
|
+
!heartbeatIsFresh(row, cutoffMs))
|
|
50
|
+
continue;
|
|
51
|
+
if ((row.name ?? "").toLowerCase() === wanted) {
|
|
52
|
+
return { instance_id: row.instance_id, name: row.name ?? name, scope: "local" };
|
|
62
53
|
}
|
|
63
54
|
}
|
|
64
55
|
for (const remote of readRemoteMachines(coordRoot)) {
|
|
@@ -92,14 +83,21 @@ export function reclaimAbandonedLocalConflict(coordRoot, conflict) {
|
|
|
92
83
|
let adapter = "claude-code";
|
|
93
84
|
let sessionId = conflict.instance_id;
|
|
94
85
|
let ageSecs;
|
|
86
|
+
const liveRow = readLiveCoordinationRow(coordRoot, conflict.instance_id);
|
|
87
|
+
if (liveRow) {
|
|
88
|
+
adapter = adapterOf(liveRow.platform);
|
|
89
|
+
sessionId = liveRow.session_id || conflict.instance_id;
|
|
90
|
+
const ts = Date.parse(liveRow.last_heartbeat);
|
|
91
|
+
if (Number.isFinite(ts))
|
|
92
|
+
ageSecs = Math.max(0, Math.floor((Date.now() - ts) / 1000));
|
|
93
|
+
}
|
|
95
94
|
if (existsSync(hbPath)) {
|
|
96
95
|
try {
|
|
97
96
|
const hb = JSON.parse(readFileSync(hbPath, "utf8"));
|
|
97
|
+
// Native producer identity is private cache metadata, not ledger authority.
|
|
98
|
+
// It is required to join the exact producer state when recording the sweep.
|
|
98
99
|
adapter = adapterOf(hb.platform);
|
|
99
100
|
sessionId = hb.session_id || conflict.instance_id;
|
|
100
|
-
const ts = Date.parse(hb.last_heartbeat);
|
|
101
|
-
if (Number.isFinite(ts))
|
|
102
|
-
ageSecs = Math.max(0, Math.floor((Date.now() - ts) / 1000));
|
|
103
101
|
}
|
|
104
102
|
catch {
|
|
105
103
|
/* content unreadable — still reclaim the file */
|
|
@@ -112,24 +110,14 @@ export function reclaimAbandonedLocalConflict(coordRoot, conflict) {
|
|
|
112
110
|
}
|
|
113
111
|
}
|
|
114
112
|
removePidmapRowsForInstance(coordRoot, conflict.instance_id);
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
reason: "stale",
|
|
124
|
-
...(ageSecs !== undefined ? { age_secs: ageSecs } : {}),
|
|
125
|
-
reclaimed_by: "identity.assume",
|
|
126
|
-
},
|
|
127
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
128
|
-
});
|
|
129
|
-
}
|
|
130
|
-
catch {
|
|
131
|
-
/* telemetry only */
|
|
132
|
-
}
|
|
113
|
+
recordLiveSweepObservationV3({
|
|
114
|
+
coordRoot,
|
|
115
|
+
owner: conflict.instance_id,
|
|
116
|
+
nativeSessionId: sessionId,
|
|
117
|
+
adapter,
|
|
118
|
+
observation: "stale_heartbeat",
|
|
119
|
+
ageMs: Math.max(0, (ageSecs ?? 0) * 1_000),
|
|
120
|
+
});
|
|
133
121
|
return true;
|
|
134
122
|
}
|
|
135
123
|
function resolveTarget(coordRoot, input) {
|
|
@@ -197,9 +185,9 @@ function adapterOf(platform) {
|
|
|
197
185
|
export function assumeIdentity(coordRoot, instanceId, target, opts) {
|
|
198
186
|
const release = acquireLock(coordRoot);
|
|
199
187
|
try {
|
|
200
|
-
const hb =
|
|
188
|
+
const hb = readLiveCoordinationRow(coordRoot, instanceId);
|
|
201
189
|
if (!hb) {
|
|
202
|
-
throw new IdentityAssumeError("
|
|
190
|
+
throw new IdentityAssumeError("no_live_generation", `no authority-safe live V3 generation for instance '${instanceId}'`);
|
|
203
191
|
}
|
|
204
192
|
if (hb.kind && hb.kind !== "session") {
|
|
205
193
|
throw new IdentityAssumeError("not_session", `identity assumption is limited to main sessions (current kind: ${hb.kind})`);
|
|
@@ -222,7 +210,10 @@ export function assumeIdentity(coordRoot, instanceId, target, opts) {
|
|
|
222
210
|
let conflict = findIdentityConflict(coordRoot, instanceId, targetIdentity.name);
|
|
223
211
|
if (conflict && reclaimAbandonedLocalConflict(coordRoot, conflict)) {
|
|
224
212
|
reclaimedInstanceId = conflict.instance_id;
|
|
225
|
-
|
|
213
|
+
// The V3 sweep is intentionally provisional, so the generation remains
|
|
214
|
+
// replay-visible after its disposable cache is removed. Ignore that one
|
|
215
|
+
// reclaimed holder while still checking for any additional namesake.
|
|
216
|
+
conflict = findIdentityConflict(coordRoot, instanceId, targetIdentity.name, Date.now(), new Set([reclaimedInstanceId]));
|
|
226
217
|
}
|
|
227
218
|
if (conflict) {
|
|
228
219
|
const where = conflict.scope === "remote" ? ` on ${conflict.machine}` : "";
|
|
@@ -232,8 +223,7 @@ export function assumeIdentity(coordRoot, instanceId, target, opts) {
|
|
|
232
223
|
const created = !targetIdentity.identity;
|
|
233
224
|
const previousName = hb.name || null;
|
|
234
225
|
const previousAgentId = hb.agent_id || null;
|
|
235
|
-
const
|
|
236
|
-
const changed = history.changed || previousName !== identity.name || previousAgentId !== identity.agent_id;
|
|
226
|
+
const changed = previousName !== identity.name || previousAgentId !== identity.agent_id;
|
|
237
227
|
if (!changed) {
|
|
238
228
|
return {
|
|
239
229
|
changed: false,
|
|
@@ -248,25 +238,17 @@ export function assumeIdentity(coordRoot, instanceId, target, opts) {
|
|
|
248
238
|
reclaimed_instance_id: reclaimedInstanceId,
|
|
249
239
|
};
|
|
250
240
|
}
|
|
251
|
-
const emitted =
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
241
|
+
const emitted = recordLiveIdentityChangeV3({
|
|
242
|
+
coordRoot,
|
|
243
|
+
owner: instanceId,
|
|
244
|
+
nativeSessionId: hb.native_session_id ?? hb.session_id,
|
|
255
245
|
adapter: adapterOf(hb.platform),
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
...(previousAgentId ? { previous_agent_id: previousAgentId } : {}),
|
|
261
|
-
...(reclaimedInstanceId ? { reclaimed_instance_id: reclaimedInstanceId } : {}),
|
|
262
|
-
},
|
|
263
|
-
}, { coordRoot });
|
|
264
|
-
if (!emitted?.projected) {
|
|
265
|
-
throw new IdentityAssumeError("projection_failed", "the durable name binding was recorded but event projection failed; rerun the command to heal it");
|
|
266
|
-
}
|
|
267
|
-
const projected = readHeartbeat(coordRoot, instanceId);
|
|
246
|
+
name: identity.name,
|
|
247
|
+
identityId: identity.agent_id,
|
|
248
|
+
});
|
|
249
|
+
const projected = readLiveCoordinationRow(coordRoot, instanceId);
|
|
268
250
|
if (projected?.name !== identity.name || projected.agent_id !== identity.agent_id) {
|
|
269
|
-
throw new IdentityAssumeError("projection_failed", "
|
|
251
|
+
throw new IdentityAssumeError("projection_failed", "coord.identity_attested was emitted but the V3 projection did not converge; rerun the command");
|
|
270
252
|
}
|
|
271
253
|
return {
|
|
272
254
|
changed: true,
|
|
@@ -277,7 +259,9 @@ export function assumeIdentity(coordRoot, instanceId, target, opts) {
|
|
|
277
259
|
name: identity.name,
|
|
278
260
|
agent_id: identity.agent_id,
|
|
279
261
|
identity_created: created,
|
|
280
|
-
event_id: emitted.
|
|
262
|
+
event_id: emitted.state === "recorded" && emitted.result.state === "recorded"
|
|
263
|
+
? emitted.result.event.event_id
|
|
264
|
+
: null,
|
|
281
265
|
reclaimed_instance_id: reclaimedInstanceId,
|
|
282
266
|
};
|
|
283
267
|
}
|
|
@@ -14,8 +14,9 @@
|
|
|
14
14
|
* so a fresh consumer gets a CLAUDE.md whose managed region imports
|
|
15
15
|
* `@AGENTS.md`. A CLAUDE.md that already imports AGENTS.md or already carries
|
|
16
16
|
* the block (a host that generates CLAUDE.md from AGENTS.md) is left alone.
|
|
17
|
-
* -
|
|
18
|
-
*
|
|
17
|
+
* - `<adapter-skill-dir>/<skill>/SKILL.md` — fully-owned files, honoring
|
|
18
|
+
* `skills.exclude` in `.harnery/config.jsonc`. Claude Code uses
|
|
19
|
+
* `.claude/skills/`; Cursor and Codex use `.agents/skills/`.
|
|
19
20
|
*/
|
|
20
21
|
/** Read `skills.exclude` from `.harnery/config.jsonc` (absent/unparseable → none). */
|
|
21
22
|
export declare function readSkillsExclude(projectRoot: string): Set<string>;
|
|
@@ -30,7 +31,7 @@ export interface ApplyResult {
|
|
|
30
31
|
}
|
|
31
32
|
/**
|
|
32
33
|
* Inject / refresh the instructions block, the CLAUDE.md import shim (claude-code),
|
|
33
|
-
* and the shipped skills
|
|
34
|
+
* and the adapter-native shipped skills. Idempotent: a re-run on current content
|
|
34
35
|
* writes nothing. `dryRun` reports without touching the fs.
|
|
35
36
|
*/
|
|
36
37
|
export declare function applyInstructions(projectRoot: string, opts: ApplyOpts): ApplyResult;
|
|
@@ -51,7 +52,7 @@ export interface CheckResult {
|
|
|
51
52
|
}
|
|
52
53
|
/**
|
|
53
54
|
* Read-only drift report for `init --check`: the AGENTS.md block and each
|
|
54
|
-
* shipped skill
|
|
55
|
+
* shipped skill for the selected adapter. Fresh → exit 0; stale / missing / hand-edit
|
|
55
56
|
* → drift (exit 2); an unreadable file → error (exit 1). Mirrors the wiki-theme
|
|
56
57
|
* `--check-only` contract the first host wires into pre-commit.
|
|
57
58
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apply.d.ts","sourceRoot":"","sources":["../../../src/lib/instructions/apply.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"apply.d.ts","sourceRoot":"","sources":["../../../src/lib/instructions/apply.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAsDH,sFAAsF;AACtF,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAYlE;AAkBD,UAAU,SAAS;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,WAAW,CA+GnF;AAED,UAAU,UAAU;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,WAAW,CAkFrF;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC;IACpC,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACzC,WAAW,CAkDb"}
|