"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.uninstallCompletionIntegration = exports.installCompletionIntegration = exports.createCompletionScript = exports.SUPPORTED_COMPLETION_SHELLS = void 0;
exports.isSupportedCompletionShell = isSupportedCompletionShell;
exports.resolveCompletionRequest = resolveCompletionRequest;
exports.formatCompletionCandidatesForShell = formatCompletionCandidatesForShell;
const node_fs_1 = __importDefault(require("node:fs"));
const node_path_1 = __importDefault(require("node:path"));
exports.SUPPORTED_COMPLETION_SHELLS = ["bash", "zsh", "fish"];
var install_1 = require("./install");
Object.defineProperty(exports, "createCompletionScript", { enumerable: true, get: function () { return install_1.createCompletionScript; } });
Object.defineProperty(exports, "installCompletionIntegration", { enumerable: true, get: function () { return install_1.installCompletionIntegration; } });
Object.defineProperty(exports, "uninstallCompletionIntegration", { enumerable: true, get: function () { return install_1.uninstallCompletionIntegration; } });
const HELP_DISCOVERY_CUE = optionCandidate("--help", "Show the complete command registry and options with day-shift --help.");
const COMMAND_COMPLETION_TREE = [
    commandNode("about", "Show compact runtime, command registry, helper, format, and exit-code discovery.", {
        common: true
    }),
    commandNode("completion", "Generate, install, uninstall, or resolve shell completions.", {
        children: [
            commandNode("complete", "Resolve candidates for the current shell line.", { path: ["completion"] }),
            commandNode("install", "Install a Day Shift-managed shell completion integration.", {
                path: ["completion"],
                options: [
                    optionCandidate("--shell", "Target shell: bash, zsh, or fish.", true, "shell"),
                    optionCandidate("--dry-run", "Show planned completion integration changes without writing."),
                    optionCandidate("--force", "Allow replacing an unmanaged shell-native completion file.")
                ],
                quickview: commandQuickview("completion install", "Requires --shell; common options are --dry-run and --force.")
            }),
            commandNode("script", "Print a sourceable Day Shift completion script.", {
                path: ["completion"],
                options: [
                    optionCandidate("--shell", "Target shell: bash, zsh, or fish.", true, "shell")
                ],
                quickview: commandQuickview("completion script", "Requires --shell with bash, zsh, or fish.")
            }),
            commandNode("uninstall", "Remove only a Day Shift-managed completion integration.", {
                path: ["completion"],
                options: [
                    optionCandidate("--shell", "Target shell: bash, zsh, or fish.", true, "shell"),
                    optionCandidate("--dry-run", "Show intended removal without writing files.")
                ],
                quickview: commandQuickview("completion uninstall", "Requires --shell; --dry-run previews removal without writing.")
            })
        ],
        options: [
            optionCandidate("--shell", "Target shell: bash, zsh, or fish.", true, "shell"),
            optionCandidate("--line", "Current command line for completion resolution.", true, "line"),
            optionCandidate("--cursor", "Cursor offset within the current command line.", true, "offset"),
            optionCandidate("--dry-run", "Show planned completion integration changes without writing."),
            optionCandidate("--force", "Allow replacing an unmanaged shell-native completion file.")
        ]
    }),
    commandNode("config", "Read or write layered Day Shift configuration.", {
        common: true,
        children: [
            commandNode("get", "Show the resolved configuration values.", { path: ["config"] }),
            commandNode("inventory", "List catalog-backed configuration inventory without writing files.", { path: ["config"] }),
            commandNode("set", "Set a writable configuration value.", { path: ["config"] })
        ]
    }),
    commandNode("doctor", "Inspect Day Shift runtime and validation health."),
    commandNode("ignore", "Manage recommended local-only ignore rules."),
    commandNode("implementation-summary", "Build, review, or update implementation summaries.", {
        children: [
            commandNode("build", "Refresh the paired implementation-summary artifact.", {
                path: ["implementation-summary"],
                options: [
                    optionCandidate("--task-definition", "Repository-relative task-definition.md path.", true, "path"),
                    optionCandidate("--format", "Output format: text or json.", true, "format")
                ],
                quickview: commandQuickview("implementation-summary build", "Requires --task-definition; writes the canonical paired summary.")
            }),
            commandNode("review", "Review a paired implementation-summary artifact.", {
                path: ["implementation-summary"],
                options: [
                    optionCandidate("--task-definition", "Repository-relative task-definition.md path.", true, "path"),
                    optionCandidate("--format", "Output format: text or json.", true, "format")
                ],
                quickview: commandQuickview("implementation-summary review", "Requires --task-definition; read-only review surface.")
            }),
            commandNode("update", "Apply metadata field updates to an implementation summary.", {
                path: ["implementation-summary"],
                options: [
                    optionCandidate("--summary", "Repository-relative implementation-summary path.", true, "path"),
                    optionCandidate("--field", "Metadata field assignment such as implementation_status=completed.", true, "key=value"),
                    optionCandidate("--format", "Output format: text or json.", true, "format")
                ],
                quickview: commandQuickview("implementation-summary update", "Requires --summary and one or more --field assignments.")
            })
        ]
    }),
    commandNode("init", "Create the baseline Day Shift workspace scaffold.", {
        common: true,
        options: [
            optionCandidate("--no-agent", "Skip scaffolding .day-shift/agents.md."),
            optionCandidate("--without-templates", "Skip shared authoring asset scaffolding."),
            optionCandidate("--dry-run", "Show intended init changes without writing files."),
            optionCandidate("--force", "Explicitly allow overwriting managed files with defaults."),
            optionCandidate("--directory", "Initialize under a specific directory.", true, "path"),
            optionCandidate("--sandbox-run-id", "Create or reuse a disposable sandbox run directory.", true, "runId")
        ]
    }),
    commandNode("link", "Inspect or materialize planning links.", {
        common: true,
        children: [
            commandNode("materialize", "Preview or write clickable links for selected planning artifacts.", {
                path: ["link"],
                options: [
                    optionCandidate("--artifact", "Repository-relative slice, phase, milestone, task, summary, or reconciliation Markdown artifact.", true, "path"),
                    optionCandidate("--dry-run", "Preview materialization candidates without writing files."),
                    optionCandidate("--write", "Apply materialization changes to the selected artifact."),
                    optionCandidate("--scope", "Materialization scope: planning.", true, "scope"),
                    optionCandidate("--format", "Output format: text or json.", true, "format")
                ],
                quickview: commandQuickview("link materialize", "Use --artifact with --dry-run or --write; writes only the selected planning artifact or directory.")
            })
        ]
    }),
    commandNode("manifest", "Inspect or update Day Shift manifests."),
    commandNode("metadata", "Inspect or update artifact metadata."),
    commandNode("milestone", "Create, review, or update milestone artifacts."),
    commandNode("phase", "Create, review, or update phase artifacts."),
    commandNode("planning", "Use read-only planning inventory, gap reporting, and advisory next-step guidance.", {
        common: true,
        children: [
            commandNode("inventory", "Report observed planning artifacts and paired execution evidence.", {
                path: ["planning"],
                options: [
                    optionCandidate("--root", "Repository-relative planning root or subdirectory.", true, "path"),
                    optionCandidate("--format", "Output format: text or json.", true, "format")
                ],
                quickview: commandQuickview("planning inventory", "Optional --root narrows the planning tree; --format accepts text or json.")
            }),
            commandNode("gap-report", "Report expected-versus-observed planning gaps.", {
                path: ["planning"],
                options: [
                    optionCandidate("--scope", "Repository-relative planning artifact or directory.", true, "path"),
                    optionCandidate("--format", "Output format: text or json.", true, "format")
                ],
                quickview: commandQuickview("planning gap-report", "Optional --scope narrows planning evidence; --format accepts text or json.")
            }),
            commandNode("next-action", "Suggest the most likely valid next planning or review step.", {
                path: ["planning"],
                options: [
                    optionCandidate("--artifact", "Repository-relative planning artifact path.", true, "path"),
                    optionCandidate("--format", "Output format: text or json.", true, "format")
                ],
                quickview: commandQuickview("planning next-action", "Requires --artifact; --format accepts text or json.")
            })
        ]
    }),
    commandNode("prompt", "Create or update prompt artifacts."),
    commandNode("reconciliation", "Build, review, or update milestone reconciliation.", {
        children: [
            commandNode("build", "Refresh a reconciliation artifact.", {
                path: ["reconciliation"],
                options: [
                    optionCandidate("--milestone-overview", "Repository-relative milestone overview path.", true, "path"),
                    optionCandidate("--task-definition", "Repository-relative task-definition.md path for task-level exception.", true, "path"),
                    optionCandidate("--format", "Output format: text or json.", true, "format")
                ],
                quickview: commandQuickview("reconciliation build", "Use --milestone-overview by default; --task-definition is an explicit task-level exception.")
            }),
            commandNode("review", "Evaluate reconciliation evidence as a read-only surface.", {
                path: ["reconciliation"],
                options: [
                    optionCandidate("--milestone-overview", "Repository-relative milestone overview path.", true, "path"),
                    optionCandidate("--task-definition", "Repository-relative task-definition.md path for task-level exception.", true, "path"),
                    optionCandidate("--format", "Output format: text or json.", true, "format")
                ],
                quickview: commandQuickview("reconciliation review", "Use --milestone-overview by default; --task-definition is an explicit task-level exception.")
            }),
            commandNode("update", "Apply metadata field updates to a reconciliation artifact.", {
                path: ["reconciliation"],
                options: [
                    optionCandidate("--reconciliation", "Repository-relative reconciliation artifact path.", true, "path"),
                    optionCandidate("--field", "Metadata field assignment such as reconciliation_status=completed.", true, "key=value"),
                    optionCandidate("--format", "Output format: text or json.", true, "format")
                ],
                quickview: commandQuickview("reconciliation update", "Requires --reconciliation and one or more --field assignments.")
            })
        ]
    }),
    commandNode("slice", "Create or update slice artifacts."),
    commandNode("spec", "Search, list, add, update, or archive specs."),
    commandNode("structural-pressure", "Report or sync structural-pressure evidence."),
    commandNode("task", "Create, promote, review, or update task artifacts.", {
        common: true,
        children: [
            commandNode("baseline", "Capture or resume a task-cycle runtime-attribution baseline.", {
                path: ["task"],
                options: [
                    optionCandidate("--task-definition", "Repository-relative task-definition.md path.", true, "path"),
                    optionCandidate("--task-cycle-id", "Stable task-cycle identity.", true, "identity"),
                    optionCandidate("--checkpoint-id", "Stable successful-readiness checkpoint identity.", true, "identity"),
                    optionCandidate("--resume", "Reuse only the exact stored baseline identity.", false),
                    optionCandidate("--adopt", "Declared path and concrete rationale as path::rationale.", false, "path::rationale"),
                    optionCandidate("--format", "Output format: text or json.", true, "format")
                ],
                quickview: commandQuickview("task baseline", "Run after readiness succeeds and before implementation writes; repeat --adopt only for intentionally pre-staged targets.")
            }),
            commandNode("new", "Create or update an ordered task workspace.", { path: ["task"] }),
            commandNode("promote", "Promote a lightweight task workspace.", { path: ["task"] }),
            commandNode("readiness-review", "Evaluate task readiness as a read-only review surface.", {
                path: ["task"],
                options: [
                    optionCandidate("--task-definition", "Repository-relative task-definition.md path.", true, "path"),
                    optionCandidate("--format", "Output format: text or json.", true, "format")
                ],
                quickview: commandQuickview("task readiness-review", "Requires --task-definition; completion only lists local planning artifacts.")
            }),
            commandNode("review", "Review a task definition as a read-only evidence surface.", {
                path: ["task"],
                options: [
                    optionCandidate("--task-definition", "Repository-relative task-definition.md path.", true, "path"),
                    optionCandidate("--format", "Output format: text or json.", true, "format")
                ],
                quickview: commandQuickview("task review", "Requires --task-definition; --format accepts text or json.")
            }),
            commandNode("update", "Apply helper-backed metadata field updates to a task definition.", {
                path: ["task"],
                options: [
                    optionCandidate("--task-definition", "Repository-relative task-definition.md path.", true, "path"),
                    optionCandidate("--field", "Metadata field assignment such as status=completed.", true, "key=value"),
                    optionCandidate("--format", "Output format: text or json.", true, "format")
                ],
                quickview: commandQuickview("task update", "Requires --task-definition and one or more --field assignments.")
            })
        ]
    }),
    commandNode("template", "Update or materialize templates."),
    commandNode("templates", "List available templates."),
    commandNode("validation", "Run validation guidance and manage forward-only validation checkpoints.", {
        common: true,
        children: [
            commandNode("checkpoint", "Write a forward-only planning validation baseline.", { path: ["validation"] }),
            commandNode("links-check", "Run a read-only validation links check.", {
                path: ["validation"],
                options: [
                    optionCandidate("--scope", "Validation scope: planning.", true, "scope"),
                    optionCandidate("--format", "Output format: text or json.", true, "format"),
                    optionCandidate("--artifact", "Repository-relative planning artifact path.", true, "path")
                ],
                quickview: commandQuickview("validation links-check", "Optional --scope planning, --artifact path, and --format text|json; read-only.")
            }),
            commandNode("rollup", "Run a read-only validation rollup.", {
                path: ["validation"],
                options: [
                    optionCandidate("--scope", "Validation scope: planning.", true, "scope"),
                    optionCandidate("--format", "Output format: text or json.", true, "format"),
                    optionCandidate("--artifact", "Repository-relative planning artifact path.", true, "path")
                ],
                quickview: commandQuickview("validation rollup", "Optional --scope planning, --artifact path, and --format text|json; read-only.")
            }),
            commandNode("smoke", "Run a concise read-only planning validation summary.", {
                path: ["validation"],
                options: [
                    optionCandidate("--scope", "Validation scope: planning.", true, "scope"),
                    optionCandidate("--artifact", "Repository-relative planning artifact path.", true, "path"),
                    optionCandidate("--format", "Output format: text or json.", true, "format")
                ],
                quickview: commandQuickview("validation smoke", "Optional --scope planning and --artifact path; --format accepts text or json.")
            })
        ]
    }),
    commandNode("workflow", "Find read-only workflow and prompt handoffs for selected planning artifacts.", {
        common: true,
        children: [
            commandNode("explain", "Report the read-only workflow, prompt handoff, and next boundary.", {
                path: ["workflow"],
                options: [
                    optionCandidate("--artifact", "Repository-relative planning artifact path.", true, "path"),
                    optionCandidate("--format", "Output format: text or json.", true, "format")
                ],
                quickview: commandQuickview("workflow explain", "Requires --artifact; --format accepts text or json.")
            })
        ]
    })
];
const COMMON_COMMAND_CANDIDATES = [
    "init",
    "config",
    "planning",
    "task",
    "workflow",
    "validation",
    "about"
].map((name) => requireCommandNode(name).candidate);
const SHELL_VALUE_CANDIDATES = exports.SUPPORTED_COMPLETION_SHELLS.map((shell) => ({
    display: shell,
    insert: shell,
    description: `Use ${shell} completion integration.`,
    kind: "value",
    option: {
        name: "--shell",
        takesValue: true,
        valueName: "shell"
    }
}));
const FORMAT_VALUE_CANDIDATES = ["text", "json"].map((format) => ({
    display: format,
    insert: format,
    description: `Use ${format} output format.`,
    kind: "value",
    option: {
        name: "--format",
        takesValue: true,
        valueName: "format"
    }
}));
const DETAIL_VALUE_CANDIDATES = ["compact", "summary", "full"].map((detail) => ({
    display: detail,
    insert: detail,
    description: `Use ${detail} JSON detail.`,
    kind: "value",
    option: {
        name: "--detail",
        takesValue: true,
        valueName: "detail"
    }
}));
const SEVERITY_VALUE_CANDIDATES = [
    "informational",
    "warning",
    "error"
].map((severity) => ({
    display: severity,
    insert: severity,
    description: `Retain ${severity} non-blocking findings.`,
    kind: "value",
    option: {
        name: "--severity",
        takesValue: true,
        valueName: "severity"
    }
}));
const GLOBAL_OUTPUT_OPTION_CANDIDATES = [
    optionCandidate("--detail", "JSON detail: compact, summary, or full.", true, "detail"),
    optionCandidate("--finding-code", "Retain a stable non-blocking finding code.", true, "code"),
    optionCandidate("--severity", "Retain a non-blocking finding severity.", true, "severity"),
    optionCandidate("--fields", "Select comma-separated top-level JSON data fields.", true, "fields"),
    optionCandidate("--limit", "Limit a top-level JSON array lane with lane=count.", true, "lane=count"),
    optionCandidate("--page-lane", "Page one top-level JSON array lane.", true, "lane"),
    optionCandidate("--page-size", "Set the positive number of entries in a JSON page.", true, "count"),
    optionCandidate("--page-cursor", "Resume from an opaque JSON page cursor.", true, "cursor"),
    optionCandidate("--output-budget", "Bound approved read-only JSON output bytes.", true, "bytes"),
    optionCandidate("--json-spacing", "Set JSON spacing to compact or pretty.", true, "spacing")
];
const PLANNING_SCOPE_VALUE_CANDIDATES = [{
        display: "planning",
        insert: "planning",
        description: "Use planning validation scope.",
        kind: "value",
        option: {
            name: "--scope",
            takesValue: true,
            valueName: "scope"
        }
    }];
const FIELD_ASSIGNMENT_VALUE_CANDIDATES = [
    ...["draft", "active", "blocked", "completed"].map((status) => fieldAssignmentCandidate("status", status, "Shared artifact status token.")),
    ...["needs more evidence", "ready", "ready to implement", "blocked", "completed"].map((readiness) => fieldAssignmentCandidate("readiness", readiness, "Task readiness token.")),
    ...["pending", "completed"].map((status) => fieldAssignmentCandidate("implementation_status", status, "Implementation summary status token.")),
    ...["pending", "partial", "blocked", "completed"].map((status) => fieldAssignmentCandidate("reconciliation_status", status, "Reconciliation status token."))
];
const MAX_PLANNING_ARTIFACT_COMPLETION_CANDIDATES = 1000;
function isSupportedCompletionShell(value) {
    return exports.SUPPORTED_COMPLETION_SHELLS.includes(value);
}
function resolveCompletionRequest(options) {
    const cursor = clampCursor(options.line, options.cursor);
    const lineToCursor = options.line.slice(0, cursor);
    const tokens = tokenizeLine(lineToCursor);
    const token = tokens.at(-1) ?? "";
    const previousToken = tokens.at(-2);
    const candidates = selectCompletionCandidates(tokens, token, previousToken);
    return {
        request: {
            shell: options.shell,
            line: options.line,
            cursor
        },
        token,
        candidates: [...candidates]
    };
}
function formatCompletionCandidatesForShell(shell, candidates) {
    return candidates
        .map((candidate) => formatCompletionCandidate(shell, candidate))
        .join("\n");
}
function commandCandidate(name, description, commandPath = []) {
    return {
        display: name,
        insert: name,
        description,
        kind: "command",
        commandPath: [...commandPath, name]
    };
}
function optionCandidate(name, description, takesValue = false, valueName) {
    return {
        display: name,
        insert: name,
        description,
        kind: "option",
        option: {
            name,
            takesValue,
            valueName
        }
    };
}
function argumentCandidate(insert, description, commandPath) {
    return {
        display: insert,
        insert,
        description,
        kind: "argument",
        commandPath: [...commandPath]
    };
}
function quickviewCandidate(commandPath, description) {
    return {
        display: "",
        insert: "",
        description: `${commandPath.join(" ")}: ${description}`,
        kind: "quickview",
        commandPath: [...commandPath],
        quickview: description
    };
}
function commandQuickview(commandPath, description) {
    return [quickviewCandidate(commandPath.split(" "), description)];
}
function fieldAssignmentCandidate(field, value, description) {
    return {
        display: `${field}=${value}`,
        insert: `${field}=${value}`,
        description,
        kind: "value",
        option: {
            name: "--field",
            takesValue: true,
            valueName: "key=value"
        }
    };
}
function commandNode(name, description, options = {}) {
    return {
        candidate: commandCandidate(name, description, options.path ?? []),
        common: options.common,
        children: options.children,
        options: options.options,
        arguments: options.arguments,
        quickview: options.quickview
    };
}
function requireCommandNode(name) {
    const node = COMMAND_COMPLETION_TREE.find((candidate) => candidate.candidate.insert === name);
    if (node === undefined) {
        throw new Error(`Missing completion metadata for command: ${name}`);
    }
    return node;
}
function clampCursor(line, cursor) {
    if (!Number.isFinite(cursor)) {
        return line.length;
    }
    return Math.max(0, Math.min(line.length, Math.trunc(cursor)));
}
function tokenizeLine(line) {
    const tokens = [];
    let current = "";
    let quote = null;
    for (const character of line) {
        if (quote !== null) {
            if (character === quote) {
                quote = null;
            }
            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 (current.length > 0 || /\s$/.test(line)) {
        tokens.push(current);
    }
    return tokens;
}
function selectCompletionCandidates(tokens, token, previousToken) {
    const commandPath = collectCommandPath(tokens.slice(0, -1));
    const valueCandidates = previousToken === undefined
        ? undefined
        : resolveOptionValueCandidates(commandPath, previousToken, token);
    if (valueCandidates !== undefined) {
        return valueCandidates;
    }
    if (token.startsWith("-")) {
        const node = resolveCommandPathNode(commandPath);
        return filterCandidates([
            ...(node?.options ?? []),
            ...GLOBAL_OUTPUT_OPTION_CANDIDATES
        ], token);
    }
    return resolveCommandDiscoveryCandidates(collectCommandPath(tokens), token);
}
function collectCommandPath(tokens) {
    const commandPath = [];
    let skipNextValue = false;
    for (const [index, candidateToken] of tokens.entries()) {
        if (index === 0 && candidateToken === "day-shift") {
            continue;
        }
        if (skipNextValue) {
            skipNextValue = false;
            continue;
        }
        if (candidateToken.startsWith("-")) {
            skipNextValue = optionTakesValue(candidateToken);
            continue;
        }
        commandPath.push(candidateToken);
    }
    return commandPath;
}
function optionTakesValue(optionName) {
    return [
        "--artifact",
        "--cursor",
        "--field",
        "--fields",
        "--finding-code",
        "--format",
        "--detail",
        "--limit",
        "--page-lane",
        "--page-size",
        "--page-cursor",
        "--output-budget",
        "--json-spacing",
        "--line",
        "--milestone-overview",
        "--reconciliation",
        "--root",
        "--scope",
        "--severity",
        "--shell",
        "--summary",
        "--task-definition"
    ].includes(optionName);
}
function resolveOptionValueCandidates(commandPath, optionName, prefix) {
    if (optionName === "--shell") {
        return filterCandidates(SHELL_VALUE_CANDIDATES, prefix);
    }
    if (optionName === "--format") {
        return filterCandidates(FORMAT_VALUE_CANDIDATES, prefix);
    }
    if (optionName === "--detail") {
        return filterCandidates(DETAIL_VALUE_CANDIDATES, prefix);
    }
    if (optionName === "--severity") {
        return filterCandidates(SEVERITY_VALUE_CANDIDATES, prefix);
    }
    if (optionName === "--scope" && commandPath[0] === "validation") {
        return filterCandidates(PLANNING_SCOPE_VALUE_CANDIDATES, prefix);
    }
    if (optionName === "--field") {
        return filterCandidates(FIELD_ASSIGNMENT_VALUE_CANDIDATES, prefix);
    }
    const artifactKind = resolvePlanningArtifactKind(commandPath, optionName);
    if (artifactKind !== null) {
        return filterCandidates(discoverPlanningArtifactCandidates(artifactKind, prefix), prefix);
    }
    return undefined;
}
function resolvePlanningArtifactKind(commandPath, optionName) {
    if (optionName === "--task-definition") {
        return "task-definition";
    }
    if (optionName === "--milestone-overview") {
        return "milestone-overview";
    }
    if (optionName === "--summary") {
        return "implementation-summary";
    }
    if (optionName === "--reconciliation") {
        return "reconciliation";
    }
    if (optionName === "--root" || (optionName === "--scope" && commandPath[0] === "planning")) {
        return "planning-any";
    }
    if (optionName === "--artifact") {
        return "planning-any";
    }
    return null;
}
function resolveCommandDiscoveryCandidates(commandPath, token) {
    if (commandPath.length === 0) {
        return [...COMMON_COMMAND_CANDIDATES, HELP_DISCOVERY_CUE];
    }
    return resolveNodeCandidates(COMMAND_COMPLETION_TREE, commandPath, token, true);
}
function resolveNodeCandidates(nodes, commandPath, token, topLevel) {
    const [currentToken, ...remainingPath] = commandPath;
    if (currentToken === undefined) {
        return [];
    }
    if (currentToken.length === 0) {
        const candidates = topLevel
            ? [...COMMON_COMMAND_CANDIDATES, HELP_DISCOVERY_CUE]
            : contextCandidates({ children: nodes });
        return filterCandidates(candidates, token);
    }
    const matches = nodes.filter((node) => node.candidate.insert.startsWith(currentToken));
    const exactMatch = nodes.find((node) => node.candidate.insert === currentToken);
    const uniqueMatch = matches.length === 1 ? matches[0] : undefined;
    const contextNode = exactMatch ?? (currentToken.length >= 2 ? uniqueMatch : undefined);
    if (remainingPath.length > 0) {
        if (contextNode === undefined) {
            return filterCandidates(matches.map((node) => node.candidate), currentToken);
        }
        if (remainingPath.length === 1
            && remainingPath[0] === ""
            && (contextNode.children ?? []).length === 0) {
            return contextCandidates(contextNode);
        }
        return resolveNodeCandidates(contextNode.children ?? [], remainingPath, token, false);
    }
    if (currentToken.length < 2) {
        const candidates = topLevel ? COMMON_COMMAND_CANDIDATES : nodes.map((node) => node.candidate);
        return filterCandidates(candidates, currentToken);
    }
    if (matches.length === 1 && uniqueMatch !== undefined) {
        return contextCandidates(uniqueMatch);
    }
    return matches.map((node) => node.candidate);
}
function resolveCommandPathNode(commandPath) {
    let nodes = COMMAND_COMPLETION_TREE;
    let currentNode;
    for (const commandToken of commandPath) {
        if (commandToken.length === 0) {
            break;
        }
        const matches = nodes.filter((node) => node.candidate.insert.startsWith(commandToken));
        currentNode = nodes.find((node) => node.candidate.insert === commandToken)
            ?? (commandToken.length >= 2 && matches.length === 1 ? matches[0] : undefined);
        if (currentNode === undefined) {
            return undefined;
        }
        nodes = currentNode.children ?? [];
    }
    return currentNode;
}
function contextCandidates(node) {
    const childCandidates = (node.children ?? []).map((child) => child.candidate);
    return childCandidates.length > 0
        ? childCandidates
        : [
            ...(node.quickview ?? []),
            ...(node.arguments ?? []),
            ...(node.options ?? [])
        ];
}
function filterCandidates(candidates, prefix) {
    return candidates.filter((candidate) => candidate.insert.startsWith(prefix));
}
function formatCompletionCandidate(shell, candidate) {
    const insert = escapeCompletionField(candidate.insert);
    const description = escapeCompletionField([
        candidate.kind,
        candidate.description
    ].filter(Boolean).join(": "));
    if (shell === "fish") {
        return `${insert}\t${description}`;
    }
    return `${insert}\t${description}`;
}
function escapeCompletionField(value) {
    return value.replace(/[\r\n\t]/g, " ");
}
function discoverPlanningArtifactCandidates(kind, prefix) {
    const normalizedPrefix = prefix.length > 0 ? prefix : ".day-shift/planning/";
    const planningPrefix = ".day-shift/planning/";
    if (!normalizedPrefix.startsWith(".day-shift/planning") && !planningPrefix.startsWith(normalizedPrefix)) {
        return [];
    }
    const planningRoot = node_path_1.default.resolve(process.cwd(), ".day-shift", "planning");
    if (!node_fs_1.default.existsSync(planningRoot)) {
        return [];
    }
    return collectPlanningArtifactPaths(planningRoot, kind)
        .filter((artifactPath) => artifactPath.startsWith(normalizedPrefix))
        .slice(0, MAX_PLANNING_ARTIFACT_COMPLETION_CANDIDATES)
        .map((artifactPath) => argumentCandidate(artifactPath, describePlanningArtifact(kind, artifactPath), []));
}
function collectPlanningArtifactPaths(planningRoot, kind) {
    const candidates = [];
    const stack = [planningRoot];
    while (stack.length > 0) {
        const current = stack.pop();
        if (current === undefined) {
            break;
        }
        const entries = node_fs_1.default.readdirSync(current, { withFileTypes: true });
        for (const entry of entries) {
            if (entry.name.startsWith(".")) {
                continue;
            }
            const absolutePath = node_path_1.default.join(current, entry.name);
            if (entry.isDirectory()) {
                stack.push(absolutePath);
                continue;
            }
            if (!entry.isFile()) {
                continue;
            }
            const relativePath = toRepositoryRelativePath(absolutePath);
            if (isPlanningArtifactMatch(relativePath, kind)) {
                candidates.push(relativePath);
            }
        }
    }
    return candidates.sort((left, right) => left.localeCompare(right));
}
function isPlanningArtifactMatch(relativePath, kind) {
    if (kind === "planning-any") {
        return /\/(overview|task-definition|implementation-summary|reconciliation)\.md$/.test(relativePath);
    }
    if (kind === "task-definition") {
        return relativePath.endsWith("/task-definition.md");
    }
    if (kind === "milestone-overview") {
        return relativePath.includes("/milestones/") && relativePath.endsWith("/overview.md");
    }
    if (kind === "implementation-summary") {
        return relativePath.endsWith("/implementation-summary.md");
    }
    return relativePath.endsWith("/reconciliation.md");
}
function describePlanningArtifact(kind, artifactPath) {
    if (kind === "task-definition") {
        return "Local task-definition artifact.";
    }
    if (kind === "milestone-overview") {
        return "Local milestone overview artifact.";
    }
    if (kind === "implementation-summary") {
        return "Local implementation-summary artifact.";
    }
    if (kind === "reconciliation") {
        return "Local reconciliation artifact.";
    }
    if (artifactPath.endsWith("/task-definition.md")) {
        return "Local task-definition artifact.";
    }
    if (artifactPath.endsWith("/implementation-summary.md")) {
        return "Local implementation-summary artifact.";
    }
    if (artifactPath.endsWith("/reconciliation.md")) {
        return "Local reconciliation artifact.";
    }
    return "Local planning artifact.";
}
function toRepositoryRelativePath(absolutePath) {
    return node_path_1.default.relative(process.cwd(), absolutePath).split(node_path_1.default.sep).join("/");
}
