@deksden-com/dd-flow-cli 0.9.0-beta.14 → 0.9.0-beta.140
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/CHANGELOG.md +733 -0
- package/README.md +143 -1
- package/dist/build-info.json +8 -8
- package/dist/cli/argument-values.js +38 -0
- package/dist/cli/command-inputs.js +376 -0
- package/dist/cli/command-metadata.js +197 -0
- package/dist/cli/command-option-descriptions.js +191 -0
- package/dist/cli/completion-cli.js +70 -0
- package/dist/cli/completion.js +57 -0
- package/dist/cli/error-output.js +52 -0
- package/dist/cli/executor-onboarding.js +76 -0
- package/dist/cli/flows.js +29 -0
- package/dist/cli/harnesses.js +84 -0
- package/dist/cli/help.js +328 -18
- package/dist/cli/hook-ingress.js +78 -0
- package/dist/cli/input-preparation.js +165 -0
- package/dist/cli/memory-flow-admission.js +44 -0
- package/dist/cli/memory-init-invocation.js +78 -0
- package/dist/cli/memory-init.js +240 -0
- package/dist/cli/memory-storage-admission.js +53 -0
- package/dist/cli/models.js +39 -0
- package/dist/cli/native-hook-ingress.js +80 -0
- package/dist/cli/operator-profiles.js +61 -0
- package/dist/cli/output-options.js +35 -0
- package/dist/cli/response-file.js +71 -0
- package/dist/cli/run-cli.js +1689 -545
- package/dist/cli/runtime-maintenance-diagnostics.js +46 -0
- package/dist/cli/runtime-maintenance-ingress.js +52 -0
- package/dist/cli/runtime-process.js +153 -0
- package/dist/cli/setup.js +149 -0
- package/dist/cli.js +71 -2
- package/dist/domain/stage-catalog.js +1 -1
- package/dist/domain/stage-handler-identities.js +20 -0
- package/dist/harness-runtime/DD-ZCODE.md +112 -0
- package/dist/harness-runtime/OPENCODE-LICENSE.txt +24 -0
- package/dist/harness-runtime/bin/dd-agy.mjs +56 -0
- package/dist/harness-runtime/bin/dd-codex.mjs +27 -0
- package/dist/harness-runtime/bin/dd-droid.mjs +34 -0
- package/dist/harness-runtime/bin/dd-grok.mjs +40 -0
- package/dist/harness-runtime/bin/dd-opencode.mjs +22 -0
- package/dist/harness-runtime/bin/dd-zcode.mjs +87 -0
- package/dist/harness-runtime/lib/adapter-timeouts.d.mts +5 -0
- package/dist/harness-runtime/lib/adapter-timeouts.mjs +34 -0
- package/dist/harness-runtime/lib/agy-hooks.d.mts +1 -0
- package/dist/harness-runtime/lib/agy-hooks.mjs +9 -0
- package/dist/harness-runtime/lib/daemon-observation.d.mts +2 -0
- package/dist/harness-runtime/lib/daemon-observation.mjs +163 -0
- package/dist/harness-runtime/lib/daemon-operations.d.mts +1 -0
- package/dist/harness-runtime/lib/daemon-operations.mjs +371 -0
- package/dist/harness-runtime/lib/dd-agy-daemon.d.mts +6 -0
- package/dist/harness-runtime/lib/dd-agy-daemon.mjs +724 -0
- package/dist/harness-runtime/lib/dd-agy.mjs +70 -0
- package/dist/harness-runtime/lib/dd-codex-daemon.d.mts +1 -0
- package/dist/harness-runtime/lib/dd-codex-daemon.mjs +196 -0
- package/dist/harness-runtime/lib/dd-codex.d.mts +1 -0
- package/dist/harness-runtime/lib/dd-codex.mjs +817 -0
- package/dist/harness-runtime/lib/dd-droid-daemon.mjs +129 -0
- package/dist/harness-runtime/lib/dd-droid.mjs +584 -0
- package/dist/harness-runtime/lib/dd-grok-daemon.mjs +498 -0
- package/dist/harness-runtime/lib/dd-grok.mjs +177 -0
- package/dist/harness-runtime/lib/dd-opencode-daemon.mjs +507 -0
- package/dist/harness-runtime/lib/dd-opencode.mjs +354 -0
- package/dist/harness-runtime/lib/dd-zcode-daemon.mjs +750 -0
- package/dist/harness-runtime/lib/dd-zcode.mjs +1145 -0
- package/dist/harness-runtime/lib/delegation-instructions.d.mts +14 -0
- package/dist/harness-runtime/lib/delegation-instructions.mjs +157 -0
- package/dist/harness-runtime/lib/dispatch-fence.mjs +14 -0
- package/dist/harness-runtime/lib/driver-recovery.mjs +139 -0
- package/dist/harness-runtime/lib/droid-observation.mjs +66 -0
- package/dist/harness-runtime/lib/lease-renewal.d.mts +8 -0
- package/dist/harness-runtime/lib/lease-renewal.mjs +37 -0
- package/dist/harness-runtime/lib/lifecycle-command.d.mts +20 -0
- package/dist/harness-runtime/lib/lifecycle-command.mjs +273 -0
- package/dist/harness-runtime/lib/lifecycle-contract.d.mts +10 -0
- package/dist/harness-runtime/lib/lifecycle-contract.mjs +19 -0
- package/dist/harness-runtime/lib/managed-daemon.d.mts +13 -0
- package/dist/harness-runtime/lib/managed-daemon.mjs +654 -0
- package/dist/harness-runtime/lib/managed-flow-env.mjs +15 -0
- package/dist/harness-runtime/lib/model-observations.mjs +101 -0
- package/dist/harness-runtime/lib/native-children.d.mts +16 -0
- package/dist/harness-runtime/lib/native-children.mjs +113 -0
- package/dist/harness-runtime/lib/native-hook-command.d.mts +7 -0
- package/dist/harness-runtime/lib/native-hook-command.mjs +251 -0
- package/dist/harness-runtime/lib/native-request-proof.d.mts +2 -0
- package/dist/harness-runtime/lib/native-request-proof.mjs +65 -0
- package/dist/harness-runtime/lib/native-streams.mjs +45 -0
- package/dist/harness-runtime/lib/observation-clock.d.mts +18 -0
- package/dist/harness-runtime/lib/observation-clock.mjs +92 -0
- package/dist/harness-runtime/lib/opencode-plugin.mjs +85 -0
- package/dist/harness-runtime/lib/operation-context.mjs +5 -0
- package/dist/harness-runtime/lib/operation-errors.d.mts +14 -0
- package/dist/harness-runtime/lib/operation-errors.mjs +116 -0
- package/dist/harness-runtime/lib/operation-progress.d.mts +7 -0
- package/dist/harness-runtime/lib/operation-progress.mjs +114 -0
- package/dist/harness-runtime/lib/process-json.d.mts +5 -0
- package/dist/harness-runtime/lib/process-json.mjs +201 -0
- package/dist/harness-runtime/lib/process-snapshot.mjs +10 -0
- package/dist/harness-runtime/lib/provider-overload-policy.d.mts +13 -0
- package/dist/harness-runtime/lib/provider-overload-policy.mjs +138 -0
- package/dist/harness-runtime/lib/runner-events.mjs +200 -0
- package/dist/harness-runtime/lib/runner-lock.mjs +42 -0
- package/dist/harness-runtime/lib/session-settlement.mjs +30 -0
- package/dist/harness-runtime/lib/setup-progress.d.mts +9 -0
- package/dist/harness-runtime/lib/setup-progress.mjs +51 -0
- package/dist/harness-runtime/lib/tool-observations.d.mts +21 -0
- package/dist/harness-runtime/lib/tool-observations.mjs +228 -0
- package/dist/harness-runtime/lib/zcode-usage.mjs +55 -0
- package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-1y4a697q.js +81 -0
- package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-2ny4vxct.js +92 -0
- package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-6mptkzbc.js +0 -0
- package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-7x67cf1q.js +52 -0
- package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-9rqn6x4v.js +16 -0
- package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-9vdz0zwn.js +1661 -0
- package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-ecs5ftka.js +1466 -0
- package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-frbwqjmf.js +145 -0
- package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-gne7h7mq.js +50 -0
- package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-gx9wnkzr.js +105 -0
- package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-m2eywc8w.js +0 -0
- package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-nwcpakzx.js +12 -0
- package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-q4g3afnw.js +623 -0
- package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-qav6mfdz.js +0 -0
- package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-sxt88q69.js +12 -0
- package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-t1xa31vm.js +39 -0
- package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-ve4aws36.js +103 -0
- package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-vmytr4q8.js +4 -0
- package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-vt9jbch8.js +36 -0
- package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-vyas3vgt.js +0 -0
- package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-wjyeq25y.js +30 -0
- package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-xgnj2w4v.js +20 -0
- package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-y2etg5bs.js +9 -0
- package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-ydhz1zrh.js +238 -0
- package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-z6qdwcsf.js +62 -0
- package/dist/harness-runtime/vendor/opencode-client/contract.d.ts +1 -0
- package/dist/harness-runtime/vendor/opencode-client/contract.js +12 -0
- package/dist/harness-runtime/vendor/opencode-client/effect/api/api.d.ts +2806 -0
- package/dist/harness-runtime/vendor/opencode-client/effect/api/api.js +0 -0
- package/dist/harness-runtime/vendor/opencode-client/effect/api.d.ts +4 -0
- package/dist/harness-runtime/vendor/opencode-client/effect/api.js +0 -0
- package/dist/harness-runtime/vendor/opencode-client/effect/client.d.ts +2530 -0
- package/dist/harness-runtime/vendor/opencode-client/effect/client.js +15 -0
- package/dist/harness-runtime/vendor/opencode-client/effect/generated/client-error.d.ts +7 -0
- package/dist/harness-runtime/vendor/opencode-client/effect/generated/client-error.js +6 -0
- package/dist/harness-runtime/vendor/opencode-client/effect/generated/client.d.ts +2529 -0
- package/dist/harness-runtime/vendor/opencode-client/effect/generated/client.js +8 -0
- package/dist/harness-runtime/vendor/opencode-client/effect/generated/index.d.ts +2 -0
- package/dist/harness-runtime/vendor/opencode-client/effect/generated/index.js +12 -0
- package/dist/harness-runtime/vendor/opencode-client/effect/index.d.ts +35 -0
- package/dist/harness-runtime/vendor/opencode-client/effect/index.js +75 -0
- package/dist/harness-runtime/vendor/opencode-client/effect/rpc.d.ts +20 -0
- package/dist/harness-runtime/vendor/opencode-client/effect/rpc.js +11 -0
- package/dist/harness-runtime/vendor/opencode-client/effect/service.d.ts +90 -0
- package/dist/harness-runtime/vendor/opencode-client/effect/service.js +187 -0
- package/dist/harness-runtime/vendor/opencode-client/package.json +84 -0
- package/dist/harness-runtime/vendor/opencode-client/promise/api.d.ts +21 -0
- package/dist/harness-runtime/vendor/opencode-client/promise/api.js +0 -0
- package/dist/harness-runtime/vendor/opencode-client/promise/client.d.ts +252 -0
- package/dist/harness-runtime/vendor/opencode-client/promise/client.js +14 -0
- package/dist/harness-runtime/vendor/opencode-client/promise/generated/client-error.d.ts +8 -0
- package/dist/harness-runtime/vendor/opencode-client/promise/generated/client-error.js +6 -0
- package/dist/harness-runtime/vendor/opencode-client/promise/generated/client.d.ts +259 -0
- package/dist/harness-runtime/vendor/opencode-client/promise/generated/client.js +7 -0
- package/dist/harness-runtime/vendor/opencode-client/promise/generated/index.d.ts +3 -0
- package/dist/harness-runtime/vendor/opencode-client/promise/generated/index.js +79 -0
- package/dist/harness-runtime/vendor/opencode-client/promise/generated/types.d.ts +8932 -0
- package/dist/harness-runtime/vendor/opencode-client/promise/generated/types.js +70 -0
- package/dist/harness-runtime/vendor/opencode-client/promise/index.d.ts +6 -0
- package/dist/harness-runtime/vendor/opencode-client/promise/index.js +83 -0
- package/dist/harness-runtime/vendor/opencode-client/promise/rpc.d.ts +32 -0
- package/dist/harness-runtime/vendor/opencode-client/promise/rpc.js +7 -0
- package/dist/harness-runtime/vendor/opencode-client/promise/service.d.ts +24 -0
- package/dist/harness-runtime/vendor/opencode-client/promise/service.js +187 -0
- package/dist/harness-runtime/vendor/opencode-client/pty-handoff.d.ts +12 -0
- package/dist/harness-runtime/vendor/opencode-client/pty-handoff.js +14 -0
- package/dist/harness-runtime/vendor/opencode-client/rpc-runtime.d.ts +20 -0
- package/dist/harness-runtime/vendor/opencode-client/rpc-runtime.js +14 -0
- package/dist/harness-runtime/vendor/opencode-client/service-contender.d.ts +37 -0
- package/dist/harness-runtime/vendor/opencode-client/service-contender.js +10 -0
- package/dist/harness-runtime/vendor/opencode-client/service-probe.d.ts +70 -0
- package/dist/harness-runtime/vendor/opencode-client/service-probe.js +16 -0
- package/dist/harness-runtime/vendor/opencode-client/service-timing.d.ts +12 -0
- package/dist/harness-runtime/vendor/opencode-client/service-timing.js +10 -0
- package/dist/harness-runtime/vendor/opencode-client/service-version.d.ts +2 -0
- package/dist/harness-runtime/vendor/opencode-client/service-version.js +6 -0
- package/dist/harness-runtime/vendor/opencode-client/service.d.ts +52 -0
- package/dist/harness-runtime/vendor/opencode-client/service.js +1 -0
- package/dist/harness-runtime/vendor/opencode-client/shared-events.d.ts +11 -0
- package/dist/harness-runtime/vendor/opencode-client/shared-events.js +8 -0
- package/dist/harness-runtime/vendor/opencode-client/solid/connection.d.ts +37 -0
- package/dist/harness-runtime/vendor/opencode-client/solid/connection.js +10 -0
- package/dist/harness-runtime/vendor/opencode-client/solid/data.d.ts +211 -0
- package/dist/harness-runtime/vendor/opencode-client/solid/data.js +18 -0
- package/dist/harness-runtime/vendor/opencode-client/solid/index.d.ts +3 -0
- package/dist/harness-runtime/vendor/opencode-client/solid/index.js +32 -0
- package/dist/harness-runtime/vendor/opencode-client/solid/pty.d.ts +22 -0
- package/dist/harness-runtime/vendor/opencode-client/solid/pty.js +8 -0
- package/dist/harness-runtime/vendor/opencode-plugin.mjs +3 -0
- package/dist/protocol/local-files.js +18 -9
- package/dist/runtime/context.js +8 -4
- package/dist/schemas/agent-profile.schema.json +1 -1
- package/dist/schemas/code-review-result.schema.json +1 -1
- package/dist/schemas/code-verification.schema.json +7 -5
- package/dist/schemas/code-work-batch.schema.json +2 -2
- package/dist/schemas/discovery-result.schema.json +184 -0
- package/dist/schemas/execution-bundle.schema.json +205 -0
- package/dist/schemas/execution-settings.schema.json +162 -0
- package/dist/schemas/flow-descriptor.schema.json +54 -0
- package/dist/schemas/flow-run.schema.json +28 -0
- package/dist/schemas/harness-catalog.schema.json +80 -0
- package/dist/schemas/mb-init-compose-result.schema.json +457 -0
- package/dist/schemas/mb-init-discover-result.schema.json +500 -0
- package/dist/schemas/mb-init-finish-result.schema.json +422 -0
- package/dist/schemas/mb-init-preflight-result.schema.json +367 -0
- package/dist/schemas/mb-init-review-result.schema.json +396 -0
- package/dist/schemas/mb-init-verify-result.schema.json +391 -0
- package/dist/schemas/memory-bootstrap-receipt-v2.schema.json +67 -0
- package/dist/schemas/memory-bootstrap-receipt.schema.json +354 -0
- package/dist/schemas/memory-composition-work-result.schema.json +38 -0
- package/dist/schemas/memory-repair-work-result.schema.json +49 -0
- package/dist/schemas/memory-review-correction-plan.schema.json +30 -0
- package/dist/schemas/memory-review-work-result.schema.json +43 -0
- package/dist/schemas/model-catalog.schema.json +153 -0
- package/dist/schemas/plan-review-decision.schema.json +3 -3
- package/dist/schemas/plan-review-result.schema.json +2 -2
- package/dist/schemas/profile-settings.schema.json +122 -0
- package/dist/schemas/release-manifest.schema.json +291 -0
- package/dist/schemas/run-control-receipt.schema.json +118 -0
- package/dist/schemas/run-control-request.schema.json +36 -0
- package/dist/schemas/run-engine-binding.schema.json +1 -1
- package/dist/schemas/vnext-protocol-plan.schema.json +2 -2
- package/dist/services/branch-context.js +3 -3
- package/dist/services/canon.js +11 -8
- package/dist/services/check-runner-evidence.js +168 -0
- package/dist/services/cleanup.js +133 -40
- package/dist/services/cli-operation-classifier.js +25 -62
- package/dist/services/cli-upgrade-allowlist.js +27 -0
- package/dist/services/code-checks.js +1156 -107
- package/dist/services/codex-hook-delivery.js +32 -0
- package/dist/services/command-context.js +80 -0
- package/dist/services/compatibility-preflight.js +13 -3
- package/dist/services/config.js +11 -8
- package/dist/services/continuation-outcome.js +20 -0
- package/dist/services/controller-child-capacity.js +13 -0
- package/dist/services/controller-child-observer.js +115 -0
- package/dist/services/controller-execution.js +88 -0
- package/dist/services/controller-fanout.js +202 -0
- package/dist/services/dashboard.js +143 -58
- package/dist/services/descriptor-coordinator-session.js +35 -0
- package/dist/services/descriptor-root-work.js +53 -0
- package/dist/services/descriptor-run-settlement.js +105 -0
- package/dist/services/descriptor-run-start.js +449 -0
- package/dist/services/descriptor-stage-coordinator.js +197 -0
- package/dist/services/descriptor-stage-settlement.js +222 -0
- package/dist/services/descriptor-stage-start.js +139 -0
- package/dist/services/discovery/agy-discovery.js +2 -0
- package/dist/services/discovery/codex-discovery.js +2 -0
- package/dist/services/discovery/droid-discovery.js +2 -0
- package/dist/services/discovery/grok-discovery.js +2 -0
- package/dist/services/discovery/opencode-discovery.js +2 -0
- package/dist/services/discovery/static.js +31 -0
- package/dist/services/discovery/zcode-discovery.js +2 -0
- package/dist/services/engines.js +294 -153
- package/dist/services/eval-snapshots.js +1215 -116
- package/dist/services/execution-bundles.js +263 -0
- package/dist/services/execution-policy.js +185 -0
- package/dist/services/executor-onboarding.js +56 -0
- package/dist/services/external-work-launch.js +308 -0
- package/dist/services/flow-catalog.js +21 -0
- package/dist/services/flow-descriptors.js +82 -0
- package/dist/services/frozen-engine.js +250 -0
- package/dist/services/generic-execution.js +164 -0
- package/dist/services/harness-adapter.js +355 -36
- package/dist/services/harness-config.js +2 -0
- package/dist/services/harness-discovery.js +29 -0
- package/dist/services/harness-doctor.js +75 -0
- package/dist/services/harness-probe-effects.js +51 -0
- package/dist/services/harness-version-probe.js +100 -0
- package/dist/services/hooks.js +771 -325
- package/dist/services/hybrid-contracts.js +483 -0
- package/dist/services/ids.js +29 -1
- package/dist/services/installation-lock.js +95 -0
- package/dist/services/installed-flow-source.js +183 -0
- package/dist/services/lanes.js +78 -65
- package/dist/services/lifecycle-command.js +1 -288
- package/dist/services/lifecycle-contract.js +1 -0
- package/dist/services/lifecycle-invocations.js +2007 -0
- package/dist/services/managed-daemon-binding.js +38 -0
- package/dist/services/managed-lease-monitor.js +133 -0
- package/dist/services/managed-processes.js +475 -55
- package/dist/services/memory-accepted-composition.js +77 -0
- package/dist/services/memory-baseline-preservation.js +65 -0
- package/dist/services/memory-completed-correction-wave.js +320 -0
- package/dist/services/memory-compose-handler.js +258 -0
- package/dist/services/memory-composition-acceptance.js +199 -0
- package/dist/services/memory-composition-graph.js +134 -0
- package/dist/services/memory-composition-registration.js +146 -0
- package/dist/services/memory-composition-work-custody.js +151 -0
- package/dist/services/memory-composition-work-results.js +96 -0
- package/dist/services/memory-corrected-review-acceptance.js +129 -0
- package/dist/services/memory-corrected-review-batch.js +30 -0
- package/dist/services/memory-corrected-review-findings.js +106 -0
- package/dist/services/memory-corrected-review-inputs.js +210 -0
- package/dist/services/memory-corrected-review-projection.js +78 -0
- package/dist/services/memory-corrected-review-receipt.js +170 -0
- package/dist/services/memory-corrected-review-registration.js +191 -0
- package/dist/services/memory-correction-check-receipt.js +219 -0
- package/dist/services/memory-correction-input-owner.js +6 -0
- package/dist/services/memory-discover-handler.js +104 -0
- package/dist/services/memory-finish-evidence.js +435 -0
- package/dist/services/memory-finish-handler.js +215 -0
- package/dist/services/memory-finish-integration.js +280 -0
- package/dist/services/memory-finish-readiness.js +122 -0
- package/dist/services/memory-git-integration.js +151 -0
- package/dist/services/memory-historical-corrected-review.js +206 -0
- package/dist/services/memory-historical-original-review.js +130 -0
- package/dist/services/memory-historical-repair-registration.js +99 -0
- package/dist/services/memory-historical-second-review.js +128 -0
- package/dist/services/memory-init-bootstrap-readiness.js +210 -0
- package/dist/services/memory-init-contexts.js +89 -0
- package/dist/services/memory-init-controller-start.js +84 -0
- package/dist/services/memory-init-engine-release.js +223 -0
- package/dist/services/memory-init-git-policy.js +136 -0
- package/dist/services/memory-init-lint-capability.js +185 -0
- package/dist/services/memory-init-native-capacity.js +296 -0
- package/dist/services/memory-init-preflight.js +330 -0
- package/dist/services/memory-init-project-bootstrap.js +599 -0
- package/dist/services/memory-init-request-candidate.js +157 -0
- package/dist/services/memory-init-request-input.js +66 -0
- package/dist/services/memory-init-resource-storage.js +125 -0
- package/dist/services/memory-init-run-allocation.js +81 -0
- package/dist/services/memory-init-run-bundle.js +98 -0
- package/dist/services/memory-init-start.js +181 -0
- package/dist/services/memory-init-startup-custody.js +80 -0
- package/dist/services/memory-init-startup-input.js +240 -0
- package/dist/services/memory-init-storage.js +81 -0
- package/dist/services/memory-init-stores.js +359 -0
- package/dist/services/memory-init-worktrunk-capability.js +178 -0
- package/dist/services/memory-layer-publication.js +611 -0
- package/dist/services/memory-layer.js +156 -0
- package/dist/services/memory-lint-config.js +85 -0
- package/dist/services/memory-native-review-copy.js +165 -0
- package/dist/services/memory-normal-flow-entry.js +75 -0
- package/dist/services/memory-ordinary-defaults.js +112 -0
- package/dist/services/memory-preflight-bootstrap-custody.js +115 -0
- package/dist/services/memory-preflight-handler.js +259 -0
- package/dist/services/memory-repair-current-view.js +299 -0
- package/dist/services/memory-repair-document-delta.js +451 -0
- package/dist/services/memory-repair-history.js +491 -0
- package/dist/services/memory-repair-physical-binding.js +312 -0
- package/dist/services/memory-repair-publication-files.js +152 -0
- package/dist/services/memory-repair-publication-intent.js +27 -0
- package/dist/services/memory-repair-publication-plan.js +160 -0
- package/dist/services/memory-repair-publication-source.js +225 -0
- package/dist/services/memory-repair-publication.js +794 -0
- package/dist/services/memory-repair-registration.js +239 -0
- package/dist/services/memory-repair-work-baseline.js +413 -0
- package/dist/services/memory-repair-work-completion.js +97 -0
- package/dist/services/memory-repair-work-custody.js +73 -0
- package/dist/services/memory-repair-work-results.js +89 -0
- package/dist/services/memory-repair-workspace.js +252 -0
- package/dist/services/memory-repair-writer-copy.js +735 -0
- package/dist/services/memory-result-binding.js +173 -0
- package/dist/services/memory-retained-review-authority.js +129 -0
- package/dist/services/memory-retained-review-results.js +70 -0
- package/dist/services/memory-retained-second-baseline.js +102 -0
- package/dist/services/memory-retained-second-repairs.js +156 -0
- package/dist/services/memory-review-acceptance.js +214 -0
- package/dist/services/memory-review-correction-plan.js +171 -0
- package/dist/services/memory-review-handler.js +585 -0
- package/dist/services/memory-review-inputs.js +200 -0
- package/dist/services/memory-review-receipt.js +180 -0
- package/dist/services/memory-review-registration.js +108 -0
- package/dist/services/memory-review-work-custody.js +124 -0
- package/dist/services/memory-review-work-input.js +72 -0
- package/dist/services/memory-review-work-results.js +73 -0
- package/dist/services/memory-second-corrected-review-inputs.js +165 -0
- package/dist/services/memory-second-correction-plan.js +76 -0
- package/dist/services/memory-second-repair-baseline.js +91 -0
- package/dist/services/memory-second-repair-launch.js +614 -0
- package/dist/services/memory-second-repair-registration.js +88 -0
- package/dist/services/memory-second-repair-source.js +187 -0
- package/dist/services/memory-second-review-acceptance.js +115 -0
- package/dist/services/memory-source-observations.js +117 -0
- package/dist/services/memory-stage-dispatch.js +28 -0
- package/dist/services/memory-stage-results.js +199 -0
- package/dist/services/memory-verification-acceptance.js +135 -0
- package/dist/services/memory-verification-checks.js +252 -0
- package/dist/services/memory-verification-receipt.js +159 -0
- package/dist/services/memory-verify-handler.js +135 -0
- package/dist/services/memory-work-result-preparation.js +63 -0
- package/dist/services/merge-queue.js +228 -149
- package/dist/services/merge-server.js +161 -35
- package/dist/services/migrations.js +37 -16
- package/dist/services/model-catalog.js +109 -0
- package/dist/services/model-discovery.js +46 -0
- package/dist/services/native-daemon-history.js +49 -0
- package/dist/services/native-session-control.js +39 -0
- package/dist/services/operator-profiles.js +236 -0
- package/dist/services/plan-runtime.js +26 -11
- package/dist/services/plans.js +28 -25
- package/dist/services/projects.js +37 -17
- package/dist/services/prompts.js +28 -17
- package/dist/services/protocols.js +163 -87
- package/dist/services/provider-capacity.js +385 -0
- package/dist/services/recovery-observation-budget.js +121 -0
- package/dist/services/recovery-snapshot-database.js +560 -0
- package/dist/services/release-archive-producer.js +52 -0
- package/dist/services/release-archive.js +143 -0
- package/dist/services/release-cache.js +142 -0
- package/dist/services/release-compatibility.js +18 -0
- package/dist/services/release-download.js +67 -0
- package/dist/services/release-envelope.js +104 -0
- package/dist/services/release-manifest.js +45 -0
- package/dist/services/release-payload.js +114 -0
- package/dist/services/release-producer.js +63 -0
- package/dist/services/release-provenance.js +160 -0
- package/dist/services/release-registry.js +66 -0
- package/dist/services/release-source.js +194 -0
- package/dist/services/repair-intents.js +42 -0
- package/dist/services/review-copy.js +165 -0
- package/dist/services/review-deferral.js +23 -0
- package/dist/services/run-control-receipt.js +56 -0
- package/dist/services/run-control-worker.js +411 -0
- package/dist/services/run-control.js +1056 -0
- package/dist/services/run-controller-adapter.js +399 -0
- package/dist/services/run-controller-capture.js +186 -0
- package/dist/services/run-controller-process.js +208 -0
- package/dist/services/run-controller-recovery.js +289 -0
- package/dist/services/run-controller-state.js +97 -0
- package/dist/services/run-controller.js +1205 -0
- package/dist/services/run-engine-bindings.js +1 -1
- package/dist/services/run-fork.js +147 -0
- package/dist/services/run-health.js +149 -0
- package/dist/services/run-observations.js +152 -0
- package/dist/services/run-projection.js +22 -64
- package/dist/services/run-recovery-guard.js +77 -0
- package/dist/services/run-recovery-runtime.js +112 -0
- package/dist/services/run-recovery.js +489 -0
- package/dist/services/run-start-custody.js +177 -0
- package/dist/services/runs.js +1019 -247
- package/dist/services/runtime-budget.js +430 -0
- package/dist/services/runtime-command.js +43 -0
- package/dist/services/runtime-scope-capture.js +52 -0
- package/dist/services/runtime-scope-control.js +468 -0
- package/dist/services/runtime-scope-resume.js +599 -0
- package/dist/services/runtime-scope-stop.js +210 -0
- package/dist/services/runtime-scope-worker.js +287 -0
- package/dist/services/runtime-service.js +96 -0
- package/dist/services/schema-validation.js +10 -8
- package/dist/services/scope-writer-cleanup.js +27 -0
- package/dist/services/sessions.js +35 -69
- package/dist/services/setup.js +377 -0
- package/dist/services/stage-blocker.js +17 -7
- package/dist/services/stage-context.js +193 -19
- package/dist/services/stage-handlers.js +74 -0
- package/dist/services/stage-lifecycle.js +100 -108
- package/dist/services/stage-pause.js +89 -75
- package/dist/services/stage-report-renderer.js +234 -6
- package/dist/services/stage-work-graph.js +52 -0
- package/dist/services/tooling.js +32 -23
- package/dist/services/usage.js +49 -101
- package/dist/services/verification-matrix.js +374 -0
- package/dist/services/vnext-code-review.js +223 -88
- package/dist/services/vnext-code.js +327 -226
- package/dist/services/vnext-contracts.js +10 -1
- package/dist/services/vnext-execution-profile.js +80 -5
- package/dist/services/vnext-fanout.js +311 -19
- package/dist/services/vnext-merge.js +332 -111
- package/dist/services/vnext-plan-review.js +279 -127
- package/dist/services/vnext-plan.js +229 -104
- package/dist/services/vnext-protocolize.js +411 -86
- package/dist/services/vnext-specify.js +119 -81
- package/dist/services/vnext-workspace-policy.js +7 -2
- package/dist/services/work-registry.js +1627 -199
- package/dist/services/workspace-bootstrap.js +52 -15
- package/dist/services/workspace-files.js +85 -0
- package/dist/services/worktrees.js +98 -44
- package/dist/shared/entity-references.js +8 -0
- package/dist/shared/errors.js +17 -0
- package/dist/storage/agent-output.js +26 -0
- package/dist/storage/database.js +891 -39
- package/dist/storage/foreign-key-transaction.js +39 -0
- package/dist/storage/immutable-input.js +45 -0
- package/dist/storage/import-guard.js +102 -0
- package/dist/storage/native-cleanup.js +52 -0
- package/dist/storage/paths.js +17 -4
- package/dist/storage/projection-lock.js +73 -0
- package/dist/storage/work-references.js +23 -0
- package/dist/storage/writer-contract.js +89 -0
- package/dist/storage/writer-migration.js +85 -0
- package/package.json +43 -13
- package/tools/create-canon-release.mjs +33 -0
- package/tools/produce-hybrid-release.mjs +41 -0
- package/tools/repair-paused-run-status.mjs +84 -0
package/dist/services/engines.js
CHANGED
|
@@ -2,40 +2,75 @@ import crypto from "node:crypto";
|
|
|
2
2
|
import fs from "node:fs";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
|
-
import { spawn
|
|
5
|
+
import { spawn } from "node:child_process";
|
|
6
|
+
import { commandText } from '../harness-runtime/lib/process-json.mjs';
|
|
7
|
+
import { SETUP_STARTUP_MS, publishSetup } from '../harness-runtime/lib/setup-progress.mjs';
|
|
6
8
|
import { createRequire } from "node:module";
|
|
9
|
+
import { valid } from "semver";
|
|
7
10
|
import { getCliBuildInfo } from "./build-info.js";
|
|
8
11
|
import { AppError } from "../shared/errors.js";
|
|
9
12
|
import { ensureDir, engineStoreRoot, engineVersionRoot, resolveProjectRoot } from "../storage/paths.js";
|
|
10
|
-
import { classifyCliOperation } from "./cli-operation-classifier.js";
|
|
13
|
+
import { classifyCliOperation, isRouterNative } from "./cli-operation-classifier.js";
|
|
11
14
|
import { requireProtocol } from "./protocols.js";
|
|
12
15
|
import { resolveCanonRootBeforeContext } from "./canon.js";
|
|
13
16
|
import { appendAudit } from "./audit.js";
|
|
17
|
+
import { readBoundedReleaseFile } from "./release-source.js";
|
|
14
18
|
import { findProjectByRoot } from "./projects.js";
|
|
19
|
+
import { parseCommandArgs } from "./lifecycle-command.js";
|
|
15
20
|
import { allRunEngineBindings, locateRunRoot, readRunEngineBinding, runEngineBindingSchemaId, writeRunEngineBinding } from "./run-engine-bindings.js";
|
|
16
21
|
export const engineManifestSchemaId = "dd-flow/engine-manifest@1";
|
|
17
|
-
const routerNativeFamilies = new Set(["engine", "version", "schema"]);
|
|
18
22
|
const sourceFile = fileURLToPath(import.meta.url);
|
|
19
|
-
const packageRequire = createRequire(sourceFile);
|
|
20
23
|
export function isEngineMode(env) {
|
|
21
24
|
return env.DD_FLOW_ENGINE_MODE === "1";
|
|
22
25
|
}
|
|
23
26
|
export function isRouterNativeCommand(args) {
|
|
24
|
-
|
|
25
|
-
if (!first || first === "--version")
|
|
26
|
-
return true;
|
|
27
|
-
if (first === "--help" || first === "-h")
|
|
28
|
-
return true;
|
|
29
|
-
if (args.includes("--help") || args.includes("-h"))
|
|
30
|
-
return true;
|
|
31
|
-
return routerNativeFamilies.has(first) || first === "codex" && args[1] === "hook" && args[2] === "handle";
|
|
27
|
+
return isRouterNative(args);
|
|
32
28
|
}
|
|
33
29
|
export function installCurrentEngine(context, input = {}) {
|
|
30
|
+
const installation = prepareInstallation(context, input);
|
|
31
|
+
const first = installation.next();
|
|
32
|
+
if (first.done && input.forRouting)
|
|
33
|
+
return first.value;
|
|
34
|
+
const manifest = first.done ? requireManifest(path.join(String(first.value.path), 'engine.json')) : first.value;
|
|
35
|
+
return probeEntrypoint(manifest, undefined, context.ddFlowHome, process.env).then(() => first.done ? first.value : installation.next().value)
|
|
36
|
+
.catch(error => {
|
|
37
|
+
let cleanup_error;
|
|
38
|
+
try {
|
|
39
|
+
installation.return({});
|
|
40
|
+
}
|
|
41
|
+
catch (cleanup) {
|
|
42
|
+
cleanup_error = { message: String(cleanup).slice(0, 2000) };
|
|
43
|
+
}
|
|
44
|
+
throw new AppError('engine_install_failed', 'Staged engine admission failed', 1, { ...error.details, cause: error.code, probe_error: { code: error.code, details: error.details }, ...(cleanup_error ? { cleanup_error } : {}) });
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
function* prepareInstallation(context, input) {
|
|
34
48
|
const build = getCliBuildInfo();
|
|
35
49
|
const packageRoot = findPackageRoot(path.dirname(sourceFile));
|
|
36
50
|
if (!packageRoot) {
|
|
37
51
|
throw new AppError("engine_install_failed", "Cannot locate package root for current dd-flow engine", 1);
|
|
38
52
|
}
|
|
53
|
+
return yield* installPackageSnapshot(context, packageRoot, build.package_name, build.version, input);
|
|
54
|
+
}
|
|
55
|
+
/** Delivery from an independently selected package, not the invoking CLI.
|
|
56
|
+
* The caller owns release/dependency qualification of expectedChecksum.
|
|
57
|
+
* Existing snapshots are preserved even when not yet bound to a RUN. */
|
|
58
|
+
export function installPackageEngine(context, input) {
|
|
59
|
+
if (!path.isAbsolute(input.packageRoot) || fs.realpathSync(input.packageRoot) !== input.packageRoot
|
|
60
|
+
|| !/^(?:@[a-z0-9][a-z0-9._-]*\/)?[a-z0-9][a-z0-9._-]*$/.test(input.packageName)
|
|
61
|
+
|| valid(input.version) !== input.version
|
|
62
|
+
|| !/^[a-f0-9]{64}$/.test(input.expectedChecksum)) {
|
|
63
|
+
throw new AppError("engine_install_failed", "Selected package requires a canonical root and independent content checksum", 1, { effect: "no_effect" });
|
|
64
|
+
}
|
|
65
|
+
const metadata = JSON.parse(readBoundedReleaseFile(path.join(input.packageRoot, "package.json"), 1024 * 1024).toString("utf8"));
|
|
66
|
+
if (metadata.name !== input.packageName || metadata.version !== input.version
|
|
67
|
+
|| snapshotFilesChecksum(packageSnapshotFiles(input.packageRoot)) !== input.expectedChecksum) {
|
|
68
|
+
throw new AppError("engine_install_failed", "Selected package identity or contents changed before delivery", 1, { effect: "no_effect" });
|
|
69
|
+
}
|
|
70
|
+
return installPackageSnapshot(context, input.packageRoot, input.packageName, input.version, { force: true, forRouting: true }, input.expectedChecksum, input.validateStaged).next().value;
|
|
71
|
+
}
|
|
72
|
+
function* installPackageSnapshot(context, packageRoot, packageName, version, input, expectedChecksum, validateStaged) {
|
|
73
|
+
const build = { package_name: packageName, version };
|
|
39
74
|
const target = engineVersionRoot(context.ddFlowHome, build.package_name, build.version);
|
|
40
75
|
const manifestPath = path.join(target, "engine.json");
|
|
41
76
|
const existing = readManifest(manifestPath);
|
|
@@ -66,14 +101,24 @@ export function installCurrentEngine(context, input = {}) {
|
|
|
66
101
|
const tmp = path.join(parent, `.${path.basename(target)}.tmp-${process.pid}-${Date.now()}`);
|
|
67
102
|
fs.rmSync(tmp, { recursive: true, force: true });
|
|
68
103
|
ensureDir(tmp);
|
|
104
|
+
publishSetup('probe_started', `engine-staging:${tmp}`);
|
|
69
105
|
copyPackageSnapshot(packageRoot, tmp);
|
|
70
106
|
const stagedManifest = buildManifest(context, build.package_name, build.version, packageRoot, target, tmp);
|
|
71
107
|
const stagedChecksum = stagedManifest.integrity.checksum;
|
|
108
|
+
if (expectedChecksum !== undefined && stagedChecksum !== expectedChecksum) {
|
|
109
|
+
throw new AppError("engine_install_failed", "Selected package changed during delivery", 1, { effect: "partial", path: tmp });
|
|
110
|
+
}
|
|
111
|
+
try {
|
|
112
|
+
validateStaged?.(tmp);
|
|
113
|
+
}
|
|
114
|
+
catch (error) {
|
|
115
|
+
throw new AppError("engine_install_failed", "Staged package no longer matches its selected release", 1, { effect: "partial", path: tmp, reason: error instanceof AppError ? error.details.reason ?? error.code : "staged_selection_changed" });
|
|
116
|
+
}
|
|
72
117
|
const activationTarget = input.force
|
|
73
118
|
&& existing
|
|
74
119
|
&& stagedChecksum
|
|
75
120
|
&& stagedChecksum !== existing.integrity.checksum
|
|
76
|
-
&& engineIsBound(context.ddFlowHome, existing)
|
|
121
|
+
&& (expectedChecksum !== undefined || engineIsBound(context.ddFlowHome, existing))
|
|
77
122
|
? `${target}--${stagedChecksum}`
|
|
78
123
|
: target;
|
|
79
124
|
const duplicate = stagedChecksum ? findInstalledManifest(context.ddFlowHome, {
|
|
@@ -81,7 +126,7 @@ export function installCurrentEngine(context, input = {}) {
|
|
|
81
126
|
packageVersion: build.version,
|
|
82
127
|
integrityChecksum: stagedChecksum
|
|
83
128
|
}) : null;
|
|
84
|
-
if (duplicate) {
|
|
129
|
+
if (duplicate && manifestDiagnostics(duplicate, { checkEntrypoint: false }).length === 0) {
|
|
85
130
|
fs.rmSync(tmp, { recursive: true, force: true });
|
|
86
131
|
return {
|
|
87
132
|
ok: true,
|
|
@@ -94,13 +139,15 @@ export function installCurrentEngine(context, input = {}) {
|
|
|
94
139
|
const manifest = { ...stagedManifest, package_root: activationTarget, snapshot_root: activationTarget };
|
|
95
140
|
fs.writeFileSync(path.join(tmp, "engine.json"), `${JSON.stringify(manifest, null, 2)}\n`);
|
|
96
141
|
const checkedManifest = requireManifest(path.join(tmp, "engine.json"));
|
|
97
|
-
const stagedDiagnostics = manifestDiagnostics({ ...checkedManifest, package_root: tmp, snapshot_root: tmp }, { checkEntrypoint:
|
|
142
|
+
const stagedDiagnostics = manifestDiagnostics({ ...checkedManifest, package_root: tmp, snapshot_root: tmp }, { checkEntrypoint: false });
|
|
98
143
|
if (stagedDiagnostics.length > 0) {
|
|
99
144
|
throw new AppError("engine_install_failed", "Staged dd-flow engine failed its integrity or dependency health check", 1, {
|
|
100
145
|
diagnostics: stagedDiagnostics,
|
|
101
146
|
path: tmp
|
|
102
147
|
});
|
|
103
148
|
}
|
|
149
|
+
if (!input.forRouting)
|
|
150
|
+
yield { ...checkedManifest, package_root: tmp, snapshot_root: tmp };
|
|
104
151
|
activateEngineAtomically(tmp, activationTarget);
|
|
105
152
|
const installed = requireManifest(path.join(activationTarget, "engine.json"));
|
|
106
153
|
return {
|
|
@@ -117,7 +164,7 @@ export function installCurrentEngine(context, input = {}) {
|
|
|
117
164
|
}
|
|
118
165
|
export function listEngines(context) {
|
|
119
166
|
const root = engineStoreRoot(context.ddFlowHome);
|
|
120
|
-
const engines = readInstalledManifests(root).map(manifestSummary);
|
|
167
|
+
const engines = readInstalledManifests(root).map(manifest => manifestSummary(manifest));
|
|
121
168
|
return { ok: true, schema_id: "dd-flow/engine-list@1", engine_store: root, engines };
|
|
122
169
|
}
|
|
123
170
|
export function engineInfo(context, input) {
|
|
@@ -135,14 +182,23 @@ export function resolveEngine(context, input = {}) {
|
|
|
135
182
|
}
|
|
136
183
|
return { ok: true, schema_id: "dd-flow/engine-resolve@1", selection, contexts: compatibilityContexts(context, { ...input, classification }) };
|
|
137
184
|
}
|
|
138
|
-
export function doctorEngines(context, input = {}) {
|
|
185
|
+
export async function doctorEngines(context, input = {}) {
|
|
139
186
|
const root = engineStoreRoot(context.ddFlowHome);
|
|
140
187
|
const installed = readInstalledManifests(root);
|
|
141
|
-
const checks =
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
188
|
+
const checks = [];
|
|
189
|
+
for (const manifest of installed) {
|
|
190
|
+
const diagnostics = manifestDiagnostics(manifest);
|
|
191
|
+
let probe_error;
|
|
192
|
+
if (!diagnostics.length)
|
|
193
|
+
try {
|
|
194
|
+
await probeEntrypoint(manifest, undefined, context.ddFlowHome, context.env);
|
|
195
|
+
}
|
|
196
|
+
catch (error) {
|
|
197
|
+
probe_error = error instanceof AppError ? error.details : { message: String(error) };
|
|
198
|
+
diagnostics.push(error instanceof AppError && error.code === 'engine_probe_failed' ? 'entrypoint_dependency_load_failed' : 'entrypoint_probe_unavailable');
|
|
199
|
+
}
|
|
200
|
+
checks.push({ engine: manifestSummary(manifest, diagnostics), status: diagnostics.includes("entrypoint_probe_unavailable") ? "unverified" : diagnostics.length ? "corrupt" : "ok", diagnostics, ...(probe_error ? { probe_error } : {}) });
|
|
201
|
+
}
|
|
146
202
|
const classification = input.classification ?? classifyCliOperation(["engine", "doctor"], input.env ?? context.env);
|
|
147
203
|
const selection = selectEngine(context, input, {}, classification);
|
|
148
204
|
return {
|
|
@@ -155,7 +211,7 @@ export function doctorEngines(context, input = {}) {
|
|
|
155
211
|
exit_code: checks.every((check) => check.status === "ok") && selection.status === "selected" ? 0 : 1
|
|
156
212
|
};
|
|
157
213
|
}
|
|
158
|
-
export function routeArgsThroughEngine(context, args, io, stdin, env, resolvedProjectRoot) {
|
|
214
|
+
export async function routeArgsThroughEngine(context, args, io, stdin, env, resolvedProjectRoot) {
|
|
159
215
|
if (isEngineMode(env) || isRouterNativeCommand(args))
|
|
160
216
|
return Promise.resolve(null);
|
|
161
217
|
const classification = classifyCliOperation(args, env);
|
|
@@ -174,13 +230,18 @@ export function routeArgsThroughEngine(context, args, io, stdin, env, resolvedPr
|
|
|
174
230
|
if (!selection.selected)
|
|
175
231
|
return Promise.resolve(null);
|
|
176
232
|
const current = getCliBuildInfo();
|
|
177
|
-
|
|
233
|
+
const currentRoot = findPackageRoot(path.dirname(sourceFile));
|
|
234
|
+
if (selection.selected.package_name === current.package_name && selection.selected.package_version === current.version
|
|
235
|
+
&& currentRoot !== null && fs.realpathSync(selection.selected.snapshot_root) === fs.realpathSync(currentRoot)) {
|
|
178
236
|
return Promise.resolve({ routed: true, exitCode: 0, inProcess: true });
|
|
179
237
|
}
|
|
180
238
|
const entrypoint = resolveManifestEntrypoint(selection.selected);
|
|
239
|
+
// The admitted immutable entrypoint executes the requested operation itself.
|
|
240
|
+
// A separate --version process adds no operation-specific admission.
|
|
181
241
|
return spawnEngine(selection.selected, entrypoint, args, io, stdin, env, current.version);
|
|
182
242
|
}
|
|
183
|
-
export function
|
|
243
|
+
export async function prepareRunEngineBind(context, input) {
|
|
244
|
+
const reason = requiredText(input.reason, "reason");
|
|
184
245
|
const projectRoot = resolveProjectRoot(input.projectRoot);
|
|
185
246
|
const located = locateRunRoot(context.db, projectRoot, input.runId);
|
|
186
247
|
if (!located)
|
|
@@ -190,40 +251,43 @@ export function bindRunEngine(context, input) {
|
|
|
190
251
|
packageName: input.packageName ?? getCliBuildInfo().package_name,
|
|
191
252
|
packageVersion: input.engineVersion,
|
|
192
253
|
...(input.integrityChecksum ? { integrityChecksum: input.integrityChecksum } : {})
|
|
193
|
-
});
|
|
254
|
+
}, { checkEntrypoint: false });
|
|
194
255
|
const requested = engineIdentity(manifest);
|
|
195
256
|
if (existing) {
|
|
196
257
|
if (sameEngineIdentity(existing.engine, requested))
|
|
197
|
-
return {
|
|
258
|
+
return { kind: "replay", binding: existing };
|
|
198
259
|
throw new AppError("run_engine_binding_immutable", "RUN engine binding cannot be changed", 1, {
|
|
199
260
|
run_id: located.run_id,
|
|
200
261
|
current: existing.engine,
|
|
201
262
|
requested
|
|
202
263
|
});
|
|
203
264
|
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
265
|
+
await probeEntrypoint(manifest, ['run', 'status', located.run_id, '--project-root', projectRoot, '--json'], context.ddFlowHome, context.env, 'run_engine');
|
|
266
|
+
return { kind: "create", projectRoot, located, manifest, requested, reason, entrypoint: resolveManifestEntrypoint(manifest) };
|
|
267
|
+
}
|
|
268
|
+
export async function bindRunEngine(context, input, supplied) {
|
|
269
|
+
const prepared = supplied ?? await prepareRunEngineBind(context, input);
|
|
270
|
+
if (prepared.kind === "replay")
|
|
271
|
+
return { ok: true, action: "run_engine_bind", changed: false, binding: prepared.binding };
|
|
272
|
+
const { projectRoot, located, manifest, requested, reason } = prepared;
|
|
273
|
+
const current = locateRunRoot(context.db, projectRoot, input.runId);
|
|
274
|
+
if (!current || current.run_root !== located.run_root)
|
|
275
|
+
throw new AppError('run_engine_binding_conflict', 'RUN identity changed during probe', 1);
|
|
276
|
+
requireBoundManifest(context.ddFlowHome, { packageName: manifest.package_name, packageVersion: manifest.package_version, integrityChecksum: requested.integrity_checksum });
|
|
277
|
+
const existing = readRunEngineBinding(located.binding_path, { allowMissing: true });
|
|
278
|
+
if (existing) {
|
|
279
|
+
if (sameEngineIdentity(existing.engine, requested))
|
|
280
|
+
return { ok: true, action: "run_engine_bind", changed: false, binding: existing };
|
|
281
|
+
throw new AppError("run_engine_binding_immutable", "RUN engine binding cannot be changed", 1, { run_id: located.run_id, current: existing.engine, requested });
|
|
219
282
|
}
|
|
283
|
+
const probeArgs = ["run", "status", located.run_id, "--project-root", projectRoot, "--json"];
|
|
220
284
|
const binding = {
|
|
221
285
|
schema_id: runEngineBindingSchemaId,
|
|
222
286
|
run_id: located.run_id,
|
|
223
287
|
project_root: projectRoot,
|
|
224
288
|
bound_at: context.now(),
|
|
225
289
|
source: "legacy_recovery",
|
|
226
|
-
reason
|
|
290
|
+
reason,
|
|
227
291
|
engine: requested,
|
|
228
292
|
probe: { status: "passed", command: `dd-flow ${probeArgs.join(" ")}` }
|
|
229
293
|
};
|
|
@@ -252,6 +316,36 @@ export function bindCurrentEngineToRun(context, input) {
|
|
|
252
316
|
};
|
|
253
317
|
return writeRunEngineBinding(path.join(input.runRoot, "engine-binding.json"), binding).binding;
|
|
254
318
|
}
|
|
319
|
+
/** Forks are a new execution authority. The source binding stays immutable;
|
|
320
|
+
* this replaces only the copied binding after proving the selected engine can
|
|
321
|
+
* read the copied RUN. */
|
|
322
|
+
export async function upgradeForkedRunEngine(context, input) {
|
|
323
|
+
const projectRoot = resolveProjectRoot(input.projectRoot);
|
|
324
|
+
const located = locateRunRoot(context.db, projectRoot, input.runId);
|
|
325
|
+
if (!located)
|
|
326
|
+
throw new AppError("not_found", `Forked RUN is not registered: ${input.runId}`, 1);
|
|
327
|
+
const manifest = requireBoundManifest(context.ddFlowHome, {
|
|
328
|
+
packageName: getCliBuildInfo().package_name,
|
|
329
|
+
packageVersion: input.engineVersion,
|
|
330
|
+
...(input.integrityChecksum ? { integrityChecksum: input.integrityChecksum } : {})
|
|
331
|
+
});
|
|
332
|
+
const requested = engineIdentity(manifest);
|
|
333
|
+
const priorBinding = fs.readFileSync(located.binding_path, 'utf8');
|
|
334
|
+
const lineage = path.join(located.run_root, "fork-lineage.json");
|
|
335
|
+
if (!fs.existsSync(lineage))
|
|
336
|
+
throw new AppError("fork_lineage_missing", "Engine upgrade is permitted only for a derived RUN", 1, { run_id: located.run_id });
|
|
337
|
+
const probeArgs = ["run", "status", located.run_id, "--project-root", projectRoot, "--json"];
|
|
338
|
+
const priorLineage = fs.readFileSync(lineage, 'utf8');
|
|
339
|
+
await probeEntrypoint(manifest, probeArgs, context.ddFlowHome, context.env, 'fork_engine');
|
|
340
|
+
if (fs.readFileSync(located.binding_path, 'utf8') !== priorBinding || fs.readFileSync(lineage, 'utf8') !== priorLineage)
|
|
341
|
+
throw new AppError('fork_engine_binding_conflict', 'Fork identity changed during probe', 1);
|
|
342
|
+
requireBoundManifest(context.ddFlowHome, { packageName: manifest.package_name, packageVersion: manifest.package_version, integrityChecksum: manifest.integrity.checksum });
|
|
343
|
+
const binding = { schema_id: runEngineBindingSchemaId, run_id: located.run_id, project_root: projectRoot, bound_at: context.now(), source: "fork_upgrade", reason: requiredText(input.reason, "reason"), engine: requested, probe: { status: "passed", command: `dd-flow ${probeArgs.join(" ")}` } };
|
|
344
|
+
const temporary = `${located.binding_path}.fork-${process.pid}-${Date.now()}.tmp`;
|
|
345
|
+
fs.writeFileSync(temporary, `${JSON.stringify(binding, null, 2)}\n`);
|
|
346
|
+
fs.renameSync(temporary, located.binding_path);
|
|
347
|
+
return binding;
|
|
348
|
+
}
|
|
255
349
|
function boundRunEngineForArgs(context, args, projectRoot) {
|
|
256
350
|
const runId = runIdForArgs(args);
|
|
257
351
|
if (!runId || !projectRoot)
|
|
@@ -274,6 +368,8 @@ function runIdForArgs(args) {
|
|
|
274
368
|
const [family, command, ...rest] = args;
|
|
275
369
|
const parsed = parseLightArgs(rest);
|
|
276
370
|
if (family === "run" && command !== "start" && command !== "list") {
|
|
371
|
+
if (["drive", "control", "recovery", "capacity"].includes(command ?? ""))
|
|
372
|
+
return option(parsed, "run");
|
|
277
373
|
if (command === "flags")
|
|
278
374
|
return positional(parsed, 1);
|
|
279
375
|
return positional(parsed, 0);
|
|
@@ -290,7 +386,7 @@ function runIdForArgs(args) {
|
|
|
290
386
|
return option(parsed, "run");
|
|
291
387
|
return null;
|
|
292
388
|
}
|
|
293
|
-
function requireBoundManifest(ddFlowHome, input) {
|
|
389
|
+
function requireBoundManifest(ddFlowHome, input, options = {}) {
|
|
294
390
|
const manifest = input.snapshotRoot
|
|
295
391
|
? requireManifest(path.join(input.snapshotRoot, "engine.json"))
|
|
296
392
|
: findInstalledManifest(ddFlowHome, {
|
|
@@ -303,7 +399,7 @@ function requireBoundManifest(ddFlowHome, input) {
|
|
|
303
399
|
|| manifest.package_version !== input.packageVersion
|
|
304
400
|
|| input.integrityChecksum !== undefined && manifest.integrity.checksum !== input.integrityChecksum
|
|
305
401
|
|| input.snapshotRoot !== undefined && path.resolve(manifest.snapshot_root) !== path.resolve(input.snapshotRoot)
|
|
306
|
-
||
|
|
402
|
+
|| manifestDiagnostics(manifest, options).length !== 0) {
|
|
307
403
|
throw new AppError("run_engine_binding_invalid", "RUN engine binding points to a missing or unhealthy engine snapshot", 1, {
|
|
308
404
|
package_name: input.packageName,
|
|
309
405
|
package_version: input.packageVersion,
|
|
@@ -344,7 +440,7 @@ function executionManifest(context) {
|
|
|
344
440
|
return requireManifest(path.join(String(installed.path), "engine.json"));
|
|
345
441
|
}
|
|
346
442
|
function requiredText(value, label) {
|
|
347
|
-
const normalized = value.trim();
|
|
443
|
+
const normalized = typeof value === "string" ? value.trim() : "";
|
|
348
444
|
if (!normalized)
|
|
349
445
|
throw new AppError("usage", `Missing required value: ${label}`, 2);
|
|
350
446
|
return normalized;
|
|
@@ -380,14 +476,14 @@ export function selectEngine(context, input, options = {}, classification = inpu
|
|
|
380
476
|
const requiredRange = stringValue(compatibility?.engine?.version_range) ?? (classification.mode === "mb_upgrade" ? null : `>=${build.version} <9999.0.0`);
|
|
381
477
|
const recommended = stringValue(compatibility?.engine?.recommended_version) ?? build.version;
|
|
382
478
|
const installHintTemplate = stringValue(compatibility?.engine?.old_engine_install_hint) ?? `npx ${packageName}@<version> engine install`;
|
|
383
|
-
|
|
479
|
+
// An engine-mode caller already executes this module's build. Another
|
|
480
|
+
// installed engine cannot establish compatibility for its current writes.
|
|
481
|
+
// Keep full snapshot validation in routing/binding, not lease maintenance.
|
|
482
|
+
const executingCurrent = options.allowCurrentInProcess && isEngineMode(input.env ?? process.env);
|
|
483
|
+
const manifests = executingCurrent ? [] : readInstalledManifests(engineStoreRoot(context.ddFlowHome))
|
|
384
484
|
.filter((manifest) => manifest.package_name === packageName)
|
|
385
485
|
.filter((manifest) => requiredRange !== null && satisfiesRange(manifest.package_version, requiredRange))
|
|
386
|
-
.filter((manifest) =>
|
|
387
|
-
&& manifest.package_name === build.package_name
|
|
388
|
-
&& manifest.package_version === build.version
|
|
389
|
-
? true
|
|
390
|
-
: manifestHealthy(manifest))
|
|
486
|
+
.filter((manifest) => manifestHealthy(manifest))
|
|
391
487
|
.sort((a, b) => {
|
|
392
488
|
const versionOrder = compareSemverStrings(b.package_version, a.package_version);
|
|
393
489
|
if (versionOrder !== 0)
|
|
@@ -402,7 +498,7 @@ export function selectEngine(context, input, options = {}, classification = inpu
|
|
|
402
498
|
requiredRange !== null &&
|
|
403
499
|
packageName === build.package_name &&
|
|
404
500
|
satisfiesRange(build.version, requiredRange)
|
|
405
|
-
? currentBuildManifest(context, build)
|
|
501
|
+
? currentBuildManifest(context, build, options.verifyCurrentContent !== false)
|
|
406
502
|
: null);
|
|
407
503
|
const diagnostics = [
|
|
408
504
|
...targetBlockers,
|
|
@@ -420,9 +516,38 @@ export function selectEngine(context, input, options = {}, classification = inpu
|
|
|
420
516
|
diagnostics
|
|
421
517
|
};
|
|
422
518
|
}
|
|
423
|
-
function currentBuildManifest(context, build) {
|
|
519
|
+
function currentBuildManifest(context, build, verifyContent) {
|
|
424
520
|
const packageRoot = findPackageRoot(path.dirname(sourceFile)) ?? process.cwd();
|
|
425
|
-
|
|
521
|
+
const manifestFile = path.join(packageRoot, "engine.json");
|
|
522
|
+
const installedLayout = path.basename(path.dirname(path.dirname(packageRoot))) === "engines"
|
|
523
|
+
&& path.basename(path.dirname(packageRoot)) === path.basename(path.dirname(engineVersionRoot(context.ddFlowHome, build.package_name, build.version)));
|
|
524
|
+
if (fs.existsSync(manifestFile) || installedLayout) {
|
|
525
|
+
const installed = readManifest(manifestFile);
|
|
526
|
+
// Use the executing module's physical root, never an environment alias.
|
|
527
|
+
// A damaged installed manifest must not become a development fallback.
|
|
528
|
+
if (!installed || installed.package_name !== build.package_name || installed.package_version !== build.version
|
|
529
|
+
|| installed.engine_version !== build.version || installed.engine_id !== "dd-flow-engine"
|
|
530
|
+
|| typeof installed.snapshot_root !== "string" || !fs.existsSync(installed.snapshot_root)
|
|
531
|
+
|| fs.realpathSync(installed.snapshot_root) !== fs.realpathSync(packageRoot)
|
|
532
|
+
|| typeof installed.entrypoint !== "string" || installed.integrity?.source !== "package_snapshot"
|
|
533
|
+
|| typeof installed.integrity?.checksum !== "string" || !/^[a-f0-9]{64}$/.test(installed.integrity.checksum)
|
|
534
|
+
|| (installed.schema_registry && (!Array.isArray(installed.schema_registry.entries)
|
|
535
|
+
|| installed.schema_registry.entries.some(entry => !entry || typeof entry.path !== "string"
|
|
536
|
+
|| typeof entry.id !== "string" || typeof entry.name !== "string" || !/^[a-f0-9]{64}$/.test(entry.checksum ?? ""))))) {
|
|
537
|
+
throw new AppError("unhealthy_engine", "Executing engine snapshot manifest does not match its build", 1, { manifest: manifestFile });
|
|
538
|
+
}
|
|
539
|
+
const diagnostics = manifestDiagnostics(installed, { checkEntrypoint: false, verifyContent });
|
|
540
|
+
if (diagnostics.length)
|
|
541
|
+
throw new AppError("unhealthy_engine", "Executing engine snapshot is unhealthy", 1, { manifest: manifestFile, diagnostics });
|
|
542
|
+
return installed;
|
|
543
|
+
}
|
|
544
|
+
// Only an unmaterialized package has no snapshot proof. Canon and
|
|
545
|
+
// package-manager aliases are expected in development checkouts.
|
|
546
|
+
const manifest = buildManifest(context, build.package_name, build.version, packageRoot, packageRoot, packageRoot, null);
|
|
547
|
+
// An ephemeral routing choice has no snapshot proof. Hash bytes only when
|
|
548
|
+
// materializing/validating an installed snapshot, never on every CLI call.
|
|
549
|
+
manifest.integrity.mode = "degraded_local_development";
|
|
550
|
+
return manifest;
|
|
426
551
|
}
|
|
427
552
|
export function compatibilityContexts(context, input = {}) {
|
|
428
553
|
const env = input.env ?? process.env;
|
|
@@ -560,40 +685,16 @@ function canonCompatibilitySha(memorybankRoot) {
|
|
|
560
685
|
return null;
|
|
561
686
|
}
|
|
562
687
|
}
|
|
563
|
-
|
|
564
|
-
const positional = [];
|
|
565
|
-
const options = new Map();
|
|
566
|
-
for (let index = 0; index < args.length; index += 1) {
|
|
567
|
-
const value = args[index];
|
|
568
|
-
if (value?.startsWith("--")) {
|
|
569
|
-
const equal = value.indexOf("=");
|
|
570
|
-
if (equal > 2) {
|
|
571
|
-
const key = value.slice(2, equal);
|
|
572
|
-
options.set(key, [...(options.get(key) ?? []), value.slice(equal + 1)]);
|
|
573
|
-
continue;
|
|
574
|
-
}
|
|
575
|
-
const key = value.slice(2);
|
|
576
|
-
const next = args[index + 1];
|
|
577
|
-
if (!next || next.startsWith("--"))
|
|
578
|
-
options.set(key, [...(options.get(key) ?? []), ""]);
|
|
579
|
-
else {
|
|
580
|
-
options.set(key, [...(options.get(key) ?? []), next]);
|
|
581
|
-
index += 1;
|
|
582
|
-
}
|
|
583
|
-
}
|
|
584
|
-
else if (value)
|
|
585
|
-
positional.push(value);
|
|
586
|
-
}
|
|
587
|
-
return { positional, options };
|
|
588
|
-
}
|
|
688
|
+
const parseLightArgs = parseCommandArgs;
|
|
589
689
|
function option(parsed, key) {
|
|
590
690
|
const values = parsed.options.get(key);
|
|
591
|
-
|
|
691
|
+
const value = values?.[values.length - 1];
|
|
692
|
+
return value && value !== "__dd_flow_flag__" ? value : null;
|
|
592
693
|
}
|
|
593
694
|
function positional(parsed, index) {
|
|
594
695
|
return parsed.positional[index] ?? null;
|
|
595
696
|
}
|
|
596
|
-
function buildManifest(context, packageName, version, packageRoot, snapshotRoot, checksumRoot) {
|
|
697
|
+
function buildManifest(context, packageName, version, packageRoot, snapshotRoot, checksumRoot, checksum = engineSnapshotChecksum(checksumRoot)) {
|
|
597
698
|
return {
|
|
598
699
|
schema_id: engineManifestSchemaId,
|
|
599
700
|
package_name: packageName,
|
|
@@ -609,35 +710,54 @@ function buildManifest(context, packageName, version, packageRoot, snapshotRoot,
|
|
|
609
710
|
supports_contracts: {
|
|
610
711
|
compatibility: ["dd-flow/compatibility@1"],
|
|
611
712
|
version: ["dd-flow/version-report@1"],
|
|
612
|
-
status: ["dd-flow/status-report@1"]
|
|
713
|
+
status: ["dd-flow/status-report@1"],
|
|
714
|
+
hybrid: ["dd-flow/flow-descriptor@1", "dd-flow/execution-settings@1", "dd-flow/execution-bundle@1", "dd-flow/memory-bootstrap-receipt@2"]
|
|
613
715
|
},
|
|
614
716
|
schema_registry: buildSchemaRegistry(checksumRoot),
|
|
615
717
|
integrity: {
|
|
616
718
|
source: "package_snapshot",
|
|
617
|
-
checksum
|
|
719
|
+
checksum,
|
|
618
720
|
mode: "full_content"
|
|
619
721
|
}
|
|
620
722
|
};
|
|
621
723
|
}
|
|
622
724
|
function copyPackageSnapshot(packageRoot, target) {
|
|
725
|
+
let copied = 0;
|
|
726
|
+
for (const [relative, source] of packageSnapshotFiles(packageRoot)) {
|
|
727
|
+
const destination = path.join(target, relative);
|
|
728
|
+
ensureDir(path.dirname(destination));
|
|
729
|
+
fs.copyFileSync(source, destination);
|
|
730
|
+
if (++copied % 64 === 0)
|
|
731
|
+
publishSetup('transfer_progress', `${target}:${copied}`);
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
/** The same source inventory drives validation and copying; no staging writes. */
|
|
735
|
+
export function packageSnapshotFiles(packageRoot) {
|
|
736
|
+
const files = new Map();
|
|
737
|
+
const collect = (source, relative, skipNodeModules = false) => {
|
|
738
|
+
if (!fs.statSync(source).isDirectory()) {
|
|
739
|
+
files.set(relative, source);
|
|
740
|
+
return;
|
|
741
|
+
}
|
|
742
|
+
for (const entry of fs.readdirSync(source, { withFileTypes: true })) {
|
|
743
|
+
if (skipNodeModules && entry.name === "node_modules")
|
|
744
|
+
continue;
|
|
745
|
+
const child = path.join(source, entry.name), name = path.join(relative, entry.name);
|
|
746
|
+
if (entry.isDirectory())
|
|
747
|
+
collect(child, name, skipNodeModules);
|
|
748
|
+
else if (entry.isFile())
|
|
749
|
+
files.set(name, child);
|
|
750
|
+
}
|
|
751
|
+
};
|
|
623
752
|
for (const item of ["dist", "package.json", "README.md", "CHANGELOG.md", "tools"]) {
|
|
624
753
|
const from = path.join(packageRoot, item);
|
|
625
754
|
if (!fs.existsSync(from))
|
|
626
755
|
continue;
|
|
627
|
-
|
|
628
|
-
const stat = fs.statSync(from);
|
|
629
|
-
if (stat.isDirectory())
|
|
630
|
-
copyDir(from, to);
|
|
631
|
-
else {
|
|
632
|
-
ensureDir(path.dirname(to));
|
|
633
|
-
fs.copyFileSync(from, to);
|
|
634
|
-
}
|
|
756
|
+
collect(from, item);
|
|
635
757
|
}
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
const queue = [{ sourceRoot: packageRoot, targetRoot: target, ancestors: new Set() }];
|
|
640
|
-
const copied = new Set();
|
|
758
|
+
const queue = [{ sourceRoot: packageRoot, targetRoot: "" }];
|
|
759
|
+
const placed = new Map();
|
|
760
|
+
const virtualRoot = path.resolve(path.sep, "dd-flow-snapshot");
|
|
641
761
|
while (queue.length > 0) {
|
|
642
762
|
const current = queue.shift();
|
|
643
763
|
if (!current)
|
|
@@ -646,17 +766,48 @@ function copyProductionDependencies(packageRoot, target) {
|
|
|
646
766
|
const sourceRoot = resolvePackageRoot(dependency, current.sourceRoot);
|
|
647
767
|
if (!sourceRoot)
|
|
648
768
|
throw new AppError("engine_install_failed", `Cannot resolve runtime dependency: ${dependency}`, 1);
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
769
|
+
// Standard Node lookup permits hoisting identical selected packages.
|
|
770
|
+
// Copying a shared DAG under every parent makes SDK snapshots grow
|
|
771
|
+
// exponentially; conflicting versions still need their own local slot.
|
|
772
|
+
const search = createRequire(path.join(virtualRoot, current.targetRoot, "package.json")).resolve.paths(dependency) ?? [];
|
|
773
|
+
const candidates = search.filter(directory => directory.startsWith(`${virtualRoot}${path.sep}`))
|
|
774
|
+
.map(directory => path.relative(virtualRoot, path.join(directory, dependency)));
|
|
775
|
+
const existing = candidates.find(candidate => placed.has(candidate));
|
|
776
|
+
if (existing && placed.get(existing) === sourceRoot)
|
|
652
777
|
continue;
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
queue.push({ sourceRoot, targetRoot, ancestors: new Set([...current.ancestors, sourceRoot]) });
|
|
778
|
+
const targetRoot = existing ? path.join(current.targetRoot, "node_modules", dependency) : path.join("node_modules", dependency);
|
|
779
|
+
placed.set(targetRoot, sourceRoot);
|
|
780
|
+
collect(sourceRoot, targetRoot, true);
|
|
781
|
+
queue.push({ sourceRoot, targetRoot });
|
|
658
782
|
}
|
|
659
783
|
}
|
|
784
|
+
return files;
|
|
785
|
+
}
|
|
786
|
+
export function prepareForkEngine(engineVersion, integrityChecksum) {
|
|
787
|
+
const build = getCliBuildInfo();
|
|
788
|
+
if (engineVersion !== build.version)
|
|
789
|
+
throw new AppError("fork_engine_unavailable", "Fork installs the invoking CLI engine; invoke the requested version to upgrade the fork", 2, { requested: engineVersion, available: build.version });
|
|
790
|
+
const packageRoot = findPackageRoot(path.dirname(sourceFile));
|
|
791
|
+
if (!packageRoot || !fs.existsSync(path.join(packageRoot, "dist", "cli.js")))
|
|
792
|
+
throw new AppError("harness_runtime_unbuilt", "Build the CLI before preparing a fork", 1);
|
|
793
|
+
const files = packageSnapshotFiles(packageRoot);
|
|
794
|
+
if (integrityChecksum !== undefined) {
|
|
795
|
+
const checksum = snapshotFilesChecksum(files);
|
|
796
|
+
if (checksum !== integrityChecksum)
|
|
797
|
+
throw new AppError("fork_engine_unavailable", "Requested engine checksum differs from the invoking CLI artifact", 2, { requested: integrityChecksum });
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
function snapshotFilesChecksum(files) {
|
|
801
|
+
const checksum = crypto.createHash("sha256");
|
|
802
|
+
for (const [relative, source] of [...files].sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0)) {
|
|
803
|
+
if (path.basename(relative) === "engine.json")
|
|
804
|
+
continue;
|
|
805
|
+
checksum.update(relative);
|
|
806
|
+
checksum.update("\0");
|
|
807
|
+
checksum.update(fs.readFileSync(source));
|
|
808
|
+
checksum.update("\0");
|
|
809
|
+
}
|
|
810
|
+
return checksum.digest("hex");
|
|
660
811
|
}
|
|
661
812
|
function readProductionDependencies(packageRoot) {
|
|
662
813
|
try {
|
|
@@ -676,20 +827,14 @@ function readProductionDependencies(packageRoot) {
|
|
|
676
827
|
}
|
|
677
828
|
}
|
|
678
829
|
function resolvePackageRoot(name, from) {
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
if (parent === current)
|
|
686
|
-
return null;
|
|
687
|
-
current = parent;
|
|
688
|
-
}
|
|
689
|
-
}
|
|
690
|
-
catch {
|
|
691
|
-
return null;
|
|
830
|
+
// Inspect package roots through Node's lookup paths, not the require entry:
|
|
831
|
+
// production dependencies can expose only an ESM import condition.
|
|
832
|
+
for (const directory of createRequire(path.join(from, "package.json")).resolve.paths(name) ?? []) {
|
|
833
|
+
const candidate = path.join(directory, name);
|
|
834
|
+
if (fs.existsSync(path.join(candidate, "package.json")))
|
|
835
|
+
return fs.realpathSync(candidate);
|
|
692
836
|
}
|
|
837
|
+
return null;
|
|
693
838
|
}
|
|
694
839
|
function inferInstallSource(packageRoot, ddFlowHome) {
|
|
695
840
|
const normalized = path.resolve(packageRoot);
|
|
@@ -713,19 +858,6 @@ function hasAncestorFile(start, name) {
|
|
|
713
858
|
current = parent;
|
|
714
859
|
}
|
|
715
860
|
}
|
|
716
|
-
function copyDir(from, to, skipNodeModules = false) {
|
|
717
|
-
ensureDir(to);
|
|
718
|
-
for (const entry of fs.readdirSync(from, { withFileTypes: true })) {
|
|
719
|
-
if (skipNodeModules && entry.name === "node_modules")
|
|
720
|
-
continue;
|
|
721
|
-
const source = path.join(from, entry.name);
|
|
722
|
-
const target = path.join(to, entry.name);
|
|
723
|
-
if (entry.isDirectory())
|
|
724
|
-
copyDir(source, target, skipNodeModules);
|
|
725
|
-
else if (entry.isFile())
|
|
726
|
-
fs.copyFileSync(source, target);
|
|
727
|
-
}
|
|
728
|
-
}
|
|
729
861
|
function acquireInstallLock(lockDir) {
|
|
730
862
|
ensureDir(path.dirname(lockDir));
|
|
731
863
|
try {
|
|
@@ -750,6 +882,9 @@ function readInstalledManifests(root) {
|
|
|
750
882
|
if (!fs.statSync(packageRoot).isDirectory())
|
|
751
883
|
continue;
|
|
752
884
|
for (const versionDir of fs.readdirSync(packageRoot)) {
|
|
885
|
+
// Failed staging, activation backups and locks are not installations.
|
|
886
|
+
if (versionDir.startsWith(".") || /\.previous-\d+-\d+$/.test(versionDir) || versionDir.endsWith(".lock"))
|
|
887
|
+
continue;
|
|
753
888
|
const manifest = readManifest(path.join(packageRoot, versionDir, "engine.json"));
|
|
754
889
|
if (manifest)
|
|
755
890
|
manifests.push(manifest);
|
|
@@ -802,7 +937,7 @@ function manifestDiagnostics(manifest, options = {}) {
|
|
|
802
937
|
if (!manifest.integrity || manifest.integrity.mode !== "full_content" || !manifest.integrity.checksum) {
|
|
803
938
|
diagnostics.push("content_checksum_missing");
|
|
804
939
|
}
|
|
805
|
-
else if (fs.existsSync(snapshotRoot)) {
|
|
940
|
+
else if (options.verifyContent !== false && fs.existsSync(snapshotRoot)) {
|
|
806
941
|
try {
|
|
807
942
|
if (engineSnapshotChecksum(snapshotRoot) !== manifest.integrity.checksum)
|
|
808
943
|
diagnostics.push("content_checksum_mismatch");
|
|
@@ -816,6 +951,8 @@ function manifestDiagnostics(manifest, options = {}) {
|
|
|
816
951
|
const schemaPath = safeResolveSnapshotPath(manifest, entry.path);
|
|
817
952
|
if (!schemaPath || !fs.existsSync(schemaPath))
|
|
818
953
|
diagnostics.push(`schema_registry_missing:${entry.name}`);
|
|
954
|
+
else if (options.verifyContent === false)
|
|
955
|
+
continue;
|
|
819
956
|
else if (fileChecksum(schemaPath) !== entry.checksum)
|
|
820
957
|
diagnostics.push(`schema_registry_checksum_mismatch:${entry.name}`);
|
|
821
958
|
else {
|
|
@@ -829,25 +966,21 @@ function manifestDiagnostics(manifest, options = {}) {
|
|
|
829
966
|
}
|
|
830
967
|
}
|
|
831
968
|
}
|
|
832
|
-
if (options.checkEntrypoint !== false && entrypoint && fs.existsSync(entrypoint) && !diagnostics.includes("entrypoint_outside_snapshot")) {
|
|
833
|
-
const health = spawnSync(process.execPath, [entrypoint, "--version", "--json"], {
|
|
834
|
-
cwd: snapshotRoot,
|
|
835
|
-
env: {
|
|
836
|
-
...process.env,
|
|
837
|
-
DD_FLOW_ENGINE_MODE: "1",
|
|
838
|
-
DD_FLOW_ENGINE_HOME: snapshotRoot,
|
|
839
|
-
DD_FLOW_ENGINE_HEALTHCHECK: "1"
|
|
840
|
-
},
|
|
841
|
-
encoding: "utf8",
|
|
842
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
843
|
-
timeout: 15_000
|
|
844
|
-
});
|
|
845
|
-
if (health.status !== 0)
|
|
846
|
-
diagnostics.push("entrypoint_dependency_load_failed");
|
|
847
|
-
}
|
|
848
969
|
return diagnostics;
|
|
849
970
|
}
|
|
850
|
-
function
|
|
971
|
+
async function probeEntrypoint(manifest, args = ['--version', '--json'], runtimeHome, env = {}, purpose = 'engine') {
|
|
972
|
+
publishSetup('probe_started', manifest.snapshot_root);
|
|
973
|
+
try {
|
|
974
|
+
await commandText(resolveManifestEntrypoint(manifest), args, { cwd: manifest.snapshot_root,
|
|
975
|
+
env: { ...env, DD_FLOW_ENGINE_MODE: '1', DD_FLOW_ENGINE_HOME: manifest.snapshot_root, ...(runtimeHome ? { DD_FLOW_HOME: runtimeHome } : {}), ...(args[0] === '--version' ? { DD_FLOW_ENGINE_HEALTHCHECK: '1' } : {}) }, startupMs: SETUP_STARTUP_MS, phase: 'engine-probe' });
|
|
976
|
+
publishSetup('probe_completed', manifest.snapshot_root);
|
|
977
|
+
}
|
|
978
|
+
catch (cause) {
|
|
979
|
+
const error = cause;
|
|
980
|
+
throw new AppError(error.details?.reason === 'child_exit' && error.details?.signal === null && error.details?.exit_code !== null ? `${purpose}_probe_failed` : `${purpose}_probe_unavailable`, 'Selected engine probe did not complete successfully', 1, { cause: error.code, message: error.message, ...error.details });
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
function manifestSummary(manifest, diagnostics = manifestDiagnostics(manifest, { checkEntrypoint: false })) {
|
|
851
984
|
return {
|
|
852
985
|
schema_id: manifest.schema_id,
|
|
853
986
|
package_name: manifest.package_name,
|
|
@@ -859,8 +992,8 @@ function manifestSummary(manifest) {
|
|
|
859
992
|
snapshot_root: manifest.snapshot_root,
|
|
860
993
|
resolved_entrypoint: safeResolveManifestEntrypoint(manifest),
|
|
861
994
|
installed_at: manifest.installed_at,
|
|
862
|
-
healthy:
|
|
863
|
-
diagnostics
|
|
995
|
+
healthy: diagnostics.length === 0,
|
|
996
|
+
diagnostics
|
|
864
997
|
};
|
|
865
998
|
}
|
|
866
999
|
function resolveManifestEntrypoint(manifest) {
|
|
@@ -1011,22 +1144,30 @@ function findPackageRoot(start) {
|
|
|
1011
1144
|
}
|
|
1012
1145
|
}
|
|
1013
1146
|
export function engineSnapshotChecksum(root) {
|
|
1147
|
+
publishSetup('probe_started', `engine-digest:${root}`);
|
|
1014
1148
|
const files = [];
|
|
1015
1149
|
collectFiles(root, root, files);
|
|
1016
1150
|
const checksum = crypto.createHash("sha256");
|
|
1151
|
+
let checked = 0;
|
|
1017
1152
|
for (const file of files.sort()) {
|
|
1018
1153
|
checksum.update(file);
|
|
1019
1154
|
checksum.update("\0");
|
|
1020
1155
|
checksum.update(fs.readFileSync(path.join(root, file)));
|
|
1156
|
+
if (++checked % 64 === 0)
|
|
1157
|
+
publishSetup('identity_digest_progress', `${root}:${checked}`);
|
|
1021
1158
|
checksum.update("\0");
|
|
1022
1159
|
}
|
|
1023
|
-
|
|
1160
|
+
const result = checksum.digest("hex");
|
|
1161
|
+
publishSetup('identity_digest_completed', root);
|
|
1162
|
+
return result;
|
|
1024
1163
|
}
|
|
1025
1164
|
function collectFiles(root, current, files) {
|
|
1026
1165
|
for (const entry of fs.readdirSync(current, { withFileTypes: true })) {
|
|
1027
1166
|
if (entry.name === "engine.json")
|
|
1028
1167
|
continue;
|
|
1029
1168
|
const full = path.join(current, entry.name);
|
|
1169
|
+
if (entry.isSymbolicLink())
|
|
1170
|
+
throw new AppError("engine_integrity_symlink", "Pinned engine snapshot contains an unhashed symbolic link", 1, { path: path.relative(root, full) });
|
|
1030
1171
|
if (entry.isDirectory())
|
|
1031
1172
|
collectFiles(root, full, files);
|
|
1032
1173
|
else if (entry.isFile())
|