harnery 0.40.0 → 0.42.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/commander.js +4 -0
- package/dist/commands/agents.d.ts.map +1 -1
- package/dist/commands/agents.js +34 -20
- package/dist/commands/artifacts.d.ts.map +1 -1
- package/dist/commands/artifacts.js +113 -12
- package/dist/commands/browse-ai.d.ts.map +1 -1
- package/dist/commands/browse-ai.js +4 -0
- package/dist/commands/browse.d.ts +164 -0
- package/dist/commands/browse.d.ts.map +1 -1
- package/dist/commands/browse.js +388 -45
- package/dist/commands/checkpoint.js +8 -12
- package/dist/commands/claude-desktop.d.ts.map +1 -1
- package/dist/commands/claude-desktop.js +52 -0
- package/dist/commands/deinit.d.ts +1 -1
- package/dist/commands/deinit.d.ts.map +1 -1
- package/dist/commands/deinit.js +8 -4
- package/dist/commands/disk.d.ts +6 -0
- package/dist/commands/disk.d.ts.map +1 -0
- package/dist/commands/disk.js +80 -0
- package/dist/commands/docs.d.ts.map +1 -1
- package/dist/commands/docs.js +2 -0
- package/dist/commands/doctor.d.ts +8 -0
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +58 -3
- package/dist/commands/fetch.d.ts.map +1 -1
- package/dist/commands/fetch.js +10 -0
- package/dist/commands/files.d.ts +16 -0
- package/dist/commands/files.d.ts.map +1 -1
- package/dist/commands/files.js +54 -2
- package/dist/commands/init.d.ts +21 -5
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +271 -109
- package/dist/commands/instructions.js +5 -4
- package/dist/commands/ledger-v3.d.ts.map +1 -1
- package/dist/commands/ledger-v3.js +2 -1
- package/dist/commands/rm.d.ts +4 -0
- package/dist/commands/rm.d.ts.map +1 -0
- package/dist/commands/rm.js +87 -0
- package/dist/commands/servers.d.ts +7 -0
- package/dist/commands/servers.d.ts.map +1 -0
- package/dist/commands/servers.js +394 -0
- package/dist/commands/tunnel.d.ts.map +1 -1
- package/dist/commands/tunnel.js +82 -2
- package/dist/commands/webview.d.ts +4 -0
- package/dist/commands/webview.d.ts.map +1 -0
- package/dist/commands/webview.js +94 -0
- package/dist/core/adapter.d.ts +50 -1
- package/dist/core/adapter.d.ts.map +1 -1
- package/dist/core/adapter.js +59 -1
- package/dist/core/adapters/attestation.d.ts.map +1 -1
- package/dist/core/adapters/attestation.js +3 -2
- package/dist/core/adapters/profiles.d.ts +29 -3
- package/dist/core/adapters/profiles.d.ts.map +1 -1
- package/dist/core/adapters/profiles.js +53 -1
- package/dist/core/adapters/registry.d.ts.map +1 -1
- package/dist/core/adapters/registry.js +33 -0
- package/dist/core/adapters/types.d.ts +9 -0
- package/dist/core/adapters/types.d.ts.map +1 -1
- package/dist/core/agents/canonical-emit.d.ts +1 -1
- package/dist/core/agents/canonical-emit.d.ts.map +1 -1
- package/dist/core/agents/canonical-emit.js +2 -7
- package/dist/core/agents/cli.js +25 -16
- package/dist/core/agents/coord-client.d.ts.map +1 -1
- package/dist/core/agents/coord-client.js +7 -2
- package/dist/core/agents/render/session-context.d.ts.map +1 -1
- package/dist/core/agents/render/session-context.js +2 -0
- package/dist/core/agents/rules/claim-conflict.d.ts.map +1 -1
- package/dist/core/agents/rules/claim-conflict.js +3 -9
- package/dist/core/agents/rules/commit-conflict.d.ts.map +1 -1
- package/dist/core/agents/rules/commit-conflict.js +2 -8
- 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 +1 -1
- package/dist/core/agents/session-events.d.ts +6 -2
- package/dist/core/agents/session-events.d.ts.map +1 -1
- package/dist/core/agents/session-events.js +105 -26
- package/dist/core/agents/session-finalization-state-v3.d.ts.map +1 -1
- package/dist/core/agents/session-finalization-state-v3.js +2 -1
- package/dist/core/agents/session-finalizer-v3.d.ts.map +1 -1
- package/dist/core/agents/session-finalizer-v3.js +5 -4
- package/dist/core/agents/session-name-display.d.ts +28 -0
- package/dist/core/agents/session-name-display.d.ts.map +1 -1
- package/dist/core/agents/session-name-display.js +43 -0
- package/dist/core/agents/state/heartbeat-reader.d.ts +7 -0
- package/dist/core/agents/state/heartbeat-reader.d.ts.map +1 -1
- package/dist/core/agents/state/heartbeat-writer.d.ts +10 -0
- package/dist/core/agents/state/heartbeat-writer.d.ts.map +1 -1
- package/dist/core/agents/state/heartbeat-writer.js +21 -2
- package/dist/core/agents/state/live-coordination-view.d.ts +20 -0
- package/dist/core/agents/state/live-coordination-view.d.ts.map +1 -1
- package/dist/core/agents/state/live-coordination-view.js +61 -0
- package/dist/core/agents/state/live-coordination-writer.js +3 -0
- package/dist/core/agents/state/stale-sweep.d.ts.map +1 -1
- package/dist/core/agents/state/stale-sweep.js +2 -10
- package/dist/core/agents/turn-changes.d.ts +17 -0
- package/dist/core/agents/turn-changes.d.ts.map +1 -0
- package/dist/core/agents/turn-changes.js +76 -0
- package/dist/core/artifacts/delivery-card.d.ts.map +1 -1
- package/dist/core/artifacts/delivery-card.js +11 -3
- package/dist/core/artifacts/index.d.ts +140 -4
- package/dist/core/artifacts/index.d.ts.map +1 -1
- package/dist/core/artifacts/index.js +526 -52
- package/dist/core/config.d.ts +73 -11
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +142 -3
- package/dist/core/context/index.d.ts.map +1 -1
- package/dist/core/context/index.js +2 -1
- package/dist/core/conversations/archive.d.ts.map +1 -1
- package/dist/core/conversations/archive.js +4 -3
- package/dist/core/diagnostics/bundle.d.ts.map +1 -1
- package/dist/core/diagnostics/bundle.js +5 -4
- package/dist/core/events/legacy-storage/canary.d.ts.map +1 -1
- package/dist/core/events/legacy-storage/canary.js +5 -4
- package/dist/core/events/legacy-storage/compression.d.ts.map +1 -1
- package/dist/core/events/legacy-storage/compression.js +2 -1
- package/dist/core/events/v3/adapter-id.d.ts +10 -2
- package/dist/core/events/v3/adapter-id.d.ts.map +1 -1
- package/dist/core/events/v3/adapter-id.js +16 -0
- package/dist/core/events/v3/authority-outbox.d.ts.map +1 -1
- package/dist/core/events/v3/authority-outbox.js +2 -1
- package/dist/core/events/v3/bootstrap.d.ts.map +1 -1
- package/dist/core/events/v3/bootstrap.js +5 -4
- package/dist/core/events/v3/capabilities.d.ts.map +1 -1
- package/dist/core/events/v3/capabilities.js +17 -0
- package/dist/core/events/v3/contract.d.ts +5 -0
- package/dist/core/events/v3/contract.d.ts.map +1 -1
- package/dist/core/events/v3/contract.js +7 -1
- package/dist/core/events/v3/control-witness.d.ts.map +1 -1
- package/dist/core/events/v3/control-witness.js +3 -2
- package/dist/core/events/v3/coordination-transaction-recovery.d.ts.map +1 -1
- package/dist/core/events/v3/coordination-transaction-recovery.js +4 -3
- package/dist/core/events/v3/fingerprint-keys.d.ts.map +1 -1
- package/dist/core/events/v3/fingerprint-keys.js +7 -6
- package/dist/core/events/v3/generated.d.ts +1 -1
- package/dist/core/events/v3/generated.js +1 -1
- package/dist/core/events/v3/live-feed.d.ts.map +1 -1
- package/dist/core/events/v3/live-feed.js +5 -4
- package/dist/core/events/v3/producers/command-recorder.d.ts.map +1 -1
- package/dist/core/events/v3/producers/command-recorder.js +8 -7
- package/dist/core/events/v3/producers/coordination-recorder.d.ts.map +1 -1
- package/dist/core/events/v3/producers/coordination-recorder.js +8 -7
- package/dist/core/events/v3/producers/diagnostic-summaries.d.ts.map +1 -1
- package/dist/core/events/v3/producers/diagnostic-summaries.js +5 -4
- package/dist/core/events/v3/producers/hook-base.d.ts +1 -0
- package/dist/core/events/v3/producers/hook-base.d.ts.map +1 -1
- package/dist/core/events/v3/producers/hook-base.js +10 -4
- package/dist/core/events/v3/producers/hook.d.ts +2 -0
- package/dist/core/events/v3/producers/hook.d.ts.map +1 -1
- package/dist/core/events/v3/producers/hook.js +16 -1
- package/dist/core/events/v3/producers/intake.d.ts.map +1 -1
- package/dist/core/events/v3/producers/intake.js +16 -6
- package/dist/core/events/v3/producers/recorder.d.ts +2 -4
- package/dist/core/events/v3/producers/recorder.d.ts.map +1 -1
- package/dist/core/events/v3/producers/recorder.js +125 -101
- package/dist/core/events/v3/projection.js +9 -1
- package/dist/core/events/v3/recovery.d.ts.map +1 -1
- package/dist/core/events/v3/recovery.js +4 -3
- package/dist/core/events/v3/support-storage/inventory.d.ts.map +1 -1
- package/dist/core/events/v3/support-storage/inventory.js +2 -1
- package/dist/core/events/v3/support-storage/maintenance.d.ts.map +1 -1
- package/dist/core/events/v3/support-storage/maintenance.js +4 -3
- package/dist/core/events/v3/support-storage/pack-reader.d.ts.map +1 -1
- package/dist/core/events/v3/support-storage/pack-reader.js +4 -3
- package/dist/core/events/v3/support-storage/pack-writer.d.ts.map +1 -1
- package/dist/core/events/v3/support-storage/pack-writer.js +6 -5
- package/dist/core/events/v3/tool-line-changes.d.ts +8 -0
- package/dist/core/events/v3/tool-line-changes.d.ts.map +1 -0
- package/dist/core/events/v3/tool-line-changes.js +135 -0
- package/dist/core/events/v3/writer.d.ts.map +1 -1
- package/dist/core/events/v3/writer.js +8 -7
- package/dist/core/governor/planning.d.ts.map +1 -1
- package/dist/core/governor/planning.js +6 -5
- package/dist/core/governor/service.d.ts.map +1 -1
- package/dist/core/governor/service.js +12 -11
- package/dist/core/governor/state.d.ts.map +1 -1
- package/dist/core/governor/state.js +7 -6
- package/dist/core/guard/evaluator.js +1 -0
- package/dist/core/guard/storage.d.ts.map +1 -1
- package/dist/core/guard/storage.js +3 -2
- package/dist/core/hooks/adapter/behaviors/claude-code.d.ts +4 -0
- package/dist/core/hooks/adapter/behaviors/claude-code.d.ts.map +1 -0
- package/dist/core/hooks/adapter/behaviors/claude-code.js +31 -0
- package/dist/core/hooks/adapter/behaviors/codex.d.ts +15 -0
- package/dist/core/hooks/adapter/behaviors/codex.d.ts.map +1 -0
- package/dist/core/hooks/adapter/behaviors/codex.js +82 -0
- package/dist/core/hooks/adapter/behaviors/cursor.d.ts +7 -0
- package/dist/core/hooks/adapter/behaviors/cursor.d.ts.map +1 -0
- package/dist/core/hooks/adapter/behaviors/cursor.js +35 -0
- package/dist/core/hooks/adapter/behaviors/index.d.ts +11 -0
- package/dist/core/hooks/adapter/behaviors/index.d.ts.map +1 -0
- package/dist/core/hooks/adapter/behaviors/index.js +20 -0
- package/dist/core/hooks/adapter/behaviors/openclaw.d.ts +7 -0
- package/dist/core/hooks/adapter/behaviors/openclaw.d.ts.map +1 -0
- package/dist/core/hooks/adapter/behaviors/openclaw.js +34 -0
- package/dist/core/hooks/adapter/behaviors/opencode.d.ts +7 -0
- package/dist/core/hooks/adapter/behaviors/opencode.d.ts.map +1 -0
- package/dist/core/hooks/adapter/behaviors/opencode.js +34 -0
- package/dist/core/hooks/adapter/behaviors/types.d.ts +89 -0
- package/dist/core/hooks/adapter/behaviors/types.d.ts.map +1 -0
- package/dist/core/hooks/adapter/behaviors/types.js +1 -0
- package/dist/core/hooks/adapter/detect.d.ts +1 -1
- package/dist/core/hooks/adapter/detect.d.ts.map +1 -1
- package/dist/core/hooks/adapter/detect.js +2 -3
- package/dist/core/hooks/adapter/events.d.ts +46 -1
- package/dist/core/hooks/adapter/events.d.ts.map +1 -1
- package/dist/core/hooks/adapter/events.js +36 -0
- package/dist/core/hooks/adapter/opencode-plugin.d.ts +60 -0
- package/dist/core/hooks/adapter/opencode-plugin.d.ts.map +1 -0
- package/dist/core/hooks/adapter/opencode-plugin.js +129 -0
- package/dist/core/hooks/adapter/output.d.ts +7 -0
- package/dist/core/hooks/adapter/output.d.ts.map +1 -1
- package/dist/core/hooks/adapter/output.js +8 -1
- package/dist/core/hooks/adapter/runtime-telemetry.js +3 -1
- package/dist/core/hooks/adapter/wiring.d.ts +52 -8
- package/dist/core/hooks/adapter/wiring.d.ts.map +1 -1
- package/dist/core/hooks/adapter/wiring.js +133 -12
- package/dist/core/hooks/cli.js +676 -531
- package/dist/core/hooks/effects/image-capture.d.ts.map +1 -1
- package/dist/core/hooks/effects/image-capture.js +2 -1
- package/dist/core/hooks/prompt-context/contract.d.ts.map +1 -1
- package/dist/core/hooks/prompt-context/contract.js +1 -0
- package/dist/core/hooks/resolve/transcript.d.ts +1 -1
- package/dist/core/hooks/resolve/transcript.d.ts.map +1 -1
- package/dist/core/hooks/resolve/transcript.js +35 -4
- package/dist/core/hooks/run-markers.d.ts +37 -0
- package/dist/core/hooks/run-markers.d.ts.map +1 -0
- package/dist/core/hooks/run-markers.js +109 -0
- package/dist/core/hooks/session-name-presence.d.ts +3 -1
- package/dist/core/hooks/session-name-presence.d.ts.map +1 -1
- package/dist/core/hooks/session-name-presence.js +7 -2
- package/dist/core/hooks/shell-waiter.d.ts +2 -0
- package/dist/core/hooks/shell-waiter.d.ts.map +1 -0
- package/dist/core/hooks/shell-waiter.js +173 -0
- package/dist/core/resources/service.d.ts.map +1 -1
- package/dist/core/resources/service.js +5 -4
- package/dist/core/semantic/review.d.ts.map +1 -1
- package/dist/core/semantic/review.js +5 -4
- package/dist/core/semantic/service.d.ts.map +1 -1
- package/dist/core/semantic/service.js +15 -14
- package/dist/core/semantic/storage.d.ts.map +1 -1
- package/dist/core/semantic/storage.js +5 -4
- package/dist/core/servers/index.d.ts +211 -0
- package/dist/core/servers/index.d.ts.map +1 -0
- package/dist/core/servers/index.js +560 -0
- package/dist/core/servers/net.d.ts +58 -0
- package/dist/core/servers/net.d.ts.map +1 -0
- package/dist/core/servers/net.js +270 -0
- package/dist/core/servers/tunnels.d.ts +14 -0
- package/dist/core/servers/tunnels.d.ts.map +1 -0
- package/dist/core/servers/tunnels.js +33 -0
- package/dist/core/storage/atomic-json.d.ts.map +1 -1
- package/dist/core/storage/atomic-json.js +7 -3
- package/dist/core/storage/builtins.js +1 -0
- package/dist/core/storage/durable-history.d.ts.map +1 -1
- package/dist/core/storage/durable-history.js +6 -5
- package/dist/core/storage/maintenance-providers.d.ts.map +1 -1
- package/dist/core/storage/maintenance-providers.js +2 -1
- package/dist/core/storage/maintenance.d.ts.map +1 -1
- package/dist/core/storage/maintenance.js +7 -6
- package/dist/core/storage/metrics.d.ts.map +1 -1
- package/dist/core/storage/metrics.js +5 -1
- package/dist/core/storage/modes.d.ts +17 -0
- package/dist/core/storage/modes.d.ts.map +1 -0
- package/dist/core/storage/modes.js +47 -0
- package/dist/core/storage/process-log.d.ts.map +1 -1
- package/dist/core/storage/process-log.js +3 -2
- package/dist/core/storage/receipts.d.ts.map +1 -1
- package/dist/core/storage/receipts.js +4 -3
- package/dist/core/storage/segments.d.ts.map +1 -1
- package/dist/core/storage/segments.js +7 -6
- package/dist/core/supervisor/hook-health.d.ts +2 -1
- package/dist/core/supervisor/hook-health.d.ts.map +1 -1
- package/dist/core/supervisor/hook-health.js +4 -3
- package/dist/core/supervisor/service.d.ts.map +1 -1
- package/dist/core/supervisor/service.js +7 -6
- package/dist/core/work/state.d.ts.map +1 -1
- package/dist/core/work/state.js +8 -7
- package/dist/core/workflow/adapters.d.ts +7 -0
- package/dist/core/workflow/adapters.d.ts.map +1 -1
- package/dist/core/workflow/adapters.js +9 -0
- package/dist/core/workflow/approvals.d.ts.map +1 -1
- package/dist/core/workflow/approvals.js +6 -5
- package/dist/core/workflow/billing.d.ts.map +1 -1
- package/dist/core/workflow/billing.js +33 -4
- package/dist/core/workflow/durable-record.d.ts.map +1 -1
- package/dist/core/workflow/durable-record.js +4 -3
- package/dist/core/workflow/engine.d.ts.map +1 -1
- package/dist/core/workflow/engine.js +30 -1
- package/dist/core/workflow/live-session-v3.d.ts.map +1 -1
- package/dist/core/workflow/live-session-v3.js +2 -3
- package/dist/core/workflow/run-state.d.ts.map +1 -1
- package/dist/core/workflow/run-state.js +3 -2
- package/dist/core/workflow/sandbox-projection.d.ts +13 -2
- package/dist/core/workflow/sandbox-projection.d.ts.map +1 -1
- package/dist/core/workflow/sandbox-projection.js +23 -0
- package/dist/core/workflow/spawn-claude.d.ts.map +1 -1
- package/dist/core/workflow/spawn-claude.js +6 -1
- package/dist/core/workflow/spawn-codex.d.ts +2 -0
- package/dist/core/workflow/spawn-codex.d.ts.map +1 -1
- package/dist/core/workflow/spawn-codex.js +20 -1
- package/dist/core/workflow/spawn-cursor.d.ts.map +1 -1
- package/dist/core/workflow/spawn-cursor.js +6 -1
- package/dist/core/workflow/spawn-opencode.d.ts +36 -0
- package/dist/core/workflow/spawn-opencode.d.ts.map +1 -0
- package/dist/core/workflow/spawn-opencode.js +135 -0
- package/dist/core/workflow/transcript.d.ts.map +1 -1
- package/dist/core/workflow/transcript.js +3 -2
- package/dist/core/workflow/types.d.ts +47 -2
- package/dist/core/workflow/types.d.ts.map +1 -1
- package/dist/core/workflow/worker-access.d.ts +92 -0
- package/dist/core/workflow/worker-access.d.ts.map +1 -0
- package/dist/core/workflow/worker-access.js +450 -0
- package/dist/core/workflow/workspaces/leases.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/leases.js +5 -4
- package/dist/core/workflow/workspaces/local-git.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/local-git.js +3 -2
- package/dist/core/workflow/workspaces/paths.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/paths.js +2 -1
- package/dist/core/workflow/workspaces/state.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/state.js +10 -9
- package/dist/lazy-commands.js +8 -1
- package/dist/lib/agent-browser/client.d.ts +9 -0
- package/dist/lib/agent-browser/client.d.ts.map +1 -1
- package/dist/lib/agent-browser/client.js +13 -0
- package/dist/lib/browser/batch-steps.d.ts +18 -0
- package/dist/lib/browser/batch-steps.d.ts.map +1 -0
- package/dist/lib/browser/batch-steps.js +82 -0
- package/dist/lib/browser/client.d.ts +35 -1
- package/dist/lib/browser/client.d.ts.map +1 -1
- package/dist/lib/browser/client.js +117 -8
- package/dist/lib/browser/collect/collector.d.ts +99 -0
- package/dist/lib/browser/collect/collector.d.ts.map +1 -0
- package/dist/lib/browser/collect/collector.js +202 -0
- package/dist/lib/browser/collect/fields.d.ts +31 -0
- package/dist/lib/browser/collect/fields.d.ts.map +1 -0
- package/dist/lib/browser/collect/fields.js +75 -0
- package/dist/lib/browser/collect/index.d.ts +6 -0
- package/dist/lib/browser/collect/index.d.ts.map +1 -0
- package/dist/lib/browser/collect/index.js +5 -0
- package/dist/lib/browser/collect/page-driver.d.ts +14 -0
- package/dist/lib/browser/collect/page-driver.d.ts.map +1 -0
- package/dist/lib/browser/collect/page-driver.js +306 -0
- package/dist/lib/browser/collect/presets.d.ts +52 -0
- package/dist/lib/browser/collect/presets.d.ts.map +1 -0
- package/dist/lib/browser/collect/presets.js +176 -0
- package/dist/lib/browser/collect/scroll-plan.d.ts +85 -0
- package/dist/lib/browser/collect/scroll-plan.d.ts.map +1 -0
- package/dist/lib/browser/collect/scroll-plan.js +118 -0
- package/dist/lib/browser/identity.d.ts +25 -0
- package/dist/lib/browser/identity.d.ts.map +1 -0
- package/dist/lib/browser/identity.js +66 -0
- package/dist/lib/browser/index.d.ts +3 -2
- package/dist/lib/browser/index.d.ts.map +1 -1
- package/dist/lib/browser/index.js +2 -1
- package/dist/lib/browser/launch-args.d.ts +26 -0
- package/dist/lib/browser/launch-args.d.ts.map +1 -1
- package/dist/lib/browser/launch-args.js +41 -1
- package/dist/lib/browser/page-review-judge.d.ts +2 -0
- package/dist/lib/browser/page-review-judge.d.ts.map +1 -1
- package/dist/lib/browser/page-review-judge.js +13 -0
- package/dist/lib/browser/qa-run-contracts.d.ts +10 -0
- package/dist/lib/browser/qa-run-contracts.d.ts.map +1 -1
- package/dist/lib/browser/qa-run.d.ts.map +1 -1
- package/dist/lib/browser/qa-run.js +1 -0
- package/dist/lib/browser/user-agent.d.ts +53 -0
- package/dist/lib/browser/user-agent.d.ts.map +1 -0
- package/dist/lib/browser/user-agent.js +79 -0
- package/dist/lib/browser/windows-chrome.d.ts +59 -0
- package/dist/lib/browser/windows-chrome.d.ts.map +1 -0
- package/dist/lib/browser/windows-chrome.js +179 -0
- package/dist/lib/claude-desktop-share.d.ts +136 -0
- package/dist/lib/claude-desktop-share.d.ts.map +1 -0
- package/dist/lib/claude-desktop-share.js +394 -0
- package/dist/lib/disk-usage.d.ts +50 -0
- package/dist/lib/disk-usage.d.ts.map +1 -0
- package/dist/lib/disk-usage.js +303 -0
- package/dist/lib/docs-lint.d.ts +6 -0
- package/dist/lib/docs-lint.d.ts.map +1 -1
- package/dist/lib/docs-lint.js +8 -3
- package/dist/lib/docs-metadata-managed.d.ts +1 -0
- package/dist/lib/docs-metadata-managed.d.ts.map +1 -1
- package/dist/lib/docs-metadata-managed.js +17 -1
- package/dist/lib/guarded-remove.d.ts +34 -0
- package/dist/lib/guarded-remove.d.ts.map +1 -0
- package/dist/lib/guarded-remove.js +310 -0
- package/dist/lib/identities/assume.d.ts.map +1 -1
- package/dist/lib/identities/assume.js +4 -9
- package/dist/lib/instructions/apply.d.ts.map +1 -1
- package/dist/lib/instructions/apply.js +2 -0
- package/dist/lib/instructions/templates.js +8 -8
- package/dist/lib/pace/index.d.ts +2 -0
- package/dist/lib/pace/index.d.ts.map +1 -0
- package/dist/lib/pace/index.js +1 -0
- package/dist/lib/pace/pace.d.ts +95 -0
- package/dist/lib/pace/pace.d.ts.map +1 -0
- package/dist/lib/pace/pace.js +313 -0
- package/dist/lib/tunnel/error-page.d.ts +1 -1
- package/dist/lib/tunnel/error-page.d.ts.map +1 -1
- package/dist/lib/tunnel/error-page.js +19 -8
- package/dist/lib/tunnel/forward-headers.d.ts +11 -0
- package/dist/lib/tunnel/forward-headers.d.ts.map +1 -0
- package/dist/lib/tunnel/forward-headers.js +17 -0
- package/dist/lib/tunnel/gate.js +34 -10
- package/dist/lib/tunnel/path-scope.d.ts +22 -0
- package/dist/lib/tunnel/path-scope.d.ts.map +1 -0
- package/dist/lib/tunnel/path-scope.js +62 -0
- package/dist/lib/tunnel/state.d.ts +5 -0
- package/dist/lib/tunnel/state.d.ts.map +1 -1
- package/dist/lib/tunnel/state.js +17 -3
- package/dist/lib/webview/index.d.ts +2 -0
- package/dist/lib/webview/index.d.ts.map +1 -0
- package/dist/lib/webview/index.js +1 -0
- package/dist/lib/webview/webview.d.ts +116 -0
- package/dist/lib/webview/webview.d.ts.map +1 -0
- package/dist/lib/webview/webview.js +289 -0
- package/opencode-plugin/package.json +19 -0
- package/opencode-plugin/src/index.ts +791 -0
- package/package.json +16 -4
- package/schemas/config.schema.json +104 -0
- package/schemas/event-v3.schema.json +164 -0
- package/src/commander.ts +26 -0
- package/src/commands/agents.ts +47 -18
- package/src/commands/artifacts.ts +171 -19
- package/src/commands/browse-ai.ts +8 -0
- package/src/commands/browse.ts +570 -48
- package/src/commands/checkpoint.ts +7 -9
- package/src/commands/claude-desktop.ts +61 -0
- package/src/commands/deinit.ts +9 -4
- package/src/commands/disk.ts +114 -0
- package/src/commands/docs.ts +2 -0
- package/src/commands/doctor.ts +63 -3
- package/src/commands/fetch.ts +14 -0
- package/src/commands/files.ts +93 -2
- package/src/commands/init.ts +334 -122
- package/src/commands/instructions.ts +8 -4
- package/src/commands/ledger-v3.ts +2 -1
- package/src/commands/rm.ts +115 -0
- package/src/commands/servers.ts +506 -0
- package/src/commands/tunnel.ts +102 -2
- package/src/commands/webview.ts +159 -0
- package/src/core/adapter.ts +102 -1
- package/src/core/adapters/attestation.ts +3 -2
- package/src/core/adapters/profiles.ts +63 -1
- package/src/core/adapters/registry.ts +37 -0
- package/src/core/adapters/types.ts +10 -0
- package/src/core/agents/canonical-emit.ts +2 -5
- package/src/core/agents/cli.ts +26 -17
- package/src/core/agents/coord-client.ts +9 -3
- package/src/core/agents/render/session-context.ts +1 -0
- package/src/core/agents/rules/claim-conflict.ts +3 -8
- package/src/core/agents/rules/commit-conflict.ts +2 -7
- package/src/core/agents/rules/stop-hook.ts +3 -1
- package/src/core/agents/session-events.ts +120 -26
- package/src/core/agents/session-finalization-state-v3.ts +2 -1
- package/src/core/agents/session-finalizer-v3.ts +5 -4
- package/src/core/agents/session-name-display.ts +48 -0
- package/src/core/agents/state/heartbeat-reader.ts +7 -0
- package/src/core/agents/state/heartbeat-writer.ts +24 -2
- package/src/core/agents/state/live-coordination-view.ts +74 -0
- package/src/core/agents/state/live-coordination-writer.ts +3 -0
- package/src/core/agents/state/stale-sweep.ts +2 -9
- package/src/core/agents/turn-changes.ts +97 -0
- package/src/core/artifacts/delivery-card.ts +12 -3
- package/src/core/artifacts/index.ts +701 -47
- package/src/core/config.ts +206 -4
- package/src/core/context/index.ts +2 -1
- package/src/core/conversations/archive.ts +4 -3
- package/src/core/diagnostics/bundle.ts +5 -3
- package/src/core/events/legacy-storage/canary.ts +5 -4
- package/src/core/events/legacy-storage/compression.ts +2 -1
- package/src/core/events/v3/adapter-id.ts +29 -1
- package/src/core/events/v3/authority-outbox.ts +2 -1
- package/src/core/events/v3/bootstrap.ts +5 -4
- package/src/core/events/v3/capabilities.ts +17 -0
- package/src/core/events/v3/contract.ts +9 -1
- package/src/core/events/v3/control-witness.ts +3 -2
- package/src/core/events/v3/coordination-transaction-recovery.ts +4 -3
- package/src/core/events/v3/fingerprint-keys.ts +7 -6
- package/src/core/events/v3/generated.ts +1 -1
- package/src/core/events/v3/live-feed.ts +5 -4
- package/src/core/events/v3/producers/command-recorder.ts +8 -6
- package/src/core/events/v3/producers/coordination-recorder.ts +8 -7
- package/src/core/events/v3/producers/diagnostic-summaries.ts +5 -4
- package/src/core/events/v3/producers/hook-base.ts +11 -4
- package/src/core/events/v3/producers/hook.ts +19 -1
- package/src/core/events/v3/producers/intake.ts +18 -6
- package/src/core/events/v3/producers/recorder.ts +139 -114
- package/src/core/events/v3/projection.ts +11 -1
- package/src/core/events/v3/recovery.ts +4 -3
- package/src/core/events/v3/support-storage/inventory.ts +2 -1
- package/src/core/events/v3/support-storage/maintenance.ts +8 -3
- package/src/core/events/v3/support-storage/pack-reader.ts +4 -3
- package/src/core/events/v3/support-storage/pack-writer.ts +6 -5
- package/src/core/events/v3/tool-line-changes.ts +139 -0
- package/src/core/events/v3/writer.ts +8 -7
- package/src/core/governor/planning.ts +6 -5
- package/src/core/governor/service.ts +12 -11
- package/src/core/governor/state.ts +7 -6
- package/src/core/guard/evaluator.ts +1 -0
- package/src/core/guard/storage.ts +3 -2
- package/src/core/hooks/adapter/behaviors/claude-code.ts +33 -0
- package/src/core/hooks/adapter/behaviors/codex.ts +96 -0
- package/src/core/hooks/adapter/behaviors/cursor.ts +37 -0
- package/src/core/hooks/adapter/behaviors/index.ts +31 -0
- package/src/core/hooks/adapter/behaviors/openclaw.ts +36 -0
- package/src/core/hooks/adapter/behaviors/opencode.ts +36 -0
- package/src/core/hooks/adapter/behaviors/types.ts +110 -0
- package/src/core/hooks/adapter/detect.ts +2 -3
- package/src/core/hooks/adapter/events.ts +72 -1
- package/src/core/hooks/adapter/opencode-plugin.ts +177 -0
- package/src/core/hooks/adapter/output.ts +8 -1
- package/src/core/hooks/adapter/runtime-telemetry.ts +3 -1
- package/src/core/hooks/adapter/wiring.ts +198 -16
- package/src/core/hooks/cli.ts +776 -539
- package/src/core/hooks/effects/image-capture.ts +2 -1
- package/src/core/hooks/prompt-context/contract.ts +1 -0
- package/src/core/hooks/resolve/transcript.ts +42 -5
- package/src/core/hooks/run-markers.ts +132 -0
- package/src/core/hooks/session-name-presence.ts +10 -3
- package/src/core/hooks/shell-waiter.ts +166 -0
- package/src/core/resources/service.ts +5 -4
- package/src/core/semantic/review.ts +5 -4
- package/src/core/semantic/service.ts +15 -14
- package/src/core/semantic/storage.ts +5 -4
- package/src/core/servers/index.ts +712 -0
- package/src/core/servers/net.ts +283 -0
- package/src/core/servers/tunnels.ts +39 -0
- package/src/core/storage/atomic-json.ts +7 -3
- package/src/core/storage/builtins.ts +1 -0
- package/src/core/storage/durable-history.ts +6 -5
- package/src/core/storage/maintenance-providers.ts +2 -1
- package/src/core/storage/maintenance.ts +7 -6
- package/src/core/storage/metrics.ts +5 -1
- package/src/core/storage/modes.ts +53 -0
- package/src/core/storage/process-log.ts +3 -2
- package/src/core/storage/receipts.ts +4 -3
- package/src/core/storage/segments.ts +7 -6
- package/src/core/supervisor/hook-health.ts +4 -4
- package/src/core/supervisor/service.ts +7 -6
- package/src/core/work/state.ts +8 -7
- package/src/core/workflow/adapters.ts +15 -0
- package/src/core/workflow/approvals.ts +6 -5
- package/src/core/workflow/billing.ts +34 -4
- package/src/core/workflow/durable-record.ts +4 -3
- package/src/core/workflow/engine.ts +38 -1
- package/src/core/workflow/live-session-v3.ts +2 -3
- package/src/core/workflow/run-state.ts +3 -2
- package/src/core/workflow/sandbox-projection.ts +38 -2
- package/src/core/workflow/spawn-claude.ts +5 -1
- package/src/core/workflow/spawn-codex.ts +18 -1
- package/src/core/workflow/spawn-cursor.ts +5 -1
- package/src/core/workflow/spawn-opencode.ts +153 -0
- package/src/core/workflow/transcript.ts +3 -2
- package/src/core/workflow/types.ts +62 -2
- package/src/core/workflow/worker-access.ts +525 -0
- package/src/core/workflow/workspaces/leases.ts +5 -4
- package/src/core/workflow/workspaces/local-git.ts +3 -2
- package/src/core/workflow/workspaces/paths.ts +2 -1
- package/src/core/workflow/workspaces/state.ts +10 -9
- package/src/lazy-commands.ts +11 -1
- package/src/lib/agent-browser/client.ts +18 -0
- package/src/lib/browser/batch-steps.ts +79 -0
- package/src/lib/browser/client.ts +147 -9
- package/src/lib/browser/collect/collector.ts +306 -0
- package/src/lib/browser/collect/fields.ts +87 -0
- package/src/lib/browser/collect/index.ts +47 -0
- package/src/lib/browser/collect/page-driver.ts +327 -0
- package/src/lib/browser/collect/presets.ts +237 -0
- package/src/lib/browser/collect/scroll-plan.ts +179 -0
- package/src/lib/browser/identity.ts +64 -0
- package/src/lib/browser/index.ts +16 -1
- package/src/lib/browser/launch-args.ts +53 -1
- package/src/lib/browser/page-review-judge.ts +16 -0
- package/src/lib/browser/qa-run-contracts.ts +11 -0
- package/src/lib/browser/qa-run.ts +1 -0
- package/src/lib/browser/user-agent.ts +130 -0
- package/src/lib/browser/windows-chrome.ts +227 -0
- package/src/lib/claude-desktop-share.ts +511 -0
- package/src/lib/disk-usage.ts +347 -0
- package/src/lib/docs-lint.ts +8 -3
- package/src/lib/docs-metadata-managed.ts +21 -0
- package/src/lib/guarded-remove.ts +376 -0
- package/src/lib/identities/assume.ts +7 -7
- package/src/lib/instructions/apply.ts +2 -0
- package/src/lib/instructions/templates.ts +8 -8
- package/src/lib/pace/index.ts +14 -0
- package/src/lib/pace/pace.ts +370 -0
- package/src/lib/tunnel/error-page.ts +25 -9
- package/src/lib/tunnel/forward-headers.ts +16 -0
- package/src/lib/tunnel/gate.ts +39 -10
- package/src/lib/tunnel/path-scope.ts +73 -0
- package/src/lib/tunnel/state.ts +20 -3
- package/src/lib/webview/index.ts +13 -0
- package/src/lib/webview/webview.ts +457 -0
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
import { spawnSync } from "node:child_process";
|
|
2
|
+
import { lstatSync, readdirSync, readlinkSync, realpathSync, rmSync } from "node:fs";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
import { basename, dirname, isAbsolute, parse, relative, resolve, sep } from "node:path";
|
|
5
|
+
const protectedNames = new Set([".git", ".harnery", ".credentials", ".ssh", ".gnupg"]);
|
|
6
|
+
const MAX_ENTRIES = 10_000;
|
|
7
|
+
/** Permanent removal is deliberately limited to inspected, untracked local outputs. */
|
|
8
|
+
export function guardedRemove(paths, options, checkClaims = () => { }) {
|
|
9
|
+
const cwd = realpathSync(process.cwd());
|
|
10
|
+
const root = checkedPath(options.root, new Set(), true);
|
|
11
|
+
const allowed = allowedProtected(options.allowProtected ?? [], root, options.liveRoots ?? []);
|
|
12
|
+
const rootStat = lstatSync(root);
|
|
13
|
+
const rootFingerprint = fingerprint(rootStat);
|
|
14
|
+
if (!rootStat.isDirectory())
|
|
15
|
+
throw new Error("--root must be a directory");
|
|
16
|
+
if (root === parse(root).root || root === realpathSync(homedir()))
|
|
17
|
+
throw new Error("--root cannot be a filesystem root or home directory");
|
|
18
|
+
if (paths.length === 0 || paths.length > 100)
|
|
19
|
+
throw new Error("Supply 1-100 explicit targets");
|
|
20
|
+
const targets = paths.map((path) => checkedPath(path, allowed));
|
|
21
|
+
const snapshots = new Map();
|
|
22
|
+
const removedProtected = new Set();
|
|
23
|
+
const links = [];
|
|
24
|
+
const gitDirs = new Set();
|
|
25
|
+
let bytes = 0;
|
|
26
|
+
const devices = new Set();
|
|
27
|
+
for (const target of targets) {
|
|
28
|
+
const home = realpathSync(homedir());
|
|
29
|
+
if (target === home || strictlyInside(target, home))
|
|
30
|
+
throw new Error(`Cannot remove the home directory or its ancestor: ${target}`);
|
|
31
|
+
const systemRoots = process.platform === "win32"
|
|
32
|
+
? [
|
|
33
|
+
process.env.SystemRoot,
|
|
34
|
+
process.env.ProgramFiles,
|
|
35
|
+
process.env["ProgramFiles(x86)"],
|
|
36
|
+
].filter((value) => Boolean(value))
|
|
37
|
+
: [
|
|
38
|
+
"/etc",
|
|
39
|
+
"/usr",
|
|
40
|
+
"/boot",
|
|
41
|
+
"/dev",
|
|
42
|
+
"/proc",
|
|
43
|
+
"/sys",
|
|
44
|
+
"/bin",
|
|
45
|
+
"/sbin",
|
|
46
|
+
"/lib",
|
|
47
|
+
"/lib64",
|
|
48
|
+
"/run",
|
|
49
|
+
];
|
|
50
|
+
if (systemRoots.some((system) => target === resolve(system) ||
|
|
51
|
+
strictlyInside(resolve(system), target) ||
|
|
52
|
+
strictlyInside(target, resolve(system))))
|
|
53
|
+
throw new Error(`System files are protected: ${target}`);
|
|
54
|
+
if (!strictlyInside(root, target))
|
|
55
|
+
throw new Error(`Target must be strictly inside --root: ${target}`);
|
|
56
|
+
if (target === cwd || strictlyInside(target, cwd))
|
|
57
|
+
throw new Error(`Cannot remove the working directory or its ancestor: ${target}`);
|
|
58
|
+
if (targets.some((other) => other !== target && strictlyInside(other, target)) ||
|
|
59
|
+
targets.filter((other) => other === target).length > 1)
|
|
60
|
+
throw new Error("Targets must not duplicate or contain one another");
|
|
61
|
+
const stat = lstatSync(target);
|
|
62
|
+
if (stat.dev !== rootStat.dev)
|
|
63
|
+
throw new Error(`Target crosses a mount boundary: ${target}`);
|
|
64
|
+
if (stat.isDirectory() && !options.recursive)
|
|
65
|
+
throw new Error(`Directory removal requires --recursive: ${target}`);
|
|
66
|
+
const device = stat.dev;
|
|
67
|
+
devices.add(device);
|
|
68
|
+
const pending = [target];
|
|
69
|
+
while (pending.length) {
|
|
70
|
+
const path = pending.pop();
|
|
71
|
+
const info = lstatSync(path);
|
|
72
|
+
if (basename(path) === ARTIFACT_RECORD && insideArtifactWorkspace(path, null))
|
|
73
|
+
throw new Error(`An artifact's record is managed by the artifact commands: ${path}`);
|
|
74
|
+
if (protectedNames.has(basename(path).toLowerCase())) {
|
|
75
|
+
if (!allowed.has(path))
|
|
76
|
+
throw new Error(protectedMessage(path));
|
|
77
|
+
removedProtected.add(path);
|
|
78
|
+
}
|
|
79
|
+
if (info.isSymbolicLink()) {
|
|
80
|
+
// A link inside the tree is removed as a link; its target is never
|
|
81
|
+
// read, followed, or counted. (The target itself and its ancestors
|
|
82
|
+
// were already refused if they were links, in checkedPath.)
|
|
83
|
+
if (path === target)
|
|
84
|
+
throw new Error(`Path contains a symlink: ${path}`);
|
|
85
|
+
if (snapshots.size >= MAX_ENTRIES)
|
|
86
|
+
throw new Error(`Removal exceeds the ${MAX_ENTRIES}-entry limit; use the owning cleanup command`);
|
|
87
|
+
snapshots.set(path, fingerprint(info));
|
|
88
|
+
links.push({ path, target: readlinkSync(path) });
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
if (info.dev !== device || (!info.isDirectory() && !info.isFile()))
|
|
92
|
+
throw new Error(`Mount boundary or special file cannot be removed: ${path}`);
|
|
93
|
+
if (snapshots.size >= MAX_ENTRIES)
|
|
94
|
+
throw new Error(`Removal exceeds the ${MAX_ENTRIES}-entry limit; use the owning cleanup command`);
|
|
95
|
+
snapshots.set(path, fingerprint(info));
|
|
96
|
+
if (info.isFile())
|
|
97
|
+
bytes += info.size;
|
|
98
|
+
else {
|
|
99
|
+
const names = readdirSync(path);
|
|
100
|
+
if (names.includes("HEAD") &&
|
|
101
|
+
names.includes("objects") &&
|
|
102
|
+
names.includes("config") &&
|
|
103
|
+
!insideAllowed(path, allowed))
|
|
104
|
+
throw new Error(`Repository metadata cannot be removed: ${path}. To remove it on purpose, name it with --allow-protected ${path}`);
|
|
105
|
+
if (allowed.has(path))
|
|
106
|
+
removedProtected.add(path);
|
|
107
|
+
if (isRepositoryMetadata(path))
|
|
108
|
+
gitDirs.add(path);
|
|
109
|
+
for (const name of names)
|
|
110
|
+
pending.push(resolve(path, name));
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
assertUntracked(target);
|
|
114
|
+
}
|
|
115
|
+
if (devices.size > 1)
|
|
116
|
+
throw new Error("Targets must be on one filesystem");
|
|
117
|
+
for (const path of allowed)
|
|
118
|
+
if (!removedProtected.has(path))
|
|
119
|
+
throw new Error(`--allow-protected names a path no target removes: ${path}`);
|
|
120
|
+
for (const dir of gitDirs)
|
|
121
|
+
assertNoUnpushedHistory(dir);
|
|
122
|
+
checkClaims(targets);
|
|
123
|
+
const report = {
|
|
124
|
+
schema: "harnery.removal/v1",
|
|
125
|
+
applied: false,
|
|
126
|
+
root,
|
|
127
|
+
targets,
|
|
128
|
+
entries: snapshots.size,
|
|
129
|
+
bytes,
|
|
130
|
+
protected: [...removedProtected].sort(),
|
|
131
|
+
links,
|
|
132
|
+
};
|
|
133
|
+
if (!options.yes || options.dryRun)
|
|
134
|
+
return report;
|
|
135
|
+
// Recheck the entire batch before its first mutation. Filesystem changes after
|
|
136
|
+
// these checks remain possible; this is a guard, not a transactional filesystem.
|
|
137
|
+
if (checkedPath(options.root, new Set(), true) !== root ||
|
|
138
|
+
fingerprint(lstatSync(root)) !== rootFingerprint)
|
|
139
|
+
throw new Error("Allowed root changed during inspection");
|
|
140
|
+
for (const target of targets) {
|
|
141
|
+
checkedPath(target, allowed);
|
|
142
|
+
assertUntracked(target);
|
|
143
|
+
}
|
|
144
|
+
for (const dir of gitDirs)
|
|
145
|
+
assertNoUnpushedHistory(dir);
|
|
146
|
+
checkClaims(targets);
|
|
147
|
+
for (const [path, previous] of snapshots) {
|
|
148
|
+
if (fingerprint(lstatSync(path)) !== previous)
|
|
149
|
+
throw new Error(`Target changed during inspection: ${path}`);
|
|
150
|
+
}
|
|
151
|
+
for (const target of targets)
|
|
152
|
+
rmSync(target, { recursive: Boolean(options.recursive), force: false });
|
|
153
|
+
return { ...report, applied: true };
|
|
154
|
+
}
|
|
155
|
+
/** The metadata file the artifact commands keep in each artifact workspace. */
|
|
156
|
+
const ARTIFACT_RECORD = ".harnery-artifact.json";
|
|
157
|
+
/**
|
|
158
|
+
* True when `path` lies strictly inside one artifact workspace,
|
|
159
|
+
* <dir>/.harnery/artifacts/<id>/..., under the `.harnery` component `state`
|
|
160
|
+
* (any `.harnery` when null). Artifact workspaces hold local outputs, so their
|
|
161
|
+
* contents may be removed; the workspace itself, its record file, and the rest
|
|
162
|
+
* of Harnery state stay protected and follow the artifact commands. `orSelf`
|
|
163
|
+
* accepts the workspace directory itself (used for --root, which is never removed).
|
|
164
|
+
*/
|
|
165
|
+
function insideArtifactWorkspace(path, state, orSelf = false) {
|
|
166
|
+
const parts = path.split(sep);
|
|
167
|
+
for (let i = 0; i < parts.length; i++) {
|
|
168
|
+
if (parts[i].toLowerCase() !== ".harnery")
|
|
169
|
+
continue;
|
|
170
|
+
if (state !== null && parts.slice(0, i + 1).join(sep) !== state)
|
|
171
|
+
continue;
|
|
172
|
+
// .harnery / artifacts / <id> / <something>
|
|
173
|
+
return (parts[i + 1] === "artifacts" && Boolean(parts[i + 2]) && parts.length >= i + (orSelf ? 3 : 4));
|
|
174
|
+
}
|
|
175
|
+
return false;
|
|
176
|
+
}
|
|
177
|
+
function protectedMessage(path) {
|
|
178
|
+
return `Protected state cannot be removed: ${path}. To remove it on purpose, name it with --allow-protected ${path}`;
|
|
179
|
+
}
|
|
180
|
+
function insideAllowed(path, allowed) {
|
|
181
|
+
for (const entry of allowed)
|
|
182
|
+
if (path === entry || strictlyInside(entry, path))
|
|
183
|
+
return true;
|
|
184
|
+
return false;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Resolves the caller's --allow-protected paths. Each must be one exact
|
|
188
|
+
* protected path strictly inside the root, reached without symlinks, and
|
|
189
|
+
* never the Git metadata or Harnery state of a live workspace root.
|
|
190
|
+
*/
|
|
191
|
+
function allowedProtected(paths, root, liveRoots) {
|
|
192
|
+
const allowed = new Set();
|
|
193
|
+
const live = liveRoots.map((dir) => resolve(dir));
|
|
194
|
+
for (const input of paths) {
|
|
195
|
+
if (!input?.trim() || /[\0\r\n*?[\]$]/.test(input))
|
|
196
|
+
throw new Error("Use a nonempty explicit --allow-protected path without wildcards");
|
|
197
|
+
const path = resolve(input);
|
|
198
|
+
let cursor = dirname(path);
|
|
199
|
+
while (true) {
|
|
200
|
+
if (lstatSync(cursor).isSymbolicLink())
|
|
201
|
+
throw new Error(`--allow-protected path contains a symlink: ${cursor}`);
|
|
202
|
+
const parent = dirname(cursor);
|
|
203
|
+
if (parent === cursor)
|
|
204
|
+
break;
|
|
205
|
+
cursor = parent;
|
|
206
|
+
}
|
|
207
|
+
const info = lstatSync(path);
|
|
208
|
+
if (info.isSymbolicLink())
|
|
209
|
+
throw new Error(`--allow-protected path is a symlink: ${path}`);
|
|
210
|
+
if (!strictlyInside(root, path))
|
|
211
|
+
throw new Error(`--allow-protected path must be strictly inside --root: ${path}`);
|
|
212
|
+
const named = protectedNames.has(basename(path).toLowerCase());
|
|
213
|
+
if (!named && !(info.isDirectory() && isRepositoryMetadata(path)))
|
|
214
|
+
throw new Error(`--allow-protected must name a protected path itself: ${path}`);
|
|
215
|
+
for (const dir of live) {
|
|
216
|
+
const own = [".git", ".harnery"].map((name) => resolve(dir, name));
|
|
217
|
+
if (path === dir ||
|
|
218
|
+
strictlyInside(path, dir) ||
|
|
219
|
+
own.some((state) => path === state || strictlyInside(state, path)))
|
|
220
|
+
throw new Error(`The live workspace's own state cannot be allowed: ${path}`);
|
|
221
|
+
}
|
|
222
|
+
allowed.add(realpathSync(path));
|
|
223
|
+
}
|
|
224
|
+
return allowed;
|
|
225
|
+
}
|
|
226
|
+
function isRepositoryMetadata(dir) {
|
|
227
|
+
const names = readdirSync(dir);
|
|
228
|
+
return names.includes("HEAD") && names.includes("objects") && names.includes("config");
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Removing a repository's metadata loses any commit that exists nowhere
|
|
232
|
+
* else. An allowed Git directory must have no branch or tag commit missing
|
|
233
|
+
* from its remotes; anything that cannot be checked is refused.
|
|
234
|
+
*/
|
|
235
|
+
function assertNoUnpushedHistory(gitDir) {
|
|
236
|
+
const result = spawnSync("git", [
|
|
237
|
+
"--git-dir",
|
|
238
|
+
gitDir,
|
|
239
|
+
"rev-list",
|
|
240
|
+
"--max-count=1",
|
|
241
|
+
"--branches",
|
|
242
|
+
"--tags",
|
|
243
|
+
"--not",
|
|
244
|
+
"--remotes",
|
|
245
|
+
], {
|
|
246
|
+
encoding: "utf8",
|
|
247
|
+
timeout: 10_000,
|
|
248
|
+
env: { ...process.env, LC_ALL: "C", GIT_DIR: undefined, GIT_WORK_TREE: undefined },
|
|
249
|
+
});
|
|
250
|
+
if (result.error || result.status !== 0)
|
|
251
|
+
throw new Error(`Cannot confirm ${gitDir} holds no unpushed history`);
|
|
252
|
+
if (result.stdout.trim())
|
|
253
|
+
throw new Error(`Repository has commits not on any remote: ${gitDir}`);
|
|
254
|
+
}
|
|
255
|
+
function strictlyInside(parent, child) {
|
|
256
|
+
const rel = relative(parent, child);
|
|
257
|
+
return rel !== "" && rel !== ".." && !rel.startsWith(`..${sep}`) && !isAbsolute(rel);
|
|
258
|
+
}
|
|
259
|
+
function checkedPath(input, allowed = new Set(), isRoot = false) {
|
|
260
|
+
if (!input?.trim() || /[\0\r\n*?[\]$]/.test(input))
|
|
261
|
+
throw new Error("Use a nonempty explicit path without wildcards or unresolved variables");
|
|
262
|
+
const path = resolve(input);
|
|
263
|
+
let cursor = path;
|
|
264
|
+
while (true) {
|
|
265
|
+
if (protectedNames.has(basename(cursor).toLowerCase()) &&
|
|
266
|
+
!allowed.has(cursor) &&
|
|
267
|
+
!insideArtifactWorkspace(path, cursor, isRoot))
|
|
268
|
+
throw new Error(cursor === path ? protectedMessage(path) : `Protected state contains this path: ${cursor}`);
|
|
269
|
+
const info = lstatSync(cursor);
|
|
270
|
+
if (info.isSymbolicLink())
|
|
271
|
+
throw new Error(`Path contains a symlink: ${cursor}`);
|
|
272
|
+
const parent = dirname(cursor);
|
|
273
|
+
if (parent === cursor)
|
|
274
|
+
break;
|
|
275
|
+
cursor = parent;
|
|
276
|
+
}
|
|
277
|
+
return realpathSync(path);
|
|
278
|
+
}
|
|
279
|
+
function fingerprint(stat) {
|
|
280
|
+
return [stat.dev, stat.ino, stat.mode, stat.size, stat.mtimeMs, stat.ctimeMs].join(":");
|
|
281
|
+
}
|
|
282
|
+
function assertUntracked(target) {
|
|
283
|
+
const git = (args) => spawnSync("git", ["-C", dirname(target), ...args], {
|
|
284
|
+
encoding: "utf8",
|
|
285
|
+
timeout: 10_000,
|
|
286
|
+
maxBuffer: 4 * 1024 * 1024,
|
|
287
|
+
env: {
|
|
288
|
+
...process.env,
|
|
289
|
+
LC_ALL: "C",
|
|
290
|
+
GIT_LITERAL_PATHSPECS: "1",
|
|
291
|
+
GIT_DIR: undefined,
|
|
292
|
+
GIT_WORK_TREE: undefined,
|
|
293
|
+
GIT_INDEX_FILE: undefined,
|
|
294
|
+
},
|
|
295
|
+
});
|
|
296
|
+
const detected = git(["rev-parse", "--show-toplevel"]);
|
|
297
|
+
if (detected.error)
|
|
298
|
+
throw new Error(`Cannot check Git ownership: ${detected.error.message}`);
|
|
299
|
+
if (detected.status !== 0) {
|
|
300
|
+
if (detected.status === 128 && detected.stderr.startsWith("fatal: not a git repository"))
|
|
301
|
+
return;
|
|
302
|
+
throw new Error(`Cannot check Git ownership: ${detected.stderr.trim()}`);
|
|
303
|
+
}
|
|
304
|
+
const repo = detected.stdout.trim();
|
|
305
|
+
const tracked = git(["ls-files", "--cached", "-z", "--full-name", "--", target]);
|
|
306
|
+
if (tracked.error || tracked.status !== 0)
|
|
307
|
+
throw new Error(`Cannot inspect Git index in ${repo}`);
|
|
308
|
+
if (tracked.stdout.length)
|
|
309
|
+
throw new Error(`Tracked files are protected; use git rm for intentional source removal: ${target}`);
|
|
310
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assume.d.ts","sourceRoot":"","sources":["../../../src/lib/identities/assume.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;
|
|
1
|
+
{"version":3,"file":"assume.d.ts","sourceRoot":"","sources":["../../../src/lib/identities/assume.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AA0BH,MAAM,MAAM,uBAAuB,GAC/B,eAAe,GACf,iBAAiB,GACjB,sBAAsB,GACtB,oBAAoB,GACpB,kBAAkB,GAClB,oBAAoB,GACpB,aAAa,GACb,mBAAmB,CAAC;AAExB,qBAAa,mBAAoB,SAAQ,KAAK;aAE1B,IAAI,EAAE,uBAAuB;gBAA7B,IAAI,EAAE,uBAAuB,EAC7C,OAAO,EAAE,MAAM;CAKlB;AAED,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,OAAO,GAAG,QAAQ,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,+DAA+D;IAC/D,qBAAqB,EAAE,MAAM,GAAG,IAAI,CAAC;CACtC;AAOD;+EAC+E;AAC/E,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EACZ,KAAK,SAAa,EAClB,mBAAmB,GAAE,WAAW,CAAC,MAAM,CAAa,GACnD,gBAAgB,GAAG,IAAI,CA6BzB;AAED;;;;;GAKG;AACH,wBAAgB,6BAA6B,CAC3C,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,gBAAgB,GACzB,OAAO,CAyCT;AAuED,gEAAgE;AAChE,wBAAgB,cAAc,CAC5B,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EACd,IAAI,CAAC,EAAE;IAAE,aAAa,CAAC,EAAE,OAAO,CAAA;CAAE,GACjC,oBAAoB,CAyHtB"}
|
|
@@ -20,7 +20,8 @@ import { recordLiveSweepObservationV3 } from "../../core/agents/live-lifecycle-v
|
|
|
20
20
|
import { readLiveCoordinationRow, readLiveCoordinationRows, } from "../../core/agents/state/live-coordination-view.js";
|
|
21
21
|
import { resolveForkAncestry } from "../../core/agents/state/names.js";
|
|
22
22
|
import { instanceHasLivePid, removePidmapRowsForInstance } from "../../core/agents/state/pidmap.js";
|
|
23
|
-
import { coordFreshnessSeconds } from "../../core/config.js";
|
|
23
|
+
import { coordFreshnessSeconds, resolveBinName } from "../../core/config.js";
|
|
24
|
+
import { eventAdapterIdV3FromPlatform, } from "../../core/events/v3/adapter-id.js";
|
|
24
25
|
import { readRemoteMachines } from "../../core/presence/index.js";
|
|
25
26
|
import { bareName, ensureIdentity, lookupById, lookupByName } from "./index.js";
|
|
26
27
|
const ASSUME_LOCK = "identity-assume.lock";
|
|
@@ -175,13 +176,7 @@ function acquireLock(coordRoot) {
|
|
|
175
176
|
throw new IdentityAssumeError("identity_busy", "another identity assumption is in progress; retry in a moment");
|
|
176
177
|
}
|
|
177
178
|
function adapterOf(platform) {
|
|
178
|
-
|
|
179
|
-
return "cursor";
|
|
180
|
-
if (platform === "codex")
|
|
181
|
-
return "codex";
|
|
182
|
-
if (platform === "openclaw")
|
|
183
|
-
return "openclaw";
|
|
184
|
-
return "claude-code";
|
|
179
|
+
return eventAdapterIdV3FromPlatform(platform, { context: "identity-assume" });
|
|
185
180
|
}
|
|
186
181
|
/** Assume `target` for one live main session. Safe to retry. */
|
|
187
182
|
export function assumeIdentity(coordRoot, instanceId, target, opts) {
|
|
@@ -189,7 +184,7 @@ export function assumeIdentity(coordRoot, instanceId, target, opts) {
|
|
|
189
184
|
try {
|
|
190
185
|
const hb = readLiveCoordinationRow(coordRoot, instanceId);
|
|
191
186
|
if (!hb) {
|
|
192
|
-
throw new IdentityAssumeError("no_live_generation", `no authority-safe live V3 generation for instance '${instanceId}'`);
|
|
187
|
+
throw new IdentityAssumeError("no_live_generation", `no authority-safe live V3 generation for instance '${instanceId}'; run \`${resolveBinName(coordRoot)} agents lifecycle active\` to open a fresh generation for this continuing session, then assume again`);
|
|
193
188
|
}
|
|
194
189
|
if (hb.kind && hb.kind !== "session") {
|
|
195
190
|
throw new IdentityAssumeError("not_session", `identity assumption is limited to main sessions (current kind: ${hb.kind})`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apply.d.ts","sourceRoot":"","sources":["../../../src/lib/instructions/apply.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;
|
|
1
|
+
{"version":3,"file":"apply.d.ts","sourceRoot":"","sources":["../../../src/lib/instructions/apply.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AA2FH,sFAAsF;AACtF,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAYlE;AAmBD,UAAU,SAAS;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,WAAW,CAoInF;AAED,UAAU,UAAU;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,WAAW,CA8FrF;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC;IACpC,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACzC,WAAW,CA2Db"}
|
|
@@ -33,6 +33,8 @@ const ADAPTER_SKILLS_DIR = {
|
|
|
33
33
|
"claude-code": join(".claude", "skills"),
|
|
34
34
|
cursor: join(".agents", "skills"),
|
|
35
35
|
codex: join(".agents", "skills"),
|
|
36
|
+
// OpenCode natively discovers .agents/skills (and .claude/skills); no mirror needed.
|
|
37
|
+
opencode: join(".agents", "skills"),
|
|
36
38
|
};
|
|
37
39
|
function adapterSkillsDir(adapter) {
|
|
38
40
|
return ADAPTER_SKILLS_DIR[adapter] ?? null;
|
|
@@ -67,8 +67,7 @@ export function renderInstructionsBlock(binName, skills = { decide: true, counci
|
|
|
67
67
|
return `## harnery coordination
|
|
68
68
|
|
|
69
69
|
This project runs [harnery](https://harnery.com) for multi-agent coordination.
|
|
70
|
-
You share this checkout with other agents; the surfaces below keep you oriented
|
|
71
|
-
and out of each other's way, and let you dispatch a team of your own when a job
|
|
70
|
+
You share this checkout with other agents; the surfaces below keep you oriented and out of each other's way, and let you dispatch a team of your own when a job
|
|
72
71
|
is bigger than one session. Run \`${b} <command> --help\` for any command's full
|
|
73
72
|
surface. ${deeper}
|
|
74
73
|
|
|
@@ -81,8 +80,7 @@ widely-shared files.
|
|
|
81
80
|
**Task lifecycle.** Beside the activity peers already see, declare whether your
|
|
82
81
|
objective is still open: \`${b} agents lifecycle blocked --reason "<why>"\` when
|
|
83
82
|
it cannot proceed, \`${b} agents lifecycle done\` when it is complete, and
|
|
84
|
-
\`${b} agents lifecycle active\` to reopen. \`done\` requires a current task and
|
|
85
|
-
a passing Git finalization check (dirty or unpushed work refuses, and nothing is
|
|
83
|
+
\`${b} agents lifecycle active\` to reopen. \`done\` requires a current task and a passing Git finalization check (dirty or unpushed work refuses, and nothing is
|
|
86
84
|
written). Ordinary \`set-task\` calls never change lifecycle, and a transition
|
|
87
85
|
that re-mints the session title tells you the new name to copy. ${endPointer}
|
|
88
86
|
|
|
@@ -107,8 +105,7 @@ It reclaims an abandoned namesake (no live process) and refuses only when anothe
|
|
|
107
105
|
live process still holds the name; never hand-edit Harnery's history, heartbeat,
|
|
108
106
|
or derived identity cache.
|
|
109
107
|
|
|
110
|
-
**Declare intent on shell commands.** Every command you run is captured to the
|
|
111
|
-
coordination ledger (\`.harnery/ledgers/v3/\`). Lead a shell command with a
|
|
108
|
+
**Declare intent on shell commands.** Every command you run is captured to the coordination ledger (\`.harnery/ledgers/v3/\`). Lead a shell command with a
|
|
112
109
|
\`# intent: <why>\` comment (or set the tool's description) so the recorded event
|
|
113
110
|
carries a reason instead of \`(no intent)\`; the [tool-intent
|
|
114
111
|
guide](https://harnery.com/guides/tool-intent/) owns the details.
|
|
@@ -132,6 +129,10 @@ After review, use \`${b} artifacts discard <id> --reason "<why no longer needed>
|
|
|
132
129
|
Do not create a repo-root temp directory; \`${b} artifacts clean\` previews
|
|
133
130
|
expired cleanup and requires \`--yes\` to delete anything.
|
|
134
131
|
|
|
132
|
+
**Removing local outputs.** Use \`${b} rm --root <directory> <paths...>\` instead of shell \`rm\`, which skips resolved-path, Git ownership, and peer-claim checks. Preview
|
|
133
|
+
is the default; \`--yes\` deletes permanently and \`--recursive\` permits directories.
|
|
134
|
+
Use \`git rm\` for tracked source and the artifact commands for managed evidence.
|
|
135
|
+
|
|
135
136
|
**Local file links.** When the operator should open a local repo file, mint the
|
|
136
137
|
URL with \`${b} files url <repo-relative-path>\` instead of guessing it. HTML opens
|
|
137
138
|
as a real page with working scripts and relative assets; other files open in the
|
|
@@ -142,8 +143,7 @@ can't resolve from the repo, file it instead. \`${b} decision file "<question>"\
|
|
|
142
143
|
records it and lets you proceed on a stated default; \`${b} decision search "<terms>"\`
|
|
143
144
|
surfaces prior decisions, so check for precedent before re-deciding. ${decidePointer}
|
|
144
145
|
|
|
145
|
-
**Councils.** For a hard or contested decision, convene a council of agents.
|
|
146
|
-
\`${b} council create "<objective>"\` runs structured rounds toward a decision. ${councilPointer}`;
|
|
146
|
+
**Councils.** For a hard or contested decision, convene a council of agents. \`${b} council create "<objective>"\` runs structured rounds toward a decision. ${councilPointer}`;
|
|
147
147
|
}
|
|
148
148
|
function decideBody(b) {
|
|
149
149
|
return `The decision docket is a persistent queue for decisions you would otherwise
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/pace/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,gBAAgB,EAChB,QAAQ,EACR,KAAK,YAAY,EACjB,KAAK,UAAU,EACf,KAAK,QAAQ,EACb,iBAAiB,EACjB,WAAW,EACX,SAAS,GACV,MAAM,WAAW,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { commandPaceGate, DEFAULT_PACE_LEDGER, DEFAULT_PACE_MAX_MS, DEFAULT_PACE_MIN_MS, describePaceWait, PaceGate, pacePolicyFromEnv, paceSiteKey, sleepSync, } from "./pace.js";
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Human-pace gate for page loads.
|
|
3
|
+
*
|
|
4
|
+
* Every Harnery surface that loads a web page (`browse`, `browse-ai`, `fetch`,
|
|
5
|
+
* and the headed browse-session verbs) reserves a slot here before the request
|
|
6
|
+
* goes out. Consecutive loads against the same registrable site are spaced by
|
|
7
|
+
* a random gap inside `[minMs, maxMs]`, the way a person reads one page before
|
|
8
|
+
* opening the next. Loads against different sites do not wait on each other.
|
|
9
|
+
* Loopback, private-network, single-label, and reserved-suffix hosts are exempt
|
|
10
|
+
* so local development and page QA keep running at machine speed.
|
|
11
|
+
*
|
|
12
|
+
* The ledger is a small machine-local JSON file (`~/.cache/harnery/pace.json`)
|
|
13
|
+
* shared by every process, so separate `harn fetch` calls in a shell loop are
|
|
14
|
+
* paced the same as one long `harn browse` session. A caller reserves the next
|
|
15
|
+
* slot before it sleeps, so concurrent processes queue behind each other
|
|
16
|
+
* instead of all firing at once.
|
|
17
|
+
*
|
|
18
|
+
* The gate is on by default. `HARNERY_PACE=off` disables it machine-wide and
|
|
19
|
+
* each command carries `--no-pace` for a single run.
|
|
20
|
+
*/
|
|
21
|
+
export declare const DEFAULT_PACE_MIN_MS = 3000;
|
|
22
|
+
export declare const DEFAULT_PACE_MAX_MS = 9000;
|
|
23
|
+
export declare const DEFAULT_PACE_LEDGER: string;
|
|
24
|
+
export interface PacePolicy {
|
|
25
|
+
/** False turns the gate into a no-op. Default true. */
|
|
26
|
+
enabled: boolean;
|
|
27
|
+
/** Shortest gap between two loads of the same site, in ms. */
|
|
28
|
+
minMs: number;
|
|
29
|
+
/** Longest gap between two loads of the same site, in ms. */
|
|
30
|
+
maxMs: number;
|
|
31
|
+
/** Extra exempt host suffixes (`example.test` matches itself and `*.example.test`). */
|
|
32
|
+
exemptSuffixes: string[];
|
|
33
|
+
/** Path of the shared reservation ledger. */
|
|
34
|
+
ledgerPath: string;
|
|
35
|
+
}
|
|
36
|
+
export interface PaceWait {
|
|
37
|
+
/** Registrable site the reservation was made against. */
|
|
38
|
+
site: string;
|
|
39
|
+
/** Milliseconds the caller waited (0 when the slot was free). */
|
|
40
|
+
waitMs: number;
|
|
41
|
+
}
|
|
42
|
+
export interface PaceGateDeps {
|
|
43
|
+
now?: () => number;
|
|
44
|
+
random?: () => number;
|
|
45
|
+
/** Called after a reservation, whether or not it waited. */
|
|
46
|
+
onWait?: (wait: PaceWait) => void;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Resolve the pace policy from the environment.
|
|
50
|
+
*
|
|
51
|
+
* - `HARNERY_PACE`: `off` (or `0`, `false`, `no`) disables the gate. Unset or
|
|
52
|
+
* `human` keeps the default.
|
|
53
|
+
* - `HARNERY_PACE_MIN_MS` / `HARNERY_PACE_MAX_MS`: gap bounds in ms. Both must
|
|
54
|
+
* be non-negative integers with min <= max.
|
|
55
|
+
* - `HARNERY_PACE_EXEMPT`: comma-separated host suffixes that never wait.
|
|
56
|
+
* - `HARNERY_PACE_LEDGER`: ledger path override.
|
|
57
|
+
*/
|
|
58
|
+
export declare function pacePolicyFromEnv(env?: NodeJS.ProcessEnv): PacePolicy;
|
|
59
|
+
/**
|
|
60
|
+
* Registrable site a URL belongs to for pacing purposes, or `null` when the
|
|
61
|
+
* URL is exempt: a non-HTTP scheme, a loopback or private address, a
|
|
62
|
+
* single-label or reserved-suffix host, or a configured exemption.
|
|
63
|
+
*/
|
|
64
|
+
export declare function paceSiteKey(url: string, exemptSuffixes?: readonly string[]): string | null;
|
|
65
|
+
/** Block the current thread for `ms`. Used by clients that drive a child process synchronously. */
|
|
66
|
+
export declare function sleepSync(ms: number): void;
|
|
67
|
+
export declare class PaceGate {
|
|
68
|
+
readonly policy: PacePolicy;
|
|
69
|
+
private readonly now;
|
|
70
|
+
private readonly random;
|
|
71
|
+
private readonly onWait;
|
|
72
|
+
constructor(policy: PacePolicy, deps?: PaceGateDeps);
|
|
73
|
+
/** A gate that never waits, for callers that opted out. */
|
|
74
|
+
static disabled(): PaceGate;
|
|
75
|
+
/**
|
|
76
|
+
* Reserve the next slot for `url` without sleeping. Returns how long the
|
|
77
|
+
* caller should wait before loading, or `null` when the URL is exempt or the
|
|
78
|
+
* gate is disabled. The reservation is recorded even when the wait is zero,
|
|
79
|
+
* so the next load of the same site owes a gap.
|
|
80
|
+
*/
|
|
81
|
+
reserve(url: string): PaceWait | null;
|
|
82
|
+
/** Reserve a slot and wait it out asynchronously. */
|
|
83
|
+
before(url: string): Promise<PaceWait | null>;
|
|
84
|
+
/** Reserve a slot and block the thread for it. For `spawnSync`-driven clients. */
|
|
85
|
+
beforeSync(url: string): PaceWait | null;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Gate for a CLI command run. `null` when the run passed `--no-pace`;
|
|
89
|
+
* otherwise the environment policy, with every non-zero wait reported through
|
|
90
|
+
* `log` so the operator can see why a load took longer.
|
|
91
|
+
*/
|
|
92
|
+
export declare function commandPaceGate(optedIn: boolean, log: (message: string) => void): PaceGate | null;
|
|
93
|
+
/** Describe a wait for a human-facing log line. */
|
|
94
|
+
export declare function describePaceWait(wait: PaceWait): string;
|
|
95
|
+
//# sourceMappingURL=pace.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pace.d.ts","sourceRoot":"","sources":["../../../src/lib/pace/pace.ts"],"names":[],"mappings":"AAaA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,eAAO,MAAM,mBAAmB,OAAQ,CAAC;AACzC,eAAO,MAAM,mBAAmB,OAAQ,CAAC;AACzC,eAAO,MAAM,mBAAmB,QAAuD,CAAC;AAUxF,MAAM,WAAW,UAAU;IACzB,uDAAuD;IACvD,OAAO,EAAE,OAAO,CAAC;IACjB,8DAA8D;IAC9D,KAAK,EAAE,MAAM,CAAC;IACd,6DAA6D;IAC7D,KAAK,EAAE,MAAM,CAAC;IACd,uFAAuF;IACvF,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,6CAA6C;IAC7C,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,QAAQ;IACvB,yDAAyD;IACzD,IAAI,EAAE,MAAM,CAAC;IACb,iEAAiE;IACjE,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,MAAM,CAAC;IACtB,4DAA4D;IAC5D,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,IAAI,CAAC;CACnC;AAgBD;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,UAAU,CAuBlF;AAwED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,cAAc,GAAE,SAAS,MAAM,EAAO,GAAG,MAAM,GAAG,IAAI,CAmB9F;AAED,mGAAmG;AACnG,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAG1C;AAED,qBAAa,QAAQ;IAMjB,QAAQ,CAAC,MAAM,EAAE,UAAU;IAL7B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;IACnC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;IACtC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAyC;gBAGrD,MAAM,EAAE,UAAU,EAC3B,IAAI,GAAE,YAAiB;IAOzB,2DAA2D;IAC3D,MAAM,CAAC,QAAQ,IAAI,QAAQ;IAI3B;;;;;OAKG;IACH,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI;IAqBrC,qDAAqD;IAC/C,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAQnD,kFAAkF;IAClF,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI;CAKzC;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GAAG,QAAQ,GAAG,IAAI,CAOjG;AAED,mDAAmD;AACnD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAGvD"}
|