/**
 * @license
 * Copyright 2026 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import { CommandKind, } from './types.js';
import { MessageType, } from '../types.js';
import { disableSkill, enableSkill } from '../../utils/skillSettings.js';
import { getErrorMessage } from '../../utils/errors.js';
import { getAdminErrorMessage } from '@google/gemini-cli-core';
import { linkSkill, renderSkillActionFeedback, } from '../../utils/skillUtils.js';
import { SettingScope } from '../../config/settings.js';
import { requestConsentInteractive, skillsConsentString, } from '../../config/extensions/consent.js';
async function listAction(context, args) {
    const subArgs = args.trim().split(/\s+/);
    // Default to SHOWING descriptions. The user can hide them with 'nodesc'.
    let useShowDescriptions = true;
    let showAll = false;
    for (const arg of subArgs) {
        if (arg === 'nodesc' || arg === '--nodesc') {
            useShowDescriptions = false;
        }
        else if (arg === 'all' || arg === '--all') {
            showAll = true;
        }
    }
    const skillManager = context.services.config?.getSkillManager();
    if (!skillManager) {
        context.ui.addItem({
            type: MessageType.ERROR,
            text: 'Could not retrieve skill manager.',
        });
        return;
    }
    const skills = showAll
        ? skillManager.getAllSkills()
        : skillManager.getAllSkills().filter((s) => !s.isBuiltin);
    const skillsListItem = {
        type: MessageType.SKILLS_LIST,
        skills: skills.map((skill) => ({
            name: skill.name,
            description: skill.description,
            disabled: skill.disabled,
            location: skill.location,
            body: skill.body,
            isBuiltin: skill.isBuiltin,
        })),
        showDescriptions: useShowDescriptions,
    };
    context.ui.addItem(skillsListItem);
}
async function linkAction(context, args) {
    const parts = args.trim().split(/\s+/);
    const sourcePath = parts[0];
    if (!sourcePath) {
        context.ui.addItem({
            type: MessageType.ERROR,
            text: 'Usage: /skills link <path> [--scope user|workspace]',
        });
        return;
    }
    let scopeArg = 'user';
    if (parts.length >= 3 && parts[1] === '--scope') {
        scopeArg = parts[2];
    }
    else if (parts.length >= 2 && parts[1].startsWith('--scope=')) {
        scopeArg = parts[1].split('=')[1];
    }
    const scope = scopeArg === 'workspace' ? 'workspace' : 'user';
    try {
        await linkSkill(sourcePath, scope, (msg) => context.ui.addItem({
            type: MessageType.INFO,
            text: msg,
        }), async (skills, targetDir) => {
            const consentString = await skillsConsentString(skills, sourcePath, targetDir, true);
            return requestConsentInteractive(consentString, context.ui.setConfirmationRequest.bind(context.ui));
        });
        context.ui.addItem({
            type: MessageType.INFO,
            text: `Successfully linked skills from "${sourcePath}" (${scope}).`,
        });
        if (context.services.config) {
            await context.services.config.reloadSkills();
        }
    }
    catch (error) {
        context.ui.addItem({
            type: MessageType.ERROR,
            text: `Failed to link skills: ${getErrorMessage(error)}`,
        });
    }
}
async function disableAction(context, args) {
    const skillName = args.trim();
    if (!skillName) {
        context.ui.addItem({
            type: MessageType.ERROR,
            text: 'Please provide a skill name to disable.',
        });
        return;
    }
    const skillManager = context.services.config?.getSkillManager();
    if (skillManager?.isAdminEnabled() === false) {
        context.ui.addItem({
            type: MessageType.ERROR,
            text: getAdminErrorMessage('Agent skills', context.services.config ?? undefined),
        }, Date.now());
        return;
    }
    const skill = skillManager?.getSkill(skillName);
    if (!skill) {
        context.ui.addItem({
            type: MessageType.ERROR,
            text: `Skill "${skillName}" not found.`,
        }, Date.now());
        return;
    }
    const scope = context.services.settings.workspace.path
        ? SettingScope.Workspace
        : SettingScope.User;
    const result = disableSkill(context.services.settings, skillName, scope);
    let feedback = renderSkillActionFeedback(result, (label, path) => `${label} (${path})`);
    if (result.status === 'success' || result.status === 'no-op') {
        feedback +=
            ' You can run "/skills reload" to refresh your current instance.';
    }
    context.ui.addItem({
        type: MessageType.INFO,
        text: feedback,
    });
}
async function enableAction(context, args) {
    const skillName = args.trim();
    if (!skillName) {
        context.ui.addItem({
            type: MessageType.ERROR,
            text: 'Please provide a skill name to enable.',
        });
        return;
    }
    const skillManager = context.services.config?.getSkillManager();
    if (skillManager?.isAdminEnabled() === false) {
        context.ui.addItem({
            type: MessageType.ERROR,
            text: getAdminErrorMessage('Agent skills', context.services.config ?? undefined),
        }, Date.now());
        return;
    }
    const result = enableSkill(context.services.settings, skillName);
    let feedback = renderSkillActionFeedback(result, (label, path) => `${label} (${path})`);
    if (result.status === 'success' || result.status === 'no-op') {
        feedback +=
            ' You can run "/skills reload" to refresh your current instance.';
    }
    context.ui.addItem({
        type: MessageType.INFO,
        text: feedback,
    });
}
async function reloadAction(context) {
    const config = context.services.config;
    if (!config) {
        context.ui.addItem({
            type: MessageType.ERROR,
            text: 'Could not retrieve configuration.',
        });
        return;
    }
    const skillManager = config.getSkillManager();
    const beforeNames = new Set(skillManager.getSkills().map((s) => s.name));
    const startTime = Date.now();
    let pendingItemSet = false;
    const pendingTimeout = setTimeout(() => {
        context.ui.setPendingItem({
            type: MessageType.INFO,
            text: 'Reloading agent skills...',
        });
        pendingItemSet = true;
    }, 100);
    try {
        await config.reloadSkills();
        clearTimeout(pendingTimeout);
        if (pendingItemSet) {
            // If we showed the pending item, make sure it stays for at least 500ms
            // total to avoid a "flicker" where it appears and immediately disappears.
            const elapsed = Date.now() - startTime;
            const minVisibleDuration = 500;
            if (elapsed < minVisibleDuration) {
                await new Promise((resolve) => setTimeout(resolve, minVisibleDuration - elapsed));
            }
            context.ui.setPendingItem(null);
        }
        const afterSkills = skillManager.getSkills();
        const afterNames = new Set(afterSkills.map((s) => s.name));
        const added = afterSkills.filter((s) => !beforeNames.has(s.name));
        const removedCount = [...beforeNames].filter((name) => !afterNames.has(name)).length;
        let successText = 'Agent skills reloaded successfully.';
        const details = [];
        if (added.length > 0) {
            details.push(`${added.length} newly available skill${added.length > 1 ? 's' : ''}`);
        }
        if (removedCount > 0) {
            details.push(`${removedCount} skill${removedCount > 1 ? 's' : ''} no longer available`);
        }
        if (details.length > 0) {
            successText += ` ${details.join(' and ')}.`;
        }
        context.ui.addItem({
            type: 'info',
            text: successText,
            icon: '✓ ',
            color: 'green',
        });
    }
    catch (error) {
        clearTimeout(pendingTimeout);
        if (pendingItemSet) {
            context.ui.setPendingItem(null);
        }
        context.ui.addItem({
            type: MessageType.ERROR,
            text: `Failed to reload skills: ${error instanceof Error ? error.message : String(error)}`,
        });
    }
}
function disableCompletion(context, partialArg) {
    const skillManager = context.services.config?.getSkillManager();
    if (!skillManager) {
        return [];
    }
    return skillManager
        .getAllSkills()
        .filter((s) => !s.disabled && s.name.startsWith(partialArg))
        .map((s) => s.name);
}
function enableCompletion(context, partialArg) {
    const skillManager = context.services.config?.getSkillManager();
    if (!skillManager) {
        return [];
    }
    return skillManager
        .getAllSkills()
        .filter((s) => s.disabled && s.name.startsWith(partialArg))
        .map((s) => s.name);
}
export const skillsCommand = {
    name: 'skills',
    description: 'List, enable, disable, or reload Gemini CLI agent skills. Usage: /skills [list | disable <name> | enable <name> | reload]',
    kind: CommandKind.BUILT_IN,
    autoExecute: false,
    subCommands: [
        {
            name: 'list',
            description: 'List available agent skills. Usage: /skills list [nodesc] [all]',
            kind: CommandKind.BUILT_IN,
            action: listAction,
        },
        {
            name: 'link',
            description: 'Link an agent skill from a local path. Usage: /skills link <path> [--scope user|workspace]',
            kind: CommandKind.BUILT_IN,
            action: linkAction,
        },
        {
            name: 'disable',
            description: 'Disable a skill by name. Usage: /skills disable <name>',
            kind: CommandKind.BUILT_IN,
            action: disableAction,
            completion: disableCompletion,
        },
        {
            name: 'enable',
            description: 'Enable a disabled skill by name. Usage: /skills enable <name>',
            kind: CommandKind.BUILT_IN,
            action: enableAction,
            completion: enableCompletion,
        },
        {
            name: 'reload',
            altNames: ['refresh'],
            description: 'Reload the list of discovered skills. Usage: /skills reload',
            kind: CommandKind.BUILT_IN,
            action: reloadAction,
        },
    ],
    action: listAction,
};
//# sourceMappingURL=skillsCommand.js.map