#!/usr/bin/env node
/**
 * @aexol/spectral — Coding agent that never sleeps
 *
 * Headless CLI wrapper — no TUI mode supported.
 *
 * Subcommand routing:
 *  - `spectral login`  → interactive auth flow (writes ~/.spectral/config.json)
 *  - `spectral logout` → deletes ~/.spectral/config.json
 *  - `spectral serve`  → start the Aexol relay WebSocket server (headless)
 *  - `spectral bind`   → link directory to an Aexol Studio project
 *  - `spectral unbind` → remove Aexol Studio project binding
 *  - `spectral --version` / `--help` → branded short-circuits, no auth needed.
 *  - anything else → error with usage hint.
 */
import { readFileSync } from "node:fs";
import { dirname, resolve } from "node:path";
import { fileURLToPath } from "node:url";
const __dirname = dirname(fileURLToPath(import.meta.url));
// ---- Read our own version ----------------------------------------------------
const pkgPath = resolve(__dirname, "..", "package.json");
const pkg = JSON.parse(readFileSync(pkgPath, "utf8"));
const VERSION = pkg.version;
const TAGLINE = "Coding agent that never sleeps";
// ---- Branded helpers ---------------------------------------------------------
function printVersion() {
    process.stdout.write(`spectral ${VERSION} — ${TAGLINE}\n`);
}
function printHeader() {
    process.stdout.write([
        `spectral ${VERSION}`,
        TAGLINE,
        "",
        "Subcommands:",
        "  spectral login         Interactive authentication (team API key or OAuth)",
        "  spectral logout        Remove stored Aexol credentials",
        "  spectral serve         Connect this machine to the Aexol relay backend",
        "  spectral bind          Link this directory to an Aexol Studio project",
        "  spectral unbind        Remove the Aexol Studio project binding",
        "  spectral --version     Print version and exit",
        "  spectral --help        Print this help and exit",
        "",
        "TUI/interactive mode has been removed. Use `spectral serve` and connect",
        "via the Aexol Studio web frontend or relay WebSocket.",
        "",
    ].join("\n"));
}
// ---- Disable interactive git editors ----------------------------------------
// Set at process level for serve mode (AgentBridge in-process → getShellEnv()
// returns process.env). Without this, `git rebase --continue`, `git commit`
// (without -m), `git merge`, etc. open an editor that hangs forever — the
// agent's bash tool runs with `stdio: ["ignore", ...]`, so there is no TTY
// to interact with.
function disableInteractiveGitEditors() {
    const editorVars = {
        GIT_EDITOR: "true",
        GIT_SEQUENCE_EDITOR: "true",
        EDITOR: "true",
        VISUAL: "true",
        GIT_PAGER: "cat",
    };
    for (const [key, value] of Object.entries(editorVars)) {
        if (!process.env[key]) {
            process.env[key] = value;
        }
    }
}
// ---- Main --------------------------------------------------------------------
async function main() {
    disableInteractiveGitEditors();
    const args = process.argv.slice(2);
    const first = args[0];
    // Branded short-circuits: never require login.
    if (first === "--version" || first === "-v") {
        printVersion();
        process.exit(0);
    }
    if (first === "--help" || first === "-h") {
        printHeader();
        process.exit(0);
    }
    // Subcommands. Dynamic import keeps the cold-start path light when users
    // are just running spectral.
    if (first === "login") {
        const { runLogin } = await import("./commands/login.js");
        await runLogin();
        process.exit(0);
    }
    if (first === "logout") {
        const { runLogout } = await import("./commands/logout.js");
        await runLogout();
        process.exit(0);
    }
    if (first === "serve") {
        const { runServeCli } = await import("./commands/serve.js");
        // runServeCli does the pre-flight login check itself and keeps the
        // process alive on the bound socket; signal handlers it installs handle
        // graceful shutdown. We intentionally don't process.exit here.
        await runServeCli(args.slice(1));
        return;
    }
    if (first === "bind") {
        const { runBind } = await import("./commands/bind.js");
        await runBind(args.slice(1));
        process.exit(0);
    }
    if (first === "unbind") {
        const { runUnbind } = await import("./commands/unbind.js");
        await runUnbind();
        process.exit(0);
    }
    // No TUI/interactive mode is supported. All other invocations must use
    // explicit subcommands.
    process.stderr.write(`spectral: unknown command "${first ?? ""}".\n` +
        `Use "spectral --help" for available subcommands.\n` +
        `To connect this machine, run: spectral serve\n`);
    process.exit(1);
}
main().catch((err) => {
    const msg = err instanceof Error ? err.message : String(err);
    process.stderr.write(`spectral: ${msg}\n`);
    process.exit(1);
});
