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,140 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import type { Adapter } from "../adapter.ts";
|
|
3
|
+
import { buildEventV3 } from "../events/v3/builder.ts";
|
|
4
|
+
import { normalizeNativeIdV3 } from "../events/v3/canonical.ts";
|
|
5
|
+
import type { EventV3 } from "../events/v3/contract.ts";
|
|
6
|
+
import { readEventV3ControlState } from "../events/v3/control.ts";
|
|
7
|
+
import { fingerprintContextV3 } from "../events/v3/fingerprint-keys.ts";
|
|
8
|
+
import {
|
|
9
|
+
liveInstanceIdV3,
|
|
10
|
+
livePlatformV3,
|
|
11
|
+
resolveLiveEventLedgerRouteV3,
|
|
12
|
+
} from "../events/v3/live-routing.ts";
|
|
13
|
+
import { readHookProducerStateV3 } from "../events/v3/producers/recorder.ts";
|
|
14
|
+
import { writeEventV3 } from "../events/v3/writer.ts";
|
|
15
|
+
import { LiveCoordinationAuthorityV3Error } from "./live-authority-v3.ts";
|
|
16
|
+
import { liveCoordinationAdapterV3 } from "./state/live-coordination-view.ts";
|
|
17
|
+
|
|
18
|
+
export type LiveLifecycleObservationV3Result = { state: "recorded"; event: EventV3 };
|
|
19
|
+
|
|
20
|
+
interface LiveLifecycleObservationBaseV3 {
|
|
21
|
+
coordRoot: string;
|
|
22
|
+
owner: string;
|
|
23
|
+
nativeSessionId: string;
|
|
24
|
+
adapter: Adapter;
|
|
25
|
+
observedAt?: string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function recordLiveSweepObservationV3(
|
|
29
|
+
input: LiveLifecycleObservationBaseV3 & {
|
|
30
|
+
observation: "stale_heartbeat" | "killed" | "unparseable_heartbeat" | "missing_timestamp";
|
|
31
|
+
ageMs: number;
|
|
32
|
+
},
|
|
33
|
+
): LiveLifecycleObservationV3Result {
|
|
34
|
+
return recordObservation(input, "lifecycle.sweep_observed", {
|
|
35
|
+
subject_instance_id: liveInstanceIdV3(input.owner),
|
|
36
|
+
observation: input.observation,
|
|
37
|
+
provisional: true,
|
|
38
|
+
age_ms: Math.max(0, Math.floor(input.ageMs)),
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function recordLiveResumeObservationV3(
|
|
43
|
+
input: LiveLifecycleObservationBaseV3,
|
|
44
|
+
): LiveLifecycleObservationV3Result {
|
|
45
|
+
const normalized = withAttestedAdapter(input);
|
|
46
|
+
const hook = requireHookState(normalized);
|
|
47
|
+
return recordObservation(normalized, "session.resumed", {
|
|
48
|
+
prior_generation_id: hook.generation_id,
|
|
49
|
+
continuity: "native",
|
|
50
|
+
evidence_reference: "heartbeat_recreated",
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function recordObservation<T extends "lifecycle.sweep_observed" | "session.resumed">(
|
|
55
|
+
input: LiveLifecycleObservationBaseV3,
|
|
56
|
+
eventType: T,
|
|
57
|
+
payload: T extends "lifecycle.sweep_observed"
|
|
58
|
+
? {
|
|
59
|
+
subject_instance_id: `inst_${string}`;
|
|
60
|
+
observation: string;
|
|
61
|
+
provisional: true;
|
|
62
|
+
age_ms: number;
|
|
63
|
+
}
|
|
64
|
+
: {
|
|
65
|
+
prior_generation_id: `gen_${string}`;
|
|
66
|
+
continuity: "native";
|
|
67
|
+
evidence_reference: string;
|
|
68
|
+
},
|
|
69
|
+
): LiveLifecycleObservationV3Result {
|
|
70
|
+
const route = resolveLiveEventLedgerRouteV3(input.coordRoot);
|
|
71
|
+
if (route.state === "blocked") throw new LiveCoordinationAuthorityV3Error(route.reason);
|
|
72
|
+
input = withAttestedAdapter(input);
|
|
73
|
+
const control = readEventV3ControlState(input.coordRoot);
|
|
74
|
+
if (control.state !== route.mode) {
|
|
75
|
+
throw new LiveCoordinationAuthorityV3Error("control_state_changed");
|
|
76
|
+
}
|
|
77
|
+
const hook = requireHookState(input);
|
|
78
|
+
if (!hook.last_event_id) throw new LiveCoordinationAuthorityV3Error("generation_has_no_event");
|
|
79
|
+
const rootId = control.genesis.event.scope.root_id as `root_${string}`;
|
|
80
|
+
const context = fingerprintContextV3(
|
|
81
|
+
input.coordRoot,
|
|
82
|
+
rootId,
|
|
83
|
+
hook.generation_id,
|
|
84
|
+
control.genesis.profile.privacy_key_epoch,
|
|
85
|
+
);
|
|
86
|
+
const nativeObservationId = `${eventType}\0${input.owner}\0${input.observedAt ?? "now"}\0${JSON.stringify(payload)}`;
|
|
87
|
+
const common = {
|
|
88
|
+
producer: {
|
|
89
|
+
producer_id: "prd_agent-coord-lifecycle" as const,
|
|
90
|
+
boot_id: `boot_${randomUUID()}` as const,
|
|
91
|
+
sequence: 1,
|
|
92
|
+
component: "agent-coord" as const,
|
|
93
|
+
build_id: route.build_id,
|
|
94
|
+
platform: livePlatformV3(),
|
|
95
|
+
},
|
|
96
|
+
scope: {
|
|
97
|
+
root_id: rootId,
|
|
98
|
+
instance_id: hook.instance_id,
|
|
99
|
+
session_id: hook.session_id,
|
|
100
|
+
generation_id: hook.generation_id,
|
|
101
|
+
},
|
|
102
|
+
attestation_id: hook.attestation_id,
|
|
103
|
+
links: { caused_by: [hook.last_event_id] },
|
|
104
|
+
provenance: {
|
|
105
|
+
source_event: `agent-coord.${eventType}`,
|
|
106
|
+
attestation: "derived" as const,
|
|
107
|
+
confidence: "exact" as const,
|
|
108
|
+
source_record_id: normalizeNativeIdV3(
|
|
109
|
+
context,
|
|
110
|
+
`agent-coord.${eventType}`,
|
|
111
|
+
nativeObservationId,
|
|
112
|
+
),
|
|
113
|
+
attribution: {
|
|
114
|
+
method: "heartbeat_match" as const,
|
|
115
|
+
state: "verified" as const,
|
|
116
|
+
observer_instance_id: hook.instance_id,
|
|
117
|
+
subject_instance_id: hook.instance_id,
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
observed_at: input.observedAt,
|
|
121
|
+
monotonic_ns: process.hrtime.bigint().toString(),
|
|
122
|
+
};
|
|
123
|
+
const event = buildEventV3(eventType, { ...common, payload } as never) as EventV3;
|
|
124
|
+
writeEventV3(input.coordRoot, event);
|
|
125
|
+
return { state: "recorded", event };
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function withAttestedAdapter<T extends LiveLifecycleObservationBaseV3>(input: T): T {
|
|
129
|
+
const adapter = liveCoordinationAdapterV3(input.coordRoot, input.owner);
|
|
130
|
+
if (!adapter) return input;
|
|
131
|
+
return { ...input, adapter };
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function requireHookState(input: LiveLifecycleObservationBaseV3) {
|
|
135
|
+
const hook = readHookProducerStateV3(input.coordRoot, input.adapter, input.nativeSessionId);
|
|
136
|
+
if (!hook || hook.instance_id !== liveInstanceIdV3(input.owner)) {
|
|
137
|
+
throw new LiveCoordinationAuthorityV3Error("hook_generation_not_joinable");
|
|
138
|
+
}
|
|
139
|
+
return hook;
|
|
140
|
+
}
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import type { Adapter } from "../adapter.ts";
|
|
3
|
+
import { buildEventV3 } from "../events/v3/builder.ts";
|
|
4
|
+
import {
|
|
5
|
+
canonicalJsonV3,
|
|
6
|
+
fingerprintV3,
|
|
7
|
+
normalizeNativeIdV3,
|
|
8
|
+
sha256V3,
|
|
9
|
+
} from "../events/v3/canonical.ts";
|
|
10
|
+
import type { EventTypeV3, EventV3 } from "../events/v3/contract.ts";
|
|
11
|
+
import { readEventV3ControlState } from "../events/v3/control.ts";
|
|
12
|
+
import { readCoordinationViewV3 } from "../events/v3/coordination-view.ts";
|
|
13
|
+
import { fingerprintContextV3 } from "../events/v3/fingerprint-keys.ts";
|
|
14
|
+
import type { LiveCoordinationObservationV3 } from "../events/v3/live-observation.ts";
|
|
15
|
+
import {
|
|
16
|
+
liveInstanceIdV3,
|
|
17
|
+
livePlatformV3,
|
|
18
|
+
resolveLiveEventLedgerRouteV3,
|
|
19
|
+
} from "../events/v3/live-routing.ts";
|
|
20
|
+
import { readHookProducerStateV3 } from "../events/v3/producers/recorder.ts";
|
|
21
|
+
import { writeEventV3 } from "../events/v3/writer.ts";
|
|
22
|
+
import { LiveCoordinationAuthorityV3Error } from "./live-authority-v3.ts";
|
|
23
|
+
import { liveCoordinationAdapterV3 } from "./state/live-coordination-view.ts";
|
|
24
|
+
|
|
25
|
+
export type { LiveCoordinationObservationV3 } from "../events/v3/live-observation.ts";
|
|
26
|
+
|
|
27
|
+
export interface RecordLiveCoordinationObservationV3Input {
|
|
28
|
+
coordRoot: string;
|
|
29
|
+
owner: string;
|
|
30
|
+
nativeSessionId: string;
|
|
31
|
+
adapter: Adapter;
|
|
32
|
+
observation: LiveCoordinationObservationV3;
|
|
33
|
+
observationId?: string;
|
|
34
|
+
observedAt?: string;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface RecordLiveCoordinationObservationV3Result {
|
|
38
|
+
state: "recorded";
|
|
39
|
+
event: EventV3;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Append a non-authority coordination observation against one attested live
|
|
44
|
+
* generation. Raw message and record bodies are used only to derive keyed
|
|
45
|
+
* fingerprints or content digests; they never enter the ledger payload.
|
|
46
|
+
*/
|
|
47
|
+
export function recordLiveCoordinationObservationV3(
|
|
48
|
+
input: RecordLiveCoordinationObservationV3Input,
|
|
49
|
+
): RecordLiveCoordinationObservationV3Result {
|
|
50
|
+
const route = resolveLiveEventLedgerRouteV3(input.coordRoot);
|
|
51
|
+
if (route.state === "blocked") throw new LiveCoordinationAuthorityV3Error(route.reason);
|
|
52
|
+
const control = readEventV3ControlState(input.coordRoot);
|
|
53
|
+
if (control.state !== route.mode) {
|
|
54
|
+
throw new LiveCoordinationAuthorityV3Error("control_state_changed");
|
|
55
|
+
}
|
|
56
|
+
const adapter = liveCoordinationAdapterV3(input.coordRoot, input.owner) ?? input.adapter;
|
|
57
|
+
const hook = readHookProducerStateV3(input.coordRoot, adapter, input.nativeSessionId);
|
|
58
|
+
if (
|
|
59
|
+
!hook ||
|
|
60
|
+
hook.terminal ||
|
|
61
|
+
!hook.last_event_id ||
|
|
62
|
+
hook.instance_id !== liveInstanceIdV3(input.owner)
|
|
63
|
+
) {
|
|
64
|
+
throw new LiveCoordinationAuthorityV3Error("hook_generation_not_joinable");
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const rootId = control.genesis.event.scope.root_id as `root_${string}`;
|
|
68
|
+
const fingerprintContext = fingerprintContextV3(
|
|
69
|
+
input.coordRoot,
|
|
70
|
+
rootId,
|
|
71
|
+
hook.generation_id,
|
|
72
|
+
control.genesis.profile.privacy_key_epoch,
|
|
73
|
+
);
|
|
74
|
+
const observationId = input.observationId ?? `${input.observation.event_type}-${randomUUID()}`;
|
|
75
|
+
const subject =
|
|
76
|
+
"subject" in input.observation && input.observation.subject
|
|
77
|
+
? liveInstanceIdV3(input.observation.subject)
|
|
78
|
+
: hook.instance_id;
|
|
79
|
+
const common = {
|
|
80
|
+
producer: {
|
|
81
|
+
producer_id: "prd_agent-coord-observation" as const,
|
|
82
|
+
boot_id: `boot_${randomUUID()}` as const,
|
|
83
|
+
sequence: 1,
|
|
84
|
+
component: "agent-coord" as const,
|
|
85
|
+
build_id: route.build_id,
|
|
86
|
+
platform: livePlatformV3(),
|
|
87
|
+
},
|
|
88
|
+
scope: {
|
|
89
|
+
root_id: rootId,
|
|
90
|
+
instance_id: hook.instance_id,
|
|
91
|
+
session_id: hook.session_id,
|
|
92
|
+
generation_id: hook.generation_id,
|
|
93
|
+
},
|
|
94
|
+
attestation_id: hook.attestation_id,
|
|
95
|
+
links: { caused_by: [hook.last_event_id] },
|
|
96
|
+
provenance: {
|
|
97
|
+
source_event: `agent-coord.${input.observation.event_type}`,
|
|
98
|
+
attestation: "derived" as const,
|
|
99
|
+
confidence: "exact" as const,
|
|
100
|
+
source_record_id: normalizeNativeIdV3(
|
|
101
|
+
fingerprintContext,
|
|
102
|
+
"agent-coord.observation",
|
|
103
|
+
observationId,
|
|
104
|
+
),
|
|
105
|
+
attribution: {
|
|
106
|
+
method: "session_env" as const,
|
|
107
|
+
state: "verified" as const,
|
|
108
|
+
observer_instance_id: hook.instance_id,
|
|
109
|
+
subject_instance_id: subject,
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
observed_at: input.observedAt,
|
|
113
|
+
monotonic_ns: process.hrtime.bigint().toString(),
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
const observation = input.observation;
|
|
117
|
+
let event: EventV3;
|
|
118
|
+
switch (observation.event_type) {
|
|
119
|
+
case "coord.status_observed":
|
|
120
|
+
event = buildEventV3("coord.status_observed", {
|
|
121
|
+
...common,
|
|
122
|
+
payload: {
|
|
123
|
+
observer_instance_id: hook.instance_id,
|
|
124
|
+
subject_instance_id: subject,
|
|
125
|
+
status: safeToken(observation.status),
|
|
126
|
+
},
|
|
127
|
+
});
|
|
128
|
+
break;
|
|
129
|
+
case "coord.presence_changed": {
|
|
130
|
+
// The ledger projection, not the independently versioned presence file,
|
|
131
|
+
// owns the canonical prior state. Omitting an unknown first prior keeps
|
|
132
|
+
// the transition honest and avoids manufacturing a history.
|
|
133
|
+
const projectedPrior = readCoordinationViewV3(input.coordRoot).instances[hook.instance_id]
|
|
134
|
+
?.presence_state;
|
|
135
|
+
event = buildEventV3("coord.presence_changed", {
|
|
136
|
+
...common,
|
|
137
|
+
payload: {
|
|
138
|
+
actor_instance_id: hook.instance_id,
|
|
139
|
+
subject_instance_id: hook.instance_id,
|
|
140
|
+
...(projectedPrior ? { prior_state: safeToken(projectedPrior) } : {}),
|
|
141
|
+
new_state: safeToken(observation.new_state),
|
|
142
|
+
reason: reasonCode(observation.reason),
|
|
143
|
+
authority: {},
|
|
144
|
+
},
|
|
145
|
+
});
|
|
146
|
+
break;
|
|
147
|
+
}
|
|
148
|
+
case "coord.message_observed":
|
|
149
|
+
event = buildEventV3("coord.message_observed", {
|
|
150
|
+
...common,
|
|
151
|
+
payload: {
|
|
152
|
+
message_id: safeToken(observation.message_id ?? `msg_${randomUUID()}`),
|
|
153
|
+
direction: observation.direction,
|
|
154
|
+
peer_instance_id: subject,
|
|
155
|
+
body_length: Buffer.byteLength(observation.body, "utf8"),
|
|
156
|
+
body_fingerprint: fingerprintV3(
|
|
157
|
+
fingerprintContext,
|
|
158
|
+
"coord.message.body",
|
|
159
|
+
observation.body,
|
|
160
|
+
"generation",
|
|
161
|
+
),
|
|
162
|
+
},
|
|
163
|
+
});
|
|
164
|
+
break;
|
|
165
|
+
case "council.state_changed":
|
|
166
|
+
event = buildEventV3("council.state_changed", {
|
|
167
|
+
...common,
|
|
168
|
+
payload: {
|
|
169
|
+
council_id: safeToken(observation.council_id),
|
|
170
|
+
...(observation.prior_state ? { prior_state: safeToken(observation.prior_state) } : {}),
|
|
171
|
+
new_state: safeToken(observation.new_state),
|
|
172
|
+
record_digest: sha256V3(canonicalJsonV3(observation.record)),
|
|
173
|
+
},
|
|
174
|
+
});
|
|
175
|
+
break;
|
|
176
|
+
case "decision.state_changed": {
|
|
177
|
+
const projectedDecisionPrior = readCoordinationViewV3(input.coordRoot).decisions[
|
|
178
|
+
observation.decision_id
|
|
179
|
+
];
|
|
180
|
+
event = buildEventV3("decision.state_changed", {
|
|
181
|
+
...common,
|
|
182
|
+
payload: {
|
|
183
|
+
decision_id: safeToken(observation.decision_id),
|
|
184
|
+
...(projectedDecisionPrior ? { prior_state: safeToken(projectedDecisionPrior) } : {}),
|
|
185
|
+
new_state: safeToken(observation.new_state),
|
|
186
|
+
record_digest: sha256V3(canonicalJsonV3(observation.record)),
|
|
187
|
+
authority: { record_id: safeToken(observation.decision_id) },
|
|
188
|
+
},
|
|
189
|
+
});
|
|
190
|
+
break;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
writeEventV3(input.coordRoot, event);
|
|
194
|
+
return { state: "recorded", event };
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
function safeToken(value: string): string {
|
|
198
|
+
const normalized = value.normalize("NFC");
|
|
199
|
+
if (!/^[a-zA-Z0-9][a-zA-Z0-9._:/+-]{0,127}$/.test(normalized)) {
|
|
200
|
+
throw new LiveCoordinationAuthorityV3Error(`invalid_safe_token:${value}`);
|
|
201
|
+
}
|
|
202
|
+
return normalized;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
function reasonCode(value: string): string {
|
|
206
|
+
const normalized = value.normalize("NFC");
|
|
207
|
+
if (!/^[a-z0-9][a-z0-9._-]{0,79}$/.test(normalized)) {
|
|
208
|
+
throw new LiveCoordinationAuthorityV3Error(`invalid_reason_code:${value}`);
|
|
209
|
+
}
|
|
210
|
+
return normalized;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
export type LiveCoordinationObservationEventTypeV3 = Extract<
|
|
214
|
+
EventTypeV3,
|
|
215
|
+
LiveCoordinationObservationV3["event_type"]
|
|
216
|
+
>;
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* council-pending hash-dedup, the cross-adapter first-session naming nudge,
|
|
4
4
|
* the Cursor/Codex set-task staleness nudge, and the Codex status-footer
|
|
5
5
|
* reminder.
|
|
6
|
-
* agent-hook's
|
|
6
|
+
* agent-hook's turn.started post-emit handler calls this
|
|
7
7
|
* and forwards the result as the adapter-shaped additionalContext payload.
|
|
8
8
|
*
|
|
9
9
|
* Four subsections combined into one additionalContext payload:
|
|
@@ -12,9 +12,9 @@
|
|
|
12
12
|
* + sorted(files_touched) + platform, sorted by instance_id).
|
|
13
13
|
* 2. Council pending: pending open-council IDs hashed; re-emits when the
|
|
14
14
|
* ID set changes.
|
|
15
|
-
* 3. Focus nudge. Until the session has
|
|
16
|
-
*
|
|
17
|
-
*
|
|
15
|
+
* 3. Focus nudge. Until the session has displayed its current suggested
|
|
16
|
+
* name, tells every adapter on every prompt to send the exact fenced block
|
|
17
|
+
* before prose or another tool call.
|
|
18
18
|
* Cursor/Codex additionally get the existing unset/stale-task reminder
|
|
19
19
|
* because their Stop hooks do not enforce task declarations as reliably
|
|
20
20
|
* as Claude Code's.
|
|
@@ -45,6 +45,12 @@ import { join } from "node:path";
|
|
|
45
45
|
import { coordEnv } from "../../../lib/env.ts";
|
|
46
46
|
import { endOfTurnStatusCommand, resolveBinName } from "../../config.ts";
|
|
47
47
|
import { type RemoteMachine, readRemoteMachines } from "../../presence/index.ts";
|
|
48
|
+
import { sessionNameDisplayBlock, sessionNameDisplayPending } from "../session-name-display.ts";
|
|
49
|
+
import {
|
|
50
|
+
readLiveCoordinationRow,
|
|
51
|
+
readLiveCoordinationRows,
|
|
52
|
+
} from "../state/live-coordination-view.ts";
|
|
53
|
+
import type { AgentActivity, TaskState } from "../state/session-state.ts";
|
|
48
54
|
import { formatPendingCouncils } from "./session-context.ts";
|
|
49
55
|
|
|
50
56
|
interface HeartbeatRow {
|
|
@@ -54,14 +60,15 @@ interface HeartbeatRow {
|
|
|
54
60
|
session_id?: string;
|
|
55
61
|
started_at?: string;
|
|
56
62
|
last_heartbeat?: string;
|
|
57
|
-
last_tool?: string;
|
|
58
|
-
last_tool_target?: string;
|
|
59
63
|
files_touched?: string[];
|
|
60
64
|
platform?: string;
|
|
61
65
|
task?: string;
|
|
62
|
-
|
|
66
|
+
activity?: AgentActivity;
|
|
67
|
+
task_state?: TaskState;
|
|
68
|
+
task_state_reason?: string;
|
|
69
|
+
task_updated_at?: string | null;
|
|
63
70
|
suggested_session_name?: string;
|
|
64
|
-
|
|
71
|
+
session_name_seen_for?: string;
|
|
65
72
|
workflow_run_id?: string;
|
|
66
73
|
}
|
|
67
74
|
|
|
@@ -79,6 +86,12 @@ export interface PromptContextOpts {
|
|
|
79
86
|
/** When true, append the non-deduplicated Codex status-footer reminder.
|
|
80
87
|
* The caller enables this only for human-facing Codex sessions. */
|
|
81
88
|
statusFooterNudge?: boolean;
|
|
89
|
+
/** Adapter id whose Stop hook ENFORCES the end-of-turn ritual (task_set +
|
|
90
|
+
* status check). When set, append a fresh per-prompt reminder of that
|
|
91
|
+
* contract so the model satisfies it before ending the turn instead of
|
|
92
|
+
* being bounced into a retry. Not hash-deduped, same rationale as the
|
|
93
|
+
* status footer. */
|
|
94
|
+
turnRitualNudge?: string;
|
|
82
95
|
}
|
|
83
96
|
|
|
84
97
|
/**
|
|
@@ -98,6 +111,7 @@ export function renderPromptContext(opts: PromptContextOpts): string {
|
|
|
98
111
|
sessionNameNudge,
|
|
99
112
|
taskNudge,
|
|
100
113
|
statusFooterNudge,
|
|
114
|
+
turnRitualNudge,
|
|
101
115
|
} = opts;
|
|
102
116
|
const sections: string[] = [];
|
|
103
117
|
|
|
@@ -130,11 +144,43 @@ export function renderPromptContext(opts: PromptContextOpts): string {
|
|
|
130
144
|
if (statusMsg) sections.push(statusMsg);
|
|
131
145
|
}
|
|
132
146
|
|
|
147
|
+
// 5. Adapters whose Stop hook ENFORCES the turn ritual get a fresh reminder
|
|
148
|
+
// on every prompt. Reminding before the reply is drafted is far cheaper than
|
|
149
|
+
// the bounce-and-retry the Stop hook otherwise forces: enforcement-only
|
|
150
|
+
// compliance was measured missing on a double-digit share of turns. Not
|
|
151
|
+
// hash-deduped for the same reason as the Codex footer.
|
|
152
|
+
if (turnRitualNudge) {
|
|
153
|
+
const ritualMsg = renderTurnRitualReminder(coordRoot, instanceId, turnRitualNudge);
|
|
154
|
+
if (ritualMsg) sections.push(ritualMsg);
|
|
155
|
+
}
|
|
156
|
+
|
|
133
157
|
return sections.join("\n\n");
|
|
134
158
|
}
|
|
135
159
|
|
|
160
|
+
function renderTurnRitualReminder(
|
|
161
|
+
coordRoot: string,
|
|
162
|
+
selfInstanceId: string,
|
|
163
|
+
adapter: string,
|
|
164
|
+
): string {
|
|
165
|
+
const hb = readLiveCoordinationRow(coordRoot, selfInstanceId);
|
|
166
|
+
if (!hb || hb.kind === "subagent" || hb.kind === "transient" || hb.workflow_run_id) return "";
|
|
167
|
+
|
|
168
|
+
const bin = resolveBinName(coordRoot);
|
|
169
|
+
const statusCommand = endOfTurnStatusCommand(coordRoot);
|
|
170
|
+
// Claude Code renders the status box only if the reply carries it; Cursor
|
|
171
|
+
// shows the box inline on its own, so it is never asked for a second copy.
|
|
172
|
+
const paste =
|
|
173
|
+
adapter === "claude-code"
|
|
174
|
+
? " and paste its output verbatim in a fenced code block at the end of your reply"
|
|
175
|
+
: "";
|
|
176
|
+
return (
|
|
177
|
+
`Turn ritual (Stop-enforced): on any turn that uses tools, run \`${bin} agents set-task "<short focus>"\` at some point during the turn (required every turn, even when the focus is unchanged; pass an empty string when there is no meaningful focus), then make \`${statusCommand}\` your final tool call${paste}. ` +
|
|
178
|
+
"A turn that ends without these is bounced by the Stop hook and costs a retry."
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
|
|
136
182
|
function renderStatusFooterReminder(coordRoot: string, selfInstanceId: string): string {
|
|
137
|
-
const hb =
|
|
183
|
+
const hb = readLiveCoordinationRow(coordRoot, selfInstanceId);
|
|
138
184
|
if (!hb || hb.kind === "subagent" || hb.kind === "transient" || hb.workflow_run_id) return "";
|
|
139
185
|
|
|
140
186
|
const statusCommand = endOfTurnStatusCommand(coordRoot);
|
|
@@ -156,14 +202,8 @@ function computeFocusNudgeIfChanged(
|
|
|
156
202
|
selfInstanceId: string,
|
|
157
203
|
opts: { sessionNameNudge: boolean; taskNudge: boolean },
|
|
158
204
|
): string {
|
|
159
|
-
const
|
|
160
|
-
if (!
|
|
161
|
-
let hb: HeartbeatRow;
|
|
162
|
-
try {
|
|
163
|
-
hb = JSON.parse(readFileSync(hbPath, "utf8"));
|
|
164
|
-
} catch {
|
|
165
|
-
return "";
|
|
166
|
-
}
|
|
205
|
+
const hb = readLiveCoordinationRow(coordRoot, selfInstanceId);
|
|
206
|
+
if (!hb) return "";
|
|
167
207
|
|
|
168
208
|
const hashFile = join(coordRoot, ".harnery", `.last-task-nudge-hash.${selfInstanceId}`);
|
|
169
209
|
// Subagents and workflow children have no human-owned session/tab to rename.
|
|
@@ -179,15 +219,17 @@ function computeFocusNudgeIfChanged(
|
|
|
179
219
|
let message = "";
|
|
180
220
|
let nudgeKind = "";
|
|
181
221
|
|
|
182
|
-
|
|
222
|
+
const pendingSessionName = sessionNameDisplayPending(hb);
|
|
223
|
+
if (opts.sessionNameNudge && (!hb.suggested_session_name || pendingSessionName)) {
|
|
183
224
|
// Keyed on "a name was ever produced", not task_updated_at: a bare clear
|
|
184
225
|
// as the first declaration must not end the naming window.
|
|
185
226
|
needsNudge = true;
|
|
186
227
|
nudgeKind = "session-name";
|
|
187
|
-
message =
|
|
188
|
-
`This session
|
|
189
|
-
|
|
190
|
-
|
|
228
|
+
message = pendingSessionName
|
|
229
|
+
? `This session name is still pending display. Before any prose or another tool call, send this exact block as your next assistant text:\n\n${sessionNameDisplayBlock(pendingSessionName)}`
|
|
230
|
+
: `This session has no name yet: run \`${bin} agents set-task "<2-5 word session topic>"\` as your first tool call. ` +
|
|
231
|
+
"When it returns `first_of_session: true`, send its `suggested_session_name` as the exact fenced block requested by the PostToolUse instruction before any prose or another tool call. " +
|
|
232
|
+
"Then continue with the task; that `set-task` also satisfies this turn's focus declaration.";
|
|
191
233
|
} else if (opts.taskNudge && !taskValue) {
|
|
192
234
|
needsNudge = true;
|
|
193
235
|
nudgeKind = "task-unset";
|
|
@@ -237,25 +279,21 @@ function computePeerTableIfChanged(
|
|
|
237
279
|
selfInstanceId: string,
|
|
238
280
|
selfSessionIdFallback: string,
|
|
239
281
|
): string {
|
|
240
|
-
const activeDir = join(coordRoot, ".harnery", "active");
|
|
241
|
-
if (!existsSync(activeDir)) return "";
|
|
242
|
-
|
|
243
282
|
// Read self heartbeat for session_id (group key); fall back to the caller's hint.
|
|
244
283
|
let mySessionId = selfSessionIdFallback;
|
|
245
|
-
const
|
|
284
|
+
const rows = readLiveCoordinationRows(coordRoot);
|
|
285
|
+
const selfHb = readLiveCoordinationRow(coordRoot, selfInstanceId);
|
|
246
286
|
if (selfHb?.session_id) mySessionId = selfHb.session_id;
|
|
247
287
|
if (!mySessionId) return "";
|
|
248
288
|
|
|
249
|
-
// Collect
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
if (!hb?.instance_id || hb.instance_id === selfInstanceId) continue;
|
|
255
|
-
peers.push(hb);
|
|
256
|
-
}
|
|
289
|
+
// Collect peers from the selected ledger route. Under V3 this is the
|
|
290
|
+
// canonical projection, never the legacy active directory.
|
|
291
|
+
const peers: HeartbeatRow[] = rows.filter(
|
|
292
|
+
(heartbeat) => heartbeat.instance_id && heartbeat.instance_id !== selfInstanceId,
|
|
293
|
+
);
|
|
257
294
|
// Cross-machine presence (ADR 0016): sessions on other machines, from the
|
|
258
|
-
// locally-fetched presence refs. Advisory
|
|
295
|
+
// locally-fetched presence refs. Advisory only; remote presence never grants
|
|
296
|
+
// claim authority.
|
|
259
297
|
const remote = readRemoteMachinesSafe(coordRoot);
|
|
260
298
|
if (peers.length === 0 && remote.length === 0) return "";
|
|
261
299
|
|
|
@@ -269,6 +307,9 @@ function computePeerTableIfChanged(
|
|
|
269
307
|
started_at: p.started_at ?? null,
|
|
270
308
|
files_touched: Array.from(p.files_touched ?? []).sort(),
|
|
271
309
|
platform: p.platform ?? null,
|
|
310
|
+
activity: p.activity ?? "unknown",
|
|
311
|
+
task_state: p.task_state ?? "active",
|
|
312
|
+
task_state_reason: p.task_state_reason ?? null,
|
|
272
313
|
}))
|
|
273
314
|
.sort((a, b) => (a.instance_id ?? "").localeCompare(b.instance_id ?? ""));
|
|
274
315
|
// Remote basis: machine + per-agent identity/task/files (published_at is
|
|
@@ -279,6 +320,9 @@ function computePeerTableIfChanged(
|
|
|
279
320
|
instance_id: a.instance_id,
|
|
280
321
|
name: a.name ?? null,
|
|
281
322
|
task: a.task ?? null,
|
|
323
|
+
activity: a.activity,
|
|
324
|
+
task_state: a.task_state,
|
|
325
|
+
task_state_reason: a.task_state_reason ?? null,
|
|
282
326
|
files_touched: Array.from(a.files_touched ?? []).sort(),
|
|
283
327
|
})),
|
|
284
328
|
}));
|
|
@@ -392,14 +436,6 @@ function computeCouncilPendingIfChanged(
|
|
|
392
436
|
|
|
393
437
|
/* ---------- helpers ---------- */
|
|
394
438
|
|
|
395
|
-
function readHeartbeat(path: string): HeartbeatRow | null {
|
|
396
|
-
try {
|
|
397
|
-
return JSON.parse(readFileSync(path, "utf8")) as HeartbeatRow;
|
|
398
|
-
} catch {
|
|
399
|
-
return null;
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
|
|
403
439
|
function safeRead(path: string): string {
|
|
404
440
|
try {
|
|
405
441
|
return readFileSync(path, "utf8").trim();
|
|
@@ -493,17 +529,24 @@ function renderSubtable(
|
|
|
493
529
|
|
|
494
530
|
function formatRow(r: HeartbeatRow & { display_files: string[] }, nowSec: number): string {
|
|
495
531
|
const taskPart = r.task ? ` "${r.task.slice(0, 60)}"` : "";
|
|
532
|
+
const statePart = formatState(r);
|
|
496
533
|
// Fall back started_at → last_heartbeat; if neither is a valid timestamp,
|
|
497
534
|
// show "age unknown" rather than the epoch-derived "20608d ago" ghost.
|
|
498
535
|
const startedSec = parseIsoSec(r.started_at) ?? parseIsoSec(r.last_heartbeat);
|
|
499
536
|
const ageFrom = startedSec === null ? "age unknown" : fmtAge(nowSec - startedSec);
|
|
500
537
|
const filesPart = fmtFiles(r.display_files);
|
|
501
|
-
const lastActivity = fmtLastActivity(r, nowSec);
|
|
502
|
-
const turnSummary = r.turn_summary ? `\n last turn: ${r.turn_summary.slice(0, 80)}` : "";
|
|
503
538
|
// Prefer a short instance_id over a bare "unknown" so an incomplete row is
|
|
504
539
|
// still identifiable.
|
|
505
540
|
const label = r.name ?? (r.instance_id ? r.instance_id.slice(0, 8) : "unknown");
|
|
506
|
-
return ` - agent-${label}${taskPart} (${
|
|
541
|
+
return ` - agent-${label}${taskPart} (${statePart}, ${ageFrom}, ${filesPart})`;
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
function formatState(r: HeartbeatRow): string {
|
|
545
|
+
const activity = r.activity ?? "unknown";
|
|
546
|
+
const lifecycle = r.task_state ?? "active";
|
|
547
|
+
const reason =
|
|
548
|
+
lifecycle === "blocked" && r.task_state_reason ? `: ${r.task_state_reason.slice(0, 80)}` : "";
|
|
549
|
+
return `activity=${activity}, lifecycle=${lifecycle}${reason}`;
|
|
507
550
|
}
|
|
508
551
|
|
|
509
552
|
function fmtFiles(files: string[]): string {
|
|
@@ -512,15 +555,6 @@ function fmtFiles(files: string[]): string {
|
|
|
512
555
|
return `holds: ${files.slice(0, 3).join(", ")}, +${files.length - 3} more`;
|
|
513
556
|
}
|
|
514
557
|
|
|
515
|
-
function fmtLastActivity(r: HeartbeatRow, nowSec: number): string {
|
|
516
|
-
if (!r.last_tool) return "";
|
|
517
|
-
const lastTs = parseIsoSec(r.last_heartbeat) ?? parseIsoSec(r.started_at);
|
|
518
|
-
const tail = r.last_tool_target ? ` ${r.last_tool_target.slice(0, 60)}` : "";
|
|
519
|
-
// No valid timestamp → render the tool without an absurd age.
|
|
520
|
-
if (lastTs === null) return `, last: ${r.last_tool}${tail}`;
|
|
521
|
-
return `, last: ${r.last_tool}${tail} ${fmtAge(nowSec - lastTs)}`;
|
|
522
|
-
}
|
|
523
|
-
|
|
524
558
|
/** Epoch-seconds for an ISO string, or null when missing/unparseable (so callers
|
|
525
559
|
* can render "age unknown" instead of an epoch-derived absurd age). */
|
|
526
560
|
function parseIsoSec(iso: string | undefined): number | null {
|