harnery 0.40.0 → 0.42.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/commander.js +4 -0
- package/dist/commands/agents.d.ts.map +1 -1
- package/dist/commands/agents.js +34 -20
- package/dist/commands/artifacts.d.ts.map +1 -1
- package/dist/commands/artifacts.js +113 -12
- package/dist/commands/browse-ai.d.ts.map +1 -1
- package/dist/commands/browse-ai.js +4 -0
- package/dist/commands/browse.d.ts +164 -0
- package/dist/commands/browse.d.ts.map +1 -1
- package/dist/commands/browse.js +388 -45
- package/dist/commands/checkpoint.js +8 -12
- package/dist/commands/claude-desktop.d.ts.map +1 -1
- package/dist/commands/claude-desktop.js +52 -0
- package/dist/commands/deinit.d.ts +1 -1
- package/dist/commands/deinit.d.ts.map +1 -1
- package/dist/commands/deinit.js +8 -4
- package/dist/commands/disk.d.ts +6 -0
- package/dist/commands/disk.d.ts.map +1 -0
- package/dist/commands/disk.js +80 -0
- package/dist/commands/docs.d.ts.map +1 -1
- package/dist/commands/docs.js +2 -0
- package/dist/commands/doctor.d.ts +8 -0
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +58 -3
- package/dist/commands/fetch.d.ts.map +1 -1
- package/dist/commands/fetch.js +10 -0
- package/dist/commands/files.d.ts +16 -0
- package/dist/commands/files.d.ts.map +1 -1
- package/dist/commands/files.js +54 -2
- package/dist/commands/init.d.ts +21 -5
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +271 -109
- package/dist/commands/instructions.js +5 -4
- package/dist/commands/ledger-v3.d.ts.map +1 -1
- package/dist/commands/ledger-v3.js +2 -1
- package/dist/commands/rm.d.ts +4 -0
- package/dist/commands/rm.d.ts.map +1 -0
- package/dist/commands/rm.js +87 -0
- package/dist/commands/servers.d.ts +7 -0
- package/dist/commands/servers.d.ts.map +1 -0
- package/dist/commands/servers.js +394 -0
- package/dist/commands/tunnel.d.ts.map +1 -1
- package/dist/commands/tunnel.js +82 -2
- package/dist/commands/webview.d.ts +4 -0
- package/dist/commands/webview.d.ts.map +1 -0
- package/dist/commands/webview.js +94 -0
- package/dist/core/adapter.d.ts +50 -1
- package/dist/core/adapter.d.ts.map +1 -1
- package/dist/core/adapter.js +59 -1
- package/dist/core/adapters/attestation.d.ts.map +1 -1
- package/dist/core/adapters/attestation.js +3 -2
- package/dist/core/adapters/profiles.d.ts +29 -3
- package/dist/core/adapters/profiles.d.ts.map +1 -1
- package/dist/core/adapters/profiles.js +53 -1
- package/dist/core/adapters/registry.d.ts.map +1 -1
- package/dist/core/adapters/registry.js +33 -0
- package/dist/core/adapters/types.d.ts +9 -0
- package/dist/core/adapters/types.d.ts.map +1 -1
- package/dist/core/agents/canonical-emit.d.ts +1 -1
- package/dist/core/agents/canonical-emit.d.ts.map +1 -1
- package/dist/core/agents/canonical-emit.js +2 -7
- package/dist/core/agents/cli.js +25 -16
- package/dist/core/agents/coord-client.d.ts.map +1 -1
- package/dist/core/agents/coord-client.js +7 -2
- package/dist/core/agents/render/session-context.d.ts.map +1 -1
- package/dist/core/agents/render/session-context.js +2 -0
- package/dist/core/agents/rules/claim-conflict.d.ts.map +1 -1
- package/dist/core/agents/rules/claim-conflict.js +3 -9
- package/dist/core/agents/rules/commit-conflict.d.ts.map +1 -1
- package/dist/core/agents/rules/commit-conflict.js +2 -8
- package/dist/core/agents/rules/stop-hook.d.ts +2 -0
- package/dist/core/agents/rules/stop-hook.d.ts.map +1 -1
- package/dist/core/agents/rules/stop-hook.js +1 -1
- package/dist/core/agents/session-events.d.ts +6 -2
- package/dist/core/agents/session-events.d.ts.map +1 -1
- package/dist/core/agents/session-events.js +105 -26
- package/dist/core/agents/session-finalization-state-v3.d.ts.map +1 -1
- package/dist/core/agents/session-finalization-state-v3.js +2 -1
- package/dist/core/agents/session-finalizer-v3.d.ts.map +1 -1
- package/dist/core/agents/session-finalizer-v3.js +5 -4
- package/dist/core/agents/session-name-display.d.ts +28 -0
- package/dist/core/agents/session-name-display.d.ts.map +1 -1
- package/dist/core/agents/session-name-display.js +43 -0
- package/dist/core/agents/state/heartbeat-reader.d.ts +7 -0
- package/dist/core/agents/state/heartbeat-reader.d.ts.map +1 -1
- package/dist/core/agents/state/heartbeat-writer.d.ts +10 -0
- package/dist/core/agents/state/heartbeat-writer.d.ts.map +1 -1
- package/dist/core/agents/state/heartbeat-writer.js +21 -2
- package/dist/core/agents/state/live-coordination-view.d.ts +20 -0
- package/dist/core/agents/state/live-coordination-view.d.ts.map +1 -1
- package/dist/core/agents/state/live-coordination-view.js +61 -0
- package/dist/core/agents/state/live-coordination-writer.js +3 -0
- package/dist/core/agents/state/stale-sweep.d.ts.map +1 -1
- package/dist/core/agents/state/stale-sweep.js +2 -10
- package/dist/core/agents/turn-changes.d.ts +17 -0
- package/dist/core/agents/turn-changes.d.ts.map +1 -0
- package/dist/core/agents/turn-changes.js +76 -0
- package/dist/core/artifacts/delivery-card.d.ts.map +1 -1
- package/dist/core/artifacts/delivery-card.js +11 -3
- package/dist/core/artifacts/index.d.ts +140 -4
- package/dist/core/artifacts/index.d.ts.map +1 -1
- package/dist/core/artifacts/index.js +526 -52
- package/dist/core/config.d.ts +73 -11
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +142 -3
- package/dist/core/context/index.d.ts.map +1 -1
- package/dist/core/context/index.js +2 -1
- package/dist/core/conversations/archive.d.ts.map +1 -1
- package/dist/core/conversations/archive.js +4 -3
- package/dist/core/diagnostics/bundle.d.ts.map +1 -1
- package/dist/core/diagnostics/bundle.js +5 -4
- package/dist/core/events/legacy-storage/canary.d.ts.map +1 -1
- package/dist/core/events/legacy-storage/canary.js +5 -4
- package/dist/core/events/legacy-storage/compression.d.ts.map +1 -1
- package/dist/core/events/legacy-storage/compression.js +2 -1
- package/dist/core/events/v3/adapter-id.d.ts +10 -2
- package/dist/core/events/v3/adapter-id.d.ts.map +1 -1
- package/dist/core/events/v3/adapter-id.js +16 -0
- package/dist/core/events/v3/authority-outbox.d.ts.map +1 -1
- package/dist/core/events/v3/authority-outbox.js +2 -1
- package/dist/core/events/v3/bootstrap.d.ts.map +1 -1
- package/dist/core/events/v3/bootstrap.js +5 -4
- package/dist/core/events/v3/capabilities.d.ts.map +1 -1
- package/dist/core/events/v3/capabilities.js +17 -0
- package/dist/core/events/v3/contract.d.ts +5 -0
- package/dist/core/events/v3/contract.d.ts.map +1 -1
- package/dist/core/events/v3/contract.js +7 -1
- package/dist/core/events/v3/control-witness.d.ts.map +1 -1
- package/dist/core/events/v3/control-witness.js +3 -2
- package/dist/core/events/v3/coordination-transaction-recovery.d.ts.map +1 -1
- package/dist/core/events/v3/coordination-transaction-recovery.js +4 -3
- package/dist/core/events/v3/fingerprint-keys.d.ts.map +1 -1
- package/dist/core/events/v3/fingerprint-keys.js +7 -6
- package/dist/core/events/v3/generated.d.ts +1 -1
- package/dist/core/events/v3/generated.js +1 -1
- package/dist/core/events/v3/live-feed.d.ts.map +1 -1
- package/dist/core/events/v3/live-feed.js +5 -4
- package/dist/core/events/v3/producers/command-recorder.d.ts.map +1 -1
- package/dist/core/events/v3/producers/command-recorder.js +8 -7
- package/dist/core/events/v3/producers/coordination-recorder.d.ts.map +1 -1
- package/dist/core/events/v3/producers/coordination-recorder.js +8 -7
- package/dist/core/events/v3/producers/diagnostic-summaries.d.ts.map +1 -1
- package/dist/core/events/v3/producers/diagnostic-summaries.js +5 -4
- package/dist/core/events/v3/producers/hook-base.d.ts +1 -0
- package/dist/core/events/v3/producers/hook-base.d.ts.map +1 -1
- package/dist/core/events/v3/producers/hook-base.js +10 -4
- package/dist/core/events/v3/producers/hook.d.ts +2 -0
- package/dist/core/events/v3/producers/hook.d.ts.map +1 -1
- package/dist/core/events/v3/producers/hook.js +16 -1
- package/dist/core/events/v3/producers/intake.d.ts.map +1 -1
- package/dist/core/events/v3/producers/intake.js +16 -6
- package/dist/core/events/v3/producers/recorder.d.ts +2 -4
- package/dist/core/events/v3/producers/recorder.d.ts.map +1 -1
- package/dist/core/events/v3/producers/recorder.js +125 -101
- package/dist/core/events/v3/projection.js +9 -1
- package/dist/core/events/v3/recovery.d.ts.map +1 -1
- package/dist/core/events/v3/recovery.js +4 -3
- package/dist/core/events/v3/support-storage/inventory.d.ts.map +1 -1
- package/dist/core/events/v3/support-storage/inventory.js +2 -1
- package/dist/core/events/v3/support-storage/maintenance.d.ts.map +1 -1
- package/dist/core/events/v3/support-storage/maintenance.js +4 -3
- package/dist/core/events/v3/support-storage/pack-reader.d.ts.map +1 -1
- package/dist/core/events/v3/support-storage/pack-reader.js +4 -3
- package/dist/core/events/v3/support-storage/pack-writer.d.ts.map +1 -1
- package/dist/core/events/v3/support-storage/pack-writer.js +6 -5
- package/dist/core/events/v3/tool-line-changes.d.ts +8 -0
- package/dist/core/events/v3/tool-line-changes.d.ts.map +1 -0
- package/dist/core/events/v3/tool-line-changes.js +135 -0
- package/dist/core/events/v3/writer.d.ts.map +1 -1
- package/dist/core/events/v3/writer.js +8 -7
- package/dist/core/governor/planning.d.ts.map +1 -1
- package/dist/core/governor/planning.js +6 -5
- package/dist/core/governor/service.d.ts.map +1 -1
- package/dist/core/governor/service.js +12 -11
- package/dist/core/governor/state.d.ts.map +1 -1
- package/dist/core/governor/state.js +7 -6
- package/dist/core/guard/evaluator.js +1 -0
- package/dist/core/guard/storage.d.ts.map +1 -1
- package/dist/core/guard/storage.js +3 -2
- package/dist/core/hooks/adapter/behaviors/claude-code.d.ts +4 -0
- package/dist/core/hooks/adapter/behaviors/claude-code.d.ts.map +1 -0
- package/dist/core/hooks/adapter/behaviors/claude-code.js +31 -0
- package/dist/core/hooks/adapter/behaviors/codex.d.ts +15 -0
- package/dist/core/hooks/adapter/behaviors/codex.d.ts.map +1 -0
- package/dist/core/hooks/adapter/behaviors/codex.js +82 -0
- package/dist/core/hooks/adapter/behaviors/cursor.d.ts +7 -0
- package/dist/core/hooks/adapter/behaviors/cursor.d.ts.map +1 -0
- package/dist/core/hooks/adapter/behaviors/cursor.js +35 -0
- package/dist/core/hooks/adapter/behaviors/index.d.ts +11 -0
- package/dist/core/hooks/adapter/behaviors/index.d.ts.map +1 -0
- package/dist/core/hooks/adapter/behaviors/index.js +20 -0
- package/dist/core/hooks/adapter/behaviors/openclaw.d.ts +7 -0
- package/dist/core/hooks/adapter/behaviors/openclaw.d.ts.map +1 -0
- package/dist/core/hooks/adapter/behaviors/openclaw.js +34 -0
- package/dist/core/hooks/adapter/behaviors/opencode.d.ts +7 -0
- package/dist/core/hooks/adapter/behaviors/opencode.d.ts.map +1 -0
- package/dist/core/hooks/adapter/behaviors/opencode.js +34 -0
- package/dist/core/hooks/adapter/behaviors/types.d.ts +89 -0
- package/dist/core/hooks/adapter/behaviors/types.d.ts.map +1 -0
- package/dist/core/hooks/adapter/behaviors/types.js +1 -0
- package/dist/core/hooks/adapter/detect.d.ts +1 -1
- package/dist/core/hooks/adapter/detect.d.ts.map +1 -1
- package/dist/core/hooks/adapter/detect.js +2 -3
- package/dist/core/hooks/adapter/events.d.ts +46 -1
- package/dist/core/hooks/adapter/events.d.ts.map +1 -1
- package/dist/core/hooks/adapter/events.js +36 -0
- package/dist/core/hooks/adapter/opencode-plugin.d.ts +60 -0
- package/dist/core/hooks/adapter/opencode-plugin.d.ts.map +1 -0
- package/dist/core/hooks/adapter/opencode-plugin.js +129 -0
- package/dist/core/hooks/adapter/output.d.ts +7 -0
- package/dist/core/hooks/adapter/output.d.ts.map +1 -1
- package/dist/core/hooks/adapter/output.js +8 -1
- package/dist/core/hooks/adapter/runtime-telemetry.js +3 -1
- package/dist/core/hooks/adapter/wiring.d.ts +52 -8
- package/dist/core/hooks/adapter/wiring.d.ts.map +1 -1
- package/dist/core/hooks/adapter/wiring.js +133 -12
- package/dist/core/hooks/cli.js +676 -531
- package/dist/core/hooks/effects/image-capture.d.ts.map +1 -1
- package/dist/core/hooks/effects/image-capture.js +2 -1
- package/dist/core/hooks/prompt-context/contract.d.ts.map +1 -1
- package/dist/core/hooks/prompt-context/contract.js +1 -0
- package/dist/core/hooks/resolve/transcript.d.ts +1 -1
- package/dist/core/hooks/resolve/transcript.d.ts.map +1 -1
- package/dist/core/hooks/resolve/transcript.js +35 -4
- package/dist/core/hooks/run-markers.d.ts +37 -0
- package/dist/core/hooks/run-markers.d.ts.map +1 -0
- package/dist/core/hooks/run-markers.js +109 -0
- package/dist/core/hooks/session-name-presence.d.ts +3 -1
- package/dist/core/hooks/session-name-presence.d.ts.map +1 -1
- package/dist/core/hooks/session-name-presence.js +7 -2
- package/dist/core/hooks/shell-waiter.d.ts +2 -0
- package/dist/core/hooks/shell-waiter.d.ts.map +1 -0
- package/dist/core/hooks/shell-waiter.js +173 -0
- package/dist/core/resources/service.d.ts.map +1 -1
- package/dist/core/resources/service.js +5 -4
- package/dist/core/semantic/review.d.ts.map +1 -1
- package/dist/core/semantic/review.js +5 -4
- package/dist/core/semantic/service.d.ts.map +1 -1
- package/dist/core/semantic/service.js +15 -14
- package/dist/core/semantic/storage.d.ts.map +1 -1
- package/dist/core/semantic/storage.js +5 -4
- package/dist/core/servers/index.d.ts +211 -0
- package/dist/core/servers/index.d.ts.map +1 -0
- package/dist/core/servers/index.js +560 -0
- package/dist/core/servers/net.d.ts +58 -0
- package/dist/core/servers/net.d.ts.map +1 -0
- package/dist/core/servers/net.js +270 -0
- package/dist/core/servers/tunnels.d.ts +14 -0
- package/dist/core/servers/tunnels.d.ts.map +1 -0
- package/dist/core/servers/tunnels.js +33 -0
- package/dist/core/storage/atomic-json.d.ts.map +1 -1
- package/dist/core/storage/atomic-json.js +7 -3
- package/dist/core/storage/builtins.js +1 -0
- package/dist/core/storage/durable-history.d.ts.map +1 -1
- package/dist/core/storage/durable-history.js +6 -5
- package/dist/core/storage/maintenance-providers.d.ts.map +1 -1
- package/dist/core/storage/maintenance-providers.js +2 -1
- package/dist/core/storage/maintenance.d.ts.map +1 -1
- package/dist/core/storage/maintenance.js +7 -6
- package/dist/core/storage/metrics.d.ts.map +1 -1
- package/dist/core/storage/metrics.js +5 -1
- package/dist/core/storage/modes.d.ts +17 -0
- package/dist/core/storage/modes.d.ts.map +1 -0
- package/dist/core/storage/modes.js +47 -0
- package/dist/core/storage/process-log.d.ts.map +1 -1
- package/dist/core/storage/process-log.js +3 -2
- package/dist/core/storage/receipts.d.ts.map +1 -1
- package/dist/core/storage/receipts.js +4 -3
- package/dist/core/storage/segments.d.ts.map +1 -1
- package/dist/core/storage/segments.js +7 -6
- package/dist/core/supervisor/hook-health.d.ts +2 -1
- package/dist/core/supervisor/hook-health.d.ts.map +1 -1
- package/dist/core/supervisor/hook-health.js +4 -3
- package/dist/core/supervisor/service.d.ts.map +1 -1
- package/dist/core/supervisor/service.js +7 -6
- package/dist/core/work/state.d.ts.map +1 -1
- package/dist/core/work/state.js +8 -7
- package/dist/core/workflow/adapters.d.ts +7 -0
- package/dist/core/workflow/adapters.d.ts.map +1 -1
- package/dist/core/workflow/adapters.js +9 -0
- package/dist/core/workflow/approvals.d.ts.map +1 -1
- package/dist/core/workflow/approvals.js +6 -5
- package/dist/core/workflow/billing.d.ts.map +1 -1
- package/dist/core/workflow/billing.js +33 -4
- package/dist/core/workflow/durable-record.d.ts.map +1 -1
- package/dist/core/workflow/durable-record.js +4 -3
- package/dist/core/workflow/engine.d.ts.map +1 -1
- package/dist/core/workflow/engine.js +30 -1
- package/dist/core/workflow/live-session-v3.d.ts.map +1 -1
- package/dist/core/workflow/live-session-v3.js +2 -3
- package/dist/core/workflow/run-state.d.ts.map +1 -1
- package/dist/core/workflow/run-state.js +3 -2
- package/dist/core/workflow/sandbox-projection.d.ts +13 -2
- package/dist/core/workflow/sandbox-projection.d.ts.map +1 -1
- package/dist/core/workflow/sandbox-projection.js +23 -0
- package/dist/core/workflow/spawn-claude.d.ts.map +1 -1
- package/dist/core/workflow/spawn-claude.js +6 -1
- package/dist/core/workflow/spawn-codex.d.ts +2 -0
- package/dist/core/workflow/spawn-codex.d.ts.map +1 -1
- package/dist/core/workflow/spawn-codex.js +20 -1
- package/dist/core/workflow/spawn-cursor.d.ts.map +1 -1
- package/dist/core/workflow/spawn-cursor.js +6 -1
- package/dist/core/workflow/spawn-opencode.d.ts +36 -0
- package/dist/core/workflow/spawn-opencode.d.ts.map +1 -0
- package/dist/core/workflow/spawn-opencode.js +135 -0
- package/dist/core/workflow/transcript.d.ts.map +1 -1
- package/dist/core/workflow/transcript.js +3 -2
- package/dist/core/workflow/types.d.ts +47 -2
- package/dist/core/workflow/types.d.ts.map +1 -1
- package/dist/core/workflow/worker-access.d.ts +92 -0
- package/dist/core/workflow/worker-access.d.ts.map +1 -0
- package/dist/core/workflow/worker-access.js +450 -0
- package/dist/core/workflow/workspaces/leases.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/leases.js +5 -4
- package/dist/core/workflow/workspaces/local-git.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/local-git.js +3 -2
- package/dist/core/workflow/workspaces/paths.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/paths.js +2 -1
- package/dist/core/workflow/workspaces/state.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/state.js +10 -9
- package/dist/lazy-commands.js +8 -1
- package/dist/lib/agent-browser/client.d.ts +9 -0
- package/dist/lib/agent-browser/client.d.ts.map +1 -1
- package/dist/lib/agent-browser/client.js +13 -0
- package/dist/lib/browser/batch-steps.d.ts +18 -0
- package/dist/lib/browser/batch-steps.d.ts.map +1 -0
- package/dist/lib/browser/batch-steps.js +82 -0
- package/dist/lib/browser/client.d.ts +35 -1
- package/dist/lib/browser/client.d.ts.map +1 -1
- package/dist/lib/browser/client.js +117 -8
- package/dist/lib/browser/collect/collector.d.ts +99 -0
- package/dist/lib/browser/collect/collector.d.ts.map +1 -0
- package/dist/lib/browser/collect/collector.js +202 -0
- package/dist/lib/browser/collect/fields.d.ts +31 -0
- package/dist/lib/browser/collect/fields.d.ts.map +1 -0
- package/dist/lib/browser/collect/fields.js +75 -0
- package/dist/lib/browser/collect/index.d.ts +6 -0
- package/dist/lib/browser/collect/index.d.ts.map +1 -0
- package/dist/lib/browser/collect/index.js +5 -0
- package/dist/lib/browser/collect/page-driver.d.ts +14 -0
- package/dist/lib/browser/collect/page-driver.d.ts.map +1 -0
- package/dist/lib/browser/collect/page-driver.js +306 -0
- package/dist/lib/browser/collect/presets.d.ts +52 -0
- package/dist/lib/browser/collect/presets.d.ts.map +1 -0
- package/dist/lib/browser/collect/presets.js +176 -0
- package/dist/lib/browser/collect/scroll-plan.d.ts +85 -0
- package/dist/lib/browser/collect/scroll-plan.d.ts.map +1 -0
- package/dist/lib/browser/collect/scroll-plan.js +118 -0
- package/dist/lib/browser/identity.d.ts +25 -0
- package/dist/lib/browser/identity.d.ts.map +1 -0
- package/dist/lib/browser/identity.js +66 -0
- package/dist/lib/browser/index.d.ts +3 -2
- package/dist/lib/browser/index.d.ts.map +1 -1
- package/dist/lib/browser/index.js +2 -1
- package/dist/lib/browser/launch-args.d.ts +26 -0
- package/dist/lib/browser/launch-args.d.ts.map +1 -1
- package/dist/lib/browser/launch-args.js +41 -1
- package/dist/lib/browser/page-review-judge.d.ts +2 -0
- package/dist/lib/browser/page-review-judge.d.ts.map +1 -1
- package/dist/lib/browser/page-review-judge.js +13 -0
- package/dist/lib/browser/qa-run-contracts.d.ts +10 -0
- package/dist/lib/browser/qa-run-contracts.d.ts.map +1 -1
- package/dist/lib/browser/qa-run.d.ts.map +1 -1
- package/dist/lib/browser/qa-run.js +1 -0
- package/dist/lib/browser/user-agent.d.ts +53 -0
- package/dist/lib/browser/user-agent.d.ts.map +1 -0
- package/dist/lib/browser/user-agent.js +79 -0
- package/dist/lib/browser/windows-chrome.d.ts +59 -0
- package/dist/lib/browser/windows-chrome.d.ts.map +1 -0
- package/dist/lib/browser/windows-chrome.js +179 -0
- package/dist/lib/claude-desktop-share.d.ts +136 -0
- package/dist/lib/claude-desktop-share.d.ts.map +1 -0
- package/dist/lib/claude-desktop-share.js +394 -0
- package/dist/lib/disk-usage.d.ts +50 -0
- package/dist/lib/disk-usage.d.ts.map +1 -0
- package/dist/lib/disk-usage.js +303 -0
- package/dist/lib/docs-lint.d.ts +6 -0
- package/dist/lib/docs-lint.d.ts.map +1 -1
- package/dist/lib/docs-lint.js +8 -3
- package/dist/lib/docs-metadata-managed.d.ts +1 -0
- package/dist/lib/docs-metadata-managed.d.ts.map +1 -1
- package/dist/lib/docs-metadata-managed.js +17 -1
- package/dist/lib/guarded-remove.d.ts +34 -0
- package/dist/lib/guarded-remove.d.ts.map +1 -0
- package/dist/lib/guarded-remove.js +310 -0
- package/dist/lib/identities/assume.d.ts.map +1 -1
- package/dist/lib/identities/assume.js +4 -9
- package/dist/lib/instructions/apply.d.ts.map +1 -1
- package/dist/lib/instructions/apply.js +2 -0
- package/dist/lib/instructions/templates.js +8 -8
- package/dist/lib/pace/index.d.ts +2 -0
- package/dist/lib/pace/index.d.ts.map +1 -0
- package/dist/lib/pace/index.js +1 -0
- package/dist/lib/pace/pace.d.ts +95 -0
- package/dist/lib/pace/pace.d.ts.map +1 -0
- package/dist/lib/pace/pace.js +313 -0
- package/dist/lib/tunnel/error-page.d.ts +1 -1
- package/dist/lib/tunnel/error-page.d.ts.map +1 -1
- package/dist/lib/tunnel/error-page.js +19 -8
- package/dist/lib/tunnel/forward-headers.d.ts +11 -0
- package/dist/lib/tunnel/forward-headers.d.ts.map +1 -0
- package/dist/lib/tunnel/forward-headers.js +17 -0
- package/dist/lib/tunnel/gate.js +34 -10
- package/dist/lib/tunnel/path-scope.d.ts +22 -0
- package/dist/lib/tunnel/path-scope.d.ts.map +1 -0
- package/dist/lib/tunnel/path-scope.js +62 -0
- package/dist/lib/tunnel/state.d.ts +5 -0
- package/dist/lib/tunnel/state.d.ts.map +1 -1
- package/dist/lib/tunnel/state.js +17 -3
- package/dist/lib/webview/index.d.ts +2 -0
- package/dist/lib/webview/index.d.ts.map +1 -0
- package/dist/lib/webview/index.js +1 -0
- package/dist/lib/webview/webview.d.ts +116 -0
- package/dist/lib/webview/webview.d.ts.map +1 -0
- package/dist/lib/webview/webview.js +289 -0
- package/opencode-plugin/package.json +19 -0
- package/opencode-plugin/src/index.ts +791 -0
- package/package.json +16 -4
- package/schemas/config.schema.json +104 -0
- package/schemas/event-v3.schema.json +164 -0
- package/src/commander.ts +26 -0
- package/src/commands/agents.ts +47 -18
- package/src/commands/artifacts.ts +171 -19
- package/src/commands/browse-ai.ts +8 -0
- package/src/commands/browse.ts +570 -48
- package/src/commands/checkpoint.ts +7 -9
- package/src/commands/claude-desktop.ts +61 -0
- package/src/commands/deinit.ts +9 -4
- package/src/commands/disk.ts +114 -0
- package/src/commands/docs.ts +2 -0
- package/src/commands/doctor.ts +63 -3
- package/src/commands/fetch.ts +14 -0
- package/src/commands/files.ts +93 -2
- package/src/commands/init.ts +334 -122
- package/src/commands/instructions.ts +8 -4
- package/src/commands/ledger-v3.ts +2 -1
- package/src/commands/rm.ts +115 -0
- package/src/commands/servers.ts +506 -0
- package/src/commands/tunnel.ts +102 -2
- package/src/commands/webview.ts +159 -0
- package/src/core/adapter.ts +102 -1
- package/src/core/adapters/attestation.ts +3 -2
- package/src/core/adapters/profiles.ts +63 -1
- package/src/core/adapters/registry.ts +37 -0
- package/src/core/adapters/types.ts +10 -0
- package/src/core/agents/canonical-emit.ts +2 -5
- package/src/core/agents/cli.ts +26 -17
- package/src/core/agents/coord-client.ts +9 -3
- package/src/core/agents/render/session-context.ts +1 -0
- package/src/core/agents/rules/claim-conflict.ts +3 -8
- package/src/core/agents/rules/commit-conflict.ts +2 -7
- package/src/core/agents/rules/stop-hook.ts +3 -1
- package/src/core/agents/session-events.ts +120 -26
- package/src/core/agents/session-finalization-state-v3.ts +2 -1
- package/src/core/agents/session-finalizer-v3.ts +5 -4
- package/src/core/agents/session-name-display.ts +48 -0
- package/src/core/agents/state/heartbeat-reader.ts +7 -0
- package/src/core/agents/state/heartbeat-writer.ts +24 -2
- package/src/core/agents/state/live-coordination-view.ts +74 -0
- package/src/core/agents/state/live-coordination-writer.ts +3 -0
- package/src/core/agents/state/stale-sweep.ts +2 -9
- package/src/core/agents/turn-changes.ts +97 -0
- package/src/core/artifacts/delivery-card.ts +12 -3
- package/src/core/artifacts/index.ts +701 -47
- package/src/core/config.ts +206 -4
- package/src/core/context/index.ts +2 -1
- package/src/core/conversations/archive.ts +4 -3
- package/src/core/diagnostics/bundle.ts +5 -3
- package/src/core/events/legacy-storage/canary.ts +5 -4
- package/src/core/events/legacy-storage/compression.ts +2 -1
- package/src/core/events/v3/adapter-id.ts +29 -1
- package/src/core/events/v3/authority-outbox.ts +2 -1
- package/src/core/events/v3/bootstrap.ts +5 -4
- package/src/core/events/v3/capabilities.ts +17 -0
- package/src/core/events/v3/contract.ts +9 -1
- package/src/core/events/v3/control-witness.ts +3 -2
- package/src/core/events/v3/coordination-transaction-recovery.ts +4 -3
- package/src/core/events/v3/fingerprint-keys.ts +7 -6
- package/src/core/events/v3/generated.ts +1 -1
- package/src/core/events/v3/live-feed.ts +5 -4
- package/src/core/events/v3/producers/command-recorder.ts +8 -6
- package/src/core/events/v3/producers/coordination-recorder.ts +8 -7
- package/src/core/events/v3/producers/diagnostic-summaries.ts +5 -4
- package/src/core/events/v3/producers/hook-base.ts +11 -4
- package/src/core/events/v3/producers/hook.ts +19 -1
- package/src/core/events/v3/producers/intake.ts +18 -6
- package/src/core/events/v3/producers/recorder.ts +139 -114
- package/src/core/events/v3/projection.ts +11 -1
- package/src/core/events/v3/recovery.ts +4 -3
- package/src/core/events/v3/support-storage/inventory.ts +2 -1
- package/src/core/events/v3/support-storage/maintenance.ts +8 -3
- package/src/core/events/v3/support-storage/pack-reader.ts +4 -3
- package/src/core/events/v3/support-storage/pack-writer.ts +6 -5
- package/src/core/events/v3/tool-line-changes.ts +139 -0
- package/src/core/events/v3/writer.ts +8 -7
- package/src/core/governor/planning.ts +6 -5
- package/src/core/governor/service.ts +12 -11
- package/src/core/governor/state.ts +7 -6
- package/src/core/guard/evaluator.ts +1 -0
- package/src/core/guard/storage.ts +3 -2
- package/src/core/hooks/adapter/behaviors/claude-code.ts +33 -0
- package/src/core/hooks/adapter/behaviors/codex.ts +96 -0
- package/src/core/hooks/adapter/behaviors/cursor.ts +37 -0
- package/src/core/hooks/adapter/behaviors/index.ts +31 -0
- package/src/core/hooks/adapter/behaviors/openclaw.ts +36 -0
- package/src/core/hooks/adapter/behaviors/opencode.ts +36 -0
- package/src/core/hooks/adapter/behaviors/types.ts +110 -0
- package/src/core/hooks/adapter/detect.ts +2 -3
- package/src/core/hooks/adapter/events.ts +72 -1
- package/src/core/hooks/adapter/opencode-plugin.ts +177 -0
- package/src/core/hooks/adapter/output.ts +8 -1
- package/src/core/hooks/adapter/runtime-telemetry.ts +3 -1
- package/src/core/hooks/adapter/wiring.ts +198 -16
- package/src/core/hooks/cli.ts +776 -539
- package/src/core/hooks/effects/image-capture.ts +2 -1
- package/src/core/hooks/prompt-context/contract.ts +1 -0
- package/src/core/hooks/resolve/transcript.ts +42 -5
- package/src/core/hooks/run-markers.ts +132 -0
- package/src/core/hooks/session-name-presence.ts +10 -3
- package/src/core/hooks/shell-waiter.ts +166 -0
- package/src/core/resources/service.ts +5 -4
- package/src/core/semantic/review.ts +5 -4
- package/src/core/semantic/service.ts +15 -14
- package/src/core/semantic/storage.ts +5 -4
- package/src/core/servers/index.ts +712 -0
- package/src/core/servers/net.ts +283 -0
- package/src/core/servers/tunnels.ts +39 -0
- package/src/core/storage/atomic-json.ts +7 -3
- package/src/core/storage/builtins.ts +1 -0
- package/src/core/storage/durable-history.ts +6 -5
- package/src/core/storage/maintenance-providers.ts +2 -1
- package/src/core/storage/maintenance.ts +7 -6
- package/src/core/storage/metrics.ts +5 -1
- package/src/core/storage/modes.ts +53 -0
- package/src/core/storage/process-log.ts +3 -2
- package/src/core/storage/receipts.ts +4 -3
- package/src/core/storage/segments.ts +7 -6
- package/src/core/supervisor/hook-health.ts +4 -4
- package/src/core/supervisor/service.ts +7 -6
- package/src/core/work/state.ts +8 -7
- package/src/core/workflow/adapters.ts +15 -0
- package/src/core/workflow/approvals.ts +6 -5
- package/src/core/workflow/billing.ts +34 -4
- package/src/core/workflow/durable-record.ts +4 -3
- package/src/core/workflow/engine.ts +38 -1
- package/src/core/workflow/live-session-v3.ts +2 -3
- package/src/core/workflow/run-state.ts +3 -2
- package/src/core/workflow/sandbox-projection.ts +38 -2
- package/src/core/workflow/spawn-claude.ts +5 -1
- package/src/core/workflow/spawn-codex.ts +18 -1
- package/src/core/workflow/spawn-cursor.ts +5 -1
- package/src/core/workflow/spawn-opencode.ts +153 -0
- package/src/core/workflow/transcript.ts +3 -2
- package/src/core/workflow/types.ts +62 -2
- package/src/core/workflow/worker-access.ts +525 -0
- package/src/core/workflow/workspaces/leases.ts +5 -4
- package/src/core/workflow/workspaces/local-git.ts +3 -2
- package/src/core/workflow/workspaces/paths.ts +2 -1
- package/src/core/workflow/workspaces/state.ts +10 -9
- package/src/lazy-commands.ts +11 -1
- package/src/lib/agent-browser/client.ts +18 -0
- package/src/lib/browser/batch-steps.ts +79 -0
- package/src/lib/browser/client.ts +147 -9
- package/src/lib/browser/collect/collector.ts +306 -0
- package/src/lib/browser/collect/fields.ts +87 -0
- package/src/lib/browser/collect/index.ts +47 -0
- package/src/lib/browser/collect/page-driver.ts +327 -0
- package/src/lib/browser/collect/presets.ts +237 -0
- package/src/lib/browser/collect/scroll-plan.ts +179 -0
- package/src/lib/browser/identity.ts +64 -0
- package/src/lib/browser/index.ts +16 -1
- package/src/lib/browser/launch-args.ts +53 -1
- package/src/lib/browser/page-review-judge.ts +16 -0
- package/src/lib/browser/qa-run-contracts.ts +11 -0
- package/src/lib/browser/qa-run.ts +1 -0
- package/src/lib/browser/user-agent.ts +130 -0
- package/src/lib/browser/windows-chrome.ts +227 -0
- package/src/lib/claude-desktop-share.ts +511 -0
- package/src/lib/disk-usage.ts +347 -0
- package/src/lib/docs-lint.ts +8 -3
- package/src/lib/docs-metadata-managed.ts +21 -0
- package/src/lib/guarded-remove.ts +376 -0
- package/src/lib/identities/assume.ts +7 -7
- package/src/lib/instructions/apply.ts +2 -0
- package/src/lib/instructions/templates.ts +8 -8
- package/src/lib/pace/index.ts +14 -0
- package/src/lib/pace/pace.ts +370 -0
- package/src/lib/tunnel/error-page.ts +25 -9
- package/src/lib/tunnel/forward-headers.ts +16 -0
- package/src/lib/tunnel/gate.ts +39 -10
- package/src/lib/tunnel/path-scope.ts +73 -0
- package/src/lib/tunnel/state.ts +20 -3
- package/src/lib/webview/index.ts +13 -0
- package/src/lib/webview/webview.ts +457 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Install-side owner of the OpenCode plugin files: what `harn init --adapter
|
|
3
|
+
* opencode` writes, what `--check`/`doctor` compare against, and what `deinit`
|
|
4
|
+
* removes. The plugin itself lives in `opencode-plugin/src/index.ts` and is
|
|
5
|
+
* copied verbatim under a hash-stamped ownership header, the same fully-owned
|
|
6
|
+
* file contract as the shipped skills (`lib/instructions/splice.ts`).
|
|
7
|
+
*
|
|
8
|
+
* Layout under the project root (`ADAPTER_SPECS.opencode.settingsFile` names
|
|
9
|
+
* the entry file):
|
|
10
|
+
*
|
|
11
|
+
* .opencode/plugins/harnery/index.ts # the plugin, header + verbatim source
|
|
12
|
+
* .opencode/plugins/harnery/harnery.json # { schema, agentHook } written by init
|
|
13
|
+
*
|
|
14
|
+
* OpenCode auto-discovers every directory under `.opencode/plugins/`, so no
|
|
15
|
+
* `opencode.json` edit is needed and a configured-plugin entry is never
|
|
16
|
+
* written (OpenCode also refuses a configured local *file*; only directories
|
|
17
|
+
* load that way).
|
|
18
|
+
*/
|
|
19
|
+
import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
20
|
+
import { dirname, resolve } from "node:path";
|
|
21
|
+
import { fileURLToPath } from "node:url";
|
|
22
|
+
import { shortHash } from "../../../lib/instructions/splice.js";
|
|
23
|
+
import { ADAPTER_SPECS } from "./events.js";
|
|
24
|
+
export const OPENCODE_PLUGIN_ENTRY = ADAPTER_SPECS.opencode.settingsFile;
|
|
25
|
+
export const OPENCODE_PLUGIN_DIR = dirname(OPENCODE_PLUGIN_ENTRY);
|
|
26
|
+
export const OPENCODE_PLUGIN_CONFIG = `${OPENCODE_PLUGIN_DIR}/harnery.json`;
|
|
27
|
+
export const OPENCODE_PLUGIN_CONFIG_SCHEMA = "harnery-opencode-plugin/v1";
|
|
28
|
+
const HEADER_RE = /^\/\/ harnery:generated opencode-plugin v=([0-9a-f]{8});[^\n]*\n/;
|
|
29
|
+
/** Package-relative path of the shipped plugin source (also listed in `files`). */
|
|
30
|
+
const PLUGIN_SOURCE = resolve(dirname(fileURLToPath(import.meta.url)), "..", "..", "..", "..", "opencode-plugin", "src", "index.ts");
|
|
31
|
+
/** The plugin source as shipped, trimmed so header + body hashing is stable. */
|
|
32
|
+
export function openCodePluginSource() {
|
|
33
|
+
return readFileSync(PLUGIN_SOURCE, "utf8").trim();
|
|
34
|
+
}
|
|
35
|
+
/** Render the installed entry file: ownership header, then the verbatim source. */
|
|
36
|
+
export function renderOpenCodePluginEntry(binName, source = openCodePluginSource()) {
|
|
37
|
+
const body = source.trim();
|
|
38
|
+
const header = `// harnery:generated opencode-plugin v=${shortHash(body)}; machine-owned; ` +
|
|
39
|
+
`regenerated by \`${binName} init --adapter opencode\`, removed by \`${binName} deinit --adapter opencode\`. ` +
|
|
40
|
+
"Edit harnery's opencode-plugin/src/index.ts, not this file.";
|
|
41
|
+
return `${header}\n${body}\n`;
|
|
42
|
+
}
|
|
43
|
+
/** Render the sibling config the plugin reads to find the `agent-hook` launcher. */
|
|
44
|
+
export function renderOpenCodePluginConfig(agentHook) {
|
|
45
|
+
return `${JSON.stringify({ schema: OPENCODE_PLUGIN_CONFIG_SCHEMA, agentHook }, null, 2)}\n`;
|
|
46
|
+
}
|
|
47
|
+
/** True when the content carries harnery's plugin ownership header. */
|
|
48
|
+
export function isOwnedOpenCodePlugin(content) {
|
|
49
|
+
return HEADER_RE.test(content);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Compare the installed plugin files with what init would write now. Pure
|
|
53
|
+
* except for reads; never writes. `foreign` means an entry file exists at the
|
|
54
|
+
* harnery path without harnery's header, which init refuses to overwrite.
|
|
55
|
+
*/
|
|
56
|
+
export function checkOpenCodePlugin(projectRoot, expected) {
|
|
57
|
+
const entryPath = resolve(projectRoot, OPENCODE_PLUGIN_ENTRY);
|
|
58
|
+
const configPath = resolve(projectRoot, OPENCODE_PLUGIN_CONFIG);
|
|
59
|
+
if (!existsSync(entryPath))
|
|
60
|
+
return { status: "missing", issues: [] };
|
|
61
|
+
const content = readFileSync(entryPath, "utf8");
|
|
62
|
+
const match = HEADER_RE.exec(content);
|
|
63
|
+
if (!match) {
|
|
64
|
+
return {
|
|
65
|
+
status: "foreign",
|
|
66
|
+
issues: [`${OPENCODE_PLUGIN_ENTRY}: exists without harnery's ownership header`],
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
const issues = [];
|
|
70
|
+
const body = content.slice(match[0].length).trim();
|
|
71
|
+
const fresh = (expected.source ?? openCodePluginSource()).trim();
|
|
72
|
+
if (match[1] !== shortHash(fresh) || body !== fresh) {
|
|
73
|
+
issues.push(`${OPENCODE_PLUGIN_ENTRY}: plugin source is stale (re-run init)`);
|
|
74
|
+
}
|
|
75
|
+
if (!existsSync(configPath)) {
|
|
76
|
+
issues.push(`${OPENCODE_PLUGIN_CONFIG}: missing`);
|
|
77
|
+
}
|
|
78
|
+
else if (readFileSync(configPath, "utf8") !== renderOpenCodePluginConfig(expected.agentHook)) {
|
|
79
|
+
issues.push(`${OPENCODE_PLUGIN_CONFIG}: stale agent-hook launcher (re-run init)`);
|
|
80
|
+
}
|
|
81
|
+
return { status: issues.length === 0 ? "fresh" : "stale", issues };
|
|
82
|
+
}
|
|
83
|
+
/** Write (or refresh) the plugin directory. Idempotent; a fresh install is a no-op. */
|
|
84
|
+
export function installOpenCodePlugin(projectRoot, opts) {
|
|
85
|
+
const check = checkOpenCodePlugin(projectRoot, opts);
|
|
86
|
+
if (check.status === "foreign") {
|
|
87
|
+
return {
|
|
88
|
+
actions: [],
|
|
89
|
+
error: `✗ ${OPENCODE_PLUGIN_ENTRY} exists but is not harnery's plugin; refusing to overwrite. ` +
|
|
90
|
+
"Move it aside and re-run.",
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
if (check.status === "fresh") {
|
|
94
|
+
return { actions: [`· opencode plugin already installed at ${OPENCODE_PLUGIN_DIR}/`] };
|
|
95
|
+
}
|
|
96
|
+
const verb = check.status === "missing" ? "install" : "refresh";
|
|
97
|
+
if (opts.dryRun) {
|
|
98
|
+
return {
|
|
99
|
+
actions: [
|
|
100
|
+
`+ would ${verb} the opencode plugin at ${OPENCODE_PLUGIN_DIR}/ (index.ts + harnery.json)`,
|
|
101
|
+
...check.issues.map((issue) => ` · ${issue}`),
|
|
102
|
+
],
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
const dir = resolve(projectRoot, OPENCODE_PLUGIN_DIR);
|
|
106
|
+
mkdirSync(dir, { recursive: true });
|
|
107
|
+
writeFileSync(resolve(projectRoot, OPENCODE_PLUGIN_ENTRY), renderOpenCodePluginEntry(opts.binName));
|
|
108
|
+
writeFileSync(resolve(projectRoot, OPENCODE_PLUGIN_CONFIG), renderOpenCodePluginConfig(opts.agentHook));
|
|
109
|
+
return {
|
|
110
|
+
actions: [
|
|
111
|
+
`+ ${verb === "install" ? "installed" : "refreshed"} the opencode plugin at ${OPENCODE_PLUGIN_DIR}/ (index.ts + harnery.json)`,
|
|
112
|
+
],
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
/** Remove the plugin directory when harnery owns it. Leaves a foreign file alone. */
|
|
116
|
+
export function removeOpenCodePlugin(projectRoot, dryRun) {
|
|
117
|
+
const dir = resolve(projectRoot, OPENCODE_PLUGIN_DIR);
|
|
118
|
+
const entryPath = resolve(projectRoot, OPENCODE_PLUGIN_ENTRY);
|
|
119
|
+
if (!existsSync(entryPath)) {
|
|
120
|
+
return [`· ${OPENCODE_PLUGIN_DIR}/ doesn't exist; no plugin to remove`];
|
|
121
|
+
}
|
|
122
|
+
if (!isOwnedOpenCodePlugin(readFileSync(entryPath, "utf8"))) {
|
|
123
|
+
return [`· ${OPENCODE_PLUGIN_ENTRY} is not harnery's plugin; left in place`];
|
|
124
|
+
}
|
|
125
|
+
if (dryRun)
|
|
126
|
+
return [`+ would remove ${OPENCODE_PLUGIN_DIR}/ (harnery-owned plugin)`];
|
|
127
|
+
rmSync(dir, { recursive: true, force: true });
|
|
128
|
+
return [`+ removed ${OPENCODE_PLUGIN_DIR}/ (harnery-owned plugin)`];
|
|
129
|
+
}
|
|
@@ -14,6 +14,9 @@
|
|
|
14
14
|
* - **Codex**: structurally identical to Claude Code for context and tool
|
|
15
15
|
* denials. Stop blocks are deliberately suppressed because their automatic
|
|
16
16
|
* continuation can replace a completed user-facing answer.
|
|
17
|
+
* - **OpenCode**: the Harnery OpenCode plugin reads the Claude Code envelope
|
|
18
|
+
* (`hookSpecificOutput.additionalContext` / `permissionDecision`) and feeds
|
|
19
|
+
* it back through OpenCode's own channels. Stop blocks are suppressed.
|
|
17
20
|
*
|
|
18
21
|
* Every helper writes to process.stdout + newline-terminates so callers can
|
|
19
22
|
* fire-and-forget. Empty text is a no-op.
|
|
@@ -46,6 +49,10 @@ export declare function emitDeny(adapter: Adapter, reason: string): void;
|
|
|
46
49
|
* answer in clients that retain only the final continuation response. Return
|
|
47
50
|
* success without output as a defense in depth behind the observe-only
|
|
48
51
|
* verdict in `agents/rules/stop-hook.ts`.
|
|
52
|
+
* - **OpenCode** has no blocking Stop channel at all: the plugin observes
|
|
53
|
+
* `session.execution.succeeded` after the turn has already completed, so a
|
|
54
|
+
* block could only arrive as a new message. Return success without output;
|
|
55
|
+
* the verdict is still recorded in the ledger.
|
|
49
56
|
* - **Cursor** ignores stop-hook exit codes (non-zero = fail-open, the turn
|
|
50
57
|
* proceeds) and re-prompts ONLY via a `followup_message` field in stdout
|
|
51
58
|
* JSON, which it auto-submits as the next user message: the sanctioned
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../../../src/core/hooks/adapter/output.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../../../src/core/hooks/adapter/output.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAIhD,MAAM,MAAM,WAAW,GACnB,cAAc,GACd,kBAAkB,GAClB,eAAe,GACf,YAAY,GACZ,aAAa,CAAC;AAElB,MAAM,WAAW,iBAAiB;IAChC,kEAAkE;IAClE,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CAC7C;AAED,+EAA+E;AAC/E,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAKvF;AAED,qFAAqF;AACrF,wBAAgB,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAI/D;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAC1C,SAAS,CAAC,EAAE,MAAM,GACjB,CAAC,GAAG,CAAC,CAEP;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,iBAAiB,EAC1B,SAAS,CAAC,EAAE,MAAM,GACjB,CAAC,GAAG,CAAC,CAuBP"}
|
|
@@ -14,6 +14,9 @@
|
|
|
14
14
|
* - **Codex**: structurally identical to Claude Code for context and tool
|
|
15
15
|
* denials. Stop blocks are deliberately suppressed because their automatic
|
|
16
16
|
* continuation can replace a completed user-facing answer.
|
|
17
|
+
* - **OpenCode**: the Harnery OpenCode plugin reads the Claude Code envelope
|
|
18
|
+
* (`hookSpecificOutput.additionalContext` / `permissionDecision`) and feeds
|
|
19
|
+
* it back through OpenCode's own channels. Stop blocks are suppressed.
|
|
17
20
|
*
|
|
18
21
|
* Every helper writes to process.stdout + newline-terminates so callers can
|
|
19
22
|
* fire-and-forget. Empty text is a no-op.
|
|
@@ -50,6 +53,10 @@ export function emitDeny(adapter, reason) {
|
|
|
50
53
|
* answer in clients that retain only the final continuation response. Return
|
|
51
54
|
* success without output as a defense in depth behind the observe-only
|
|
52
55
|
* verdict in `agents/rules/stop-hook.ts`.
|
|
56
|
+
* - **OpenCode** has no blocking Stop channel at all: the plugin observes
|
|
57
|
+
* `session.execution.succeeded` after the turn has already completed, so a
|
|
58
|
+
* block could only arrive as a new message. Return success without output;
|
|
59
|
+
* the verdict is still recorded in the ledger.
|
|
53
60
|
* - **Cursor** ignores stop-hook exit codes (non-zero = fail-open, the turn
|
|
54
61
|
* proceeds) and re-prompts ONLY via a `followup_message` field in stdout
|
|
55
62
|
* JSON, which it auto-submits as the next user message: the sanctioned
|
|
@@ -64,7 +71,7 @@ export function emitStopBlock(adapter, verdict, coordRoot) {
|
|
|
64
71
|
* Emit the adapter-specific response for one Stop outcome.
|
|
65
72
|
*/
|
|
66
73
|
export function emitStopOutcome(adapter, options, coordRoot) {
|
|
67
|
-
if (adapter === "codex")
|
|
74
|
+
if (adapter === "codex" || adapter === "opencode")
|
|
68
75
|
return 0;
|
|
69
76
|
const verdict = options.verdict;
|
|
70
77
|
if (!verdict)
|
|
@@ -409,7 +409,9 @@ function claudeModelContextCapability(model) {
|
|
|
409
409
|
const normalized = model.toLowerCase();
|
|
410
410
|
const oneMillionTokenModels = new Set([
|
|
411
411
|
"claude-fable-5",
|
|
412
|
+
"claude-opus-5-5",
|
|
412
413
|
"claude-opus-5",
|
|
414
|
+
"claude-sonnet-5-5",
|
|
413
415
|
"claude-sonnet-5",
|
|
414
416
|
"claude-opus-4-8",
|
|
415
417
|
"claude-opus-4-7",
|
|
@@ -417,7 +419,7 @@ function claudeModelContextCapability(model) {
|
|
|
417
419
|
"claude-sonnet-4-6",
|
|
418
420
|
]);
|
|
419
421
|
if (oneMillionTokenModels.has(normalized)) {
|
|
420
|
-
return { limit_tokens: 1_000_000, authority: "
|
|
422
|
+
return { limit_tokens: 1_000_000, authority: "anthropic_model_capabilities_2026_09" };
|
|
421
423
|
}
|
|
422
424
|
if (normalized === "claude-haiku-4-5" || normalized === "claude-haiku-4-5-20251001") {
|
|
423
425
|
return { limit_tokens: 200_000, authority: "anthropic_model_capabilities_2026_08" };
|
|
@@ -11,21 +11,30 @@
|
|
|
11
11
|
* — there's exactly one definition of the `agent-hook <subcommand>` match.
|
|
12
12
|
*/
|
|
13
13
|
import { type AdapterId, type AdapterSpec, type HookEntryShape, type HookEvent } from "./events.js";
|
|
14
|
-
/** Claude Code
|
|
14
|
+
/** One Claude Code or Codex command handler. */
|
|
15
|
+
export interface ClaudeHookHandler {
|
|
16
|
+
type: string;
|
|
17
|
+
command: string;
|
|
18
|
+
/** Codex: run instead of `command` on Windows. */
|
|
19
|
+
commandWindows?: string;
|
|
20
|
+
timeout?: number;
|
|
21
|
+
}
|
|
22
|
+
/** Claude Code + Codex entry: `{ hooks: [{ type, command, commandWindows?, timeout? }] }`. */
|
|
15
23
|
export interface ClaudeHookGroup {
|
|
16
24
|
matcher?: string;
|
|
17
|
-
hooks:
|
|
18
|
-
type: string;
|
|
19
|
-
command: string;
|
|
20
|
-
}[];
|
|
25
|
+
hooks: ClaudeHookHandler[];
|
|
21
26
|
}
|
|
22
27
|
/** Cursor entry: a flat `{ command }`. */
|
|
23
28
|
export interface CursorHookGroup {
|
|
24
29
|
command: string;
|
|
25
30
|
type?: string;
|
|
26
31
|
matcher?: string;
|
|
32
|
+
/** Cursor Stop followup cap. Harnery pins 2; Cursor's own default is 5. */
|
|
33
|
+
loop_limit?: number;
|
|
27
34
|
}
|
|
28
35
|
export type HookGroup = ClaudeHookGroup | CursorHookGroup;
|
|
36
|
+
/** Bound Cursor Stop `followup_message` retries so a missed ritual cannot loop 5 times. */
|
|
37
|
+
export declare const CURSOR_STOP_FOLLOWUP_LOOP_LIMIT = 2;
|
|
29
38
|
export interface SettingsFile {
|
|
30
39
|
version?: number;
|
|
31
40
|
description?: string;
|
|
@@ -33,7 +42,36 @@ export interface SettingsFile {
|
|
|
33
42
|
[k: string]: unknown;
|
|
34
43
|
}
|
|
35
44
|
/** Build a hook entry in the adapter's shape. */
|
|
36
|
-
export declare function makeEntry(shape: HookEntryShape, command: string
|
|
45
|
+
export declare function makeEntry(shape: HookEntryShape, command: string, extras?: {
|
|
46
|
+
loop_limit?: number;
|
|
47
|
+
timeout?: number;
|
|
48
|
+
commandWindows?: string;
|
|
49
|
+
}): HookGroup;
|
|
50
|
+
/**
|
|
51
|
+
* Rebuild a handler with Harnery's fields first in a fixed order, dropping
|
|
52
|
+
* undefined ones and keeping any other fields after them.
|
|
53
|
+
*/
|
|
54
|
+
export declare function orderHandlerKeys(handler: ClaudeHookHandler): ClaudeHookHandler;
|
|
55
|
+
/**
|
|
56
|
+
* The Windows command for an opted-in project (ADR 0197). It hands the hook to
|
|
57
|
+
* the bridge entry point when that is on PATH and the working directory is a
|
|
58
|
+
* WSL UNC path, and otherwise runs the usual command. `ProviderPath` drops the
|
|
59
|
+
* provider prefix that `Path` carries. The trailing `exit $LASTEXITCODE` is
|
|
60
|
+
* required: without it PowerShell reports any non-zero exit from inside the
|
|
61
|
+
* `if` block as 1, which would turn a hook's blocking exit 2 into a failure.
|
|
62
|
+
*/
|
|
63
|
+
export declare function hookCommandWindows(spec: AdapterSpec, agentHookPath: string, subcommand: string, adapter: AdapterId, entryPoint: string): string;
|
|
64
|
+
/** Project-level choices that change what init writes. */
|
|
65
|
+
export interface WiringOptions {
|
|
66
|
+
/** Bridge entry point from `hooks.codexWindowsBridge`, or null when not opted in. */
|
|
67
|
+
windowsBridgeEntryPoint?: string | null;
|
|
68
|
+
}
|
|
69
|
+
/** The `commandWindows` init writes for one event, or undefined for none. */
|
|
70
|
+
export declare function expectedCommandWindows(spec: AdapterSpec, agentHookPath: string, subcommand: string, adapter: AdapterId, options?: WiringOptions): string | undefined;
|
|
71
|
+
/** The `timeout` init writes on one event's Harnery hook, or undefined for none. */
|
|
72
|
+
export declare function hookTimeoutFor(spec: AdapterSpec, subcommand: string): number | undefined;
|
|
73
|
+
/** Pin Cursor Stop followups to Harnery's loop cap. Returns true when the entry changed. */
|
|
74
|
+
export declare function applyCursorStopLoopLimit(group: HookGroup, subcommand: string): boolean;
|
|
37
75
|
/** Pull every command string out of a hook entry, regardless of shape. */
|
|
38
76
|
export declare function groupCommands(group: HookGroup): string[];
|
|
39
77
|
/**
|
|
@@ -68,7 +106,7 @@ export interface WiringDiff {
|
|
|
68
106
|
duplicates: HookEvent[];
|
|
69
107
|
/** Spec events wired under an event key other than the canonical one. */
|
|
70
108
|
misplaced: HookEvent[];
|
|
71
|
-
/** Spec events whose correct-key command differs from init
|
|
109
|
+
/** Spec events whose correct-key command, `commandWindows`, or `timeout` differs from what init writes. */
|
|
72
110
|
stale: HookEvent[];
|
|
73
111
|
/** Settings fields rejected by a adapter with a strict top-level schema. */
|
|
74
112
|
invalidTopLevelKeys: string[];
|
|
@@ -82,7 +120,7 @@ export interface WiringDiff {
|
|
|
82
120
|
export declare function diffWiring(settings: SettingsFile, spec: AdapterSpec, expected?: {
|
|
83
121
|
agentHookPath: string;
|
|
84
122
|
adapter: AdapterId;
|
|
85
|
-
}): WiringDiff;
|
|
123
|
+
} & WiringOptions): WiringDiff;
|
|
86
124
|
export interface AdapterWiringStatus {
|
|
87
125
|
adapter: AdapterId;
|
|
88
126
|
/** Settings file path, relative to the project root. */
|
|
@@ -95,6 +133,12 @@ export interface AdapterWiringStatus {
|
|
|
95
133
|
invalidTopLevelKeys: string[];
|
|
96
134
|
invalidEventKeys: string[];
|
|
97
135
|
parseError?: string;
|
|
136
|
+
/**
|
|
137
|
+
* `opencode-plugin` install mode only: why the installed plugin differs from
|
|
138
|
+
* what init writes now (stale source, missing/stale `harnery.json`, or a
|
|
139
|
+
* foreign file at the harnery path). Hook-map fields stay empty for it.
|
|
140
|
+
*/
|
|
141
|
+
pluginIssues?: string[];
|
|
98
142
|
}
|
|
99
143
|
/**
|
|
100
144
|
* Inspect every adapter whose settings file exists under `projectRoot` and
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wiring.d.ts","sourceRoot":"","sources":["../../../../src/core/hooks/adapter/wiring.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;
|
|
1
|
+
{"version":3,"file":"wiring.d.ts","sourceRoot":"","sources":["../../../../src/core/hooks/adapter/wiring.ts"],"names":[],"mappings":"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"}
|
|
@@ -13,10 +13,78 @@
|
|
|
13
13
|
import { existsSync, readFileSync } from "node:fs";
|
|
14
14
|
import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
15
15
|
import { fileURLToPath } from "node:url";
|
|
16
|
+
import { codexWindowsBridgeConfig, resolveBinName } from "../../config.js";
|
|
16
17
|
import { ADAPTER_SPECS, } from "./events.js";
|
|
18
|
+
import { checkOpenCodePlugin, isOwnedOpenCodePlugin } from "./opencode-plugin.js";
|
|
19
|
+
/** Bound Cursor Stop `followup_message` retries so a missed ritual cannot loop 5 times. */
|
|
20
|
+
export const CURSOR_STOP_FOLLOWUP_LOOP_LIMIT = 2;
|
|
17
21
|
/** Build a hook entry in the adapter's shape. */
|
|
18
|
-
export function makeEntry(shape, command) {
|
|
19
|
-
|
|
22
|
+
export function makeEntry(shape, command, extras) {
|
|
23
|
+
if (shape !== "cursor") {
|
|
24
|
+
return {
|
|
25
|
+
hooks: [
|
|
26
|
+
orderHandlerKeys({
|
|
27
|
+
type: "command",
|
|
28
|
+
command,
|
|
29
|
+
commandWindows: extras?.commandWindows,
|
|
30
|
+
timeout: extras?.timeout,
|
|
31
|
+
}),
|
|
32
|
+
],
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
return extras?.loop_limit !== undefined
|
|
36
|
+
? { command, loop_limit: extras.loop_limit }
|
|
37
|
+
: { command };
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Rebuild a handler with Harnery's fields first in a fixed order, dropping
|
|
41
|
+
* undefined ones and keeping any other fields after them.
|
|
42
|
+
*/
|
|
43
|
+
export function orderHandlerKeys(handler) {
|
|
44
|
+
const { type, command, commandWindows, timeout, ...rest } = handler;
|
|
45
|
+
return {
|
|
46
|
+
type,
|
|
47
|
+
command,
|
|
48
|
+
...(commandWindows !== undefined ? { commandWindows } : {}),
|
|
49
|
+
...(timeout !== undefined ? { timeout } : {}),
|
|
50
|
+
...rest,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* The Windows command for an opted-in project (ADR 0197). It hands the hook to
|
|
55
|
+
* the bridge entry point when that is on PATH and the working directory is a
|
|
56
|
+
* WSL UNC path, and otherwise runs the usual command. `ProviderPath` drops the
|
|
57
|
+
* provider prefix that `Path` carries. The trailing `exit $LASTEXITCODE` is
|
|
58
|
+
* required: without it PowerShell reports any non-zero exit from inside the
|
|
59
|
+
* `if` block as 1, which would turn a hook's blocking exit 2 into a failure.
|
|
60
|
+
*/
|
|
61
|
+
export function hookCommandWindows(spec, agentHookPath, subcommand, adapter, entryPoint) {
|
|
62
|
+
const direct = hookCommand(spec, agentHookPath, subcommand, adapter);
|
|
63
|
+
return (`if ((Get-Command ${entryPoint} -ErrorAction Ignore) -and $PWD.ProviderPath -like '\\\\wsl*') ` +
|
|
64
|
+
`{ ${entryPoint} ${subcommand} --adapter ${adapter} } else { ${direct} }; exit $LASTEXITCODE`);
|
|
65
|
+
}
|
|
66
|
+
/** The `commandWindows` init writes for one event, or undefined for none. */
|
|
67
|
+
export function expectedCommandWindows(spec, agentHookPath, subcommand, adapter, options) {
|
|
68
|
+
if (!spec.windowsBridgeHooks || !options?.windowsBridgeEntryPoint)
|
|
69
|
+
return undefined;
|
|
70
|
+
return hookCommandWindows(spec, agentHookPath, subcommand, adapter, options.windowsBridgeEntryPoint);
|
|
71
|
+
}
|
|
72
|
+
/** The `timeout` init writes on one event's Harnery hook, or undefined for none. */
|
|
73
|
+
export function hookTimeoutFor(spec, subcommand) {
|
|
74
|
+
if (!spec.hookTimeouts)
|
|
75
|
+
return undefined;
|
|
76
|
+
return spec.hookTimeouts.bySubcommand?.[subcommand] ?? spec.hookTimeouts.default;
|
|
77
|
+
}
|
|
78
|
+
/** Pin Cursor Stop followups to Harnery's loop cap. Returns true when the entry changed. */
|
|
79
|
+
export function applyCursorStopLoopLimit(group, subcommand) {
|
|
80
|
+
if (subcommand !== "stop")
|
|
81
|
+
return false;
|
|
82
|
+
if (!("command" in group) || typeof group.command !== "string")
|
|
83
|
+
return false;
|
|
84
|
+
if (group.loop_limit === CURSOR_STOP_FOLLOWUP_LOOP_LIMIT)
|
|
85
|
+
return false;
|
|
86
|
+
group.loop_limit = CURSOR_STOP_FOLLOWUP_LOOP_LIMIT;
|
|
87
|
+
return true;
|
|
20
88
|
}
|
|
21
89
|
/** Pull every command string out of a hook entry, regardless of shape. */
|
|
22
90
|
export function groupCommands(group) {
|
|
@@ -88,7 +156,15 @@ export function diffWiring(settings, spec, expected) {
|
|
|
88
156
|
duplicates.push(event);
|
|
89
157
|
if (expected && commands.length > 0) {
|
|
90
158
|
const canonical = hookCommand(spec, expected.agentHookPath, event.subcommand, expected.adapter);
|
|
91
|
-
|
|
159
|
+
const timeout = hookTimeoutFor(spec, event.subcommand);
|
|
160
|
+
const commandWindows = expectedCommandWindows(spec, expected.agentHookPath, event.subcommand, expected.adapter, expected);
|
|
161
|
+
const handlerDrift = groups.some((group) => "hooks" in group &&
|
|
162
|
+
Array.isArray(group.hooks) &&
|
|
163
|
+
group.hooks.some((hook) => typeof hook.command === "string" &&
|
|
164
|
+
commandWiresSubcommand(hook.command, event.subcommand) &&
|
|
165
|
+
((timeout !== undefined && hook.timeout !== timeout) ||
|
|
166
|
+
(spec.windowsBridgeHooks === true && hook.commandWindows !== commandWindows))));
|
|
167
|
+
if (handlerDrift || commands.some((command) => command !== canonical))
|
|
92
168
|
stale.push(event);
|
|
93
169
|
}
|
|
94
170
|
const wrongKey = Object.entries(hooks).some(([key, otherGroups]) => key !== event.settingsKey &&
|
|
@@ -131,6 +207,39 @@ export function diffWiring(settings, spec, expected) {
|
|
|
131
207
|
invalidEventKeys,
|
|
132
208
|
};
|
|
133
209
|
}
|
|
210
|
+
function emptyWiringStatus(adapter, settingsFile) {
|
|
211
|
+
return {
|
|
212
|
+
adapter,
|
|
213
|
+
settingsFile,
|
|
214
|
+
missing: [],
|
|
215
|
+
orphans: [],
|
|
216
|
+
duplicates: [],
|
|
217
|
+
misplaced: [],
|
|
218
|
+
stale: [],
|
|
219
|
+
invalidTopLevelKeys: [],
|
|
220
|
+
invalidEventKeys: [],
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Plugin-mode drift: the installed entry exists but is not what init would
|
|
225
|
+
* write now. Absent entry → not opted in → null (mirrors the hook-map rule).
|
|
226
|
+
* Without a resolvable package root the launcher cannot be compared, so only
|
|
227
|
+
* the source freshness is judged.
|
|
228
|
+
*/
|
|
229
|
+
function pluginDrift(projectRoot, id, spec) {
|
|
230
|
+
if (!existsSync(resolve(projectRoot, spec.settingsFile)))
|
|
231
|
+
return null;
|
|
232
|
+
const packageRoot = harneryPackageRoot();
|
|
233
|
+
const check = checkOpenCodePlugin(projectRoot, {
|
|
234
|
+
binName: resolveBinName(projectRoot),
|
|
235
|
+
agentHook: packageRoot ? agentHookPathForProject(projectRoot, packageRoot) : "agent-hook",
|
|
236
|
+
});
|
|
237
|
+
if (check.status === "fresh")
|
|
238
|
+
return null;
|
|
239
|
+
if (check.status === "missing")
|
|
240
|
+
return null;
|
|
241
|
+
return { ...emptyWiringStatus(id, spec.settingsFile), pluginIssues: check.issues };
|
|
242
|
+
}
|
|
134
243
|
/**
|
|
135
244
|
* Inspect every adapter whose settings file exists under `projectRoot` and
|
|
136
245
|
* return only those with *drift*. Read-only; never writes.
|
|
@@ -145,6 +254,12 @@ export function diffWiring(settings, spec, expected) {
|
|
|
145
254
|
export function loadAdapterWiring(projectRoot) {
|
|
146
255
|
const out = [];
|
|
147
256
|
for (const [id, spec] of Object.entries(ADAPTER_SPECS)) {
|
|
257
|
+
if (spec.installMode === "opencode-plugin") {
|
|
258
|
+
const drift = pluginDrift(projectRoot, id, spec);
|
|
259
|
+
if (drift)
|
|
260
|
+
out.push(drift);
|
|
261
|
+
continue;
|
|
262
|
+
}
|
|
148
263
|
const settingsPath = resolve(projectRoot, spec.settingsFile);
|
|
149
264
|
if (!existsSync(settingsPath))
|
|
150
265
|
continue;
|
|
@@ -154,15 +269,7 @@ export function loadAdapterWiring(projectRoot) {
|
|
|
154
269
|
}
|
|
155
270
|
catch (error) {
|
|
156
271
|
out.push({
|
|
157
|
-
|
|
158
|
-
settingsFile: spec.settingsFile,
|
|
159
|
-
missing: [],
|
|
160
|
-
orphans: [],
|
|
161
|
-
duplicates: [],
|
|
162
|
-
misplaced: [],
|
|
163
|
-
stale: [],
|
|
164
|
-
invalidTopLevelKeys: [],
|
|
165
|
-
invalidEventKeys: [],
|
|
272
|
+
...emptyWiringStatus(id, spec.settingsFile),
|
|
166
273
|
parseError: error.message,
|
|
167
274
|
});
|
|
168
275
|
continue;
|
|
@@ -172,6 +279,7 @@ export function loadAdapterWiring(projectRoot) {
|
|
|
172
279
|
? {
|
|
173
280
|
agentHookPath: agentHookPathForProject(projectRoot, packageRoot),
|
|
174
281
|
adapter: id,
|
|
282
|
+
windowsBridgeEntryPoint: codexWindowsBridgeConfig(projectRoot).entryPoint,
|
|
175
283
|
}
|
|
176
284
|
: undefined);
|
|
177
285
|
if (diff.present.length === 0)
|
|
@@ -220,6 +328,19 @@ export function summarizeAdapterWiring(projectRoot) {
|
|
|
220
328
|
unwired.push(id);
|
|
221
329
|
continue;
|
|
222
330
|
}
|
|
331
|
+
if (spec.installMode === "opencode-plugin") {
|
|
332
|
+
// The entry counts as wired only when harnery owns it; a foreign file at
|
|
333
|
+
// that path is drift (surfaced by loadAdapterWiring), not a wiring.
|
|
334
|
+
let content;
|
|
335
|
+
try {
|
|
336
|
+
content = readFileSync(settingsPath, "utf8");
|
|
337
|
+
}
|
|
338
|
+
catch {
|
|
339
|
+
continue;
|
|
340
|
+
}
|
|
341
|
+
(isOwnedOpenCodePlugin(content) ? wired : unwired).push(id);
|
|
342
|
+
continue;
|
|
343
|
+
}
|
|
223
344
|
let settings;
|
|
224
345
|
try {
|
|
225
346
|
settings = JSON.parse(readFileSync(settingsPath, "utf8"));
|