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/README.md
CHANGED
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
- **Standalone web UI.** `harn web up` boots a local Next.js dashboard for the coord layer, councils, per-project state, and a local coding-agent status view (Claude Code / Codex / Cursor usage, backed by `harn devtools`). Ships with the git clone, not the npm package (see [Install](#install)).
|
|
29
29
|
- **Backup + sync.** `harn backup` snapshots `.harnery/` via [restic](https://restic.net/); `harn sync` keeps a curated subset live across machines via [rclone](https://rclone.org/) (Google Drive or any rclone remote).
|
|
30
30
|
|
|
31
|
-
The CLI also ships batteries: portable utility commands (`tokens`, `eml`, `env`, `grep` for parallel, ripgrep-accelerated monorepo search, plus `docs`, `browse`, `fetch`, `read`, `devtools`, and more) and the library toolkit they're built from. Useful, cross-platform, and dependency-light, but deliberately not the headline. Coordination is why harnery exists; the toolkit exists because the CLI needed it (see [Public surface tiers](#public-surface-tiers)).
|
|
31
|
+
The CLI also ships batteries: portable utility commands (`tokens`, `eml`, `env`, `grep` for parallel, ripgrep-accelerated monorepo search, plus `docs`, `browse`, `fetch`, `read`, `webview`, `devtools`, and more) and the library toolkit they're built from. Every page loader reads at human pace by default, waiting 3 to 9 seconds between loads of one site through a machine-wide ledger, with `--no-pace` and `HARNERY_PACE=off` to opt out. Useful, cross-platform, and dependency-light, but deliberately not the headline. Coordination is why harnery exists; the toolkit exists because the CLI needed it (see [Public surface tiers](#public-surface-tiers)).
|
|
32
32
|
|
|
33
33
|
## Install
|
|
34
34
|
|
package/dist/commander.js
CHANGED
|
@@ -113,6 +113,7 @@ function harneryCommandBundles({ emit, context, binName, }) {
|
|
|
113
113
|
lazy("admission", "Machine-wide admission control for heavy jobs: `admission run --resource <name> -- <command…>` waits for a FIFO slot then runs the command; `admission status` lists holders and waiters per resource.", async (program) => (await import("./commands/admission.js")).registerAdmissionCommand(program, emit)),
|
|
114
114
|
lazy("browse-session", "Control an opted-in headed browse session through an owner-only descriptor", async (program) => (await import("./commands/browse-session.js")).registerBrowseSessionCommand(program, emit)),
|
|
115
115
|
lazy("browse-ai <url>", `agent-browser (Vercel Labs) wrapper: accessibility-tree snapshots with element refs (@e1, @e2) for LLM consumption. Daemon-mode: successive calls reuse the same browser instance. Sister to ${binName} browse (Playwright).`, async (program) => (await import("./commands/browse-ai.js")).registerBrowseAiCommand(program, emit, context), { hasOptions: true }),
|
|
116
|
+
lazy("webview <url>", `Lightweight headless page probe through Bun.WebView (experimental, Bun 1.4+). Fresh ephemeral browser per call; use ${binName} browse for login, cookies, HAR, and QA.`, async (program) => (await import("./commands/webview.js")).registerWebviewCommand(program, emit, binName), { hasOptions: true }),
|
|
116
117
|
{
|
|
117
118
|
commands: [
|
|
118
119
|
{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../src/commands/agents.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAcH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAS1E,OAAO,EAGL,qBAAqB,EAMtB,MAAM,yBAAyB,CAAC;AAejC,OAAO,EAKL,KAAK,4BAA4B,EAClC,MAAM,wCAAwC,CAAC;AAMhD,OAAO,EAGL,KAAK,SAAS,EAEf,MAAM,0CAA0C,CAAC;
|
|
1
|
+
{"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../src/commands/agents.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/agents.js
CHANGED
|
@@ -29,9 +29,10 @@ import { agentDisplayName } from "../core/agents/state/activity-log.js";
|
|
|
29
29
|
import { buildLifecycleSuggestedName, buildSuggestedName, readHeartbeat as readHeartbeatCache, } from "../core/agents/state/heartbeat-writer.js";
|
|
30
30
|
import { readLiveCoordinationRow, readLiveCoordinationRows, } from "../core/agents/state/live-coordination-view.js";
|
|
31
31
|
import { foldSessionState, } from "../core/agents/state/session-state.js";
|
|
32
|
+
import { turnChangesStatusRow } from "../core/agents/turn-changes.js";
|
|
32
33
|
import { turnElapsedStatusRow } from "../core/agents/turn-elapsed.js";
|
|
33
34
|
import { coordFreshnessSeconds, resolveBinName, sessionFinalizationConfig, } from "../core/config.js";
|
|
34
|
-
import { EVENT_ADAPTER_IDS_V3 } from "../core/events/v3/adapter-id.js";
|
|
35
|
+
import { EVENT_ADAPTER_IDS_V3, normalizeEventAdapterIdV3, } from "../core/events/v3/adapter-id.js";
|
|
35
36
|
import { readEventV3ControlState } from "../core/events/v3/control.js";
|
|
36
37
|
import { projectCoordinationViewV3, readCoordinationViewV3, } from "../core/events/v3/coordination-view.js";
|
|
37
38
|
import { liveInstanceIdV3 } from "../core/events/v3/live-routing.js";
|
|
@@ -337,7 +338,7 @@ export function registerAgentsCommand(program, emitParam, programContext, binNam
|
|
|
337
338
|
.option("--kind <kind>", "pidmap | cache. Defaults to cache.")
|
|
338
339
|
.option("--session-id <id>", "(--kind cache) native session id used to join the authoritative V3 generation.")
|
|
339
340
|
.option("--adapter <id>", "(--kind cache) adapter used to validate the authoritative V3 generation: " +
|
|
340
|
-
"claude-code | cursor | codex.")
|
|
341
|
+
"claude-code | cursor | codex | opencode.")
|
|
341
342
|
.option("--pid <pid>", "(--kind pidmap) PID to register in pid-map. Default: walk " +
|
|
342
343
|
"this shell's ppid chain for a claude process. Pass explicitly " +
|
|
343
344
|
"when calling from outside Claude Code's Bash tool tree (e.g. " +
|
|
@@ -813,7 +814,7 @@ function runWhoami(opts) {
|
|
|
813
814
|
if (!hb) {
|
|
814
815
|
emit.error({
|
|
815
816
|
code: "no_live_generation",
|
|
816
|
-
message: noLiveGenerationMessage(myOwner),
|
|
817
|
+
message: noLiveGenerationMessage(root, myOwner),
|
|
817
818
|
});
|
|
818
819
|
process.exit(1);
|
|
819
820
|
}
|
|
@@ -994,9 +995,18 @@ function normalizeKind(kind) {
|
|
|
994
995
|
* This id is actionable: the reader may pass it to cache repair or explicit
|
|
995
996
|
* finalization. Abbreviate ids for display elsewhere, never in a diagnostic
|
|
996
997
|
* whose purpose is to hand the caller a canonical identity.
|
|
998
|
+
*
|
|
999
|
+
* The message also names the recovery. A session whose generation ended while
|
|
1000
|
+
* it sat idle (a stale sweep, or a `done` it has since outlived) still has a
|
|
1001
|
+
* live process, and `agents lifecycle active` is the one command that opens a
|
|
1002
|
+
* fresh generation for it (ADR 0088). Without the pointer every coordination
|
|
1003
|
+
* command refuses in turn and the caller has no way to guess the path back.
|
|
997
1004
|
*/
|
|
998
|
-
function noLiveGenerationMessage(owner) {
|
|
999
|
-
return `resolved owner=${owner} but no authority-safe live V3 generation exists for it`;
|
|
1005
|
+
function noLiveGenerationMessage(root, owner) {
|
|
1006
|
+
return `resolved owner=${owner} but no authority-safe live V3 generation exists for it; ${lifecycleReopenHint(root)}`;
|
|
1007
|
+
}
|
|
1008
|
+
function lifecycleReopenHint(root) {
|
|
1009
|
+
return `run \`${resolveBinName(root)} agents lifecycle active\` to open a fresh generation for this continuing session`;
|
|
1000
1010
|
}
|
|
1001
1011
|
/**
|
|
1002
1012
|
* The instance_id of a live V3 generation that `prefix` strictly prefixes, or null.
|
|
@@ -1470,7 +1480,7 @@ function runLifecycle(rawState, opts) {
|
|
|
1470
1480
|
if (state !== "active") {
|
|
1471
1481
|
emit.error({
|
|
1472
1482
|
code: "no_live_generation",
|
|
1473
|
-
message:
|
|
1483
|
+
message: noLiveGenerationMessage(root, myOwner),
|
|
1474
1484
|
});
|
|
1475
1485
|
process.exitCode = 1;
|
|
1476
1486
|
return;
|
|
@@ -1693,7 +1703,7 @@ function runStatus(opts) {
|
|
|
1693
1703
|
if (!hb) {
|
|
1694
1704
|
emit.error({
|
|
1695
1705
|
code: "no_live_generation",
|
|
1696
|
-
message: noLiveGenerationMessage(myOwner),
|
|
1706
|
+
message: noLiveGenerationMessage(root, myOwner),
|
|
1697
1707
|
});
|
|
1698
1708
|
process.exit(1);
|
|
1699
1709
|
}
|
|
@@ -1822,6 +1832,7 @@ function runStatus(opts) {
|
|
|
1822
1832
|
// one inside the same session. Best-effort by contract — no turn evidence,
|
|
1823
1833
|
// no row.
|
|
1824
1834
|
const turnElapsed = turnElapsedStatusRow({ coordRoot: root, instanceId: hb.instance_id });
|
|
1835
|
+
const turnChanges = turnChangesStatusRow({ coordRoot: root, instanceId: hb.instance_id });
|
|
1825
1836
|
const resources = readResourceStatus(root);
|
|
1826
1837
|
const data = {
|
|
1827
1838
|
name: displayName,
|
|
@@ -1830,6 +1841,7 @@ function runStatus(opts) {
|
|
|
1830
1841
|
session_age_secs: ageSecs,
|
|
1831
1842
|
turn_elapsed_secs: turnElapsed ? turnElapsed.elapsed.secs : null,
|
|
1832
1843
|
turn_complete: turnElapsed ? turnElapsed.elapsed.complete : null,
|
|
1844
|
+
turn_changes: turnChanges.changes,
|
|
1833
1845
|
activity: activityOf(hb),
|
|
1834
1846
|
activity_updated_at: hb.activity_updated_at ?? null,
|
|
1835
1847
|
activity_source: hb.activity_source ?? null,
|
|
@@ -1875,6 +1887,7 @@ function runStatus(opts) {
|
|
|
1875
1887
|
const rows = [
|
|
1876
1888
|
["session", formatAge(ageSecs)],
|
|
1877
1889
|
...(turnElapsed ? [["turn", turnElapsed.value]] : []),
|
|
1890
|
+
["changes", turnChanges.value],
|
|
1878
1891
|
["activity", activityOf(hb)],
|
|
1879
1892
|
["lifecycle", lifecycleLabel(hb)],
|
|
1880
1893
|
["context", ctxStr],
|
|
@@ -2112,15 +2125,7 @@ export function readAgentDiagnosticEventsInWindow(root, cutoffMs) {
|
|
|
2112
2125
|
}
|
|
2113
2126
|
/** Normalize adapter event data into the heartbeat platform value. */
|
|
2114
2127
|
function adapterToPlatform(adapter) {
|
|
2115
|
-
|
|
2116
|
-
return "claude-code";
|
|
2117
|
-
if (adapter === "cursor")
|
|
2118
|
-
return "cursor";
|
|
2119
|
-
if (adapter === "codex")
|
|
2120
|
-
return "codex";
|
|
2121
|
-
if (adapter === "openclaw")
|
|
2122
|
-
return "openclaw";
|
|
2123
|
-
return "unknown";
|
|
2128
|
+
return normalizeEventAdapterIdV3(adapter) ?? "unknown";
|
|
2124
2129
|
}
|
|
2125
2130
|
/** Project a canonical health.* event into the HealEvent shape the aggregators
|
|
2126
2131
|
* already consume. Returns null for non-heal events. instance_id → display name
|
|
@@ -4006,10 +4011,11 @@ function runHeal(opts) {
|
|
|
4006
4011
|
if (opts.adapter &&
|
|
4007
4012
|
opts.adapter !== "claude-code" &&
|
|
4008
4013
|
opts.adapter !== "cursor" &&
|
|
4009
|
-
opts.adapter !== "codex"
|
|
4014
|
+
opts.adapter !== "codex" &&
|
|
4015
|
+
opts.adapter !== "opencode") {
|
|
4010
4016
|
emit.error({
|
|
4011
4017
|
code: "bad_adapter",
|
|
4012
|
-
message: "--adapter must be one of: claude-code, cursor, codex",
|
|
4018
|
+
message: "--adapter must be one of: claude-code, cursor, codex, opencode",
|
|
4013
4019
|
});
|
|
4014
4020
|
process.exit(1);
|
|
4015
4021
|
}
|
|
@@ -4226,7 +4232,7 @@ function cacheHealAuthorityRefusal(root, owner, sessionId, adapter, currentRow)
|
|
|
4226
4232
|
if (producer?.terminal) {
|
|
4227
4233
|
return {
|
|
4228
4234
|
reason: "terminal_generation",
|
|
4229
|
-
message:
|
|
4235
|
+
message: `the matching generation is terminal and cannot be repaired or reopened by heal; ${lifecycleReopenHint(root)}`,
|
|
4230
4236
|
};
|
|
4231
4237
|
}
|
|
4232
4238
|
if (producer && producer.instance_id !== liveInstanceIdV3(owner)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browse-ai.d.ts","sourceRoot":"","sources":["../../src/commands/browse-ai.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"browse-ai.d.ts","sourceRoot":"","sources":["../../src/commands/browse-ai.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAmD1E,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,WAAW,EACtB,OAAO,CAAC,EAAE,qBAAqB,GAC9B,IAAI,CAgDN"}
|
|
@@ -2,6 +2,7 @@ import { homedir } from "node:os";
|
|
|
2
2
|
import { resolve } from "node:path";
|
|
3
3
|
import { AgentBrowser } from "../lib/agent-browser/index.js";
|
|
4
4
|
import { applyExtraCookies, CookieJar } from "../lib/cookies/index.js";
|
|
5
|
+
import { commandPaceGate } from "../lib/pace/index.js";
|
|
5
6
|
// Module-scoped emit assigned by registerBrowseAiCommand. Same pattern as
|
|
6
7
|
// cookies/read/browse: helper functions close over `emit` so action
|
|
7
8
|
// callbacks stay concise.
|
|
@@ -45,6 +46,8 @@ export function registerBrowseAiCommand(program, emitParam, context) {
|
|
|
45
46
|
'E.g., --batch "click @e5; wait 1000; snapshot"')
|
|
46
47
|
.option("--network-har <path>", "Record a HAR file from open() through end of run")
|
|
47
48
|
.option("--no-cookies", "Skip cookie-jar attach and persist")
|
|
49
|
+
.option("--no-pace", "Skip the human-pace gap (3 to 9 s) between page loads of the same site for this run. " +
|
|
50
|
+
"HARNERY_PACE=off disables it machine-wide; local and private hosts never wait.")
|
|
48
51
|
.option("--store <path>", `Cookie store path (default ${DEFAULT_STORE})`)
|
|
49
52
|
.option("--json", "Emit a JSON envelope (snapshot, screenshot path, step results)")
|
|
50
53
|
.option("--timeout <ms>", "Per-step timeout in ms", "60000")
|
|
@@ -68,6 +71,7 @@ function runBrowseAi(url, opts, context) {
|
|
|
68
71
|
const ab = new AgentBrowser({
|
|
69
72
|
jar,
|
|
70
73
|
timeoutMs: Number.parseInt(opts.timeout, 10),
|
|
74
|
+
pace: commandPaceGate(opts.pace !== false, (message) => emit.log(message, "info")),
|
|
71
75
|
});
|
|
72
76
|
const stepLog = [];
|
|
73
77
|
// 1. Open + optional HAR start.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browse.d.ts","sourceRoot":"","sources":["../../src/commands/browse.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"browse.d.ts","sourceRoot":"","sources":["../../src/commands/browse.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGzC,OAAO,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AA2S1E,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,WAAW,EACtB,OAAO,CAAC,EAAE,qBAAqB,EAC/B,OAAO,SAAmB,GACzB,IAAI,CAiiBN;AA61DD;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB,qCAAqC,CAAC"}
|
package/dist/commands/browse.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
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";
|
|
5
|
+
import { chromium } from "playwright";
|
|
4
6
|
import { PNG } from "pngjs";
|
|
5
7
|
import { resolveBinName } from "../core/config.js";
|
|
6
8
|
import { CAPTURE_FIDELITY_MISMATCH_THRESHOLD, compareBand, cropNativePng, decideFidelity, pngDimensions, } from "../lib/browser/capture-fidelity.js";
|
|
7
|
-
import { Browser, browserProxyFromEnv, browserProxyGateFromEnv, captureDevOverlay, DEFAULT_CRITIQUE_RUBRIC, extractObservedIp, parseAssertSpec, runCritique, tilesFromFullPage, WEBRTC_PROXY_ONLY_ARG, writeNetscapeCookieFile, wslHeadedLaunchArgs, } from "../lib/browser/index.js";
|
|
9
|
+
import { Browser, browserProxyFromEnv, browserProxyGateFromEnv, captureDevOverlay, chromeMajorFromExecutable, DEFAULT_CRITIQUE_RUBRIC, extractObservedIp, installedChromeChannel, installedChromePath, parseAssertSpec, resolveUserAgent, runCritique, tilesFromFullPage, WEBRTC_PROXY_ONLY_ARG, writeNetscapeCookieFile, wslHeadedLaunchArgs, } from "../lib/browser/index.js";
|
|
8
10
|
import { allocateTileBudget, validatePageReviewAllocation, } from "../lib/browser/page-review-budget.js";
|
|
9
11
|
import { PAGE_REVIEW_CAPTURE_PLAN_SCHEMA, } from "../lib/browser/page-review-contracts.js";
|
|
10
12
|
import { findPackTile, gateHitsFromEnvelope, readPackContext, tileId, writePackContext, writePackExpandedTile, } from "../lib/browser/page-review-pack.js";
|
|
@@ -18,6 +20,7 @@ import { captureThumbnailFingerprint, registerCaptureThumbnail, } from "../lib/b
|
|
|
18
20
|
import { reviewCandidateRects } from "../lib/browser/tiling.js";
|
|
19
21
|
import { diffAgainstBaseline, saveBaseline, } from "../lib/browser/visual-diff.js";
|
|
20
22
|
import { applyExtraCookies, CookieJar } from "../lib/cookies/index.js";
|
|
23
|
+
import { commandPaceGate } from "../lib/pace/index.js";
|
|
21
24
|
/**
|
|
22
25
|
* `harn browse <url>`: Playwright-backed page navigation with shared
|
|
23
26
|
* cookie jar + persistent profile + diagnostics capture for LLM
|
|
@@ -72,24 +75,39 @@ export function registerBrowseCommand(program, emitParam, context, binName = res
|
|
|
72
75
|
"`click <selector>`, `fill <selector=>value>`, `press <key>`, `wait <selector|ms>`, `eval <js>`, `reload`. " +
|
|
73
76
|
'Example: `--batch "click button; wait 1500; reload; wait 3000"`. `reload` preserves sessionStorage + cookies, which is how to repro sessionStorage-restored UI state.')
|
|
74
77
|
.option("--network-har <path>", "Record network traffic to a HAR file (finalized on close)")
|
|
75
|
-
.option("--viewport <preset|WxH>", "Viewport: mobile (390x844), tablet (820x1180), desktop (1280x800), hd (1920x1080), or explicit '1920x1080'
|
|
78
|
+
.option("--viewport <preset|WxH>", "Viewport: mobile (390x844), tablet (820x1180), desktop (1280x800), hd (1920x1080), or explicit '1920x1080'. Default: real window in headed mode, desktop in headless mode")
|
|
76
79
|
.option("--color-scheme <scheme>", "Emulate prefers-color-scheme for the whole session: light | dark. " +
|
|
77
80
|
"Renders theme-aware pages in that scheme without page-specific toggles. " +
|
|
78
81
|
"Absent = browser default (unchanged behavior).")
|
|
79
82
|
.option("--login", "Headed mode for one-time auth flow (cookies persist in profile)")
|
|
83
|
+
.option("--plain", "With --login: open the URL in the installed Google Chrome with nothing attached (no DevTools " +
|
|
84
|
+
"protocol, no Playwright) on the same persistent profile. Use it for sign-in flows whose " +
|
|
85
|
+
"verification step detects automation itself (X does). Sign in, then close the window or " +
|
|
86
|
+
"create the --login-close-file; later browse and browse-session runs reuse the profile's cookies. " +
|
|
87
|
+
"Not compatible with --control-file, because nothing is attached to drive.")
|
|
80
88
|
.option("--login-close-file <path>", "With --login, wait for this file instead of terminal Enter, then remove it and close cleanly")
|
|
81
89
|
.option("--control-file <path>", "With --login, publish an owner-only descriptor for repeated browse-session control")
|
|
82
90
|
.option("--headed", "Headed mode for one-off (no auth-flow framing)")
|
|
91
|
+
.option("--browser-channel <name>", "Browser to launch: chrome | chrome-beta | msedge | chromium. Headed launches (--login, --headed) " +
|
|
92
|
+
"default to the installed Google Chrome with the automation signals removed, because the bundled " +
|
|
93
|
+
'"Chrome for Testing" build advertises itself and sign-in flows refuse clicks; chromium forces the ' +
|
|
94
|
+
"bundled build. HARNERY_BROWSER_CHANNEL sets the default machine-wide.")
|
|
95
|
+
.option("--user-agent <ua|auto|native>", "User agent to present. Default: a normal Windows (or macOS on a Mac) Chrome user agent at the launched " +
|
|
96
|
+
"Chrome's major version, stored at ~/.cache/harnery/user-agent.json and reused by every surface; never " +
|
|
97
|
+
"Linux, never HeadlessChrome. A string rewrites the store, auto refreshes it, native uses the browser's own. " +
|
|
98
|
+
"HARNERY_BROWSER_UA overrides for one environment.")
|
|
83
99
|
.option("--browser-arg <flag>", "Extra Chromium launch flag, passed straight to the browser (repeatable). " +
|
|
84
100
|
"e.g. --browser-arg --disable-gpu. Also settable machine-wide via the " +
|
|
85
|
-
"HARNERY_BROWSER_ARGS env var (whitespace-separated). Under WSL,
|
|
86
|
-
"
|
|
87
|
-
"
|
|
101
|
+
"HARNERY_BROWSER_ARGS env var (whitespace-separated). Under WSL, set " +
|
|
102
|
+
"HARNERY_BROWSER_WSL_DISABLE_GPU=1 to add --disable-gpu when a headed window paints blank; " +
|
|
103
|
+
"it is off by default because software WebGL is a bot tell.", (value, prev = []) => [...prev, value], [])
|
|
88
104
|
.option("--proxy-from-env", "Pass HTTP(S)_PROXY to Playwright as an authenticated browser proxy. " +
|
|
89
105
|
"Credentials stay in the child environment, never command arguments. " +
|
|
90
106
|
"When the host also injects the HARNERY_BROWSER_PROXY_* gate variables, " +
|
|
91
107
|
"the expected IP is verified before the requested URL opens.")
|
|
92
108
|
.option("--no-cookies", "Skip cookie-jar attach and persist")
|
|
109
|
+
.option("--no-pace", "Skip the human-pace gap (3 to 9 s) between page loads of the same site for this run. " +
|
|
110
|
+
"HARNERY_PACE=off disables it machine-wide; local and private hosts never wait.")
|
|
93
111
|
.option("--store <path>", `Cookie store path (default ${DEFAULT_STORE})`)
|
|
94
112
|
.option("--profile <dir>", `Persistent Chromium profile dir (default ${DEFAULT_PROFILE})`)
|
|
95
113
|
.option("--export-cookies <path>", "Write live profile cookies as an owner-only Netscape cookies.txt file on close")
|
|
@@ -332,20 +350,54 @@ async function runBrowse(url, opts, context) {
|
|
|
332
350
|
if (loginCloseFile && existsSync(loginCloseFile)) {
|
|
333
351
|
throw new Error(`Login close signal already exists at ${loginCloseFile}. Remove the stale file before launching.`);
|
|
334
352
|
}
|
|
353
|
+
const pace = commandPaceGate(opts.pace !== false, (message) => emit.log(message, "info"));
|
|
354
|
+
if (opts.plain) {
|
|
355
|
+
if (!opts.login)
|
|
356
|
+
throw new Error("--plain requires --login.");
|
|
357
|
+
if (opts.controlFile) {
|
|
358
|
+
throw new Error("--plain cannot take --control-file: nothing is attached to drive the window.");
|
|
359
|
+
}
|
|
360
|
+
const plainExecutable = installedChromePath();
|
|
361
|
+
const plainUa = resolveUserAgent({
|
|
362
|
+
requested: opts.userAgent,
|
|
363
|
+
env: process.env.HARNERY_BROWSER_UA,
|
|
364
|
+
chromeMajor: plainExecutable ? chromeMajorFromExecutable(plainExecutable) : undefined,
|
|
365
|
+
});
|
|
366
|
+
await pace?.before(url);
|
|
367
|
+
await runPlainLogin(url, opts.profile ?? DEFAULT_PROFILE, loginCloseFile, plainUa, emit);
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
const channel = resolveBrowserChannel(opts, Boolean(headed));
|
|
371
|
+
const userAgent = resolveUserAgent({
|
|
372
|
+
requested: opts.userAgent,
|
|
373
|
+
env: process.env.HARNERY_BROWSER_UA,
|
|
374
|
+
chromeMajor: launchedChromeMajor(channel),
|
|
375
|
+
});
|
|
335
376
|
const browser = new Browser({
|
|
336
377
|
profileDir: opts.profile ?? DEFAULT_PROFILE,
|
|
337
378
|
headed,
|
|
338
379
|
jar,
|
|
339
|
-
viewport,
|
|
380
|
+
viewport: headed && !opts.viewport ? null : viewport,
|
|
340
381
|
...(deviceScaleFactor !== undefined ? { deviceScaleFactor } : {}),
|
|
341
382
|
...(colorScheme ? { colorScheme } : {}),
|
|
342
383
|
navigationTimeout: Number.parseInt(opts.timeout, 10),
|
|
343
384
|
waitUntil: opts.waitUntil,
|
|
344
385
|
recordHarPath: opts.networkHar ? resolve(opts.networkHar) : undefined,
|
|
345
386
|
extraHeaders: context?.extraHeaders,
|
|
387
|
+
pace,
|
|
346
388
|
launchArgs: resolveLaunchArgs(opts, Boolean(headed), Boolean(proxy)),
|
|
389
|
+
...(channel ? { channel } : {}),
|
|
390
|
+
hideAutomation: Boolean(headed),
|
|
391
|
+
...(userAgent ? { userAgent } : {}),
|
|
347
392
|
proxy,
|
|
348
393
|
});
|
|
394
|
+
if (userAgent)
|
|
395
|
+
emit.log(`Presenting as: ${userAgent}`, "debug");
|
|
396
|
+
if (headed) {
|
|
397
|
+
emit.log(channel && channel !== "chromium"
|
|
398
|
+
? `Headed session uses the installed ${channel} channel with automation signals hidden.`
|
|
399
|
+
: "Headed session uses Playwright's bundled Chromium (no Google Chrome found); automation signals hidden.", "info");
|
|
400
|
+
}
|
|
349
401
|
// Print mode: --snapshot / --html / --json all suppress file writes.
|
|
350
402
|
const printMode = opts.snapshot || opts.html || opts.json;
|
|
351
403
|
let controlServer = null;
|
|
@@ -2035,15 +2087,50 @@ function summarizeDiagnostics(diag) {
|
|
|
2035
2087
|
}
|
|
2036
2088
|
/**
|
|
2037
2089
|
* Merge Chromium launch flags from three sources, in order, de-duped:
|
|
2038
|
-
* 1. WSLg
|
|
2039
|
-
*
|
|
2040
|
-
*
|
|
2090
|
+
* 1. WSLg `--disable-gpu`, only when HARNERY_BROWSER_WSL_DISABLE_GPU=1. It
|
|
2091
|
+
* was the default for headed launches, but software WebGL (SwiftShader)
|
|
2092
|
+
* is a bot tell that sign-in flows screen for, and current WSLg exposes
|
|
2093
|
+
* the host GPU through D3D12, so the flag is now opt-in for machines
|
|
2094
|
+
* that still paint a blank headed window without it.
|
|
2041
2095
|
* 2. HARNERY_BROWSER_ARGS env (whitespace-separated) — a machine-wide default.
|
|
2042
2096
|
* 3. --browser-arg flags on this invocation (repeatable).
|
|
2043
2097
|
*/
|
|
2098
|
+
const BROWSER_CHANNELS = new Set(["chrome", "chrome-beta", "msedge", "chromium"]);
|
|
2099
|
+
/**
|
|
2100
|
+
* Pick the browser channel: `--browser-channel`, then `HARNERY_BROWSER_CHANNEL`,
|
|
2101
|
+
* then (headed only) the installed Google Chrome when one exists. Headless runs
|
|
2102
|
+
* keep the bundled Chromium unless told otherwise, so QA renders stay stable.
|
|
2103
|
+
*/
|
|
2104
|
+
function resolveBrowserChannel(opts, headed) {
|
|
2105
|
+
const requested = (opts.browserChannel ?? process.env.HARNERY_BROWSER_CHANNEL)?.trim();
|
|
2106
|
+
if (requested) {
|
|
2107
|
+
if (!BROWSER_CHANNELS.has(requested)) {
|
|
2108
|
+
throw new Error(`Unknown --browser-channel "${requested}". Use chrome, chrome-beta, msedge, or chromium.`);
|
|
2109
|
+
}
|
|
2110
|
+
return requested;
|
|
2111
|
+
}
|
|
2112
|
+
return headed ? installedChromeChannel() : undefined;
|
|
2113
|
+
}
|
|
2114
|
+
/**
|
|
2115
|
+
* Major version of the Chrome that will launch: the installed Chrome for the
|
|
2116
|
+
* `chrome` channel, else Playwright's bundled Chromium. Unknown when neither
|
|
2117
|
+
* answers `--version`; the user-agent store then keeps its last value.
|
|
2118
|
+
*/
|
|
2119
|
+
function launchedChromeMajor(channel) {
|
|
2120
|
+
if (channel === "chrome") {
|
|
2121
|
+
const exe = installedChromePath();
|
|
2122
|
+
return exe ? chromeMajorFromExecutable(exe) : undefined;
|
|
2123
|
+
}
|
|
2124
|
+
try {
|
|
2125
|
+
return chromeMajorFromExecutable(chromium.executablePath());
|
|
2126
|
+
}
|
|
2127
|
+
catch {
|
|
2128
|
+
return undefined;
|
|
2129
|
+
}
|
|
2130
|
+
}
|
|
2044
2131
|
function resolveLaunchArgs(opts, headed, proxyEnabled) {
|
|
2045
2132
|
const args = [];
|
|
2046
|
-
if (headed &&
|
|
2133
|
+
if (headed && process.env.HARNERY_BROWSER_WSL_DISABLE_GPU === "1") {
|
|
2047
2134
|
args.push(...wslHeadedLaunchArgs());
|
|
2048
2135
|
}
|
|
2049
2136
|
const envArgs = process.env.HARNERY_BROWSER_ARGS?.trim();
|
|
@@ -2067,6 +2154,50 @@ async function verifyBrowserProxyGate(browser, gate) {
|
|
|
2067
2154
|
}
|
|
2068
2155
|
emit.log(`browser proxy gate: ${observedIp} · expected IP confirmed`, "info");
|
|
2069
2156
|
}
|
|
2157
|
+
/**
|
|
2158
|
+
* `--login --plain`: spawn the installed Google Chrome directly on the shared
|
|
2159
|
+
* persistent profile, with no DevTools protocol attached. Playwright enables
|
|
2160
|
+
* its runtime hooks in every frame it drives, and sign-in verification vendors
|
|
2161
|
+
* (X's is the reported case) detect that and fail the flow with no explanation.
|
|
2162
|
+
* The person signs in here; cookies land in the same profile that later
|
|
2163
|
+
* `browse` and `browse-session` runs open, so read-only captures inherit the
|
|
2164
|
+
* session without ever repeating the sign-in under automation.
|
|
2165
|
+
*/
|
|
2166
|
+
async function runPlainLogin(url, profileDir, loginCloseFile, userAgent, emit) {
|
|
2167
|
+
const executable = installedChromePath();
|
|
2168
|
+
if (!executable) {
|
|
2169
|
+
throw new Error("--plain needs an installed Google Chrome at a standard path; none was found on this machine.");
|
|
2170
|
+
}
|
|
2171
|
+
mkdirSync(profileDir, { recursive: true });
|
|
2172
|
+
const child = spawn(executable, [
|
|
2173
|
+
`--user-data-dir=${profileDir}`,
|
|
2174
|
+
"--no-first-run",
|
|
2175
|
+
"--no-default-browser-check",
|
|
2176
|
+
...(userAgent ? [`--user-agent=${userAgent}`] : []),
|
|
2177
|
+
url,
|
|
2178
|
+
], { stdio: "ignore" });
|
|
2179
|
+
const exited = new Promise((resolveExit) => {
|
|
2180
|
+
child.once("exit", () => resolveExit());
|
|
2181
|
+
child.once("error", () => resolveExit());
|
|
2182
|
+
});
|
|
2183
|
+
const lifecycleAbort = new AbortController();
|
|
2184
|
+
const waits = [exited];
|
|
2185
|
+
if (loginCloseFile) {
|
|
2186
|
+
emit.log(`[--login --plain] Plain Google Chrome is open with nothing attached. Sign in, then close the window or create ${loginCloseFile}.`, "info");
|
|
2187
|
+
waits.push(waitForLoginCloseFile(loginCloseFile, lifecycleAbort.signal));
|
|
2188
|
+
}
|
|
2189
|
+
else {
|
|
2190
|
+
emit.log("[--login --plain] Plain Google Chrome is open with nothing attached. Sign in, then close the window or press Enter here.", "info");
|
|
2191
|
+
waits.push(waitForTerminalEnter(lifecycleAbort.signal));
|
|
2192
|
+
}
|
|
2193
|
+
await Promise.race(waits);
|
|
2194
|
+
lifecycleAbort.abort();
|
|
2195
|
+
if (child.exitCode === null && child.signalCode === null) {
|
|
2196
|
+
child.kill("SIGTERM");
|
|
2197
|
+
await Promise.race([exited, new Promise((r) => setTimeout(r, 5000))]);
|
|
2198
|
+
}
|
|
2199
|
+
emit.log(`[--login --plain] Chrome closed; cookies persisted in ${profileDir}.`, "info");
|
|
2200
|
+
}
|
|
2070
2201
|
async function waitForLoginCloseFile(path, signal) {
|
|
2071
2202
|
while (!existsSync(path) && !signal?.aborted) {
|
|
2072
2203
|
await new Promise((resolve) => setTimeout(resolve, 250));
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ADAPTERS, normalizeAdapter } from "../core/adapter.js";
|
|
1
2
|
import { monorepoRoot, resolveOwner } from "../core/agents/index.js";
|
|
2
3
|
import { readLiveCoordinationRow } from "../core/agents/state/live-coordination-view.js";
|
|
3
4
|
import { checkpointContext, readContextState, readLatestCapsule, } from "../core/context/index.js";
|
|
@@ -58,7 +59,7 @@ export function registerCheckpointCommand(program, emit, context) {
|
|
|
58
59
|
.description("Create a durable context-continuity capsule for the current work")
|
|
59
60
|
.option("--session <id>", "Session id (defaults to the current agent heartbeat)")
|
|
60
61
|
.option("--instance <id>", "Agent instance id (defaults to the current owner)")
|
|
61
|
-
.option("--adapter <id>", "
|
|
62
|
+
.option("--adapter <id>", `${ADAPTERS.join(", ")} (inferred from heartbeat)`)
|
|
62
63
|
.option("--reason <reason>", "manual, pressure, pre_compact, or session_end", "manual")
|
|
63
64
|
.option("--note <text>", "Short continuation note for the recovered agent")
|
|
64
65
|
.option("--json", "Structured JSON output")
|
|
@@ -68,7 +69,7 @@ export function registerCheckpointCommand(program, emit, context) {
|
|
|
68
69
|
const reason = parseCheckpointReason(opts.reason);
|
|
69
70
|
const identity = resolveContinuityIdentity(context, opts);
|
|
70
71
|
if (!identity.adapter) {
|
|
71
|
-
throw new Error(
|
|
72
|
+
throw new Error(`could not infer the adapter; pass --adapter ${ADAPTERS.join("|")}`);
|
|
72
73
|
}
|
|
73
74
|
const result = checkpointContext(identity.coordRoot, {
|
|
74
75
|
sessionId: identity.sessionId,
|
|
@@ -135,18 +136,13 @@ function resolveContinuityIdentity(context, opts) {
|
|
|
135
136
|
return { coordRoot, instanceId, sessionId, adapter };
|
|
136
137
|
}
|
|
137
138
|
function adapterFromPlatform(platform) {
|
|
138
|
-
|
|
139
|
-
return "claude-code";
|
|
140
|
-
if (platform === "cursor")
|
|
141
|
-
return "cursor";
|
|
142
|
-
if (platform === "codex")
|
|
143
|
-
return "codex";
|
|
144
|
-
return null;
|
|
139
|
+
return normalizeAdapter(platform);
|
|
145
140
|
}
|
|
146
141
|
function parseAdapter(value) {
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
142
|
+
const adapter = normalizeAdapter(value);
|
|
143
|
+
if (adapter)
|
|
144
|
+
return adapter;
|
|
145
|
+
throw new Error(`invalid adapter "${value}"; expected one of ${ADAPTERS.join(", ")}`);
|
|
150
146
|
}
|
|
151
147
|
function parseCheckpointReason(value) {
|
|
152
148
|
if (value === "manual" ||
|
|
@@ -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`.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deinit.d.ts","sourceRoot":"","sources":["../../src/commands/deinit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAMH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"deinit.d.ts","sourceRoot":"","sources":["../../src/commands/deinit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAMH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAiBnD,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CA4HjG;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,EAAE;IACtC,UAAU,EAAE,OAAO,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,OAAO,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;CACtB,GAAG,OAAO,CAEV;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAM1C"}
|
package/dist/commands/deinit.js
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`.
|
|
@@ -31,6 +31,7 @@ import { relative, resolve } from "node:path";
|
|
|
31
31
|
import { createInterface } from "node:readline";
|
|
32
32
|
import { DEFAULT_BIN_NAME } from "../core/config.js";
|
|
33
33
|
import { ADAPTER_SPECS } from "../core/hooks/adapter/events.js";
|
|
34
|
+
import { removeOpenCodePlugin } from "../core/hooks/adapter/opencode-plugin.js";
|
|
34
35
|
import { removeIndexerExclusions } from "../lib/indexer-exclusions.js";
|
|
35
36
|
import { removeInstructions } from "../lib/instructions/apply.js";
|
|
36
37
|
import { removeGitHooks } from "../lib/instructions/git-hooks.js";
|
|
@@ -47,7 +48,7 @@ export function registerDeinitCommand(program, emit, binName) {
|
|
|
47
48
|
"settings file (keeps any others). Pass --purge-state to also delete the " +
|
|
48
49
|
".harnery/ coord root (on a terminal it asks first). Idempotent; use " +
|
|
49
50
|
"--dry-run to preview.")
|
|
50
|
-
.option("--adapter <id>", "claude-code | cursor | codex", "claude-code")
|
|
51
|
+
.option("--adapter <id>", "claude-code | cursor | codex | opencode", "claude-code")
|
|
51
52
|
.option("--dry-run", "Show what would change without writing")
|
|
52
53
|
.option("--project-root <path>", "Project root (default: git toplevel, else cwd)")
|
|
53
54
|
.option("--purge-state", "Also delete the .harnery/ coord root (runtime state, destructive)")
|
|
@@ -55,7 +56,7 @@ export function registerDeinitCommand(program, emit, binName) {
|
|
|
55
56
|
const adapter = opts.adapter;
|
|
56
57
|
const spec = ADAPTER_SPECS[adapter];
|
|
57
58
|
if (!spec) {
|
|
58
|
-
emit.text(`Unknown adapter '${opts.adapter}'. Expected: claude-code | cursor | codex.`);
|
|
59
|
+
emit.text(`Unknown adapter '${opts.adapter}'. Expected: claude-code | cursor | codex | opencode.`);
|
|
59
60
|
emit.setExitCode(1);
|
|
60
61
|
return;
|
|
61
62
|
}
|
|
@@ -77,7 +78,10 @@ export function registerDeinitCommand(program, emit, binName) {
|
|
|
77
78
|
}
|
|
78
79
|
// ── 1. unwire adapter hooks ────────────────────────────────────────────
|
|
79
80
|
const settingsPath = resolve(projectRoot, spec.settingsFile);
|
|
80
|
-
if (
|
|
81
|
+
if (spec.installMode === "opencode-plugin") {
|
|
82
|
+
actions.push(...removeOpenCodePlugin(projectRoot, dryRun));
|
|
83
|
+
}
|
|
84
|
+
else if (!existsSync(settingsPath)) {
|
|
81
85
|
actions.push(`· ${rel(projectRoot, settingsPath)} doesn't exist; no hooks to remove`);
|
|
82
86
|
}
|
|
83
87
|
else {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"docs.d.ts","sourceRoot":"","sources":["../../src/commands/docs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"docs.d.ts","sourceRoot":"","sources":["../../src/commands/docs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAqC1E,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,WAAW,EACtB,OAAO,CAAC,EAAE,qBAAqB,GAC9B,IAAI,CA2ON"}
|
package/dist/commands/docs.js
CHANGED
|
@@ -4,6 +4,7 @@ import { initDocsContext as initDocsLinks, runLinks } from "../lib/docs-links.js
|
|
|
4
4
|
import { initDocsContext as initDocsLint, runLint } from "../lib/docs-lint.js";
|
|
5
5
|
import { readDocsMetadata, readDocsMetadataKey } from "../lib/docs-meta.js";
|
|
6
6
|
import { initDocsMetadataAuditContext, runDocsMetadataAudit } from "../lib/docs-metadata-audit.js";
|
|
7
|
+
import { initDocsMetadataExclusions } from "../lib/docs-metadata-managed.js";
|
|
7
8
|
import { initDocsMetadataSyncContext, runDocsMetadataSync } from "../lib/docs-metadata-sync.js";
|
|
8
9
|
import { createDocsFile } from "../lib/docs-new.js";
|
|
9
10
|
import { countColdHandoffs, initDocsContext as initDocsSweep, runSweep, } from "../lib/docs-sweep.js";
|
|
@@ -20,6 +21,7 @@ function ensureContext(context) {
|
|
|
20
21
|
docsRootAllowlist: context.docsRootAllowlist,
|
|
21
22
|
});
|
|
22
23
|
initDocsLinks({ ...opts, extraExcludedPrefixes: context.extraDocsExcludedPrefixes });
|
|
24
|
+
initDocsMetadataExclusions(context.extraDocsExcludedPrefixes);
|
|
23
25
|
initDocsMetadataAuditContext(opts);
|
|
24
26
|
initDocsMetadataSyncContext(opts);
|
|
25
27
|
initDocsSweep(opts);
|
package/dist/commands/doctor.js
CHANGED
|
@@ -476,12 +476,20 @@ function checkAdapterHooks(installedAdapters = []) {
|
|
|
476
476
|
if (d.invalidEventKeys.length > 0) {
|
|
477
477
|
bits.push(`unsupported events (${d.invalidEventKeys.join(", ")})`);
|
|
478
478
|
}
|
|
479
|
+
if (d.pluginIssues && d.pluginIssues.length > 0) {
|
|
480
|
+
// Plugin issues already name their file; render them as-is.
|
|
481
|
+
return d.pluginIssues.join("; ");
|
|
482
|
+
}
|
|
479
483
|
return `${d.settingsFile}: ${bits.join("; ")}`;
|
|
480
484
|
});
|
|
481
485
|
for (const id of unwired) {
|
|
482
|
-
|
|
486
|
+
const what = ADAPTER_SPECS[id].installMode === "opencode-plugin" ? "plugin" : "hooks";
|
|
487
|
+
parts.push(`${ADAPTER_SPECS[id].settingsFile}: ${id} CLI installed, no harnery ${what} wired`);
|
|
483
488
|
}
|
|
484
|
-
const needsManualRepair = drift.some((d) => d.parseError ||
|
|
489
|
+
const needsManualRepair = drift.some((d) => d.parseError ||
|
|
490
|
+
d.invalidTopLevelKeys.length > 0 ||
|
|
491
|
+
d.invalidEventKeys.length > 0 ||
|
|
492
|
+
d.pluginIssues?.some((issue) => issue.includes("without harnery's ownership header")));
|
|
485
493
|
const wireHints = unwired.map((id) => `\`${bin} init --adapter ${id}\``);
|
|
486
494
|
let hint;
|
|
487
495
|
if (needsManualRepair) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../src/commands/fetch.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../src/commands/fetch.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AA+B1E,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,WAAW,EACjB,OAAO,CAAC,EAAE,qBAAqB,GAC9B,IAAI,CAgCN"}
|