"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.assertPlanningArtifactSelectionIsConsistent = assertPlanningArtifactSelectionIsConsistent;
exports.readRequiredStringOption = readRequiredStringOption;
exports.parseFieldAssignments = parseFieldAssignments;
exports.assertNoPairOwnedLifecycleAssignments = assertNoPairOwnedLifecycleAssignments;
exports.detectMetadataFamily = detectMetadataFamily;
exports.applyFamilyAwareUpdates = applyFamilyAwareUpdates;
exports.toStringUpdateMap = toStringUpdateMap;
exports.toFieldChanges = toFieldChanges;
exports.readFrontMatter = readFrontMatter;
const node_fs_1 = __importDefault(require("node:fs"));
const node_path_1 = __importDefault(require("node:path"));
const config_contract_1 = require("../../../lib/config/config-contract");
const cli_constants_1 = require("../../../lib/config/cli-constants");
const errors_1 = require("../../../lib/errors");
const paths_1 = require("../../../lib/paths");
const front_matter_utils_1 = require("../../../lib/planning/front-matter-utils");
const artifact_policy_projection_1 = require("../../../lib/planning/artifact-policy-projection");
const spec_registry_1 = require("../../../lib/spec-registry");
function assertPlanningArtifactSelectionIsConsistent(options) {
    const metadata = readPlanningMetadata(options.artifactPath, options.content);
    const artifactType = metadata.get("artifact_type") ?? "";
    const planningDepth = metadata.get("planning_depth") ?? "";
    const topology = artifactType === "task_definition" || artifactType === "implementation_summary"
        ? (0, artifact_policy_projection_1.projectArtifactPolicy)(options.content).topology
        : null;
    const expected = getExpectedPlanningArtifactEvidence(options.artifactPath, artifactType, planningDepth, topology);
    if (expected === null) {
        return;
    }
    for (const [field, expectedValue] of Object.entries(expected.coordinates)) {
        assertMetadataEvidenceMatches({
            artifactPath: options.artifactPath,
            field,
            actualValue: metadata.get(field),
            expectedValue,
            evidenceSource: "selected artifact path and front matter"
        });
    }
    for (const [field, expectedValue] of Object.entries(expected.parents)) {
        assertParentOverviewEvidenceMatches({
            repositoryRoot: options.repositoryRoot,
            artifactPath: options.artifactPath,
            field,
            actualValue: metadata.get(field),
            expectedValue
        });
    }
}
function assertParentOverviewEvidenceMatches(options) {
    if (options.actualValue === options.expectedValue) {
        return;
    }
    const compatibleLayer = getParentOverviewLayerForField(options.field);
    if (compatibleLayer !== null && options.actualValue !== undefined) {
        const expectedDirectory = node_path_1.default.posix.dirname(options.expectedValue);
        const resolution = (0, paths_1.resolvePlanningOverviewPath)(options.repositoryRoot, {
            layer: compatibleLayer,
            directoryPath: expectedDirectory
        });
        if (resolution.selected?.path === options.actualValue) {
            return;
        }
    }
    assertMetadataEvidenceMatches({
        artifactPath: options.artifactPath,
        field: options.field,
        actualValue: options.actualValue,
        expectedValue: options.expectedValue,
        evidenceSource: "selected artifact path and explicit upstream parent link"
    });
}
function getParentOverviewLayerForField(field) {
    switch (field) {
        case "upstream.slice_overview":
            return "slice";
        case "upstream.phase_overview":
            return "phase";
        case "upstream.milestone_overview":
            return "milestone";
        default:
            return null;
    }
}
function getExpectedPlanningArtifactEvidence(artifactPath, artifactType, planningDepth, topology) {
    const segments = (0, paths_1.parseRepositoryRelativePath)(artifactPath).segments;
    const planningIndex = segments.indexOf("planning");
    if (segments[0] !== ".day-shift" || planningIndex === -1 || segments.length < planningIndex + 3) {
        return null;
    }
    const phasesIndex = segments.indexOf("phases");
    const milestonesIndex = segments.indexOf("milestones");
    const tasksIndex = segments.indexOf("tasks");
    const slicesIndex = segments.indexOf("slices", planningIndex + 1);
    const governedPlanningPath = segments[planningIndex + 1] === "governed";
    const formerGovernedSlicePath = governedPlanningPath
        && slicesIndex >= 0
        && slicesIndex + 1 < segments.length;
    const canonicalGovernedSlicePath = governedPlanningPath
        && slicesIndex < 0
        && /^(?:0\d|[1-9]\d+)-[a-z0-9]+(?:-[a-z0-9]+)*$/u.test(segments[planningIndex + 2] ?? "");
    const sliceSegment = formerGovernedSlicePath
        ? segments[slicesIndex + 1]
        : canonicalGovernedSlicePath
            ? segments[planningIndex + 2]
            : segments[planningIndex + 1];
    const sliceSlug = formerGovernedSlicePath || canonicalGovernedSlicePath
        ? sliceSegment
        : stripOrderedPrefix(sliceSegment);
    const coordinates = {};
    const parents = {};
    if (artifactType === "slice_overview") {
        coordinates.slice = sliceSlug;
        return { coordinates, parents };
    }
    if (phasesIndex >= 0) {
        coordinates.slice = sliceSlug;
        parents["upstream.slice_overview"] = (0, paths_1.composeCanonicalPlanningOverviewPath)("slice", segments.slice(0, phasesIndex).join("/"));
    }
    if (artifactType === "phase_overview" &&
        phasesIndex >= 0 &&
        (segments[phasesIndex + 2] === "phase-overview.md" || segments[phasesIndex + 2] === "overview.md")) {
        coordinates.phase = segments[phasesIndex + 1];
        return { coordinates, parents };
    }
    if (milestonesIndex >= 0) {
        coordinates.phase = segments[phasesIndex + 1];
        parents["upstream.phase_overview"] = (0, paths_1.composeCanonicalPlanningOverviewPath)("phase", segments.slice(0, phasesIndex + 2).join("/"));
    }
    if (artifactType === "milestone_overview" &&
        milestonesIndex >= 0 &&
        (segments[milestonesIndex + 2] === "milestone-overview.md" || segments[milestonesIndex + 2] === "overview.md")) {
        coordinates.milestone = segments[milestonesIndex + 1];
        return { coordinates, parents };
    }
    if (tasksIndex >= 0) {
        if (topology?.workflowLevel === "structured") {
            parents["upstream.work_overview"] = segments
                .slice(0, tasksIndex)
                .concat("overview.md")
                .join("/");
        }
        else if (topology?.workflowLevel === "basic") {
            // Basic task pairs have no organization parent.
        }
        else if (topology?.variant === "lightweight" || planningDepth === "lightweight") {
            parents["upstream.slice_overview"] = (0, paths_1.composeCanonicalPlanningOverviewPath)("slice", segments.slice(0, tasksIndex).join("/"));
        }
        else if (milestonesIndex >= 0) {
            coordinates.milestone = segments[milestonesIndex + 1];
            parents["upstream.milestone_overview"] = (0, paths_1.composeCanonicalPlanningOverviewPath)("milestone", segments.slice(0, milestonesIndex + 2).join("/"));
        }
    }
    if (artifactType === "task_definition" &&
        tasksIndex >= 0 &&
        segments[tasksIndex + 2] === "task-definition.md") {
        coordinates.task = topology?.workflowLevel === "basic"
            ? stripOrderedPrefix(segments[tasksIndex + 1])
            : segments[tasksIndex + 1];
        return { coordinates, parents };
    }
    if (artifactType === "implementation_summary" &&
        tasksIndex >= 0 &&
        segments[tasksIndex + 2] === "implementation-summary.md") {
        coordinates.task = topology?.workflowLevel === "basic"
            ? stripOrderedPrefix(segments[tasksIndex + 1])
            : segments[tasksIndex + 1];
        parents["upstream.task_definition"] = segments.slice(0, tasksIndex + 2).concat("task-definition.md").join("/");
        return { coordinates, parents };
    }
    if (artifactType === "reconciliation" &&
        milestonesIndex >= 0 &&
        segments[milestonesIndex + 2] === "reconciliation.md") {
        coordinates.milestone = segments[milestonesIndex + 1];
        parents["upstream.milestone_overview"] = (0, paths_1.composeCanonicalPlanningOverviewPath)("milestone", segments.slice(0, milestonesIndex + 2).join("/"));
        return { coordinates, parents };
    }
    return null;
}
function assertMetadataEvidenceMatches(options) {
    if (options.actualValue === options.expectedValue) {
        return;
    }
    throw new TypeError([
        `Active artifact conflict for '${options.artifactPath}'.`,
        `Evidence source: ${options.evidenceSource}.`,
        `Field '${options.field}' is '${options.actualValue ?? "<missing>"}'; expected '${options.expectedValue}'.`,
        "Recovery: pass the artifact that matches the recorded metadata, or repair the selected artifact's metadata with a compatible planning workflow before rerunning this write command."
    ].join(" "));
}
function stripOrderedPrefix(value) {
    return value.replace(/^\d{2,}-/u, "");
}
function readRequiredStringOption(value, optionName) {
    if (typeof value !== "string" || value.trim() === "") {
        throw (0, errors_1.createUsageError)(`${optionName} is required.`);
    }
    return value.trim();
}
function parseFieldAssignments(rawFields) {
    if (!Array.isArray(rawFields) || rawFields.length === 0) {
        throw (0, errors_1.createUsageError)("Provide one or more --field <key>=<value> assignments.", ["Example: --field agent_mode=guided"]);
    }
    return rawFields.map((token) => {
        const separatorIndex = token.indexOf("=");
        if (separatorIndex <= 0) {
            throw (0, errors_1.createUsageError)(`Invalid --field assignment '${token}'.`, ["Each assignment must use <key>=<value>."]);
        }
        const key = token.slice(0, separatorIndex).trim();
        const rawValue = token.slice(separatorIndex + 1);
        if (key === "") {
            throw (0, errors_1.createUsageError)(`Invalid --field assignment '${token}'.`, ["Field keys must be non-empty."]);
        }
        return { key, rawValue };
    });
}
function assertNoPairOwnedLifecycleAssignments(options) {
    const fields = new Set(options.assignments.map((assignment) => assignment.key));
    const controlled = options.artifactType === "task_definition"
        ? ["status", "readiness"]
        : options.artifactType === "implementation_summary"
            ? ["status", "readiness", "implementation_status", "review_disposition", "current_attempt_id", "attempts", "completed_at"]
            : [];
    const rejected = controlled.find((field) => fields.has(field));
    if (rejected === undefined)
        return;
    throw new TypeError([
        `Pair-owned lifecycle field '${rejected}' cannot be changed through a generic metadata or artifact update surface.`,
        "Lifecycle state is derived from the task-definition/implementation-summary pair and may change only through the explicit task lifecycle commands.",
        "Recovery: use task readiness-authorize, task block, task disposition, task close, or task cancel as appropriate. No partial write was applied."
    ].join(" "));
}
function detectMetadataFamily(artifactPath, content) {
    if (artifactPath === cli_constants_1.CLI_SPEC_INDEX_PATH) {
        return "spec-registry";
    }
    if (artifactPath.endsWith(".json")) {
        const parsed = JSON.parse(content);
        if (!isPlainObject(parsed)) {
            throw new TypeError("JSON metadata surfaces must be object-shaped.");
        }
        if (typeof parsed.prompt_manifest_version === "number") {
            return "prompt-manifest";
        }
        if (typeof parsed.template_manifest_version === "number") {
            return "template-manifest";
        }
        throw new TypeError("Unsupported JSON metadata family for generic metadata update.");
    }
    if (!artifactPath.endsWith(".md")) {
        throw new TypeError("Unsupported artifact extension for metadata updates.");
    }
    const frontMatter = readFrontMatter(artifactPath, content);
    if (frontMatter.artifactType !== undefined && frontMatter.artifactType.trim() !== "") {
        return "planning-artifact";
    }
    if (artifactPath.startsWith(".day-shift/prompts/")) {
        return "prompt";
    }
    if (artifactPath.startsWith(".day-shift/templates/")) {
        return "template";
    }
    throw new TypeError("Unsupported Markdown metadata family for generic metadata update.");
}
function applyFamilyAwareUpdates(options) {
    switch (options.family) {
        case "planning-artifact": {
            const updates = toStringUpdateMap(options.assignments);
            const transitionUpdates = {};
            const frontMatterUpdates = {};
            for (const [key, value] of Object.entries(updates)) {
                if (cli_constants_1.CLI_METADATA_STATUS_AND_PLANNING_FIELDS.has(key)) {
                    transitionUpdates[key] = value;
                }
                else {
                    frontMatterUpdates[key] = value;
                }
            }
            let nextContent = options.originalContent;
            if (Object.keys(transitionUpdates).length > 0) {
                nextContent = (0, front_matter_utils_1.applyStatusAndPlanningFieldTransition)(nextContent, transitionUpdates);
            }
            if (Object.keys(frontMatterUpdates).length > 0) {
                nextContent = (0, front_matter_utils_1.applyPlanningFrontMatterFieldUpdates)(nextContent, frontMatterUpdates, {
                    repositoryRelativePathKeys: cli_constants_1.CLI_REPOSITORY_RELATIVE_PARENT_LINK_KEYS
                });
            }
            return nextContent;
        }
        case "prompt": {
            assertWritablePromptLayerPath(options.artifactPath);
            return (0, front_matter_utils_1.applyNonArtifactFrontMatterFieldUpdates)(options.originalContent, toStringUpdateMap(options.assignments), {
                family: "prompt",
                requiredKeys: ["prompt_version", "layer", "action"]
            });
        }
        case "template": {
            return (0, front_matter_utils_1.applyNonArtifactFrontMatterFieldUpdates)(options.originalContent, toStringUpdateMap(options.assignments), { family: "template" });
        }
        case "prompt-manifest":
        case "template-manifest": {
            const manifestUpdates = toManifestUpdates(options.assignments);
            return (0, front_matter_utils_1.applyManifestMetadataFieldUpdates)(options.originalContent, {
                family: options.family,
                topLevelFields: Object.keys(manifestUpdates.topLevelFields).length > 0
                    ? manifestUpdates.topLevelFields
                    : undefined,
                entryPatches: manifestUpdates.entryPatches.length > 0
                    ? manifestUpdates.entryPatches
                    : undefined,
                entryReplacements: manifestUpdates.entryReplacements.length > 0
                    ? manifestUpdates.entryReplacements
                    : undefined
            });
        }
        case "spec-registry": {
            const specUpdates = toSpecFieldUpdates(options.assignments);
            const currentDocument = (0, spec_registry_1.parseSpecIndexDocumentText)(options.originalContent);
            const nextDocument = (0, spec_registry_1.applySpecIndexEntryFieldUpdates)({
                currentDocument,
                entryId: specUpdates.entryId,
                updates: specUpdates.updates
            });
            if (Object.keys(specUpdates.updates).some((key) => key.startsWith("linked_slice."))) {
                assertLinkedSliceTargetIsWritable({
                    repositoryRoot: options.repositoryRoot,
                    entryId: specUpdates.entryId,
                    document: nextDocument
                });
            }
            return (0, spec_registry_1.renderSpecIndexDocument)(nextDocument);
        }
        default:
            return assertUnreachable(options.family);
    }
}
function assertLinkedSliceTargetIsWritable(options) {
    const entry = options.document.entries.find((candidate) => candidate.id === options.entryId);
    const linkedSlice = entry?.optional.linked_slice;
    if (entry === undefined || linkedSlice === undefined) {
        throw new TypeError(`Spec index entry '${options.entryId}' must include linked_slice.slice and linked_slice.path after a linked_slice update.`);
    }
    const targetAbsolutePath = (0, paths_1.resolveRepositoryRelativePath)(options.repositoryRoot, (0, paths_1.parseRepositoryRelativePath)(linkedSlice.path));
    if (!node_fs_1.default.existsSync(targetAbsolutePath)) {
        throw new TypeError(`Spec index entry '${options.entryId}' linked_slice.path '${linkedSlice.path}' must reference an existing slice overview before the registry update can be written.`);
    }
    const targetContent = node_fs_1.default.readFileSync(targetAbsolutePath, "utf8");
    const frontMatter = readPlanningFrontMatter(linkedSlice.path, targetContent);
    assertFrontMatterValue(frontMatter, "artifact_type", "slice_overview", linkedSlice.path);
    assertFrontMatterValue(frontMatter, "slice", linkedSlice.slice, linkedSlice.path);
    const missingCompanions = [
        node_path_1.default.posix.join(node_path_1.default.posix.dirname(linkedSlice.path), "decisions", ".gitkeep"),
        node_path_1.default.posix.join(node_path_1.default.posix.dirname(linkedSlice.path), "notes", ".gitkeep")
    ].filter((companionPath) => !node_fs_1.default.existsSync((0, paths_1.resolveRepositoryRelativePath)(options.repositoryRoot, (0, paths_1.parseRepositoryRelativePath)(companionPath))));
    if (missingCompanions.length > 0) {
        throw new TypeError(`Spec index entry '${options.entryId}' linked_slice.path '${linkedSlice.path}' is missing required slice companion artifacts: ${missingCompanions.join(", ")}.`);
    }
    const workflowProvenance = frontMatter.get("workflow_provenance") ?? "";
    const workflowCliCommand = frontMatter.get("workflow_cli_command") ?? "";
    const workflowManualException = frontMatter.get("workflow_manual_exception") ?? "";
    const isCliScaffolded = workflowProvenance === "cli" &&
        /^day-shift slice new\b|^node dist\/cli\/index\.js slice new\b/u.test(workflowCliCommand);
    const isManualException = workflowProvenance === "manual-exception" &&
        isAllowedManualException(workflowManualException) &&
        workflowCliCommand.trim() !== "";
    const isMigratedDestination = isRecordedWorkspaceMigrationDestination(options.repositoryRoot, linkedSlice.path);
    if (!isCliScaffolded && !isManualException && !isMigratedDestination) {
        throw new TypeError([
            `Spec index entry '${options.entryId}' linked_slice.path '${linkedSlice.path}' must reference a CLI-scaffolded slice overview, an allowed manual-exception artifact, or a destination recorded by an applied workspace-structure migration.`,
            `Found workflow_provenance '${workflowProvenance || "<missing>"}', workflow_cli_command '${workflowCliCommand || "<missing>"}', workflow_manual_exception '${workflowManualException || "<missing>"}'.`
        ].join(" "));
    }
}
function isRecordedWorkspaceMigrationDestination(repositoryRoot, artifactPath) {
    const migrationDirectory = node_path_1.default.join(repositoryRoot, ".day-shift", "state", "migrations");
    if (!node_fs_1.default.existsSync(migrationDirectory)) {
        return false;
    }
    for (const entry of node_fs_1.default.readdirSync(migrationDirectory, { withFileTypes: true })) {
        if (!entry.isFile() || !/^workspace-structure-[a-f0-9]{16}\.json$/u.test(entry.name)) {
            continue;
        }
        try {
            const record = JSON.parse(node_fs_1.default.readFileSync(node_path_1.default.join(migrationDirectory, entry.name), "utf8"));
            if (record.migrationKind !== "workspace-structure" ||
                typeof record.transactionId !== "string" ||
                !/^migration-[a-f0-9]{36}$/u.test(record.transactionId) ||
                !Array.isArray(record.pathMappings)) {
                continue;
            }
            if (record.pathMappings.some((mapping) => typeof mapping === "object" &&
                mapping !== null &&
                !Array.isArray(mapping) &&
                mapping.destinationPath === artifactPath)) {
                return true;
            }
        }
        catch {
            // Malformed or unrelated migration evidence cannot authorize a registry write.
        }
    }
    return false;
}
function assertFrontMatterValue(frontMatter, field, expected, artifactPath) {
    const actual = frontMatter.get(field);
    if (actual !== expected) {
        throw new TypeError(`Linked slice target '${artifactPath}' has ${field} '${actual ?? "<missing>"}'; expected '${expected}'.`);
    }
}
function isAllowedManualException(value) {
    return value === "unsupported by CLI" ||
        value === "CLI failed" ||
        value === "manual recovery after scaffold verification";
}
function readPlanningFrontMatter(filePath, content) {
    return readPlanningMetadata(filePath, content, false);
}
function readPlanningMetadata(filePath, content, includeNested = true) {
    const lines = content.split(/\r?\n/);
    if (lines[0] !== "---") {
        throw new TypeError(`Planning artifact '${filePath}' is missing YAML front matter.`);
    }
    const closingIndex = lines.findIndex((line, index) => index > 0 && line === "---");
    if (closingIndex === -1) {
        throw new TypeError(`Planning artifact '${filePath}' has malformed YAML front matter.`);
    }
    const values = new Map();
    let parentKey = null;
    for (let index = 1; index < closingIndex; index += 1) {
        const line = lines[index];
        const topLevelMatch = line.match(/^([A-Za-z0-9_]+):\s*(.*)$/);
        if (topLevelMatch !== null) {
            parentKey = topLevelMatch[2].trim() === "" ? topLevelMatch[1] : null;
            values.set(topLevelMatch[1], (0, front_matter_utils_1.parseScalar)(topLevelMatch[2]));
            continue;
        }
        if (!includeNested || parentKey === null) {
            continue;
        }
        const nestedMatch = line.match(/^\s{2}([A-Za-z0-9_]+):\s*(.*)$/);
        if (nestedMatch !== null) {
            values.set(`${parentKey}.${nestedMatch[1]}`, (0, front_matter_utils_1.parseScalar)(nestedMatch[2]));
        }
    }
    return values;
}
function assertWritablePromptLayerPath(artifactPath) {
    const layer = (0, config_contract_1.classifyPromptWorkspaceLayer)(artifactPath, config_contract_1.BUILT_IN_CONFIG_DEFAULTS);
    if (layer === "user") {
        return;
    }
    if (layer === "latest") {
        throw new TypeError(`Prompt metadata updates may not write directly to latest-layer prompt '${artifactPath}'. Copy the active prompt into '${config_contract_1.BUILT_IN_CONFIG_DEFAULTS.prompt_user_root}/' before mutation; latest and packaged-default layers remain read-only sources.`);
    }
    if (layer === "shared-root") {
        throw new TypeError(`Prompt metadata updates may target only user-layer prompt files under '${config_contract_1.BUILT_IN_CONFIG_DEFAULTS.prompt_user_root}/'.`);
    }
    throw new TypeError(`Prompt metadata updates may target only repository prompt files under '${config_contract_1.BUILT_IN_CONFIG_DEFAULTS.prompt_user_root}/'.`);
}
function toStringUpdateMap(assignments) {
    const updates = {};
    for (const assignment of assignments) {
        updates[assignment.key] = (0, front_matter_utils_1.parseScalar)(assignment.rawValue);
    }
    return updates;
}
function toFieldChanges(assignments) {
    return assignments.map((assignment) => ({
        key: assignment.key,
        value: (0, front_matter_utils_1.parseScalar)(assignment.rawValue)
    }));
}
function toManifestUpdates(assignments) {
    const topLevelFields = {};
    const entryPatchMap = new Map();
    const entryReplacements = [];
    for (const assignment of assignments) {
        if (assignment.key.startsWith("entry:")) {
            const [entryPath, field] = parseManifestEntryKey(assignment.key);
            const updatesForPath = entryPatchMap.get(entryPath) ?? {};
            updatesForPath[field] = parseLooseValue(assignment.rawValue);
            entryPatchMap.set(entryPath, updatesForPath);
            continue;
        }
        if (assignment.key.startsWith("replace:")) {
            const entryPath = parseManifestReplacementKey(assignment.key);
            const replacementValue = parseLooseValue(assignment.rawValue);
            if (!isPlainObject(replacementValue)) {
                throw new TypeError(`Manifest replacement '${assignment.key}' requires an object-shaped JSON value.`);
            }
            entryReplacements.push({
                path: entryPath,
                entry: replacementValue
            });
            continue;
        }
        const topLevelKey = assignment.key.startsWith("top:")
            ? assignment.key.slice("top:".length)
            : assignment.key;
        if (topLevelKey.trim() === "") {
            throw new TypeError("Manifest top-level field keys must be non-empty.");
        }
        topLevelFields[topLevelKey] = parseLooseValue(assignment.rawValue);
    }
    const entryPatches = Array.from(entryPatchMap.entries()).map(([entryPath, fields]) => ({
        path: entryPath,
        fields
    }));
    return {
        topLevelFields,
        entryPatches,
        entryReplacements
    };
}
function parseManifestReplacementKey(key) {
    const entryPath = key.slice("replace:".length).trim();
    if (entryPath === "") {
        throw new TypeError(`Invalid manifest replacement key '${key}'. Use 'replace:<path>'.`);
    }
    return entryPath;
}
function parseManifestEntryKey(key) {
    const firstSeparator = key.indexOf(":");
    const secondSeparator = key.indexOf(":", firstSeparator + 1);
    if (secondSeparator === -1) {
        throw new TypeError(`Invalid manifest entry update key '${key}'. Use 'entry:<path>:<field>'.`);
    }
    const entryPath = key.slice(firstSeparator + 1, secondSeparator).trim();
    const field = key.slice(secondSeparator + 1).trim();
    if (entryPath === "" || field === "") {
        throw new TypeError(`Invalid manifest entry update key '${key}'. Use 'entry:<path>:<field>'.`);
    }
    return [entryPath, field];
}
function toSpecFieldUpdates(assignments) {
    let entryId = null;
    const updates = {};
    for (const assignment of assignments) {
        const [parsedEntryId, fieldPath] = parseSpecEntryKey(assignment.key);
        if (entryId === null) {
            entryId = parsedEntryId;
        }
        else if (entryId !== parsedEntryId) {
            throw new TypeError("Spec-registry updates must target exactly one entry id per command invocation.");
        }
        updates[fieldPath] = parseLooseValue(assignment.rawValue);
    }
    if (entryId === null) {
        throw new TypeError("Spec-registry updates require at least one entry field update.");
    }
    return {
        entryId,
        updates
    };
}
function parseSpecEntryKey(key) {
    if (!key.startsWith("entry:")) {
        throw new TypeError(`Invalid spec-registry update key '${key}'. Use 'entry:<id>:<field-path>'.`);
    }
    const firstSeparator = key.indexOf(":");
    const secondSeparator = key.indexOf(":", firstSeparator + 1);
    if (secondSeparator === -1) {
        throw new TypeError(`Invalid spec-registry update key '${key}'. Use 'entry:<id>:<field-path>'.`);
    }
    const entryId = key.slice(firstSeparator + 1, secondSeparator).trim();
    const fieldPath = key.slice(secondSeparator + 1).trim();
    if (entryId === "" || fieldPath === "") {
        throw new TypeError(`Invalid spec-registry update key '${key}'. Use 'entry:<id>:<field-path>'.`);
    }
    return [entryId, fieldPath];
}
function parseLooseValue(rawValue) {
    const trimmed = rawValue.trim();
    if (trimmed === "") {
        return "";
    }
    if ((trimmed.startsWith("\"") && trimmed.endsWith("\"")) || (trimmed.startsWith("'") && trimmed.endsWith("'"))) {
        return (0, front_matter_utils_1.parseScalar)(trimmed);
    }
    if (trimmed === "true") {
        return true;
    }
    if (trimmed === "false") {
        return false;
    }
    if (trimmed === "null") {
        return null;
    }
    if (/^-?\d+(\.\d+)?$/.test(trimmed)) {
        const parsedNumber = Number(trimmed);
        if (!Number.isNaN(parsedNumber)) {
            return parsedNumber;
        }
    }
    if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
        return JSON.parse(trimmed);
    }
    return (0, front_matter_utils_1.parseScalar)(rawValue);
}
function readFrontMatter(filePath, content) {
    const lines = content.split(/\r?\n/);
    if (lines[0] !== "---") {
        throw new TypeError(`Markdown metadata surface '${filePath}' is missing YAML front matter.`);
    }
    const closingIndex = lines.findIndex((line, index) => index > 0 && line === "---");
    if (closingIndex === -1) {
        throw new TypeError(`Markdown metadata surface '${filePath}' has malformed YAML front matter.`);
    }
    let artifactType;
    for (let index = 1; index < closingIndex; index += 1) {
        const match = lines[index].match(/^([A-Za-z0-9_]+):\s*(.*)$/);
        if (match === null) {
            continue;
        }
        if (match[1] === "artifact_type") {
            artifactType = (0, front_matter_utils_1.parseScalar)(match[2]);
        }
    }
    return { artifactType };
}
function isPlainObject(value) {
    return typeof value === "object" && value !== null && !Array.isArray(value);
}
function assertUnreachable(value) {
    throw new TypeError(`Unsupported metadata family '${String(value)}'.`);
}
