import { existsSync, lstatSync, mkdirSync, symlinkSync, unlinkSync, } from "node:fs";
import { homedir } from "node:os";
import { dirname, join } from "node:path";
import * as p from "@clack/prompts";
import { areSkillsInstalled, getConfigPath, getLocalConfigPath, hasProjectContext, isConfigured, loadConfig, saveLocalConfig, } from "../config.js";
import { buildSkillFile, HARMONY_WORKFLOW_PROMPT } from "../skills.js";
import { detectAgents } from "./agents.js";
import { runDocsStep } from "./docs.js";
import { colors, formatPath, messages } from "./theme.js";
import { getWriteSummary, writeFilesWithProgress } from "./writer.js";
// Central skills directory for global installation
const GLOBAL_SKILLS_DIR = join(homedir(), ".agents", "skills");
// API base URL
const API_URL = "https://app.gethmy.com/api";
/**
 * Register MCP server using Claude CLI
 * Returns true if successful, false if CLI unavailable or failed
 */
async function registerMcpServer() {
    try {
        const { execSync } = await import("node:child_process");
        // Use the official CLI command to register the MCP server (npx for no global install)
        execSync("claude mcp add --transport stdio harmony -- npx -y @gethmy/mcp@latest serve", {
            stdio: "pipe",
        });
        return true;
    }
    catch {
        return false;
    }
}
/**
 * Write MCP server config directly to settings.json (fallback method)
 */
async function writeMcpConfigFallback(home) {
    const { readFileSync, writeFileSync, mkdirSync, existsSync } = await import("node:fs");
    const settingsPath = join(home, ".claude", "settings.json");
    const settingsDir = dirname(settingsPath);
    // Ensure directory exists
    if (!existsSync(settingsDir)) {
        mkdirSync(settingsDir, { recursive: true });
    }
    // Read existing settings or start fresh
    let settings = {};
    if (existsSync(settingsPath)) {
        try {
            settings = JSON.parse(readFileSync(settingsPath, "utf-8"));
        }
        catch {
            // Invalid JSON, start fresh
        }
    }
    // Merge mcpServers config
    const mcpServers = settings.mcpServers || {};
    mcpServers.harmony = {
        command: "npx",
        args: ["-y", "@gethmy/mcp@latest", "serve"],
    };
    settings.mcpServers = mcpServers;
    // Write back
    writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
}
/**
 * Validate API key by testing connectivity
 */
async function validateApiKey(apiKey, apiUrl = API_URL) {
    try {
        const response = await fetch(`${apiUrl}/v1/workspaces`, {
            method: "GET",
            headers: {
                "Content-Type": "application/json",
                "X-API-Key": apiKey,
            },
        });
        if (!response.ok) {
            const data = await response.json().catch(() => ({}));
            return {
                valid: false,
                error: data.error || `API returned ${response.status}`,
            };
        }
        // Try to get user info from /me endpoint if available
        const meResponse = await fetch(`${apiUrl}/v1/me`, {
            method: "GET",
            headers: {
                "Content-Type": "application/json",
                "X-API-Key": apiKey,
            },
        });
        if (meResponse.ok) {
            const meData = await meResponse.json();
            return { valid: true, email: meData.user?.email };
        }
        return { valid: true };
    }
    catch (error) {
        return {
            valid: false,
            error: error instanceof Error ? error.message : "Connection failed",
        };
    }
}
/**
 * Fetch workspaces from API
 */
async function fetchWorkspaces(apiKey) {
    const response = await fetch(`${API_URL}/v1/workspaces`, {
        method: "GET",
        headers: {
            "Content-Type": "application/json",
            "X-API-Key": apiKey,
        },
    });
    if (!response.ok) {
        throw new Error(`Failed to fetch workspaces: ${response.status}`);
    }
    const data = await response.json();
    return data.workspaces || [];
}
/**
 * Fetch projects from API
 */
async function fetchProjects(apiKey, workspaceId) {
    const response = await fetch(`${API_URL}/v1/workspaces/${workspaceId}/projects`, {
        method: "GET",
        headers: {
            "Content-Type": "application/json",
            "X-API-Key": apiKey,
        },
    });
    if (!response.ok) {
        throw new Error(`Failed to fetch projects: ${response.status}`);
    }
    const data = await response.json();
    return data.projects || [];
}
/**
 * Generate agent configuration files
 */
function getAgentFiles(agentId, cwd, installMode = "global") {
    const home = homedir();
    const files = [];
    const symlinks = [];
    switch (agentId) {
        case "claude": {
            // Claude Code skill files built from the central skill registry
            const skillContent = buildSkillFile("hmy", "claude");
            const planSkillContent = buildSkillFile("hmy-plan", "claude");
            if (installMode === "global") {
                // Global mode: Write skills to ~/.agents/skills/, symlink directories to ~/.claude/skills/
                files.push({
                    path: join(GLOBAL_SKILLS_DIR, "hmy", "SKILL.md"),
                    content: skillContent,
                    type: "text",
                });
                symlinks.push({
                    target: join(GLOBAL_SKILLS_DIR, "hmy"),
                    link: join(home, ".claude", "skills", "hmy"),
                });
                files.push({
                    path: join(GLOBAL_SKILLS_DIR, "hmy-plan", "SKILL.md"),
                    content: planSkillContent,
                    type: "text",
                });
                symlinks.push({
                    target: join(GLOBAL_SKILLS_DIR, "hmy-plan"),
                    link: join(home, ".claude", "skills", "hmy-plan"),
                });
            }
            else {
                // Local mode: Write skills directly to project directory
                files.push({
                    path: join(cwd, ".claude", "skills", "hmy", "SKILL.md"),
                    content: skillContent,
                    type: "text",
                });
                files.push({
                    path: join(cwd, ".claude", "skills", "hmy-plan", "SKILL.md"),
                    content: planSkillContent,
                    type: "text",
                });
            }
            // Note: MCP server registration is handled separately via `claude mcp add` CLI
            // in runSetup() after file writing, with fallback to settings.json if CLI unavailable
            break;
        }
        case "codex": {
            // AGENTS.md in project root (always local - project context)
            const agentsContent = `# Harmony Integration

This project uses Harmony for task management. When working on tasks:

## Starting Work on a Card

When given a card reference (e.g., #42 or a card name), follow this workflow:

1. Use \`harmony_get_card_by_short_id\` or \`harmony_search_cards\` to find the card
2. Move the card to "In Progress" using \`harmony_move_card\`
3. Add the "agent" label using \`harmony_add_label_to_card\`
4. Start a session with \`harmony_start_agent_session\` (agentIdentifier: "codex", agentName: "OpenAI Codex")
5. Show the card details to the user
6. Use \`harmony_generate_prompt\` to get guidance, then implement the solution
7. Update progress periodically with \`harmony_update_agent_progress\`
8. When done, call \`harmony_end_agent_session\` and move to "Review"

## Available Harmony Tools

- \`harmony_get_card\`, \`harmony_get_card_by_short_id\`, \`harmony_search_cards\` - Find cards
- \`harmony_move_card\` - Move cards between columns
- \`harmony_add_label_to_card\`, \`harmony_remove_label_from_card\` - Manage labels
- \`harmony_start_agent_session\`, \`harmony_update_agent_progress\`, \`harmony_end_agent_session\` - Track work
- \`harmony_get_board\` - Get board state
- \`harmony_generate_prompt\` - Get role-based guidance and focus areas for the card
`;
            files.push({
                path: join(cwd, "AGENTS.md"),
                content: agentsContent,
                type: "text",
            });
            // Codex prompt file
            const promptContent = `---
name: hmy
description: Start working on a Harmony card
arguments:
  - name: card
    description: Card reference (#42, UUID, or name)
    required: true
---

${HARMONY_WORKFLOW_PROMPT.replace("$ARGUMENTS", "{{card}}").replace("Your agent identifier", "codex").replace("Your agent name", "OpenAI Codex")}
`;
            if (installMode === "global") {
                // Global mode: Write prompt to central location, symlink to ~/.codex/prompts/
                files.push({
                    path: join(GLOBAL_SKILLS_DIR, "codex", "hmy.md"),
                    content: promptContent,
                    type: "text",
                });
                symlinks.push({
                    target: join(GLOBAL_SKILLS_DIR, "codex", "hmy.md"),
                    link: join(home, ".codex", "prompts", "hmy.md"),
                });
            }
            else {
                // Local mode: Write prompt directly to ~/.codex/prompts/
                files.push({
                    path: join(home, ".codex", "prompts", "hmy.md"),
                    content: promptContent,
                    type: "text",
                });
            }
            // Codex config.toml (always global)
            const tomlContent = `
# Harmony MCP Server
[mcp_servers.harmony]
command = "npx"
args = ["-y", "@gethmy/mcp@latest", "serve"]
`;
            files.push({
                path: join(home, ".codex", "config.toml"),
                content: tomlContent,
                type: "toml",
                tomlSection: "mcp_servers.harmony",
            });
            break;
        }
        case "cursor": {
            // Cursor MCP config (always project-level)
            files.push({
                path: join(cwd, ".cursor", "mcp.json"),
                content: JSON.stringify({
                    mcpServers: {
                        harmony: {
                            command: "npx",
                            args: ["-y", "@gethmy/mcp@latest", "serve"],
                        },
                    },
                }, null, 2),
                type: "json",
            });
            // Cursor rule file
            const ruleContent = `---
description: Harmony card workflow rule
globs:
  - "**/*"
alwaysApply: false
---

# Harmony Integration

When the user asks you to work on a Harmony card (references like #42, card names, or UUIDs):

${HARMONY_WORKFLOW_PROMPT.replace("$ARGUMENTS", "the card reference").replace("Your agent identifier", "cursor").replace("Your agent name", "Cursor AI")}
`;
            if (installMode === "global") {
                // Global mode: Write rule to central location, symlink to ~/.cursor/rules/
                files.push({
                    path: join(GLOBAL_SKILLS_DIR, "cursor", "harmony.mdc"),
                    content: ruleContent,
                    type: "text",
                });
                symlinks.push({
                    target: join(GLOBAL_SKILLS_DIR, "cursor", "harmony.mdc"),
                    link: join(home, ".cursor", "rules", "harmony.mdc"),
                });
            }
            else {
                // Local mode: Write rule directly to project directory
                files.push({
                    path: join(cwd, ".cursor", "rules", "harmony.mdc"),
                    content: ruleContent,
                    type: "text",
                });
            }
            break;
        }
        case "windsurf": {
            // Windsurf global MCP config (always global)
            files.push({
                path: join(home, ".codeium", "windsurf", "mcp_config.json"),
                content: JSON.stringify({
                    mcpServers: {
                        harmony: {
                            command: "npx",
                            args: ["-y", "@gethmy/mcp@latest", "serve"],
                            disabled: false,
                            alwaysAllow: [],
                        },
                    },
                }, null, 2),
                type: "json",
            });
            // Windsurf rule file
            const ruleContent = `---
trigger: model_decision
description: Activate when user asks to work on a Harmony card (references like #42, card names, or task management)
---

# Harmony Card Workflow

When working on a Harmony card:

${HARMONY_WORKFLOW_PROMPT.replace("$ARGUMENTS", "the card reference").replace("Your agent identifier", "windsurf").replace("Your agent name", "Windsurf AI")}
`;
            if (installMode === "global") {
                // Global mode: Write rule to central location, symlink to ~/.codeium/windsurf/rules/
                files.push({
                    path: join(GLOBAL_SKILLS_DIR, "windsurf", "harmony.md"),
                    content: ruleContent,
                    type: "text",
                });
                symlinks.push({
                    target: join(GLOBAL_SKILLS_DIR, "windsurf", "harmony.md"),
                    link: join(home, ".codeium", "windsurf", "rules", "harmony.md"),
                });
            }
            else {
                // Local mode: Write rule directly to project directory
                files.push({
                    path: join(cwd, ".windsurf", "rules", "harmony.md"),
                    content: ruleContent,
                    type: "text",
                });
            }
            break;
        }
    }
    return { files, symlinks };
}
/**
 * Main setup wizard with smart detection
 */
export async function runSetup(options = {}) {
    const cwd = process.cwd();
    const home = homedir();
    console.clear();
    console.log(messages.header());
    // Check existing configuration
    const existingConfig = loadConfig();
    const alreadyConfigured = isConfigured();
    const skillsStatus = areSkillsInstalled(cwd);
    const hasContext = hasProjectContext(cwd);
    // Track what we need to do
    let needsApiKey = !alreadyConfigured;
    let needsSkills = !skillsStatus.installed || options.force;
    let needsContext = !hasContext && !options.skipContext;
    // If workspace/project provided via flags, we'll set context
    if (options.workspaceId || options.projectId) {
        needsContext = true;
    }
    // Step 1: API Key
    let apiKey = options.apiKey || existingConfig.apiKey;
    let userEmail = options.userEmail || existingConfig.userEmail || undefined;
    if (needsApiKey || !apiKey || !apiKey.startsWith("hmy_")) {
        const keyInput = await p.text({
            message: "Enter your Harmony API key",
            placeholder: "hmy_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
            validate: (value) => {
                if (!value)
                    return "API key is required";
                if (!value.startsWith("hmy_"))
                    return 'API key must start with "hmy_"';
                if (value.length < 20)
                    return "API key is too short";
                return undefined;
            },
        });
        if (p.isCancel(keyInput)) {
            p.cancel("Setup cancelled");
            process.exit(0);
        }
        apiKey = keyInput;
        needsApiKey = true;
    }
    else {
        p.log.success(`Using existing API key: ${apiKey.slice(0, 8)}...`);
    }
    // Validate API key
    const spinner = p.spinner();
    spinner.start("Validating API key...");
    const validation = await validateApiKey(apiKey);
    if (!validation.valid) {
        spinner.stop(colors.error("API key validation failed"));
        p.log.error(validation.error || "Could not connect to Harmony API");
        p.log.info("Get an API key at: https://app.gethmy.com/user/keys");
        process.exit(1);
    }
    if (!userEmail) {
        userEmail = validation.email;
    }
    spinner.stop(colors.success(userEmail ? `Connected as ${userEmail}` : "API key validated"));
    // Step 2: Check if skills are already installed
    let selectedAgents = [];
    let installMode = options.installMode || "global";
    if (skillsStatus.installed && !options.force) {
        p.log.success(`Skills already installed (${skillsStatus.location})`);
        const reinstall = await p.confirm({
            message: "Reinstall skills?",
            initialValue: false,
        });
        if (p.isCancel(reinstall)) {
            p.cancel("Setup cancelled");
            process.exit(0);
        }
        needsSkills = reinstall;
    }
    if (needsSkills) {
        // Detect and select agents
        const detectedAgents = detectAgents(cwd);
        if (options.agents && options.agents.length > 0) {
            selectedAgents = options.agents;
        }
        else {
            const agentOptions = detectedAgents.map((agent) => ({
                value: agent.id,
                label: agent.name,
                hint: agent.detected
                    ? colors.success(`${agent.description} (detected)`)
                    : colors.dim(`${agent.description}`),
            }));
            const agentSelection = await p.multiselect({
                message: "Select agents to configure",
                options: agentOptions,
                initialValues: detectedAgents
                    .filter((a) => a.detected)
                    .map((a) => a.id),
                required: true,
            });
            if (p.isCancel(agentSelection)) {
                p.cancel("Setup cancelled");
                process.exit(0);
            }
            selectedAgents = agentSelection;
        }
        if (selectedAgents.length === 0) {
            p.log.warning("No agents selected. Skipping skills installation.");
            needsSkills = false;
        }
        else if (!options.installMode) {
            // Select install mode
            const modeSelection = await p.select({
                message: "Where should Harmony skills be installed?",
                options: [
                    {
                        value: "global",
                        label: "Global (shared) - Recommended",
                        hint: "Skills in ~/.agents/skills/, available in all projects",
                    },
                    {
                        value: "local",
                        label: "Local (project directory)",
                        hint: "Skills in .claude/skills/, committed to git",
                    },
                ],
                initialValue: "global",
            });
            if (p.isCancel(modeSelection)) {
                p.cancel("Setup cancelled");
                process.exit(0);
            }
            installMode = modeSelection;
        }
    }
    // Step 3: Workspace and Project Selection
    let selectedWorkspaceId = options.workspaceId;
    let selectedProjectId = options.projectId;
    let selectedWorkspaceName;
    let selectedProjectName;
    if (needsContext && !options.skipContext) {
        // Fetch workspaces
        spinner.start("Fetching workspaces...");
        let workspaces = [];
        try {
            workspaces = await fetchWorkspaces(apiKey);
            spinner.stop(colors.success(`Found ${workspaces.length} workspace(s)`));
        }
        catch (_error) {
            spinner.stop(colors.warning("Could not fetch workspaces"));
            p.log.warning("Skipping workspace/project selection. You can set this later.");
            needsContext = false;
        }
        if (needsContext && workspaces.length > 0) {
            // Select workspace
            if (!selectedWorkspaceId) {
                const workspaceOptions = workspaces.map((ws) => ({
                    value: ws.id,
                    label: ws.name,
                }));
                const workspaceSelection = await p.select({
                    message: "Select workspace",
                    options: workspaceOptions,
                });
                if (p.isCancel(workspaceSelection)) {
                    p.cancel("Setup cancelled");
                    process.exit(0);
                }
                selectedWorkspaceId = workspaceSelection;
            }
            selectedWorkspaceName = workspaces.find((w) => w.id === selectedWorkspaceId)?.name;
            // Fetch and select project
            spinner.start("Fetching projects...");
            let projects = [];
            try {
                projects = await fetchProjects(apiKey, selectedWorkspaceId);
                spinner.stop(colors.success(`Found ${projects.length} project(s)`));
            }
            catch (_error) {
                spinner.stop(colors.warning("Could not fetch projects"));
                p.log.warning("Skipping project selection. You can set this later.");
            }
            if (projects.length > 0 && !selectedProjectId) {
                const projectOptions = projects.map((proj) => ({
                    value: proj.id,
                    label: proj.name,
                    hint: proj.description
                        ? colors.dim(proj.description.slice(0, 50))
                        : undefined,
                }));
                const projectSelection = await p.select({
                    message: "Select project",
                    options: projectOptions,
                });
                if (p.isCancel(projectSelection)) {
                    p.cancel("Setup cancelled");
                    process.exit(0);
                }
                selectedProjectId = projectSelection;
                selectedProjectName = projects.find((p) => p.id === selectedProjectId)?.name;
            }
        }
    }
    // Step 4: Collect all files and symlinks to create
    const allFiles = [];
    const allSymlinks = [];
    // Always save global config if we have an API key change
    if (needsApiKey || !alreadyConfigured) {
        allFiles.push({
            path: getConfigPath(),
            content: JSON.stringify({
                apiKey,
                apiUrl: API_URL,
                userEmail: userEmail || null,
                activeWorkspaceId: null,
                activeProjectId: null,
            }, null, 2),
            type: "text", // Use text to avoid merging
        });
    }
    // Project docs scaffold / verification
    if (!options.skipDocs) {
        const docsResult = await runDocsStep(cwd);
        if (!docsResult.skipped) {
            for (const file of docsResult.files) {
                allFiles.push(file);
            }
        }
    }
    // Agent-specific files
    if (needsSkills && selectedAgents.length > 0) {
        for (const agentId of selectedAgents) {
            const { files, symlinks } = getAgentFiles(agentId, cwd, installMode);
            allFiles.push(...files);
            allSymlinks.push(...symlinks);
        }
    }
    // Step 5: Show summary
    const detectedAgents = detectAgents(cwd);
    console.log("");
    p.log.step("Summary");
    console.log("");
    console.log(`  ${colors.bold("API Key:")} ${apiKey.slice(0, 8)}...`);
    if (userEmail) {
        console.log(`  ${colors.bold("Email:")} ${userEmail}`);
    }
    if (needsSkills && selectedAgents.length > 0) {
        console.log(`  ${colors.bold("Agents:")} ${selectedAgents.map((a) => detectedAgents.find((d) => d.id === a)?.name).join(", ")}`);
        console.log(`  ${colors.bold("Install:")} ${installMode === "global" ? "Global (~/.agents/skills/)" : "Local (project)"}`);
    }
    else {
        console.log(`  ${colors.bold("Skills:")} Already installed (${skillsStatus.location || "none"})`);
    }
    if (selectedWorkspaceId) {
        console.log(`  ${colors.bold("Workspace:")} ${selectedWorkspaceName || selectedWorkspaceId}`);
    }
    if (selectedProjectId) {
        console.log(`  ${colors.bold("Project:")} ${selectedProjectName || selectedProjectId}`);
    }
    if (allFiles.length > 0) {
        const summary = getWriteSummary(allFiles, {
            force: options.force || needsSkills,
        });
        if (summary.toCreate.length > 0) {
            console.log("");
            console.log(`  ${colors.success("Files to create:")}`);
            for (const path of summary.toCreate) {
                console.log(`    ${colors.dim("\u2022")} ${path}`);
            }
        }
        if (allSymlinks.length > 0) {
            console.log("");
            console.log(`  ${colors.info("Symlinks to create:")}`);
            for (const symlink of allSymlinks) {
                console.log(`    ${colors.dim("\u{1F517}")} ${formatPath(symlink.link, home)} → ${formatPath(symlink.target, home)}`);
            }
        }
        if (summary.toUpdate.length > 0) {
            console.log("");
            console.log(`  ${colors.info("Files to update:")}`);
            for (const path of summary.toUpdate) {
                console.log(`    ${colors.dim("\u2022")} ${path}`);
            }
        }
        if (summary.toSkip.length > 0 && !options.force) {
            console.log("");
            console.log(`  ${colors.dim("Files to skip (already exist):")}`);
            for (const path of summary.toSkip) {
                console.log(`    ${colors.dim("\u2022")} ${path}`);
            }
        }
    }
    console.log("");
    // Step 6: Confirm and execute
    const shouldProceed = await p.confirm({
        message: "Proceed with setup?",
        initialValue: true,
    });
    if (p.isCancel(shouldProceed) || !shouldProceed) {
        p.cancel("Setup cancelled");
        process.exit(0);
    }
    console.log("");
    // Step 7: Write files
    // Force-write when user chose to reinstall skills — skill files are
    // package-generated content that should always match the installed version.
    if (allFiles.length > 0) {
        await writeFilesWithProgress(allFiles, {
            force: options.force || needsSkills,
        });
    }
    // Step 8: Create symlinks
    if (allSymlinks.length > 0) {
        for (const symlink of allSymlinks) {
            try {
                // Ensure parent directory exists
                const linkDir = dirname(symlink.link);
                if (!existsSync(linkDir)) {
                    mkdirSync(linkDir, { recursive: true });
                }
                // Check if link already exists
                let linkExists = false;
                try {
                    lstatSync(symlink.link);
                    linkExists = true;
                }
                catch {
                    // Link doesn't exist
                }
                if (linkExists) {
                    if (options.force) {
                        unlinkSync(symlink.link);
                    }
                    else {
                        // Skip existing symlink
                        continue;
                    }
                }
                symlinkSync(symlink.target, symlink.link);
            }
            catch {
                p.log.warning(`Failed to create symlink: ${symlink.link}`);
            }
        }
    }
    // Step 8b: Register MCP server for Claude (project-local scope)
    const claudeDetected = detectAgents(cwd).some((a) => a.id === "claude" && a.detected);
    if (claudeDetected || selectedAgents.includes("claude")) {
        const mcpRegistered = await registerMcpServer();
        if (mcpRegistered) {
            console.log(`  ${colors.success("\u2713")} ${colors.dim("MCP server registered via claude CLI")}`);
        }
        else {
            // Fallback: write directly to settings.json
            try {
                await writeMcpConfigFallback(home);
                console.log(`  ${colors.success("\u2713")} ${colors.dim(formatPath(join(home, ".claude", "settings.json"), home))} ${colors.dim("(updated)")}`);
            }
            catch {
                p.log.warning("Could not register MCP server. Run manually: claude mcp add --transport stdio harmony -- npx -y @gethmy/mcp@latest serve");
            }
        }
    }
    // Step 9: Save local context
    if (selectedWorkspaceId || selectedProjectId) {
        const localConfig = {};
        if (selectedWorkspaceId)
            localConfig.workspaceId = selectedWorkspaceId;
        if (selectedProjectId)
            localConfig.projectId = selectedProjectId;
        saveLocalConfig(localConfig, cwd);
        console.log(`  ${colors.success("\u2713")} ${colors.dim(formatPath(getLocalConfigPath(cwd), home))} ${colors.dim("(created)")}`);
    }
    // Step 10: Show completion message
    console.log("");
    p.outro(colors.success("Setup complete!"));
    console.log("");
    console.log(`  ${colors.bold("Configuration:")}`);
    console.log(`    API key:   ${formatPath(getConfigPath(), home)}`);
    if (needsSkills && selectedAgents.length > 0) {
        console.log(`    Skills:    ${installMode === "global" ? "~/.agents/skills/ (global)" : ".claude/skills/ (local)"}`);
    }
    if (selectedWorkspaceId || selectedProjectId) {
        console.log(`    Context:   ${formatPath(getLocalConfigPath(cwd), home)}`);
    }
    console.log("");
    console.log(`  ${colors.bold("Usage:")}`);
    if (!needsSkills || selectedAgents.includes("claude")) {
        console.log(`    ${colors.brand("Claude Code:")} ${colors.highlight("/hmy #42")} or ${colors.highlight("/hmy-plan")} ${colors.dim("(create or execute plans)")}`);
    }
    if (selectedAgents.includes("codex")) {
        console.log(`    ${colors.brand("Codex:")} ${colors.highlight("/prompts:hmy #42")}`);
    }
    if (selectedAgents.includes("cursor") ||
        selectedAgents.includes("windsurf")) {
        console.log(`    ${colors.brand("Cursor/Windsurf:")} MCP tools available automatically`);
    }
    console.log("");
    console.log(`  ${colors.dim("Add to new project: npx @gethmy/mcp setup")}`);
    console.log(`  ${colors.dim("Need help? Visit https://app.gethmy.com/docs/mcp")}`);
    console.log("");
}
