@harness-engineering/cli 1.24.1 → 1.24.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/dist/{agents-md-MMVRF77L.js → agents-md-PBKKTSQY.js} +1 -1
  2. package/dist/{architecture-JAEDPYQZ.js → architecture-FBSLURIB.js} +3 -3
  3. package/dist/{assess-project-7JZCVM7D.js → assess-project-74UVWPMB.js} +1 -1
  4. package/dist/bin/harness-mcp.js +13 -13
  5. package/dist/bin/harness.js +18 -17
  6. package/dist/{check-phase-gate-YQHAH4LL.js → check-phase-gate-WY6UICCL.js} +3 -3
  7. package/dist/{chunk-MS6KDQW7.js → chunk-3VYWO6QN.js} +6 -6
  8. package/dist/chunk-3XAPHB2Z.js +43 -0
  9. package/dist/{chunk-AVVJ5EUU.js → chunk-5PMRARB5.js} +1 -1
  10. package/dist/{chunk-NU3BPEDR.js → chunk-A737JDL4.js} +2 -2
  11. package/dist/{chunk-IDZNPTYD.js → chunk-EPUKTTJZ.js} +6 -1
  12. package/dist/{chunk-2DAMN7ED.js → chunk-FJYP32IV.js} +6 -6
  13. package/dist/{chunk-PCWYYFBP.js → chunk-H4U2QNY2.js} +32 -6
  14. package/dist/{chunk-C5FTJ3EU.js → chunk-L5UONZ53.js} +58 -1
  15. package/dist/{chunk-LY3YVKXL.js → chunk-O6UF33QH.js} +351 -104
  16. package/dist/{chunk-W2OZK3KC.js → chunk-SPTKLCKC.js} +1 -1
  17. package/dist/{chunk-TUJAHI22.js → chunk-TB427QOK.js} +5 -5
  18. package/dist/{chunk-HVFCCARH.js → chunk-UFQQBGC3.js} +1 -1
  19. package/dist/{chunk-JGMCHJ6B.js → chunk-V2FGX2KD.js} +3 -3
  20. package/dist/{chunk-JT732X6S.js → chunk-WEN5Z7CL.js} +2 -2
  21. package/dist/{chunk-BWWNQPPO.js → chunk-YPKKEP3O.js} +4 -4
  22. package/dist/{chunk-ZKVLBOYA.js → chunk-ZAMT24QN.js} +426 -383
  23. package/dist/{ci-workflow-HDH4LCOF.js → ci-workflow-QZRHAIO2.js} +1 -1
  24. package/dist/{dist-TZQUURSP.js → dist-7EBSGAHX.js} +3 -1
  25. package/dist/{docs-6SPJYTRR.js → docs-H34GBVRS.js} +4 -4
  26. package/dist/{engine-CSITRE3J.js → engine-VUQEAJFZ.js} +1 -1
  27. package/dist/{entropy-FZP643BK.js → entropy-ZAY73R6A.js} +3 -3
  28. package/dist/{feedback-RSPUJCJJ.js → feedback-TMEGYMWU.js} +2 -2
  29. package/dist/{generate-agent-definitions-OLYWXTYH.js → generate-agent-definitions-PQPG6SX5.js} +1 -1
  30. package/dist/index.d.ts +8 -8
  31. package/dist/index.js +23 -21
  32. package/dist/{loader-P2P7CV2A.js → loader-Y6A42WBD.js} +1 -1
  33. package/dist/{mcp-JZG22CYT.js → mcp-LCHC4NZ5.js} +13 -13
  34. package/dist/{performance-VVWOIJTE.js → performance-N67YJJDG.js} +4 -4
  35. package/dist/{review-pipeline-XSRO7HYZ.js → review-pipeline-YXF5ITL2.js} +4 -1
  36. package/dist/{runtime-VMOIIP6B.js → runtime-XNJUJCSG.js} +1 -1
  37. package/dist/scan-U67OKDRS.js +8 -0
  38. package/dist/{security-4AQ46P3H.js → security-L2YN3CTI.js} +1 -1
  39. package/dist/{validate-T7UTXLEQ.js → validate-MNE25KLZ.js} +2 -2
  40. package/dist/{validate-cross-check-M4NP2UF5.js → validate-cross-check-Y4PDR63C.js} +1 -1
  41. package/package.json +5 -5
@@ -1,6 +1,12 @@
1
+ import {
2
+ generateAgentsMd
3
+ } from "./chunk-I4QR3HNH.js";
1
4
  import {
2
5
  generateCIWorkflow
3
6
  } from "./chunk-LOUH2LIC.js";
7
+ import {
8
+ TemplateEngine
9
+ } from "./chunk-FP53DDB5.js";
4
10
  import {
5
11
  generate,
6
12
  validate
@@ -8,9 +14,6 @@ import {
8
14
  import {
9
15
  generateRuntime
10
16
  } from "./chunk-LM5Z2WCA.js";
11
- import {
12
- generateAgentsMd
13
- } from "./chunk-I4QR3HNH.js";
14
17
  import {
15
18
  runPersona
16
19
  } from "./chunk-GISMXMVL.js";
@@ -25,7 +28,7 @@ import {
25
28
  OutputMode,
26
29
  createCheckPhaseGateCommand,
27
30
  findFiles
28
- } from "./chunk-W2OZK3KC.js";
31
+ } from "./chunk-SPTKLCKC.js";
29
32
  import {
30
33
  createGenerateAgentDefinitionsCommand,
31
34
  generateAgentDefinitions
@@ -38,8 +41,8 @@ import {
38
41
  loadPersona
39
42
  } from "./chunk-YDRB55Q4.js";
40
43
  import {
41
- TemplateEngine
42
- } from "./chunk-FP53DDB5.js";
44
+ createScanCommand
45
+ } from "./chunk-3XAPHB2Z.js";
43
46
  import {
44
47
  appendFrameworkAgents,
45
48
  captureHealthSnapshot,
@@ -53,11 +56,11 @@ import {
53
56
  loadOrRebuildIndex,
54
57
  persistToolingConfig,
55
58
  recommend
56
- } from "./chunk-LY3YVKXL.js";
59
+ } from "./chunk-O6UF33QH.js";
57
60
  import {
58
61
  findConfigFile,
59
62
  resolveConfig
60
- } from "./chunk-AVVJ5EUU.js";
63
+ } from "./chunk-5PMRARB5.js";
61
64
  import {
62
65
  VALID_PLATFORMS
63
66
  } from "./chunk-3ISINLYT.js";
@@ -137,7 +140,7 @@ import {
137
140
  validateKnowledgeMap,
138
141
  writeConfig,
139
142
  writeLockfile
140
- } from "./chunk-PCWYYFBP.js";
143
+ } from "./chunk-H4U2QNY2.js";
141
144
  import {
142
145
  Err,
143
146
  Ok
@@ -158,7 +161,7 @@ import {
158
161
  } from "./chunk-3WGJMBKH.js";
159
162
 
160
163
  // src/index.ts
161
- import { Command as Command80 } from "commander";
164
+ import { Command as Command79 } from "commander";
162
165
 
163
166
  // src/commands/add.ts
164
167
  import { Command } from "commander";
@@ -346,7 +349,7 @@ function registerSkillsCommand(adoption) {
346
349
  const globalOpts = cmd.optsWithGlobals();
347
350
  const limit = Math.max(parseInt(opts.limit, 10) || 20, 1);
348
351
  const cwd = process.cwd();
349
- const { readAdoptionRecords, aggregateBySkill } = await import("./dist-TZQUURSP.js");
352
+ const { readAdoptionRecords, aggregateBySkill } = await import("./dist-7EBSGAHX.js");
350
353
  const records = readAdoptionRecords(cwd);
351
354
  if (records.length === 0) {
352
355
  if (globalOpts.json) {
@@ -382,7 +385,7 @@ function registerRecentCommand(adoption) {
382
385
  const globalOpts = cmd.optsWithGlobals();
383
386
  const limit = Math.max(parseInt(opts.limit, 10) || 20, 1);
384
387
  const cwd = process.cwd();
385
- const { readAdoptionRecords } = await import("./dist-TZQUURSP.js");
388
+ const { readAdoptionRecords } = await import("./dist-7EBSGAHX.js");
386
389
  const records = readAdoptionRecords(cwd);
387
390
  if (records.length === 0) {
388
391
  if (globalOpts.json) {
@@ -419,7 +422,7 @@ function registerSkillCommand(adoption) {
419
422
  adoption.command("skill <name>").description("Show detail for a specific skill").action(async (name, _opts, cmd) => {
420
423
  const globalOpts = cmd.optsWithGlobals();
421
424
  const cwd = process.cwd();
422
- const { readAdoptionRecords, aggregateBySkill } = await import("./dist-TZQUURSP.js");
425
+ const { readAdoptionRecords, aggregateBySkill } = await import("./dist-7EBSGAHX.js");
423
426
  const records = readAdoptionRecords(cwd);
424
427
  const skillRecords = records.filter((r) => r.skill === name);
425
428
  if (skillRecords.length === 0) {
@@ -1899,7 +1902,7 @@ function runDashboard(opts) {
1899
1902
  const clientPort = Number(opts.port ?? DEFAULT_CLIENT_PORT);
1900
1903
  const apiPort = Number(opts.apiPort ?? DEFAULT_API_PORT);
1901
1904
  const projectPath = resolve10(opts.cwd ?? process.cwd());
1902
- const url = `http://localhost:${clientPort}`;
1905
+ const url = `http://localhost:${apiPort}`;
1903
1906
  const server = resolveServerScript();
1904
1907
  if (!server) {
1905
1908
  console.error("Could not locate the dashboard server. Run `pnpm build` in packages/dashboard.");
@@ -2495,7 +2498,7 @@ function createGenerateCommand() {
2495
2498
  }
2496
2499
 
2497
2500
  // src/commands/graph/index.ts
2498
- import { Command as Command24 } from "commander";
2501
+ import { Command as Command23 } from "commander";
2499
2502
 
2500
2503
  // src/commands/graph/status.ts
2501
2504
  import * as path14 from "path";
@@ -2570,54 +2573,15 @@ async function runGraphExport(projectPath, format) {
2570
2573
  }
2571
2574
 
2572
2575
  // src/commands/graph/index.ts
2573
- import * as path19 from "path";
2576
+ import * as path18 from "path";
2574
2577
 
2575
- // src/commands/graph/scan.ts
2578
+ // src/commands/graph/query.ts
2576
2579
  import { Command as Command21 } from "commander";
2577
2580
  import * as path16 from "path";
2578
- async function runScan(projectPath) {
2579
- const { GraphStore, CodeIngestor, TopologicalLinker, KnowledgeIngestor, GitIngestor } = await import("./dist-QW5G3GX3.js");
2580
- const store = new GraphStore();
2581
- const start = Date.now();
2582
- await new CodeIngestor(store).ingest(projectPath);
2583
- new TopologicalLinker(store).link();
2584
- const knowledgeIngestor = new KnowledgeIngestor(store);
2585
- await knowledgeIngestor.ingestAll(projectPath);
2586
- try {
2587
- await new GitIngestor(store).ingest(projectPath);
2588
- } catch {
2589
- }
2590
- const graphDir = path16.join(projectPath, ".harness", "graph");
2591
- await store.save(graphDir);
2592
- return { nodeCount: store.nodeCount, edgeCount: store.edgeCount, durationMs: Date.now() - start };
2593
- }
2594
- function createScanCommand() {
2595
- return new Command21("scan").description("Scan project and build knowledge graph").argument("[path]", "Project root path", ".").action(async (inputPath, _opts, cmd) => {
2596
- const projectPath = path16.resolve(inputPath);
2597
- const globalOpts = cmd.optsWithGlobals();
2598
- try {
2599
- const result = await runScan(projectPath);
2600
- if (globalOpts.json) {
2601
- console.log(JSON.stringify(result));
2602
- } else {
2603
- console.log(
2604
- `Graph built: ${result.nodeCount} nodes, ${result.edgeCount} edges (${result.durationMs}ms)`
2605
- );
2606
- }
2607
- } catch (err) {
2608
- console.error("Scan failed:", err instanceof Error ? err.message : err);
2609
- process.exit(2);
2610
- }
2611
- });
2612
- }
2613
-
2614
- // src/commands/graph/query.ts
2615
- import { Command as Command22 } from "commander";
2616
- import * as path17 from "path";
2617
2581
  async function runQuery(projectPath, rootNodeId, opts) {
2618
2582
  const { GraphStore, ContextQL } = await import("./dist-QW5G3GX3.js");
2619
2583
  const store = new GraphStore();
2620
- const graphDir = path17.join(projectPath, ".harness", "graph");
2584
+ const graphDir = path16.join(projectPath, ".harness", "graph");
2621
2585
  const loaded = await store.load(graphDir);
2622
2586
  if (!loaded) throw new Error("No graph found. Run `harness scan` first.");
2623
2587
  const params = {
@@ -2639,7 +2603,7 @@ function printQueryResult(result) {
2639
2603
  }
2640
2604
  }
2641
2605
  async function runQueryAction(rootNodeId, opts, globalOpts) {
2642
- const projectPath = path17.resolve(globalOpts.config ? path17.dirname(globalOpts.config) : ".");
2606
+ const projectPath = path16.resolve(globalOpts.config ? path16.dirname(globalOpts.config) : ".");
2643
2607
  try {
2644
2608
  const result = await runQuery(projectPath, rootNodeId, {
2645
2609
  depth: parseInt(opts.depth),
@@ -2658,18 +2622,18 @@ async function runQueryAction(rootNodeId, opts, globalOpts) {
2658
2622
  }
2659
2623
  }
2660
2624
  function createQueryCommand() {
2661
- return new Command22("query").description("Query the knowledge graph").argument("<rootNodeId>", "Starting node ID").option("--depth <n>", "Max traversal depth", "3").option("--types <types>", "Comma-separated node types to include").option("--edges <edges>", "Comma-separated edge types to include").option("--bidirectional", "Traverse both directions").action(async (rootNodeId, opts, cmd) => {
2625
+ return new Command21("query").description("Query the knowledge graph").argument("<rootNodeId>", "Starting node ID").option("--depth <n>", "Max traversal depth", "3").option("--types <types>", "Comma-separated node types to include").option("--edges <edges>", "Comma-separated edge types to include").option("--bidirectional", "Traverse both directions").action(async (rootNodeId, opts, cmd) => {
2662
2626
  await runQueryAction(rootNodeId, opts, cmd.optsWithGlobals());
2663
2627
  });
2664
2628
  }
2665
2629
 
2666
2630
  // src/commands/graph/ingest.ts
2667
- import { Command as Command23 } from "commander";
2668
- import * as path18 from "path";
2631
+ import { Command as Command22 } from "commander";
2632
+ import * as path17 from "path";
2669
2633
  async function loadConnectorConfig(projectPath, source) {
2670
2634
  try {
2671
2635
  const fs36 = await import("fs/promises");
2672
- const configPath = path18.join(projectPath, "harness.config.json");
2636
+ const configPath = path17.join(projectPath, "harness.config.json");
2673
2637
  const config = JSON.parse(await fs36.readFile(configPath, "utf-8"));
2674
2638
  const connector = config.graph?.connectors?.[source];
2675
2639
  return connector ?? {};
@@ -2710,7 +2674,7 @@ async function runIngest(projectPath, source, opts) {
2710
2674
  CIConnector,
2711
2675
  ConfluenceConnector
2712
2676
  } = await import("./dist-QW5G3GX3.js");
2713
- const graphDir = path18.join(projectPath, ".harness", "graph");
2677
+ const graphDir = path17.join(projectPath, ".harness", "graph");
2714
2678
  const store = new GraphStore();
2715
2679
  await store.load(graphDir);
2716
2680
  if (opts?.all) {
@@ -2777,7 +2741,7 @@ async function runIngest(projectPath, source, opts) {
2777
2741
  return result;
2778
2742
  }
2779
2743
  function createIngestCommand() {
2780
- return new Command23("ingest").description("Ingest data into the knowledge graph").option(
2744
+ return new Command22("ingest").description("Ingest data into the knowledge graph").option(
2781
2745
  "--source <name>",
2782
2746
  "Source to ingest (code, knowledge, git, jira, slack, ci, confluence)"
2783
2747
  ).option("--all", "Run all sources (code, knowledge, git, and configured connectors)").option("--full", "Force full re-ingestion").action(async (opts, cmd) => {
@@ -2786,7 +2750,7 @@ function createIngestCommand() {
2786
2750
  process.exit(1);
2787
2751
  }
2788
2752
  const globalOpts = cmd.optsWithGlobals();
2789
- const projectPath = path18.resolve(globalOpts.config ? path18.dirname(globalOpts.config) : ".");
2753
+ const projectPath = path17.resolve(globalOpts.config ? path17.dirname(globalOpts.config) : ".");
2790
2754
  try {
2791
2755
  const result = await runIngest(projectPath, opts.source ?? "", {
2792
2756
  full: opts.full,
@@ -2809,7 +2773,7 @@ function createIngestCommand() {
2809
2773
 
2810
2774
  // src/commands/graph/index.ts
2811
2775
  function resolveProjectPath(globalOpts) {
2812
- return path19.resolve(globalOpts.config ? path19.dirname(globalOpts.config) : ".");
2776
+ return path18.resolve(globalOpts.config ? path18.dirname(globalOpts.config) : ".");
2813
2777
  }
2814
2778
  function printGraphStatus(result) {
2815
2779
  if (result.status === "no_graph") {
@@ -2853,19 +2817,19 @@ async function runExportAction(opts, cmd) {
2853
2817
  }
2854
2818
  }
2855
2819
  function createGraphCommand() {
2856
- const graph = new Command24("graph").description("Knowledge graph management");
2820
+ const graph = new Command23("graph").description("Knowledge graph management");
2857
2821
  graph.command("status").description("Show graph statistics").action(runStatusAction);
2858
2822
  graph.command("export").description("Export graph").requiredOption("--format <format>", "Output format (json, mermaid)").action(runExportAction);
2859
2823
  return graph;
2860
2824
  }
2861
2825
 
2862
2826
  // src/commands/hooks/index.ts
2863
- import { Command as Command29 } from "commander";
2827
+ import { Command as Command28 } from "commander";
2864
2828
 
2865
2829
  // src/commands/hooks/init.ts
2866
- import { Command as Command25 } from "commander";
2830
+ import { Command as Command24 } from "commander";
2867
2831
  import * as fs6 from "fs";
2868
- import * as path20 from "path";
2832
+ import * as path19 from "path";
2869
2833
  import { fileURLToPath as fileURLToPath2 } from "url";
2870
2834
 
2871
2835
  // src/hooks/profiles.ts
@@ -2895,10 +2859,10 @@ var PROFILES = {
2895
2859
 
2896
2860
  // src/commands/hooks/init.ts
2897
2861
  var __filename2 = fileURLToPath2(import.meta.url);
2898
- var __dirname2 = path20.dirname(__filename2);
2862
+ var __dirname2 = path19.dirname(__filename2);
2899
2863
  var VALID_PROFILES = ["minimal", "standard", "strict"];
2900
2864
  function resolveHookSourceDir() {
2901
- const candidate = path20.resolve(__dirname2, "..", "..", "hooks");
2865
+ const candidate = path19.resolve(__dirname2, "..", "..", "hooks");
2902
2866
  if (fs6.existsSync(candidate)) {
2903
2867
  return candidate;
2904
2868
  }
@@ -2927,12 +2891,12 @@ function mergeSettings(existing, hooksConfig) {
2927
2891
  }
2928
2892
  function initHooks(options) {
2929
2893
  const { profile, projectDir } = options;
2930
- const hooksDestDir = path20.join(projectDir, ".harness", "hooks");
2894
+ const hooksDestDir = path19.join(projectDir, ".harness", "hooks");
2931
2895
  fs6.mkdirSync(hooksDestDir, { recursive: true });
2932
2896
  if (fs6.existsSync(hooksDestDir)) {
2933
2897
  for (const entry of fs6.readdirSync(hooksDestDir)) {
2934
2898
  if (entry.endsWith(".js")) {
2935
- fs6.unlinkSync(path20.join(hooksDestDir, entry));
2899
+ fs6.unlinkSync(path19.join(hooksDestDir, entry));
2936
2900
  }
2937
2901
  }
2938
2902
  }
@@ -2941,18 +2905,18 @@ function initHooks(options) {
2941
2905
  const activeNames = PROFILES[profile];
2942
2906
  const activeScripts = HOOK_SCRIPTS.filter((h) => activeNames.includes(h.name));
2943
2907
  for (const script of activeScripts) {
2944
- const srcFile = path20.join(sourceDir, `${script.name}.js`);
2945
- const destFile = path20.join(hooksDestDir, `${script.name}.js`);
2908
+ const srcFile = path19.join(sourceDir, `${script.name}.js`);
2909
+ const destFile = path19.join(hooksDestDir, `${script.name}.js`);
2946
2910
  if (fs6.existsSync(srcFile)) {
2947
2911
  fs6.copyFileSync(srcFile, destFile);
2948
2912
  copiedScripts.push(script.name);
2949
2913
  }
2950
2914
  }
2951
- const profilePath = path20.join(hooksDestDir, "profile.json");
2915
+ const profilePath = path19.join(hooksDestDir, "profile.json");
2952
2916
  fs6.writeFileSync(profilePath, JSON.stringify({ profile }, null, 2) + "\n");
2953
- const claudeDir = path20.join(projectDir, ".claude");
2917
+ const claudeDir = path19.join(projectDir, ".claude");
2954
2918
  fs6.mkdirSync(claudeDir, { recursive: true });
2955
- const settingsPath = path20.join(claudeDir, "settings.json");
2919
+ const settingsPath = path19.join(claudeDir, "settings.json");
2956
2920
  let existing = {};
2957
2921
  if (fs6.existsSync(settingsPath)) {
2958
2922
  try {
@@ -2970,7 +2934,7 @@ function initHooks(options) {
2970
2934
  return { copiedScripts, settingsPath, profilePath };
2971
2935
  }
2972
2936
  function createInitCommand2() {
2973
- return new Command25("init").description("Install Claude Code hook configurations into the current project").option("--profile <profile>", "Hook profile: minimal, standard, or strict", "standard").action(async (opts, cmd) => {
2937
+ return new Command24("init").description("Install Claude Code hook configurations into the current project").option("--profile <profile>", "Hook profile: minimal, standard, or strict", "standard").action(async (opts, cmd) => {
2974
2938
  const globalOpts = cmd.optsWithGlobals();
2975
2939
  const profile = opts.profile;
2976
2940
  if (!VALID_PROFILES.includes(profile)) {
@@ -2994,7 +2958,7 @@ function createInitCommand2() {
2994
2958
  `Installed ${result.copiedScripts.length} hook scripts to .harness/hooks/`
2995
2959
  );
2996
2960
  logger.info(`Profile: ${profile}`);
2997
- logger.info(`Settings: ${path20.relative(projectDir, result.settingsPath)}`);
2961
+ logger.info(`Settings: ${path19.relative(projectDir, result.settingsPath)}`);
2998
2962
  logger.dim("Run 'harness hooks list' to see installed hooks");
2999
2963
  }
3000
2964
  } catch (err) {
@@ -3006,12 +2970,12 @@ function createInitCommand2() {
3006
2970
  }
3007
2971
 
3008
2972
  // src/commands/hooks/list.ts
3009
- import { Command as Command26 } from "commander";
2973
+ import { Command as Command25 } from "commander";
3010
2974
  import * as fs7 from "fs";
3011
- import * as path21 from "path";
2975
+ import * as path20 from "path";
3012
2976
  function listHooks(projectDir) {
3013
- const hooksDir = path21.join(projectDir, ".harness", "hooks");
3014
- const profilePath = path21.join(hooksDir, "profile.json");
2977
+ const hooksDir = path20.join(projectDir, ".harness", "hooks");
2978
+ const profilePath = path20.join(hooksDir, "profile.json");
3015
2979
  if (!fs7.existsSync(profilePath)) {
3016
2980
  return { installed: false, profile: null, hooks: [] };
3017
2981
  }
@@ -3030,7 +2994,7 @@ function listHooks(projectDir) {
3030
2994
  name: h.name,
3031
2995
  event: h.event,
3032
2996
  matcher: h.matcher,
3033
- scriptPath: path21.join(".harness", "hooks", `${h.name}.js`)
2997
+ scriptPath: path20.join(".harness", "hooks", `${h.name}.js`)
3034
2998
  }));
3035
2999
  const result = { installed: true, profile, hooks };
3036
3000
  if (warning) {
@@ -3039,7 +3003,7 @@ function listHooks(projectDir) {
3039
3003
  return result;
3040
3004
  }
3041
3005
  function createListCommand() {
3042
- return new Command26("list").description("Show installed hooks and active profile").action(async (_opts, cmd) => {
3006
+ return new Command25("list").description("Show installed hooks and active profile").action(async (_opts, cmd) => {
3043
3007
  const globalOpts = cmd.optsWithGlobals();
3044
3008
  const projectDir = process.cwd();
3045
3009
  const result = listHooks(projectDir);
@@ -3060,12 +3024,12 @@ function createListCommand() {
3060
3024
  }
3061
3025
 
3062
3026
  // src/commands/hooks/remove.ts
3063
- import { Command as Command27 } from "commander";
3027
+ import { Command as Command26 } from "commander";
3064
3028
  import * as fs8 from "fs";
3065
- import * as path22 from "path";
3029
+ import * as path21 from "path";
3066
3030
  function removeHooks(projectDir) {
3067
- const hooksDir = path22.join(projectDir, ".harness", "hooks");
3068
- const settingsPath = path22.join(projectDir, ".claude", "settings.json");
3031
+ const hooksDir = path21.join(projectDir, ".harness", "hooks");
3032
+ const settingsPath = path21.join(projectDir, ".claude", "settings.json");
3069
3033
  let removed = false;
3070
3034
  let settingsCleaned = false;
3071
3035
  if (fs8.existsSync(hooksDir)) {
@@ -3090,7 +3054,7 @@ function removeHooks(projectDir) {
3090
3054
  return { removed, hooksDir, settingsCleaned };
3091
3055
  }
3092
3056
  function createRemoveCommand() {
3093
- return new Command27("remove").description("Remove harness-managed hooks from the current project").action(async (_opts, cmd) => {
3057
+ return new Command26("remove").description("Remove harness-managed hooks from the current project").action(async (_opts, cmd) => {
3094
3058
  const globalOpts = cmd.optsWithGlobals();
3095
3059
  const projectDir = process.cwd();
3096
3060
  const result = removeHooks(projectDir);
@@ -3112,16 +3076,16 @@ function createRemoveCommand() {
3112
3076
  }
3113
3077
 
3114
3078
  // src/commands/hooks/add.ts
3115
- import { Command as Command28 } from "commander";
3079
+ import { Command as Command27 } from "commander";
3116
3080
  import * as fs9 from "fs";
3117
- import * as path23 from "path";
3081
+ import * as path22 from "path";
3118
3082
  import { fileURLToPath as fileURLToPath3 } from "url";
3119
- var __dirname3 = path23.dirname(fileURLToPath3(import.meta.url));
3083
+ var __dirname3 = path22.dirname(fileURLToPath3(import.meta.url));
3120
3084
  var ALIASES = {
3121
3085
  sentinel: ["sentinel-pre", "sentinel-post"]
3122
3086
  };
3123
3087
  function hookSourceDir() {
3124
- const d = path23.resolve(__dirname3, "..", "..", "hooks");
3088
+ const d = path22.resolve(__dirname3, "..", "..", "hooks");
3125
3089
  if (fs9.existsSync(d)) return d;
3126
3090
  throw new Error(`Hook scripts not found: ${d}`);
3127
3091
  }
@@ -3139,11 +3103,11 @@ function addHooks(hookName, projectDir) {
3139
3103
  const names = ALIASES[hookName] ?? [hookName];
3140
3104
  const result = { added: [], alreadyInstalled: [], notFound: [] };
3141
3105
  const srcDir = hookSourceDir();
3142
- const destDir = path23.join(projectDir, ".harness", "hooks");
3106
+ const destDir = path22.join(projectDir, ".harness", "hooks");
3143
3107
  fs9.mkdirSync(destDir, { recursive: true });
3144
- const claudeDir = path23.join(projectDir, ".claude");
3108
+ const claudeDir = path22.join(projectDir, ".claude");
3145
3109
  fs9.mkdirSync(claudeDir, { recursive: true });
3146
- const settingsPath = path23.join(claudeDir, "settings.json");
3110
+ const settingsPath = path22.join(claudeDir, "settings.json");
3147
3111
  const settings = readJson(settingsPath);
3148
3112
  if (!settings.hooks) settings.hooks = {};
3149
3113
  for (const name of names) {
@@ -3152,8 +3116,8 @@ function addHooks(hookName, projectDir) {
3152
3116
  result.notFound.push(name);
3153
3117
  continue;
3154
3118
  }
3155
- const src = path23.join(srcDir, `${name}.js`);
3156
- const dest = path23.join(destDir, `${name}.js`);
3119
+ const src = path22.join(srcDir, `${name}.js`);
3120
+ const dest = path22.join(destDir, `${name}.js`);
3157
3121
  if (fs9.existsSync(dest)) {
3158
3122
  result.alreadyInstalled.push(name);
3159
3123
  } else if (!fs9.existsSync(src)) {
@@ -3169,7 +3133,7 @@ function addHooks(hookName, projectDir) {
3169
3133
  return result;
3170
3134
  }
3171
3135
  function createAddCommand2() {
3172
- return new Command28("add").argument("<hook-name>", "Hook name or alias (e.g., sentinel)").description("Add a hook without changing the profile").action(async (hookName, _opts, cmd) => {
3136
+ return new Command27("add").argument("<hook-name>", "Hook name or alias (e.g., sentinel)").description("Add a hook without changing the profile").action(async (hookName, _opts, cmd) => {
3173
3137
  const projectDir = process.cwd();
3174
3138
  try {
3175
3139
  const res = addHooks(hookName, projectDir);
@@ -3194,7 +3158,7 @@ function createAddCommand2() {
3194
3158
 
3195
3159
  // src/commands/hooks/index.ts
3196
3160
  function createHooksCommand() {
3197
- const command = new Command29("hooks").description("Manage Claude Code hook configurations");
3161
+ const command = new Command28("hooks").description("Manage Claude Code hook configurations");
3198
3162
  command.addCommand(createInitCommand2());
3199
3163
  command.addCommand(createListCommand());
3200
3164
  command.addCommand(createRemoveCommand());
@@ -3203,9 +3167,9 @@ function createHooksCommand() {
3203
3167
  }
3204
3168
 
3205
3169
  // src/commands/impact-preview.ts
3206
- import { Command as Command30 } from "commander";
3170
+ import { Command as Command29 } from "commander";
3207
3171
  import { execSync as execSync4 } from "child_process";
3208
- import * as path24 from "path";
3172
+ import * as path23 from "path";
3209
3173
  import * as fs10 from "fs";
3210
3174
  function getStagedFiles(cwd) {
3211
3175
  try {
@@ -3220,7 +3184,7 @@ function getStagedFiles(cwd) {
3220
3184
  }
3221
3185
  function graphExists(projectPath) {
3222
3186
  try {
3223
- return fs10.existsSync(path24.join(projectPath, ".harness", "graph", "graph.json"));
3187
+ return fs10.existsSync(path23.join(projectPath, ".harness", "graph", "graph.json"));
3224
3188
  } catch {
3225
3189
  return false;
3226
3190
  }
@@ -3229,7 +3193,7 @@ function extractNodeName(id) {
3229
3193
  const parts = id.split(":");
3230
3194
  if (parts.length > 1) {
3231
3195
  const fullPath = parts.slice(1).join(":");
3232
- return path24.basename(fullPath);
3196
+ return path23.basename(fullPath);
3233
3197
  }
3234
3198
  return id;
3235
3199
  }
@@ -3384,7 +3348,7 @@ function formatImpactOutput(stagedFiles, acc, options) {
3384
3348
  return options.detailed ? formatDetailed(stagedFiles.length, merged, acc.aggregateCounts) : formatCompact(stagedFiles.length, merged, acc.aggregateCounts);
3385
3349
  }
3386
3350
  async function runImpactPreview(options) {
3387
- const projectPath = path24.resolve(options.path ?? process.cwd());
3351
+ const projectPath = path23.resolve(options.path ?? process.cwd());
3388
3352
  const stagedFiles = getStagedFiles(projectPath);
3389
3353
  if (stagedFiles.length === 0) return "Impact Preview: no staged changes";
3390
3354
  if (!graphExists(projectPath)) {
@@ -3402,7 +3366,7 @@ async function runImpactPreview(options) {
3402
3366
  return formatImpactOutput(stagedFiles, acc, options);
3403
3367
  }
3404
3368
  function createImpactPreviewCommand() {
3405
- const command = new Command30("impact-preview").description("Show blast radius of staged changes using the knowledge graph").option("--detailed", "Show all affected files instead of top items").option("--per-file", "Show impact per staged file instead of aggregate").option("--path <dir>", "Project root (default: cwd)").action(async (opts) => {
3369
+ const command = new Command29("impact-preview").description("Show blast radius of staged changes using the knowledge graph").option("--detailed", "Show all affected files instead of top items").option("--per-file", "Show impact per staged file instead of aggregate").option("--path <dir>", "Project root (default: cwd)").action(async (opts) => {
3406
3370
  const output = await runImpactPreview({
3407
3371
  detailed: opts.detailed,
3408
3372
  perFile: opts.perFile,
@@ -3415,24 +3379,24 @@ function createImpactPreviewCommand() {
3415
3379
  }
3416
3380
 
3417
3381
  // src/commands/init.ts
3418
- import { Command as Command32 } from "commander";
3382
+ import { Command as Command31 } from "commander";
3419
3383
  import chalk3 from "chalk";
3420
3384
  import * as fs13 from "fs";
3421
- import * as path27 from "path";
3385
+ import * as path26 from "path";
3422
3386
 
3423
3387
  // src/commands/setup-mcp.ts
3424
- import { Command as Command31 } from "commander";
3388
+ import { Command as Command30 } from "commander";
3425
3389
  import * as fs12 from "fs";
3426
- import * as path26 from "path";
3390
+ import * as path25 from "path";
3427
3391
  import * as os2 from "os";
3428
3392
  import chalk2 from "chalk";
3429
3393
  import * as clack from "@clack/prompts";
3430
3394
 
3431
3395
  // src/integrations/toml.ts
3432
3396
  import * as fs11 from "fs";
3433
- import * as path25 from "path";
3397
+ import * as path24 from "path";
3434
3398
  function writeTomlMcpEntry(filePath, name, entry) {
3435
- const dir = path25.dirname(filePath);
3399
+ const dir = path24.dirname(filePath);
3436
3400
  if (!fs11.existsSync(dir)) {
3437
3401
  fs11.mkdirSync(dir, { recursive: true });
3438
3402
  }
@@ -3613,7 +3577,7 @@ function readJsonFile(filePath) {
3613
3577
  }
3614
3578
  }
3615
3579
  function writeJsonFile(filePath, data) {
3616
- const dir = path26.dirname(filePath);
3580
+ const dir = path25.dirname(filePath);
3617
3581
  if (!fs12.existsSync(dir)) {
3618
3582
  fs12.mkdirSync(dir, { recursive: true });
3619
3583
  }
@@ -3632,7 +3596,7 @@ function configureMcpServer(configPath) {
3632
3596
  return true;
3633
3597
  }
3634
3598
  function addGeminiTrustedFolder(cwd) {
3635
- const trustedPath = path26.join(os2.homedir(), ".gemini", "trustedFolders.json");
3599
+ const trustedPath = path25.join(os2.homedir(), ".gemini", "trustedFolders.json");
3636
3600
  const folders = readJsonFile(trustedPath) ?? {};
3637
3601
  if (folders[cwd] === "TRUST_FOLDER") {
3638
3602
  return false;
@@ -3646,7 +3610,7 @@ function setupMcp(cwd, client) {
3646
3610
  const skipped = [];
3647
3611
  let trustedFolder = false;
3648
3612
  if (client === "all" || client === "claude") {
3649
- const configPath = path26.join(cwd, ".mcp.json");
3613
+ const configPath = path25.join(cwd, ".mcp.json");
3650
3614
  if (configureMcpServer(configPath)) {
3651
3615
  configured.push("Claude Code");
3652
3616
  } else {
@@ -3654,7 +3618,7 @@ function setupMcp(cwd, client) {
3654
3618
  }
3655
3619
  }
3656
3620
  if (client === "all" || client === "gemini") {
3657
- const configPath = path26.join(cwd, ".gemini", "settings.json");
3621
+ const configPath = path25.join(cwd, ".gemini", "settings.json");
3658
3622
  if (configureMcpServer(configPath)) {
3659
3623
  configured.push("Gemini CLI");
3660
3624
  } else {
@@ -3663,7 +3627,7 @@ function setupMcp(cwd, client) {
3663
3627
  trustedFolder = addGeminiTrustedFolder(cwd);
3664
3628
  }
3665
3629
  if (client === "all" || client === "codex") {
3666
- const configPath = path26.join(cwd, ".codex", "config.toml");
3630
+ const configPath = path25.join(cwd, ".codex", "config.toml");
3667
3631
  const alreadyConfigured = (() => {
3668
3632
  if (!fs12.existsSync(configPath)) return false;
3669
3633
  const content = fs12.readFileSync(configPath, "utf-8");
@@ -3681,7 +3645,7 @@ function setupMcp(cwd, client) {
3681
3645
  }
3682
3646
  }
3683
3647
  if (client === "all" || client === "cursor") {
3684
- const configPath = path26.join(cwd, ".cursor", "mcp.json");
3648
+ const configPath = path25.join(cwd, ".cursor", "mcp.json");
3685
3649
  const existing = readJsonFile(configPath);
3686
3650
  if (existing?.mcpServers?.["harness"]) {
3687
3651
  skipped.push("Cursor");
@@ -3695,7 +3659,7 @@ function setupMcp(cwd, client) {
3695
3659
  async function resolveCursorWithPicker(cwd, pick) {
3696
3660
  const configured = [];
3697
3661
  const skipped = [];
3698
- const cursorConfigPath = path26.join(cwd, ".cursor", "mcp.json");
3662
+ const cursorConfigPath = path25.join(cwd, ".cursor", "mcp.json");
3699
3663
  const existing = readJsonFile(cursorConfigPath);
3700
3664
  if (existing?.mcpServers?.["harness"] && !pick) {
3701
3665
  skipped.push("Cursor");
@@ -3739,7 +3703,7 @@ function printMcpResult(configured, skipped, trustedFolder) {
3739
3703
  console.log("");
3740
3704
  }
3741
3705
  function createSetupMcpCommand() {
3742
- return new Command31("setup-mcp").description("Configure MCP server for AI agent integration").option("--client <client>", "Client to configure (claude, gemini, codex, cursor, all)", "all").option("--pick", "Launch interactive tool picker (Cursor only)").option("--yes", "Bypass interactive picker and use curated 25-tool set (Cursor only)").action(async (opts, cmd) => {
3706
+ return new Command30("setup-mcp").description("Configure MCP server for AI agent integration").option("--client <client>", "Client to configure (claude, gemini, codex, cursor, all)", "all").option("--pick", "Launch interactive tool picker (Cursor only)").option("--yes", "Bypass interactive picker and use curated 25-tool set (Cursor only)").action(async (opts, cmd) => {
3743
3707
  const globalOpts = cmd.optsWithGlobals();
3744
3708
  const cwd = process.cwd();
3745
3709
  let configured;
@@ -3766,11 +3730,11 @@ function loadEngineAndTemplates(_options) {
3766
3730
  }
3767
3731
  function resolveInitDefaults(options) {
3768
3732
  const cwd = options.cwd ?? process.cwd();
3769
- return { cwd, name: options.name ?? path27.basename(cwd), force: options.force ?? false };
3733
+ return { cwd, name: options.name ?? path26.basename(cwd), force: options.force ?? false };
3770
3734
  }
3771
3735
  async function runInit(options) {
3772
3736
  const { cwd, name, force } = resolveInitDefaults(options);
3773
- const configPath = path27.join(cwd, "harness.config.json");
3737
+ const configPath = path26.join(cwd, "harness.config.json");
3774
3738
  if (!force && fs13.existsSync(configPath)) {
3775
3739
  return Err(
3776
3740
  new CLIError("Project already initialized. Use --force to overwrite.", ExitCode.ERROR)
@@ -3879,7 +3843,7 @@ async function runInitAction2(opts) {
3879
3843
  process.exit(ExitCode.SUCCESS);
3880
3844
  }
3881
3845
  function createInitCommand3() {
3882
- const command = new Command32("init").description("Initialize a new harness-engineering project").option("-n, --name <name>", "Project name").option("-l, --level <level>", "Adoption level (basic, intermediate, advanced)", "basic").option("--framework <framework>", "Framework overlay (nextjs)").option("--language <language>", "Target language (typescript, python, go, rust, java)").option("-f, --force", "Overwrite existing files").option("-y, --yes", "Use defaults without prompting").action(async (opts, cmd) => {
3846
+ const command = new Command31("init").description("Initialize a new harness-engineering project").option("-n, --name <name>", "Project name").option("-l, --level <level>", "Adoption level (basic, intermediate, advanced)", "basic").option("--framework <framework>", "Framework overlay (nextjs)").option("--language <language>", "Target language (typescript, python, go, rust, java)").option("-f, --force", "Overwrite existing files").option("-y, --yes", "Use defaults without prompting").action(async (opts, cmd) => {
3883
3847
  const globalOpts = cmd.optsWithGlobals();
3884
3848
  await runInitAction2({
3885
3849
  name: opts.name,
@@ -3896,14 +3860,14 @@ function createInitCommand3() {
3896
3860
  // src/commands/install.ts
3897
3861
  import * as fs18 from "fs";
3898
3862
  import * as os5 from "os";
3899
- import * as path32 from "path";
3863
+ import * as path31 from "path";
3900
3864
  import { execFileSync as execFileSync3 } from "child_process";
3901
- import { Command as Command33 } from "commander";
3865
+ import { Command as Command32 } from "commander";
3902
3866
  import { parse as yamlParse } from "yaml";
3903
3867
 
3904
3868
  // src/registry/npm-client.ts
3905
3869
  import * as fs14 from "fs";
3906
- import * as path28 from "path";
3870
+ import * as path27 from "path";
3907
3871
  import * as os3 from "os";
3908
3872
  var NPM_REGISTRY = "https://registry.npmjs.org";
3909
3873
  var FETCH_TIMEOUT_MS = 3e4;
@@ -3926,7 +3890,7 @@ function extractSkillName(packageName) {
3926
3890
  function readNpmrcToken(registryUrl) {
3927
3891
  const { hostname, pathname } = new URL(registryUrl);
3928
3892
  const registryPath = `//${hostname}${pathname.replace(/\/$/, "")}/:_authToken=`;
3929
- const candidates = [path28.join(process.cwd(), ".npmrc"), path28.join(os3.homedir(), ".npmrc")];
3893
+ const candidates = [path27.join(process.cwd(), ".npmrc"), path27.join(os3.homedir(), ".npmrc")];
3930
3894
  for (const npmrcPath of candidates) {
3931
3895
  try {
3932
3896
  const content = fs14.readFileSync(npmrcPath, "utf-8");
@@ -4025,12 +3989,12 @@ async function searchNpmRegistry(query, registryUrl) {
4025
3989
 
4026
3990
  // src/registry/tarball.ts
4027
3991
  import * as fs15 from "fs";
4028
- import * as path29 from "path";
3992
+ import * as path28 from "path";
4029
3993
  import * as os4 from "os";
4030
3994
  import { execFileSync as execFileSync2 } from "child_process";
4031
3995
  function extractTarball(tarballBuffer) {
4032
- const tmpDir = fs15.mkdtempSync(path29.join(os4.tmpdir(), "harness-skill-install-"));
4033
- const tarballPath = path29.join(tmpDir, "package.tgz");
3996
+ const tmpDir = fs15.mkdtempSync(path28.join(os4.tmpdir(), "harness-skill-install-"));
3997
+ const tarballPath = path28.join(tmpDir, "package.tgz");
4034
3998
  try {
4035
3999
  fs15.writeFileSync(tarballPath, tarballBuffer);
4036
4000
  execFileSync2("tar", ["-xzf", tarballPath, "-C", tmpDir], {
@@ -4049,15 +4013,15 @@ function extractTarball(tarballBuffer) {
4049
4013
  function placeSkillContent(extractedPkgDir, communityBaseDir, skillName, platforms) {
4050
4014
  const files = fs15.readdirSync(extractedPkgDir);
4051
4015
  for (const platform of platforms) {
4052
- const targetDir = path29.join(communityBaseDir, platform, skillName);
4016
+ const targetDir = path28.join(communityBaseDir, platform, skillName);
4053
4017
  if (fs15.existsSync(targetDir)) {
4054
4018
  fs15.rmSync(targetDir, { recursive: true, force: true });
4055
4019
  }
4056
4020
  fs15.mkdirSync(targetDir, { recursive: true });
4057
4021
  for (const file of files) {
4058
4022
  if (file === "package.json" || file === "node_modules") continue;
4059
- const srcPath = path29.join(extractedPkgDir, file);
4060
- const destPath = path29.join(targetDir, file);
4023
+ const srcPath = path28.join(extractedPkgDir, file);
4024
+ const destPath = path28.join(targetDir, file);
4061
4025
  const stat = fs15.statSync(srcPath);
4062
4026
  if (stat.isDirectory()) {
4063
4027
  fs15.cpSync(srcPath, destPath, { recursive: true });
@@ -4069,7 +4033,7 @@ function placeSkillContent(extractedPkgDir, communityBaseDir, skillName, platfor
4069
4033
  }
4070
4034
  function removeSkillContent(communityBaseDir, skillName, platforms) {
4071
4035
  for (const platform of platforms) {
4072
- const targetDir = path29.join(communityBaseDir, platform, skillName);
4036
+ const targetDir = path28.join(communityBaseDir, platform, skillName);
4073
4037
  if (fs15.existsSync(targetDir)) {
4074
4038
  fs15.rmSync(targetDir, { recursive: true, force: true });
4075
4039
  }
@@ -4120,7 +4084,7 @@ function findDependentsOf(lockfile, targetPackageName) {
4120
4084
 
4121
4085
  // src/registry/lockfile.ts
4122
4086
  import * as fs16 from "fs";
4123
- import * as path30 from "path";
4087
+ import * as path29 from "path";
4124
4088
  function createEmptyLockfile() {
4125
4089
  return { version: 1, skills: {} };
4126
4090
  }
@@ -4160,7 +4124,7 @@ function readLockfile2(filePath) {
4160
4124
  return parsed;
4161
4125
  }
4162
4126
  function writeLockfile2(filePath, lockfile) {
4163
- const dir = path30.dirname(filePath);
4127
+ const dir = path29.dirname(filePath);
4164
4128
  fs16.mkdirSync(dir, { recursive: true });
4165
4129
  fs16.writeFileSync(filePath, sortedStringify(lockfile) + "\n", "utf-8");
4166
4130
  }
@@ -4186,7 +4150,7 @@ function removeLockfileEntry(lockfile, name) {
4186
4150
 
4187
4151
  // src/registry/bundled-skills.ts
4188
4152
  import * as fs17 from "fs";
4189
- import * as path31 from "path";
4153
+ import * as path30 from "path";
4190
4154
  function getBundledSkillNames(bundledSkillsDir) {
4191
4155
  if (!fs17.existsSync(bundledSkillsDir)) {
4192
4156
  return /* @__PURE__ */ new Set();
@@ -4195,7 +4159,7 @@ function getBundledSkillNames(bundledSkillsDir) {
4195
4159
  const names = /* @__PURE__ */ new Set();
4196
4160
  for (const entry of entries) {
4197
4161
  try {
4198
- const stat = fs17.statSync(path31.join(bundledSkillsDir, String(entry)));
4162
+ const stat = fs17.statSync(path30.join(bundledSkillsDir, String(entry)));
4199
4163
  if (stat.isDirectory()) {
4200
4164
  names.add(String(entry));
4201
4165
  }
@@ -4222,12 +4186,12 @@ function validateSkillYaml(parsed) {
4222
4186
  function resolveCommunityBase(global) {
4223
4187
  if (global) {
4224
4188
  const communityBase2 = resolveGlobalCommunityBaseDir();
4225
- return { communityBase: communityBase2, lockfilePath: path32.join(communityBase2, "skills-lock.json") };
4189
+ return { communityBase: communityBase2, lockfilePath: path31.join(communityBase2, "skills-lock.json") };
4226
4190
  }
4227
4191
  const globalDir = resolveGlobalSkillsDir();
4228
- const skillsDir = path32.dirname(globalDir);
4229
- const communityBase = path32.join(skillsDir, "community");
4230
- return { communityBase, lockfilePath: path32.join(communityBase, "skills-lock.json") };
4192
+ const skillsDir = path31.dirname(globalDir);
4193
+ const communityBase = path31.join(skillsDir, "community");
4194
+ return { communityBase, lockfilePath: path31.join(communityBase, "skills-lock.json") };
4231
4195
  }
4232
4196
  function parseGitHubRef(from) {
4233
4197
  const ghPrefix = from.match(/^github:([^/]+)\/([^#]+?)(?:#(.+))?$/);
@@ -4243,7 +4207,7 @@ function parseGitHubRef(from) {
4243
4207
  return null;
4244
4208
  }
4245
4209
  function cloneGitHubRepo(owner, repo, ref) {
4246
- const tmpDir = fs18.mkdtempSync(path32.join(os5.tmpdir(), "harness-gh-install-"));
4210
+ const tmpDir = fs18.mkdtempSync(path31.join(os5.tmpdir(), "harness-gh-install-"));
4247
4211
  const url = `https://github.com/${owner}/${repo}.git`;
4248
4212
  try {
4249
4213
  const cloneArgs = ["clone", "--depth", "1"];
@@ -4265,7 +4229,7 @@ function discoverSkillDirs(rootDir) {
4265
4229
  function scan(dir, depth) {
4266
4230
  if (depth > 3) return;
4267
4231
  if (!fs18.existsSync(dir)) return;
4268
- if (fs18.existsSync(path32.join(dir, "skill.yaml"))) {
4232
+ if (fs18.existsSync(path31.join(dir, "skill.yaml"))) {
4269
4233
  skillDirs.push(dir);
4270
4234
  return;
4271
4235
  }
@@ -4273,14 +4237,14 @@ function discoverSkillDirs(rootDir) {
4273
4237
  for (const entry of entries) {
4274
4238
  if (!entry.isDirectory()) continue;
4275
4239
  if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
4276
- scan(path32.join(dir, entry.name), depth + 1);
4240
+ scan(path31.join(dir, entry.name), depth + 1);
4277
4241
  }
4278
4242
  }
4279
4243
  scan(rootDir, 0);
4280
4244
  return skillDirs;
4281
4245
  }
4282
4246
  function resolveLocalPkgDir(fromPath) {
4283
- const resolvedPath = path32.resolve(fromPath);
4247
+ const resolvedPath = path31.resolve(fromPath);
4284
4248
  if (!fs18.existsSync(resolvedPath)) {
4285
4249
  throw new Error(`--from path does not exist: ${resolvedPath}`);
4286
4250
  }
@@ -4291,12 +4255,12 @@ function resolveLocalPkgDir(fromPath) {
4291
4255
  if (resolvedPath.endsWith(".tgz") || resolvedPath.endsWith(".tar.gz")) {
4292
4256
  const tarballBuffer = fs18.readFileSync(resolvedPath);
4293
4257
  const extractDir = extractTarball(tarballBuffer);
4294
- return { pkgDir: path32.join(extractDir, "package"), extractDir };
4258
+ return { pkgDir: path31.join(extractDir, "package"), extractDir };
4295
4259
  }
4296
4260
  throw new Error(`--from path must be a directory or .tgz file. Got: ${resolvedPath}`);
4297
4261
  }
4298
4262
  function installSkillDir(pkgDir, resolvedPath, options) {
4299
- const skillYamlPath = path32.join(pkgDir, "skill.yaml");
4263
+ const skillYamlPath = path31.join(pkgDir, "skill.yaml");
4300
4264
  if (!fs18.existsSync(skillYamlPath)) {
4301
4265
  throw new Error(`No skill.yaml found at ${skillYamlPath}`);
4302
4266
  }
@@ -4328,7 +4292,7 @@ function installSkillDir(pkgDir, resolvedPath, options) {
4328
4292
  async function runLocalInstall(fromPath, options) {
4329
4293
  const { pkgDir, extractDir } = resolveLocalPkgDir(fromPath);
4330
4294
  try {
4331
- return installSkillDir(pkgDir, path32.resolve(fromPath), options);
4295
+ return installSkillDir(pkgDir, path31.resolve(fromPath), options);
4332
4296
  } finally {
4333
4297
  if (extractDir) cleanupTempDir(extractDir);
4334
4298
  }
@@ -4371,8 +4335,8 @@ async function runInstall(skillName, options) {
4371
4335
  version: installed.map((r) => r.version).join(", ")
4372
4336
  };
4373
4337
  }
4374
- const resolvedFrom = path32.resolve(options.from);
4375
- if (fs18.existsSync(resolvedFrom) && fs18.statSync(resolvedFrom).isDirectory() && !fs18.existsSync(path32.join(resolvedFrom, "skill.yaml"))) {
4338
+ const resolvedFrom = path31.resolve(options.from);
4339
+ if (fs18.existsSync(resolvedFrom) && fs18.statSync(resolvedFrom).isDirectory() && !fs18.existsSync(path31.join(resolvedFrom, "skill.yaml"))) {
4376
4340
  const results = await runBulkInstall(resolvedFrom, options);
4377
4341
  const installed = results.filter((r) => r.installed);
4378
4342
  return {
@@ -4413,8 +4377,8 @@ async function runInstall(skillName, options) {
4413
4377
  const extractDir = extractTarball(tarballBuffer);
4414
4378
  let skillYaml;
4415
4379
  try {
4416
- const extractedPkgDir = path32.join(extractDir, "package");
4417
- const skillYamlPath = path32.join(extractedPkgDir, "skill.yaml");
4380
+ const extractedPkgDir = path31.join(extractDir, "package");
4381
+ const skillYamlPath = path31.join(extractedPkgDir, "skill.yaml");
4418
4382
  if (!fs18.existsSync(skillYamlPath)) {
4419
4383
  throw new Error(`contains invalid skill.yaml: file not found in package`);
4420
4384
  }
@@ -4458,7 +4422,7 @@ async function runInstall(skillName, options) {
4458
4422
  return result;
4459
4423
  }
4460
4424
  function createInstallCommand() {
4461
- const cmd = new Command33("install");
4425
+ const cmd = new Command32("install");
4462
4426
  cmd.description("Install skills from npm registry, local directory, or GitHub repository").argument("<skill>", 'Skill name, @harness-skills/scoped package, or "." for bulk install').option("--version <range>", "Semver range or exact version to install").option("--force", "Force reinstall even if same version is already installed").option(
4463
4427
  "--from <source>",
4464
4428
  "Install from local path, directory, or GitHub (github:owner/repo, https://github.com/owner/repo)"
@@ -4492,8 +4456,8 @@ function createInstallCommand() {
4492
4456
 
4493
4457
  // src/commands/install-constraints.ts
4494
4458
  import * as fs19 from "fs/promises";
4495
- import * as path33 from "path";
4496
- import { Command as Command34 } from "commander";
4459
+ import * as path32 from "path";
4460
+ import { Command as Command33 } from "commander";
4497
4461
  import semver3 from "semver";
4498
4462
  async function runInstallConstraints(options) {
4499
4463
  const { source, configPath, lockfilePath } = options;
@@ -4690,7 +4654,7 @@ function isNodeError(err) {
4690
4654
  return err instanceof Error && "code" in err;
4691
4655
  }
4692
4656
  function resolveConfigPath(opts) {
4693
- if (opts.config) return path33.resolve(opts.config);
4657
+ if (opts.config) return path32.resolve(opts.config);
4694
4658
  const found = findConfigFile();
4695
4659
  if (!found.ok) {
4696
4660
  logger.error(found.error.message);
@@ -4725,9 +4689,9 @@ function logInstallResult(val, opts) {
4725
4689
  }
4726
4690
  async function handleInstallConstraints(source, opts) {
4727
4691
  const configPath = resolveConfigPath(opts);
4728
- const projectRoot = path33.dirname(configPath);
4729
- const lockfilePath = path33.join(projectRoot, ".harness", "constraints.lock.json");
4730
- const resolvedSource = path33.resolve(source);
4692
+ const projectRoot = path32.dirname(configPath);
4693
+ const lockfilePath = path32.join(projectRoot, ".harness", "constraints.lock.json");
4694
+ const resolvedSource = path32.resolve(source);
4731
4695
  if (opts.forceLocal && opts.forcePackage) {
4732
4696
  logger.error("Cannot use both --force-local and --force-package.");
4733
4697
  process.exit(1);
@@ -4747,18 +4711,18 @@ async function handleInstallConstraints(source, opts) {
4747
4711
  logInstallResult(result.value, opts);
4748
4712
  }
4749
4713
  function createInstallConstraintsCommand() {
4750
- const cmd = new Command34("install-constraints");
4714
+ const cmd = new Command33("install-constraints");
4751
4715
  cmd.description("Install a constraints bundle into the local harness config").argument("<source>", "Path to a .harness-constraints.json bundle file").option("--force-local", "Resolve all conflicts by keeping local values").option("--force-package", "Resolve all conflicts by using package values").option("--dry-run", "Show what would change without writing files").option("-c, --config <path>", "Path to harness.config.json").action(handleInstallConstraints);
4752
4716
  return cmd;
4753
4717
  }
4754
4718
 
4755
4719
  // src/commands/integrations/index.ts
4756
- import { Command as Command39 } from "commander";
4720
+ import { Command as Command38 } from "commander";
4757
4721
 
4758
4722
  // src/commands/integrations/add.ts
4759
- import { Command as Command35 } from "commander";
4723
+ import { Command as Command34 } from "commander";
4760
4724
  import * as fs20 from "fs";
4761
- import * as path34 from "path";
4725
+ import * as path33 from "path";
4762
4726
  import chalk4 from "chalk";
4763
4727
  function buildMcpEntry(def) {
4764
4728
  const entry = { command: def.mcpConfig.command };
@@ -4767,14 +4731,14 @@ function buildMcpEntry(def) {
4767
4731
  return entry;
4768
4732
  }
4769
4733
  function writeMcpEntries(cwd, defName, mcpEntry) {
4770
- writeMcpEntry(path34.join(cwd, ".mcp.json"), defName, mcpEntry);
4771
- const geminiDir = path34.join(cwd, ".gemini");
4734
+ writeMcpEntry(path33.join(cwd, ".mcp.json"), defName, mcpEntry);
4735
+ const geminiDir = path33.join(cwd, ".gemini");
4772
4736
  if (fs20.existsSync(geminiDir)) {
4773
- writeMcpEntry(path34.join(geminiDir, "settings.json"), defName, mcpEntry);
4737
+ writeMcpEntry(path33.join(geminiDir, "settings.json"), defName, mcpEntry);
4774
4738
  }
4775
4739
  }
4776
4740
  function updateIntegrationsConfig(cwd, defName) {
4777
- const configPath = path34.join(cwd, "harness.config.json");
4741
+ const configPath = path33.join(cwd, "harness.config.json");
4778
4742
  const integConfig = readIntegrationsConfig(configPath);
4779
4743
  if (!integConfig.enabled.includes(defName)) integConfig.enabled.push(defName);
4780
4744
  integConfig.dismissed = integConfig.dismissed.filter((d) => d !== defName);
@@ -4820,7 +4784,7 @@ function printAddSuccess(value) {
4820
4784
  }
4821
4785
  }
4822
4786
  function createAddIntegrationCommand() {
4823
- return new Command35("add").description("Enable an MCP integration").argument("<name>", "Integration name (e.g. perplexity, augment-code)").action(async (name, _opts, cmd) => {
4787
+ return new Command34("add").description("Enable an MCP integration").argument("<name>", "Integration name (e.g. perplexity, augment-code)").action(async (name, _opts, cmd) => {
4824
4788
  const globalOpts = cmd.optsWithGlobals();
4825
4789
  const result = addIntegration(process.cwd(), name);
4826
4790
  if (!result.ok) {
@@ -4834,8 +4798,8 @@ function createAddIntegrationCommand() {
4834
4798
  }
4835
4799
 
4836
4800
  // src/commands/integrations/list.ts
4837
- import { Command as Command36 } from "commander";
4838
- import * as path35 from "path";
4801
+ import { Command as Command35 } from "commander";
4802
+ import * as path34 from "path";
4839
4803
  import chalk5 from "chalk";
4840
4804
  function printTier0Integrations(tier0, mcpServers) {
4841
4805
  console.log(" Tier 0 (zero-config):");
@@ -4859,8 +4823,8 @@ function printTier1Integrations(tier1, mcpServers, dismissed) {
4859
4823
  }
4860
4824
  async function runListIntegrations(globalOpts) {
4861
4825
  const cwd = process.cwd();
4862
- const mcpConfig = readMcpConfig(path35.join(cwd, ".mcp.json"));
4863
- const integConfig = readIntegrationsConfig(path35.join(cwd, "harness.config.json"));
4826
+ const mcpConfig = readMcpConfig(path34.join(cwd, ".mcp.json"));
4827
+ const integConfig = readIntegrationsConfig(path34.join(cwd, "harness.config.json"));
4864
4828
  const mcpServers = mcpConfig.mcpServers ?? {};
4865
4829
  if (globalOpts.json) {
4866
4830
  const entries = INTEGRATION_REGISTRY.map((i) => ({
@@ -4891,13 +4855,13 @@ async function runListIntegrations(globalOpts) {
4891
4855
  process.exit(ExitCode.SUCCESS);
4892
4856
  }
4893
4857
  function createListIntegrationsCommand() {
4894
- return new Command36("list").description("Show all MCP integrations with status").action(async (_opts, cmd) => runListIntegrations(cmd.optsWithGlobals()));
4858
+ return new Command35("list").description("Show all MCP integrations with status").action(async (_opts, cmd) => runListIntegrations(cmd.optsWithGlobals()));
4895
4859
  }
4896
4860
 
4897
4861
  // src/commands/integrations/remove.ts
4898
- import { Command as Command37 } from "commander";
4862
+ import { Command as Command36 } from "commander";
4899
4863
  import * as fs21 from "fs";
4900
- import * as path36 from "path";
4864
+ import * as path35 from "path";
4901
4865
  function removeIntegration(cwd, name) {
4902
4866
  const def = INTEGRATION_REGISTRY.find((i) => i.name === name);
4903
4867
  if (!def) {
@@ -4908,21 +4872,21 @@ function removeIntegration(cwd, name) {
4908
4872
  )
4909
4873
  );
4910
4874
  }
4911
- const mcpPath = path36.join(cwd, ".mcp.json");
4875
+ const mcpPath = path35.join(cwd, ".mcp.json");
4912
4876
  removeMcpEntry(mcpPath, def.name);
4913
- const geminiDir = path36.join(cwd, ".gemini");
4877
+ const geminiDir = path35.join(cwd, ".gemini");
4914
4878
  if (fs21.existsSync(geminiDir)) {
4915
- const geminiPath = path36.join(geminiDir, "settings.json");
4879
+ const geminiPath = path35.join(geminiDir, "settings.json");
4916
4880
  removeMcpEntry(geminiPath, def.name);
4917
4881
  }
4918
- const configPath = path36.join(cwd, "harness.config.json");
4882
+ const configPath = path35.join(cwd, "harness.config.json");
4919
4883
  const integConfig = readIntegrationsConfig(configPath);
4920
4884
  integConfig.enabled = integConfig.enabled.filter((e) => e !== def.name);
4921
4885
  writeIntegrationsConfig(configPath, integConfig);
4922
4886
  return Ok(def.displayName);
4923
4887
  }
4924
4888
  function createRemoveIntegrationCommand() {
4925
- return new Command37("remove").description("Remove an MCP integration").argument("<name>", "Integration name (e.g. perplexity, augment-code)").action(async (name, _opts, cmd) => {
4889
+ return new Command36("remove").description("Remove an MCP integration").argument("<name>", "Integration name (e.g. perplexity, augment-code)").action(async (name, _opts, cmd) => {
4926
4890
  const globalOpts = cmd.optsWithGlobals();
4927
4891
  const cwd = process.cwd();
4928
4892
  const result = removeIntegration(cwd, name);
@@ -4943,8 +4907,8 @@ function createRemoveIntegrationCommand() {
4943
4907
  }
4944
4908
 
4945
4909
  // src/commands/integrations/dismiss.ts
4946
- import { Command as Command38 } from "commander";
4947
- import * as path37 from "path";
4910
+ import { Command as Command37 } from "commander";
4911
+ import * as path36 from "path";
4948
4912
  function dismissIntegration(cwd, name) {
4949
4913
  const def = INTEGRATION_REGISTRY.find((i) => i.name === name);
4950
4914
  if (!def) {
@@ -4955,7 +4919,7 @@ function dismissIntegration(cwd, name) {
4955
4919
  )
4956
4920
  );
4957
4921
  }
4958
- const configPath = path37.join(cwd, "harness.config.json");
4922
+ const configPath = path36.join(cwd, "harness.config.json");
4959
4923
  const integConfig = readIntegrationsConfig(configPath);
4960
4924
  if (!integConfig.dismissed.includes(def.name)) {
4961
4925
  integConfig.dismissed.push(def.name);
@@ -4965,7 +4929,7 @@ function dismissIntegration(cwd, name) {
4965
4929
  return Ok(def.displayName);
4966
4930
  }
4967
4931
  function createDismissIntegrationCommand() {
4968
- return new Command38("dismiss").description("Suppress doctor recommendations for an integration").argument("<name>", "Integration name (e.g. perplexity, augment-code)").action(async (name, _opts, cmd) => {
4932
+ return new Command37("dismiss").description("Suppress doctor recommendations for an integration").argument("<name>", "Integration name (e.g. perplexity, augment-code)").action(async (name, _opts, cmd) => {
4969
4933
  const globalOpts = cmd.optsWithGlobals();
4970
4934
  const cwd = process.cwd();
4971
4935
  const result = dismissIntegration(cwd, name);
@@ -4989,7 +4953,7 @@ function createDismissIntegrationCommand() {
4989
4953
 
4990
4954
  // src/commands/integrations/index.ts
4991
4955
  function createIntegrationsCommand() {
4992
- const command = new Command39("integrations").description(
4956
+ const command = new Command38("integrations").description(
4993
4957
  "Manage MCP peer integrations (add, list, remove, dismiss)"
4994
4958
  );
4995
4959
  command.addCommand(createListIntegrationsCommand());
@@ -5000,13 +4964,13 @@ function createIntegrationsCommand() {
5000
4964
  }
5001
4965
 
5002
4966
  // src/commands/learnings/index.ts
5003
- import { Command as Command41 } from "commander";
4967
+ import { Command as Command40 } from "commander";
5004
4968
 
5005
4969
  // src/commands/learnings/prune.ts
5006
- import { Command as Command40 } from "commander";
5007
- import * as path38 from "path";
4970
+ import { Command as Command39 } from "commander";
4971
+ import * as path37 from "path";
5008
4972
  async function handlePrune(opts) {
5009
- const projectPath = path38.resolve(opts.path);
4973
+ const projectPath = path37.resolve(opts.path);
5010
4974
  const result = await pruneLearnings(projectPath, opts.stream);
5011
4975
  if (!result.ok) {
5012
4976
  logger.error(result.error.message);
@@ -5045,23 +5009,23 @@ function printPatternProposals(patterns) {
5045
5009
  );
5046
5010
  }
5047
5011
  function createPruneCommand() {
5048
- return new Command40("prune").description(
5012
+ return new Command39("prune").description(
5049
5013
  "Analyze global learnings for patterns, present improvement proposals, and archive old entries"
5050
5014
  ).option("--path <path>", "Project root path", ".").option("--stream <name>", "Target a specific stream").action(handlePrune);
5051
5015
  }
5052
5016
 
5053
5017
  // src/commands/learnings/index.ts
5054
5018
  function createLearningsCommand() {
5055
- const command = new Command41("learnings").description("Learnings management commands");
5019
+ const command = new Command40("learnings").description("Learnings management commands");
5056
5020
  command.addCommand(createPruneCommand());
5057
5021
  return command;
5058
5022
  }
5059
5023
 
5060
5024
  // src/commands/linter/index.ts
5061
- import { Command as Command44 } from "commander";
5025
+ import { Command as Command43 } from "commander";
5062
5026
 
5063
5027
  // src/commands/linter/generate.ts
5064
- import { Command as Command42 } from "commander";
5028
+ import { Command as Command41 } from "commander";
5065
5029
  function formatGenerateError(e) {
5066
5030
  switch (e.type) {
5067
5031
  case "parse":
@@ -5105,7 +5069,7 @@ function handleSuccess(result, useJson) {
5105
5069
  Generated ${result.rulesGenerated.length} rules to ${result.outputDir}`);
5106
5070
  }
5107
5071
  function createGenerateCommand2() {
5108
- return new Command42("generate").description("Generate ESLint rules from harness-linter.yml").option("-c, --config <path>", "Path to harness-linter.yml", "./harness-linter.yml").option("-o, --output <dir>", "Override output directory").option("--clean", "Remove existing files before generating").option("--dry-run", "Preview without writing files").option("--json", "Output as JSON").option("--verbose", "Show detailed output").action(async (options) => {
5072
+ return new Command41("generate").description("Generate ESLint rules from harness-linter.yml").option("-c, --config <path>", "Path to harness-linter.yml", "./harness-linter.yml").option("-o, --output <dir>", "Override output directory").option("--clean", "Remove existing files before generating").option("--dry-run", "Preview without writing files").option("--json", "Output as JSON").option("--verbose", "Show detailed output").action(async (options) => {
5109
5073
  try {
5110
5074
  if (options.verbose) logger.info(`Parsing config: ${options.config}`);
5111
5075
  const result = await generate({
@@ -5127,9 +5091,9 @@ function createGenerateCommand2() {
5127
5091
  }
5128
5092
 
5129
5093
  // src/commands/linter/validate.ts
5130
- import { Command as Command43 } from "commander";
5094
+ import { Command as Command42 } from "commander";
5131
5095
  function createValidateCommand() {
5132
- return new Command43("validate").description("Validate harness-linter.yml config").option("-c, --config <path>", "Path to harness-linter.yml", "./harness-linter.yml").option("--json", "Output as JSON").action(async (options) => {
5096
+ return new Command42("validate").description("Validate harness-linter.yml config").option("-c, --config <path>", "Path to harness-linter.yml", "./harness-linter.yml").option("--json", "Output as JSON").action(async (options) => {
5133
5097
  try {
5134
5098
  const result = await validate({ configPath: options.config });
5135
5099
  if (options.json) {
@@ -5148,7 +5112,7 @@ function createValidateCommand() {
5148
5112
 
5149
5113
  // src/commands/linter/index.ts
5150
5114
  function createLinterCommand() {
5151
- const linter = new Command44("linter").description(
5115
+ const linter = new Command43("linter").description(
5152
5116
  "Generate and validate ESLint rules from YAML config"
5153
5117
  );
5154
5118
  linter.addCommand(createGenerateCommand2());
@@ -5157,22 +5121,22 @@ function createLinterCommand() {
5157
5121
  }
5158
5122
 
5159
5123
  // src/commands/mcp.ts
5160
- import { Command as Command45 } from "commander";
5124
+ import { Command as Command44 } from "commander";
5161
5125
  function createMcpCommand() {
5162
- return new Command45("mcp").description("Start the MCP (Model Context Protocol) server on stdio").option("--tools <tools...>", "Only register the specified tools (used by Cursor integration)").action(async (opts) => {
5163
- const { startServer: startServer2 } = await import("./mcp-JZG22CYT.js");
5126
+ return new Command44("mcp").description("Start the MCP (Model Context Protocol) server on stdio").option("--tools <tools...>", "Only register the specified tools (used by Cursor integration)").action(async (opts) => {
5127
+ const { startServer: startServer2 } = await import("./mcp-LCHC4NZ5.js");
5164
5128
  await startServer2(opts.tools);
5165
5129
  });
5166
5130
  }
5167
5131
 
5168
5132
  // src/commands/orchestrator.ts
5169
- import { Command as Command46 } from "commander";
5170
- import * as path39 from "path";
5133
+ import { Command as Command45 } from "commander";
5134
+ import * as path38 from "path";
5171
5135
  import { Orchestrator, WorkflowLoader, launchTUI } from "@harness-engineering/orchestrator";
5172
5136
  function createOrchestratorCommand() {
5173
- const orchestrator = new Command46("orchestrator");
5137
+ const orchestrator = new Command45("orchestrator");
5174
5138
  orchestrator.command("run").description("Run the orchestrator daemon").option("-w, --workflow <path>", "Path to WORKFLOW.md", "WORKFLOW.md").action(async (opts) => {
5175
- const workflowPath = path39.resolve(process.cwd(), opts.workflow);
5139
+ const workflowPath = path38.resolve(process.cwd(), opts.workflow);
5176
5140
  const loader = new WorkflowLoader();
5177
5141
  const result = await loader.loadWorkflow(workflowPath);
5178
5142
  if (!result.ok) {
@@ -5196,13 +5160,13 @@ function createOrchestratorCommand() {
5196
5160
  }
5197
5161
 
5198
5162
  // src/commands/perf.ts
5199
- import { Command as Command47 } from "commander";
5200
- import * as path40 from "path";
5163
+ import { Command as Command46 } from "commander";
5164
+ import * as path39 from "path";
5201
5165
  function registerBenchCommand(perf) {
5202
5166
  perf.command("bench [glob]").description("Run benchmarks via vitest bench").action(async (glob, _opts, cmd) => {
5203
5167
  const globalOpts = cmd.optsWithGlobals();
5204
5168
  const cwd = process.cwd();
5205
- const { BenchmarkRunner } = await import("./dist-TZQUURSP.js");
5169
+ const { BenchmarkRunner } = await import("./dist-7EBSGAHX.js");
5206
5170
  const runner = new BenchmarkRunner();
5207
5171
  const benchFiles = runner.discover(cwd, glob);
5208
5172
  if (benchFiles.length === 0) {
@@ -5266,7 +5230,7 @@ async function runBaselinesShow(globalOpts) {
5266
5230
  }
5267
5231
  async function runBaselinesUpdate(globalOpts) {
5268
5232
  const cwd = process.cwd();
5269
- const { BenchmarkRunner } = await import("./dist-TZQUURSP.js");
5233
+ const { BenchmarkRunner } = await import("./dist-7EBSGAHX.js");
5270
5234
  const runner = new BenchmarkRunner();
5271
5235
  const manager = new BaselineManager(cwd);
5272
5236
  logger.info("Running benchmarks to update baselines...");
@@ -5307,9 +5271,9 @@ function registerReportCommand(perf) {
5307
5271
  perf.command("report").description("Full performance report with metrics, trends, and hotspots").action(async (_opts, cmd) => {
5308
5272
  const globalOpts = cmd.optsWithGlobals();
5309
5273
  const cwd = process.cwd();
5310
- const { EntropyAnalyzer: EntropyAnalyzer2 } = await import("./dist-TZQUURSP.js");
5274
+ const { EntropyAnalyzer: EntropyAnalyzer2 } = await import("./dist-7EBSGAHX.js");
5311
5275
  const analyzer = new EntropyAnalyzer2({
5312
- rootDir: path40.resolve(cwd),
5276
+ rootDir: path39.resolve(cwd),
5313
5277
  analyze: { complexity: true, coupling: true }
5314
5278
  });
5315
5279
  const result = await analyzer.analyze();
@@ -5368,7 +5332,7 @@ function registerCriticalPathsCommand(perf) {
5368
5332
  });
5369
5333
  }
5370
5334
  function createPerfCommand() {
5371
- const perf = new Command47("perf").description("Performance benchmark and baseline management");
5335
+ const perf = new Command46("perf").description("Performance benchmark and baseline management");
5372
5336
  registerBenchCommand(perf);
5373
5337
  registerBaselinesCommands(perf);
5374
5338
  registerReportCommand(perf);
@@ -5377,10 +5341,10 @@ function createPerfCommand() {
5377
5341
  }
5378
5342
 
5379
5343
  // src/commands/persona/index.ts
5380
- import { Command as Command50 } from "commander";
5344
+ import { Command as Command49 } from "commander";
5381
5345
 
5382
5346
  // src/commands/persona/list.ts
5383
- import { Command as Command48 } from "commander";
5347
+ import { Command as Command47 } from "commander";
5384
5348
  function printPersonaList(personas) {
5385
5349
  if (personas.length === 0) {
5386
5350
  logger.info("No personas found.");
@@ -5394,7 +5358,7 @@ function printPersonaList(personas) {
5394
5358
  }
5395
5359
  }
5396
5360
  function createListCommand2() {
5397
- return new Command48("list").description("List available agent personas").action(async (_opts, cmd) => {
5361
+ return new Command47("list").description("List available agent personas").action(async (_opts, cmd) => {
5398
5362
  const globalOpts = cmd.optsWithGlobals();
5399
5363
  const personasDir = resolvePersonasDir();
5400
5364
  const result = listPersonas(personasDir);
@@ -5414,17 +5378,17 @@ function createListCommand2() {
5414
5378
  }
5415
5379
 
5416
5380
  // src/commands/persona/generate.ts
5417
- import { Command as Command49 } from "commander";
5381
+ import { Command as Command48 } from "commander";
5418
5382
  import * as fs22 from "fs";
5419
- import * as path41 from "path";
5383
+ import * as path40 from "path";
5420
5384
  function generatePersonaArtifacts(persona, outputDir, only) {
5421
5385
  const slug = toKebabCase(persona.name);
5422
5386
  const generated = [];
5423
5387
  if (!only || only === "runtime") {
5424
5388
  const result = generateRuntime(persona);
5425
5389
  if (result.ok) {
5426
- const outPath = path41.join(outputDir, `${slug}.runtime.json`);
5427
- fs22.mkdirSync(path41.dirname(outPath), { recursive: true });
5390
+ const outPath = path40.join(outputDir, `${slug}.runtime.json`);
5391
+ fs22.mkdirSync(path40.dirname(outPath), { recursive: true });
5428
5392
  fs22.writeFileSync(outPath, result.value);
5429
5393
  generated.push(outPath);
5430
5394
  }
@@ -5432,7 +5396,7 @@ function generatePersonaArtifacts(persona, outputDir, only) {
5432
5396
  if (!only || only === "agents-md") {
5433
5397
  const result = generateAgentsMd(persona);
5434
5398
  if (result.ok) {
5435
- const outPath = path41.join(outputDir, `${slug}.agents.md`);
5399
+ const outPath = path40.join(outputDir, `${slug}.agents.md`);
5436
5400
  fs22.writeFileSync(outPath, result.value);
5437
5401
  generated.push(outPath);
5438
5402
  }
@@ -5440,8 +5404,8 @@ function generatePersonaArtifacts(persona, outputDir, only) {
5440
5404
  if (!only || only === "ci") {
5441
5405
  const result = generateCIWorkflow(persona, "github");
5442
5406
  if (result.ok) {
5443
- const outPath = path41.join(outputDir, ".github", "workflows", `${slug}.yml`);
5444
- fs22.mkdirSync(path41.dirname(outPath), { recursive: true });
5407
+ const outPath = path40.join(outputDir, ".github", "workflows", `${slug}.yml`);
5408
+ fs22.mkdirSync(path40.dirname(outPath), { recursive: true });
5445
5409
  fs22.writeFileSync(outPath, result.value);
5446
5410
  generated.push(outPath);
5447
5411
  }
@@ -5449,16 +5413,16 @@ function generatePersonaArtifacts(persona, outputDir, only) {
5449
5413
  return generated;
5450
5414
  }
5451
5415
  function createGenerateCommand3() {
5452
- return new Command49("generate").description("Generate artifacts from a persona config").argument("<name>", "Persona name (e.g., architecture-enforcer)").option("--output-dir <dir>", "Output directory", ".").option("--only <type>", "Generate only: ci, agents-md, runtime").action(async (name, opts, cmd) => {
5416
+ return new Command48("generate").description("Generate artifacts from a persona config").argument("<name>", "Persona name (e.g., architecture-enforcer)").option("--output-dir <dir>", "Output directory", ".").option("--only <type>", "Generate only: ci, agents-md, runtime").action(async (name, opts, cmd) => {
5453
5417
  const globalOpts = cmd.optsWithGlobals();
5454
- const personaResult = loadPersona(path41.join(resolvePersonasDir(), `${name}.yaml`));
5418
+ const personaResult = loadPersona(path40.join(resolvePersonasDir(), `${name}.yaml`));
5455
5419
  if (!personaResult.ok) {
5456
5420
  logger.error(personaResult.error.message);
5457
5421
  process.exit(ExitCode.ERROR);
5458
5422
  }
5459
5423
  const generated = generatePersonaArtifacts(
5460
5424
  personaResult.value,
5461
- path41.resolve(opts.outputDir),
5425
+ path40.resolve(opts.outputDir),
5462
5426
  opts.only
5463
5427
  );
5464
5428
  if (!globalOpts.quiet) {
@@ -5471,14 +5435,14 @@ function createGenerateCommand3() {
5471
5435
 
5472
5436
  // src/commands/persona/index.ts
5473
5437
  function createPersonaCommand() {
5474
- const command = new Command50("persona").description("Agent persona management commands");
5438
+ const command = new Command49("persona").description("Agent persona management commands");
5475
5439
  command.addCommand(createListCommand2());
5476
5440
  command.addCommand(createGenerateCommand3());
5477
5441
  return command;
5478
5442
  }
5479
5443
 
5480
5444
  // src/commands/predict.ts
5481
- import { Command as Command51 } from "commander";
5445
+ import { Command as Command50 } from "commander";
5482
5446
  import chalk6 from "chalk";
5483
5447
  var CATEGORY_ORDER = [
5484
5448
  "circular-deps",
@@ -5584,7 +5548,7 @@ function handlePredictError(err, mode) {
5584
5548
  process.exit(ExitCode.ERROR);
5585
5549
  }
5586
5550
  function createPredictCommand() {
5587
- const command = new Command51("predict").description("Predict which architectural constraints will break and when").option("--category <name>", "Filter to a single metric category").option("--no-roadmap", "Baseline only \u2014 skip roadmap spec impact").option("--horizon <weeks>", "Forecast horizon in weeks (default: 12)", "12").action(async (opts, cmd) => {
5551
+ const command = new Command50("predict").description("Predict which architectural constraints will break and when").option("--category <name>", "Filter to a single metric category").option("--no-roadmap", "Baseline only \u2014 skip roadmap spec impact").option("--horizon <weeks>", "Forecast horizon in weeks (default: 12)", "12").action(async (opts, cmd) => {
5588
5552
  const globalOpts = cmd.optsWithGlobals();
5589
5553
  const mode = globalOpts.json ? OutputMode.JSON : OutputMode.TEXT;
5590
5554
  try {
@@ -5607,7 +5571,7 @@ function createPredictCommand() {
5607
5571
  }
5608
5572
 
5609
5573
  // src/commands/recommend.ts
5610
- import { Command as Command52 } from "commander";
5574
+ import { Command as Command51 } from "commander";
5611
5575
  import chalk7 from "chalk";
5612
5576
  async function resolveSnapshot(cwd, noCache) {
5613
5577
  if (!noCache) {
@@ -5671,7 +5635,7 @@ function printRecommendations(result) {
5671
5635
  console.log("");
5672
5636
  }
5673
5637
  function createRecommendCommand() {
5674
- const command = new Command52("recommend").description("Recommend skills based on codebase health analysis").option("--no-cache", "Force fresh health snapshot").option("--top <n>", "Max recommendations (default 5)", "5").action(async (opts, cmd) => {
5638
+ const command = new Command51("recommend").description("Recommend skills based on codebase health analysis").option("--no-cache", "Force fresh health snapshot").option("--top <n>", "Max recommendations (default 5)", "5").action(async (opts, cmd) => {
5675
5639
  const globalOpts = cmd.optsWithGlobals();
5676
5640
  const mode = globalOpts.json ? OutputMode.JSON : OutputMode.TEXT;
5677
5641
  try {
@@ -5707,9 +5671,9 @@ function createRecommendCommand() {
5707
5671
  }
5708
5672
 
5709
5673
  // src/commands/scan-config.ts
5710
- import { Command as Command53 } from "commander";
5674
+ import { Command as Command52 } from "commander";
5711
5675
  import { existsSync as existsSync21, readFileSync as readFileSync11, writeFileSync as writeFileSync12 } from "fs";
5712
- import { join as join32, relative as relative2 } from "path";
5676
+ import { join as join31, relative as relative2 } from "path";
5713
5677
  var CONFIG_FILES = ["CLAUDE.md", "AGENTS.md", ".gemini/settings.json", "skill.yaml"];
5714
5678
  function stripHighSeverityPatterns(content, injectionFindings) {
5715
5679
  const highLines = /* @__PURE__ */ new Set();
@@ -5766,7 +5730,7 @@ async function runScanConfig(targetDir, options) {
5766
5730
  const scanner = new SecurityScanner(parseSecurityConfig({}));
5767
5731
  const results = [];
5768
5732
  for (const configFile of CONFIG_FILES) {
5769
- const result = scanSingleFile(join32(targetDir, configFile), targetDir, scanner, options);
5733
+ const result = scanSingleFile(join31(targetDir, configFile), targetDir, scanner, options);
5770
5734
  if (result) results.push(result);
5771
5735
  }
5772
5736
  return { exitCode: computeScanExitCode(results), results };
@@ -5796,7 +5760,7 @@ function formatTextOutput(result) {
5796
5760
  }
5797
5761
  }
5798
5762
  function createScanConfigCommand() {
5799
- const command = new Command53("scan-config").description(
5763
+ const command = new Command52("scan-config").description(
5800
5764
  "Scan CLAUDE.md, AGENTS.md, .gemini/settings.json, and skill.yaml for prompt injection patterns"
5801
5765
  ).option("--path <dir>", "Target directory to scan (default: cwd)").option("--fix", "Strip high-severity patterns from files in-place").action(async (opts, cmd) => {
5802
5766
  const globalOpts = cmd.optsWithGlobals();
@@ -5813,18 +5777,18 @@ function createScanConfigCommand() {
5813
5777
  }
5814
5778
 
5815
5779
  // src/commands/setup.ts
5816
- import { Command as Command54 } from "commander";
5780
+ import { Command as Command53 } from "commander";
5817
5781
  import * as fs24 from "fs";
5818
5782
  import * as os7 from "os";
5819
- import * as path43 from "path";
5783
+ import * as path42 from "path";
5820
5784
  import chalk8 from "chalk";
5821
5785
 
5822
5786
  // src/utils/first-run.ts
5823
5787
  import * as fs23 from "fs";
5824
5788
  import * as os6 from "os";
5825
- import * as path42 from "path";
5826
- var HARNESS_DIR = path42.join(os6.homedir(), ".harness");
5827
- var MARKER_FILE = path42.join(HARNESS_DIR, ".setup-complete");
5789
+ import * as path41 from "path";
5790
+ var HARNESS_DIR = path41.join(os6.homedir(), ".harness");
5791
+ var MARKER_FILE = path41.join(HARNESS_DIR, ".setup-complete");
5828
5792
  function isFirstRun() {
5829
5793
  return !fs23.existsSync(MARKER_FILE);
5830
5794
  }
@@ -5868,7 +5832,7 @@ function runSlashCommandGeneration() {
5868
5832
  }
5869
5833
  }
5870
5834
  function detectClient(dirName) {
5871
- return fs24.existsSync(path43.join(os7.homedir(), dirName));
5835
+ return fs24.existsSync(path42.join(os7.homedir(), dirName));
5872
5836
  }
5873
5837
  async function runMcpSetup(cwd) {
5874
5838
  const results = [];
@@ -5910,7 +5874,7 @@ function formatStep(result) {
5910
5874
  }
5911
5875
  function configureTier0Integrations(cwd) {
5912
5876
  try {
5913
- const mcpPath = path43.join(cwd, ".mcp.json");
5877
+ const mcpPath = path42.join(cwd, ".mcp.json");
5914
5878
  const config = readMcpConfig(mcpPath);
5915
5879
  const tier0 = INTEGRATION_REGISTRY.filter((i) => i.tier === 0);
5916
5880
  const added = [];
@@ -5919,9 +5883,9 @@ function configureTier0Integrations(cwd) {
5919
5883
  writeMcpEntry(mcpPath, integration.name, integration.mcpConfig);
5920
5884
  added.push(integration.displayName);
5921
5885
  }
5922
- const geminiDir = path43.join(cwd, ".gemini");
5886
+ const geminiDir = path42.join(cwd, ".gemini");
5923
5887
  if (fs24.existsSync(geminiDir)) {
5924
- const geminiPath = path43.join(geminiDir, "settings.json");
5888
+ const geminiPath = path42.join(geminiDir, "settings.json");
5925
5889
  const geminiConfig = readMcpConfig(geminiPath);
5926
5890
  for (const integration of tier0) {
5927
5891
  if (!geminiConfig.mcpServers[integration.name]) {
@@ -5941,6 +5905,44 @@ function configureTier0Integrations(cwd) {
5941
5905
  return { status: "fail", message: `Tier 0 integration configuration failed \u2014 ${msg}` };
5942
5906
  }
5943
5907
  }
5908
+ function ensureHooks(cwd) {
5909
+ const configPath = path42.join(cwd, "harness.config.json");
5910
+ if (!fs24.existsSync(configPath)) {
5911
+ return { status: "warn", message: "Not a harness project \u2014 skipped hook installation" };
5912
+ }
5913
+ let profile = "standard";
5914
+ const profilePath = path42.join(cwd, ".harness", "hooks", "profile.json");
5915
+ try {
5916
+ const data = JSON.parse(fs24.readFileSync(profilePath, "utf-8"));
5917
+ if (data.profile && ["minimal", "standard", "strict"].includes(data.profile)) {
5918
+ profile = data.profile;
5919
+ }
5920
+ } catch {
5921
+ }
5922
+ try {
5923
+ const result = initHooks({ profile, projectDir: cwd });
5924
+ return {
5925
+ status: "pass",
5926
+ message: `Installed ${result.copiedScripts.length} hooks (${profile} profile)`
5927
+ };
5928
+ } catch (error) {
5929
+ const msg = error instanceof Error ? error.message : String(error);
5930
+ return { status: "warn", message: `Hook installation skipped \u2014 ${msg}` };
5931
+ }
5932
+ }
5933
+ async function runInitialGraphScan(cwd) {
5934
+ try {
5935
+ const { runScan: runScan2 } = await import("./scan-U67OKDRS.js");
5936
+ const result = await runScan2(cwd);
5937
+ return {
5938
+ status: "pass",
5939
+ message: `Built knowledge graph: ${result.nodeCount} nodes, ${result.edgeCount} edges`
5940
+ };
5941
+ } catch (error) {
5942
+ const msg = error instanceof Error ? error.message : String(error);
5943
+ return { status: "warn", message: `Knowledge graph creation skipped \u2014 ${msg}` };
5944
+ }
5945
+ }
5944
5946
  async function runSetup(cwd) {
5945
5947
  const steps = [];
5946
5948
  const nodeResult = checkNodeVersion3();
@@ -5954,6 +5956,10 @@ async function runSetup(cwd) {
5954
5956
  steps.push(...mcpResults);
5955
5957
  const tier0Result = configureTier0Integrations(cwd);
5956
5958
  steps.push(tier0Result);
5959
+ const hooksResult = ensureHooks(cwd);
5960
+ steps.push(hooksResult);
5961
+ const graphResult = await runInitialGraphScan(cwd);
5962
+ steps.push(graphResult);
5957
5963
  const success = steps.every((s) => s.status !== "fail");
5958
5964
  if (success) {
5959
5965
  markSetupComplete();
@@ -5961,7 +5967,7 @@ async function runSetup(cwd) {
5961
5967
  return { steps, success };
5962
5968
  }
5963
5969
  function createSetupCommand() {
5964
- return new Command54("setup").description("Configure harness environment: slash commands, MCP, and more").action(async () => {
5970
+ return new Command53("setup").description("Configure harness environment: slash commands, MCP, and more").action(async () => {
5965
5971
  const cwd = process.cwd();
5966
5972
  console.log("");
5967
5973
  console.log(` ${chalk8.bold("harness setup")}`);
@@ -5983,14 +5989,14 @@ function createSetupCommand() {
5983
5989
  }
5984
5990
 
5985
5991
  // src/commands/share.ts
5986
- import { Command as Command55 } from "commander";
5992
+ import { Command as Command54 } from "commander";
5987
5993
  import * as fs25 from "fs";
5988
- import * as path44 from "path";
5994
+ import * as path43 from "path";
5989
5995
  import { parse as parseYaml } from "yaml";
5990
5996
  var MANIFEST_FILENAME = "constraints.yaml";
5991
5997
  async function runShareAction(projectPath, options) {
5992
- const rootDir = path44.resolve(projectPath);
5993
- const manifestPath = path44.join(rootDir, MANIFEST_FILENAME);
5998
+ const rootDir = path43.resolve(projectPath);
5999
+ const manifestPath = path43.join(rootDir, MANIFEST_FILENAME);
5994
6000
  if (!fs25.existsSync(manifestPath)) {
5995
6001
  logger.error(
5996
6002
  `No ${MANIFEST_FILENAME} found at ${manifestPath}.
@@ -6014,7 +6020,7 @@ Create a constraints.yaml in your project root to define what to share.`
6014
6020
  process.exit(1);
6015
6021
  }
6016
6022
  const manifest = manifestResult.value;
6017
- const configResult = resolveConfig(path44.join(rootDir, "harness.config.json"));
6023
+ const configResult = resolveConfig(path43.join(rootDir, "harness.config.json"));
6018
6024
  if (!configResult.ok) {
6019
6025
  logger.error(configResult.error.message);
6020
6026
  process.exit(1);
@@ -6032,8 +6038,8 @@ Create a constraints.yaml in your project root to define what to share.`
6032
6038
  );
6033
6039
  process.exit(1);
6034
6040
  }
6035
- const outputDir = path44.resolve(options.output);
6036
- const outputPath = path44.join(outputDir, `${manifest.name}.harness-constraints.json`);
6041
+ const outputDir = path43.resolve(options.output);
6042
+ const outputPath = path43.join(outputDir, `${manifest.name}.harness-constraints.json`);
6037
6043
  const writeResult = await writeConfig(outputPath, bundle);
6038
6044
  if (!writeResult.ok) {
6039
6045
  logger.error(`Failed to write bundle: ${writeResult.error.message}`);
@@ -6042,25 +6048,25 @@ Create a constraints.yaml in your project root to define what to share.`
6042
6048
  logger.success(`Bundle written to ${outputPath}`);
6043
6049
  }
6044
6050
  function createShareCommand() {
6045
- return new Command55("share").description("Extract and publish a constraints bundle from constraints.yaml").argument("[path]", "Path to the project root", ".").option("-o, --output <dir>", "Output directory for the bundle", ".").action(async (projectPath, options) => {
6051
+ return new Command54("share").description("Extract and publish a constraints bundle from constraints.yaml").argument("[path]", "Path to the project root", ".").option("-o, --output <dir>", "Output directory for the bundle", ".").action(async (projectPath, options) => {
6046
6052
  await runShareAction(projectPath, options);
6047
6053
  });
6048
6054
  }
6049
6055
 
6050
6056
  // src/commands/skill/index.ts
6051
- import { Command as Command63 } from "commander";
6057
+ import { Command as Command62 } from "commander";
6052
6058
 
6053
6059
  // src/commands/skill/list.ts
6054
- import { Command as Command56 } from "commander";
6060
+ import { Command as Command55 } from "commander";
6055
6061
  import * as fs26 from "fs";
6056
- import * as path45 from "path";
6062
+ import * as path44 from "path";
6057
6063
  import { parse } from "yaml";
6058
6064
  function scanDirectory(dirPath, source) {
6059
6065
  if (!fs26.existsSync(dirPath)) return [];
6060
6066
  const entries = fs26.readdirSync(dirPath, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
6061
6067
  const skills = [];
6062
6068
  for (const name of entries) {
6063
- const yamlPath = path45.join(dirPath, name, "skill.yaml");
6069
+ const yamlPath = path44.join(dirPath, name, "skill.yaml");
6064
6070
  if (!fs26.existsSync(yamlPath)) continue;
6065
6071
  try {
6066
6072
  const raw = fs26.readFileSync(yamlPath, "utf-8");
@@ -6081,10 +6087,10 @@ function scanDirectory(dirPath, source) {
6081
6087
  }
6082
6088
  function collectCommunitySkills(seen, allSkills) {
6083
6089
  const globalDir = resolveGlobalSkillsDir();
6084
- const skillsDir = path45.dirname(globalDir);
6085
- const communityBase = path45.join(skillsDir, "community");
6086
- const communityPlatformDir = path45.join(communityBase, "claude-code");
6087
- const lockfilePath = path45.join(communityBase, "skills-lock.json");
6090
+ const skillsDir = path44.dirname(globalDir);
6091
+ const communityBase = path44.join(skillsDir, "community");
6092
+ const communityPlatformDir = path44.join(communityBase, "claude-code");
6093
+ const lockfilePath = path44.join(communityBase, "skills-lock.json");
6088
6094
  const lockfile = readLockfile2(lockfilePath);
6089
6095
  const communitySkills = scanDirectory(communityPlatformDir, "community");
6090
6096
  for (const skill of communitySkills) {
@@ -6154,7 +6160,7 @@ function printSkillsVerbose(skills) {
6154
6160
  for (const s of skills) printSkillEntry(s);
6155
6161
  }
6156
6162
  function createListCommand3() {
6157
- return new Command56("list").description("List available skills").option("--installed", "Show only community-installed skills").option("--local", "Show only project-local skills").option("--all", "Show all skills (default)").action(async (opts, cmd) => {
6163
+ return new Command55("list").description("List available skills").option("--installed", "Show only community-installed skills").option("--local", "Show only project-local skills").option("--all", "Show all skills (default)").action(async (opts, cmd) => {
6158
6164
  const globalOpts = cmd.optsWithGlobals();
6159
6165
  const skills = collectSkills({ filter: resolveFilter(opts) });
6160
6166
  if (globalOpts.json) {
@@ -6169,9 +6175,9 @@ function createListCommand3() {
6169
6175
  }
6170
6176
 
6171
6177
  // src/commands/skill/run.ts
6172
- import { Command as Command57 } from "commander";
6178
+ import { Command as Command56 } from "commander";
6173
6179
  import * as fs27 from "fs";
6174
- import * as path46 from "path";
6180
+ import * as path45 from "path";
6175
6181
  import { parse as parse2 } from "yaml";
6176
6182
 
6177
6183
  // src/skill/complexity.ts
@@ -6267,7 +6273,7 @@ ${options.principles}`);
6267
6273
 
6268
6274
  // src/commands/skill/run.ts
6269
6275
  function loadSkillMetadata(skillDir) {
6270
- const yamlPath = path46.join(skillDir, "skill.yaml");
6276
+ const yamlPath = path45.join(skillDir, "skill.yaml");
6271
6277
  if (!fs27.existsSync(yamlPath)) return null;
6272
6278
  try {
6273
6279
  const result = SkillMetadataSchema.safeParse(parse2(fs27.readFileSync(yamlPath, "utf-8")));
@@ -6282,18 +6288,18 @@ function resolveComplexity(metadata, requested, projectPath) {
6282
6288
  return requested;
6283
6289
  }
6284
6290
  function loadPrinciples(projectPath) {
6285
- const principlesPath = path46.join(projectPath, "docs", "principles.md");
6291
+ const principlesPath = path45.join(projectPath, "docs", "principles.md");
6286
6292
  return fs27.existsSync(principlesPath) ? fs27.readFileSync(principlesPath, "utf-8") : void 0;
6287
6293
  }
6288
6294
  function readMostRecentFileInDir(dirPath) {
6289
- const files = fs27.readdirSync(dirPath).map((f) => ({ name: f, mtime: fs27.statSync(path46.join(dirPath, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime);
6290
- if (files.length > 0) return fs27.readFileSync(path46.join(dirPath, files[0].name), "utf-8");
6295
+ const files = fs27.readdirSync(dirPath).map((f) => ({ name: f, mtime: fs27.statSync(path45.join(dirPath, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime);
6296
+ if (files.length > 0) return fs27.readFileSync(path45.join(dirPath, files[0].name), "utf-8");
6291
6297
  return void 0;
6292
6298
  }
6293
6299
  function loadPriorState(metadata, projectPath) {
6294
6300
  if (!metadata?.state.persistent || metadata.state.files.length === 0) return void 0;
6295
6301
  for (const stateFilePath of metadata.state.files) {
6296
- const fullPath = path46.join(projectPath, stateFilePath);
6302
+ const fullPath = path45.join(projectPath, stateFilePath);
6297
6303
  if (!fs27.existsSync(fullPath)) continue;
6298
6304
  const stat = fs27.statSync(fullPath);
6299
6305
  if (stat.isDirectory()) return readMostRecentFileInDir(fullPath);
@@ -6317,7 +6323,7 @@ function resolvePhaseState(metadata, projectPath, phase) {
6317
6323
  }
6318
6324
  function appendProjectState(content, metadata, projectPath, hasPathOpt) {
6319
6325
  if (!metadata?.state.persistent || !hasPathOpt) return content;
6320
- const stateFile = path46.join(projectPath, ".harness", "state.json");
6326
+ const stateFile = path45.join(projectPath, ".harness", "state.json");
6321
6327
  if (!fs27.existsSync(stateFile)) return content;
6322
6328
  const stateContent = fs27.readFileSync(stateFile, "utf-8");
6323
6329
  return content + `
@@ -6331,14 +6337,14 @@ ${stateContent}
6331
6337
  }
6332
6338
  async function runSkill(name, opts) {
6333
6339
  const skillsDir = resolveSkillsDir();
6334
- const skillDir = path46.join(skillsDir, name);
6340
+ const skillDir = path45.join(skillsDir, name);
6335
6341
  if (!fs27.existsSync(skillDir)) {
6336
6342
  logger.error(`Skill not found: ${name}`);
6337
6343
  process.exit(ExitCode.ERROR);
6338
6344
  return;
6339
6345
  }
6340
6346
  const metadata = loadSkillMetadata(skillDir);
6341
- const projectPath = opts.path ? path46.resolve(opts.path) : process.cwd();
6347
+ const projectPath = opts.path ? path45.resolve(opts.path) : process.cwd();
6342
6348
  const complexity = resolveComplexity(
6343
6349
  metadata,
6344
6350
  opts.complexity ?? "standard",
@@ -6365,7 +6371,7 @@ async function runSkill(name, opts) {
6365
6371
  ...stateWarning !== void 0 && { stateWarning },
6366
6372
  ...opts.party !== void 0 && { party: opts.party }
6367
6373
  });
6368
- const skillMdPath = path46.join(skillDir, "SKILL.md");
6374
+ const skillMdPath = path45.join(skillDir, "SKILL.md");
6369
6375
  if (!fs27.existsSync(skillMdPath)) {
6370
6376
  logger.error(`SKILL.md not found for skill: ${name}`);
6371
6377
  process.exit(ExitCode.ERROR);
@@ -6381,13 +6387,13 @@ async function runSkill(name, opts) {
6381
6387
  process.exit(ExitCode.SUCCESS);
6382
6388
  }
6383
6389
  function createRunCommand2() {
6384
- return new Command57("run").description("Run a skill (outputs SKILL.md content with context preamble)").argument("<name>", "Skill name (e.g., harness-tdd)").option("--path <path>", "Project root path for context injection").option("--complexity <level>", "Rigor level: fast, standard, thorough", "standard").option("--phase <name>", "Start at a specific phase (for re-entry)").option("--party", "Enable multi-perspective evaluation").action(async (name, opts) => runSkill(name, opts));
6390
+ return new Command56("run").description("Run a skill (outputs SKILL.md content with context preamble)").argument("<name>", "Skill name (e.g., harness-tdd)").option("--path <path>", "Project root path for context injection").option("--complexity <level>", "Rigor level: fast, standard, thorough", "standard").option("--phase <name>", "Start at a specific phase (for re-entry)").option("--party", "Enable multi-perspective evaluation").action(async (name, opts) => runSkill(name, opts));
6385
6391
  }
6386
6392
 
6387
6393
  // src/commands/skill/validate.ts
6388
- import { Command as Command58 } from "commander";
6394
+ import { Command as Command57 } from "commander";
6389
6395
  import * as fs28 from "fs";
6390
- import * as path47 from "path";
6396
+ import * as path46 from "path";
6391
6397
  import { parse as parse3 } from "yaml";
6392
6398
  var BEHAVIORAL_REQUIRED_SECTIONS = [
6393
6399
  "## When to Use",
@@ -6428,8 +6434,8 @@ function validateSkillMd(name, skillMdPath, skillType, errors) {
6428
6434
  }
6429
6435
  }
6430
6436
  function validateSkillEntry(name, skillsDir, errors) {
6431
- const skillDir = path47.join(skillsDir, name);
6432
- const yamlPath = path47.join(skillDir, "skill.yaml");
6437
+ const skillDir = path46.join(skillsDir, name);
6438
+ const yamlPath = path46.join(skillDir, "skill.yaml");
6433
6439
  if (!fs28.existsSync(yamlPath)) {
6434
6440
  errors.push(`${name}: missing skill.yaml`);
6435
6441
  return false;
@@ -6441,7 +6447,7 @@ function validateSkillEntry(name, skillsDir, errors) {
6441
6447
  errors.push(`${name}/skill.yaml: ${result.error.message}`);
6442
6448
  return false;
6443
6449
  }
6444
- validateSkillMd(name, path47.join(skillDir, "SKILL.md"), result.data.type, errors);
6450
+ validateSkillMd(name, path46.join(skillDir, "SKILL.md"), result.data.type, errors);
6445
6451
  return true;
6446
6452
  } catch (e) {
6447
6453
  errors.push(`${name}: parse error \u2014 ${e instanceof Error ? e.message : String(e)}`);
@@ -6449,7 +6455,7 @@ function validateSkillEntry(name, skillsDir, errors) {
6449
6455
  }
6450
6456
  }
6451
6457
  function createValidateCommand2() {
6452
- return new Command58("validate").description("Validate all skill.yaml files and SKILL.md structure").action(async (_opts, cmd) => {
6458
+ return new Command57("validate").description("Validate all skill.yaml files and SKILL.md structure").action(async (_opts, cmd) => {
6453
6459
  const globalOpts = cmd.optsWithGlobals();
6454
6460
  const skillsDir = resolveSkillsDir();
6455
6461
  if (!fs28.existsSync(skillsDir)) {
@@ -6479,18 +6485,18 @@ function createValidateCommand2() {
6479
6485
  }
6480
6486
 
6481
6487
  // src/commands/skill/info.ts
6482
- import { Command as Command59 } from "commander";
6488
+ import { Command as Command58 } from "commander";
6483
6489
  import * as fs29 from "fs";
6484
- import * as path48 from "path";
6490
+ import * as path47 from "path";
6485
6491
  import { parse as parse4 } from "yaml";
6486
6492
  function loadSkillMetadata2(name) {
6487
6493
  const skillsDir = resolveSkillsDir();
6488
- const skillDir = path48.join(skillsDir, name);
6494
+ const skillDir = path47.join(skillsDir, name);
6489
6495
  if (!fs29.existsSync(skillDir)) {
6490
6496
  logger.error(`Skill not found: ${name}`);
6491
6497
  return { ok: false, exitCode: ExitCode.ERROR };
6492
6498
  }
6493
- const yamlPath = path48.join(skillDir, "skill.yaml");
6499
+ const yamlPath = path47.join(skillDir, "skill.yaml");
6494
6500
  if (!fs29.existsSync(yamlPath)) {
6495
6501
  logger.error(`skill.yaml not found for skill: ${name}`);
6496
6502
  return { ok: false, exitCode: ExitCode.ERROR };
@@ -6525,7 +6531,7 @@ function printSkillInfo(skill) {
6525
6531
  console.log(`Persistent: ${skill.state.persistent}`);
6526
6532
  }
6527
6533
  function createInfoCommand() {
6528
- return new Command59("info").description("Show metadata for a skill").argument("<name>", "Skill name (e.g., harness-tdd)").action(async (name, _opts, cmd) => {
6534
+ return new Command58("info").description("Show metadata for a skill").argument("<name>", "Skill name (e.g., harness-tdd)").action(async (name, _opts, cmd) => {
6529
6535
  const globalOpts = cmd.optsWithGlobals();
6530
6536
  const loaded = loadSkillMetadata2(name);
6531
6537
  if (!loaded.ok) {
@@ -6542,7 +6548,7 @@ function createInfoCommand() {
6542
6548
  }
6543
6549
 
6544
6550
  // src/commands/skill/search.ts
6545
- import { Command as Command60 } from "commander";
6551
+ import { Command as Command59 } from "commander";
6546
6552
  async function runSearch(query, opts) {
6547
6553
  const results = await searchNpmRegistry(query, opts.registry);
6548
6554
  return results.filter((r) => {
@@ -6587,14 +6593,14 @@ async function runSearchAction(query, opts, globalOpts) {
6587
6593
  }
6588
6594
  }
6589
6595
  function createSearchCommand() {
6590
- return new Command60("search").description("Search for community skills on the @harness-skills registry").argument("<query>", "Search query").option("--platform <platform>", "Filter by platform (e.g., claude-code)").option("--trigger <trigger>", "Filter by trigger type (e.g., manual, automatic)").option("--registry <url>", "Use a custom npm registry URL").action(async (query, opts, cmd) => {
6596
+ return new Command59("search").description("Search for community skills on the @harness-skills registry").argument("<query>", "Search query").option("--platform <platform>", "Filter by platform (e.g., claude-code)").option("--trigger <trigger>", "Filter by trigger type (e.g., manual, automatic)").option("--registry <url>", "Use a custom npm registry URL").action(async (query, opts, cmd) => {
6591
6597
  await runSearchAction(query, opts, cmd.optsWithGlobals());
6592
6598
  });
6593
6599
  }
6594
6600
 
6595
6601
  // src/commands/skill/create.ts
6596
- import { Command as Command61 } from "commander";
6597
- import * as path49 from "path";
6602
+ import { Command as Command60 } from "commander";
6603
+ import * as path48 from "path";
6598
6604
  import * as fs30 from "fs";
6599
6605
  import YAML from "yaml";
6600
6606
  var KEBAB_CASE_RE = /^[a-z][a-z0-9]*(-[a-z0-9]+)*$/;
@@ -6679,21 +6685,21 @@ function runCreate(name, opts) {
6679
6685
  if (!KEBAB_CASE_RE.test(name)) {
6680
6686
  throw new Error(`Invalid skill name "${name}". Must be kebab-case (e.g., my-skill).`);
6681
6687
  }
6682
- const baseDir = opts.outputDir ?? path49.join(process.cwd(), "agents", "skills", "claude-code");
6683
- const skillDir = path49.join(baseDir, name);
6688
+ const baseDir = opts.outputDir ?? path48.join(process.cwd(), "agents", "skills", "claude-code");
6689
+ const skillDir = path48.join(baseDir, name);
6684
6690
  if (fs30.existsSync(skillDir)) {
6685
6691
  throw new Error(`Skill directory already exists: ${skillDir}`);
6686
6692
  }
6687
6693
  fs30.mkdirSync(skillDir, { recursive: true });
6688
6694
  const description = opts.description || `A community skill: ${name}`;
6689
6695
  const skillYaml = buildSkillYaml(name, opts);
6690
- const skillYamlPath = path49.join(skillDir, "skill.yaml");
6696
+ const skillYamlPath = path48.join(skillDir, "skill.yaml");
6691
6697
  fs30.writeFileSync(skillYamlPath, YAML.stringify(skillYaml));
6692
6698
  const skillMd = buildSkillMd(name, description);
6693
- const skillMdPath = path49.join(skillDir, "SKILL.md");
6699
+ const skillMdPath = path48.join(skillDir, "SKILL.md");
6694
6700
  fs30.writeFileSync(skillMdPath, skillMd);
6695
6701
  const readme = buildReadme(name, description);
6696
- const readmePath = path49.join(skillDir, "README.md");
6702
+ const readmePath = path48.join(skillDir, "README.md");
6697
6703
  fs30.writeFileSync(readmePath, readme);
6698
6704
  return {
6699
6705
  name,
@@ -6708,12 +6714,12 @@ function printCreateResult(name, result) {
6708
6714
  }
6709
6715
  logger.info(`
6710
6716
  Next steps:`);
6711
- logger.info(` 1. Edit ${path49.join(result.directory, "SKILL.md")} with your skill content`);
6717
+ logger.info(` 1. Edit ${path48.join(result.directory, "SKILL.md")} with your skill content`);
6712
6718
  logger.info(` 2. Run: harness skill validate ${name}`);
6713
6719
  logger.info(` 3. Run: harness skills publish`);
6714
6720
  }
6715
6721
  function createCreateCommand() {
6716
- return new Command61("create").description("Scaffold a new community skill").argument("<name>", "Skill name (kebab-case)").option("--description <desc>", "Skill description").option("--type <type>", "Skill type: rigid or flexible", "flexible").option("--platforms <platforms>", "Comma-separated platforms (default: claude-code)").option("--triggers <triggers>", "Comma-separated triggers (default: manual)").option("--output-dir <dir>", "Output directory (default: agents/skills/claude-code/)").action(async (name, opts, cmd) => {
6722
+ return new Command60("create").description("Scaffold a new community skill").argument("<name>", "Skill name (kebab-case)").option("--description <desc>", "Skill description").option("--type <type>", "Skill type: rigid or flexible", "flexible").option("--platforms <platforms>", "Comma-separated platforms (default: claude-code)").option("--triggers <triggers>", "Comma-separated triggers (default: manual)").option("--output-dir <dir>", "Output directory (default: agents/skills/claude-code/)").action(async (name, opts, cmd) => {
6717
6723
  const globalOpts = cmd.optsWithGlobals();
6718
6724
  try {
6719
6725
  const result = runCreate(name, {
@@ -6736,19 +6742,19 @@ function createCreateCommand() {
6736
6742
  }
6737
6743
 
6738
6744
  // src/commands/skill/publish.ts
6739
- import { Command as Command62 } from "commander";
6745
+ import { Command as Command61 } from "commander";
6740
6746
  import * as fs32 from "fs";
6741
- import * as path51 from "path";
6747
+ import * as path50 from "path";
6742
6748
  import { execFileSync as execFileSync5 } from "child_process";
6743
6749
 
6744
6750
  // src/registry/validator.ts
6745
6751
  import * as fs31 from "fs";
6746
- import * as path50 from "path";
6752
+ import * as path49 from "path";
6747
6753
  import { parse as parse5 } from "yaml";
6748
6754
  import semver4 from "semver";
6749
6755
  async function validateForPublish(skillDir, registryUrl) {
6750
6756
  const errors = [];
6751
- const skillYamlPath = path50.join(skillDir, "skill.yaml");
6757
+ const skillYamlPath = path49.join(skillDir, "skill.yaml");
6752
6758
  if (!fs31.existsSync(skillYamlPath)) {
6753
6759
  errors.push("skill.yaml not found. Create one with: harness skill create <name>");
6754
6760
  return { valid: false, errors };
@@ -6777,7 +6783,7 @@ async function validateForPublish(skillDir, registryUrl) {
6777
6783
  if (!skillMeta.triggers || skillMeta.triggers.length === 0) {
6778
6784
  errors.push("At least one trigger is required. Add triggers to skill.yaml.");
6779
6785
  }
6780
- const skillMdPath = path50.join(skillDir, "SKILL.md");
6786
+ const skillMdPath = path49.join(skillDir, "SKILL.md");
6781
6787
  if (!fs31.existsSync(skillMdPath)) {
6782
6788
  errors.push("SKILL.md not found. Create it with content describing your skill.");
6783
6789
  } else {
@@ -6861,11 +6867,11 @@ ${errorList}`);
6861
6867
  }
6862
6868
  const meta = validation.skillMeta;
6863
6869
  const pkg = derivePackageJson(meta);
6864
- const pkgPath = path51.join(skillDir, "package.json");
6870
+ const pkgPath = path50.join(skillDir, "package.json");
6865
6871
  fs32.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + "\n");
6866
- const readmePath = path51.join(skillDir, "README.md");
6872
+ const readmePath = path50.join(skillDir, "README.md");
6867
6873
  if (!fs32.existsSync(readmePath)) {
6868
- const skillMdContent = fs32.readFileSync(path51.join(skillDir, "SKILL.md"), "utf-8");
6874
+ const skillMdContent = fs32.readFileSync(path50.join(skillDir, "SKILL.md"), "utf-8");
6869
6875
  const readme = `# ${pkg.name}
6870
6876
 
6871
6877
  ${meta.description}
@@ -6905,7 +6911,7 @@ ${skillMdContent}`;
6905
6911
  };
6906
6912
  }
6907
6913
  function createPublishCommand() {
6908
- return new Command62("publish").description("Validate and publish a skill to @harness-skills on npm").option("--dry-run", "Run validation and generate package.json without publishing").option("--dir <dir>", "Skill directory (default: current directory)").option("--registry <url>", "Use a custom npm registry URL").action(async (opts, cmd) => {
6914
+ return new Command61("publish").description("Validate and publish a skill to @harness-skills on npm").option("--dry-run", "Run validation and generate package.json without publishing").option("--dir <dir>", "Skill directory (default: current directory)").option("--registry <url>", "Use a custom npm registry URL").action(async (opts, cmd) => {
6909
6915
  const globalOpts = cmd.optsWithGlobals();
6910
6916
  const skillDir = opts.dir || process.cwd();
6911
6917
  try {
@@ -6930,7 +6936,7 @@ function createPublishCommand() {
6930
6936
 
6931
6937
  // src/commands/skill/index.ts
6932
6938
  function createSkillCommand() {
6933
- const command = new Command63("skill").description("Skill management commands");
6939
+ const command = new Command62("skill").description("Skill management commands");
6934
6940
  command.addCommand(createListCommand3());
6935
6941
  command.addCommand(createRunCommand2());
6936
6942
  command.addCommand(createValidateCommand2());
@@ -6942,7 +6948,7 @@ function createSkillCommand() {
6942
6948
  }
6943
6949
 
6944
6950
  // src/commands/snapshot.ts
6945
- import { Command as Command64 } from "commander";
6951
+ import { Command as Command63 } from "commander";
6946
6952
  import { execSync as execSync5 } from "child_process";
6947
6953
  import chalk9 from "chalk";
6948
6954
  function getCommitHash3(cwd) {
@@ -7124,7 +7130,7 @@ function registerListCommand(parent) {
7124
7130
  });
7125
7131
  }
7126
7132
  function createSnapshotCommand() {
7127
- const command = new Command64("snapshot").description("Architecture timeline snapshot commands");
7133
+ const command = new Command63("snapshot").description("Architecture timeline snapshot commands");
7128
7134
  registerCaptureCommand(command);
7129
7135
  registerTrendsCommand(command);
7130
7136
  registerListCommand(command);
@@ -7132,11 +7138,11 @@ function createSnapshotCommand() {
7132
7138
  }
7133
7139
 
7134
7140
  // src/commands/state/index.ts
7135
- import { Command as Command69 } from "commander";
7141
+ import { Command as Command68 } from "commander";
7136
7142
 
7137
7143
  // src/commands/state/show.ts
7138
- import { Command as Command65 } from "commander";
7139
- import * as path52 from "path";
7144
+ import { Command as Command64 } from "commander";
7145
+ import * as path51 from "path";
7140
7146
  function printStateText(state, stream) {
7141
7147
  if (stream) console.log(`Stream: ${stream}`);
7142
7148
  console.log(`Schema Version: ${state.schemaVersion}`);
@@ -7160,9 +7166,9 @@ function printStateProgress(progress) {
7160
7166
  }
7161
7167
  }
7162
7168
  function createShowCommand() {
7163
- return new Command65("show").description("Show current project state").option("--path <path>", "Project root path", ".").option("--stream <name>", "Target a specific stream").action(async (opts, cmd) => {
7169
+ return new Command64("show").description("Show current project state").option("--path <path>", "Project root path", ".").option("--stream <name>", "Target a specific stream").action(async (opts, cmd) => {
7164
7170
  const globalOpts = cmd.optsWithGlobals();
7165
- const result = await loadState(path52.resolve(opts.path), opts.stream);
7171
+ const result = await loadState(path51.resolve(opts.path), opts.stream);
7166
7172
  if (!result.ok) {
7167
7173
  logger.error(result.error.message);
7168
7174
  process.exit(ExitCode.ERROR);
@@ -7177,9 +7183,9 @@ function createShowCommand() {
7177
7183
  }
7178
7184
 
7179
7185
  // src/commands/state/reset.ts
7180
- import { Command as Command66 } from "commander";
7186
+ import { Command as Command65 } from "commander";
7181
7187
  import * as fs33 from "fs";
7182
- import * as path53 from "path";
7188
+ import * as path52 from "path";
7183
7189
  import * as readline from "readline";
7184
7190
  async function resolveStatePath(projectPath, stream) {
7185
7191
  if (stream) {
@@ -7188,20 +7194,20 @@ async function resolveStatePath(projectPath, stream) {
7188
7194
  logger.error(streamResult.error.message);
7189
7195
  process.exit(ExitCode.ERROR);
7190
7196
  }
7191
- return path53.join(streamResult.value, "state.json");
7197
+ return path52.join(streamResult.value, "state.json");
7192
7198
  }
7193
- return path53.join(projectPath, ".harness", "state.json");
7199
+ return path52.join(projectPath, ".harness", "state.json");
7194
7200
  }
7195
7201
  async function confirmReset() {
7196
7202
  const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
7197
- const answer = await new Promise((resolve33) => {
7198
- rl.question("Reset project state? This cannot be undone. [y/N] ", resolve33);
7203
+ const answer = await new Promise((resolve32) => {
7204
+ rl.question("Reset project state? This cannot be undone. [y/N] ", resolve32);
7199
7205
  });
7200
7206
  rl.close();
7201
7207
  return answer.toLowerCase() === "y" || answer.toLowerCase() === "yes";
7202
7208
  }
7203
7209
  async function runReset(opts) {
7204
- const projectPath = path53.resolve(opts.path);
7210
+ const projectPath = path52.resolve(opts.path);
7205
7211
  const statePath = await resolveStatePath(projectPath, opts.stream);
7206
7212
  if (!fs33.existsSync(statePath)) {
7207
7213
  logger.info("No state file found. Nothing to reset.");
@@ -7221,15 +7227,15 @@ async function runReset(opts) {
7221
7227
  process.exit(ExitCode.SUCCESS);
7222
7228
  }
7223
7229
  function createResetCommand() {
7224
- return new Command66("reset").description("Reset project state (deletes .harness/state.json)").option("--path <path>", "Project root path", ".").option("--stream <name>", "Target a specific stream").option("--yes", "Skip confirmation prompt").action(async (opts) => runReset(opts));
7230
+ return new Command65("reset").description("Reset project state (deletes .harness/state.json)").option("--path <path>", "Project root path", ".").option("--stream <name>", "Target a specific stream").option("--yes", "Skip confirmation prompt").action(async (opts) => runReset(opts));
7225
7231
  }
7226
7232
 
7227
7233
  // src/commands/state/learn.ts
7228
- import { Command as Command67 } from "commander";
7229
- import * as path54 from "path";
7234
+ import { Command as Command66 } from "commander";
7235
+ import * as path53 from "path";
7230
7236
  function createLearnCommand() {
7231
- return new Command67("learn").description("Append a learning to .harness/learnings.md").argument("<message>", "The learning to record").option("--path <path>", "Project root path", ".").option("--stream <name>", "Target a specific stream").action(async (message, opts, _cmd) => {
7232
- const projectPath = path54.resolve(opts.path);
7237
+ return new Command66("learn").description("Append a learning to .harness/learnings.md").argument("<message>", "The learning to record").option("--path <path>", "Project root path", ".").option("--stream <name>", "Target a specific stream").action(async (message, opts, _cmd) => {
7238
+ const projectPath = path53.resolve(opts.path);
7233
7239
  const result = await appendLearning(projectPath, message, void 0, void 0, opts.stream);
7234
7240
  if (!result.ok) {
7235
7241
  logger.error(result.error.message);
@@ -7242,10 +7248,10 @@ function createLearnCommand() {
7242
7248
  }
7243
7249
 
7244
7250
  // src/commands/state/streams.ts
7245
- import { Command as Command68 } from "commander";
7246
- import * as path55 from "path";
7251
+ import { Command as Command67 } from "commander";
7252
+ import * as path54 from "path";
7247
7253
  async function runListStreams(opts, globalOpts) {
7248
- const projectPath = path55.resolve(opts.path);
7254
+ const projectPath = path54.resolve(opts.path);
7249
7255
  const indexResult = await loadStreamIndex(projectPath);
7250
7256
  const result = await listStreams(projectPath);
7251
7257
  if (!result.ok) {
@@ -7266,7 +7272,7 @@ async function runListStreams(opts, globalOpts) {
7266
7272
  process.exit(ExitCode.SUCCESS);
7267
7273
  }
7268
7274
  async function runCreateStream(name, opts) {
7269
- const result = await createStream(path55.resolve(opts.path), name, opts.branch);
7275
+ const result = await createStream(path54.resolve(opts.path), name, opts.branch);
7270
7276
  if (!result.ok) {
7271
7277
  logger.error(result.error.message);
7272
7278
  process.exit(ExitCode.ERROR);
@@ -7275,7 +7281,7 @@ async function runCreateStream(name, opts) {
7275
7281
  process.exit(ExitCode.SUCCESS);
7276
7282
  }
7277
7283
  async function runArchiveStream(name, opts) {
7278
- const result = await archiveStream(path55.resolve(opts.path), name);
7284
+ const result = await archiveStream(path54.resolve(opts.path), name);
7279
7285
  if (!result.ok) {
7280
7286
  logger.error(result.error.message);
7281
7287
  process.exit(ExitCode.ERROR);
@@ -7284,7 +7290,7 @@ async function runArchiveStream(name, opts) {
7284
7290
  process.exit(ExitCode.SUCCESS);
7285
7291
  }
7286
7292
  async function runActivateStream(name, opts) {
7287
- const result = await setActiveStream(path55.resolve(opts.path), name);
7293
+ const result = await setActiveStream(path54.resolve(opts.path), name);
7288
7294
  if (!result.ok) {
7289
7295
  logger.error(result.error.message);
7290
7296
  process.exit(ExitCode.ERROR);
@@ -7293,7 +7299,7 @@ async function runActivateStream(name, opts) {
7293
7299
  process.exit(ExitCode.SUCCESS);
7294
7300
  }
7295
7301
  function createStreamsCommand() {
7296
- const command = new Command68("streams").description("Manage state streams");
7302
+ const command = new Command67("streams").description("Manage state streams");
7297
7303
  command.command("list").description("List all known streams").option("--path <path>", "Project root path", ".").action(async (opts, cmd) => runListStreams(opts, cmd.optsWithGlobals()));
7298
7304
  command.command("create <name>").description("Create a new stream").option("--path <path>", "Project root path", ".").option("--branch <branch>", "Associate with a git branch").action(async (name, opts) => runCreateStream(name, opts));
7299
7305
  command.command("archive <name>").description("Archive a stream").option("--path <path>", "Project root path", ".").action(async (name, opts) => runArchiveStream(name, opts));
@@ -7303,7 +7309,7 @@ function createStreamsCommand() {
7303
7309
 
7304
7310
  // src/commands/state/index.ts
7305
7311
  function createStateCommand() {
7306
- const command = new Command69("state").description("Project state management commands");
7312
+ const command = new Command68("state").description("Project state management commands");
7307
7313
  command.addCommand(createShowCommand());
7308
7314
  command.addCommand(createResetCommand());
7309
7315
  command.addCommand(createLearnCommand());
@@ -7312,7 +7318,7 @@ function createStateCommand() {
7312
7318
  }
7313
7319
 
7314
7320
  // src/commands/taint.ts
7315
- import { Command as Command70 } from "commander";
7321
+ import { Command as Command69 } from "commander";
7316
7322
  function getProjectRoot() {
7317
7323
  return process.cwd();
7318
7324
  }
@@ -7384,25 +7390,25 @@ function registerStatusCommand(taint) {
7384
7390
  });
7385
7391
  }
7386
7392
  function createTaintCommand() {
7387
- const taint = new Command70("taint").description("Manage sentinel session taint state");
7393
+ const taint = new Command69("taint").description("Manage sentinel session taint state");
7388
7394
  registerClearCommand(taint);
7389
7395
  registerStatusCommand(taint);
7390
7396
  return taint;
7391
7397
  }
7392
7398
 
7393
7399
  // src/commands/telemetry/index.ts
7394
- import { Command as Command73 } from "commander";
7400
+ import { Command as Command72 } from "commander";
7395
7401
 
7396
7402
  // src/commands/telemetry/identify.ts
7397
- import { Command as Command71 } from "commander";
7403
+ import { Command as Command70 } from "commander";
7398
7404
  import * as fs34 from "fs";
7399
- import * as path56 from "path";
7405
+ import * as path55 from "path";
7400
7406
  function telemetryFilePath(cwd) {
7401
- return path56.join(cwd, ".harness", "telemetry.json");
7407
+ return path55.join(cwd, ".harness", "telemetry.json");
7402
7408
  }
7403
7409
  function writeTelemetryFile(cwd, data) {
7404
7410
  const filePath = telemetryFilePath(cwd);
7405
- const dir = path56.dirname(filePath);
7411
+ const dir = path55.dirname(filePath);
7406
7412
  fs34.mkdirSync(dir, { recursive: true });
7407
7413
  fs34.writeFileSync(filePath, JSON.stringify(data, null, 2) + "\n", "utf-8");
7408
7414
  }
@@ -7418,7 +7424,7 @@ function printIdentity(identity) {
7418
7424
  }
7419
7425
  }
7420
7426
  function createIdentifyCommand() {
7421
- const cmd = new Command71("identify").description("Set or clear telemetry identity fields in .harness/telemetry.json").option("--project <name>", "Project name").option("--team <name>", "Team name").option("--alias <name>", "User alias").option("--clear", "Remove all identity fields").action((opts) => {
7427
+ const cmd = new Command70("identify").description("Set or clear telemetry identity fields in .harness/telemetry.json").option("--project <name>", "Project name").option("--team <name>", "Team name").option("--alias <name>", "User alias").option("--clear", "Remove all identity fields").action((opts) => {
7422
7428
  const cwd = process.cwd();
7423
7429
  if (opts.clear) {
7424
7430
  writeTelemetryFile(cwd, { identity: {} });
@@ -7442,7 +7448,7 @@ function createIdentifyCommand() {
7442
7448
  }
7443
7449
 
7444
7450
  // src/commands/telemetry/status.ts
7445
- import { Command as Command72 } from "commander";
7451
+ import { Command as Command71 } from "commander";
7446
7452
  function gatherEnvOverrides() {
7447
7453
  const overrides = {};
7448
7454
  if (process.env.DO_NOT_TRACK) overrides.DO_NOT_TRACK = process.env.DO_NOT_TRACK;
@@ -7480,7 +7486,7 @@ function printHumanStatus(result) {
7480
7486
  }
7481
7487
  }
7482
7488
  function createStatusCommand() {
7483
- const cmd = new Command72("status").description("Show current telemetry consent state, install ID, and identity").option("--json", "Output as JSON").action((opts) => {
7489
+ const cmd = new Command71("status").description("Show current telemetry consent state, install ID, and identity").option("--json", "Output as JSON").action((opts) => {
7484
7490
  const cwd = process.cwd();
7485
7491
  const envOverrides = gatherEnvOverrides();
7486
7492
  const consent = resolveConsent(cwd, void 0);
@@ -7513,14 +7519,14 @@ function createStatusCommand() {
7513
7519
 
7514
7520
  // src/commands/telemetry/index.ts
7515
7521
  function createTelemetryCommand() {
7516
- const command = new Command73("telemetry").description("Telemetry identity and status management");
7522
+ const command = new Command72("telemetry").description("Telemetry identity and status management");
7517
7523
  command.addCommand(createIdentifyCommand());
7518
7524
  command.addCommand(createStatusCommand());
7519
7525
  return command;
7520
7526
  }
7521
7527
 
7522
7528
  // src/commands/traceability.ts
7523
- import { Command as Command74 } from "commander";
7529
+ import { Command as Command73 } from "commander";
7524
7530
  import chalk10 from "chalk";
7525
7531
  function confidenceLabel(maxConfidence) {
7526
7532
  if (maxConfidence >= 0.8) return "explicit";
@@ -7651,7 +7657,7 @@ async function runTraceability(options) {
7651
7657
  process.exit(ExitCode.SUCCESS);
7652
7658
  }
7653
7659
  function createTraceabilityCommand() {
7654
- return new Command74("traceability").description("Show spec-to-implementation traceability from the knowledge graph").option("--spec <path>", "Filter by spec file path").option("--feature <name>", "Filter by feature name").action(async (opts, cmd) => {
7660
+ return new Command73("traceability").description("Show spec-to-implementation traceability from the knowledge graph").option("--spec <path>", "Filter by spec file path").option("--feature <name>", "Filter by feature name").action(async (opts, cmd) => {
7655
7661
  const globalOpts = cmd.optsWithGlobals();
7656
7662
  await runTraceability({
7657
7663
  spec: opts.spec,
@@ -7664,15 +7670,15 @@ function createTraceabilityCommand() {
7664
7670
  }
7665
7671
 
7666
7672
  // src/commands/uninstall.ts
7667
- import * as path57 from "path";
7668
- import { Command as Command75 } from "commander";
7673
+ import * as path56 from "path";
7674
+ import { Command as Command74 } from "commander";
7669
7675
  async function runUninstall(skillName, options) {
7670
7676
  const packageName = resolvePackageName(skillName);
7671
7677
  const shortName = extractSkillName(packageName);
7672
7678
  const globalDir = resolveGlobalSkillsDir();
7673
- const skillsDir = path57.dirname(globalDir);
7674
- const communityBase = path57.join(skillsDir, "community");
7675
- const lockfilePath = path57.join(communityBase, "skills-lock.json");
7679
+ const skillsDir = path56.dirname(globalDir);
7680
+ const communityBase = path56.join(skillsDir, "community");
7681
+ const lockfilePath = path56.join(communityBase, "skills-lock.json");
7676
7682
  const lockfile = readLockfile2(lockfilePath);
7677
7683
  const entry = lockfile.skills[packageName];
7678
7684
  if (!entry) {
@@ -7702,7 +7708,7 @@ async function runUninstall(skillName, options) {
7702
7708
  return result;
7703
7709
  }
7704
7710
  function createUninstallCommand() {
7705
- const cmd = new Command75("uninstall");
7711
+ const cmd = new Command74("uninstall");
7706
7712
  cmd.description("Uninstall a community skill").argument("<skill>", "Skill name or @harness-skills/scoped package name").option("--force", "Remove even if other skills depend on this one").action(async (skill, opts) => {
7707
7713
  try {
7708
7714
  const result = await runUninstall(skill, opts);
@@ -7722,8 +7728,8 @@ function createUninstallCommand() {
7722
7728
 
7723
7729
  // src/commands/uninstall-constraints.ts
7724
7730
  import * as fs35 from "fs/promises";
7725
- import * as path58 from "path";
7726
- import { Command as Command76 } from "commander";
7731
+ import * as path57 from "path";
7732
+ import { Command as Command75 } from "commander";
7727
7733
  async function runUninstallConstraints(options) {
7728
7734
  const { packageName, configPath, lockfilePath } = options;
7729
7735
  const lockfileResult = await readLockfile(lockfilePath);
@@ -7780,11 +7786,11 @@ async function runUninstallConstraints(options) {
7780
7786
  };
7781
7787
  }
7782
7788
  function createUninstallConstraintsCommand() {
7783
- const cmd = new Command76("uninstall-constraints");
7789
+ const cmd = new Command75("uninstall-constraints");
7784
7790
  cmd.description("Remove a previously installed constraints package").argument("<name>", "Name of the constraint package to uninstall").option("-c, --config <path>", "Path to harness.config.json").action(async (name, opts) => {
7785
7791
  let configPath;
7786
7792
  if (opts.config) {
7787
- configPath = path58.resolve(opts.config);
7793
+ configPath = path57.resolve(opts.config);
7788
7794
  } else {
7789
7795
  const found = findConfigFile();
7790
7796
  if (!found.ok) {
@@ -7793,8 +7799,8 @@ function createUninstallConstraintsCommand() {
7793
7799
  }
7794
7800
  configPath = found.value;
7795
7801
  }
7796
- const projectRoot = path58.dirname(configPath);
7797
- const lockfilePath = path58.join(projectRoot, ".harness", "constraints.lock.json");
7802
+ const projectRoot = path57.dirname(configPath);
7803
+ const lockfilePath = path57.join(projectRoot, ".harness", "constraints.lock.json");
7798
7804
  const result = await runUninstallConstraints({
7799
7805
  packageName: name,
7800
7806
  configPath,
@@ -7819,9 +7825,10 @@ function createUninstallConstraintsCommand() {
7819
7825
  }
7820
7826
 
7821
7827
  // src/commands/update.ts
7822
- import { Command as Command77 } from "commander";
7828
+ import { Command as Command76 } from "commander";
7823
7829
  import { execFile, execFileSync as execFileSync6 } from "child_process";
7824
- import { realpathSync } from "fs";
7830
+ import { realpathSync, existsSync as existsSync33, readFileSync as readFileSync20 } from "fs";
7831
+ import { join as join46 } from "path";
7825
7832
  import { promisify } from "util";
7826
7833
  import readline2 from "readline";
7827
7834
  import chalk11 from "chalk";
@@ -7887,16 +7894,48 @@ function prompt(question) {
7887
7894
  input: process.stdin,
7888
7895
  output: process.stdout
7889
7896
  });
7890
- return new Promise((resolve33) => {
7897
+ return new Promise((resolve32) => {
7891
7898
  rl.question(question, (answer) => {
7892
7899
  rl.close();
7893
- resolve33(answer.trim().toLowerCase());
7900
+ resolve32(answer.trim().toLowerCase());
7894
7901
  });
7895
7902
  });
7896
7903
  }
7904
+ function refreshHooks() {
7905
+ const cwd = process.cwd();
7906
+ const configPath = join46(cwd, "harness.config.json");
7907
+ if (!existsSync33(configPath)) return;
7908
+ let profile = "standard";
7909
+ const profilePath = join46(cwd, ".harness", "hooks", "profile.json");
7910
+ try {
7911
+ const data = JSON.parse(readFileSync20(profilePath, "utf-8"));
7912
+ if (data.profile && ["minimal", "standard", "strict"].includes(data.profile)) {
7913
+ profile = data.profile;
7914
+ }
7915
+ } catch {
7916
+ }
7917
+ try {
7918
+ const result = initHooks({ profile, projectDir: cwd });
7919
+ logger.success(`Refreshed ${result.copiedScripts.length} hooks (${profile} profile)`);
7920
+ } catch (err) {
7921
+ const msg = err instanceof Error ? err.message : String(err);
7922
+ logger.warn(`Hook refresh failed: ${msg}`);
7923
+ }
7924
+ }
7925
+ function runLocalGraphScan() {
7926
+ try {
7927
+ logger.info("Scanning codebase to rebuild knowledge graph...");
7928
+ execFileSync6("harness", ["graph", "scan", "."], { stdio: "inherit" });
7929
+ } catch {
7930
+ logger.warn("Graph scan failed. Run manually:");
7931
+ console.log(` ${chalk11.cyan("harness graph scan .")}`);
7932
+ }
7933
+ }
7897
7934
  async function offerRegeneration() {
7898
7935
  console.log("");
7899
- const regenAnswer = await prompt("Regenerate slash commands and agent definitions? (Y/n) ");
7936
+ const regenAnswer = await prompt(
7937
+ "Regenerate slash commands, agent definitions, and knowledge graph? (Y/n) "
7938
+ );
7900
7939
  if (regenAnswer === "n" || regenAnswer === "no") return;
7901
7940
  const scopeAnswer = await prompt("Generate for (G)lobal or (l)ocal project? (G/l) ");
7902
7941
  const isGlobal = scopeAnswer !== "l" && scopeAnswer !== "local";
@@ -7908,6 +7947,9 @@ async function offerRegeneration() {
7908
7947
  logger.warn("Generation failed. Run manually:");
7909
7948
  console.log(` ${chalk11.cyan(`harness generate${isGlobal ? " --global" : ""}`)}`);
7910
7949
  }
7950
+ if (!isGlobal) {
7951
+ runLocalGraphScan();
7952
+ }
7911
7953
  }
7912
7954
  async function checkAllPackages(packages, installedVersions) {
7913
7955
  logger.info("Checking for updates...");
@@ -7958,6 +8000,7 @@ async function runUpdateAction(opts, globalOpts) {
7958
8000
  const { hasUpdates, outdated } = await checkAllPackages(packages, installedVersions);
7959
8001
  if (!hasUpdates) {
7960
8002
  logger.success("All packages are up to date");
8003
+ refreshHooks();
7961
8004
  await offerRegeneration();
7962
8005
  process.exit(ExitCode.SUCCESS);
7963
8006
  }
@@ -7984,11 +8027,12 @@ async function runUpdateAction(opts, globalOpts) {
7984
8027
  console.log(` ${chalk11.cyan(installCmd)}`);
7985
8028
  process.exit(ExitCode.ERROR);
7986
8029
  }
8030
+ refreshHooks();
7987
8031
  await offerRegeneration();
7988
8032
  process.exit(ExitCode.SUCCESS);
7989
8033
  }
7990
8034
  function createUpdateCommand() {
7991
- return new Command77("update").description("Update all @harness-engineering packages to the latest version").option("--version <semver>", "Pin @harness-engineering/cli to a specific version").option("--force", "Force update even if versions match").option(
8035
+ return new Command76("update").description("Update all @harness-engineering packages to the latest version").option("--version <semver>", "Pin @harness-engineering/cli to a specific version").option("--force", "Force update even if versions match").option(
7992
8036
  "--regenerate",
7993
8037
  "Only regenerate slash commands and agent definitions (skip package updates)"
7994
8038
  ).action(async (opts, cmd) => {
@@ -7998,9 +8042,9 @@ function createUpdateCommand() {
7998
8042
  }
7999
8043
 
8000
8044
  // src/commands/usage.ts
8001
- import { Command as Command78 } from "commander";
8045
+ import { Command as Command77 } from "commander";
8002
8046
  async function loadAndPriceRecords(cwd, includeClaudeSessions = false) {
8003
- const { readCostRecords, loadPricingData, calculateCost, parseCCRecords } = await import("./dist-TZQUURSP.js");
8047
+ const { readCostRecords, loadPricingData, calculateCost, parseCCRecords } = await import("./dist-7EBSGAHX.js");
8004
8048
  const records = readCostRecords(cwd);
8005
8049
  if (includeClaudeSessions) {
8006
8050
  const ccRecords = parseCCRecords();
@@ -8051,7 +8095,7 @@ function registerDailyCommand(usage) {
8051
8095
  }
8052
8096
  return;
8053
8097
  }
8054
- const { aggregateByDay } = await import("./dist-TZQUURSP.js");
8098
+ const { aggregateByDay } = await import("./dist-7EBSGAHX.js");
8055
8099
  const dailyData = aggregateByDay(records);
8056
8100
  const limited = dailyData.slice(0, days);
8057
8101
  if (globalOpts.json) {
@@ -8103,7 +8147,7 @@ function registerSessionsCommand(usage) {
8103
8147
  }
8104
8148
  return;
8105
8149
  }
8106
- const { aggregateBySession } = await import("./dist-TZQUURSP.js");
8150
+ const { aggregateBySession } = await import("./dist-7EBSGAHX.js");
8107
8151
  const sessionData = aggregateBySession(records);
8108
8152
  const limited = sessionData.slice(0, limit);
8109
8153
  if (globalOpts.json) {
@@ -8176,7 +8220,7 @@ function registerSessionCommand(usage) {
8176
8220
  const globalOpts = cmd.optsWithGlobals();
8177
8221
  const cwd = process.cwd();
8178
8222
  const records = await loadAndPriceRecords(cwd, globalOpts.includeClaudeSessions);
8179
- const { aggregateBySession } = await import("./dist-TZQUURSP.js");
8223
+ const { aggregateBySession } = await import("./dist-7EBSGAHX.js");
8180
8224
  const sessionData = aggregateBySession(records);
8181
8225
  const match = sessionData.find((s) => s.sessionId === id);
8182
8226
  if (!match) {
@@ -8209,7 +8253,7 @@ function registerLatestCommand(usage) {
8209
8253
  }
8210
8254
  return;
8211
8255
  }
8212
- const { aggregateBySession } = await import("./dist-TZQUURSP.js");
8256
+ const { aggregateBySession } = await import("./dist-7EBSGAHX.js");
8213
8257
  const sessionData = aggregateBySession(records);
8214
8258
  const latest = sessionData[0];
8215
8259
  if (!latest) {
@@ -8235,7 +8279,7 @@ function registerLatestCommand(usage) {
8235
8279
  });
8236
8280
  }
8237
8281
  function createUsageCommand() {
8238
- const usage = new Command78("usage").description("Token usage and cost tracking");
8282
+ const usage = new Command77("usage").description("Token usage and cost tracking");
8239
8283
  usage.option(
8240
8284
  "--include-claude-sessions",
8241
8285
  "Include Claude Code session data from ~/.claude/projects/"
@@ -8248,15 +8292,15 @@ function createUsageCommand() {
8248
8292
  }
8249
8293
 
8250
8294
  // src/commands/validate.ts
8251
- import { Command as Command79 } from "commander";
8252
- import * as path59 from "path";
8295
+ import { Command as Command78 } from "commander";
8296
+ import * as path58 from "path";
8253
8297
  async function runValidate(options) {
8254
8298
  const configResult = resolveConfig(options.configPath);
8255
8299
  if (!configResult.ok) {
8256
8300
  return configResult;
8257
8301
  }
8258
8302
  const config = configResult.value;
8259
- const cwd = options.cwd ?? (options.configPath ? path59.dirname(path59.resolve(options.configPath)) : process.cwd());
8303
+ const cwd = options.cwd ?? (options.configPath ? path58.dirname(path58.resolve(options.configPath)) : process.cwd());
8260
8304
  const result = {
8261
8305
  valid: true,
8262
8306
  checks: {
@@ -8266,7 +8310,7 @@ async function runValidate(options) {
8266
8310
  },
8267
8311
  issues: []
8268
8312
  };
8269
- const agentsMapPath = path59.resolve(cwd, config.agentsMapPath);
8313
+ const agentsMapPath = path58.resolve(cwd, config.agentsMapPath);
8270
8314
  const agentsResult = await validateAgentsMap(agentsMapPath);
8271
8315
  if (agentsResult.ok) {
8272
8316
  result.checks.agentsMap = true;
@@ -8311,11 +8355,11 @@ function resolveValidateMode(globalOpts) {
8311
8355
  return OutputMode.TEXT;
8312
8356
  }
8313
8357
  async function printCrossCheckWarnings(mode) {
8314
- const { runCrossCheck: runCrossCheck2 } = await import("./validate-cross-check-M4NP2UF5.js");
8358
+ const { runCrossCheck: runCrossCheck2 } = await import("./validate-cross-check-Y4PDR63C.js");
8315
8359
  const cwd = process.cwd();
8316
8360
  const crossResult = await runCrossCheck2({
8317
- specsDir: path59.join(cwd, "docs", "specs"),
8318
- plansDir: path59.join(cwd, "docs", "plans"),
8361
+ specsDir: path58.join(cwd, "docs", "specs"),
8362
+ plansDir: path58.join(cwd, "docs", "plans"),
8319
8363
  projectPath: cwd
8320
8364
  });
8321
8365
  if (!crossResult.ok || crossResult.value.warnings === 0) return;
@@ -8327,7 +8371,7 @@ async function printCrossCheckWarnings(mode) {
8327
8371
  ${crossResult.value.warnings} warnings`);
8328
8372
  }
8329
8373
  function createValidateCommand3() {
8330
- const command = new Command79("validate").description("Run all validation checks").option("--cross-check", "Run cross-artifact consistency validation").action(async (opts, cmd) => {
8374
+ const command = new Command78("validate").description("Run all validation checks").option("--cross-check", "Run cross-artifact consistency validation").action(async (opts, cmd) => {
8331
8375
  const globalOpts = cmd.optsWithGlobals();
8332
8376
  const mode = resolveValidateMode(globalOpts);
8333
8377
  const formatter = new OutputFormatter(mode);
@@ -8412,7 +8456,7 @@ var commandCreators = [
8412
8456
 
8413
8457
  // src/index.ts
8414
8458
  function createProgram() {
8415
- const program = new Command80();
8459
+ const program = new Command79();
8416
8460
  program.name("harness").description("CLI for Harness Engineering toolkit").version(CLI_VERSION).option("-c, --config <path>", "Path to config file").option("--json", "Output as JSON").option("--verbose", "Verbose output").option("--quiet", "Minimal output");
8417
8461
  for (const creator of commandCreators) {
8418
8462
  program.addCommand(creator());
@@ -8424,7 +8468,6 @@ export {
8424
8468
  runCheckArch,
8425
8469
  runGraphStatus,
8426
8470
  runGraphExport,
8427
- runScan,
8428
8471
  runQuery,
8429
8472
  runIngest,
8430
8473
  runImpactPreview,