harnery 0.45.1 → 0.46.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 +13 -0
- package/dist/commander.d.ts.map +1 -1
- package/dist/commands/admission.d.ts.map +1 -1
- package/dist/commands/admission.js +214 -27
- package/dist/commands/agents.d.ts +4 -0
- package/dist/commands/agents.d.ts.map +1 -1
- package/dist/commands/agents.js +102 -25
- package/dist/commands/browse.d.ts +3 -0
- package/dist/commands/browse.d.ts.map +1 -1
- package/dist/commands/browse.js +172 -8
- package/dist/commands/fetch.js +1 -0
- package/dist/commands/ledger-v3.d.ts.map +1 -1
- package/dist/commands/ledger-v3.js +8 -2
- package/dist/commands/presence.d.ts.map +1 -1
- package/dist/commands/presence.js +40 -0
- package/dist/commands/qa-run.d.ts.map +1 -1
- package/dist/commands/qa-run.js +4 -3
- package/dist/commands/review-pack.d.ts.map +1 -1
- package/dist/commands/review-pack.js +33 -6
- package/dist/commands/workflow.d.ts.map +1 -1
- package/dist/commands/workflow.js +6 -45
- package/dist/core/agents/coord-client.d.ts.map +1 -1
- package/dist/core/agents/coord-client.js +0 -18
- package/dist/core/agents/index.d.ts +1 -0
- package/dist/core/agents/index.d.ts.map +1 -1
- package/dist/core/agents/index.js +1 -0
- package/dist/core/agents/live-authority-v3.d.ts.map +1 -1
- package/dist/core/agents/live-authority-v3.js +11 -4
- package/dist/core/agents/render/session-context.d.ts +0 -6
- package/dist/core/agents/render/session-context.d.ts.map +1 -1
- package/dist/core/agents/render/session-context.js +1 -6
- package/dist/core/agents/session-events.d.ts.map +1 -1
- package/dist/core/agents/session-events.js +12 -4
- package/dist/core/agents/state/heartbeat-reader.d.ts +3 -0
- package/dist/core/agents/state/heartbeat-reader.d.ts.map +1 -1
- package/dist/core/agents/state/live-coordination-view.d.ts +3 -1
- package/dist/core/agents/state/live-coordination-view.d.ts.map +1 -1
- package/dist/core/agents/state/live-coordination-view.js +6 -2
- package/dist/core/agents/state/parent-reference-contract.d.ts +16 -0
- package/dist/core/agents/state/parent-reference-contract.d.ts.map +1 -0
- package/dist/core/agents/state/parent-reference-contract.js +1 -0
- package/dist/core/agents/state/parent-reference.d.ts +18 -0
- package/dist/core/agents/state/parent-reference.d.ts.map +1 -0
- package/dist/core/agents/state/parent-reference.js +119 -0
- package/dist/core/agents/state/pidmap.js +2 -2
- package/dist/core/agents/state/proc-start.d.ts +20 -31
- package/dist/core/agents/state/proc-start.d.ts.map +1 -1
- package/dist/core/agents/state/proc-start.js +37 -70
- package/dist/core/agents/state/service-process.d.ts +61 -0
- package/dist/core/agents/state/service-process.d.ts.map +1 -0
- package/dist/core/agents/state/service-process.js +143 -0
- package/dist/core/config.d.ts +39 -0
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +63 -0
- package/dist/core/context/index.d.ts +6 -4
- package/dist/core/context/index.d.ts.map +1 -1
- package/dist/core/context/index.js +194 -256
- package/dist/core/context/observation.d.ts +9 -9
- package/dist/core/context/observation.d.ts.map +1 -1
- package/dist/core/context/observation.js +37 -6
- package/dist/core/diagnostics/path-identity.d.ts +1 -1
- package/dist/core/diagnostics/path-identity.d.ts.map +1 -1
- package/dist/core/diagnostics/path-identity.js +51 -6
- package/dist/core/events/v3/canonical.js +43 -14
- package/dist/core/events/v3/index.d.ts +1 -1
- package/dist/core/events/v3/index.d.ts.map +1 -1
- package/dist/core/events/v3/index.js +1 -1
- package/dist/core/events/v3/producers/recorder.d.ts +34 -0
- package/dist/core/events/v3/producers/recorder.d.ts.map +1 -1
- package/dist/core/events/v3/producers/recorder.js +117 -13
- package/dist/core/events/v3/reader.d.ts.map +1 -1
- package/dist/core/events/v3/reader.js +53 -13
- package/dist/core/events/v3/runtime-build.d.ts +14 -0
- package/dist/core/events/v3/runtime-build.d.ts.map +1 -1
- package/dist/core/events/v3/runtime-build.js +44 -0
- package/dist/core/events/v3/validate.d.ts.map +1 -1
- package/dist/core/events/v3/validate.js +36 -1
- package/dist/core/governor/index.d.ts +2 -1
- package/dist/core/governor/index.d.ts.map +1 -1
- package/dist/core/governor/index.js +2 -1
- package/dist/core/governor/service-read.d.ts +3 -10
- package/dist/core/governor/service-read.d.ts.map +1 -1
- package/dist/core/governor/service-read.js +10 -94
- package/dist/core/governor/service.d.ts +3 -7
- package/dist/core/governor/service.d.ts.map +1 -1
- package/dist/core/governor/service.js +17 -182
- package/dist/core/hooks/adapter/native-parent.d.ts +23 -0
- package/dist/core/hooks/adapter/native-parent.d.ts.map +1 -0
- package/dist/core/hooks/adapter/native-parent.js +91 -0
- package/dist/core/hooks/cli.js +79 -4
- package/dist/core/hooks/resolve/owner.d.ts +0 -11
- package/dist/core/hooks/resolve/owner.d.ts.map +1 -1
- package/dist/core/hooks/resolve/owner.js +2 -25
- package/dist/core/hooks/shell-admission.d.ts +84 -0
- package/dist/core/hooks/shell-admission.d.ts.map +1 -0
- package/dist/core/hooks/shell-admission.js +622 -0
- package/dist/core/hooks/shell-commit-tree.d.ts +2 -0
- package/dist/core/hooks/shell-commit-tree.d.ts.map +1 -0
- package/dist/core/hooks/shell-commit-tree.js +104 -0
- package/dist/core/inbox/contract.d.ts +12 -0
- package/dist/core/inbox/contract.d.ts.map +1 -1
- package/dist/core/inbox/contract.js +16 -0
- package/dist/core/inbox/peer-messages.d.ts +41 -16
- package/dist/core/inbox/peer-messages.d.ts.map +1 -1
- package/dist/core/inbox/peer-messages.js +372 -15
- package/dist/core/inbox/service.d.ts +8 -1
- package/dist/core/inbox/service.d.ts.map +1 -1
- package/dist/core/inbox/service.js +83 -3
- package/dist/core/inbox/targets.d.ts +17 -3
- package/dist/core/inbox/targets.d.ts.map +1 -1
- package/dist/core/inbox/targets.js +77 -2
- package/dist/core/presence/git.d.ts +18 -12
- package/dist/core/presence/git.d.ts.map +1 -1
- package/dist/core/presence/git.js +32 -38
- package/dist/core/presence/index.d.ts +2 -2
- package/dist/core/presence/index.d.ts.map +1 -1
- package/dist/core/presence/index.js +8 -6
- package/dist/core/presence/mail.d.ts +133 -0
- package/dist/core/presence/mail.d.ts.map +1 -0
- package/dist/core/presence/mail.js +464 -0
- package/dist/core/resources/sampler.js +2 -2
- package/dist/core/resources/service-status.d.ts +2 -14
- package/dist/core/resources/service-status.d.ts.map +1 -1
- package/dist/core/resources/service-status.js +3 -23
- package/dist/core/resources/service.d.ts +3 -7
- package/dist/core/resources/service.d.ts.map +1 -1
- package/dist/core/resources/service.js +12 -101
- package/dist/core/resources/status.d.ts.map +1 -1
- package/dist/core/resources/status.js +3 -2
- package/dist/core/semantic/contract.d.ts +5 -5
- package/dist/core/semantic/service.d.ts.map +1 -1
- package/dist/core/semantic/service.js +9 -2
- package/dist/core/servers/index.d.ts +0 -2
- package/dist/core/servers/index.d.ts.map +1 -1
- package/dist/core/servers/index.js +3 -18
- package/dist/core/storage/modes.d.ts +4 -0
- package/dist/core/storage/modes.d.ts.map +1 -1
- package/dist/core/storage/modes.js +4 -0
- package/dist/core/storage/segments.d.ts.map +1 -1
- package/dist/core/storage/segments.js +5 -4
- package/dist/core/supervisor/service.d.ts +4 -7
- package/dist/core/supervisor/service.d.ts.map +1 -1
- package/dist/core/supervisor/service.js +23 -122
- package/dist/core/supervisor/services.js +2 -2
- package/dist/core/supervisor/status.d.ts +3 -17
- package/dist/core/supervisor/status.d.ts.map +1 -1
- package/dist/core/supervisor/status.js +7 -70
- package/dist/core/workflow/engine.js +2 -1
- package/dist/core/workflow/index.d.ts +3 -4
- package/dist/core/workflow/index.d.ts.map +1 -1
- package/dist/core/workflow/index.js +2 -2
- package/dist/core/workflow/proof.d.ts.map +1 -1
- package/dist/core/workflow/proof.js +30 -74
- package/dist/core/workflow/resume-lock.d.ts +17 -0
- package/dist/core/workflow/resume-lock.d.ts.map +1 -0
- package/dist/core/workflow/resume-lock.js +158 -0
- package/dist/core/workflow/run-state.d.ts +0 -21
- package/dist/core/workflow/run-state.d.ts.map +1 -1
- package/dist/core/workflow/run-state.js +3 -174
- package/dist/core/workflow/workspaces/leases.d.ts +4 -0
- package/dist/core/workflow/workspaces/leases.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/leases.js +1 -1
- package/dist/core/workflow/workspaces/local-git.js +91 -210
- package/dist/core/workflow/workspaces/ownership.d.ts +0 -7
- package/dist/core/workflow/workspaces/ownership.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/ownership.js +3 -130
- package/dist/core/workflow/workspaces/reclaim.d.ts +4 -7
- package/dist/core/workflow/workspaces/reclaim.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/reclaim.js +0 -4
- package/dist/core/workflow/workspaces/recovery.d.ts +1 -1
- package/dist/core/workflow/workspaces/recovery.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/recovery.js +1 -1
- package/dist/core/workflow/workspaces/state.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/state.js +1 -4
- package/dist/lib/admission-history.d.ts +96 -0
- package/dist/lib/admission-history.d.ts.map +1 -0
- package/dist/lib/admission-history.js +196 -0
- package/dist/lib/admission.d.ts +56 -7
- package/dist/lib/admission.d.ts.map +1 -1
- package/dist/lib/admission.js +161 -19
- package/dist/lib/browser/client.d.ts +18 -0
- package/dist/lib/browser/client.d.ts.map +1 -1
- package/dist/lib/browser/client.js +100 -12
- package/dist/lib/browser/content-checks.d.ts +3 -1
- package/dist/lib/browser/content-checks.d.ts.map +1 -1
- package/dist/lib/browser/content-checks.js +10 -2
- package/dist/lib/browser/critique.d.ts +32 -0
- package/dist/lib/browser/critique.d.ts.map +1 -1
- package/dist/lib/browser/critique.js +72 -3
- package/dist/lib/browser/geometry.d.ts +2 -0
- package/dist/lib/browser/geometry.d.ts.map +1 -1
- package/dist/lib/browser/geometry.js +61 -15
- package/dist/lib/browser/index.d.ts +1 -1
- package/dist/lib/browser/index.d.ts.map +1 -1
- package/dist/lib/browser/index.js +1 -1
- package/dist/lib/browser/page-review-contracts.d.ts +6 -1
- package/dist/lib/browser/page-review-contracts.d.ts.map +1 -1
- package/dist/lib/browser/page-review-contracts.js +6 -1
- package/dist/lib/browser/page-review-judge.d.ts +3 -1
- package/dist/lib/browser/page-review-judge.d.ts.map +1 -1
- package/dist/lib/browser/page-review-judge.js +41 -11
- package/dist/lib/browser/page-review-pack.d.ts +3 -0
- package/dist/lib/browser/page-review-pack.d.ts.map +1 -1
- package/dist/lib/browser/page-review-pack.js +5 -2
- package/dist/lib/browser/qa-run-contracts.d.ts +11 -0
- package/dist/lib/browser/qa-run-contracts.d.ts.map +1 -1
- package/dist/lib/browser/qa-run-contracts.js +11 -4
- package/dist/lib/browser/qa-run.d.ts.map +1 -1
- package/dist/lib/browser/qa-run.js +73 -16
- package/dist/lib/browser/runts.d.ts +4 -2
- package/dist/lib/browser/runts.d.ts.map +1 -1
- package/dist/lib/browser/runts.js +84 -33
- package/dist/lib/browser/windows-chrome.d.ts +14 -0
- package/dist/lib/browser/windows-chrome.d.ts.map +1 -1
- package/dist/lib/browser/windows-chrome.js +42 -0
- package/dist/lib/browser/windows-login-sync.d.ts +110 -0
- package/dist/lib/browser/windows-login-sync.d.ts.map +1 -0
- package/dist/lib/browser/windows-login-sync.js +171 -0
- package/dist/lib/cookies/client.d.ts +30 -5
- package/dist/lib/cookies/client.d.ts.map +1 -1
- package/dist/lib/cookies/client.js +55 -10
- package/dist/lib/cookies/index.d.ts +1 -1
- package/dist/lib/cookies/index.d.ts.map +1 -1
- package/dist/lib/cookies/index.js +1 -1
- package/dist/lib/docs-metadata-sync.d.ts.map +1 -1
- package/dist/lib/docs-metadata-sync.js +41 -2
- package/dist/lib/durable-job.d.ts +8 -0
- package/dist/lib/durable-job.d.ts.map +1 -1
- package/dist/lib/durable-job.js +10 -0
- package/dist/lib/http/client.d.ts +9 -8
- package/dist/lib/http/client.d.ts.map +1 -1
- package/dist/lib/http/client.js +44 -2
- package/dist/lib/instructions/templates.js +4 -4
- package/package.json +2 -2
- package/src/commander.ts +13 -0
- package/src/commands/admission.ts +272 -29
- package/src/commands/agents.ts +132 -27
- package/src/commands/browse.ts +208 -6
- package/src/commands/fetch.ts +1 -0
- package/src/commands/ledger-v3.ts +8 -2
- package/src/commands/presence.ts +49 -0
- package/src/commands/qa-run.ts +4 -3
- package/src/commands/review-pack.ts +41 -5
- package/src/commands/workflow.ts +8 -58
- package/src/core/agents/coord-client.ts +0 -20
- package/src/core/agents/index.ts +6 -0
- package/src/core/agents/live-authority-v3.ts +11 -4
- package/src/core/agents/render/session-context.ts +1 -7
- package/src/core/agents/session-events.ts +18 -3
- package/src/core/agents/state/heartbeat-reader.ts +3 -0
- package/src/core/agents/state/live-coordination-view.ts +13 -6
- package/src/core/agents/state/parent-reference-contract.ts +14 -0
- package/src/core/agents/state/parent-reference.ts +179 -0
- package/src/core/agents/state/pidmap.ts +2 -2
- package/src/core/agents/state/proc-start.ts +41 -69
- package/src/core/agents/state/service-process.ts +217 -0
- package/src/core/config.ts +85 -0
- package/src/core/context/index.ts +207 -272
- package/src/core/context/observation.ts +40 -9
- package/src/core/diagnostics/path-identity.ts +52 -6
- package/src/core/events/v3/canonical.ts +46 -13
- package/src/core/events/v3/index.ts +3 -0
- package/src/core/events/v3/producers/recorder.ts +151 -13
- package/src/core/events/v3/reader.ts +55 -11
- package/src/core/events/v3/runtime-build.ts +62 -0
- package/src/core/events/v3/validate.ts +42 -1
- package/src/core/governor/index.ts +1 -2
- package/src/core/governor/service-read.ts +15 -114
- package/src/core/governor/service.ts +36 -220
- package/src/core/hooks/adapter/native-parent.ts +109 -0
- package/src/core/hooks/cli.ts +83 -4
- package/src/core/hooks/resolve/owner.ts +2 -25
- package/src/core/hooks/shell-admission.ts +634 -0
- package/src/core/hooks/shell-commit-tree.ts +102 -0
- package/src/core/inbox/contract.ts +18 -0
- package/src/core/inbox/peer-messages.ts +501 -15
- package/src/core/inbox/service.ts +108 -3
- package/src/core/inbox/targets.ts +94 -3
- package/src/core/presence/git.ts +45 -37
- package/src/core/presence/index.ts +16 -8
- package/src/core/presence/mail.ts +620 -0
- package/src/core/resources/sampler.ts +3 -2
- package/src/core/resources/service-status.ts +6 -35
- package/src/core/resources/service.ts +23 -133
- package/src/core/resources/status.ts +3 -2
- package/src/core/semantic/service.ts +8 -2
- package/src/core/servers/index.ts +3 -23
- package/src/core/storage/modes.ts +6 -0
- package/src/core/storage/segments.ts +5 -4
- package/src/core/supervisor/service.ts +33 -155
- package/src/core/supervisor/services.ts +2 -2
- package/src/core/supervisor/status.ts +10 -85
- package/src/core/workflow/engine.ts +1 -1
- package/src/core/workflow/index.ts +2 -13
- package/src/core/workflow/proof.ts +35 -83
- package/src/core/workflow/resume-lock.ts +179 -0
- package/src/core/workflow/run-state.ts +3 -207
- package/src/core/workflow/workspaces/leases.ts +1 -1
- package/src/core/workflow/workspaces/local-git.ts +120 -239
- package/src/core/workflow/workspaces/ownership.ts +3 -158
- package/src/core/workflow/workspaces/reclaim.ts +3 -9
- package/src/core/workflow/workspaces/recovery.ts +1 -1
- package/src/core/workflow/workspaces/state.ts +1 -5
- package/src/lib/admission-history.ts +267 -0
- package/src/lib/admission.ts +217 -19
- package/src/lib/browser/client.ts +147 -35
- package/src/lib/browser/content-checks.ts +14 -3
- package/src/lib/browser/critique.ts +113 -3
- package/src/lib/browser/geometry.ts +63 -14
- package/src/lib/browser/index.ts +5 -0
- package/src/lib/browser/page-review-contracts.ts +6 -1
- package/src/lib/browser/page-review-judge.ts +58 -13
- package/src/lib/browser/page-review-pack.ts +13 -2
- package/src/lib/browser/qa-run-contracts.ts +30 -4
- package/src/lib/browser/qa-run.ts +78 -17
- package/src/lib/browser/runts.ts +85 -37
- package/src/lib/browser/windows-chrome.ts +50 -0
- package/src/lib/browser/windows-login-sync.ts +275 -0
- package/src/lib/cookies/client.ts +62 -10
- package/src/lib/cookies/index.ts +3 -0
- package/src/lib/docs-metadata-sync.ts +44 -2
- package/src/lib/durable-job.ts +15 -0
- package/src/lib/http/client.ts +63 -1
- package/src/lib/instructions/templates.ts +4 -4
- package/dist/core/agents/state/process-handle.d.ts +0 -26
- package/dist/core/agents/state/process-handle.d.ts.map +0 -1
- package/dist/core/agents/state/process-handle.js +0 -121
- package/dist/core/workflow/recovery-audit.d.ts +0 -30
- package/dist/core/workflow/recovery-audit.d.ts.map +0 -1
- package/dist/core/workflow/recovery-audit.js +0 -116
- package/src/core/agents/state/process-handle.ts +0 -165
- package/src/core/workflow/recovery-audit.ts +0 -181
package/dist/commands/agents.js
CHANGED
|
@@ -28,6 +28,7 @@ import { agentDisplayName } from "../core/agents/state/activity-log.js";
|
|
|
28
28
|
import { buildLifecycleSuggestedName, buildSuggestedName, readHeartbeat as readHeartbeatCache, } from "../core/agents/state/heartbeat-writer.js";
|
|
29
29
|
import { describeLiveAuthorityBlockV3, liveAuthorityBlockHintV3, liveAuthorityBlockV3, readLiveCoordinationRow, readLiveCoordinationRows, } from "../core/agents/state/live-coordination-view.js";
|
|
30
30
|
import { forkRelationLabels, resolveForkAncestry } from "../core/agents/state/names.js";
|
|
31
|
+
import { resolveAgentParentReference, } from "../core/agents/state/parent-reference.js";
|
|
31
32
|
import { foldSessionState, } from "../core/agents/state/session-state.js";
|
|
32
33
|
import { turnChangesStatusRow } from "../core/agents/turn-changes.js";
|
|
33
34
|
import { turnElapsedStatusRow } from "../core/agents/turn-elapsed.js";
|
|
@@ -39,13 +40,13 @@ import { nativeInstanceIdV3 } from "../core/events/v3/live-route-observer.js";
|
|
|
39
40
|
import { liveInstanceIdV3 } from "../core/events/v3/live-routing.js";
|
|
40
41
|
import { countSummarizedSinceV3, listDiagnosticSummariesV3, } from "../core/events/v3/producers/diagnostic-summaries.js";
|
|
41
42
|
import { listHookIntakeGroupsV3, listHookIntakeRecordsV3, } from "../core/events/v3/producers/intake.js";
|
|
42
|
-
import { listHookProducerStateRecordsV3, readHookProducerStateV3, } from "../core/events/v3/producers/recorder.js";
|
|
43
|
+
import { listHookProducerStateRecordsV3, readHookProducerStateV3, scanHookProducerStateRecordsV3, } from "../core/events/v3/producers/recorder.js";
|
|
43
44
|
import { readLedgerV3 } from "../core/events/v3/reader.js";
|
|
44
45
|
import { EVENT_V3_LEDGER_RELATIVE_ROOT } from "../core/events/v3/writer.js";
|
|
45
46
|
import { evaluateRunQualityIfDue } from "../core/guard/index.js";
|
|
46
47
|
import { readRuntimeContextTelemetry, readRuntimeContextUsage, } from "../core/hooks/adapter/runtime-telemetry.js";
|
|
47
48
|
import { HarneryInboxCapacityError } from "../core/inbox/contract.js";
|
|
48
|
-
import { peerInbox, sendPeerMessage } from "../core/inbox/peer-messages.js";
|
|
49
|
+
import { peerInbox, sendPeerMessage, } from "../core/inbox/peer-messages.js";
|
|
49
50
|
import { readRemoteMachines } from "../core/presence/index.js";
|
|
50
51
|
import { formatResourceSummary, readResourceStatus } from "../core/resources/status.js";
|
|
51
52
|
import { registerContextCommand } from "./context.js";
|
|
@@ -290,9 +291,13 @@ export function registerAgentsCommand(program, emitParam, programContext, binNam
|
|
|
290
291
|
cmd
|
|
291
292
|
.command("ping <name> <message...>")
|
|
292
293
|
.description("Queue a durable message for one known task instance by name. Stale or " +
|
|
293
|
-
"done tasks receive it when that same task resumes.
|
|
294
|
+
"done tasks receive it when that same task resumes. A recipient on " +
|
|
295
|
+
"another machine is reached through the shared origin. Ambiguous names " +
|
|
294
296
|
"require an exact instance; receipts do not confirm attention.")
|
|
295
297
|
.option("--instance-id <id>", "Select the exact known recipient instance")
|
|
298
|
+
.option("--generation-id <id>", "Require the exact recipient generation")
|
|
299
|
+
.option("--operation-id <id>", "Reuse a frozen delivery operation after a caller retry")
|
|
300
|
+
.option("--operation-replay-only", "Require an existing plan after an ambiguous caller dispatch")
|
|
296
301
|
.option("--require-live", "Refuse a recipient outside live presence")
|
|
297
302
|
.option("--json", "JSON output")
|
|
298
303
|
.action((name, message, opts) => {
|
|
@@ -1216,6 +1221,7 @@ async function runShow(name, opts) {
|
|
|
1216
1221
|
tool_counts: report?.tool_counts ?? [],
|
|
1217
1222
|
total_events: report?.total_events ?? 0,
|
|
1218
1223
|
bq_error: bqError,
|
|
1224
|
+
parent_reference: resolveAgentParentReference(root, hb),
|
|
1219
1225
|
};
|
|
1220
1226
|
if (opts.json) {
|
|
1221
1227
|
emit.config({ format: "json" });
|
|
@@ -1232,6 +1238,7 @@ async function runShow(name, opts) {
|
|
|
1232
1238
|
lines.push(`agent-${data.name} ${subtitle}`);
|
|
1233
1239
|
lines.push(` session ${formatAge(ageSecs)} old · kind=${data.kind} · session_id=${data.session_id.slice(0, 8)}…`);
|
|
1234
1240
|
lines.push(` last heartbeat: ${formatAge(heartbeatAgeSecs)} ago`);
|
|
1241
|
+
lines.push(` parent: ${describeParentReference(data.parent_reference)}`);
|
|
1235
1242
|
lines.push(` activity: ${data.activity}`);
|
|
1236
1243
|
lines.push(` lifecycle: ${data.task_state}${data.task_state === "blocked" && data.task_state_reason ? `: ${data.task_state_reason}` : ""}`);
|
|
1237
1244
|
if (data.files_held.length > 0) {
|
|
@@ -1900,6 +1907,7 @@ function runStatus(opts) {
|
|
|
1900
1907
|
name: displayName,
|
|
1901
1908
|
instance_id: hb.instance_id,
|
|
1902
1909
|
kind: normalizeKind(hb.kind),
|
|
1910
|
+
parent_reference: resolveAgentParentReference(root, hb),
|
|
1903
1911
|
session_age_secs: ageSecs,
|
|
1904
1912
|
turn_elapsed_secs: turnElapsed ? turnElapsed.elapsed.secs : null,
|
|
1905
1913
|
turn_complete: turnElapsed ? turnElapsed.elapsed.complete : null,
|
|
@@ -1952,6 +1960,7 @@ function runStatus(opts) {
|
|
|
1952
1960
|
["changes", turnChanges.value],
|
|
1953
1961
|
["activity", activityOf(hb)],
|
|
1954
1962
|
["lifecycle", lifecycleLabel(hb)],
|
|
1963
|
+
["parent", describeParentReference(data.parent_reference)],
|
|
1955
1964
|
["context", ctxStr],
|
|
1956
1965
|
["resources", formatResourceSummary(resources)],
|
|
1957
1966
|
["files", filesStr],
|
|
@@ -2440,7 +2449,11 @@ export function collectEventLedgerHealthV3(root, nowMs = Date.now()) {
|
|
|
2440
2449
|
const generations = [];
|
|
2441
2450
|
const spanPressure = [];
|
|
2442
2451
|
try {
|
|
2443
|
-
|
|
2452
|
+
const scan = scanHookProducerStateRecordsV3(root);
|
|
2453
|
+
for (const file of scan.invalid) {
|
|
2454
|
+
collectionErrors.push(`producer state skipped (${file.adapter}/${file.session_hash}.json): ${file.reason}`);
|
|
2455
|
+
}
|
|
2456
|
+
for (const { state } of scan.records) {
|
|
2444
2457
|
if (state.spans.length >= SPAN_PRESSURE_SOFT_WATERMARK) {
|
|
2445
2458
|
spanPressure.push({
|
|
2446
2459
|
instance_id: state.instance_id,
|
|
@@ -3846,6 +3859,28 @@ function formatDuration(ms) {
|
|
|
3846
3859
|
const h = Math.round((ms % 86_400_000) / 3_600_000);
|
|
3847
3860
|
return h > 0 ? `${d}d${h}h` : `${d}d`;
|
|
3848
3861
|
}
|
|
3862
|
+
export function describeParentReference(reference) {
|
|
3863
|
+
return reference.state === "verified"
|
|
3864
|
+
? `${reference.parent_name ?? "unnamed"} (${reference.parent_instance_id}; ${reference.source}; ${reference.addressable ? "addressable" : "not addressable"})`
|
|
3865
|
+
: `${reference.state}: ${reference.reason}`;
|
|
3866
|
+
}
|
|
3867
|
+
export function formatPeerRecipientReceipt(recipient) {
|
|
3868
|
+
if (!recipient.ok)
|
|
3869
|
+
return `${recipient.code}: ${recipient.message}`;
|
|
3870
|
+
const address = `agent-${recipient.target.name} (${recipient.target.instance_id})`;
|
|
3871
|
+
if (recipient.delivery_state === "delivered")
|
|
3872
|
+
return `Previously acknowledged by the recipient machine for ${address}; task attention is not confirmed.`;
|
|
3873
|
+
if (recipient.delivery_state === "expired")
|
|
3874
|
+
return `The prior remote message for ${address} expired; no new delivery is established.`;
|
|
3875
|
+
if (recipient.target.machine)
|
|
3876
|
+
return (`Stored for ${address} on ${recipient.target.machine} as ${recipient.message_id}. ` +
|
|
3877
|
+
(recipient.published
|
|
3878
|
+
? "Published to origin; recipient-machine import is not confirmed."
|
|
3879
|
+
: `Publication is not confirmed${recipient.publish_error ? ` (${recipient.publish_error})` : ""}.`));
|
|
3880
|
+
return recipient.state === "duplicate"
|
|
3881
|
+
? `Previously stored for ${address} as ${recipient.message_id}; current surface state is not established by this receipt.`
|
|
3882
|
+
: `Stored for ${address} as ${recipient.message_id}; task attention is not confirmed.`;
|
|
3883
|
+
}
|
|
3849
3884
|
function runPing(name, message, opts) {
|
|
3850
3885
|
if (!message || message.trim().length === 0) {
|
|
3851
3886
|
emit.error({ code: "empty_message", message: "message is required (and non-empty)" });
|
|
@@ -3869,10 +3904,17 @@ function runPing(name, message, opts) {
|
|
|
3869
3904
|
try {
|
|
3870
3905
|
sent = sendPeerMessage({
|
|
3871
3906
|
coordRoot,
|
|
3872
|
-
target: {
|
|
3907
|
+
target: {
|
|
3908
|
+
name,
|
|
3909
|
+
instanceId: opts.instanceId,
|
|
3910
|
+
generationId: opts.generationId,
|
|
3911
|
+
requireLive: opts.requireLive,
|
|
3912
|
+
},
|
|
3913
|
+
operationId: opts.operationId,
|
|
3914
|
+
operationReplayOnly: opts.operationReplayOnly,
|
|
3873
3915
|
senderName: fromName,
|
|
3874
3916
|
senderInstanceId: myOwner,
|
|
3875
|
-
body: message
|
|
3917
|
+
body: message,
|
|
3876
3918
|
});
|
|
3877
3919
|
}
|
|
3878
3920
|
catch (error) {
|
|
@@ -3882,46 +3924,81 @@ function runPing(name, message, opts) {
|
|
|
3882
3924
|
}
|
|
3883
3925
|
throw error;
|
|
3884
3926
|
}
|
|
3927
|
+
if (opts.json)
|
|
3928
|
+
emit.config({ format: "json" });
|
|
3929
|
+
const routing = {
|
|
3930
|
+
operation_id: sent.operation_id,
|
|
3931
|
+
child: sent.child,
|
|
3932
|
+
parent_reference: sent.parent_reference,
|
|
3933
|
+
parent_copy: sent.parent_copy,
|
|
3934
|
+
complete: sent.complete,
|
|
3935
|
+
};
|
|
3936
|
+
// Keep both actual recipient writes visible, including parent-only success.
|
|
3937
|
+
for (const recipient of [sent.child, sent.parent_copy]) {
|
|
3938
|
+
if (!("ok" in recipient) || !recipient.ok)
|
|
3939
|
+
continue;
|
|
3940
|
+
emitEventV3({
|
|
3941
|
+
owner: myOwner,
|
|
3942
|
+
session: nativeSessionIdentity(myHb, myOwner),
|
|
3943
|
+
adapter: normalizeAdapter(myHb?.platform),
|
|
3944
|
+
observation: {
|
|
3945
|
+
event_type: "coord.message_observed",
|
|
3946
|
+
direction: "sent",
|
|
3947
|
+
subject: recipient.target.instance_id,
|
|
3948
|
+
message_id: recipient.message_id,
|
|
3949
|
+
body: recipient === sent.child
|
|
3950
|
+
? message
|
|
3951
|
+
: `[Parent copy for agent-${sent.child.target?.name} (${sent.child.target?.instance_id})]\n${message}`,
|
|
3952
|
+
},
|
|
3953
|
+
});
|
|
3954
|
+
}
|
|
3885
3955
|
if (!sent.ok) {
|
|
3886
|
-
emit.
|
|
3956
|
+
emit.data({
|
|
3957
|
+
...routing,
|
|
3958
|
+
ok: false,
|
|
3887
3959
|
code: sent.code,
|
|
3888
3960
|
message: sent.message,
|
|
3961
|
+
from: fromName,
|
|
3889
3962
|
...(sent.candidates ? { candidates: sent.candidates } : {}),
|
|
3890
3963
|
});
|
|
3891
|
-
process.
|
|
3964
|
+
process.exitCode = 1;
|
|
3965
|
+
return;
|
|
3892
3966
|
}
|
|
3893
|
-
|
|
3894
|
-
// in data, so read-only observers can render the communication without
|
|
3895
|
-
// joining journal files.
|
|
3896
|
-
emitEventV3({
|
|
3897
|
-
owner: myOwner,
|
|
3898
|
-
session: nativeSessionIdentity(myHb, myOwner),
|
|
3899
|
-
adapter: normalizeAdapter(myHb?.platform),
|
|
3900
|
-
observation: {
|
|
3901
|
-
event_type: "coord.message_observed",
|
|
3902
|
-
direction: "sent",
|
|
3903
|
-
subject: sent.target.instance_id,
|
|
3904
|
-
message_id: sent.message_id,
|
|
3905
|
-
body: message.trim(),
|
|
3906
|
-
},
|
|
3907
|
-
});
|
|
3967
|
+
const remote = "published" in sent ? sent : null;
|
|
3908
3968
|
const data = {
|
|
3969
|
+
...routing,
|
|
3909
3970
|
peer: sent.target.name,
|
|
3910
3971
|
peer_instance_id: sent.target.instance_id,
|
|
3972
|
+
...(sent.target.machine ? { peer_machine: sent.target.machine } : {}),
|
|
3911
3973
|
state: sent.state,
|
|
3912
3974
|
message_id: sent.message_id,
|
|
3913
3975
|
synced: sent.synced,
|
|
3914
3976
|
body_bytes: sent.body_bytes,
|
|
3915
3977
|
from: fromName,
|
|
3978
|
+
...(remote
|
|
3979
|
+
? {
|
|
3980
|
+
published: remote.published,
|
|
3981
|
+
...(remote.delivery_state ? { delivery_state: remote.delivery_state } : {}),
|
|
3982
|
+
...(remote.publish_error ? { publish_error: remote.publish_error } : {}),
|
|
3983
|
+
}
|
|
3984
|
+
: {}),
|
|
3916
3985
|
};
|
|
3917
3986
|
if (opts.json) {
|
|
3918
3987
|
emit.config({ format: "json" });
|
|
3919
3988
|
emit.data(data);
|
|
3989
|
+
if (!sent.complete)
|
|
3990
|
+
process.exitCode = 1;
|
|
3920
3991
|
return;
|
|
3921
3992
|
}
|
|
3922
3993
|
emit.data(data);
|
|
3923
|
-
|
|
3924
|
-
|
|
3994
|
+
if (!sent.complete)
|
|
3995
|
+
process.exitCode = 1;
|
|
3996
|
+
emit.text(`parent copy: ${"ok" in sent.parent_copy
|
|
3997
|
+
? sent.parent_copy.ok
|
|
3998
|
+
? formatPeerRecipientReceipt(sent.parent_copy)
|
|
3999
|
+
: `${sent.parent_copy.code}: ${sent.parent_copy.message}`
|
|
4000
|
+
: `skipped (${sent.parent_copy.reason})`}\n`);
|
|
4001
|
+
emit.text(`${formatPeerRecipientReceipt(sent.child)}\n`);
|
|
3925
4002
|
}
|
|
3926
4003
|
async function runWait(name, opts) {
|
|
3927
4004
|
const timeoutMs = parseDurationToMs(opts.timeout);
|
|
@@ -50,6 +50,7 @@ interface BrowseOpts {
|
|
|
50
50
|
collectOut?: string;
|
|
51
51
|
networkHar?: string;
|
|
52
52
|
login?: boolean;
|
|
53
|
+
syncLogin?: boolean;
|
|
53
54
|
attached?: boolean;
|
|
54
55
|
loginCloseFile?: string;
|
|
55
56
|
controlFile?: string;
|
|
@@ -79,7 +80,9 @@ interface BrowseOpts {
|
|
|
79
80
|
checkWidthFail?: boolean;
|
|
80
81
|
checkWidthAnnotate?: boolean;
|
|
81
82
|
checkRunts?: boolean | string;
|
|
83
|
+
checkScanNodeBudget?: string;
|
|
82
84
|
checkRuntsMinChars?: string;
|
|
85
|
+
checkRuntsMaxFindings?: string;
|
|
83
86
|
checkRuntsFail?: boolean;
|
|
84
87
|
checkRuntsAnnotate?: boolean;
|
|
85
88
|
checkOverflow?: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browse.d.ts","sourceRoot":"","sources":["../../src/commands/browse.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGzC,OAAO,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAmE1E,OAAO,
|
|
1
|
+
{"version":3,"file":"browse.d.ts","sourceRoot":"","sources":["../../src/commands/browse.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/browse.js
CHANGED
|
@@ -11,7 +11,7 @@ import { createPageDriver, createRng, DEFAULT_COLLECT_LIMITS, PACING_LIMITS, par
|
|
|
11
11
|
import { Browser, browserProxyFromEnv, browserProxyGateFromEnv, captureDevOverlay, chromeMajorFromExecutable, DEFAULT_CRITIQUE_RUBRIC, extractObservedIp, installedChromeChannel, installedChromePath, parseAssertSpec, resolveUserAgent, runCritique, tilesFromFullPage, WEBRTC_PROXY_ONLY_ARG, writeNetscapeCookieFile, wslHeadedLaunchArgs, } from "../lib/browser/index.js";
|
|
12
12
|
import { isWSL } from "../lib/browser/launch-args.js";
|
|
13
13
|
import { allocateTileBudget, validatePageReviewAllocation, } from "../lib/browser/page-review-budget.js";
|
|
14
|
-
import { PAGE_REVIEW_CAPTURE_PLAN_SCHEMA, } from "../lib/browser/page-review-contracts.js";
|
|
14
|
+
import { PAGE_REVIEW_CAPTURE_PLAN_SCHEMA, PAGE_REVIEW_MAX_TILE_BUDGET, } from "../lib/browser/page-review-contracts.js";
|
|
15
15
|
import { findPackTile, gateHitsFromEnvelope, readPackContext, tileId, writePackContext, writePackExpandedTile, } from "../lib/browser/page-review-pack.js";
|
|
16
16
|
import { retainPageReviewSourceIdentity } from "../lib/browser/page-review-source.js";
|
|
17
17
|
import { buildQaManifest, classifySignatures, } from "../lib/browser/qa-plan.js";
|
|
@@ -22,7 +22,8 @@ import { startBrowserSessionServer, } from "../lib/browser/session-control.js";
|
|
|
22
22
|
import { captureThumbnailFingerprint, registerCaptureThumbnail, } from "../lib/browser/thumbnail-association.js";
|
|
23
23
|
import { reviewCandidateRects } from "../lib/browser/tiling.js";
|
|
24
24
|
import { diffAgainstBaseline, saveBaseline, } from "../lib/browser/visual-diff.js";
|
|
25
|
-
import { harvestDomain, harvestWindowsChromeCookies, keepWindowsChromeSession, stopWindowsChromeProfile, windowsChromePath, windowsLocalAppData, windowsPlainProfile, wslPathToWindows, } from "../lib/browser/windows-chrome.js";
|
|
25
|
+
import { harvestDomain, harvestWindowsChromeCookies, keepWindowsChromeSession, stopWindowsChromeProfile, windowsChromePath, windowsChromeProfileProcesses, windowsLocalAppData, windowsPathToWsl, windowsPlainProfile, wslPathToWindows, } from "../lib/browser/windows-chrome.js";
|
|
26
|
+
import { profileCookieDbMtimeMs, recordLoginSync, syncLoginCookies, } from "../lib/browser/windows-login-sync.js";
|
|
26
27
|
import { applyExtraCookies, CookieJar, mergeCookies } from "../lib/cookies/index.js";
|
|
27
28
|
import { commandPaceGate } from "../lib/pace/index.js";
|
|
28
29
|
/**
|
|
@@ -57,8 +58,10 @@ const VIEWPORT_PRESETS = {
|
|
|
57
58
|
// cookies/read: the many helper functions in this large file close over
|
|
58
59
|
// `emit` so action callbacks stay concise.
|
|
59
60
|
let emit;
|
|
61
|
+
let browseBinName = "harn";
|
|
60
62
|
export function registerBrowseCommand(program, emitParam, context, binName = resolveBinName()) {
|
|
61
63
|
emit = emitParam;
|
|
64
|
+
browseBinName = binName;
|
|
62
65
|
program
|
|
63
66
|
.command("browse <url>")
|
|
64
67
|
.description("Headless Chromium with persistent profile + cookie jar. Default writes a trio of files (last.png, last.html, last.json) for the LLM iteration loop; --snapshot/--html/--json switch to stdout-print mode.")
|
|
@@ -108,9 +111,14 @@ export function registerBrowseCommand(program, emitParam, context, binName = res
|
|
|
108
111
|
"Renders theme-aware pages in that scheme without page-specific toggles. " +
|
|
109
112
|
"Absent = browser default (unchanged behavior).")
|
|
110
113
|
.option("--login", "Open the URL in the installed Google Chrome with nothing attached (no DevTools protocol, no " +
|
|
111
|
-
"Playwright) so a person can sign in; under WSL this is the Windows host's Chrome
|
|
112
|
-
"close the window or create the --login-close-file; later browse
|
|
113
|
-
"the cookies.
|
|
114
|
+
"Playwright) so a person can sign in; under WSL this is the Windows host's Chrome on a dedicated " +
|
|
115
|
+
"sign-in profile. Sign in, then close the window or create the --login-close-file; later browse " +
|
|
116
|
+
"and browse-session runs reuse the cookies. Under WSL the profile can also stay in use as an " +
|
|
117
|
+
"ordinary browser: each headless browse copies the target site's cookies from it when it changed " +
|
|
118
|
+
"and is closed, and an open profile is left alone (see --sync-login). Sites cannot tell this " +
|
|
119
|
+
"window from the person's own browser.")
|
|
120
|
+
.option("--sync-login", "WSL only: copy the URL's site cookies from the Windows sign-in profile into the cookie store " +
|
|
121
|
+
"now, then exit without loading the page. Refuses while Chrome is open on that profile.")
|
|
114
122
|
.option("--attached", "With --login: open an automation-controlled Chrome that this process and --control-file can drive. " +
|
|
115
123
|
"Sites can detect it and may lock the account, so use it only for agent-driven headed sessions on " +
|
|
116
124
|
"sites you own. Never use it to sign in to a third-party account.")
|
|
@@ -173,6 +181,8 @@ export function registerBrowseCommand(program, emitParam, context, binName = res
|
|
|
173
181
|
"Atomic tokens (URLs, emails, phone numbers) are excluded. Reports hits in the JSON " +
|
|
174
182
|
"envelope under `runts` and annotates them on the screenshot.")
|
|
175
183
|
.option("--check-runts-min-chars <n>", "Minimum block text length to scan (default 40; smaller labels can't meaningfully wrap).", "40")
|
|
184
|
+
.option("--check-runts-max-findings <n>", "Maximum runt findings to retain (integer 1..5000, default 50). Reaching the limit " +
|
|
185
|
+
"still marks the sweep incomplete; the separate 5000-block scan cap is unchanged.", "50")
|
|
176
186
|
.option("--check-runts-fail", "Run a document-wide runt check when needed; exit 2 on a runt, missing scope, or incomplete sweep.")
|
|
177
187
|
.option("--no-check-runts-annotate", "Skip drawing runt boxes on the screenshot (JSON still emitted).")
|
|
178
188
|
.option("--check-align <selector>", "Check rendered child-content alignment inside this container (repeatable).", (value, previous = []) => [...previous, value], [])
|
|
@@ -206,6 +216,7 @@ export function registerBrowseCommand(program, emitParam, context, binName = res
|
|
|
206
216
|
"Pairs closer than this are flagged; negative separation (overlap) always flags.", "6")
|
|
207
217
|
.option("--check-crowd-fail", "Exit 2 when a crowd target fails, is unknown, or is missing.")
|
|
208
218
|
.option("--no-check-crowd-annotate", "Skip crowd screenshot annotations.")
|
|
219
|
+
.option("--check-scan-node-budget <n>", "Explicit geometry/content traversal budget per scope (1–100000 nodes). Omit to keep each rule's existing limit; incomplete scans remain unknown.")
|
|
209
220
|
.option("--check-placeholder [selector]", "Scan rendered text for unrendered template tokens and bound-value tells: " +
|
|
210
221
|
"JS template literals, `{{x}}` handlebars, `[object Object]`, `Invalid Date`, " +
|
|
211
222
|
"`NaN`, or an element whose whole text is literally 'undefined' / 'null'. Optional selector " +
|
|
@@ -241,7 +252,7 @@ export function registerBrowseCommand(program, emitParam, context, binName = res
|
|
|
241
252
|
"reports `skipped`. Findings land under `critique` in the JSON envelope.")
|
|
242
253
|
.option("--check-critique-band <px>", "Band height for default tiling (default 1400).", "1400")
|
|
243
254
|
.option("--check-critique-overlap <px>", "Vertical overlap between bands so a finding at a seam stays visible (default 120).", "120")
|
|
244
|
-
.option("--check-critique-max-tiles <n>",
|
|
255
|
+
.option("--check-critique-max-tiles <n>", `Cap on tiles sent to the model, to bound cost (default 24, at most ${PAGE_REVIEW_MAX_TILE_BUDGET}).`, "24")
|
|
245
256
|
.option("--check-critique-rubric <text>", "Override the default critique rubric.")
|
|
246
257
|
.option("--check-critique-fail", "Run a whole-page critique when needed; exit 2 unless the critique conclusively passes.")
|
|
247
258
|
.option("--assert <expr>", "Assert a page value (repeatable). Grammar: '<op> <selector> => <expected>', where op is " +
|
|
@@ -336,6 +347,17 @@ async function runBrowse(url, opts, context) {
|
|
|
336
347
|
const clipThreshold = parseNonNegativeNumber(opts.checkClipThreshold ?? "0", "--check-clip-threshold");
|
|
337
348
|
const overlapThreshold = parseNonNegativeNumber(opts.checkOverlapThreshold ?? "0", "--check-overlap-threshold");
|
|
338
349
|
const crowdMin = parseNonNegativeNumber(opts.checkCrowdMin ?? "6", "--check-crowd-min");
|
|
350
|
+
const scanNodeBudget = opts.checkScanNodeBudget === undefined
|
|
351
|
+
? undefined
|
|
352
|
+
: parsePositiveInt(opts.checkScanNodeBudget, "--check-scan-node-budget");
|
|
353
|
+
if (scanNodeBudget !== undefined &&
|
|
354
|
+
(!Number.isSafeInteger(scanNodeBudget) || scanNodeBudget > 100_000)) {
|
|
355
|
+
throw new Error("--check-scan-node-budget must be an integer from 1 to 100000.");
|
|
356
|
+
}
|
|
357
|
+
const runtsMaxFindings = parsePositiveInt(opts.checkRuntsMaxFindings ?? "50", "--check-runts-max-findings");
|
|
358
|
+
if (runtsMaxFindings > 5000) {
|
|
359
|
+
throw new Error("--check-runts-max-findings must be an integer from 1 to 5000.");
|
|
360
|
+
}
|
|
339
361
|
const hitProfile = parseTargetSizeProfile(opts.checkHitProfile ?? "wcag-aa");
|
|
340
362
|
// Commander: `--no-cookies` turns `opts.cookies` into `false`. Default is `true`.
|
|
341
363
|
const jar = opts.cookies === false
|
|
@@ -374,6 +396,14 @@ async function runBrowse(url, opts, context) {
|
|
|
374
396
|
if (loginCloseFile && existsSync(loginCloseFile)) {
|
|
375
397
|
throw new Error(`Login close signal already exists at ${loginCloseFile}. Remove the stale file before launching.`);
|
|
376
398
|
}
|
|
399
|
+
if (opts.syncLogin) {
|
|
400
|
+
if (opts.login)
|
|
401
|
+
throw new Error("--sync-login cannot run with --login.");
|
|
402
|
+
if (!jar)
|
|
403
|
+
throw new Error("--sync-login needs the cookie store; drop --no-cookies.");
|
|
404
|
+
runSyncLogin(url, jar.path);
|
|
405
|
+
return;
|
|
406
|
+
}
|
|
377
407
|
const collectPlan = opts.collect ? buildCollectPlan(opts) : null;
|
|
378
408
|
const pace = commandPaceGate(opts.pace !== false, (message) => emit.log(message, "info"));
|
|
379
409
|
if (loginMode === "plain") {
|
|
@@ -391,12 +421,15 @@ async function runBrowse(url, opts, context) {
|
|
|
391
421
|
await runPlainLogin(url, opts.profile ?? DEFAULT_PROFILE, loginCloseFile, plainUa, emit);
|
|
392
422
|
return;
|
|
393
423
|
}
|
|
424
|
+
if (jar && loginMode === "none")
|
|
425
|
+
autoSyncLoginCookies(url, jar.path);
|
|
394
426
|
const channel = resolveBrowserChannel(opts, Boolean(headed));
|
|
395
427
|
const userAgent = resolveUserAgent({
|
|
396
428
|
requested: opts.userAgent,
|
|
397
429
|
env: process.env.HARNERY_BROWSER_UA,
|
|
398
430
|
chromeMajor: launchedChromeMajor(channel),
|
|
399
431
|
});
|
|
432
|
+
const cookieGuard = context?.cookieGuard?.();
|
|
400
433
|
const browser = new Browser({
|
|
401
434
|
profileDir: opts.profile ?? DEFAULT_PROFILE,
|
|
402
435
|
headed,
|
|
@@ -408,6 +441,7 @@ async function runBrowse(url, opts, context) {
|
|
|
408
441
|
waitUntil: opts.waitUntil,
|
|
409
442
|
recordHarPath: opts.networkHar ? resolve(opts.networkHar) : undefined,
|
|
410
443
|
extraHeaders: context?.extraHeaders,
|
|
444
|
+
...(cookieGuard ? { cookieGuard } : {}),
|
|
411
445
|
pace,
|
|
412
446
|
launchArgs: resolveLaunchArgs(opts, Boolean(headed), Boolean(proxy)),
|
|
413
447
|
...(channel ? { channel } : {}),
|
|
@@ -498,6 +532,7 @@ async function runBrowse(url, opts, context) {
|
|
|
498
532
|
runts = await browser.checkRunts({
|
|
499
533
|
scope: typeof opts.checkRunts === "string" ? opts.checkRunts : null,
|
|
500
534
|
minChars: Number.parseInt(opts.checkRuntsMinChars ?? "40", 10),
|
|
535
|
+
maxFindings: runtsMaxFindings,
|
|
501
536
|
});
|
|
502
537
|
}
|
|
503
538
|
const hasLayoutLint = (opts.checkAlign?.length ?? 0) > 0 ||
|
|
@@ -508,6 +543,7 @@ async function runBrowse(url, opts, context) {
|
|
|
508
543
|
let layoutLint;
|
|
509
544
|
if (hasLayoutLint) {
|
|
510
545
|
layoutLint = await browser.checkLayoutLint({
|
|
546
|
+
scanNodeBudget,
|
|
511
547
|
align: (opts.checkAlign ?? []).map((selector) => ({
|
|
512
548
|
selector,
|
|
513
549
|
axis: alignAxis,
|
|
@@ -544,6 +580,7 @@ async function runBrowse(url, opts, context) {
|
|
|
544
580
|
let content;
|
|
545
581
|
if (hasContentChecks) {
|
|
546
582
|
content = await browser.checkContent({
|
|
583
|
+
scanNodeBudget,
|
|
547
584
|
placeholder: opts.checkPlaceholder !== undefined
|
|
548
585
|
? { scope: contentScope(opts.checkPlaceholder) }
|
|
549
586
|
: null,
|
|
@@ -983,6 +1020,10 @@ async function runBrowse(url, opts, context) {
|
|
|
983
1020
|
process.exitCode = 2;
|
|
984
1021
|
}
|
|
985
1022
|
}
|
|
1023
|
+
catch (error) {
|
|
1024
|
+
// A cookie guard that stopped the session is the real failure, not the closed-page errors it caused.
|
|
1025
|
+
throw browser.cookieGuardFault ?? error;
|
|
1026
|
+
}
|
|
986
1027
|
finally {
|
|
987
1028
|
process.removeListener("SIGINT", handleSigint);
|
|
988
1029
|
process.removeListener("SIGTERM", handleSigterm);
|
|
@@ -991,6 +1032,8 @@ async function runBrowse(url, opts, context) {
|
|
|
991
1032
|
if (receivedSignal)
|
|
992
1033
|
process.exitCode = receivedSignal === "SIGINT" ? 130 : 143;
|
|
993
1034
|
}
|
|
1035
|
+
if (browser.cookieGuardFault)
|
|
1036
|
+
throw browser.cookieGuardFault;
|
|
994
1037
|
}
|
|
995
1038
|
function parsePositiveInt(raw, flag) {
|
|
996
1039
|
if (!/^\d+$/.test(raw.trim()) || Number.parseInt(raw, 10) < 1) {
|
|
@@ -1822,7 +1865,7 @@ async function runQaPlanning(browser, targetArg, renderedUrl, opts) {
|
|
|
1822
1865
|
const pageHeight = await browser.currentPage.evaluate(() => Math.max(document.documentElement.scrollHeight, document.body?.scrollHeight ?? 0));
|
|
1823
1866
|
const band = Number.parseInt(opts.checkCritiqueBand ?? "1400", 10);
|
|
1824
1867
|
const overlap = Number.parseInt(opts.checkCritiqueOverlap ?? "120", 10);
|
|
1825
|
-
const maxTiles =
|
|
1868
|
+
const maxTiles = critiqueTilingKnobs(opts).maxTiles;
|
|
1826
1869
|
const estimatedFullPageTiles = Math.min(maxTiles, Math.max(1, Math.ceil(pageHeight / Math.max(1, band - overlap))));
|
|
1827
1870
|
const explicitScopes = [];
|
|
1828
1871
|
for (const selector of opts.qaScope ?? []) {
|
|
@@ -1844,7 +1887,9 @@ async function runQaPlanning(browser, targetArg, renderedUrl, opts) {
|
|
|
1844
1887
|
* routed provider's vision long-edge budget caps band height so tiles are
|
|
1845
1888
|
* never silently downscaled by the model. */
|
|
1846
1889
|
function critiqueTilingKnobs(opts, tileBudgetPx) {
|
|
1847
|
-
|
|
1890
|
+
// No flag value can exceed the hard per-invocation ceiling.
|
|
1891
|
+
const requested = Number.parseInt(opts.checkCritiqueMaxTiles ?? "24", 10);
|
|
1892
|
+
const maxTiles = Math.min(PAGE_REVIEW_MAX_TILE_BUDGET, Math.max(1, Number.isFinite(requested) ? requested : 24));
|
|
1848
1893
|
const bandFlag = Math.max(200, Number.parseInt(opts.checkCritiqueBand ?? "1400", 10));
|
|
1849
1894
|
const band = tileBudgetPx ? Math.max(200, Math.min(bandFlag, tileBudgetPx)) : bandFlag;
|
|
1850
1895
|
const overlap = Math.max(0, Number.parseInt(opts.checkCritiqueOverlap ?? "120", 10));
|
|
@@ -2356,6 +2401,114 @@ async function runPlainLogin(url, profileDir, loginCloseFile, userAgent, emit) {
|
|
|
2356
2401
|
}
|
|
2357
2402
|
emit.log(`[--login] Chrome closed; cookies persisted in ${profileDir}.`, "info");
|
|
2358
2403
|
}
|
|
2404
|
+
/**
|
|
2405
|
+
* The WSL sign-in profile and the operations the cookie sync needs, or
|
|
2406
|
+
* `undefined` when this machine has none (not WSL, no Windows Chrome, or
|
|
2407
|
+
* `HARNERY_BROWSER_WSL_PLAIN=linux`).
|
|
2408
|
+
*/
|
|
2409
|
+
function windowsLoginProfile() {
|
|
2410
|
+
if (!useWindowsPlainLogin())
|
|
2411
|
+
return undefined;
|
|
2412
|
+
const chromeLinux = windowsChromePath();
|
|
2413
|
+
const localAppData = windowsLocalAppData();
|
|
2414
|
+
if (!chromeLinux || !localAppData)
|
|
2415
|
+
return undefined;
|
|
2416
|
+
const chromeWindows = wslPathToWindows(chromeLinux);
|
|
2417
|
+
const profileWindows = windowsPlainProfile(localAppData);
|
|
2418
|
+
const profileLinux = windowsPathToWsl(profileWindows);
|
|
2419
|
+
return {
|
|
2420
|
+
profileWindows,
|
|
2421
|
+
deps: {
|
|
2422
|
+
cookieDbMtimeMs: () => profileCookieDbMtimeMs(profileLinux),
|
|
2423
|
+
profileProcesses: () => windowsChromeProfileProcesses(profileWindows),
|
|
2424
|
+
harvest: (domain) => harvestWindowsChromeCookies({
|
|
2425
|
+
chromeWindows,
|
|
2426
|
+
profileWindows,
|
|
2427
|
+
domain,
|
|
2428
|
+
pageTimeoutSeconds: 0,
|
|
2429
|
+
}),
|
|
2430
|
+
},
|
|
2431
|
+
};
|
|
2432
|
+
}
|
|
2433
|
+
/** One-line summary of a sync that read cookies. Names only, never values. */
|
|
2434
|
+
function loginSyncSummary(result, storePath) {
|
|
2435
|
+
if (result.status === "synced") {
|
|
2436
|
+
return `Copied ${result.merged} ${result.domain} cookies (${result.sessionCookies} browser-session) from the sign-in profile into ${storePath}: ${result.names.join(", ")}.`;
|
|
2437
|
+
}
|
|
2438
|
+
return `The sign-in profile's ${result.domain} cookies (${result.cookies}) match the last copy; the cookie store was left as it is.`;
|
|
2439
|
+
}
|
|
2440
|
+
/**
|
|
2441
|
+
* Before a headless run under WSL, copy the target site's cookies from the
|
|
2442
|
+
* sign-in profile when the profile changed since the last copy and no
|
|
2443
|
+
* Chrome is open on it. Failures are warnings; the run continues.
|
|
2444
|
+
* `HARNERY_BROWSER_LOGIN_SYNC=off` turns it off.
|
|
2445
|
+
*/
|
|
2446
|
+
function autoSyncLoginCookies(url, storePath) {
|
|
2447
|
+
if ((process.env.HARNERY_BROWSER_LOGIN_SYNC ?? "").toLowerCase() === "off")
|
|
2448
|
+
return;
|
|
2449
|
+
let profile;
|
|
2450
|
+
let domain;
|
|
2451
|
+
try {
|
|
2452
|
+
profile = windowsLoginProfile();
|
|
2453
|
+
domain = harvestDomain(url);
|
|
2454
|
+
}
|
|
2455
|
+
catch {
|
|
2456
|
+
return;
|
|
2457
|
+
}
|
|
2458
|
+
if (!profile)
|
|
2459
|
+
return;
|
|
2460
|
+
try {
|
|
2461
|
+
const result = syncLoginCookies({ domain, storePath, deps: profile.deps });
|
|
2462
|
+
if (result.status === "open") {
|
|
2463
|
+
emit.log(`[login-sync] The shared sign-in window (Windows Chrome on ${profile.profileWindows}) is open and changed since ${domain} cookies were last copied; this run uses the cookie store as it is. Its ${domain} session reaches headless runs after you close that window, or run \`${browseBinName} browse --sync-login ${url}\` once it is closed.`, "info");
|
|
2464
|
+
}
|
|
2465
|
+
else if (result.status === "busy") {
|
|
2466
|
+
emit.log("[login-sync] Another run is copying sign-in cookies; this run did not wait.", "debug");
|
|
2467
|
+
}
|
|
2468
|
+
else if (result.status === "synced" || result.status === "unchanged") {
|
|
2469
|
+
emit.log(`[login-sync] ${loginSyncSummary(result, storePath)}`, "info");
|
|
2470
|
+
}
|
|
2471
|
+
}
|
|
2472
|
+
catch (err) {
|
|
2473
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
2474
|
+
emit.log(`[login-sync] Could not copy ${domain} cookies from the sign-in profile; continuing with the cookie store as it is. ${message}`, "warn");
|
|
2475
|
+
}
|
|
2476
|
+
}
|
|
2477
|
+
/** `--sync-login`: copy the URL's site cookies from the sign-in profile now. */
|
|
2478
|
+
function runSyncLogin(url, storePath) {
|
|
2479
|
+
const profile = windowsLoginProfile();
|
|
2480
|
+
if (!profile) {
|
|
2481
|
+
throw new Error("--sync-login needs WSL with the Windows Google Chrome; this machine has no Windows sign-in profile.");
|
|
2482
|
+
}
|
|
2483
|
+
const domain = harvestDomain(url);
|
|
2484
|
+
const result = syncLoginCookies({ domain, storePath, deps: profile.deps, force: true });
|
|
2485
|
+
if (result.status === "no-profile") {
|
|
2486
|
+
throw new Error(`The sign-in profile ${profile.profileWindows} has no cookies yet; sign in with \`${browseBinName} browse --login ${url}\` first.`);
|
|
2487
|
+
}
|
|
2488
|
+
if (result.status === "open") {
|
|
2489
|
+
throw new Error(`Chrome is open on the sign-in profile ${profile.profileWindows} (process ${result.processes.join(", ")}). Close that window, then run --sync-login again.`);
|
|
2490
|
+
}
|
|
2491
|
+
if (result.status === "busy") {
|
|
2492
|
+
throw new Error("Another run is copying sign-in cookies right now; try again in a moment.");
|
|
2493
|
+
}
|
|
2494
|
+
if (result.cookies === 0) {
|
|
2495
|
+
emit.log(`[--sync-login] No ${domain} cookies were found in the sign-in profile.`, "warn");
|
|
2496
|
+
}
|
|
2497
|
+
else {
|
|
2498
|
+
emit.log(`[--sync-login] ${loginSyncSummary(result, storePath)}`, "info");
|
|
2499
|
+
}
|
|
2500
|
+
emit.data({
|
|
2501
|
+
loginSync: {
|
|
2502
|
+
domain,
|
|
2503
|
+
store: storePath,
|
|
2504
|
+
status: result.status,
|
|
2505
|
+
cookies: result.cookies,
|
|
2506
|
+
merged: result.merged,
|
|
2507
|
+
sessionCookies: result.sessionCookies,
|
|
2508
|
+
names: result.names,
|
|
2509
|
+
},
|
|
2510
|
+
});
|
|
2511
|
+
}
|
|
2359
2512
|
/**
|
|
2360
2513
|
* Under WSL, `--login` opens the Windows host's Google Chrome when one
|
|
2361
2514
|
* is installed. Some sign-in flows reject every browser running inside WSL,
|
|
@@ -2411,6 +2564,17 @@ async function runWindowsPlainLogin(url, storePath, loginCloseFile, emit) {
|
|
|
2411
2564
|
await Promise.race([exited, new Promise((r) => setTimeout(r, 5000))]);
|
|
2412
2565
|
const domain = harvestDomain(url);
|
|
2413
2566
|
const { cookies, pages } = harvestWindowsChromeCookies({ chromeWindows, profileWindows, domain });
|
|
2567
|
+
try {
|
|
2568
|
+
recordLoginSync({
|
|
2569
|
+
domain,
|
|
2570
|
+
storePath,
|
|
2571
|
+
cookies,
|
|
2572
|
+
cookieDbMtimeMs: profileCookieDbMtimeMs(windowsPathToWsl(profileWindows)),
|
|
2573
|
+
});
|
|
2574
|
+
}
|
|
2575
|
+
catch {
|
|
2576
|
+
// The record only saves the next headless run a repeat read.
|
|
2577
|
+
}
|
|
2414
2578
|
const lastPage = pages[0] ?? null;
|
|
2415
2579
|
const names = [...new Set(cookies.map((cookie) => cookie.name))].sort();
|
|
2416
2580
|
const sessionCookies = cookies.filter((cookie) => cookie.expires <= 0).length;
|
package/dist/commands/fetch.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ledger-v3.d.ts","sourceRoot":"","sources":["../../src/commands/ledger-v3.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAwC1E,2DAA2D;AAC3D,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,WAAW,EACjB,OAAO,CAAC,EAAE,qBAAqB,GAC9B,IAAI,
|
|
1
|
+
{"version":3,"file":"ledger-v3.d.ts","sourceRoot":"","sources":["../../src/commands/ledger-v3.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAwC1E,2DAA2D;AAC3D,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,WAAW,EACjB,OAAO,CAAC,EAAE,qBAAqB,GAC9B,IAAI,CAsbN"}
|
|
@@ -3,7 +3,7 @@ import { createHash } from "node:crypto";
|
|
|
3
3
|
import { existsSync, mkdirSync, readFileSync } from "node:fs";
|
|
4
4
|
import { resolve } from "node:path";
|
|
5
5
|
import { compressSealedLegacyV1Segments, inventoryLegacyV1Segments, streamLegacyV1Rows, verifyLegacyV1HardFence, writeLegacyV1Canary, } from "../core/events/legacy-storage/index.js";
|
|
6
|
-
import { cleanEventV3Archives, initializeEventLedgerV3, inventoryEventV3Archives,
|
|
6
|
+
import { cleanEventV3Archives, initializeEventLedgerV3, inventoryEventV3Archives, readEventV3ControlState, recoverInvalidEventLedgerV3, scanHookProducerStateRecordsV3, sha256V3, } from "../core/events/v3/index.js";
|
|
7
7
|
import { authorizeEventV3SupportReplacement, inventoryEventV3Support, planEventV3SupportReplacement, planEventV3SupportTransaction, readEventV3SupportPackManifest, readEventV3SupportTransaction, streamEventV3SupportPackRecords, unpackEventV3SupportPack, verifyEventV3SupportTransactionShadow, writeEventV3SupportTransactionShadow, } from "../core/events/v3/support-storage/index.js";
|
|
8
8
|
import { stateDirMode } from "../core/storage/modes.js";
|
|
9
9
|
/** Inspect or initialize the universal V3 event ledger. */
|
|
@@ -19,7 +19,8 @@ export function registerLedgerV3Command(program, emit, context) {
|
|
|
19
19
|
try {
|
|
20
20
|
const root = resolve(options.root ?? coordRoot(context));
|
|
21
21
|
const control = readEventV3ControlState(root);
|
|
22
|
-
const
|
|
22
|
+
const scan = scanHookProducerStateRecordsV3(root, { includeTerminal: true });
|
|
23
|
+
const producers = scan.records;
|
|
23
24
|
const counts = producers.reduce((summary, record) => {
|
|
24
25
|
summary[record.state.adapter] = (summary[record.state.adapter] ?? 0) + 1;
|
|
25
26
|
return summary;
|
|
@@ -30,6 +31,11 @@ export function registerLedgerV3Command(program, emit, context) {
|
|
|
30
31
|
adapters: Object.keys(counts).sort(),
|
|
31
32
|
producer_states: producers.length,
|
|
32
33
|
producer_states_by_adapter: counts,
|
|
34
|
+
invalid_producer_states: scan.invalid.map((file) => ({
|
|
35
|
+
adapter: file.adapter,
|
|
36
|
+
session_hash: file.session_hash,
|
|
37
|
+
reason: file.reason,
|
|
38
|
+
})),
|
|
33
39
|
},
|
|
34
40
|
});
|
|
35
41
|
}
|