harnery 0.40.0 → 0.42.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/commander.js +4 -0
- package/dist/commands/agents.d.ts.map +1 -1
- package/dist/commands/agents.js +34 -20
- package/dist/commands/artifacts.d.ts.map +1 -1
- package/dist/commands/artifacts.js +113 -12
- package/dist/commands/browse-ai.d.ts.map +1 -1
- package/dist/commands/browse-ai.js +4 -0
- package/dist/commands/browse.d.ts +164 -0
- package/dist/commands/browse.d.ts.map +1 -1
- package/dist/commands/browse.js +388 -45
- package/dist/commands/checkpoint.js +8 -12
- package/dist/commands/claude-desktop.d.ts.map +1 -1
- package/dist/commands/claude-desktop.js +52 -0
- package/dist/commands/deinit.d.ts +1 -1
- package/dist/commands/deinit.d.ts.map +1 -1
- package/dist/commands/deinit.js +8 -4
- package/dist/commands/disk.d.ts +6 -0
- package/dist/commands/disk.d.ts.map +1 -0
- package/dist/commands/disk.js +80 -0
- package/dist/commands/docs.d.ts.map +1 -1
- package/dist/commands/docs.js +2 -0
- package/dist/commands/doctor.d.ts +8 -0
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +58 -3
- package/dist/commands/fetch.d.ts.map +1 -1
- package/dist/commands/fetch.js +10 -0
- package/dist/commands/files.d.ts +16 -0
- package/dist/commands/files.d.ts.map +1 -1
- package/dist/commands/files.js +54 -2
- package/dist/commands/init.d.ts +21 -5
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +271 -109
- package/dist/commands/instructions.js +5 -4
- package/dist/commands/ledger-v3.d.ts.map +1 -1
- package/dist/commands/ledger-v3.js +2 -1
- package/dist/commands/rm.d.ts +4 -0
- package/dist/commands/rm.d.ts.map +1 -0
- package/dist/commands/rm.js +87 -0
- package/dist/commands/servers.d.ts +7 -0
- package/dist/commands/servers.d.ts.map +1 -0
- package/dist/commands/servers.js +394 -0
- package/dist/commands/tunnel.d.ts.map +1 -1
- package/dist/commands/tunnel.js +82 -2
- package/dist/commands/webview.d.ts +4 -0
- package/dist/commands/webview.d.ts.map +1 -0
- package/dist/commands/webview.js +94 -0
- package/dist/core/adapter.d.ts +50 -1
- package/dist/core/adapter.d.ts.map +1 -1
- package/dist/core/adapter.js +59 -1
- package/dist/core/adapters/attestation.d.ts.map +1 -1
- package/dist/core/adapters/attestation.js +3 -2
- package/dist/core/adapters/profiles.d.ts +29 -3
- package/dist/core/adapters/profiles.d.ts.map +1 -1
- package/dist/core/adapters/profiles.js +53 -1
- package/dist/core/adapters/registry.d.ts.map +1 -1
- package/dist/core/adapters/registry.js +33 -0
- package/dist/core/adapters/types.d.ts +9 -0
- package/dist/core/adapters/types.d.ts.map +1 -1
- package/dist/core/agents/canonical-emit.d.ts +1 -1
- package/dist/core/agents/canonical-emit.d.ts.map +1 -1
- package/dist/core/agents/canonical-emit.js +2 -7
- package/dist/core/agents/cli.js +25 -16
- package/dist/core/agents/coord-client.d.ts.map +1 -1
- package/dist/core/agents/coord-client.js +7 -2
- package/dist/core/agents/render/session-context.d.ts.map +1 -1
- package/dist/core/agents/render/session-context.js +2 -0
- package/dist/core/agents/rules/claim-conflict.d.ts.map +1 -1
- package/dist/core/agents/rules/claim-conflict.js +3 -9
- package/dist/core/agents/rules/commit-conflict.d.ts.map +1 -1
- package/dist/core/agents/rules/commit-conflict.js +2 -8
- package/dist/core/agents/rules/stop-hook.d.ts +2 -0
- package/dist/core/agents/rules/stop-hook.d.ts.map +1 -1
- package/dist/core/agents/rules/stop-hook.js +1 -1
- package/dist/core/agents/session-events.d.ts +6 -2
- package/dist/core/agents/session-events.d.ts.map +1 -1
- package/dist/core/agents/session-events.js +105 -26
- package/dist/core/agents/session-finalization-state-v3.d.ts.map +1 -1
- package/dist/core/agents/session-finalization-state-v3.js +2 -1
- package/dist/core/agents/session-finalizer-v3.d.ts.map +1 -1
- package/dist/core/agents/session-finalizer-v3.js +5 -4
- package/dist/core/agents/session-name-display.d.ts +28 -0
- package/dist/core/agents/session-name-display.d.ts.map +1 -1
- package/dist/core/agents/session-name-display.js +43 -0
- package/dist/core/agents/state/heartbeat-reader.d.ts +7 -0
- package/dist/core/agents/state/heartbeat-reader.d.ts.map +1 -1
- package/dist/core/agents/state/heartbeat-writer.d.ts +10 -0
- package/dist/core/agents/state/heartbeat-writer.d.ts.map +1 -1
- package/dist/core/agents/state/heartbeat-writer.js +21 -2
- package/dist/core/agents/state/live-coordination-view.d.ts +20 -0
- package/dist/core/agents/state/live-coordination-view.d.ts.map +1 -1
- package/dist/core/agents/state/live-coordination-view.js +61 -0
- package/dist/core/agents/state/live-coordination-writer.js +3 -0
- package/dist/core/agents/state/stale-sweep.d.ts.map +1 -1
- package/dist/core/agents/state/stale-sweep.js +2 -10
- package/dist/core/agents/turn-changes.d.ts +17 -0
- package/dist/core/agents/turn-changes.d.ts.map +1 -0
- package/dist/core/agents/turn-changes.js +76 -0
- package/dist/core/artifacts/delivery-card.d.ts.map +1 -1
- package/dist/core/artifacts/delivery-card.js +11 -3
- package/dist/core/artifacts/index.d.ts +140 -4
- package/dist/core/artifacts/index.d.ts.map +1 -1
- package/dist/core/artifacts/index.js +526 -52
- package/dist/core/config.d.ts +73 -11
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +142 -3
- package/dist/core/context/index.d.ts.map +1 -1
- package/dist/core/context/index.js +2 -1
- package/dist/core/conversations/archive.d.ts.map +1 -1
- package/dist/core/conversations/archive.js +4 -3
- package/dist/core/diagnostics/bundle.d.ts.map +1 -1
- package/dist/core/diagnostics/bundle.js +5 -4
- package/dist/core/events/legacy-storage/canary.d.ts.map +1 -1
- package/dist/core/events/legacy-storage/canary.js +5 -4
- package/dist/core/events/legacy-storage/compression.d.ts.map +1 -1
- package/dist/core/events/legacy-storage/compression.js +2 -1
- package/dist/core/events/v3/adapter-id.d.ts +10 -2
- package/dist/core/events/v3/adapter-id.d.ts.map +1 -1
- package/dist/core/events/v3/adapter-id.js +16 -0
- package/dist/core/events/v3/authority-outbox.d.ts.map +1 -1
- package/dist/core/events/v3/authority-outbox.js +2 -1
- package/dist/core/events/v3/bootstrap.d.ts.map +1 -1
- package/dist/core/events/v3/bootstrap.js +5 -4
- package/dist/core/events/v3/capabilities.d.ts.map +1 -1
- package/dist/core/events/v3/capabilities.js +17 -0
- package/dist/core/events/v3/contract.d.ts +5 -0
- package/dist/core/events/v3/contract.d.ts.map +1 -1
- package/dist/core/events/v3/contract.js +7 -1
- package/dist/core/events/v3/control-witness.d.ts.map +1 -1
- package/dist/core/events/v3/control-witness.js +3 -2
- package/dist/core/events/v3/coordination-transaction-recovery.d.ts.map +1 -1
- package/dist/core/events/v3/coordination-transaction-recovery.js +4 -3
- package/dist/core/events/v3/fingerprint-keys.d.ts.map +1 -1
- package/dist/core/events/v3/fingerprint-keys.js +7 -6
- package/dist/core/events/v3/generated.d.ts +1 -1
- package/dist/core/events/v3/generated.js +1 -1
- package/dist/core/events/v3/live-feed.d.ts.map +1 -1
- package/dist/core/events/v3/live-feed.js +5 -4
- package/dist/core/events/v3/producers/command-recorder.d.ts.map +1 -1
- package/dist/core/events/v3/producers/command-recorder.js +8 -7
- package/dist/core/events/v3/producers/coordination-recorder.d.ts.map +1 -1
- package/dist/core/events/v3/producers/coordination-recorder.js +8 -7
- package/dist/core/events/v3/producers/diagnostic-summaries.d.ts.map +1 -1
- package/dist/core/events/v3/producers/diagnostic-summaries.js +5 -4
- package/dist/core/events/v3/producers/hook-base.d.ts +1 -0
- package/dist/core/events/v3/producers/hook-base.d.ts.map +1 -1
- package/dist/core/events/v3/producers/hook-base.js +10 -4
- package/dist/core/events/v3/producers/hook.d.ts +2 -0
- package/dist/core/events/v3/producers/hook.d.ts.map +1 -1
- package/dist/core/events/v3/producers/hook.js +16 -1
- package/dist/core/events/v3/producers/intake.d.ts.map +1 -1
- package/dist/core/events/v3/producers/intake.js +16 -6
- package/dist/core/events/v3/producers/recorder.d.ts +2 -4
- package/dist/core/events/v3/producers/recorder.d.ts.map +1 -1
- package/dist/core/events/v3/producers/recorder.js +125 -101
- package/dist/core/events/v3/projection.js +9 -1
- package/dist/core/events/v3/recovery.d.ts.map +1 -1
- package/dist/core/events/v3/recovery.js +4 -3
- package/dist/core/events/v3/support-storage/inventory.d.ts.map +1 -1
- package/dist/core/events/v3/support-storage/inventory.js +2 -1
- package/dist/core/events/v3/support-storage/maintenance.d.ts.map +1 -1
- package/dist/core/events/v3/support-storage/maintenance.js +4 -3
- package/dist/core/events/v3/support-storage/pack-reader.d.ts.map +1 -1
- package/dist/core/events/v3/support-storage/pack-reader.js +4 -3
- package/dist/core/events/v3/support-storage/pack-writer.d.ts.map +1 -1
- package/dist/core/events/v3/support-storage/pack-writer.js +6 -5
- package/dist/core/events/v3/tool-line-changes.d.ts +8 -0
- package/dist/core/events/v3/tool-line-changes.d.ts.map +1 -0
- package/dist/core/events/v3/tool-line-changes.js +135 -0
- package/dist/core/events/v3/writer.d.ts.map +1 -1
- package/dist/core/events/v3/writer.js +8 -7
- package/dist/core/governor/planning.d.ts.map +1 -1
- package/dist/core/governor/planning.js +6 -5
- package/dist/core/governor/service.d.ts.map +1 -1
- package/dist/core/governor/service.js +12 -11
- package/dist/core/governor/state.d.ts.map +1 -1
- package/dist/core/governor/state.js +7 -6
- package/dist/core/guard/evaluator.js +1 -0
- package/dist/core/guard/storage.d.ts.map +1 -1
- package/dist/core/guard/storage.js +3 -2
- package/dist/core/hooks/adapter/behaviors/claude-code.d.ts +4 -0
- package/dist/core/hooks/adapter/behaviors/claude-code.d.ts.map +1 -0
- package/dist/core/hooks/adapter/behaviors/claude-code.js +31 -0
- package/dist/core/hooks/adapter/behaviors/codex.d.ts +15 -0
- package/dist/core/hooks/adapter/behaviors/codex.d.ts.map +1 -0
- package/dist/core/hooks/adapter/behaviors/codex.js +82 -0
- package/dist/core/hooks/adapter/behaviors/cursor.d.ts +7 -0
- package/dist/core/hooks/adapter/behaviors/cursor.d.ts.map +1 -0
- package/dist/core/hooks/adapter/behaviors/cursor.js +35 -0
- package/dist/core/hooks/adapter/behaviors/index.d.ts +11 -0
- package/dist/core/hooks/adapter/behaviors/index.d.ts.map +1 -0
- package/dist/core/hooks/adapter/behaviors/index.js +20 -0
- package/dist/core/hooks/adapter/behaviors/openclaw.d.ts +7 -0
- package/dist/core/hooks/adapter/behaviors/openclaw.d.ts.map +1 -0
- package/dist/core/hooks/adapter/behaviors/openclaw.js +34 -0
- package/dist/core/hooks/adapter/behaviors/opencode.d.ts +7 -0
- package/dist/core/hooks/adapter/behaviors/opencode.d.ts.map +1 -0
- package/dist/core/hooks/adapter/behaviors/opencode.js +34 -0
- package/dist/core/hooks/adapter/behaviors/types.d.ts +89 -0
- package/dist/core/hooks/adapter/behaviors/types.d.ts.map +1 -0
- package/dist/core/hooks/adapter/behaviors/types.js +1 -0
- package/dist/core/hooks/adapter/detect.d.ts +1 -1
- package/dist/core/hooks/adapter/detect.d.ts.map +1 -1
- package/dist/core/hooks/adapter/detect.js +2 -3
- package/dist/core/hooks/adapter/events.d.ts +46 -1
- package/dist/core/hooks/adapter/events.d.ts.map +1 -1
- package/dist/core/hooks/adapter/events.js +36 -0
- package/dist/core/hooks/adapter/opencode-plugin.d.ts +60 -0
- package/dist/core/hooks/adapter/opencode-plugin.d.ts.map +1 -0
- package/dist/core/hooks/adapter/opencode-plugin.js +129 -0
- package/dist/core/hooks/adapter/output.d.ts +7 -0
- package/dist/core/hooks/adapter/output.d.ts.map +1 -1
- package/dist/core/hooks/adapter/output.js +8 -1
- package/dist/core/hooks/adapter/runtime-telemetry.js +3 -1
- package/dist/core/hooks/adapter/wiring.d.ts +52 -8
- package/dist/core/hooks/adapter/wiring.d.ts.map +1 -1
- package/dist/core/hooks/adapter/wiring.js +133 -12
- package/dist/core/hooks/cli.js +676 -531
- package/dist/core/hooks/effects/image-capture.d.ts.map +1 -1
- package/dist/core/hooks/effects/image-capture.js +2 -1
- package/dist/core/hooks/prompt-context/contract.d.ts.map +1 -1
- package/dist/core/hooks/prompt-context/contract.js +1 -0
- package/dist/core/hooks/resolve/transcript.d.ts +1 -1
- package/dist/core/hooks/resolve/transcript.d.ts.map +1 -1
- package/dist/core/hooks/resolve/transcript.js +35 -4
- package/dist/core/hooks/run-markers.d.ts +37 -0
- package/dist/core/hooks/run-markers.d.ts.map +1 -0
- package/dist/core/hooks/run-markers.js +109 -0
- package/dist/core/hooks/session-name-presence.d.ts +3 -1
- package/dist/core/hooks/session-name-presence.d.ts.map +1 -1
- package/dist/core/hooks/session-name-presence.js +7 -2
- package/dist/core/hooks/shell-waiter.d.ts +2 -0
- package/dist/core/hooks/shell-waiter.d.ts.map +1 -0
- package/dist/core/hooks/shell-waiter.js +173 -0
- package/dist/core/resources/service.d.ts.map +1 -1
- package/dist/core/resources/service.js +5 -4
- package/dist/core/semantic/review.d.ts.map +1 -1
- package/dist/core/semantic/review.js +5 -4
- package/dist/core/semantic/service.d.ts.map +1 -1
- package/dist/core/semantic/service.js +15 -14
- package/dist/core/semantic/storage.d.ts.map +1 -1
- package/dist/core/semantic/storage.js +5 -4
- package/dist/core/servers/index.d.ts +211 -0
- package/dist/core/servers/index.d.ts.map +1 -0
- package/dist/core/servers/index.js +560 -0
- package/dist/core/servers/net.d.ts +58 -0
- package/dist/core/servers/net.d.ts.map +1 -0
- package/dist/core/servers/net.js +270 -0
- package/dist/core/servers/tunnels.d.ts +14 -0
- package/dist/core/servers/tunnels.d.ts.map +1 -0
- package/dist/core/servers/tunnels.js +33 -0
- package/dist/core/storage/atomic-json.d.ts.map +1 -1
- package/dist/core/storage/atomic-json.js +7 -3
- package/dist/core/storage/builtins.js +1 -0
- package/dist/core/storage/durable-history.d.ts.map +1 -1
- package/dist/core/storage/durable-history.js +6 -5
- package/dist/core/storage/maintenance-providers.d.ts.map +1 -1
- package/dist/core/storage/maintenance-providers.js +2 -1
- package/dist/core/storage/maintenance.d.ts.map +1 -1
- package/dist/core/storage/maintenance.js +7 -6
- package/dist/core/storage/metrics.d.ts.map +1 -1
- package/dist/core/storage/metrics.js +5 -1
- package/dist/core/storage/modes.d.ts +17 -0
- package/dist/core/storage/modes.d.ts.map +1 -0
- package/dist/core/storage/modes.js +47 -0
- package/dist/core/storage/process-log.d.ts.map +1 -1
- package/dist/core/storage/process-log.js +3 -2
- package/dist/core/storage/receipts.d.ts.map +1 -1
- package/dist/core/storage/receipts.js +4 -3
- package/dist/core/storage/segments.d.ts.map +1 -1
- package/dist/core/storage/segments.js +7 -6
- package/dist/core/supervisor/hook-health.d.ts +2 -1
- package/dist/core/supervisor/hook-health.d.ts.map +1 -1
- package/dist/core/supervisor/hook-health.js +4 -3
- package/dist/core/supervisor/service.d.ts.map +1 -1
- package/dist/core/supervisor/service.js +7 -6
- package/dist/core/work/state.d.ts.map +1 -1
- package/dist/core/work/state.js +8 -7
- package/dist/core/workflow/adapters.d.ts +7 -0
- package/dist/core/workflow/adapters.d.ts.map +1 -1
- package/dist/core/workflow/adapters.js +9 -0
- package/dist/core/workflow/approvals.d.ts.map +1 -1
- package/dist/core/workflow/approvals.js +6 -5
- package/dist/core/workflow/billing.d.ts.map +1 -1
- package/dist/core/workflow/billing.js +33 -4
- package/dist/core/workflow/durable-record.d.ts.map +1 -1
- package/dist/core/workflow/durable-record.js +4 -3
- package/dist/core/workflow/engine.d.ts.map +1 -1
- package/dist/core/workflow/engine.js +30 -1
- package/dist/core/workflow/live-session-v3.d.ts.map +1 -1
- package/dist/core/workflow/live-session-v3.js +2 -3
- package/dist/core/workflow/run-state.d.ts.map +1 -1
- package/dist/core/workflow/run-state.js +3 -2
- package/dist/core/workflow/sandbox-projection.d.ts +13 -2
- package/dist/core/workflow/sandbox-projection.d.ts.map +1 -1
- package/dist/core/workflow/sandbox-projection.js +23 -0
- package/dist/core/workflow/spawn-claude.d.ts.map +1 -1
- package/dist/core/workflow/spawn-claude.js +6 -1
- package/dist/core/workflow/spawn-codex.d.ts +2 -0
- package/dist/core/workflow/spawn-codex.d.ts.map +1 -1
- package/dist/core/workflow/spawn-codex.js +20 -1
- package/dist/core/workflow/spawn-cursor.d.ts.map +1 -1
- package/dist/core/workflow/spawn-cursor.js +6 -1
- package/dist/core/workflow/spawn-opencode.d.ts +36 -0
- package/dist/core/workflow/spawn-opencode.d.ts.map +1 -0
- package/dist/core/workflow/spawn-opencode.js +135 -0
- package/dist/core/workflow/transcript.d.ts.map +1 -1
- package/dist/core/workflow/transcript.js +3 -2
- package/dist/core/workflow/types.d.ts +47 -2
- package/dist/core/workflow/types.d.ts.map +1 -1
- package/dist/core/workflow/worker-access.d.ts +92 -0
- package/dist/core/workflow/worker-access.d.ts.map +1 -0
- package/dist/core/workflow/worker-access.js +450 -0
- package/dist/core/workflow/workspaces/leases.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/leases.js +5 -4
- package/dist/core/workflow/workspaces/local-git.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/local-git.js +3 -2
- package/dist/core/workflow/workspaces/paths.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/paths.js +2 -1
- package/dist/core/workflow/workspaces/state.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/state.js +10 -9
- package/dist/lazy-commands.js +8 -1
- package/dist/lib/agent-browser/client.d.ts +9 -0
- package/dist/lib/agent-browser/client.d.ts.map +1 -1
- package/dist/lib/agent-browser/client.js +13 -0
- package/dist/lib/browser/batch-steps.d.ts +18 -0
- package/dist/lib/browser/batch-steps.d.ts.map +1 -0
- package/dist/lib/browser/batch-steps.js +82 -0
- package/dist/lib/browser/client.d.ts +35 -1
- package/dist/lib/browser/client.d.ts.map +1 -1
- package/dist/lib/browser/client.js +117 -8
- package/dist/lib/browser/collect/collector.d.ts +99 -0
- package/dist/lib/browser/collect/collector.d.ts.map +1 -0
- package/dist/lib/browser/collect/collector.js +202 -0
- package/dist/lib/browser/collect/fields.d.ts +31 -0
- package/dist/lib/browser/collect/fields.d.ts.map +1 -0
- package/dist/lib/browser/collect/fields.js +75 -0
- package/dist/lib/browser/collect/index.d.ts +6 -0
- package/dist/lib/browser/collect/index.d.ts.map +1 -0
- package/dist/lib/browser/collect/index.js +5 -0
- package/dist/lib/browser/collect/page-driver.d.ts +14 -0
- package/dist/lib/browser/collect/page-driver.d.ts.map +1 -0
- package/dist/lib/browser/collect/page-driver.js +306 -0
- package/dist/lib/browser/collect/presets.d.ts +52 -0
- package/dist/lib/browser/collect/presets.d.ts.map +1 -0
- package/dist/lib/browser/collect/presets.js +176 -0
- package/dist/lib/browser/collect/scroll-plan.d.ts +85 -0
- package/dist/lib/browser/collect/scroll-plan.d.ts.map +1 -0
- package/dist/lib/browser/collect/scroll-plan.js +118 -0
- package/dist/lib/browser/identity.d.ts +25 -0
- package/dist/lib/browser/identity.d.ts.map +1 -0
- package/dist/lib/browser/identity.js +66 -0
- package/dist/lib/browser/index.d.ts +3 -2
- package/dist/lib/browser/index.d.ts.map +1 -1
- package/dist/lib/browser/index.js +2 -1
- package/dist/lib/browser/launch-args.d.ts +26 -0
- package/dist/lib/browser/launch-args.d.ts.map +1 -1
- package/dist/lib/browser/launch-args.js +41 -1
- package/dist/lib/browser/page-review-judge.d.ts +2 -0
- package/dist/lib/browser/page-review-judge.d.ts.map +1 -1
- package/dist/lib/browser/page-review-judge.js +13 -0
- package/dist/lib/browser/qa-run-contracts.d.ts +10 -0
- package/dist/lib/browser/qa-run-contracts.d.ts.map +1 -1
- package/dist/lib/browser/qa-run.d.ts.map +1 -1
- package/dist/lib/browser/qa-run.js +1 -0
- package/dist/lib/browser/user-agent.d.ts +53 -0
- package/dist/lib/browser/user-agent.d.ts.map +1 -0
- package/dist/lib/browser/user-agent.js +79 -0
- package/dist/lib/browser/windows-chrome.d.ts +59 -0
- package/dist/lib/browser/windows-chrome.d.ts.map +1 -0
- package/dist/lib/browser/windows-chrome.js +179 -0
- package/dist/lib/claude-desktop-share.d.ts +136 -0
- package/dist/lib/claude-desktop-share.d.ts.map +1 -0
- package/dist/lib/claude-desktop-share.js +394 -0
- package/dist/lib/disk-usage.d.ts +50 -0
- package/dist/lib/disk-usage.d.ts.map +1 -0
- package/dist/lib/disk-usage.js +303 -0
- package/dist/lib/docs-lint.d.ts +6 -0
- package/dist/lib/docs-lint.d.ts.map +1 -1
- package/dist/lib/docs-lint.js +8 -3
- package/dist/lib/docs-metadata-managed.d.ts +1 -0
- package/dist/lib/docs-metadata-managed.d.ts.map +1 -1
- package/dist/lib/docs-metadata-managed.js +17 -1
- package/dist/lib/guarded-remove.d.ts +34 -0
- package/dist/lib/guarded-remove.d.ts.map +1 -0
- package/dist/lib/guarded-remove.js +310 -0
- package/dist/lib/identities/assume.d.ts.map +1 -1
- package/dist/lib/identities/assume.js +4 -9
- package/dist/lib/instructions/apply.d.ts.map +1 -1
- package/dist/lib/instructions/apply.js +2 -0
- package/dist/lib/instructions/templates.js +8 -8
- package/dist/lib/pace/index.d.ts +2 -0
- package/dist/lib/pace/index.d.ts.map +1 -0
- package/dist/lib/pace/index.js +1 -0
- package/dist/lib/pace/pace.d.ts +95 -0
- package/dist/lib/pace/pace.d.ts.map +1 -0
- package/dist/lib/pace/pace.js +313 -0
- package/dist/lib/tunnel/error-page.d.ts +1 -1
- package/dist/lib/tunnel/error-page.d.ts.map +1 -1
- package/dist/lib/tunnel/error-page.js +19 -8
- package/dist/lib/tunnel/forward-headers.d.ts +11 -0
- package/dist/lib/tunnel/forward-headers.d.ts.map +1 -0
- package/dist/lib/tunnel/forward-headers.js +17 -0
- package/dist/lib/tunnel/gate.js +34 -10
- package/dist/lib/tunnel/path-scope.d.ts +22 -0
- package/dist/lib/tunnel/path-scope.d.ts.map +1 -0
- package/dist/lib/tunnel/path-scope.js +62 -0
- package/dist/lib/tunnel/state.d.ts +5 -0
- package/dist/lib/tunnel/state.d.ts.map +1 -1
- package/dist/lib/tunnel/state.js +17 -3
- package/dist/lib/webview/index.d.ts +2 -0
- package/dist/lib/webview/index.d.ts.map +1 -0
- package/dist/lib/webview/index.js +1 -0
- package/dist/lib/webview/webview.d.ts +116 -0
- package/dist/lib/webview/webview.d.ts.map +1 -0
- package/dist/lib/webview/webview.js +289 -0
- package/opencode-plugin/package.json +19 -0
- package/opencode-plugin/src/index.ts +791 -0
- package/package.json +16 -4
- package/schemas/config.schema.json +104 -0
- package/schemas/event-v3.schema.json +164 -0
- package/src/commander.ts +26 -0
- package/src/commands/agents.ts +47 -18
- package/src/commands/artifacts.ts +171 -19
- package/src/commands/browse-ai.ts +8 -0
- package/src/commands/browse.ts +570 -48
- package/src/commands/checkpoint.ts +7 -9
- package/src/commands/claude-desktop.ts +61 -0
- package/src/commands/deinit.ts +9 -4
- package/src/commands/disk.ts +114 -0
- package/src/commands/docs.ts +2 -0
- package/src/commands/doctor.ts +63 -3
- package/src/commands/fetch.ts +14 -0
- package/src/commands/files.ts +93 -2
- package/src/commands/init.ts +334 -122
- package/src/commands/instructions.ts +8 -4
- package/src/commands/ledger-v3.ts +2 -1
- package/src/commands/rm.ts +115 -0
- package/src/commands/servers.ts +506 -0
- package/src/commands/tunnel.ts +102 -2
- package/src/commands/webview.ts +159 -0
- package/src/core/adapter.ts +102 -1
- package/src/core/adapters/attestation.ts +3 -2
- package/src/core/adapters/profiles.ts +63 -1
- package/src/core/adapters/registry.ts +37 -0
- package/src/core/adapters/types.ts +10 -0
- package/src/core/agents/canonical-emit.ts +2 -5
- package/src/core/agents/cli.ts +26 -17
- package/src/core/agents/coord-client.ts +9 -3
- package/src/core/agents/render/session-context.ts +1 -0
- package/src/core/agents/rules/claim-conflict.ts +3 -8
- package/src/core/agents/rules/commit-conflict.ts +2 -7
- package/src/core/agents/rules/stop-hook.ts +3 -1
- package/src/core/agents/session-events.ts +120 -26
- package/src/core/agents/session-finalization-state-v3.ts +2 -1
- package/src/core/agents/session-finalizer-v3.ts +5 -4
- package/src/core/agents/session-name-display.ts +48 -0
- package/src/core/agents/state/heartbeat-reader.ts +7 -0
- package/src/core/agents/state/heartbeat-writer.ts +24 -2
- package/src/core/agents/state/live-coordination-view.ts +74 -0
- package/src/core/agents/state/live-coordination-writer.ts +3 -0
- package/src/core/agents/state/stale-sweep.ts +2 -9
- package/src/core/agents/turn-changes.ts +97 -0
- package/src/core/artifacts/delivery-card.ts +12 -3
- package/src/core/artifacts/index.ts +701 -47
- package/src/core/config.ts +206 -4
- package/src/core/context/index.ts +2 -1
- package/src/core/conversations/archive.ts +4 -3
- package/src/core/diagnostics/bundle.ts +5 -3
- package/src/core/events/legacy-storage/canary.ts +5 -4
- package/src/core/events/legacy-storage/compression.ts +2 -1
- package/src/core/events/v3/adapter-id.ts +29 -1
- package/src/core/events/v3/authority-outbox.ts +2 -1
- package/src/core/events/v3/bootstrap.ts +5 -4
- package/src/core/events/v3/capabilities.ts +17 -0
- package/src/core/events/v3/contract.ts +9 -1
- package/src/core/events/v3/control-witness.ts +3 -2
- package/src/core/events/v3/coordination-transaction-recovery.ts +4 -3
- package/src/core/events/v3/fingerprint-keys.ts +7 -6
- package/src/core/events/v3/generated.ts +1 -1
- package/src/core/events/v3/live-feed.ts +5 -4
- package/src/core/events/v3/producers/command-recorder.ts +8 -6
- package/src/core/events/v3/producers/coordination-recorder.ts +8 -7
- package/src/core/events/v3/producers/diagnostic-summaries.ts +5 -4
- package/src/core/events/v3/producers/hook-base.ts +11 -4
- package/src/core/events/v3/producers/hook.ts +19 -1
- package/src/core/events/v3/producers/intake.ts +18 -6
- package/src/core/events/v3/producers/recorder.ts +139 -114
- package/src/core/events/v3/projection.ts +11 -1
- package/src/core/events/v3/recovery.ts +4 -3
- package/src/core/events/v3/support-storage/inventory.ts +2 -1
- package/src/core/events/v3/support-storage/maintenance.ts +8 -3
- package/src/core/events/v3/support-storage/pack-reader.ts +4 -3
- package/src/core/events/v3/support-storage/pack-writer.ts +6 -5
- package/src/core/events/v3/tool-line-changes.ts +139 -0
- package/src/core/events/v3/writer.ts +8 -7
- package/src/core/governor/planning.ts +6 -5
- package/src/core/governor/service.ts +12 -11
- package/src/core/governor/state.ts +7 -6
- package/src/core/guard/evaluator.ts +1 -0
- package/src/core/guard/storage.ts +3 -2
- package/src/core/hooks/adapter/behaviors/claude-code.ts +33 -0
- package/src/core/hooks/adapter/behaviors/codex.ts +96 -0
- package/src/core/hooks/adapter/behaviors/cursor.ts +37 -0
- package/src/core/hooks/adapter/behaviors/index.ts +31 -0
- package/src/core/hooks/adapter/behaviors/openclaw.ts +36 -0
- package/src/core/hooks/adapter/behaviors/opencode.ts +36 -0
- package/src/core/hooks/adapter/behaviors/types.ts +110 -0
- package/src/core/hooks/adapter/detect.ts +2 -3
- package/src/core/hooks/adapter/events.ts +72 -1
- package/src/core/hooks/adapter/opencode-plugin.ts +177 -0
- package/src/core/hooks/adapter/output.ts +8 -1
- package/src/core/hooks/adapter/runtime-telemetry.ts +3 -1
- package/src/core/hooks/adapter/wiring.ts +198 -16
- package/src/core/hooks/cli.ts +776 -539
- package/src/core/hooks/effects/image-capture.ts +2 -1
- package/src/core/hooks/prompt-context/contract.ts +1 -0
- package/src/core/hooks/resolve/transcript.ts +42 -5
- package/src/core/hooks/run-markers.ts +132 -0
- package/src/core/hooks/session-name-presence.ts +10 -3
- package/src/core/hooks/shell-waiter.ts +166 -0
- package/src/core/resources/service.ts +5 -4
- package/src/core/semantic/review.ts +5 -4
- package/src/core/semantic/service.ts +15 -14
- package/src/core/semantic/storage.ts +5 -4
- package/src/core/servers/index.ts +712 -0
- package/src/core/servers/net.ts +283 -0
- package/src/core/servers/tunnels.ts +39 -0
- package/src/core/storage/atomic-json.ts +7 -3
- package/src/core/storage/builtins.ts +1 -0
- package/src/core/storage/durable-history.ts +6 -5
- package/src/core/storage/maintenance-providers.ts +2 -1
- package/src/core/storage/maintenance.ts +7 -6
- package/src/core/storage/metrics.ts +5 -1
- package/src/core/storage/modes.ts +53 -0
- package/src/core/storage/process-log.ts +3 -2
- package/src/core/storage/receipts.ts +4 -3
- package/src/core/storage/segments.ts +7 -6
- package/src/core/supervisor/hook-health.ts +4 -4
- package/src/core/supervisor/service.ts +7 -6
- package/src/core/work/state.ts +8 -7
- package/src/core/workflow/adapters.ts +15 -0
- package/src/core/workflow/approvals.ts +6 -5
- package/src/core/workflow/billing.ts +34 -4
- package/src/core/workflow/durable-record.ts +4 -3
- package/src/core/workflow/engine.ts +38 -1
- package/src/core/workflow/live-session-v3.ts +2 -3
- package/src/core/workflow/run-state.ts +3 -2
- package/src/core/workflow/sandbox-projection.ts +38 -2
- package/src/core/workflow/spawn-claude.ts +5 -1
- package/src/core/workflow/spawn-codex.ts +18 -1
- package/src/core/workflow/spawn-cursor.ts +5 -1
- package/src/core/workflow/spawn-opencode.ts +153 -0
- package/src/core/workflow/transcript.ts +3 -2
- package/src/core/workflow/types.ts +62 -2
- package/src/core/workflow/worker-access.ts +525 -0
- package/src/core/workflow/workspaces/leases.ts +5 -4
- package/src/core/workflow/workspaces/local-git.ts +3 -2
- package/src/core/workflow/workspaces/paths.ts +2 -1
- package/src/core/workflow/workspaces/state.ts +10 -9
- package/src/lazy-commands.ts +11 -1
- package/src/lib/agent-browser/client.ts +18 -0
- package/src/lib/browser/batch-steps.ts +79 -0
- package/src/lib/browser/client.ts +147 -9
- package/src/lib/browser/collect/collector.ts +306 -0
- package/src/lib/browser/collect/fields.ts +87 -0
- package/src/lib/browser/collect/index.ts +47 -0
- package/src/lib/browser/collect/page-driver.ts +327 -0
- package/src/lib/browser/collect/presets.ts +237 -0
- package/src/lib/browser/collect/scroll-plan.ts +179 -0
- package/src/lib/browser/identity.ts +64 -0
- package/src/lib/browser/index.ts +16 -1
- package/src/lib/browser/launch-args.ts +53 -1
- package/src/lib/browser/page-review-judge.ts +16 -0
- package/src/lib/browser/qa-run-contracts.ts +11 -0
- package/src/lib/browser/qa-run.ts +1 -0
- package/src/lib/browser/user-agent.ts +130 -0
- package/src/lib/browser/windows-chrome.ts +227 -0
- package/src/lib/claude-desktop-share.ts +511 -0
- package/src/lib/disk-usage.ts +347 -0
- package/src/lib/docs-lint.ts +8 -3
- package/src/lib/docs-metadata-managed.ts +21 -0
- package/src/lib/guarded-remove.ts +376 -0
- package/src/lib/identities/assume.ts +7 -7
- package/src/lib/instructions/apply.ts +2 -0
- package/src/lib/instructions/templates.ts +8 -8
- package/src/lib/pace/index.ts +14 -0
- package/src/lib/pace/pace.ts +370 -0
- package/src/lib/tunnel/error-page.ts +25 -9
- package/src/lib/tunnel/forward-headers.ts +16 -0
- package/src/lib/tunnel/gate.ts +39 -10
- package/src/lib/tunnel/path-scope.ts +73 -0
- package/src/lib/tunnel/state.ts +20 -3
- package/src/lib/webview/index.ts +13 -0
- package/src/lib/webview/webview.ts +457 -0
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
import {
|
|
2
|
+
planScrollStep,
|
|
3
|
+
type Rng,
|
|
4
|
+
type ScrollPacing,
|
|
5
|
+
type ScrollStepPlan,
|
|
6
|
+
uniform,
|
|
7
|
+
type WheelTick,
|
|
8
|
+
} from "./scroll-plan.ts";
|
|
9
|
+
|
|
10
|
+
/** One item as read from the page in a single harvest. */
|
|
11
|
+
export interface HarvestedItem {
|
|
12
|
+
key: string;
|
|
13
|
+
fields: Record<string, unknown>;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface CollectedItem {
|
|
17
|
+
key: string;
|
|
18
|
+
/** Step index the item was first seen at (0 is the initial harvest). */
|
|
19
|
+
firstSeenStep: number;
|
|
20
|
+
[field: string]: unknown;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface PageMetrics {
|
|
24
|
+
scrollTop: number;
|
|
25
|
+
scrollHeight: number;
|
|
26
|
+
viewportHeight: number;
|
|
27
|
+
atBottom: boolean;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** What the collector needs from a page. The Playwright driver implements it. */
|
|
31
|
+
export interface CollectDriver {
|
|
32
|
+
harvest(): Promise<HarvestedItem[]>;
|
|
33
|
+
metrics(): Promise<PageMetrics>;
|
|
34
|
+
/** Scroll by these wheel notches. Returns true when a non-wheel fallback was used. */
|
|
35
|
+
wheel(ticks: WheelTick[]): Promise<boolean>;
|
|
36
|
+
/** Click up to `limit` unexpanded "show more" buttons; returns how many were clicked. */
|
|
37
|
+
expand(limit: number): Promise<number>;
|
|
38
|
+
/** A short reason when the page shows a login wall or rate limit, else null. */
|
|
39
|
+
blocked(): Promise<string | null>;
|
|
40
|
+
sleep(ms: number): Promise<void>;
|
|
41
|
+
now(): number;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface CollectLimits {
|
|
45
|
+
/** Stop once this many unique items are collected (null: no item cap). */
|
|
46
|
+
maxItems: number | null;
|
|
47
|
+
/** Stop after this many scroll steps. */
|
|
48
|
+
maxScrolls: number;
|
|
49
|
+
/** Stop once this much wall time has passed, in ms. */
|
|
50
|
+
maxMs: number;
|
|
51
|
+
/** Stop after this many consecutive steps with no new items and no page growth. */
|
|
52
|
+
idleSteps: number;
|
|
53
|
+
/** Expand clicks per step (0 disables expansion). */
|
|
54
|
+
expandPerStep: number;
|
|
55
|
+
/** Expand clicks per run. */
|
|
56
|
+
expandTotal: number;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export const DEFAULT_COLLECT_LIMITS: CollectLimits = {
|
|
60
|
+
maxItems: null,
|
|
61
|
+
maxScrolls: 60,
|
|
62
|
+
maxMs: 300_000,
|
|
63
|
+
idleSteps: 5,
|
|
64
|
+
expandPerStep: 0,
|
|
65
|
+
expandTotal: 50,
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
export type StopReason =
|
|
69
|
+
| "max-items"
|
|
70
|
+
| "max-scrolls"
|
|
71
|
+
| "time-budget"
|
|
72
|
+
| "idle"
|
|
73
|
+
| "end-of-feed"
|
|
74
|
+
| "blocked"
|
|
75
|
+
| "interrupted";
|
|
76
|
+
|
|
77
|
+
export interface CollectStats {
|
|
78
|
+
/** Scroll steps taken (the initial harvest is step 0 and not counted). */
|
|
79
|
+
steps: number;
|
|
80
|
+
harvests: number;
|
|
81
|
+
items: number;
|
|
82
|
+
/** Sightings of an already-collected key across all harvests. */
|
|
83
|
+
duplicates: number;
|
|
84
|
+
expanded: number;
|
|
85
|
+
readingPauses: number;
|
|
86
|
+
scrollBacks: number;
|
|
87
|
+
/** Steps where wheel scrolling did not move the page and a fallback ran. */
|
|
88
|
+
scrollFallbacks: number;
|
|
89
|
+
elapsedMs: number;
|
|
90
|
+
stopReason: StopReason;
|
|
91
|
+
stopDetail: string | null;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export interface CollectResult {
|
|
95
|
+
items: CollectedItem[];
|
|
96
|
+
stats: CollectStats;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export interface CollectRunOptions {
|
|
100
|
+
limits: CollectLimits;
|
|
101
|
+
pacing: ScrollPacing;
|
|
102
|
+
rng: Rng;
|
|
103
|
+
/** Polled between and during pauses; true stops the run with "interrupted". */
|
|
104
|
+
shouldStop?: () => boolean;
|
|
105
|
+
onStep?: (info: { step: number; items: number; added: number; plan: ScrollStepPlan }) => void;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function isEmpty(value: unknown): boolean {
|
|
109
|
+
return (
|
|
110
|
+
value === null ||
|
|
111
|
+
value === undefined ||
|
|
112
|
+
value === "" ||
|
|
113
|
+
(Array.isArray(value) && value.length === 0)
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Ordered, de-duplicated item store. The first sighting fixes an item's
|
|
119
|
+
* position and step; later sightings only fill in what was missing: empty
|
|
120
|
+
* fields, longer text (an expanded "show more"), and new array members.
|
|
121
|
+
*/
|
|
122
|
+
export class ItemStore {
|
|
123
|
+
private byKey = new Map<string, CollectedItem>();
|
|
124
|
+
duplicates = 0;
|
|
125
|
+
|
|
126
|
+
get size(): number {
|
|
127
|
+
return this.byKey.size;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
add(items: HarvestedItem[], step: number, maxItems: number | null = null): number {
|
|
131
|
+
let added = 0;
|
|
132
|
+
for (const item of items) {
|
|
133
|
+
if (!item.key) continue;
|
|
134
|
+
const existing = this.byKey.get(item.key);
|
|
135
|
+
if (existing) {
|
|
136
|
+
this.duplicates++;
|
|
137
|
+
mergeFields(existing, item.fields);
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
if (maxItems !== null && this.byKey.size >= maxItems) continue;
|
|
141
|
+
this.byKey.set(item.key, { key: item.key, firstSeenStep: step, ...item.fields });
|
|
142
|
+
added++;
|
|
143
|
+
}
|
|
144
|
+
return added;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
items(): CollectedItem[] {
|
|
148
|
+
return [...this.byKey.values()];
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function mergeFields(target: CollectedItem, fields: Record<string, unknown>): void {
|
|
153
|
+
for (const [name, value] of Object.entries(fields)) {
|
|
154
|
+
const current = target[name];
|
|
155
|
+
if (isEmpty(value)) continue;
|
|
156
|
+
if (isEmpty(current)) {
|
|
157
|
+
target[name] = value;
|
|
158
|
+
} else if (typeof current === "string" && typeof value === "string") {
|
|
159
|
+
if (value.length > current.length) target[name] = value;
|
|
160
|
+
} else if (Array.isArray(current) && Array.isArray(value)) {
|
|
161
|
+
const merged = [...current];
|
|
162
|
+
for (const v of value) if (!merged.includes(v)) merged.push(v);
|
|
163
|
+
target[name] = merged;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Scroll a feed like a reader and collect every item that passes through the
|
|
170
|
+
* DOM. Each step harvests right after scrolling and again after the pause, so
|
|
171
|
+
* a virtualized list cannot drop an item between two harvests.
|
|
172
|
+
*/
|
|
173
|
+
export async function runCollect(
|
|
174
|
+
driver: CollectDriver,
|
|
175
|
+
options: CollectRunOptions,
|
|
176
|
+
): Promise<CollectResult> {
|
|
177
|
+
const { limits, pacing, rng } = options;
|
|
178
|
+
const store = new ItemStore();
|
|
179
|
+
const started = driver.now();
|
|
180
|
+
const stats: CollectStats = {
|
|
181
|
+
steps: 0,
|
|
182
|
+
harvests: 0,
|
|
183
|
+
items: 0,
|
|
184
|
+
duplicates: 0,
|
|
185
|
+
expanded: 0,
|
|
186
|
+
readingPauses: 0,
|
|
187
|
+
scrollBacks: 0,
|
|
188
|
+
scrollFallbacks: 0,
|
|
189
|
+
elapsedMs: 0,
|
|
190
|
+
stopReason: "idle",
|
|
191
|
+
stopDetail: null,
|
|
192
|
+
};
|
|
193
|
+
const elapsed = () => driver.now() - started;
|
|
194
|
+
const interrupted = () => options.shouldStop?.() === true;
|
|
195
|
+
const full = () => limits.maxItems !== null && store.size >= limits.maxItems;
|
|
196
|
+
|
|
197
|
+
const harvest = async (step: number): Promise<number> => {
|
|
198
|
+
stats.harvests++;
|
|
199
|
+
return store.add(await driver.harvest(), step, limits.maxItems);
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
/** Sleep in slices so an interrupt or the time budget cuts a pause short. */
|
|
203
|
+
const pause = async (ms: number) => {
|
|
204
|
+
let remaining = Math.min(ms, Math.max(0, limits.maxMs - elapsed()));
|
|
205
|
+
while (remaining > 0 && !interrupted()) {
|
|
206
|
+
const slice = Math.min(remaining, 250);
|
|
207
|
+
await driver.sleep(slice);
|
|
208
|
+
remaining -= slice;
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
const expand = async (step: number): Promise<number> => {
|
|
213
|
+
if (limits.expandPerStep <= 0) return 0;
|
|
214
|
+
const budget = Math.min(limits.expandPerStep, limits.expandTotal - stats.expanded);
|
|
215
|
+
if (budget <= 0) return 0;
|
|
216
|
+
const clicked = await driver.expand(budget);
|
|
217
|
+
stats.expanded += clicked;
|
|
218
|
+
return clicked > 0 ? harvest(step) : 0;
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
const stop = (reason: StopReason, detail: string | null = null) => {
|
|
222
|
+
stats.stopReason = reason;
|
|
223
|
+
stats.stopDetail = detail;
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
await harvest(0);
|
|
227
|
+
await expand(0);
|
|
228
|
+
let idle = 0;
|
|
229
|
+
let before = await driver.metrics();
|
|
230
|
+
|
|
231
|
+
for (;;) {
|
|
232
|
+
if (interrupted()) {
|
|
233
|
+
stop("interrupted");
|
|
234
|
+
break;
|
|
235
|
+
}
|
|
236
|
+
if (full()) {
|
|
237
|
+
stop("max-items", `collected ${store.size} items`);
|
|
238
|
+
break;
|
|
239
|
+
}
|
|
240
|
+
if (stats.steps >= limits.maxScrolls) {
|
|
241
|
+
stop("max-scrolls", `took ${stats.steps} scroll steps`);
|
|
242
|
+
break;
|
|
243
|
+
}
|
|
244
|
+
if (elapsed() >= limits.maxMs) {
|
|
245
|
+
stop("time-budget", `ran ${Math.round(elapsed() / 1000)} s`);
|
|
246
|
+
break;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
const step = ++stats.steps;
|
|
250
|
+
const plan = planScrollStep(rng, pacing, before.viewportHeight);
|
|
251
|
+
let added = 0;
|
|
252
|
+
if (plan.back.length > 0) {
|
|
253
|
+
stats.scrollBacks++;
|
|
254
|
+
await driver.wheel(plan.back);
|
|
255
|
+
added += await harvest(step);
|
|
256
|
+
await pause(plan.backPauseMs);
|
|
257
|
+
}
|
|
258
|
+
if (await driver.wheel(plan.ticks)) stats.scrollFallbacks++;
|
|
259
|
+
added += await harvest(step);
|
|
260
|
+
if (plan.reading) stats.readingPauses++;
|
|
261
|
+
// Split the pause so items rendered mid-pause are harvested too.
|
|
262
|
+
const firstHalf = Math.round(plan.pauseMs * uniform(rng, { min: 0.35, max: 0.65 }));
|
|
263
|
+
await pause(firstHalf);
|
|
264
|
+
added += await harvest(step);
|
|
265
|
+
added += await expand(step);
|
|
266
|
+
await pause(plan.pauseMs - firstHalf);
|
|
267
|
+
added += await harvest(step);
|
|
268
|
+
|
|
269
|
+
const after = await driver.metrics();
|
|
270
|
+
options.onStep?.({ step, items: store.size, added, plan });
|
|
271
|
+
const grew = after.scrollHeight > before.scrollHeight;
|
|
272
|
+
const moved = after.scrollTop > before.scrollTop;
|
|
273
|
+
before = after;
|
|
274
|
+
|
|
275
|
+
if (added > 0 || grew) {
|
|
276
|
+
idle = 0;
|
|
277
|
+
continue;
|
|
278
|
+
}
|
|
279
|
+
if (full()) continue;
|
|
280
|
+
const blocked = await driver.blocked();
|
|
281
|
+
if (blocked) {
|
|
282
|
+
stop("blocked", blocked);
|
|
283
|
+
break;
|
|
284
|
+
}
|
|
285
|
+
idle++;
|
|
286
|
+
if (idle >= limits.idleSteps) {
|
|
287
|
+
if (after.atBottom) {
|
|
288
|
+
stop("end-of-feed", `no new items or page growth for ${idle} steps at the bottom`);
|
|
289
|
+
} else if (!moved) {
|
|
290
|
+
stop("idle", `the page stopped scrolling; no new items for ${idle} steps`);
|
|
291
|
+
} else {
|
|
292
|
+
stop("idle", `no new items or page growth for ${idle} steps`);
|
|
293
|
+
}
|
|
294
|
+
break;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
const items = store.items();
|
|
299
|
+
stats.items = items.length;
|
|
300
|
+
stats.duplicates = store.duplicates;
|
|
301
|
+
stats.elapsedMs = Math.round(elapsed());
|
|
302
|
+
if (items.length === 0 && stats.stopDetail && stats.stopReason !== "blocked") {
|
|
303
|
+
stats.stopDetail += " (the item selector matched nothing)";
|
|
304
|
+
}
|
|
305
|
+
return { items, stats };
|
|
306
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Field extractor grammar shared by presets and `--collect-field`.
|
|
3
|
+
*
|
|
4
|
+
* <name>=<selector>[@<attr>]
|
|
5
|
+
* <name>[]=<selector>[@<attr>] every match, as a de-duplicated array
|
|
6
|
+
*
|
|
7
|
+
* The selector runs inside each item. An empty selector or `:scope` means the
|
|
8
|
+
* item itself. Without `@attr` the value is the element's visible text; with
|
|
9
|
+
* it, the attribute (href and src resolve to absolute URLs).
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
export interface Extractor {
|
|
13
|
+
/** CSS selector relative to the item; "" means the item itself. */
|
|
14
|
+
selector: string;
|
|
15
|
+
/** Attribute to read; null reads visible text. */
|
|
16
|
+
attr: string | null;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface FieldSpec extends Extractor {
|
|
20
|
+
name: string;
|
|
21
|
+
/** Collect every match as an array instead of the first one. */
|
|
22
|
+
all: boolean;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** Item properties the collector owns; fields cannot reuse these names. */
|
|
26
|
+
export const RESERVED_FIELD_NAMES = new Set(["key", "firstSeenStep"]);
|
|
27
|
+
|
|
28
|
+
const NAME_RE = /^[A-Za-z_][\w-]*$/;
|
|
29
|
+
const ATTR_RE = /^[A-Za-z_:][-\w:.]*$/;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Parse `<selector>[@<attr>]`. The attribute separator is the last `@` that
|
|
33
|
+
* sits outside quotes and brackets, so `a[href*="@"]@href` works.
|
|
34
|
+
*/
|
|
35
|
+
export function parseExtractor(spec: string): Extractor {
|
|
36
|
+
const text = spec.trim();
|
|
37
|
+
let at = -1;
|
|
38
|
+
let quote: string | null = null;
|
|
39
|
+
let depth = 0;
|
|
40
|
+
for (let i = 0; i < text.length; i++) {
|
|
41
|
+
const ch = text[i];
|
|
42
|
+
if (quote) {
|
|
43
|
+
if (ch === "\\") i++;
|
|
44
|
+
else if (ch === quote) quote = null;
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
if (ch === '"' || ch === "'") quote = ch;
|
|
48
|
+
else if (ch === "[" || ch === "(") depth++;
|
|
49
|
+
else if (ch === "]" || ch === ")") depth = Math.max(0, depth - 1);
|
|
50
|
+
else if (ch === "@" && depth === 0) at = i;
|
|
51
|
+
}
|
|
52
|
+
let selector = text;
|
|
53
|
+
let attr: string | null = null;
|
|
54
|
+
if (at >= 0) {
|
|
55
|
+
const candidate = text.slice(at + 1).trim();
|
|
56
|
+
if (!ATTR_RE.test(candidate)) {
|
|
57
|
+
throw new Error(`Extractor "${spec}": "${candidate}" is not a valid attribute name.`);
|
|
58
|
+
}
|
|
59
|
+
attr = candidate;
|
|
60
|
+
selector = text.slice(0, at).trim();
|
|
61
|
+
}
|
|
62
|
+
if (selector === ":scope") selector = "";
|
|
63
|
+
return { selector, attr };
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** Parse `<name>=<extractor>` or `<name>[]=<extractor>`. */
|
|
67
|
+
export function parseFieldSpec(raw: string): FieldSpec {
|
|
68
|
+
const eq = raw.indexOf("=");
|
|
69
|
+
if (eq <= 0) {
|
|
70
|
+
throw new Error(
|
|
71
|
+
`--collect-field expects <name>=<selector>[@attr] (got "${raw}"). Example: time=time@datetime`,
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
let name = raw.slice(0, eq).trim();
|
|
75
|
+
let all = false;
|
|
76
|
+
if (name.endsWith("[]")) {
|
|
77
|
+
all = true;
|
|
78
|
+
name = name.slice(0, -2);
|
|
79
|
+
}
|
|
80
|
+
if (!NAME_RE.test(name)) {
|
|
81
|
+
throw new Error(`Field name "${name}" must start with a letter or _ and use word characters.`);
|
|
82
|
+
}
|
|
83
|
+
if (RESERVED_FIELD_NAMES.has(name)) {
|
|
84
|
+
throw new Error(`Field name "${name}" is reserved by the collector.`);
|
|
85
|
+
}
|
|
86
|
+
return { name, all, ...parseExtractor(raw.slice(eq + 1)) };
|
|
87
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export {
|
|
2
|
+
type CollectDriver,
|
|
3
|
+
type CollectedItem,
|
|
4
|
+
type CollectLimits,
|
|
5
|
+
type CollectResult,
|
|
6
|
+
type CollectRunOptions,
|
|
7
|
+
type CollectStats,
|
|
8
|
+
DEFAULT_COLLECT_LIMITS,
|
|
9
|
+
type HarvestedItem,
|
|
10
|
+
ItemStore,
|
|
11
|
+
type PageMetrics,
|
|
12
|
+
runCollect,
|
|
13
|
+
type StopReason,
|
|
14
|
+
} from "./collector.ts";
|
|
15
|
+
export {
|
|
16
|
+
type Extractor,
|
|
17
|
+
type FieldSpec,
|
|
18
|
+
parseExtractor,
|
|
19
|
+
parseFieldSpec,
|
|
20
|
+
RESERVED_FIELD_NAMES,
|
|
21
|
+
} from "./fields.ts";
|
|
22
|
+
export { createPageDriver, type PageDriverDeps } from "./page-driver.ts";
|
|
23
|
+
export {
|
|
24
|
+
COLLECT_PRESETS,
|
|
25
|
+
type CollectPreset,
|
|
26
|
+
type CollectSpecOverrides,
|
|
27
|
+
presetNames,
|
|
28
|
+
type ResolvedCollectSpec,
|
|
29
|
+
resolveCollectSpec,
|
|
30
|
+
} from "./presets.ts";
|
|
31
|
+
export {
|
|
32
|
+
createRng,
|
|
33
|
+
DEFAULT_SCROLL_PACING,
|
|
34
|
+
PACING_LIMITS,
|
|
35
|
+
parseProbability,
|
|
36
|
+
parseRange,
|
|
37
|
+
planScrollStep,
|
|
38
|
+
type Range,
|
|
39
|
+
type Rng,
|
|
40
|
+
randomSeed,
|
|
41
|
+
type ScrollPacing,
|
|
42
|
+
type ScrollStepPlan,
|
|
43
|
+
scrollPacingFromEnv,
|
|
44
|
+
uniform,
|
|
45
|
+
type WheelTick,
|
|
46
|
+
wheelTicks,
|
|
47
|
+
} from "./scroll-plan.ts";
|