#!/usr/bin/env node
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.createProgram = createProgram;
exports.run = run;
const node_fs_1 = __importDefault(require("node:fs"));
const node_path_1 = __importDefault(require("node:path"));
const node_module_1 = require("node:module");
const runtime_contract_1 = require("../lib/runtime/runtime-contract");
const runtime_contract_2 = require("../lib/runtime/runtime-contract");
const errors_1 = require("../lib/errors");
const output_1 = require("../lib/output");
const paths_1 = require("../lib/paths");
const lifecycle_run_context_1 = require("../lib/lifecycle-run-context");
const pagination_1 = require("../lib/output/pagination");
const budget_1 = require("../lib/output/budget");
const workspace_compatibility_1 = require("../lib/workspace-compatibility");
const runtime_state_1 = require("../lib/version-manager/runtime-state");
const commands_1 = require("./commands");
const output_lifecycle_1 = require("./commands/release/output-lifecycle");
const node_child_process_1 = require("node:child_process");
const automation_protocol_1 = require("../lib/automation-protocol");
const cli_constants_1 = require("../lib/config/cli-constants");
const task_lifecycle_timestamps_1 = require("../lib/planning/task-lifecycle-timestamps");
function getCommandTreeChildren(command) {
    const children = command.commands;
    if (!Array.isArray(children)) {
        return [];
    }
    return children.filter((entry) => typeof entry === 'object' && entry !== null);
}
async function createProgram() {
    const { Command } = await import('commander');
    const program = new Command();
    const runtimeProgram = program;
    const capturedOutput = {
        stdout: '',
        stderr: '',
    };
    const explicitRoot = process.env.DAY_SHIFT_REPOSITORY_ROOT;
    const repositoryDetection = (0, runtime_contract_2.detectRepositoryRoot)({
        explicitRoot: explicitRoot && explicitRoot.trim().length > 0 ? explicitRoot : undefined,
    });
    const repositoryContext = (0, runtime_contract_2.createRepositoryContext)(repositoryDetection, false);
    program
        .name(runtime_contract_1.CLI_NAME)
        .description(runtime_contract_1.CLI_DESCRIPTION)
        .version(runtime_contract_1.CLI_VERSION)
        .option('--format <format>', `Set output format for supported command output: ${output_1.OUTPUT_FORMATS.join(' or ')}.`, output_1.DEFAULT_OUTPUT_FORMAT)
        .option('--protocol-version <version>', 'Select automation protocol version 1 or 2.')
        .option('--detail <detail>', 'Set JSON detail: compact, summary, or full.')
        .option('--finding-code <code>', 'Retain a stable non-blocking finding code. Repeat to include more codes.')
        .option('--severity <severity>', 'Retain a non-blocking finding severity. Repeat to include more severities.')
        .option('--fields <fields>', 'Select comma-separated top-level JSON data fields.')
        .option('--limit <lane=count>', 'Limit a top-level JSON array lane. Repeat for independent lanes.')
        .option('--page-lane <lane>', 'Page one top-level JSON array lane.')
        .option('--page-size <count>', 'Set the positive number of entries in a JSON page.')
        .option('--page-cursor <cursor>', 'Resume a JSON page from an opaque continuation cursor.')
        .option('--output-budget <bytes>', 'Bound approved read-only JSON output to a safe byte count.')
        .option('--json-spacing <spacing>', 'Set JSON serialization spacing: compact or pretty.')
        .option('--output-file <path>', 'Atomically persist the emitted JSON envelope to a new repository-local file.')
        .option('--run-gate <identity>', 'Lifecycle gate identity for manifest-owned capture; requires --run-directory.')
        .option('--run-artifact <path>', 'Optional repository-relative artifact attributed to the captured lifecycle result.')
        .configureOutput({
        writeOut: (text) => {
            capturedOutput.stdout += text;
        },
        writeErr: (text) => {
            capturedOutput.stderr += text;
        },
    })
        .showHelpAfterError()
        .showSuggestionAfterError()
        .exitOverride();
    program.addHelpText('after', cli_constants_1.CLI_ROOT_HELP_INIT_WORKSPACE_LOCATION);
    program.addHelpText('after', [
        '',
        'Global lifecycle capture:',
        '  --run-directory <path>  Bind one JSON command result to an existing fresh lifecycle run manifest when paired with --run-gate.',
        '  Successful capture exposes data.lifecycleRunCapture.evidencePath as the exact indexed caller-consumable envelope.',
        '  For phase update, milestone update, and task scope-recover, provide their existing --run-directory option after the command; the same value supplies the global binding.',
        '  Use task scope-recover for an exact posture-authorized additive contract-impact delta in the same fresh full-cycle-strict run.',
        '  Use resume run revise-contract only for an explicitly authorized, current-reviewed bounded phase or active planning contract revision.',
    ].join('\n'));
    runtimeProgram.capturedOutput = capturedOutput;
    runtimeProgram.configRepositoryContext = repositoryContext;
    await (0, commands_1.registerCommands)(program);
    return program;
}
async function run(argv = process.argv) {
    (0, output_1.selectOutputFileTarget)(null);
    (0, output_1.selectLifecycleRunOutputCapture)(null);
    try {
        return await runWithSelectedOutput(argv);
    }
    finally {
        (0, output_1.selectOutputFileTarget)(null);
        (0, output_1.selectLifecycleRunOutputCapture)(null);
    }
}
async function runWithSelectedOutput(argv) {
    const protocolInput = normalizeProtocolVersionInput(argv);
    const normalizedArgv = normalizeVersionOptionAliases(protocolInput.argv);
    const format = (0, output_1.detectRequestedOutputFormat)(normalizedArgv);
    const invalidGlobalFormat = (0, output_1.detectInvalidGlobalOutputFormat)(normalizedArgv);
    const program = await createProgram();
    const commandIdentity = resolveRegisteredCommandIdentity(program, normalizedArgv);
    if (protocolInput.requested !== undefined && protocolInput.version === null) {
        (0, automation_protocol_1.selectAutomationProtocolVersion)(automation_protocol_1.AUTOMATION_PROTOCOL_VERSION);
        const lifecycleRunError = invalidGlobalFormat === null ? configureLifecycleRunCapture(normalizedArgv, format, commandIdentity) : null;
        if (lifecycleRunError !== null) {
            (0, output_1.emitError)({
                command: commandIdentity,
                format,
                code: lifecycleRunError.code,
                message: lifecycleRunError.message,
                ...(0, errors_1.getRuntimeErrorEnvelopeFields)(lifecycleRunError),
                details: lifecycleRunError.details,
                findings: lifecycleRunError.findings,
            });
            return lifecycleRunError.exitCode;
        }
        const outputFileError = invalidGlobalFormat === null ? configureOutputFilePersistence(normalizedArgv, format) : null;
        if (outputFileError !== null) {
            (0, output_1.emitError)({
                command: commandIdentity,
                format,
                code: outputFileError.code,
                message: outputFileError.message,
                ...(0, errors_1.getRuntimeErrorEnvelopeFields)(outputFileError),
                details: outputFileError.details,
                findings: outputFileError.findings,
            });
            return outputFileError.exitCode;
        }
        const runtimeError = (0, errors_1.createUsageError)(`Unsupported automation protocol version '${String(protocolInput.requested)}'.`, [
            'Supported protocol versions: 1, 2',
            'Pin compatibility output with --protocol-version 1.',
            'No command work was performed.',
        ]);
        (0, output_1.emitError)({
            command: commandIdentity,
            format,
            code: runtimeError.code,
            message: runtimeError.message,
            ...(0, errors_1.getRuntimeErrorEnvelopeFields)(runtimeError),
            details: runtimeError.details,
            findings: runtimeError.findings,
        });
        return runtimeError.exitCode;
    }
    (0, automation_protocol_1.selectAutomationProtocolVersion)(protocolInput.version ?? automation_protocol_1.AUTOMATION_PROTOCOL_VERSION);
    if (invalidGlobalFormat !== null) {
        const runtimeError = (0, errors_1.createUnsupportedOutputFormatError)({
            received: invalidGlobalFormat,
            commandBoundary: `${runtime_contract_1.CLI_NAME} global --format option before command execution`,
        });
        (0, output_1.emitError)({
            command: commandIdentity,
            format: output_1.DEFAULT_OUTPUT_FORMAT,
            code: runtimeError.code,
            message: runtimeError.message,
            ...(0, errors_1.getRuntimeErrorEnvelopeFields)(runtimeError),
            details: runtimeError.details,
            findings: runtimeError.findings,
        });
        return runtimeError.exitCode;
    }
    const lifecycleRunError = configureLifecycleRunCapture(normalizedArgv, format, commandIdentity);
    if (lifecycleRunError !== null) {
        (0, output_1.emitError)({
            command: commandIdentity,
            format,
            code: lifecycleRunError.code,
            message: lifecycleRunError.message,
            ...(0, errors_1.getRuntimeErrorEnvelopeFields)(lifecycleRunError),
            details: lifecycleRunError.details,
            findings: lifecycleRunError.findings,
        });
        return lifecycleRunError.exitCode;
    }
    const outputFileError = configureOutputFilePersistence(normalizedArgv, format);
    if (outputFileError !== null) {
        (0, output_1.emitError)({
            command: commandIdentity,
            format,
            code: outputFileError.code,
            message: outputFileError.message,
            ...(0, errors_1.getRuntimeErrorEnvelopeFields)(outputFileError),
            details: outputFileError.details,
            findings: outputFileError.findings,
        });
        return outputFileError.exitCode;
    }
    const shimDispatchExitCode = dispatchManagedCliFromShimIfNeeded(normalizedArgv, format, commandIdentity);
    if (shimDispatchExitCode !== null) {
        return shimDispatchExitCode;
    }
    try {
        const outputOptions = (0, output_1.detectOutputProjectionOptions)(normalizedArgv);
        if (outputOptions.pageLane !== undefined && !isPaginationReadCommand(normalizedArgv)) {
            throw new TypeError('Pagination is supported only on approved read-only discovery, inventory, validation, health, and context commands.');
        }
        if (outputOptions.outputBudget !== undefined &&
            !(0, budget_1.isApprovedBoundedReadCommand)(detectCommandIdentity(normalizedArgv))) {
            throw new TypeError('Output budgets are supported only on approved read-only discovery, inventory, validation, health, and context commands.');
        }
    }
    catch (error) {
        const runtimeError = (0, errors_1.createUsageError)(error instanceof Error ? error.message : 'Invalid output control.', [
            'Supported detail values: compact, summary, full',
            'Supported severities: informational, warning, error',
            'Limits use: --limit <lane>=<non-negative integer>',
            'No command work was performed.',
        ]);
        (0, output_1.emitError)({
            command: commandIdentity,
            format,
            code: runtimeError.code,
            message: runtimeError.message,
            ...(0, errors_1.getRuntimeErrorEnvelopeFields)(runtimeError),
            details: runtimeError.details,
            findings: runtimeError.findings,
        });
        return runtimeError.exitCode;
    }
    const compatibilityError = checkInstalledWorkspaceCompatibility(normalizedArgv);
    if (compatibilityError !== null) {
        (0, output_1.emitError)({
            command: commandIdentity,
            format,
            code: compatibilityError.code,
            message: compatibilityError.message,
            ...(0, errors_1.getRuntimeErrorEnvelopeFields)(compatibilityError),
            details: compatibilityError.details,
            findings: compatibilityError.findings,
        });
        return compatibilityError.exitCode;
    }
    try {
        await program.parseAsync(lifecycleCaptureCommanderArgv(normalizedArgv, commandIdentity));
        const requestedExitCode = program.runtimeExitCode;
        return typeof requestedExitCode === 'number' ? requestedExitCode : errors_1.RuntimeExitCode.SUCCESS;
    }
    catch (error) {
        const capturedOutput = program.capturedOutput ?? { stdout: '', stderr: '' };
        if ((0, errors_1.isCommanderLifecycleSignal)(error)) {
            if (capturedOutput.stdout) {
                (0, output_1.writeCapturedOutputText)(capturedOutput.stdout, process.stdout);
            }
            if (capturedOutput.stderr) {
                (0, output_1.writeCapturedOutputText)(capturedOutput.stderr, process.stderr);
            }
            return errors_1.RuntimeExitCode.SUCCESS;
        }
        if ((0, errors_1.isCommanderUsageError)(error)) {
            const runtimeError = (0, errors_1.createCommanderUsageError)({
                error,
                capturedStderr: capturedOutput.stderr,
            });
            const repairEvidence = (0, errors_1.createUsageCommandRepairEvidence)(normalizedArgv.slice(2), repositoryDetectionRoot());
            if (format === 'json') {
                (0, output_1.emitError)({
                    command: commandIdentity,
                    format,
                    code: runtimeError.code,
                    message: runtimeError.message,
                    ...(0, errors_1.getRuntimeErrorEnvelopeFields)(runtimeError),
                    details: runtimeError.details,
                    findings: runtimeError.findings,
                    data: repairEvidence,
                });
            }
            else {
                if (capturedOutput.stdout) {
                    (0, output_1.writeCapturedOutputText)(capturedOutput.stdout, process.stdout);
                }
                if (capturedOutput.stderr) {
                    (0, output_1.writeCapturedOutputText)(capturedOutput.stderr, process.stderr);
                }
            }
            return runtimeError.exitCode;
        }
        if (error instanceof task_lifecycle_timestamps_1.TaskLifecycleTimestampValidationError &&
            error.code === 'timestamp-in-future') {
            const runtimeError = new errors_1.RuntimeError({
                message: 'A lifecycle event timestamp is later than the command clock.',
                code: task_lifecycle_timestamps_1.TASK_LIFECYCLE_TIMESTAMP_IN_FUTURE,
                exitCode: errors_1.RuntimeExitCode.USAGE,
                writeOutcome: 'no-writes',
                details: [
                    `field: ${error.field}`,
                    `suppliedTimestamp: ${String(error.suppliedTimestamp)}`,
                    `normalizedInstant: ${error.normalizedInstant ?? 'null'}`,
                    `observedAt: ${error.observedAt}`,
                    `differenceMs: ${error.differenceMs ?? 'null'}`,
                    error.message,
                ],
                findings: [{
                        code: task_lifecycle_timestamps_1.TASK_LIFECYCLE_TIMESTAMP_IN_FUTURE,
                        severity: 'error',
                        message: error.message,
                        noWriteBoundary: 'Future lifecycle timestamps are rejected before artifact, transaction, or lifecycle-run writes.',
                    }],
            });
            (0, output_1.emitError)({
                command: commandIdentity,
                format,
                code: runtimeError.code,
                message: runtimeError.message,
                ...(0, errors_1.getRuntimeErrorEnvelopeFields)(runtimeError),
                details: runtimeError.details,
                findings: runtimeError.findings,
            });
            return runtimeError.exitCode;
        }
        if (error instanceof pagination_1.PaginationCursorError) {
            const runtimeError = (0, errors_1.createUsageError)(`${error.code}: ${error.message}`, [
                'Pagination cursor validation failed before output was accepted.',
                'No pagination write was performed; refresh the first page and use its returned next cursor.',
            ]);
            (0, output_1.emitError)({
                command: commandIdentity,
                format,
                code: runtimeError.code,
                message: runtimeError.message,
                ...(0, errors_1.getRuntimeErrorEnvelopeFields)(runtimeError),
                details: runtimeError.details,
                findings: runtimeError.findings,
            });
            return runtimeError.exitCode;
        }
        if (error instanceof budget_1.OutputBudgetError) {
            const runtimeError = (0, errors_1.createUsageError)(`${error.code}: ${error.message}`, [
                `Minimum safe budget: ${error.minimumBytes} bytes`,
                'Use fields, limits, pagination, compact detail, or a larger output budget.',
                'No partial JSON document was emitted.',
            ]);
            (0, output_1.emitError)({
                command: commandIdentity,
                format,
                code: runtimeError.code,
                message: runtimeError.message,
                ...(0, errors_1.getRuntimeErrorEnvelopeFields)(runtimeError),
                details: runtimeError.details,
                findings: runtimeError.findings,
            });
            return runtimeError.exitCode;
        }
        const runtimeError = (0, errors_1.createUnexpectedError)(error);
        const repairEvidence = runtimeError.exitCode === errors_1.RuntimeExitCode.USAGE
            ? (0, errors_1.createUsageCommandRepairEvidence)(normalizedArgv.slice(2), repositoryDetectionRoot())
            : undefined;
        (0, output_1.emitError)({
            command: commandIdentity,
            format,
            code: runtimeError.code,
            message: runtimeError.message,
            ...(0, errors_1.getRuntimeErrorEnvelopeFields)(runtimeError),
            details: runtimeError.details,
            findings: runtimeError.findings,
            data: repairEvidence,
        });
        return runtimeError.exitCode;
    }
}
function repositoryDetectionRoot() {
    try {
        const explicitRoot = process.env.DAY_SHIFT_REPOSITORY_ROOT;
        return (0, runtime_contract_2.detectRepositoryRoot)({
            explicitRoot: explicitRoot && explicitRoot.trim().length > 0 ? explicitRoot : undefined,
        }).root;
    }
    catch {
        return undefined;
    }
}
function normalizeProtocolVersionInput(argv) {
    const normalized = [...argv];
    let requested;
    for (let index = 2; index < normalized.length; index += 1) {
        if (normalized[index] === '--protocol-version')
            requested = normalized[index + 1];
        else if (normalized[index].startsWith('--protocol-version='))
            requested = normalized[index].slice('--protocol-version='.length);
        if (normalized[index] === '--input-json' || normalized[index].startsWith('--input-json=')) {
            const inline = normalized[index].startsWith('--input-json=');
            const jsonIndex = inline ? index : index + 1;
            const json = inline ? normalized[index].slice('--input-json='.length) : normalized[jsonIndex];
            try {
                const parsed = JSON.parse(json);
                if (parsed &&
                    typeof parsed === 'object' &&
                    !Array.isArray(parsed) &&
                    Object.hasOwn(parsed, 'protocolVersion')) {
                    if (requested !== undefined)
                        return { argv: normalized, requested: 'multiple selections', version: null };
                    requested = parsed.protocolVersion;
                    delete parsed.protocolVersion;
                    const replacement = JSON.stringify(parsed);
                    normalized[jsonIndex] = inline ? `--input-json=${replacement}` : replacement;
                }
            }
            catch {
                /* command-specific structured-input handling owns malformed JSON */
            }
        }
    }
    return {
        argv: normalized,
        ...(requested === undefined ? {} : { requested }),
        version: requested === undefined ? automation_protocol_1.AUTOMATION_PROTOCOL_VERSION : (0, automation_protocol_1.resolveAutomationProtocolVersion)(requested),
    };
}
function isPaginationReadCommand(argv) {
    return (0, budget_1.isApprovedBoundedReadCommand)(detectCommandIdentity(argv));
}
function detectCommandIdentity(argv) {
    const valueOptions = new Set([
        '--format',
        '--protocol-version',
        '--detail',
        '--finding-code',
        '--severity',
        '--fields',
        '--limit',
        '--page-lane',
        '--page-size',
        '--page-cursor',
        '--output-budget',
        '--json-spacing',
        '--output-file',
        ...output_1.LIFECYCLE_RUN_CAPTURE_GLOBAL_OPTIONS,
    ]);
    const commandTokens = [];
    for (let index = 2; index < argv.length; index += 1) {
        const token = argv[index];
        const optionName = token.split('=', 1)[0];
        if (valueOptions.has(optionName)) {
            if (!token.includes('=')) {
                index += 1;
            }
            continue;
        }
        if (token.startsWith('-')) {
            continue;
        }
        commandTokens.push(token);
        const nestedRunAnalysisCommand = commandTokens[0] === 'resume' && commandTokens[1] === 'run';
        if (commandTokens.length === 2 && !nestedRunAnalysisCommand) {
            break;
        }
        if (commandTokens.length === 3) {
            break;
        }
    }
    return commandTokens.join(' ');
}
function resolveRegisteredCommandIdentity(program, argv) {
    const valueOptions = new Set([
        '--format',
        '--protocol-version',
        '--detail',
        '--finding-code',
        '--severity',
        '--fields',
        '--limit',
        '--page-lane',
        '--page-size',
        '--page-cursor',
        '--output-budget',
        '--json-spacing',
        '--output-file',
        ...output_1.LIFECYCLE_RUN_CAPTURE_GLOBAL_OPTIONS,
    ]);
    const names = [];
    let current = program;
    for (let index = 2; index < argv.length; index += 1) {
        const token = argv[index];
        if (token === '--')
            break;
        const optionName = token.split('=', 1)[0];
        if (valueOptions.has(optionName)) {
            if (!token.includes('='))
                index += 1;
            continue;
        }
        if (token.startsWith('-'))
            continue;
        const child = getCommandTreeChildren(current).find((candidate) => candidate.name() === token || candidate.aliases().includes(token));
        if (child === undefined)
            break;
        names.push(child.name());
        current = child;
        if (getCommandTreeChildren(current).length === 0)
            break;
    }
    return names.length === 0 ? runtime_contract_1.CLI_NAME : names.join(' ');
}
function configureOutputFilePersistence(argv, format) {
    const requestedPath = (0, output_1.detectRequestedOutputFile)(argv);
    if (requestedPath === null)
        return null;
    if (format !== 'json') {
        return (0, errors_1.createUsageError)('--output-file requires --format json.', [
            'Non-JSON output-file persistence is unsupported.',
            'No output file or command work was created.',
        ]);
    }
    try {
        const explicitRoot = process.env.DAY_SHIFT_REPOSITORY_ROOT;
        const detection = (0, runtime_contract_2.detectRepositoryRoot)({
            explicitRoot: explicitRoot && explicitRoot.trim().length > 0 ? explicitRoot : undefined,
        });
        const target = (0, paths_1.resolveAtomicOutputFileTargetSync)(detection.root, requestedPath);
        (0, output_1.selectOutputFileTarget)(target);
        return null;
    }
    catch (error) {
        return (0, errors_1.createInvalidConfigError)('Output-file persistence request was rejected.', [
            error instanceof Error ? error.message : String(error),
            'The destination was not created, truncated, replaced, or followed through a symlink.',
            'Choose a new repository-relative JSON result path whose parent directory already exists.',
        ]);
    }
}
function configureLifecycleRunCapture(argv, format, commandIdentity) {
    const [runDirectoryName, runGateName, runArtifactName] = output_1.LIFECYCLE_RUN_CAPTURE_GLOBAL_OPTIONS;
    const runDirectory = detectGlobalValueOption(argv, runDirectoryName);
    const runGate = detectGlobalValueOption(argv, runGateName);
    const runArtifact = detectGlobalValueOption(argv, runArtifactName);
    if (!runGate.present && !runArtifact.present)
        return null;
    const invalid = [runDirectory, runGate, runArtifact].find((option) => option.error !== null);
    if (invalid?.error !== null && invalid?.error !== undefined) {
        return (0, errors_1.createUsageError)(invalid.error, ['No lifecycle command work was performed.']);
    }
    if (!runDirectory.present || runDirectory.value === null || !runGate.present || runGate.value === null) {
        return (0, errors_1.createUsageError)('Lifecycle run capture requires both --run-directory and --run-gate.', [
            '--run-artifact is optional and cannot select capture by itself.',
            'No command work was performed.',
        ]);
    }
    if (format !== 'json') {
        return (0, errors_1.createUsageError)('Lifecycle run capture requires --format json.', [
            'Only the final structured success or error envelope can be manifest-owned evidence.',
            'No command work was performed.',
        ]);
    }
    if ((0, output_1.detectRequestedOutputFile)(argv) !== null ||
        argv.some((token) => token === '--output-file' || token.startsWith('--output-file='))) {
        return (0, errors_1.createUsageError)('--output-file cannot be combined with lifecycle run capture.', [
            'The lifecycle evidence directory is owned by run-context.json and must not receive a second loose result copy.',
            'Use --run-directory and --run-gate alone for the selected lifecycle gate.',
        ]);
    }
    try {
        const explicitRoot = process.env.DAY_SHIFT_REPOSITORY_ROOT;
        const detection = (0, runtime_contract_2.detectRepositoryRoot)({
            explicitRoot: explicitRoot && explicitRoot.trim().length > 0 ? explicitRoot : undefined,
        });
        const binding = (0, lifecycle_run_context_1.prepareLifecycleRunCapture)({
            repositoryRoot: detection.root,
            runDirectory: runDirectory.value,
            commandIdentity,
            artifactPath: runArtifact.value,
            gate: runGate.value,
        });
        const pendingEnvelopes = [];
        const evidencePaths = {
            ok: (0, lifecycle_run_context_1.projectLifecycleRunCaptureEvidencePath)(binding, 'ok'),
            error: (0, lifecycle_run_context_1.projectLifecycleRunCaptureEvidencePath)(binding, 'error'),
        };
        (0, output_1.selectLifecycleRunOutputCapture)({
            runDirectory: binding.runDirectory,
            manifestPath: binding.manifestPath,
            gate: binding.gate,
            artifactPath: binding.artifactPath,
            artifactRevision: binding.artifactHash,
            activeArtifactPath: binding.activeArtifactPath,
            activeArtifactRevision: binding.activeArtifactHash,
            evidencePaths,
            queueEnvelope: (envelope) => {
                if (pendingEnvelopes.length >= 64) {
                    throw (0, errors_1.createUsageError)('One command may queue at most 64 lifecycle sub-results.');
                }
                pendingEnvelopes.push({ ...envelope });
                const finalBinding = {
                    ...binding,
                    nextSequence: binding.nextSequence + pendingEnvelopes.length,
                };
                evidencePaths.ok = (0, lifecycle_run_context_1.projectLifecycleRunCaptureEvidencePath)(finalBinding, 'ok');
                evidencePaths.error = (0, lifecycle_run_context_1.projectLifecycleRunCaptureEvidencePath)(finalBinding, 'error');
            },
            capture: (envelopeText) => {
                let currentBinding = binding;
                for (const pending of pendingEnvelopes) {
                    (0, lifecycle_run_context_1.captureLifecycleRunEnvelope)({
                        binding: {
                            ...currentBinding,
                            commandIdentity: pending.commandIdentity,
                            artifactPath: pending.artifactPath,
                            gate: pending.gate,
                        },
                        envelopeText: pending.envelopeText,
                    });
                    currentBinding = (0, lifecycle_run_context_1.prepareLifecycleRunCapture)({
                        repositoryRoot: binding.repositoryRoot,
                        runDirectory: binding.runDirectory,
                        commandIdentity: binding.commandIdentity,
                        artifactPath: binding.artifactPath,
                        gate: binding.gate,
                    });
                }
                (0, lifecycle_run_context_1.captureLifecycleRunEnvelope)({ binding: currentBinding, envelopeText });
            },
        });
        return null;
    }
    catch (error) {
        return error instanceof errors_1.RuntimeError
            ? error
            : (0, errors_1.createInvalidConfigError)('Lifecycle run capture binding was rejected.', [
                error instanceof Error ? error.message : String(error),
                'No underlying command work was performed.',
            ]);
    }
}
function detectGlobalValueOption(argv, name) {
    let present = false;
    let value = null;
    let count = 0;
    for (let index = 2; index < argv.length; index += 1) {
        const token = argv[index];
        if (token === '--')
            break;
        if (token === name) {
            present = true;
            count += 1;
            const next = argv[index + 1];
            if (next === undefined || next.startsWith('-')) {
                return { present, value: null, error: `${name} requires one value.` };
            }
            value = next;
            index += 1;
        }
        else if (token.startsWith(`${name}=`)) {
            present = true;
            count += 1;
            value = token.slice(name.length + 1);
            if (value === '')
                return { present, value: null, error: `${name} requires one value.` };
        }
    }
    return count > 1 ? { present, value, error: `${name} may be provided only once.` } : { present, value, error: null };
}
function lifecycleCaptureCommanderArgv(argv, commandIdentity) {
    const runGate = detectGlobalValueOption(argv, '--run-gate');
    const runArtifact = detectGlobalValueOption(argv, '--run-artifact');
    if (!runGate.present && !runArtifact.present)
        return [...argv];
    if (commandIdentity === 'phase update' ||
        commandIdentity === 'milestone update' ||
        commandIdentity === 'task scope-recover') {
        return [...argv];
    }
    const result = argv.slice(0, 2);
    for (let index = 2; index < argv.length; index += 1) {
        const token = argv[index];
        if (token === '--') {
            result.push(...argv.slice(index));
            break;
        }
        if (token === '--run-directory') {
            if (argv[index + 1] !== undefined)
                index += 1;
            continue;
        }
        if (token.startsWith('--run-directory='))
            continue;
        result.push(token);
    }
    return result;
}
function dispatchManagedCliFromShimIfNeeded(argv, format, commandIdentity) {
    if (!(0, runtime_state_1.isVersionManagerShimMode)() || (0, runtime_state_1.isVersionManagerCommand)(argv)) {
        return null;
    }
    const resolution = (0, runtime_state_1.resolveSelectedManagedCli)({ currentExecutablePath: argv[1] });
    if (!resolution.ok) {
        (0, output_1.emitError)({
            command: commandIdentity,
            format,
            code: resolution.reason.toUpperCase().replace(/-/g, '_'),
            message: resolution.message,
            details: [...resolution.details, 'Recovery: run day-shift version doctor for local runtime context.'],
            findings: [
                (0, output_1.createBlockingValidationFinding)({
                    code: `VERSION_MANAGER_${resolution.reason.toUpperCase().replace(/-/g, '_')}`,
                    message: resolution.message,
                    blockingReason: 'invalid-command-input',
                    recovery: 'Inspect local version-manager state with day-shift version doctor, then repair selected metadata or managed package layout.',
                    evidence: {
                        category: 'command-specific',
                        details: {
                            reason: resolution.reason,
                            details: resolution.details,
                        },
                    },
                }),
            ],
        });
        return errors_1.RuntimeExitCode.ERROR;
    }
    const spawnCommand = resolution.target.executablePath.endsWith('.js') ? 'node' : resolution.target.executablePath;
    const spawnArgs = resolution.target.executablePath.endsWith('.js')
        ? [resolution.target.executablePath, ...argv.slice(2)]
        : argv.slice(2);
    const result = (0, node_child_process_1.spawnSync)(spawnCommand, spawnArgs, {
        stdio: 'pipe',
        encoding: 'utf8',
        env: {
            ...process.env,
            DAY_SHIFT_MANAGED_VERSION: resolution.target.selectedVersion,
            DAY_SHIFT_MANAGED_PACKAGE_ROOT: resolution.target.packageRoot,
        },
    });
    if (result.stdout) {
        process.stdout.write(result.stdout);
    }
    if (result.stderr) {
        process.stderr.write(result.stderr);
    }
    if (result.error !== undefined) {
        if (result.error &&
            result.error.code === 'EPERM' &&
            resolution.target.executablePath.endsWith('.js')) {
            return runManagedJavaScriptInProcess(resolution.target.executablePath, argv.slice(2), {
                DAY_SHIFT_MANAGED_VERSION: resolution.target.selectedVersion,
                DAY_SHIFT_MANAGED_PACKAGE_ROOT: resolution.target.packageRoot,
            }, commandIdentity);
        }
        (0, output_1.emitError)({
            command: commandIdentity,
            format,
            code: 'MANAGED_CLI_SPAWN_FAILED',
            message: 'Failed to spawn selected Day Shift managed executable.',
            details: [`Executable path: ${resolution.target.executablePath}`, result.error.message],
            findings: [
                (0, output_1.createBlockingValidationFinding)({
                    code: 'VERSION_MANAGER_MANAGED_CLI_SPAWN_FAILED',
                    message: 'Failed to spawn selected Day Shift managed executable.',
                    blockingReason: 'invalid-command-input',
                    recovery: 'Verify that the managed executable exists, is executable, and is not blocked by the host environment.',
                    evidence: {
                        category: 'command-specific',
                        details: {
                            executablePath: resolution.target.executablePath,
                            error: result.error.message,
                        },
                    },
                }),
            ],
        });
        return errors_1.RuntimeExitCode.ERROR;
    }
    return result.status ?? errors_1.RuntimeExitCode.ERROR;
}
function runManagedJavaScriptInProcess(executablePath, args, managedEnvironment, commandIdentity) {
    const previousArgv = process.argv;
    const previousExitCode = process.exitCode;
    const previousEnvironment = {};
    const previousStdoutWrite = process.stdout.write;
    const previousStderrWrite = process.stderr.write;
    let capturedStdout = '';
    let capturedStderr = '';
    for (const key of Object.keys(managedEnvironment)) {
        previousEnvironment[key] = process.env[key];
        process.env[key] = managedEnvironment[key];
    }
    process.argv = [process.execPath, executablePath, ...args];
    process.exitCode = undefined;
    process.stdout.write = ((chunk, ...writeArgs) => {
        capturedStdout += typeof chunk === 'string' ? chunk : Buffer.from(chunk).toString('utf8');
        const callback = writeArgs.find((arg) => typeof arg === 'function');
        callback?.();
        return true;
    });
    process.stderr.write = ((chunk, ...writeArgs) => {
        capturedStderr += typeof chunk === 'string' ? chunk : Buffer.from(chunk).toString('utf8');
        const callback = writeArgs.find((arg) => typeof arg === 'function');
        callback?.();
        return true;
    });
    try {
        const runtimeRequire = (0, node_module_1.createRequire)(executablePath);
        delete runtimeRequire.cache[runtimeRequire.resolve(executablePath)];
        runtimeRequire(executablePath);
        if (capturedStdout) {
            node_fs_1.default.writeSync(1, capturedStdout);
        }
        if (capturedStderr) {
            node_fs_1.default.writeSync(2, capturedStderr);
        }
        return typeof process.exitCode === 'number' ? process.exitCode : errors_1.RuntimeExitCode.SUCCESS;
    }
    catch (error) {
        (0, output_1.emitError)({
            command: commandIdentity,
            format: output_1.DEFAULT_OUTPUT_FORMAT,
            code: 'MANAGED_CLI_IN_PROCESS_FAILED',
            message: 'Failed to run selected Day Shift managed JavaScript executable in-process.',
            details: [error instanceof Error ? error.message : String(error)],
        });
        return errors_1.RuntimeExitCode.ERROR;
    }
    finally {
        process.stdout.write = previousStdoutWrite;
        process.stderr.write = previousStderrWrite;
        process.argv = previousArgv;
        process.exitCode = previousExitCode;
        for (const [key, value] of Object.entries(previousEnvironment)) {
            if (value === undefined) {
                delete process.env[key];
            }
            else {
                process.env[key] = value;
            }
        }
    }
}
function checkInstalledWorkspaceCompatibility(argv) {
    if (shouldSkipInstalledWorkspaceCompatibilityGate(argv)) {
        return null;
    }
    const explicitRoot = process.env.DAY_SHIFT_REPOSITORY_ROOT;
    const repositoryDetection = (0, runtime_contract_2.detectRepositoryRoot)({
        explicitRoot: explicitRoot && explicitRoot.trim().length > 0 ? explicitRoot : undefined,
    });
    const dayShiftDirectory = node_path_1.default.join(repositoryDetection.root, runtime_contract_1.DAY_SHIFT_DIRECTORY_NAME);
    if (!node_fs_1.default.existsSync(dayShiftDirectory) || !node_fs_1.default.statSync(dayShiftDirectory).isDirectory()) {
        return null;
    }
    if (!workspaceHasCompatibilityEvidence(repositoryDetection.root)) {
        return null;
    }
    const evidence = (0, workspace_compatibility_1.discoverWorkspaceCompatibilityVersions)({
        repositoryRoot: repositoryDetection.root,
    });
    const checks = (0, workspace_compatibility_1.checkWorkspaceCompatibility)({
        evidence,
        compatibility: output_lifecycle_1.CURRENT_RELEASE_COMPATIBILITY,
    });
    const diagnostics = (0, workspace_compatibility_1.createWorkspaceCompatibilityDiagnostics)({
        checks,
        evidence,
    });
    if (diagnostics.length === 0) {
        return null;
    }
    const findings = (0, workspace_compatibility_1.createWorkspaceCompatibilityFindings)(diagnostics);
    return (0, errors_1.createInvalidConfigError)('Day Shift workspace compatibility check failed before command execution.', [
        'No-write boundary: no workspace files were changed.',
        'Recovery: use a CLI release compatible with the detected workspace metadata, or run an explicit migration with a compatible CLI before retrying.',
        (0, output_1.renderValidationFindingsText)(findings, 'Compatibility findings'),
    ], findings);
}
function workspaceHasCompatibilityEvidence(repositoryRoot) {
    return (workspaceRootContainsMarkdownEvidence(node_path_1.default.join(repositoryRoot, '.day-shift', 'specs')) ||
        workspaceRootContainsMarkdownEvidence(node_path_1.default.join(repositoryRoot, '.day-shift', 'planning')));
}
function workspaceRootContainsMarkdownEvidence(rootPath) {
    if (!node_fs_1.default.existsSync(rootPath) || !node_fs_1.default.statSync(rootPath).isDirectory()) {
        return false;
    }
    const entries = node_fs_1.default.readdirSync(rootPath, { withFileTypes: true });
    for (const entry of entries) {
        const childPath = node_path_1.default.join(rootPath, entry.name);
        if (entry.isFile() && entry.name.endsWith('.md')) {
            return true;
        }
        if (entry.isDirectory() && workspaceRootContainsMarkdownEvidence(childPath)) {
            return true;
        }
    }
    return false;
}
function shouldSkipInstalledWorkspaceCompatibilityGate(argv) {
    if (require.main !== module) {
        return true;
    }
    if (process.env.DAY_SHIFT_SKIP_WORKSPACE_COMPATIBILITY_GATE === '1') {
        return true;
    }
    const commandArgs = argv.slice(2);
    if (commandArgs.some((arg) => arg === '--help' || arg === '-h' || arg === 'help')) {
        return true;
    }
    if (commandArgs.some((arg) => arg === '--version' || arg === '-V')) {
        return true;
    }
    const globalValueOptions = new Set([
        '--format',
        '--protocol-version',
        '--detail',
        '--finding-code',
        '--severity',
        '--fields',
        '--limit',
        '--page-lane',
        '--page-size',
        '--page-cursor',
        '--output-budget',
        '--json-spacing',
        '--output-file',
        ...output_1.LIFECYCLE_RUN_CAPTURE_GLOBAL_OPTIONS,
    ]);
    const commandTokens = [];
    for (let index = 0; index < commandArgs.length && commandTokens.length < 2; index += 1) {
        const token = commandArgs[index];
        const optionName = token.split('=', 1)[0];
        if (globalValueOptions.has(optionName)) {
            if (!token.includes('='))
                index += 1;
            continue;
        }
        if (!token.startsWith('-'))
            commandTokens.push(token);
    }
    const firstCommand = commandTokens[0];
    if (firstCommand === 'workspace') {
        const workspaceSubcommand = commandTokens[1];
        return workspaceSubcommand === 'migrate' || workspaceSubcommand === 'upgrade';
    }
    return (firstCommand === 'about' || firstCommand === 'completion' || firstCommand === 'init' || firstCommand === 'license');
}
function normalizeVersionOptionAliases(argv) {
    return normalizeVersionInstallVersionOption(normalizeReleaseVersionOption(argv));
}
function normalizeVersionInstallVersionOption(argv) {
    const versionIndex = argv.indexOf('version');
    const installIndex = argv.indexOf('install');
    if (versionIndex === -1 ||
        installIndex === -1 ||
        installIndex !== versionIndex + 1 ||
        installIndex >= argv.length - 1) {
        return argv;
    }
    let changed = false;
    const normalized = argv.map((arg, index) => {
        if (index <= installIndex) {
            return arg;
        }
        if (arg === '--version') {
            changed = true;
            return '--assert-version';
        }
        if (arg.startsWith('--version=')) {
            changed = true;
            return `--assert-version=${arg.slice('--version='.length)}`;
        }
        return arg;
    });
    return changed ? normalized : argv;
}
function normalizeReleaseVersionOption(argv) {
    const releaseIndex = argv.indexOf('release');
    if (releaseIndex === -1 || releaseIndex >= argv.length - 1) {
        return argv;
    }
    let changed = false;
    const normalized = argv.map((arg, index) => {
        if (index <= releaseIndex) {
            return arg;
        }
        if (arg === '--version') {
            changed = true;
            return '--release-version';
        }
        if (arg.startsWith('--version=')) {
            changed = true;
            return `--release-version=${arg.slice('--version='.length)}`;
        }
        return arg;
    });
    return changed ? normalized : argv;
}
if (require.main === module) {
    void run().then((exitCode) => {
        process.exitCode = exitCode;
    });
}
