import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
/**
 * /skills slash command. Lists every skill loaded by the bootstrap, with
 * its shape (single-file or bundle), priority, member counts, and any
 * active subscriptions.
 *
 * `/skills show <name>` drills into one skill: member paths, subscription
 * details, visibility setting, and any registration warnings.
 *
 * See `agents/2026-05-20-skills-unification-plan.md` step 22.
 */
import { Box, Text } from 'ink';
import React from 'react';
import { InfoField } from '../components/ui/info-field.js';
import { TitledBoxWithPreferences } from '../components/ui/titled-box.js';
import { useTerminalWidth } from '../hooks/useTerminalWidth.js';
import { useTheme } from '../hooks/useTheme.js';
import { generateKey } from '../session/key-generator.js';
import { checkSkillBundle } from '../skills/check.js';
import { applyPromotion, planPromotion, } from '../skills/promote.js';
import { findSkill, getLoadedSkills } from '../skills/skill-registry.js';
import { errorMsg, infoMsg, successMsg, warningMsg, } from '../utils/message-factory.js';
function memberCount(skill) {
    const parts = [];
    if (skill.commands?.length) {
        parts.push(`${skill.commands.length} command${skill.commands.length === 1 ? '' : 's'}`);
    }
    if (skill.subagent)
        parts.push('1 agent');
    if (skill.tools?.length) {
        parts.push(`${skill.tools.length} tool${skill.tools.length === 1 ? '' : 's'}`);
    }
    return parts.length === 0 ? 'no members' : parts.join(', ');
}
function SkillsListView({ skills }) {
    const boxWidth = useTerminalWidth();
    const { colors } = useTheme();
    if (skills.length === 0) {
        return (_jsx(TitledBoxWithPreferences, { title: "Skills", width: boxWidth, borderColor: colors.primary, paddingX: 2, paddingY: 1, flexDirection: "column", children: _jsx(Text, { color: colors.secondary, children: "No skills loaded. Drop a directory with a `skill.yaml` under .nanocoder/skills/ and restart." }) }));
    }
    const sorted = [...skills].sort((a, b) => a.name.localeCompare(b.name));
    return (_jsx(TitledBoxWithPreferences, { title: `Skills (${skills.length})`, width: boxWidth, borderColor: colors.primary, paddingX: 2, paddingY: 1, flexDirection: "column", children: sorted.map((skill, i) => (_jsxs(Box, { flexDirection: "column", marginBottom: i < sorted.length - 1 ? 1 : 0, children: [_jsxs(Box, { children: [_jsxs(Text, { color: colors.text, bold: true, children: ["\u203A ", skill.name] }), _jsxs(Text, { color: colors.secondary, children: [' ', "\u00B7 ", skill.source.shape, " / ", skill.source.priority] })] }), _jsx(Box, { marginLeft: 4, children: _jsx(Text, { color: colors.secondary, children: skill.description }) }), _jsx(Box, { marginLeft: 4, children: _jsxs(Text, { color: colors.secondary, children: [memberCount(skill), skill.subscribe?.length
                                ? ` · ${skill.subscribe.length} subscription${skill.subscribe.length === 1 ? '' : 's'}`
                                : ''] }) })] }, skill.name))) }));
}
function SkillDetailView({ skill }) {
    const boxWidth = useTerminalWidth();
    const { colors } = useTheme();
    const fields = [
        { label: 'Source', value: skill.source.rootPath ?? '(unknown)' },
        {
            label: 'Shape',
            value: `${skill.source.shape} / ${skill.source.priority}`,
        },
        ...(skill.version
            ? [
                {
                    label: 'Version',
                    value: `${skill.version}${skill.author ? ` (${skill.author})` : ''}`,
                },
            ]
            : []),
        { label: 'Tools visibility', value: skill.toolsVisibility },
    ];
    const hasMembers = !!skill.commands?.length || !!skill.subagent || !!skill.tools?.length;
    return (_jsxs(TitledBoxWithPreferences, { title: `Skill: ${skill.name}`, width: boxWidth, borderColor: colors.primary, paddingX: 2, paddingY: 1, flexDirection: "column", marginBottom: 1, children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { children: skill.description }) }), fields.map(f => (_jsx(InfoField, { label: f.label, value: f.value }, f.label))), _jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Text, { color: colors.primary, bold: true, children: "Members" }), !hasMembers ? (_jsx(Text, { color: colors.secondary, children: "(no members)" })) : (_jsxs(_Fragment, { children: [(skill.commands ?? []).map(c => (_jsxs(Text, { color: colors.secondary, children: ["\u203A command: /", c.command.fullName, " (", c.filePath, ")"] }, c.command.fullName))), skill.subagent ? (_jsxs(Text, { color: colors.secondary, children: ["\u203A agent: ", skill.subagent.subagent.name, " (", skill.subagent.filePath, ")"] })) : null, (skill.tools ?? []).map(t => (_jsxs(Text, { color: colors.secondary, children: ["\u203A tool: ", t.tool.name, " (", t.filePath, ")"] }, t.tool.name)))] }))] }), skill.subscribe?.length ? (_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Text, { color: colors.primary, bold: true, children: "Subscriptions" }), skill.subscribe.map((trig, i) => (_jsxs(Text, { color: colors.secondary, children: ["\u203A ", trig.kind, " \u2192 ", trig.target ?? '(self)', trig.confirm ? ' [confirm: plan mode]' : ''] }, `${trig.kind}-${i}`)))] })) : null] }));
}
function SkillCheckView({ report }) {
    const boxWidth = useTerminalWidth();
    const { colors } = useTheme();
    const errorCount = report.issues.filter(i => i.severity === 'error').length;
    const warningCount = report.issues.filter(i => i.severity === 'warning').length;
    const headline = report.ok
        ? `PASS · ${report.memberSummary}`
        : !report.found
            ? 'FAIL · not found'
            : `FAIL · ${errorCount} error${errorCount === 1 ? '' : 's'}${warningCount ? `, ${warningCount} warning${warningCount === 1 ? '' : 's'}` : ''}`;
    return (_jsxs(Box, { width: boxWidth, marginBottom: 1, flexDirection: "column", children: [_jsxs(Box, { marginBottom: report.issues.length > 0 ? 1 : 0, children: [_jsx(Text, { color: report.ok ? colors.success : colors.error, bold: true, children: headline }), _jsxs(Text, { color: colors.secondary, children: [" \u00B7 ", report.bundlePath] })] }), report.issues.map((issue, i) => (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { marginBottom: 1, children: [_jsxs(Text, { color: issue.severity === 'error' ? colors.error : colors.warning, children: [issue.severity === 'error' ? '✗ ' : '! ', ' '] }), _jsx(Text, { color: colors.text, children: issue.message })] }), issue.filePath ? (_jsx(Box, { marginLeft: 2, children: _jsx(Text, { color: colors.secondary, children: issue.filePath }) })) : null] }, `${issue.severity}-${i}`))), report.ok && report.issues.length === 0 ? (_jsx(Text, { color: colors.secondary, children: "No problems found. Restart nanocoder to load it." })) : null] }));
}
async function handlePromotion(direction, args) {
    const verb = direction; // 'promote' | 'demote'
    const positional = args.filter(a => !a.startsWith('--'));
    const force = args.includes('--force');
    const move = args.includes('--move');
    const name = positional[1];
    if (!name) {
        return infoMsg(`Usage: /skills ${verb} <name> [--force] [--move]\nExample: /skills ${verb} pr-reviewer\n\n--move removes the original after copying (default is copy, leaving both).`, 'skills');
    }
    const skill = findSkill(name);
    if (!skill) {
        return errorMsg(`No skill named "${name}" is loaded.`, 'skills');
    }
    const planned = planPromotion(skill, direction, process.cwd());
    if ('error' in planned) {
        return infoMsg(planned.error, 'skills');
    }
    const { plan } = planned;
    const result = await applyPromotion(plan, { force, move });
    if (result.destExists) {
        return warningMsg(`A skill already exists at ${plan.dest}.\nRe-run with --force to overwrite it:\n  /skills ${verb} ${name} --force${move ? ' --move' : ''}`, 'skills');
    }
    if (!result.ok) {
        return errorMsg(`Failed to ${verb} "${name}": ${result.error ?? 'unknown error'}`, 'skills');
    }
    const action = result.moved
        ? `Moved "${name}"`
        : `${verb === 'promote' ? 'Promoted' : 'Demoted'} "${name}"`;
    const trailer = result.moved
        ? '\nRemoved the original. Restart nanocoder to load it.'
        : '\nRestart nanocoder to load it.';
    return successMsg(`${action} (${plan.fromLevel} → ${plan.toLevel}).\n  ${plan.source}\n  → ${plan.dest}${trailer}`, 'skills');
}
export const skillsCommand = {
    name: 'skills',
    description: 'List loaded skills. Subcommands: show <name>, create <name>, check <name>, promote <name>, demote <name>.',
    handler: async (args, _messages, _metadata) => {
        if (args[0] === 'promote' || args[0] === 'demote') {
            return handlePromotion(args[0], args);
        }
        if (args[0] === 'check') {
            const name = args[1];
            if (!name) {
                return infoMsg('Usage: /skills check <name>\nExample: /skills check pr-reviewer', 'skills');
            }
            const report = await checkSkillBundle(process.cwd(), name);
            return React.createElement(SkillCheckView, {
                report,
                key: generateKey('skills'),
            });
        }
        if (args[0] === 'create') {
            // `create` is intercepted in app-util.ts before dispatch. Show usage
            // if the user reached this branch (no name supplied, or non-app
            // context like /plain mode).
            return Promise.resolve(infoMsg('Usage: /skills create <name>\nExample: /skills create pr-reviewer\n\nScaffolds a bundle directory under .nanocoder/skills/<name>/. For single-piece skills, use /commands create, /agents create, or /tools create.', 'skills'));
        }
        if (args[0] === 'show') {
            const name = args[1];
            if (!name) {
                return Promise.resolve(infoMsg('Usage: /skills show <name>', 'skills'));
            }
            const skill = findSkill(name);
            if (!skill) {
                return Promise.resolve(infoMsg(`No skill named "${name}" is loaded.`, 'skills'));
            }
            return Promise.resolve(React.createElement(SkillDetailView, {
                skill,
                key: generateKey('skills'),
            }));
        }
        return Promise.resolve(React.createElement(SkillsListView, {
            skills: getLoadedSkills(),
            key: generateKey('skills'),
        }));
    },
};
//# sourceMappingURL=skills.js.map