harnery 0.40.0 → 0.42.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/commander.js +4 -0
- package/dist/commands/agents.d.ts.map +1 -1
- package/dist/commands/agents.js +34 -20
- package/dist/commands/artifacts.d.ts.map +1 -1
- package/dist/commands/artifacts.js +113 -12
- package/dist/commands/browse-ai.d.ts.map +1 -1
- package/dist/commands/browse-ai.js +4 -0
- package/dist/commands/browse.d.ts +164 -0
- package/dist/commands/browse.d.ts.map +1 -1
- package/dist/commands/browse.js +388 -45
- package/dist/commands/checkpoint.js +8 -12
- package/dist/commands/claude-desktop.d.ts.map +1 -1
- package/dist/commands/claude-desktop.js +52 -0
- package/dist/commands/deinit.d.ts +1 -1
- package/dist/commands/deinit.d.ts.map +1 -1
- package/dist/commands/deinit.js +8 -4
- package/dist/commands/disk.d.ts +6 -0
- package/dist/commands/disk.d.ts.map +1 -0
- package/dist/commands/disk.js +80 -0
- package/dist/commands/docs.d.ts.map +1 -1
- package/dist/commands/docs.js +2 -0
- package/dist/commands/doctor.d.ts +8 -0
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +58 -3
- package/dist/commands/fetch.d.ts.map +1 -1
- package/dist/commands/fetch.js +10 -0
- package/dist/commands/files.d.ts +16 -0
- package/dist/commands/files.d.ts.map +1 -1
- package/dist/commands/files.js +54 -2
- package/dist/commands/init.d.ts +21 -5
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +271 -109
- package/dist/commands/instructions.js +5 -4
- package/dist/commands/ledger-v3.d.ts.map +1 -1
- package/dist/commands/ledger-v3.js +2 -1
- package/dist/commands/rm.d.ts +4 -0
- package/dist/commands/rm.d.ts.map +1 -0
- package/dist/commands/rm.js +87 -0
- package/dist/commands/servers.d.ts +7 -0
- package/dist/commands/servers.d.ts.map +1 -0
- package/dist/commands/servers.js +394 -0
- package/dist/commands/tunnel.d.ts.map +1 -1
- package/dist/commands/tunnel.js +82 -2
- package/dist/commands/webview.d.ts +4 -0
- package/dist/commands/webview.d.ts.map +1 -0
- package/dist/commands/webview.js +94 -0
- package/dist/core/adapter.d.ts +50 -1
- package/dist/core/adapter.d.ts.map +1 -1
- package/dist/core/adapter.js +59 -1
- package/dist/core/adapters/attestation.d.ts.map +1 -1
- package/dist/core/adapters/attestation.js +3 -2
- package/dist/core/adapters/profiles.d.ts +29 -3
- package/dist/core/adapters/profiles.d.ts.map +1 -1
- package/dist/core/adapters/profiles.js +53 -1
- package/dist/core/adapters/registry.d.ts.map +1 -1
- package/dist/core/adapters/registry.js +33 -0
- package/dist/core/adapters/types.d.ts +9 -0
- package/dist/core/adapters/types.d.ts.map +1 -1
- package/dist/core/agents/canonical-emit.d.ts +1 -1
- package/dist/core/agents/canonical-emit.d.ts.map +1 -1
- package/dist/core/agents/canonical-emit.js +2 -7
- package/dist/core/agents/cli.js +25 -16
- package/dist/core/agents/coord-client.d.ts.map +1 -1
- package/dist/core/agents/coord-client.js +7 -2
- package/dist/core/agents/render/session-context.d.ts.map +1 -1
- package/dist/core/agents/render/session-context.js +2 -0
- package/dist/core/agents/rules/claim-conflict.d.ts.map +1 -1
- package/dist/core/agents/rules/claim-conflict.js +3 -9
- package/dist/core/agents/rules/commit-conflict.d.ts.map +1 -1
- package/dist/core/agents/rules/commit-conflict.js +2 -8
- package/dist/core/agents/rules/stop-hook.d.ts +2 -0
- package/dist/core/agents/rules/stop-hook.d.ts.map +1 -1
- package/dist/core/agents/rules/stop-hook.js +1 -1
- package/dist/core/agents/session-events.d.ts +6 -2
- package/dist/core/agents/session-events.d.ts.map +1 -1
- package/dist/core/agents/session-events.js +105 -26
- package/dist/core/agents/session-finalization-state-v3.d.ts.map +1 -1
- package/dist/core/agents/session-finalization-state-v3.js +2 -1
- package/dist/core/agents/session-finalizer-v3.d.ts.map +1 -1
- package/dist/core/agents/session-finalizer-v3.js +5 -4
- package/dist/core/agents/session-name-display.d.ts +28 -0
- package/dist/core/agents/session-name-display.d.ts.map +1 -1
- package/dist/core/agents/session-name-display.js +43 -0
- package/dist/core/agents/state/heartbeat-reader.d.ts +7 -0
- package/dist/core/agents/state/heartbeat-reader.d.ts.map +1 -1
- package/dist/core/agents/state/heartbeat-writer.d.ts +10 -0
- package/dist/core/agents/state/heartbeat-writer.d.ts.map +1 -1
- package/dist/core/agents/state/heartbeat-writer.js +21 -2
- package/dist/core/agents/state/live-coordination-view.d.ts +20 -0
- package/dist/core/agents/state/live-coordination-view.d.ts.map +1 -1
- package/dist/core/agents/state/live-coordination-view.js +61 -0
- package/dist/core/agents/state/live-coordination-writer.js +3 -0
- package/dist/core/agents/state/stale-sweep.d.ts.map +1 -1
- package/dist/core/agents/state/stale-sweep.js +2 -10
- package/dist/core/agents/turn-changes.d.ts +17 -0
- package/dist/core/agents/turn-changes.d.ts.map +1 -0
- package/dist/core/agents/turn-changes.js +76 -0
- package/dist/core/artifacts/delivery-card.d.ts.map +1 -1
- package/dist/core/artifacts/delivery-card.js +11 -3
- package/dist/core/artifacts/index.d.ts +140 -4
- package/dist/core/artifacts/index.d.ts.map +1 -1
- package/dist/core/artifacts/index.js +526 -52
- package/dist/core/config.d.ts +73 -11
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +142 -3
- package/dist/core/context/index.d.ts.map +1 -1
- package/dist/core/context/index.js +2 -1
- package/dist/core/conversations/archive.d.ts.map +1 -1
- package/dist/core/conversations/archive.js +4 -3
- package/dist/core/diagnostics/bundle.d.ts.map +1 -1
- package/dist/core/diagnostics/bundle.js +5 -4
- package/dist/core/events/legacy-storage/canary.d.ts.map +1 -1
- package/dist/core/events/legacy-storage/canary.js +5 -4
- package/dist/core/events/legacy-storage/compression.d.ts.map +1 -1
- package/dist/core/events/legacy-storage/compression.js +2 -1
- package/dist/core/events/v3/adapter-id.d.ts +10 -2
- package/dist/core/events/v3/adapter-id.d.ts.map +1 -1
- package/dist/core/events/v3/adapter-id.js +16 -0
- package/dist/core/events/v3/authority-outbox.d.ts.map +1 -1
- package/dist/core/events/v3/authority-outbox.js +2 -1
- package/dist/core/events/v3/bootstrap.d.ts.map +1 -1
- package/dist/core/events/v3/bootstrap.js +5 -4
- package/dist/core/events/v3/capabilities.d.ts.map +1 -1
- package/dist/core/events/v3/capabilities.js +17 -0
- package/dist/core/events/v3/contract.d.ts +5 -0
- package/dist/core/events/v3/contract.d.ts.map +1 -1
- package/dist/core/events/v3/contract.js +7 -1
- package/dist/core/events/v3/control-witness.d.ts.map +1 -1
- package/dist/core/events/v3/control-witness.js +3 -2
- package/dist/core/events/v3/coordination-transaction-recovery.d.ts.map +1 -1
- package/dist/core/events/v3/coordination-transaction-recovery.js +4 -3
- package/dist/core/events/v3/fingerprint-keys.d.ts.map +1 -1
- package/dist/core/events/v3/fingerprint-keys.js +7 -6
- package/dist/core/events/v3/generated.d.ts +1 -1
- package/dist/core/events/v3/generated.js +1 -1
- package/dist/core/events/v3/live-feed.d.ts.map +1 -1
- package/dist/core/events/v3/live-feed.js +5 -4
- package/dist/core/events/v3/producers/command-recorder.d.ts.map +1 -1
- package/dist/core/events/v3/producers/command-recorder.js +8 -7
- package/dist/core/events/v3/producers/coordination-recorder.d.ts.map +1 -1
- package/dist/core/events/v3/producers/coordination-recorder.js +8 -7
- package/dist/core/events/v3/producers/diagnostic-summaries.d.ts.map +1 -1
- package/dist/core/events/v3/producers/diagnostic-summaries.js +5 -4
- package/dist/core/events/v3/producers/hook-base.d.ts +1 -0
- package/dist/core/events/v3/producers/hook-base.d.ts.map +1 -1
- package/dist/core/events/v3/producers/hook-base.js +10 -4
- package/dist/core/events/v3/producers/hook.d.ts +2 -0
- package/dist/core/events/v3/producers/hook.d.ts.map +1 -1
- package/dist/core/events/v3/producers/hook.js +16 -1
- package/dist/core/events/v3/producers/intake.d.ts.map +1 -1
- package/dist/core/events/v3/producers/intake.js +16 -6
- package/dist/core/events/v3/producers/recorder.d.ts +2 -4
- package/dist/core/events/v3/producers/recorder.d.ts.map +1 -1
- package/dist/core/events/v3/producers/recorder.js +125 -101
- package/dist/core/events/v3/projection.js +9 -1
- package/dist/core/events/v3/recovery.d.ts.map +1 -1
- package/dist/core/events/v3/recovery.js +4 -3
- package/dist/core/events/v3/support-storage/inventory.d.ts.map +1 -1
- package/dist/core/events/v3/support-storage/inventory.js +2 -1
- package/dist/core/events/v3/support-storage/maintenance.d.ts.map +1 -1
- package/dist/core/events/v3/support-storage/maintenance.js +4 -3
- package/dist/core/events/v3/support-storage/pack-reader.d.ts.map +1 -1
- package/dist/core/events/v3/support-storage/pack-reader.js +4 -3
- package/dist/core/events/v3/support-storage/pack-writer.d.ts.map +1 -1
- package/dist/core/events/v3/support-storage/pack-writer.js +6 -5
- package/dist/core/events/v3/tool-line-changes.d.ts +8 -0
- package/dist/core/events/v3/tool-line-changes.d.ts.map +1 -0
- package/dist/core/events/v3/tool-line-changes.js +135 -0
- package/dist/core/events/v3/writer.d.ts.map +1 -1
- package/dist/core/events/v3/writer.js +8 -7
- package/dist/core/governor/planning.d.ts.map +1 -1
- package/dist/core/governor/planning.js +6 -5
- package/dist/core/governor/service.d.ts.map +1 -1
- package/dist/core/governor/service.js +12 -11
- package/dist/core/governor/state.d.ts.map +1 -1
- package/dist/core/governor/state.js +7 -6
- package/dist/core/guard/evaluator.js +1 -0
- package/dist/core/guard/storage.d.ts.map +1 -1
- package/dist/core/guard/storage.js +3 -2
- package/dist/core/hooks/adapter/behaviors/claude-code.d.ts +4 -0
- package/dist/core/hooks/adapter/behaviors/claude-code.d.ts.map +1 -0
- package/dist/core/hooks/adapter/behaviors/claude-code.js +31 -0
- package/dist/core/hooks/adapter/behaviors/codex.d.ts +15 -0
- package/dist/core/hooks/adapter/behaviors/codex.d.ts.map +1 -0
- package/dist/core/hooks/adapter/behaviors/codex.js +82 -0
- package/dist/core/hooks/adapter/behaviors/cursor.d.ts +7 -0
- package/dist/core/hooks/adapter/behaviors/cursor.d.ts.map +1 -0
- package/dist/core/hooks/adapter/behaviors/cursor.js +35 -0
- package/dist/core/hooks/adapter/behaviors/index.d.ts +11 -0
- package/dist/core/hooks/adapter/behaviors/index.d.ts.map +1 -0
- package/dist/core/hooks/adapter/behaviors/index.js +20 -0
- package/dist/core/hooks/adapter/behaviors/openclaw.d.ts +7 -0
- package/dist/core/hooks/adapter/behaviors/openclaw.d.ts.map +1 -0
- package/dist/core/hooks/adapter/behaviors/openclaw.js +34 -0
- package/dist/core/hooks/adapter/behaviors/opencode.d.ts +7 -0
- package/dist/core/hooks/adapter/behaviors/opencode.d.ts.map +1 -0
- package/dist/core/hooks/adapter/behaviors/opencode.js +34 -0
- package/dist/core/hooks/adapter/behaviors/types.d.ts +89 -0
- package/dist/core/hooks/adapter/behaviors/types.d.ts.map +1 -0
- package/dist/core/hooks/adapter/behaviors/types.js +1 -0
- package/dist/core/hooks/adapter/detect.d.ts +1 -1
- package/dist/core/hooks/adapter/detect.d.ts.map +1 -1
- package/dist/core/hooks/adapter/detect.js +2 -3
- package/dist/core/hooks/adapter/events.d.ts +46 -1
- package/dist/core/hooks/adapter/events.d.ts.map +1 -1
- package/dist/core/hooks/adapter/events.js +36 -0
- package/dist/core/hooks/adapter/opencode-plugin.d.ts +60 -0
- package/dist/core/hooks/adapter/opencode-plugin.d.ts.map +1 -0
- package/dist/core/hooks/adapter/opencode-plugin.js +129 -0
- package/dist/core/hooks/adapter/output.d.ts +7 -0
- package/dist/core/hooks/adapter/output.d.ts.map +1 -1
- package/dist/core/hooks/adapter/output.js +8 -1
- package/dist/core/hooks/adapter/runtime-telemetry.js +3 -1
- package/dist/core/hooks/adapter/wiring.d.ts +52 -8
- package/dist/core/hooks/adapter/wiring.d.ts.map +1 -1
- package/dist/core/hooks/adapter/wiring.js +133 -12
- package/dist/core/hooks/cli.js +676 -531
- package/dist/core/hooks/effects/image-capture.d.ts.map +1 -1
- package/dist/core/hooks/effects/image-capture.js +2 -1
- package/dist/core/hooks/prompt-context/contract.d.ts.map +1 -1
- package/dist/core/hooks/prompt-context/contract.js +1 -0
- package/dist/core/hooks/resolve/transcript.d.ts +1 -1
- package/dist/core/hooks/resolve/transcript.d.ts.map +1 -1
- package/dist/core/hooks/resolve/transcript.js +35 -4
- package/dist/core/hooks/run-markers.d.ts +37 -0
- package/dist/core/hooks/run-markers.d.ts.map +1 -0
- package/dist/core/hooks/run-markers.js +109 -0
- package/dist/core/hooks/session-name-presence.d.ts +3 -1
- package/dist/core/hooks/session-name-presence.d.ts.map +1 -1
- package/dist/core/hooks/session-name-presence.js +7 -2
- package/dist/core/hooks/shell-waiter.d.ts +2 -0
- package/dist/core/hooks/shell-waiter.d.ts.map +1 -0
- package/dist/core/hooks/shell-waiter.js +173 -0
- package/dist/core/resources/service.d.ts.map +1 -1
- package/dist/core/resources/service.js +5 -4
- package/dist/core/semantic/review.d.ts.map +1 -1
- package/dist/core/semantic/review.js +5 -4
- package/dist/core/semantic/service.d.ts.map +1 -1
- package/dist/core/semantic/service.js +15 -14
- package/dist/core/semantic/storage.d.ts.map +1 -1
- package/dist/core/semantic/storage.js +5 -4
- package/dist/core/servers/index.d.ts +211 -0
- package/dist/core/servers/index.d.ts.map +1 -0
- package/dist/core/servers/index.js +560 -0
- package/dist/core/servers/net.d.ts +58 -0
- package/dist/core/servers/net.d.ts.map +1 -0
- package/dist/core/servers/net.js +270 -0
- package/dist/core/servers/tunnels.d.ts +14 -0
- package/dist/core/servers/tunnels.d.ts.map +1 -0
- package/dist/core/servers/tunnels.js +33 -0
- package/dist/core/storage/atomic-json.d.ts.map +1 -1
- package/dist/core/storage/atomic-json.js +7 -3
- package/dist/core/storage/builtins.js +1 -0
- package/dist/core/storage/durable-history.d.ts.map +1 -1
- package/dist/core/storage/durable-history.js +6 -5
- package/dist/core/storage/maintenance-providers.d.ts.map +1 -1
- package/dist/core/storage/maintenance-providers.js +2 -1
- package/dist/core/storage/maintenance.d.ts.map +1 -1
- package/dist/core/storage/maintenance.js +7 -6
- package/dist/core/storage/metrics.d.ts.map +1 -1
- package/dist/core/storage/metrics.js +5 -1
- package/dist/core/storage/modes.d.ts +17 -0
- package/dist/core/storage/modes.d.ts.map +1 -0
- package/dist/core/storage/modes.js +47 -0
- package/dist/core/storage/process-log.d.ts.map +1 -1
- package/dist/core/storage/process-log.js +3 -2
- package/dist/core/storage/receipts.d.ts.map +1 -1
- package/dist/core/storage/receipts.js +4 -3
- package/dist/core/storage/segments.d.ts.map +1 -1
- package/dist/core/storage/segments.js +7 -6
- package/dist/core/supervisor/hook-health.d.ts +2 -1
- package/dist/core/supervisor/hook-health.d.ts.map +1 -1
- package/dist/core/supervisor/hook-health.js +4 -3
- package/dist/core/supervisor/service.d.ts.map +1 -1
- package/dist/core/supervisor/service.js +7 -6
- package/dist/core/work/state.d.ts.map +1 -1
- package/dist/core/work/state.js +8 -7
- package/dist/core/workflow/adapters.d.ts +7 -0
- package/dist/core/workflow/adapters.d.ts.map +1 -1
- package/dist/core/workflow/adapters.js +9 -0
- package/dist/core/workflow/approvals.d.ts.map +1 -1
- package/dist/core/workflow/approvals.js +6 -5
- package/dist/core/workflow/billing.d.ts.map +1 -1
- package/dist/core/workflow/billing.js +33 -4
- package/dist/core/workflow/durable-record.d.ts.map +1 -1
- package/dist/core/workflow/durable-record.js +4 -3
- package/dist/core/workflow/engine.d.ts.map +1 -1
- package/dist/core/workflow/engine.js +30 -1
- package/dist/core/workflow/live-session-v3.d.ts.map +1 -1
- package/dist/core/workflow/live-session-v3.js +2 -3
- package/dist/core/workflow/run-state.d.ts.map +1 -1
- package/dist/core/workflow/run-state.js +3 -2
- package/dist/core/workflow/sandbox-projection.d.ts +13 -2
- package/dist/core/workflow/sandbox-projection.d.ts.map +1 -1
- package/dist/core/workflow/sandbox-projection.js +23 -0
- package/dist/core/workflow/spawn-claude.d.ts.map +1 -1
- package/dist/core/workflow/spawn-claude.js +6 -1
- package/dist/core/workflow/spawn-codex.d.ts +2 -0
- package/dist/core/workflow/spawn-codex.d.ts.map +1 -1
- package/dist/core/workflow/spawn-codex.js +20 -1
- package/dist/core/workflow/spawn-cursor.d.ts.map +1 -1
- package/dist/core/workflow/spawn-cursor.js +6 -1
- package/dist/core/workflow/spawn-opencode.d.ts +36 -0
- package/dist/core/workflow/spawn-opencode.d.ts.map +1 -0
- package/dist/core/workflow/spawn-opencode.js +135 -0
- package/dist/core/workflow/transcript.d.ts.map +1 -1
- package/dist/core/workflow/transcript.js +3 -2
- package/dist/core/workflow/types.d.ts +47 -2
- package/dist/core/workflow/types.d.ts.map +1 -1
- package/dist/core/workflow/worker-access.d.ts +92 -0
- package/dist/core/workflow/worker-access.d.ts.map +1 -0
- package/dist/core/workflow/worker-access.js +450 -0
- package/dist/core/workflow/workspaces/leases.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/leases.js +5 -4
- package/dist/core/workflow/workspaces/local-git.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/local-git.js +3 -2
- package/dist/core/workflow/workspaces/paths.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/paths.js +2 -1
- package/dist/core/workflow/workspaces/state.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/state.js +10 -9
- package/dist/lazy-commands.js +8 -1
- package/dist/lib/agent-browser/client.d.ts +9 -0
- package/dist/lib/agent-browser/client.d.ts.map +1 -1
- package/dist/lib/agent-browser/client.js +13 -0
- package/dist/lib/browser/batch-steps.d.ts +18 -0
- package/dist/lib/browser/batch-steps.d.ts.map +1 -0
- package/dist/lib/browser/batch-steps.js +82 -0
- package/dist/lib/browser/client.d.ts +35 -1
- package/dist/lib/browser/client.d.ts.map +1 -1
- package/dist/lib/browser/client.js +117 -8
- package/dist/lib/browser/collect/collector.d.ts +99 -0
- package/dist/lib/browser/collect/collector.d.ts.map +1 -0
- package/dist/lib/browser/collect/collector.js +202 -0
- package/dist/lib/browser/collect/fields.d.ts +31 -0
- package/dist/lib/browser/collect/fields.d.ts.map +1 -0
- package/dist/lib/browser/collect/fields.js +75 -0
- package/dist/lib/browser/collect/index.d.ts +6 -0
- package/dist/lib/browser/collect/index.d.ts.map +1 -0
- package/dist/lib/browser/collect/index.js +5 -0
- package/dist/lib/browser/collect/page-driver.d.ts +14 -0
- package/dist/lib/browser/collect/page-driver.d.ts.map +1 -0
- package/dist/lib/browser/collect/page-driver.js +306 -0
- package/dist/lib/browser/collect/presets.d.ts +52 -0
- package/dist/lib/browser/collect/presets.d.ts.map +1 -0
- package/dist/lib/browser/collect/presets.js +176 -0
- package/dist/lib/browser/collect/scroll-plan.d.ts +85 -0
- package/dist/lib/browser/collect/scroll-plan.d.ts.map +1 -0
- package/dist/lib/browser/collect/scroll-plan.js +118 -0
- package/dist/lib/browser/identity.d.ts +25 -0
- package/dist/lib/browser/identity.d.ts.map +1 -0
- package/dist/lib/browser/identity.js +66 -0
- package/dist/lib/browser/index.d.ts +3 -2
- package/dist/lib/browser/index.d.ts.map +1 -1
- package/dist/lib/browser/index.js +2 -1
- package/dist/lib/browser/launch-args.d.ts +26 -0
- package/dist/lib/browser/launch-args.d.ts.map +1 -1
- package/dist/lib/browser/launch-args.js +41 -1
- package/dist/lib/browser/page-review-judge.d.ts +2 -0
- package/dist/lib/browser/page-review-judge.d.ts.map +1 -1
- package/dist/lib/browser/page-review-judge.js +13 -0
- package/dist/lib/browser/qa-run-contracts.d.ts +10 -0
- package/dist/lib/browser/qa-run-contracts.d.ts.map +1 -1
- package/dist/lib/browser/qa-run.d.ts.map +1 -1
- package/dist/lib/browser/qa-run.js +1 -0
- package/dist/lib/browser/user-agent.d.ts +53 -0
- package/dist/lib/browser/user-agent.d.ts.map +1 -0
- package/dist/lib/browser/user-agent.js +79 -0
- package/dist/lib/browser/windows-chrome.d.ts +59 -0
- package/dist/lib/browser/windows-chrome.d.ts.map +1 -0
- package/dist/lib/browser/windows-chrome.js +179 -0
- package/dist/lib/claude-desktop-share.d.ts +136 -0
- package/dist/lib/claude-desktop-share.d.ts.map +1 -0
- package/dist/lib/claude-desktop-share.js +394 -0
- package/dist/lib/disk-usage.d.ts +50 -0
- package/dist/lib/disk-usage.d.ts.map +1 -0
- package/dist/lib/disk-usage.js +303 -0
- package/dist/lib/docs-lint.d.ts +6 -0
- package/dist/lib/docs-lint.d.ts.map +1 -1
- package/dist/lib/docs-lint.js +8 -3
- package/dist/lib/docs-metadata-managed.d.ts +1 -0
- package/dist/lib/docs-metadata-managed.d.ts.map +1 -1
- package/dist/lib/docs-metadata-managed.js +17 -1
- package/dist/lib/guarded-remove.d.ts +34 -0
- package/dist/lib/guarded-remove.d.ts.map +1 -0
- package/dist/lib/guarded-remove.js +310 -0
- package/dist/lib/identities/assume.d.ts.map +1 -1
- package/dist/lib/identities/assume.js +4 -9
- package/dist/lib/instructions/apply.d.ts.map +1 -1
- package/dist/lib/instructions/apply.js +2 -0
- package/dist/lib/instructions/templates.js +8 -8
- package/dist/lib/pace/index.d.ts +2 -0
- package/dist/lib/pace/index.d.ts.map +1 -0
- package/dist/lib/pace/index.js +1 -0
- package/dist/lib/pace/pace.d.ts +95 -0
- package/dist/lib/pace/pace.d.ts.map +1 -0
- package/dist/lib/pace/pace.js +313 -0
- package/dist/lib/tunnel/error-page.d.ts +1 -1
- package/dist/lib/tunnel/error-page.d.ts.map +1 -1
- package/dist/lib/tunnel/error-page.js +19 -8
- package/dist/lib/tunnel/forward-headers.d.ts +11 -0
- package/dist/lib/tunnel/forward-headers.d.ts.map +1 -0
- package/dist/lib/tunnel/forward-headers.js +17 -0
- package/dist/lib/tunnel/gate.js +34 -10
- package/dist/lib/tunnel/path-scope.d.ts +22 -0
- package/dist/lib/tunnel/path-scope.d.ts.map +1 -0
- package/dist/lib/tunnel/path-scope.js +62 -0
- package/dist/lib/tunnel/state.d.ts +5 -0
- package/dist/lib/tunnel/state.d.ts.map +1 -1
- package/dist/lib/tunnel/state.js +17 -3
- package/dist/lib/webview/index.d.ts +2 -0
- package/dist/lib/webview/index.d.ts.map +1 -0
- package/dist/lib/webview/index.js +1 -0
- package/dist/lib/webview/webview.d.ts +116 -0
- package/dist/lib/webview/webview.d.ts.map +1 -0
- package/dist/lib/webview/webview.js +289 -0
- package/opencode-plugin/package.json +19 -0
- package/opencode-plugin/src/index.ts +791 -0
- package/package.json +16 -4
- package/schemas/config.schema.json +104 -0
- package/schemas/event-v3.schema.json +164 -0
- package/src/commander.ts +26 -0
- package/src/commands/agents.ts +47 -18
- package/src/commands/artifacts.ts +171 -19
- package/src/commands/browse-ai.ts +8 -0
- package/src/commands/browse.ts +570 -48
- package/src/commands/checkpoint.ts +7 -9
- package/src/commands/claude-desktop.ts +61 -0
- package/src/commands/deinit.ts +9 -4
- package/src/commands/disk.ts +114 -0
- package/src/commands/docs.ts +2 -0
- package/src/commands/doctor.ts +63 -3
- package/src/commands/fetch.ts +14 -0
- package/src/commands/files.ts +93 -2
- package/src/commands/init.ts +334 -122
- package/src/commands/instructions.ts +8 -4
- package/src/commands/ledger-v3.ts +2 -1
- package/src/commands/rm.ts +115 -0
- package/src/commands/servers.ts +506 -0
- package/src/commands/tunnel.ts +102 -2
- package/src/commands/webview.ts +159 -0
- package/src/core/adapter.ts +102 -1
- package/src/core/adapters/attestation.ts +3 -2
- package/src/core/adapters/profiles.ts +63 -1
- package/src/core/adapters/registry.ts +37 -0
- package/src/core/adapters/types.ts +10 -0
- package/src/core/agents/canonical-emit.ts +2 -5
- package/src/core/agents/cli.ts +26 -17
- package/src/core/agents/coord-client.ts +9 -3
- package/src/core/agents/render/session-context.ts +1 -0
- package/src/core/agents/rules/claim-conflict.ts +3 -8
- package/src/core/agents/rules/commit-conflict.ts +2 -7
- package/src/core/agents/rules/stop-hook.ts +3 -1
- package/src/core/agents/session-events.ts +120 -26
- package/src/core/agents/session-finalization-state-v3.ts +2 -1
- package/src/core/agents/session-finalizer-v3.ts +5 -4
- package/src/core/agents/session-name-display.ts +48 -0
- package/src/core/agents/state/heartbeat-reader.ts +7 -0
- package/src/core/agents/state/heartbeat-writer.ts +24 -2
- package/src/core/agents/state/live-coordination-view.ts +74 -0
- package/src/core/agents/state/live-coordination-writer.ts +3 -0
- package/src/core/agents/state/stale-sweep.ts +2 -9
- package/src/core/agents/turn-changes.ts +97 -0
- package/src/core/artifacts/delivery-card.ts +12 -3
- package/src/core/artifacts/index.ts +701 -47
- package/src/core/config.ts +206 -4
- package/src/core/context/index.ts +2 -1
- package/src/core/conversations/archive.ts +4 -3
- package/src/core/diagnostics/bundle.ts +5 -3
- package/src/core/events/legacy-storage/canary.ts +5 -4
- package/src/core/events/legacy-storage/compression.ts +2 -1
- package/src/core/events/v3/adapter-id.ts +29 -1
- package/src/core/events/v3/authority-outbox.ts +2 -1
- package/src/core/events/v3/bootstrap.ts +5 -4
- package/src/core/events/v3/capabilities.ts +17 -0
- package/src/core/events/v3/contract.ts +9 -1
- package/src/core/events/v3/control-witness.ts +3 -2
- package/src/core/events/v3/coordination-transaction-recovery.ts +4 -3
- package/src/core/events/v3/fingerprint-keys.ts +7 -6
- package/src/core/events/v3/generated.ts +1 -1
- package/src/core/events/v3/live-feed.ts +5 -4
- package/src/core/events/v3/producers/command-recorder.ts +8 -6
- package/src/core/events/v3/producers/coordination-recorder.ts +8 -7
- package/src/core/events/v3/producers/diagnostic-summaries.ts +5 -4
- package/src/core/events/v3/producers/hook-base.ts +11 -4
- package/src/core/events/v3/producers/hook.ts +19 -1
- package/src/core/events/v3/producers/intake.ts +18 -6
- package/src/core/events/v3/producers/recorder.ts +139 -114
- package/src/core/events/v3/projection.ts +11 -1
- package/src/core/events/v3/recovery.ts +4 -3
- package/src/core/events/v3/support-storage/inventory.ts +2 -1
- package/src/core/events/v3/support-storage/maintenance.ts +8 -3
- package/src/core/events/v3/support-storage/pack-reader.ts +4 -3
- package/src/core/events/v3/support-storage/pack-writer.ts +6 -5
- package/src/core/events/v3/tool-line-changes.ts +139 -0
- package/src/core/events/v3/writer.ts +8 -7
- package/src/core/governor/planning.ts +6 -5
- package/src/core/governor/service.ts +12 -11
- package/src/core/governor/state.ts +7 -6
- package/src/core/guard/evaluator.ts +1 -0
- package/src/core/guard/storage.ts +3 -2
- package/src/core/hooks/adapter/behaviors/claude-code.ts +33 -0
- package/src/core/hooks/adapter/behaviors/codex.ts +96 -0
- package/src/core/hooks/adapter/behaviors/cursor.ts +37 -0
- package/src/core/hooks/adapter/behaviors/index.ts +31 -0
- package/src/core/hooks/adapter/behaviors/openclaw.ts +36 -0
- package/src/core/hooks/adapter/behaviors/opencode.ts +36 -0
- package/src/core/hooks/adapter/behaviors/types.ts +110 -0
- package/src/core/hooks/adapter/detect.ts +2 -3
- package/src/core/hooks/adapter/events.ts +72 -1
- package/src/core/hooks/adapter/opencode-plugin.ts +177 -0
- package/src/core/hooks/adapter/output.ts +8 -1
- package/src/core/hooks/adapter/runtime-telemetry.ts +3 -1
- package/src/core/hooks/adapter/wiring.ts +198 -16
- package/src/core/hooks/cli.ts +776 -539
- package/src/core/hooks/effects/image-capture.ts +2 -1
- package/src/core/hooks/prompt-context/contract.ts +1 -0
- package/src/core/hooks/resolve/transcript.ts +42 -5
- package/src/core/hooks/run-markers.ts +132 -0
- package/src/core/hooks/session-name-presence.ts +10 -3
- package/src/core/hooks/shell-waiter.ts +166 -0
- package/src/core/resources/service.ts +5 -4
- package/src/core/semantic/review.ts +5 -4
- package/src/core/semantic/service.ts +15 -14
- package/src/core/semantic/storage.ts +5 -4
- package/src/core/servers/index.ts +712 -0
- package/src/core/servers/net.ts +283 -0
- package/src/core/servers/tunnels.ts +39 -0
- package/src/core/storage/atomic-json.ts +7 -3
- package/src/core/storage/builtins.ts +1 -0
- package/src/core/storage/durable-history.ts +6 -5
- package/src/core/storage/maintenance-providers.ts +2 -1
- package/src/core/storage/maintenance.ts +7 -6
- package/src/core/storage/metrics.ts +5 -1
- package/src/core/storage/modes.ts +53 -0
- package/src/core/storage/process-log.ts +3 -2
- package/src/core/storage/receipts.ts +4 -3
- package/src/core/storage/segments.ts +7 -6
- package/src/core/supervisor/hook-health.ts +4 -4
- package/src/core/supervisor/service.ts +7 -6
- package/src/core/work/state.ts +8 -7
- package/src/core/workflow/adapters.ts +15 -0
- package/src/core/workflow/approvals.ts +6 -5
- package/src/core/workflow/billing.ts +34 -4
- package/src/core/workflow/durable-record.ts +4 -3
- package/src/core/workflow/engine.ts +38 -1
- package/src/core/workflow/live-session-v3.ts +2 -3
- package/src/core/workflow/run-state.ts +3 -2
- package/src/core/workflow/sandbox-projection.ts +38 -2
- package/src/core/workflow/spawn-claude.ts +5 -1
- package/src/core/workflow/spawn-codex.ts +18 -1
- package/src/core/workflow/spawn-cursor.ts +5 -1
- package/src/core/workflow/spawn-opencode.ts +153 -0
- package/src/core/workflow/transcript.ts +3 -2
- package/src/core/workflow/types.ts +62 -2
- package/src/core/workflow/worker-access.ts +525 -0
- package/src/core/workflow/workspaces/leases.ts +5 -4
- package/src/core/workflow/workspaces/local-git.ts +3 -2
- package/src/core/workflow/workspaces/paths.ts +2 -1
- package/src/core/workflow/workspaces/state.ts +10 -9
- package/src/lazy-commands.ts +11 -1
- package/src/lib/agent-browser/client.ts +18 -0
- package/src/lib/browser/batch-steps.ts +79 -0
- package/src/lib/browser/client.ts +147 -9
- package/src/lib/browser/collect/collector.ts +306 -0
- package/src/lib/browser/collect/fields.ts +87 -0
- package/src/lib/browser/collect/index.ts +47 -0
- package/src/lib/browser/collect/page-driver.ts +327 -0
- package/src/lib/browser/collect/presets.ts +237 -0
- package/src/lib/browser/collect/scroll-plan.ts +179 -0
- package/src/lib/browser/identity.ts +64 -0
- package/src/lib/browser/index.ts +16 -1
- package/src/lib/browser/launch-args.ts +53 -1
- package/src/lib/browser/page-review-judge.ts +16 -0
- package/src/lib/browser/qa-run-contracts.ts +11 -0
- package/src/lib/browser/qa-run.ts +1 -0
- package/src/lib/browser/user-agent.ts +130 -0
- package/src/lib/browser/windows-chrome.ts +227 -0
- package/src/lib/claude-desktop-share.ts +511 -0
- package/src/lib/disk-usage.ts +347 -0
- package/src/lib/docs-lint.ts +8 -3
- package/src/lib/docs-metadata-managed.ts +21 -0
- package/src/lib/guarded-remove.ts +376 -0
- package/src/lib/identities/assume.ts +7 -7
- package/src/lib/instructions/apply.ts +2 -0
- package/src/lib/instructions/templates.ts +8 -8
- package/src/lib/pace/index.ts +14 -0
- package/src/lib/pace/pace.ts +370 -0
- package/src/lib/tunnel/error-page.ts +25 -9
- package/src/lib/tunnel/forward-headers.ts +16 -0
- package/src/lib/tunnel/gate.ts +39 -10
- package/src/lib/tunnel/path-scope.ts +73 -0
- package/src/lib/tunnel/state.ts +20 -3
- package/src/lib/webview/index.ts +13 -0
- package/src/lib/webview/webview.ts +457 -0
package/src/lazy-commands.ts
CHANGED
|
@@ -256,7 +256,17 @@ function selectedCommand(
|
|
|
256
256
|
if (token === "--") return undefined;
|
|
257
257
|
if (token.startsWith("-")) {
|
|
258
258
|
const option = findRootOption(program, token);
|
|
259
|
-
|
|
259
|
+
// `--format=json` carries its value inline, so the next token is the
|
|
260
|
+
// command, not the value. Skipping it here consumed the command name and
|
|
261
|
+
// the wrong bundle (or none) was materialized, which surfaced downstream
|
|
262
|
+
// as empty output or a bogus "too many arguments" error.
|
|
263
|
+
const inlineValue = token.includes("=");
|
|
264
|
+
if (
|
|
265
|
+
!inlineValue &&
|
|
266
|
+
(option?.required || (option?.optional && !args[index + 1]?.startsWith("-")))
|
|
267
|
+
) {
|
|
268
|
+
index++;
|
|
269
|
+
}
|
|
260
270
|
continue;
|
|
261
271
|
}
|
|
262
272
|
if (token === "help") return state.byName.get(args[index + 1] ?? "");
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type SpawnSyncOptions, spawnSync } from "node:child_process";
|
|
2
2
|
import { writeFileSync } from "node:fs";
|
|
3
3
|
import type { CookieJar, Cookie as JarCookie } from "../cookies/index.ts";
|
|
4
|
+
import { PaceGate, pacePolicyFromEnv } from "../pace/index.ts";
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Thin wrapper over Vercel Labs' `agent-browser` Rust CLI.
|
|
@@ -34,6 +35,11 @@ export interface AgentBrowserOptions {
|
|
|
34
35
|
* agent-browser session. Defaults to a tmp file derived from the jar.
|
|
35
36
|
*/
|
|
36
37
|
stateFilePath?: string;
|
|
38
|
+
/**
|
|
39
|
+
* Human-pace gate applied before every `open`. Unset resolves the default
|
|
40
|
+
* from the `HARNERY_PACE*` environment; `null` disables pacing.
|
|
41
|
+
*/
|
|
42
|
+
pace?: PaceGate | null;
|
|
37
43
|
}
|
|
38
44
|
|
|
39
45
|
export interface ExecResult {
|
|
@@ -48,11 +54,21 @@ const DEFAULT_TIMEOUT_MS = 60_000;
|
|
|
48
54
|
export class AgentBrowser {
|
|
49
55
|
private readonly opts: AgentBrowserOptions;
|
|
50
56
|
private cookiesSeeded = false;
|
|
57
|
+
private paceGate: PaceGate | null | undefined;
|
|
51
58
|
|
|
52
59
|
constructor(opts: AgentBrowserOptions = {}) {
|
|
53
60
|
this.opts = opts;
|
|
54
61
|
}
|
|
55
62
|
|
|
63
|
+
/** Block for the human-pace slot before a page load. Synchronous like the rest of this client. */
|
|
64
|
+
private paceBefore(url: string): void {
|
|
65
|
+
if (this.paceGate === undefined) {
|
|
66
|
+
this.paceGate =
|
|
67
|
+
this.opts.pace === undefined ? new PaceGate(pacePolicyFromEnv()) : this.opts.pace;
|
|
68
|
+
}
|
|
69
|
+
this.paceGate?.beforeSync(url);
|
|
70
|
+
}
|
|
71
|
+
|
|
56
72
|
/**
|
|
57
73
|
* Run an `agent-browser` subcommand. Returns a structured result.
|
|
58
74
|
* Throws only on spawn failure (e.g., binary not found); non-zero exit
|
|
@@ -132,6 +148,7 @@ export class AgentBrowser {
|
|
|
132
148
|
|
|
133
149
|
open(url: string, timeoutMs?: number): ExecResult {
|
|
134
150
|
this.seedCookies();
|
|
151
|
+
this.paceBefore(url);
|
|
135
152
|
return this.execOrThrow(["open", url], timeoutMs);
|
|
136
153
|
}
|
|
137
154
|
|
|
@@ -183,6 +200,7 @@ export class AgentBrowser {
|
|
|
183
200
|
// Naive shell-like splitting; agent-browser's own argv parser handles
|
|
184
201
|
// the actual command; we just split on whitespace for the wrapper.
|
|
185
202
|
const args = trimmed.split(/\s+/);
|
|
203
|
+
if (args[0] === "open" && args[1]) this.paceBefore(args[1]);
|
|
186
204
|
results.push(this.exec(args));
|
|
187
205
|
}
|
|
188
206
|
return results;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Split a `browse --batch` string into steps.
|
|
3
|
+
*
|
|
4
|
+
* Steps are separated by `;`. Two rules keep JavaScript intact:
|
|
5
|
+
*
|
|
6
|
+
* 1. A step that starts with the `eval` verb ends only at a `;` that sits
|
|
7
|
+
* outside JavaScript quotes ('...', "...", `...`) and outside (), [] and {}.
|
|
8
|
+
* So `eval (() => { const a = 1; return a })(); wait 500` is two steps.
|
|
9
|
+
* 2. Every other step ends at the next `;`, exactly as before. Selectors and
|
|
10
|
+
* fill values may contain apostrophes or brackets that are not balanced
|
|
11
|
+
* JavaScript, so they get no quote or bracket tracking.
|
|
12
|
+
*
|
|
13
|
+
* `\;` always inserts a literal `;` without ending the step, in any verb.
|
|
14
|
+
* A top-level `;` inside an eval (two bare statements) still ends the step:
|
|
15
|
+
* wrap multiple statements in a block or an arrow function.
|
|
16
|
+
*/
|
|
17
|
+
export function splitBatchSteps(input: string): string[] {
|
|
18
|
+
const steps: string[] = [];
|
|
19
|
+
let buf = "";
|
|
20
|
+
let stepStart = true;
|
|
21
|
+
let jsAware = false;
|
|
22
|
+
let quote: string | null = null;
|
|
23
|
+
let depth = 0;
|
|
24
|
+
|
|
25
|
+
const endStep = () => {
|
|
26
|
+
if (buf.trim()) steps.push(buf);
|
|
27
|
+
buf = "";
|
|
28
|
+
stepStart = true;
|
|
29
|
+
jsAware = false;
|
|
30
|
+
quote = null;
|
|
31
|
+
depth = 0;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
for (let i = 0; i < input.length; i++) {
|
|
35
|
+
if (stepStart) {
|
|
36
|
+
// Decide the splitting rule once per step from its leading verb.
|
|
37
|
+
jsAware = /^\s*eval(\s|$)/i.test(input.slice(i));
|
|
38
|
+
stepStart = false;
|
|
39
|
+
}
|
|
40
|
+
const ch = input[i] as string;
|
|
41
|
+
if (ch === "\\" && input[i + 1] === ";") {
|
|
42
|
+
buf += ";";
|
|
43
|
+
i++;
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
if (jsAware) {
|
|
47
|
+
if (quote) {
|
|
48
|
+
buf += ch;
|
|
49
|
+
if (ch === "\\" && i + 1 < input.length) {
|
|
50
|
+
buf += input[i + 1];
|
|
51
|
+
i++;
|
|
52
|
+
} else if (ch === quote) {
|
|
53
|
+
quote = null;
|
|
54
|
+
}
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
if (ch === "'" || ch === '"' || ch === "`") {
|
|
58
|
+
quote = ch;
|
|
59
|
+
buf += ch;
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
if (ch === "(" || ch === "[" || ch === "{") depth++;
|
|
63
|
+
else if (ch === ")" || ch === "]" || ch === "}") depth = Math.max(0, depth - 1);
|
|
64
|
+
if (ch === ";" && depth === 0) {
|
|
65
|
+
endStep();
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
buf += ch;
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
if (ch === ";") {
|
|
72
|
+
endStep();
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
buf += ch;
|
|
76
|
+
}
|
|
77
|
+
if (buf.trim()) steps.push(buf);
|
|
78
|
+
return steps;
|
|
79
|
+
}
|
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
CookieStoreParseError,
|
|
17
17
|
type Cookie as JarCookie,
|
|
18
18
|
} from "../cookies/index.ts";
|
|
19
|
+
import { PaceGate, pacePolicyFromEnv } from "../pace/index.ts";
|
|
19
20
|
import { type AssertResult, type AssertSpec, buildAssertCheck } from "./asserts.js";
|
|
20
21
|
import { stitchPngRows } from "./capture-fidelity.js";
|
|
21
22
|
import {
|
|
@@ -33,6 +34,8 @@ import {
|
|
|
33
34
|
type LayoutLintRequest,
|
|
34
35
|
type LayoutLintResult,
|
|
35
36
|
} from "./geometry.js";
|
|
37
|
+
import { browserIdentity, installDocumentIdentity } from "./identity.js";
|
|
38
|
+
import { AUTOMATION_DEFAULT_ARGS_TO_DROP, automationDisguiseArgs } from "./launch-args.js";
|
|
36
39
|
import {
|
|
37
40
|
buildClearLayoutAnnotationsScript,
|
|
38
41
|
buildLayoutAnnotateScript,
|
|
@@ -91,7 +94,7 @@ export interface BrowserOptions {
|
|
|
91
94
|
/** Cookie jar to seed/sync with. Pass `null` to skip jar entirely. */
|
|
92
95
|
jar?: CookieJar | null;
|
|
93
96
|
/** Viewport. Default 1280x800. */
|
|
94
|
-
viewport?: { width: number; height: number };
|
|
97
|
+
viewport?: { width: number; height: number } | null;
|
|
95
98
|
/**
|
|
96
99
|
* Device scale factor (DPR) for the context. Unset keeps Playwright's
|
|
97
100
|
* default of 1, so screenshots are CSS-pixel sized. A higher value renders
|
|
@@ -128,6 +131,13 @@ export interface BrowserOptions {
|
|
|
128
131
|
* via this callback (e.g., a Cloudflare-bypass header for specific zones).
|
|
129
132
|
*/
|
|
130
133
|
extraHeaders?: (url: string) => Record<string, string>;
|
|
134
|
+
/**
|
|
135
|
+
* Human-pace gate applied before every page load: `navigate`, `reload`, and
|
|
136
|
+
* the session tab verbs. Unset resolves the default from the `HARNERY_PACE*`
|
|
137
|
+
* environment (on, 3 to 9 seconds between loads of one site). `null`
|
|
138
|
+
* disables pacing for this client.
|
|
139
|
+
*/
|
|
140
|
+
pace?: PaceGate | null;
|
|
131
141
|
/**
|
|
132
142
|
* Extra Chromium command-line flags, passed through to Playwright's
|
|
133
143
|
* `launchPersistentContext` `args`. Used for environment-specific
|
|
@@ -136,6 +146,28 @@ export interface BrowserOptions {
|
|
|
136
146
|
* defaults only.
|
|
137
147
|
*/
|
|
138
148
|
launchArgs?: string[];
|
|
149
|
+
/**
|
|
150
|
+
* Playwright browser channel. `"chrome"` launches the operator's installed
|
|
151
|
+
* Google Chrome instead of the bundled "Chrome for Testing" build. Unset or
|
|
152
|
+
* `"chromium"` keeps the bundled browser.
|
|
153
|
+
*/
|
|
154
|
+
channel?: "chrome" | "chrome-beta" | "msedge" | "chromium";
|
|
155
|
+
/**
|
|
156
|
+
* Drop Playwright's `--enable-automation` default, disable Blink's
|
|
157
|
+
* AutomationControlled feature, and run with the Chromium sandbox on (no
|
|
158
|
+
* `--no-sandbox`), so pages do not see `navigator.webdriver`, the automation
|
|
159
|
+
* infobar, or the unsupported-flag banner. Headed sessions set this; sites
|
|
160
|
+
* that screen for automation otherwise refuse clicks a person makes in the
|
|
161
|
+
* window.
|
|
162
|
+
*/
|
|
163
|
+
hideAutomation?: boolean;
|
|
164
|
+
/**
|
|
165
|
+
* User agent to present. Set by `browse` from `lib/browser/user-agent`
|
|
166
|
+
* (never Linux, never HeadlessChrome). Applied both as the Playwright
|
|
167
|
+
* context override and as `--user-agent` so workers and frames agree.
|
|
168
|
+
* Unset keeps the browser's native string.
|
|
169
|
+
*/
|
|
170
|
+
userAgent?: string;
|
|
139
171
|
/** Authenticated browser proxy passed directly to Playwright. */
|
|
140
172
|
proxy?: { server: string; username?: string; password?: string };
|
|
141
173
|
}
|
|
@@ -306,6 +338,7 @@ export class Browser {
|
|
|
306
338
|
private consoleEvents: ConsoleEvent[] = [];
|
|
307
339
|
private pageErrors: PageErrorEvent[] = [];
|
|
308
340
|
private failedRequests: FailedRequest[] = [];
|
|
341
|
+
private identityReady = new WeakMap<Page, Promise<void>>();
|
|
309
342
|
|
|
310
343
|
constructor(private opts: BrowserOptions = {}) {
|
|
311
344
|
this.profileDir = opts.profileDir ?? DEFAULT_PROFILE;
|
|
@@ -326,20 +359,54 @@ export class Browser {
|
|
|
326
359
|
*/
|
|
327
360
|
private async openOnce(): Promise<void> {
|
|
328
361
|
const jarCookies = this.opts.jar?.list() ?? [];
|
|
362
|
+
const launchIdentity = this.opts.userAgent ? browserIdentity(this.opts.userAgent) : undefined;
|
|
363
|
+
const launchArgs = [
|
|
364
|
+
...new Set([
|
|
365
|
+
...(this.opts.headed && this.opts.viewport == null ? ["--window-size=1536,864"] : []),
|
|
366
|
+
...(this.opts.launchArgs ?? []),
|
|
367
|
+
...(this.opts.hideAutomation ? automationDisguiseArgs() : []),
|
|
368
|
+
...(this.opts.userAgent ? [`--user-agent=${this.opts.userAgent}`] : []),
|
|
369
|
+
]),
|
|
370
|
+
];
|
|
329
371
|
|
|
330
372
|
// Hold a launch slot only across the spawn itself, not the browser's life.
|
|
331
373
|
await acquireLaunchSlot();
|
|
332
374
|
try {
|
|
333
375
|
this.context = await chromium.launchPersistentContext(this.profileDir, {
|
|
334
376
|
headless: !this.opts.headed,
|
|
335
|
-
|
|
377
|
+
// Service-worker-owned navigations bypass Playwright request routes.
|
|
378
|
+
...(this.getPaceGate()?.policy.enabled ? { serviceWorkers: "block" as const } : {}),
|
|
379
|
+
viewport:
|
|
380
|
+
this.opts.viewport !== undefined
|
|
381
|
+
? this.opts.viewport
|
|
382
|
+
: this.opts.headed
|
|
383
|
+
? null
|
|
384
|
+
: { width: 1280, height: 800 },
|
|
336
385
|
...(this.opts.deviceScaleFactor !== undefined
|
|
337
386
|
? { deviceScaleFactor: this.opts.deviceScaleFactor }
|
|
338
387
|
: {}),
|
|
339
388
|
...(this.opts.colorScheme ? { colorScheme: this.opts.colorScheme } : {}),
|
|
389
|
+
...(this.opts.userAgent ? { userAgent: this.opts.userAgent } : {}),
|
|
390
|
+
...(launchIdentity
|
|
391
|
+
? {
|
|
392
|
+
extraHTTPHeaders: {
|
|
393
|
+
"sec-ch-ua-platform": JSON.stringify(launchIdentity.userAgentMetadata.platform),
|
|
394
|
+
"sec-ch-ua-mobile": "?0",
|
|
395
|
+
"sec-ch-ua": launchIdentity.userAgentMetadata.brands
|
|
396
|
+
.map(
|
|
397
|
+
({ brand, version }) => `${JSON.stringify(brand)};v=${JSON.stringify(version)}`,
|
|
398
|
+
)
|
|
399
|
+
.join(", "),
|
|
400
|
+
},
|
|
401
|
+
}
|
|
402
|
+
: {}),
|
|
340
403
|
...(this.opts.launchTimeout !== undefined ? { timeout: this.opts.launchTimeout } : {}),
|
|
341
|
-
...(
|
|
342
|
-
|
|
404
|
+
...(launchArgs.length > 0 ? { args: launchArgs } : {}),
|
|
405
|
+
...(this.opts.channel && this.opts.channel !== "chromium"
|
|
406
|
+
? { channel: this.opts.channel }
|
|
407
|
+
: {}),
|
|
408
|
+
...(this.opts.hideAutomation
|
|
409
|
+
? { ignoreDefaultArgs: [...AUTOMATION_DEFAULT_ARGS_TO_DROP], chromiumSandbox: true }
|
|
343
410
|
: {}),
|
|
344
411
|
...(this.opts.proxy ? { proxy: this.opts.proxy } : {}),
|
|
345
412
|
...(this.opts.recordHarPath
|
|
@@ -350,18 +417,55 @@ export class Browser {
|
|
|
350
417
|
releaseLaunchSlot();
|
|
351
418
|
}
|
|
352
419
|
this.context.setDefaultNavigationTimeout(this.opts.navigationTimeout ?? 30_000);
|
|
420
|
+
const identity = this.opts.userAgent
|
|
421
|
+
? browserIdentity(this.opts.userAgent, this.context.browser()?.version())
|
|
422
|
+
: undefined;
|
|
423
|
+
if (identity) await this.context.addInitScript(installDocumentIdentity, identity);
|
|
353
424
|
|
|
354
425
|
if (jarCookies.length > 0) {
|
|
355
426
|
await this.context.addCookies(jarCookies.map(toPWCookie));
|
|
356
427
|
}
|
|
357
428
|
|
|
358
|
-
//
|
|
359
|
-
//
|
|
360
|
-
//
|
|
429
|
+
// Gate actual document requests, including links, forms, script navigation,
|
|
430
|
+
// and the first request of a popup. Method-level waits miss those loads.
|
|
431
|
+
// Redirect hops are part of the original load, not additional reservations.
|
|
361
432
|
const headersCb = this.opts.extraHeaders;
|
|
362
|
-
if (headersCb) {
|
|
433
|
+
if (this.getPaceGate()?.policy.enabled || headersCb || this.opts.userAgent) {
|
|
363
434
|
await this.context.route("**/*", async (route, request) => {
|
|
364
|
-
|
|
435
|
+
let mainDocument = false;
|
|
436
|
+
if (request.isNavigationRequest() && !request.redirectedFrom()) {
|
|
437
|
+
try {
|
|
438
|
+
mainDocument = request.frame() === request.frame().page().mainFrame();
|
|
439
|
+
} catch {
|
|
440
|
+
// A popup's first request can precede creation of its Page/Frame.
|
|
441
|
+
mainDocument = true;
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
if (mainDocument) {
|
|
445
|
+
try {
|
|
446
|
+
await this.getPaceGate()?.before(request.url());
|
|
447
|
+
} catch {
|
|
448
|
+
await route.abort("failed");
|
|
449
|
+
return;
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
const extra = { ...headersCb?.(request.url()) };
|
|
453
|
+
// Popup request headers are already computed before its CDP session is
|
|
454
|
+
// available. Keep negotiated hints consistent on that first request too.
|
|
455
|
+
if (identity) {
|
|
456
|
+
const metadata = identity.userAgentMetadata;
|
|
457
|
+
extra["sec-ch-ua-platform"] = JSON.stringify(metadata.platform);
|
|
458
|
+
extra["sec-ch-ua-mobile"] = "?0";
|
|
459
|
+
extra["sec-ch-ua"] = metadata.brands
|
|
460
|
+
.map(({ brand, version }) => `${JSON.stringify(brand)};v=${JSON.stringify(version)}`)
|
|
461
|
+
.join(", ");
|
|
462
|
+
for (const [header, value] of Object.entries({
|
|
463
|
+
"sec-ch-ua-platform-version": metadata.platformVersion,
|
|
464
|
+
"sec-ch-ua-arch": metadata.architecture,
|
|
465
|
+
"sec-ch-ua-bitness": metadata.bitness,
|
|
466
|
+
}))
|
|
467
|
+
if (header in request.headers()) extra[header] = JSON.stringify(value);
|
|
468
|
+
}
|
|
365
469
|
if (Object.keys(extra).length === 0) return route.continue();
|
|
366
470
|
const headers = { ...request.headers(), ...extra };
|
|
367
471
|
return route.continue({ headers });
|
|
@@ -370,6 +474,7 @@ export class Browser {
|
|
|
370
474
|
|
|
371
475
|
const pages = this.context.pages();
|
|
372
476
|
const firstPage = pages[0] ?? (await this.context.newPage());
|
|
477
|
+
await Promise.all(this.context.pages().map((page) => this.preparePageIdentity(page)));
|
|
373
478
|
for (const page of this.context.pages()) this.trackPage(page, page === firstPage);
|
|
374
479
|
this.context.on("page", (page) => this.trackPage(page, true));
|
|
375
480
|
}
|
|
@@ -491,6 +596,10 @@ export class Browser {
|
|
|
491
596
|
type: "unknown",
|
|
492
597
|
});
|
|
493
598
|
this.attachDiagnosticListeners(page);
|
|
599
|
+
void this.preparePageIdentity(page).catch((error) => {
|
|
600
|
+
if (!page.isClosed())
|
|
601
|
+
this.pageErrors.push({ message: `Browser identity setup failed: ${String(error)}` });
|
|
602
|
+
});
|
|
494
603
|
page.on("domcontentloaded", () => this.recordDocumentNavigation(page));
|
|
495
604
|
page.once("close", () => {
|
|
496
605
|
this.pageRecency.delete(page);
|
|
@@ -501,6 +610,23 @@ export class Browser {
|
|
|
501
610
|
if (makeActive) this.setActivePage(page);
|
|
502
611
|
}
|
|
503
612
|
|
|
613
|
+
private preparePageIdentity(page: Page): Promise<void> {
|
|
614
|
+
if (!this.opts.userAgent || !this.context) return Promise.resolve();
|
|
615
|
+
let ready = this.identityReady.get(page);
|
|
616
|
+
if (!ready) {
|
|
617
|
+
const context = this.context;
|
|
618
|
+
const userAgent = this.opts.userAgent;
|
|
619
|
+
ready = (async () => {
|
|
620
|
+
const identity = browserIdentity(userAgent, context.browser()?.version());
|
|
621
|
+
if (!identity) return;
|
|
622
|
+
const session = await context.newCDPSession(page);
|
|
623
|
+
await session.send("Emulation.setUserAgentOverride", identity);
|
|
624
|
+
})();
|
|
625
|
+
this.identityReady.set(page, ready);
|
|
626
|
+
}
|
|
627
|
+
return ready;
|
|
628
|
+
}
|
|
629
|
+
|
|
504
630
|
private setActivePage(page: Page): void {
|
|
505
631
|
if (page.isClosed()) return;
|
|
506
632
|
this.page = page;
|
|
@@ -569,8 +695,19 @@ export class Browser {
|
|
|
569
695
|
};
|
|
570
696
|
}
|
|
571
697
|
|
|
698
|
+
private paceGate: PaceGate | null | undefined;
|
|
699
|
+
|
|
700
|
+
private getPaceGate(): PaceGate | null {
|
|
701
|
+
if (this.paceGate === undefined) {
|
|
702
|
+
this.paceGate =
|
|
703
|
+
this.opts.pace === undefined ? new PaceGate(pacePolicyFromEnv()) : this.opts.pace;
|
|
704
|
+
}
|
|
705
|
+
return this.paceGate;
|
|
706
|
+
}
|
|
707
|
+
|
|
572
708
|
async navigate(url: string): Promise<NavigateResult> {
|
|
573
709
|
const page = this.currentPage;
|
|
710
|
+
await this.preparePageIdentity(page);
|
|
574
711
|
const response = await page.goto(url, { waitUntil: this.opts.waitUntil ?? "load" });
|
|
575
712
|
return {
|
|
576
713
|
url: page.url(),
|
|
@@ -1381,6 +1518,7 @@ export class Browser {
|
|
|
1381
1518
|
const page = await this.context.newPage();
|
|
1382
1519
|
this.trackPage(page, true);
|
|
1383
1520
|
try {
|
|
1521
|
+
await this.preparePageIdentity(page);
|
|
1384
1522
|
await page.goto(url, { waitUntil: this.opts.waitUntil ?? "load" });
|
|
1385
1523
|
this.sessionRevision++;
|
|
1386
1524
|
return await this.describeTab(page);
|