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
|
@@ -9,56 +9,20 @@
|
|
|
9
9
|
* half-written intermediate. Concurrent writers serialize via the rename
|
|
10
10
|
* (last write wins).
|
|
11
11
|
*
|
|
12
|
-
*
|
|
12
|
+
* Cache identity invariant: every action operates on the generation-bound row at
|
|
13
|
+
* `.harnery/active/<instance_id>.json`; the canonical V3 ledger remains authoritative.
|
|
13
14
|
* (the file IS the heartbeat). No mutations happen elsewhere.
|
|
14
15
|
*/
|
|
15
16
|
import { existsSync, mkdirSync, readdirSync, readFileSync, renameSync, unlinkSync, writeFileSync, } from "node:fs";
|
|
16
|
-
import { dirname, join } from "node:path";
|
|
17
|
-
import {
|
|
18
|
-
/** Inline adapter normalizer (mirrors canonical-emit.normalizeAdapter), kept
|
|
19
|
-
* local so the writer's only cross-module dep is the in-process emit(). */
|
|
20
|
-
function adapterOf(platform) {
|
|
21
|
-
if (platform === "cursor")
|
|
22
|
-
return "cursor";
|
|
23
|
-
if (platform === "codex")
|
|
24
|
-
return "codex";
|
|
25
|
-
return "claude-code";
|
|
26
|
-
}
|
|
27
|
-
/** Preserve the canonical adapter id in heartbeat state. Mirrors
|
|
28
|
-
* heartbeat-projector.adapterToPlatform so a healed heartbeat carries the same
|
|
29
|
-
* platform value projection would have written. */
|
|
30
|
-
function adapterToPlatform(adapter) {
|
|
31
|
-
if (adapter === "cursor")
|
|
32
|
-
return "cursor";
|
|
33
|
-
if (adapter === "codex")
|
|
34
|
-
return "codex";
|
|
35
|
-
return "claude-code";
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* Emit a canonical `health.*` event for an actual self-heal write. This is the
|
|
39
|
-
* single source of truth for heal telemetry across BOTH the live auto-heal
|
|
40
|
-
* (the pre-tool-use hook → agent-coord heal-heartbeat) and the manual `harn agents
|
|
41
|
-
* heal` path. Write-only by construction (callers only invoke it after a real
|
|
42
|
-
* write), so an already-correct heal records nothing.
|
|
43
|
-
* Best-effort: never throws into the heal path.
|
|
44
|
-
*/
|
|
45
|
-
function emitHealthHeal(coordRoot, type, instanceId, hb, data) {
|
|
46
|
-
try {
|
|
47
|
-
emit(coordRoot, {
|
|
48
|
-
event_type: type,
|
|
49
|
-
instance_id: instanceId,
|
|
50
|
-
session_id: hb?.session_id ?? instanceId,
|
|
51
|
-
adapter: adapterOf(hb?.platform),
|
|
52
|
-
source: "agent-coord",
|
|
53
|
-
data,
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
catch {
|
|
57
|
-
/* telemetry only, never break a heal */
|
|
58
|
-
}
|
|
59
|
-
}
|
|
17
|
+
import { basename, dirname, join } from "node:path";
|
|
18
|
+
import { assertSafeInstanceId, resolveContainedFile } from "../coord-client.js";
|
|
60
19
|
function heartbeatPath(coordRoot, instanceId) {
|
|
61
|
-
|
|
20
|
+
assertSafeInstanceId(instanceId);
|
|
21
|
+
const safeInstanceId = basename(instanceId);
|
|
22
|
+
if (safeInstanceId !== instanceId) {
|
|
23
|
+
throw new Error("instance_id must be a direct-child coordination basename");
|
|
24
|
+
}
|
|
25
|
+
return resolveContainedFile(join(coordRoot, ".harnery", "active"), `${safeInstanceId}.json`);
|
|
62
26
|
}
|
|
63
27
|
function nowIsoSeconds() {
|
|
64
28
|
return new Date().toISOString().replace(/\.\d{3}Z$/, "Z");
|
|
@@ -80,6 +44,16 @@ export function readHeartbeat(coordRoot, instanceId) {
|
|
|
80
44
|
return null;
|
|
81
45
|
}
|
|
82
46
|
}
|
|
47
|
+
/** Persist operator-facing lifecycle prose in the generation-bound cache only. */
|
|
48
|
+
export function setLifecycleCache(coordRoot, instanceId, state, reason, suggestedSessionName) {
|
|
49
|
+
return mutate(coordRoot, instanceId, (heartbeat) => ({
|
|
50
|
+
...heartbeat,
|
|
51
|
+
task_state: state,
|
|
52
|
+
task_state_updated_at: nowIsoSeconds(),
|
|
53
|
+
task_state_reason: state === "active" ? undefined : reason,
|
|
54
|
+
...(suggestedSessionName ? { suggested_session_name: suggestedSessionName } : {}),
|
|
55
|
+
}));
|
|
56
|
+
}
|
|
83
57
|
function mutate(coordRoot, instanceId, fn) {
|
|
84
58
|
const hb = readHeartbeat(coordRoot, instanceId);
|
|
85
59
|
if (!hb)
|
|
@@ -104,10 +78,21 @@ export function setTask(coordRoot, instanceId, task) {
|
|
|
104
78
|
...hb,
|
|
105
79
|
task: cleared ? undefined : task,
|
|
106
80
|
task_updated_at: nowIsoSeconds(),
|
|
81
|
+
...(hb.schema_version === 2 ? { v3_task_state: cleared ? "cleared" : "set" } : {}),
|
|
107
82
|
...(built ? { suggested_session_name: built.suggestedName } : {}),
|
|
108
83
|
};
|
|
109
84
|
});
|
|
110
85
|
}
|
|
86
|
+
/** Update the disposable identity cache after a canonical V3 attestation. */
|
|
87
|
+
export function setIdentityCache(coordRoot, instanceId, name, agentId) {
|
|
88
|
+
const heartbeat = readHeartbeat(coordRoot, instanceId);
|
|
89
|
+
if (!heartbeat)
|
|
90
|
+
return null;
|
|
91
|
+
heartbeat.name = name;
|
|
92
|
+
heartbeat.agent_id = agentId;
|
|
93
|
+
atomicWrite(heartbeatPath(coordRoot, instanceId), JSON.stringify(heartbeat, null, 2));
|
|
94
|
+
return heartbeat;
|
|
95
|
+
}
|
|
111
96
|
/**
|
|
112
97
|
* Build the copy-pasteable session name from the coord identity + the agent's
|
|
113
98
|
* description parts. Pure (no coord-state reads) so it's unit-testable; collapses
|
|
@@ -120,6 +105,16 @@ export function buildSuggestedName(agentName, descriptionParts) {
|
|
|
120
105
|
const name = agentName?.trim() || "unknown";
|
|
121
106
|
return { suggestedName: `Agent ${name} - ${description}`, description };
|
|
122
107
|
}
|
|
108
|
+
/** Build the sole lifecycle-driven title: the terminal done projection. */
|
|
109
|
+
export function buildLifecycleSuggestedName(currentSessionName, state) {
|
|
110
|
+
if (state !== "done" || !currentSessionName?.trim())
|
|
111
|
+
return null;
|
|
112
|
+
const baseName = currentSessionName
|
|
113
|
+
.trim()
|
|
114
|
+
.replace(/^\[DONE\]\s+/, "")
|
|
115
|
+
.replace(/^\[BLOCKED\]\s*-\s*/, "");
|
|
116
|
+
return baseName ? `[DONE] ${baseName}` : null;
|
|
117
|
+
}
|
|
123
118
|
/** Stamp the sighting once the suggested name has been observed in assistant
|
|
124
119
|
* reply text; later turns skip the transcript scan. Records WHICH name was seen,
|
|
125
120
|
* because the skip is only valid for that one: if a later set-task mints a
|
|
@@ -132,13 +127,6 @@ export function stampSessionNameSeen(coordRoot, instanceId, name) {
|
|
|
132
127
|
...(name ? { session_name_seen_for: name } : {}),
|
|
133
128
|
}));
|
|
134
129
|
}
|
|
135
|
-
export function setTurnSummary(coordRoot, instanceId, summary) {
|
|
136
|
-
return mutate(coordRoot, instanceId, (hb) => ({
|
|
137
|
-
...hb,
|
|
138
|
-
turn_summary: summary,
|
|
139
|
-
turn_summary_updated_at: nowIsoSeconds(),
|
|
140
|
-
}));
|
|
141
|
-
}
|
|
142
130
|
export function releaseClaim(coordRoot, instanceId, path) {
|
|
143
131
|
// files_touched can hold either absolute-under-coordRoot or canonical
|
|
144
132
|
// monorepo-relative entries; normalize both sides so release matches
|
|
@@ -151,13 +139,22 @@ export function releaseClaim(coordRoot, instanceId, path) {
|
|
|
151
139
|
files_touched: (hb.files_touched ?? []).filter((p) => norm(p) !== target),
|
|
152
140
|
}));
|
|
153
141
|
}
|
|
142
|
+
/** Materialize one V3 write-claim authority transition into the heartbeat cache. */
|
|
143
|
+
export function acquireClaim(coordRoot, instanceId, path) {
|
|
144
|
+
const norm = (p) => p.startsWith(`${coordRoot}/`) ? p.slice(coordRoot.length + 1) : p;
|
|
145
|
+
const target = norm(path);
|
|
146
|
+
return mutate(coordRoot, instanceId, (hb) => ({
|
|
147
|
+
...hb,
|
|
148
|
+
files_touched: [...new Set([...(hb.files_touched ?? []).map(norm), target])].sort(),
|
|
149
|
+
}));
|
|
150
|
+
}
|
|
154
151
|
/**
|
|
155
152
|
* Session-group-wide unclaim. Walks every heartbeat sharing `groupId`
|
|
156
153
|
* (parent's session_id == group_id;
|
|
157
154
|
* subagents inherit it) and removes the path from each one's files_touched.
|
|
158
155
|
* Idempotent: heartbeats that don't hold the path are untouched. Returns the
|
|
159
156
|
* heartbeats that actually dropped the path so the caller can emit the
|
|
160
|
-
* durable `
|
|
157
|
+
* durable `coord.claim_changed` release events; a file-only prune is silently reverted by
|
|
161
158
|
* the next projector replay.
|
|
162
159
|
*
|
|
163
160
|
* Tool payloads and release calls can supply either absolute-under-coordRoot or
|
|
@@ -168,7 +165,7 @@ export function releaseClaim(coordRoot, instanceId, path) {
|
|
|
168
165
|
* subagent-held claim that doesn't live on the parent's heartbeat still gets
|
|
169
166
|
* pruned because the walk covers the whole group.
|
|
170
167
|
*/
|
|
171
|
-
export function
|
|
168
|
+
export function findGroupClaims(coordRoot, groupId, path) {
|
|
172
169
|
const hits = [];
|
|
173
170
|
if (!groupId || !path)
|
|
174
171
|
return hits;
|
|
@@ -192,27 +189,17 @@ export function groupUnclaim(coordRoot, groupId, path) {
|
|
|
192
189
|
if (peerSession !== groupId)
|
|
193
190
|
continue;
|
|
194
191
|
const files = body.files_touched ?? [];
|
|
195
|
-
|
|
196
|
-
if (next.length === files.length)
|
|
192
|
+
if (!files.some((candidate) => norm(candidate) === target))
|
|
197
193
|
continue;
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
hits.push({
|
|
204
|
-
instance_id: body.instance_id ?? f.replace(/\.json$/, ""),
|
|
205
|
-
session_id: body.session_id,
|
|
206
|
-
platform: body.platform,
|
|
207
|
-
});
|
|
208
|
-
}
|
|
209
|
-
catch {
|
|
210
|
-
/* silent */
|
|
211
|
-
}
|
|
194
|
+
hits.push({
|
|
195
|
+
instance_id: body.instance_id ?? f.replace(/\.json$/, ""),
|
|
196
|
+
session_id: body.session_id,
|
|
197
|
+
platform: body.platform,
|
|
198
|
+
});
|
|
212
199
|
}
|
|
213
200
|
return hits;
|
|
214
201
|
}
|
|
215
|
-
export function
|
|
202
|
+
export function clearCoordinationCache(coordRoot, instanceId) {
|
|
216
203
|
const path = heartbeatPath(coordRoot, instanceId);
|
|
217
204
|
if (!existsSync(path))
|
|
218
205
|
return false;
|
|
@@ -244,131 +231,4 @@ export function healPidmap(coordRoot, instanceId, pid) {
|
|
|
244
231
|
if (existingOwner === instanceId)
|
|
245
232
|
return;
|
|
246
233
|
atomicWrite(pmPath, `${instanceId}\t${platform}`);
|
|
247
|
-
emitHealthHeal(coordRoot, "health.pidmap_heal", instanceId, hb, {
|
|
248
|
-
reason: existingOwner ? "stale" : "missing",
|
|
249
|
-
pid,
|
|
250
|
-
kind: "pidmap",
|
|
251
|
-
...(existingOwner ? { prior: existingOwner.slice(0, 8) } : {}),
|
|
252
|
-
});
|
|
253
|
-
}
|
|
254
|
-
export function healHeartbeat(coordRoot, instanceId, sessionId, model, adapter, opts) {
|
|
255
|
-
const path = heartbeatPath(coordRoot, instanceId);
|
|
256
|
-
if (existsSync(path)) {
|
|
257
|
-
// Already alive, return it.
|
|
258
|
-
return readHeartbeat(coordRoot, instanceId);
|
|
259
|
-
}
|
|
260
|
-
const now = nowIsoSeconds();
|
|
261
|
-
// Recover name + kind from .name-history if present (idempotent across
|
|
262
|
-
// sweeps: same instance_id always gets the same name).
|
|
263
|
-
let name = "";
|
|
264
|
-
let kind = "session";
|
|
265
|
-
let agentId = "";
|
|
266
|
-
try {
|
|
267
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
268
|
-
const names = require("./names.ts");
|
|
269
|
-
const resolved = names.resolveName(coordRoot, instanceId, sessionId);
|
|
270
|
-
if (resolved) {
|
|
271
|
-
name = resolved.name;
|
|
272
|
-
kind = resolved.kind;
|
|
273
|
-
// An explicitly assumed session carries its durable persona UUID in
|
|
274
|
-
// name-history. Native subagents continue to use instance_id.
|
|
275
|
-
agentId = resolved.agent_id ?? (resolved.kind === "subagent" ? instanceId : "");
|
|
276
|
-
}
|
|
277
|
-
else if (!sessionId || sessionId === instanceId) {
|
|
278
|
-
// A main session with NO history at all never fired session.start —
|
|
279
|
-
// the CC fork flow (SessionStart fires under the parent's id before
|
|
280
|
-
// the fork id is minted), or a partially-wired adapter. Mint its pool
|
|
281
|
-
// name here instead of leaving a nameless heartbeat, and stamp the
|
|
282
|
-
// detected fork lineage while we're at it. A sessionId that differs
|
|
283
|
-
// from instanceId is left alone: that shape is a subagent whose parent
|
|
284
|
-
// is also unknown, and guessing "session" would be wrong.
|
|
285
|
-
name = names.assignName(coordRoot, instanceId, "session", opts?.forkedFrom ? { forkedFrom: opts.forkedFrom } : undefined);
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
catch {
|
|
289
|
-
/* names module unavailable, fall back to empty */
|
|
290
|
-
}
|
|
291
|
-
const hb = {
|
|
292
|
-
schema_version: 1,
|
|
293
|
-
instance_id: instanceId,
|
|
294
|
-
session_id: sessionId ?? instanceId,
|
|
295
|
-
name,
|
|
296
|
-
kind,
|
|
297
|
-
agent_id: agentId,
|
|
298
|
-
model: model ?? "",
|
|
299
|
-
started_at: now,
|
|
300
|
-
last_heartbeat: now,
|
|
301
|
-
files_touched: [],
|
|
302
|
-
// Default to claude-code only when the caller can't tell us the adapter
|
|
303
|
-
// (e.g. manual `harn agents heal`). The live tool.pre_use heal threads the
|
|
304
|
-
// detected adapter so a pruned Cursor/Codex heartbeat is recreated with
|
|
305
|
-
// the correct platform instead of being mislabeled claude-code.
|
|
306
|
-
platform: adapterToPlatform(adapter),
|
|
307
|
-
};
|
|
308
|
-
atomicWrite(path, JSON.stringify(hb, null, 2));
|
|
309
|
-
// Write-only telemetry: only the actual-recreate branch reaches here (the
|
|
310
|
-
// already-alive case returned above), so this records exactly the heals that
|
|
311
|
-
// happened. Recorded fork lineage rides the event too, so derived readers
|
|
312
|
-
// rebuilding from the ledger converge with .name-history.
|
|
313
|
-
emitHealthHeal(coordRoot, "health.heartbeat_heal", instanceId, hb, {
|
|
314
|
-
reason: "missing",
|
|
315
|
-
kind: "heartbeat",
|
|
316
|
-
...(opts?.forkedFrom ? { forked_from: opts.forkedFrom } : {}),
|
|
317
|
-
});
|
|
318
|
-
return hb;
|
|
319
|
-
}
|
|
320
|
-
/**
|
|
321
|
-
* Register a workflow child in the coordination layer from the ENGINE side.
|
|
322
|
-
*
|
|
323
|
-
* Previously a spawned child was visible only if its adapter fired Harnery's
|
|
324
|
-
* hooks, which made coordination visibility a property of the vendor CLI
|
|
325
|
-
* rather than of the engine. Headless `codex exec` fires no hooks, so codex
|
|
326
|
-
* children never appeared in `harn agents list` and rendered as "no live
|
|
327
|
-
* session" on the run page while actively working — for the entire length of
|
|
328
|
-
* a multi-minute stage.
|
|
329
|
-
*
|
|
330
|
-
* The engine already knows every fact a heartbeat needs at spawn time, so it
|
|
331
|
-
* writes one itself. Hook-firing adapters keep enriching the same file
|
|
332
|
-
* (last_tool, files_touched); non-hook adapters at least become visible and
|
|
333
|
-
* attributable. Pair with `killHeartbeat` when the child ends.
|
|
334
|
-
*
|
|
335
|
-
* Idempotent: re-registering refreshes in place and preserves `started_at`
|
|
336
|
-
* and any claims a hook already recorded.
|
|
337
|
-
*/
|
|
338
|
-
export function registerWorkflowChild(coordRoot, opts) {
|
|
339
|
-
const now = nowIsoSeconds();
|
|
340
|
-
const prior = readHeartbeat(coordRoot, opts.instanceId);
|
|
341
|
-
const hb = {
|
|
342
|
-
...(prior ?? {}),
|
|
343
|
-
schema_version: 1,
|
|
344
|
-
instance_id: opts.instanceId,
|
|
345
|
-
// The reader keys children by session_id and skips any heartbeat missing
|
|
346
|
-
// one, so it must always be set even before the adapter mints a real id.
|
|
347
|
-
session_id: prior?.session_id ?? opts.sessionId ?? opts.instanceId,
|
|
348
|
-
name: opts.label || opts.agentId,
|
|
349
|
-
kind: "workflow-child",
|
|
350
|
-
agent_id: opts.agentId,
|
|
351
|
-
model: opts.model ?? prior?.model ?? "",
|
|
352
|
-
platform: adapterToPlatform(opts.adapter),
|
|
353
|
-
started_at: prior?.started_at ?? now,
|
|
354
|
-
last_heartbeat: now,
|
|
355
|
-
files_touched: prior?.files_touched ?? [],
|
|
356
|
-
task: opts.label ?? "",
|
|
357
|
-
workflow_run_id: opts.runId,
|
|
358
|
-
workflow_agent_id: opts.agentId,
|
|
359
|
-
};
|
|
360
|
-
atomicWrite(heartbeatPath(coordRoot, opts.instanceId), JSON.stringify(hb, null, 2));
|
|
361
|
-
return hb;
|
|
362
|
-
}
|
|
363
|
-
/**
|
|
364
|
-
* Stamp the heartbeat with the most-recent tool name + target. Written from
|
|
365
|
-
* the post-tool-use hook.
|
|
366
|
-
*/
|
|
367
|
-
export function stampToolActivity(coordRoot, instanceId, toolName, target) {
|
|
368
|
-
return mutate(coordRoot, instanceId, (hb) => ({
|
|
369
|
-
...hb,
|
|
370
|
-
last_tool: toolName,
|
|
371
|
-
last_tool_target: target,
|
|
372
|
-
last_tool_at: nowIsoSeconds(),
|
|
373
|
-
}));
|
|
374
234
|
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { Adapter } from "../../adapter.js";
|
|
2
|
+
import { type Heartbeat } from "./heartbeat-writer.js";
|
|
3
|
+
/**
|
|
4
|
+
* Heartbeat files are disposable V3 caches. These bindings prevent a stale
|
|
5
|
+
* row from a prior generation from being mistaken for current authority.
|
|
6
|
+
*/
|
|
7
|
+
export interface V3HeartbeatMaterialization extends Heartbeat {
|
|
8
|
+
schema_version: 2;
|
|
9
|
+
v3_instance_id: `inst_${string}`;
|
|
10
|
+
v3_generation_id: `gen_${string}`;
|
|
11
|
+
v3_projection_event_id: string;
|
|
12
|
+
v3_task_state: "set" | "cleared";
|
|
13
|
+
}
|
|
14
|
+
/** Read the live coordination rows through the hard-cut ledger route. */
|
|
15
|
+
export declare function readLiveCoordinationRows(coordRoot: string): V3HeartbeatMaterialization[];
|
|
16
|
+
/** Read one current row from the authority-safe V3 projection. */
|
|
17
|
+
export declare function readLiveCoordinationRow(coordRoot: string, nativeInstanceId: string): V3HeartbeatMaterialization | null;
|
|
18
|
+
/**
|
|
19
|
+
* Resolve the adapter from the current authority-safe V3 generation. A live
|
|
20
|
+
* V3 generation is stronger evidence than a missing or stale heartbeat, so
|
|
21
|
+
* callers must never substitute another adapter when this function succeeds.
|
|
22
|
+
*/
|
|
23
|
+
export declare function liveCoordinationAdapterV3(coordRoot: string, nativeInstanceId: string): Adapter | null;
|
|
24
|
+
/**
|
|
25
|
+
* Ensure the current V3 generation has a mutation target. The resulting file
|
|
26
|
+
* is explicitly generation-bound and disposable: V3 remains the source of
|
|
27
|
+
* truth, while the cache gives the crash-safe authority outbox an atomic local
|
|
28
|
+
* state to reconcile.
|
|
29
|
+
*/
|
|
30
|
+
export declare function ensureLiveCoordinationHeartbeat(coordRoot: string, nativeInstanceId: string, nativeSessionId: string, _adapter: Adapter, model?: string): Heartbeat | null;
|
|
31
|
+
//# sourceMappingURL=live-coordination-view.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"live-coordination-view.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/state/live-coordination-view.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAYhD,OAAO,EAAE,KAAK,SAAS,EAAiB,MAAM,uBAAuB,CAAC;AAGtE;;;GAGG;AACH,MAAM,WAAW,0BAA2B,SAAQ,SAAS;IAC3D,cAAc,EAAE,CAAC,CAAC;IAClB,cAAc,EAAE,QAAQ,MAAM,EAAE,CAAC;IACjC,gBAAgB,EAAE,OAAO,MAAM,EAAE,CAAC;IAClC,sBAAsB,EAAE,MAAM,CAAC;IAC/B,aAAa,EAAE,KAAK,GAAG,SAAS,CAAC;CAClC;AAED,yEAAyE;AACzE,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,GAAG,0BAA0B,EAAE,CA2BxF;AAED,kEAAkE;AAClE,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,MAAM,GACvB,0BAA0B,GAAG,IAAI,CAuBnC;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,MAAM,GACvB,OAAO,GAAG,IAAI,CAWhB;AAED;;;;;GAKG;AACH,wBAAgB,+BAA+B,CAC7C,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,MAAM,EACxB,eAAe,EAAE,MAAM,EACvB,QAAQ,EAAE,OAAO,EACjB,KAAK,CAAC,EAAE,MAAM,GACb,SAAS,GAAG,IAAI,CAgClB"}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readdirSync, readFileSync, renameSync, writeFileSync, } from "node:fs";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { readCoordinationViewV3, requireAuthoritySafeCoordinationViewV3, } from "../../events/v3/coordination-view.js";
|
|
4
|
+
import { liveInstanceIdV3, nativeInstanceIdV3, resolveLiveEventLedgerRouteV3, } from "../../events/v3/live-routing.js";
|
|
5
|
+
import { readHeartbeat } from "./heartbeat-writer.js";
|
|
6
|
+
import { resolveName } from "./names.js";
|
|
7
|
+
/** Read the live coordination rows through the hard-cut ledger route. */
|
|
8
|
+
export function readLiveCoordinationRows(coordRoot) {
|
|
9
|
+
const route = resolveLiveEventLedgerRouteV3(coordRoot);
|
|
10
|
+
if (route.state === "blocked")
|
|
11
|
+
return [];
|
|
12
|
+
let view;
|
|
13
|
+
try {
|
|
14
|
+
view = requireAuthoritySafeCoordinationViewV3(readCoordinationViewV3(coordRoot));
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
return [];
|
|
18
|
+
}
|
|
19
|
+
const caches = readV3Caches(coordRoot);
|
|
20
|
+
const byGeneration = new Map(Object.values(view.instances).map((generation) => [generation.generation_id, generation]));
|
|
21
|
+
return Object.values(view.instances)
|
|
22
|
+
.filter((generation) => generation.authority_eligible)
|
|
23
|
+
.map((generation) => {
|
|
24
|
+
const parent = generation.parent_generation_id
|
|
25
|
+
? byGeneration.get(generation.parent_generation_id)
|
|
26
|
+
: undefined;
|
|
27
|
+
return projectHeartbeatV3(coordRoot, generation, matchingCache(caches, generation), undefined, parent);
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
/** Read one current row from the authority-safe V3 projection. */
|
|
31
|
+
export function readLiveCoordinationRow(coordRoot, nativeInstanceId) {
|
|
32
|
+
const route = resolveLiveEventLedgerRouteV3(coordRoot);
|
|
33
|
+
if (route.state === "blocked")
|
|
34
|
+
return null;
|
|
35
|
+
try {
|
|
36
|
+
const view = requireAuthoritySafeCoordinationViewV3(readCoordinationViewV3(coordRoot));
|
|
37
|
+
const generation = view.instances[liveInstanceIdV3(nativeInstanceId)];
|
|
38
|
+
if (!generation?.authority_eligible)
|
|
39
|
+
return null;
|
|
40
|
+
const cache = readHeartbeat(coordRoot, nativeInstanceId);
|
|
41
|
+
const parent = generation.parent_generation_id
|
|
42
|
+
? Object.values(view.instances).find((candidate) => candidate.generation_id === generation.parent_generation_id)
|
|
43
|
+
: undefined;
|
|
44
|
+
return projectHeartbeatV3(coordRoot, generation, isCurrentCache(cache, generation) ? cache : undefined, nativeInstanceId, parent);
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Resolve the adapter from the current authority-safe V3 generation. A live
|
|
52
|
+
* V3 generation is stronger evidence than a missing or stale heartbeat, so
|
|
53
|
+
* callers must never substitute another adapter when this function succeeds.
|
|
54
|
+
*/
|
|
55
|
+
export function liveCoordinationAdapterV3(coordRoot, nativeInstanceId) {
|
|
56
|
+
const route = resolveLiveEventLedgerRouteV3(coordRoot);
|
|
57
|
+
if (route.state === "blocked")
|
|
58
|
+
throw new Error(`event_v3_coordination_view:${route.reason}`);
|
|
59
|
+
const view = requireAuthoritySafeCoordinationViewV3(readCoordinationViewV3(coordRoot));
|
|
60
|
+
const generation = view.instances[liveInstanceIdV3(nativeInstanceId)];
|
|
61
|
+
if (!generation?.authority_eligible)
|
|
62
|
+
return null;
|
|
63
|
+
const adapter = observedAdapter(generation);
|
|
64
|
+
if (!isAdapter(adapter)) {
|
|
65
|
+
throw new Error("event_v3_coordination_view:adapter_not_observed");
|
|
66
|
+
}
|
|
67
|
+
return adapter;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Ensure the current V3 generation has a mutation target. The resulting file
|
|
71
|
+
* is explicitly generation-bound and disposable: V3 remains the source of
|
|
72
|
+
* truth, while the cache gives the crash-safe authority outbox an atomic local
|
|
73
|
+
* state to reconcile.
|
|
74
|
+
*/
|
|
75
|
+
export function ensureLiveCoordinationHeartbeat(coordRoot, nativeInstanceId, nativeSessionId, _adapter, model) {
|
|
76
|
+
const route = resolveLiveEventLedgerRouteV3(coordRoot);
|
|
77
|
+
if (route.state === "blocked")
|
|
78
|
+
throw new Error(`event_v3_coordination_view:${route.reason}`);
|
|
79
|
+
const view = requireAuthoritySafeCoordinationViewV3(readCoordinationViewV3(coordRoot));
|
|
80
|
+
const generation = view.instances[liveInstanceIdV3(nativeInstanceId)];
|
|
81
|
+
if (!generation?.authority_eligible)
|
|
82
|
+
return null;
|
|
83
|
+
const generationAdapter = observedAdapter(generation);
|
|
84
|
+
if (!isAdapter(generationAdapter)) {
|
|
85
|
+
throw new Error("event_v3_coordination_view:adapter_not_observed");
|
|
86
|
+
}
|
|
87
|
+
const current = readHeartbeat(coordRoot, nativeInstanceId);
|
|
88
|
+
if (isCurrentCache(current, generation) && current.platform === generationAdapter)
|
|
89
|
+
return current;
|
|
90
|
+
const resolved = resolveName(coordRoot, nativeInstanceId, nativeSessionId);
|
|
91
|
+
const projected = projectHeartbeatV3(coordRoot, generation, undefined, nativeInstanceId);
|
|
92
|
+
const materialized = {
|
|
93
|
+
...projected,
|
|
94
|
+
schema_version: 2,
|
|
95
|
+
instance_id: nativeInstanceId,
|
|
96
|
+
session_id: nativeSessionId,
|
|
97
|
+
name: resolved?.name ?? "",
|
|
98
|
+
kind: resolved?.kind ?? projected.kind,
|
|
99
|
+
agent_id: resolved?.agent_id ?? (resolved?.kind === "subagent" ? nativeInstanceId : ""),
|
|
100
|
+
model: projected.model ?? model ?? "",
|
|
101
|
+
platform: generationAdapter,
|
|
102
|
+
v3_instance_id: generation.instance_id,
|
|
103
|
+
v3_generation_id: generation.generation_id,
|
|
104
|
+
v3_projection_event_id: generation.last_event_id,
|
|
105
|
+
v3_task_state: generation.task_state === "set" ? "set" : "cleared",
|
|
106
|
+
};
|
|
107
|
+
writeHeartbeatCache(coordRoot, nativeInstanceId, materialized);
|
|
108
|
+
return materialized;
|
|
109
|
+
}
|
|
110
|
+
function readCacheRows(coordRoot) {
|
|
111
|
+
const dir = join(coordRoot, ".harnery", "active");
|
|
112
|
+
if (!existsSync(dir))
|
|
113
|
+
return [];
|
|
114
|
+
const rows = [];
|
|
115
|
+
for (const file of readdirSync(dir)) {
|
|
116
|
+
if (!file.endsWith(".json"))
|
|
117
|
+
continue;
|
|
118
|
+
try {
|
|
119
|
+
rows.push(JSON.parse(readFileSync(join(dir, file), "utf8")));
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
// A partial heartbeat is ignored exactly as before.
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return rows;
|
|
126
|
+
}
|
|
127
|
+
function readV3Caches(coordRoot) {
|
|
128
|
+
return readCacheRows(coordRoot).filter((row) => row.schema_version === 2 && typeof row.v3_generation_id === "string");
|
|
129
|
+
}
|
|
130
|
+
function matchingCache(caches, generation) {
|
|
131
|
+
return caches.find((cache) => isCurrentCache(cache, generation));
|
|
132
|
+
}
|
|
133
|
+
function isCurrentCache(cache, generation) {
|
|
134
|
+
return (cache?.schema_version === 2 &&
|
|
135
|
+
cache.v3_instance_id === generation.instance_id &&
|
|
136
|
+
cache.v3_generation_id === generation.generation_id);
|
|
137
|
+
}
|
|
138
|
+
function projectHeartbeatV3(coordRoot, generation, cache, nativeInstanceId, parent) {
|
|
139
|
+
const adapter = observedAdapter(generation) ?? cache?.platform ?? "unknown";
|
|
140
|
+
const model = observedModel(generation) ?? cache?.model ?? "";
|
|
141
|
+
const instanceId = nativeInstanceId ?? cache?.instance_id ?? nativeInstanceIdV3(generation.instance_id);
|
|
142
|
+
const durableIdentity = resolveName(coordRoot, instanceId, cache?.session_id ?? generation.session_id);
|
|
143
|
+
const taskIsSet = generation.task_state === "set";
|
|
144
|
+
const lifecycle = isLifecycleState(generation.lifecycle_state)
|
|
145
|
+
? generation.lifecycle_state
|
|
146
|
+
: "active";
|
|
147
|
+
return {
|
|
148
|
+
schema_version: 2,
|
|
149
|
+
instance_id: instanceId,
|
|
150
|
+
session_id: parent?.session_id ?? generation.session_id,
|
|
151
|
+
native_session_id: cache?.session_id,
|
|
152
|
+
name: cache?.name || durableIdentity?.name,
|
|
153
|
+
kind: cache?.kind ??
|
|
154
|
+
durableIdentity?.kind ??
|
|
155
|
+
(generation.parent_generation_id || generation.delegation_id
|
|
156
|
+
? "subagent"
|
|
157
|
+
: generation.workflow_id
|
|
158
|
+
? "workflow-child"
|
|
159
|
+
: "session"),
|
|
160
|
+
agent_id: cache?.agent_id ?? durableIdentity?.agent_id,
|
|
161
|
+
model,
|
|
162
|
+
platform: adapter,
|
|
163
|
+
started_at: generation.started_at,
|
|
164
|
+
last_heartbeat: generation.last_observed_at,
|
|
165
|
+
files_touched: generation.files_touched,
|
|
166
|
+
...(taskIsSet && cache?.task ? { task: cache.task } : {}),
|
|
167
|
+
task_updated_at: taskIsSet ? cache?.task_updated_at : null,
|
|
168
|
+
activity: generation.activity === "terminal" ? "idle" : generation.activity,
|
|
169
|
+
activity_updated_at: generation.last_observed_at,
|
|
170
|
+
activity_source: "event-v3-coordination-view",
|
|
171
|
+
task_state: lifecycle,
|
|
172
|
+
task_state_updated_at: generation.lifecycle_state_updated_at,
|
|
173
|
+
task_state_reason: lifecycle === "blocked" ? cache?.task_state_reason : undefined,
|
|
174
|
+
suggested_session_name: cache?.suggested_session_name,
|
|
175
|
+
session_name_seen_at: cache?.session_name_seen_at,
|
|
176
|
+
session_name_seen_for: cache?.session_name_seen_for,
|
|
177
|
+
workflow_run_id: generation.run_id,
|
|
178
|
+
workflow_agent_id: generation.workflow_agent_id,
|
|
179
|
+
parent_instance_id: parent ? nativeInstanceIdV3(parent.instance_id) : undefined,
|
|
180
|
+
v3_instance_id: generation.instance_id,
|
|
181
|
+
v3_generation_id: generation.generation_id,
|
|
182
|
+
v3_projection_event_id: generation.last_event_id,
|
|
183
|
+
v3_task_state: taskIsSet ? "set" : "cleared",
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
function observedAdapter(generation) {
|
|
187
|
+
const observation = generation.runtime_attestation.adapter;
|
|
188
|
+
return observation.state === "observed" ? observation.value.id : undefined;
|
|
189
|
+
}
|
|
190
|
+
function isAdapter(value) {
|
|
191
|
+
return value === "claude-code" || value === "cursor" || value === "codex";
|
|
192
|
+
}
|
|
193
|
+
function observedModel(generation) {
|
|
194
|
+
const observation = generation.runtime_attestation.model;
|
|
195
|
+
return observation.state === "observed" ? observation.value.id : undefined;
|
|
196
|
+
}
|
|
197
|
+
function isLifecycleState(value) {
|
|
198
|
+
return value === "active" || value === "blocked" || value === "done";
|
|
199
|
+
}
|
|
200
|
+
function writeHeartbeatCache(coordRoot, instanceId, heartbeat) {
|
|
201
|
+
if (!/^[a-zA-Z0-9._-]{1,128}$/.test(instanceId)) {
|
|
202
|
+
throw new Error("instance_id is unsafe for heartbeat materialization");
|
|
203
|
+
}
|
|
204
|
+
const path = join(coordRoot, ".harnery", "active", `${instanceId}.json`);
|
|
205
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
206
|
+
const temporary = `${path}.tmp.${process.pid}`;
|
|
207
|
+
writeFileSync(temporary, JSON.stringify(heartbeat, null, 2), "utf8");
|
|
208
|
+
renameSync(temporary, path);
|
|
209
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/** What the agent is doing now. `unknown` is evidence-safe, not an error. */
|
|
2
|
+
export type AgentActivity = "unknown" | "working" | "needs_input" | "idle";
|
|
3
|
+
/** Whether the declared task remains open. Activity never changes this axis. */
|
|
4
|
+
export type TaskState = "active" | "blocked" | "done";
|
|
5
|
+
/** Raw fields stored in the disposable V3 coordination cache and rebuilt from canonical events. */
|
|
6
|
+
export interface SessionStateFields {
|
|
7
|
+
activity?: AgentActivity;
|
|
8
|
+
activity_updated_at?: string;
|
|
9
|
+
activity_source?: string;
|
|
10
|
+
task_state?: TaskState;
|
|
11
|
+
task_state_updated_at?: string;
|
|
12
|
+
task_state_reason?: string;
|
|
13
|
+
}
|
|
14
|
+
/** Reader-facing state with compatibility defaults applied. */
|
|
15
|
+
export interface SessionState extends SessionStateFields {
|
|
16
|
+
activity: AgentActivity;
|
|
17
|
+
task_state: TaskState;
|
|
18
|
+
}
|
|
19
|
+
export interface SessionStateSelector {
|
|
20
|
+
instance_id?: string;
|
|
21
|
+
session_id?: string;
|
|
22
|
+
}
|
|
23
|
+
export interface SessionStateEvidenceEvent {
|
|
24
|
+
event_type: EventTypeV3;
|
|
25
|
+
ts: string;
|
|
26
|
+
payload?: Record<string, unknown>;
|
|
27
|
+
instance_id?: string;
|
|
28
|
+
session_id?: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Apply one canonical event to the two independent state axes.
|
|
32
|
+
*
|
|
33
|
+
* The table is deliberately evidence-only. Output chunks, post-tool events,
|
|
34
|
+
* narration, coordination commands, and elapsed time cannot clear an observed
|
|
35
|
+
* input wait. A command start only counts as progress when the session was
|
|
36
|
+
* already inside an open turn (`working` or `needs_input`).
|
|
37
|
+
*/
|
|
38
|
+
export declare function applySessionStateEvent(current: Readonly<SessionStateFields>, event: SessionStateEvidenceEvent): SessionStateFields;
|
|
39
|
+
/**
|
|
40
|
+
* Rebuild both axes from canonical events after a heartbeat has disappeared.
|
|
41
|
+
* Events may be the whole ledger or an already-filtered session slice.
|
|
42
|
+
*/
|
|
43
|
+
export declare function foldSessionState(events: readonly SessionStateEvidenceEvent[], selector?: SessionStateSelector): SessionState;
|
|
44
|
+
import type { EventTypeV3 } from "../../events/v3/contract.js";
|
|
45
|
+
//# sourceMappingURL=session-state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-state.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/state/session-state.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,SAAS,GAAG,aAAa,GAAG,MAAM,CAAC;AAE3E,gFAAgF;AAChF,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,CAAC;AAEtD,mGAAmG;AACnG,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,+DAA+D;AAC/D,MAAM,WAAW,YAAa,SAAQ,kBAAkB;IACtD,QAAQ,EAAE,aAAa,CAAC;IACxB,UAAU,EAAE,SAAS,CAAC;CACvB;AAED,MAAM,WAAW,oBAAoB;IACnC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,yBAAyB;IACxC,UAAU,EAAE,WAAW,CAAC;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAQD;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,QAAQ,CAAC,kBAAkB,CAAC,EACrC,KAAK,EAAE,yBAAyB,GAC/B,kBAAkB,CAwCpB;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,SAAS,yBAAyB,EAAE,EAC5C,QAAQ,GAAE,oBAAyB,GAClC,YAAY,CAcd;AA2BD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC"}
|