harnery 0.34.1 → 0.36.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/dist/commander.d.ts +30 -5
- package/dist/commander.d.ts.map +1 -1
- package/dist/commander.js +124 -94
- package/dist/commands/agents.d.ts +37 -6
- package/dist/commands/agents.d.ts.map +1 -1
- package/dist/commands/agents.js +466 -371
- package/dist/commands/backup.d.ts.map +1 -1
- package/dist/commands/backup.js +10 -10
- package/dist/commands/browse-session.d.ts.map +1 -1
- package/dist/commands/browse-session.js +12 -0
- package/dist/commands/browse.d.ts +1 -1
- package/dist/commands/browse.d.ts.map +1 -1
- package/dist/commands/browse.js +31 -6
- package/dist/commands/conversations.d.ts +10 -0
- package/dist/commands/conversations.d.ts.map +1 -0
- package/dist/commands/conversations.js +201 -0
- package/dist/commands/decision.d.ts.map +1 -1
- package/dist/commands/decision.js +2 -2
- package/dist/commands/deinit.d.ts.map +1 -1
- package/dist/commands/deinit.js +5 -0
- package/dist/commands/docs.d.ts.map +1 -1
- package/dist/commands/docs.js +13 -2
- package/dist/commands/doctor.d.ts +5 -0
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +51 -7
- package/dist/commands/events.d.ts.map +1 -1
- package/dist/commands/events.js +18 -1
- package/dist/commands/fetch.js +6 -5
- package/dist/commands/files.d.ts +22 -0
- package/dist/commands/files.d.ts.map +1 -0
- package/dist/commands/files.js +113 -0
- package/dist/commands/governor.js +14 -12
- package/dist/commands/inbox.d.ts +5 -0
- package/dist/commands/inbox.d.ts.map +1 -0
- package/dist/commands/inbox.js +57 -0
- package/dist/commands/init.d.ts +4 -5
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +63 -13
- package/dist/commands/ledger-v3.d.ts.map +1 -1
- package/dist/commands/ledger-v3.js +347 -1
- package/dist/commands/logs.d.ts +4 -0
- package/dist/commands/logs.d.ts.map +1 -0
- package/dist/commands/logs.js +169 -0
- package/dist/commands/messages.d.ts +5 -0
- package/dist/commands/messages.d.ts.map +1 -0
- package/dist/commands/messages.js +45 -0
- package/dist/commands/outline.d.ts +1 -1
- package/dist/commands/outline.d.ts.map +1 -1
- package/dist/commands/outline.js +2 -2
- package/dist/commands/presence.d.ts.map +1 -1
- package/dist/commands/presence.js +2 -2
- package/dist/commands/read.d.ts +1 -1
- package/dist/commands/read.d.ts.map +1 -1
- package/dist/commands/read.js +2 -2
- package/dist/commands/semantic.d.ts +4 -0
- package/dist/commands/semantic.d.ts.map +1 -0
- package/dist/commands/semantic.js +199 -0
- package/dist/commands/storage.d.ts +4 -0
- package/dist/commands/storage.d.ts.map +1 -0
- package/dist/commands/storage.js +238 -0
- package/dist/commands/tunnel.d.ts +5 -1
- package/dist/commands/tunnel.d.ts.map +1 -1
- package/dist/commands/tunnel.js +44 -31
- package/dist/commands/web.d.ts +3 -0
- package/dist/commands/web.d.ts.map +1 -1
- package/dist/commands/web.js +84 -7
- package/dist/commands/work.js +3 -3
- package/dist/commands/workflow.js +13 -13
- package/dist/core/adapters/profiles.d.ts +1 -1
- package/dist/core/agents/canonical-emit.d.ts +3 -0
- package/dist/core/agents/canonical-emit.d.ts.map +1 -1
- package/dist/core/agents/canonical-emit.js +12 -0
- package/dist/core/agents/claim-path.d.ts +11 -0
- package/dist/core/agents/claim-path.d.ts.map +1 -0
- package/dist/core/agents/claim-path.js +22 -0
- package/dist/core/agents/cli.js +209 -39
- package/dist/core/agents/coord-client.d.ts +29 -3
- package/dist/core/agents/coord-client.d.ts.map +1 -1
- package/dist/core/agents/coord-client.js +88 -9
- package/dist/core/agents/live-authority-v3.d.ts +47 -1
- package/dist/core/agents/live-authority-v3.d.ts.map +1 -1
- package/dist/core/agents/live-authority-v3.js +245 -13
- package/dist/core/agents/live-lifecycle-v3.js +9 -4
- package/dist/core/agents/live-observation-v3.d.ts.map +1 -1
- package/dist/core/agents/live-observation-v3.js +8 -3
- package/dist/core/agents/render/prompt-context.d.ts +9 -3
- package/dist/core/agents/render/prompt-context.d.ts.map +1 -1
- package/dist/core/agents/render/prompt-context.js +36 -17
- 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 +115 -22
- package/dist/core/agents/rules/verdict.d.ts +1 -0
- package/dist/core/agents/rules/verdict.d.ts.map +1 -1
- package/dist/core/agents/session-events.d.ts.map +1 -1
- package/dist/core/agents/session-events.js +4 -0
- package/dist/core/agents/session-finalization-state-v3.js +1 -1
- package/dist/core/agents/session-finalizer-v3.js +5 -1
- package/dist/core/agents/session-name-display.d.ts +1 -0
- package/dist/core/agents/session-name-display.d.ts.map +1 -1
- package/dist/core/agents/session-name-display.js +8 -1
- package/dist/core/agents/state/activity-log.d.ts +3 -0
- package/dist/core/agents/state/activity-log.d.ts.map +1 -1
- package/dist/core/agents/state/activity-log.js +6 -3
- package/dist/core/agents/state/heartbeat-reader.d.ts +46 -0
- package/dist/core/agents/state/heartbeat-reader.d.ts.map +1 -0
- package/dist/core/agents/state/heartbeat-reader.js +25 -0
- package/dist/core/agents/state/heartbeat-writer.d.ts +9 -48
- package/dist/core/agents/state/heartbeat-writer.d.ts.map +1 -1
- package/dist/core/agents/state/heartbeat-writer.js +34 -34
- package/dist/core/agents/state/live-coordination-view.d.ts +6 -8
- package/dist/core/agents/state/live-coordination-view.d.ts.map +1 -1
- package/dist/core/agents/state/live-coordination-view.js +16 -67
- package/dist/core/agents/state/live-coordination-writer.d.ts +12 -0
- package/dist/core/agents/state/live-coordination-writer.d.ts.map +1 -0
- package/dist/core/agents/state/live-coordination-writer.js +92 -0
- package/dist/core/agents/state/names.d.ts +9 -1
- package/dist/core/agents/state/names.d.ts.map +1 -1
- package/dist/core/agents/state/names.js +190 -182
- package/dist/core/agents/state/stale-sweep.d.ts.map +1 -1
- package/dist/core/agents/state/stale-sweep.js +23 -5
- package/dist/core/artifacts/constants.d.ts +5 -0
- package/dist/core/artifacts/constants.d.ts.map +1 -0
- package/dist/core/artifacts/constants.js +4 -0
- package/dist/core/artifacts/index.d.ts +24 -3
- package/dist/core/artifacts/index.d.ts.map +1 -1
- package/dist/core/artifacts/index.js +96 -8
- package/dist/core/config.d.ts +62 -4
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +98 -4
- package/dist/core/conversations/archive.d.ts +49 -0
- package/dist/core/conversations/archive.d.ts.map +1 -0
- package/dist/core/conversations/archive.js +136 -0
- package/dist/core/conversations/catalog.d.ts +10 -0
- package/dist/core/conversations/catalog.d.ts.map +1 -0
- package/dist/core/conversations/catalog.js +72 -0
- package/dist/core/conversations/context-pack.d.ts +6 -0
- package/dist/core/conversations/context-pack.d.ts.map +1 -0
- package/dist/core/conversations/context-pack.js +60 -0
- package/dist/core/conversations/contract.d.ts +155 -0
- package/dist/core/conversations/contract.d.ts.map +1 -0
- package/dist/core/conversations/contract.js +1 -0
- package/dist/core/conversations/evaluation.d.ts +16 -0
- package/dist/core/conversations/evaluation.d.ts.map +1 -0
- package/dist/core/conversations/evaluation.js +9 -0
- package/dist/core/conversations/index.d.ts +10 -0
- package/dist/core/conversations/index.d.ts.map +1 -0
- package/dist/core/conversations/index.js +9 -0
- package/dist/core/conversations/lifecycle.d.ts +28 -0
- package/dist/core/conversations/lifecycle.d.ts.map +1 -0
- package/dist/core/conversations/lifecycle.js +29 -0
- package/dist/core/conversations/normalize.d.ts +14 -0
- package/dist/core/conversations/normalize.d.ts.map +1 -0
- package/dist/core/conversations/normalize.js +82 -0
- package/dist/core/conversations/query.d.ts +8 -0
- package/dist/core/conversations/query.d.ts.map +1 -0
- package/dist/core/conversations/query.js +280 -0
- package/dist/core/conversations/search-index.d.ts +9 -0
- package/dist/core/conversations/search-index.d.ts.map +1 -0
- package/dist/core/conversations/search-index.js +29 -0
- package/dist/core/events/legacy-storage/canary.d.ts +18 -0
- package/dist/core/events/legacy-storage/canary.d.ts.map +1 -0
- package/dist/core/events/legacy-storage/canary.js +150 -0
- package/dist/core/events/legacy-storage/fence.d.ts +15 -0
- package/dist/core/events/legacy-storage/fence.d.ts.map +1 -0
- package/dist/core/events/legacy-storage/fence.js +115 -0
- package/dist/core/events/legacy-storage/index.d.ts +6 -0
- package/dist/core/events/legacy-storage/index.d.ts.map +1 -0
- package/dist/core/events/legacy-storage/index.js +5 -0
- package/dist/core/events/legacy-storage/inventory.d.ts +10 -0
- package/dist/core/events/legacy-storage/inventory.d.ts.map +1 -0
- package/dist/core/events/legacy-storage/inventory.js +40 -0
- package/dist/core/events/legacy-storage/manifest.d.ts +23 -0
- package/dist/core/events/legacy-storage/manifest.d.ts.map +1 -0
- package/dist/core/events/legacy-storage/manifest.js +108 -0
- package/dist/core/events/legacy-storage/reader.d.ts +15 -0
- package/dist/core/events/legacy-storage/reader.d.ts.map +1 -0
- package/dist/core/events/legacy-storage/reader.js +154 -0
- package/dist/core/events/v3/authority-outbox.d.ts +7 -2
- package/dist/core/events/v3/authority-outbox.d.ts.map +1 -1
- package/dist/core/events/v3/authority-outbox.js +16 -3
- package/dist/core/events/v3/base-contract.d.ts +851 -16
- package/dist/core/events/v3/base-contract.d.ts.map +1 -1
- package/dist/core/events/v3/base-contract.js +50 -7
- package/dist/core/events/v3/bootstrap.d.ts +39 -0
- package/dist/core/events/v3/bootstrap.d.ts.map +1 -1
- package/dist/core/events/v3/bootstrap.js +167 -3
- package/dist/core/events/v3/capabilities.d.ts +11 -0
- package/dist/core/events/v3/capabilities.d.ts.map +1 -1
- package/dist/core/events/v3/capabilities.js +26 -3
- package/dist/core/events/v3/control-witness.d.ts +44 -0
- package/dist/core/events/v3/control-witness.d.ts.map +1 -0
- package/dist/core/events/v3/control-witness.js +233 -0
- package/dist/core/events/v3/control-writer.d.ts +4 -0
- package/dist/core/events/v3/control-writer.d.ts.map +1 -0
- package/dist/core/events/v3/control-writer.js +16 -0
- package/dist/core/events/v3/control.d.ts +8 -2
- package/dist/core/events/v3/control.d.ts.map +1 -1
- package/dist/core/events/v3/control.js +46 -18
- package/dist/core/events/v3/coordination-transaction-recovery.d.ts +42 -0
- package/dist/core/events/v3/coordination-transaction-recovery.d.ts.map +1 -0
- package/dist/core/events/v3/coordination-transaction-recovery.js +342 -0
- package/dist/core/events/v3/coordination-view.d.ts.map +1 -1
- package/dist/core/events/v3/coordination-view.js +16 -1
- package/dist/core/events/v3/generated.d.ts +1 -1
- package/dist/core/events/v3/generated.js +1 -1
- package/dist/core/events/v3/index.d.ts +8 -5
- package/dist/core/events/v3/index.d.ts.map +1 -1
- package/dist/core/events/v3/index.js +7 -4
- package/dist/core/events/v3/latency.d.ts +31 -1
- package/dist/core/events/v3/latency.d.ts.map +1 -1
- package/dist/core/events/v3/latency.js +127 -3
- package/dist/core/events/v3/live-route-observer.d.ts +31 -0
- package/dist/core/events/v3/live-route-observer.d.ts.map +1 -0
- package/dist/core/events/v3/live-route-observer.js +58 -0
- package/dist/core/events/v3/live-routing.d.ts +42 -20
- package/dist/core/events/v3/live-routing.d.ts.map +1 -1
- package/dist/core/events/v3/live-routing.js +153 -41
- package/dist/core/events/v3/producers/command-recorder.d.ts.map +1 -1
- package/dist/core/events/v3/producers/command-recorder.js +10 -1
- package/dist/core/events/v3/producers/coordination-recorder.d.ts +11 -1
- package/dist/core/events/v3/producers/coordination-recorder.d.ts.map +1 -1
- package/dist/core/events/v3/producers/coordination-recorder.js +90 -13
- package/dist/core/events/v3/producers/diagnostic-summaries.d.ts +129 -0
- package/dist/core/events/v3/producers/diagnostic-summaries.d.ts.map +1 -0
- package/dist/core/events/v3/producers/diagnostic-summaries.js +499 -0
- package/dist/core/events/v3/producers/hook-base.d.ts +17 -1
- package/dist/core/events/v3/producers/hook-base.d.ts.map +1 -1
- package/dist/core/events/v3/producers/hook-base.js +83 -2
- package/dist/core/events/v3/producers/intake.d.ts +13 -0
- package/dist/core/events/v3/producers/intake.d.ts.map +1 -1
- package/dist/core/events/v3/producers/intake.js +36 -2
- package/dist/core/events/v3/producers/producer-state-observer.d.ts +8 -0
- package/dist/core/events/v3/producers/producer-state-observer.d.ts.map +1 -0
- package/dist/core/events/v3/producers/producer-state-observer.js +45 -0
- package/dist/core/events/v3/producers/recorder.d.ts +117 -1
- package/dist/core/events/v3/producers/recorder.d.ts.map +1 -1
- package/dist/core/events/v3/producers/recorder.js +992 -27
- package/dist/core/events/v3/reader.d.ts +51 -0
- package/dist/core/events/v3/reader.d.ts.map +1 -1
- package/dist/core/events/v3/reader.js +181 -1
- package/dist/core/events/v3/rotation-config.d.ts +9 -0
- package/dist/core/events/v3/rotation-config.d.ts.map +1 -0
- package/dist/core/events/v3/rotation-config.js +91 -0
- package/dist/core/events/v3/runtime-build.d.ts +11 -0
- package/dist/core/events/v3/runtime-build.d.ts.map +1 -0
- package/dist/core/events/v3/runtime-build.js +39 -0
- package/dist/core/events/v3/runtime-identity.d.ts +5 -0
- package/dist/core/events/v3/runtime-identity.d.ts.map +1 -0
- package/dist/core/events/v3/runtime-identity.js +18 -0
- package/dist/core/events/v3/runtime-telemetry-capabilities.d.ts +52 -0
- package/dist/core/events/v3/runtime-telemetry-capabilities.d.ts.map +1 -0
- package/dist/core/events/v3/runtime-telemetry-capabilities.js +54 -0
- package/dist/core/events/v3/support-storage/classify.d.ts +46 -0
- package/dist/core/events/v3/support-storage/classify.d.ts.map +1 -0
- package/dist/core/events/v3/support-storage/classify.js +149 -0
- package/dist/core/events/v3/support-storage/eligibility.d.ts +29 -0
- package/dist/core/events/v3/support-storage/eligibility.d.ts.map +1 -0
- package/dist/core/events/v3/support-storage/eligibility.js +35 -0
- package/dist/core/events/v3/support-storage/index.d.ts +10 -0
- package/dist/core/events/v3/support-storage/index.d.ts.map +1 -0
- package/dist/core/events/v3/support-storage/index.js +9 -0
- package/dist/core/events/v3/support-storage/inventory.d.ts +30 -0
- package/dist/core/events/v3/support-storage/inventory.d.ts.map +1 -0
- package/dist/core/events/v3/support-storage/inventory.js +94 -0
- package/dist/core/events/v3/support-storage/logical-authority.d.ts +14 -0
- package/dist/core/events/v3/support-storage/logical-authority.d.ts.map +1 -0
- package/dist/core/events/v3/support-storage/logical-authority.js +104 -0
- package/dist/core/events/v3/support-storage/maintenance.d.ts +98 -0
- package/dist/core/events/v3/support-storage/maintenance.d.ts.map +1 -0
- package/dist/core/events/v3/support-storage/maintenance.js +352 -0
- package/dist/core/events/v3/support-storage/pack-contract.d.ts +59 -0
- package/dist/core/events/v3/support-storage/pack-contract.d.ts.map +1 -0
- package/dist/core/events/v3/support-storage/pack-contract.js +249 -0
- package/dist/core/events/v3/support-storage/pack-reader.d.ts +34 -0
- package/dist/core/events/v3/support-storage/pack-reader.d.ts.map +1 -0
- package/dist/core/events/v3/support-storage/pack-reader.js +258 -0
- package/dist/core/events/v3/support-storage/pack-writer.d.ts +30 -0
- package/dist/core/events/v3/support-storage/pack-writer.d.ts.map +1 -0
- package/dist/core/events/v3/support-storage/pack-writer.js +268 -0
- package/dist/core/events/v3/support-storage/recovery.d.ts +15 -0
- package/dist/core/events/v3/support-storage/recovery.d.ts.map +1 -0
- package/dist/core/events/v3/support-storage/recovery.js +22 -0
- package/dist/core/events/v3/turn-telemetry.d.ts +21 -6
- package/dist/core/events/v3/turn-telemetry.d.ts.map +1 -1
- package/dist/core/events/v3/turn-telemetry.js +32 -2
- package/dist/core/events/v3/writer.d.ts +13 -1
- package/dist/core/events/v3/writer.d.ts.map +1 -1
- package/dist/core/events/v3/writer.js +126 -12
- package/dist/core/governor/plan-read.d.ts.map +1 -1
- package/dist/core/governor/plan-read.js +5 -21
- package/dist/core/governor/planning.js +6 -8
- package/dist/core/governor/service-read.d.ts +12 -0
- package/dist/core/governor/service-read.d.ts.map +1 -1
- package/dist/core/governor/service-read.js +266 -2
- package/dist/core/governor/service.d.ts +1 -0
- package/dist/core/governor/service.d.ts.map +1 -1
- package/dist/core/governor/service.js +53 -18
- package/dist/core/guard/evidence-v3.d.ts.map +1 -1
- package/dist/core/guard/evidence-v3.js +2 -0
- package/dist/core/hooks/adapter/events.d.ts.map +1 -1
- package/dist/core/hooks/adapter/events.js +1 -0
- package/dist/core/hooks/adapter/output.d.ts +4 -2
- package/dist/core/hooks/adapter/output.d.ts.map +1 -1
- package/dist/core/hooks/adapter/output.js +13 -5
- package/dist/core/hooks/adapter/parse.d.ts +3 -0
- package/dist/core/hooks/adapter/parse.d.ts.map +1 -1
- package/dist/core/hooks/adapter/parse.js +14 -0
- package/dist/core/hooks/adapter/runtime-telemetry.d.ts +142 -0
- package/dist/core/hooks/adapter/runtime-telemetry.d.ts.map +1 -0
- package/dist/core/hooks/adapter/runtime-telemetry.js +869 -0
- package/dist/core/hooks/cli.js +318 -61
- package/dist/core/hooks/effects/image-capture.d.ts +1 -1
- package/dist/core/hooks/effects/image-capture.d.ts.map +1 -1
- package/dist/core/hooks/effects/image-capture.js +4 -2
- package/dist/core/hooks/remediation-cap.d.ts +39 -0
- package/dist/core/hooks/remediation-cap.d.ts.map +1 -0
- package/dist/core/hooks/remediation-cap.js +63 -0
- package/dist/core/hooks/resolve/coord-root.d.ts +22 -9
- package/dist/core/hooks/resolve/coord-root.d.ts.map +1 -1
- package/dist/core/hooks/resolve/coord-root.js +92 -11
- package/dist/core/hooks/resolve/owner.d.ts.map +1 -1
- package/dist/core/hooks/resolve/owner.js +5 -0
- package/dist/core/hooks/resolve/transcript.d.ts +33 -9
- package/dist/core/hooks/resolve/transcript.d.ts.map +1 -1
- package/dist/core/hooks/resolve/transcript.js +33 -10
- package/dist/core/inbox/contract.d.ts +64 -0
- package/dist/core/inbox/contract.d.ts.map +1 -0
- package/dist/core/inbox/contract.js +13 -0
- package/dist/core/inbox/index.d.ts +5 -0
- package/dist/core/inbox/index.d.ts.map +1 -0
- package/dist/core/inbox/index.js +4 -0
- package/dist/core/inbox/lifecycle.d.ts +22 -0
- package/dist/core/inbox/lifecycle.d.ts.map +1 -0
- package/dist/core/inbox/lifecycle.js +41 -0
- package/dist/core/inbox/service.d.ts +36 -0
- package/dist/core/inbox/service.d.ts.map +1 -0
- package/dist/core/inbox/service.js +210 -0
- package/dist/core/inbox/watcher.d.ts +7 -0
- package/dist/core/inbox/watcher.d.ts.map +1 -0
- package/dist/core/inbox/watcher.js +26 -0
- package/dist/core/presence/codec-digest.d.ts.map +1 -1
- package/dist/core/presence/codec-digest.js +14 -3
- package/dist/core/presence/relay-client.d.ts +1 -0
- package/dist/core/presence/relay-client.d.ts.map +1 -1
- package/dist/core/presence/relay-client.js +52 -8
- package/dist/core/semantic/adapters.d.ts +37 -0
- package/dist/core/semantic/adapters.d.ts.map +1 -0
- package/dist/core/semantic/adapters.js +360 -0
- package/dist/core/semantic/contract.d.ts +1072 -0
- package/dist/core/semantic/contract.d.ts.map +1 -0
- package/dist/core/semantic/contract.js +331 -0
- package/dist/core/semantic/evidence.d.ts +11 -0
- package/dist/core/semantic/evidence.d.ts.map +1 -0
- package/dist/core/semantic/evidence.js +262 -0
- package/dist/core/semantic/index.d.ts +14 -0
- package/dist/core/semantic/index.d.ts.map +1 -0
- package/dist/core/semantic/index.js +13 -0
- package/dist/core/semantic/once.d.ts +38 -0
- package/dist/core/semantic/once.d.ts.map +1 -0
- package/dist/core/semantic/once.js +364 -0
- package/dist/core/semantic/prompt.d.ts +12 -0
- package/dist/core/semantic/prompt.d.ts.map +1 -0
- package/dist/core/semantic/prompt.js +83 -0
- package/dist/core/semantic/review.d.ts +144 -0
- package/dist/core/semantic/review.d.ts.map +1 -0
- package/dist/core/semantic/review.js +544 -0
- package/dist/core/semantic/routes.d.ts +10 -0
- package/dist/core/semantic/routes.d.ts.map +1 -0
- package/dist/core/semantic/routes.js +21 -0
- package/dist/core/semantic/scheduler.d.ts +27 -0
- package/dist/core/semantic/scheduler.d.ts.map +1 -0
- package/dist/core/semantic/scheduler.js +91 -0
- package/dist/core/semantic/service-status.d.ts +51 -0
- package/dist/core/semantic/service-status.d.ts.map +1 -0
- package/dist/core/semantic/service-status.js +140 -0
- package/dist/core/semantic/service.d.ts +52 -0
- package/dist/core/semantic/service.d.ts.map +1 -0
- package/dist/core/semantic/service.js +559 -0
- package/dist/core/semantic/soak.d.ts +75 -0
- package/dist/core/semantic/soak.d.ts.map +1 -0
- package/dist/core/semantic/soak.js +476 -0
- package/dist/core/semantic/storage.d.ts +81 -0
- package/dist/core/semantic/storage.d.ts.map +1 -0
- package/dist/core/semantic/storage.js +180 -0
- package/dist/core/semantic/usage.d.ts +43 -0
- package/dist/core/semantic/usage.d.ts.map +1 -0
- package/dist/core/semantic/usage.js +193 -0
- package/dist/core/semantic/validate.d.ts +18 -0
- package/dist/core/semantic/validate.d.ts.map +1 -0
- package/dist/core/semantic/validate.js +207 -0
- package/dist/core/storage/buffer.d.ts +28 -0
- package/dist/core/storage/buffer.d.ts.map +1 -0
- package/dist/core/storage/buffer.js +101 -0
- package/dist/core/storage/builtins.d.ts +3 -0
- package/dist/core/storage/builtins.d.ts.map +1 -0
- package/dist/core/storage/builtins.js +683 -0
- package/dist/core/storage/catalog.d.ts +19 -0
- package/dist/core/storage/catalog.d.ts.map +1 -0
- package/dist/core/storage/catalog.js +365 -0
- package/dist/core/storage/config.d.ts +16 -0
- package/dist/core/storage/config.d.ts.map +1 -0
- package/dist/core/storage/config.js +311 -0
- package/dist/core/storage/contract.d.ts +275 -0
- package/dist/core/storage/contract.d.ts.map +1 -0
- package/dist/core/storage/contract.js +3 -0
- package/dist/core/storage/durable-history.d.ts +36 -0
- package/dist/core/storage/durable-history.d.ts.map +1 -0
- package/dist/core/storage/durable-history.js +606 -0
- package/dist/core/storage/health.d.ts +4 -0
- package/dist/core/storage/health.d.ts.map +1 -0
- package/dist/core/storage/health.js +65 -0
- package/dist/core/storage/index.d.ts +16 -0
- package/dist/core/storage/index.d.ts.map +1 -0
- package/dist/core/storage/index.js +15 -0
- package/dist/core/storage/inventory.d.ts +25 -0
- package/dist/core/storage/inventory.d.ts.map +1 -0
- package/dist/core/storage/inventory.js +666 -0
- package/dist/core/storage/jsonl.d.ts +52 -0
- package/dist/core/storage/jsonl.d.ts.map +1 -0
- package/dist/core/storage/jsonl.js +156 -0
- package/dist/core/storage/log-retention.d.ts +52 -0
- package/dist/core/storage/log-retention.d.ts.map +1 -0
- package/dist/core/storage/log-retention.js +419 -0
- package/dist/core/storage/logger.d.ts +82 -0
- package/dist/core/storage/logger.d.ts.map +1 -0
- package/dist/core/storage/logger.js +411 -0
- package/dist/core/storage/maintenance-providers.d.ts +26 -0
- package/dist/core/storage/maintenance-providers.d.ts.map +1 -0
- package/dist/core/storage/maintenance-providers.js +141 -0
- package/dist/core/storage/maintenance.d.ts +125 -0
- package/dist/core/storage/maintenance.d.ts.map +1 -0
- package/dist/core/storage/maintenance.js +609 -0
- package/dist/core/storage/metrics.d.ts +60 -0
- package/dist/core/storage/metrics.d.ts.map +1 -0
- package/dist/core/storage/metrics.js +134 -0
- package/dist/core/storage/policy.d.ts +7 -0
- package/dist/core/storage/policy.d.ts.map +1 -0
- package/dist/core/storage/policy.js +110 -0
- package/dist/core/storage/process-log.d.ts +38 -0
- package/dist/core/storage/process-log.d.ts.map +1 -0
- package/dist/core/storage/process-log.js +165 -0
- package/dist/core/storage/query.d.ts +34 -0
- package/dist/core/storage/query.d.ts.map +1 -0
- package/dist/core/storage/query.js +295 -0
- package/dist/core/storage/receipts.d.ts +23 -0
- package/dist/core/storage/receipts.d.ts.map +1 -0
- package/dist/core/storage/receipts.js +117 -0
- package/dist/core/storage/segments.d.ts +84 -0
- package/dist/core/storage/segments.d.ts.map +1 -0
- package/dist/core/storage/segments.js +542 -0
- package/dist/core/storage/sink-graph.d.ts +65 -0
- package/dist/core/storage/sink-graph.d.ts.map +1 -0
- package/dist/core/storage/sink-graph.js +213 -0
- package/dist/core/storage/storm-control.d.ts +23 -0
- package/dist/core/storage/storm-control.d.ts.map +1 -0
- package/dist/core/storage/storm-control.js +59 -0
- package/dist/core/work/state.d.ts.map +1 -1
- package/dist/core/work/state.js +10 -14
- package/dist/core/workflow/live-session-v3.d.ts.map +1 -1
- package/dist/core/workflow/live-session-v3.js +2 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/lazy-commands.d.ts +26 -0
- package/dist/lazy-commands.d.ts.map +1 -0
- package/dist/lazy-commands.js +210 -0
- package/dist/lib/browser/client.d.ts +11 -0
- package/dist/lib/browser/client.d.ts.map +1 -1
- package/dist/lib/browser/client.js +13 -0
- package/dist/lib/browser/index.d.ts +1 -0
- package/dist/lib/browser/index.d.ts.map +1 -1
- package/dist/lib/browser/standalone-html.d.ts +25 -0
- package/dist/lib/browser/standalone-html.d.ts.map +1 -0
- package/dist/lib/browser/standalone-html.js +284 -0
- package/dist/lib/docs-lint.d.ts +2 -0
- package/dist/lib/docs-lint.d.ts.map +1 -1
- package/dist/lib/docs-lint.js +45 -80
- package/dist/lib/docs-metadata-audit.d.ts +3 -0
- package/dist/lib/docs-metadata-audit.d.ts.map +1 -1
- package/dist/lib/docs-metadata-audit.js +13 -23
- package/dist/lib/docs-metadata-sync.d.ts +1 -0
- package/dist/lib/docs-metadata-sync.d.ts.map +1 -1
- package/dist/lib/docs-metadata-sync.js +28 -10
- package/dist/lib/docs-repository-view.d.ts +22 -0
- package/dist/lib/docs-repository-view.d.ts.map +1 -0
- package/dist/lib/docs-repository-view.js +185 -0
- package/dist/lib/http/client.d.ts +11 -5
- package/dist/lib/http/client.d.ts.map +1 -1
- package/dist/lib/http/client.js +22 -4
- package/dist/lib/http/index.d.ts +1 -1
- package/dist/lib/http/index.d.ts.map +1 -1
- package/dist/lib/http/index.js +1 -1
- package/dist/lib/indexer-exclusions.d.ts +27 -0
- package/dist/lib/indexer-exclusions.d.ts.map +1 -0
- package/dist/lib/indexer-exclusions.js +176 -0
- package/dist/lib/instructions/apply.d.ts.map +1 -1
- package/dist/lib/instructions/apply.js +1 -0
- package/dist/lib/instructions/templates.d.ts +2 -0
- package/dist/lib/instructions/templates.d.ts.map +1 -1
- package/dist/lib/instructions/templates.js +149 -4
- package/dist/lib/local-file-url.d.ts +9 -0
- package/dist/lib/local-file-url.d.ts.map +1 -0
- package/dist/lib/local-file-url.js +20 -0
- package/dist/lib/web-performance.d.ts +118 -0
- package/dist/lib/web-performance.d.ts.map +1 -0
- package/dist/lib/web-performance.js +192 -0
- package/package.json +34 -2
- package/schemas/config.schema.json +58 -0
- package/schemas/event-v3.schema.json +3073 -581
- package/src/commander.ts +462 -93
- package/src/commands/agents.ts +617 -355
- package/src/commands/backup.ts +18 -14
- package/src/commands/browse-session.ts +12 -0
- package/src/commands/browse.ts +31 -9
- package/src/commands/conversations.ts +279 -0
- package/src/commands/decision.ts +8 -2
- package/src/commands/deinit.ts +6 -0
- package/src/commands/docs.ts +25 -6
- package/src/commands/doctor.ts +75 -9
- package/src/commands/events.ts +21 -1
- package/src/commands/fetch.ts +7 -6
- package/src/commands/files.ts +143 -0
- package/src/commands/governor.ts +13 -12
- package/src/commands/inbox.ts +61 -0
- package/src/commands/init.ts +78 -16
- package/src/commands/ledger-v3.ts +421 -1
- package/src/commands/logs.ts +224 -0
- package/src/commands/messages.ts +61 -0
- package/src/commands/outline.ts +6 -2
- package/src/commands/presence.ts +7 -2
- package/src/commands/read.ts +6 -2
- package/src/commands/semantic.ts +244 -0
- package/src/commands/storage.ts +310 -0
- package/src/commands/tunnel.ts +66 -52
- package/src/commands/web.ts +92 -7
- package/src/commands/work.ts +3 -3
- package/src/commands/workflow.ts +13 -13
- package/src/core/agents/canonical-emit.ts +15 -0
- package/src/core/agents/claim-path.ts +23 -0
- package/src/core/agents/cli.ts +259 -53
- package/src/core/agents/coord-client.ts +92 -8
- package/src/core/agents/live-authority-v3.ts +342 -14
- package/src/core/agents/live-lifecycle-v3.ts +14 -4
- package/src/core/agents/live-observation-v3.ts +13 -3
- package/src/core/agents/render/prompt-context.ts +40 -16
- package/src/core/agents/rules/stop-hook.ts +129 -25
- package/src/core/agents/rules/verdict.ts +1 -0
- package/src/core/agents/session-events.ts +4 -0
- package/src/core/agents/session-finalization-state-v3.ts +1 -1
- package/src/core/agents/session-finalizer-v3.ts +4 -1
- package/src/core/agents/session-name-display.ts +9 -1
- package/src/core/agents/state/activity-log.ts +7 -2
- package/src/core/agents/state/heartbeat-reader.ts +69 -0
- package/src/core/agents/state/heartbeat-writer.ts +47 -84
- package/src/core/agents/state/live-coordination-view.ts +17 -81
- package/src/core/agents/state/live-coordination-writer.ts +141 -0
- package/src/core/agents/state/names.ts +190 -182
- package/src/core/agents/state/stale-sweep.ts +25 -5
- package/src/core/artifacts/constants.ts +4 -0
- package/src/core/artifacts/index.ts +113 -8
- package/src/core/config.ts +126 -5
- package/src/core/conversations/archive.ts +237 -0
- package/src/core/conversations/catalog.ts +79 -0
- package/src/core/conversations/context-pack.ts +72 -0
- package/src/core/conversations/contract.ts +178 -0
- package/src/core/conversations/evaluation.ts +30 -0
- package/src/core/conversations/index.ts +9 -0
- package/src/core/conversations/lifecycle.ts +63 -0
- package/src/core/conversations/normalize.ts +105 -0
- package/src/core/conversations/query.ts +318 -0
- package/src/core/conversations/search-index.ts +48 -0
- package/src/core/events/legacy-storage/canary.ts +177 -0
- package/src/core/events/legacy-storage/fence.ts +129 -0
- package/src/core/events/legacy-storage/index.ts +5 -0
- package/src/core/events/legacy-storage/inventory.ts +51 -0
- package/src/core/events/legacy-storage/manifest.ts +136 -0
- package/src/core/events/legacy-storage/reader.ts +178 -0
- package/src/core/events/v3/authority-outbox.ts +22 -1
- package/src/core/events/v3/base-contract.ts +56 -7
- package/src/core/events/v3/bootstrap.ts +195 -2
- package/src/core/events/v3/capabilities.ts +37 -3
- package/src/core/events/v3/control-witness.ts +339 -0
- package/src/core/events/v3/control-writer.ts +16 -0
- package/src/core/events/v3/control.ts +54 -18
- package/src/core/events/v3/coordination-transaction-recovery.ts +477 -0
- package/src/core/events/v3/coordination-view.ts +17 -1
- package/src/core/events/v3/generated.ts +1 -1
- package/src/core/events/v3/index.ts +26 -2
- package/src/core/events/v3/latency.ts +213 -2
- package/src/core/events/v3/live-route-observer.ts +80 -0
- package/src/core/events/v3/live-routing.ts +182 -45
- package/src/core/events/v3/producers/command-recorder.ts +10 -1
- package/src/core/events/v3/producers/coordination-recorder.ts +112 -15
- package/src/core/events/v3/producers/diagnostic-summaries.ts +593 -0
- package/src/core/events/v3/producers/hook-base.ts +116 -2
- package/src/core/events/v3/producers/intake.ts +48 -2
- package/src/core/events/v3/producers/producer-state-observer.ts +52 -0
- package/src/core/events/v3/producers/recorder.ts +1403 -30
- package/src/core/events/v3/reader.ts +243 -2
- package/src/core/events/v3/rotation-config.ts +98 -0
- package/src/core/events/v3/runtime-build.ts +41 -0
- package/src/core/events/v3/runtime-identity.ts +16 -0
- package/src/core/events/v3/runtime-telemetry-capabilities.ts +143 -0
- package/src/core/events/v3/support-storage/classify.ts +209 -0
- package/src/core/events/v3/support-storage/eligibility.ts +58 -0
- package/src/core/events/v3/support-storage/index.ts +9 -0
- package/src/core/events/v3/support-storage/inventory.ts +135 -0
- package/src/core/events/v3/support-storage/logical-authority.ts +117 -0
- package/src/core/events/v3/support-storage/maintenance.ts +501 -0
- package/src/core/events/v3/support-storage/pack-contract.ts +337 -0
- package/src/core/events/v3/support-storage/pack-reader.ts +346 -0
- package/src/core/events/v3/support-storage/pack-writer.ts +352 -0
- package/src/core/events/v3/support-storage/recovery.ts +43 -0
- package/src/core/events/v3/turn-telemetry.ts +66 -5
- package/src/core/events/v3/writer.ts +168 -16
- package/src/core/governor/plan-read.ts +5 -18
- package/src/core/governor/planning.ts +5 -8
- package/src/core/governor/service-read.ts +320 -2
- package/src/core/governor/service.ts +49 -22
- package/src/core/guard/evidence-v3.ts +1 -0
- package/src/core/hooks/adapter/events.ts +1 -0
- package/src/core/hooks/adapter/output.ts +12 -5
- package/src/core/hooks/adapter/parse.ts +16 -0
- package/src/core/hooks/adapter/runtime-telemetry.ts +1200 -0
- package/src/core/hooks/cli.ts +342 -64
- package/src/core/hooks/effects/image-capture.ts +4 -1
- package/src/core/hooks/remediation-cap.ts +83 -0
- package/src/core/hooks/resolve/coord-root.ts +91 -11
- package/src/core/hooks/resolve/owner.ts +4 -0
- package/src/core/hooks/resolve/transcript.ts +55 -11
- package/src/core/inbox/contract.ts +81 -0
- package/src/core/inbox/index.ts +4 -0
- package/src/core/inbox/lifecycle.ts +104 -0
- package/src/core/inbox/service.ts +305 -0
- package/src/core/inbox/watcher.ts +36 -0
- package/src/core/presence/codec-digest.ts +15 -9
- package/src/core/presence/relay-client.ts +55 -7
- package/src/core/semantic/adapters.ts +452 -0
- package/src/core/semantic/contract.ts +430 -0
- package/src/core/semantic/evidence.ts +336 -0
- package/src/core/semantic/index.ts +201 -0
- package/src/core/semantic/once.ts +496 -0
- package/src/core/semantic/prompt.ts +96 -0
- package/src/core/semantic/review.ts +803 -0
- package/src/core/semantic/routes.ts +30 -0
- package/src/core/semantic/scheduler.ts +151 -0
- package/src/core/semantic/service-status.ts +212 -0
- package/src/core/semantic/service.ts +681 -0
- package/src/core/semantic/soak.ts +638 -0
- package/src/core/semantic/storage.ts +300 -0
- package/src/core/semantic/usage.ts +272 -0
- package/src/core/semantic/validate.ts +243 -0
- package/src/core/storage/buffer.ts +124 -0
- package/src/core/storage/builtins.ts +916 -0
- package/src/core/storage/catalog.ts +467 -0
- package/src/core/storage/config.ts +423 -0
- package/src/core/storage/contract.ts +342 -0
- package/src/core/storage/durable-history.ts +738 -0
- package/src/core/storage/health.ts +76 -0
- package/src/core/storage/index.ts +15 -0
- package/src/core/storage/inventory.ts +859 -0
- package/src/core/storage/jsonl.ts +213 -0
- package/src/core/storage/log-retention.ts +555 -0
- package/src/core/storage/logger.ts +546 -0
- package/src/core/storage/maintenance-providers.ts +200 -0
- package/src/core/storage/maintenance.ts +929 -0
- package/src/core/storage/metrics.ts +199 -0
- package/src/core/storage/policy.ts +141 -0
- package/src/core/storage/process-log.ts +203 -0
- package/src/core/storage/query.ts +360 -0
- package/src/core/storage/receipts.ts +162 -0
- package/src/core/storage/segments.ts +721 -0
- package/src/core/storage/sink-graph.ts +343 -0
- package/src/core/storage/storm-control.ts +91 -0
- package/src/core/work/state.ts +12 -21
- package/src/core/workflow/live-session-v3.ts +2 -4
- package/src/index.ts +2 -0
- package/src/lazy-commands.ts +294 -0
- package/src/lib/browser/client.ts +21 -0
- package/src/lib/browser/index.ts +4 -0
- package/src/lib/browser/standalone-html.ts +312 -0
- package/src/lib/docs-lint.ts +58 -77
- package/src/lib/docs-metadata-audit.ts +26 -21
- package/src/lib/docs-metadata-sync.ts +32 -9
- package/src/lib/docs-repository-view.ts +220 -0
- package/src/lib/http/client.ts +44 -8
- package/src/lib/http/index.ts +6 -1
- package/src/lib/indexer-exclusions.ts +173 -0
- package/src/lib/instructions/apply.ts +1 -0
- package/src/lib/instructions/templates.ts +154 -4
- package/src/lib/local-file-url.ts +31 -0
- package/src/lib/web-performance.ts +335 -0
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
import { type Command, Option, type ParseOptions } from "commander";
|
|
2
|
+
|
|
3
|
+
const lazyState = Symbol("harnery.lazy-command-state");
|
|
4
|
+
|
|
5
|
+
export interface LazyCommandDefinition {
|
|
6
|
+
/** Commander signature, including any top-level positional arguments. */
|
|
7
|
+
command: string;
|
|
8
|
+
description: string;
|
|
9
|
+
aliases?: readonly string[];
|
|
10
|
+
hidden?: boolean;
|
|
11
|
+
/** Preserve the `[options]` marker in root help without loading the implementation. */
|
|
12
|
+
hasOptions?: boolean;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface LazyCommandBundle {
|
|
16
|
+
commands: readonly LazyCommandDefinition[];
|
|
17
|
+
load(program: Command): void | Promise<void>;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
type LoadStatus = "placeholder" | "loading" | "loaded";
|
|
21
|
+
|
|
22
|
+
interface RegisteredBundle {
|
|
23
|
+
readonly definition: LazyCommandBundle;
|
|
24
|
+
readonly placeholders: Map<string, Command>;
|
|
25
|
+
status: LoadStatus;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
interface LazyCommandState {
|
|
29
|
+
readonly bundles: RegisteredBundle[];
|
|
30
|
+
readonly byName: Map<string, RegisteredBundle>;
|
|
31
|
+
readonly hooks: Map<string, Array<(program: Command) => void | Promise<void>>>;
|
|
32
|
+
readonly originalParse: Command["parse"];
|
|
33
|
+
readonly originalParseAsync: Command["parseAsync"];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Add lightweight top-level command placeholders whose implementations load
|
|
38
|
+
* immediately before Commander parses the selected command.
|
|
39
|
+
*/
|
|
40
|
+
export function registerLazyCommandBundles(
|
|
41
|
+
program: Command,
|
|
42
|
+
definitions: readonly LazyCommandBundle[],
|
|
43
|
+
): Command {
|
|
44
|
+
const state = stateFor(program);
|
|
45
|
+
for (const definition of definitions) {
|
|
46
|
+
const registered: RegisteredBundle = {
|
|
47
|
+
definition,
|
|
48
|
+
placeholders: new Map(),
|
|
49
|
+
status: "placeholder",
|
|
50
|
+
};
|
|
51
|
+
for (const metadata of definition.commands) {
|
|
52
|
+
const name = commandName(metadata.command);
|
|
53
|
+
const claimedNames = [name, ...(metadata.aliases ?? [])];
|
|
54
|
+
for (const claimedName of claimedNames) {
|
|
55
|
+
if (state.byName.has(claimedName) || findCommand(program, claimedName)) {
|
|
56
|
+
throw new Error(`Cannot register lazy command "${claimedName}": name already exists`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const placeholder = program
|
|
61
|
+
.command(metadata.command, { hidden: metadata.hidden === true })
|
|
62
|
+
.description(metadata.description);
|
|
63
|
+
for (const alias of metadata.aliases ?? []) placeholder.alias(alias);
|
|
64
|
+
if (metadata.hasOptions) {
|
|
65
|
+
placeholder.addOption(new Option("--__lazy-command-placeholder").hideHelp());
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
registered.placeholders.set(name, placeholder);
|
|
69
|
+
for (const claimedName of claimedNames) state.byName.set(claimedName, registered);
|
|
70
|
+
}
|
|
71
|
+
state.bundles.push(registered);
|
|
72
|
+
}
|
|
73
|
+
return program;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** Load one top-level command by canonical name or alias. */
|
|
77
|
+
export async function loadLazyCommand(
|
|
78
|
+
program: Command,
|
|
79
|
+
name: string,
|
|
80
|
+
): Promise<Command | undefined> {
|
|
81
|
+
const state = getState(program);
|
|
82
|
+
const bundle = state?.byName.get(name);
|
|
83
|
+
if (!state || !bundle) return findCommand(program, name);
|
|
84
|
+
await loadBundle(program, state, bundle);
|
|
85
|
+
return findCommand(program, name);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** Materialize every remaining lazy bundle, for whole-tree discovery and completion. */
|
|
89
|
+
export async function loadAllLazyCommands(program: Command): Promise<Command> {
|
|
90
|
+
const state = getState(program);
|
|
91
|
+
if (!state) return program;
|
|
92
|
+
for (const bundle of state.bundles) await loadBundle(program, state, bundle);
|
|
93
|
+
return program;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/** Run a host hook after a named lazy command becomes concrete. */
|
|
97
|
+
export async function onLazyCommandLoaded(
|
|
98
|
+
program: Command,
|
|
99
|
+
name: string,
|
|
100
|
+
hook: (program: Command) => void | Promise<void>,
|
|
101
|
+
): Promise<void> {
|
|
102
|
+
const state = getState(program);
|
|
103
|
+
const bundle = state?.byName.get(name);
|
|
104
|
+
if (!state || !bundle || bundle.status === "loaded") {
|
|
105
|
+
await hook(program);
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
const hooks = state.hooks.get(name) ?? [];
|
|
109
|
+
hooks.push(hook);
|
|
110
|
+
state.hooks.set(name, hooks);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function stateFor(program: Command): LazyCommandState {
|
|
114
|
+
const existing = getState(program);
|
|
115
|
+
if (existing) return existing;
|
|
116
|
+
|
|
117
|
+
const originalParse = program.parse;
|
|
118
|
+
const originalParseAsync = program.parseAsync;
|
|
119
|
+
const state: LazyCommandState = {
|
|
120
|
+
bundles: [],
|
|
121
|
+
byName: new Map(),
|
|
122
|
+
hooks: new Map(),
|
|
123
|
+
originalParse,
|
|
124
|
+
originalParseAsync,
|
|
125
|
+
};
|
|
126
|
+
Object.defineProperty(program, lazyState, { value: state });
|
|
127
|
+
|
|
128
|
+
program.parseAsync = async function lazyParseAsync(
|
|
129
|
+
argv?: readonly string[],
|
|
130
|
+
parseOptions?: ParseOptions,
|
|
131
|
+
): Promise<Command> {
|
|
132
|
+
const selected = selectedCommand(program, state, argv, parseOptions);
|
|
133
|
+
if (selected) await loadBundle(program, state, selected);
|
|
134
|
+
return originalParseAsync.call(this, argv, parseOptions);
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
program.parse = function lazyParse(
|
|
138
|
+
argv?: readonly string[],
|
|
139
|
+
parseOptions?: ParseOptions,
|
|
140
|
+
): Command {
|
|
141
|
+
const selected = selectedCommand(program, state, argv, parseOptions);
|
|
142
|
+
if (selected && selected.status !== "loaded") {
|
|
143
|
+
throw new Error(
|
|
144
|
+
`Command "${selected.definition.commands[0]?.command ?? "unknown"}" loads asynchronously; use parseAsync()`,
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
return originalParse.call(this, argv, parseOptions);
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
return state;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
function getState(program: Command): LazyCommandState | undefined {
|
|
154
|
+
return (program as Command & { [lazyState]?: LazyCommandState })[lazyState];
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
async function loadBundle(
|
|
158
|
+
program: Command,
|
|
159
|
+
state: LazyCommandState,
|
|
160
|
+
bundle: RegisteredBundle,
|
|
161
|
+
): Promise<void> {
|
|
162
|
+
if (bundle.status === "loaded" || bundle.status === "loading") return;
|
|
163
|
+
bundle.status = "loading";
|
|
164
|
+
|
|
165
|
+
const positions = new Map<string, number>();
|
|
166
|
+
for (const [name, placeholder] of bundle.placeholders) {
|
|
167
|
+
const index = program.commands.indexOf(placeholder);
|
|
168
|
+
if (index >= 0) positions.set(name, index);
|
|
169
|
+
}
|
|
170
|
+
for (const placeholder of [...bundle.placeholders.values()].sort(
|
|
171
|
+
(a, b) => program.commands.indexOf(b) - program.commands.indexOf(a),
|
|
172
|
+
)) {
|
|
173
|
+
const index = program.commands.indexOf(placeholder);
|
|
174
|
+
if (index >= 0) mutableCommands(program).splice(index, 1);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
const commandsBefore = new Set(program.commands);
|
|
178
|
+
try {
|
|
179
|
+
await bundle.definition.load(program);
|
|
180
|
+
for (const metadata of bundle.definition.commands) {
|
|
181
|
+
const name = commandName(metadata.command);
|
|
182
|
+
const concrete = program.commands.find(
|
|
183
|
+
(candidate) => !commandsBefore.has(candidate) && candidate.name() === name,
|
|
184
|
+
);
|
|
185
|
+
if (!concrete) {
|
|
186
|
+
throw new Error(`Lazy command loader did not register "${name}"`);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
restoreCommandOrder(program, bundle, positions);
|
|
191
|
+
bundle.status = "loaded";
|
|
192
|
+
for (const metadata of bundle.definition.commands) {
|
|
193
|
+
const name = commandName(metadata.command);
|
|
194
|
+
for (const hook of state.hooks.get(name) ?? []) await hook(program);
|
|
195
|
+
state.hooks.delete(name);
|
|
196
|
+
}
|
|
197
|
+
} catch (error) {
|
|
198
|
+
for (let index = program.commands.length - 1; index >= 0; index--) {
|
|
199
|
+
if (!commandsBefore.has(program.commands[index]!)) mutableCommands(program).splice(index, 1);
|
|
200
|
+
}
|
|
201
|
+
restorePlaceholders(program, bundle, positions);
|
|
202
|
+
bundle.status = "placeholder";
|
|
203
|
+
throw error;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
function restoreCommandOrder(
|
|
208
|
+
program: Command,
|
|
209
|
+
bundle: RegisteredBundle,
|
|
210
|
+
positions: ReadonlyMap<string, number>,
|
|
211
|
+
): void {
|
|
212
|
+
const ordered = bundle.definition.commands
|
|
213
|
+
.map((metadata) => {
|
|
214
|
+
const name = commandName(metadata.command);
|
|
215
|
+
const command = findCommand(program, name);
|
|
216
|
+
const position = positions.get(name);
|
|
217
|
+
return command && position !== undefined ? { command, position } : undefined;
|
|
218
|
+
})
|
|
219
|
+
.filter((entry): entry is { command: Command; position: number } => entry !== undefined)
|
|
220
|
+
.sort((a, b) => a.position - b.position);
|
|
221
|
+
|
|
222
|
+
for (const { command } of ordered) {
|
|
223
|
+
const index = program.commands.indexOf(command);
|
|
224
|
+
if (index >= 0) mutableCommands(program).splice(index, 1);
|
|
225
|
+
}
|
|
226
|
+
for (const { command, position } of ordered) {
|
|
227
|
+
mutableCommands(program).splice(Math.min(position, program.commands.length), 0, command);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
function restorePlaceholders(
|
|
232
|
+
program: Command,
|
|
233
|
+
bundle: RegisteredBundle,
|
|
234
|
+
positions: ReadonlyMap<string, number>,
|
|
235
|
+
): void {
|
|
236
|
+
const ordered = [...bundle.placeholders]
|
|
237
|
+
.map(([name, command]) => ({ command, position: positions.get(name) }))
|
|
238
|
+
.filter(
|
|
239
|
+
(entry): entry is { command: Command; position: number } => entry.position !== undefined,
|
|
240
|
+
)
|
|
241
|
+
.sort((a, b) => a.position - b.position);
|
|
242
|
+
for (const { command, position } of ordered) {
|
|
243
|
+
mutableCommands(program).splice(Math.min(position, program.commands.length), 0, command);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
function selectedCommand(
|
|
248
|
+
program: Command,
|
|
249
|
+
state: LazyCommandState,
|
|
250
|
+
argv: readonly string[] | undefined,
|
|
251
|
+
parseOptions: ParseOptions | undefined,
|
|
252
|
+
): RegisteredBundle | undefined {
|
|
253
|
+
const args = userArguments(argv ?? process.argv, parseOptions?.from);
|
|
254
|
+
for (let index = 0; index < args.length; index++) {
|
|
255
|
+
const token = args[index]!;
|
|
256
|
+
if (token === "--") return undefined;
|
|
257
|
+
if (token.startsWith("-")) {
|
|
258
|
+
const option = findRootOption(program, token);
|
|
259
|
+
if (option?.required || (option?.optional && !args[index + 1]?.startsWith("-"))) index++;
|
|
260
|
+
continue;
|
|
261
|
+
}
|
|
262
|
+
if (token === "help") return state.byName.get(args[index + 1] ?? "");
|
|
263
|
+
return state.byName.get(token);
|
|
264
|
+
}
|
|
265
|
+
return undefined;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
function userArguments(
|
|
269
|
+
argv: readonly string[],
|
|
270
|
+
from: ParseOptions["from"] | undefined,
|
|
271
|
+
): readonly string[] {
|
|
272
|
+
if (from === "user") return argv;
|
|
273
|
+
if (from === "electron") return argv.slice(1);
|
|
274
|
+
return argv.slice(2);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
function findRootOption(program: Command, token: string): Option | undefined {
|
|
278
|
+
const flag = token.includes("=") ? token.slice(0, token.indexOf("=")) : token;
|
|
279
|
+
return program.options.find((option) => option.short === flag || option.long === flag);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
function findCommand(program: Command, name: string): Command | undefined {
|
|
283
|
+
return program.commands.find(
|
|
284
|
+
(candidate) => candidate.name() === name || candidate.aliases().includes(name),
|
|
285
|
+
);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
function mutableCommands(program: Command): Command[] {
|
|
289
|
+
return program.commands as Command[];
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
function commandName(signature: string): string {
|
|
293
|
+
return signature.trim().split(/[\s|]/, 1)[0] ?? signature;
|
|
294
|
+
}
|
|
@@ -42,6 +42,12 @@ import {
|
|
|
42
42
|
buildRuntsCheck,
|
|
43
43
|
type RuntsResult,
|
|
44
44
|
} from "./runts.js";
|
|
45
|
+
import {
|
|
46
|
+
buildStandaloneHtmlScript,
|
|
47
|
+
DEFAULT_MAX_RESOURCE_BYTES,
|
|
48
|
+
DEFAULT_MAX_TOTAL_RESOURCE_BYTES,
|
|
49
|
+
type StandaloneHtmlResult,
|
|
50
|
+
} from "./standalone-html.js";
|
|
45
51
|
import {
|
|
46
52
|
buildClearTargetSizeAnnotationsScript,
|
|
47
53
|
buildTargetSizeAnnotateScript,
|
|
@@ -1011,6 +1017,21 @@ export class Browser {
|
|
|
1011
1017
|
return await page.content();
|
|
1012
1018
|
}
|
|
1013
1019
|
|
|
1020
|
+
/**
|
|
1021
|
+
* Self-contained snapshot of the page: stylesheets inlined, fonts and images
|
|
1022
|
+
* embedded as data: URIs, everything else rewritten to absolute URLs on the
|
|
1023
|
+
* captured origin. Use this for anything written to a file — a raw
|
|
1024
|
+
* `htmlContent()` dump renders unstyled once it leaves the page's own origin.
|
|
1025
|
+
*/
|
|
1026
|
+
async standaloneHtml(
|
|
1027
|
+
opts: { maxResourceBytes?: number; maxTotalResourceBytes?: number } = {},
|
|
1028
|
+
): Promise<StandaloneHtmlResult> {
|
|
1029
|
+
return await this.currentPage.evaluate(buildStandaloneHtmlScript(), {
|
|
1030
|
+
maxResourceBytes: opts.maxResourceBytes ?? DEFAULT_MAX_RESOURCE_BYTES,
|
|
1031
|
+
maxTotalResourceBytes: opts.maxTotalResourceBytes ?? DEFAULT_MAX_TOTAL_RESOURCE_BYTES,
|
|
1032
|
+
});
|
|
1033
|
+
}
|
|
1034
|
+
|
|
1014
1035
|
async click(selector: string): Promise<void> {
|
|
1015
1036
|
await this.currentPage.click(selector);
|
|
1016
1037
|
}
|
package/src/lib/browser/index.ts
CHANGED
|
@@ -140,6 +140,10 @@ export {
|
|
|
140
140
|
sendBrowserSessionRequest,
|
|
141
141
|
startBrowserSessionServer,
|
|
142
142
|
} from "./session-control.js";
|
|
143
|
+
export type {
|
|
144
|
+
StandaloneHtmlRequest,
|
|
145
|
+
StandaloneHtmlResult,
|
|
146
|
+
} from "./standalone-html.js";
|
|
143
147
|
export type {
|
|
144
148
|
TargetSizeNode,
|
|
145
149
|
TargetSizeOutcome,
|
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
// Self-contained HTML snapshots for `harn browse` trio mode.
|
|
2
|
+
//
|
|
3
|
+
// `page.content()` serializes the DOM but not the resources it points at, and
|
|
4
|
+
// framework pages reference those with root-absolute paths (`/_next/static/…`).
|
|
5
|
+
// Written to a file and reopened from anywhere else — the files origin, another
|
|
6
|
+
// host, `file://` — every one of those paths resolves against the wrong root and
|
|
7
|
+
// 404s, so the snapshot renders as unstyled black-on-white text with broken
|
|
8
|
+
// images. That is what an operator sees when they preview an artifact's `.html`.
|
|
9
|
+
//
|
|
10
|
+
// This rewrite makes the saved document stand on its own:
|
|
11
|
+
// - stylesheets are fetched and inlined as <style>
|
|
12
|
+
// - fonts, images, and icons are inlined as data: URIs under a byte budget
|
|
13
|
+
// - anything left over (too large, cross-origin, unreachable) is rewritten to
|
|
14
|
+
// an absolute URL on the captured origin rather than left root-relative
|
|
15
|
+
// - <script> and preload/prefetch hints are dropped: none of them can work in
|
|
16
|
+
// a snapshot, and a dead script tag only invites a hydration attempt
|
|
17
|
+
//
|
|
18
|
+
// The live page is untouched — everything happens on a clone of the document.
|
|
19
|
+
|
|
20
|
+
/** Byte budget for one inlined sub-resource. Larger ones stay as absolute URLs. */
|
|
21
|
+
export const DEFAULT_MAX_RESOURCE_BYTES = 512 * 1024;
|
|
22
|
+
|
|
23
|
+
/** Byte budget for all inlined sub-resources in one snapshot. */
|
|
24
|
+
export const DEFAULT_MAX_TOTAL_RESOURCE_BYTES = 8 * 1024 * 1024;
|
|
25
|
+
|
|
26
|
+
export interface StandaloneHtmlRequest {
|
|
27
|
+
maxResourceBytes: number;
|
|
28
|
+
maxTotalResourceBytes: number;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface StandaloneHtmlResult {
|
|
32
|
+
html: string;
|
|
33
|
+
/** Source URL the snapshot was taken from. */
|
|
34
|
+
source: string;
|
|
35
|
+
/** Stylesheets inlined as <style>. */
|
|
36
|
+
stylesheetsInlined: number;
|
|
37
|
+
/** Stylesheets left as absolute <link> (unreachable or cross-origin). */
|
|
38
|
+
stylesheetsLinked: number;
|
|
39
|
+
/** Sub-resources (fonts, images, icons) inlined as data: URIs. */
|
|
40
|
+
resourcesInlined: number;
|
|
41
|
+
/** Sub-resources left as absolute URLs (over budget or unreachable). */
|
|
42
|
+
resourcesLinked: number;
|
|
43
|
+
/** Bytes of sub-resource payload inlined. */
|
|
44
|
+
inlinedBytes: number;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function buildStandaloneHtmlScript(): (
|
|
48
|
+
args: StandaloneHtmlRequest,
|
|
49
|
+
) => Promise<StandaloneHtmlResult> {
|
|
50
|
+
return async ({ maxResourceBytes, maxTotalResourceBytes }) => {
|
|
51
|
+
const SKIP = /^(?:data:|blob:|javascript:|mailto:|tel:|sms:|about:|#)/i;
|
|
52
|
+
const base = document.baseURI;
|
|
53
|
+
|
|
54
|
+
let inlinedBytes = 0;
|
|
55
|
+
let resourcesInlined = 0;
|
|
56
|
+
let resourcesLinked = 0;
|
|
57
|
+
let stylesheetsInlined = 0;
|
|
58
|
+
let stylesheetsLinked = 0;
|
|
59
|
+
|
|
60
|
+
const absolute = (url: string, from: string): string | null => {
|
|
61
|
+
try {
|
|
62
|
+
return new URL(url, from).href;
|
|
63
|
+
} catch {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const dataUriCache = new Map<string, string | null>();
|
|
69
|
+
|
|
70
|
+
/** Fetch a resource as a data: URI, or null when it is unreachable or over budget. */
|
|
71
|
+
const toDataUri = async (url: string): Promise<string | null> => {
|
|
72
|
+
const cached = dataUriCache.get(url);
|
|
73
|
+
if (cached !== undefined) return cached;
|
|
74
|
+
let result: string | null = null;
|
|
75
|
+
try {
|
|
76
|
+
const res = await fetch(url, { credentials: "include" });
|
|
77
|
+
if (res.ok) {
|
|
78
|
+
const buf = await res.arrayBuffer();
|
|
79
|
+
const fits =
|
|
80
|
+
buf.byteLength <= maxResourceBytes &&
|
|
81
|
+
inlinedBytes + buf.byteLength <= maxTotalResourceBytes;
|
|
82
|
+
if (fits) {
|
|
83
|
+
const bytes = new Uint8Array(buf);
|
|
84
|
+
let binary = "";
|
|
85
|
+
const chunk = 0x8000;
|
|
86
|
+
for (let i = 0; i < bytes.length; i += chunk) {
|
|
87
|
+
binary += String.fromCharCode(...bytes.subarray(i, i + chunk));
|
|
88
|
+
}
|
|
89
|
+
const type = (res.headers.get("content-type") ?? "").split(";")[0]?.trim();
|
|
90
|
+
result = `data:${type || "application/octet-stream"};base64,${btoa(binary)}`;
|
|
91
|
+
inlinedBytes += buf.byteLength;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
} catch {
|
|
95
|
+
result = null;
|
|
96
|
+
}
|
|
97
|
+
dataUriCache.set(url, result);
|
|
98
|
+
return result;
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
/** Resolve one reference: data: URI when it fits, absolute URL otherwise. */
|
|
102
|
+
const resolveRef = async (
|
|
103
|
+
raw: string,
|
|
104
|
+
from: string,
|
|
105
|
+
inline: boolean,
|
|
106
|
+
): Promise<string | null> => {
|
|
107
|
+
const trimmed = raw.trim();
|
|
108
|
+
if (!trimmed || SKIP.test(trimmed)) return null;
|
|
109
|
+
const url = absolute(trimmed, from);
|
|
110
|
+
if (!url) return null;
|
|
111
|
+
if (!inline) return url;
|
|
112
|
+
const dataUri = await toDataUri(url);
|
|
113
|
+
if (dataUri) {
|
|
114
|
+
resourcesInlined += 1;
|
|
115
|
+
return dataUri;
|
|
116
|
+
}
|
|
117
|
+
resourcesLinked += 1;
|
|
118
|
+
return url;
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
/** Rewrite url() and @import references inside a stylesheet against its own URL. */
|
|
122
|
+
const rewriteCss = async (css: string, from: string): Promise<string> => {
|
|
123
|
+
const urlRef = /url\(\s*(['"]?)([^'")]*)\1\s*\)/g;
|
|
124
|
+
const importRef = /@import\s+(['"])([^'"]+)\1/g;
|
|
125
|
+
|
|
126
|
+
const replacements = new Map<string, string>();
|
|
127
|
+
const collect = async (pattern: RegExp, inline: boolean) => {
|
|
128
|
+
pattern.lastIndex = 0;
|
|
129
|
+
const seen: string[] = [];
|
|
130
|
+
for (let m = pattern.exec(css); m; m = pattern.exec(css)) {
|
|
131
|
+
const raw = m[2];
|
|
132
|
+
if (raw !== undefined && !replacements.has(raw)) seen.push(raw);
|
|
133
|
+
}
|
|
134
|
+
for (const raw of seen) {
|
|
135
|
+
const resolved = await resolveRef(raw, from, inline);
|
|
136
|
+
if (resolved) replacements.set(raw, resolved);
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
await collect(urlRef, true);
|
|
140
|
+
await collect(importRef, false);
|
|
141
|
+
|
|
142
|
+
return css
|
|
143
|
+
.replace(urlRef, (full, _q, raw: string) => {
|
|
144
|
+
const next = replacements.get(raw);
|
|
145
|
+
return next ? `url("${next}")` : full;
|
|
146
|
+
})
|
|
147
|
+
.replace(importRef, (full, _q, raw: string) => {
|
|
148
|
+
const next = replacements.get(raw);
|
|
149
|
+
return next ? `@import "${next}"` : full;
|
|
150
|
+
});
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
const doc = document.cloneNode(true) as Document;
|
|
154
|
+
|
|
155
|
+
// Nothing executable survives a snapshot; leaving these in only produces
|
|
156
|
+
// console noise and a doomed hydration pass on reopen.
|
|
157
|
+
for (const node of Array.from(doc.querySelectorAll("script, base"))) node.remove();
|
|
158
|
+
const deadHints = 'link[rel~="preload"],link[rel~="modulepreload"],link[rel~="prefetch"]';
|
|
159
|
+
for (const node of Array.from(doc.querySelectorAll(deadHints))) node.remove();
|
|
160
|
+
|
|
161
|
+
// Stylesheets: fetch → inline. Falls back to the CSSOM (which covers rules a
|
|
162
|
+
// same-origin sheet already parsed) and finally to an absolute <link>.
|
|
163
|
+
for (const link of Array.from(doc.querySelectorAll('link[rel~="stylesheet"]'))) {
|
|
164
|
+
const href = link.getAttribute("href");
|
|
165
|
+
const url = href ? absolute(href, base) : null;
|
|
166
|
+
if (!url) {
|
|
167
|
+
link.remove();
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
let css: string | null = null;
|
|
171
|
+
try {
|
|
172
|
+
const res = await fetch(url, { credentials: "include" });
|
|
173
|
+
if (res.ok) css = await res.text();
|
|
174
|
+
} catch {
|
|
175
|
+
css = null;
|
|
176
|
+
}
|
|
177
|
+
if (css === null) {
|
|
178
|
+
for (const sheet of Array.from(document.styleSheets)) {
|
|
179
|
+
if (sheet.href !== url) continue;
|
|
180
|
+
try {
|
|
181
|
+
css = Array.from(sheet.cssRules)
|
|
182
|
+
.map((rule) => rule.cssText)
|
|
183
|
+
.join("\n");
|
|
184
|
+
} catch {
|
|
185
|
+
css = null;
|
|
186
|
+
}
|
|
187
|
+
break;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
if (css === null) {
|
|
191
|
+
link.setAttribute("href", url);
|
|
192
|
+
stylesheetsLinked += 1;
|
|
193
|
+
continue;
|
|
194
|
+
}
|
|
195
|
+
const style = doc.createElement("style");
|
|
196
|
+
style.setAttribute("data-harnery-inlined-from", url);
|
|
197
|
+
const media = link.getAttribute("media");
|
|
198
|
+
if (media) style.setAttribute("media", media);
|
|
199
|
+
style.textContent = await rewriteCss(css, url);
|
|
200
|
+
link.replaceWith(style);
|
|
201
|
+
stylesheetsInlined += 1;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// Inline <style> blocks carry their own relative refs (framework @font-face
|
|
205
|
+
// rules in particular), so they need the same treatment.
|
|
206
|
+
for (const style of Array.from(doc.querySelectorAll("style"))) {
|
|
207
|
+
if (style.hasAttribute("data-harnery-inlined-from")) continue;
|
|
208
|
+
const css = style.textContent;
|
|
209
|
+
if (css) style.textContent = await rewriteCss(css, base);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// Stylesheets adopted via CSSOM never appear in the DOM and would be lost.
|
|
213
|
+
const adopted = (document as Document & { adoptedStyleSheets?: CSSStyleSheet[] })
|
|
214
|
+
.adoptedStyleSheets;
|
|
215
|
+
if (adopted?.length) {
|
|
216
|
+
const parts: string[] = [];
|
|
217
|
+
for (const sheet of adopted) {
|
|
218
|
+
try {
|
|
219
|
+
parts.push(
|
|
220
|
+
Array.from(sheet.cssRules)
|
|
221
|
+
.map((rule) => rule.cssText)
|
|
222
|
+
.join("\n"),
|
|
223
|
+
);
|
|
224
|
+
} catch {
|
|
225
|
+
// Constructed sheet with unreadable rules; nothing to recover.
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
if (parts.length) {
|
|
229
|
+
const style = doc.createElement("style");
|
|
230
|
+
style.setAttribute("data-harnery-adopted", "");
|
|
231
|
+
style.textContent = await rewriteCss(parts.join("\n"), base);
|
|
232
|
+
doc.head?.appendChild(style);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// Element references. Media and icons are worth inlining; navigation targets
|
|
237
|
+
// only need to stop pointing at the wrong root.
|
|
238
|
+
const inlineAttrs: Array<[string, string]> = [
|
|
239
|
+
["img", "src"],
|
|
240
|
+
["source", "src"],
|
|
241
|
+
["video", "src"],
|
|
242
|
+
["video", "poster"],
|
|
243
|
+
["audio", "src"],
|
|
244
|
+
["track", "src"],
|
|
245
|
+
["input", "src"],
|
|
246
|
+
["object", "data"],
|
|
247
|
+
['link[rel~="icon"]', "href"],
|
|
248
|
+
['link[rel~="apple-touch-icon"]', "href"],
|
|
249
|
+
["image", "href"],
|
|
250
|
+
["use", "href"],
|
|
251
|
+
];
|
|
252
|
+
const absoluteAttrs: Array<[string, string]> = [
|
|
253
|
+
["a", "href"],
|
|
254
|
+
["area", "href"],
|
|
255
|
+
["form", "action"],
|
|
256
|
+
["iframe", "src"],
|
|
257
|
+
["embed", "src"],
|
|
258
|
+
["link", "href"],
|
|
259
|
+
];
|
|
260
|
+
|
|
261
|
+
const applyAttrs = async (specs: Array<[string, string]>, inline: boolean) => {
|
|
262
|
+
for (const [selector, attr] of specs) {
|
|
263
|
+
for (const el of Array.from(doc.querySelectorAll(selector))) {
|
|
264
|
+
const raw = el.getAttribute(attr);
|
|
265
|
+
if (!raw) continue;
|
|
266
|
+
const next = await resolveRef(raw, base, inline);
|
|
267
|
+
if (next) el.setAttribute(attr, next);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
};
|
|
271
|
+
await applyAttrs(inlineAttrs, true);
|
|
272
|
+
await applyAttrs(absoluteAttrs, false);
|
|
273
|
+
|
|
274
|
+
// srcset is a comma-separated list of `url descriptor` pairs.
|
|
275
|
+
for (const el of Array.from(doc.querySelectorAll("img[srcset], source[srcset]"))) {
|
|
276
|
+
const raw = el.getAttribute("srcset");
|
|
277
|
+
if (!raw) continue;
|
|
278
|
+
const rewritten: string[] = [];
|
|
279
|
+
for (const candidate of raw.split(",")) {
|
|
280
|
+
const parts = candidate.trim().split(/\s+/);
|
|
281
|
+
const url = parts.shift();
|
|
282
|
+
if (!url) continue;
|
|
283
|
+
const next = (await resolveRef(url, base, true)) ?? url;
|
|
284
|
+
rewritten.push([next, ...parts].join(" "));
|
|
285
|
+
}
|
|
286
|
+
if (rewritten.length) el.setAttribute("srcset", rewritten.join(", "));
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
// Inline style attributes can carry background-image url().
|
|
290
|
+
for (const el of Array.from(doc.querySelectorAll("[style]"))) {
|
|
291
|
+
const raw = el.getAttribute("style");
|
|
292
|
+
if (!raw?.includes("url(")) continue;
|
|
293
|
+
el.setAttribute("style", await rewriteCss(raw, base));
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
const provenance = doc.createElement("meta");
|
|
297
|
+
provenance.setAttribute("name", "harnery:snapshot-source");
|
|
298
|
+
provenance.setAttribute("content", location.href);
|
|
299
|
+
doc.head?.prepend(provenance);
|
|
300
|
+
|
|
301
|
+
const doctype = document.doctype ? `<!DOCTYPE ${document.doctype.name}>` : "<!DOCTYPE html>";
|
|
302
|
+
return {
|
|
303
|
+
html: `${doctype}\n${doc.documentElement.outerHTML}\n`,
|
|
304
|
+
source: location.href,
|
|
305
|
+
stylesheetsInlined,
|
|
306
|
+
stylesheetsLinked,
|
|
307
|
+
resourcesInlined,
|
|
308
|
+
resourcesLinked,
|
|
309
|
+
inlinedBytes,
|
|
310
|
+
};
|
|
311
|
+
};
|
|
312
|
+
}
|