harnery 0.38.0 → 0.40.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/agents.d.ts.map +1 -1
- package/dist/commands/agents.js +32 -8
- package/dist/commands/artifacts.d.ts.map +1 -1
- package/dist/commands/artifacts.js +97 -6
- package/dist/commands/backup.d.ts +16 -0
- package/dist/commands/backup.d.ts.map +1 -1
- package/dist/commands/backup.js +239 -33
- package/dist/commands/browse.d.ts +8 -0
- package/dist/commands/browse.d.ts.map +1 -1
- package/dist/commands/browse.js +466 -231
- package/dist/commands/diagnostics.d.ts.map +1 -1
- package/dist/commands/diagnostics.js +6 -3
- package/dist/commands/ledger-v3.d.ts.map +1 -1
- package/dist/commands/ledger-v3.js +20 -4
- package/dist/commands/qa-run.d.ts.map +1 -1
- package/dist/commands/qa-run.js +26 -3
- package/dist/commands/qa-status.d.ts.map +1 -1
- package/dist/commands/qa-status.js +7 -2
- package/dist/commands/resources.d.ts.map +1 -1
- package/dist/commands/resources.js +23 -3
- package/dist/commands/review-pack.d.ts.map +1 -1
- package/dist/commands/review-pack.js +98 -23
- package/dist/commands/tunnel.d.ts.map +1 -1
- package/dist/commands/tunnel.js +2 -2
- package/dist/core/adapters/profiles.d.ts +1 -1
- package/dist/core/agents/canonical-emit.d.ts +3 -2
- package/dist/core/agents/canonical-emit.d.ts.map +1 -1
- package/dist/core/agents/canonical-emit.js +2 -0
- package/dist/core/agents/cli.js +13 -6
- package/dist/core/agents/live-authority-v3.d.ts.map +1 -1
- package/dist/core/agents/live-authority-v3.js +5 -3
- package/dist/core/agents/live-lifecycle-v3.d.ts +2 -2
- package/dist/core/agents/live-lifecycle-v3.d.ts.map +1 -1
- package/dist/core/agents/render/prompt-context.d.ts +7 -5
- package/dist/core/agents/render/prompt-context.d.ts.map +1 -1
- package/dist/core/agents/render/prompt-context.js +63 -8
- package/dist/core/agents/session-finalizer-v3.d.ts +2 -2
- package/dist/core/agents/session-finalizer-v3.d.ts.map +1 -1
- package/dist/core/agents/state/live-coordination-view.d.ts +3 -3
- package/dist/core/agents/state/live-coordination-view.d.ts.map +1 -1
- package/dist/core/agents/state/live-coordination-view.js +2 -1
- package/dist/core/agents/state/names.d.ts +35 -2
- package/dist/core/agents/state/names.d.ts.map +1 -1
- package/dist/core/agents/state/names.js +80 -5
- package/dist/core/agents/state/stale-sweep.d.ts +2 -1
- package/dist/core/agents/state/stale-sweep.d.ts.map +1 -1
- package/dist/core/agents/state/stale-sweep.js +23 -6
- package/dist/core/agents/turn-elapsed.d.ts +51 -0
- package/dist/core/agents/turn-elapsed.d.ts.map +1 -0
- package/dist/core/agents/turn-elapsed.js +91 -0
- package/dist/core/artifacts/activity.d.ts +14 -0
- package/dist/core/artifacts/activity.d.ts.map +1 -0
- package/dist/core/artifacts/activity.js +52 -0
- package/dist/core/artifacts/delivery-card.d.ts +39 -0
- package/dist/core/artifacts/delivery-card.d.ts.map +1 -0
- package/dist/core/artifacts/delivery-card.js +282 -0
- package/dist/core/artifacts/index.d.ts +42 -7
- package/dist/core/artifacts/index.d.ts.map +1 -1
- package/dist/core/artifacts/index.js +288 -76
- package/dist/core/artifacts/mutation-lock.d.ts +2 -0
- package/dist/core/artifacts/mutation-lock.d.ts.map +1 -0
- package/dist/core/artifacts/mutation-lock.js +91 -0
- package/dist/core/backup/host-snapshot.d.ts +18 -0
- package/dist/core/backup/host-snapshot.d.ts.map +1 -0
- package/dist/core/backup/host-snapshot.js +64 -0
- package/dist/core/config.d.ts +20 -5
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +44 -10
- package/dist/core/diagnostics/advice.d.ts +38 -3
- package/dist/core/diagnostics/advice.d.ts.map +1 -1
- package/dist/core/diagnostics/advice.js +103 -99
- package/dist/core/diagnostics/bundle.d.ts.map +1 -1
- package/dist/core/diagnostics/bundle.js +111 -47
- package/dist/core/diagnostics/comparison.d.ts.map +1 -1
- package/dist/core/diagnostics/comparison.js +3 -2
- package/dist/core/diagnostics/contract.d.ts +15 -31
- package/dist/core/diagnostics/contract.d.ts.map +1 -1
- package/dist/core/diagnostics/contract.js +2 -5
- package/dist/core/diagnostics/index.d.ts +2 -0
- package/dist/core/diagnostics/index.d.ts.map +1 -1
- package/dist/core/diagnostics/index.js +2 -0
- package/dist/core/diagnostics/pressure-contract.d.ts +260 -0
- package/dist/core/diagnostics/pressure-contract.d.ts.map +1 -0
- package/dist/core/diagnostics/pressure-contract.js +70 -0
- package/dist/core/diagnostics/pressure.d.ts +25 -0
- package/dist/core/diagnostics/pressure.d.ts.map +1 -0
- package/dist/core/diagnostics/pressure.js +1138 -0
- package/dist/core/diagnostics/replay.d.ts.map +1 -1
- package/dist/core/diagnostics/replay.js +90 -10
- package/dist/core/events/v3/adapter-id.d.ts +6 -0
- package/dist/core/events/v3/adapter-id.d.ts.map +1 -0
- package/dist/core/events/v3/adapter-id.js +7 -0
- package/dist/core/events/v3/archive-retention.d.ts.map +1 -1
- package/dist/core/events/v3/archive-retention.js +3 -2
- package/dist/core/events/v3/bootstrap.d.ts +41 -4
- package/dist/core/events/v3/bootstrap.d.ts.map +1 -1
- package/dist/core/events/v3/bootstrap.js +120 -17
- package/dist/core/events/v3/capabilities.d.ts +16 -9
- package/dist/core/events/v3/capabilities.d.ts.map +1 -1
- package/dist/core/events/v3/capabilities.js +37 -2
- package/dist/core/events/v3/capability-drift.d.ts +2 -2
- package/dist/core/events/v3/capability-drift.d.ts.map +1 -1
- package/dist/core/events/v3/control-witness.d.ts +48 -5
- package/dist/core/events/v3/control-witness.d.ts.map +1 -1
- package/dist/core/events/v3/control-witness.js +91 -36
- package/dist/core/events/v3/control.d.ts.map +1 -1
- package/dist/core/events/v3/control.js +22 -2
- package/dist/core/events/v3/index.d.ts +2 -1
- package/dist/core/events/v3/index.d.ts.map +1 -1
- package/dist/core/events/v3/index.js +2 -1
- package/dist/core/events/v3/live-feed.d.ts +7 -1
- package/dist/core/events/v3/live-feed.d.ts.map +1 -1
- package/dist/core/events/v3/live-feed.js +21 -3
- package/dist/core/events/v3/live-routing.d.ts.map +1 -1
- package/dist/core/events/v3/live-routing.js +10 -2
- package/dist/core/events/v3/producers/command-recorder.d.ts +2 -2
- package/dist/core/events/v3/producers/command-recorder.d.ts.map +1 -1
- package/dist/core/events/v3/producers/command-recorder.js +2 -1
- package/dist/core/events/v3/producers/coordination-recorder.d.ts +2 -2
- package/dist/core/events/v3/producers/coordination-recorder.d.ts.map +1 -1
- package/dist/core/events/v3/producers/coordination-recorder.js +2 -1
- package/dist/core/events/v3/producers/hook-base.d.ts +2 -2
- package/dist/core/events/v3/producers/hook-base.d.ts.map +1 -1
- package/dist/core/events/v3/producers/hook-base.js +15 -5
- package/dist/core/events/v3/producers/hook.d.ts.map +1 -1
- package/dist/core/events/v3/producers/hook.js +17 -4
- package/dist/core/events/v3/producers/intake.d.ts +4 -4
- package/dist/core/events/v3/producers/intake.d.ts.map +1 -1
- package/dist/core/events/v3/producers/intake.js +3 -2
- package/dist/core/events/v3/producers/producer-state-observer.d.ts.map +1 -1
- package/dist/core/events/v3/producers/producer-state-observer.js +2 -1
- package/dist/core/events/v3/producers/recorder.d.ts +16 -5
- package/dist/core/events/v3/producers/recorder.d.ts.map +1 -1
- package/dist/core/events/v3/producers/recorder.js +31 -9
- package/dist/core/events/v3/reader.d.ts.map +1 -1
- package/dist/core/events/v3/reader.js +10 -13
- package/dist/core/events/v3/runtime-build.d.ts.map +1 -1
- package/dist/core/events/v3/runtime-build.js +3 -2
- package/dist/core/events/v3/runtime-telemetry-capabilities.d.ts +2 -2
- package/dist/core/events/v3/runtime-telemetry-capabilities.d.ts.map +1 -1
- package/dist/core/events/v3/turn-telemetry.d.ts +2 -2
- package/dist/core/events/v3/turn-telemetry.d.ts.map +1 -1
- package/dist/core/hooks/adapter/output.d.ts +16 -14
- package/dist/core/hooks/adapter/output.d.ts.map +1 -1
- package/dist/core/hooks/adapter/output.js +36 -38
- package/dist/core/hooks/backup-schedule.d.ts +34 -0
- package/dist/core/hooks/backup-schedule.d.ts.map +1 -0
- package/dist/core/hooks/backup-schedule.js +114 -0
- package/dist/core/hooks/cli.js +61 -18
- package/dist/core/hooks/codex-wsl-bridge.d.ts +2 -0
- package/dist/core/hooks/codex-wsl-bridge.d.ts.map +1 -1
- package/dist/core/hooks/codex-wsl-bridge.js +18 -4
- package/dist/core/hooks/index.d.ts +1 -0
- package/dist/core/hooks/index.d.ts.map +1 -1
- package/dist/core/hooks/index.js +1 -0
- package/dist/core/hooks/prompt-context/contract.d.ts +61 -0
- package/dist/core/hooks/prompt-context/contract.d.ts.map +1 -0
- package/dist/core/hooks/prompt-context/contract.js +102 -0
- package/dist/core/hooks/prompt-context/index.d.ts +5 -0
- package/dist/core/hooks/prompt-context/index.d.ts.map +1 -0
- package/dist/core/hooks/prompt-context/index.js +2 -0
- package/dist/core/hooks/prompt-context/runner.d.ts +24 -0
- package/dist/core/hooks/prompt-context/runner.d.ts.map +1 -0
- package/dist/core/hooks/prompt-context/runner.js +249 -0
- package/dist/core/qa-artifacts.d.ts +3 -0
- package/dist/core/qa-artifacts.d.ts.map +1 -1
- package/dist/core/qa-artifacts.js +25 -3
- package/dist/core/resources/contract.d.ts +69 -3
- package/dist/core/resources/contract.d.ts.map +1 -1
- package/dist/core/resources/contract.js +1 -1
- package/dist/core/resources/index.d.ts +1 -0
- package/dist/core/resources/index.d.ts.map +1 -1
- package/dist/core/resources/index.js +1 -0
- package/dist/core/resources/native.d.ts +36 -0
- package/dist/core/resources/native.d.ts.map +1 -0
- package/dist/core/resources/native.js +418 -0
- package/dist/core/resources/sampler.d.ts +2 -0
- package/dist/core/resources/sampler.d.ts.map +1 -1
- package/dist/core/resources/sampler.js +31 -1
- package/dist/core/resources/status.d.ts +61 -0
- package/dist/core/resources/status.d.ts.map +1 -0
- package/dist/core/resources/status.js +536 -0
- package/dist/core/resources/system.d.ts +27 -0
- package/dist/core/resources/system.d.ts.map +1 -0
- package/dist/core/resources/system.js +439 -0
- package/dist/core/semantic/contract.d.ts +13 -13
- package/dist/core/semantic/service.d.ts +2 -0
- package/dist/core/semantic/service.d.ts.map +1 -1
- package/dist/core/semantic/service.js +27 -4
- package/dist/core/storage/builtins.js +41 -0
- package/dist/core/supervisor/contract.d.ts +41 -3
- package/dist/core/supervisor/contract.d.ts.map +1 -1
- package/dist/core/supervisor/contract.js +3 -2
- package/dist/core/supervisor/findings.d.ts +3 -0
- package/dist/core/supervisor/findings.d.ts.map +1 -1
- package/dist/core/supervisor/findings.js +88 -0
- package/dist/core/supervisor/history.d.ts.map +1 -1
- package/dist/core/supervisor/history.js +14 -0
- package/dist/core/supervisor/ledger-state.d.ts +55 -0
- package/dist/core/supervisor/ledger-state.d.ts.map +1 -0
- package/dist/core/supervisor/ledger-state.js +0 -0
- package/dist/core/supervisor/service.d.ts.map +1 -1
- package/dist/core/supervisor/service.js +120 -7
- package/dist/core/supervisor/storage.d.ts +3 -1
- package/dist/core/supervisor/storage.d.ts.map +1 -1
- package/dist/core/supervisor/storage.js +4 -0
- package/dist/core/workflow/admission.d.ts +3 -0
- package/dist/core/workflow/admission.d.ts.map +1 -1
- package/dist/core/workflow/admission.js +28 -16
- package/dist/core/workflow/engine.js +2 -2
- package/dist/core/workflow/live-session-v3.d.ts.map +1 -1
- package/dist/core/workflow/live-session-v3.js +6 -1
- package/dist/core/workflow/proof.d.ts.map +1 -1
- package/dist/core/workflow/proof.js +4 -3
- package/dist/lib/browser/capture-fidelity.d.ts +7 -0
- package/dist/lib/browser/capture-fidelity.d.ts.map +1 -1
- package/dist/lib/browser/capture-fidelity.js +17 -0
- package/dist/lib/browser/client.d.ts +9 -0
- package/dist/lib/browser/client.d.ts.map +1 -1
- package/dist/lib/browser/client.js +85 -37
- package/dist/lib/browser/index.d.ts +3 -1
- package/dist/lib/browser/index.d.ts.map +1 -1
- package/dist/lib/browser/index.js +2 -1
- package/dist/lib/browser/page-review-budget.d.ts +13 -0
- package/dist/lib/browser/page-review-budget.d.ts.map +1 -0
- package/dist/lib/browser/page-review-budget.js +251 -0
- package/dist/lib/browser/page-review-contracts.d.ts +127 -0
- package/dist/lib/browser/page-review-contracts.d.ts.map +1 -0
- package/dist/lib/browser/page-review-contracts.js +5 -0
- package/dist/lib/browser/page-review-evidence.d.ts +48 -0
- package/dist/lib/browser/page-review-evidence.d.ts.map +1 -0
- package/dist/lib/browser/page-review-evidence.js +340 -0
- package/dist/lib/browser/page-review-judge.d.ts +1 -1
- package/dist/lib/browser/page-review-judge.d.ts.map +1 -1
- package/dist/lib/browser/page-review-judge.js +46 -38
- package/dist/lib/browser/page-review-pack.d.ts +44 -22
- package/dist/lib/browser/page-review-pack.d.ts.map +1 -1
- package/dist/lib/browser/page-review-pack.js +116 -36
- package/dist/lib/browser/page-review-source.d.ts +12 -0
- package/dist/lib/browser/page-review-source.d.ts.map +1 -0
- package/dist/lib/browser/page-review-source.js +22 -0
- package/dist/lib/browser/qa-run-contracts.d.ts +35 -9
- package/dist/lib/browser/qa-run-contracts.d.ts.map +1 -1
- package/dist/lib/browser/qa-run-contracts.js +48 -14
- package/dist/lib/browser/qa-run.d.ts.map +1 -1
- package/dist/lib/browser/qa-run.js +215 -68
- package/dist/lib/browser/qa-snapshot.d.ts +6 -0
- package/dist/lib/browser/qa-snapshot.d.ts.map +1 -1
- package/dist/lib/browser/qa-snapshot.js +259 -48
- package/dist/lib/browser/review-capture-transaction.d.ts +13 -0
- package/dist/lib/browser/review-capture-transaction.d.ts.map +1 -0
- package/dist/lib/browser/review-capture-transaction.js +79 -0
- package/dist/lib/browser/standalone-html.d.ts.map +1 -1
- package/dist/lib/browser/standalone-html.js +4 -2
- package/dist/lib/browser/thumbnail-association.d.ts +34 -0
- package/dist/lib/browser/thumbnail-association.d.ts.map +1 -0
- package/dist/lib/browser/thumbnail-association.js +158 -0
- package/dist/lib/browser/tiling.d.ts +30 -0
- package/dist/lib/browser/tiling.d.ts.map +1 -1
- package/dist/lib/browser/tiling.js +38 -0
- package/dist/lib/docs-metadata-managed.d.ts.map +1 -1
- package/dist/lib/docs-metadata-managed.js +4 -1
- package/dist/lib/identities/assume.d.ts.map +1 -1
- package/dist/lib/identities/assume.js +7 -1
- package/dist/lib/instructions/templates.d.ts.map +1 -1
- package/dist/lib/instructions/templates.js +1 -0
- package/dist/lib/local-file-url.d.ts +12 -0
- package/dist/lib/local-file-url.d.ts.map +1 -1
- package/dist/lib/local-file-url.js +16 -2
- package/dist/lib/tunnel/state.d.ts +19 -4
- package/dist/lib/tunnel/state.d.ts.map +1 -1
- package/dist/lib/tunnel/state.js +53 -13
- package/package.json +7 -4
- package/schemas/config.schema.json +69 -2
- package/src/commands/agents.ts +42 -9
- package/src/commands/artifacts.ts +130 -6
- package/src/commands/backup.ts +287 -34
- package/src/commands/browse.ts +564 -267
- package/src/commands/diagnostics.ts +6 -3
- package/src/commands/ledger-v3.ts +20 -3
- package/src/commands/qa-run.ts +37 -3
- package/src/commands/qa-status.ts +11 -2
- package/src/commands/resources.ts +23 -3
- package/src/commands/review-pack.ts +165 -62
- package/src/commands/tunnel.ts +2 -1
- package/src/core/agents/canonical-emit.ts +4 -2
- package/src/core/agents/cli.ts +14 -6
- package/src/core/agents/live-authority-v3.ts +7 -3
- package/src/core/agents/live-lifecycle-v3.ts +2 -2
- package/src/core/agents/render/prompt-context.ts +68 -14
- package/src/core/agents/session-finalizer-v3.ts +2 -2
- package/src/core/agents/state/live-coordination-view.ts +4 -4
- package/src/core/agents/state/names.ts +92 -7
- package/src/core/agents/state/stale-sweep.ts +22 -8
- package/src/core/agents/turn-elapsed.ts +135 -0
- package/src/core/artifacts/activity.ts +71 -0
- package/src/core/artifacts/delivery-card.ts +375 -0
- package/src/core/artifacts/index.ts +385 -91
- package/src/core/artifacts/mutation-lock.ts +106 -0
- package/src/core/backup/host-snapshot.ts +76 -0
- package/src/core/config.ts +66 -13
- package/src/core/diagnostics/advice.ts +148 -120
- package/src/core/diagnostics/bundle.ts +138 -52
- package/src/core/diagnostics/comparison.ts +6 -2
- package/src/core/diagnostics/contract.ts +39 -42
- package/src/core/diagnostics/index.ts +2 -0
- package/src/core/diagnostics/pressure-contract.ts +294 -0
- package/src/core/diagnostics/pressure.ts +1361 -0
- package/src/core/diagnostics/replay.ts +116 -11
- package/src/core/events/v3/adapter-id.ts +12 -0
- package/src/core/events/v3/archive-retention.ts +3 -6
- package/src/core/events/v3/bootstrap.ts +163 -16
- package/src/core/events/v3/capabilities.ts +75 -25
- package/src/core/events/v3/capability-drift.ts +2 -2
- package/src/core/events/v3/control-witness.ts +172 -41
- package/src/core/events/v3/control.ts +34 -2
- package/src/core/events/v3/index.ts +3 -0
- package/src/core/events/v3/live-feed.ts +23 -5
- package/src/core/events/v3/live-routing.ts +14 -2
- package/src/core/events/v3/producers/command-recorder.ts +4 -4
- package/src/core/events/v3/producers/coordination-recorder.ts +4 -4
- package/src/core/events/v3/producers/hook-base.ts +21 -16
- package/src/core/events/v3/producers/hook.ts +21 -4
- package/src/core/events/v3/producers/intake.ts +6 -6
- package/src/core/events/v3/producers/producer-state-observer.ts +2 -1
- package/src/core/events/v3/producers/recorder.ts +50 -21
- package/src/core/events/v3/reader.ts +14 -13
- package/src/core/events/v3/runtime-build.ts +3 -2
- package/src/core/events/v3/runtime-telemetry-capabilities.ts +3 -3
- package/src/core/events/v3/turn-telemetry.ts +4 -4
- package/src/core/hooks/adapter/output.ts +50 -36
- package/src/core/hooks/backup-schedule.ts +147 -0
- package/src/core/hooks/cli.ts +65 -14
- package/src/core/hooks/codex-wsl-bridge.ts +21 -5
- package/src/core/hooks/index.ts +1 -0
- package/src/core/hooks/prompt-context/contract.ts +177 -0
- package/src/core/hooks/prompt-context/index.ts +22 -0
- package/src/core/hooks/prompt-context/runner.ts +303 -0
- package/src/core/qa-artifacts.ts +29 -3
- package/src/core/resources/contract.ts +76 -3
- package/src/core/resources/index.ts +1 -0
- package/src/core/resources/native.ts +481 -0
- package/src/core/resources/sampler.ts +46 -1
- package/src/core/resources/status.ts +717 -0
- package/src/core/resources/system.ts +530 -0
- package/src/core/semantic/service.ts +37 -3
- package/src/core/storage/builtins.ts +41 -0
- package/src/core/supervisor/contract.ts +45 -3
- package/src/core/supervisor/findings.ts +159 -0
- package/src/core/supervisor/history.ts +15 -0
- package/src/core/supervisor/ledger-state.ts +0 -0
- package/src/core/supervisor/service.ts +133 -5
- package/src/core/supervisor/storage.ts +7 -0
- package/src/core/workflow/admission.ts +33 -17
- package/src/core/workflow/engine.ts +2 -2
- package/src/core/workflow/live-session-v3.ts +6 -8
- package/src/core/workflow/proof.ts +4 -3
- package/src/lib/browser/capture-fidelity.ts +23 -0
- package/src/lib/browser/client.ts +96 -44
- package/src/lib/browser/index.ts +15 -1
- package/src/lib/browser/page-review-budget.ts +309 -0
- package/src/lib/browser/page-review-contracts.ts +129 -0
- package/src/lib/browser/page-review-evidence.ts +465 -0
- package/src/lib/browser/page-review-judge.ts +56 -40
- package/src/lib/browser/page-review-pack.ts +181 -43
- package/src/lib/browser/page-review-source.ts +30 -0
- package/src/lib/browser/qa-run-contracts.ts +62 -18
- package/src/lib/browser/qa-run.ts +259 -71
- package/src/lib/browser/qa-snapshot.ts +289 -48
- package/src/lib/browser/review-capture-transaction.ts +106 -0
- package/src/lib/browser/standalone-html.ts +4 -2
- package/src/lib/browser/thumbnail-association.ts +190 -0
- package/src/lib/browser/tiling.ts +63 -0
- package/src/lib/docs-metadata-managed.ts +4 -1
- package/src/lib/identities/assume.ts +12 -4
- package/src/lib/instructions/templates.ts +1 -0
- package/src/lib/local-file-url.ts +17 -2
- package/src/lib/tunnel/state.ts +70 -13
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { EVENT_ADAPTER_IDS_V3 } from "../events/v3/adapter-id.js";
|
|
2
3
|
import { canonicalJsonV3, normalizeNativeIdV3, sha256V3 } from "../events/v3/canonical.js";
|
|
3
4
|
import { readEventV3ControlState } from "../events/v3/control.js";
|
|
4
5
|
import { readCoordinationViewV3, requireAuthoritySafeCoordinationViewV3, } from "../events/v3/coordination-view.js";
|
|
@@ -131,9 +132,7 @@ function readAuthoritySafeViewForBootstrap(coordRoot) {
|
|
|
131
132
|
}
|
|
132
133
|
function readSessionProducerStatesForBootstrap(coordRoot, nativeSessionId) {
|
|
133
134
|
try {
|
|
134
|
-
return
|
|
135
|
-
.map((adapter) => readHookProducerStateV3(coordRoot, adapter, nativeSessionId))
|
|
136
|
-
.filter((state) => state !== undefined);
|
|
135
|
+
return EVENT_ADAPTER_IDS_V3.map((adapter) => readHookProducerStateV3(coordRoot, adapter, nativeSessionId)).filter((state) => state !== undefined);
|
|
137
136
|
}
|
|
138
137
|
catch {
|
|
139
138
|
throw new LiveCoordinationAuthorityV3Error("producer_state_unsafe");
|
|
@@ -270,6 +269,9 @@ export function reopenLiveCoordinationGenerationV3(input) {
|
|
|
270
269
|
if (!terminalView || terminalView.instance_id !== instanceId) {
|
|
271
270
|
throw new LiveCoordinationAuthorityV3Error("terminal_generation_authority_missing");
|
|
272
271
|
}
|
|
272
|
+
if (terminal.adapter === "openclaw") {
|
|
273
|
+
throw new LiveCoordinationAuthorityV3Error("lifecycle_not_human_facing");
|
|
274
|
+
}
|
|
273
275
|
if (terminalView.parent_generation_id || terminalView.delegation_id || terminalView.workflow_id) {
|
|
274
276
|
throw new LiveCoordinationAuthorityV3Error("lifecycle_not_human_facing");
|
|
275
277
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { EventAdapterIdV3 } from "../events/v3/adapter-id.js";
|
|
2
2
|
import type { EventV3 } from "../events/v3/contract.js";
|
|
3
3
|
export type LiveLifecycleObservationV3Result = {
|
|
4
4
|
state: "recorded";
|
|
@@ -8,7 +8,7 @@ interface LiveLifecycleObservationBaseV3 {
|
|
|
8
8
|
coordRoot: string;
|
|
9
9
|
owner: string;
|
|
10
10
|
nativeSessionId: string;
|
|
11
|
-
adapter:
|
|
11
|
+
adapter: EventAdapterIdV3;
|
|
12
12
|
observedAt?: string;
|
|
13
13
|
}
|
|
14
14
|
export declare function recordLiveSweepObservationV3(input: LiveLifecycleObservationBaseV3 & {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"live-lifecycle-v3.d.ts","sourceRoot":"","sources":["../../../src/core/agents/live-lifecycle-v3.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"live-lifecycle-v3.d.ts","sourceRoot":"","sources":["../../../src/core/agents/live-lifecycle-v3.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAGnE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AAaxD,MAAM,MAAM,gCAAgC,GAAG;IAAE,KAAK,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAC;AAErF,UAAU,8BAA8B;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,gBAAgB,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,8BAA8B,GAAG;IACtC,WAAW,EAAE,iBAAiB,GAAG,QAAQ,GAAG,uBAAuB,GAAG,mBAAmB,CAAC;IAC1F,KAAK,EAAE,MAAM,CAAC;CACf,GACA,gCAAgC,CAOlC;AAED,wBAAgB,6BAA6B,CAC3C,KAAK,EAAE,8BAA8B,GACpC,gCAAgC,CAQlC"}
|
|
@@ -49,11 +49,6 @@ export interface PromptContextOpts {
|
|
|
49
49
|
/** When true, append the non-deduplicated Codex status-footer reminder.
|
|
50
50
|
* The caller enables this only for human-facing Codex sessions. */
|
|
51
51
|
statusFooterNudge?: boolean;
|
|
52
|
-
/** Adapter id this prompt is being rendered for. Gates the mailbox drain:
|
|
53
|
-
* an adapter that cannot receive UserPromptSubmit context must not consume
|
|
54
|
-
* messages here, or they are removed from the queue and never shown. When
|
|
55
|
-
* omitted, delivery is attempted (the default route can receive). */
|
|
56
|
-
adapter?: string;
|
|
57
52
|
/** Adapter id whose Stop hook ENFORCES the end-of-turn ritual (task_set +
|
|
58
53
|
* status check). When set, append a fresh per-prompt reminder of that
|
|
59
54
|
* contract so the model satisfies it before ending the turn instead of
|
|
@@ -70,4 +65,11 @@ export interface PromptContextOpts {
|
|
|
70
65
|
* councils are pending, matching the bash behavior).
|
|
71
66
|
*/
|
|
72
67
|
export declare function renderPromptContext(opts: PromptContextOpts): string;
|
|
68
|
+
/**
|
|
69
|
+
* Prompts receive the published assessment, and only when it changes in a way
|
|
70
|
+
* that changes what an agent should do. The dedupe key is scope, state, and
|
|
71
|
+
* recommended action, so a moving number or a different contributor does not
|
|
72
|
+
* re-emit the same advice.
|
|
73
|
+
*/
|
|
74
|
+
export declare function resourceWarningIfChanged(coordRoot: string, instanceId: string): string;
|
|
73
75
|
//# sourceMappingURL=prompt-context.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompt-context.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/render/prompt-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;
|
|
1
|
+
{"version":3,"file":"prompt-context.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/render/prompt-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAgDH,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;8EAC0E;IAC1E,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;kFAC8E;IAC9E,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;kFAC8E;IAC9E,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B;uEACmE;IACnE,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;;;wBAIoB;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,iBAAiB,GAAG,MAAM,CAkFnE;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CA6CtF"}
|
|
@@ -37,10 +37,11 @@ import { existsSync, mkdirSync, readdirSync, readFileSync, renameSync, rmSync, w
|
|
|
37
37
|
import { join } from "node:path";
|
|
38
38
|
import { coordEnv } from "../../../lib/env.js";
|
|
39
39
|
import { endOfTurnStatusCommand, hostPromptReminder, resolveBinName } from "../../config.js";
|
|
40
|
-
import { canReceiveContext } from "../../hooks/adapter/output.js";
|
|
41
40
|
import { readRemoteMachines } from "../../presence/index.js";
|
|
41
|
+
import { readResourceStatus } from "../../resources/status.js";
|
|
42
42
|
import { drainMailbox, formatMailboxDelivery } from "../mailbox.js";
|
|
43
43
|
import { sessionNameDisplayBlock, sessionNameDisplayPending } from "../session-name-display.js";
|
|
44
|
+
import { heartbeatPath } from "../state/heartbeat-reader.js";
|
|
44
45
|
import { readLiveCoordinationRow, readLiveCoordinationRows, } from "../state/live-coordination-view.js";
|
|
45
46
|
import { formatPendingCouncils, recordDeliveredMessages } from "./session-context.js";
|
|
46
47
|
/**
|
|
@@ -52,7 +53,7 @@ import { formatPendingCouncils, recordDeliveredMessages } from "./session-contex
|
|
|
52
53
|
* councils are pending, matching the bash behavior).
|
|
53
54
|
*/
|
|
54
55
|
export function renderPromptContext(opts) {
|
|
55
|
-
const { coordRoot, instanceId, sessionId, agentName, sessionNameNudge, taskNudge, hostPromptReminder: promptReminderEnabled, statusFooterNudge, turnRitualNudge,
|
|
56
|
+
const { coordRoot, instanceId, sessionId, agentName, sessionNameNudge, taskNudge, hostPromptReminder: promptReminderEnabled, statusFooterNudge, turnRitualNudge, } = opts;
|
|
56
57
|
const sections = [];
|
|
57
58
|
// The hook route does not pass --name, so resolve it from the heartbeat.
|
|
58
59
|
// Every name-addressed section below (messages, councils) is silently
|
|
@@ -62,12 +63,7 @@ export function renderPromptContext(opts) {
|
|
|
62
63
|
// exactly once, and it is the one section here that carries new information
|
|
63
64
|
// from another agent rather than a reminder.
|
|
64
65
|
//
|
|
65
|
-
|
|
66
|
-
// context. Cursor cannot, so draining there would empty the queue into output
|
|
67
|
-
// that is discarded; those sessions get their messages at SessionStart, which
|
|
68
|
-
// Cursor does deliver.
|
|
69
|
-
const canDeliverHere = !adapter || canReceiveContext(adapter, "UserPromptSubmit");
|
|
70
|
-
if (resolvedName && canDeliverHere) {
|
|
66
|
+
if (resolvedName) {
|
|
71
67
|
const delivered = drainMailbox(coordRoot, resolvedName);
|
|
72
68
|
if (delivered.length > 0) {
|
|
73
69
|
recordDeliveredMessages(instanceId, delivered);
|
|
@@ -78,6 +74,9 @@ export function renderPromptContext(opts) {
|
|
|
78
74
|
const peerTable = computePeerTableIfChanged(coordRoot, instanceId, sessionId);
|
|
79
75
|
if (peerTable)
|
|
80
76
|
sections.push(peerTable);
|
|
77
|
+
const resources = resourceWarningIfChanged(coordRoot, instanceId);
|
|
78
|
+
if (resources)
|
|
79
|
+
sections.push(resources);
|
|
81
80
|
// 3. Council pending with hash dedup.
|
|
82
81
|
if (resolvedName) {
|
|
83
82
|
const councilMsg = computeCouncilPendingIfChanged(coordRoot, instanceId, resolvedName);
|
|
@@ -123,6 +122,62 @@ export function renderPromptContext(opts) {
|
|
|
123
122
|
}
|
|
124
123
|
return sections.join("\n\n");
|
|
125
124
|
}
|
|
125
|
+
/**
|
|
126
|
+
* Prompts receive the published assessment, and only when it changes in a way
|
|
127
|
+
* that changes what an agent should do. The dedupe key is scope, state, and
|
|
128
|
+
* recommended action, so a moving number or a different contributor does not
|
|
129
|
+
* re-emit the same advice.
|
|
130
|
+
*/
|
|
131
|
+
export function resourceWarningIfChanged(coordRoot, instanceId) {
|
|
132
|
+
try {
|
|
133
|
+
heartbeatPath(coordRoot, instanceId);
|
|
134
|
+
const status = readResourceStatus(coordRoot);
|
|
135
|
+
const assessment = status.assessment;
|
|
136
|
+
const hashFile = join(coordRoot, ".harnery", `.last-resource-hash.${instanceId}`);
|
|
137
|
+
const previous = safeRead(hashFile);
|
|
138
|
+
// Existing users without an observer should retain ordinary coordination.
|
|
139
|
+
if (status.assessment_capability.reason_code === "pressure_record_missing" && !previous) {
|
|
140
|
+
return "";
|
|
141
|
+
}
|
|
142
|
+
const key = `${assessment.scope}:${assessment.state}:${assessment.recommended_action}`;
|
|
143
|
+
if (previous === key)
|
|
144
|
+
return "";
|
|
145
|
+
writeHashFile(hashFile, key);
|
|
146
|
+
const warning = assessment.state === "elevated" || assessment.state === "critical";
|
|
147
|
+
const wasWarning = !!previous && (previous.includes(":elevated:") || previous.includes(":critical:"));
|
|
148
|
+
if (!warning && !wasWarning)
|
|
149
|
+
return "";
|
|
150
|
+
const lines = [`Resource update: ${assessment.summary}`];
|
|
151
|
+
if (assessment.state === "unknown") {
|
|
152
|
+
lines.push("Resource headroom cannot be measured right now, so continue normal coordination and judge heavy work yourself.");
|
|
153
|
+
}
|
|
154
|
+
else if (!warning && wasWarning) {
|
|
155
|
+
lines.push("The previously reported resource warning has cleared.");
|
|
156
|
+
}
|
|
157
|
+
for (const item of assessment.guidance) {
|
|
158
|
+
lines.push(`${WORKLOAD_LABEL[item.workload_class]}: ${item.summary}`);
|
|
159
|
+
}
|
|
160
|
+
const owners = assessment.contributors
|
|
161
|
+
.filter((row) => row.attribution_confidence === "exact" && row.owner_id)
|
|
162
|
+
.slice(0, 3)
|
|
163
|
+
.map((row) => `${row.owner_kind ?? "owner"} ${row.owner_id}`);
|
|
164
|
+
if (owners.length) {
|
|
165
|
+
lines.push(`Measured owners of the contended resource: ${owners.join(", ")}. That says who is holding it, not what the machine as a whole can take.`);
|
|
166
|
+
}
|
|
167
|
+
lines.push(`Read \`${resolveBinName(coordRoot)} resources status --json\` for the evidence behind this.`);
|
|
168
|
+
return lines.join("\n");
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
return "";
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
/** How an agent recognizes the work each guidance entry is about. */
|
|
175
|
+
const WORKLOAD_LABEL = {
|
|
176
|
+
lightweight: "Reads and small edits",
|
|
177
|
+
"cpu-heavy": "Builds and test runs",
|
|
178
|
+
"memory-heavy": "Browser captures and page QA",
|
|
179
|
+
"storage-heavy": "Large writes and exports",
|
|
180
|
+
};
|
|
126
181
|
function renderHostPromptReminder(coordRoot, selfInstanceId) {
|
|
127
182
|
const hb = readLiveCoordinationRow(coordRoot, selfInstanceId);
|
|
128
183
|
if (!hb || hb.kind === "subagent" || hb.kind === "transient" || hb.workflow_run_id)
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { EventAdapterIdV3 } from "../events/v3/adapter-id.js";
|
|
2
2
|
import type { EventV3 } from "../events/v3/contract.js";
|
|
3
3
|
import { type SessionFinalizationRequestV3 } from "./session-finalization-state-v3.js";
|
|
4
4
|
export { listSessionFinalizationRequestsV3, type SessionFinalizationRequestV3, type SessionFinalizationTriggerV3, } from "./session-finalization-state-v3.js";
|
|
5
5
|
export interface SessionArchiveObservationV3 {
|
|
6
|
-
adapter:
|
|
6
|
+
adapter: EventAdapterIdV3;
|
|
7
7
|
native_session_id: string;
|
|
8
8
|
archived: boolean;
|
|
9
9
|
observed_at: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-finalizer-v3.d.ts","sourceRoot":"","sources":["../../../src/core/agents/session-finalizer-v3.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"session-finalizer-v3.d.ts","sourceRoot":"","sources":["../../../src/core/agents/session-finalizer-v3.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAGnE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AAmBxD,OAAO,EAIL,KAAK,4BAA4B,EAIlC,MAAM,oCAAoC,CAAC;AAE5C,OAAO,EACL,iCAAiC,EACjC,KAAK,4BAA4B,EACjC,KAAK,4BAA4B,GAClC,MAAM,oCAAoC,CAAC;AAK5C,MAAM,WAAW,2BAA2B;IAC1C,OAAO,EAAE,gBAAgB,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,qCAAqC;IACpD,GAAG,CAAC,EAAE,IAAI,CAAC;IACX,oBAAoB,CAAC,EAAE,SAAS,2BAA2B,EAAE,CAAC;CAC/D;AAED,MAAM,WAAW,oCAAoC;IACnD,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,yBAAyB;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,QAAQ,MAAM,EAAE,CAAC;IAC9B,aAAa,EAAE,OAAO,MAAM,EAAE,CAAC;IAC/B,OAAO,CAAC,EAAE,4BAA4B,CAAC,SAAS,CAAC,CAAC;IAClD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sBAAsB,EAAE,OAAO,CAAC;CACjC;AAED,MAAM,WAAW,gCAAiC,SAAQ,yBAAyB;CAAG;AAEtF,MAAM,MAAM,iCAAiC,GACzC,UAAU,CAAC,OAAO,oBAAoB,CAAC,GACvC;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GACjB;IAAE,KAAK,EAAE,wBAAwB,CAAA;CAAE,GACnC;IAAE,KAAK,EAAE,qBAAqB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC/C;IAAE,KAAK,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,4BAA4B,CAAA;CAAE,GAC1D;IACE,KAAK,EAAE,mBAAmB,CAAC;IAC3B,OAAO,EAAE,4BAA4B,CAAC;IACtC,oIAAoI;IACpI,OAAO,EAAE;QACP,aAAa,EAAE,QAAQ,MAAM,EAAE,EAAE,CAAC;QAClC,iBAAiB,EAAE,OAAO,CAAC;QAC3B,cAAc,EAAE,MAAM,CAAC;KACxB,CAAC;CACH,CAAC;AAEN,MAAM,WAAW,6BAA6B;IAC5C,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,QAAQ,MAAM,EAAE,CAAC;IAC9B,aAAa,EAAE,OAAO,MAAM,EAAE,CAAC;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,yBAAyB;;;;;;;;;;;;;;;;;EA6BpE;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,gCAAgC,GACtC,iCAAiC,CA8DnC;AAED,wBAAgB,8BAA8B,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAIzE;AAED,qFAAqF;AACrF,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,6BAA6B;;;;;;;;;;;;;;;;;;;;EAiC5E;AAED,wBAAgB,8BAA8B,CAC5C,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,qCAA0C,GAClD,oCAAoC,CAmOtC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type EventAdapterIdV3 } from "../../events/v3/adapter-id.js";
|
|
2
2
|
import { type CoordinationGenerationViewV3 } from "../../events/v3/coordination-view.js";
|
|
3
3
|
import { type Heartbeat } from "./heartbeat-reader.js";
|
|
4
4
|
/**
|
|
@@ -21,9 +21,9 @@ export declare function readLiveCoordinationRow(coordRoot: string, nativeInstanc
|
|
|
21
21
|
* V3 generation is stronger evidence than a missing or stale heartbeat, so
|
|
22
22
|
* callers must never substitute another adapter when this function succeeds.
|
|
23
23
|
*/
|
|
24
|
-
export declare function liveCoordinationAdapterV3(coordRoot: string, nativeInstanceId: string):
|
|
24
|
+
export declare function liveCoordinationAdapterV3(coordRoot: string, nativeInstanceId: string): EventAdapterIdV3 | null;
|
|
25
25
|
export declare function isCurrentV3HeartbeatCache(cache: Heartbeat | null | undefined, generation: CoordinationGenerationViewV3): cache is Heartbeat;
|
|
26
26
|
export declare function projectHeartbeatV3(coordRoot: string, generation: CoordinationGenerationViewV3, cache: Heartbeat | undefined, nativeInstanceId: string | undefined, parent?: CoordinationGenerationViewV3): V3HeartbeatMaterialization;
|
|
27
27
|
export declare function observedAdapterV3(generation: CoordinationGenerationViewV3): string | undefined;
|
|
28
|
-
export declare function isAdapterV3(value: string | undefined): value is
|
|
28
|
+
export declare function isAdapterV3(value: string | undefined): value is EventAdapterIdV3;
|
|
29
29
|
//# sourceMappingURL=live-coordination-view.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"live-coordination-view.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/state/live-coordination-view.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"live-coordination-view.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/state/live-coordination-view.ts"],"names":[],"mappings":"AAEA,OAAO,EAAwB,KAAK,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAC5F,OAAO,EACL,KAAK,4BAA4B,EAIlC,MAAM,sCAAsC,CAAC;AAM9C,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,gBAAgB,GAAG,IAAI,CAWzB;AA8BD,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,SAAS,GAAG,IAAI,GAAG,SAAS,EACnC,UAAU,EAAE,4BAA4B,GACvC,KAAK,IAAI,SAAS,CAMpB;AAED,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,4BAA4B,EACxC,KAAK,EAAE,SAAS,GAAG,SAAS,EAC5B,gBAAgB,EAAE,MAAM,GAAG,SAAS,EACpC,MAAM,CAAC,EAAE,4BAA4B,GACpC,0BAA0B,CAsD5B;AAED,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,4BAA4B,GAAG,MAAM,GAAG,SAAS,CAG9F;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,KAAK,IAAI,gBAAgB,CAEhF"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
|
+
import { EVENT_ADAPTER_IDS_V3 } from "../../events/v3/adapter-id.js";
|
|
3
4
|
import { readCoordinationViewV3, requireAuthoritySafeCoordinationViewV3, } from "../../events/v3/coordination-view.js";
|
|
4
5
|
import { liveInstanceIdV3, nativeInstanceIdV3, observeLiveEventLedgerRouteV3, } from "../../events/v3/live-route-observer.js";
|
|
5
6
|
import { readHeartbeat } from "./heartbeat-reader.js";
|
|
@@ -148,7 +149,7 @@ export function observedAdapterV3(generation) {
|
|
|
148
149
|
return observation.state === "observed" ? observation.value.id : undefined;
|
|
149
150
|
}
|
|
150
151
|
export function isAdapterV3(value) {
|
|
151
|
-
return value
|
|
152
|
+
return EVENT_ADAPTER_IDS_V3.includes(value ?? "");
|
|
152
153
|
}
|
|
153
154
|
function observedModel(generation) {
|
|
154
155
|
const observation = generation.runtime_attestation.model;
|
|
@@ -25,10 +25,17 @@
|
|
|
25
25
|
* new binding instead of rewriting history; readers therefore resolve from the
|
|
26
26
|
* end of the file. Older one-row histories retain their original behavior.
|
|
27
27
|
* 3. Else: new assignment, consume a counter slot.
|
|
28
|
+
*
|
|
29
|
+
* Live-name skip: the pool holds 260 names and a busy repo consumes ~100 a
|
|
30
|
+
* day, so the counter wraps roughly every three days while sessions that
|
|
31
|
+
* resume under a stable instance_id keep a name for far longer. A counter-only
|
|
32
|
+
* pick therefore hands a live agent's name to a new one (observed 2026-09-06:
|
|
33
|
+
* two concurrent "Maya" agents, their pool slots exactly 520 apart). Assignment
|
|
34
|
+
* now probes forward past any name a fresh heartbeat still holds.
|
|
28
35
|
*/
|
|
29
36
|
/** All 260 names. */
|
|
30
37
|
export declare const COORD_NAMES: readonly ["Anna", "Bob", "Carmen", "Dorian", "Erika", "Fred", "Gemma", "Hank", "Imelda", "Jerry", "Karen", "Lorenzo", "Mindy", "Nate", "Odette", "Peter", "Quinn", "Rafael", "Sara", "Tony", "Ursula", "Vinson", "Whitney", "Xander", "Yara", "Zane", "Alex", "Bertha", "Carlos", "Dalia", "Ernesto", "Francine", "Gordon", "Helene", "Isaias", "Joyce", "Kirk", "Lucia", "Milton", "Nadine", "Oscar", "Patty", "Quentin", "Rebekah", "Sean", "Tammy", "Ulrik", "Valerie", "Wallace", "Xanthe", "Yusuf", "Zara", "Adelaide", "Bruno", "Cora", "Damon", "Edna", "Felix", "Greta", "Hugo", "Ines", "Jasper", "Kaia", "Larry", "Maxine", "Nicholas", "Olive", "Paxton", "Querida", "Roman", "Stella", "Tobias", "Una", "Virgil", "Willow", "Xavier", "Yolanda", "Zephyr", "Aaron", "Beatrice", "Cyrus", "Delia", "Elias", "Florence", "Galileo", "Hester", "Ian", "Jenna", "Klaus", "Linda", "Marco", "Nora", "Otto", "Paulette", "Quill", "Renee", "Sebastian", "Theresa", "Umberto", "Vera", "Walter", "Xena", "Yves", "Zoe", "Anita", "Beau", "Celeste", "Dexter", "Edith", "Fitz", "Gloria", "Hadley", "Iris", "Jude", "Kira", "Leo", "Maya", "Nash", "Olga", "Phillip", "Quetzal", "Royce", "Sage", "Trent", "Uma", "Vincent", "Wynne", "Xerxes", "Yvette", "Zoltan", "Andre", "Bonnie", "Caleb", "Daphne", "Ezra", "Fiona", "Gibson", "Holly", "Ivan", "Juno", "Knox", "Lila", "Mason", "Nila", "Owen", "Petra", "Quincy", "Rosa", "Sterling", "Talia", "Uri", "Violet", "Wesley", "Ximena", "Yuri", "Zelda", "Astrid", "Boris", "Cassidy", "Davis", "Esme", "Forrest", "Genevieve", "Henry", "Imogen", "Joaquin", "Kestrel", "Luther", "Margot", "Nigel", "Ophelia", "Percy", "Quenby", "Reagan", "Sienna", "Truman", "Undine", "Voss", "Wren", "Xan", "Yael", "Zia", "Arthur", "Bianca", "Cody", "Dahlia", "Evander", "Fern", "Gustavo", "Harriet", "Ira", "Josephine", "Kendrick", "Lainey", "Miles", "Naomi", "Orion", "Pearl", "Quark", "Rylie", "Saul", "Tessa", "Ulysses", "Vesper", "Wyatt", "Xiomara", "Yancy", "Zinnia", "Amelia", "Barnaby", "Calliope", "Drake", "Estelle", "Foster", "Greer", "Hollis", "Irene", "Jericho", "Klara", "Logan", "Mavis", "Nico", "Oakley", "Pascal", "Quito", "Rhett", "Scout", "Theron", "Unity", "Vance", "Winifred", "Xola", "Yvonne", "Zev", "Atticus", "Brenda", "Crispin", "Dolores", "Eustace", "Felicity", "Granger", "Hazel", "Idris", "Jovi", "Kasper", "Lyric", "Magnus", "Noor", "Otis", "Phoebe", "Querubin", "Rosalind", "Silas", "Tatum", "Upton", "Vivian", "Wendell", "Xuxa", "Yann", "Zora"];
|
|
31
|
-
export type NameKind = "session" | "subagent" | "transient";
|
|
38
|
+
export type NameKind = "session" | "subagent" | "transient" | "workflow-child";
|
|
32
39
|
export interface NameHistoryRow {
|
|
33
40
|
instance_id: string;
|
|
34
41
|
name: string;
|
|
@@ -74,12 +81,38 @@ export interface NameAssumptionResult {
|
|
|
74
81
|
* this auditable and retry-safe without mutating prior assignment history.
|
|
75
82
|
*/
|
|
76
83
|
export declare function recordNameAssumption(coordRoot: string, instanceId: string, name: string, agentId: string, kind?: NameKind): NameAssumptionResult;
|
|
84
|
+
/**
|
|
85
|
+
* Names a live agent currently holds, read from the generation-bound heartbeat
|
|
86
|
+
* cache (`.harnery/active/<instance>.json`).
|
|
87
|
+
*
|
|
88
|
+
* Deliberately reads the cache directly rather than the V3 coordination view:
|
|
89
|
+
* that view imports `resolveName` from this module, so depending on it here
|
|
90
|
+
* would build an import cycle. The cache is the same set the view materializes
|
|
91
|
+
* from and is pruned as sessions end, so it answers "is this name taken right
|
|
92
|
+
* now" without one.
|
|
93
|
+
*
|
|
94
|
+
* Both error directions are safe for the caller. A stale row that slips past
|
|
95
|
+
* the freshness window costs one skipped pool slot; a live agent missing from
|
|
96
|
+
* the cache just restores the old counter-only behavior for that assignment.
|
|
97
|
+
*/
|
|
98
|
+
export declare function readLiveNames(coordRoot: string, opts: {
|
|
99
|
+
freshnessSecs: number;
|
|
100
|
+
nowMs?: number;
|
|
101
|
+
}): Set<string>;
|
|
77
102
|
/**
|
|
78
103
|
* Assign a name to <instanceId> with the given <kind>. Counter-consuming when
|
|
79
104
|
* the owner is new. Idempotent: returns existing name on resume.
|
|
105
|
+
*
|
|
106
|
+
* Slot choice probes forward from the counter and takes the first name no live
|
|
107
|
+
* agent holds, then advances the counter past every slot it skipped so the skip
|
|
108
|
+
* is durable rather than re-probed on the next assignment. A full lap without a
|
|
109
|
+
* free name means all 260 are genuinely live, so the raw counter slot is used:
|
|
110
|
+
* a duplicate name beats refusing to name an agent at all.
|
|
80
111
|
*/
|
|
81
|
-
export declare function assignName(coordRoot: string, instanceId: string, kind: NameKind, opts
|
|
112
|
+
export declare function assignName(coordRoot: string, instanceId: string, kind: NameKind, opts: {
|
|
113
|
+
freshnessSecs: number;
|
|
82
114
|
forkedFrom?: string;
|
|
115
|
+
nowMs?: number;
|
|
83
116
|
}): string;
|
|
84
117
|
/** One step of recorded fork lineage: the latest row for <instanceId> that
|
|
85
118
|
* carries `forked_from` (latest-row-wins, matching resolveName). */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"names.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/state/names.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"names.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/state/names.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAYH,qBAAqB;AACrB,eAAO,MAAM,WAAW,85EA+Qd,CAAC;AAMX,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,UAAU,GAAG,WAAW,GAAG,gBAAgB,CAAC;AAE/E,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,QAAQ,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;IACX,oEAAoE;IACpE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kFAAkF;IAClF,MAAM,CAAC,EAAE,MAAM,GAAG,iBAAiB,CAAC;IACpC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;2DAEuD;IACvD,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAsCD;;;;;;GAMG;AACH,wBAAgB,WAAW,CACzB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,SAAS,CAAC,EAAE,MAAM,GACjB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CA4B5D;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,QAAQ,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACrE,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,QAAQ,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;CAC7D;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,QAAoB,GACzB,oBAAoB,CAoBtB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,aAAa,CAC3B,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE;IAAE,aAAa,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAC9C,GAAG,CAAC,MAAM,CAAC,CA4Bb;AAED;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CACxB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,QAAQ,EACd,IAAI,EAAE;IAAE,aAAa,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GACnE,MAAM,CA4CR;AAED;oEACoE;AACpE,wBAAgB,cAAc,CAC5B,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAAG,IAAI,CAUrD;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB,KAAK,CAAC;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,CAYrD"}
|
|
@@ -25,8 +25,15 @@
|
|
|
25
25
|
* new binding instead of rewriting history; readers therefore resolve from the
|
|
26
26
|
* end of the file. Older one-row histories retain their original behavior.
|
|
27
27
|
* 3. Else: new assignment, consume a counter slot.
|
|
28
|
+
*
|
|
29
|
+
* Live-name skip: the pool holds 260 names and a busy repo consumes ~100 a
|
|
30
|
+
* day, so the counter wraps roughly every three days while sessions that
|
|
31
|
+
* resume under a stable instance_id keep a name for far longer. A counter-only
|
|
32
|
+
* pick therefore hands a live agent's name to a new one (observed 2026-09-06:
|
|
33
|
+
* two concurrent "Maya" agents, their pool slots exactly 520 apart). Assignment
|
|
34
|
+
* now probes forward past any name a fresh heartbeat still holds.
|
|
28
35
|
*/
|
|
29
|
-
import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
|
|
36
|
+
import { existsSync, mkdirSync, readdirSync, readFileSync, renameSync, writeFileSync, } from "node:fs";
|
|
30
37
|
import { dirname, join } from "node:path";
|
|
31
38
|
/** All 260 names. */
|
|
32
39
|
export const COORD_NAMES = [
|
|
@@ -393,9 +400,62 @@ export function recordNameAssumption(coordRoot, instanceId, name, agentId, kind
|
|
|
393
400
|
});
|
|
394
401
|
return { changed: true, previous, current };
|
|
395
402
|
}
|
|
403
|
+
/**
|
|
404
|
+
* Names a live agent currently holds, read from the generation-bound heartbeat
|
|
405
|
+
* cache (`.harnery/active/<instance>.json`).
|
|
406
|
+
*
|
|
407
|
+
* Deliberately reads the cache directly rather than the V3 coordination view:
|
|
408
|
+
* that view imports `resolveName` from this module, so depending on it here
|
|
409
|
+
* would build an import cycle. The cache is the same set the view materializes
|
|
410
|
+
* from and is pruned as sessions end, so it answers "is this name taken right
|
|
411
|
+
* now" without one.
|
|
412
|
+
*
|
|
413
|
+
* Both error directions are safe for the caller. A stale row that slips past
|
|
414
|
+
* the freshness window costs one skipped pool slot; a live agent missing from
|
|
415
|
+
* the cache just restores the old counter-only behavior for that assignment.
|
|
416
|
+
*/
|
|
417
|
+
export function readLiveNames(coordRoot, opts) {
|
|
418
|
+
const live = new Set();
|
|
419
|
+
const dir = join(coordRoot, ".harnery", "active");
|
|
420
|
+
let entries;
|
|
421
|
+
try {
|
|
422
|
+
entries = readdirSync(dir);
|
|
423
|
+
}
|
|
424
|
+
catch {
|
|
425
|
+
return live; // No cache yet (fresh checkout) → nothing is live.
|
|
426
|
+
}
|
|
427
|
+
const nowMs = opts.nowMs ?? Date.now();
|
|
428
|
+
const cutoffMs = nowMs - opts.freshnessSecs * 1000;
|
|
429
|
+
for (const entry of entries) {
|
|
430
|
+
if (!entry.endsWith(".json"))
|
|
431
|
+
continue;
|
|
432
|
+
let row;
|
|
433
|
+
try {
|
|
434
|
+
row = JSON.parse(readFileSync(join(dir, entry), "utf8"));
|
|
435
|
+
}
|
|
436
|
+
catch {
|
|
437
|
+
continue; // A torn or half-written row cannot prove a name is held.
|
|
438
|
+
}
|
|
439
|
+
if (typeof row.name !== "string" || row.name.length === 0)
|
|
440
|
+
continue;
|
|
441
|
+
if (typeof row.last_heartbeat !== "string")
|
|
442
|
+
continue;
|
|
443
|
+
const beatMs = Date.parse(row.last_heartbeat);
|
|
444
|
+
if (!Number.isFinite(beatMs) || beatMs < cutoffMs)
|
|
445
|
+
continue;
|
|
446
|
+
live.add(row.name);
|
|
447
|
+
}
|
|
448
|
+
return live;
|
|
449
|
+
}
|
|
396
450
|
/**
|
|
397
451
|
* Assign a name to <instanceId> with the given <kind>. Counter-consuming when
|
|
398
452
|
* the owner is new. Idempotent: returns existing name on resume.
|
|
453
|
+
*
|
|
454
|
+
* Slot choice probes forward from the counter and takes the first name no live
|
|
455
|
+
* agent holds, then advances the counter past every slot it skipped so the skip
|
|
456
|
+
* is durable rather than re-probed on the next assignment. A full lap without a
|
|
457
|
+
* free name means all 260 are genuinely live, so the raw counter slot is used:
|
|
458
|
+
* a duplicate name beats refusing to name an agent at all.
|
|
399
459
|
*/
|
|
400
460
|
export function assignName(coordRoot, instanceId, kind, opts) {
|
|
401
461
|
// Check 1: existing history row → original name. A resume re-enters here,
|
|
@@ -404,7 +464,14 @@ export function assignName(coordRoot, instanceId, kind, opts) {
|
|
|
404
464
|
const existing = resolveName(coordRoot, instanceId);
|
|
405
465
|
if (existing)
|
|
406
466
|
return existing.name;
|
|
407
|
-
// New owner: consume a counter slot.
|
|
467
|
+
// New owner: consume a counter slot. The live set is gathered BEFORE the
|
|
468
|
+
// counter read on purpose. Counter read-modify-write is already unlocked, so
|
|
469
|
+
// concurrent assignments can collide on one slot; doing the directory scan
|
|
470
|
+
// first keeps that window exactly as narrow as it was before the skip existed.
|
|
471
|
+
const live = readLiveNames(coordRoot, {
|
|
472
|
+
freshnessSecs: opts.freshnessSecs,
|
|
473
|
+
...(opts.nowMs !== undefined ? { nowMs: opts.nowMs } : {}),
|
|
474
|
+
});
|
|
408
475
|
const cPath = counterPath(coordRoot);
|
|
409
476
|
let counter = 0;
|
|
410
477
|
if (existsSync(cPath)) {
|
|
@@ -412,9 +479,17 @@ export function assignName(coordRoot, instanceId, kind, opts) {
|
|
|
412
479
|
if (/^\d+$/.test(raw))
|
|
413
480
|
counter = Number.parseInt(raw, 10);
|
|
414
481
|
}
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
482
|
+
let chosen = counter;
|
|
483
|
+
for (let probe = 0; probe < 260; probe++) {
|
|
484
|
+
const candidate = COORD_NAMES[(counter + probe) % 260];
|
|
485
|
+
if (!live.has(candidate)) {
|
|
486
|
+
chosen = counter + probe;
|
|
487
|
+
break;
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
const name = COORD_NAMES[chosen % 260];
|
|
491
|
+
atomicWrite(cPath, String(chosen + 1));
|
|
492
|
+
const forkedFrom = opts.forkedFrom;
|
|
418
493
|
appendHistory(coordRoot, {
|
|
419
494
|
instance_id: instanceId,
|
|
420
495
|
name,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Stale-sweep: prune dead heartbeats + orphaned pid-map +
|
|
2
|
+
* Stale-sweep: prune dead heartbeats + orphaned pid-map + prompt hash
|
|
3
3
|
* files.
|
|
4
4
|
*
|
|
5
5
|
* Runs after session.started to clean up crashed-peer detritus before the new
|
|
@@ -13,5 +13,6 @@ export declare function staleSweep(coordRoot: string): {
|
|
|
13
13
|
heartbeatsRemoved: string[];
|
|
14
14
|
pidmapsRemoved: number;
|
|
15
15
|
peerHashesRemoved: number;
|
|
16
|
+
resourceHashesRemoved: number;
|
|
16
17
|
};
|
|
17
18
|
//# sourceMappingURL=stale-sweep.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stale-sweep.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/state/stale-sweep.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;
|
|
1
|
+
{"version":3,"file":"stale-sweep.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/state/stale-sweep.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAyEH,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG;IAC7C,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,qBAAqB,EAAE,MAAM,CAAC;CAC/B,CAyJA"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Stale-sweep: prune dead heartbeats + orphaned pid-map +
|
|
2
|
+
* Stale-sweep: prune dead heartbeats + orphaned pid-map + prompt hash
|
|
3
3
|
* files.
|
|
4
4
|
*
|
|
5
5
|
* Runs after session.started to clean up crashed-peer detritus before the new
|
|
@@ -20,6 +20,8 @@ function adapterFromPlatform(platform) {
|
|
|
20
20
|
return "cursor";
|
|
21
21
|
if (platform === "codex")
|
|
22
22
|
return "codex";
|
|
23
|
+
if (platform === "openclaw")
|
|
24
|
+
return "openclaw";
|
|
23
25
|
return "claude-code";
|
|
24
26
|
}
|
|
25
27
|
/**
|
|
@@ -72,6 +74,7 @@ export function staleSweep(coordRoot) {
|
|
|
72
74
|
const heartbeatsRemoved = [];
|
|
73
75
|
let pidmapsRemoved = 0;
|
|
74
76
|
let peerHashesRemoved = 0;
|
|
77
|
+
let resourceHashesRemoved = 0;
|
|
75
78
|
const freshness = coordFreshnessSeconds(coordRoot);
|
|
76
79
|
const nowSec = Math.floor(Date.now() / 1000);
|
|
77
80
|
const cutoff = nowSec - freshness;
|
|
@@ -173,17 +176,31 @@ export function staleSweep(coordRoot) {
|
|
|
173
176
|
}
|
|
174
177
|
}
|
|
175
178
|
}
|
|
176
|
-
// 3. Prune
|
|
179
|
+
// 3. Prune prompt hashes for dead owners. Resource hashes retain their own
|
|
180
|
+
// count so existing peer-hash telemetry keeps its original meaning.
|
|
177
181
|
const agentsDir = join(coordRoot, ".harnery");
|
|
178
182
|
if (existsSync(agentsDir)) {
|
|
179
183
|
for (const f of readdirSync(agentsDir)) {
|
|
180
|
-
|
|
184
|
+
const resourceHash = f.startsWith(".last-resource-hash.");
|
|
185
|
+
const prefix = resourceHash ? ".last-resource-hash." : ".last-peer-hash.";
|
|
186
|
+
if (!f.startsWith(prefix))
|
|
181
187
|
continue;
|
|
182
|
-
const owner = f.slice(
|
|
188
|
+
const owner = f.slice(prefix.length);
|
|
189
|
+
if (resourceHash) {
|
|
190
|
+
// Ignore atomic-write temporary files and preserve hashes when a
|
|
191
|
+
// retained heartbeat's liveness could not be determined safely.
|
|
192
|
+
if (!/^[A-Za-z0-9_-]{1,128}$/.test(owner))
|
|
193
|
+
continue;
|
|
194
|
+
if (existsSync(join(d, `${owner}.json`)))
|
|
195
|
+
continue;
|
|
196
|
+
}
|
|
183
197
|
if (!liveInstanceIds.has(owner)) {
|
|
184
198
|
try {
|
|
185
199
|
unlinkSync(join(agentsDir, f));
|
|
186
|
-
|
|
200
|
+
if (resourceHash)
|
|
201
|
+
resourceHashesRemoved += 1;
|
|
202
|
+
else
|
|
203
|
+
peerHashesRemoved += 1;
|
|
187
204
|
}
|
|
188
205
|
catch {
|
|
189
206
|
/* swallow */
|
|
@@ -191,5 +208,5 @@ export function staleSweep(coordRoot) {
|
|
|
191
208
|
}
|
|
192
209
|
}
|
|
193
210
|
}
|
|
194
|
-
return { heartbeatsRemoved, pidmapsRemoved, peerHashesRemoved };
|
|
211
|
+
return { heartbeatsRemoved, pidmapsRemoved, peerHashesRemoved, resourceHashesRemoved };
|
|
195
212
|
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How long the current turn has been running, for the closing status box.
|
|
3
|
+
*
|
|
4
|
+
* The box already reports `session`, which is cumulative and says nothing
|
|
5
|
+
* about the work just done: a 9-minute session hides whether this turn took
|
|
6
|
+
* twelve seconds or eight minutes. `turn` measures from the operator's prompt
|
|
7
|
+
* (`turn.started`) to the moment the box renders, so the operator reads the
|
|
8
|
+
* cost of the turn they are about to be handed.
|
|
9
|
+
*
|
|
10
|
+
* Every read here is best-effort by contract. A missing ledger, an
|
|
11
|
+
* unvalidated one, or no `turn.started` for this owner renders no row rather
|
|
12
|
+
* than failing the status command.
|
|
13
|
+
*/
|
|
14
|
+
import type { EventV3 } from "../events/v3/contract.js";
|
|
15
|
+
export interface TurnElapsed {
|
|
16
|
+
/** Seconds from the turn's start to its terminal, or to `now` while open. */
|
|
17
|
+
secs: number;
|
|
18
|
+
/** True once a `turn.completed` closed the turn this measures. */
|
|
19
|
+
complete: boolean;
|
|
20
|
+
/** Stop-hook restarts folded into this measurement. */
|
|
21
|
+
remediation_restarts: number;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Measure the newest turn for `instanceId` from an already-read event stream.
|
|
25
|
+
*
|
|
26
|
+
* A Stop-hook bounce ends one `turn.started` and opens another carrying
|
|
27
|
+
* `stop_remediation`. The operator experiences those as one turn, so the walk
|
|
28
|
+
* back over remediation restarts reports elapsed time since their prompt, not
|
|
29
|
+
* since the last retry. The walk stays inside one generation: a resumed
|
|
30
|
+
* session must not absorb the previous generation's turn into its own.
|
|
31
|
+
*/
|
|
32
|
+
export declare function resolveTurnElapsed(events: readonly EventV3[], instanceId: string, now?: number): TurnElapsed | null;
|
|
33
|
+
/**
|
|
34
|
+
* Render a turn duration for the box. Seconds stay visible below an hour
|
|
35
|
+
* because most turns land there and a bare `4m` cannot be compared with the
|
|
36
|
+
* turn before it.
|
|
37
|
+
*/
|
|
38
|
+
export declare function formatTurnElapsed(secs: number): string;
|
|
39
|
+
export interface TurnElapsedTarget {
|
|
40
|
+
coordRoot: string;
|
|
41
|
+
instanceId: string;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* The whole status-box contribution in one best-effort call: read the ledger
|
|
45
|
+
* and render this session's `turn` row. Null means render no row.
|
|
46
|
+
*/
|
|
47
|
+
export declare function turnElapsedStatusRow(target: TurnElapsedTarget, now?: number): {
|
|
48
|
+
value: string;
|
|
49
|
+
elapsed: TurnElapsed;
|
|
50
|
+
} | null;
|
|
51
|
+
//# sourceMappingURL=turn-elapsed.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"turn-elapsed.d.ts","sourceRoot":"","sources":["../../../src/core/agents/turn-elapsed.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AAOxD,MAAM,WAAW,WAAW;IAC1B,6EAA6E;IAC7E,IAAI,EAAE,MAAM,CAAC;IACb,kEAAkE;IAClE,QAAQ,EAAE,OAAO,CAAC;IAClB,uDAAuD;IACvD,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAWD;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,SAAS,OAAO,EAAE,EAC1B,UAAU,EAAE,MAAM,EAClB,GAAG,GAAE,MAAmB,GACvB,WAAW,GAAG,IAAI,CA0CpB;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMtD;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,iBAAiB,EACzB,GAAG,GAAE,MAAmB,GACvB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,WAAW,CAAA;CAAE,GAAG,IAAI,CAchD"}
|