harnery 0.35.0 → 0.36.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/commander.d.ts +30 -5
- package/dist/commander.d.ts.map +1 -1
- package/dist/commander.js +124 -96
- package/dist/commands/agents.d.ts +23 -3
- package/dist/commands/agents.d.ts.map +1 -1
- package/dist/commands/agents.js +379 -198
- package/dist/commands/backup.d.ts.map +1 -1
- package/dist/commands/backup.js +10 -10
- package/dist/commands/browse-session.d.ts.map +1 -1
- package/dist/commands/browse-session.js +12 -0
- package/dist/commands/browse.d.ts +1 -1
- package/dist/commands/browse.d.ts.map +1 -1
- package/dist/commands/browse.js +5 -4
- package/dist/commands/conversations.d.ts +10 -0
- package/dist/commands/conversations.d.ts.map +1 -0
- package/dist/commands/conversations.js +201 -0
- package/dist/commands/deinit.d.ts.map +1 -1
- package/dist/commands/deinit.js +5 -0
- package/dist/commands/docs.d.ts.map +1 -1
- package/dist/commands/docs.js +13 -2
- package/dist/commands/doctor.d.ts +5 -0
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +51 -7
- package/dist/commands/fetch.js +6 -5
- package/dist/commands/files.d.ts +22 -0
- package/dist/commands/files.d.ts.map +1 -0
- package/dist/commands/files.js +113 -0
- package/dist/commands/governor.js +14 -12
- package/dist/commands/inbox.d.ts +5 -0
- package/dist/commands/inbox.d.ts.map +1 -0
- package/dist/commands/inbox.js +57 -0
- package/dist/commands/init.d.ts +4 -5
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +63 -13
- package/dist/commands/ledger-v3.d.ts.map +1 -1
- package/dist/commands/ledger-v3.js +347 -1
- package/dist/commands/logs.d.ts +4 -0
- package/dist/commands/logs.d.ts.map +1 -0
- package/dist/commands/logs.js +169 -0
- package/dist/commands/messages.d.ts +5 -0
- package/dist/commands/messages.d.ts.map +1 -0
- package/dist/commands/messages.js +45 -0
- package/dist/commands/outline.d.ts +1 -1
- package/dist/commands/outline.d.ts.map +1 -1
- package/dist/commands/outline.js +2 -2
- package/dist/commands/read.d.ts +1 -1
- package/dist/commands/read.d.ts.map +1 -1
- package/dist/commands/read.js +2 -2
- package/dist/commands/semantic.d.ts.map +1 -1
- package/dist/commands/semantic.js +54 -2
- package/dist/commands/storage.d.ts +4 -0
- package/dist/commands/storage.d.ts.map +1 -0
- package/dist/commands/storage.js +238 -0
- package/dist/commands/tunnel.d.ts +5 -1
- package/dist/commands/tunnel.d.ts.map +1 -1
- package/dist/commands/tunnel.js +44 -31
- package/dist/commands/web.d.ts +3 -0
- package/dist/commands/web.d.ts.map +1 -1
- package/dist/commands/web.js +67 -7
- package/dist/commands/work.js +3 -3
- package/dist/commands/workflow.js +13 -13
- package/dist/core/adapters/profiles.d.ts +1 -1
- package/dist/core/agents/cli.js +209 -39
- package/dist/core/agents/live-authority-v3.d.ts +47 -1
- package/dist/core/agents/live-authority-v3.d.ts.map +1 -1
- package/dist/core/agents/live-authority-v3.js +244 -10
- package/dist/core/agents/live-lifecycle-v3.js +6 -1
- package/dist/core/agents/live-observation-v3.d.ts.map +1 -1
- package/dist/core/agents/live-observation-v3.js +6 -1
- package/dist/core/agents/render/prompt-context.d.ts +9 -3
- package/dist/core/agents/render/prompt-context.d.ts.map +1 -1
- package/dist/core/agents/render/prompt-context.js +24 -7
- package/dist/core/agents/rules/stop-hook.d.ts +2 -0
- package/dist/core/agents/rules/stop-hook.d.ts.map +1 -1
- package/dist/core/agents/rules/stop-hook.js +94 -13
- package/dist/core/agents/rules/verdict.d.ts +1 -0
- package/dist/core/agents/rules/verdict.d.ts.map +1 -1
- package/dist/core/agents/session-events.d.ts.map +1 -1
- package/dist/core/agents/session-events.js +4 -0
- package/dist/core/agents/session-finalization-state-v3.js +1 -1
- package/dist/core/agents/session-finalizer-v3.js +5 -1
- package/dist/core/agents/state/activity-log.d.ts +3 -0
- package/dist/core/agents/state/activity-log.d.ts.map +1 -1
- package/dist/core/agents/state/activity-log.js +6 -3
- package/dist/core/agents/state/heartbeat-writer.d.ts +6 -0
- package/dist/core/agents/state/heartbeat-writer.d.ts.map +1 -1
- package/dist/core/agents/state/heartbeat-writer.js +18 -0
- package/dist/core/agents/state/live-coordination-view.d.ts +5 -7
- package/dist/core/agents/state/live-coordination-view.d.ts.map +1 -1
- package/dist/core/agents/state/live-coordination-view.js +15 -90
- package/dist/core/agents/state/live-coordination-writer.d.ts +12 -0
- package/dist/core/agents/state/live-coordination-writer.d.ts.map +1 -0
- package/dist/core/agents/state/live-coordination-writer.js +92 -0
- package/dist/core/artifacts/index.d.ts +21 -0
- package/dist/core/artifacts/index.d.ts.map +1 -1
- package/dist/core/artifacts/index.js +46 -1
- package/dist/core/config.d.ts +62 -4
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +98 -4
- package/dist/core/conversations/archive.d.ts +49 -0
- package/dist/core/conversations/archive.d.ts.map +1 -0
- package/dist/core/conversations/archive.js +136 -0
- package/dist/core/conversations/catalog.d.ts +10 -0
- package/dist/core/conversations/catalog.d.ts.map +1 -0
- package/dist/core/conversations/catalog.js +72 -0
- package/dist/core/conversations/context-pack.d.ts +6 -0
- package/dist/core/conversations/context-pack.d.ts.map +1 -0
- package/dist/core/conversations/context-pack.js +60 -0
- package/dist/core/conversations/contract.d.ts +155 -0
- package/dist/core/conversations/contract.d.ts.map +1 -0
- package/dist/core/conversations/contract.js +1 -0
- package/dist/core/conversations/evaluation.d.ts +16 -0
- package/dist/core/conversations/evaluation.d.ts.map +1 -0
- package/dist/core/conversations/evaluation.js +9 -0
- package/dist/core/conversations/index.d.ts +10 -0
- package/dist/core/conversations/index.d.ts.map +1 -0
- package/dist/core/conversations/index.js +9 -0
- package/dist/core/conversations/lifecycle.d.ts +28 -0
- package/dist/core/conversations/lifecycle.d.ts.map +1 -0
- package/dist/core/conversations/lifecycle.js +29 -0
- package/dist/core/conversations/normalize.d.ts +14 -0
- package/dist/core/conversations/normalize.d.ts.map +1 -0
- package/dist/core/conversations/normalize.js +82 -0
- package/dist/core/conversations/query.d.ts +8 -0
- package/dist/core/conversations/query.d.ts.map +1 -0
- package/dist/core/conversations/query.js +280 -0
- package/dist/core/conversations/search-index.d.ts +9 -0
- package/dist/core/conversations/search-index.d.ts.map +1 -0
- package/dist/core/conversations/search-index.js +29 -0
- package/dist/core/events/legacy-storage/canary.d.ts +18 -0
- package/dist/core/events/legacy-storage/canary.d.ts.map +1 -0
- package/dist/core/events/legacy-storage/canary.js +150 -0
- package/dist/core/events/legacy-storage/fence.d.ts +15 -0
- package/dist/core/events/legacy-storage/fence.d.ts.map +1 -0
- package/dist/core/events/legacy-storage/fence.js +115 -0
- package/dist/core/events/legacy-storage/index.d.ts +6 -0
- package/dist/core/events/legacy-storage/index.d.ts.map +1 -0
- package/dist/core/events/legacy-storage/index.js +5 -0
- package/dist/core/events/legacy-storage/inventory.d.ts +10 -0
- package/dist/core/events/legacy-storage/inventory.d.ts.map +1 -0
- package/dist/core/events/legacy-storage/inventory.js +40 -0
- package/dist/core/events/legacy-storage/manifest.d.ts +23 -0
- package/dist/core/events/legacy-storage/manifest.d.ts.map +1 -0
- package/dist/core/events/legacy-storage/manifest.js +108 -0
- package/dist/core/events/legacy-storage/reader.d.ts +15 -0
- package/dist/core/events/legacy-storage/reader.d.ts.map +1 -0
- package/dist/core/events/legacy-storage/reader.js +154 -0
- package/dist/core/events/v3/authority-outbox.d.ts +7 -2
- package/dist/core/events/v3/authority-outbox.d.ts.map +1 -1
- package/dist/core/events/v3/authority-outbox.js +16 -3
- package/dist/core/events/v3/base-contract.d.ts +81 -41
- package/dist/core/events/v3/base-contract.d.ts.map +1 -1
- package/dist/core/events/v3/base-contract.js +17 -7
- package/dist/core/events/v3/bootstrap.d.ts +39 -0
- package/dist/core/events/v3/bootstrap.d.ts.map +1 -1
- package/dist/core/events/v3/bootstrap.js +167 -3
- package/dist/core/events/v3/capabilities.js +3 -3
- package/dist/core/events/v3/control-witness.d.ts +44 -0
- package/dist/core/events/v3/control-witness.d.ts.map +1 -0
- package/dist/core/events/v3/control-witness.js +233 -0
- package/dist/core/events/v3/control-writer.d.ts +4 -0
- package/dist/core/events/v3/control-writer.d.ts.map +1 -0
- package/dist/core/events/v3/control-writer.js +16 -0
- package/dist/core/events/v3/control.d.ts +8 -2
- package/dist/core/events/v3/control.d.ts.map +1 -1
- package/dist/core/events/v3/control.js +46 -18
- package/dist/core/events/v3/coordination-transaction-recovery.d.ts +42 -0
- package/dist/core/events/v3/coordination-transaction-recovery.d.ts.map +1 -0
- package/dist/core/events/v3/coordination-transaction-recovery.js +342 -0
- package/dist/core/events/v3/coordination-view.d.ts.map +1 -1
- package/dist/core/events/v3/coordination-view.js +16 -1
- package/dist/core/events/v3/generated.d.ts +1 -1
- package/dist/core/events/v3/generated.js +1 -1
- package/dist/core/events/v3/index.d.ts +4 -2
- package/dist/core/events/v3/index.d.ts.map +1 -1
- package/dist/core/events/v3/index.js +3 -1
- package/dist/core/events/v3/live-route-observer.d.ts +31 -0
- package/dist/core/events/v3/live-route-observer.d.ts.map +1 -0
- package/dist/core/events/v3/live-route-observer.js +58 -0
- package/dist/core/events/v3/live-routing.d.ts +13 -21
- package/dist/core/events/v3/live-routing.d.ts.map +1 -1
- package/dist/core/events/v3/live-routing.js +45 -41
- package/dist/core/events/v3/producers/coordination-recorder.d.ts +11 -1
- package/dist/core/events/v3/producers/coordination-recorder.d.ts.map +1 -1
- package/dist/core/events/v3/producers/coordination-recorder.js +76 -10
- package/dist/core/events/v3/producers/diagnostic-summaries.d.ts +129 -0
- package/dist/core/events/v3/producers/diagnostic-summaries.d.ts.map +1 -0
- package/dist/core/events/v3/producers/diagnostic-summaries.js +499 -0
- package/dist/core/events/v3/producers/hook-base.js +1 -1
- package/dist/core/events/v3/producers/intake.d.ts +7 -0
- package/dist/core/events/v3/producers/intake.d.ts.map +1 -1
- package/dist/core/events/v3/producers/intake.js +25 -2
- package/dist/core/events/v3/producers/producer-state-observer.d.ts +8 -0
- package/dist/core/events/v3/producers/producer-state-observer.d.ts.map +1 -0
- package/dist/core/events/v3/producers/producer-state-observer.js +45 -0
- package/dist/core/events/v3/producers/recorder.d.ts +55 -1
- package/dist/core/events/v3/producers/recorder.d.ts.map +1 -1
- package/dist/core/events/v3/producers/recorder.js +353 -24
- package/dist/core/events/v3/reader.d.ts +51 -0
- package/dist/core/events/v3/reader.d.ts.map +1 -1
- package/dist/core/events/v3/reader.js +181 -1
- package/dist/core/events/v3/rotation-config.d.ts +9 -0
- package/dist/core/events/v3/rotation-config.d.ts.map +1 -0
- package/dist/core/events/v3/rotation-config.js +91 -0
- package/dist/core/events/v3/runtime-build.d.ts +11 -0
- package/dist/core/events/v3/runtime-build.d.ts.map +1 -0
- package/dist/core/events/v3/runtime-build.js +39 -0
- package/dist/core/events/v3/runtime-identity.d.ts +5 -0
- package/dist/core/events/v3/runtime-identity.d.ts.map +1 -0
- package/dist/core/events/v3/runtime-identity.js +18 -0
- package/dist/core/events/v3/runtime-telemetry-capabilities.d.ts +6 -5
- package/dist/core/events/v3/runtime-telemetry-capabilities.d.ts.map +1 -1
- package/dist/core/events/v3/runtime-telemetry-capabilities.js +1 -1
- package/dist/core/events/v3/support-storage/classify.d.ts +46 -0
- package/dist/core/events/v3/support-storage/classify.d.ts.map +1 -0
- package/dist/core/events/v3/support-storage/classify.js +149 -0
- package/dist/core/events/v3/support-storage/eligibility.d.ts +29 -0
- package/dist/core/events/v3/support-storage/eligibility.d.ts.map +1 -0
- package/dist/core/events/v3/support-storage/eligibility.js +35 -0
- package/dist/core/events/v3/support-storage/index.d.ts +10 -0
- package/dist/core/events/v3/support-storage/index.d.ts.map +1 -0
- package/dist/core/events/v3/support-storage/index.js +9 -0
- package/dist/core/events/v3/support-storage/inventory.d.ts +30 -0
- package/dist/core/events/v3/support-storage/inventory.d.ts.map +1 -0
- package/dist/core/events/v3/support-storage/inventory.js +94 -0
- package/dist/core/events/v3/support-storage/logical-authority.d.ts +14 -0
- package/dist/core/events/v3/support-storage/logical-authority.d.ts.map +1 -0
- package/dist/core/events/v3/support-storage/logical-authority.js +104 -0
- package/dist/core/events/v3/support-storage/maintenance.d.ts +98 -0
- package/dist/core/events/v3/support-storage/maintenance.d.ts.map +1 -0
- package/dist/core/events/v3/support-storage/maintenance.js +352 -0
- package/dist/core/events/v3/support-storage/pack-contract.d.ts +59 -0
- package/dist/core/events/v3/support-storage/pack-contract.d.ts.map +1 -0
- package/dist/core/events/v3/support-storage/pack-contract.js +249 -0
- package/dist/core/events/v3/support-storage/pack-reader.d.ts +34 -0
- package/dist/core/events/v3/support-storage/pack-reader.d.ts.map +1 -0
- package/dist/core/events/v3/support-storage/pack-reader.js +258 -0
- package/dist/core/events/v3/support-storage/pack-writer.d.ts +30 -0
- package/dist/core/events/v3/support-storage/pack-writer.d.ts.map +1 -0
- package/dist/core/events/v3/support-storage/pack-writer.js +268 -0
- package/dist/core/events/v3/support-storage/recovery.d.ts +15 -0
- package/dist/core/events/v3/support-storage/recovery.d.ts.map +1 -0
- package/dist/core/events/v3/support-storage/recovery.js +22 -0
- package/dist/core/events/v3/turn-telemetry.d.ts +14 -8
- package/dist/core/events/v3/turn-telemetry.d.ts.map +1 -1
- package/dist/core/events/v3/turn-telemetry.js +32 -2
- package/dist/core/events/v3/writer.d.ts +13 -1
- package/dist/core/events/v3/writer.d.ts.map +1 -1
- package/dist/core/events/v3/writer.js +126 -12
- package/dist/core/governor/plan-read.d.ts.map +1 -1
- package/dist/core/governor/plan-read.js +5 -21
- package/dist/core/governor/planning.js +6 -8
- package/dist/core/governor/service-read.d.ts +12 -0
- package/dist/core/governor/service-read.d.ts.map +1 -1
- package/dist/core/governor/service-read.js +266 -2
- package/dist/core/governor/service.d.ts +1 -0
- package/dist/core/governor/service.d.ts.map +1 -1
- package/dist/core/governor/service.js +53 -18
- package/dist/core/guard/evidence-v3.d.ts.map +1 -1
- package/dist/core/guard/evidence-v3.js +2 -0
- package/dist/core/hooks/adapter/events.d.ts.map +1 -1
- package/dist/core/hooks/adapter/events.js +1 -0
- package/dist/core/hooks/adapter/output.d.ts +4 -2
- package/dist/core/hooks/adapter/output.d.ts.map +1 -1
- package/dist/core/hooks/adapter/output.js +13 -5
- package/dist/core/hooks/adapter/runtime-telemetry.d.ts +27 -4
- package/dist/core/hooks/adapter/runtime-telemetry.d.ts.map +1 -1
- package/dist/core/hooks/adapter/runtime-telemetry.js +307 -6
- package/dist/core/hooks/cli.js +212 -30
- package/dist/core/hooks/effects/image-capture.d.ts +1 -1
- package/dist/core/hooks/effects/image-capture.d.ts.map +1 -1
- package/dist/core/hooks/effects/image-capture.js +4 -2
- package/dist/core/hooks/remediation-cap.d.ts +8 -3
- package/dist/core/hooks/remediation-cap.d.ts.map +1 -1
- package/dist/core/hooks/remediation-cap.js +3 -11
- package/dist/core/hooks/resolve/coord-root.d.ts +22 -9
- package/dist/core/hooks/resolve/coord-root.d.ts.map +1 -1
- package/dist/core/hooks/resolve/coord-root.js +92 -11
- package/dist/core/hooks/resolve/owner.d.ts.map +1 -1
- package/dist/core/hooks/resolve/owner.js +5 -0
- package/dist/core/hooks/resolve/transcript.d.ts +8 -0
- package/dist/core/hooks/resolve/transcript.d.ts.map +1 -1
- package/dist/core/hooks/resolve/transcript.js +11 -0
- package/dist/core/inbox/contract.d.ts +64 -0
- package/dist/core/inbox/contract.d.ts.map +1 -0
- package/dist/core/inbox/contract.js +13 -0
- package/dist/core/inbox/index.d.ts +5 -0
- package/dist/core/inbox/index.d.ts.map +1 -0
- package/dist/core/inbox/index.js +4 -0
- package/dist/core/inbox/lifecycle.d.ts +22 -0
- package/dist/core/inbox/lifecycle.d.ts.map +1 -0
- package/dist/core/inbox/lifecycle.js +41 -0
- package/dist/core/inbox/service.d.ts +36 -0
- package/dist/core/inbox/service.d.ts.map +1 -0
- package/dist/core/inbox/service.js +210 -0
- package/dist/core/inbox/watcher.d.ts +7 -0
- package/dist/core/inbox/watcher.d.ts.map +1 -0
- package/dist/core/inbox/watcher.js +26 -0
- package/dist/core/presence/codec-digest.d.ts.map +1 -1
- package/dist/core/presence/codec-digest.js +14 -3
- package/dist/core/presence/relay-client.d.ts +1 -0
- package/dist/core/presence/relay-client.d.ts.map +1 -1
- package/dist/core/presence/relay-client.js +52 -8
- package/dist/core/semantic/adapters.d.ts +11 -8
- package/dist/core/semantic/adapters.d.ts.map +1 -1
- package/dist/core/semantic/adapters.js +169 -31
- package/dist/core/semantic/contract.d.ts +532 -48
- package/dist/core/semantic/contract.d.ts.map +1 -1
- package/dist/core/semantic/contract.js +104 -3
- package/dist/core/semantic/index.d.ts +7 -3
- package/dist/core/semantic/index.d.ts.map +1 -1
- package/dist/core/semantic/index.js +7 -3
- package/dist/core/semantic/once.d.ts +6 -1
- package/dist/core/semantic/once.d.ts.map +1 -1
- package/dist/core/semantic/once.js +80 -9
- package/dist/core/semantic/prompt.d.ts.map +1 -1
- package/dist/core/semantic/prompt.js +14 -1
- package/dist/core/semantic/review.d.ts +144 -0
- package/dist/core/semantic/review.d.ts.map +1 -0
- package/dist/core/semantic/review.js +544 -0
- package/dist/core/semantic/routes.d.ts +10 -0
- package/dist/core/semantic/routes.d.ts.map +1 -0
- package/dist/core/semantic/routes.js +21 -0
- package/dist/core/semantic/scheduler.d.ts +14 -3
- package/dist/core/semantic/scheduler.d.ts.map +1 -1
- package/dist/core/semantic/scheduler.js +30 -6
- package/dist/core/semantic/service-status.d.ts +20 -0
- package/dist/core/semantic/service-status.d.ts.map +1 -1
- package/dist/core/semantic/service-status.js +60 -4
- package/dist/core/semantic/service.d.ts +1 -0
- package/dist/core/semantic/service.d.ts.map +1 -1
- package/dist/core/semantic/service.js +104 -15
- package/dist/core/semantic/soak.d.ts +75 -0
- package/dist/core/semantic/soak.d.ts.map +1 -0
- package/dist/core/semantic/soak.js +476 -0
- package/dist/core/semantic/storage.d.ts +11 -1
- package/dist/core/semantic/storage.d.ts.map +1 -1
- package/dist/core/semantic/storage.js +4 -3
- package/dist/core/semantic/usage.d.ts +43 -0
- package/dist/core/semantic/usage.d.ts.map +1 -0
- package/dist/core/semantic/usage.js +193 -0
- package/dist/core/semantic/validate.d.ts +3 -1
- package/dist/core/semantic/validate.d.ts.map +1 -1
- package/dist/core/semantic/validate.js +34 -1
- package/dist/core/storage/buffer.d.ts +28 -0
- package/dist/core/storage/buffer.d.ts.map +1 -0
- package/dist/core/storage/buffer.js +101 -0
- package/dist/core/storage/builtins.d.ts +3 -0
- package/dist/core/storage/builtins.d.ts.map +1 -0
- package/dist/core/storage/builtins.js +683 -0
- package/dist/core/storage/catalog.d.ts +19 -0
- package/dist/core/storage/catalog.d.ts.map +1 -0
- package/dist/core/storage/catalog.js +365 -0
- package/dist/core/storage/config.d.ts +16 -0
- package/dist/core/storage/config.d.ts.map +1 -0
- package/dist/core/storage/config.js +311 -0
- package/dist/core/storage/contract.d.ts +275 -0
- package/dist/core/storage/contract.d.ts.map +1 -0
- package/dist/core/storage/contract.js +3 -0
- package/dist/core/storage/durable-history.d.ts +36 -0
- package/dist/core/storage/durable-history.d.ts.map +1 -0
- package/dist/core/storage/durable-history.js +606 -0
- package/dist/core/storage/health.d.ts +4 -0
- package/dist/core/storage/health.d.ts.map +1 -0
- package/dist/core/storage/health.js +65 -0
- package/dist/core/storage/index.d.ts +16 -0
- package/dist/core/storage/index.d.ts.map +1 -0
- package/dist/core/storage/index.js +15 -0
- package/dist/core/storage/inventory.d.ts +25 -0
- package/dist/core/storage/inventory.d.ts.map +1 -0
- package/dist/core/storage/inventory.js +666 -0
- package/dist/core/storage/jsonl.d.ts +52 -0
- package/dist/core/storage/jsonl.d.ts.map +1 -0
- package/dist/core/storage/jsonl.js +156 -0
- package/dist/core/storage/log-retention.d.ts +52 -0
- package/dist/core/storage/log-retention.d.ts.map +1 -0
- package/dist/core/storage/log-retention.js +419 -0
- package/dist/core/storage/logger.d.ts +82 -0
- package/dist/core/storage/logger.d.ts.map +1 -0
- package/dist/core/storage/logger.js +411 -0
- package/dist/core/storage/maintenance-providers.d.ts +26 -0
- package/dist/core/storage/maintenance-providers.d.ts.map +1 -0
- package/dist/core/storage/maintenance-providers.js +141 -0
- package/dist/core/storage/maintenance.d.ts +125 -0
- package/dist/core/storage/maintenance.d.ts.map +1 -0
- package/dist/core/storage/maintenance.js +609 -0
- package/dist/core/storage/metrics.d.ts +60 -0
- package/dist/core/storage/metrics.d.ts.map +1 -0
- package/dist/core/storage/metrics.js +134 -0
- package/dist/core/storage/policy.d.ts +7 -0
- package/dist/core/storage/policy.d.ts.map +1 -0
- package/dist/core/storage/policy.js +110 -0
- package/dist/core/storage/process-log.d.ts +38 -0
- package/dist/core/storage/process-log.d.ts.map +1 -0
- package/dist/core/storage/process-log.js +165 -0
- package/dist/core/storage/query.d.ts +34 -0
- package/dist/core/storage/query.d.ts.map +1 -0
- package/dist/core/storage/query.js +295 -0
- package/dist/core/storage/receipts.d.ts +23 -0
- package/dist/core/storage/receipts.d.ts.map +1 -0
- package/dist/core/storage/receipts.js +117 -0
- package/dist/core/storage/segments.d.ts +84 -0
- package/dist/core/storage/segments.d.ts.map +1 -0
- package/dist/core/storage/segments.js +542 -0
- package/dist/core/storage/sink-graph.d.ts +65 -0
- package/dist/core/storage/sink-graph.d.ts.map +1 -0
- package/dist/core/storage/sink-graph.js +213 -0
- package/dist/core/storage/storm-control.d.ts +23 -0
- package/dist/core/storage/storm-control.d.ts.map +1 -0
- package/dist/core/storage/storm-control.js +59 -0
- package/dist/core/work/state.d.ts.map +1 -1
- package/dist/core/work/state.js +10 -14
- package/dist/core/workflow/live-session-v3.d.ts.map +1 -1
- package/dist/core/workflow/live-session-v3.js +2 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/lazy-commands.d.ts +26 -0
- package/dist/lazy-commands.d.ts.map +1 -0
- package/dist/lazy-commands.js +210 -0
- package/dist/lib/docs-lint.d.ts +2 -0
- package/dist/lib/docs-lint.d.ts.map +1 -1
- package/dist/lib/docs-lint.js +45 -80
- package/dist/lib/docs-metadata-audit.d.ts +3 -0
- package/dist/lib/docs-metadata-audit.d.ts.map +1 -1
- package/dist/lib/docs-metadata-audit.js +13 -23
- package/dist/lib/docs-metadata-sync.d.ts +1 -0
- package/dist/lib/docs-metadata-sync.d.ts.map +1 -1
- package/dist/lib/docs-metadata-sync.js +28 -10
- package/dist/lib/docs-repository-view.d.ts +22 -0
- package/dist/lib/docs-repository-view.d.ts.map +1 -0
- package/dist/lib/docs-repository-view.js +185 -0
- package/dist/lib/http/client.d.ts +11 -5
- package/dist/lib/http/client.d.ts.map +1 -1
- package/dist/lib/http/client.js +22 -4
- package/dist/lib/http/index.d.ts +1 -1
- package/dist/lib/http/index.d.ts.map +1 -1
- package/dist/lib/http/index.js +1 -1
- package/dist/lib/indexer-exclusions.d.ts +27 -0
- package/dist/lib/indexer-exclusions.d.ts.map +1 -0
- package/dist/lib/indexer-exclusions.js +176 -0
- package/dist/lib/instructions/templates.d.ts.map +1 -1
- package/dist/lib/instructions/templates.js +5 -0
- package/dist/lib/local-file-url.d.ts +9 -0
- package/dist/lib/local-file-url.d.ts.map +1 -0
- package/dist/lib/local-file-url.js +20 -0
- package/dist/lib/web-performance.d.ts +118 -0
- package/dist/lib/web-performance.d.ts.map +1 -0
- package/dist/lib/web-performance.js +192 -0
- package/package.json +29 -2
- package/schemas/config.schema.json +58 -0
- package/schemas/event-v3.schema.json +324 -112
- package/src/commander.ts +462 -95
- package/src/commands/agents.ts +517 -190
- package/src/commands/backup.ts +18 -14
- package/src/commands/browse-session.ts +12 -0
- package/src/commands/browse.ts +6 -7
- package/src/commands/conversations.ts +279 -0
- package/src/commands/deinit.ts +6 -0
- package/src/commands/docs.ts +25 -6
- package/src/commands/doctor.ts +75 -9
- package/src/commands/fetch.ts +7 -6
- package/src/commands/files.ts +143 -0
- package/src/commands/governor.ts +13 -12
- package/src/commands/inbox.ts +61 -0
- package/src/commands/init.ts +78 -16
- package/src/commands/ledger-v3.ts +421 -1
- package/src/commands/logs.ts +224 -0
- package/src/commands/messages.ts +61 -0
- package/src/commands/outline.ts +6 -2
- package/src/commands/read.ts +6 -2
- package/src/commands/semantic.ts +66 -1
- package/src/commands/storage.ts +310 -0
- package/src/commands/tunnel.ts +66 -52
- package/src/commands/web.ts +77 -7
- package/src/commands/work.ts +3 -3
- package/src/commands/workflow.ts +13 -13
- package/src/core/agents/cli.ts +259 -53
- package/src/core/agents/live-authority-v3.ts +341 -10
- package/src/core/agents/live-lifecycle-v3.ts +6 -1
- package/src/core/agents/live-observation-v3.ts +6 -1
- package/src/core/agents/render/prompt-context.ts +27 -6
- package/src/core/agents/rules/stop-hook.ts +107 -16
- package/src/core/agents/rules/verdict.ts +1 -0
- package/src/core/agents/session-events.ts +4 -0
- package/src/core/agents/session-finalization-state-v3.ts +1 -1
- package/src/core/agents/session-finalizer-v3.ts +4 -1
- package/src/core/agents/state/activity-log.ts +7 -2
- package/src/core/agents/state/heartbeat-writer.ts +27 -0
- package/src/core/agents/state/live-coordination-view.ts +16 -105
- package/src/core/agents/state/live-coordination-writer.ts +141 -0
- package/src/core/artifacts/index.ts +64 -1
- package/src/core/config.ts +126 -5
- package/src/core/conversations/archive.ts +237 -0
- package/src/core/conversations/catalog.ts +79 -0
- package/src/core/conversations/context-pack.ts +72 -0
- package/src/core/conversations/contract.ts +178 -0
- package/src/core/conversations/evaluation.ts +30 -0
- package/src/core/conversations/index.ts +9 -0
- package/src/core/conversations/lifecycle.ts +63 -0
- package/src/core/conversations/normalize.ts +105 -0
- package/src/core/conversations/query.ts +318 -0
- package/src/core/conversations/search-index.ts +48 -0
- package/src/core/events/legacy-storage/canary.ts +177 -0
- package/src/core/events/legacy-storage/fence.ts +129 -0
- package/src/core/events/legacy-storage/index.ts +5 -0
- package/src/core/events/legacy-storage/inventory.ts +51 -0
- package/src/core/events/legacy-storage/manifest.ts +136 -0
- package/src/core/events/legacy-storage/reader.ts +178 -0
- package/src/core/events/v3/authority-outbox.ts +22 -1
- package/src/core/events/v3/base-contract.ts +17 -7
- package/src/core/events/v3/bootstrap.ts +195 -2
- package/src/core/events/v3/capabilities.ts +3 -3
- package/src/core/events/v3/control-witness.ts +339 -0
- package/src/core/events/v3/control-writer.ts +16 -0
- package/src/core/events/v3/control.ts +54 -18
- package/src/core/events/v3/coordination-transaction-recovery.ts +477 -0
- package/src/core/events/v3/coordination-view.ts +17 -1
- package/src/core/events/v3/generated.ts +1 -1
- package/src/core/events/v3/index.ts +5 -2
- package/src/core/events/v3/live-route-observer.ts +80 -0
- package/src/core/events/v3/live-routing.ts +64 -46
- package/src/core/events/v3/producers/coordination-recorder.ts +95 -10
- package/src/core/events/v3/producers/diagnostic-summaries.ts +593 -0
- package/src/core/events/v3/producers/hook-base.ts +1 -1
- package/src/core/events/v3/producers/intake.ts +30 -2
- package/src/core/events/v3/producers/producer-state-observer.ts +52 -0
- package/src/core/events/v3/producers/recorder.ts +571 -33
- package/src/core/events/v3/reader.ts +243 -2
- package/src/core/events/v3/rotation-config.ts +98 -0
- package/src/core/events/v3/runtime-build.ts +41 -0
- package/src/core/events/v3/runtime-identity.ts +16 -0
- package/src/core/events/v3/runtime-telemetry-capabilities.ts +14 -8
- package/src/core/events/v3/support-storage/classify.ts +209 -0
- package/src/core/events/v3/support-storage/eligibility.ts +58 -0
- package/src/core/events/v3/support-storage/index.ts +9 -0
- package/src/core/events/v3/support-storage/inventory.ts +135 -0
- package/src/core/events/v3/support-storage/logical-authority.ts +117 -0
- package/src/core/events/v3/support-storage/maintenance.ts +501 -0
- package/src/core/events/v3/support-storage/pack-contract.ts +337 -0
- package/src/core/events/v3/support-storage/pack-reader.ts +346 -0
- package/src/core/events/v3/support-storage/pack-writer.ts +352 -0
- package/src/core/events/v3/support-storage/recovery.ts +43 -0
- package/src/core/events/v3/turn-telemetry.ts +58 -7
- package/src/core/events/v3/writer.ts +168 -16
- package/src/core/governor/plan-read.ts +5 -18
- package/src/core/governor/planning.ts +5 -8
- package/src/core/governor/service-read.ts +320 -2
- package/src/core/governor/service.ts +49 -22
- package/src/core/guard/evidence-v3.ts +1 -0
- package/src/core/hooks/adapter/events.ts +1 -0
- package/src/core/hooks/adapter/output.ts +12 -5
- package/src/core/hooks/adapter/runtime-telemetry.ts +408 -13
- package/src/core/hooks/cli.ts +226 -32
- package/src/core/hooks/effects/image-capture.ts +4 -1
- package/src/core/hooks/remediation-cap.ts +12 -6
- package/src/core/hooks/resolve/coord-root.ts +91 -11
- package/src/core/hooks/resolve/owner.ts +4 -0
- package/src/core/hooks/resolve/transcript.ts +18 -0
- package/src/core/inbox/contract.ts +81 -0
- package/src/core/inbox/index.ts +4 -0
- package/src/core/inbox/lifecycle.ts +104 -0
- package/src/core/inbox/service.ts +305 -0
- package/src/core/inbox/watcher.ts +36 -0
- package/src/core/presence/codec-digest.ts +15 -9
- package/src/core/presence/relay-client.ts +55 -7
- package/src/core/semantic/adapters.ts +200 -41
- package/src/core/semantic/contract.ts +135 -3
- package/src/core/semantic/index.ts +76 -2
- package/src/core/semantic/once.ts +93 -7
- package/src/core/semantic/prompt.ts +13 -1
- package/src/core/semantic/review.ts +803 -0
- package/src/core/semantic/routes.ts +30 -0
- package/src/core/semantic/scheduler.ts +49 -5
- package/src/core/semantic/service-status.ts +99 -5
- package/src/core/semantic/service.ts +116 -15
- package/src/core/semantic/soak.ts +638 -0
- package/src/core/semantic/storage.ts +20 -6
- package/src/core/semantic/usage.ts +272 -0
- package/src/core/semantic/validate.ts +31 -0
- package/src/core/storage/buffer.ts +124 -0
- package/src/core/storage/builtins.ts +916 -0
- package/src/core/storage/catalog.ts +467 -0
- package/src/core/storage/config.ts +423 -0
- package/src/core/storage/contract.ts +342 -0
- package/src/core/storage/durable-history.ts +738 -0
- package/src/core/storage/health.ts +76 -0
- package/src/core/storage/index.ts +15 -0
- package/src/core/storage/inventory.ts +859 -0
- package/src/core/storage/jsonl.ts +213 -0
- package/src/core/storage/log-retention.ts +555 -0
- package/src/core/storage/logger.ts +546 -0
- package/src/core/storage/maintenance-providers.ts +200 -0
- package/src/core/storage/maintenance.ts +929 -0
- package/src/core/storage/metrics.ts +199 -0
- package/src/core/storage/policy.ts +141 -0
- package/src/core/storage/process-log.ts +203 -0
- package/src/core/storage/query.ts +360 -0
- package/src/core/storage/receipts.ts +162 -0
- package/src/core/storage/segments.ts +721 -0
- package/src/core/storage/sink-graph.ts +343 -0
- package/src/core/storage/storm-control.ts +91 -0
- package/src/core/work/state.ts +12 -21
- package/src/core/workflow/live-session-v3.ts +2 -4
- package/src/index.ts +2 -0
- package/src/lazy-commands.ts +294 -0
- package/src/lib/docs-lint.ts +58 -77
- package/src/lib/docs-metadata-audit.ts +26 -21
- package/src/lib/docs-metadata-sync.ts +32 -9
- package/src/lib/docs-repository-view.ts +220 -0
- package/src/lib/http/client.ts +44 -8
- package/src/lib/http/index.ts +6 -1
- package/src/lib/indexer-exclusions.ts +173 -0
- package/src/lib/instructions/templates.ts +5 -0
- package/src/lib/local-file-url.ts +31 -0
- package/src/lib/web-performance.ts +335 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { readFileSync, statSync } from "node:fs";
|
|
1
2
|
import { resolve } from "node:path";
|
|
2
|
-
import { createSemanticAdapters, discoverSemanticReaders, inspectSemanticDocument, readSemanticManifest, readSemanticServiceStatus, requestSemanticServiceStop, runSemanticOnce, runSemanticServiceDaemon, semanticPaths, spawnSemanticService, } from "../core/semantic/index.js";
|
|
3
|
+
import { createSemanticAdapters, discoverSemanticReaders, inspectSemanticDocument, prepareSemanticReviewStudy, readSemanticManifest, readSemanticServiceStatus, readSemanticSoakReport, requestSemanticServiceStop, runSemanticOnce, runSemanticServiceDaemon, semanticPaths, spawnSemanticService, storeSemanticReviewSubmission, } from "../core/semantic/index.js";
|
|
3
4
|
export function registerSemanticCommand(program, emit, context) {
|
|
4
5
|
const semantic = program
|
|
5
6
|
.command("semantic")
|
|
@@ -40,7 +41,7 @@ export function registerSemanticCommand(program, emit, context) {
|
|
|
40
41
|
});
|
|
41
42
|
service
|
|
42
43
|
.command("status")
|
|
43
|
-
.description("Show
|
|
44
|
+
.description("Show reader liveness, rolling calls, token usage, routes, and pending work")
|
|
44
45
|
.option("--root <path>", "Explicit coordination root")
|
|
45
46
|
.action((options) => {
|
|
46
47
|
try {
|
|
@@ -101,6 +102,57 @@ export function registerSemanticCommand(program, emit, context) {
|
|
|
101
102
|
emitFailure(emit, "semantic_inspect_failed", error);
|
|
102
103
|
}
|
|
103
104
|
});
|
|
105
|
+
semantic
|
|
106
|
+
.command("soak")
|
|
107
|
+
.description("Summarize recent reader outcomes, controlled cues, stability, and token usage")
|
|
108
|
+
.option("--root <path>", "Explicit coordination root")
|
|
109
|
+
.option("--minutes <count>", "Lookback window in whole minutes", integer)
|
|
110
|
+
.action((options) => {
|
|
111
|
+
try {
|
|
112
|
+
emit.data(readSemanticSoakReport(resolve(options.root ?? coordRoot(context)), {
|
|
113
|
+
...(options.minutes !== undefined ? { minutes: options.minutes } : {}),
|
|
114
|
+
}));
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
emitFailure(emit, "semantic_soak_failed", error);
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
const review = semantic
|
|
121
|
+
.command("review")
|
|
122
|
+
.description("Prepare and record a local human review of accepted semantic readings");
|
|
123
|
+
review
|
|
124
|
+
.command("prepare")
|
|
125
|
+
.description("Capture current accepted readings and return the next bounded review set")
|
|
126
|
+
.option("--root <path>", "Explicit coordination root")
|
|
127
|
+
.option("--limit <count>", "Maximum candidates in this review set", integer)
|
|
128
|
+
.action((options) => {
|
|
129
|
+
try {
|
|
130
|
+
emit.data(prepareSemanticReviewStudy(resolve(options.root ?? coordRoot(context)), {
|
|
131
|
+
...(options.limit !== undefined ? { limit: options.limit } : {}),
|
|
132
|
+
}));
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
emitFailure(emit, "semantic_review_prepare_failed", error);
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
review
|
|
139
|
+
.command("submit")
|
|
140
|
+
.description("Validate one frozen review set and store its controlled-label receipt")
|
|
141
|
+
.requiredOption("--file <path>", "JSON submission file")
|
|
142
|
+
.option("--root <path>", "Explicit coordination root")
|
|
143
|
+
.action((options) => {
|
|
144
|
+
try {
|
|
145
|
+
const file = resolve(options.file);
|
|
146
|
+
const size = statSync(file).size;
|
|
147
|
+
if (size <= 0 || size > 128 * 1024) {
|
|
148
|
+
throw new Error("semantic review submission has invalid size");
|
|
149
|
+
}
|
|
150
|
+
emit.data(storeSemanticReviewSubmission(resolve(options.root ?? coordRoot(context)), JSON.parse(readFileSync(file, "utf8"))));
|
|
151
|
+
}
|
|
152
|
+
catch (error) {
|
|
153
|
+
emitFailure(emit, "semantic_review_submit_failed", error);
|
|
154
|
+
}
|
|
155
|
+
});
|
|
104
156
|
semantic
|
|
105
157
|
.command("doctor")
|
|
106
158
|
.description("Inspect semantic reader availability without making a model request")
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Command } from "commander";
|
|
2
|
+
import type { EmitContext, HarneryProgramContext } from "../commander.js";
|
|
3
|
+
export declare function registerStorageCommand(program: Command, emit: EmitContext, context?: HarneryProgramContext): void;
|
|
4
|
+
//# sourceMappingURL=storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/commands/storage.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAwD1E,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,WAAW,EACjB,OAAO,CAAC,EAAE,qBAAqB,GAC9B,IAAI,CA+IN"}
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import { resolve } from "node:path";
|
|
2
|
+
import { resolveCoordRoot as resolveCanonicalCoordRoot } from "../core/agents/coord-client.js";
|
|
3
|
+
import { createStorageCatalog } from "../core/storage/catalog.js";
|
|
4
|
+
import { storageHealth } from "../core/storage/health.js";
|
|
5
|
+
import { filterStorageInventory, inventoryStorage } from "../core/storage/inventory.js";
|
|
6
|
+
import { DEFAULT_MAINTENANCE_BUDGET, executeStorageMaintenance, HARNERY_MAINTENANCE_PRESSURE_SCHEMA, HarneryMaintenanceError, listMaintenanceTransactions, planStorageMaintenance, readMaintenanceTransaction, } from "../core/storage/maintenance.js";
|
|
7
|
+
import { createStructuredLogMaintenanceProviders } from "../core/storage/maintenance-providers.js";
|
|
8
|
+
const STORAGE_CLASSES = new Set([
|
|
9
|
+
"canonical-authority",
|
|
10
|
+
"recovery-state",
|
|
11
|
+
"operational-log",
|
|
12
|
+
"debug-log",
|
|
13
|
+
"durable-object-history",
|
|
14
|
+
"repairable-cache",
|
|
15
|
+
"managed-artifact",
|
|
16
|
+
]);
|
|
17
|
+
export function registerStorageCommand(program, emit, context) {
|
|
18
|
+
const storage = program
|
|
19
|
+
.command("storage")
|
|
20
|
+
.description("Inspect registered Harnery storage without reading file bodies");
|
|
21
|
+
storage
|
|
22
|
+
.command("inventory")
|
|
23
|
+
.description("Inventory .harnery and explicitly registered external storage roots")
|
|
24
|
+
.option("--family <id>", "Show one registered storage family")
|
|
25
|
+
.option("--class <class>", "Show one registered storage class")
|
|
26
|
+
.option("--json", "Emit the stable versioned inventory schema")
|
|
27
|
+
.action(async (options) => {
|
|
28
|
+
await run(emit, async () => {
|
|
29
|
+
const catalog = catalogFor(context);
|
|
30
|
+
if (options.family && !catalog.get(options.family)) {
|
|
31
|
+
throw new StorageCommandError("unknown_storage_family", `unknown storage family: ${options.family}`);
|
|
32
|
+
}
|
|
33
|
+
const storageClass = parseStorageClass(options.class);
|
|
34
|
+
const report = filterStorageInventory(await inventoryStorage(catalog), {
|
|
35
|
+
...(options.family ? { family_id: options.family } : {}),
|
|
36
|
+
...(storageClass ? { storage_class: storageClass } : {}),
|
|
37
|
+
});
|
|
38
|
+
if (options.json) {
|
|
39
|
+
emit.config({ format: "json" });
|
|
40
|
+
emit.data(report);
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
emit.rows(inventoryRows(report));
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
storage
|
|
48
|
+
.command("health")
|
|
49
|
+
.description("Report reason-coded health for every registered storage family")
|
|
50
|
+
.option("--json", "Emit the stable versioned health schema")
|
|
51
|
+
.action(async (options) => {
|
|
52
|
+
await run(emit, async () => {
|
|
53
|
+
const report = storageHealth(await inventoryStorage(catalogFor(context)));
|
|
54
|
+
if (options.json) {
|
|
55
|
+
emit.config({ format: "json" });
|
|
56
|
+
emit.data(report);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
emit.text(`storage health: ${report.status}\n`);
|
|
60
|
+
emit.rows(report.families.map((family) => ({
|
|
61
|
+
family_id: family.family_id,
|
|
62
|
+
status: family.status,
|
|
63
|
+
reasons: family.reason_codes.join(",") || "none",
|
|
64
|
+
maintenance: family.maintenance.state,
|
|
65
|
+
max_bytes: family.log_storage?.effective_policy?.max_bytes ?? "unavailable",
|
|
66
|
+
max_age_days: family.log_storage?.effective_policy?.max_age_days ?? "unavailable",
|
|
67
|
+
managed_bytes: family.log_storage?.usage.managed_bytes ?? "not-a-log",
|
|
68
|
+
unmanaged_bytes: family.log_storage?.usage.unmanaged_bytes ?? "not-a-log",
|
|
69
|
+
pressure: family.log_storage?.pressure.state ?? "not-a-log",
|
|
70
|
+
enforcement: family.log_storage?.retention.enforcement ?? "not-a-log",
|
|
71
|
+
})));
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
storage
|
|
76
|
+
.command("maintain")
|
|
77
|
+
.description("Plan bounded maintenance, or execute one exact transaction")
|
|
78
|
+
.option("--family <id>", "Limit a new plan to one registered family")
|
|
79
|
+
.option("--budget <duration>", "Wall-time budget such as 500ms, 5s, or 1m")
|
|
80
|
+
.option("--dry-run", "Plan without mutating source storage", true)
|
|
81
|
+
.option("--transaction <id>", "Execute one previously planned exact transaction")
|
|
82
|
+
.option("--yes", "Confirm execution of the exact transaction")
|
|
83
|
+
.option("--authorize-structured-log-deletion", "Authorize deletion only for exact manifest-backed structured-log actions")
|
|
84
|
+
.option("--json", "Emit the versioned transaction schema")
|
|
85
|
+
.action(async (options) => {
|
|
86
|
+
await run(emit, async () => {
|
|
87
|
+
const catalog = catalogFor(context);
|
|
88
|
+
const providers = [
|
|
89
|
+
...createStructuredLogMaintenanceProviders(catalog),
|
|
90
|
+
...(context?.storageMaintenanceProviders ?? []),
|
|
91
|
+
];
|
|
92
|
+
const transaction = options.transaction
|
|
93
|
+
? await executeStorageMaintenance(catalog, providers, options.transaction, {
|
|
94
|
+
yes: options.yes === true,
|
|
95
|
+
authorize_structured_log_deletion: options.authorizeStructuredLogDeletion === true,
|
|
96
|
+
})
|
|
97
|
+
: await planStorageMaintenance(catalog, providers, await pressureFor(catalog), {
|
|
98
|
+
...(options.family ? { family_id: options.family } : {}),
|
|
99
|
+
budget: {
|
|
100
|
+
...DEFAULT_MAINTENANCE_BUDGET,
|
|
101
|
+
max_duration_ms: parseDuration(options.budget),
|
|
102
|
+
},
|
|
103
|
+
persist: true,
|
|
104
|
+
});
|
|
105
|
+
if (options.json) {
|
|
106
|
+
emit.config({ format: "json" });
|
|
107
|
+
emit.data(transaction);
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
emit.rows([
|
|
111
|
+
{
|
|
112
|
+
transaction_id: transaction.transaction_id,
|
|
113
|
+
state: transaction.state,
|
|
114
|
+
dry_run: transaction.dry_run,
|
|
115
|
+
actions: transaction.actions.length,
|
|
116
|
+
files: transaction.actions.reduce((sum, action) => sum + action.files, 0),
|
|
117
|
+
bytes: transaction.actions.reduce((sum, action) => sum + action.bytes, 0),
|
|
118
|
+
reasons: transaction.reason_codes.join(",") || "none",
|
|
119
|
+
},
|
|
120
|
+
]);
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
storage
|
|
125
|
+
.command("status")
|
|
126
|
+
.description("Inspect maintenance transactions without changing storage")
|
|
127
|
+
.option("--transaction <id>", "Show one exact transaction")
|
|
128
|
+
.option("--json", "Emit versioned transaction records")
|
|
129
|
+
.action(async (options) => {
|
|
130
|
+
await run(emit, async () => {
|
|
131
|
+
const catalog = catalogFor(context);
|
|
132
|
+
const transactions = options.transaction
|
|
133
|
+
? [readMaintenanceTransaction(catalog.context.coord_root, options.transaction)]
|
|
134
|
+
: listMaintenanceTransactions(catalog.context.coord_root);
|
|
135
|
+
if (options.json) {
|
|
136
|
+
emit.config({ format: "json" });
|
|
137
|
+
emit.data(transactions);
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
emit.rows(transactions.map((transaction) => ({
|
|
141
|
+
transaction_id: transaction.transaction_id,
|
|
142
|
+
state: transaction.state,
|
|
143
|
+
created_at: transaction.created_at,
|
|
144
|
+
actions: transaction.actions.length,
|
|
145
|
+
reasons: transaction.reason_codes.join(",") || "none",
|
|
146
|
+
})));
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
function catalogFor(context) {
|
|
152
|
+
const coordRoot = resolve(context?.resolveCoordRoot?.() ??
|
|
153
|
+
context?.repoRoot ??
|
|
154
|
+
process.env.HARNERY_COORD_ROOT ??
|
|
155
|
+
resolveCanonicalCoordRoot() ??
|
|
156
|
+
process.cwd());
|
|
157
|
+
return createStorageCatalog({ coord_root: coordRoot, project_root: resolve(context?.repoRoot ?? coordRoot) }, context?.storage);
|
|
158
|
+
}
|
|
159
|
+
function parseStorageClass(value) {
|
|
160
|
+
if (value === undefined)
|
|
161
|
+
return undefined;
|
|
162
|
+
if (!STORAGE_CLASSES.has(value)) {
|
|
163
|
+
throw new StorageCommandError("unknown_storage_class", `unknown storage class: ${value}`);
|
|
164
|
+
}
|
|
165
|
+
return value;
|
|
166
|
+
}
|
|
167
|
+
async function pressureFor(catalog) {
|
|
168
|
+
const inventory = await inventoryStorage(catalog);
|
|
169
|
+
return {
|
|
170
|
+
schema: HARNERY_MAINTENANCE_PRESSURE_SCHEMA,
|
|
171
|
+
captured_at: inventory.captured_at,
|
|
172
|
+
families: inventory.families.map((family) => ({
|
|
173
|
+
family_id: family.family_id,
|
|
174
|
+
logical_bytes: family.totals.logical_bytes.state === "observed" ? family.totals.logical_bytes.value : 0,
|
|
175
|
+
regular_files: family.totals.regular_files.state === "observed" ? family.totals.regular_files.value : 0,
|
|
176
|
+
needs_maintenance: family.maintenance.state === "eligible",
|
|
177
|
+
observed_at: inventory.captured_at,
|
|
178
|
+
})),
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
function parseDuration(value) {
|
|
182
|
+
if (value === undefined)
|
|
183
|
+
return DEFAULT_MAINTENANCE_BUDGET.max_duration_ms;
|
|
184
|
+
const match = /^(\d+)(ms|s|m)$/.exec(value);
|
|
185
|
+
if (!match)
|
|
186
|
+
throw new StorageCommandError("invalid_maintenance_budget", `invalid duration: ${value}`);
|
|
187
|
+
const amount = Number(match[1]);
|
|
188
|
+
const multiplier = match[2] === "ms" ? 1 : match[2] === "s" ? 1_000 : 60_000;
|
|
189
|
+
const result = amount * multiplier;
|
|
190
|
+
if (!Number.isSafeInteger(result) || result <= 0 || result > 60 * 60 * 1_000) {
|
|
191
|
+
throw new StorageCommandError("invalid_maintenance_budget", `invalid duration: ${value}`);
|
|
192
|
+
}
|
|
193
|
+
return result;
|
|
194
|
+
}
|
|
195
|
+
function inventoryRows(report) {
|
|
196
|
+
return report.families.map((family) => ({
|
|
197
|
+
family_id: family.family_id,
|
|
198
|
+
class: family.storage_class,
|
|
199
|
+
state: family.state,
|
|
200
|
+
regular_files: measurementValue(family.totals.regular_files),
|
|
201
|
+
logical_bytes: measurementValue(family.totals.logical_bytes),
|
|
202
|
+
allocated_bytes: measurementValue(family.totals.allocated_bytes),
|
|
203
|
+
maintenance: family.maintenance.state,
|
|
204
|
+
max_bytes: family.log_storage?.effective_policy?.max_bytes ?? "unavailable",
|
|
205
|
+
max_age_days: family.log_storage?.effective_policy?.max_age_days ?? "unavailable",
|
|
206
|
+
managed_bytes: family.log_storage?.usage.managed_bytes ?? "not-a-log",
|
|
207
|
+
unmanaged_bytes: family.log_storage?.usage.unmanaged_bytes ?? "not-a-log",
|
|
208
|
+
pressure: family.log_storage?.pressure.state ?? "not-a-log",
|
|
209
|
+
enforcement: family.log_storage?.retention.enforcement ?? "not-a-log",
|
|
210
|
+
reasons: family.reason_codes.join(",") || "none",
|
|
211
|
+
}));
|
|
212
|
+
}
|
|
213
|
+
function measurementValue(measurement) {
|
|
214
|
+
return measurement.state === "observed"
|
|
215
|
+
? measurement.value
|
|
216
|
+
: `unavailable:${measurement.reason_code}`;
|
|
217
|
+
}
|
|
218
|
+
class StorageCommandError extends Error {
|
|
219
|
+
code;
|
|
220
|
+
constructor(code, message) {
|
|
221
|
+
super(message);
|
|
222
|
+
this.code = code;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
async function run(emit, action) {
|
|
226
|
+
try {
|
|
227
|
+
await action();
|
|
228
|
+
}
|
|
229
|
+
catch (error) {
|
|
230
|
+
emit.error({
|
|
231
|
+
code: error instanceof StorageCommandError || error instanceof HarneryMaintenanceError
|
|
232
|
+
? error.code
|
|
233
|
+
: "storage_inspection_failed",
|
|
234
|
+
message: error instanceof Error ? error.message : String(error),
|
|
235
|
+
});
|
|
236
|
+
emit.setExitCode(1);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import type { Command } from "commander";
|
|
2
2
|
import type { EmitContext, HarneryProgramContext } from "../commander.js";
|
|
3
|
-
import { type TunnelState } from "../lib/tunnel/state.js";
|
|
3
|
+
import { type TunnelProvider, type TunnelState } from "../lib/tunnel/state.js";
|
|
4
|
+
export declare function tunnelLogDestinations(name: string, provider: TunnelProvider, env?: NodeJS.ProcessEnv, root?: string): {
|
|
5
|
+
gate: string;
|
|
6
|
+
provider: string;
|
|
7
|
+
};
|
|
4
8
|
/**
|
|
5
9
|
* Restart ONE instance's gate in place, deliberately leaving the provider
|
|
6
10
|
* process running.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tunnel.d.ts","sourceRoot":"","sources":["../../src/commands/tunnel.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"tunnel.d.ts","sourceRoot":"","sources":["../../src/commands/tunnel.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAQ1E,OAAO,EAWL,KAAK,cAAc,EACnB,KAAK,WAAW,EAGjB,MAAM,wBAAwB,CAAC;AAoDhC,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,cAAc,EACxB,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,IAAI,SAAgB,GACnB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAcpC;AAuoBD;;;;;;;;;;GAUG;AACH,wBAAsB,SAAS,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAsE7F;AA+MD,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,WAAW,EACtB,YAAY,CAAC,EAAE,qBAAqB,GACnC,IAAI,CA2EN"}
|
package/dist/commands/tunnel.js
CHANGED
|
@@ -1,12 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const dir = resolve(process.cwd(), ".cache", tool);
|
|
4
|
-
return resolve(dir, filename);
|
|
5
|
-
}
|
|
6
|
-
import { spawn, spawnSync } from "node:child_process";
|
|
7
|
-
import { existsSync, openSync, readFileSync, writeFileSync } from "node:fs";
|
|
1
|
+
import { spawnSync } from "node:child_process";
|
|
2
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
8
3
|
import { resolve } from "node:path";
|
|
9
4
|
import { resolveBinName } from "../core/config.js";
|
|
5
|
+
import { processLogDestination, runRotatingProcessSync, spawnRotatingProcess, } from "../core/storage/process-log.js";
|
|
10
6
|
import { clearState, DEFAULT_INSTANCE, ensureCloudflared, gateLogFile, isProcessAlive, listStates, providerLogFile, readConfig, readState, writeConfig, writeState, } from "../lib/tunnel/state.js";
|
|
11
7
|
/**
|
|
12
8
|
* `tunnel`: provider-backed tunnel in front of a local upstream.
|
|
@@ -24,6 +20,20 @@ const DEFAULT_TARGET = "127.0.0.1:8001";
|
|
|
24
20
|
const DEFAULT_VHOST = "localhost";
|
|
25
21
|
const DEFAULT_GATE_PORT = 9001;
|
|
26
22
|
const MAX_GATE_PORT = DEFAULT_GATE_PORT + 99; // auto-allocation scan ceiling
|
|
23
|
+
export function tunnelLogDestinations(name, provider, env = process.env, root = process.cwd()) {
|
|
24
|
+
const destination = (filename) => processLogDestination({
|
|
25
|
+
coord_root: root,
|
|
26
|
+
project_root: root,
|
|
27
|
+
family_id: "tunnel-process-log",
|
|
28
|
+
filename,
|
|
29
|
+
legacy_path: resolve(root, ".cache", "tunnel", filename),
|
|
30
|
+
env,
|
|
31
|
+
});
|
|
32
|
+
return {
|
|
33
|
+
gate: destination(gateLogFile(name)),
|
|
34
|
+
provider: destination(providerLogFile(name, provider)),
|
|
35
|
+
};
|
|
36
|
+
}
|
|
27
37
|
/**
|
|
28
38
|
* Validate + normalize an instance name. Names become filename fragments
|
|
29
39
|
* (state-<name>.json) and pgrep patterns, so they're restricted to a safe
|
|
@@ -270,7 +280,6 @@ function tailscaleCommand(mode) {
|
|
|
270
280
|
return mode === "funnel" ? "funnel" : "serve";
|
|
271
281
|
}
|
|
272
282
|
function runTailscaleShare(mode, targetUrl, path, httpsPort, logPath) {
|
|
273
|
-
const fd = openSync(logPath, "a");
|
|
274
283
|
const args = [
|
|
275
284
|
tailscaleCommand(mode),
|
|
276
285
|
"--bg",
|
|
@@ -279,31 +288,36 @@ function runTailscaleShare(mode, targetUrl, path, httpsPort, logPath) {
|
|
|
279
288
|
`--set-path=${path}`,
|
|
280
289
|
targetUrl,
|
|
281
290
|
];
|
|
282
|
-
const
|
|
283
|
-
|
|
291
|
+
const status = runRotatingProcessSync({
|
|
292
|
+
path: logPath,
|
|
293
|
+
command: "tailscale",
|
|
294
|
+
arguments: args,
|
|
284
295
|
});
|
|
285
|
-
if (
|
|
296
|
+
if (status !== 0) {
|
|
286
297
|
emit.error({
|
|
287
298
|
code: "tunnel_tailscale_failed",
|
|
288
299
|
message: `tailscale ${tailscaleCommand(mode)} failed. Check log: ${logPath}`,
|
|
289
300
|
});
|
|
290
|
-
process.exit(
|
|
301
|
+
process.exit(status ?? 1);
|
|
291
302
|
}
|
|
292
303
|
}
|
|
293
304
|
function stopTailscaleShare(state) {
|
|
294
305
|
if (state.provider !== "tailscale" || !state.tailscale_mode)
|
|
295
306
|
return true;
|
|
296
307
|
const cmd = tailscaleCommand(state.tailscale_mode);
|
|
297
|
-
const logPath =
|
|
298
|
-
const fd = openSync(logPath, "a");
|
|
308
|
+
const logPath = tunnelLogDestinations(state.name, "tailscale").provider;
|
|
299
309
|
const args = [
|
|
300
310
|
cmd,
|
|
301
311
|
`--https=${state.tailscale_https_port ?? 443}`,
|
|
302
312
|
`--set-path=${state.tailscale_path ?? "/"}`,
|
|
303
313
|
"off",
|
|
304
314
|
];
|
|
305
|
-
const
|
|
306
|
-
|
|
315
|
+
const status = runRotatingProcessSync({
|
|
316
|
+
path: logPath,
|
|
317
|
+
command: "tailscale",
|
|
318
|
+
arguments: args,
|
|
319
|
+
});
|
|
320
|
+
if (status !== 0) {
|
|
307
321
|
// The gate is torn down and its port is freed for reuse regardless, so a
|
|
308
322
|
// surviving serve/funnel mapping could later re-expose whatever next binds
|
|
309
323
|
// that port. Surface it loudly so the operator can clear it by hand.
|
|
@@ -339,12 +353,12 @@ function tunnelIsAlive(state) {
|
|
|
339
353
|
* re-reads — that snapshot is precisely why `reload` has to exist.
|
|
340
354
|
*/
|
|
341
355
|
function spawnGate(o) {
|
|
342
|
-
const gateFd = openSync(o.gateLogPath, "a");
|
|
343
356
|
// `--name`/`--port` on argv mirror the env vars; they're what makes the gate
|
|
344
357
|
// process distinguishable per-instance in `pgrep -f` (see sweepStrays).
|
|
345
|
-
const gateProc =
|
|
346
|
-
|
|
347
|
-
|
|
358
|
+
const gateProc = spawnRotatingProcess({
|
|
359
|
+
path: o.gateLogPath,
|
|
360
|
+
command: "bun",
|
|
361
|
+
arguments: ["run", gateScriptPath(), "--name", o.name, "--port", String(o.gatePort)],
|
|
348
362
|
env: {
|
|
349
363
|
...process.env,
|
|
350
364
|
HARNERY_TUNNEL_ALLOW: o.allowedIps.join(","),
|
|
@@ -414,10 +428,9 @@ async function up(opts) {
|
|
|
414
428
|
});
|
|
415
429
|
process.exit(1);
|
|
416
430
|
}
|
|
417
|
-
const
|
|
418
|
-
const
|
|
419
|
-
|
|
420
|
-
writeFileSync(providerLogPath, "");
|
|
431
|
+
const logPaths = tunnelLogDestinations(name, provider);
|
|
432
|
+
const gateLogPath = logPaths.gate;
|
|
433
|
+
const providerLogPath = logPaths.provider;
|
|
421
434
|
const gateProc = spawnGate({
|
|
422
435
|
name,
|
|
423
436
|
gatePort,
|
|
@@ -439,15 +452,15 @@ async function up(opts) {
|
|
|
439
452
|
let registered = true;
|
|
440
453
|
let cloudflaredPid;
|
|
441
454
|
if (provider === "cloudflare") {
|
|
442
|
-
const cfdFd = openSync(providerLogPath, "a");
|
|
443
455
|
// Force HTTP/2 transport. The default QUIC transport wedges at precheck on
|
|
444
456
|
// constrained hosts (e.g. WSL, where UDP receive buffers can't grow and ICMP
|
|
445
457
|
// is restricted): the URL prints but the edge never registers. HTTP/2 is
|
|
446
458
|
// marginally higher-latency but registers reliably, which is what a dev
|
|
447
459
|
// tunnel needs.
|
|
448
|
-
const cfdProc =
|
|
449
|
-
|
|
450
|
-
|
|
460
|
+
const cfdProc = spawnRotatingProcess({
|
|
461
|
+
path: providerLogPath,
|
|
462
|
+
command: cloudflaredBin,
|
|
463
|
+
arguments: ["tunnel", "--protocol", "http2", "--url", `http://localhost:${gatePort}`],
|
|
451
464
|
});
|
|
452
465
|
cfdProc.unref();
|
|
453
466
|
cloudflaredPid = cfdProc.pid;
|
|
@@ -649,7 +662,7 @@ export async function reloadOne(state) {
|
|
|
649
662
|
vhost: state.vhost,
|
|
650
663
|
provider: state.provider,
|
|
651
664
|
allowedIps: cfg.allowed_ips,
|
|
652
|
-
gateLogPath:
|
|
665
|
+
gateLogPath: tunnelLogDestinations(name, state.provider).gate,
|
|
653
666
|
});
|
|
654
667
|
await sleep(800);
|
|
655
668
|
const pid = gateProc.pid;
|
|
@@ -794,8 +807,8 @@ function logs(opts) {
|
|
|
794
807
|
const name = resolveName(opts.name);
|
|
795
808
|
const state = readState(name);
|
|
796
809
|
const provider = state?.provider ?? "cloudflare";
|
|
797
|
-
const
|
|
798
|
-
const path =
|
|
810
|
+
const destinations = tunnelLogDestinations(name, provider);
|
|
811
|
+
const path = opts.provider ? destinations.provider : destinations.gate;
|
|
799
812
|
if (!existsSync(path)) {
|
|
800
813
|
emit.error({ code: "tunnel_no_log", message: `No log file at ${path}` });
|
|
801
814
|
process.exit(1);
|
package/dist/commands/web.d.ts
CHANGED
|
@@ -19,6 +19,9 @@ export declare function resolveMaxOldSpaceMb(flag?: string): number;
|
|
|
19
19
|
* wins without clobbering flags the caller set (source maps, inspector, …).
|
|
20
20
|
*/
|
|
21
21
|
export declare function nodeOptionsWithHeapCap(mb: number): string | undefined;
|
|
22
|
+
/** Preload the request diagnostics hook without replacing Next's HTTP server. */
|
|
23
|
+
export declare function nodeOptionsWithWebDiagnostics(webDir: string, mb: number): string;
|
|
24
|
+
export declare function webPerformanceLogDestination(coordRoot: string, env?: Readonly<Record<string, string | undefined>>): string;
|
|
22
25
|
/**
|
|
23
26
|
* Probe the exact localhost socket Next will claim. This is deliberately a
|
|
24
27
|
* check-and-report step, not an alternate-port allocator: Harnery keeps one
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web.d.ts","sourceRoot":"","sources":["../../src/commands/web.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"web.d.ts","sourceRoot":"","sources":["../../src/commands/web.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAyCnD;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAM1D;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAKrE;AAED,iFAAiF;AACjF,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAKhF;AAED,wBAAgB,4BAA4B,CAC1C,SAAS,EAAE,MAAM,EACjB,GAAG,GAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAe,GAC9D,MAAM,CAQR;AAyCD;;;;GAIG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAevE;AAsBD,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,GAAG,IAAI,CAuN5E"}
|
package/dist/commands/web.js
CHANGED
|
@@ -2,9 +2,11 @@ import { spawn, spawnSync } from "node:child_process";
|
|
|
2
2
|
import { existsSync } from "node:fs";
|
|
3
3
|
import { createServer } from "node:net";
|
|
4
4
|
import path from "node:path";
|
|
5
|
-
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
6
6
|
import { DEFAULT_WEB_PORT, resolveWebPort } from "../core/config.js";
|
|
7
7
|
import { ensureSemanticServiceRunning } from "../core/semantic/service.js";
|
|
8
|
+
import { processLogDestination } from "../core/storage/process-log.js";
|
|
9
|
+
import { parsePerformanceWindow, readWebPerformanceReport, WEB_PERFORMANCE_LOG, } from "../lib/web-performance.js";
|
|
8
10
|
import { lazyFetchWebRoot, webRunner } from "./web-fetch.js";
|
|
9
11
|
/**
|
|
10
12
|
* `harn web`: Next.js dashboard for harnery's coord state.
|
|
@@ -13,6 +15,7 @@ import { lazyFetchWebRoot, webRunner } from "./web-fetch.js";
|
|
|
13
15
|
* up [--prod]: start the server (dev mode default; --prod runs next start)
|
|
14
16
|
* build: next build (production bundle)
|
|
15
17
|
* start: next start (must `harn web build` first)
|
|
18
|
+
* performance: summarize request latency and event-loop delays
|
|
16
19
|
*
|
|
17
20
|
* Launches the Next.js app under `harnery/web/` against the user's current
|
|
18
21
|
* working directory. The web app reads `.harnery/` via `HARNERY_COORD_ROOT`;
|
|
@@ -66,6 +69,23 @@ export function nodeOptionsWithHeapCap(mb) {
|
|
|
66
69
|
return inherited;
|
|
67
70
|
return `${inherited} --max-old-space-size=${mb}`.trim();
|
|
68
71
|
}
|
|
72
|
+
/** Preload the request diagnostics hook without replacing Next's HTTP server. */
|
|
73
|
+
export function nodeOptionsWithWebDiagnostics(webDir, mb) {
|
|
74
|
+
const inherited = nodeOptionsWithHeapCap(mb) ?? "";
|
|
75
|
+
if (inherited.includes("server-performance.mjs"))
|
|
76
|
+
return inherited;
|
|
77
|
+
const preload = pathToFileURL(path.join(webDir, "server-performance.mjs")).href;
|
|
78
|
+
return `${inherited} --import=${preload}`.trim();
|
|
79
|
+
}
|
|
80
|
+
export function webPerformanceLogDestination(coordRoot, env = process.env) {
|
|
81
|
+
return processLogDestination({
|
|
82
|
+
coord_root: coordRoot,
|
|
83
|
+
family_id: "web-performance-log",
|
|
84
|
+
filename: "active.jsonl",
|
|
85
|
+
legacy_path: path.join(coordRoot, ".harnery", "logs", WEB_PERFORMANCE_LOG),
|
|
86
|
+
env,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
69
89
|
async function startSemanticServiceWithWeb(coordRoot, emit) {
|
|
70
90
|
const result = await ensureSemanticServiceRunning(coordRoot);
|
|
71
91
|
if (result.state === "started")
|
|
@@ -185,9 +205,12 @@ export function registerWebCommand(program, emit) {
|
|
|
185
205
|
return;
|
|
186
206
|
await startSemanticServiceWithWeb(coordRoot, emit);
|
|
187
207
|
const heapMb = resolveMaxOldSpaceMb(opts.maxOldSpace);
|
|
208
|
+
const nodeOptions = nodeOptionsWithWebDiagnostics(root, heapMb);
|
|
209
|
+
const performanceLogPath = webPerformanceLogDestination(coordRoot);
|
|
188
210
|
emit.log(`harn web · http://localhost:${port} (${mode})`, "info");
|
|
189
211
|
emit.log(`files origin · http://harnery-files.localhost:${port}`, "info");
|
|
190
212
|
emit.log(`reading .harnery/ from: ${coordRoot}`, "info");
|
|
213
|
+
emit.log(`performance log · ${performanceLogPath}`, "info");
|
|
191
214
|
if (heapMb > 0)
|
|
192
215
|
emit.log(`heap ceiling · ${heapMb} MB`, "info");
|
|
193
216
|
const child = spawn(webRunner(), ["run", mode], {
|
|
@@ -196,9 +219,9 @@ export function registerWebCommand(program, emit) {
|
|
|
196
219
|
...process.env,
|
|
197
220
|
HARNERY_COORD_ROOT: coordRoot,
|
|
198
221
|
HARNERY_WEB_PORT: String(port),
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
222
|
+
HARNERY_WEB_MODE: mode,
|
|
223
|
+
HARNERY_WEB_PERFORMANCE_LOG_PATH: performanceLogPath,
|
|
224
|
+
NODE_OPTIONS: nodeOptions,
|
|
202
225
|
},
|
|
203
226
|
stdio: "inherit",
|
|
204
227
|
});
|
|
@@ -271,8 +294,11 @@ export function registerWebCommand(program, emit) {
|
|
|
271
294
|
return;
|
|
272
295
|
await startSemanticServiceWithWeb(coordRoot, emit);
|
|
273
296
|
const heapMb = resolveMaxOldSpaceMb(opts.maxOldSpace);
|
|
297
|
+
const nodeOptions = nodeOptionsWithWebDiagnostics(root, heapMb);
|
|
298
|
+
const performanceLogPath = webPerformanceLogDestination(coordRoot);
|
|
274
299
|
emit.log(`harn web · http://localhost:${port} (start)`, "info");
|
|
275
300
|
emit.log(`reading .harnery/ from: ${coordRoot}`, "info");
|
|
301
|
+
emit.log(`performance log · ${performanceLogPath}`, "info");
|
|
276
302
|
if (heapMb > 0)
|
|
277
303
|
emit.log(`heap ceiling · ${heapMb} MB`, "info");
|
|
278
304
|
const child = spawn(webRunner(), ["run", "start"], {
|
|
@@ -281,9 +307,9 @@ export function registerWebCommand(program, emit) {
|
|
|
281
307
|
...process.env,
|
|
282
308
|
HARNERY_COORD_ROOT: coordRoot,
|
|
283
309
|
HARNERY_WEB_PORT: String(port),
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
310
|
+
HARNERY_WEB_MODE: "start",
|
|
311
|
+
HARNERY_WEB_PERFORMANCE_LOG_PATH: performanceLogPath,
|
|
312
|
+
NODE_OPTIONS: nodeOptions,
|
|
287
313
|
},
|
|
288
314
|
stdio: "inherit",
|
|
289
315
|
});
|
|
@@ -297,4 +323,38 @@ export function registerWebCommand(program, emit) {
|
|
|
297
323
|
process.exitCode = code ?? 0;
|
|
298
324
|
});
|
|
299
325
|
});
|
|
326
|
+
web
|
|
327
|
+
.command("performance")
|
|
328
|
+
.description("Summarize dashboard request, event-loop, memory, and GC diagnostics")
|
|
329
|
+
.option("--coord-root <dir>", "Override the coordination root", process.cwd())
|
|
330
|
+
.option("--since <window>", "Include the last Nm, Nh, or Nd", "1h")
|
|
331
|
+
.option("--limit <n>", "Keep the N slowest requests and delays", "20")
|
|
332
|
+
.option("--json", "Emit structured JSON")
|
|
333
|
+
.action((opts) => {
|
|
334
|
+
const windowMs = parsePerformanceWindow(opts.since);
|
|
335
|
+
if (windowMs === null) {
|
|
336
|
+
emit.error({
|
|
337
|
+
code: "invalid_web_performance_window",
|
|
338
|
+
message: `invalid --since value '${opts.since}'`,
|
|
339
|
+
hint: "Use Nm, Nh, or Nd, for example 30m, 1h, or 7d.",
|
|
340
|
+
});
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
343
|
+
const limit = Number(opts.limit);
|
|
344
|
+
if (!Number.isSafeInteger(limit) || limit < 1 || limit > 500) {
|
|
345
|
+
emit.error({
|
|
346
|
+
code: "invalid_web_performance_limit",
|
|
347
|
+
message: `invalid --limit value '${opts.limit}'`,
|
|
348
|
+
hint: "Use an integer from 1 through 500.",
|
|
349
|
+
});
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
if (opts.json)
|
|
353
|
+
emit.config({ format: "json" });
|
|
354
|
+
emit.data(readWebPerformanceReport({
|
|
355
|
+
root: opts.coordRoot,
|
|
356
|
+
since: opts.since,
|
|
357
|
+
limit,
|
|
358
|
+
}));
|
|
359
|
+
});
|
|
300
360
|
}
|