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
package/src/core/config.ts
CHANGED
|
@@ -80,6 +80,8 @@ interface HarneryConfig {
|
|
|
80
80
|
/** Optional host prompt-context extension. Project config only. */
|
|
81
81
|
hooks?: {
|
|
82
82
|
promptContext?: unknown;
|
|
83
|
+
/** Project-only opt-in; read via `codexWindowsBridgeConfig()`. */
|
|
84
|
+
codexWindowsBridge?: unknown;
|
|
83
85
|
};
|
|
84
86
|
/**
|
|
85
87
|
* Agent-ritual policy owned by the host project. Git finalization is opt-in:
|
|
@@ -107,7 +109,7 @@ interface HarneryConfig {
|
|
|
107
109
|
* `workflow run` in this repo to subscription billing (API-key vars are
|
|
108
110
|
* scrubbed from child envs) without anyone having to remember the flag.
|
|
109
111
|
*/
|
|
110
|
-
workflow?: { subscriptionOnly?: boolean };
|
|
112
|
+
workflow?: { subscriptionOnly?: boolean; workerFullAccess?: unknown };
|
|
111
113
|
/**
|
|
112
114
|
* Cross-machine presence (ADR 0016). `{ enabled: false }` opts a repo out of
|
|
113
115
|
* the git-refs transport (publishing `refs/harnery/presence/<machine>` to
|
|
@@ -152,15 +154,36 @@ interface HarneryConfig {
|
|
|
152
154
|
archive_keep_min?: number;
|
|
153
155
|
archive_auto_clean?: boolean;
|
|
154
156
|
};
|
|
157
|
+
/**
|
|
158
|
+
* Who can use this project's `.harnery/` state. `private` (the default) keeps every state
|
|
159
|
+
* directory 0700 and every state file 0600, owned by whoever wrote it. `group` makes them 0770 and
|
|
160
|
+
* 0660 so several Unix users who share the project directory's group can coordinate in one
|
|
161
|
+
* project. It never grants access to other users. The project directory must be setgid to that
|
|
162
|
+
* group so new state inherits it. Read via `storageSharing()`.
|
|
163
|
+
*/
|
|
164
|
+
storage?: {
|
|
165
|
+
sharing?: "private" | "group";
|
|
166
|
+
};
|
|
155
167
|
/**
|
|
156
168
|
* Managed working-artifact defaults. `default_retention_days` is the
|
|
157
169
|
* create-time TTL when the caller does not pass `artifacts create --days`.
|
|
158
170
|
*/
|
|
171
|
+
/** Local server registry (`servers` command, `harnery/core/servers`). */
|
|
172
|
+
servers?: {
|
|
173
|
+
/** Inclusive port range per server type, e.g. `"preview": [3100, 3199]`. */
|
|
174
|
+
port_ranges?: Record<string, unknown>;
|
|
175
|
+
idle_hours?: number;
|
|
176
|
+
owner_stale_hours?: number;
|
|
177
|
+
};
|
|
159
178
|
artifacts?: {
|
|
160
179
|
default_retention_days?: number;
|
|
161
180
|
auto_clean?: boolean;
|
|
162
181
|
max_bytes?: number;
|
|
163
182
|
max_unit_bytes?: number;
|
|
183
|
+
idle_grace_hours?: number;
|
|
184
|
+
hold_days?: number;
|
|
185
|
+
max_held_bytes?: number;
|
|
186
|
+
min_free_bytes?: number;
|
|
164
187
|
};
|
|
165
188
|
/**
|
|
166
189
|
* Page review packs. `auto_clean` lets `qa-run` and `review-pack create`
|
|
@@ -484,6 +507,42 @@ export function resolveHooksSetupHint(coordRoot?: string | null): string | null
|
|
|
484
507
|
* values fail closed to no reminder so a malformed optional setting cannot
|
|
485
508
|
* break the prompt hook.
|
|
486
509
|
*/
|
|
510
|
+
/** A plain Windows command name, so it is safe to splice into a PowerShell hook command. */
|
|
511
|
+
const CODEX_WINDOWS_BRIDGE_ENTRY_POINT = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/;
|
|
512
|
+
|
|
513
|
+
export interface CodexWindowsBridgeConfig {
|
|
514
|
+
/** Command name Windows-native Codex hooks hand off to, or null when not opted in. */
|
|
515
|
+
entryPoint: string | null;
|
|
516
|
+
/** Why the configured value was ignored, when it was. */
|
|
517
|
+
error: string | null;
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
/**
|
|
521
|
+
* Per-project opt-in that routes Windows-native Codex hooks through a resident
|
|
522
|
+
* WSL bridge (ADR 0197). Read from the project config only: the value is
|
|
523
|
+
* written into the committed `.codex/hooks.json`, so a user-level setting
|
|
524
|
+
* would make `init` output differ between machines. An invalid value is
|
|
525
|
+
* ignored and reported rather than spliced into a shell command.
|
|
526
|
+
*/
|
|
527
|
+
export function codexWindowsBridgeConfig(projectRoot: string): CodexWindowsBridgeConfig {
|
|
528
|
+
const raw = readProjectConfig(projectRoot).hooks?.codexWindowsBridge;
|
|
529
|
+
if (raw === undefined) return { entryPoint: null, error: null };
|
|
530
|
+
const entryPoint = isPlainObject(raw) ? raw.entryPoint : undefined;
|
|
531
|
+
if (typeof entryPoint !== "string") {
|
|
532
|
+
return {
|
|
533
|
+
entryPoint: null,
|
|
534
|
+
error: "hooks.codexWindowsBridge.entryPoint must be a command name",
|
|
535
|
+
};
|
|
536
|
+
}
|
|
537
|
+
if (!CODEX_WINDOWS_BRIDGE_ENTRY_POINT.test(entryPoint)) {
|
|
538
|
+
return {
|
|
539
|
+
entryPoint: null,
|
|
540
|
+
error: `hooks.codexWindowsBridge.entryPoint ${JSON.stringify(entryPoint)} is not a plain command name`,
|
|
541
|
+
};
|
|
542
|
+
}
|
|
543
|
+
return { entryPoint, error: null };
|
|
544
|
+
}
|
|
545
|
+
|
|
487
546
|
export function hostPromptReminder(coordRoot?: string | null): string | null {
|
|
488
547
|
const root = coordRoot ?? findCoordRoot();
|
|
489
548
|
if (!root) return null;
|
|
@@ -591,6 +650,40 @@ export function workflowSubscriptionOnly(coordRoot?: string | null): boolean {
|
|
|
591
650
|
return readConfig(root).workflow?.subscriptionOnly === true;
|
|
592
651
|
}
|
|
593
652
|
|
|
653
|
+
/**
|
|
654
|
+
* The host's raw worker full-access policy (ADR 0192), validated by
|
|
655
|
+
* `parseWorkerFullAccessPolicy` in the workflow layer, which knows each
|
|
656
|
+
* adapter's effort scale.
|
|
657
|
+
*
|
|
658
|
+
* `.harnery/config.jsonc`:
|
|
659
|
+
* `{ "workflow": { "workerFullAccess": { "enabled": true, "floors": { ... } } } }`
|
|
660
|
+
*
|
|
661
|
+
* This is a trust boundary, so it comes only from the project config, like
|
|
662
|
+
* `agents.finalizationRoots`: a user-global file cannot remove the sandbox from
|
|
663
|
+
* one project's workers. `HARNERY_WORKFLOW_WORKER_FULL_ACCESS=0` turns it off
|
|
664
|
+
* for one process. There is deliberately no `=1`: an environment variable can
|
|
665
|
+
* withdraw the grant but never supply it.
|
|
666
|
+
*/
|
|
667
|
+
export function workflowWorkerFullAccessConfig(coordRoot?: string | null): unknown {
|
|
668
|
+
if (coordEnv("WORKFLOW_WORKER_FULL_ACCESS") === "0") return { enabled: false };
|
|
669
|
+
const root = coordRoot ?? findCoordRoot();
|
|
670
|
+
if (!root) return undefined;
|
|
671
|
+
return readProjectConfig(root).workflow?.workerFullAccess;
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
/**
|
|
675
|
+
* How this project's `.harnery/` state is shared: `private` or `group`. `HARNERY_STORAGE_SHARING`
|
|
676
|
+
* overrides per process; an unrecognized value falls back to `private`, the safer reading.
|
|
677
|
+
*/
|
|
678
|
+
export function storageSharing(coordRoot?: string | null): "private" | "group" {
|
|
679
|
+
const env = coordEnv("STORAGE_SHARING");
|
|
680
|
+
if (env === "group" || env === "private") return env;
|
|
681
|
+
const root = coordRoot ?? findCoordRoot();
|
|
682
|
+
if (!root) return "private";
|
|
683
|
+
// Project file only: a user-global "group" would loosen every project that user touches.
|
|
684
|
+
return readProjectConfig(root).storage?.sharing === "group" ? "group" : "private";
|
|
685
|
+
}
|
|
686
|
+
|
|
594
687
|
/**
|
|
595
688
|
* Whether cross-machine presence (ADR 0016) is enabled for this repo.
|
|
596
689
|
* Default ON — the transport itself additionally gates on an origin remote
|
|
@@ -742,6 +835,46 @@ export function resolveWebPort(explicitPort?: string, coordRoot?: string | null)
|
|
|
742
835
|
return DEFAULT_WEB_PORT;
|
|
743
836
|
}
|
|
744
837
|
|
|
838
|
+
/** The configured inclusive port range for one server type, or null. */
|
|
839
|
+
export function serverPortRange(type: string, coordRoot?: string | null): [number, number] | null {
|
|
840
|
+
const root = coordRoot ?? findCoordRoot();
|
|
841
|
+
const value = root ? readConfig(root).servers?.port_ranges?.[type] : undefined;
|
|
842
|
+
if (!Array.isArray(value) || value.length !== 2) return null;
|
|
843
|
+
const [low, high] = value as unknown[];
|
|
844
|
+
const valid = (n: unknown): n is number =>
|
|
845
|
+
Number.isInteger(n) && (n as number) > 0 && (n as number) < 65536;
|
|
846
|
+
return valid(low) && valid(high) && low <= high ? [low, high] : null;
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
/** Every configured server port range, keyed by type (invalid entries dropped). */
|
|
850
|
+
export function serverPortRanges(coordRoot?: string | null): Record<string, [number, number]> {
|
|
851
|
+
const root = coordRoot ?? findCoordRoot();
|
|
852
|
+
const ranges = root ? readConfig(root).servers?.port_ranges : undefined;
|
|
853
|
+
const out: Record<string, [number, number]> = {};
|
|
854
|
+
for (const type of Object.keys(ranges ?? {})) {
|
|
855
|
+
const range = serverPortRange(type, root);
|
|
856
|
+
if (range) out[type] = range;
|
|
857
|
+
}
|
|
858
|
+
return out;
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
/** Configured `servers gc` windows; undefined fields use the built-in defaults. */
|
|
862
|
+
export function serverGcConfig(coordRoot?: string | null): {
|
|
863
|
+
idle_hours?: number;
|
|
864
|
+
owner_stale_hours?: number;
|
|
865
|
+
} {
|
|
866
|
+
const root = coordRoot ?? findCoordRoot();
|
|
867
|
+
const configured = root ? readConfig(root).servers : undefined;
|
|
868
|
+
const positive = (n: unknown): n is number =>
|
|
869
|
+
typeof n === "number" && Number.isFinite(n) && n > 0;
|
|
870
|
+
return {
|
|
871
|
+
...(positive(configured?.idle_hours) ? { idle_hours: configured.idle_hours } : {}),
|
|
872
|
+
...(positive(configured?.owner_stale_hours)
|
|
873
|
+
? { owner_stale_hours: configured.owner_stale_hours }
|
|
874
|
+
: {}),
|
|
875
|
+
};
|
|
876
|
+
}
|
|
877
|
+
|
|
745
878
|
/** Policy for converging independent termination signals on one finalizer. */
|
|
746
879
|
export function sessionFinalizationConfig(coordRoot?: string | null): SessionFinalizationConfig {
|
|
747
880
|
const root = coordRoot ?? findCoordRoot();
|
|
@@ -820,12 +953,81 @@ export function artifactMaxUnitBytes(coordRoot?: string | null): number {
|
|
|
820
953
|
);
|
|
821
954
|
}
|
|
822
955
|
|
|
956
|
+
/**
|
|
957
|
+
* How long an unexpired workspace must sit idle before a size rule (the
|
|
958
|
+
* per-bundle ceiling or the repository budget) may delete it. Idle means no
|
|
959
|
+
* change inside the workspace and no heartbeat from its owner. An agent waiting
|
|
960
|
+
* on a human reply looks idle, so a short window deletes work someone is still
|
|
961
|
+
* reviewing. Precedence: `HARNERY_ARTIFACT_IDLE_GRACE_HOURS` ->
|
|
962
|
+
* `artifacts.idle_grace_hours` -> 24. Expiry never waits for this grace.
|
|
963
|
+
*/
|
|
964
|
+
export function artifactIdleGraceHours(coordRoot?: string | null): number {
|
|
965
|
+
const root = coordRoot ?? findCoordRoot();
|
|
966
|
+
return integerSetting(
|
|
967
|
+
coordEnv("ARTIFACT_IDLE_GRACE_HOURS"),
|
|
968
|
+
root ? readConfig(root).artifacts?.idle_grace_hours : undefined,
|
|
969
|
+
1,
|
|
970
|
+
24 * 365,
|
|
971
|
+
24,
|
|
972
|
+
);
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
/**
|
|
976
|
+
* Default lifetime of an artifact hold. A hold that is not renewed lapses after
|
|
977
|
+
* this many days and the workspace returns to ordinary retention. Precedence:
|
|
978
|
+
* `HARNERY_ARTIFACT_HOLD_DAYS` -> `artifacts.hold_days` -> 14.
|
|
979
|
+
*/
|
|
980
|
+
export function artifactHoldDays(coordRoot?: string | null): number {
|
|
981
|
+
const root = coordRoot ?? findCoordRoot();
|
|
982
|
+
return integerSetting(
|
|
983
|
+
coordEnv("ARTIFACT_HOLD_DAYS"),
|
|
984
|
+
root ? readConfig(root).artifacts?.hold_days : undefined,
|
|
985
|
+
1,
|
|
986
|
+
365,
|
|
987
|
+
14,
|
|
988
|
+
);
|
|
989
|
+
}
|
|
990
|
+
|
|
991
|
+
/**
|
|
992
|
+
* Advisory budget for held artifact bytes. Exceeding it produces warnings
|
|
993
|
+
* only: holds record owner intent, so cleanup never deletes held work.
|
|
994
|
+
* Precedence: `HARNERY_ARTIFACT_MAX_HELD_BYTES` -> `artifacts.max_held_bytes`
|
|
995
|
+
* -> 20 GiB.
|
|
996
|
+
*/
|
|
997
|
+
export function artifactMaxHeldBytes(coordRoot?: string | null): number {
|
|
998
|
+
const root = coordRoot ?? findCoordRoot();
|
|
999
|
+
return integerSetting(
|
|
1000
|
+
coordEnv("ARTIFACT_MAX_HELD_BYTES"),
|
|
1001
|
+
root ? readConfig(root).artifacts?.max_held_bytes : undefined,
|
|
1002
|
+
64 * 1024 * 1024,
|
|
1003
|
+
1024 * 1024 * 1024 * 1024,
|
|
1004
|
+
DEFAULT_ARTIFACT_MAX_BYTES,
|
|
1005
|
+
);
|
|
1006
|
+
}
|
|
1007
|
+
|
|
1008
|
+
/**
|
|
1009
|
+
* Free-disk floor for the artifact store. Below it, artifact commands warn and
|
|
1010
|
+
* `artifacts create --big` refuses unless `--allow-low-disk` is passed.
|
|
1011
|
+
* Precedence: `HARNERY_ARTIFACT_MIN_FREE_BYTES` -> `artifacts.min_free_bytes`
|
|
1012
|
+
* -> 20 GiB. Zero disables the floor.
|
|
1013
|
+
*/
|
|
1014
|
+
export function artifactMinFreeBytes(coordRoot?: string | null): number {
|
|
1015
|
+
const root = coordRoot ?? findCoordRoot();
|
|
1016
|
+
return integerSetting(
|
|
1017
|
+
coordEnv("ARTIFACT_MIN_FREE_BYTES"),
|
|
1018
|
+
root ? readConfig(root).artifacts?.min_free_bytes : undefined,
|
|
1019
|
+
0,
|
|
1020
|
+
1024 * 1024 * 1024 * 1024 * 1024,
|
|
1021
|
+
20 * 1024 * 1024 * 1024,
|
|
1022
|
+
);
|
|
1023
|
+
}
|
|
1024
|
+
|
|
823
1025
|
/**
|
|
824
1026
|
* Whether opportunistic cleanup of expired artifact workspaces runs.
|
|
825
1027
|
* Precedence: `HARNERY_ARTIFACT_AUTO_CLEAN` (0/false disables) ->
|
|
826
|
-
* `artifacts.auto_clean` -> enabled. The sweep
|
|
827
|
-
* `managed-expired`
|
|
828
|
-
* `artifacts clean --yes
|
|
1028
|
+
* `artifacts.auto_clean` -> enabled. The sweep deletes the same
|
|
1029
|
+
* `managed-expired`, `managed-oversize`, and `managed-over-budget` entries as
|
|
1030
|
+
* `artifacts clean --yes`, through the same guarded classifier.
|
|
829
1031
|
*/
|
|
830
1032
|
export function artifactAutoCleanEnabled(coordRoot?: string | null): boolean {
|
|
831
1033
|
const env = coordEnv("ARTIFACT_AUTO_CLEAN");
|
|
@@ -11,6 +11,7 @@ import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "
|
|
|
11
11
|
import { dirname, join } from "node:path";
|
|
12
12
|
import type { Adapter } from "../adapter.ts";
|
|
13
13
|
import { readLiveCoordinationRow } from "../agents/state/live-coordination-view.ts";
|
|
14
|
+
import { stateFileMode } from "../storage/modes.ts";
|
|
14
15
|
|
|
15
16
|
export const CONTEXT_SCHEMA_VERSION = 1 as const;
|
|
16
17
|
export const MAX_CAPSULE_BYTES = 32 * 1024;
|
|
@@ -499,7 +500,7 @@ function writeBoundedJson(path: string, value: unknown, maxBytes: number): void
|
|
|
499
500
|
}
|
|
500
501
|
mkdirSync(dirname(path), { recursive: true });
|
|
501
502
|
const temp = `${path}.tmp.${process.pid}.${randomUUID()}`;
|
|
502
|
-
writeFileSync(temp, text, { encoding: "utf8", mode:
|
|
503
|
+
writeFileSync(temp, text, { encoding: "utf8", mode: stateFileMode() });
|
|
503
504
|
renameSync(temp, path);
|
|
504
505
|
}
|
|
505
506
|
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
type DurableHistoryFaultBoundary,
|
|
6
6
|
readDurableHistorySync,
|
|
7
7
|
} from "../storage/durable-history.ts";
|
|
8
|
+
import { stateDirMode, stateFileMode } from "../storage/modes.ts";
|
|
8
9
|
import type {
|
|
9
10
|
HarneryConversationAccessMode,
|
|
10
11
|
HarneryConversationArchiveAuthorityMode,
|
|
@@ -69,10 +70,10 @@ export async function captureProviderConversation(
|
|
|
69
70
|
provider.capabilities.provider_id,
|
|
70
71
|
options.conversation_id,
|
|
71
72
|
);
|
|
72
|
-
mkdirSync(objectDir, { recursive: true, mode:
|
|
73
|
+
mkdirSync(objectDir, { recursive: true, mode: stateDirMode() });
|
|
73
74
|
const lease = join(objectDir, ".capture.lease");
|
|
74
75
|
try {
|
|
75
|
-
mkdirSync(lease, { mode:
|
|
76
|
+
mkdirSync(lease, { mode: stateDirMode() });
|
|
76
77
|
} catch {
|
|
77
78
|
throw new Error(`conversation capture lease busy: ${options.conversation_id}`);
|
|
78
79
|
}
|
|
@@ -223,7 +224,7 @@ function manifestFor(
|
|
|
223
224
|
function publishManifest(objectDir: string, manifest: HarneryConversationArchiveManifest): void {
|
|
224
225
|
const path = join(objectDir, "manifest.json");
|
|
225
226
|
const temp = `${path}.tmp-${process.pid}`;
|
|
226
|
-
writeFileSync(temp, `${JSON.stringify(manifest, null, 2)}\n`, { mode:
|
|
227
|
+
writeFileSync(temp, `${JSON.stringify(manifest, null, 2)}\n`, { mode: stateFileMode() });
|
|
227
228
|
renameSync(temp, path);
|
|
228
229
|
}
|
|
229
230
|
|
|
@@ -15,6 +15,7 @@ import type {
|
|
|
15
15
|
} from "../artifacts/index.ts";
|
|
16
16
|
import {
|
|
17
17
|
ARTIFACT_MANIFEST,
|
|
18
|
+
artifactHoldState,
|
|
18
19
|
artifactsRoot,
|
|
19
20
|
configuredArtifactRetentionDays,
|
|
20
21
|
createArtifact,
|
|
@@ -25,6 +26,7 @@ import {
|
|
|
25
26
|
} from "../artifacts/index.ts";
|
|
26
27
|
import { currentHarneryRuntimeBuild } from "../events/v3/runtime-build.ts";
|
|
27
28
|
import { writePrivateJsonAtomic } from "../storage/atomic-json.ts";
|
|
29
|
+
import { stateDirMode } from "../storage/modes.ts";
|
|
28
30
|
import {
|
|
29
31
|
SUPERVISOR_DIAGNOSTIC_LIMITS,
|
|
30
32
|
SUPERVISOR_EXPLANATION_SCHEMA_VERSION,
|
|
@@ -171,8 +173,8 @@ export function captureDiagnosticBundle(
|
|
|
171
173
|
now,
|
|
172
174
|
});
|
|
173
175
|
const inputsPath = join(created.path, "inputs");
|
|
174
|
-
mkdirSync(inputsPath, { recursive: true, mode:
|
|
175
|
-
tryChmod(inputsPath,
|
|
176
|
+
mkdirSync(inputsPath, { recursive: true, mode: stateDirMode() });
|
|
177
|
+
tryChmod(inputsPath, stateDirMode());
|
|
176
178
|
|
|
177
179
|
const payloads: Record<(typeof PAYLOAD_FILES)[number], unknown> = {
|
|
178
180
|
"inputs/observations.json": observations,
|
|
@@ -411,7 +413,7 @@ function candidateArtifactId(artifactPath: string): string | undefined {
|
|
|
411
413
|
function candidateClassification(
|
|
412
414
|
manifest: ArtifactManifestV2,
|
|
413
415
|
): ArtifactInventoryEntry["classification"] {
|
|
414
|
-
if (manifest.
|
|
416
|
+
if (artifactHoldState(manifest).active.length > 0) return "managed-held";
|
|
415
417
|
if (!manifest.released_at) return "managed-active";
|
|
416
418
|
return Date.parse(manifest.retention.expires_at) <= Date.now()
|
|
417
419
|
? "managed-expired"
|
|
@@ -4,6 +4,7 @@ import { chmod, lstat, mkdir, open, rename, rm } from "node:fs/promises";
|
|
|
4
4
|
import { basename, join, resolve } from "node:path";
|
|
5
5
|
import { pipeline } from "node:stream/promises";
|
|
6
6
|
import { createGzip } from "node:zlib";
|
|
7
|
+
import { stateDirMode, stateFileMode } from "../../storage/modes.ts";
|
|
7
8
|
import { canonicalJsonV3 } from "../v3/canonical.ts";
|
|
8
9
|
import { verifyLegacyV1HardFence } from "./fence.ts";
|
|
9
10
|
import { type LegacyV1SegmentManifest, validateLegacyV1SegmentManifest } from "./manifest.ts";
|
|
@@ -46,8 +47,8 @@ export async function writeLegacyV1Canary(input: {
|
|
|
46
47
|
.digest("hex")
|
|
47
48
|
.slice(0, 32)}` as const;
|
|
48
49
|
const outputDirectory = resolve(input.output_directory);
|
|
49
|
-
await mkdir(outputDirectory, { recursive: true, mode:
|
|
50
|
-
await chmod(outputDirectory,
|
|
50
|
+
await mkdir(outputDirectory, { recursive: true, mode: stateDirMode() });
|
|
51
|
+
await chmod(outputDirectory, stateDirMode());
|
|
51
52
|
const payloadPath = join(outputDirectory, `${segmentId}.ndjson.gz`);
|
|
52
53
|
const manifestPath = join(outputDirectory, `${segmentId}.manifest.json`);
|
|
53
54
|
const partialPayload = `${payloadPath}.partial`;
|
|
@@ -57,7 +58,7 @@ export async function writeLegacyV1Canary(input: {
|
|
|
57
58
|
await pipeline(
|
|
58
59
|
createReadStream(source),
|
|
59
60
|
createGzip({ level: 9 }),
|
|
60
|
-
createWriteStream(partialPayload, { flags: "wx", mode:
|
|
61
|
+
createWriteStream(partialPayload, { flags: "wx", mode: stateFileMode() }),
|
|
61
62
|
);
|
|
62
63
|
await rename(partialPayload, payloadPath);
|
|
63
64
|
const payloadStat = await lstat(payloadPath);
|
|
@@ -85,7 +86,7 @@ export async function writeLegacyV1Canary(input: {
|
|
|
85
86
|
const handle = await open(
|
|
86
87
|
partialManifest,
|
|
87
88
|
constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL,
|
|
88
|
-
|
|
89
|
+
stateFileMode(),
|
|
89
90
|
);
|
|
90
91
|
try {
|
|
91
92
|
await handle.writeFile(`${canonicalJsonV3(manifest)}\n`, "utf8");
|
|
@@ -5,6 +5,7 @@ import { chmod, lstat, rename, rm } from "node:fs/promises";
|
|
|
5
5
|
import { basename } from "node:path";
|
|
6
6
|
import { pipeline } from "node:stream/promises";
|
|
7
7
|
import { createGzip } from "node:zlib";
|
|
8
|
+
import { stateFileMode } from "../../storage/modes.ts";
|
|
8
9
|
import { verifyLegacyV1HardFence } from "./fence.ts";
|
|
9
10
|
import { inventoryLegacyV1Segments } from "./inventory.ts";
|
|
10
11
|
import { streamLegacyV1Rows } from "./reader.ts";
|
|
@@ -84,7 +85,7 @@ export async function compressSealedLegacyV1Segments(
|
|
|
84
85
|
await pipeline(
|
|
85
86
|
createReadStream(row.path),
|
|
86
87
|
createGzip({ level: 9 }),
|
|
87
|
-
createWriteStream(temporary, { flags: "wx", mode:
|
|
88
|
+
createWriteStream(temporary, { flags: "wx", mode: stateFileMode() }),
|
|
88
89
|
);
|
|
89
90
|
await proveRowParity(row.path, temporary);
|
|
90
91
|
const unchanged = (await inventoryLegacyV1Segments(coordRoot)).find(
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import
|
|
1
|
+
import {
|
|
2
|
+
type Adapter,
|
|
3
|
+
type AdapterFallbackOptions,
|
|
4
|
+
DEFAULT_ADAPTER,
|
|
5
|
+
normalizeAdapterId,
|
|
6
|
+
resolveAdapterId,
|
|
7
|
+
} from "../../adapter.ts";
|
|
2
8
|
|
|
3
9
|
/** Harness identities that may produce or describe Event Ledger V3 evidence. */
|
|
4
10
|
export type EventAdapterIdV3 = Adapter | "openclaw";
|
|
@@ -8,5 +14,27 @@ export const EVENT_ADAPTER_IDS_V3 = [
|
|
|
8
14
|
"claude-code",
|
|
9
15
|
"codex",
|
|
10
16
|
"cursor",
|
|
17
|
+
"opencode",
|
|
11
18
|
"openclaw",
|
|
12
19
|
] as const satisfies readonly EventAdapterIdV3[];
|
|
20
|
+
|
|
21
|
+
type MissingEventAdapterId = Exclude<EventAdapterIdV3, (typeof EVENT_ADAPTER_IDS_V3)[number]>;
|
|
22
|
+
const eventAdapterIdsComplete: [MissingEventAdapterId] extends [never] ? true : never = true;
|
|
23
|
+
void eventAdapterIdsComplete;
|
|
24
|
+
|
|
25
|
+
/** Strict event-adapter normalizer: a known id or `null`. */
|
|
26
|
+
export function normalizeEventAdapterIdV3(value: unknown): EventAdapterIdV3 | null {
|
|
27
|
+
return normalizeAdapterId(value, EVENT_ADAPTER_IDS_V3);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Heartbeat `platform` to an event adapter id, substituting `DEFAULT_ADAPTER`
|
|
32
|
+
* and reporting the substitution. Use this wherever a row must be attributed
|
|
33
|
+
* to some adapter; use `normalizeEventAdapterIdV3` when `null` is acceptable.
|
|
34
|
+
*/
|
|
35
|
+
export function eventAdapterIdV3FromPlatform(
|
|
36
|
+
value: unknown,
|
|
37
|
+
options?: AdapterFallbackOptions,
|
|
38
|
+
): EventAdapterIdV3 {
|
|
39
|
+
return resolveAdapterId(value, EVENT_ADAPTER_IDS_V3, DEFAULT_ADAPTER, options);
|
|
40
|
+
}
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
writeFileSync,
|
|
12
12
|
} from "node:fs";
|
|
13
13
|
import { join } from "node:path";
|
|
14
|
+
import { stateFileMode } from "../../storage/modes.ts";
|
|
14
15
|
import { fsyncParentDirectory } from "../../workflow/durable-record.ts";
|
|
15
16
|
import { canonicalJsonV3, sha256V3 } from "./canonical.ts";
|
|
16
17
|
import type { EventV3 } from "./contract.ts";
|
|
@@ -540,7 +541,7 @@ function publishExclusive(path: string, serialized: string): void {
|
|
|
540
541
|
const temporary = `${path}.tmp-${process.pid}-${randomUUID()}`;
|
|
541
542
|
let fd: number | undefined;
|
|
542
543
|
try {
|
|
543
|
-
fd = openSync(temporary, "wx",
|
|
544
|
+
fd = openSync(temporary, "wx", stateFileMode());
|
|
544
545
|
writeFileSync(fd, serialized, "utf8");
|
|
545
546
|
fsyncSync(fd);
|
|
546
547
|
closeSync(fd);
|
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
import { hostname } from "node:os";
|
|
17
17
|
import { dirname, join, resolve } from "node:path";
|
|
18
18
|
import { fileURLToPath } from "node:url";
|
|
19
|
+
import { stateDirMode, stateFileMode } from "../../storage/modes.ts";
|
|
19
20
|
import { fsyncParentDirectory } from "../../workflow/durable-record.ts";
|
|
20
21
|
import { acquireNoClobberLease } from "../../workflow/workspaces/leases.ts";
|
|
21
22
|
import { canonicalJsonV3, sha256V3 } from "./canonical.ts";
|
|
@@ -524,7 +525,7 @@ function archiveCurrentEpoch(root: string, createdAt: string): string | undefine
|
|
|
524
525
|
const current = join(root, ".harnery", "ledgers", "v3");
|
|
525
526
|
if (!existsSync(current)) return undefined;
|
|
526
527
|
const archives = join(root, ".harnery", "ledgers", "v3-archives");
|
|
527
|
-
mkdirSync(archives, { recursive: true, mode:
|
|
528
|
+
mkdirSync(archives, { recursive: true, mode: stateDirMode() });
|
|
528
529
|
const stamp = createdAt.replace(/[^0-9]/g, "");
|
|
529
530
|
let target = join(archives, `epoch-${stamp}`);
|
|
530
531
|
let suffix = 0;
|
|
@@ -535,20 +536,20 @@ function archiveCurrentEpoch(root: string, createdAt: string): string | undefine
|
|
|
535
536
|
}
|
|
536
537
|
|
|
537
538
|
function publishControlFile(path: string, value: unknown): void {
|
|
538
|
-
mkdirSync(dirname(path), { recursive: true, mode:
|
|
539
|
+
mkdirSync(dirname(path), { recursive: true, mode: stateDirMode() });
|
|
539
540
|
const temp = `${path}.tmp.${process.pid}`;
|
|
540
541
|
// A prior failed publish by this same pid would otherwise make every retry
|
|
541
542
|
// fail on the exclusive create, which is exactly how one transient error
|
|
542
543
|
// turns into a permanently stranded epoch.
|
|
543
544
|
if (existsSync(temp)) unlinkSync(temp);
|
|
544
|
-
const fd = openSync(temp, "wx",
|
|
545
|
+
const fd = openSync(temp, "wx", stateFileMode());
|
|
545
546
|
try {
|
|
546
547
|
writeFileSync(fd, `${canonicalJsonV3(value)}\n`, "utf8");
|
|
547
548
|
fsyncSync(fd);
|
|
548
549
|
} finally {
|
|
549
550
|
closeSync(fd);
|
|
550
551
|
}
|
|
551
|
-
chmodSync(temp,
|
|
552
|
+
chmodSync(temp, stateFileMode());
|
|
552
553
|
renameSync(temp, path);
|
|
553
554
|
fsyncParentDirectory(path);
|
|
554
555
|
}
|
|
@@ -115,6 +115,19 @@ const BASE_SIGNAL_SUPPORT: Record<
|
|
|
115
115
|
post_compaction: "unsupported",
|
|
116
116
|
context_usage: "conditional",
|
|
117
117
|
},
|
|
118
|
+
opencode: {
|
|
119
|
+
...SHARED_SIGNAL_SUPPORT,
|
|
120
|
+
// OpenCode sessions are persistent server objects; the plugin observes a
|
|
121
|
+
// turn boundary (session.idle) rather than a clean session close, so end is
|
|
122
|
+
// conditional. Turns group by messageID without a first-class turn id.
|
|
123
|
+
session_end: "conditional",
|
|
124
|
+
turn_id: "conditional",
|
|
125
|
+
permission: "native",
|
|
126
|
+
// Compaction is intercepted (session.hook("compaction")); post-compaction
|
|
127
|
+
// recovery and SQLite-backed context usage are not yet certified.
|
|
128
|
+
post_compaction: "unsupported",
|
|
129
|
+
context_usage: "unsupported",
|
|
130
|
+
},
|
|
118
131
|
openclaw: {
|
|
119
132
|
session_start: "conditional",
|
|
120
133
|
session_end: "native",
|
|
@@ -169,6 +182,10 @@ export const ADAPTER_CAPABILITY_PROFILES_V3: Record<EventAdapterIdV3, AdapterCap
|
|
|
169
182
|
model_usage: "unsupported",
|
|
170
183
|
inference_timing: "unsupported",
|
|
171
184
|
}),
|
|
185
|
+
opencode: profile("opencode", {
|
|
186
|
+
model_usage: "conditional",
|
|
187
|
+
inference_timing: "unsupported",
|
|
188
|
+
}),
|
|
172
189
|
openclaw: profile(
|
|
173
190
|
"openclaw",
|
|
174
191
|
{
|
|
@@ -123,8 +123,15 @@ export const TurnCompletedV3Schema = eventV3("turn.completed", {
|
|
|
123
123
|
}),
|
|
124
124
|
});
|
|
125
125
|
|
|
126
|
+
export const ToolLineChangesV3Schema = StrictObject({
|
|
127
|
+
added: Type.Integer({ minimum: 0 }),
|
|
128
|
+
removed: Type.Integer({ minimum: 0 }),
|
|
129
|
+
});
|
|
130
|
+
|
|
126
131
|
export const ToolCompletedV3Schema = eventV3("tool.completed", {
|
|
127
|
-
payload: terminalPayloadV3("tool.completed"
|
|
132
|
+
payload: terminalPayloadV3("tool.completed", {
|
|
133
|
+
line_changes: Type.Optional(ObservationV3Schema(ToolLineChangesV3Schema)),
|
|
134
|
+
}),
|
|
128
135
|
});
|
|
129
136
|
|
|
130
137
|
export const CommandCompletedV3Schema = eventV3("command.completed", {
|
|
@@ -260,6 +267,7 @@ type ToolCompletedEventV3 = ReplaceEventV3<
|
|
|
260
267
|
Omit<EventOfTypeV3Base<"tool.completed">["payload"], "duration_ms"> & {
|
|
261
268
|
duration_ms: SpanSummaryValueV3["duration_ms"];
|
|
262
269
|
span: SpanSummaryValueV3;
|
|
270
|
+
line_changes?: Static<ReturnType<typeof ObservationV3Schema<typeof ToolLineChangesV3Schema>>>;
|
|
263
271
|
}
|
|
264
272
|
>;
|
|
265
273
|
type CommandCompletedEventV3 = ReplaceEventV3<
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
unlinkSync,
|
|
11
11
|
writeFileSync,
|
|
12
12
|
} from "node:fs";
|
|
13
|
+
import { stateFileMode } from "../../storage/modes.ts";
|
|
13
14
|
import { fsyncParentDirectory } from "../../workflow/durable-record.ts";
|
|
14
15
|
import { canonicalJsonV3, type FingerprintV3, fingerprintV3, sha256V3 } from "./canonical.ts";
|
|
15
16
|
import type { ActivationManifestV3, CandidateGenesisManifestV3 } from "./control.ts";
|
|
@@ -332,12 +333,12 @@ function publishCanonicalFileV3(path: string, value: unknown): boolean {
|
|
|
332
333
|
const temporary = `${path}.tmp-${process.pid}-${randomUUID()}`;
|
|
333
334
|
let fd: number | undefined;
|
|
334
335
|
try {
|
|
335
|
-
fd = openSync(temporary, "wx",
|
|
336
|
+
fd = openSync(temporary, "wx", stateFileMode());
|
|
336
337
|
writeFileSync(fd, `${canonicalJsonV3(value)}\n`, "utf8");
|
|
337
338
|
fsyncSync(fd);
|
|
338
339
|
closeSync(fd);
|
|
339
340
|
fd = undefined;
|
|
340
|
-
chmodSync(temporary,
|
|
341
|
+
chmodSync(temporary, stateFileMode());
|
|
341
342
|
renameSync(temporary, path);
|
|
342
343
|
fsyncParentDirectory(path);
|
|
343
344
|
return true;
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
writeFileSync,
|
|
14
14
|
} from "node:fs";
|
|
15
15
|
import { join } from "node:path";
|
|
16
|
+
import { stateDirMode, stateFileMode } from "../../storage/modes.ts";
|
|
16
17
|
import { fsyncParentDirectory } from "../../workflow/durable-record.ts";
|
|
17
18
|
import {
|
|
18
19
|
type AuthorityTransactionV3,
|
|
@@ -306,8 +307,8 @@ function recoveryPaths(coordRoot: string, transactionId: string) {
|
|
|
306
307
|
|
|
307
308
|
function ensureRecoveryLayout(paths: ReturnType<typeof recoveryPaths>): void {
|
|
308
309
|
for (const path of [paths.root, paths.quarantineRoot]) {
|
|
309
|
-
mkdirSync(path, { recursive: true, mode:
|
|
310
|
-
chmodSync(path,
|
|
310
|
+
mkdirSync(path, { recursive: true, mode: stateDirMode() });
|
|
311
|
+
chmodSync(path, stateDirMode());
|
|
311
312
|
}
|
|
312
313
|
}
|
|
313
314
|
|
|
@@ -325,7 +326,7 @@ function publishSerializedExclusive(path: string, serialized: string): void {
|
|
|
325
326
|
const temporary = `${path}.tmp-${process.pid}-${randomUUID()}`;
|
|
326
327
|
let fd: number | undefined;
|
|
327
328
|
try {
|
|
328
|
-
fd = openSync(temporary, "wx",
|
|
329
|
+
fd = openSync(temporary, "wx", stateFileMode());
|
|
329
330
|
writeFileSync(fd, serialized, "utf8");
|
|
330
331
|
fsyncSync(fd);
|
|
331
332
|
closeSync(fd);
|
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
} from "node:fs";
|
|
15
15
|
import { hostname } from "node:os";
|
|
16
16
|
import { join, resolve } from "node:path";
|
|
17
|
+
import { stateDirMode, stateFileMode, stateModeTooOpen } from "../../storage/modes.ts";
|
|
17
18
|
import { fsyncParentDirectory } from "../../workflow/durable-record.ts";
|
|
18
19
|
import { acquireNoClobberLease } from "../../workflow/workspaces/leases.ts";
|
|
19
20
|
import type { FingerprintContextV3 } from "./canonical.ts";
|
|
@@ -78,8 +79,8 @@ export function readFingerprintKeyStoreV3(coordRoot: string): FingerprintKeyStor
|
|
|
78
79
|
|
|
79
80
|
function readKeyStoreValue(path: string): unknown {
|
|
80
81
|
const mode = statSync(path).mode & 0o777;
|
|
81
|
-
if ((mode
|
|
82
|
-
throw new Error("fingerprint key store
|
|
82
|
+
if (stateModeTooOpen(mode)) {
|
|
83
|
+
throw new Error("fingerprint key store is open to other users");
|
|
83
84
|
}
|
|
84
85
|
let parsed: unknown;
|
|
85
86
|
try {
|
|
@@ -135,8 +136,8 @@ export function fingerprintContextV3(
|
|
|
135
136
|
|
|
136
137
|
function withKeyStoreLock<T>(coordRoot: string, operation: () => T): T {
|
|
137
138
|
const privateDir = join(resolve(coordRoot), ".harnery/private");
|
|
138
|
-
mkdirSync(privateDir, { recursive: true, mode:
|
|
139
|
-
chmodSync(privateDir,
|
|
139
|
+
mkdirSync(privateDir, { recursive: true, mode: stateDirMode() });
|
|
140
|
+
chmodSync(privateDir, stateDirMode());
|
|
140
141
|
const leasePath = join(privateDir, "fingerprint-key-lease");
|
|
141
142
|
const authority = createHash("sha256").update(resolve(coordRoot)).digest("hex");
|
|
142
143
|
let lease: ReturnType<typeof acquireNoClobberLease> | undefined;
|
|
@@ -178,12 +179,12 @@ function publishKeyStore(path: string, store: FingerprintKeyStoreV3, replacing:
|
|
|
178
179
|
const temporary = `${path}.tmp-${process.pid}-${randomUUID()}`;
|
|
179
180
|
let fd: number | undefined;
|
|
180
181
|
try {
|
|
181
|
-
fd = openSync(temporary, "wx",
|
|
182
|
+
fd = openSync(temporary, "wx", stateFileMode());
|
|
182
183
|
writeFileSync(fd, `${JSON.stringify(store)}\n`, "utf8");
|
|
183
184
|
fsyncSync(fd);
|
|
184
185
|
closeSync(fd);
|
|
185
186
|
fd = undefined;
|
|
186
|
-
chmodSync(temporary,
|
|
187
|
+
chmodSync(temporary, stateFileMode());
|
|
187
188
|
if (!replacing && existsSync(path)) throw new Error("fingerprint key store already exists");
|
|
188
189
|
renameSync(temporary, path);
|
|
189
190
|
fsyncParentDirectory(path);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** Generated by scripts/generate-event-v3-contract.ts. Do not edit. */
|
|
2
2
|
export const EVENT_V3_SCHEMA_DIGEST =
|
|
3
|
-
"sha256:
|
|
3
|
+
"sha256:07137e2cdf5eaed58d55a34e4036c87aa1f375d45c88274d07ad1cc69a6fe6f7" as const;
|
|
4
4
|
export const EVENT_V3_GENERATED_CORE_TYPES = [
|
|
5
5
|
"ledger.genesis",
|
|
6
6
|
"ledger.activated",
|