// src/index.ts
import { Command as Command11 } from "commander";
import { VERSION } from "@harness-engineering/core";

// src/commands/validate.ts
import { Command } from "commander";
import * as path2 from "path";
import { Ok as Ok2 } from "@harness-engineering/core";
import { validateAgentsMap, validateKnowledgeMap } from "@harness-engineering/core";

// src/config/loader.ts
import * as fs from "fs";
import * as path from "path";
import { Ok, Err } from "@harness-engineering/core";

// src/config/schema.ts
import { z } from "zod";
var LayerSchema = z.object({
  name: z.string(),
  pattern: z.string(),
  allowedDependencies: z.array(z.string())
});
var ForbiddenImportSchema = z.object({
  from: z.string(),
  disallow: z.array(z.string()),
  message: z.string().optional()
});
var BoundaryConfigSchema = z.object({
  requireSchema: z.array(z.string())
});
var AgentConfigSchema = z.object({
  executor: z.enum(["subprocess", "cloud", "noop"]).default("subprocess"),
  timeout: z.number().default(3e5),
  skills: z.array(z.string()).optional()
});
var EntropyConfigSchema = z.object({
  excludePatterns: z.array(z.string()).default(["**/node_modules/**", "**/*.test.ts"]),
  autoFix: z.boolean().default(false)
});
var HarnessConfigSchema = z.object({
  version: z.literal(1),
  name: z.string().optional(),
  rootDir: z.string().default("."),
  layers: z.array(LayerSchema).optional(),
  forbiddenImports: z.array(ForbiddenImportSchema).optional(),
  boundaries: BoundaryConfigSchema.optional(),
  agentsMapPath: z.string().default("./AGENTS.md"),
  docsDir: z.string().default("./docs"),
  agent: AgentConfigSchema.optional(),
  entropy: EntropyConfigSchema.optional()
});

// src/utils/errors.ts
var ExitCode = {
  SUCCESS: 0,
  VALIDATION_FAILED: 1,
  ERROR: 2
};
var CLIError = class extends Error {
  exitCode;
  constructor(message, exitCode = ExitCode.ERROR) {
    super(message);
    this.name = "CLIError";
    this.exitCode = exitCode;
  }
};
function formatError(error) {
  if (error instanceof CLIError) {
    return `Error: ${error.message}`;
  }
  if (error instanceof Error) {
    return `Error: ${error.message}`;
  }
  return `Error: ${String(error)}`;
}
function handleError(error) {
  const message = formatError(error);
  console.error(message);
  const exitCode = error instanceof CLIError ? error.exitCode : ExitCode.ERROR;
  process.exit(exitCode);
}

// src/config/loader.ts
var CONFIG_FILENAMES = ["harness.config.json"];
function findConfigFile(startDir = process.cwd()) {
  let currentDir = path.resolve(startDir);
  const root = path.parse(currentDir).root;
  while (currentDir !== root) {
    for (const filename of CONFIG_FILENAMES) {
      const configPath = path.join(currentDir, filename);
      if (fs.existsSync(configPath)) {
        return Ok(configPath);
      }
    }
    currentDir = path.dirname(currentDir);
  }
  return Err(new CLIError(
    'No harness.config.json found. Run "harness init" to create one.',
    ExitCode.ERROR
  ));
}
function loadConfig(configPath) {
  if (!fs.existsSync(configPath)) {
    return Err(new CLIError(
      `Config file not found: ${configPath}`,
      ExitCode.ERROR
    ));
  }
  let rawConfig;
  try {
    const content = fs.readFileSync(configPath, "utf-8");
    rawConfig = JSON.parse(content);
  } catch (error) {
    return Err(new CLIError(
      `Failed to parse config: ${error instanceof Error ? error.message : "Unknown error"}`,
      ExitCode.ERROR
    ));
  }
  const parsed = HarnessConfigSchema.safeParse(rawConfig);
  if (!parsed.success) {
    const issues = parsed.error.issues.map((i) => `  - ${i.path.join(".")}: ${i.message}`).join("\n");
    return Err(new CLIError(
      `Invalid config:
${issues}`,
      ExitCode.ERROR
    ));
  }
  return Ok(parsed.data);
}
function resolveConfig(configPath) {
  if (configPath) {
    return loadConfig(configPath);
  }
  const findResult = findConfigFile();
  if (!findResult.ok) {
    return findResult;
  }
  return loadConfig(findResult.value);
}

// src/output/formatter.ts
import chalk from "chalk";
var OutputMode = {
  JSON: "json",
  TEXT: "text",
  QUIET: "quiet",
  VERBOSE: "verbose"
};
var OutputFormatter = class {
  constructor(mode = OutputMode.TEXT) {
    this.mode = mode;
  }
  /**
   * Format raw data (for JSON mode)
   */
  format(data) {
    if (this.mode === OutputMode.JSON) {
      return JSON.stringify(data, null, 2);
    }
    return String(data);
  }
  /**
   * Format validation result
   */
  formatValidation(result) {
    if (this.mode === OutputMode.JSON) {
      return JSON.stringify(result, null, 2);
    }
    if (this.mode === OutputMode.QUIET) {
      if (result.valid) return "";
      return result.issues.map((i) => `${i.file ?? ""}: ${i.message}`).join("\n");
    }
    const lines = [];
    if (result.valid) {
      lines.push(chalk.green("v validation passed"));
    } else {
      lines.push(chalk.red(`x Validation failed (${result.issues.length} issues)`));
      lines.push("");
      for (const issue of result.issues) {
        const location = issue.file ? issue.line ? `${issue.file}:${issue.line}` : issue.file : "unknown";
        lines.push(`  ${chalk.yellow("*")} ${chalk.dim(location)}`);
        lines.push(`    ${issue.message}`);
        if (issue.suggestion && this.mode === OutputMode.VERBOSE) {
          lines.push(`    ${chalk.dim("->")} ${issue.suggestion}`);
        }
      }
    }
    return lines.join("\n");
  }
  /**
   * Format a summary line
   */
  formatSummary(label, value, success) {
    if (this.mode === OutputMode.JSON || this.mode === OutputMode.QUIET) {
      return "";
    }
    const icon = success ? chalk.green("v") : chalk.red("x");
    return `${icon} ${label}: ${value}`;
  }
};

// src/output/logger.ts
import chalk2 from "chalk";
var logger = {
  info: (message) => console.log(chalk2.blue("i"), message),
  success: (message) => console.log(chalk2.green("v"), message),
  warn: (message) => console.log(chalk2.yellow("!"), message),
  error: (message) => console.error(chalk2.red("x"), message),
  dim: (message) => console.log(chalk2.dim(message)),
  // For JSON output mode
  raw: (data) => console.log(JSON.stringify(data, null, 2))
};

// src/commands/validate.ts
async function runValidate(options) {
  const configResult = resolveConfig(options.configPath);
  if (!configResult.ok) {
    return configResult;
  }
  const config = configResult.value;
  const cwd = options.cwd ?? (options.configPath ? path2.dirname(path2.resolve(options.configPath)) : process.cwd());
  const result = {
    valid: true,
    checks: {
      agentsMap: false,
      fileStructure: false,
      knowledgeMap: false
    },
    issues: []
  };
  const agentsMapPath = path2.resolve(cwd, config.agentsMapPath);
  const agentsResult = await validateAgentsMap(agentsMapPath);
  if (agentsResult.ok) {
    result.checks.agentsMap = true;
  } else {
    result.valid = false;
    result.issues.push({
      check: "agentsMap",
      file: config.agentsMapPath,
      message: agentsResult.error.message,
      suggestion: agentsResult.error.suggestions?.[0] ?? void 0
    });
  }
  const knowledgeResult = await validateKnowledgeMap(cwd);
  if (knowledgeResult.ok && knowledgeResult.value.brokenLinks.length === 0) {
    result.checks.knowledgeMap = true;
  } else if (knowledgeResult.ok) {
    result.valid = false;
    for (const broken of knowledgeResult.value.brokenLinks) {
      result.issues.push({
        check: "knowledgeMap",
        file: broken.path,
        message: `Broken link: ${broken.path}`,
        suggestion: broken.suggestion || "Remove or fix the broken link"
      });
    }
  } else {
    result.valid = false;
    result.issues.push({
      check: "knowledgeMap",
      message: knowledgeResult.error.message
    });
  }
  result.checks.fileStructure = true;
  return Ok2(result);
}
function createValidateCommand() {
  const command = new Command("validate").description("Run all validation checks").action(async (_opts, cmd) => {
    const globalOpts = cmd.optsWithGlobals();
    const mode = globalOpts.json ? OutputMode.JSON : globalOpts.quiet ? OutputMode.QUIET : globalOpts.verbose ? OutputMode.VERBOSE : OutputMode.TEXT;
    const formatter = new OutputFormatter(mode);
    const result = await runValidate({
      configPath: globalOpts.config,
      json: globalOpts.json,
      verbose: globalOpts.verbose,
      quiet: globalOpts.quiet
    });
    if (!result.ok) {
      if (mode === OutputMode.JSON) {
        console.log(JSON.stringify({ error: result.error.message }));
      } else {
        logger.error(result.error.message);
      }
      process.exit(result.error.exitCode);
    }
    const output = formatter.formatValidation({
      valid: result.value.valid,
      issues: result.value.issues
    });
    if (output) {
      console.log(output);
    }
    process.exit(result.value.valid ? ExitCode.SUCCESS : ExitCode.VALIDATION_FAILED);
  });
  return command;
}

// src/commands/check-deps.ts
import { Command as Command2 } from "commander";
import * as path3 from "path";
import { Ok as Ok3 } from "@harness-engineering/core";
import {
  validateDependencies,
  detectCircularDepsInFiles,
  defineLayer,
  TypeScriptParser
} from "@harness-engineering/core";

// src/utils/files.ts
import { glob } from "glob";
async function findFiles(pattern, cwd = process.cwd()) {
  return glob(pattern, { cwd, absolute: true });
}

// src/commands/check-deps.ts
async function runCheckDeps(options) {
  const cwd = options.cwd ?? process.cwd();
  const configResult = resolveConfig(options.configPath);
  if (!configResult.ok) {
    return configResult;
  }
  const config = configResult.value;
  const result = {
    valid: true,
    layerViolations: [],
    circularDeps: []
  };
  if (!config.layers || config.layers.length === 0) {
    return Ok3(result);
  }
  const rootDir = path3.resolve(cwd, config.rootDir);
  const parser = new TypeScriptParser();
  const layers = config.layers.map(
    (l) => defineLayer(l.name, [l.pattern], l.allowedDependencies)
  );
  const layerConfig = {
    layers,
    rootDir,
    parser,
    fallbackBehavior: "warn"
  };
  const depsResult = await validateDependencies(layerConfig);
  if (depsResult.ok) {
    for (const violation of depsResult.value.violations) {
      result.valid = false;
      result.layerViolations.push({
        file: violation.file,
        imports: violation.imports,
        fromLayer: violation.fromLayer ?? "unknown",
        toLayer: violation.toLayer ?? "unknown",
        message: violation.reason
      });
    }
  }
  const allFiles = [];
  for (const layer of config.layers) {
    const files = await findFiles(layer.pattern, rootDir);
    allFiles.push(...files);
  }
  const uniqueFiles = [...new Set(allFiles)];
  if (uniqueFiles.length > 0) {
    const circularResult = await detectCircularDepsInFiles(uniqueFiles, parser);
    if (circularResult.ok && circularResult.value.hasCycles) {
      result.valid = false;
      for (const cycle of circularResult.value.cycles) {
        result.circularDeps.push({ cycle: cycle.cycle });
      }
    }
  }
  return Ok3(result);
}
function createCheckDepsCommand() {
  const command = new Command2("check-deps").description("Validate dependency layers and detect circular dependencies").action(async (_opts, cmd) => {
    const globalOpts = cmd.optsWithGlobals();
    const mode = globalOpts.json ? OutputMode.JSON : globalOpts.quiet ? OutputMode.QUIET : globalOpts.verbose ? OutputMode.VERBOSE : OutputMode.TEXT;
    const formatter = new OutputFormatter(mode);
    const result = await runCheckDeps({
      configPath: globalOpts.config,
      json: globalOpts.json,
      verbose: globalOpts.verbose,
      quiet: globalOpts.quiet
    });
    if (!result.ok) {
      if (mode === OutputMode.JSON) {
        console.log(JSON.stringify({ error: result.error.message }));
      } else {
        logger.error(result.error.message);
      }
      process.exit(result.error.exitCode);
    }
    const issues = [
      ...result.value.layerViolations.map((v) => ({
        file: v.file,
        message: `Layer violation: ${v.fromLayer} -> ${v.toLayer} (${v.message})`
      })),
      ...result.value.circularDeps.map((c) => ({
        message: `Circular dependency: ${c.cycle.join(" -> ")}`
      }))
    ];
    const output = formatter.formatValidation({
      valid: result.value.valid,
      issues
    });
    if (output) {
      console.log(output);
    }
    process.exit(result.value.valid ? ExitCode.SUCCESS : ExitCode.VALIDATION_FAILED);
  });
  return command;
}

// src/commands/check-docs.ts
import { Command as Command3 } from "commander";
import * as path4 from "path";
import { Ok as Ok4, Err as Err2 } from "@harness-engineering/core";
import { checkDocCoverage, validateKnowledgeMap as validateKnowledgeMap2 } from "@harness-engineering/core";
async function runCheckDocs(options) {
  const cwd = options.cwd ?? process.cwd();
  const minCoverage = options.minCoverage ?? 80;
  const configResult = resolveConfig(options.configPath);
  if (!configResult.ok) {
    return configResult;
  }
  const config = configResult.value;
  const docsDir = path4.resolve(cwd, config.docsDir);
  const sourceDir = path4.resolve(cwd, config.rootDir);
  const coverageResult = await checkDocCoverage("project", {
    docsDir,
    sourceDir,
    excludePatterns: ["**/*.test.ts", "**/*.spec.ts", "**/node_modules/**"]
  });
  if (!coverageResult.ok) {
    return Err2(new CLIError(
      `Documentation coverage check failed: ${coverageResult.error.message}`,
      ExitCode.ERROR
    ));
  }
  const knowledgeResult = await validateKnowledgeMap2(cwd);
  let brokenLinks = [];
  if (knowledgeResult.ok) {
    brokenLinks = knowledgeResult.value.brokenLinks.map((b) => b.path);
  } else {
    logger.warn(`Knowledge map validation failed: ${knowledgeResult.error.message}`);
  }
  const coveragePercent = coverageResult.value.coveragePercentage;
  const result = {
    valid: coveragePercent >= minCoverage && brokenLinks.length === 0,
    coveragePercent,
    documented: coverageResult.value.documented,
    undocumented: coverageResult.value.undocumented,
    brokenLinks
  };
  return Ok4(result);
}
function createCheckDocsCommand() {
  const command = new Command3("check-docs").description("Check documentation coverage").option("--min-coverage <percent>", "Minimum coverage percentage", "80").action(async (opts, cmd) => {
    const globalOpts = cmd.optsWithGlobals();
    const mode = globalOpts.json ? OutputMode.JSON : globalOpts.quiet ? OutputMode.QUIET : globalOpts.verbose ? OutputMode.VERBOSE : OutputMode.TEXT;
    const formatter = new OutputFormatter(mode);
    const result = await runCheckDocs({
      configPath: globalOpts.config,
      minCoverage: parseInt(opts.minCoverage, 10),
      json: globalOpts.json,
      verbose: globalOpts.verbose,
      quiet: globalOpts.quiet
    });
    if (!result.ok) {
      if (mode === OutputMode.JSON) {
        console.log(JSON.stringify({ error: result.error.message }));
      } else {
        logger.error(result.error.message);
      }
      process.exit(result.error.exitCode);
    }
    if (mode === OutputMode.JSON) {
      console.log(JSON.stringify(result.value, null, 2));
    } else if (mode !== OutputMode.QUIET) {
      const { value } = result;
      console.log(formatter.formatSummary(
        "Documentation coverage",
        `${value.coveragePercent.toFixed(1)}%`,
        value.valid
      ));
      if (value.undocumented.length > 0 && (mode === OutputMode.VERBOSE || !value.valid)) {
        console.log("\nUndocumented files:");
        for (const file of value.undocumented.slice(0, 10)) {
          console.log(`  - ${file}`);
        }
        if (value.undocumented.length > 10) {
          console.log(`  ... and ${value.undocumented.length - 10} more`);
        }
      }
      if (value.brokenLinks.length > 0) {
        console.log("\nBroken links:");
        for (const link of value.brokenLinks) {
          console.log(`  - ${link}`);
        }
      }
    }
    process.exit(result.value.valid ? ExitCode.SUCCESS : ExitCode.VALIDATION_FAILED);
  });
  return command;
}

// src/commands/init.ts
import { Command as Command4 } from "commander";
import * as fs2 from "fs";
import * as path5 from "path";
import { Ok as Ok5, Err as Err3 } from "@harness-engineering/core";

// src/templates/basic.ts
var CONFIG_TEMPLATE = (name) => ({
  version: 1,
  name,
  layers: [
    { name: "types", pattern: "src/types/**", allowedDependencies: [] },
    { name: "domain", pattern: "src/domain/**", allowedDependencies: ["types"] },
    { name: "services", pattern: "src/services/**", allowedDependencies: ["types", "domain"] },
    { name: "api", pattern: "src/api/**", allowedDependencies: ["types", "domain", "services"] }
  ],
  agentsMapPath: "./AGENTS.md",
  docsDir: "./docs"
});
var AGENTS_MD_TEMPLATE = (name) => `# ${name} Knowledge Map

## About This Project

${name} - A project using Harness Engineering practices.

## Documentation

- Main docs: \`docs/\`

## Source Code

- Entry point: \`src/index.ts\`

## Architecture

See \`docs/architecture.md\` for architectural decisions.
`;
var DOCS_INDEX_TEMPLATE = (name) => `# ${name} Documentation

Welcome to the ${name} documentation.

## Getting Started

TODO: Add getting started guide.

## Architecture

TODO: Add architecture documentation.
`;

// src/commands/init.ts
async function runInit(options) {
  const cwd = options.cwd ?? process.cwd();
  const name = options.name ?? path5.basename(cwd);
  const force = options.force ?? false;
  const configPath = path5.join(cwd, "harness.config.json");
  const agentsPath = path5.join(cwd, "AGENTS.md");
  const docsDir = path5.join(cwd, "docs");
  if (!force && fs2.existsSync(configPath)) {
    return Err3(new CLIError(
      "Project already initialized. Use --force to overwrite.",
      ExitCode.ERROR
    ));
  }
  const filesCreated = [];
  try {
    const config = CONFIG_TEMPLATE(name);
    fs2.writeFileSync(configPath, JSON.stringify(config, null, 2));
    filesCreated.push("harness.config.json");
    if (!fs2.existsSync(agentsPath) || force) {
      fs2.writeFileSync(agentsPath, AGENTS_MD_TEMPLATE(name));
      filesCreated.push("AGENTS.md");
    }
    if (!fs2.existsSync(docsDir)) {
      fs2.mkdirSync(docsDir, { recursive: true });
      fs2.writeFileSync(path5.join(docsDir, "index.md"), DOCS_INDEX_TEMPLATE(name));
      filesCreated.push("docs/index.md");
    }
    return Ok5({ filesCreated });
  } catch (error) {
    return Err3(new CLIError(
      `Failed to initialize: ${error instanceof Error ? error.message : "Unknown error"}`,
      ExitCode.ERROR
    ));
  }
}
function createInitCommand() {
  const command = new Command4("init").description("Initialize a new harness-engineering project").option("-n, --name <name>", "Project name").option("-f, --force", "Overwrite existing files").action(async (opts, cmd) => {
    const globalOpts = cmd.optsWithGlobals();
    const result = await runInit({
      name: opts.name,
      force: opts.force
    });
    if (!result.ok) {
      logger.error(result.error.message);
      process.exit(result.error.exitCode);
    }
    if (!globalOpts.quiet) {
      logger.success("Project initialized!");
      logger.info("Created files:");
      for (const file of result.value.filesCreated) {
        console.log(`  - ${file}`);
      }
      console.log("\nNext steps:");
      console.log("  1. Review harness.config.json");
      console.log("  2. Update AGENTS.md with your project structure");
      console.log('  3. Run "harness validate" to check your setup');
    }
    process.exit(ExitCode.SUCCESS);
  });
  return command;
}

// src/commands/cleanup.ts
import { Command as Command5 } from "commander";
import * as path6 from "path";
import { Ok as Ok6, Err as Err4, EntropyAnalyzer } from "@harness-engineering/core";
async function runCleanup(options) {
  const cwd = options.cwd ?? process.cwd();
  const type = options.type ?? "all";
  const configResult = resolveConfig(options.configPath);
  if (!configResult.ok) {
    return Err4(configResult.error);
  }
  const config = configResult.value;
  const result = {
    driftIssues: [],
    deadCode: [],
    patternViolations: [],
    totalIssues: 0
  };
  const rootDir = path6.resolve(cwd, config.rootDir);
  const docsDir = path6.resolve(cwd, config.docsDir);
  const entropyConfig = {
    rootDir,
    entryPoints: [path6.join(rootDir, "src/index.ts")],
    docPaths: [docsDir],
    analyze: {
      drift: type === "all" || type === "drift",
      deadCode: type === "all" || type === "dead-code",
      patterns: type === "all" || type === "patterns" ? { patterns: [] } : false
    },
    exclude: config.entropy?.excludePatterns ?? ["**/node_modules/**", "**/*.test.ts"]
  };
  const analyzer = new EntropyAnalyzer(entropyConfig);
  const analysisResult = await analyzer.analyze();
  if (!analysisResult.ok) {
    return Err4(new CLIError(
      `Entropy analysis failed: ${analysisResult.error.message}`,
      ExitCode.ERROR
    ));
  }
  const report = analysisResult.value;
  if (report.drift) {
    result.driftIssues = report.drift.drifts.map((d) => ({
      file: d.docFile,
      issue: `${d.issue}: ${d.details}`
    }));
  }
  if (report.deadCode) {
    result.deadCode = [
      ...report.deadCode.deadFiles.map((f) => ({ file: f.path })),
      ...report.deadCode.deadExports.map((e) => ({ file: e.file, symbol: e.name }))
    ];
  }
  if (report.patterns) {
    result.patternViolations = report.patterns.violations.map((v) => ({
      file: v.file,
      pattern: v.pattern,
      message: v.message
    }));
  }
  result.totalIssues = result.driftIssues.length + result.deadCode.length + result.patternViolations.length;
  return Ok6(result);
}
function createCleanupCommand() {
  const command = new Command5("cleanup").description("Detect entropy issues (doc drift, dead code, patterns)").option("-t, --type <type>", "Issue type: drift, dead-code, patterns, all", "all").action(async (opts, cmd) => {
    const globalOpts = cmd.optsWithGlobals();
    const mode = globalOpts.json ? OutputMode.JSON : globalOpts.quiet ? OutputMode.QUIET : globalOpts.verbose ? OutputMode.VERBOSE : OutputMode.TEXT;
    const formatter = new OutputFormatter(mode);
    const result = await runCleanup({
      configPath: globalOpts.config,
      type: opts.type,
      json: globalOpts.json,
      verbose: globalOpts.verbose,
      quiet: globalOpts.quiet
    });
    if (!result.ok) {
      if (mode === OutputMode.JSON) {
        console.log(JSON.stringify({ error: result.error.message }));
      } else {
        logger.error(result.error.message);
      }
      process.exit(result.error.exitCode);
    }
    if (mode === OutputMode.JSON) {
      console.log(JSON.stringify(result.value, null, 2));
    } else if (mode !== OutputMode.QUIET || result.value.totalIssues > 0) {
      console.log(formatter.formatSummary(
        "Entropy issues",
        result.value.totalIssues.toString(),
        result.value.totalIssues === 0
      ));
      if (result.value.driftIssues.length > 0) {
        console.log("\nDocumentation drift:");
        for (const issue of result.value.driftIssues) {
          console.log(`  - ${issue.file}: ${issue.issue}`);
        }
      }
      if (result.value.deadCode.length > 0) {
        console.log("\nDead code:");
        for (const item of result.value.deadCode.slice(0, 10)) {
          console.log(`  - ${item.file}${item.symbol ? `: ${item.symbol}` : ""}`);
        }
        if (result.value.deadCode.length > 10) {
          console.log(`  ... and ${result.value.deadCode.length - 10} more`);
        }
      }
      if (result.value.patternViolations.length > 0) {
        console.log("\nPattern violations:");
        for (const violation of result.value.patternViolations.slice(0, 10)) {
          console.log(`  - ${violation.file} [${violation.pattern}]: ${violation.message}`);
        }
        if (result.value.patternViolations.length > 10) {
          console.log(`  ... and ${result.value.patternViolations.length - 10} more`);
        }
      }
    }
    process.exit(result.value.totalIssues === 0 ? ExitCode.SUCCESS : ExitCode.VALIDATION_FAILED);
  });
  return command;
}

// src/commands/fix-drift.ts
import { Command as Command6 } from "commander";
import * as path7 from "path";
import {
  Ok as Ok7,
  Err as Err5,
  buildSnapshot,
  detectDocDrift,
  detectDeadCode,
  createFixes,
  applyFixes,
  generateSuggestions
} from "@harness-engineering/core";
async function runFixDrift(options) {
  const cwd = options.cwd ?? process.cwd();
  const dryRun = options.dryRun !== false;
  const configResult = resolveConfig(options.configPath);
  if (!configResult.ok) {
    return Err5(configResult.error);
  }
  const config = configResult.value;
  const rootDir = path7.resolve(cwd, config.rootDir);
  const docsDir = path7.resolve(cwd, config.docsDir);
  const entropyConfig = {
    rootDir,
    entryPoints: [path7.join(rootDir, "src/index.ts")],
    docPaths: [docsDir],
    analyze: {
      drift: true,
      deadCode: true,
      patterns: false
    },
    exclude: config.entropy?.excludePatterns ?? ["**/node_modules/**", "**/*.test.ts"]
  };
  const snapshotResult = await buildSnapshot(entropyConfig);
  if (!snapshotResult.ok) {
    return Err5(new CLIError(
      `Failed to build snapshot: ${snapshotResult.error.message}`,
      ExitCode.ERROR
    ));
  }
  const snapshot = snapshotResult.value;
  const driftResult = await detectDocDrift(snapshot);
  if (!driftResult.ok) {
    return Err5(new CLIError(
      `Failed to detect drift: ${driftResult.error.message}`,
      ExitCode.ERROR
    ));
  }
  const driftReport = driftResult.value;
  const deadCodeResult = await detectDeadCode(snapshot);
  if (!deadCodeResult.ok) {
    return Err5(new CLIError(
      `Failed to detect dead code: ${deadCodeResult.error.message}`,
      ExitCode.ERROR
    ));
  }
  const deadCodeReport = deadCodeResult.value;
  const fixes = createFixes(deadCodeReport);
  const appliedFixes = [];
  if (!dryRun && fixes.length > 0) {
    const applyResult = await applyFixes(fixes, { dryRun: false });
    if (!applyResult.ok) {
      return Err5(new CLIError(
        `Failed to apply fixes: ${applyResult.error.message}`,
        ExitCode.ERROR
      ));
    }
    for (const fix of applyResult.value.applied) {
      appliedFixes.push({
        file: fix.file,
        action: fix.action,
        applied: true
      });
    }
    for (const fix of applyResult.value.skipped) {
      appliedFixes.push({
        file: fix.file,
        action: fix.action,
        applied: false
      });
    }
    for (const { fix } of applyResult.value.errors) {
      appliedFixes.push({
        file: fix.file,
        action: fix.action,
        applied: false
      });
    }
  } else {
    for (const fix of fixes) {
      appliedFixes.push({
        file: fix.file,
        action: fix.action,
        applied: false
      });
    }
  }
  const suggestionReport = generateSuggestions(deadCodeReport, driftReport);
  const suggestions = [];
  for (const suggestion of suggestionReport.suggestions) {
    for (const file of suggestion.files) {
      suggestions.push({
        file,
        suggestion: suggestion.title
      });
    }
  }
  const result = {
    dryRun,
    fixes: appliedFixes,
    suggestions
  };
  return Ok7(result);
}
function createFixDriftCommand() {
  const command = new Command6("fix-drift").description("Auto-fix entropy issues (doc drift, dead code)").option("--no-dry-run", "Actually apply fixes (default is dry-run mode)").action(async (opts, cmd) => {
    const globalOpts = cmd.optsWithGlobals();
    const mode = globalOpts.json ? OutputMode.JSON : globalOpts.quiet ? OutputMode.QUIET : globalOpts.verbose ? OutputMode.VERBOSE : OutputMode.TEXT;
    const formatter = new OutputFormatter(mode);
    const result = await runFixDrift({
      configPath: globalOpts.config,
      dryRun: opts.dryRun,
      json: globalOpts.json,
      verbose: globalOpts.verbose,
      quiet: globalOpts.quiet
    });
    if (!result.ok) {
      if (mode === OutputMode.JSON) {
        console.log(JSON.stringify({ error: result.error.message }));
      } else {
        logger.error(result.error.message);
      }
      process.exit(result.error.exitCode);
    }
    if (mode === OutputMode.JSON) {
      console.log(JSON.stringify(result.value, null, 2));
    } else if (mode !== OutputMode.QUIET || result.value.fixes.length > 0 || result.value.suggestions.length > 0) {
      const { value } = result;
      const statusMessage = value.dryRun ? "(dry-run)" : "";
      console.log(formatter.formatSummary(
        `Fix drift ${statusMessage}`,
        `${value.fixes.length} fixes, ${value.suggestions.length} suggestions`,
        value.fixes.length === 0 && value.suggestions.length === 0
      ));
      if (value.fixes.length > 0) {
        console.log("\nFixes:");
        for (const fix of value.fixes.slice(0, 10)) {
          const status = fix.applied ? "[applied]" : "[pending]";
          console.log(`  ${status} ${fix.action}: ${fix.file}`);
        }
        if (value.fixes.length > 10) {
          console.log(`  ... and ${value.fixes.length - 10} more`);
        }
      }
      if (value.suggestions.length > 0 && (mode === OutputMode.VERBOSE || value.fixes.length === 0)) {
        console.log("\nSuggestions:");
        for (const suggestion of value.suggestions.slice(0, 10)) {
          console.log(`  - ${suggestion.file}: ${suggestion.suggestion}`);
        }
        if (value.suggestions.length > 10) {
          console.log(`  ... and ${value.suggestions.length - 10} more`);
        }
      }
      if (value.dryRun && value.fixes.length > 0) {
        console.log("\nRun with --no-dry-run to apply fixes.");
      }
    }
    process.exit(ExitCode.SUCCESS);
  });
  return command;
}

// src/commands/agent/index.ts
import { Command as Command9 } from "commander";

// src/commands/agent/run.ts
import { Command as Command7 } from "commander";
import { Ok as Ok8, Err as Err6 } from "@harness-engineering/core";
import { requestPeerReview } from "@harness-engineering/core";
async function runAgentTask(task, options) {
  const configResult = resolveConfig(options.configPath);
  if (!configResult.ok) {
    return configResult;
  }
  const agentTypeMap = {
    review: "architecture-enforcer",
    "doc-review": "documentation-maintainer",
    "test-review": "test-reviewer"
  };
  const agentType = agentTypeMap[task];
  if (!agentType) {
    return Err6(
      new CLIError(
        `Unknown task: ${task}. Available: ${Object.keys(agentTypeMap).join(", ")}`,
        ExitCode.ERROR
      )
    );
  }
  const config = configResult.value;
  const timeout = options.timeout ?? config.agent?.timeout ?? 3e5;
  const reviewResult = await requestPeerReview(
    agentType,
    {
      files: [],
      diff: "",
      commitMessage: task,
      metadata: { task, timeout }
    },
    { timeout }
  );
  if (!reviewResult.ok) {
    return Err6(
      new CLIError(`Agent task failed: ${reviewResult.error.message}`, ExitCode.ERROR)
    );
  }
  const review = reviewResult.value;
  return Ok8({
    success: review.approved,
    output: review.approved ? `Agent task '${task}' completed successfully` : `Agent task '${task}' found issues:
${review.comments.map((c) => `  - ${c.message}`).join("\n")}`
  });
}
function createRunCommand() {
  return new Command7("run").description("Run an agent task").argument("<task>", "Task to run (review, doc-review, test-review)").option("--timeout <ms>", "Timeout in milliseconds", "300000").action(async (task, opts, cmd) => {
    const globalOpts = cmd.optsWithGlobals();
    const result = await runAgentTask(task, {
      configPath: globalOpts.config,
      timeout: parseInt(opts.timeout, 10)
    });
    if (!result.ok) {
      logger.error(result.error.message);
      process.exit(result.error.exitCode);
    }
    logger.success(result.value.output);
    process.exit(ExitCode.SUCCESS);
  });
}

// src/commands/agent/review.ts
import { Command as Command8 } from "commander";
import { execSync } from "child_process";
import { Ok as Ok9, Err as Err7 } from "@harness-engineering/core";
import { createSelfReview, parseDiff } from "@harness-engineering/core";
async function runAgentReview(options) {
  const configResult = resolveConfig(options.configPath);
  if (!configResult.ok) {
    return configResult;
  }
  const config = configResult.value;
  let diff;
  try {
    diff = execSync("git diff --cached", { encoding: "utf-8" });
    if (!diff) {
      diff = execSync("git diff", { encoding: "utf-8" });
    }
  } catch {
    return Err7(new CLIError("Failed to get git diff", ExitCode.ERROR));
  }
  if (!diff) {
    return Ok9({
      passed: true,
      checklist: [{ check: "No changes to review", passed: true }]
    });
  }
  const parsedDiffResult = parseDiff(diff);
  if (!parsedDiffResult.ok) {
    return Err7(new CLIError(parsedDiffResult.error.message, ExitCode.ERROR));
  }
  const codeChanges = parsedDiffResult.value;
  const review = await createSelfReview(codeChanges, {
    rootDir: config.rootDir,
    diffAnalysis: {
      enabled: true,
      checkTestCoverage: true
    }
  });
  if (!review.ok) {
    return Err7(new CLIError(review.error.message, ExitCode.ERROR));
  }
  return Ok9({
    passed: review.value.passed,
    checklist: review.value.items.map((item) => ({
      check: item.check,
      passed: item.passed,
      details: item.details
    }))
  });
}
function createReviewCommand() {
  return new Command8("review").description("Run self-review on current changes").action(async (_opts, cmd) => {
    const globalOpts = cmd.optsWithGlobals();
    const mode = globalOpts.json ? OutputMode.JSON : globalOpts.quiet ? OutputMode.QUIET : OutputMode.TEXT;
    const result = await runAgentReview({
      configPath: globalOpts.config,
      json: globalOpts.json,
      verbose: globalOpts.verbose,
      quiet: globalOpts.quiet
    });
    if (!result.ok) {
      if (mode === OutputMode.JSON) {
        console.log(JSON.stringify({ error: result.error.message }));
      } else {
        logger.error(result.error.message);
      }
      process.exit(result.error.exitCode);
    }
    if (mode === OutputMode.JSON) {
      console.log(JSON.stringify(result.value, null, 2));
    } else if (mode !== OutputMode.QUIET) {
      console.log(result.value.passed ? "v Self-review passed" : "x Self-review found issues");
      console.log("");
      for (const item of result.value.checklist) {
        const icon = item.passed ? "v" : "x";
        console.log(`  ${icon} ${item.check}`);
        if (item.details && !item.passed) {
          console.log(`    ${item.details}`);
        }
      }
    }
    process.exit(result.value.passed ? ExitCode.SUCCESS : ExitCode.VALIDATION_FAILED);
  });
}

// src/commands/agent/index.ts
function createAgentCommand() {
  const command = new Command9("agent").description("Agent orchestration commands");
  command.addCommand(createRunCommand());
  command.addCommand(createReviewCommand());
  return command;
}

// src/commands/add.ts
import { Command as Command10 } from "commander";
import * as fs3 from "fs";
import * as path8 from "path";
import { Ok as Ok10, Err as Err8 } from "@harness-engineering/core";
var LAYER_INDEX_TEMPLATE = (name) => `// ${name} layer
// Add your ${name} exports here

export {};
`;
var MODULE_TEMPLATE = (name) => `/**
 * ${name} module
 */

export function ${name}() {
  // TODO: Implement
}
`;
var DOC_TEMPLATE = (name) => `# ${name}

## Overview

TODO: Add overview

## Usage

TODO: Add usage examples
`;
async function runAdd(componentType, name, options) {
  const cwd = options.cwd ?? process.cwd();
  const NAME_PATTERN = /^[a-zA-Z][a-zA-Z0-9_-]*$/;
  if (!name || !NAME_PATTERN.test(name)) {
    return Err8(new CLIError(
      "Invalid name. Must start with a letter and contain only alphanumeric characters, hyphens, and underscores.",
      ExitCode.ERROR
    ));
  }
  const configResult = resolveConfig(options.configPath);
  if (!configResult.ok) {
  }
  const created = [];
  try {
    switch (componentType) {
      case "layer": {
        const layerDir = path8.join(cwd, "src", name);
        if (!fs3.existsSync(layerDir)) {
          fs3.mkdirSync(layerDir, { recursive: true });
          created.push(`src/${name}/`);
        }
        const indexPath = path8.join(layerDir, "index.ts");
        if (!fs3.existsSync(indexPath)) {
          fs3.writeFileSync(indexPath, LAYER_INDEX_TEMPLATE(name));
          created.push(`src/${name}/index.ts`);
        }
        break;
      }
      case "module": {
        const modulePath = path8.join(cwd, "src", `${name}.ts`);
        if (fs3.existsSync(modulePath)) {
          return Err8(new CLIError(`Module ${name} already exists`, ExitCode.ERROR));
        }
        fs3.writeFileSync(modulePath, MODULE_TEMPLATE(name));
        created.push(`src/${name}.ts`);
        break;
      }
      case "doc": {
        const docsDir = path8.join(cwd, "docs");
        if (!fs3.existsSync(docsDir)) {
          fs3.mkdirSync(docsDir, { recursive: true });
        }
        const docPath = path8.join(docsDir, `${name}.md`);
        if (fs3.existsSync(docPath)) {
          return Err8(new CLIError(`Doc ${name} already exists`, ExitCode.ERROR));
        }
        fs3.writeFileSync(docPath, DOC_TEMPLATE(name));
        created.push(`docs/${name}.md`);
        break;
      }
      default:
        return Err8(new CLIError(
          `Unknown component type: ${componentType}. Use: layer, module, doc`,
          ExitCode.ERROR
        ));
    }
    return Ok10({ created });
  } catch (error) {
    return Err8(new CLIError(
      `Failed to add ${componentType}: ${error instanceof Error ? error.message : "Unknown error"}`,
      ExitCode.ERROR
    ));
  }
}
function createAddCommand() {
  const command = new Command10("add").description("Add a component to the project").argument("<type>", "Component type (layer, module, doc)").argument("<name>", "Component name").action(async (type, name, _opts, cmd) => {
    const globalOpts = cmd.optsWithGlobals();
    const result = await runAdd(type, name, {
      configPath: globalOpts.config
    });
    if (!result.ok) {
      logger.error(result.error.message);
      process.exit(result.error.exitCode);
    }
    if (!globalOpts.quiet) {
      logger.success(`Added ${type}: ${name}`);
      for (const file of result.value.created) {
        console.log(`  + ${file}`);
      }
    }
    process.exit(ExitCode.SUCCESS);
  });
  return command;
}

// src/index.ts
function createProgram() {
  const program = new Command11();
  program.name("harness").description("CLI for Harness Engineering toolkit").version(VERSION).option("-c, --config <path>", "Path to config file").option("--json", "Output as JSON").option("--verbose", "Verbose output").option("--quiet", "Minimal output");
  program.addCommand(createValidateCommand());
  program.addCommand(createCheckDepsCommand());
  program.addCommand(createCheckDocsCommand());
  program.addCommand(createInitCommand());
  program.addCommand(createCleanupCommand());
  program.addCommand(createFixDriftCommand());
  program.addCommand(createAgentCommand());
  program.addCommand(createAddCommand());
  return program;
}

export {
  ExitCode,
  CLIError,
  handleError,
  findConfigFile,
  loadConfig,
  resolveConfig,
  OutputMode,
  OutputFormatter,
  logger,
  createProgram
};
