#!/usr/bin/env node
import {
  getAgentDefinitions,
  recompileAgents
} from "../chunk-YHCYKUA3.js";
import {
  ERROR_MESSAGES,
  INFO_MESSAGES,
  STATUS_MESSAGES,
  SUCCESS_MESSAGES
} from "../chunk-MR6OBL3B.js";
import {
  detectInstallation,
  discoverAllPluginSkills,
  getStackSkillIds,
  loadProjectConfigFromDir,
  resolveSource
} from "../chunk-TZXYBG3R.js";
import {
  parseFrontmatter
} from "../chunk-OCEFD7V6.js";
import {
  typedEntries,
  typedKeys
} from "../chunk-T4EXUIBY.js";
import {
  BaseCommand,
  EXIT_CODES
} from "../chunk-VR3CDXDT.js";
import {
  directoryExists,
  ensureDir,
  fileExists,
  glob,
  readFile,
  setVerbose,
  verbose,
  warn
} from "../chunk-LWXRUR6B.js";
import {
  CLI_BIN_NAME,
  GLOBAL_INSTALL_ROOT,
  LOCAL_SKILLS_PATH,
  STANDARD_FILES
} from "../chunk-6OWHQ7HM.js";
import "../chunk-EC3UJRKZ.js";
import {
  init_esm_shims
} from "../chunk-DHET7RCE.js";

// src/cli/commands/compile.ts
init_esm_shims();
import { Flags } from "@oclif/core";
import os from "os";
import path from "path";
async function loadSkillsFromDir(skillsDir, pathPrefix = "") {
  const skills = {};
  if (!await directoryExists(skillsDir)) {
    return skills;
  }
  const skillFiles = await glob("**/SKILL.md", skillsDir);
  for (const skillFile of skillFiles) {
    const skillPath = path.join(skillsDir, skillFile);
    const skillDir = path.dirname(skillPath);
    const relativePath = path.relative(skillsDir, skillDir);
    const skillDirName = path.basename(skillDir);
    const metadataPath = path.join(skillDir, STANDARD_FILES.METADATA_YAML);
    if (!await fileExists(metadataPath)) {
      const displayPath = pathPrefix ? `${pathPrefix}/${relativePath}/` : `${relativePath}/`;
      warn(
        `Skill '${skillDirName}' in '${displayPath}' is missing ${STANDARD_FILES.METADATA_YAML} \u2014 skipped. Add ${STANDARD_FILES.METADATA_YAML} to register it with the CLI.`
      );
      continue;
    }
    try {
      const content = await readFile(skillPath);
      const frontmatter = parseFrontmatter(content, skillPath);
      const skillName = frontmatter?.name || path.basename(skillDir);
      const canonicalId = skillName;
      const skill = {
        id: canonicalId,
        path: pathPrefix ? `${pathPrefix}/${relativePath}/` : `${relativePath}/`,
        description: frontmatter?.description || ""
      };
      skills[canonicalId] = skill;
      verbose(`  Loaded skill: ${canonicalId}`);
    } catch (error) {
      verbose(`  Failed to load skill: ${skillFile} - ${error}`);
    }
  }
  return skills;
}
async function discoverLocalProjectSkills(projectDir) {
  const localSkillsDir = path.join(projectDir, LOCAL_SKILLS_PATH);
  return loadSkillsFromDir(localSkillsDir, LOCAL_SKILLS_PATH);
}
function mergeSkills(...skillSources) {
  const merged = {};
  for (const source of skillSources) {
    for (const [id, skill] of typedEntries(source)) {
      if (skill) {
        merged[id] = skill;
      }
    }
  }
  return merged;
}
var Compile = class _Compile extends BaseCommand {
  static summary = "Compile agents using local skills and agent definitions";
  static description = "Compile agents with resolved skill references. By default, compiles to the Claude plugin directory. Use --output to compile to a custom directory.";
  static examples = [
    "<%= config.bin %> <%= command.id %>",
    "<%= config.bin %> <%= command.id %> --verbose",
    "<%= config.bin %> <%= command.id %> --output ./agents"
  ];
  static flags = {
    ...BaseCommand.baseFlags,
    verbose: Flags.boolean({
      char: "v",
      description: "Enable verbose logging",
      default: false
    }),
    "agent-source": Flags.string({
      description: "Remote agent partials source (default: local CLI)"
    }),
    output: Flags.string({
      char: "o",
      description: "Output directory for compiled agents (skips plugin mode)"
    })
  };
  async run() {
    const { flags } = await this.parse(_Compile);
    setVerbose(flags.verbose);
    if (flags.output) {
      await this.runCustomOutputCompile({
        ...flags,
        output: flags.output
      });
      return;
    }
    const installation = await detectInstallation();
    if (!installation) {
      this.error(ERROR_MESSAGES.NO_INSTALLATION, {
        exit: EXIT_CODES.ERROR
      });
    }
    if (installation.projectDir === os.homedir()) {
      this.log("Using global installation from ~/.claude-src/");
    }
    if (installation.mode === "local") {
      this.log("");
      this.log("Local Mode Compile (auto-detected)");
      this.log("");
      await this.runCustomOutputCompile({
        ...flags,
        output: installation.agentsDir
      });
    } else {
      await this.runPluginModeCompile(flags, installation);
    }
  }
  async discoverAllSkills(projectDir = process.cwd()) {
    this.log(STATUS_MESSAGES.DISCOVERING_SKILLS);
    const pluginSkills = await discoverAllPluginSkills(projectDir);
    const pluginSkillCount = typedKeys(pluginSkills).length;
    verbose(`  Found ${pluginSkillCount} skills from installed plugins`);
    const isGlobalProject = projectDir === GLOBAL_INSTALL_ROOT;
    const globalLocalSkillsDir = path.join(GLOBAL_INSTALL_ROOT, LOCAL_SKILLS_PATH);
    const globalLocalSkills = isGlobalProject ? {} : await loadSkillsFromDir(globalLocalSkillsDir, LOCAL_SKILLS_PATH);
    const globalLocalSkillCount = typedKeys(globalLocalSkills).length;
    if (globalLocalSkillCount > 0) {
      verbose(`  Found ${globalLocalSkillCount} global local skills from ~/.claude/skills/`);
    }
    const localSkills = await discoverLocalProjectSkills(projectDir);
    const localSkillCount = typedKeys(localSkills).length;
    verbose(`  Found ${localSkillCount} local skills from .claude/skills/`);
    const allSkills = mergeSkills(pluginSkills, globalLocalSkills, localSkills);
    const totalSkillCount = typedKeys(allSkills).length;
    if (totalSkillCount === 0) {
      this.log(ERROR_MESSAGES.NO_SKILLS_FOUND);
      this.error(
        `No skills found. Add skills with '${CLI_BIN_NAME} add <skill>' or create in .claude/skills/.`,
        { exit: EXIT_CODES.ERROR }
      );
    }
    if (pluginSkillCount > 0 && totalSkillCount > pluginSkillCount) {
      const localCount = totalSkillCount - pluginSkillCount;
      this.log(
        `Discovered ${totalSkillCount} skills (${pluginSkillCount} from plugins, ${localCount} local)`
      );
    } else if (pluginSkillCount > 0) {
      this.log(`Discovered ${pluginSkillCount} skills from plugins`);
    } else {
      this.log(`Discovered ${totalSkillCount} local skills`);
    }
    return { allSkills, totalSkillCount };
  }
  async resolveSourceForCompile(flags) {
    this.log(STATUS_MESSAGES.RESOLVING_SOURCE);
    try {
      const sourceConfig = await resolveSource(flags.source);
      this.log(`Source: ${sourceConfig.sourceOrigin}`);
    } catch (error) {
      this.log(ERROR_MESSAGES.FAILED_RESOLVE_SOURCE);
      this.handleError(error);
    }
  }
  async loadAgentDefsForCompile(flags) {
    const projectDir = process.cwd();
    this.log(
      flags["agent-source"] ? STATUS_MESSAGES.FETCHING_AGENT_PARTIALS : STATUS_MESSAGES.LOADING_AGENT_PARTIALS
    );
    try {
      const agentDefs = await getAgentDefinitions(flags["agent-source"], {
        projectDir
      });
      this.log(flags["agent-source"] ? "Agent partials fetched" : "Agent partials loaded");
      verbose(`  Agents: ${agentDefs.agentsDir}`);
      verbose(`  Templates: ${agentDefs.templatesDir}`);
      return agentDefs;
    } catch (error) {
      this.log(ERROR_MESSAGES.FAILED_LOAD_AGENT_PARTIALS);
      return this.handleError(error);
    }
  }
  async runPluginModeCompile(flags, installation) {
    this.log("");
    this.log("Plugin Mode Compile");
    this.log("");
    const projectDir = installation.projectDir;
    const agentsDir = installation.agentsDir;
    this.log("Using individual plugin mode");
    verbose(`  Project: ${projectDir}`);
    verbose(`  Agents: ${agentsDir}`);
    const loaded = await loadProjectConfigFromDir(projectDir);
    if (loaded) {
      const config = loaded.config;
      const agentCount = config.agents?.length ?? 0;
      const stackSkillCount = config.stack ? getStackSkillIds(config.stack).length : 0;
      this.log(`Using config (${agentCount} agents, ${stackSkillCount} skills)`);
      verbose(`  Config: ${loaded.configPath}`);
    } else {
      verbose(`  No config found - using defaults`);
    }
    const { allSkills } = await this.discoverAllSkills(projectDir);
    await this.resolveSourceForCompile(flags);
    const agentDefs = await this.loadAgentDefsForCompile(flags);
    this.log(STATUS_MESSAGES.RECOMPILING_AGENTS);
    try {
      const recompileResult = await recompileAgents({
        pluginDir: projectDir,
        sourcePath: agentDefs.sourcePath,
        skills: allSkills,
        projectDir,
        outputDir: agentsDir
      });
      if (recompileResult.failed.length > 0) {
        this.log(
          `Recompiled ${recompileResult.compiled.length} agents (${recompileResult.failed.length} failed)`
        );
        for (const warning of recompileResult.warnings) {
          this.warn(warning);
        }
      } else if (recompileResult.compiled.length > 0) {
        this.log(`Recompiled ${recompileResult.compiled.length} agents`);
      } else {
        this.log(INFO_MESSAGES.NO_AGENTS_TO_RECOMPILE);
      }
      if (recompileResult.compiled.length > 0) {
        verbose(`  Compiled: ${recompileResult.compiled.join(", ")}`);
      }
    } catch (error) {
      this.log(ERROR_MESSAGES.FAILED_COMPILE_AGENTS);
      this.handleError(error);
    }
    this.log("");
    this.logSuccess(SUCCESS_MESSAGES.PLUGIN_COMPILE_COMPLETE);
    this.log("");
  }
  async runCustomOutputCompile(flags) {
    const outputDir = path.resolve(process.cwd(), flags.output);
    this.log("");
    this.log("Custom Output Compile");
    this.log("");
    this.log(`Output directory: ${outputDir}`);
    this.log("");
    await ensureDir(outputDir);
    const { allSkills } = await this.discoverAllSkills();
    await this.resolveSourceForCompile(flags);
    const agentDefs = await this.loadAgentDefsForCompile(flags);
    const projectDir = process.cwd();
    this.log(STATUS_MESSAGES.COMPILING_AGENTS);
    try {
      const recompileResult = await recompileAgents({
        pluginDir: projectDir,
        sourcePath: agentDefs.sourcePath,
        skills: allSkills,
        outputDir,
        projectDir
      });
      if (recompileResult.failed.length > 0) {
        this.log(
          `Compiled ${recompileResult.compiled.length} agents (${recompileResult.failed.length} failed)`
        );
        for (const warning of recompileResult.warnings) {
          this.warn(warning);
        }
      } else if (recompileResult.compiled.length > 0) {
        this.log(`Compiled ${recompileResult.compiled.length} agents`);
      } else {
        this.log(INFO_MESSAGES.NO_AGENTS_TO_COMPILE);
      }
      if (recompileResult.compiled.length > 0) {
        verbose(`  Compiled: ${recompileResult.compiled.join(", ")}`);
        this.log("");
        this.log("Agents compiled to:");
        this.log(`  ${outputDir}`);
        for (const agentName of recompileResult.compiled) {
          this.log(`    ${agentName}.md`);
        }
      }
    } catch (error) {
      this.log(ERROR_MESSAGES.FAILED_COMPILE_AGENTS);
      this.handleError(error);
    }
    this.log("");
    this.logSuccess(SUCCESS_MESSAGES.CUSTOM_COMPILE_COMPLETE);
    this.log("");
  }
};
export {
  Compile as default
};
//# sourceMappingURL=compile.js.map