/**
 * olam skills onboard — fresh-install umbrella that composes the 3-step
 * recipe into one operator-friendly verb.
 *
 *   olam skills onboard --name <n> --git-url <url> [--branch main]
 *                       [--trust] [--scope project|user]
 *
 * Pipeline:
 *   1. addSkillSource({ trustMethod: 'flag' }) — `--trust` is the only
 *      sanctioned trust method here. Onboard is non-interactive by
 *      design (it composes 4 steps; an interactive picker mid-pipeline
 *      would be confusing). Operators who want the picker should run
 *      `olam skills source add` directly.
 *   2. cloneSkillSource(...) — register + clone.
 *   3. installSkillsHookToFile(...) at --scope (default project).
 *   4. syncSkills() — first sync.
 *   5. Print a single success summary covering all 4 steps.
 *
 * Failure rollback: any failure AFTER step 1 (clone, hook install,
 * sync) unwinds the registered source so the operator can re-try
 * cleanly. Each step appends an audit row so the trust-coverage gate
 * stays accurate even when the umbrella partially fails.
 */
import pc from 'picocolors';
import { addSkillSource, cloneSkillSource, installSkillsHookToFile, removeSkillSource, removeSkillSourceClone, skillsHookSettingsPathFor, syncSkills, updateSkillSource, appendTrustAudit, redactUrl, } from '@olam/core/src/skill-sources/index.js';
import { printError, printInfo, printSuccess, printHeader } from '../output.js';
function asMessage(err) {
    return err instanceof Error ? err.message : String(err);
}
export function registerSkillsOnboard(program) {
    const skills = program.commands.find((c) => c.name() === 'skills') ??
        program.command('skills').description('Manage skill sources and synchronization');
    skills
        .command('onboard')
        .description('Fresh-install umbrella: register + clone + install SessionStart hook + first sync, in one verb')
        .requiredOption('--name <name>', 'Display name (lowercase, digits, dash)')
        .requiredOption('--git-url <url>', 'git URL (https://, git@, ssh://, file://, or absolute path)')
        .option('--branch <branch>', 'Branch to track', 'main')
        .option('--trust', 'Acknowledge that registering grants symlink-into-~/.claude permission (required: onboard is non-interactive)')
        .option('--scope <scope>', 'Hook install scope: project (<cwd>/.claude/settings.json) or user (~/.claude/settings.json)', 'project')
        .action(async (opts) => {
        const scope = opts.scope === 'user' ? 'user' : 'project';
        // Onboard composes 4 steps end-to-end. Surfacing a TTY trust prompt
        // mid-pipeline would split operator attention; require --trust as
        // the only sanctioned path here. Operators who want the picker can
        // run `olam skills source add` (then run install-hook + sync
        // themselves) — same surface, different ergonomic.
        if (opts.trust !== true) {
            try {
                appendTrustAudit({
                    gitUrl: redactUrl(opts.gitUrl),
                    action: 'auto-rejected',
                    trustMethod: 'auto-reject-tty',
                    note: 'onboard: --trust required (composed pipeline; no mid-flow picker)',
                });
            }
            catch {
                // best-effort audit
            }
            printError('`olam skills onboard` requires --trust. Registering a skill source grants ' +
                'symlink-into-~/.claude permission; onboard is non-interactive so the operator ' +
                'must acknowledge up front. (For the interactive picker use `olam skills source add`.)');
            process.exitCode = 1;
            return;
        }
        // ---------------------------------------------------------------
        // Step 1: register the source (writes 'added' audit entry internally).
        // ---------------------------------------------------------------
        let entry;
        try {
            entry = addSkillSource({
                name: opts.name,
                gitUrl: opts.gitUrl,
                branch: opts.branch ?? 'main',
                trustMethod: 'flag',
            });
        }
        catch (err) {
            try {
                appendTrustAudit({
                    gitUrl: redactUrl(opts.gitUrl),
                    action: 'failed',
                    trustMethod: 'flag',
                    note: `onboard step=add: ${asMessage(err)}`,
                });
            }
            catch {
                // best-effort
            }
            printError(asMessage(err));
            process.exitCode = 1;
            return;
        }
        // ---------------------------------------------------------------
        // Step 2: clone the source. Rolls back step 1 on failure.
        // ---------------------------------------------------------------
        let headSha;
        try {
            const result = cloneSkillSource({
                gitUrl: entry.gitUrl,
                branch: entry.branch,
                id: entry.id,
            });
            headSha = result.headSha;
            updateSkillSource(entry.id, { lastPulledSha: result.headSha });
        }
        catch (err) {
            try {
                removeSkillSource(entry.id);
            }
            catch {
                // best-effort
            }
            try {
                appendTrustAudit({
                    gitUrl: redactUrl(entry.gitUrl),
                    action: 'failed',
                    trustMethod: 'flag',
                    sourceId: entry.id,
                    note: `onboard step=clone: ${asMessage(err)}`,
                });
            }
            catch {
                // best-effort
            }
            printError(asMessage(err));
            process.exitCode = 1;
            return;
        }
        // ---------------------------------------------------------------
        // Step 3: install SessionStart hook. Rolls back clone + register
        // on failure so the operator's state stays clean.
        // ---------------------------------------------------------------
        const hookFilePath = skillsHookSettingsPathFor(scope);
        let hookStatus;
        let hookBackupPath;
        try {
            const result = installSkillsHookToFile(hookFilePath);
            hookStatus = result.status;
            hookBackupPath = result.backupPath;
        }
        catch (err) {
            try {
                removeSkillSourceClone(entry.id);
                removeSkillSource(entry.id);
            }
            catch {
                // best-effort
            }
            try {
                appendTrustAudit({
                    gitUrl: redactUrl(entry.gitUrl),
                    action: 'failed',
                    trustMethod: 'flag',
                    sourceId: entry.id,
                    note: `onboard step=install-hook: ${asMessage(err)}`,
                });
            }
            catch {
                // best-effort
            }
            printError(`install-hook failed: ${asMessage(err)}`);
            process.exitCode = 1;
            return;
        }
        // ---------------------------------------------------------------
        // Step 4: first sync. Rolls back clone + register on failure so
        // the operator can re-try cleanly. Leaves the hook in place — the
        // hook is independently useful even if THIS source failed to
        // deploy artifacts; uninstall-hook is its own surgical action.
        // ---------------------------------------------------------------
        let syncedArtifacts = 0;
        try {
            const summary = await syncSkills({});
            syncedArtifacts = summary.artifactCount;
        }
        catch (err) {
            try {
                removeSkillSourceClone(entry.id);
                removeSkillSource(entry.id);
            }
            catch {
                // best-effort
            }
            try {
                appendTrustAudit({
                    gitUrl: redactUrl(entry.gitUrl),
                    action: 'failed',
                    trustMethod: 'flag',
                    sourceId: entry.id,
                    note: `onboard step=sync: ${asMessage(err)}`,
                });
            }
            catch {
                // best-effort
            }
            printError(`sync failed: ${asMessage(err)}`);
            process.exitCode = 1;
            return;
        }
        // ---------------------------------------------------------------
        // Single success summary covering all 4 steps.
        // ---------------------------------------------------------------
        printHeader('skills onboard — complete');
        printSuccess(`registered "${entry.name}" (${entry.id}) @ ${headSha.slice(0, 8)}`);
        printInfo('git url', entry.gitUrl);
        printInfo('branch', entry.branch);
        printInfo('clone', `(see ~/.olam/state/skill-sources/${entry.id})`);
        switch (hookStatus) {
            case 'installed':
                printInfo('hook', `installed (${scope} scope) at ${hookFilePath}`);
                if (hookBackupPath)
                    printInfo('backup', hookBackupPath);
                break;
            case 'already-present':
                printInfo('hook', `already installed at ${hookFilePath}`);
                break;
            case 'no-op':
                printInfo('hook', `no change at ${hookFilePath}`);
                break;
        }
        printInfo('sync', `${syncedArtifacts} artifact(s) deployed`);
        console.log();
        console.log(pc.dim('  Open a new Claude Code session to pick up the deployed skills.'));
    });
}
//# sourceMappingURL=skills-onboard.js.map