@deksden-com/dd-flow-cli 0.9.0-beta.151 → 0.9.0-beta.155
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 +23 -0
- package/dist/build-info.json +8 -8
- package/dist/cli/command-inputs.js +33 -3
- package/dist/cli/command-metadata.js +73 -2
- package/dist/cli/delivery.js +108 -0
- package/dist/cli/diagnostic-invocation.js +23 -7
- package/dist/cli/diagnostic.js +14 -3
- package/dist/cli/help.js +117 -1
- package/dist/cli/hook-ingress.js +36 -49
- package/dist/cli/interactive-invocation.js +33 -0
- package/dist/cli/interactive.js +114 -0
- package/dist/cli/memory-fix-invocation.js +52 -0
- package/dist/cli/memory-fix.js +100 -0
- package/dist/cli/memory-flow-admission.js +7 -3
- package/dist/cli/memory-init.js +5 -4
- package/dist/cli/native-hook-ingress.js +5 -1
- package/dist/cli/native-hook-preparation.js +31 -4
- package/dist/cli/run-cli.js +273 -19
- package/dist/cli.js +17 -3
- package/dist/domain/delivery-flows.js +8 -0
- package/dist/domain/distill-flow.js +20 -0
- package/dist/domain/interactive-flow.js +1 -0
- package/dist/domain/memory-fix-flow.js +2 -0
- package/dist/domain/review-fix-flow.js +2 -0
- package/dist/domain/source-snapshot-flows.js +4 -0
- package/dist/harness-runtime/bin/dd-agy.mjs +18 -3
- package/dist/harness-runtime/bin/dd-grok.mjs +15 -5
- package/dist/harness-runtime/bin/dd-zcode.mjs +15 -7
- package/dist/harness-runtime/lib/agy-error-boundary.mjs +18 -10
- package/dist/harness-runtime/lib/agy-native-inspection.mjs +12 -3
- package/dist/harness-runtime/lib/agy-native-inventory.mjs +19 -0
- package/dist/harness-runtime/lib/agy-terminal-envelope.mjs +13 -6
- package/dist/harness-runtime/lib/agy-transcript-stream.mjs +54 -0
- package/dist/harness-runtime/lib/daemon-observation.d.mts +1 -0
- package/dist/harness-runtime/lib/daemon-observation.mjs +12 -4
- package/dist/harness-runtime/lib/daemon-operations.mjs +20 -5
- package/dist/harness-runtime/lib/dd-agy-daemon.d.mts +1 -0
- package/dist/harness-runtime/lib/dd-agy-daemon.mjs +371 -114
- package/dist/harness-runtime/lib/dd-codex-daemon.mjs +43 -3
- package/dist/harness-runtime/lib/dd-codex.mjs +36 -4
- package/dist/harness-runtime/lib/dd-droid-daemon.mjs +25 -11
- package/dist/harness-runtime/lib/dd-droid.mjs +124 -11
- package/dist/harness-runtime/lib/dd-grok-daemon.d.mts +1 -0
- package/dist/harness-runtime/lib/dd-grok-daemon.mjs +137 -25
- package/dist/harness-runtime/lib/dd-grok.mjs +4 -2
- package/dist/harness-runtime/lib/dd-opencode-daemon.mjs +170 -25
- package/dist/harness-runtime/lib/dd-opencode.mjs +40 -19
- package/dist/harness-runtime/lib/dd-zcode-daemon.d.mts +1 -0
- package/dist/harness-runtime/lib/dd-zcode-daemon.mjs +115 -22
- package/dist/harness-runtime/lib/dd-zcode.mjs +75 -36
- package/dist/harness-runtime/lib/delegation-instructions.d.mts +1 -0
- package/dist/harness-runtime/lib/delegation-instructions.mjs +10 -3
- package/dist/harness-runtime/lib/delivery-command.mjs +84 -0
- package/dist/harness-runtime/lib/driver-recovery.mjs +0 -19
- package/dist/harness-runtime/lib/droid-observation.mjs +9 -5
- package/dist/harness-runtime/lib/lifecycle-contract.d.mts +1 -0
- package/dist/harness-runtime/lib/lifecycle-contract.mjs +2 -1
- package/dist/harness-runtime/lib/native-hook-command.d.mts +3 -2
- package/dist/harness-runtime/lib/native-hook-command.mjs +63 -8
- package/dist/harness-runtime/lib/native-streams.mjs +3 -10
- package/dist/harness-runtime/lib/opencode-plugin.mjs +36 -9
- package/dist/harness-runtime/lib/operation-errors.mjs +13 -0
- package/dist/harness-runtime/lib/operation-progress.mjs +6 -2
- package/dist/harness-runtime/lib/process-json.mjs +4 -5
- package/dist/harness-runtime/lib/tool-observations.mjs +20 -10
- package/dist/harness-runtime/lib/zcode-native-hook-ownership.mjs +109 -0
- package/dist/schemas/code-work-result.schema.json +2 -1
- package/dist/schemas/delivery-stage-result.schema.json +286 -0
- package/dist/schemas/distill-stage-result.schema.json +667 -0
- package/dist/schemas/distill-work-result.schema.json +428 -0
- package/dist/schemas/execution-bundle.schema.json +6 -2
- package/dist/schemas/interactive-stage-result.schema.json +47 -0
- package/dist/schemas/interactive-work-result.schema.json +63 -0
- package/dist/schemas/mb-fix-stage-result.schema.json +93 -0
- package/dist/schemas/project-flow-pack-manifest.schema.json +2 -2
- package/dist/schemas/review-fix-stage-result.schema.json +210 -0
- package/dist/schemas/run-control-receipt.schema.json +1 -0
- package/dist/services/assigned-lifecycle.js +382 -0
- package/dist/services/check-runner-evidence.js +77 -10
- package/dist/services/check-runner-proof.js +69 -1
- package/dist/services/cli-operation-classifier.js +6 -1
- package/dist/services/code-checks.js +56 -23
- package/dist/services/codex-hook-delivery.js +11 -2
- package/dist/services/controller-execution.js +4 -1
- package/dist/services/controller-fanout.js +9 -4
- package/dist/services/controller-memory-worker.js +6 -4
- package/dist/services/controller-result-authority.js +122 -0
- package/dist/services/dashboard.js +4 -2
- package/dist/services/delivery-access.js +123 -0
- package/dist/services/delivery-approval.js +68 -0
- package/dist/services/delivery-artifact.js +86 -0
- package/dist/services/delivery-checks.js +178 -0
- package/dist/services/delivery-execution.js +181 -0
- package/dist/services/delivery-intents.js +212 -0
- package/dist/services/delivery-operation.js +81 -0
- package/dist/services/delivery-policy.js +91 -0
- package/dist/services/delivery-procedures.js +43 -0
- package/dist/services/delivery-request.js +99 -0
- package/dist/services/delivery-result.js +144 -0
- package/dist/services/delivery-stage-commands.js +26 -0
- package/dist/services/delivery-stage-entry.js +56 -0
- package/dist/services/delivery-stage-handlers.js +135 -0
- package/dist/services/delivery-stage-results.js +94 -0
- package/dist/services/descriptor-coordinator-session.js +3 -1
- package/dist/services/descriptor-run-start.js +24 -4
- package/dist/services/descriptor-stage-coordinator.js +78 -10
- package/dist/services/descriptor-stage-settlement.js +59 -14
- package/dist/services/diagnostic-repair-intake.js +123 -0
- package/dist/services/diagnostic-repair-source-intake.js +102 -0
- package/dist/services/diagnostic-report.js +30 -0
- package/dist/services/diagnostic-run-bundle.js +48 -9
- package/dist/services/diagnostic-snapshot.js +2 -2
- package/dist/services/diagnostic-stage-handlers.js +3 -2
- package/dist/services/diagnostic-stage-results.js +26 -0
- package/dist/services/diagnostic-start.js +56 -6
- package/dist/services/diagnostic-work-collection.js +3 -3
- package/dist/services/distill-document-publication.js +280 -0
- package/dist/services/distill-promotion.js +197 -0
- package/dist/services/distill-publication-custody.js +162 -0
- package/dist/services/distill-stage-handlers.js +249 -0
- package/dist/services/distill-stage-results.js +105 -0
- package/dist/services/distill-user-inputs.js +4 -0
- package/dist/services/distill-work-batch.js +42 -0
- package/dist/services/distill-work-collection.js +74 -0
- package/dist/services/distill-work-registration.js +93 -0
- package/dist/services/distill-work-results.js +98 -0
- package/dist/services/eval-snapshots.js +17 -7
- package/dist/services/external-work-launch.js +8 -2
- package/dist/services/flow-catalog.js +24 -0
- package/dist/services/frozen-engine.js +19 -2
- package/dist/services/generic-execution.js +4 -3
- package/dist/services/harness-adapter.js +2 -14
- package/dist/services/hook-memory-routing.js +1 -1
- package/dist/services/hooks.js +31 -6
- package/dist/services/hybrid-contracts.js +6 -1
- package/dist/services/installed-flow-source.js +37 -2
- package/dist/services/interactive-attached-session.js +215 -0
- package/dist/services/interactive-baseline-custody.js +54 -0
- package/dist/services/interactive-before-versions.js +148 -0
- package/dist/services/interactive-bundle-data.js +85 -0
- package/dist/services/interactive-checks.js +179 -0
- package/dist/services/interactive-execution.js +33 -0
- package/dist/services/interactive-finish-integration.js +236 -0
- package/dist/services/interactive-git-baseline.js +230 -0
- package/dist/services/interactive-git-dispatch.js +278 -0
- package/dist/services/interactive-input-delivery.js +82 -0
- package/dist/services/interactive-mutation-scope.js +231 -0
- package/dist/services/interactive-request.js +287 -0
- package/dist/services/interactive-run-bundle.js +109 -0
- package/dist/services/interactive-stage-entry.js +41 -0
- package/dist/services/interactive-stage-handlers.js +289 -0
- package/dist/services/interactive-stage-observation.js +136 -0
- package/dist/services/interactive-stage-results.js +111 -0
- package/dist/services/interactive-user-inputs.js +142 -0
- package/dist/services/interactive-work-batch.js +43 -0
- package/dist/services/interactive-work-collection.js +119 -0
- package/dist/services/interactive-work-completion.js +180 -0
- package/dist/services/interactive-work-context.js +249 -0
- package/dist/services/interactive-work-history.js +112 -0
- package/dist/services/interactive-work-registration.js +124 -0
- package/dist/services/interactive-work-results.js +115 -0
- package/dist/services/interactive-work-start.js +155 -0
- package/dist/services/lifecycle-invocations.js +214 -24
- package/dist/services/managed-daemon-binding.js +52 -1
- package/dist/services/memory-compose-handler.js +2 -22
- package/dist/services/memory-finish-integration.js +58 -17
- package/dist/services/memory-fix-finish-integration.js +129 -0
- package/dist/services/memory-fix-git-dispatch.js +139 -0
- package/dist/services/memory-fix-intake-custody.js +11 -0
- package/dist/services/memory-fix-intake-settlement.js +127 -0
- package/dist/services/memory-fix-publication.js +196 -0
- package/dist/services/memory-fix-repair-admission.js +116 -0
- package/dist/services/memory-fix-request.js +141 -0
- package/dist/services/memory-fix-run-bundle.js +83 -0
- package/dist/services/memory-fix-scope.js +78 -0
- package/dist/services/memory-fix-sources.js +85 -0
- package/dist/services/memory-fix-stage-entry.js +24 -0
- package/dist/services/memory-fix-stage-handlers.js +282 -0
- package/dist/services/memory-fix-stage-results.js +106 -0
- package/dist/services/memory-fix-workspace.js +127 -0
- package/dist/services/memory-flow-user-inputs.js +88 -0
- package/dist/services/memory-init-contexts.js +55 -5
- package/dist/services/memory-init-controller-start.js +20 -4
- package/dist/services/memory-layer.js +7 -3
- package/dist/services/memory-native-review-copy.js +27 -3
- package/dist/services/memory-repair-document-delta.js +1 -0
- package/dist/services/project-flow-source.js +195 -0
- package/dist/services/project-git-integration.js +92 -0
- package/dist/services/repair-intents.js +2 -4
- package/dist/services/retained-native-hook.js +245 -0
- package/dist/services/review-fix-handoff.js +82 -0
- package/dist/services/review-fix-intake-custody.js +17 -0
- package/dist/services/review-fix-stage-entry.js +43 -0
- package/dist/services/review-fix-stage-handlers.js +176 -0
- package/dist/services/review-fix-stage-results.js +86 -0
- package/dist/services/run-control-worker.js +42 -1
- package/dist/services/run-control.js +40 -5
- package/dist/services/run-controller-adapter.js +37 -3
- package/dist/services/run-controller-process.js +12 -4
- package/dist/services/run-controller-recovery.js +46 -6
- package/dist/services/run-controller-state.js +3 -2
- package/dist/services/run-controller.js +209 -43
- package/dist/services/run-recovery.js +31 -2
- package/dist/services/run-timeline.js +59 -0
- package/dist/services/runs.js +18 -31
- package/dist/services/sessions.js +2 -1
- package/dist/services/stage-handlers.js +55 -3
- package/dist/services/stage-lifecycle.js +4 -3
- package/dist/services/stage-pause.js +26 -9
- package/dist/services/stage-report-renderer.js +2 -6
- package/dist/services/technical-notes.js +31 -0
- package/dist/services/verification-matrix.js +1 -1
- package/dist/services/version-status.js +1 -1
- package/dist/services/vnext-code-review.js +74 -5
- package/dist/services/vnext-code.js +9 -32
- package/dist/services/vnext-fanout.js +53 -8
- package/dist/services/vnext-merge.js +10 -5
- package/dist/services/vnext-plan-review.js +1 -1
- package/dist/services/vnext-plan.js +1 -1
- package/dist/services/vnext-protocolize.js +1 -1
- package/dist/services/vnext-specify.js +10 -5
- package/dist/services/work-registry.js +252 -66
- package/dist/services/worktrees.js +7 -4
- package/dist/storage/database.js +2 -1
- package/dist/verification-components.json +82 -0
- package/package.json +4 -3
- package/tools/verification-jobs.mjs +342 -0
package/dist/cli/memory-init.js
CHANGED
|
@@ -13,7 +13,8 @@ import { PreparedMemoryInitLintCapability } from "../services/memory-init-lint-c
|
|
|
13
13
|
import { PreparedMemoryInitWorktrunkCapability } from "../services/memory-init-worktrunk-capability.js";
|
|
14
14
|
import { produceMemoryInitNativeCapacity } from "../services/memory-init-native-capacity.js";
|
|
15
15
|
import { openMemoryInitStores, assertMemoryInitStorePrerequisites } from "../services/memory-init-stores.js";
|
|
16
|
-
import { prepareMemoryInitControllerStart, prepareMemoryUpgradeControllerStart } from "../services/memory-init-controller-start.js";
|
|
16
|
+
import { prepareMemoryInitControllerStart, prepareMemoryUpgradeControllerStart, prepareInteractiveControllerStart, prepareDeliveryControllerStart } from "../services/memory-init-controller-start.js";
|
|
17
|
+
import { isDeliveryFlow } from "../domain/delivery-flows.js";
|
|
17
18
|
import { runControllerStatus } from "../services/run-controller.js";
|
|
18
19
|
import { requireRun } from "../services/run-controller-state.js";
|
|
19
20
|
import { requireProjectByRoot } from "../services/projects.js";
|
|
@@ -28,8 +29,8 @@ import { onboardExecutor } from "../services/executor-onboarding.js";
|
|
|
28
29
|
import { readOperatorProfiles, readOperatorProfileInput } from "../services/operator-profiles.js";
|
|
29
30
|
import { resolveDdFlowHome } from "../storage/paths.js";
|
|
30
31
|
import { askExecutorChoice } from "./executor-onboarding.js";
|
|
31
|
-
import {
|
|
32
|
-
import { prepareDiagnosticControllerStart } from "../services/memory-init-controller-start.js";
|
|
32
|
+
import { isSourceSnapshotFlow } from "../domain/source-snapshot-flows.js";
|
|
33
|
+
import { prepareDiagnosticControllerStart, prepareMemoryFixControllerStart } from "../services/memory-init-controller-start.js";
|
|
33
34
|
/** Backpressure bounds the observing client's output; closing it never controls the RUN. */
|
|
34
35
|
export async function writeMemoryInitObservation(stdout, text) {
|
|
35
36
|
const disconnected = () => Boolean(stdout.destroyed);
|
|
@@ -186,7 +187,7 @@ export async function launchAndObserveMemoryFlow(context, invocation, started, f
|
|
|
186
187
|
await writeMemoryInitObservation(io.stdout, `${JSON.stringify(writeResponseFile(response, output), null, output.json || output.progressJsonl ? undefined : 2)}\n`);
|
|
187
188
|
return 0;
|
|
188
189
|
}
|
|
189
|
-
const launch =
|
|
190
|
+
const launch = isDeliveryFlow(flowId) ? prepareDeliveryControllerStart(context, invocation.scope, flowId) : flowId === "interactive" ? prepareInteractiveControllerStart(context, invocation.scope) : flowId === "mb-fix" ? prepareMemoryFixControllerStart(context, invocation.scope) : isSourceSnapshotFlow(flowId) ? prepareDiagnosticControllerStart(context, invocation.scope, flowId)
|
|
190
191
|
: (flowId === "mb-init" ? prepareMemoryInitControllerStart : prepareMemoryUpgradeControllerStart)(context, invocation.scope);
|
|
191
192
|
// Use the existing RUN-bound router: a global CLI must not launch its own
|
|
192
193
|
// controller code in place of the independently frozen RUN executable.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { AppError, errorRecord } from "../shared/errors.js";
|
|
2
2
|
import { parseCommandArgs } from "../services/lifecycle-command.js";
|
|
3
3
|
import { channel } from "node:diagnostics_channel";
|
|
4
|
-
import { nativeHookNonParticipation } from "./native-hook-preparation.js";
|
|
4
|
+
import { nativeHookAssignedSettlement, nativeHookNonParticipation } from "./native-hook-preparation.js";
|
|
5
5
|
/** These ingress commands consume a prepared store; they never prepare it. */
|
|
6
6
|
export function isNativeHookIngress(args) {
|
|
7
7
|
return args[2] === "handle" && ((args[1] === "event" && ["agy", "grok", "droid", "opencode", "zcode"].includes(args[0] ?? ""))
|
|
@@ -31,6 +31,10 @@ export async function dispatchNativeHook(args, stdin, env) {
|
|
|
31
31
|
phase("ack");
|
|
32
32
|
return unrelated;
|
|
33
33
|
}
|
|
34
|
+
if (nativeHookAssignedSettlement(args, stdin, env)) {
|
|
35
|
+
phase("ack");
|
|
36
|
+
return { ok: true, observed: false, reason: "cli_invocation_owns_admission" };
|
|
37
|
+
}
|
|
34
38
|
const [hooks, { createContext }, { resolveDdFlowHome }] = await Promise.all([
|
|
35
39
|
import("../services/hooks.js"), import("../runtime/context.js"), import("../storage/paths.js")
|
|
36
40
|
]);
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import { parseJsonObject } from "../shared/json.js";
|
|
3
|
-
import { continuationCommand, parseLifecycleCommand } from "../services/lifecycle-command.js";
|
|
3
|
+
import { commandOption, continuationCommand, parseLifecycleCommand } from "../services/lifecycle-command.js";
|
|
4
4
|
const object = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
5
5
|
const text = (value) => typeof value === "string" && value.length > 0 ? value : undefined;
|
|
6
6
|
/** Only a validated, ordinary before-tool command can skip the stateful handler.
|
|
7
7
|
* In particular after-tool, Stop, malformed and ambiguous events remain owned
|
|
8
8
|
* by their existing handler; this gate does not invent an admission policy. */
|
|
9
|
-
|
|
9
|
+
function beforeCommand(args, stdin) {
|
|
10
10
|
const payload = parseJsonObject(stdin || "{}", "native hook stdin");
|
|
11
11
|
let command;
|
|
12
12
|
if (args[0] === "zcode" && args[1] === "event") {
|
|
@@ -47,9 +47,36 @@ export function nativeHookNonParticipation(args, stdin) {
|
|
|
47
47
|
const input = object(payload.input);
|
|
48
48
|
command = text(input.command) ?? text(input.cmd) ?? text(input.CommandLine);
|
|
49
49
|
}
|
|
50
|
-
|
|
50
|
+
return command ? { command, reason: args[0] === "zcode" && args[1] === "event" ? "acp_evidence_only" : "event_not_participating" } : null;
|
|
51
|
+
}
|
|
52
|
+
export function nativeHookNonParticipation(args, stdin) {
|
|
53
|
+
const before = beforeCommand(args, stdin);
|
|
54
|
+
if (!before)
|
|
51
55
|
return null;
|
|
56
|
+
const { command, reason } = before;
|
|
52
57
|
const parsed = parseLifecycleCommand(command);
|
|
53
58
|
return parsed.participation === "none" && !continuationCommand(command)
|
|
54
|
-
? { ok: true, observed: false, reason
|
|
59
|
+
? { ok: true, observed: false, reason } : null;
|
|
60
|
+
}
|
|
61
|
+
/** A supplied ID is not a grant. The executing CLI must prove its retained
|
|
62
|
+
* assignment; the synchronous native hook has no second admission role. */
|
|
63
|
+
export function assignedLifecycleHookCommand(command, env) {
|
|
64
|
+
if (!env.DD_FLOW_DAEMON_ID)
|
|
65
|
+
return false;
|
|
66
|
+
const parsed = parseLifecycleCommand(command);
|
|
67
|
+
return parsed.kind === "standalone" && Boolean(commandOption(parsed.invocation, "invocation-id"))
|
|
68
|
+
&& ["stage_start", "stage_finish", "stage_pause", "stage_resume", "work_finish", "work_fail"].includes(parsed.invocation.operation);
|
|
69
|
+
}
|
|
70
|
+
/** The native daemon has already retained this exact delivery; the CLI will
|
|
71
|
+
* verify and materialize it before admitting the issued Work invocation. */
|
|
72
|
+
export function retainedWorkStartHookCommand(command, binding) {
|
|
73
|
+
const retained = object(binding), parsed = parseLifecycleCommand(command);
|
|
74
|
+
return parsed.kind === "standalone" && parsed.invocation.operation === "work_start"
|
|
75
|
+
&& Boolean(commandOption(parsed.invocation, "invocation-id"))
|
|
76
|
+
&& retained.schema_id === "dd-flow/hook-request@1" && retained.source_harness === "codex-desktop"
|
|
77
|
+
&& retained.native_command === command && typeof retained.request_id === "string" && retained.request_id.length > 0;
|
|
78
|
+
}
|
|
79
|
+
export function nativeHookAssignedSettlement(args, stdin, env) {
|
|
80
|
+
const before = beforeCommand(args, stdin);
|
|
81
|
+
return Boolean(before && assignedLifecycleHookCommand(before.command, env));
|
|
55
82
|
}
|
package/dist/cli/run-cli.js
CHANGED
|
@@ -3,13 +3,14 @@ import { prepareResponseDestination, writeResponseFile } from "./response-file.j
|
|
|
3
3
|
import { preparePromptDelivery, publishPromptDelivery } from "../services/prompt-delivery.js";
|
|
4
4
|
import { requiredOption, optionalOption, optionalNumber, optionalPositiveNumber } from "./argument-values.js";
|
|
5
5
|
import { resolveCommandPaths, resolveCommandProjectRoot } from "../services/command-context.js";
|
|
6
|
-
import { assertAuxiliaryCommandScope, cliManagedInvocationScope, manualRecoveryInvocationScope, assertManualRecoveryInvocationTarget } from "../services/lifecycle-invocations.js";
|
|
6
|
+
import { assertAuxiliaryCommandScope, cliManagedInvocationScope, manualRecoveryInvocationScope, assertManualRecoveryInvocationTarget, currentAssignedLifecycle } from "../services/lifecycle-invocations.js";
|
|
7
7
|
import path from "node:path";
|
|
8
8
|
import { randomUUID } from "node:crypto";
|
|
9
9
|
import { quote } from "shell-quote";
|
|
10
10
|
import { observeLifecycleCommand, observedLifecycleNativeEvent } from "../services/lifecycle-invocations.js";
|
|
11
11
|
import { verifyCodexHookDelivery } from "../services/codex-hook-delivery.js";
|
|
12
12
|
import { assertLifecycleInvocationCurrent, awaitLifecycleInvocation, bindLifecyclePublishedPacket, expandLifecycleInvocationArgs, issueLifecycleInvocation, prepareLifecycleIssuance, lifecycleInvocationScope, observedLifecycleDiagnostic, observedLifecycleInvocation, resolveObservedLifecycleArgs, retainObservedLifecycleSemantics, settleLifecycleInvocation, settleLifecyclePreparationRejection, settleLifecycleRejection, validateLifecyclePathAliases } from "../services/lifecycle-invocations.js";
|
|
13
|
+
import { readAcceptedAssignedWork } from "../services/assigned-lifecycle.js";
|
|
13
14
|
import { createContext, createRouterContext } from "../runtime/context.js";
|
|
14
15
|
import { dispatchNativeHook, isNativeHookIngress } from "./native-hook-ingress.js";
|
|
15
16
|
import { isRuntimeMaintenance, runtimeMaintenanceDiagnostics, withMaintenanceDiagnosticScope } from "./runtime-maintenance-diagnostics.js";
|
|
@@ -66,9 +67,43 @@ import { applyVnextMerge, getVnextMergeRequest, isVnextMergeRun, prepareVnextMer
|
|
|
66
67
|
import { sdlcStageHandlers } from "../services/stage-handlers.js";
|
|
67
68
|
import { startMemoryStage, finishMemoryStage, startMemoryUpgradeStage, finishMemoryUpgradeStage } from "../services/memory-stage-dispatch.js";
|
|
68
69
|
import { startDiagnosticStage, finishDiagnosticStage } from "../services/diagnostic-stage-handlers.js";
|
|
70
|
+
import { startDistillStage, finishDistillStage } from "../services/distill-stage-handlers.js";
|
|
71
|
+
import { startMemoryFixStage } from "../services/memory-fix-stage-entry.js";
|
|
72
|
+
import { finishMemoryFixStage } from "../services/memory-fix-stage-handlers.js";
|
|
73
|
+
import { startReviewFixStage } from "../services/review-fix-stage-entry.js";
|
|
74
|
+
import { finishReviewFixStage } from "../services/review-fix-stage-handlers.js";
|
|
75
|
+
import { startInteractiveStage } from "../services/interactive-stage-entry.js";
|
|
76
|
+
import { isDeliveryFlow } from "../domain/delivery-flows.js";
|
|
77
|
+
import { startDeliveryStage, readDeliveryStageScope, assertDeliveryCommandOwner } from "../services/delivery-stage-entry.js";
|
|
78
|
+
import { finishDeliveryStage } from "../services/delivery-stage-handlers.js";
|
|
79
|
+
import { prepareDeliveryChecks } from "../services/delivery-checks.js";
|
|
80
|
+
import { executeDeliveryOperation } from "../services/delivery-operation.js";
|
|
81
|
+
import { observeDeliveryResult } from "../services/delivery-result.js";
|
|
82
|
+
import { prepareDeliveryProjectBinding } from "../services/delivery-policy.js";
|
|
83
|
+
import { deliveryApprovalScope } from "../services/delivery-approval.js";
|
|
84
|
+
import { issueDeliveryStageCommands } from "../services/delivery-stage-commands.js";
|
|
85
|
+
import { readDescriptorStageInput } from "../services/descriptor-stage-coordinator.js";
|
|
86
|
+
import { readAcceptedStageData } from "../services/stage-report-renderer.js";
|
|
87
|
+
import { finishInteractiveStage, registerInteractiveReviewCorrection, registerInteractiveCorrectionReview } from "../services/interactive-stage-handlers.js";
|
|
88
|
+
import { observeInteractiveOriginalGitInputs } from "../services/interactive-finish-integration.js";
|
|
89
|
+
import { readInteractiveUserInputs } from "../services/interactive-user-inputs.js";
|
|
90
|
+
import { deliverInteractiveUserInput } from "../services/interactive-input-delivery.js";
|
|
91
|
+
import { PreparedInteractiveMutationScope } from "../services/interactive-mutation-scope.js";
|
|
92
|
+
import { PreparedInteractiveChecks } from "../services/interactive-checks.js";
|
|
93
|
+
import { registerInteractiveStageGraph } from "../services/interactive-work-registration.js";
|
|
94
|
+
import { readInteractiveWorkGit } from "../services/interactive-work-start.js";
|
|
95
|
+
import { integrateInteractiveFinish } from "../services/interactive-git-dispatch.js";
|
|
96
|
+
import { readMemoryFixSourceIntake } from "../services/memory-fix-intake-custody.js";
|
|
97
|
+
import { readMemoryFixUserInputs } from "../services/diagnostic-repair-intake.js";
|
|
98
|
+
import { prepareMemoryFixScopeEvidence } from "../services/memory-fix-scope.js";
|
|
99
|
+
import { prepareMemoryFixPublication } from "../services/memory-fix-publication.js";
|
|
100
|
+
import { integrateMemoryFixFinish } from "../services/memory-fix-git-dispatch.js";
|
|
69
101
|
import { isDiagnosticFlow } from "../domain/diagnostic-flows.js";
|
|
70
102
|
import { bindStageCoordinatorWork } from "../services/work-registry.js";
|
|
71
103
|
import { registerMemoryCompositionFromStage, publishMemoryUpgradeFromStage } from "../services/memory-compose-handler.js";
|
|
104
|
+
import { publishDistillFromStage } from "../services/distill-promotion.js";
|
|
105
|
+
import { readDistillUserInputs } from "../services/distill-user-inputs.js";
|
|
106
|
+
import { hybridDigest } from "../services/hybrid-contracts.js";
|
|
72
107
|
import { runMemoryVerificationChecks } from "../services/memory-verify-handler.js";
|
|
73
108
|
import { registerMemoryReviewFromStage, collectMemoryInitialReviewFromStage } from "../services/memory-review-handler.js";
|
|
74
109
|
import { PreparedRetainedMemoryReviewAuthority } from "../services/memory-retained-review-authority.js";
|
|
@@ -77,7 +112,7 @@ import { registerMemoryCorrectionsFromStage, registerMemorySecondCorrectionsFrom
|
|
|
77
112
|
import { integrateMemoryFinishFromStage, registerMemoryFinishEvidenceFromStage } from "../services/memory-finish-handler.js";
|
|
78
113
|
import { registerMemoryRepairBaselineFromStage, registerMemorySecondRepairBaselineFromStage, reserveMemoryRepairWriterCopyFromStage, reserveMemorySecondRepairCopyFromStage, materializeMemoryRepairWriterCopyFromStage, materializeMemorySecondRepairCopyFromStage, prepareMemoryRepairDispatchFromStage, prepareMemorySecondRepairDispatchFromStage, registerMemoryRepairCurrentViewFromStage, registerMemorySecondRepairCurrentViewFromStage, registerMemoryRepairPublicationSourceFromStage, reserveMemoryRepairPublicationAgainstSourceFromStage, reserveMemorySecondRepairPublicationFromStage, applyMemoryRepairPublicationFromStage, applyMemorySecondRepairPublicationFromStage, finishMemoryRepairPublicationFromStage, finishMemorySecondRepairPublicationFromStage } from "../services/memory-review-handler.js";
|
|
79
114
|
import { mergeServerStatus, serveMergeRequests, stopMergeServer } from "../services/merge-server.js";
|
|
80
|
-
import { getVnextFanoutStatus,
|
|
115
|
+
import { getVnextFanoutStatus, registeredStageFanoutDescriptor, observeVnextNativeChildren, prepareNativeObservations, reconcileVnextFanout } from "../services/vnext-fanout.js";
|
|
81
116
|
import { pauseStageForUser, resumeStageAfterUser, prepareStagePause, prepareStageResume, stagePauseCommand } from "../services/stage-pause.js";
|
|
82
117
|
import { runtimeCommand } from "../services/runtime-command.js";
|
|
83
118
|
import { managedLifecycleCommand } from "../services/lifecycle-invocations.js";
|
|
@@ -132,6 +167,10 @@ async function runCliRequest(args, io, env) {
|
|
|
132
167
|
let output;
|
|
133
168
|
try {
|
|
134
169
|
output = parseOutputOptions(args);
|
|
170
|
+
// Expand before routing/context selection, after stripping transport flags.
|
|
171
|
+
// The alias keeps the existing RUN's engine and prepared-store rules.
|
|
172
|
+
if (output.args[0] === "finish")
|
|
173
|
+
output.args = ["interactive", "finish", ...output.args.slice(1)];
|
|
135
174
|
}
|
|
136
175
|
catch (error) {
|
|
137
176
|
const rejection = isAppError(error) ? error : new AppError("usage", error instanceof Error ? error.message : String(error), 2);
|
|
@@ -349,6 +388,7 @@ async function runCliRequest(args, io, env) {
|
|
|
349
388
|
// after admission; retained outcomes must not need a fresh hook receipt.
|
|
350
389
|
if (invocationId) {
|
|
351
390
|
const command = quote(["dd-flow", ...invocationArgs]);
|
|
391
|
+
let nextNativeObservation = 0;
|
|
352
392
|
const admission = await awaitLifecycleInvocation(dispatchContext, { id: invocationId, command,
|
|
353
393
|
validateArgs: () => {
|
|
354
394
|
try {
|
|
@@ -362,7 +402,14 @@ async function runCliRequest(args, io, env) {
|
|
|
362
402
|
}
|
|
363
403
|
},
|
|
364
404
|
prepare: async () => { preparedInput = await prepareCliInput(invocationArgs, dispatchContext, io, scopeProjectRoot, output.responseFile, preparedRoute, commandProgress(io, output)); },
|
|
365
|
-
assertCurrent: scope => assertLifecycleInvocationCurrent(dispatchContext, scope, command), progress: commandProgress(io, output)
|
|
405
|
+
assertCurrent: scope => assertLifecycleInvocationCurrent(dispatchContext, scope, command), progress: commandProgress(io, output),
|
|
406
|
+
...((env.DD_FLOW_RUNTIME_OWNER || env.DD_FLOW_CODEX_STATE_DIR || env.DD_AGY_STATE_DIR || env.DD_GROK_STATE_DIR || env.DD_ZCODE_STATE_DIR) ? { reconcileNativeObservation: async (scope, onProgress) => {
|
|
407
|
+
if (Date.now() < nextNativeObservation)
|
|
408
|
+
return;
|
|
409
|
+
nextNativeObservation = Date.now() + 250;
|
|
410
|
+
const { reconcileRetainedNativeHook } = await import("../services/retained-native-hook.js");
|
|
411
|
+
await reconcileRetainedNativeHook(dispatchContext, { scope, invocationId, onProgress });
|
|
412
|
+
} } : {}) });
|
|
366
413
|
if (admission.replay) {
|
|
367
414
|
retainedOutcome = admission.outcome;
|
|
368
415
|
settleHook = undefined;
|
|
@@ -372,8 +419,10 @@ async function runCliRequest(args, io, env) {
|
|
|
372
419
|
invocationSettlement = { context: dispatchContext, id: invocationId };
|
|
373
420
|
if (observedInvocation)
|
|
374
421
|
retainObservedLifecycleSemantics(dispatchContext, invocationId, invocationArgs);
|
|
375
|
-
|
|
376
|
-
|
|
422
|
+
if (admission.kind === "native_hook") {
|
|
423
|
+
dispatchArgs = [...invocationArgs, "--hook-event-id", admission.eventKey];
|
|
424
|
+
preparedInput?.route?.parsed.options.set("hook-event-id", [admission.eventKey]);
|
|
425
|
+
}
|
|
377
426
|
dispatchContext.env.DD_FLOW_INVOCATION_SCOPE = JSON.stringify(lifecycleInvocationScope(dispatchContext, invocationId));
|
|
378
427
|
dispatchContext.env.DD_FLOW_CURRENT_INVOCATION = invocationId;
|
|
379
428
|
}
|
|
@@ -498,6 +547,23 @@ async function runCliRequest(args, io, env) {
|
|
|
498
547
|
io.stderr.write(`Invocation settlement persistence failed: ${String(persistenceError)}\n`);
|
|
499
548
|
}
|
|
500
549
|
}
|
|
550
|
+
if (invocationSettlement && error.details.work_result_accepted === true) {
|
|
551
|
+
const accepted = readAcceptedAssignedWork(invocationSettlement.context, invocationSettlement.id);
|
|
552
|
+
if (accepted) {
|
|
553
|
+
// The Work/WorkSession commit is authoritative. Report its retained
|
|
554
|
+
// answer even if a derivative publication failed after that commit.
|
|
555
|
+
const payload = addWarnings(accepted, [{ code: "work_post_commit_pending", message: "Work result accepted; derivative publication requires reconciliation" }]);
|
|
556
|
+
try {
|
|
557
|
+
writeResponseFile(payload, output);
|
|
558
|
+
}
|
|
559
|
+
catch { /* Accepted SQL reply remains available on stdout/replay. */ }
|
|
560
|
+
if (output.json)
|
|
561
|
+
writeJson(io.stdout, payload);
|
|
562
|
+
else
|
|
563
|
+
io.stdout.write(renderHumanResult(output.args, payload));
|
|
564
|
+
return completedCommandExitCode(payload);
|
|
565
|
+
}
|
|
566
|
+
}
|
|
501
567
|
if (settleHook) {
|
|
502
568
|
try {
|
|
503
569
|
settleHook({ error: isAppError(error) ? error : { code: "unexpected", message: String(error), details: {} } });
|
|
@@ -560,6 +626,9 @@ function databaseModeForCommand(args, classification) {
|
|
|
560
626
|
if (isRuntimeMaintenance(args))
|
|
561
627
|
return "read_existing";
|
|
562
628
|
const [family, command] = args;
|
|
629
|
+
// Bound interactive operations never initialize or migrate a RUN store.
|
|
630
|
+
if (family === "interactive" && classification.mode !== "read_only_diagnostics")
|
|
631
|
+
return "prepared_existing";
|
|
563
632
|
if (family === "migration" && command === "readiness")
|
|
564
633
|
return "prepared_existing";
|
|
565
634
|
// Managed attempts are issued only from a prepared store. Opening that
|
|
@@ -872,6 +941,57 @@ async function prepareCliInput(...args) {
|
|
|
872
941
|
async function prepareCliInputValue(args, context, io, scopeProjectRoot, responseFile = null, route = prepareCommandRoute(args), progress) {
|
|
873
942
|
const { family, command, parsed } = route;
|
|
874
943
|
const prepared = { route };
|
|
944
|
+
if (family === "delivery" && ["checks", "execute"].includes(command ?? "")) {
|
|
945
|
+
const file = requiredOption(parsed, "result-file"), text = prepareTextFile(file, "Delivery input", 1024 * 1024);
|
|
946
|
+
const value = prepareJsonText(text.text, { file, label: "Delivery input" }).value;
|
|
947
|
+
const keys = command === "checks" ? "path,sha256,subject_ref,version" : "basis,expires_at,reason,scope_sha256,user_inputs_sha256";
|
|
948
|
+
if (!value || typeof value !== "object" || Array.isArray(value) || Object.keys(value).sort().join() !== keys)
|
|
949
|
+
throw new AppError("usage", "Delivery input must match the selected command's exact JSON contract", 2, { phase: "prepare", effect: "no_effect" });
|
|
950
|
+
if (command === "checks")
|
|
951
|
+
prepared.deliveryArtifact = value;
|
|
952
|
+
else
|
|
953
|
+
prepared.deliveryApproval = value;
|
|
954
|
+
}
|
|
955
|
+
if (family === "interactive" && command === "integrate" && hasOption(parsed, "result-file")) {
|
|
956
|
+
const file = requiredOption(parsed, "result-file"), input = prepareTextFile(file, "Interactive Git agreement", 1024 * 1024);
|
|
957
|
+
const value = prepareJsonText(input.text, { file, label: "Interactive Git agreement" }).value;
|
|
958
|
+
if (!value || typeof value !== "object" || Array.isArray(value) || Object.keys(value).sort().join() !== "basis,include_existing_paths,reason")
|
|
959
|
+
throw new AppError("usage", "Interactive Git agreement requires basis, include_existing_paths and reason", 2, { phase: "prepare", effect: "no_effect" });
|
|
960
|
+
prepared.interactiveGitAgreement = value;
|
|
961
|
+
}
|
|
962
|
+
if (family === "interactive" && command === "checks") {
|
|
963
|
+
const file = requiredOption(parsed, "result-file"), input = prepareTextFile(file, "Interactive check selection", 1024 * 1024);
|
|
964
|
+
const value = prepareJsonText(input.text, { file, label: "Interactive check selection" }).value;
|
|
965
|
+
if (!value || typeof value !== "object" || Array.isArray(value)
|
|
966
|
+
|| !["additionalChecks", "additionalChecks,noChecksReason"].includes(Object.keys(value).sort().join()))
|
|
967
|
+
throw new AppError("usage", "Interactive checks require additionalChecks and optional noChecksReason", 2, { phase: "prepare", effect: "no_effect" });
|
|
968
|
+
prepared.interactiveChecksProposal = value;
|
|
969
|
+
}
|
|
970
|
+
if (family === "interactive" && command === "scope") {
|
|
971
|
+
const file = requiredOption(parsed, "result-file"), input = prepareTextFile(file, "Interactive mutation scope", 1024 * 1024);
|
|
972
|
+
const value = prepareJsonText(input.text, { file, label: "Interactive mutation scope" }).value;
|
|
973
|
+
if (!value || typeof value !== "object" || Array.isArray(value)
|
|
974
|
+
|| Object.keys(value).sort().join() !== "basis,expectedInputsSha256,paths,reason,requestId")
|
|
975
|
+
throw new AppError("usage", "Interactive scope requires requestId, paths, basis, reason and expectedInputsSha256", 2, { phase: "prepare", effect: "no_effect" });
|
|
976
|
+
const basis = recordObject(recordObject(value).basis);
|
|
977
|
+
if (!basis || Object.keys(basis).sort().join() !== "event_id,role,sha256"
|
|
978
|
+
|| !["request", "turn", "answer", "finish"].includes(String(basis.role))
|
|
979
|
+
|| typeof basis.event_id !== "number" || !Number.isSafeInteger(basis.event_id) || basis.event_id < 0
|
|
980
|
+
|| typeof basis.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(basis.sha256))
|
|
981
|
+
throw new AppError("usage", "Interactive scope basis requires role request|turn|answer|finish, a nonnegative integer event_id and a SHA-256", 2, {
|
|
982
|
+
reason: "invalid_scope_basis_shape", phase: "prepare", effect: "no_effect", recoverable: true,
|
|
983
|
+
retry_command: runtimeCommand(context, ["interactive", "scope", "--project-root", requiredOption(parsed, "project-root"),
|
|
984
|
+
"--run", requiredOption(parsed, "run"), "--result-file", file, "--json", "--progress-jsonl"]),
|
|
985
|
+
retry_instruction: "Correct only the rejected basis shape. For the original request use role=request, event_id=0 and initial_request.sha256 from interactive inputs. For a later user message copy its exact role, integer event_id and sha256 from messages; a question is not user approval. No scope was retained by this call. Reuse this exact retry_command; valid-shaped but unowned evidence or conflicting accepted scope identities remain refusals."
|
|
986
|
+
});
|
|
987
|
+
prepared.interactiveScopeProposal = value;
|
|
988
|
+
}
|
|
989
|
+
if (family === "interactive" && (command === "turn" || command === "finish")) {
|
|
990
|
+
const input = prepareTextFile(requiredOption(parsed, "intake-file"), "Interactive user input", 1024 * 1024);
|
|
991
|
+
prepared.interactiveInputBytes = Buffer.from(input.text);
|
|
992
|
+
if (!prepared.interactiveInputBytes.length || !/^[a-f0-9]{64}$/.test(requiredOption(parsed, "expected-inputs-sha256")))
|
|
993
|
+
throw new AppError("usage", "Interactive delivery requires nonempty UTF-8 input and its current input digest", 2, { phase: "prepare", effect: "no_effect" });
|
|
994
|
+
}
|
|
875
995
|
if (optionalOption(parsed, "reason-file")) {
|
|
876
996
|
const value = prepareJsonFile(requiredOption(parsed, "reason-file"), "Check recovery evidence").value;
|
|
877
997
|
if (!value || typeof value.reason !== "string" || !value.reason.trim() || Object.keys(value).some(key => key !== "reason"))
|
|
@@ -1232,7 +1352,7 @@ async function prepareCliInputValue(args, context, io, scopeProjectRoot, respons
|
|
|
1232
1352
|
const bundle = readFlowRunExecutionBundle(context, { projectRoot: requiredOption(parsed, "project-root"), runId: requiredPosition(parsed, 0, "run-id") });
|
|
1233
1353
|
if (bundle)
|
|
1234
1354
|
prepared.stageBindingBundle = { stage, bundle, ...(contextSha256 ? { contextSha256 } : {}) };
|
|
1235
|
-
if (bundle && (["mb-init", "mb-upgrade"].includes(bundle.descriptor.descriptor.id) || isDiagnosticFlow(bundle.descriptor.descriptor.id))) {
|
|
1355
|
+
if (bundle && (["interactive", "mb-init", "mb-upgrade", "mb-distill", "mb-fix", "review-fix"].includes(bundle.descriptor.descriptor.id) || isDiagnosticFlow(bundle.descriptor.descriptor.id) || isDeliveryFlow(bundle.descriptor.descriptor.id))) {
|
|
1236
1356
|
bundle.descriptor.stage(stage);
|
|
1237
1357
|
if (hasOption(parsed, "dir"))
|
|
1238
1358
|
throw new AppError("usage", "Memory stage layout belongs to its frozen descriptor", 2);
|
|
@@ -1240,7 +1360,7 @@ async function prepareCliInputValue(args, context, io, scopeProjectRoot, respons
|
|
|
1240
1360
|
if (loaded)
|
|
1241
1361
|
prepared.stageStart = { externalContext: loaded };
|
|
1242
1362
|
prepared.memoryStage = { operation: "start", bytes: loaded ? Buffer.from(loaded.bytes) : Buffer.alloc(0),
|
|
1243
|
-
flowId: isDiagnosticFlow(bundle.descriptor.descriptor.id) ? bundle.descriptor.descriptor.id : bundle.descriptor.descriptor.id === "mb-upgrade" ? "mb-upgrade" : "mb-init" };
|
|
1363
|
+
flowId: isDeliveryFlow(bundle.descriptor.descriptor.id) ? bundle.descriptor.descriptor.id : bundle.descriptor.descriptor.id === "interactive" ? "interactive" : bundle.descriptor.descriptor.id === "review-fix" ? "review-fix" : bundle.descriptor.descriptor.id === "mb-fix" ? "mb-fix" : bundle.descriptor.descriptor.id === "mb-distill" ? "mb-distill" : isDiagnosticFlow(bundle.descriptor.descriptor.id) ? bundle.descriptor.descriptor.id : bundle.descriptor.descriptor.id === "mb-upgrade" ? "mb-upgrade" : "mb-init" };
|
|
1244
1364
|
return prepared;
|
|
1245
1365
|
}
|
|
1246
1366
|
}
|
|
@@ -1345,7 +1465,8 @@ async function prepareCliInputValue(args, context, io, scopeProjectRoot, respons
|
|
|
1345
1465
|
prepared.observations = prepareNativeObservations(prepareJsonFile(requiredOption(parsed, "observations-file"), "native observations").value);
|
|
1346
1466
|
}
|
|
1347
1467
|
if (family === "memory" && (["compose", "corrections"].includes(command ?? "") && parsed.positional[0] === "register"
|
|
1348
|
-
|| command === "repair" && parsed.positional[0] === "publication-reserve"
|
|
1468
|
+
|| command === "repair" && parsed.positional[0] === "publication-reserve"
|
|
1469
|
+
|| command === "distill" && parsed.positional[0] === "publish")) {
|
|
1349
1470
|
try {
|
|
1350
1471
|
const bytes = prepareFileBytes(requiredOption(parsed, "result-file"), `Memory ${command} result`, 1024 * 1024).bytes;
|
|
1351
1472
|
if (!bytes.length || bytes.length > 1024 * 1024)
|
|
@@ -1359,6 +1480,12 @@ async function prepareCliInputValue(args, context, io, scopeProjectRoot, respons
|
|
|
1359
1480
|
throw error;
|
|
1360
1481
|
}
|
|
1361
1482
|
}
|
|
1483
|
+
if (family === "memory" && command === "fix" && ["scope", "publish", "integrate"].includes(parsed.positional[0] ?? "") && hasOption(parsed, "result-file")) {
|
|
1484
|
+
const file = requiredOption(parsed, "result-file"), input = prepareTextFile(file, "Memory repair proposal", 1024 * 1024);
|
|
1485
|
+
prepared.memoryFixProposal = prepareJsonText(input.text, { file, label: "Memory repair proposal" }).value;
|
|
1486
|
+
if (!prepared.memoryFixProposal || typeof prepared.memoryFixProposal !== "object" || Array.isArray(prepared.memoryFixProposal))
|
|
1487
|
+
throw new AppError("usage", "Memory repair proposal must be a JSON object", 2, { phase: "prepare", effect: "no_effect" });
|
|
1488
|
+
}
|
|
1362
1489
|
if (family !== "stage" || command !== "finish")
|
|
1363
1490
|
return prepared;
|
|
1364
1491
|
const projectRoot = requiredOption(parsed, "project-root");
|
|
@@ -1375,9 +1502,9 @@ async function prepareCliInputValue(args, context, io, scopeProjectRoot, respons
|
|
|
1375
1502
|
const resultFile = optionalOption(parsed, "result-file") ?? semanticFile;
|
|
1376
1503
|
const runtime = run(projectRoot, runId);
|
|
1377
1504
|
const retainedFlowId = JSON.parse(runtime.indexJson).execution_bundle?.flow_id;
|
|
1378
|
-
if (["mb-init", "mb-upgrade"].includes(retainedFlowId) || isDiagnosticFlow(retainedFlowId)) {
|
|
1505
|
+
if (["interactive", "mb-init", "mb-upgrade", "mb-distill", "mb-fix", "review-fix"].includes(retainedFlowId) || isDiagnosticFlow(retainedFlowId) || isDeliveryFlow(retainedFlowId)) {
|
|
1379
1506
|
const bundle = readFlowRunExecutionBundle(context, { projectRoot, runId });
|
|
1380
|
-
if (!bundle || !["mb-init", "mb-upgrade"].includes(bundle.descriptor.descriptor.id) && !isDiagnosticFlow(bundle.descriptor.descriptor.id))
|
|
1507
|
+
if (!bundle || !["interactive", "mb-init", "mb-upgrade", "mb-distill", "mb-fix", "review-fix"].includes(bundle.descriptor.descriptor.id) && !isDiagnosticFlow(bundle.descriptor.descriptor.id) && !isDeliveryFlow(bundle.descriptor.descriptor.id))
|
|
1381
1508
|
throw new AppError("cli_input_unprepared", "Registered RUN bundle is unavailable", 1);
|
|
1382
1509
|
bundle.descriptor.stage(stage);
|
|
1383
1510
|
if (["dir", "outcome", "decision-file", "verification-file", "retry-check", "reason", "reason-file", "request", "work"].some(option => hasOption(parsed, option)))
|
|
@@ -1387,7 +1514,7 @@ async function prepareCliInputValue(args, context, io, scopeProjectRoot, respons
|
|
|
1387
1514
|
const bytes = resultStdin ? Buffer.from(await readStdin(io.stdin, 1024 * 1024)) : prepareFileBytes(resultFile, "Memory stage result", 1024 * 1024).bytes;
|
|
1388
1515
|
if (!bytes.length || bytes.length > 1024 * 1024)
|
|
1389
1516
|
throw new AppError("usage", "Memory stage result exceeds its byte bound", 2);
|
|
1390
|
-
prepared.memoryStage = { operation: "finish", bytes, flowId: isDiagnosticFlow(bundle.descriptor.descriptor.id) ? bundle.descriptor.descriptor.id : bundle.descriptor.descriptor.id === "mb-upgrade" ? "mb-upgrade" : "mb-init" };
|
|
1517
|
+
prepared.memoryStage = { operation: "finish", bytes, flowId: isDeliveryFlow(bundle.descriptor.descriptor.id) ? bundle.descriptor.descriptor.id : bundle.descriptor.descriptor.id === "interactive" ? "interactive" : bundle.descriptor.descriptor.id === "review-fix" ? "review-fix" : bundle.descriptor.descriptor.id === "mb-fix" ? "mb-fix" : bundle.descriptor.descriptor.id === "mb-distill" ? "mb-distill" : isDiagnosticFlow(bundle.descriptor.descriptor.id) ? bundle.descriptor.descriptor.id : bundle.descriptor.descriptor.id === "mb-upgrade" ? "mb-upgrade" : "mb-init" };
|
|
1391
1518
|
return prepared;
|
|
1392
1519
|
}
|
|
1393
1520
|
const terminalReplay = (name) => {
|
|
@@ -1776,12 +1903,12 @@ async function dispatch(args, context, io, scopeProjectRoot = null, classificati
|
|
|
1776
1903
|
const externalContext = prepared.stageStart?.externalContext;
|
|
1777
1904
|
if (prepared.memoryStage?.operation === "start") {
|
|
1778
1905
|
const runId = requiredPosition(parsed, 0, "run-id");
|
|
1779
|
-
const event = hookEventId ?? findRecentMatchingHookEvent(context, {
|
|
1906
|
+
const event = hookEventId ?? (currentAssignedLifecycle(context) ? undefined : findRecentMatchingHookEvent(context, {
|
|
1780
1907
|
projectId: requireProjectByRoot(context, resolveProjectRoot(projectRoot)).id,
|
|
1781
1908
|
matchKey: entityReferenceVariants(runId).map(reference => stageStartMatchKey(reference, stage, projectRoot, contextSha256)),
|
|
1782
1909
|
errorCode: "trusted_session_binding_required", operation: "Memory stage start"
|
|
1783
|
-
}).eventKey;
|
|
1784
|
-
const work = (isDiagnosticFlow(prepared.memoryStage.flowId) ? startDiagnosticStage : prepared.memoryStage.flowId === "mb-upgrade" ? startMemoryUpgradeStage : startMemoryStage)(context, { projectRoot, runId, stage, bytes: prepared.memoryStage.bytes });
|
|
1910
|
+
}).eventKey);
|
|
1911
|
+
const work = (isDeliveryFlow(prepared.memoryStage.flowId) ? startDeliveryStage : prepared.memoryStage.flowId === "interactive" ? startInteractiveStage : prepared.memoryStage.flowId === "review-fix" ? startReviewFixStage : prepared.memoryStage.flowId === "mb-fix" ? startMemoryFixStage : prepared.memoryStage.flowId === "mb-distill" ? startDistillStage : isDiagnosticFlow(prepared.memoryStage.flowId) ? startDiagnosticStage : prepared.memoryStage.flowId === "mb-upgrade" ? startMemoryUpgradeStage : startMemoryStage)(context, { projectRoot, runId, stage, bytes: prepared.memoryStage.bytes });
|
|
1785
1912
|
try {
|
|
1786
1913
|
const binding = bindStageCoordinatorWork(context, { workId: work.work_id, hookEventId: event, stage,
|
|
1787
1914
|
promptPath: work.prompt_path, resultPath: work.result_path, ...(contextSha256 ? { contextSha256 } : {}) });
|
|
@@ -1791,9 +1918,12 @@ async function dispatch(args, context, io, scopeProjectRoot = null, classificati
|
|
|
1791
1918
|
const finish = managedLifecycleCommand(context, runtimeCommand(context, ["stage", "finish", runId,
|
|
1792
1919
|
"--stage", stage, "--project-root", projectRoot, "--result-file", work.result_path, "--json"]));
|
|
1793
1920
|
const pause = stagePauseCommand(context, { projectRoot, runId, stage, workId: work.work_id });
|
|
1794
|
-
|
|
1921
|
+
// These assignments belong to this native coordinator delivery, not to
|
|
1922
|
+
// the immutable semantic packet restored by auxiliary owners.
|
|
1923
|
+
const deliveryInstructions = isDeliveryFlow(prepared.memoryStage.flowId) ? issueDeliveryStageCommands(context, { flowId: prepared.memoryStage.flowId, projectRoot, runId, stage, stageRoot: path.dirname(work.result_path) }).instructions : "";
|
|
1924
|
+
const orchestration = registeredStageFanoutDescriptor(context, { projectRoot, runId, stage });
|
|
1795
1925
|
const delivery = { ...work, binding, ...(orchestration ? { orchestration } : {}), next: { finish_command: finish, pause_command: pause },
|
|
1796
|
-
worker_prompt_markdown: `${work.worker_prompt_markdown}\n## Current lifecycle commands\n\nWrite the semantic result to the assigned result path, then execute exactly:\n${finish}\n\nFor a required user choice, write the question file named by this command, then execute exactly:\n${pause}\n` };
|
|
1926
|
+
worker_prompt_markdown: `${work.worker_prompt_markdown}${deliveryInstructions}\n## Current lifecycle commands\n\nWrite the semantic result to the assigned result path, then execute exactly:\n${finish}\n\nFor a required user choice, write the question file named by this command, then execute exactly:\n${pause}\n` };
|
|
1797
1927
|
bindLifecyclePublishedPacket(context, delivery.worker_prompt_markdown);
|
|
1798
1928
|
return controlLifecycleReply(context, { projectRoot, runId }, delivery);
|
|
1799
1929
|
}
|
|
@@ -1803,6 +1933,8 @@ async function dispatch(args, context, io, scopeProjectRoot = null, classificati
|
|
|
1803
1933
|
}
|
|
1804
1934
|
}
|
|
1805
1935
|
const claimVnextStageStart = (runId) => {
|
|
1936
|
+
if (currentAssignedLifecycle(context)?.operation === "stage_start")
|
|
1937
|
+
return undefined;
|
|
1806
1938
|
registerProject(context, { root: projectRoot });
|
|
1807
1939
|
return findRecentMatchingHookEvent(context, {
|
|
1808
1940
|
projectId: requireProjectByRoot(context, resolveProjectRoot(projectRoot)).id,
|
|
@@ -1900,12 +2032,12 @@ async function dispatch(args, context, io, scopeProjectRoot = null, classificati
|
|
|
1900
2032
|
// Descriptor settlement validates exact coordinator custody and claims
|
|
1901
2033
|
// the fresh hook atomically with result acceptance. Do not consume it
|
|
1902
2034
|
// through the SDLC lifecycle owner before that settlement.
|
|
1903
|
-
return controlledReply((isDiagnosticFlow(prepared.memoryStage.flowId) ? finishDiagnosticStage : prepared.memoryStage.flowId === "mb-upgrade" ? finishMemoryUpgradeStage : finishMemoryStage)(context, { projectRoot, runId, stage, bytes: prepared.memoryStage.bytes,
|
|
1904
|
-
hookEventId: hookEventId ?? findRecentMatchingHookEvent(context, {
|
|
2035
|
+
return controlledReply((isDeliveryFlow(prepared.memoryStage.flowId) ? finishDeliveryStage : prepared.memoryStage.flowId === "interactive" ? finishInteractiveStage : prepared.memoryStage.flowId === "review-fix" ? finishReviewFixStage : prepared.memoryStage.flowId === "mb-fix" ? finishMemoryFixStage : prepared.memoryStage.flowId === "mb-distill" ? finishDistillStage : isDiagnosticFlow(prepared.memoryStage.flowId) ? finishDiagnosticStage : prepared.memoryStage.flowId === "mb-upgrade" ? finishMemoryUpgradeStage : finishMemoryStage)(context, { projectRoot, runId, stage, bytes: prepared.memoryStage.bytes,
|
|
2036
|
+
hookEventId: hookEventId ?? (currentAssignedLifecycle(context) ? "" : findRecentMatchingHookEvent(context, {
|
|
1905
2037
|
projectId: requireProjectByRoot(context, resolveProjectRoot(projectRoot)).id,
|
|
1906
2038
|
matchKey: entityReferenceVariants(runId).map(reference => stageLifecycleMatchKey("stage_finish", reference, stage, projectRoot)),
|
|
1907
2039
|
errorCode: "trusted_session_binding_required", operation: "Memory stage finish"
|
|
1908
|
-
}).eventKey }));
|
|
2040
|
+
}).eventKey) }));
|
|
1909
2041
|
}
|
|
1910
2042
|
const protectedLifecycle = (stage === "specify" && isVnextSpecifyRun(context, { projectRoot, runId }))
|
|
1911
2043
|
|| (stage === "protocolize" && isVnextProtocolizeRun(context, { projectRoot, runId }))
|
|
@@ -2112,6 +2244,102 @@ async function dispatch(args, context, io, scopeProjectRoot = null, classificati
|
|
|
2112
2244
|
if (family === "schema") {
|
|
2113
2245
|
return prepared.schemaValidation;
|
|
2114
2246
|
}
|
|
2247
|
+
if (family === "delivery") {
|
|
2248
|
+
const projectRoot = requiredOption(parsed, "project-root"), project = requireProjectByRoot(context, resolveProjectRoot(projectRoot));
|
|
2249
|
+
const runId = resolveRun(context, project.id, requiredPosition(parsed, 0, "run-id")).id, stage = requiredOption(parsed, "stage");
|
|
2250
|
+
const input = { projectRoot, runId, stage, command: quote(["dd-flow", ...args]) };
|
|
2251
|
+
const selected = command === "inputs" ? readDeliveryStageScope(context, input) : assertDeliveryCommandOwner(context, input);
|
|
2252
|
+
if (command === "checks") {
|
|
2253
|
+
if (!prepared.deliveryArtifact)
|
|
2254
|
+
throw new AppError("cli_input_unprepared", "Delivery artifact was not prepared", 1);
|
|
2255
|
+
const checks = prepareDeliveryChecks(context, { ...input, artifact: prepared.deliveryArtifact });
|
|
2256
|
+
await checks.run();
|
|
2257
|
+
return { ok: true, verification: checks.evidence().receipt };
|
|
2258
|
+
}
|
|
2259
|
+
if (command === "execute") {
|
|
2260
|
+
if (!prepared.deliveryApproval)
|
|
2261
|
+
throw new AppError("cli_input_unprepared", "Delivery approval was not prepared", 1);
|
|
2262
|
+
return executeDeliveryOperation(context, { ...input, approval: prepared.deliveryApproval });
|
|
2263
|
+
}
|
|
2264
|
+
const packet = readDescriptorStageInput(context, selected.scope, selected.bundle);
|
|
2265
|
+
const previous = packet.input.predecessor ? readAcceptedStageData(context, { ...selected.scope, stage: packet.input.predecessor.stage }) : null;
|
|
2266
|
+
const details = previous ? JSON.parse(previous.bytes.toString("utf8")).details : null;
|
|
2267
|
+
const operation = details?.decision && details?.artifact ? deliveryApprovalScope(selected.scope, selected.bundle, { operationId: details.decision.operation_id, binding: details.decision.binding,
|
|
2268
|
+
artifact: { subject_ref: details.artifact.subject_ref, version: details.artifact.version, sha256: details.artifact.sha256 } }) : null;
|
|
2269
|
+
if (command === "inputs")
|
|
2270
|
+
return { flow_id: selected.flowId, run_id: runId, stage, user_inputs: selected.users,
|
|
2271
|
+
user_inputs_sha256: selected.userInputsSha256, operation_scope: operation, scope_sha256: operation ? hybridDigest(operation) : null };
|
|
2272
|
+
if (command === "reconcile") {
|
|
2273
|
+
if (!details?.decision)
|
|
2274
|
+
throw new AppError("delivery_stage_invalid", "Original delivery decision is required", 2, { effect: "no_effect" });
|
|
2275
|
+
const policy = prepareDeliveryProjectBinding(selected.bundle.execution.snapshot().scope.workspace, details.decision.policy, details.decision.binding.selector);
|
|
2276
|
+
if (hybridDigest(policy.binding) !== hybridDigest(details.decision.binding))
|
|
2277
|
+
throw new AppError("delivery_stage_invalid", "Original delivery policy changed", 2, { effect: "no_effect" });
|
|
2278
|
+
return observeDeliveryResult(context, { ...selected.scope, binding: policy.binding,
|
|
2279
|
+
assertCurrent() { assertDeliveryCommandOwner(context, input); policy.assertCurrent(); } });
|
|
2280
|
+
}
|
|
2281
|
+
throw new AppError("usage", "Unknown delivery command", 2);
|
|
2282
|
+
}
|
|
2283
|
+
if (family === "interactive") {
|
|
2284
|
+
const projectRoot = requiredOption(parsed, "project-root"), project = requireProjectByRoot(context, resolveProjectRoot(projectRoot));
|
|
2285
|
+
const runId = resolveRun(context, project.id, requiredOption(parsed, "run")).id;
|
|
2286
|
+
if (command === "integrate")
|
|
2287
|
+
return integrateInteractiveFinish(context, { projectRoot, runId,
|
|
2288
|
+
...(prepared.interactiveGitAgreement ? { agreement: prepared.interactiveGitAgreement } : {}) });
|
|
2289
|
+
if (command === "correction")
|
|
2290
|
+
return registerInteractiveReviewCorrection(context, { projectRoot, runId, reviewWorkId: requiredOption(parsed, "work") });
|
|
2291
|
+
if (command === "re-review")
|
|
2292
|
+
return registerInteractiveCorrectionReview(context, { projectRoot, runId, correctionWorkId: requiredOption(parsed, "work") });
|
|
2293
|
+
if (command === "checks") {
|
|
2294
|
+
if (!prepared.interactiveChecksProposal)
|
|
2295
|
+
throw new AppError("cli_input_unprepared", "Interactive check selection was not prepared", 1);
|
|
2296
|
+
let checks;
|
|
2297
|
+
try {
|
|
2298
|
+
checks = PreparedInteractiveChecks.prepare(context, { projectRoot, runId,
|
|
2299
|
+
stage: requiredOption(parsed, "stage"), ...prepared.interactiveChecksProposal });
|
|
2300
|
+
}
|
|
2301
|
+
catch (error) {
|
|
2302
|
+
if (isAppError(error) && error.code === "interactive_checks_invalid"
|
|
2303
|
+
&& error.details.reason === "invalid_check_selection" && error.details.effect === "no_effect") {
|
|
2304
|
+
Object.assign(error.details, { phase: "prepare", recoverable: true,
|
|
2305
|
+
retry_command: runtimeCommand(context, ["interactive", "checks", "--project-root", projectRoot, "--run", runId,
|
|
2306
|
+
"--stage", requiredOption(parsed, "stage"), "--result-file", requiredOption(parsed, "result-file"), "--json", "--progress-jsonl"]),
|
|
2307
|
+
retry_instruction: "Correct only the rejected check selection JSON: additionalChecks contains unique id,command,purpose entries; IDs match ^CHK-[A-Za-z0-9-]{1,64}$ and must not collide with policy checks. No plan or check execution was retained by this call. Keep existing obligations and use this exact retry_command; this does not authorize replay of executed checks or bypass other refusals." });
|
|
2308
|
+
}
|
|
2309
|
+
throw error;
|
|
2310
|
+
}
|
|
2311
|
+
return checks.execute(context).then(receipts => ({ plan_sha256: checks.sha256, plan: checks.value(), receipts }));
|
|
2312
|
+
}
|
|
2313
|
+
if (command === "register") {
|
|
2314
|
+
const bundle = readFlowRunExecutionBundle(context, { projectRoot, runId });
|
|
2315
|
+
if (!bundle || bundle.manifest.flow_id !== "interactive")
|
|
2316
|
+
throw new AppError("interactive_stage_invalid", "Bound interactive RUN required", 2, { effect: "no_effect" });
|
|
2317
|
+
return registerInteractiveStageGraph(context, { projectRoot, runId, stage: requiredOption(parsed, "stage"),
|
|
2318
|
+
gitExecutable: readInteractiveWorkGit(bundle).git_executable });
|
|
2319
|
+
}
|
|
2320
|
+
if (command === "git-inputs")
|
|
2321
|
+
return observeInteractiveOriginalGitInputs(context, { projectRoot, runId, stage: requiredOption(parsed, "stage") });
|
|
2322
|
+
if (command === "inputs" || command === "turn" || command === "finish" || command === "scope") {
|
|
2323
|
+
const bundle = readFlowRunExecutionBundle(context, { projectRoot, runId });
|
|
2324
|
+
if (!bundle || bundle.manifest.flow_id !== "interactive")
|
|
2325
|
+
throw new AppError("interactive_stage_invalid", "Bound interactive RUN required", 2, { effect: "no_effect" });
|
|
2326
|
+
const scope = { projectId: project.id, runId };
|
|
2327
|
+
if (command === "inputs")
|
|
2328
|
+
return readInteractiveUserInputs(context, scope, bundle);
|
|
2329
|
+
if (command === "scope") {
|
|
2330
|
+
if (!prepared.interactiveScopeProposal)
|
|
2331
|
+
throw new AppError("cli_input_unprepared", "Interactive scope proposal was not prepared", 1);
|
|
2332
|
+
const result = PreparedInteractiveMutationScope.prepare(context, scope, bundle, prepared.interactiveScopeProposal).retain(context);
|
|
2333
|
+
return { changed: result.changed, scope_revision: result.scope.revision, user_inputs_sha256: result.scope.inputs.sha256,
|
|
2334
|
+
baseline_sha256: result.scope.baseline.sha256, paths: result.scope.active_paths, needs_scope_refresh: result.scope.needs_scope_refresh };
|
|
2335
|
+
}
|
|
2336
|
+
if (!prepared.interactiveInputBytes)
|
|
2337
|
+
throw new AppError("cli_input_unprepared", "Interactive user bytes were not prepared", 1);
|
|
2338
|
+
return deliverInteractiveUserInput(context, scope, bundle, { projectRoot, intakeFile: requiredOption(parsed, "intake-file"),
|
|
2339
|
+
requestId: requiredOption(parsed, "request-id"), kind: command, bytes: prepared.interactiveInputBytes,
|
|
2340
|
+
expectedInputsSha256: requiredOption(parsed, "expected-inputs-sha256") });
|
|
2341
|
+
}
|
|
2342
|
+
}
|
|
2115
2343
|
if (family === "memory") {
|
|
2116
2344
|
return dispatchMemory(context, command, parsed, prepared);
|
|
2117
2345
|
}
|
|
@@ -2502,6 +2730,32 @@ function dispatchMemory(context, command, parsed, prepared) {
|
|
|
2502
2730
|
}
|
|
2503
2731
|
if (command === "upgrade" && subcommand === "publish")
|
|
2504
2732
|
return publishMemoryUpgradeFromStage(context, scope());
|
|
2733
|
+
if (command === "distill" && subcommand === "inputs") {
|
|
2734
|
+
const inputs = readDistillUserInputs(context, scope());
|
|
2735
|
+
return { ...inputs, user_inputs_sha256: hybridDigest(inputs) };
|
|
2736
|
+
}
|
|
2737
|
+
if (command === "fix" && subcommand === "context") {
|
|
2738
|
+
const intake = readMemoryFixSourceIntake(context, scope()), users = readMemoryFixUserInputs(context, scope());
|
|
2739
|
+
return { ...intake, user_inputs: users, user_inputs_sha256: hybridDigest(users) };
|
|
2740
|
+
}
|
|
2741
|
+
if (command === "fix" && subcommand === "scope") {
|
|
2742
|
+
const proposal = prepared.memoryFixProposal;
|
|
2743
|
+
if (!proposal || Object.keys(proposal).sort().join() !== "routing,write_scope")
|
|
2744
|
+
throw new AppError("usage", "Repair scope proposal requires routing and write_scope", 2, { effect: "no_effect" });
|
|
2745
|
+
return prepareMemoryFixScopeEvidence(context, { ...scope(), routing: proposal.routing, writeScope: proposal.write_scope }).snapshot();
|
|
2746
|
+
}
|
|
2747
|
+
if (command === "fix" && subcommand === "publish") {
|
|
2748
|
+
if (!prepared.memoryFixProposal)
|
|
2749
|
+
throw new AppError("cli_input_unprepared", "Repair proposal was not prepared", 1);
|
|
2750
|
+
return prepareMemoryFixPublication(context, { ...scope(), proposal: prepared.memoryFixProposal }).apply();
|
|
2751
|
+
}
|
|
2752
|
+
if (command === "fix" && subcommand === "integrate")
|
|
2753
|
+
return integrateMemoryFixFinish(context, { ...scope(), ...(prepared.memoryFixProposal ? { agreement: prepared.memoryFixProposal } : {}) });
|
|
2754
|
+
if (command === "distill" && subcommand === "publish") {
|
|
2755
|
+
if (!prepared.memoryOperationBytes)
|
|
2756
|
+
throw new AppError("cli_input_unprepared", "Distillation proposal bytes were not prepared", 1);
|
|
2757
|
+
return publishDistillFromStage(context, { ...scope(), bytes: prepared.memoryOperationBytes });
|
|
2758
|
+
}
|
|
2505
2759
|
if (command === "verify" && subcommand === "checks")
|
|
2506
2760
|
return runMemoryVerificationChecks(context, scope());
|
|
2507
2761
|
if (command === "review" && subcommand === "register")
|
package/dist/cli.js
CHANGED
|
@@ -53,12 +53,26 @@ if (args[0] === "upgrade" || args[0] === "flow" && args[1] === "mb-upgrade") {
|
|
|
53
53
|
const { runMemoryUpgradeCli } = await import("./cli/memory-upgrade.js");
|
|
54
54
|
process.exit(await runMemoryUpgradeCli(args, process.env));
|
|
55
55
|
}
|
|
56
|
-
if (args[0] === "review" || args[0] === "flow" && ["mb-audit", "project-review"].includes(args[1] ?? "")) {
|
|
56
|
+
if (args[0] === "review" || args[0] === "flow" && ["mb-audit", "project-review", "mb-distill", "review-fix"].includes(args[1] ?? "")) {
|
|
57
57
|
publishSetup('ingress_entered');
|
|
58
58
|
const { runDiagnosticCli } = await import("./cli/diagnostic.js");
|
|
59
59
|
publishSetup('imports_ready');
|
|
60
60
|
process.exit(await runDiagnosticCli(args, process.env));
|
|
61
61
|
}
|
|
62
|
+
if (args[0] === "flow" && args[1] === "mb-fix") {
|
|
63
|
+
publishSetup('ingress_entered');
|
|
64
|
+
const { runMemoryFixCli } = await import("./cli/memory-fix.js");
|
|
65
|
+
publishSetup('imports_ready');
|
|
66
|
+
process.exit(await runMemoryFixCli(args, process.env));
|
|
67
|
+
}
|
|
68
|
+
if (args[0] === "flow" && args[1] === "interactive") {
|
|
69
|
+
const { runInteractiveCli } = await import("./cli/interactive.js");
|
|
70
|
+
process.exit(await runInteractiveCli(args, process.env));
|
|
71
|
+
}
|
|
72
|
+
if (args[0] === "flow" && ["release", "deploy", "publish"].includes(args[1] ?? "")) {
|
|
73
|
+
const { runDeliveryCli } = await import("./cli/delivery.js");
|
|
74
|
+
process.exit(await runDeliveryCli(args, process.env));
|
|
75
|
+
}
|
|
62
76
|
if (args.slice(0, 3).join(" ") === "runtime storage admit") {
|
|
63
77
|
const { runMemoryStorageAdmissionCli } = await import("./cli/memory-storage-admission.js");
|
|
64
78
|
process.exit(runMemoryStorageAdmissionCli(args));
|
|
@@ -75,10 +89,10 @@ if (args.slice(0, 3).join(" ") === "runtime flow admit") {
|
|
|
75
89
|
const { runMemoryFlowAdmissionCli } = await import("./cli/memory-flow-admission.js");
|
|
76
90
|
process.exit(await runMemoryFlowAdmissionCli(args));
|
|
77
91
|
}
|
|
78
|
-
const
|
|
92
|
+
const codexHook = args.slice(0, 3).join(" ") === "codex hook handle";
|
|
79
93
|
const exitCode = isRuntimeMaintenanceIngress(args, process.env)
|
|
80
94
|
? await runRuntimeMaintenanceIngress(args)
|
|
81
|
-
:
|
|
95
|
+
: codexHook
|
|
82
96
|
? await (await import("./cli/hook-ingress.js")).runHookIngress(args)
|
|
83
97
|
: isNativeHookIngress(args)
|
|
84
98
|
? await (await import("./cli/native-hook-ingress.js")).runNativeHookIngress(args)
|