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
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Command } from "commander";
|
|
2
2
|
import type { EmitContext, HarneryProgramContext } from "../commander.ts";
|
|
3
|
-
import type
|
|
3
|
+
import { ADAPTERS, type Adapter, normalizeAdapter } from "../core/adapter.ts";
|
|
4
4
|
import { monorepoRoot, resolveOwner } from "../core/agents/index.ts";
|
|
5
5
|
import { readLiveCoordinationRow } from "../core/agents/state/live-coordination-view.ts";
|
|
6
6
|
import {
|
|
@@ -76,7 +76,7 @@ export function registerCheckpointCommand(
|
|
|
76
76
|
.description("Create a durable context-continuity capsule for the current work")
|
|
77
77
|
.option("--session <id>", "Session id (defaults to the current agent heartbeat)")
|
|
78
78
|
.option("--instance <id>", "Agent instance id (defaults to the current owner)")
|
|
79
|
-
.option("--adapter <id>", "
|
|
79
|
+
.option("--adapter <id>", `${ADAPTERS.join(", ")} (inferred from heartbeat)`)
|
|
80
80
|
.option("--reason <reason>", "manual, pressure, pre_compact, or session_end", "manual")
|
|
81
81
|
.option("--note <text>", "Short continuation note for the recovered agent")
|
|
82
82
|
.option("--json", "Structured JSON output")
|
|
@@ -94,7 +94,7 @@ export function registerCheckpointCommand(
|
|
|
94
94
|
const reason = parseCheckpointReason(opts.reason);
|
|
95
95
|
const identity = resolveContinuityIdentity(context, opts);
|
|
96
96
|
if (!identity.adapter) {
|
|
97
|
-
throw new Error(
|
|
97
|
+
throw new Error(`could not infer the adapter; pass --adapter ${ADAPTERS.join("|")}`);
|
|
98
98
|
}
|
|
99
99
|
const result = checkpointContext(identity.coordRoot, {
|
|
100
100
|
sessionId: identity.sessionId,
|
|
@@ -166,15 +166,13 @@ function resolveContinuityIdentity(
|
|
|
166
166
|
}
|
|
167
167
|
|
|
168
168
|
function adapterFromPlatform(platform: string | undefined): Adapter | null {
|
|
169
|
-
|
|
170
|
-
if (platform === "cursor") return "cursor";
|
|
171
|
-
if (platform === "codex") return "codex";
|
|
172
|
-
return null;
|
|
169
|
+
return normalizeAdapter(platform);
|
|
173
170
|
}
|
|
174
171
|
|
|
175
172
|
function parseAdapter(value: string): Adapter {
|
|
176
|
-
|
|
177
|
-
|
|
173
|
+
const adapter = normalizeAdapter(value);
|
|
174
|
+
if (adapter) return adapter;
|
|
175
|
+
throw new Error(`invalid adapter "${value}"; expected one of ${ADAPTERS.join(", ")}`);
|
|
178
176
|
}
|
|
179
177
|
|
|
180
178
|
function parseCheckpointReason(value: string): CheckpointReason {
|
|
@@ -8,6 +8,13 @@ import {
|
|
|
8
8
|
planMirror,
|
|
9
9
|
readCliAccount,
|
|
10
10
|
} from "../lib/claude-desktop.ts";
|
|
11
|
+
import {
|
|
12
|
+
applyShare,
|
|
13
|
+
defaultShareDir,
|
|
14
|
+
planShare,
|
|
15
|
+
shareSummary,
|
|
16
|
+
} from "../lib/claude-desktop-share.ts";
|
|
17
|
+
import { resolveMachineLabel } from "../lib/machine.ts";
|
|
11
18
|
|
|
12
19
|
/**
|
|
13
20
|
* `claude-desktop`: make Claude desktop-app sessions survive account
|
|
@@ -186,6 +193,60 @@ export function registerClaudeDesktopCommand(
|
|
|
186
193
|
}
|
|
187
194
|
},
|
|
188
195
|
);
|
|
196
|
+
|
|
197
|
+
cmd
|
|
198
|
+
.command("share")
|
|
199
|
+
.description(
|
|
200
|
+
"Share sessions with your other computers through a synced folder (iCloud Drive by default): " +
|
|
201
|
+
"publish this machine's recent sessions and list + resume every other machine's here. " +
|
|
202
|
+
"Dry-run by default; --yes applies. Restart the desktop app afterward to see new entries.",
|
|
203
|
+
)
|
|
204
|
+
.option("--dir <path>", "Shared folder (default: iCloud Drive/Harnery/claude-sessions)")
|
|
205
|
+
.option("--days <n>", "Only sessions active in the last N days", "14")
|
|
206
|
+
.option("--data-dir <path>", "Explicit desktop-app data directory")
|
|
207
|
+
.option("--yes", "Apply the plan (default is dry-run)")
|
|
208
|
+
.action((opts: { dir?: string; days: string; dataDir?: string; yes?: boolean }) => {
|
|
209
|
+
const shareDir = opts.dir ?? process.env.HARNERY_SESSION_SHARE_DIR ?? defaultShareDir();
|
|
210
|
+
if (!shareDir) {
|
|
211
|
+
emit.error({
|
|
212
|
+
code: "no_share_dir",
|
|
213
|
+
message: "no shared folder: pass --dir <path> or set HARNERY_SESSION_SHARE_DIR",
|
|
214
|
+
});
|
|
215
|
+
process.exit(2);
|
|
216
|
+
}
|
|
217
|
+
const cli = readCliAccount();
|
|
218
|
+
if (!cli) {
|
|
219
|
+
emit.error({
|
|
220
|
+
code: "no_account",
|
|
221
|
+
message: "cannot read the signed-in account from ~/.claude.json",
|
|
222
|
+
});
|
|
223
|
+
process.exit(2);
|
|
224
|
+
}
|
|
225
|
+
const [dataDir] = requireDataDirs(emit, opts.dataDir);
|
|
226
|
+
const shareOpts = {
|
|
227
|
+
shareDir,
|
|
228
|
+
machine: resolveMachineLabel(),
|
|
229
|
+
days: Number(opts.days) || 14,
|
|
230
|
+
dataDir: dataDir as string,
|
|
231
|
+
targetAccountUuid: cli.accountUuid,
|
|
232
|
+
};
|
|
233
|
+
const plan = planShare(shareOpts);
|
|
234
|
+
const summary = { share_dir: shareDir, machine: shareOpts.machine, ...shareSummary(plan) };
|
|
235
|
+
if (!opts.yes) {
|
|
236
|
+
emit.data({ dry_run: true, ...summary, hint: "re-run with --yes to apply" });
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
const result = applyShare(plan, shareOpts);
|
|
240
|
+
emit.data({
|
|
241
|
+
dry_run: false,
|
|
242
|
+
...summary,
|
|
243
|
+
...result,
|
|
244
|
+
hint:
|
|
245
|
+
result.imported > 0
|
|
246
|
+
? "quit the Claude desktop app fully (Cmd+Q) and reopen it to see the new sessions"
|
|
247
|
+
: "sidebar already current",
|
|
248
|
+
});
|
|
249
|
+
});
|
|
189
250
|
}
|
|
190
251
|
|
|
191
252
|
function collect(value: string, previous: string[]): string[] {
|
package/src/commands/deinit.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* `init` makes two kinds of change outside the harnery package:
|
|
5
5
|
* 1. Merges `agent-hook` entries into the adapter settings file
|
|
6
6
|
* (Claude Code `.claude/settings.json`, Cursor `.cursor/hooks.json`, or
|
|
7
|
-
* Codex `.codex/hooks.json`).
|
|
7
|
+
* Codex `.codex/hooks.json`), or installs the OpenCode plugin directory.
|
|
8
8
|
* 2. Creates the `.harnery/` coord root (runtime state: events, councils,
|
|
9
9
|
* identities, journal) and stamps the host bin name into
|
|
10
10
|
* `.harnery/config.jsonc`.
|
|
@@ -34,6 +34,7 @@ import type { Command } from "commander";
|
|
|
34
34
|
import type { EmitContext } from "../commander.ts";
|
|
35
35
|
import { DEFAULT_BIN_NAME } from "../core/config.ts";
|
|
36
36
|
import { ADAPTER_SPECS, type AdapterId } from "../core/hooks/adapter/events.ts";
|
|
37
|
+
import { removeOpenCodePlugin } from "../core/hooks/adapter/opencode-plugin.ts";
|
|
37
38
|
import type { SettingsFile } from "../core/hooks/adapter/wiring.ts";
|
|
38
39
|
import { removeIndexerExclusions } from "../lib/indexer-exclusions.ts";
|
|
39
40
|
import { removeInstructions } from "../lib/instructions/apply.ts";
|
|
@@ -62,7 +63,7 @@ export function registerDeinitCommand(program: Command, emit: EmitContext, binNa
|
|
|
62
63
|
".harnery/ coord root (on a terminal it asks first). Idempotent; use " +
|
|
63
64
|
"--dry-run to preview.",
|
|
64
65
|
)
|
|
65
|
-
.option("--adapter <id>", "claude-code | cursor | codex", "claude-code")
|
|
66
|
+
.option("--adapter <id>", "claude-code | cursor | codex | opencode", "claude-code")
|
|
66
67
|
.option("--dry-run", "Show what would change without writing")
|
|
67
68
|
.option("--project-root <path>", "Project root (default: git toplevel, else cwd)")
|
|
68
69
|
.option("--purge-state", "Also delete the .harnery/ coord root (runtime state, destructive)")
|
|
@@ -70,7 +71,9 @@ export function registerDeinitCommand(program: Command, emit: EmitContext, binNa
|
|
|
70
71
|
const adapter = opts.adapter as AdapterId;
|
|
71
72
|
const spec = ADAPTER_SPECS[adapter];
|
|
72
73
|
if (!spec) {
|
|
73
|
-
emit.text(
|
|
74
|
+
emit.text(
|
|
75
|
+
`Unknown adapter '${opts.adapter}'. Expected: claude-code | cursor | codex | opencode.`,
|
|
76
|
+
);
|
|
74
77
|
emit.setExitCode(1);
|
|
75
78
|
return;
|
|
76
79
|
}
|
|
@@ -97,7 +100,9 @@ export function registerDeinitCommand(program: Command, emit: EmitContext, binNa
|
|
|
97
100
|
|
|
98
101
|
// ── 1. unwire adapter hooks ────────────────────────────────────────────
|
|
99
102
|
const settingsPath = resolve(projectRoot, spec.settingsFile);
|
|
100
|
-
if (
|
|
103
|
+
if (spec.installMode === "opencode-plugin") {
|
|
104
|
+
actions.push(...removeOpenCodePlugin(projectRoot, dryRun));
|
|
105
|
+
} else if (!existsSync(settingsPath)) {
|
|
101
106
|
actions.push(`· ${rel(projectRoot, settingsPath)} doesn't exist; no hooks to remove`);
|
|
102
107
|
} else {
|
|
103
108
|
let settings: SettingsFile;
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { type Command, InvalidArgumentError } from "commander";
|
|
2
|
+
import type { EmitContext } from "../commander.ts";
|
|
3
|
+
import {
|
|
4
|
+
type DiskGroup,
|
|
5
|
+
type DiskOptions,
|
|
6
|
+
type DiskReport,
|
|
7
|
+
diskUsage,
|
|
8
|
+
parseDiskSize,
|
|
9
|
+
} from "../lib/disk-usage.ts";
|
|
10
|
+
|
|
11
|
+
function positive(value: string): number {
|
|
12
|
+
if (!/^\d+$/.test(value) || !Number.isSafeInteger(Number(value)) || Number(value) < 1)
|
|
13
|
+
throw new InvalidArgumentError("requires a positive integer");
|
|
14
|
+
return Number(value);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function registerDiskCommand(program: Command, emit: EmitContext): void {
|
|
18
|
+
program
|
|
19
|
+
.command("disk [path]")
|
|
20
|
+
.description("Measure checkout disk usage, including nested repositories and ignored files")
|
|
21
|
+
.option(
|
|
22
|
+
"--git <states>",
|
|
23
|
+
"Filter: tracked, untracked, ignored, git-metadata, non-repository, unknown (comma-separated)",
|
|
24
|
+
)
|
|
25
|
+
.option(
|
|
26
|
+
"--type <types>",
|
|
27
|
+
"File extensions or video, audio, image, media, archive (comma-separated)",
|
|
28
|
+
)
|
|
29
|
+
.option(
|
|
30
|
+
"--exclude <paths>",
|
|
31
|
+
"Skip directory names at any depth or root-relative paths; repeatable, comma-separated",
|
|
32
|
+
(value: string, previous: string[]) => [...previous, value],
|
|
33
|
+
[],
|
|
34
|
+
)
|
|
35
|
+
.option("--group <by>", "Group by directory, repository, extension, git, or files", "directory")
|
|
36
|
+
.option("--depth <n>", "Directory grouping depth; does not limit the scan", positive, 1)
|
|
37
|
+
.option("--top <n>", "Maximum groups and largest files to display", positive, 20)
|
|
38
|
+
.option(
|
|
39
|
+
"--min-size <size>",
|
|
40
|
+
"Include individual files at least this size (e.g. 10MB, 1GiB)",
|
|
41
|
+
parseDiskSize,
|
|
42
|
+
)
|
|
43
|
+
.option("--apparent", "Rank and filter by file lengths instead of allocated blocks")
|
|
44
|
+
.option("--json", "Emit the versioned disk usage report")
|
|
45
|
+
.action(
|
|
46
|
+
(path: string | undefined, options: DiskOptions & { group: DiskGroup; json?: boolean }) => {
|
|
47
|
+
try {
|
|
48
|
+
const { json, ...filters } = options;
|
|
49
|
+
const report = diskUsage(path, filters);
|
|
50
|
+
if (json) {
|
|
51
|
+
emit.config({ format: "json" });
|
|
52
|
+
emit.data(report);
|
|
53
|
+
} else emit.text(renderDiskUsage(report));
|
|
54
|
+
if (!report.complete) emit.setExitCode(1);
|
|
55
|
+
} catch (error) {
|
|
56
|
+
emit.error({
|
|
57
|
+
code: "disk_usage_failed",
|
|
58
|
+
message: error instanceof Error ? error.message : String(error),
|
|
59
|
+
});
|
|
60
|
+
emit.setExitCode(1);
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function renderDiskUsage(report: DiskReport): string {
|
|
67
|
+
const bytes = (value: number): string =>
|
|
68
|
+
value >= 1e9
|
|
69
|
+
? `${(value / 1e9).toFixed(2)} GB`
|
|
70
|
+
: value >= 1e6
|
|
71
|
+
? `${(value / 1e6).toFixed(2)} MB`
|
|
72
|
+
: value >= 1e3
|
|
73
|
+
? `${(value / 1e3).toFixed(2)} KB`
|
|
74
|
+
: `${value} B`;
|
|
75
|
+
const size = (row: { allocated_bytes: number | null; apparent_bytes: number }): string =>
|
|
76
|
+
bytes(
|
|
77
|
+
report.measurement === "allocated"
|
|
78
|
+
? (row.allocated_bytes ?? row.apparent_bytes)
|
|
79
|
+
: row.apparent_bytes,
|
|
80
|
+
);
|
|
81
|
+
const lines = [
|
|
82
|
+
`Disk usage: ${report.root}`,
|
|
83
|
+
`${size(report.totals)} in ${report.totals.files.toLocaleString()} regular files (${report.measurement})`,
|
|
84
|
+
`File lengths: ${bytes(report.totals.apparent_bytes)}. Directory metadata and symlinks are excluded.`,
|
|
85
|
+
"",
|
|
86
|
+
"Git state:",
|
|
87
|
+
];
|
|
88
|
+
for (const [state, totals] of Object.entries(report.git))
|
|
89
|
+
if (totals.files)
|
|
90
|
+
lines.push(
|
|
91
|
+
`${size(totals).padStart(12)} ${String(totals.files).padStart(8)} files ${state}`,
|
|
92
|
+
);
|
|
93
|
+
lines.push(
|
|
94
|
+
"",
|
|
95
|
+
`Largest ${report.filters.group} groups (${report.groups.length} of ${report.group_count}):`,
|
|
96
|
+
);
|
|
97
|
+
for (const row of report.groups)
|
|
98
|
+
lines.push(`${size(row).padStart(12)} ${String(row.files).padStart(8)} files ${row.path}`);
|
|
99
|
+
if (report.filters.group !== "files") {
|
|
100
|
+
lines.push("", "Largest files:");
|
|
101
|
+
for (const row of report.largest_files)
|
|
102
|
+
lines.push(`${size(row).padStart(12)} ${row.git.padEnd(14)} ${row.path}`);
|
|
103
|
+
}
|
|
104
|
+
if (report.skipped.symlinks || report.skipped.special_files || report.skipped.excluded)
|
|
105
|
+
lines.push(
|
|
106
|
+
"",
|
|
107
|
+
`Skipped: ${report.skipped.symlinks} symlinks, ${report.skipped.special_files} special files, ${report.skipped.excluded} excluded entries.`,
|
|
108
|
+
);
|
|
109
|
+
if (report.issues.length) {
|
|
110
|
+
lines.push("", "Incomplete scan:");
|
|
111
|
+
for (const issue of report.issues) lines.push(`${issue.path}: ${issue.message}`);
|
|
112
|
+
}
|
|
113
|
+
return `${lines.join("\n")}\n`;
|
|
114
|
+
}
|
package/src/commands/docs.ts
CHANGED
|
@@ -6,6 +6,7 @@ import { initDocsContext as initDocsLinks, runLinks } from "../lib/docs-links.ts
|
|
|
6
6
|
import { initDocsContext as initDocsLint, runLint } from "../lib/docs-lint.ts";
|
|
7
7
|
import { readDocsMetadata, readDocsMetadataKey } from "../lib/docs-meta.ts";
|
|
8
8
|
import { initDocsMetadataAuditContext, runDocsMetadataAudit } from "../lib/docs-metadata-audit.ts";
|
|
9
|
+
import { initDocsMetadataExclusions } from "../lib/docs-metadata-managed.ts";
|
|
9
10
|
import { initDocsMetadataSyncContext, runDocsMetadataSync } from "../lib/docs-metadata-sync.ts";
|
|
10
11
|
import { createDocsFile } from "../lib/docs-new.ts";
|
|
11
12
|
import {
|
|
@@ -27,6 +28,7 @@ function ensureContext(context: HarneryProgramContext | undefined): void {
|
|
|
27
28
|
docsRootAllowlist: context.docsRootAllowlist,
|
|
28
29
|
});
|
|
29
30
|
initDocsLinks({ ...opts, extraExcludedPrefixes: context.extraDocsExcludedPrefixes });
|
|
31
|
+
initDocsMetadataExclusions(context.extraDocsExcludedPrefixes);
|
|
30
32
|
initDocsMetadataAuditContext(opts);
|
|
31
33
|
initDocsMetadataSyncContext(opts);
|
|
32
34
|
initDocsSweep(opts);
|
package/src/commands/doctor.ts
CHANGED
|
@@ -18,7 +18,7 @@ import path from "node:path";
|
|
|
18
18
|
import type { Command } from "commander";
|
|
19
19
|
import type { EmitContext } from "../commander.ts";
|
|
20
20
|
import { BUILTIN_ADAPTER_IDS } from "../core/adapters/index.ts";
|
|
21
|
-
import { resolveBinName, ripgrepAutoInstall } from "../core/config.ts";
|
|
21
|
+
import { codexWindowsBridgeConfig, resolveBinName, ripgrepAutoInstall } from "../core/config.ts";
|
|
22
22
|
import {
|
|
23
23
|
countSummarizedSinceV3,
|
|
24
24
|
listDiagnosticSummariesV3,
|
|
@@ -33,6 +33,7 @@ import {
|
|
|
33
33
|
type CodexWslBridgeStatus,
|
|
34
34
|
inspectCodexWslBridge,
|
|
35
35
|
} from "../core/hooks/codex-wsl-bridge.ts";
|
|
36
|
+
import { findUnfinishedHookRuns } from "../core/hooks/run-markers.ts";
|
|
36
37
|
import {
|
|
37
38
|
ADAPTER_BINARIES,
|
|
38
39
|
ADAPTER_INSTALL_HINTS,
|
|
@@ -115,6 +116,8 @@ export async function runChecks(): Promise<Check[]> {
|
|
|
115
116
|
const codexWslStatus = inspectCodexWslBridge();
|
|
116
117
|
const recentCodexMidFlightCount = root ? countRecentCodexMidFlightOnboardings(root) : 0;
|
|
117
118
|
const codexWslBridge = codexWslBridgeCheck(codexWslStatus, recentCodexMidFlightCount);
|
|
119
|
+
const codexHookRuns = codexHookRunsCheck(root);
|
|
120
|
+
const codexWindowsRoute = codexWindowsBridgeCheck(root);
|
|
118
121
|
// Probe the adapter CLIs before the hook check runs, not in output order:
|
|
119
122
|
// an unwired adapter only matters if its CLI is actually installed, and
|
|
120
123
|
// probing once here keeps that join to one spawn per CLI.
|
|
@@ -131,6 +134,8 @@ export async function runChecks(): Promise<Check[]> {
|
|
|
131
134
|
...(codexAuthorization ? [codexAuthorization] : []),
|
|
132
135
|
checkGitHookRegions(),
|
|
133
136
|
...(codexWslBridge ? [codexWslBridge] : []),
|
|
137
|
+
...(codexWindowsRoute ? [codexWindowsRoute] : []),
|
|
138
|
+
...(codexHookRuns ? [codexHookRuns] : []),
|
|
134
139
|
...workflow.map((w) => w.check),
|
|
135
140
|
checkRestic(),
|
|
136
141
|
checkRclone(),
|
|
@@ -189,6 +194,52 @@ export function codexWslBridgeCheck(
|
|
|
189
194
|
};
|
|
190
195
|
}
|
|
191
196
|
|
|
197
|
+
/**
|
|
198
|
+
* Hook runs that started but never finished (ADR 0197). Codex kills a hook at
|
|
199
|
+
* its timeout and the tool proceeds without that hook's checks; the start
|
|
200
|
+
* marker is the only trace such a run leaves.
|
|
201
|
+
*/
|
|
202
|
+
export function codexHookRunsCheck(
|
|
203
|
+
coordRoot: string | null,
|
|
204
|
+
nowMs = Date.now(),
|
|
205
|
+
isAlive?: (pid: number) => boolean,
|
|
206
|
+
): Check | null {
|
|
207
|
+
if (!coordRoot) return null;
|
|
208
|
+
const runs = findUnfinishedHookRuns(coordRoot, nowMs, undefined, isAlive);
|
|
209
|
+
if (runs.count === 0) return null;
|
|
210
|
+
const events = runs.events.map((e) => `${e.event} ×${e.count}`).join(", ");
|
|
211
|
+
return {
|
|
212
|
+
name: "codex:hook runs",
|
|
213
|
+
severity: "warn",
|
|
214
|
+
detail:
|
|
215
|
+
`${runs.count} hook run${runs.count === 1 ? "" : "s"} started but never finished in the last 24h ` +
|
|
216
|
+
`(${events}; latest ${runs.latest}); their tools proceeded without those hooks' checks`,
|
|
217
|
+
hint: "a hook that outlives its timeout is killed; look for a stalled WSL session or a slow hook",
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/** Report the per-project Windows bridge opt-in, or an invalid value init ignored. */
|
|
222
|
+
export function codexWindowsBridgeCheck(coordRoot: string | null): Check | null {
|
|
223
|
+
if (!coordRoot) return null;
|
|
224
|
+
const bridge = codexWindowsBridgeConfig(coordRoot);
|
|
225
|
+
if (bridge.error) {
|
|
226
|
+
return {
|
|
227
|
+
name: "codex:Windows hook route",
|
|
228
|
+
severity: "warn",
|
|
229
|
+
detail: `${bridge.error}; Codex hooks are wired without commandWindows`,
|
|
230
|
+
hint: "set hooks.codexWindowsBridge.entryPoint to a plain command name in .harnery/config.jsonc, then re-run init",
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
if (!bridge.entryPoint) return null;
|
|
234
|
+
return {
|
|
235
|
+
name: "codex:Windows hook route",
|
|
236
|
+
severity: "ok",
|
|
237
|
+
detail:
|
|
238
|
+
`opted in: Windows-native Codex hooks hand off to \`${bridge.entryPoint}\` from WSL paths ` +
|
|
239
|
+
`when it is on PATH, otherwise run the usual command; bridge health is reported by the bridge itself`,
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
|
|
192
243
|
const CODEX_MID_FLIGHT_HISTORY_WINDOW_MS = 48 * 60 * 60 * 1000;
|
|
193
244
|
|
|
194
245
|
/** Count bounded, privacy-safe recovery diagnostics so a healthy environment
|
|
@@ -557,13 +608,22 @@ function checkAdapterHooks(installedAdapters: AdapterId[] = []): Check {
|
|
|
557
608
|
if (d.invalidEventKeys.length > 0) {
|
|
558
609
|
bits.push(`unsupported events (${d.invalidEventKeys.join(", ")})`);
|
|
559
610
|
}
|
|
611
|
+
if (d.pluginIssues && d.pluginIssues.length > 0) {
|
|
612
|
+
// Plugin issues already name their file; render them as-is.
|
|
613
|
+
return d.pluginIssues.join("; ");
|
|
614
|
+
}
|
|
560
615
|
return `${d.settingsFile}: ${bits.join("; ")}`;
|
|
561
616
|
});
|
|
562
617
|
for (const id of unwired) {
|
|
563
|
-
|
|
618
|
+
const what = ADAPTER_SPECS[id].installMode === "opencode-plugin" ? "plugin" : "hooks";
|
|
619
|
+
parts.push(`${ADAPTER_SPECS[id].settingsFile}: ${id} CLI installed, no harnery ${what} wired`);
|
|
564
620
|
}
|
|
565
621
|
const needsManualRepair = drift.some(
|
|
566
|
-
(d) =>
|
|
622
|
+
(d) =>
|
|
623
|
+
d.parseError ||
|
|
624
|
+
d.invalidTopLevelKeys.length > 0 ||
|
|
625
|
+
d.invalidEventKeys.length > 0 ||
|
|
626
|
+
d.pluginIssues?.some((issue) => issue.includes("without harnery's ownership header")),
|
|
567
627
|
);
|
|
568
628
|
const wireHints = unwired.map((id) => `\`${bin} init --adapter ${id}\``);
|
|
569
629
|
let hint: string;
|
package/src/commands/fetch.ts
CHANGED
|
@@ -3,8 +3,10 @@ import { homedir } from "node:os";
|
|
|
3
3
|
import { resolve } from "node:path";
|
|
4
4
|
import type { Command } from "commander";
|
|
5
5
|
import type { EmitContext, HarneryProgramContext } from "../commander.ts";
|
|
6
|
+
import { resolveUserAgent } from "../lib/browser/user-agent.js";
|
|
6
7
|
import { CookieJar } from "../lib/cookies/index.ts";
|
|
7
8
|
import { fetchWithJar } from "../lib/http/index.ts";
|
|
9
|
+
import { commandPaceGate } from "../lib/pace/index.ts";
|
|
8
10
|
|
|
9
11
|
/**
|
|
10
12
|
* `harn fetch`: HTTP request with cookie-jar attach + persist.
|
|
@@ -23,6 +25,7 @@ interface FetchOpts {
|
|
|
23
25
|
output?: string;
|
|
24
26
|
store?: string;
|
|
25
27
|
cookies?: boolean;
|
|
28
|
+
pace?: boolean;
|
|
26
29
|
redirect: string;
|
|
27
30
|
timeout: string;
|
|
28
31
|
status?: boolean;
|
|
@@ -47,6 +50,11 @@ export function registerFetchCommand(
|
|
|
47
50
|
.option("-o, --output <file>", "Write response body to file (default: stdout)")
|
|
48
51
|
.option("--store <path>", `Cookie store path (default ${DEFAULT_STORE})`)
|
|
49
52
|
.option("--no-cookies", "Skip cookie-jar attach + persist")
|
|
53
|
+
.option(
|
|
54
|
+
"--no-pace",
|
|
55
|
+
"Skip the human-pace gap (3 to 9 s) between requests to the same site for this run. " +
|
|
56
|
+
"HARNERY_PACE=off disables it machine-wide; local and private hosts never wait.",
|
|
57
|
+
)
|
|
50
58
|
.option("--redirect <mode>", "Redirect handling: follow | error | manual", "follow")
|
|
51
59
|
.option("--timeout <ms>", "Request timeout in milliseconds", "30000")
|
|
52
60
|
.option("--status", "Print status to stderr")
|
|
@@ -70,6 +78,10 @@ async function runFetch(
|
|
|
70
78
|
context: HarneryProgramContext | undefined,
|
|
71
79
|
): Promise<void> {
|
|
72
80
|
const headers: Record<string, string> = {};
|
|
81
|
+
{
|
|
82
|
+
const ua = resolveUserAgent({ env: process.env.HARNERY_BROWSER_UA });
|
|
83
|
+
if (ua) headers["User-Agent"] = ua;
|
|
84
|
+
}
|
|
73
85
|
for (const h of opts.header ?? []) {
|
|
74
86
|
const idx = h.indexOf(":");
|
|
75
87
|
if (idx < 0) {
|
|
@@ -83,6 +95,8 @@ async function runFetch(
|
|
|
83
95
|
? new CookieJar({ path: opts.store ?? DEFAULT_STORE, source: "harn-fetch" })
|
|
84
96
|
: null;
|
|
85
97
|
|
|
98
|
+
await commandPaceGate(opts.pace !== false, (message) => emit.log(message, "info"))?.before(url);
|
|
99
|
+
|
|
86
100
|
const timeoutMs = Number.parseInt(opts.timeout, 10);
|
|
87
101
|
const ac = new AbortController();
|
|
88
102
|
const timer = setTimeout(() => ac.abort(), timeoutMs);
|
package/src/commands/files.ts
CHANGED
|
@@ -5,7 +5,21 @@ import type { EmitContext, HarneryProgramContext } from "../commander.ts";
|
|
|
5
5
|
import { resolveCoordRoot } from "../core/agents/coord-client.ts";
|
|
6
6
|
import { DEFAULT_WEB_PORT, resolveWebPort } from "../core/config.ts";
|
|
7
7
|
import { coordRootId, localCoordRootIdUrl } from "../lib/coord-root-id.ts";
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
encodedRepoPath,
|
|
10
|
+
encodeLinkSafeComponent,
|
|
11
|
+
FILES_ORIGIN_HOST,
|
|
12
|
+
localFilesOriginUrl,
|
|
13
|
+
localFileViewerUrl,
|
|
14
|
+
} from "../lib/local-file-url.ts";
|
|
15
|
+
import { isPathAllowed } from "../lib/tunnel/path-scope.ts";
|
|
16
|
+
import {
|
|
17
|
+
isTunnelStateLive,
|
|
18
|
+
listStates,
|
|
19
|
+
type ProcessAliveCheck,
|
|
20
|
+
type TunnelState,
|
|
21
|
+
tunnelTargetPort,
|
|
22
|
+
} from "../lib/tunnel/state.ts";
|
|
9
23
|
|
|
10
24
|
export { FILES_ORIGIN_HOST } from "../lib/local-file-url.ts";
|
|
11
25
|
|
|
@@ -162,6 +176,72 @@ export function mintLocalFileUrl(input: string, options: LocalFileUrlOptions): L
|
|
|
162
176
|
return { url, relPath, mode };
|
|
163
177
|
}
|
|
164
178
|
|
|
179
|
+
export class TunnelLinkError extends Error {
|
|
180
|
+
constructor(
|
|
181
|
+
message: string,
|
|
182
|
+
readonly hint: string,
|
|
183
|
+
) {
|
|
184
|
+
super(message);
|
|
185
|
+
this.name = "TunnelLinkError";
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
function vhostName(vhost: string): string {
|
|
190
|
+
return vhost.replace(/:\d+$/, "").toLowerCase();
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function newestFirst(states: TunnelState[]): TunnelState[] {
|
|
194
|
+
return [...states].sort((a, b) => b.started_at.localeCompare(a.started_at));
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Turn a minted local URL into the same file's URL on a live tunnel.
|
|
199
|
+
*
|
|
200
|
+
* HTML needs a tunnel in front of the isolated files origin (its vhost is
|
|
201
|
+
* FILES_ORIGIN_HOST), because only that origin renders the page and serves its
|
|
202
|
+
* relative assets; a dashboard tunnel can only show the viewer, which displays
|
|
203
|
+
* HTML as source. Other files need a dashboard tunnel that serves the viewer.
|
|
204
|
+
* In both cases the tunnel's path scope must forward the request, or its gate
|
|
205
|
+
* would refuse the link, so a tunnel that does not cover the file is skipped.
|
|
206
|
+
*/
|
|
207
|
+
export function tunnelFileUrl(
|
|
208
|
+
local: LocalFileUrl,
|
|
209
|
+
port: number,
|
|
210
|
+
states: TunnelState[],
|
|
211
|
+
processAlive?: ProcessAliveCheck,
|
|
212
|
+
): string {
|
|
213
|
+
const live = states.filter(
|
|
214
|
+
(state) => tunnelTargetPort(state) === port && isTunnelStateLive(state, processAlive),
|
|
215
|
+
);
|
|
216
|
+
if (local.mode === "raw") {
|
|
217
|
+
const path = `/${encodedRepoPath(local.relPath)}`;
|
|
218
|
+
const tunnel = newestFirst(live).find(
|
|
219
|
+
(state) =>
|
|
220
|
+
vhostName(state.vhost) === FILES_ORIGIN_HOST && isPathAllowed(path, state.allow_paths),
|
|
221
|
+
);
|
|
222
|
+
if (tunnel) return `${tunnel.url.replace(/\/+$/, "")}${path}`;
|
|
223
|
+
const folder = local.relPath.includes("/")
|
|
224
|
+
? `/${local.relPath.slice(0, local.relPath.lastIndexOf("/"))}`
|
|
225
|
+
: "/";
|
|
226
|
+
throw new TunnelLinkError(
|
|
227
|
+
`no live tunnel serves the files origin for /${local.relPath}`,
|
|
228
|
+
`Start one scoped to the page's folder, for example: tunnel up --name pages --target 127.0.0.1:${port} --vhost ${FILES_ORIGIN_HOST} --allow-path ${folder}`,
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
const tunnel = newestFirst(live).find(
|
|
232
|
+
(state) =>
|
|
233
|
+
vhostName(state.vhost) !== FILES_ORIGIN_HOST &&
|
|
234
|
+
["/files", "/api/file", "/_next"].every((path) => isPathAllowed(path, state.allow_paths)),
|
|
235
|
+
);
|
|
236
|
+
if (tunnel) {
|
|
237
|
+
return `${tunnel.url.replace(/\/+$/, "")}/files?path=${encodeLinkSafeComponent(local.relPath)}`;
|
|
238
|
+
}
|
|
239
|
+
throw new TunnelLinkError(
|
|
240
|
+
`no live tunnel serves the dashboard file viewer on port ${port}`,
|
|
241
|
+
`Start one, for example: tunnel up --name files --target 127.0.0.1:${port} --allow-path /files --allow-path /api/file --allow-path /_next`,
|
|
242
|
+
);
|
|
243
|
+
}
|
|
244
|
+
|
|
165
245
|
export function registerFilesCommand(
|
|
166
246
|
program: Command,
|
|
167
247
|
emit: EmitContext,
|
|
@@ -180,6 +260,10 @@ export function registerFilesCommand(
|
|
|
180
260
|
.option("--raw", "Use the isolated files origin, regardless of extension")
|
|
181
261
|
.option("--viewer", "Use the dashboard file viewer, regardless of extension")
|
|
182
262
|
.option("--no-verify", "Mint without checking the running dashboard's repository identity")
|
|
263
|
+
.option(
|
|
264
|
+
"--tunnel",
|
|
265
|
+
"Print the file's URL on a live tunnel instead of localhost (HTML uses a files-origin tunnel)",
|
|
266
|
+
)
|
|
183
267
|
.action(
|
|
184
268
|
async (
|
|
185
269
|
filePath: string,
|
|
@@ -189,6 +273,7 @@ export function registerFilesCommand(
|
|
|
189
273
|
raw?: boolean;
|
|
190
274
|
viewer?: boolean;
|
|
191
275
|
verify?: boolean;
|
|
276
|
+
tunnel?: boolean;
|
|
192
277
|
},
|
|
193
278
|
) => {
|
|
194
279
|
if (opts.raw && opts.viewer) {
|
|
@@ -224,8 +309,14 @@ export function registerFilesCommand(
|
|
|
224
309
|
mode: opts.raw ? "raw" : opts.viewer ? "viewer" : "auto",
|
|
225
310
|
});
|
|
226
311
|
if (opts.verify !== false) await verifyDashboardRoot(coordRoot, port);
|
|
227
|
-
|
|
312
|
+
const url = opts.tunnel ? tunnelFileUrl(result, port, listStates(coordRoot)) : result.url;
|
|
313
|
+
emit.text(`${url}\n`);
|
|
228
314
|
} catch (error) {
|
|
315
|
+
if (error instanceof TunnelLinkError) {
|
|
316
|
+
emit.error({ code: "no_tunnel_for_file", message: error.message, hint: error.hint });
|
|
317
|
+
emit.setExitCode(1);
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
229
320
|
if (error instanceof DashboardRootError) {
|
|
230
321
|
emit.error({ code: error.code, message: error.message, hint: error.hint });
|
|
231
322
|
emit.setExitCode(1);
|