harnery 0.40.0 → 0.41.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 +1 -0
- package/dist/commands/agents.d.ts.map +1 -1
- package/dist/commands/agents.js +25 -19
- package/dist/commands/browse-ai.d.ts.map +1 -1
- package/dist/commands/browse-ai.js +4 -0
- package/dist/commands/browse.d.ts.map +1 -1
- package/dist/commands/browse.js +141 -10
- package/dist/commands/checkpoint.js +8 -12
- 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/docs.d.ts.map +1 -1
- package/dist/commands/docs.js +2 -0
- package/dist/commands/doctor.js +10 -2
- package/dist/commands/fetch.d.ts.map +1 -1
- package/dist/commands/fetch.js +10 -0
- package/dist/commands/init.d.ts +19 -3
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +232 -104
- 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/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 +20 -3
- package/dist/core/adapters/profiles.d.ts.map +1 -1
- package/dist/core/adapters/profiles.js +32 -1
- package/dist/core/adapters/registry.d.ts.map +1 -1
- package/dist/core/adapters/registry.js +33 -0
- 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 +18 -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/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.map +1 -1
- package/dist/core/agents/state/live-coordination-view.js +1 -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 +2 -1
- package/dist/core/artifacts/index.d.ts.map +1 -1
- package/dist/core/artifacts/index.js +4 -3
- package/dist/core/config.d.ts +5 -0
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +14 -0
- 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 +3 -2
- 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 +109 -101
- 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 +29 -1
- package/dist/core/hooks/adapter/events.d.ts.map +1 -1
- package/dist/core/hooks/adapter/events.js +31 -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/wiring.d.ts +15 -1
- package/dist/core/hooks/adapter/wiring.d.ts.map +1 -1
- package/dist/core/hooks/adapter/wiring.js +74 -11
- package/dist/core/hooks/cli.js +635 -529
- 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/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/storage/atomic-json.d.ts.map +1 -1
- package/dist/core/storage/atomic-json.js +7 -3
- 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/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/spawn-opencode.d.ts +36 -0
- package/dist/core/workflow/spawn-opencode.d.ts.map +1 -0
- package/dist/core/workflow/spawn-opencode.js +132 -0
- package/dist/core/workflow/transcript.d.ts.map +1 -1
- package/dist/core/workflow/transcript.js +3 -2
- 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/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/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 +2 -1
- 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/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/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/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/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/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 +15 -10
- 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 +11 -4
- package/schemas/config.schema.json +13 -0
- package/schemas/event-v3.schema.json +164 -0
- package/src/commander.ts +7 -0
- package/src/commands/agents.ts +33 -18
- package/src/commands/browse-ai.ts +8 -0
- package/src/commands/browse.ts +189 -10
- package/src/commands/checkpoint.ts +7 -9
- package/src/commands/deinit.ts +9 -4
- package/src/commands/docs.ts +2 -0
- package/src/commands/doctor.ts +11 -2
- package/src/commands/fetch.ts +14 -0
- package/src/commands/init.ts +281 -119
- package/src/commands/instructions.ts +8 -4
- package/src/commands/ledger-v3.ts +2 -1
- 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 +42 -1
- package/src/core/adapters/registry.ts +37 -0
- package/src/core/agents/canonical-emit.ts +2 -5
- package/src/core/agents/cli.ts +18 -17
- package/src/core/agents/coord-client.ts +9 -3
- 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 +1 -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 +2 -1
- package/src/core/artifacts/index.ts +4 -3
- package/src/core/config.ts +23 -0
- package/src/core/context/index.ts +2 -1
- package/src/core/conversations/archive.ts +4 -3
- package/src/core/diagnostics/bundle.ts +3 -2
- 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 +123 -114
- 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 +53 -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/wiring.ts +85 -11
- package/src/core/hooks/cli.ts +733 -537
- 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/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/storage/atomic-json.ts +7 -3
- 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/live-session-v3.ts +2 -3
- package/src/core/workflow/run-state.ts +3 -2
- package/src/core/workflow/spawn-opencode.ts +150 -0
- package/src/core/workflow/transcript.ts +3 -2
- 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/client.ts +147 -9
- package/src/lib/browser/identity.ts +64 -0
- package/src/lib/browser/index.ts +15 -1
- package/src/lib/browser/launch-args.ts +53 -1
- package/src/lib/browser/user-agent.ts +130 -0
- package/src/lib/docs-metadata-managed.ts +21 -0
- package/src/lib/identities/assume.ts +7 -7
- package/src/lib/instructions/apply.ts +2 -0
- package/src/lib/pace/index.ts +14 -0
- package/src/lib/pace/pace.ts +370 -0
- package/src/lib/tunnel/forward-headers.ts +16 -0
- package/src/lib/tunnel/gate.ts +18 -10
- package/src/lib/webview/index.ts +13 -0
- package/src/lib/webview/webview.ts +457 -0
package/src/commands/browse.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
1
2
|
import { existsSync, mkdirSync, readFileSync, statSync, unlinkSync, writeFileSync } from "node:fs";
|
|
2
3
|
import { homedir } from "node:os";
|
|
3
4
|
import { dirname, isAbsolute, resolve } from "node:path";
|
|
4
5
|
import type { Command } from "commander";
|
|
6
|
+
import { chromium } from "playwright";
|
|
5
7
|
import { PNG } from "pngjs";
|
|
6
8
|
import type { EmitContext, HarneryProgramContext } from "../commander.ts";
|
|
7
9
|
import { resolveBinName } from "../core/config.ts";
|
|
@@ -24,15 +26,19 @@ import {
|
|
|
24
26
|
type CritiqueResult,
|
|
25
27
|
type CritiqueTile,
|
|
26
28
|
captureDevOverlay,
|
|
29
|
+
chromeMajorFromExecutable,
|
|
27
30
|
DEFAULT_CRITIQUE_RUBRIC,
|
|
28
31
|
type DevOverlayResult,
|
|
29
32
|
type Diagnostics,
|
|
30
33
|
extractObservedIp,
|
|
34
|
+
installedChromeChannel,
|
|
35
|
+
installedChromePath,
|
|
31
36
|
type LayoutAxis,
|
|
32
37
|
type LayoutLintResult,
|
|
33
38
|
type OverflowResult,
|
|
34
39
|
parseAssertSpec,
|
|
35
40
|
type RuntsResult,
|
|
41
|
+
resolveUserAgent,
|
|
36
42
|
runCritique,
|
|
37
43
|
type StandaloneHtmlResult,
|
|
38
44
|
type TargetSizeProfile,
|
|
@@ -108,6 +114,7 @@ import {
|
|
|
108
114
|
saveBaseline,
|
|
109
115
|
} from "../lib/browser/visual-diff.ts";
|
|
110
116
|
import { applyExtraCookies, CookieJar } from "../lib/cookies/index.ts";
|
|
117
|
+
import { commandPaceGate } from "../lib/pace/index.ts";
|
|
111
118
|
|
|
112
119
|
/**
|
|
113
120
|
* `harn browse <url>`: Playwright-backed page navigation with shared
|
|
@@ -162,13 +169,17 @@ interface BrowseOpts {
|
|
|
162
169
|
batch?: string;
|
|
163
170
|
networkHar?: string;
|
|
164
171
|
login?: boolean;
|
|
172
|
+
plain?: boolean;
|
|
165
173
|
loginCloseFile?: string;
|
|
166
174
|
controlFile?: string;
|
|
167
175
|
headed?: boolean;
|
|
168
176
|
browserArg?: string[];
|
|
177
|
+
browserChannel?: string;
|
|
178
|
+
userAgent?: string;
|
|
169
179
|
proxyFromEnv?: boolean;
|
|
170
180
|
exportCookies?: string;
|
|
171
181
|
cookies?: boolean;
|
|
182
|
+
pace?: boolean;
|
|
172
183
|
store?: string;
|
|
173
184
|
profile?: string;
|
|
174
185
|
viewport?: string;
|
|
@@ -339,8 +350,7 @@ export function registerBrowseCommand(
|
|
|
339
350
|
.option("--network-har <path>", "Record network traffic to a HAR file (finalized on close)")
|
|
340
351
|
.option(
|
|
341
352
|
"--viewport <preset|WxH>",
|
|
342
|
-
"Viewport: mobile (390x844), tablet (820x1180), desktop (1280x800), hd (1920x1080), or explicit '1920x1080'",
|
|
343
|
-
"desktop",
|
|
353
|
+
"Viewport: mobile (390x844), tablet (820x1180), desktop (1280x800), hd (1920x1080), or explicit '1920x1080'. Default: real window in headed mode, desktop in headless mode",
|
|
344
354
|
)
|
|
345
355
|
.option(
|
|
346
356
|
"--color-scheme <scheme>",
|
|
@@ -349,6 +359,14 @@ export function registerBrowseCommand(
|
|
|
349
359
|
"Absent = browser default (unchanged behavior).",
|
|
350
360
|
)
|
|
351
361
|
.option("--login", "Headed mode for one-time auth flow (cookies persist in profile)")
|
|
362
|
+
.option(
|
|
363
|
+
"--plain",
|
|
364
|
+
"With --login: open the URL in the installed Google Chrome with nothing attached (no DevTools " +
|
|
365
|
+
"protocol, no Playwright) on the same persistent profile. Use it for sign-in flows whose " +
|
|
366
|
+
"verification step detects automation itself (X does). Sign in, then close the window or " +
|
|
367
|
+
"create the --login-close-file; later browse and browse-session runs reuse the profile's cookies. " +
|
|
368
|
+
"Not compatible with --control-file, because nothing is attached to drive.",
|
|
369
|
+
)
|
|
352
370
|
.option(
|
|
353
371
|
"--login-close-file <path>",
|
|
354
372
|
"With --login, wait for this file instead of terminal Enter, then remove it and close cleanly",
|
|
@@ -358,13 +376,27 @@ export function registerBrowseCommand(
|
|
|
358
376
|
"With --login, publish an owner-only descriptor for repeated browse-session control",
|
|
359
377
|
)
|
|
360
378
|
.option("--headed", "Headed mode for one-off (no auth-flow framing)")
|
|
379
|
+
.option(
|
|
380
|
+
"--browser-channel <name>",
|
|
381
|
+
"Browser to launch: chrome | chrome-beta | msedge | chromium. Headed launches (--login, --headed) " +
|
|
382
|
+
"default to the installed Google Chrome with the automation signals removed, because the bundled " +
|
|
383
|
+
'"Chrome for Testing" build advertises itself and sign-in flows refuse clicks; chromium forces the ' +
|
|
384
|
+
"bundled build. HARNERY_BROWSER_CHANNEL sets the default machine-wide.",
|
|
385
|
+
)
|
|
386
|
+
.option(
|
|
387
|
+
"--user-agent <ua|auto|native>",
|
|
388
|
+
"User agent to present. Default: a normal Windows (or macOS on a Mac) Chrome user agent at the launched " +
|
|
389
|
+
"Chrome's major version, stored at ~/.cache/harnery/user-agent.json and reused by every surface; never " +
|
|
390
|
+
"Linux, never HeadlessChrome. A string rewrites the store, auto refreshes it, native uses the browser's own. " +
|
|
391
|
+
"HARNERY_BROWSER_UA overrides for one environment.",
|
|
392
|
+
)
|
|
361
393
|
.option(
|
|
362
394
|
"--browser-arg <flag>",
|
|
363
395
|
"Extra Chromium launch flag, passed straight to the browser (repeatable). " +
|
|
364
396
|
"e.g. --browser-arg --disable-gpu. Also settable machine-wide via the " +
|
|
365
|
-
"HARNERY_BROWSER_ARGS env var (whitespace-separated). Under WSL,
|
|
366
|
-
"
|
|
367
|
-
"
|
|
397
|
+
"HARNERY_BROWSER_ARGS env var (whitespace-separated). Under WSL, set " +
|
|
398
|
+
"HARNERY_BROWSER_WSL_DISABLE_GPU=1 to add --disable-gpu when a headed window paints blank; " +
|
|
399
|
+
"it is off by default because software WebGL is a bot tell.",
|
|
368
400
|
(value: string, prev: string[] = []) => [...prev, value],
|
|
369
401
|
[] as string[],
|
|
370
402
|
)
|
|
@@ -376,6 +408,11 @@ export function registerBrowseCommand(
|
|
|
376
408
|
"the expected IP is verified before the requested URL opens.",
|
|
377
409
|
)
|
|
378
410
|
.option("--no-cookies", "Skip cookie-jar attach and persist")
|
|
411
|
+
.option(
|
|
412
|
+
"--no-pace",
|
|
413
|
+
"Skip the human-pace gap (3 to 9 s) between page loads of the same site for this run. " +
|
|
414
|
+
"HARNERY_PACE=off disables it machine-wide; local and private hosts never wait.",
|
|
415
|
+
)
|
|
379
416
|
.option("--store <path>", `Cookie store path (default ${DEFAULT_STORE})`)
|
|
380
417
|
.option("--profile <dir>", `Persistent Chromium profile dir (default ${DEFAULT_PROFILE})`)
|
|
381
418
|
.option(
|
|
@@ -901,20 +938,58 @@ async function runBrowse(
|
|
|
901
938
|
);
|
|
902
939
|
}
|
|
903
940
|
|
|
941
|
+
const pace = commandPaceGate(opts.pace !== false, (message) => emit.log(message, "info"));
|
|
942
|
+
if (opts.plain) {
|
|
943
|
+
if (!opts.login) throw new Error("--plain requires --login.");
|
|
944
|
+
if (opts.controlFile) {
|
|
945
|
+
throw new Error(
|
|
946
|
+
"--plain cannot take --control-file: nothing is attached to drive the window.",
|
|
947
|
+
);
|
|
948
|
+
}
|
|
949
|
+
const plainExecutable = installedChromePath();
|
|
950
|
+
const plainUa = resolveUserAgent({
|
|
951
|
+
requested: opts.userAgent,
|
|
952
|
+
env: process.env.HARNERY_BROWSER_UA,
|
|
953
|
+
chromeMajor: plainExecutable ? chromeMajorFromExecutable(plainExecutable) : undefined,
|
|
954
|
+
});
|
|
955
|
+
await pace?.before(url);
|
|
956
|
+
await runPlainLogin(url, opts.profile ?? DEFAULT_PROFILE, loginCloseFile, plainUa, emit);
|
|
957
|
+
return;
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
const channel = resolveBrowserChannel(opts, Boolean(headed));
|
|
961
|
+
const userAgent = resolveUserAgent({
|
|
962
|
+
requested: opts.userAgent,
|
|
963
|
+
env: process.env.HARNERY_BROWSER_UA,
|
|
964
|
+
chromeMajor: launchedChromeMajor(channel),
|
|
965
|
+
});
|
|
904
966
|
const browser = new Browser({
|
|
905
967
|
profileDir: opts.profile ?? DEFAULT_PROFILE,
|
|
906
968
|
headed,
|
|
907
969
|
jar,
|
|
908
|
-
viewport,
|
|
970
|
+
viewport: headed && !opts.viewport ? null : viewport,
|
|
909
971
|
...(deviceScaleFactor !== undefined ? { deviceScaleFactor } : {}),
|
|
910
972
|
...(colorScheme ? { colorScheme } : {}),
|
|
911
973
|
navigationTimeout: Number.parseInt(opts.timeout, 10),
|
|
912
974
|
waitUntil: opts.waitUntil as BrowseOpts["waitUntil"] as never,
|
|
913
975
|
recordHarPath: opts.networkHar ? resolve(opts.networkHar) : undefined,
|
|
914
976
|
extraHeaders: context?.extraHeaders,
|
|
977
|
+
pace,
|
|
915
978
|
launchArgs: resolveLaunchArgs(opts, Boolean(headed), Boolean(proxy)),
|
|
979
|
+
...(channel ? { channel } : {}),
|
|
980
|
+
hideAutomation: Boolean(headed),
|
|
981
|
+
...(userAgent ? { userAgent } : {}),
|
|
916
982
|
proxy,
|
|
917
983
|
});
|
|
984
|
+
if (userAgent) emit.log(`Presenting as: ${userAgent}`, "debug");
|
|
985
|
+
if (headed) {
|
|
986
|
+
emit.log(
|
|
987
|
+
channel && channel !== "chromium"
|
|
988
|
+
? `Headed session uses the installed ${channel} channel with automation signals hidden.`
|
|
989
|
+
: "Headed session uses Playwright's bundled Chromium (no Google Chrome found); automation signals hidden.",
|
|
990
|
+
"info",
|
|
991
|
+
);
|
|
992
|
+
}
|
|
918
993
|
|
|
919
994
|
// Print mode: --snapshot / --html / --json all suppress file writes.
|
|
920
995
|
const printMode = opts.snapshot || opts.html || opts.json;
|
|
@@ -2967,15 +3042,57 @@ function summarizeDiagnostics(diag: Diagnostics): Record<string, unknown> {
|
|
|
2967
3042
|
|
|
2968
3043
|
/**
|
|
2969
3044
|
* Merge Chromium launch flags from three sources, in order, de-duped:
|
|
2970
|
-
* 1. WSLg
|
|
2971
|
-
*
|
|
2972
|
-
*
|
|
3045
|
+
* 1. WSLg `--disable-gpu`, only when HARNERY_BROWSER_WSL_DISABLE_GPU=1. It
|
|
3046
|
+
* was the default for headed launches, but software WebGL (SwiftShader)
|
|
3047
|
+
* is a bot tell that sign-in flows screen for, and current WSLg exposes
|
|
3048
|
+
* the host GPU through D3D12, so the flag is now opt-in for machines
|
|
3049
|
+
* that still paint a blank headed window without it.
|
|
2973
3050
|
* 2. HARNERY_BROWSER_ARGS env (whitespace-separated) — a machine-wide default.
|
|
2974
3051
|
* 3. --browser-arg flags on this invocation (repeatable).
|
|
2975
3052
|
*/
|
|
3053
|
+
const BROWSER_CHANNELS = new Set(["chrome", "chrome-beta", "msedge", "chromium"]);
|
|
3054
|
+
|
|
3055
|
+
/**
|
|
3056
|
+
* Pick the browser channel: `--browser-channel`, then `HARNERY_BROWSER_CHANNEL`,
|
|
3057
|
+
* then (headed only) the installed Google Chrome when one exists. Headless runs
|
|
3058
|
+
* keep the bundled Chromium unless told otherwise, so QA renders stay stable.
|
|
3059
|
+
*/
|
|
3060
|
+
function resolveBrowserChannel(
|
|
3061
|
+
opts: BrowseOpts,
|
|
3062
|
+
headed: boolean,
|
|
3063
|
+
): "chrome" | "chrome-beta" | "msedge" | "chromium" | undefined {
|
|
3064
|
+
const requested = (opts.browserChannel ?? process.env.HARNERY_BROWSER_CHANNEL)?.trim();
|
|
3065
|
+
if (requested) {
|
|
3066
|
+
if (!BROWSER_CHANNELS.has(requested)) {
|
|
3067
|
+
throw new Error(
|
|
3068
|
+
`Unknown --browser-channel "${requested}". Use chrome, chrome-beta, msedge, or chromium.`,
|
|
3069
|
+
);
|
|
3070
|
+
}
|
|
3071
|
+
return requested as "chrome" | "chrome-beta" | "msedge" | "chromium";
|
|
3072
|
+
}
|
|
3073
|
+
return headed ? installedChromeChannel() : undefined;
|
|
3074
|
+
}
|
|
3075
|
+
|
|
3076
|
+
/**
|
|
3077
|
+
* Major version of the Chrome that will launch: the installed Chrome for the
|
|
3078
|
+
* `chrome` channel, else Playwright's bundled Chromium. Unknown when neither
|
|
3079
|
+
* answers `--version`; the user-agent store then keeps its last value.
|
|
3080
|
+
*/
|
|
3081
|
+
function launchedChromeMajor(channel: string | undefined): number | undefined {
|
|
3082
|
+
if (channel === "chrome") {
|
|
3083
|
+
const exe = installedChromePath();
|
|
3084
|
+
return exe ? chromeMajorFromExecutable(exe) : undefined;
|
|
3085
|
+
}
|
|
3086
|
+
try {
|
|
3087
|
+
return chromeMajorFromExecutable(chromium.executablePath());
|
|
3088
|
+
} catch {
|
|
3089
|
+
return undefined;
|
|
3090
|
+
}
|
|
3091
|
+
}
|
|
3092
|
+
|
|
2976
3093
|
function resolveLaunchArgs(opts: BrowseOpts, headed: boolean, proxyEnabled: boolean): string[] {
|
|
2977
3094
|
const args: string[] = [];
|
|
2978
|
-
if (headed &&
|
|
3095
|
+
if (headed && process.env.HARNERY_BROWSER_WSL_DISABLE_GPU === "1") {
|
|
2979
3096
|
args.push(...wslHeadedLaunchArgs());
|
|
2980
3097
|
}
|
|
2981
3098
|
const envArgs = process.env.HARNERY_BROWSER_ARGS?.trim();
|
|
@@ -3005,6 +3122,68 @@ async function verifyBrowserProxyGate(
|
|
|
3005
3122
|
emit.log(`browser proxy gate: ${observedIp} · expected IP confirmed`, "info");
|
|
3006
3123
|
}
|
|
3007
3124
|
|
|
3125
|
+
/**
|
|
3126
|
+
* `--login --plain`: spawn the installed Google Chrome directly on the shared
|
|
3127
|
+
* persistent profile, with no DevTools protocol attached. Playwright enables
|
|
3128
|
+
* its runtime hooks in every frame it drives, and sign-in verification vendors
|
|
3129
|
+
* (X's is the reported case) detect that and fail the flow with no explanation.
|
|
3130
|
+
* The person signs in here; cookies land in the same profile that later
|
|
3131
|
+
* `browse` and `browse-session` runs open, so read-only captures inherit the
|
|
3132
|
+
* session without ever repeating the sign-in under automation.
|
|
3133
|
+
*/
|
|
3134
|
+
async function runPlainLogin(
|
|
3135
|
+
url: string,
|
|
3136
|
+
profileDir: string,
|
|
3137
|
+
loginCloseFile: string | null,
|
|
3138
|
+
userAgent: string | undefined,
|
|
3139
|
+
emit: { log: (message: string, level: "info" | "warn" | "error" | "debug") => void },
|
|
3140
|
+
): Promise<void> {
|
|
3141
|
+
const executable = installedChromePath();
|
|
3142
|
+
if (!executable) {
|
|
3143
|
+
throw new Error(
|
|
3144
|
+
"--plain needs an installed Google Chrome at a standard path; none was found on this machine.",
|
|
3145
|
+
);
|
|
3146
|
+
}
|
|
3147
|
+
mkdirSync(profileDir, { recursive: true });
|
|
3148
|
+
const child = spawn(
|
|
3149
|
+
executable,
|
|
3150
|
+
[
|
|
3151
|
+
`--user-data-dir=${profileDir}`,
|
|
3152
|
+
"--no-first-run",
|
|
3153
|
+
"--no-default-browser-check",
|
|
3154
|
+
...(userAgent ? [`--user-agent=${userAgent}`] : []),
|
|
3155
|
+
url,
|
|
3156
|
+
],
|
|
3157
|
+
{ stdio: "ignore" },
|
|
3158
|
+
);
|
|
3159
|
+
const exited = new Promise<void>((resolveExit) => {
|
|
3160
|
+
child.once("exit", () => resolveExit());
|
|
3161
|
+
child.once("error", () => resolveExit());
|
|
3162
|
+
});
|
|
3163
|
+
const lifecycleAbort = new AbortController();
|
|
3164
|
+
const waits: Promise<void>[] = [exited];
|
|
3165
|
+
if (loginCloseFile) {
|
|
3166
|
+
emit.log(
|
|
3167
|
+
`[--login --plain] Plain Google Chrome is open with nothing attached. Sign in, then close the window or create ${loginCloseFile}.`,
|
|
3168
|
+
"info",
|
|
3169
|
+
);
|
|
3170
|
+
waits.push(waitForLoginCloseFile(loginCloseFile, lifecycleAbort.signal));
|
|
3171
|
+
} else {
|
|
3172
|
+
emit.log(
|
|
3173
|
+
"[--login --plain] Plain Google Chrome is open with nothing attached. Sign in, then close the window or press Enter here.",
|
|
3174
|
+
"info",
|
|
3175
|
+
);
|
|
3176
|
+
waits.push(waitForTerminalEnter(lifecycleAbort.signal));
|
|
3177
|
+
}
|
|
3178
|
+
await Promise.race(waits);
|
|
3179
|
+
lifecycleAbort.abort();
|
|
3180
|
+
if (child.exitCode === null && child.signalCode === null) {
|
|
3181
|
+
child.kill("SIGTERM");
|
|
3182
|
+
await Promise.race([exited, new Promise((r) => setTimeout(r, 5000))]);
|
|
3183
|
+
}
|
|
3184
|
+
emit.log(`[--login --plain] Chrome closed; cookies persisted in ${profileDir}.`, "info");
|
|
3185
|
+
}
|
|
3186
|
+
|
|
3008
3187
|
async function waitForLoginCloseFile(path: string, signal?: AbortSignal): Promise<void> {
|
|
3009
3188
|
while (!existsSync(path) && !signal?.aborted) {
|
|
3010
3189
|
await new Promise((resolve) => setTimeout(resolve, 250));
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Command } from "commander";
|
|
2
2
|
import type { EmitContext, HarneryProgramContext } from "../commander.ts";
|
|
3
|
-
import type
|
|
3
|
+
import { ADAPTERS, type Adapter, normalizeAdapter } from "../core/adapter.ts";
|
|
4
4
|
import { monorepoRoot, resolveOwner } from "../core/agents/index.ts";
|
|
5
5
|
import { readLiveCoordinationRow } from "../core/agents/state/live-coordination-view.ts";
|
|
6
6
|
import {
|
|
@@ -76,7 +76,7 @@ export function registerCheckpointCommand(
|
|
|
76
76
|
.description("Create a durable context-continuity capsule for the current work")
|
|
77
77
|
.option("--session <id>", "Session id (defaults to the current agent heartbeat)")
|
|
78
78
|
.option("--instance <id>", "Agent instance id (defaults to the current owner)")
|
|
79
|
-
.option("--adapter <id>", "
|
|
79
|
+
.option("--adapter <id>", `${ADAPTERS.join(", ")} (inferred from heartbeat)`)
|
|
80
80
|
.option("--reason <reason>", "manual, pressure, pre_compact, or session_end", "manual")
|
|
81
81
|
.option("--note <text>", "Short continuation note for the recovered agent")
|
|
82
82
|
.option("--json", "Structured JSON output")
|
|
@@ -94,7 +94,7 @@ export function registerCheckpointCommand(
|
|
|
94
94
|
const reason = parseCheckpointReason(opts.reason);
|
|
95
95
|
const identity = resolveContinuityIdentity(context, opts);
|
|
96
96
|
if (!identity.adapter) {
|
|
97
|
-
throw new Error(
|
|
97
|
+
throw new Error(`could not infer the adapter; pass --adapter ${ADAPTERS.join("|")}`);
|
|
98
98
|
}
|
|
99
99
|
const result = checkpointContext(identity.coordRoot, {
|
|
100
100
|
sessionId: identity.sessionId,
|
|
@@ -166,15 +166,13 @@ function resolveContinuityIdentity(
|
|
|
166
166
|
}
|
|
167
167
|
|
|
168
168
|
function adapterFromPlatform(platform: string | undefined): Adapter | null {
|
|
169
|
-
|
|
170
|
-
if (platform === "cursor") return "cursor";
|
|
171
|
-
if (platform === "codex") return "codex";
|
|
172
|
-
return null;
|
|
169
|
+
return normalizeAdapter(platform);
|
|
173
170
|
}
|
|
174
171
|
|
|
175
172
|
function parseAdapter(value: string): Adapter {
|
|
176
|
-
|
|
177
|
-
|
|
173
|
+
const adapter = normalizeAdapter(value);
|
|
174
|
+
if (adapter) return adapter;
|
|
175
|
+
throw new Error(`invalid adapter "${value}"; expected one of ${ADAPTERS.join(", ")}`);
|
|
178
176
|
}
|
|
179
177
|
|
|
180
178
|
function parseCheckpointReason(value: string): CheckpointReason {
|
package/src/commands/deinit.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* `init` makes two kinds of change outside the harnery package:
|
|
5
5
|
* 1. Merges `agent-hook` entries into the adapter settings file
|
|
6
6
|
* (Claude Code `.claude/settings.json`, Cursor `.cursor/hooks.json`, or
|
|
7
|
-
* Codex `.codex/hooks.json`).
|
|
7
|
+
* Codex `.codex/hooks.json`), or installs the OpenCode plugin directory.
|
|
8
8
|
* 2. Creates the `.harnery/` coord root (runtime state: events, councils,
|
|
9
9
|
* identities, journal) and stamps the host bin name into
|
|
10
10
|
* `.harnery/config.jsonc`.
|
|
@@ -34,6 +34,7 @@ import type { Command } from "commander";
|
|
|
34
34
|
import type { EmitContext } from "../commander.ts";
|
|
35
35
|
import { DEFAULT_BIN_NAME } from "../core/config.ts";
|
|
36
36
|
import { ADAPTER_SPECS, type AdapterId } from "../core/hooks/adapter/events.ts";
|
|
37
|
+
import { removeOpenCodePlugin } from "../core/hooks/adapter/opencode-plugin.ts";
|
|
37
38
|
import type { SettingsFile } from "../core/hooks/adapter/wiring.ts";
|
|
38
39
|
import { removeIndexerExclusions } from "../lib/indexer-exclusions.ts";
|
|
39
40
|
import { removeInstructions } from "../lib/instructions/apply.ts";
|
|
@@ -62,7 +63,7 @@ export function registerDeinitCommand(program: Command, emit: EmitContext, binNa
|
|
|
62
63
|
".harnery/ coord root (on a terminal it asks first). Idempotent; use " +
|
|
63
64
|
"--dry-run to preview.",
|
|
64
65
|
)
|
|
65
|
-
.option("--adapter <id>", "claude-code | cursor | codex", "claude-code")
|
|
66
|
+
.option("--adapter <id>", "claude-code | cursor | codex | opencode", "claude-code")
|
|
66
67
|
.option("--dry-run", "Show what would change without writing")
|
|
67
68
|
.option("--project-root <path>", "Project root (default: git toplevel, else cwd)")
|
|
68
69
|
.option("--purge-state", "Also delete the .harnery/ coord root (runtime state, destructive)")
|
|
@@ -70,7 +71,9 @@ export function registerDeinitCommand(program: Command, emit: EmitContext, binNa
|
|
|
70
71
|
const adapter = opts.adapter as AdapterId;
|
|
71
72
|
const spec = ADAPTER_SPECS[adapter];
|
|
72
73
|
if (!spec) {
|
|
73
|
-
emit.text(
|
|
74
|
+
emit.text(
|
|
75
|
+
`Unknown adapter '${opts.adapter}'. Expected: claude-code | cursor | codex | opencode.`,
|
|
76
|
+
);
|
|
74
77
|
emit.setExitCode(1);
|
|
75
78
|
return;
|
|
76
79
|
}
|
|
@@ -97,7 +100,9 @@ export function registerDeinitCommand(program: Command, emit: EmitContext, binNa
|
|
|
97
100
|
|
|
98
101
|
// ── 1. unwire adapter hooks ────────────────────────────────────────────
|
|
99
102
|
const settingsPath = resolve(projectRoot, spec.settingsFile);
|
|
100
|
-
if (
|
|
103
|
+
if (spec.installMode === "opencode-plugin") {
|
|
104
|
+
actions.push(...removeOpenCodePlugin(projectRoot, dryRun));
|
|
105
|
+
} else if (!existsSync(settingsPath)) {
|
|
101
106
|
actions.push(`· ${rel(projectRoot, settingsPath)} doesn't exist; no hooks to remove`);
|
|
102
107
|
} else {
|
|
103
108
|
let settings: SettingsFile;
|
package/src/commands/docs.ts
CHANGED
|
@@ -6,6 +6,7 @@ import { initDocsContext as initDocsLinks, runLinks } from "../lib/docs-links.ts
|
|
|
6
6
|
import { initDocsContext as initDocsLint, runLint } from "../lib/docs-lint.ts";
|
|
7
7
|
import { readDocsMetadata, readDocsMetadataKey } from "../lib/docs-meta.ts";
|
|
8
8
|
import { initDocsMetadataAuditContext, runDocsMetadataAudit } from "../lib/docs-metadata-audit.ts";
|
|
9
|
+
import { initDocsMetadataExclusions } from "../lib/docs-metadata-managed.ts";
|
|
9
10
|
import { initDocsMetadataSyncContext, runDocsMetadataSync } from "../lib/docs-metadata-sync.ts";
|
|
10
11
|
import { createDocsFile } from "../lib/docs-new.ts";
|
|
11
12
|
import {
|
|
@@ -27,6 +28,7 @@ function ensureContext(context: HarneryProgramContext | undefined): void {
|
|
|
27
28
|
docsRootAllowlist: context.docsRootAllowlist,
|
|
28
29
|
});
|
|
29
30
|
initDocsLinks({ ...opts, extraExcludedPrefixes: context.extraDocsExcludedPrefixes });
|
|
31
|
+
initDocsMetadataExclusions(context.extraDocsExcludedPrefixes);
|
|
30
32
|
initDocsMetadataAuditContext(opts);
|
|
31
33
|
initDocsMetadataSyncContext(opts);
|
|
32
34
|
initDocsSweep(opts);
|
package/src/commands/doctor.ts
CHANGED
|
@@ -557,13 +557,22 @@ function checkAdapterHooks(installedAdapters: AdapterId[] = []): Check {
|
|
|
557
557
|
if (d.invalidEventKeys.length > 0) {
|
|
558
558
|
bits.push(`unsupported events (${d.invalidEventKeys.join(", ")})`);
|
|
559
559
|
}
|
|
560
|
+
if (d.pluginIssues && d.pluginIssues.length > 0) {
|
|
561
|
+
// Plugin issues already name their file; render them as-is.
|
|
562
|
+
return d.pluginIssues.join("; ");
|
|
563
|
+
}
|
|
560
564
|
return `${d.settingsFile}: ${bits.join("; ")}`;
|
|
561
565
|
});
|
|
562
566
|
for (const id of unwired) {
|
|
563
|
-
|
|
567
|
+
const what = ADAPTER_SPECS[id].installMode === "opencode-plugin" ? "plugin" : "hooks";
|
|
568
|
+
parts.push(`${ADAPTER_SPECS[id].settingsFile}: ${id} CLI installed, no harnery ${what} wired`);
|
|
564
569
|
}
|
|
565
570
|
const needsManualRepair = drift.some(
|
|
566
|
-
(d) =>
|
|
571
|
+
(d) =>
|
|
572
|
+
d.parseError ||
|
|
573
|
+
d.invalidTopLevelKeys.length > 0 ||
|
|
574
|
+
d.invalidEventKeys.length > 0 ||
|
|
575
|
+
d.pluginIssues?.some((issue) => issue.includes("without harnery's ownership header")),
|
|
567
576
|
);
|
|
568
577
|
const wireHints = unwired.map((id) => `\`${bin} init --adapter ${id}\``);
|
|
569
578
|
let hint: string;
|
package/src/commands/fetch.ts
CHANGED
|
@@ -3,8 +3,10 @@ import { homedir } from "node:os";
|
|
|
3
3
|
import { resolve } from "node:path";
|
|
4
4
|
import type { Command } from "commander";
|
|
5
5
|
import type { EmitContext, HarneryProgramContext } from "../commander.ts";
|
|
6
|
+
import { resolveUserAgent } from "../lib/browser/user-agent.js";
|
|
6
7
|
import { CookieJar } from "../lib/cookies/index.ts";
|
|
7
8
|
import { fetchWithJar } from "../lib/http/index.ts";
|
|
9
|
+
import { commandPaceGate } from "../lib/pace/index.ts";
|
|
8
10
|
|
|
9
11
|
/**
|
|
10
12
|
* `harn fetch`: HTTP request with cookie-jar attach + persist.
|
|
@@ -23,6 +25,7 @@ interface FetchOpts {
|
|
|
23
25
|
output?: string;
|
|
24
26
|
store?: string;
|
|
25
27
|
cookies?: boolean;
|
|
28
|
+
pace?: boolean;
|
|
26
29
|
redirect: string;
|
|
27
30
|
timeout: string;
|
|
28
31
|
status?: boolean;
|
|
@@ -47,6 +50,11 @@ export function registerFetchCommand(
|
|
|
47
50
|
.option("-o, --output <file>", "Write response body to file (default: stdout)")
|
|
48
51
|
.option("--store <path>", `Cookie store path (default ${DEFAULT_STORE})`)
|
|
49
52
|
.option("--no-cookies", "Skip cookie-jar attach + persist")
|
|
53
|
+
.option(
|
|
54
|
+
"--no-pace",
|
|
55
|
+
"Skip the human-pace gap (3 to 9 s) between requests to the same site for this run. " +
|
|
56
|
+
"HARNERY_PACE=off disables it machine-wide; local and private hosts never wait.",
|
|
57
|
+
)
|
|
50
58
|
.option("--redirect <mode>", "Redirect handling: follow | error | manual", "follow")
|
|
51
59
|
.option("--timeout <ms>", "Request timeout in milliseconds", "30000")
|
|
52
60
|
.option("--status", "Print status to stderr")
|
|
@@ -70,6 +78,10 @@ async function runFetch(
|
|
|
70
78
|
context: HarneryProgramContext | undefined,
|
|
71
79
|
): Promise<void> {
|
|
72
80
|
const headers: Record<string, string> = {};
|
|
81
|
+
{
|
|
82
|
+
const ua = resolveUserAgent({ env: process.env.HARNERY_BROWSER_UA });
|
|
83
|
+
if (ua) headers["User-Agent"] = ua;
|
|
84
|
+
}
|
|
73
85
|
for (const h of opts.header ?? []) {
|
|
74
86
|
const idx = h.indexOf(":");
|
|
75
87
|
if (idx < 0) {
|
|
@@ -83,6 +95,8 @@ async function runFetch(
|
|
|
83
95
|
? new CookieJar({ path: opts.store ?? DEFAULT_STORE, source: "harn-fetch" })
|
|
84
96
|
: null;
|
|
85
97
|
|
|
98
|
+
await commandPaceGate(opts.pace !== false, (message) => emit.log(message, "info"))?.before(url);
|
|
99
|
+
|
|
86
100
|
const timeoutMs = Number.parseInt(opts.timeout, 10);
|
|
87
101
|
const ac = new AbortController();
|
|
88
102
|
const timer = setTimeout(() => ac.abort(), timeoutMs);
|