"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.createReleaseCommand = createReleaseCommand;
exports.parseInstalledCommandName = parseInstalledCommandName;
exports.createReleaseCommandInvocationMapping = createReleaseCommandInvocationMapping;
exports.writeReleaseLocalValidationReport = writeReleaseLocalValidationReport;
const node_fs_1 = __importDefault(require("node:fs"));
const node_path_1 = __importDefault(require("node:path"));
const node_child_process_1 = require("node:child_process");
const node_module_1 = require("node:module");
const node_zlib_1 = __importDefault(require("node:zlib"));
const errors_1 = require("../../../lib/errors");
const output_1 = require("../../../lib/output");
const output_safety_1 = require("../../../lib/output/output-safety");
const build_input_manifest_1 = require("../../../lib/runtime/build-input-manifest");
const registration_1 = require("../registration");
const repository_state_1 = require("./repository-state");
const output_lifecycle_1 = require("./output-lifecycle");
const version_1 = require("./version");
const release_notes_1 = require("./release-notes");
const RELEASE_SUBCOMMANDS = [
    {
        name: "build",
        description: "Declare the local release build surface for future versioned artifact creation.",
        mode: "write",
        boundary: "future generated release directory creation under release/<version>/",
        options: ["version", "commandName", "outputDir", "dryRun", "dirty"]
    },
    {
        name: "check",
        description: "Declare the read-only local release validation surface.",
        mode: "read-only check",
        boundary: "read-only validation of local release inputs and staged outputs",
        options: ["version", "commandName", "outputDir"]
    },
    {
        name: "manifest",
        description: "Declare the release manifest generation surface.",
        mode: "generated asset creation",
        boundary: "future release manifest generation inside release/<version>/",
        options: ["version", "commandName", "outputDir", "dryRun"]
    },
    {
        name: "archive",
        description: "Declare the platform archive generation surface.",
        mode: "generated asset creation",
        boundary: "future macOS/Linux and Windows archive generation",
        options: ["version", "outputDir", "dryRun"]
    },
    {
        name: "checksum",
        description: "Declare the checksum generation surface.",
        mode: "generated asset creation",
        boundary: "future SHA-256 checksum generation for release artifacts",
        options: ["version", "outputDir", "dryRun"]
    },
    {
        name: "installer",
        description: "Declare the installer asset generation surface.",
        mode: "generated asset creation",
        boundary: "future POSIX and Windows installer asset generation",
        options: ["version", "commandName", "outputDir", "dryRun"]
    },
    {
        name: "notes",
        description: "Declare the draft release notes generation surface.",
        mode: "generated asset creation",
        boundary: "future draft release notes generation from planning evidence",
        options: ["version", "commandName", "outputDir", "dryRun"]
    },
    {
        name: "retention",
        description: "Declare the local release-output retention surface.",
        mode: "retention pruning",
        boundary: "future local release-output pruning that preserves the current release plus recent successful releases",
        options: ["version", "outputDir", "keep", "dryRun"]
    },
    {
        name: "cleanup",
        description: "Declare the explicit local release-output cleanup surface.",
        mode: "explicit cleanup",
        boundary: "future explicit cleanup of generated local release outputs only",
        options: ["outputDir", "confirm", "dryRun"]
    }
];
const DEFAULT_INSTALLED_COMMAND_NAME = "day-shift";
const INSTALLED_COMMAND_NAME_PATTERN = /^(?=.*[A-Za-z0-9])[A-Za-z0-9][A-Za-z0-9._-]*$/;
async function createReleaseCommand() {
    const { Command } = await import("commander");
    const command = new Command("release");
    command.description("Coordinate local release command surfaces without public npm publication or website upload.");
    for (const releaseSubcommand of RELEASE_SUBCOMMANDS) {
        (0, registration_1.registerCommand)(command, createReleaseSubcommand(Command, releaseSubcommand));
    }
    return command;
}
function createReleaseSubcommand(Command, releaseSubcommand) {
    const command = new Command(releaseSubcommand.name);
    command.description(releaseSubcommand.description);
    addReleaseOptions(command, releaseSubcommand.options);
    command.action((options, commandInstance) => {
        const format = (0, output_1.resolveOutputFormat)(commandInstance.optsWithGlobals().format);
        if (format === null) {
            throw (0, errors_1.createUnsupportedOutputFormatError)({
                received: commandInstance.optsWithGlobals().format,
                commandBoundary: `release ${releaseSubcommand.name} command output format`
            });
        }
        const commandName = releaseSubcommandHasOption(releaseSubcommand, "commandName")
            ? requireInstalledCommandName(releaseSubcommand, options.commandName)
            : null;
        const parsedVersion = requireReleaseVersion(releaseSubcommand, options.releaseVersion);
        const dirty = releaseSubcommandHasOption(releaseSubcommand, "dirty") && options.dirty === true;
        const effectiveOutputDir = resolveReleaseOutputDirOption({
            outputDir: options.outputDir,
            dirty
        });
        const repositoryState = checkReleaseState(releaseSubcommand, effectiveOutputDir, commandInstance, dirty);
        const dryRun = options.dryRun === true;
        const repositoryRoot = getRootCommand(commandInstance).configRepositoryContext?.root ?? process.cwd();
        const outputState = (0, output_lifecycle_1.resolveReleaseOutputState)({
            repositoryRoot,
            outputDir: effectiveOutputDir,
            version: parsedVersion.ok ? parsedVersion.version : null
        });
        const invocation = commandName === null
            ? null
            : createReleaseCommandInvocationMapping({
                installedCommandName: commandName,
                stagedExecutablePath: resolveStagedReleaseExecutablePath(outputState, commandName),
                args: createReleaseInvocationArgs(releaseSubcommand, parsedVersion, options, effectiveOutputDir)
            });
        const packageBoundary = createReleasePackageBoundaryMetadata({
            repositoryRoot,
            installedCommandName: commandName ?? DEFAULT_INSTALLED_COMMAND_NAME
        });
        const buildPreflight = resolveReleaseBuildPreflight({
            releaseSubcommand,
            dryRun,
            repositoryRoot
        });
        const operation = resolveReleaseOutputOperation({
            releaseSubcommand,
            dryRun,
            confirm: options.confirm === true,
            keep: options.keep,
            version: parsedVersion.ok ? parsedVersion.version : null,
            outputState
        });
        const releaseNotesSourceSummary = resolveReleaseNotesSourceSummary({
            releaseSubcommand,
            repositoryRoot,
            outputState,
            version: parsedVersion.ok ? parsedVersion.version : null
        });
        const releaseNotesDraft = resolveReleaseNotesDraft({
            releaseSubcommand,
            dryRun,
            repositoryRoot,
            outputState,
            version: parsedVersion.ok ? parsedVersion.version : null,
            releaseNotesSourceSummary
        });
        const effectiveReleaseNotesSourceSummary = releaseNotesDraft.sourceSummary ?? releaseNotesSourceSummary;
        const stagingPayload = resolveReleaseStagingPayload({
            releaseSubcommand,
            dryRun,
            repositoryRoot,
            outputState,
            version: parsedVersion.ok ? parsedVersion.version : null,
            installedCommandName: commandName ?? DEFAULT_INSTALLED_COMMAND_NAME,
            operation,
            releaseNotesSourceSummary: effectiveReleaseNotesSourceSummary
        });
        const installationReadme = resolveReleaseInstallationReadme({
            releaseSubcommand,
            dryRun,
            outputState,
            version: parsedVersion.ok ? parsedVersion.version : null,
            commandName: commandName ?? DEFAULT_INSTALLED_COMMAND_NAME,
            packageName: packageBoundary.name,
            requiredNodeVersion: packageBoundary.engines.node
        });
        const archivePayloads = resolveReleaseArchivePayloads({
            releaseSubcommand,
            dryRun,
            outputState,
            version: parsedVersion.ok ? parsedVersion.version : null,
            installedCommandName: commandName ?? DEFAULT_INSTALLED_COMMAND_NAME,
            packageName: packageBoundary.name,
            stagingPayload
        });
        const installerAssets = resolveReleaseInstallerAssets({
            releaseSubcommand,
            dryRun,
            outputState,
            version: parsedVersion.ok ? parsedVersion.version : null,
            installedCommandName: commandName ?? DEFAULT_INSTALLED_COMMAND_NAME,
            archivePayloads
        });
        const artifactChecksums = resolveReleaseArtifactChecksums({
            releaseSubcommand,
            dryRun,
            outputState,
            archivePayloads,
            installerAssets
        });
        const releaseManifest = resolveReleaseManifest({
            releaseSubcommand,
            dryRun,
            outputState,
            version: parsedVersion.ok ? parsedVersion.version : null,
            commandName: commandName ?? DEFAULT_INSTALLED_COMMAND_NAME,
            stagedCommandPath: invocation?.stagedRelease.executable ?? resolveStagedReleaseExecutablePath(outputState, commandName ?? DEFAULT_INSTALLED_COMMAND_NAME),
            cliVersion: packageBoundary.version,
            requiredNodeVersion: packageBoundary.engines.node,
            artifactChecksums,
            releaseNotesSourceSummary: effectiveReleaseNotesSourceSummary
        });
        const downloadBundle = resolveReleaseDownloadBundle({
            releaseSubcommand,
            dryRun,
            outputState,
            stagingPayload,
            archivePayloads,
            installerAssets,
            artifactChecksums,
            releaseManifest,
            installationReadme
        });
        const installerSafetyValidation = resolveReleaseInstallerSafetyValidation({
            releaseSubcommand,
            dryRun,
            outputState,
            version: parsedVersion.ok ? parsedVersion.version : null,
            commandName: commandName ?? DEFAULT_INSTALLED_COMMAND_NAME,
            stagedCommandPath: invocation?.stagedRelease.executable ?? resolveStagedReleaseExecutablePath(outputState, commandName ?? DEFAULT_INSTALLED_COMMAND_NAME),
            archivePayloads,
            releaseManifest
        });
        const localValidation = resolveReleaseLocalValidation({
            releaseSubcommand,
            dryRun,
            repositoryRoot,
            outputState,
            version: parsedVersion.ok ? parsedVersion.version : null,
            commandName: commandName ?? DEFAULT_INSTALLED_COMMAND_NAME,
            stagingPayload,
            archivePayloads
        });
        const localValidationReport = writeReleaseLocalValidationReport({
            releaseSubcommand,
            dryRun,
            outputState,
            version: parsedVersion.ok ? parsedVersion.version : null,
            commandName: commandName ?? DEFAULT_INSTALLED_COMMAND_NAME,
            installerSafetyValidation,
            localValidation
        });
        const successMarker = parsedVersion.ok
            ? resolveReleaseSuccessMarkerState({
                releaseSubcommand,
                dryRun,
                outputState,
                version: parsedVersion.version,
                operation
            })
            : createUnavailableMarkerState();
        const data = {
            command: `release ${releaseSubcommand.name}`,
            mode: releaseSubcommand.mode,
            boundary: releaseSubcommand.boundary,
            noWriteInThisMilestone: dryRun || !operation.changed,
            options: {
                version: parsedVersion.ok ? parsedVersion.version : null,
                commandName,
                outputDir: effectiveOutputDir,
                keep: options.keep ?? null,
                confirm: options.confirm === true,
                dryRun,
                dirty
            },
            invocation,
            packageBoundary,
            buildPreflight,
            stagingPayload,
            archivePayloads,
            installerAssets,
            artifactChecksums,
            releaseManifest,
            downloadBundle,
            installationReadme,
            releaseNotesSourceSummary: effectiveReleaseNotesSourceSummary,
            releaseNotesDraft,
            installerSafetyValidation,
            localValidation,
            localValidationReport,
            output: outputState,
            operation,
            successMarker,
            repositoryState,
            publication: {
                websiteUpload: "out-of-scope",
                publicNpmPublication: "out-of-scope"
            },
            nextImplementation: "downstream release pipeline milestones implement payload internals"
        };
        (0, output_1.emitSuccess)({
            command: `release ${releaseSubcommand.name}`,
            format,
            text: renderReleaseContractSummary(data),
            data
        });
    });
    return command;
}
function requireReleaseVersion(releaseSubcommand, value) {
    if (!releaseSubcommandHasOption(releaseSubcommand, "version")) {
        return { ok: false, input: null, reason: "missing", message: "", correctiveAction: "" };
    }
    const parsedVersion = (0, version_1.parseReleaseVersion)(value);
    if (!parsedVersion.ok) {
        throw (0, errors_1.createUsageError)(parsedVersion.message, [
            `Command: release ${releaseSubcommand.name}`,
            `Rejected version: ${parsedVersion.input ?? "(not provided)"}`,
            `Reason: ${parsedVersion.reason}`,
            `Recovery: ${parsedVersion.correctiveAction}`,
            "Exit behavior: exits before generated release output directories or artifacts are created."
        ]);
    }
    return parsedVersion;
}
function releaseSubcommandHasOption(releaseSubcommand, option) {
    return releaseSubcommand.options.includes(option);
}
function parseInstalledCommandName(value) {
    const input = value ?? DEFAULT_INSTALLED_COMMAND_NAME;
    if (typeof input !== "string") {
        return rejectInstalledCommandName(input, "invalid-type", "Use a non-empty executable basename such as day-shift.");
    }
    const commandName = input.trim();
    if (commandName.length === 0) {
        return rejectInstalledCommandName(input, "missing", "Use a non-empty executable basename such as day-shift.");
    }
    if (commandName === "." || commandName === "..") {
        return rejectInstalledCommandName(input, "reserved-path-segment", "Use an executable basename, not a relative path segment.");
    }
    if (/[\\/]/.test(commandName)) {
        return rejectInstalledCommandName(input, "path-like", "Use only the executable basename, without directories or path separators.");
    }
    if (/\s/.test(commandName)) {
        return rejectInstalledCommandName(input, "contains-whitespace", "Use a single executable basename without spaces or shell quoting.");
    }
    if (/[;&|<>`$(){}[\]*?!'"=:,]/.test(commandName)) {
        return rejectInstalledCommandName(input, "unsafe-shell-character", "Use only ASCII letters, numbers, dots, underscores, and hyphens.");
    }
    if (/\.(?:bat|cmd|ps1|sh)$/i.test(commandName)) {
        return rejectInstalledCommandName(input, "script-file-name", "Use the installed executable basename, not a platform script filename.");
    }
    if (!INSTALLED_COMMAND_NAME_PATTERN.test(commandName)) {
        return rejectInstalledCommandName(input, "unsafe-basename", "Use a basename that starts with a letter or number and contains only letters, numbers, dots, underscores, and hyphens.");
    }
    return {
        ok: true,
        input,
        commandName
    };
}
function createReleaseCommandInvocationMapping(options) {
    const parsedCommandName = parseInstalledCommandName(options.installedCommandName);
    if (!parsedCommandName.ok) {
        throw (0, errors_1.createUsageError)(parsedCommandName.message, [
            `Rejected command name: ${typeof parsedCommandName.input === "string" ? parsedCommandName.input : String(parsedCommandName.input)}`,
            `Reason: ${parsedCommandName.reason}`,
            `Recovery: ${parsedCommandName.correctiveAction}`
        ]);
    }
    const args = options.args.map((arg) => String(arg));
    return {
        args: [...args],
        development: createReleaseCommandInvocation("development", "node", ["dist/cli/index.js", ...args]),
        stagedRelease: createReleaseCommandInvocation("staged-release", options.stagedExecutablePath, args),
        installedUser: createReleaseCommandInvocation("installed-user", parsedCommandName.commandName, args)
    };
}
function createReleaseCommandInvocation(mode, executable, args) {
    return {
        mode,
        executable,
        args: [...args],
        command: [executable, ...args]
    };
}
function createReleaseInvocationArgs(releaseSubcommand, parsedVersion, options, effectiveOutputDir) {
    const args = ["release", releaseSubcommand.name];
    if (parsedVersion.ok) {
        args.push("--version", parsedVersion.version);
    }
    if (releaseSubcommandHasOption(releaseSubcommand, "outputDir")) {
        args.push("--output-dir", effectiveOutputDir);
    }
    if (releaseSubcommandHasOption(releaseSubcommand, "keep")) {
        args.push("--keep", String(options.keep ?? "3"));
    }
    if (releaseSubcommandHasOption(releaseSubcommand, "confirm") && options.confirm === true) {
        args.push("--confirm");
    }
    if (releaseSubcommandHasOption(releaseSubcommand, "dryRun") && options.dryRun === true) {
        args.push("--dry-run");
    }
    if (releaseSubcommandHasOption(releaseSubcommand, "dirty") && options.dirty === true) {
        args.push("--dirty");
    }
    return args;
}
function resolveReleaseOutputDirOption(options) {
    if (typeof options.outputDir === "string" && options.outputDir.trim().length > 0) {
        return options.outputDir;
    }
    return options.dirty ? "dirty-release" : "release";
}
function resolveStagedReleaseExecutablePath(outputState, commandName) {
    const releaseRoot = outputState.versionDirectoryRelative ?? outputState.releaseRootRelative;
    return `${releaseRoot}/bin/${commandName}`;
}
function createReleasePackageBoundaryMetadata(options) {
    const packageJsonPath = node_path_1.default.join(options.repositoryRoot, "package.json");
    if (!node_fs_1.default.existsSync(packageJsonPath)) {
        throw (0, errors_1.createUsageError)("Release command requires package.json metadata.", [
            "Reason: missing-package-metadata",
            "Recovery: restore package.json before running release commands.",
            "Exit behavior: exits before generated release output directories or artifacts are created."
        ]);
    }
    const packageJson = JSON.parse(node_fs_1.default.readFileSync(packageJsonPath, "utf8"));
    const bin = normalizeStringRecord(packageJson.bin);
    const localReleaseScripts = Object.fromEntries(Object.entries(normalizeStringRecord(packageJson.scripts))
        .filter(([scriptName, script]) => scriptName.startsWith("release:") &&
        script.trim().startsWith("node dist/cli/index.js release "))
        .sort(([left], [right]) => left.localeCompare(right)));
    const packageBinName = Object.keys(bin).find((binName) => binName === DEFAULT_INSTALLED_COMMAND_NAME) ?? Object.keys(bin)[0] ?? null;
    return {
        packageJsonPath: "package.json",
        name: readOptionalString(packageJson.name),
        version: readOptionalString(packageJson.version),
        private: packageJson.private === true,
        main: readOptionalString(packageJson.main),
        files: Array.isArray(packageJson.files)
            ? packageJson.files.filter((entry) => typeof entry === "string")
            : [],
        bin,
        installedCommandName: options.installedCommandName,
        packageBinName,
        packageBinPath: packageBinName === null ? null : bin[packageBinName] ?? null,
        engines: {
            node: typeof packageJson.engines === "object" && packageJson.engines !== null
                ? readOptionalString(packageJson.engines.node)
                : null
        },
        packageManager: readOptionalString(packageJson.packageManager),
        localReleaseScripts,
        publication: {
            publicNpmPublication: "out-of-scope",
            publicRegistryInstall: "out-of-scope"
        }
    };
}
function normalizeStringRecord(value) {
    if (typeof value !== "object" || value === null || Array.isArray(value)) {
        return {};
    }
    return Object.fromEntries(Object.entries(value)
        .filter((entry) => typeof entry[1] === "string"));
}
function readOptionalString(value) {
    return typeof value === "string" ? value : null;
}
function rejectInstalledCommandName(input, reason, correctiveAction) {
    const received = typeof input === "string" ? JSON.stringify(input) : String(input);
    return {
        ok: false,
        input,
        reason,
        message: `Rejected installed command name ${received}: ${correctiveAction}`,
        correctiveAction
    };
}
function requireInstalledCommandName(releaseSubcommand, value) {
    const parsedCommandName = parseInstalledCommandName(value);
    if (!parsedCommandName.ok) {
        throw (0, errors_1.createUsageError)(parsedCommandName.message, [
            `Command: release ${releaseSubcommand.name}`,
            `Rejected command name: ${typeof parsedCommandName.input === "string" ? parsedCommandName.input : String(parsedCommandName.input)}`,
            `Reason: ${parsedCommandName.reason}`,
            `Recovery: ${parsedCommandName.correctiveAction}`,
            "Exit behavior: exits before generated release output directories, launchers, manifests, installers, validation reports, or snippets are created."
        ]);
    }
    return parsedCommandName.commandName;
}
function checkReleaseState(releaseSubcommand, outputDir, commandInstance, dirty) {
    if (!releaseSubcommandHasOption(releaseSubcommand, "version")) {
        return {
            cleanRequired: false,
            dirtyAllowed: false,
            dirtyPaths: [],
            ignoredGeneratedOutputPaths: []
        };
    }
    const repositoryRoot = getRootCommand(commandInstance).configRepositoryContext?.root ?? process.cwd();
    if (releaseSubcommand.name === "check") {
        const state = (0, repository_state_1.checkReleaseRepositoryState)({
            repositoryRoot,
            outputDir,
            allowDirty: true
        });
        return {
            cleanRequired: false,
            dirtyAllowed: false,
            dirtyPaths: state.ok ? state.dirtyPaths : state.dirtyPaths,
            ignoredGeneratedOutputPaths: state.ok ? state.ignoredGeneratedOutputPaths : state.ignoredGeneratedOutputPaths
        };
    }
    const state = (0, repository_state_1.checkReleaseRepositoryState)({
        repositoryRoot,
        outputDir,
        allowDirty: dirty
    });
    if (!state.ok) {
        throw (0, errors_1.createUsageError)(state.message, [
            `Command: release ${releaseSubcommand.name}`,
            `Dirty paths: ${state.dirtyPaths.join(", ")}`,
            `Ignored generated output paths: ${state.ignoredGeneratedOutputPaths.length > 0 ? state.ignoredGeneratedOutputPaths.join(", ") : "(none)"}`,
            `Recovery: ${state.correctiveAction}`,
            "Exit behavior: exits before generated release output directories or artifacts are created."
        ]);
    }
    return {
        cleanRequired: !dirty,
        dirtyAllowed: dirty,
        dirtyPaths: state.dirtyPaths,
        ignoredGeneratedOutputPaths: state.ignoredGeneratedOutputPaths
    };
}
function resolveReleaseOutputOperation(options) {
    if (options.releaseSubcommand.name === "retention") {
        if (options.outputState.versionDirectoryRelative === null || options.version === null) {
            throw (0, errors_1.createUsageError)("Release retention requires an explicit release version.", [
                "Exit behavior: exits before local generated release output is pruned."
            ]);
        }
        return (0, output_lifecycle_1.applyReleaseRetention)({
            state: options.outputState,
            currentVersion: options.version,
            keepSuccessfulPriorCount: (0, output_lifecycle_1.parseRetentionKeep)(options.keep),
            dryRun: options.dryRun
        });
    }
    if (options.releaseSubcommand.name === "cleanup") {
        return (0, output_lifecycle_1.applyReleaseCleanup)({
            state: options.outputState,
            confirm: options.confirm,
            dryRun: options.dryRun
        });
    }
    if (options.dryRun) {
        return (0, output_lifecycle_1.createDryRunOperation)("dry-run", options.outputState.versionDirectoryRelative === null
            ? `Dry run did not modify local generated release output under ${options.outputState.releaseRootRelative}.`
            : `Dry run did not modify local generated release output under ${options.outputState.versionDirectoryRelative}.`);
    }
    if (options.releaseSubcommand.name === "build") {
        return (0, output_lifecycle_1.prepareFreshReleaseBuildDirectory)(options.outputState);
    }
    if (options.releaseSubcommand.name === "notes") {
        return {
            kind: "release-notes-draft",
            dryRun: false,
            changed: true,
            removedPaths: [],
            retainedPaths: options.outputState.versionDirectoryRelative === null
                ? []
                : [options.outputState.versionDirectoryRelative],
            message: "Generated editable draft release notes in the versioned release directory."
        };
    }
    if (options.releaseSubcommand.name === "installer") {
        return {
            kind: "installer-assets",
            dryRun: false,
            changed: true,
            removedPaths: [],
            retainedPaths: options.outputState.versionDirectoryRelative === null
                ? []
                : [options.outputState.versionDirectoryRelative],
            message: "Generated local installer assets in the versioned release directory without website upload."
        };
    }
    return {
        kind: "report-only",
        dryRun: false,
        changed: false,
        removedPaths: [],
        retainedPaths: [],
        message: `Release ${options.releaseSubcommand.name} did not modify local generated release output in this checkpoint.`
    };
}
function resolveReleaseNotesDraft(options) {
    if (!["build", "notes"].includes(options.releaseSubcommand.name)) {
        return (0, release_notes_1.createNotApplicableReleaseNotesDraft)();
    }
    if (options.dryRun) {
        return (0, release_notes_1.createSkippedReleaseNotesDraft)({
            versionDirectoryRelative: options.outputState.versionDirectoryRelative,
            sourceSummary: options.releaseNotesSourceSummary
        });
    }
    if (options.version === null ||
        options.outputState.versionDirectory === null ||
        options.outputState.versionDirectoryRelative === null ||
        options.releaseNotesSourceSummary === null) {
        return (0, release_notes_1.createNotApplicableReleaseNotesDraft)();
    }
    return (0, release_notes_1.writeReleaseNotesDraft)({
        repositoryRoot: options.repositoryRoot,
        version: options.version,
        versionDirectory: options.outputState.versionDirectory,
        versionDirectoryRelative: options.outputState.versionDirectoryRelative,
        sourceSummary: options.releaseNotesSourceSummary
    });
}
function resolveReleaseStagingPayload(options) {
    if (options.releaseSubcommand.name !== "build") {
        return (0, output_lifecycle_1.createNotApplicableStagingPayload)();
    }
    if (options.dryRun) {
        return (0, output_lifecycle_1.createSkippedStagingPayload)(options.outputState);
    }
    if (options.version === null || !options.operation.changed) {
        return (0, output_lifecycle_1.createNotApplicableStagingPayload)();
    }
    return (0, output_lifecycle_1.populateReleaseStagingPayload)({
        repositoryRoot: options.repositoryRoot,
        state: options.outputState,
        version: options.version,
        installedCommandName: options.installedCommandName,
        releaseNotesSourceSummary: options.releaseNotesSourceSummary
    });
}
function resolveReleaseArchivePayloads(options) {
    if (options.releaseSubcommand.name !== "build") {
        return (0, output_lifecycle_1.createNotApplicableArchivePayloads)();
    }
    if (options.dryRun) {
        return (0, output_lifecycle_1.createSkippedArchivePayloads)(options.outputState);
    }
    if (options.version === null || options.stagingPayload.status !== "created") {
        return (0, output_lifecycle_1.createNotApplicableArchivePayloads)();
    }
    return (0, output_lifecycle_1.populateReleaseArchivePayloads)({
        state: options.outputState,
        stagingPayload: options.stagingPayload,
        packageName: options.packageName,
        version: options.version,
        installedCommandName: options.installedCommandName
    });
}
function resolveReleaseArtifactChecksums(options) {
    if (options.releaseSubcommand.name !== "build") {
        return (0, output_lifecycle_1.createNotApplicableArtifactChecksums)();
    }
    if (options.dryRun) {
        return (0, output_lifecycle_1.createSkippedArtifactChecksums)(options.outputState);
    }
    if (options.archivePayloads.status !== "created" || options.installerAssets.status !== "created") {
        return (0, output_lifecycle_1.createNotApplicableArtifactChecksums)();
    }
    return (0, output_lifecycle_1.populateReleaseArtifactChecksums)({
        state: options.outputState,
        archivePayloads: options.archivePayloads
    });
}
function resolveReleaseInstallerAssets(options) {
    if (options.releaseSubcommand.name !== "build" && options.releaseSubcommand.name !== "installer") {
        return (0, output_lifecycle_1.createNotApplicableInstallerAssets)();
    }
    if (options.dryRun) {
        return (0, output_lifecycle_1.createSkippedInstallerAssets)(options.outputState);
    }
    if (options.version === null) {
        return (0, output_lifecycle_1.createNotApplicableInstallerAssets)();
    }
    if (options.releaseSubcommand.name === "build" && options.archivePayloads.status !== "created") {
        return (0, output_lifecycle_1.createNotApplicableInstallerAssets)();
    }
    return (0, output_lifecycle_1.populateReleaseInstallerAssets)({
        state: options.outputState,
        version: options.version,
        installedCommandName: options.installedCommandName
    });
}
function resolveReleaseManifest(options) {
    if (options.releaseSubcommand.name !== "build") {
        return (0, output_lifecycle_1.createNotApplicableReleaseManifest)();
    }
    if (options.dryRun) {
        return (0, output_lifecycle_1.createSkippedReleaseManifest)(options.outputState);
    }
    if (options.version === null || options.artifactChecksums.status !== "created" || options.releaseNotesSourceSummary === null) {
        return (0, output_lifecycle_1.createNotApplicableReleaseManifest)();
    }
    return (0, output_lifecycle_1.populateReleaseManifest)({
        state: options.outputState,
        version: options.version,
        cliVersion: options.cliVersion,
        installedCommandName: options.commandName,
        stagedCommandPath: options.stagedCommandPath,
        requiredNodeVersion: options.requiredNodeVersion,
        artifactChecksums: options.artifactChecksums,
        releaseNotesSourceSummary: options.releaseNotesSourceSummary
    });
}
function resolveReleaseDownloadBundle(options) {
    if (options.releaseSubcommand.name !== "build") {
        return (0, output_lifecycle_1.createNotApplicableDownloadBundle)();
    }
    if (options.dryRun) {
        return (0, output_lifecycle_1.createSkippedDownloadBundle)(options.outputState);
    }
    return (0, output_lifecycle_1.populateReleaseDownloadBundle)({
        state: options.outputState,
        noticeFiles: options.stagingPayload.noticeFiles,
        archivePayloads: options.archivePayloads,
        installerAssets: options.installerAssets,
        artifactChecksums: options.artifactChecksums,
        releaseManifest: options.releaseManifest,
        installationReadme: options.installationReadme
    });
}
function resolveReleaseInstallationReadme(options) {
    if (options.releaseSubcommand.name !== "build") {
        return (0, output_lifecycle_1.createNotApplicableInstallationReadme)();
    }
    if (options.dryRun) {
        return (0, output_lifecycle_1.createSkippedInstallationReadme)(options.outputState);
    }
    if (options.version === null) {
        return (0, output_lifecycle_1.createNotApplicableInstallationReadme)();
    }
    return (0, output_lifecycle_1.populateReleaseInstallationReadmeFromBuildMetadata)({
        state: options.outputState,
        version: options.version,
        packageName: options.packageName,
        installedCommandName: options.commandName,
        requiredNodeVersion: options.requiredNodeVersion
    });
}
function resolveReleaseNotesSourceSummary(options) {
    if (!["build", "manifest", "notes"].includes(options.releaseSubcommand.name) || options.version === null) {
        return null;
    }
    return (0, release_notes_1.createReleaseNotesSourceSummary)({
        repositoryRoot: options.repositoryRoot,
        releaseRoot: options.outputState.releaseRoot,
        releaseRootRelative: options.outputState.releaseRootRelative,
        version: options.version,
        notesGenerated: options.outputState.versionDirectory === null
            ? false
            : (node_fs_1.default.existsSync(node_path_1.default.join(options.outputState.versionDirectory, "download-bundle", "release-notes.md")) ||
                node_fs_1.default.existsSync(node_path_1.default.join(options.outputState.versionDirectory, "release-notes.md")))
    });
}
function resolveReleaseInstallerSafetyValidation(options) {
    const installRoot = options.outputState.versionDirectoryRelative === null
        ? null
        : `${options.outputState.versionDirectoryRelative}/installer-validation`;
    if (options.releaseSubcommand.name !== "build") {
        return {
            status: "not-applicable",
            installRoot,
            targets: []
        };
    }
    if (options.dryRun) {
        return {
            status: "skipped-dry-run",
            installRoot,
            targets: []
        };
    }
    if (options.version === null ||
        options.outputState.versionDirectory === null ||
        options.outputState.versionDirectoryRelative === null ||
        options.archivePayloads.status !== "created" ||
        options.releaseManifest.status !== "created" ||
        options.releaseManifest.data === null ||
        installRoot === null) {
        return {
            status: "not-applicable",
            installRoot,
            targets: []
        };
    }
    return {
        status: "passed",
        installRoot,
        targets: options.archivePayloads.targets.map((target) => (0, output_lifecycle_1.validateReleaseInstallerSafety)({
            versionDirectory: options.outputState.versionDirectory,
            versionDirectoryRelative: options.outputState.versionDirectoryRelative,
            expectedVersion: options.version,
            expectedInstalledCommandName: options.commandName,
            expectedStagedCommandPath: options.stagedCommandPath,
            manifest: options.releaseManifest.data,
            target: target.target,
            payloadDirectory: target.payloadDirectory,
            installRoot: `${installRoot}/${target.target}`,
            nodeVersion: process.version
        }))
    };
}
function resolveReleaseLocalValidation(options) {
    if (options.dryRun) {
        return {
            status: "skipped-dry-run",
            staging: null,
            archives: []
        };
    }
    if (options.releaseSubcommand.name === "build" &&
        options.version !== null &&
        options.stagingPayload.status === "created" &&
        options.archivePayloads.status === "created") {
        return {
            status: "requires-post-build-check",
            staging: null,
            archives: []
        };
    }
    if (options.releaseSubcommand.name === "check") {
        const validationInputs = resolveExistingReleaseValidationInputs({
            repositoryRoot: options.repositoryRoot,
            outputState: options.outputState,
            version: options.version,
            commandName: options.commandName
        });
        if (validationInputs === null) {
            return {
                status: "not-applicable",
                staging: null,
                archives: []
            };
        }
        const staging = validateReleaseExecutable({
            executable: validationInputs.stagedExecutable,
            artifactRoot: validationInputs.stagingArtifactRoot,
            repositoryRoot: options.repositoryRoot,
            versionDirectory: validationInputs.versionDirectory,
            version: validationInputs.version,
            commandName: options.commandName
        });
        const archives = validationInputs.archivePayloads.targets.map((target) => validateReleaseArchiveExecution({
            target,
            repositoryRoot: options.repositoryRoot,
            versionDirectory: validationInputs.versionDirectory,
            version: validationInputs.version,
            commandName: options.commandName
        }));
        return {
            status: "passed",
            staging,
            archives
        };
    }
    if (options.version === null ||
        options.outputState.versionDirectory === null ||
        options.stagingPayload.status !== "created" ||
        options.stagingPayload.stagingDirectory === null ||
        options.archivePayloads.status !== "created") {
        return {
            status: "not-applicable",
            staging: null,
            archives: []
        };
    }
    return {
        status: "not-applicable",
        staging: null,
        archives: []
    };
}
function writeReleaseLocalValidationReport(options) {
    if (options.dryRun) {
        return {
            status: "skipped-dry-run",
            reportPath: null,
            reportPathRelative: options.outputState.versionDirectoryRelative === null
                ? null
                : `${options.outputState.versionDirectoryRelative}/release-validation-report.json`
        };
    }
    if (options.releaseSubcommand.name !== "check" ||
        options.version === null ||
        options.outputState.versionDirectory === null ||
        options.outputState.versionDirectoryRelative === null ||
        options.localValidation.status !== "passed") {
        return {
            status: "not-applicable",
            reportPath: null,
            reportPathRelative: options.outputState.versionDirectoryRelative === null
                ? null
                : `${options.outputState.versionDirectoryRelative}/release-validation-report.json`
        };
    }
    const reportPath = node_path_1.default.join(options.outputState.versionDirectory, "release-validation-report.json");
    const reportPathRelative = `${options.outputState.versionDirectoryRelative}/release-validation-report.json`;
    const executableValidations = [
        options.localValidation.staging,
        ...options.localValidation.archives.map((archive) => archive.execution)
    ].filter((validation) => validation !== null);
    const noWriteIsolation = executableValidations.map((validation) => ({
        executable: validation.executable,
        artifactRoot: validation.artifactRoot,
        validationScratchRoot: validation.validationScratchRoot,
        validationScratchCleaned: validation.validationScratchCleaned,
        stateDir: validation.isolatedEnvironment.stateDir,
        configHome: validation.isolatedEnvironment.configHome,
        licenseFile: validation.isolatedEnvironment.licenseFile,
        commandCount: validation.commands.length
    }));
    const report = {
        schemaVersion: 1,
        generatedBy: "day-shift-release-check",
        command: "release check",
        version: options.version,
        installedCommandName: options.commandName,
        generatedAt: new Date().toISOString(),
        reportPath: reportPathRelative,
        publication: {
            websiteUpload: "out-of-scope",
            publicNpmPublication: "out-of-scope"
        },
        evidence: {
            releaseCheck: {
                status: options.localValidation.status,
                stagingStatus: options.localValidation.staging?.status ?? null,
                archiveStatuses: options.localValidation.archives.map((archive) => ({
                    target: archive.target,
                    status: archive.status,
                    archivePath: archive.archivePath,
                    requiredFiles: archive.requiredFiles,
                    missingFiles: archive.missingFiles,
                    executionStatus: archive.execution?.status ?? null,
                    executionSkippedReason: archive.executionSkippedReason,
                    temporaryCleaned: archive.temporaryCleaned
                }))
            },
            stagedExecution: options.localValidation.staging,
            archiveValidation: options.localValidation.archives,
            runtimeDiagnostics: executableValidations.map((validation) => validation.diagnostics),
            installerSafetyValidation: options.installerSafetyValidation,
            noWriteIsolation,
            installerFailureEvidence: [
                {
                    reason: "artifact-checksum-mismatch",
                    boundary: "fails before existing installation replacement"
                },
                {
                    reason: "installer-manifest-archive-missing",
                    boundary: "fails before existing installation replacement"
                },
                {
                    reason: "missing-node",
                    boundary: "fails before existing installation replacement"
                },
                {
                    reason: "unsupported-node-version",
                    boundary: "fails before existing installation replacement"
                },
                {
                    reason: "missing-executable-shim",
                    boundary: "fails before existing installation replacement"
                },
                {
                    reason: "installer-replacement-failed",
                    boundary: "restores existing installation before returning failure"
                }
            ],
            managedSandboxLauncherStdoutLimitation: {
                status: "documented",
                summary: "Generated release launcher execution can emit blank stdout inside the managed sandbox; authoritative executable validation is the post-build release check harness outside that limitation."
            }
        }
    };
    node_fs_1.default.writeFileSync(reportPath, `${JSON.stringify(report, null, 2)}\n`, "utf8");
    return {
        status: "written",
        reportPath,
        reportPathRelative
    };
}
function resolveExistingReleaseValidationInputs(options) {
    if (options.version === null ||
        options.outputState.versionDirectory === null ||
        options.outputState.versionDirectoryRelative === null) {
        return null;
    }
    const versionDirectory = options.outputState.versionDirectory;
    const stagingArtifactRoot = node_path_1.default.join(versionDirectory, "staging");
    const stagedExecutable = node_path_1.default.join(stagingArtifactRoot, "bin", options.commandName);
    const bundledManifestPath = node_path_1.default.join(versionDirectory, "download-bundle", "release-manifest.json");
    const manifestPath = node_fs_1.default.existsSync(bundledManifestPath)
        ? bundledManifestPath
        : node_path_1.default.join(versionDirectory, "release-manifest.json");
    if (!node_fs_1.default.existsSync(stagedExecutable) && !node_fs_1.default.existsSync(manifestPath)) {
        return null;
    }
    if (!node_fs_1.default.existsSync(stagedExecutable)) {
        throw (0, errors_1.createUsageError)("Release check requires the staged executable produced by release build.", [
            "Reason: release-check-staged-executable-missing",
            `Expected executable: ${toReleaseValidationPath(stagedExecutable, options.repositoryRoot)}`,
            "Recovery: run release build before release check, or repair the staged release payload.",
            "Exit behavior: exits before successful release validation is reported."
        ]);
    }
    if (!node_fs_1.default.existsSync(manifestPath)) {
        throw (0, errors_1.createUsageError)("Release check requires the release manifest produced by release build.", [
            "Reason: release-check-manifest-missing",
            `Expected manifest: ${toReleaseValidationPath(manifestPath, options.repositoryRoot)}`,
            "Recovery: run release build before release check, or repair the release manifest.",
            "Exit behavior: exits before successful release validation is reported."
        ]);
    }
    const manifest = readExistingReleaseManifest(manifestPath, options.repositoryRoot);
    const archiveArtifacts = manifest.artifacts
        .filter(isReleaseArchiveManifestArtifact)
        .sort((a, b) => a.target.localeCompare(b.target));
    if (archiveArtifacts.length !== 2) {
        throw (0, errors_1.createUsageError)("Release check requires macOS/Linux and Windows archive records in the release manifest.", [
            "Reason: release-check-archive-manifest-records-missing",
            `Manifest: ${toReleaseValidationPath(manifestPath, options.repositoryRoot)}`,
            `Archive records: ${archiveArtifacts.map((artifact) => artifact.target).join(", ") || "(none)"}`,
            "Recovery: rerun release build so the manifest records both archive targets.",
            "Exit behavior: exits before successful release validation is reported."
        ]);
    }
    const archivePayloads = {
        status: "created",
        rootDirectory: `${options.outputState.versionDirectoryRelative}/archive-payloads`,
        targets: archiveArtifacts.map((artifact) => {
            const rootDirectoryName = stripReleaseArchiveExtension(artifact.filename);
            const payloadDirectory = `${options.outputState.versionDirectoryRelative}/archive-payloads/${rootDirectoryName}`;
            const payloadDirectoryAbsolute = node_path_1.default.join(options.repositoryRoot, ...payloadDirectory.split("/"));
            return {
                target: artifact.target,
                runtimeModel: artifact.runtimeModel,
                rootDirectoryName,
                payloadDirectory,
                archiveFilename: artifact.filename,
                archivePath: artifact.path,
                launcherPaths: artifact.target === "macos-linux"
                    ? [`bin/${options.commandName}`]
                    : [`bin/${options.commandName}.cmd`, `bin/${options.commandName}.ps1`],
                files: node_fs_1.default.existsSync(payloadDirectoryAbsolute)
                    ? collectRelativeFilePaths(payloadDirectoryAbsolute)
                    : [],
                validation: null
            };
        })
    };
    return {
        version: options.version,
        versionDirectory,
        stagingArtifactRoot,
        stagedExecutable,
        archivePayloads
    };
}
function readExistingReleaseManifest(manifestPath, repositoryRoot) {
    try {
        return JSON.parse(node_fs_1.default.readFileSync(manifestPath, "utf8"));
    }
    catch (error) {
        throw (0, errors_1.createUsageError)("Release check requires a parseable release manifest.", [
            "Reason: release-check-manifest-unparseable",
            `Manifest: ${toReleaseValidationPath(manifestPath, repositoryRoot)}`,
            `Error: ${error instanceof Error ? error.message : String(error)}`,
            "Recovery: rerun release build so the manifest is regenerated.",
            "Exit behavior: exits before successful release validation is reported."
        ]);
    }
}
function isReleaseArchiveManifestArtifact(artifact) {
    return artifact.kind === "archive" && (artifact.target === "macos-linux" || artifact.target === "windows");
}
function stripReleaseArchiveExtension(filename) {
    if (filename.endsWith(".tar.gz")) {
        return filename.slice(0, -".tar.gz".length);
    }
    if (filename.endsWith(".zip")) {
        return filename.slice(0, -".zip".length);
    }
    return filename;
}
function collectRelativeFilePaths(rootDirectory) {
    const files = [];
    const visit = (directory) => {
        for (const entry of node_fs_1.default.readdirSync(directory, { withFileTypes: true })) {
            const entryPath = node_path_1.default.join(directory, entry.name);
            if (entry.isDirectory()) {
                visit(entryPath);
                continue;
            }
            if (entry.isFile()) {
                files.push(node_path_1.default.relative(rootDirectory, entryPath).split(node_path_1.default.sep).join("/"));
            }
        }
    };
    visit(rootDirectory);
    return files.sort();
}
function validateReleaseArchiveExecution(options) {
    const tempRoot = node_fs_1.default.mkdtempSync(node_path_1.default.join(options.versionDirectory, "archive-validation-"));
    const requiredFiles = [
        "dist/cli/index.js",
        "package.json",
        ".day-shift-release.json",
        "INSTALL.md",
        "release-notes.md",
        ...options.target.launcherPaths
    ];
    let result = null;
    try {
        extractReleaseArchive({
            archivePath: node_path_1.default.join(options.repositoryRoot, ...options.target.archivePath.split("/")),
            destinationDirectory: tempRoot,
            target: options.target.target
        });
        const roots = node_fs_1.default.readdirSync(tempRoot, { withFileTypes: true })
            .filter((entry) => entry.isDirectory())
            .map((entry) => entry.name)
            .sort();
        if (roots.length !== 1 || roots[0] !== options.target.rootDirectoryName) {
            throw (0, errors_1.createUsageError)("Release archive validation requires exactly one expected payload root directory.", [
                "Reason: archive-unpack-root-mismatch",
                `Archive: ${options.target.archivePath}`,
                `Expected root: ${options.target.rootDirectoryName}`,
                `Found roots: ${roots.length === 0 ? "(none)" : roots.join(", ")}`,
                "Recovery: regenerate release archives with the expected root directory layout.",
                "Exit behavior: exits before successful-release state is recorded."
            ]);
        }
        const artifactRoot = node_path_1.default.join(tempRoot, options.target.rootDirectoryName);
        const missingFiles = requiredFiles.filter((filePath) => !node_fs_1.default.existsSync(node_path_1.default.join(artifactRoot, ...filePath.split("/"))));
        if (missingFiles.length > 0) {
            throw (0, errors_1.createUsageError)("Release archive validation requires expected runtime files after unpacking.", [
                "Reason: archive-unpack-layout-missing-files",
                `Archive: ${options.target.archivePath}`,
                `Missing files: ${missingFiles.join(", ")}`,
                "Recovery: regenerate release archives with the expected runtime layout.",
                "Exit behavior: exits before successful-release state is recorded."
            ]);
        }
        result = {
            status: "passed",
            target: options.target.target,
            archivePath: options.target.archivePath,
            rootDirectoryName: options.target.rootDirectoryName,
            temporaryRoot: tempRoot,
            requiredFiles,
            missingFiles: [],
            execution: options.target.target === "macos-linux"
                ? validateReleaseExecutable({
                    executable: node_path_1.default.join(artifactRoot, "bin", options.commandName),
                    artifactRoot,
                    repositoryRoot: options.repositoryRoot,
                    versionDirectory: options.versionDirectory,
                    version: options.version,
                    commandName: options.commandName
                })
                : null,
            executionSkippedReason: options.target.target === "macos-linux"
                ? null
                : "Windows archive execution requires a Windows command shell; layout is validated on this runner."
        };
    }
    finally {
        node_fs_1.default.rmSync(tempRoot, { recursive: true, force: true });
    }
    if (result === null) {
        throw (0, errors_1.createUsageError)("Release archive validation did not produce execution evidence.", [
            "Reason: archive-validation-missing-result",
            `Archive: ${options.target.archivePath}`,
            "Recovery: rerun release build after regenerating archive validation.",
            "Exit behavior: exits before successful-release state is recorded."
        ]);
    }
    return {
        ...result,
        temporaryCleaned: !node_fs_1.default.existsSync(tempRoot)
    };
}
function validateReleaseExecutable(options) {
    const validationScratchRoot = node_fs_1.default.mkdtempSync(node_path_1.default.join(options.versionDirectory, "validation-scratch-"));
    const isolatedEnvironment = {
        stateDir: node_fs_1.default.mkdtempSync(node_path_1.default.join(validationScratchRoot, "day-shift-release-validation-state-")),
        configHome: node_fs_1.default.mkdtempSync(node_path_1.default.join(validationScratchRoot, "day-shift-release-validation-config-")),
        licenseFile: node_path_1.default.join(node_fs_1.default.mkdtempSync(node_path_1.default.join(validationScratchRoot, "day-shift-release-validation-license-")), "license.json")
    };
    const commandSpecs = [
        { name: "help", args: ["--help"], format: "human" },
        { name: "version", args: ["--version"], format: "human" },
        { name: "about", args: ["about"], format: "human" },
        { name: "about-json", args: ["about", "--format", "json"], format: "json" }
    ];
    const outputs = new Map();
    let usedNodeEntrypointFallback = false;
    let validation = null;
    try {
        const commands = commandSpecs.map((spec) => {
            const result = runReleaseValidationCommand({
                executable: options.executable,
                artifactRoot: options.artifactRoot,
                args: spec.args,
                isolatedEnvironment,
                validationScratchRoot
            });
            usedNodeEntrypointFallback ||= result.usedNodeEntrypointFallback;
            outputs.set(spec.name, result.stdout);
            return {
                name: spec.name,
                args: [...spec.args],
                format: spec.format,
                status: "passed",
                exitCode: 0,
                stdoutSummary: summarizeCommandOutput(result.stdout)
            };
        });
        const versionOutput = outputs.get("version")?.trim() ?? "";
        const aboutOutput = outputs.get("about") ?? "";
        const aboutJsonOutput = outputs.get("about-json") ?? "";
        const aboutJson = parseAboutJson(aboutJsonOutput);
        const acceptedArtifactRoots = new Set([
            options.artifactRoot,
            (0, output_safety_1.sanitizeOutputText)(options.artifactRoot, { repositoryRoot: options.repositoryRoot }),
            (0, output_safety_1.sanitizeOutputText)(options.artifactRoot, { repositoryRoot: options.artifactRoot })
        ]);
        const sourceCheckoutPathPresent = [aboutOutput, aboutJsonOutput]
            .some((output) => output.split(options.artifactRoot).join("").includes(options.repositoryRoot));
        if (versionOutput !== options.version) {
            throw (0, errors_1.createUsageError)("Release validation expected packaged --version output to match release metadata.", [
                "Reason: release-runtime-version-mismatch",
                `Executable: ${options.executable}`,
                `Expected version: ${options.version}`,
                `Received version: ${versionOutput}`,
                "Recovery: ensure packaged runtime metadata is read from the release artifact.",
                "Exit behavior: exits before successful-release state is recorded."
            ]);
        }
        if (aboutJson.status !== "ok" ||
            aboutJson.command !== "about" ||
            aboutJson.data?.release?.version !== options.version ||
            aboutJson.data?.release?.installedCommandName !== options.commandName ||
            typeof aboutJson.data?.runtime?.artifactRoot !== "string" ||
            !acceptedArtifactRoots.has(aboutJson.data.runtime.artifactRoot) ||
            aboutJson.data?.runtime?.entrypoint !== "dist/cli/index.js") {
            throw (0, errors_1.createUsageError)("Release validation expected packaged about JSON to report artifact-relative runtime metadata.", [
                "Reason: release-runtime-diagnostic-mismatch",
                `Executable: ${options.executable}`,
                "Recovery: ensure packaged about output reads release metadata and reports artifact-relative runtime paths.",
                "Exit behavior: exits before successful-release state is recorded."
            ]);
        }
        if (!aboutOutput.includes(`Release version: ${options.version}`) ||
            !aboutOutput.includes(`Installed command: ${options.commandName}`) ||
            !aboutOutput.includes("Entrypoint: dist/cli/index.js") ||
            sourceCheckoutPathPresent) {
            throw (0, errors_1.createUsageError)("Release validation expected packaged about text to report artifact runtime metadata without source checkout paths.", [
                "Reason: release-runtime-diagnostic-text-mismatch",
                `Executable: ${options.executable}`,
                "Recovery: ensure packaged about text uses release metadata and artifact-relative paths.",
                "Exit behavior: exits before successful-release state is recorded."
            ]);
        }
        validation = {
            status: "passed",
            executable: toReleaseValidationPath(options.executable, options.repositoryRoot),
            invocationMethod: usedNodeEntrypointFallback ? "posix-shell-with-node-entrypoint-fallback" : "posix-shell",
            artifactRoot: toReleaseValidationPath(options.artifactRoot, options.repositoryRoot),
            commands,
            diagnostics: {
                status: "passed",
                version: options.version,
                installedCommandName: options.commandName,
                artifactRoot: toReleaseValidationPath(options.artifactRoot, options.repositoryRoot),
                entrypoint: aboutJson.data.runtime.entrypoint,
                commandRegistry: aboutJson.data.runtime.commandRegistry,
                sourceCheckoutPathPresent,
                jsonOutput: true,
                humanOutput: true
            },
            validationScratchRoot: toReleaseValidationPath(validationScratchRoot, options.repositoryRoot),
            isolatedEnvironment: {
                stateDir: toReleaseValidationPath(isolatedEnvironment.stateDir, options.repositoryRoot),
                configHome: toReleaseValidationPath(isolatedEnvironment.configHome, options.repositoryRoot),
                licenseFile: toReleaseValidationPath(isolatedEnvironment.licenseFile, options.repositoryRoot)
            }
        };
    }
    finally {
        node_fs_1.default.rmSync(validationScratchRoot, { recursive: true, force: true });
    }
    if (validation === null) {
        throw (0, errors_1.createUsageError)("Release validation did not produce packaged command evidence.", [
            "Reason: release-runtime-validation-missing-result",
            `Executable: ${options.executable}`,
            "Recovery: rerun release check after regenerating the staged release payload.",
            "Exit behavior: exits before successful-release state is recorded."
        ]);
    }
    return {
        ...validation,
        validationScratchCleaned: !node_fs_1.default.existsSync(validationScratchRoot)
    };
}
function runReleaseValidationCommand(options) {
    const env = {
        ...process.env,
        DAY_SHIFT_REPOSITORY_ROOT: options.artifactRoot,
        DAY_SHIFT_STATE_DIR: options.isolatedEnvironment.stateDir,
        XDG_CONFIG_HOME: options.isolatedEnvironment.configHome,
        DAY_SHIFT_LICENSE_FILE: options.isolatedEnvironment.licenseFile
    };
    const stdout = captureReleaseValidationStdout("sh", [options.executable, ...options.args], {
        cwd: options.artifactRoot,
        env,
        validationScratchRoot: options.validationScratchRoot
    });
    if (stdout.trim().length > 0) {
        return {
            stdout,
            usedNodeEntrypointFallback: false
        };
    }
    return {
        stdout: captureReleaseValidationStdout(process.execPath, [node_path_1.default.join(options.artifactRoot, "dist", "cli", "index.js"), ...options.args], {
            cwd: options.artifactRoot,
            env,
            validationScratchRoot: options.validationScratchRoot
        }),
        usedNodeEntrypointFallback: true
    };
}
function captureReleaseValidationStdout(command, args, options) {
    const outputDirectory = node_fs_1.default.mkdtempSync(node_path_1.default.join(options.validationScratchRoot, "day-shift-release-validation-stdout-"));
    const outputPath = node_path_1.default.join(outputDirectory, "stdout.txt");
    const outputFd = node_fs_1.default.openSync(outputPath, "w");
    try {
        const result = (0, node_child_process_1.spawnSync)(command, args, {
            cwd: options.cwd,
            encoding: "utf8",
            env: options.env,
            stdio: ["ignore", outputFd, "pipe"]
        });
        if (result.error !== undefined) {
            throw result.error;
        }
        if (result.status !== 0) {
            throw (0, errors_1.createUsageError)("Release validation command failed.", [
                "Reason: release-validation-command-failed",
                `Command: ${[command, ...args].join(" ")}`,
                `Exit code: ${result.status ?? "unknown"}`,
                `Stderr: ${typeof result.stderr === "string" && result.stderr.trim().length > 0 ? summarizeCommandOutput(result.stderr) : "(empty)"}`,
                "Recovery: inspect the packaged release command and rerun release check.",
                "Exit behavior: exits before successful-release state is recorded."
            ]);
        }
        node_fs_1.default.closeSync(outputFd);
        return node_fs_1.default.readFileSync(outputPath, "utf8");
    }
    finally {
        try {
            node_fs_1.default.closeSync(outputFd);
        }
        catch {
            // The descriptor may already be closed after a successful command.
        }
        node_fs_1.default.rmSync(outputDirectory, { recursive: true, force: true });
    }
}
function extractReleaseArchive(options) {
    if (options.target === "macos-linux") {
        extractTarGzipArchive(options.archivePath, options.destinationDirectory);
        return;
    }
    extractStoredZipArchive(options.archivePath, options.destinationDirectory);
}
function extractTarGzipArchive(archivePath, destinationDirectory) {
    const tar = node_zlib_1.default.gunzipSync(node_fs_1.default.readFileSync(archivePath));
    let offset = 0;
    while (offset + 512 <= tar.length) {
        const header = tar.subarray(offset, offset + 512);
        if (header.every((byte) => byte === 0)) {
            break;
        }
        const name = readTarString(header, 0, 100);
        const prefix = readTarString(header, 345, 155);
        const entryName = prefix.length > 0 ? `${prefix}/${name}` : name;
        const mode = Number.parseInt(readTarString(header, 100, 8).trim() || "644", 8);
        const size = Number.parseInt(readTarString(header, 124, 12).trim() || "0", 8);
        const fileStart = offset + 512;
        const fileEnd = fileStart + size;
        const destinationPath = resolveArchiveDestination(destinationDirectory, entryName);
        node_fs_1.default.mkdirSync(node_path_1.default.dirname(destinationPath), { recursive: true });
        node_fs_1.default.writeFileSync(destinationPath, tar.subarray(fileStart, fileEnd));
        node_fs_1.default.chmodSync(destinationPath, mode);
        offset = fileEnd + ((512 - (size % 512)) % 512);
    }
}
function extractStoredZipArchive(archivePath, destinationDirectory) {
    const zip = node_fs_1.default.readFileSync(archivePath);
    let offset = 0;
    while (offset + 30 <= zip.length && zip.readUInt32LE(offset) === 0x04034b50) {
        const compressionMethod = zip.readUInt16LE(offset + 8);
        const compressedSize = zip.readUInt32LE(offset + 18);
        const uncompressedSize = zip.readUInt32LE(offset + 22);
        const fileNameLength = zip.readUInt16LE(offset + 26);
        const extraLength = zip.readUInt16LE(offset + 28);
        const nameStart = offset + 30;
        const dataStart = nameStart + fileNameLength + extraLength;
        const dataEnd = dataStart + compressedSize;
        const entryName = zip.subarray(nameStart, nameStart + fileNameLength).toString("utf8");
        if (compressionMethod !== 0 || compressedSize !== uncompressedSize) {
            throw (0, errors_1.createUsageError)("Release archive validation only supports stored ZIP entries from the deterministic archive writer.", [
                "Reason: unsupported-zip-compression",
                `Archive: ${archivePath}`,
                "Recovery: update archive validation when ZIP compression is introduced.",
                "Exit behavior: exits before successful-release state is recorded."
            ]);
        }
        const destinationPath = resolveArchiveDestination(destinationDirectory, entryName);
        node_fs_1.default.mkdirSync(node_path_1.default.dirname(destinationPath), { recursive: true });
        node_fs_1.default.writeFileSync(destinationPath, zip.subarray(dataStart, dataEnd));
        offset = dataEnd;
    }
}
function parseAboutJson(output) {
    try {
        return JSON.parse(output);
    }
    catch {
        throw (0, errors_1.createUsageError)("Release validation expected about JSON output to be parseable.", [
            "Reason: release-runtime-about-json-unparseable",
            `Output: ${summarizeCommandOutput(output)}`,
            "Recovery: ensure packaged about output still supports --format json.",
            "Exit behavior: exits before successful-release state is recorded."
        ]);
    }
}
function readTarString(buffer, offset, length) {
    const end = buffer.indexOf(0, offset);
    const sliceEnd = end === -1 || end > offset + length ? offset + length : end;
    return buffer.subarray(offset, sliceEnd).toString("utf8").trim();
}
function resolveArchiveDestination(root, entryName) {
    const destinationPath = node_path_1.default.resolve(root, ...entryName.split("/"));
    const resolvedRoot = node_path_1.default.resolve(root);
    if (destinationPath !== resolvedRoot && !destinationPath.startsWith(`${resolvedRoot}${node_path_1.default.sep}`)) {
        throw (0, errors_1.createUsageError)("Release archive validation rejected an unsafe archive entry path.", [
            "Reason: archive-entry-outside-validation-root",
            `Entry: ${entryName}`,
            "Recovery: regenerate release archives without absolute or parent-traversing entries.",
            "Exit behavior: exits before successful-release state is recorded."
        ]);
    }
    return destinationPath;
}
function summarizeCommandOutput(output) {
    return output.replace(/\s+/g, " ").trim().slice(0, 160);
}
function toReleaseValidationPath(value, repositoryRoot) {
    const relative = node_path_1.default.relative(repositoryRoot, value).split(node_path_1.default.sep).join("/");
    return relative.length > 0 && !relative.startsWith("..")
        ? relative
        : value;
}
function resolveReleaseBuildPreflight(options) {
    if (options.releaseSubcommand.name !== "build") {
        return {
            required: false,
            status: "not-applicable",
            steps: [],
            testReceipt: createNotApplicableTestReceiptEvidence(),
            dist: createNotApplicableDistEvidence()
        };
    }
    if (options.dryRun) {
        return {
            required: true,
            status: "skipped-dry-run",
            steps: createReleaseBuildPreflightSteps().map((step) => ({
                ...step,
                status: "skipped-dry-run"
            })),
            testReceipt: createSkippedTestReceiptEvidence(),
            dist: createSkippedDistEvidence()
        };
    }
    return runReleaseBuildPreflight({
        repositoryRoot: options.repositoryRoot
    });
}
function runReleaseBuildPreflight(options) {
    const completedSteps = [];
    let testReceipt = createNotApplicableTestReceiptEvidence();
    for (const step of createReleaseBuildPreflightSteps()) {
        try {
            if (step.name === "repository tests") {
                const before = inspectReleaseTestReceipt(options.repositoryRoot);
                if (before.applicable && before.evidence.receiptStatus === "complete") {
                    testReceipt = {
                        ...before.evidence,
                        status: "reused",
                        suiteExecutions: 0,
                        reason: "verified-complete-receipt"
                    };
                }
                else {
                    runPackageScript(options.repositoryRoot, step.scriptName);
                    const after = inspectReleaseTestReceipt(options.repositoryRoot);
                    if (before.applicable && after.evidence.receiptStatus !== "complete") {
                        throw new Error("Configured V2 suite did not produce a verified complete current receipt.");
                    }
                    testReceipt = before.applicable
                        ? createExecutedTestReceiptEvidence(before.evidence, after.evidence)
                        : {
                            ...before.evidence,
                            status: "executed",
                            suiteExecutions: 1,
                            reason: "non-v2-test-script"
                        };
                }
            }
            else {
                runPackageScript(options.repositoryRoot, step.scriptName);
            }
            completedSteps.push({
                ...step,
                status: "passed"
            });
        }
        catch (error) {
            throw (0, errors_1.createUsageError)(`Release build preflight failed during ${step.name}.`, [
                `Command: ${step.command.join(" ")}`,
                `Reason: ${step.name} failed`,
                `Recovery: fix the failing ${step.name} command and rerun release build.`,
                "Exit behavior: exits before generated release output directories or artifacts are created.",
                ...formatPreflightFailureOutput(error)
            ]);
        }
    }
    const distAfterBuild = readDistPayloadEvidence(options.repositoryRoot, "fresh");
    assertFreshDistPayload(distAfterBuild);
    return {
        required: true,
        status: "passed",
        steps: completedSteps,
        testReceipt,
        dist: distAfterBuild
    };
}
function createReleaseBuildPreflightSteps() {
    return [
        {
            name: "repository verification",
            scriptName: "check",
            command: ["pnpm", "run", "check"],
            status: "passed"
        },
        {
            name: "repository tests",
            scriptName: "test",
            command: ["pnpm", "run", "test"],
            status: "passed"
        },
        {
            name: "production build",
            scriptName: "build",
            command: ["pnpm", "run", "build"],
            status: "passed"
        }
    ];
}
function inspectReleaseTestReceipt(repositoryRoot) {
    const packageJson = JSON.parse(node_fs_1.default.readFileSync(node_path_1.default.join(repositoryRoot, "package.json"), "utf8"));
    const testScript = packageJson.scripts?.test;
    if (typeof testScript !== "string" || !isDefaultV2TestScript(testScript)) {
        return { applicable: false, evidence: createNotApplicableTestReceiptEvidence() };
    }
    const testsRoot = node_path_1.default.join(repositoryRoot, "tests_v2");
    const testFiles = node_fs_1.default.existsSync(testsRoot)
        ? collectFiles(testsRoot)
            .filter((filePath) => filePath.endsWith(".test.js"))
            .map((filePath) => node_path_1.default.relative(repositoryRoot, filePath).split(node_path_1.default.sep).join("/"))
            .sort((left, right) => left.localeCompare(right, "en"))
        : [];
    const authorityPath = node_path_1.default.join(repositoryRoot, "scripts", "lib", "v2-test-receipts.js");
    if (testFiles.length === 0 || !node_fs_1.default.existsSync(authorityPath)) {
        return {
            applicable: true,
            evidence: createInvalidTestReceiptEvidence(testFiles.length, "receipt-authority-unavailable")
        };
    }
    try {
        const authority = (0, node_module_1.createRequire)(node_path_1.default.join(repositoryRoot, "package.json"))(authorityPath);
        const result = authority.verifyCompleteReceipt({
            repositoryRoot,
            testFiles,
            scope: { label: "tests_v2" }
        });
        return {
            applicable: true,
            evidence: {
                status: "not-applicable",
                receiptStatus: result.inspection.status,
                suiteIdentity: result.context.suiteIdentity,
                suiteExecutions: 0,
                reason: `receipt-${result.inspection.status}`,
                counters: { ...result.inspection.counters }
            }
        };
    }
    catch {
        return {
            applicable: true,
            evidence: createInvalidTestReceiptEvidence(testFiles.length, "receipt-verification-failed")
        };
    }
}
function isDefaultV2TestScript(script) {
    const commands = splitPackageScriptCommands(script);
    if (commands.length !== 1)
        return false;
    const args = tokenizePackageScriptCommand(commands[0]);
    if (args[0] !== "node" || args[1]?.split(node_path_1.default.sep).join("/") !== "scripts/run-v2-test-files.js")
        return false;
    return args.slice(2).every((arg) => ["--resume", "--keep-sandbox", "--verbose"].includes(arg));
}
function createExecutedTestReceiptEvidence(before, after) {
    const selected = after.counters.selected || before.counters.selected;
    return {
        status: "executed",
        receiptStatus: after.receiptStatus,
        suiteIdentity: after.suiteIdentity,
        suiteExecutions: 1,
        reason: `recovered-from-${before.receiptStatus}`,
        counters: {
            selected,
            reused: before.counters.reused,
            executed: Math.max(0, selected - before.counters.reused),
            invalidated: before.counters.invalidated,
            remaining: after.counters.remaining
        }
    };
}
function createInvalidTestReceiptEvidence(selected, reason) {
    return {
        status: "not-applicable",
        receiptStatus: "invalid",
        suiteIdentity: null,
        suiteExecutions: 0,
        reason,
        counters: { selected, reused: 0, executed: 0, invalidated: 0, remaining: selected }
    };
}
function createSkippedTestReceiptEvidence() {
    return {
        ...createNotApplicableTestReceiptEvidence(),
        status: "skipped-dry-run",
        reason: "release-dry-run"
    };
}
function createNotApplicableTestReceiptEvidence() {
    return {
        status: "not-applicable",
        receiptStatus: "not-applicable",
        suiteIdentity: null,
        suiteExecutions: 0,
        reason: "not-applicable",
        counters: { selected: 0, reused: 0, executed: 0, invalidated: 0, remaining: 0 }
    };
}
function runPackageScript(repositoryRoot, scriptName, seenScripts = []) {
    if (seenScripts.includes(scriptName)) {
        throw new Error(`Recursive package script invocation: ${[...seenScripts, scriptName].join(" -> ")}`);
    }
    const packageJson = JSON.parse(node_fs_1.default.readFileSync(node_path_1.default.join(repositoryRoot, "package.json"), "utf8"));
    const script = packageJson.scripts?.[scriptName];
    if (typeof script !== "string" || script.trim().length === 0) {
        throw new Error(`Missing package script: ${scriptName}`);
    }
    for (const command of splitPackageScriptCommands(script)) {
        runPackageScriptCommand(repositoryRoot, command, [...seenScripts, scriptName]);
    }
}
function readDistPayloadEvidence(repositoryRoot, fallbackStatus) {
    const distPath = node_path_1.default.join(repositoryRoot, "dist");
    const requiredEntrypoint = "dist/cli/index.js";
    if (!node_fs_1.default.existsSync(distPath) || !node_fs_1.default.statSync(distPath).isDirectory()) {
        return {
            status: "missing",
            path: "dist",
            requiredEntrypoint,
            requiredEntrypointPresent: false,
            fileCount: 0,
            manifestPath: null,
            manifestDigest: null,
            distributionIdentity: null,
            freshnessReason: "dist-missing"
        };
    }
    const files = collectFiles(distPath);
    const manifest = (0, build_input_manifest_1.inspectBuildInputManifest)(repositoryRoot);
    const status = manifest.status === "current"
        ? fallbackStatus
        : manifest.status === "malformed" || manifest.status === "unknown"
            ? "incompatible"
            : manifest.status;
    return {
        status,
        path: "dist",
        requiredEntrypoint,
        requiredEntrypointPresent: node_fs_1.default.existsSync(node_path_1.default.join(repositoryRoot, requiredEntrypoint)),
        fileCount: files.length,
        manifestPath: manifest.manifestPath,
        manifestDigest: manifest.aggregateDigest,
        distributionIdentity: manifest.distributionIdentity,
        freshnessReason: manifest.reason
    };
}
function collectFiles(directoryPath) {
    const files = [];
    for (const entry of node_fs_1.default.readdirSync(directoryPath, { withFileTypes: true })) {
        const entryPath = node_path_1.default.join(directoryPath, entry.name);
        if (entry.isDirectory()) {
            files.push(...collectFiles(entryPath));
        }
        else if (entry.isFile()) {
            files.push(entryPath);
        }
    }
    return files;
}
function assertFreshDistPayload(evidence) {
    if (evidence.fileCount === 0) {
        evidence.status = "missing";
        throw (0, errors_1.createUsageError)("Release build dist payload is missing after production build.", [
            "Reason: missing-dist",
            "Recovery: fix the production build so it emits compiled files under dist/.",
            "Exit behavior: exits before generated release output directories or artifacts are created."
        ]);
    }
    if (!evidence.requiredEntrypointPresent) {
        evidence.status = "incompatible";
        throw (0, errors_1.createUsageError)("Release build dist payload is inconsistent after production build.", [
            "Reason: dist-entrypoint-missing",
            `Required entrypoint: ${evidence.requiredEntrypoint}`,
            "Recovery: fix the production build so dist/ contains the compiled CLI entrypoint.",
            "Exit behavior: exits before generated release output directories or artifacts are created."
        ]);
    }
    if (evidence.status !== "fresh") {
        throw (0, errors_1.createUsageError)(`Release build dist payload is ${evidence.status} after production build.`, [
            `Reason: ${evidence.freshnessReason ?? "build-input-manifest-unverifiable"}`,
            `Manifest: ${evidence.manifestPath ?? "(none)"}`,
            `Manifest digest: ${evidence.manifestDigest ?? "(none)"}`,
            "Recovery: run the production build that emits a manifest matching current inputs and compiled dist output.",
            "Exit behavior: exits before generated release output directories or artifacts are created."
        ]);
    }
}
function createSkippedDistEvidence() {
    return {
        status: "skipped-dry-run",
        path: "dist",
        requiredEntrypoint: "dist/cli/index.js",
        requiredEntrypointPresent: false,
        fileCount: 0,
        manifestPath: null,
        manifestDigest: null,
        distributionIdentity: null,
        freshnessReason: null
    };
}
function createNotApplicableDistEvidence() {
    return {
        status: "not-applicable",
        path: null,
        requiredEntrypoint: null,
        requiredEntrypointPresent: false,
        fileCount: 0,
        manifestPath: null,
        manifestDigest: null,
        distributionIdentity: null,
        freshnessReason: null
    };
}
function splitPackageScriptCommands(script) {
    return script
        .split("&&")
        .map((command) => command.trim())
        .filter((command) => command.length > 0);
}
function runPackageScriptCommand(repositoryRoot, command, seenScripts) {
    const args = tokenizePackageScriptCommand(command);
    const executable = args[0];
    if (executable === "node") {
        runInlineNodeCommand(repositoryRoot, args.slice(1));
        return;
    }
    if (executable === "pnpm" && args[1] === "run" && typeof args[2] === "string") {
        runPackageScript(repositoryRoot, args[2], seenScripts);
        return;
    }
    if (executable === "tsc") {
        (0, node_child_process_1.execFileSync)(process.execPath, [require.resolve("typescript/bin/tsc"), ...args.slice(1)], {
            cwd: repositoryRoot,
            encoding: "utf8",
            stdio: "pipe",
            env: process.env
        });
        return;
    }
    throw new Error(`Unsupported release preflight package-script command: ${command}`);
}
function runInlineNodeCommand(repositoryRoot, args) {
    if (args[0] !== "-e" || typeof args[1] !== "string") {
        runLocalNodeScriptCommand(repositoryRoot, args);
        return;
    }
    const previousCwd = process.cwd();
    const previousExit = process.exit;
    try {
        process.chdir(repositoryRoot);
        process.exit = ((code) => {
            const normalizedCode = typeof code === "number" ? code : Number(code ?? 0);
            const exitError = new Error(`Inline node command exited with code ${normalizedCode}`);
            exitError.status = normalizedCode;
            throw exitError;
        });
        try {
            // Execute release preflight package scripts in-process so sandboxed test repositories do not need child-process execution permission.
            new Function("require", "process", "console", args[1])(require, process, console);
        }
        catch (error) {
            if (typeof error.status === "number" && error.status === 0) {
                return;
            }
            throw error;
        }
    }
    finally {
        process.exit = previousExit;
        process.chdir(previousCwd);
    }
}
function runLocalNodeScriptCommand(repositoryRoot, args) {
    const scriptPath = args[0];
    if (typeof scriptPath !== "string" || scriptPath.trim().length === 0) {
        throw new Error(`Unsupported release preflight node command: node ${args.join(" ")}`);
    }
    if (scriptPath.startsWith("-")) {
        throw new Error(`Unsupported release preflight node command: node ${args.join(" ")}`);
    }
    const resolvedScriptPath = node_path_1.default.resolve(repositoryRoot, scriptPath);
    const relativeScriptPath = node_path_1.default.relative(repositoryRoot, resolvedScriptPath);
    if (relativeScriptPath === "" ||
        relativeScriptPath === ".." ||
        relativeScriptPath.startsWith(`..${node_path_1.default.sep}`) ||
        node_path_1.default.isAbsolute(relativeScriptPath)) {
        throw new Error(`Unsupported release preflight node script outside repository: ${scriptPath}`);
    }
    if (!node_fs_1.default.existsSync(resolvedScriptPath) || !node_fs_1.default.statSync(resolvedScriptPath).isFile()) {
        throw new Error(`Unsupported release preflight node script missing: ${scriptPath}`);
    }
    (0, node_child_process_1.execFileSync)(process.execPath, [resolvedScriptPath, ...args.slice(1)], {
        cwd: repositoryRoot,
        env: process.env,
        stdio: "inherit"
    });
}
function runNodeScriptInProcess(options) {
    const previousCwd = process.cwd();
    const previousArgv = process.argv;
    const previousExit = process.exit;
    try {
        process.chdir(options.repositoryRoot);
        process.argv = [process.execPath, options.scriptPath, ...options.args];
        process.exit = ((code) => {
            const normalizedCode = typeof code === "number" ? code : Number(code ?? 0);
            const exitError = new Error(`Node script exited with code ${normalizedCode}`);
            exitError.status = normalizedCode;
            throw exitError;
        });
        try {
            const scriptSource = stripNodeShebang(node_fs_1.default.readFileSync(options.scriptPath, "utf8"));
            const scriptModule = {
                exports: {}
            };
            new Function("require", "module", "exports", "process", "console", "__filename", "__dirname", scriptSource)((0, node_module_1.createRequire)(options.scriptPath), scriptModule, scriptModule.exports, process, console, options.scriptPath, node_path_1.default.dirname(options.scriptPath));
        }
        catch (error) {
            if (typeof error.status === "number" && error.status === 0) {
                return;
            }
            throw error;
        }
    }
    finally {
        process.exit = previousExit;
        process.argv = previousArgv;
        process.chdir(previousCwd);
    }
}
function stripNodeShebang(source) {
    if (!source.startsWith("#!")) {
        return source;
    }
    const lineBreakIndex = source.indexOf("\n");
    if (lineBreakIndex === -1) {
        return "";
    }
    return source.slice(lineBreakIndex + 1);
}
function tokenizePackageScriptCommand(command) {
    const tokens = [];
    let current = "";
    let quote = null;
    for (let index = 0; index < command.length; index += 1) {
        const character = command[index];
        if (quote !== null) {
            if (character === quote) {
                quote = null;
            }
            else if (character === "\\" &&
                quote === "\"" &&
                index + 1 < command.length &&
                ["\"", "\\", "$", "`"].includes(command[index + 1])) {
                index += 1;
                current += command[index];
            }
            else {
                current += character;
            }
            continue;
        }
        if (character === "\"" || character === "'") {
            quote = character;
            continue;
        }
        if (/\s/.test(character)) {
            if (current.length > 0) {
                tokens.push(current);
                current = "";
            }
            continue;
        }
        current += character;
    }
    if (quote !== null) {
        throw new Error(`Unterminated quote in package script command: ${command}`);
    }
    if (current.length > 0) {
        tokens.push(current);
    }
    return tokens;
}
function formatPreflightFailureOutput(error) {
    const output = [];
    const maybeOutput = error;
    if (typeof maybeOutput.message === "string" && maybeOutput.message.trim().length > 0) {
        output.push(`Error: ${maybeOutput.message.trim()}`);
    }
    if (typeof maybeOutput.status === "number") {
        output.push(`Exit code: ${maybeOutput.status}`);
    }
    if (typeof maybeOutput.stderr === "string" && maybeOutput.stderr.trim().length > 0) {
        output.push(`stderr: ${maybeOutput.stderr.trim()}`);
    }
    if (typeof maybeOutput.stdout === "string" && maybeOutput.stdout.trim().length > 0) {
        output.push(`stdout: ${maybeOutput.stdout.trim()}`);
    }
    return output;
}
function createUnavailableMarkerState() {
    return {
        present: false,
        valid: false,
        path: null,
        version: null,
        completedAt: null
    };
}
function resolveReleaseSuccessMarkerState(options) {
    if (options.releaseSubcommand.name === "build" &&
        !options.dryRun &&
        options.operation.changed) {
        return (0, output_lifecycle_1.writeReleaseSuccessMarker)({
            state: options.outputState,
            version: options.version,
            command: "release build"
        });
    }
    return (0, output_lifecycle_1.readReleaseSuccessMarker)(options.outputState);
}
function getRootCommand(commandInstance) {
    let current = commandInstance;
    while (current?.parent != null) {
        current = current.parent;
    }
    return current ?? commandInstance;
}
function addReleaseOptions(command, options) {
    if (options.includes("version")) {
        command
            .option("--release-version <version>", "Explicit release version for the local release surface.")
            .addHelpText("after", "  --version <version>  Alias for --release-version on release subcommands.");
    }
    if (options.includes("commandName")) {
        command.option("--command-name <name>", "Configured installed command basename used by release artifacts.", DEFAULT_INSTALLED_COMMAND_NAME);
    }
    if (options.includes("outputDir")) {
        command.option("--output-dir <path>", "Generated local release output root.");
    }
    if (options.includes("keep")) {
        command.option("--keep <count>", "Number of successful prior local release directories to keep.", "3");
    }
    if (options.includes("confirm")) {
        command.option("--confirm", "Acknowledge that future cleanup is an explicit generated-output cleanup operation.");
    }
    if (options.includes("dryRun")) {
        command.option("--dry-run", "Report the release command contract without generating, pruning, or deleting files.");
    }
    if (options.includes("dirty")) {
        command.option("--dirty", "Permit uncommitted local changes and route release build output to dirty-release/<version> by default.");
    }
}
function renderReleaseContractSummary(data) {
    return [
        (0, output_1.renderTerminalHeading)("Release command surface", "title"),
        (0, output_1.renderTerminalSection)({
            heading: "Contract",
            headingStyle: "section",
            fields: [
                { label: "Command", value: data.command },
                { label: "Mode", value: data.mode },
                { label: "Boundary", value: data.boundary },
                { label: "Release output root", value: data.output.releaseRootRelative },
                { label: "Version directory", value: data.output.versionDirectoryRelative ?? "(not applicable)" },
                { label: "Staging directory", value: data.output.stagingDirectoryRelative ?? "(not applicable)" },
                { label: "Success marker", value: data.successMarker.valid ? "present" : "not present" },
                { label: "Build preflight", value: data.buildPreflight.status },
                { label: "Test receipt", value: data.buildPreflight.testReceipt.status },
                { label: "Dist payload", value: data.buildPreflight.dist.status },
                { label: "Staging payload", value: data.stagingPayload.status },
                { label: "Archive payloads", value: data.archivePayloads.status },
                { label: "Installer assets", value: data.installerAssets.status },
                { label: "Checksums", value: data.artifactChecksums.status },
                { label: "Manifest", value: data.releaseManifest.status },
                { label: "Download bundle", value: data.downloadBundle.status },
                { label: "Installation README", value: data.installationReadme.status },
                { label: "Installer safety validation", value: data.installerSafetyValidation.status },
                { label: "Local release validation", value: data.localValidation.status },
                { label: "Local validation report", value: data.localValidationReport.status },
                { label: "Local output changed", value: data.operation.changed },
                { label: "Clean repository required", value: data.repositoryState.cleanRequired },
                { label: "Dirty release mode", value: data.repositoryState.dirtyAllowed },
                { label: "Dirty repository paths", value: data.repositoryState.dirtyPaths.length },
                { label: "Ignored generated output paths", value: data.repositoryState.ignoredGeneratedOutputPaths.length },
                { label: "Website upload", value: data.publication.websiteUpload },
                { label: "Public npm publication", value: data.publication.publicNpmPublication },
                { label: "Next implementation", value: data.nextImplementation }
            ]
        }),
        (0, output_1.renderTerminalCompactList)({
            heading: "Build preflight",
            headingStyle: "section",
            entries: data.buildPreflight.steps.length === 0
                ? [{ label: "not-applicable", fields: [{ label: "Required", value: data.buildPreflight.required }] }]
                : data.buildPreflight.steps.map((step) => ({
                    label: step.name,
                    fields: [
                        { label: "Status", value: step.status },
                        { label: "Command", value: step.command.join(" ") }
                    ]
                }))
        }),
        (0, output_1.renderTerminalSection)({
            heading: "Test receipt",
            headingStyle: "section",
            fields: [
                { label: "Status", value: data.buildPreflight.testReceipt.status },
                { label: "Receipt status", value: data.buildPreflight.testReceipt.receiptStatus },
                { label: "Suite identity", value: data.buildPreflight.testReceipt.suiteIdentity ?? "(not applicable)" },
                { label: "Suite executions", value: data.buildPreflight.testReceipt.suiteExecutions },
                { label: "Reason", value: data.buildPreflight.testReceipt.reason },
                { label: "Selected files", value: data.buildPreflight.testReceipt.counters.selected },
                { label: "Reused files", value: data.buildPreflight.testReceipt.counters.reused },
                { label: "Executed files", value: data.buildPreflight.testReceipt.counters.executed },
                { label: "Invalidated files", value: data.buildPreflight.testReceipt.counters.invalidated },
                { label: "Remaining files", value: data.buildPreflight.testReceipt.counters.remaining }
            ]
        }),
        (0, output_1.renderTerminalSection)({
            heading: "Dist payload",
            headingStyle: "section",
            fields: [
                { label: "Status", value: data.buildPreflight.dist.status },
                { label: "Path", value: data.buildPreflight.dist.path ?? "(not applicable)" },
                { label: "Required entrypoint", value: data.buildPreflight.dist.requiredEntrypoint ?? "(not applicable)" },
                { label: "Required entrypoint present", value: data.buildPreflight.dist.requiredEntrypointPresent },
                { label: "File count", value: data.buildPreflight.dist.fileCount },
                { label: "Build input manifest", value: data.buildPreflight.dist.manifestPath ?? "(none)" },
                { label: "Build input digest", value: data.buildPreflight.dist.manifestDigest ?? "(none)" },
                { label: "Distribution identity", value: data.buildPreflight.dist.distributionIdentity ?? "(none)" },
                { label: "Freshness reason", value: data.buildPreflight.dist.freshnessReason ?? "(none)" }
            ]
        }),
        (0, output_1.renderTerminalSection)({
            heading: "Staging payload",
            headingStyle: "section",
            fields: [
                { label: "Status", value: data.stagingPayload.status },
                { label: "Staging directory", value: data.stagingPayload.stagingDirectory ?? "(not applicable)" },
                { label: "Production dependencies", value: data.stagingPayload.productionDependencies.length },
                { label: "Notice files", value: data.stagingPayload.noticeFiles.length },
                { label: "Launchers", value: data.stagingPayload.launchers.length },
                { label: "Files", value: data.stagingPayload.files.length }
            ]
        }),
        (0, output_1.renderTerminalCompactList)({
            heading: "Archive payloads",
            headingStyle: "section",
            entries: data.archivePayloads.targets.length === 0
                ? [{ label: data.archivePayloads.status, fields: [{ label: "Root directory", value: data.archivePayloads.rootDirectory ?? "(not applicable)" }] }]
                : data.archivePayloads.targets.map((target) => ({
                    label: target.target,
                    fields: [
                        { label: "Payload directory", value: target.payloadDirectory },
                        { label: "Archive filename", value: target.archiveFilename },
                        { label: "Archive path", value: target.archivePath },
                        { label: "Launchers", value: target.launcherPaths.join(", ") },
                        { label: "Files", value: target.files.length }
                    ]
                }))
        }),
        (0, output_1.renderTerminalSection)({
            heading: "Artifact checksums",
            headingStyle: "section",
            fields: [
                { label: "Status", value: data.artifactChecksums.status },
                { label: "Checksum JSON", value: data.artifactChecksums.checksumJsonPath ?? "(not applicable)" },
                { label: "Checksum text", value: data.artifactChecksums.checksumTextPath ?? "(not applicable)" },
                { label: "Artifacts", value: data.artifactChecksums.artifacts.length }
            ]
        }),
        (0, output_1.renderTerminalSection)({
            heading: "Download bundle",
            headingStyle: "section",
            fields: [
                { label: "Status", value: data.downloadBundle.status },
                { label: "Directory", value: data.downloadBundle.directory ?? "(not applicable)" },
                { label: "Files", value: data.downloadBundle.files.length }
            ]
        }),
        (0, output_1.renderTerminalSection)({
            heading: "Installation README",
            headingStyle: "section",
            fields: [
                { label: "Status", value: data.installationReadme.status },
                { label: "Path", value: data.installationReadme.path ?? "(not applicable)" }
            ]
        }),
        (0, output_1.renderTerminalSection)({
            heading: "Installer safety validation",
            headingStyle: "section",
            fields: [
                { label: "Status", value: data.installerSafetyValidation.status },
                { label: "Install root", value: data.installerSafetyValidation.installRoot ?? "(not applicable)" },
                { label: "Targets", value: data.installerSafetyValidation.targets.length }
            ]
        }),
        (0, output_1.renderTerminalSection)({
            heading: "Local release validation",
            headingStyle: "section",
            fields: [
                { label: "Status", value: data.localValidation.status },
                { label: "Staging executable", value: data.localValidation.staging?.executable ?? "(not applicable)" },
                { label: "Staging commands", value: data.localValidation.staging?.commands.length ?? 0 },
                { label: "Archive validations", value: data.localValidation.archives.length },
                { label: "Archive executions", value: data.localValidation.archives.filter((target) => target.execution !== null).length },
                { label: "Report", value: data.localValidationReport.reportPathRelative ?? "(not applicable)" }
            ]
        }),
        (0, output_1.renderTerminalSection)({
            heading: "Package boundary",
            headingStyle: "section",
            fields: [
                { label: "Package metadata", value: data.packageBoundary.packageJsonPath },
                { label: "Private package", value: data.packageBoundary.private },
                { label: "Package bin", value: data.packageBoundary.packageBinName === null ? "(missing)" : `${data.packageBoundary.packageBinName} -> ${data.packageBoundary.packageBinPath}` },
                { label: "Installed command", value: data.packageBoundary.installedCommandName },
                { label: "Node engine", value: data.packageBoundary.engines.node ?? "(missing)" },
                { label: "Package manager", value: data.packageBoundary.packageManager ?? "(missing)" },
                { label: "Public registry install", value: data.packageBoundary.publication.publicRegistryInstall }
            ]
        }),
        (0, output_1.renderTerminalSection)({
            heading: "Local output operation",
            headingStyle: "section",
            fields: [
                { label: "Kind", value: data.operation.kind },
                { label: "Dry run", value: data.operation.dryRun },
                { label: "Message", value: data.operation.message },
                { label: "Published artifacts affected", value: "none" }
            ]
        }),
        (0, output_1.renderTerminalCompactList)({
            heading: "Command invocations",
            headingStyle: "section",
            entries: data.invocation === null
                ? [{ label: "unavailable", fields: [{ label: "Reason", value: "command-name metadata is not configured for this release subcommand" }] }]
                : [
                    { label: "development", fields: [{ label: "Command", value: data.invocation.development.command.join(" ") }] },
                    { label: "staged-release", fields: [{ label: "Command", value: data.invocation.stagedRelease.command.join(" ") }] },
                    { label: "installed-user", fields: [{ label: "Command", value: data.invocation.installedUser.command.join(" ") }] }
                ]
        }),
        (0, output_1.renderTerminalCompactList)({
            heading: "Options",
            headingStyle: "section",
            entries: [
                { label: "version", fields: [{ label: "Value", value: formatReleaseOptionValue(data.options.version, "(not provided)") }] },
                { label: "command-name", fields: [{ label: "Value", value: formatReleaseOptionValue(data.options.commandName, "(not applicable)") }] },
                { label: "output-dir", fields: [{ label: "Value", value: formatReleaseOptionValue(data.options.outputDir, "release") }] },
                { label: "keep", fields: [{ label: "Value", value: formatReleaseOptionValue(data.options.keep, "(not applicable)") }] },
                { label: "confirm", fields: [{ label: "Value", value: data.options.confirm }] },
                { label: "dry-run", fields: [{ label: "Value", value: data.options.dryRun }] },
                { label: "dirty", fields: [{ label: "Value", value: data.options.dirty }] }
            ]
        }),
        data.options.dryRun
            ? (0, output_1.renderTerminalBoundary)({ kind: "dry-run" })
            : (0, output_1.renderTerminalBoundary)({
                kind: "mutating-no-op",
                reason: "This milestone declares release command surfaces only; payload writes and cleanup are implemented by later milestones."
            })
    ].join("\n");
}
function formatReleaseOptionValue(value, fallback) {
    if (value === undefined || value === null || value === "") {
        return fallback;
    }
    return String(value);
}
