import { parsePersonaReference } from "./persona_reference.js";
import { REASONING_LEVELS, RiskLevelSchema, } from "./types.js";
export class CliError extends Error {
    constructor(message) {
        super(message);
        this.name = "CliError";
    }
}
export function resolvePersonaId(raw, personas) {
    const trimmed = raw.trim();
    if (!trimmed)
        return undefined;
    return personas.find((p) => p.id === trimmed)?.id;
}
export function parsePersonaString(raw, personas) {
    const parsed = parsePersonaReference(raw);
    if (!parsed.personaId || parsed.error) {
        return { personaId: undefined, reasoning: undefined };
    }
    const personaId = resolvePersonaId(parsed.personaId, personas);
    return {
        personaId,
        reasoning: personaId ? parsed.reasoning : undefined,
    };
}
function parsePersonaOption(raw, personas) {
    const parsedReference = parsePersonaReference(raw);
    if (parsedReference.error === "missing-reasoning") {
        throw new CliError("missing reasoning level after ':' in --persona");
    }
    if (parsedReference.error === "invalid-reasoning") {
        const allowed = REASONING_LEVELS.join(", ");
        throw new CliError(`invalid reasoning level '${parsedReference.rawReasoning}'. allowed levels: ${allowed}`);
    }
    if (!parsedReference.personaId) {
        throw new CliError("missing persona id in --persona");
    }
    const personaId = resolvePersonaId(parsedReference.personaId, personas);
    if (!personaId) {
        const available = personas.map((p) => p.id).join(", ");
        throw new CliError(`unknown persona '${parsedReference.personaId}'. available personas: ${available}`);
    }
    return {
        personaId,
        reasoningOverride: parsedReference.reasoning,
    };
}
function parseRiskOption(raw) {
    const normalized = raw.trim();
    if (!normalized) {
        throw new CliError("missing value for --risk");
    }
    const parsed = RiskLevelSchema.safeParse(normalized);
    if (!parsed.success) {
        const allowed = RiskLevelSchema.options.join(", ");
        throw new CliError(`invalid risk level '${raw}'. allowed levels: ${allowed}`);
    }
    return parsed.data;
}
function parseValue(arg, argv, index) {
    const eqIndex = arg.indexOf("=");
    if (eqIndex !== -1) {
        const value = arg.slice(eqIndex + 1);
        if (!value) {
            throw new CliError(`missing value for ${arg.slice(0, eqIndex)}`);
        }
        return { value, nextIndex: index };
    }
    const next = argv[index + 1];
    if (!next || next.startsWith("-")) {
        throw new CliError(`missing value for ${arg}`);
    }
    return { value: next, nextIndex: index + 1 };
}
export function parseCliArgs(argv, personas) {
    let help = false;
    let debug = false;
    let loadPath;
    let personaId;
    let reasoningOverride;
    let riskLevel;
    let caffeinated = false;
    let noAgentContextFiles = false;
    for (let i = 0; i < argv.length; i++) {
        const arg = argv[i];
        if (arg === "--help" || arg === "-h") {
            help = true;
            continue;
        }
        if (arg === "--debug") {
            debug = true;
            continue;
        }
        if (arg === "--load" || arg === "-l" || arg.startsWith("--load=") || arg.startsWith("-l=")) {
            const parsed = parseValue(arg, argv, i);
            loadPath = parsed.value;
            i = parsed.nextIndex;
            continue;
        }
        if (arg === "--no-agent-context-files") {
            noAgentContextFiles = true;
            continue;
        }
        if (arg === "--caffeinated") {
            caffeinated = true;
            continue;
        }
        if (arg === "--persona" ||
            arg === "-p" ||
            arg.startsWith("--persona=") ||
            arg.startsWith("-p=")) {
            const parsed = parseValue(arg, argv, i);
            const persona = parsePersonaOption(parsed.value, personas);
            personaId = persona.personaId;
            reasoningOverride = persona.reasoningOverride;
            i = parsed.nextIndex;
            continue;
        }
        if (arg === "--risk" || arg === "-r" || arg.startsWith("--risk=") || arg.startsWith("-r=")) {
            const parsed = parseValue(arg, argv, i);
            riskLevel = parseRiskOption(parsed.value);
            i = parsed.nextIndex;
            continue;
        }
        if (arg.startsWith("-")) {
            throw new CliError(`unknown option: ${arg}`);
        }
        throw new CliError(`unexpected argument: ${arg}`);
    }
    return {
        help,
        debug,
        loadPath,
        personaId,
        reasoningOverride,
        riskLevel,
        caffeinated,
        noAgentContextFiles,
    };
}
export function printHelp(personas) {
    const personaList = personas.map((p) => p.id).join(", ");
    const reasoningList = REASONING_LEVELS.join(", ");
    const riskList = RiskLevelSchema.options.join(", ");
    console.log([
        "tau - terminal chat",
        "",
        "usage:",
        "  tau [options]",
        "  tau rpc [options]",
        "  tau auth <subcommand>",
        "  tau usage [options]",
        "  tau install [options]",
        "  tau tool <command>",
        "  tau async <command>",
        "  tau diff-tool [--help]",
        "",
        "options:",
        "  --help                        show this help and exit.",
        "  --debug                       print debug info (personas, prompts, skills, system prompt) and exit.",
        "  --load, -l <file>             load a checkpoint file.",
        `  --persona, -p <id>[:<level>]  start with a persona. available: ${personaList}.`,
        `                                optionally specify reasoning level. levels: ${reasoningList}.`,
        `                                if not specified, uses resolved config defaultPersona.`,
        `  --risk, -r <level>            set initial model risk level. levels: ${riskList}.`,
        `                                if not specified, uses resolved config defaultRisk (default: read-only).`,
        "  --caffeinated                 keep macOS awake during active assistant turns in TUI mode (no-op on Linux).",
        "  --no-agent-context-files      disable AGENTS.md injection into the system prompt.",
        "",
        "subcommands:",
        "  rpc                           run headless stdio RPC mode (no TUI).",
        "  auth                          authenticate/list/logout Codex OAuth accounts.",
        "  usage                         summarize usage logs.",
        "  install                       install starter prompts and skills.",
        "  tool                          run built-in utility tools.",
        "  async                         run async daemon/client commands.",
        "  diff-tool                     built-in browser diff review demo tool.",
        "",
        "examples:",
        "  tau --persona gpt-5.4-chat:high",
        "  tau -p opus-4.8-coder",
        "  tau --persona gpt-5.4-chat:medium --risk read-write",
        "  tau -p gpt-5.4-coder:high -r read-write",
        "  tau -l /tmp/tau-checkpoint-abc123/checkpoint.json",
        "",
        "notes:",
        "  use `tau auth login codex` to authenticate ChatGPT subscription credentials.",
        "  use `tau auth logout codex --account <email>` to remove stored OAuth credentials.",
        "  use `tau usage` to view daily usage totals from ~/.config/tau/logs.",
        "  use `tau install` to install starter prompts and skills.",
        "  use `tau tool pdf-unpack <file.pdf>` to extract markdown and page image patches from a PDF.",
        "  /diff uses Tau's built-in browser diff tool by default; config.diffTool overrides it.",
        "  you can switch persona during a session with /persona:<id>.",
        "  insert prompt templates with /prompt:<id>.",
        "  you can change model risk level during a session with /risk:read-only or /risk:read-write.",
        "  if stdin is piped, its contents are sent as the first message automatically in TUI mode.",
        "  in RPC mode, stdin/stdout are reserved for protocol traffic.",
        "  reasoning only affects providers that support it.",
    ].join("\n"));
}
export function printDiffToolHelp() {
    console.log([
        "usage:",
        "  tau diff-tool [--help]",
        "",
        "the built-in browser diff review demo tool used by /diff when config.diffTool is not set.",
        "tau launches this automatically during an active diff review session.",
        "it expects TAU_DIFF_* environment variables from Tau and is not meant to be launched directly.",
        "",
        "examples:",
        "  tau diff-tool --help",
        "  /diff --staged    # launches tau diff-tool automatically unless diffTool is configured",
    ].join("\n"));
}
//# sourceMappingURL=cli.js.map