@harness-engineering/cli 1.27.1 → 1.28.0

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 (108) hide show
  1. package/dist/agents/skills/claude-code/harness-architecture-advisor/SKILL.md +17 -5
  2. package/dist/agents/skills/claude-code/harness-architecture-advisor/skill.yaml +1 -1
  3. package/dist/agents/skills/claude-code/harness-autopilot/SKILL.md +4 -4
  4. package/dist/agents/skills/claude-code/harness-code-review/SKILL.md +1 -1
  5. package/dist/agents/skills/claude-code/harness-design-system/SKILL.md +6 -1
  6. package/dist/agents/skills/claude-code/harness-execution/SKILL.md +4 -4
  7. package/dist/agents/skills/claude-code/harness-i18n-process/SKILL.md +2 -2
  8. package/dist/agents/skills/claude-code/harness-integration/SKILL.md +1 -1
  9. package/dist/agents/skills/claude-code/harness-knowledge-pipeline/SKILL.md +1 -0
  10. package/dist/agents/skills/claude-code/harness-onboarding/SKILL.md +1 -1
  11. package/dist/agents/skills/claude-code/harness-planning/SKILL.md +3 -3
  12. package/dist/agents/skills/claude-code/harness-roadmap/SKILL.md +4 -3
  13. package/dist/agents/skills/claude-code/initialize-harness-project/SKILL.md +150 -10
  14. package/dist/agents/skills/claude-code/initialize-harness-project/skill.yaml +2 -1
  15. package/dist/agents/skills/codex/harness-architecture-advisor/SKILL.md +17 -5
  16. package/dist/agents/skills/codex/harness-architecture-advisor/skill.yaml +1 -1
  17. package/dist/agents/skills/codex/harness-autopilot/SKILL.md +4 -4
  18. package/dist/agents/skills/codex/harness-code-review/SKILL.md +1 -1
  19. package/dist/agents/skills/codex/harness-design-system/SKILL.md +6 -1
  20. package/dist/agents/skills/codex/harness-execution/SKILL.md +4 -4
  21. package/dist/agents/skills/codex/harness-i18n-process/SKILL.md +2 -2
  22. package/dist/agents/skills/codex/harness-integration/SKILL.md +1 -1
  23. package/dist/agents/skills/codex/harness-knowledge-pipeline/SKILL.md +1 -0
  24. package/dist/agents/skills/codex/harness-onboarding/SKILL.md +1 -1
  25. package/dist/agents/skills/codex/harness-planning/SKILL.md +3 -3
  26. package/dist/agents/skills/codex/harness-roadmap/SKILL.md +4 -3
  27. package/dist/agents/skills/codex/initialize-harness-project/SKILL.md +150 -10
  28. package/dist/agents/skills/codex/initialize-harness-project/skill.yaml +2 -1
  29. package/dist/agents/skills/cursor/harness-architecture-advisor/SKILL.md +17 -5
  30. package/dist/agents/skills/cursor/harness-architecture-advisor/skill.yaml +1 -1
  31. package/dist/agents/skills/cursor/harness-autopilot/SKILL.md +4 -4
  32. package/dist/agents/skills/cursor/harness-code-review/SKILL.md +1 -1
  33. package/dist/agents/skills/cursor/harness-design-system/SKILL.md +6 -1
  34. package/dist/agents/skills/cursor/harness-execution/SKILL.md +4 -4
  35. package/dist/agents/skills/cursor/harness-i18n-process/SKILL.md +2 -2
  36. package/dist/agents/skills/cursor/harness-integration/SKILL.md +1 -1
  37. package/dist/agents/skills/cursor/harness-knowledge-pipeline/SKILL.md +1 -0
  38. package/dist/agents/skills/cursor/harness-onboarding/SKILL.md +1 -1
  39. package/dist/agents/skills/cursor/harness-planning/SKILL.md +3 -3
  40. package/dist/agents/skills/cursor/harness-roadmap/SKILL.md +4 -3
  41. package/dist/agents/skills/cursor/initialize-harness-project/SKILL.md +150 -10
  42. package/dist/agents/skills/cursor/initialize-harness-project/skill.yaml +2 -1
  43. package/dist/agents/skills/gemini-cli/harness-architecture-advisor/SKILL.md +17 -5
  44. package/dist/agents/skills/gemini-cli/harness-architecture-advisor/skill.yaml +1 -1
  45. package/dist/agents/skills/gemini-cli/harness-autopilot/SKILL.md +4 -4
  46. package/dist/agents/skills/gemini-cli/harness-code-review/SKILL.md +1 -1
  47. package/dist/agents/skills/gemini-cli/harness-design-system/SKILL.md +6 -1
  48. package/dist/agents/skills/gemini-cli/harness-execution/SKILL.md +4 -4
  49. package/dist/agents/skills/gemini-cli/harness-i18n-process/SKILL.md +2 -2
  50. package/dist/agents/skills/gemini-cli/harness-integration/SKILL.md +1 -1
  51. package/dist/agents/skills/gemini-cli/harness-knowledge-pipeline/SKILL.md +1 -0
  52. package/dist/agents/skills/gemini-cli/harness-onboarding/SKILL.md +1 -1
  53. package/dist/agents/skills/gemini-cli/harness-planning/SKILL.md +3 -3
  54. package/dist/agents/skills/gemini-cli/harness-roadmap/SKILL.md +4 -3
  55. package/dist/agents/skills/gemini-cli/initialize-harness-project/SKILL.md +150 -10
  56. package/dist/agents/skills/gemini-cli/initialize-harness-project/skill.yaml +2 -1
  57. package/dist/{agents-md-2RN666DE.js → agents-md-76IEMV6O.js} +3 -3
  58. package/dist/{architecture-ZR33YKJB.js → architecture-5GVJRRUD.js} +4 -4
  59. package/dist/{assess-project-LLWWEQEV.js → assess-project-WDUFL7SO.js} +1 -1
  60. package/dist/bin/harness-mcp.js +15 -15
  61. package/dist/bin/harness.js +25 -25
  62. package/dist/{check-phase-gate-ZVG56NT2.js → check-phase-gate-QR3ONJYP.js} +4 -4
  63. package/dist/{chunk-FUS4OOGC.js → chunk-3WLXR23L.js} +1 -1
  64. package/dist/{chunk-IBTHD2UA.js → chunk-6JBJ5FSW.js} +2 -1
  65. package/dist/{chunk-C7RPQWBG.js → chunk-77OMOFZL.js} +1 -1
  66. package/dist/{chunk-YZH4I4JO.js → chunk-AJG2LCMA.js} +1 -1
  67. package/dist/{chunk-3AJW7VQ3.js → chunk-CS7K6ZQ3.js} +2 -2
  68. package/dist/{chunk-SDDQPMZK.js → chunk-D25P6763.js} +1 -1
  69. package/dist/{chunk-XKU37HGH.js → chunk-DHGL3SF2.js} +1 -1
  70. package/dist/{chunk-CJYNZMOP.js → chunk-E7QD4YHA.js} +8 -8
  71. package/dist/{chunk-BO4AJZRE.js → chunk-H43UQY6B.js} +1 -1
  72. package/dist/{chunk-SDPHFDQS.js → chunk-ILVO6LZY.js} +1 -1
  73. package/dist/{chunk-BZZNYHRY.js → chunk-K5ZOBBQB.js} +9 -9
  74. package/dist/{chunk-A4ETL34H.js → chunk-KLE6FXWM.js} +23 -1
  75. package/dist/{chunk-F3Y64VNF.js → chunk-L4RURCSF.js} +6 -6
  76. package/dist/{chunk-EGRQHLDM.js → chunk-LINAFNIK.js} +5 -5
  77. package/dist/{chunk-EHTUWULH.js → chunk-OPOSSZJS.js} +97 -93
  78. package/dist/{chunk-L3Y7L4EG.js → chunk-OQS7KURX.js} +1 -1
  79. package/dist/{chunk-T7UZOJF4.js → chunk-QZ46CI6E.js} +9 -9
  80. package/dist/{chunk-MGPVA2EM.js → chunk-TFNQ72RF.js} +5 -5
  81. package/dist/{chunk-3XMOWLK3.js → chunk-USG7DV5N.js} +2 -2
  82. package/dist/{chunk-776JFSPK.js → chunk-VITLE3PS.js} +1 -1
  83. package/dist/{chunk-2FOLD76X.js → chunk-WPSM7WT6.js} +2 -2
  84. package/dist/{chunk-GAIOIINV.js → chunk-X7XQ3ELM.js} +108 -36
  85. package/dist/{chunk-EICASBYP.js → chunk-YZZVOT7I.js} +1 -1
  86. package/dist/{chunk-VCC47EXU.js → chunk-Z63IDQ7Y.js} +860 -412
  87. package/dist/{chunk-Q5DKIL46.js → chunk-Z7ZF2XDL.js} +3 -3
  88. package/dist/{ci-workflow-JFOL4YWW.js → ci-workflow-GYQXE5X4.js} +3 -3
  89. package/dist/{dist-CPKL5Y2R.js → dist-46VOJIG4.js} +2 -2
  90. package/dist/{dist-BZS2XRLG.js → dist-BP6E6QGG.js} +7 -1
  91. package/dist/{docs-FUTRJQHA.js → docs-CVQMSMQC.js} +4 -4
  92. package/dist/{engine-FB3HCNVT.js → engine-23PJMRHA.js} +3 -3
  93. package/dist/{entropy-FIEE4YDA.js → entropy-K2YTZFCP.js} +3 -3
  94. package/dist/{feedback-7EC4T6XG.js → feedback-6HP42GTK.js} +1 -1
  95. package/dist/{generate-agent-definitions-FOSFADNR.js → generate-agent-definitions-6RJKL6VW.js} +4 -4
  96. package/dist/{graph-loader-QEI7SYOQ.js → graph-loader-BI3OFFFS.js} +1 -1
  97. package/dist/index.d.ts +44 -1
  98. package/dist/index.js +25 -25
  99. package/dist/{loader-HXUOBTYA.js → loader-U2WEC3PZ.js} +3 -3
  100. package/dist/{mcp-NUG4BMKJ.js → mcp-N6XVWPXJ.js} +15 -15
  101. package/dist/{performance-TYXBCTR7.js → performance-T3XAESWR.js} +4 -4
  102. package/dist/{review-pipeline-B4WPU6BQ.js → review-pipeline-HTC5HA5X.js} +3 -3
  103. package/dist/{runtime-HQQNOARD.js → runtime-UFXMNN3Q.js} +3 -3
  104. package/dist/{scan-M4EGDAQ2.js → scan-XRGMTO6K.js} +1 -1
  105. package/dist/{security-25VFLIAO.js → security-ROK5IFDA.js} +1 -1
  106. package/dist/{validate-EAVGKZQB.js → validate-IJHHQHT5.js} +4 -4
  107. package/dist/{validate-cross-check-SPL3H4O5.js → validate-cross-check-LUQYIA46.js} +3 -3
  108. package/package.json +6 -6
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  generateRuntime
3
- } from "./chunk-EICASBYP.js";
3
+ } from "./chunk-YZZVOT7I.js";
4
4
  import {
5
5
  generateAgentsMd
6
- } from "./chunk-C7RPQWBG.js";
6
+ } from "./chunk-77OMOFZL.js";
7
7
  import {
8
8
  generateCIWorkflow
9
- } from "./chunk-FUS4OOGC.js";
9
+ } from "./chunk-3WLXR23L.js";
10
10
  import {
11
11
  TemplateEngine
12
- } from "./chunk-L3Y7L4EG.js";
12
+ } from "./chunk-OQS7KURX.js";
13
13
  import {
14
14
  generate,
15
15
  validate
@@ -28,21 +28,21 @@ import {
28
28
  OutputMode,
29
29
  createCheckPhaseGateCommand,
30
30
  findFiles
31
- } from "./chunk-3XMOWLK3.js";
31
+ } from "./chunk-USG7DV5N.js";
32
32
  import {
33
33
  createGenerateAgentDefinitionsCommand,
34
34
  generateAgentDefinitions
35
- } from "./chunk-SDDQPMZK.js";
35
+ } from "./chunk-D25P6763.js";
36
36
  import {
37
37
  toKebabCase
38
38
  } from "./chunk-KET4QQZB.js";
39
39
  import {
40
40
  listPersonas,
41
41
  loadPersona
42
- } from "./chunk-BO4AJZRE.js";
42
+ } from "./chunk-H43UQY6B.js";
43
43
  import {
44
44
  createScanCommand
45
- } from "./chunk-XKU37HGH.js";
45
+ } from "./chunk-DHGL3SF2.js";
46
46
  import {
47
47
  appendFrameworkAgents,
48
48
  captureHealthSnapshot,
@@ -56,17 +56,17 @@ import {
56
56
  loadCachedSnapshot,
57
57
  persistToolingConfig,
58
58
  recommend
59
- } from "./chunk-EHTUWULH.js";
59
+ } from "./chunk-OPOSSZJS.js";
60
60
  import {
61
61
  loadGraphStore
62
- } from "./chunk-776JFSPK.js";
62
+ } from "./chunk-VITLE3PS.js";
63
63
  import {
64
64
  loadOrRebuildIndex
65
65
  } from "./chunk-27AJKSQY.js";
66
66
  import {
67
67
  findConfigFile,
68
68
  resolveConfig
69
- } from "./chunk-A4ETL34H.js";
69
+ } from "./chunk-KLE6FXWM.js";
70
70
  import {
71
71
  VALID_PLATFORMS
72
72
  } from "./chunk-3ISINLYT.js";
@@ -151,7 +151,7 @@ import {
151
151
  validateKnowledgeMap,
152
152
  writeConfig,
153
153
  writeLockfile
154
- } from "./chunk-IBTHD2UA.js";
154
+ } from "./chunk-6JBJ5FSW.js";
155
155
  import {
156
156
  Err,
157
157
  Ok
@@ -176,7 +176,7 @@ import {
176
176
  } from "./chunk-KFQGP6VL.js";
177
177
 
178
178
  // src/index.ts
179
- import { Command as Command85 } from "commander";
179
+ import { Command as Command86 } from "commander";
180
180
 
181
181
  // src/commands/add.ts
182
182
  init_dist();
@@ -365,7 +365,7 @@ function registerSkillsCommand(adoption) {
365
365
  const globalOpts = cmd.optsWithGlobals();
366
366
  const limit = Math.max(parseInt(opts.limit, 10) || 20, 1);
367
367
  const cwd = process.cwd();
368
- const { readAdoptionRecords, aggregateBySkill } = await import("./dist-CPKL5Y2R.js");
368
+ const { readAdoptionRecords, aggregateBySkill } = await import("./dist-46VOJIG4.js");
369
369
  const records = readAdoptionRecords(cwd);
370
370
  if (records.length === 0) {
371
371
  if (globalOpts.json) {
@@ -401,7 +401,7 @@ function registerRecentCommand(adoption) {
401
401
  const globalOpts = cmd.optsWithGlobals();
402
402
  const limit = Math.max(parseInt(opts.limit, 10) || 20, 1);
403
403
  const cwd = process.cwd();
404
- const { readAdoptionRecords } = await import("./dist-CPKL5Y2R.js");
404
+ const { readAdoptionRecords } = await import("./dist-46VOJIG4.js");
405
405
  const records = readAdoptionRecords(cwd);
406
406
  if (records.length === 0) {
407
407
  if (globalOpts.json) {
@@ -479,7 +479,7 @@ function registerSkillCommand(adoption) {
479
479
  adoption.command("skill <name>").description("Show detail for a specific skill").action(async (name, _opts, cmd) => {
480
480
  const globalOpts = cmd.optsWithGlobals();
481
481
  const cwd = process.cwd();
482
- const { readAdoptionRecords, aggregateBySkill } = await import("./dist-CPKL5Y2R.js");
482
+ const { readAdoptionRecords, aggregateBySkill } = await import("./dist-46VOJIG4.js");
483
483
  const records = readAdoptionRecords(cwd);
484
484
  const skillRecords = records.filter((r) => r.skill === name);
485
485
  if (skillRecords.length === 0) {
@@ -1424,10 +1424,10 @@ async function runCheckSecurity(cwd, options) {
1424
1424
  const projectRoot = path8.resolve(cwd);
1425
1425
  let configData = {};
1426
1426
  try {
1427
- const fs41 = await import("fs");
1427
+ const fs42 = await import("fs");
1428
1428
  const configPath = path8.join(projectRoot, "harness.config.json");
1429
- if (fs41.existsSync(configPath)) {
1430
- const raw = fs41.readFileSync(configPath, "utf-8");
1429
+ if (fs42.existsSync(configPath)) {
1430
+ const raw = fs42.readFileSync(configPath, "utf-8");
1431
1431
  const parsed = JSON.parse(raw);
1432
1432
  configData = parsed.security ?? {};
1433
1433
  }
@@ -2768,16 +2768,16 @@ import { Command as Command25 } from "commander";
2768
2768
  // src/commands/graph/status.ts
2769
2769
  import * as path15 from "path";
2770
2770
  async function runGraphStatus(projectPath) {
2771
- const { GraphStore } = await import("./dist-BZS2XRLG.js");
2771
+ const { GraphStore } = await import("./dist-BP6E6QGG.js");
2772
2772
  const graphDir = path15.join(projectPath, ".harness", "graph");
2773
2773
  const store = new GraphStore();
2774
2774
  const loaded = await store.load(graphDir);
2775
2775
  if (!loaded) return { status: "no_graph", message: "No graph found. Run `harness scan` first." };
2776
- const fs41 = await import("fs/promises");
2776
+ const fs42 = await import("fs/promises");
2777
2777
  const metaPath = path15.join(graphDir, "metadata.json");
2778
2778
  let lastScan = "unknown";
2779
2779
  try {
2780
- const meta = JSON.parse(await fs41.readFile(metaPath, "utf-8"));
2780
+ const meta = JSON.parse(await fs42.readFile(metaPath, "utf-8"));
2781
2781
  lastScan = meta.lastScanTimestamp;
2782
2782
  } catch {
2783
2783
  }
@@ -2789,7 +2789,7 @@ async function runGraphStatus(projectPath) {
2789
2789
  let connectorSyncStatus = {};
2790
2790
  try {
2791
2791
  const syncMetaPath = path15.join(graphDir, "sync-metadata.json");
2792
- const syncMeta = JSON.parse(await fs41.readFile(syncMetaPath, "utf-8"));
2792
+ const syncMeta = JSON.parse(await fs42.readFile(syncMetaPath, "utf-8"));
2793
2793
  for (const [name, data] of Object.entries(syncMeta.connectors ?? {})) {
2794
2794
  connectorSyncStatus[name] = data.lastSyncTimestamp;
2795
2795
  }
@@ -2808,7 +2808,7 @@ async function runGraphStatus(projectPath) {
2808
2808
  // src/commands/graph/export.ts
2809
2809
  import * as path16 from "path";
2810
2810
  async function runGraphExport(projectPath, format) {
2811
- const { GraphStore } = await import("./dist-BZS2XRLG.js");
2811
+ const { GraphStore } = await import("./dist-BP6E6QGG.js");
2812
2812
  const graphDir = path16.join(projectPath, ".harness", "graph");
2813
2813
  const store = new GraphStore();
2814
2814
  const loaded = await store.load(graphDir);
@@ -2844,7 +2844,7 @@ import * as path19 from "path";
2844
2844
  import { Command as Command23 } from "commander";
2845
2845
  import * as path17 from "path";
2846
2846
  async function runQuery(projectPath, rootNodeId, opts) {
2847
- const { GraphStore, ContextQL } = await import("./dist-BZS2XRLG.js");
2847
+ const { GraphStore, ContextQL } = await import("./dist-BP6E6QGG.js");
2848
2848
  const store = new GraphStore();
2849
2849
  const graphDir = path17.join(projectPath, ".harness", "graph");
2850
2850
  const loaded = await store.load(graphDir);
@@ -2897,9 +2897,9 @@ import { Command as Command24 } from "commander";
2897
2897
  import * as path18 from "path";
2898
2898
  async function loadConnectorConfig(projectPath, source) {
2899
2899
  try {
2900
- const fs41 = await import("fs/promises");
2900
+ const fs42 = await import("fs/promises");
2901
2901
  const configPath = path18.join(projectPath, "harness.config.json");
2902
- const config = JSON.parse(await fs41.readFile(configPath, "utf-8"));
2902
+ const config = JSON.parse(await fs42.readFile(configPath, "utf-8"));
2903
2903
  const connector = config.graph?.connectors?.[source];
2904
2904
  return connector ?? {};
2905
2905
  } catch {
@@ -2941,7 +2941,7 @@ async function runIngest(projectPath, source, opts) {
2941
2941
  ConfluenceConnector,
2942
2942
  FigmaConnector,
2943
2943
  MiroConnector
2944
- } = await import("./dist-BZS2XRLG.js");
2944
+ } = await import("./dist-BP6E6QGG.js");
2945
2945
  const graphDir = path18.join(projectPath, ".harness", "graph");
2946
2946
  const store = new GraphStore();
2947
2947
  await store.load(graphDir);
@@ -2954,7 +2954,7 @@ async function runIngest(projectPath, source, opts) {
2954
2954
  path18.join(projectPath, "docs", "changes")
2955
2955
  );
2956
2956
  const gitResult = await new GitIngestor(store).ingest(projectPath);
2957
- const { createExtractionRunner } = await import("./dist-BZS2XRLG.js");
2957
+ const { createExtractionRunner } = await import("./dist-BP6E6QGG.js");
2958
2958
  const extractedDir = path18.join(projectPath, ".harness", "knowledge", "extracted");
2959
2959
  const signalsResult = await createExtractionRunner().run(projectPath, store, extractedDir);
2960
2960
  const syncManager = new SyncManager(store, graphDir);
@@ -3000,7 +3000,7 @@ async function runIngest(projectPath, source, opts) {
3000
3000
  );
3001
3001
  break;
3002
3002
  case "business-signals": {
3003
- const { createExtractionRunner } = await import("./dist-BZS2XRLG.js");
3003
+ const { createExtractionRunner } = await import("./dist-BP6E6QGG.js");
3004
3004
  const extractedDir = path18.join(projectPath, ".harness", "knowledge", "extracted");
3005
3005
  result = await createExtractionRunner().run(projectPath, store, extractedDir);
3006
3006
  break;
@@ -5299,21 +5299,28 @@ function createKnowledgePipelineCommand() {
5299
5299
  const projectDir = process.cwd();
5300
5300
  try {
5301
5301
  const graphDir = path38.join(projectDir, ".harness", "graph");
5302
- const fs41 = await import("fs/promises");
5303
- await fs41.mkdir(graphDir, { recursive: true });
5304
- const { GraphStore, KnowledgePipelineRunner } = await import("./dist-BZS2XRLG.js");
5302
+ const fs42 = await import("fs/promises");
5303
+ await fs42.mkdir(graphDir, { recursive: true });
5304
+ const { GraphStore, KnowledgePipelineRunner } = await import("./dist-BP6E6QGG.js");
5305
5305
  const store = new GraphStore();
5306
5306
  try {
5307
5307
  await store.load(graphDir);
5308
5308
  } catch {
5309
5309
  }
5310
+ const cfgResult = resolveConfig();
5311
+ const cfgKnowledge = cfgResult.ok ? cfgResult.value.knowledge : void 0;
5312
+ const inferenceOptions = cfgKnowledge && ((cfgKnowledge.domainPatterns?.length ?? 0) > 0 || (cfgKnowledge.domainBlocklist?.length ?? 0) > 0) ? {
5313
+ ...(cfgKnowledge.domainPatterns?.length ?? 0) > 0 ? { extraPatterns: cfgKnowledge.domainPatterns } : {},
5314
+ ...(cfgKnowledge.domainBlocklist?.length ?? 0) > 0 ? { extraBlocklist: cfgKnowledge.domainBlocklist } : {}
5315
+ } : void 0;
5310
5316
  const pipelineOpts = {
5311
5317
  projectDir,
5312
5318
  fix: Boolean(opts.fix),
5313
5319
  ci: Boolean(opts.ci),
5314
5320
  ...opts.domain ? { domain: opts.domain } : {},
5315
5321
  graphDir,
5316
- analyzeImages: Boolean(opts.analyzeImages)
5322
+ analyzeImages: Boolean(opts.analyzeImages),
5323
+ ...inferenceOptions ? { inferenceOptions } : {}
5317
5324
  };
5318
5325
  if (opts.imagePaths) {
5319
5326
  pipelineOpts.imagePaths = opts.imagePaths.split(",").map((p) => p.trim());
@@ -5636,7 +5643,7 @@ function createMcpCommand() {
5636
5643
  parseBudget
5637
5644
  ).action(async (opts) => {
5638
5645
  const [{ startServer: startServer2, getToolDefinitions: getToolDefinitions2 }, { selectTier }] = await Promise.all([
5639
- import("./mcp-NUG4BMKJ.js"),
5646
+ import("./mcp-N6XVWPXJ.js"),
5640
5647
  import("./tool-tiers-7QGZ3FKY.js")
5641
5648
  ]);
5642
5649
  if (opts.tools && opts.tools.length > 0) {
@@ -5656,14 +5663,439 @@ function createMcpCommand() {
5656
5663
  });
5657
5664
  }
5658
5665
 
5659
- // src/commands/orchestrator.ts
5666
+ // src/commands/migrate.ts
5667
+ init_dist();
5660
5668
  import { Command as Command48 } from "commander";
5669
+ import * as fs24 from "fs";
5661
5670
  import * as path40 from "path";
5671
+ import * as readline from "readline";
5672
+ import { execFileSync as execFileSync4 } from "child_process";
5673
+ import chalk7 from "chalk";
5674
+ function isGitRepo(cwd) {
5675
+ try {
5676
+ execFileSync4("git", ["rev-parse", "--is-inside-work-tree"], { cwd, stdio: "pipe" });
5677
+ return true;
5678
+ } catch {
5679
+ return false;
5680
+ }
5681
+ }
5682
+ function readJson2(p) {
5683
+ try {
5684
+ return JSON.parse(fs24.readFileSync(p, "utf8"));
5685
+ } catch {
5686
+ return null;
5687
+ }
5688
+ }
5689
+ function listDirs(p) {
5690
+ if (!fs24.existsSync(p)) return [];
5691
+ return fs24.readdirSync(p, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name);
5692
+ }
5693
+ function listFiles(p, predicate) {
5694
+ if (!fs24.existsSync(p)) return [];
5695
+ return fs24.readdirSync(p, { withFileTypes: true }).filter((e) => e.isFile() && predicate(e.name)).map((e) => e.name);
5696
+ }
5697
+ function walk(dir, predicate) {
5698
+ if (!fs24.existsSync(dir)) return [];
5699
+ const out = [];
5700
+ for (const entry of fs24.readdirSync(dir, { withFileTypes: true })) {
5701
+ if (entry.name === "node_modules" || entry.name === ".git" || entry.name === "dist") continue;
5702
+ const full = path40.join(dir, entry.name);
5703
+ if (entry.isDirectory()) out.push(...walk(full, predicate));
5704
+ else if (predicate(full)) out.push(full);
5705
+ }
5706
+ return out;
5707
+ }
5708
+ function buildAutopilotMap(cwd) {
5709
+ const map = /* @__PURE__ */ new Map();
5710
+ const sessionsDir = path40.join(cwd, ".harness", "sessions");
5711
+ if (!fs24.existsSync(sessionsDir)) return map;
5712
+ for (const session of listDirs(sessionsDir)) {
5713
+ if (!session.startsWith("changes--")) continue;
5714
+ const statePath = path40.join(sessionsDir, session, "autopilot-state.json");
5715
+ const state = readJson2(statePath);
5716
+ if (!state) continue;
5717
+ const specMatch = (state.specPath ?? "").match(/^docs\/changes\/([^/]+)\/proposal\.md$/);
5718
+ if (!specMatch || !specMatch[1]) continue;
5719
+ const topic = specMatch[1];
5720
+ for (const phase of state.phases ?? []) {
5721
+ if (phase.planPath) map.set(phase.planPath, topic);
5722
+ }
5723
+ }
5724
+ return map;
5725
+ }
5726
+ function extractTopicFromHeader(planAbs, proposalTopics) {
5727
+ let text;
5728
+ try {
5729
+ text = fs24.readFileSync(planAbs, "utf8").slice(0, 4e3);
5730
+ } catch {
5731
+ return null;
5732
+ }
5733
+ const patterns = [
5734
+ /docs\/changes\/([a-z0-9-]+)\/proposal\.md/i,
5735
+ /\*\*Spec[^:]*:\*\*\s*\[?[^\]]*?docs\/changes\/([a-z0-9-]+)/i
5736
+ ];
5737
+ for (const re of patterns) {
5738
+ const m = text.match(re);
5739
+ if (m && m[1] && proposalTopics.has(m[1])) return m[1];
5740
+ }
5741
+ return null;
5742
+ }
5743
+ function extractTopicFromFilename(filename, proposalTopics) {
5744
+ const stripped = filename.replace(/\.md$/, "").replace(/^\d{4}-\d{2}-\d{2}-/, "").replace(/-plan$/, "").replace(/-phase\d+(-plan)?$/, "");
5745
+ if (proposalTopics.has(stripped)) return stripped;
5746
+ let best = null;
5747
+ for (const topic of proposalTopics) {
5748
+ const matches = stripped === topic || stripped.startsWith(`${topic}-`);
5749
+ if (matches && (!best || topic.length > best.length)) best = topic;
5750
+ }
5751
+ return best;
5752
+ }
5753
+ async function buildPlan(opts) {
5754
+ const cwd = opts.cwd ?? process.cwd();
5755
+ const configPath = path40.join(cwd, "harness.config.json");
5756
+ const configResult = fs24.existsSync(configPath) ? resolveConfig(configPath) : null;
5757
+ let docsDir;
5758
+ if (configResult?.ok) {
5759
+ docsDir = configResult.value.docsDir;
5760
+ } else if (configResult && !configResult.ok) {
5761
+ docsDir = "./docs";
5762
+ logger.warn(
5763
+ ` harness.config.json failed to load (${configResult.error.message}); defaulting docsDir to ./docs`
5764
+ );
5765
+ } else {
5766
+ docsDir = "./docs";
5767
+ }
5768
+ const docsAbs = path40.resolve(cwd, docsDir);
5769
+ const relRaw = path40.relative(cwd, docsAbs).replaceAll("\\", "/");
5770
+ const docsRel = relRaw === "" ? "docs" : relRaw;
5771
+ const plan = {
5772
+ cwd,
5773
+ isGitRepo: isGitRepo(cwd),
5774
+ docsDir: docsRel,
5775
+ adrMoves: [],
5776
+ planMoves: [],
5777
+ orphanPlans: [],
5778
+ proposalTopics: /* @__PURE__ */ new Set()
5779
+ };
5780
+ const legacyAdrDir = path40.join(cwd, ".harness", "architecture");
5781
+ if (fs24.existsSync(legacyAdrDir)) {
5782
+ for (const topic of listDirs(legacyAdrDir)) {
5783
+ const topicSrc = path40.join(legacyAdrDir, topic);
5784
+ for (const file of listFiles(topicSrc, (n) => n.endsWith(".md"))) {
5785
+ const src = `.harness/architecture/${topic}/${file}`;
5786
+ const dest = `${docsRel}/architecture/${topic}/${file}`;
5787
+ plan.adrMoves.push({ src, dest });
5788
+ }
5789
+ }
5790
+ }
5791
+ const legacyPlanDir = path40.join(cwd, "docs", "plans");
5792
+ const changesDir = path40.join(cwd, "docs", "changes");
5793
+ for (const topic of listDirs(changesDir)) {
5794
+ if (fs24.existsSync(path40.join(changesDir, topic, "proposal.md"))) {
5795
+ plan.proposalTopics.add(topic);
5796
+ }
5797
+ }
5798
+ if (fs24.existsSync(legacyPlanDir)) {
5799
+ const autopilotMap = buildAutopilotMap(cwd);
5800
+ for (const file of listFiles(legacyPlanDir, (n) => n.endsWith(".md") && n !== "index.md")) {
5801
+ const planRel = `docs/plans/${file}`;
5802
+ const planAbs = path40.join(legacyPlanDir, file);
5803
+ const isVerification = file.includes("VERIFICATION");
5804
+ const subdir = isVerification ? "verifications" : "plans";
5805
+ let topic = null;
5806
+ let via = null;
5807
+ const fromAutopilot = autopilotMap.get(planRel);
5808
+ if (fromAutopilot) {
5809
+ topic = fromAutopilot;
5810
+ via = "autopilot";
5811
+ } else {
5812
+ const fromHeader = extractTopicFromHeader(planAbs, plan.proposalTopics);
5813
+ if (fromHeader) {
5814
+ topic = fromHeader;
5815
+ via = "header";
5816
+ } else {
5817
+ const fromFilename = extractTopicFromFilename(file, plan.proposalTopics);
5818
+ if (fromFilename) {
5819
+ topic = fromFilename;
5820
+ via = "filename";
5821
+ }
5822
+ }
5823
+ }
5824
+ if (topic && via) {
5825
+ plan.planMoves.push({
5826
+ src: planRel,
5827
+ dest: `docs/changes/${topic}/${subdir}/${file}`,
5828
+ topic,
5829
+ via,
5830
+ subdir
5831
+ });
5832
+ } else {
5833
+ plan.orphanPlans.push(planRel);
5834
+ }
5835
+ }
5836
+ }
5837
+ return plan;
5838
+ }
5839
+ function gitMv(cwd, src, dest, useGit) {
5840
+ const destAbs = path40.join(cwd, dest);
5841
+ fs24.mkdirSync(path40.dirname(destAbs), { recursive: true });
5842
+ if (useGit) {
5843
+ try {
5844
+ execFileSync4("git", ["mv", src, dest], { cwd, stdio: "pipe" });
5845
+ return;
5846
+ } catch {
5847
+ }
5848
+ }
5849
+ fs24.renameSync(path40.join(cwd, src), destAbs);
5850
+ }
5851
+ function executeMigration(plan) {
5852
+ let moved = 0;
5853
+ let failed = 0;
5854
+ const allMoves = [
5855
+ ...plan.adrMoves.map((m) => ({ src: m.src, dest: m.dest })),
5856
+ ...plan.planMoves.map((m) => ({ src: m.src, dest: m.dest }))
5857
+ ];
5858
+ for (const { src, dest } of allMoves) {
5859
+ try {
5860
+ gitMv(plan.cwd, src, dest, plan.isGitRepo);
5861
+ moved++;
5862
+ } catch (err) {
5863
+ failed++;
5864
+ logger.error(` ${src} -> ${dest}: ${err.message}`);
5865
+ }
5866
+ }
5867
+ return { moved, failed };
5868
+ }
5869
+ function buildPathLookup(plan) {
5870
+ const lookup = /* @__PURE__ */ new Map();
5871
+ for (const m of plan.adrMoves) lookup.set(m.src, m.dest);
5872
+ for (const m of plan.planMoves) lookup.set(m.src, m.dest);
5873
+ return lookup;
5874
+ }
5875
+ function updateReferences(plan) {
5876
+ const lookup = buildPathLookup(plan);
5877
+ if (lookup.size === 0) return { files: 0, replacements: 0 };
5878
+ let files = 0;
5879
+ let replacements = 0;
5880
+ const targets = [
5881
+ ...walk(path40.join(plan.cwd, "docs"), (p) => p.endsWith(".md")),
5882
+ ...walk(path40.join(plan.cwd, ".harness", "sessions"), (p) => p.endsWith(".json"))
5883
+ ];
5884
+ for (const target of targets) {
5885
+ let text;
5886
+ try {
5887
+ text = fs24.readFileSync(target, "utf8");
5888
+ } catch {
5889
+ continue;
5890
+ }
5891
+ let result = text;
5892
+ let count = 0;
5893
+ for (const [oldPath, newPath] of lookup) {
5894
+ if (!result.includes(oldPath)) continue;
5895
+ const occurrences = result.split(oldPath).length - 1;
5896
+ result = result.split(oldPath).join(newPath);
5897
+ count += occurrences;
5898
+ }
5899
+ if (count > 0 && result !== text) {
5900
+ fs24.writeFileSync(target, result);
5901
+ files++;
5902
+ replacements += count;
5903
+ }
5904
+ }
5905
+ return { files, replacements };
5906
+ }
5907
+ async function prompt(question, def = "n") {
5908
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
5909
+ const answer = await new Promise((resolve37) => rl.question(question, resolve37));
5910
+ rl.close();
5911
+ return (answer.trim() || def).toLowerCase();
5912
+ }
5913
+ async function resolveOrphans(plan, opts) {
5914
+ if (plan.orphanPlans.length === 0) return Ok({ bucketed: false });
5915
+ const strategy = opts.orphanStrategy ?? "ask";
5916
+ if (opts.dryRun && strategy === "ask") {
5917
+ logger.info(
5918
+ ` Dry run + --orphan-strategy=ask: not prompting; ${plan.orphanPlans.length} orphan(s) would be asked about interactively.`
5919
+ );
5920
+ return Ok({ bucketed: false });
5921
+ }
5922
+ if (strategy === "skip" || strategy === "ask" && !process.stdin.isTTY) {
5923
+ logger.warn(
5924
+ ` Leaving ${plan.orphanPlans.length} orphan plan(s) in docs/plans/ (no proposal match)`
5925
+ );
5926
+ return Ok({ bucketed: false });
5927
+ }
5928
+ if (strategy === "bucket") {
5929
+ const topic = opts.orphanTopic;
5930
+ if (!topic) {
5931
+ return Err(
5932
+ new CLIError(
5933
+ "--orphan-strategy=bucket requires --orphan-topic <name>",
5934
+ ExitCode.VALIDATION_FAILED
5935
+ )
5936
+ );
5937
+ }
5938
+ bucketOrphans(plan, topic);
5939
+ return Ok({ bucketed: true });
5940
+ }
5941
+ console.log("");
5942
+ logger.warn(`Found ${plan.orphanPlans.length} plan(s) with no matching proposal:`);
5943
+ for (const p of plan.orphanPlans.slice(0, 10)) console.log(` - ${p}`);
5944
+ if (plan.orphanPlans.length > 10) console.log(` ... and ${plan.orphanPlans.length - 10} more`);
5945
+ console.log("");
5946
+ console.log(" [s] skip \u2014 leave them in docs/plans/");
5947
+ console.log(" [b] bucket \u2014 move all into a single stub topic");
5948
+ const answer = await prompt("Choose [s/b]: ", "s");
5949
+ if (answer === "b") {
5950
+ const topicAnswer = await prompt("Stub topic name (e.g., legacy-plans): ", "legacy-plans");
5951
+ bucketOrphans(plan, topicAnswer);
5952
+ return Ok({ bucketed: true });
5953
+ }
5954
+ logger.info(` Leaving ${plan.orphanPlans.length} orphan plan(s) in docs/plans/`);
5955
+ return Ok({ bucketed: false });
5956
+ }
5957
+ function bucketOrphans(plan, topic) {
5958
+ for (const src of plan.orphanPlans) {
5959
+ const file = path40.basename(src);
5960
+ const isVerification = file.includes("VERIFICATION");
5961
+ const subdir = isVerification ? "verifications" : "plans";
5962
+ plan.planMoves.push({
5963
+ src,
5964
+ dest: `docs/changes/${topic}/${subdir}/${file}`,
5965
+ topic,
5966
+ via: "orphan-bucket",
5967
+ subdir
5968
+ });
5969
+ }
5970
+ plan.orphanPlans = [];
5971
+ }
5972
+ function summarize(plan) {
5973
+ console.log("");
5974
+ console.log(chalk7.bold(" Migration plan"));
5975
+ console.log("");
5976
+ if (plan.adrMoves.length === 0 && plan.planMoves.length === 0 && plan.orphanPlans.length === 0) {
5977
+ logger.success(" Nothing to migrate. Layout is already up to date.");
5978
+ return;
5979
+ }
5980
+ if (plan.adrMoves.length > 0) {
5981
+ logger.info(
5982
+ ` ADR moves: ${plan.adrMoves.length} file(s) \u2014 .harness/architecture/ \u2192 ${plan.docsDir}/architecture/`
5983
+ );
5984
+ }
5985
+ if (plan.planMoves.length > 0) {
5986
+ const byVia = plan.planMoves.reduce((acc, m) => {
5987
+ acc[m.via] = (acc[m.via] ?? 0) + 1;
5988
+ return acc;
5989
+ }, {});
5990
+ logger.info(
5991
+ ` Plan moves: ${plan.planMoves.length} file(s) \u2014 docs/plans/ \u2192 docs/changes/<topic>/{plans,verifications}/`
5992
+ );
5993
+ for (const [via, n] of Object.entries(byVia)) console.log(chalk7.dim(` via ${via}: ${n}`));
5994
+ }
5995
+ if (plan.orphanPlans.length > 0) {
5996
+ logger.warn(` Orphan plans: ${plan.orphanPlans.length} (no proposal match \u2014 needs decision)`);
5997
+ }
5998
+ console.log("");
5999
+ }
6000
+ async function detectLegacyArtifacts(cwd) {
6001
+ const adrLegacyDir = path40.join(cwd, ".harness", "architecture");
6002
+ const adrLegacy = fs24.existsSync(adrLegacyDir) && listDirs(adrLegacyDir).length > 0;
6003
+ const planLegacyDir = path40.join(cwd, "docs", "plans");
6004
+ const planLegacy = fs24.existsSync(planLegacyDir) && listFiles(planLegacyDir, (n) => n.endsWith(".md") && n !== "index.md").length > 0;
6005
+ return { adrLegacy, planLegacy };
6006
+ }
6007
+ async function runMigrate(opts) {
6008
+ const cwd = opts.cwd ?? process.cwd();
6009
+ const plan = await buildPlan({ ...opts, cwd });
6010
+ summarize(plan);
6011
+ const empty = {
6012
+ movesPlanned: 0,
6013
+ movesApplied: 0,
6014
+ movesFailed: 0,
6015
+ orphansRemaining: 0,
6016
+ references: { files: 0, replacements: 0 },
6017
+ dryRun: opts.dryRun ?? false,
6018
+ cancelled: false
6019
+ };
6020
+ if (plan.adrMoves.length === 0 && plan.planMoves.length === 0 && plan.orphanPlans.length === 0) {
6021
+ return Ok(empty);
6022
+ }
6023
+ const orphanResult = await resolveOrphans(plan, opts);
6024
+ if (!orphanResult.ok) return orphanResult;
6025
+ if (orphanResult.value.bucketed) summarize(plan);
6026
+ const movesPlanned = plan.adrMoves.length + plan.planMoves.length;
6027
+ if (opts.dryRun) {
6028
+ logger.info(" Dry run \u2014 no files moved.");
6029
+ return Ok({
6030
+ ...empty,
6031
+ movesPlanned,
6032
+ orphansRemaining: plan.orphanPlans.length
6033
+ });
6034
+ }
6035
+ if (!opts.yes && process.stdin.isTTY) {
6036
+ const answer = await prompt("Apply this migration? [y/N] ", "n");
6037
+ if (answer !== "y" && answer !== "yes") {
6038
+ logger.info(" Cancelled.");
6039
+ return Ok({ ...empty, movesPlanned, cancelled: true });
6040
+ }
6041
+ }
6042
+ const { moved, failed } = executeMigration(plan);
6043
+ console.log("");
6044
+ if (failed > 0) logger.error(` Moved ${moved} file(s); ${failed} failed.`);
6045
+ else logger.success(` Moved ${moved} file(s).`);
6046
+ let references = { files: 0, replacements: 0 };
6047
+ if (!opts.skipReferences) {
6048
+ references = updateReferences(plan);
6049
+ if (references.replacements > 0) {
6050
+ logger.success(
6051
+ ` Updated ${references.replacements} reference(s) across ${references.files} file(s).`
6052
+ );
6053
+ } else {
6054
+ logger.info(" No reference updates needed.");
6055
+ }
6056
+ }
6057
+ console.log("");
6058
+ logger.info(" Next: review changes with `git status` / `git diff`, then commit.");
6059
+ return Ok({
6060
+ movesPlanned,
6061
+ movesApplied: moved,
6062
+ movesFailed: failed,
6063
+ orphansRemaining: plan.orphanPlans.length,
6064
+ references,
6065
+ dryRun: false,
6066
+ cancelled: false
6067
+ });
6068
+ }
6069
+ function createMigrateCommand() {
6070
+ return new Command48("migrate").description("Migrate legacy harness artifact locations to current layout").option("--dry-run", "Show the migration plan without moving files", false).option("--yes", "Skip confirmation prompt", false).option(
6071
+ "--skip-references",
6072
+ "Do not update path references in docs/sessions after moves",
6073
+ false
6074
+ ).option("--orphan-strategy <strategy>", "How to handle orphan plans (ask|skip|bucket)", "ask").option("--orphan-topic <name>", "Stub topic name when --orphan-strategy=bucket").action(async (options) => {
6075
+ const result = await runMigrate({
6076
+ cwd: process.cwd(),
6077
+ dryRun: options.dryRun,
6078
+ yes: options.yes,
6079
+ skipReferences: options.skipReferences,
6080
+ orphanStrategy: options.orphanStrategy,
6081
+ orphanTopic: options.orphanTopic
6082
+ });
6083
+ if (!result.ok) {
6084
+ logger.error(result.error.message);
6085
+ process.exit(result.error.exitCode);
6086
+ }
6087
+ process.exit(result.value.movesFailed === 0 ? ExitCode.SUCCESS : ExitCode.ERROR);
6088
+ });
6089
+ }
6090
+
6091
+ // src/commands/orchestrator.ts
6092
+ import { Command as Command49 } from "commander";
6093
+ import * as path41 from "path";
5662
6094
  import { Orchestrator, WorkflowLoader, launchTUI } from "@harness-engineering/orchestrator";
5663
6095
  function createOrchestratorCommand() {
5664
- const orchestrator = new Command48("orchestrator");
6096
+ const orchestrator = new Command49("orchestrator");
5665
6097
  orchestrator.command("run").description("Run the orchestrator daemon").option("-w, --workflow <path>", "Path to harness.orchestrator.md", "harness.orchestrator.md").option("--headless", "Run without TUI (server-only mode for use with web dashboard)").action(async (opts) => {
5666
- const workflowPath = path40.resolve(process.cwd(), opts.workflow);
6098
+ const workflowPath = path41.resolve(process.cwd(), opts.workflow);
5667
6099
  const loader = new WorkflowLoader();
5668
6100
  const result = await loader.loadWorkflow(workflowPath);
5669
6101
  if (!result.ok) {
@@ -5696,13 +6128,13 @@ function createOrchestratorCommand() {
5696
6128
 
5697
6129
  // src/commands/perf.ts
5698
6130
  init_dist();
5699
- import { Command as Command49 } from "commander";
5700
- import * as path41 from "path";
6131
+ import { Command as Command50 } from "commander";
6132
+ import * as path42 from "path";
5701
6133
  function registerBenchCommand(perf) {
5702
6134
  perf.command("bench [glob]").description("Run benchmarks via vitest bench").action(async (glob2, _opts, cmd) => {
5703
6135
  const globalOpts = cmd.optsWithGlobals();
5704
6136
  const cwd = process.cwd();
5705
- const { BenchmarkRunner } = await import("./dist-CPKL5Y2R.js");
6137
+ const { BenchmarkRunner } = await import("./dist-46VOJIG4.js");
5706
6138
  const runner = new BenchmarkRunner();
5707
6139
  const benchFiles = runner.discover(cwd, glob2);
5708
6140
  if (benchFiles.length === 0) {
@@ -5766,7 +6198,7 @@ async function runBaselinesShow(globalOpts) {
5766
6198
  }
5767
6199
  async function runBaselinesUpdate(globalOpts) {
5768
6200
  const cwd = process.cwd();
5769
- const { BenchmarkRunner } = await import("./dist-CPKL5Y2R.js");
6201
+ const { BenchmarkRunner } = await import("./dist-46VOJIG4.js");
5770
6202
  const runner = new BenchmarkRunner();
5771
6203
  const manager = new BaselineManager(cwd);
5772
6204
  logger.info("Running benchmarks to update baselines...");
@@ -5807,9 +6239,9 @@ function registerReportCommand(perf) {
5807
6239
  perf.command("report").description("Full performance report with metrics, trends, and hotspots").action(async (_opts, cmd) => {
5808
6240
  const globalOpts = cmd.optsWithGlobals();
5809
6241
  const cwd = process.cwd();
5810
- const { EntropyAnalyzer: EntropyAnalyzer2 } = await import("./dist-CPKL5Y2R.js");
6242
+ const { EntropyAnalyzer: EntropyAnalyzer2 } = await import("./dist-46VOJIG4.js");
5811
6243
  const analyzer = new EntropyAnalyzer2({
5812
- rootDir: path41.resolve(cwd),
6244
+ rootDir: path42.resolve(cwd),
5813
6245
  analyze: { complexity: true, coupling: true }
5814
6246
  });
5815
6247
  const result = await analyzer.analyze();
@@ -5868,7 +6300,7 @@ function registerCriticalPathsCommand(perf) {
5868
6300
  });
5869
6301
  }
5870
6302
  function createPerfCommand() {
5871
- const perf = new Command49("perf").description("Performance benchmark and baseline management");
6303
+ const perf = new Command50("perf").description("Performance benchmark and baseline management");
5872
6304
  registerBenchCommand(perf);
5873
6305
  registerBaselinesCommands(perf);
5874
6306
  registerReportCommand(perf);
@@ -5877,10 +6309,10 @@ function createPerfCommand() {
5877
6309
  }
5878
6310
 
5879
6311
  // src/commands/persona/index.ts
5880
- import { Command as Command52 } from "commander";
6312
+ import { Command as Command53 } from "commander";
5881
6313
 
5882
6314
  // src/commands/persona/list.ts
5883
- import { Command as Command50 } from "commander";
6315
+ import { Command as Command51 } from "commander";
5884
6316
  function printPersonaList(personas) {
5885
6317
  if (personas.length === 0) {
5886
6318
  logger.info("No personas found.");
@@ -5894,7 +6326,7 @@ function printPersonaList(personas) {
5894
6326
  }
5895
6327
  }
5896
6328
  function createListCommand2() {
5897
- return new Command50("list").description("List available agent personas").action(async (_opts, cmd) => {
6329
+ return new Command51("list").description("List available agent personas").action(async (_opts, cmd) => {
5898
6330
  const globalOpts = cmd.optsWithGlobals();
5899
6331
  const personasDir = resolvePersonasDir();
5900
6332
  const result = listPersonas(personasDir);
@@ -5914,51 +6346,51 @@ function createListCommand2() {
5914
6346
  }
5915
6347
 
5916
6348
  // src/commands/persona/generate.ts
5917
- import { Command as Command51 } from "commander";
5918
- import * as fs24 from "fs";
5919
- import * as path42 from "path";
6349
+ import { Command as Command52 } from "commander";
6350
+ import * as fs25 from "fs";
6351
+ import * as path43 from "path";
5920
6352
  function generatePersonaArtifacts(persona, outputDir, only) {
5921
6353
  const slug = toKebabCase(persona.name);
5922
6354
  const generated = [];
5923
6355
  if (!only || only === "runtime") {
5924
6356
  const result = generateRuntime(persona);
5925
6357
  if (result.ok) {
5926
- const outPath = path42.join(outputDir, `${slug}.runtime.json`);
5927
- fs24.mkdirSync(path42.dirname(outPath), { recursive: true });
5928
- fs24.writeFileSync(outPath, result.value);
6358
+ const outPath = path43.join(outputDir, `${slug}.runtime.json`);
6359
+ fs25.mkdirSync(path43.dirname(outPath), { recursive: true });
6360
+ fs25.writeFileSync(outPath, result.value);
5929
6361
  generated.push(outPath);
5930
6362
  }
5931
6363
  }
5932
6364
  if (!only || only === "agents-md") {
5933
6365
  const result = generateAgentsMd(persona);
5934
6366
  if (result.ok) {
5935
- const outPath = path42.join(outputDir, `${slug}.agents.md`);
5936
- fs24.writeFileSync(outPath, result.value);
6367
+ const outPath = path43.join(outputDir, `${slug}.agents.md`);
6368
+ fs25.writeFileSync(outPath, result.value);
5937
6369
  generated.push(outPath);
5938
6370
  }
5939
6371
  }
5940
6372
  if (!only || only === "ci") {
5941
6373
  const result = generateCIWorkflow(persona, "github");
5942
6374
  if (result.ok) {
5943
- const outPath = path42.join(outputDir, ".github", "workflows", `${slug}.yml`);
5944
- fs24.mkdirSync(path42.dirname(outPath), { recursive: true });
5945
- fs24.writeFileSync(outPath, result.value);
6375
+ const outPath = path43.join(outputDir, ".github", "workflows", `${slug}.yml`);
6376
+ fs25.mkdirSync(path43.dirname(outPath), { recursive: true });
6377
+ fs25.writeFileSync(outPath, result.value);
5946
6378
  generated.push(outPath);
5947
6379
  }
5948
6380
  }
5949
6381
  return generated;
5950
6382
  }
5951
6383
  function createGenerateCommand3() {
5952
- return new Command51("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) => {
6384
+ return new Command52("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) => {
5953
6385
  const globalOpts = cmd.optsWithGlobals();
5954
- const personaResult = loadPersona(path42.join(resolvePersonasDir(), `${name}.yaml`));
6386
+ const personaResult = loadPersona(path43.join(resolvePersonasDir(), `${name}.yaml`));
5955
6387
  if (!personaResult.ok) {
5956
6388
  logger.error(personaResult.error.message);
5957
6389
  process.exit(ExitCode.ERROR);
5958
6390
  }
5959
6391
  const generated = generatePersonaArtifacts(
5960
6392
  personaResult.value,
5961
- path42.resolve(opts.outputDir),
6393
+ path43.resolve(opts.outputDir),
5962
6394
  opts.only
5963
6395
  );
5964
6396
  if (!globalOpts.quiet) {
@@ -5971,7 +6403,7 @@ function createGenerateCommand3() {
5971
6403
 
5972
6404
  // src/commands/persona/index.ts
5973
6405
  function createPersonaCommand() {
5974
- const command = new Command52("persona").description("Agent persona management commands");
6406
+ const command = new Command53("persona").description("Agent persona management commands");
5975
6407
  command.addCommand(createListCommand2());
5976
6408
  command.addCommand(createGenerateCommand3());
5977
6409
  return command;
@@ -5979,8 +6411,8 @@ function createPersonaCommand() {
5979
6411
 
5980
6412
  // src/commands/predict.ts
5981
6413
  init_dist();
5982
- import { Command as Command53 } from "commander";
5983
- import chalk7 from "chalk";
6414
+ import { Command as Command54 } from "commander";
6415
+ import chalk8 from "chalk";
5984
6416
  var CATEGORY_ORDER = [
5985
6417
  "circular-deps",
5986
6418
  "layer-violations",
@@ -6001,11 +6433,11 @@ function crossingLabel(weeks) {
6001
6433
  function severityPrefix(severity) {
6002
6434
  switch (severity) {
6003
6435
  case "critical":
6004
- return chalk7.red("[critical]");
6436
+ return chalk8.red("[critical]");
6005
6437
  case "warning":
6006
- return chalk7.yellow("[warning]");
6438
+ return chalk8.yellow("[warning]");
6007
6439
  case "info":
6008
- return chalk7.blue("[info]");
6440
+ return chalk8.blue("[info]");
6009
6441
  }
6010
6442
  }
6011
6443
  function printCategoryTable(result) {
@@ -6085,7 +6517,7 @@ function handlePredictError(err, mode) {
6085
6517
  process.exit(ExitCode.ERROR);
6086
6518
  }
6087
6519
  function createPredictCommand() {
6088
- const command = new Command53("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) => {
6520
+ const command = new Command54("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) => {
6089
6521
  const globalOpts = cmd.optsWithGlobals();
6090
6522
  const mode = globalOpts.json ? OutputMode.JSON : OutputMode.TEXT;
6091
6523
  try {
@@ -6108,9 +6540,9 @@ function createPredictCommand() {
6108
6540
  }
6109
6541
 
6110
6542
  // src/commands/publish-analyses.ts
6111
- import * as fs25 from "fs";
6112
- import * as path43 from "path";
6113
- import { Command as Command54 } from "commander";
6543
+ import * as fs26 from "fs";
6544
+ import * as path44 from "path";
6545
+ import { Command as Command55 } from "commander";
6114
6546
  init_dist();
6115
6547
  import {
6116
6548
  renderAnalysisComment,
@@ -6118,7 +6550,7 @@ import {
6118
6550
  savePublishedIndex
6119
6551
  } from "@harness-engineering/orchestrator";
6120
6552
  function bootstrapTrackerCommand(opts, verb) {
6121
- const projectPath = path43.resolve(opts.dir);
6553
+ const projectPath = path44.resolve(opts.dir);
6122
6554
  const trackerConfig = loadTrackerSyncConfig(projectPath);
6123
6555
  if (!trackerConfig) {
6124
6556
  logger.error(`No tracker config found in harness.config.json. Cannot ${verb}.`);
@@ -6130,8 +6562,8 @@ function bootstrapTrackerCommand(opts, verb) {
6130
6562
  );
6131
6563
  return null;
6132
6564
  }
6133
- const projectEnvPath = path43.join(projectPath, ".env");
6134
- if (fs25.existsSync(projectEnvPath) && !process.env.GITHUB_TOKEN) {
6565
+ const projectEnvPath = path44.join(projectPath, ".env");
6566
+ if (fs26.existsSync(projectEnvPath) && !process.env.GITHUB_TOKEN) {
6135
6567
  __require("dotenv").config({ path: projectEnvPath });
6136
6568
  }
6137
6569
  const token = process.env.GITHUB_TOKEN;
@@ -6142,13 +6574,13 @@ function bootstrapTrackerCommand(opts, verb) {
6142
6574
  return { token, projectPath, trackerConfig };
6143
6575
  }
6144
6576
  function buildNameToExternalIdMap(projectPath) {
6145
- const roadmapFile = path43.join(projectPath, "docs", "roadmap.md");
6146
- if (!fs25.existsSync(roadmapFile)) {
6577
+ const roadmapFile = path44.join(projectPath, "docs", "roadmap.md");
6578
+ if (!fs26.existsSync(roadmapFile)) {
6147
6579
  logger.error("No docs/roadmap.md found. Cannot map issue hashes to external IDs.");
6148
6580
  return null;
6149
6581
  }
6150
6582
  const { parseRoadmap } = (init_dist(), __toCommonJS(dist_exports));
6151
- const roadmapParsed = parseRoadmap(fs25.readFileSync(roadmapFile, "utf-8"));
6583
+ const roadmapParsed = parseRoadmap(fs26.readFileSync(roadmapFile, "utf-8"));
6152
6584
  if (!roadmapParsed.ok) {
6153
6585
  logger.error("Failed to parse docs/roadmap.md");
6154
6586
  return null;
@@ -6198,8 +6630,8 @@ async function runPublishAnalyses(opts) {
6198
6630
  const nameToExternalId = buildNameToExternalIdMap(projectPath);
6199
6631
  if (!nameToExternalId) return process.exit(1);
6200
6632
  const { AnalysisArchive } = await import("@harness-engineering/orchestrator");
6201
- const { GitHubIssuesSyncAdapter: GitHubIssuesSyncAdapter2 } = await import("./dist-CPKL5Y2R.js");
6202
- const archive = new AnalysisArchive(path43.join(projectPath, ".harness", "analyses"));
6633
+ const { GitHubIssuesSyncAdapter: GitHubIssuesSyncAdapter2 } = await import("./dist-46VOJIG4.js");
6634
+ const archive = new AnalysisArchive(path44.join(projectPath, ".harness", "analyses"));
6203
6635
  const analyses = await archive.list();
6204
6636
  if (analyses.length === 0) {
6205
6637
  logger.info("No analyses found to publish.");
@@ -6221,7 +6653,7 @@ async function runPublishAnalyses(opts) {
6221
6653
  }
6222
6654
  }
6223
6655
  function createPublishAnalysesCommand() {
6224
- const command = new Command54("publish-analyses").description(
6656
+ const command = new Command55("publish-analyses").description(
6225
6657
  "Publishes locally generated intelligence analyses to the external issue tracker (e.g., GitHub)"
6226
6658
  ).option("-d, --dir <path>", "Workspace directory", process.cwd()).action(async (opts) => {
6227
6659
  try {
@@ -6237,8 +6669,8 @@ function createPublishAnalysesCommand() {
6237
6669
  }
6238
6670
 
6239
6671
  // src/commands/recommend.ts
6240
- import { Command as Command55 } from "commander";
6241
- import chalk8 from "chalk";
6672
+ import { Command as Command56 } from "commander";
6673
+ import chalk9 from "chalk";
6242
6674
  async function resolveSnapshot(cwd, noCache) {
6243
6675
  if (!noCache) {
6244
6676
  const cached = loadCachedSnapshot(cwd);
@@ -6272,12 +6704,12 @@ async function runRecommend(options) {
6272
6704
  function formatRecommendation(rec) {
6273
6705
  const lines = [];
6274
6706
  if (rec.urgency === "critical") {
6275
- lines.push(` ${chalk8.red("[CRITICAL]")} ${rec.sequence}. ${rec.skillName}`);
6707
+ lines.push(` ${chalk9.red("[CRITICAL]")} ${rec.sequence}. ${rec.skillName}`);
6276
6708
  } else {
6277
6709
  lines.push(` ${rec.sequence}. ${rec.skillName} (${rec.score.toFixed(2)})`);
6278
6710
  }
6279
6711
  for (const reason of rec.reasons) {
6280
- lines.push(` ${chalk8.dim("\u2192")} ${reason}`);
6712
+ lines.push(` ${chalk9.dim("\u2192")} ${reason}`);
6281
6713
  }
6282
6714
  return lines.join("\n");
6283
6715
  }
@@ -6301,7 +6733,7 @@ function printRecommendations(result) {
6301
6733
  console.log("");
6302
6734
  }
6303
6735
  function createRecommendCommand() {
6304
- const command = new Command55("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) => {
6736
+ const command = new Command56("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) => {
6305
6737
  const globalOpts = cmd.optsWithGlobals();
6306
6738
  const mode = globalOpts.json ? OutputMode.JSON : OutputMode.TEXT;
6307
6739
  try {
@@ -6338,9 +6770,9 @@ function createRecommendCommand() {
6338
6770
 
6339
6771
  // src/commands/scan-config.ts
6340
6772
  init_dist();
6341
- import { Command as Command56 } from "commander";
6342
- import { existsSync as existsSync22, readFileSync as readFileSync14, writeFileSync as writeFileSync12 } from "fs";
6343
- import { join as join31, relative as relative2 } from "path";
6773
+ import { Command as Command57 } from "commander";
6774
+ import { existsSync as existsSync23, readFileSync as readFileSync15, writeFileSync as writeFileSync13 } from "fs";
6775
+ import { join as join32, relative as relative3 } from "path";
6344
6776
  var CONFIG_FILES = ["CLAUDE.md", "AGENTS.md", ".gemini/settings.json", "skill.yaml"];
6345
6777
  function stripHighSeverityPatterns(content, injectionFindings) {
6346
6778
  const highLines = /* @__PURE__ */ new Set();
@@ -6366,17 +6798,17 @@ function applyFix(filePath, targetDir, content, injectionFindings) {
6366
6798
  if (!hasHighSeverity) return;
6367
6799
  const { cleaned, linesStripped } = stripHighSeverityPatterns(content, injectionFindings);
6368
6800
  if (linesStripped > 0) {
6369
- writeFileSync12(filePath, cleaned);
6801
+ writeFileSync13(filePath, cleaned);
6370
6802
  logger.info(
6371
- `scan-config --fix: stripped ${linesStripped} high-severity line(s) from ${relative2(targetDir, filePath).replaceAll("\\", "/")}`
6803
+ `scan-config --fix: stripped ${linesStripped} high-severity line(s) from ${relative3(targetDir, filePath).replaceAll("\\", "/")}`
6372
6804
  );
6373
6805
  }
6374
6806
  }
6375
6807
  function scanSingleFile(filePath, targetDir, scanner, options) {
6376
- if (!existsSync22(filePath)) return null;
6808
+ if (!existsSync23(filePath)) return null;
6377
6809
  let content;
6378
6810
  try {
6379
- content = readFileSync14(filePath, "utf8");
6811
+ content = readFileSync15(filePath, "utf8");
6380
6812
  } catch {
6381
6813
  return null;
6382
6814
  }
@@ -6388,7 +6820,7 @@ function scanSingleFile(filePath, targetDir, scanner, options) {
6388
6820
  applyFix(filePath, targetDir, content, injectionFindings);
6389
6821
  }
6390
6822
  return {
6391
- file: relative2(targetDir, filePath).replaceAll("\\", "/"),
6823
+ file: relative3(targetDir, filePath).replaceAll("\\", "/"),
6392
6824
  findings,
6393
6825
  overallSeverity: computeOverallSeverity(findings)
6394
6826
  };
@@ -6397,7 +6829,7 @@ async function runScanConfig(targetDir, options) {
6397
6829
  const scanner = new SecurityScanner(parseSecurityConfig({}));
6398
6830
  const results = [];
6399
6831
  for (const configFile of CONFIG_FILES) {
6400
- const result = scanSingleFile(join31(targetDir, configFile), targetDir, scanner, options);
6832
+ const result = scanSingleFile(join32(targetDir, configFile), targetDir, scanner, options);
6401
6833
  if (result) results.push(result);
6402
6834
  }
6403
6835
  return { exitCode: computeScanExitCode(results), results };
@@ -6427,7 +6859,7 @@ function formatTextOutput(result) {
6427
6859
  }
6428
6860
  }
6429
6861
  function createScanConfigCommand() {
6430
- const command = new Command56("scan-config").description(
6862
+ const command = new Command57("scan-config").description(
6431
6863
  "Scan CLAUDE.md, AGENTS.md, .gemini/settings.json, and skill.yaml for prompt injection patterns"
6432
6864
  ).option("--path <dir>", "Target directory to scan (default: cwd)").option("--fix", "Strip high-severity patterns from files in-place").action(async (opts, cmd) => {
6433
6865
  const globalOpts = cmd.optsWithGlobals();
@@ -6444,24 +6876,24 @@ function createScanConfigCommand() {
6444
6876
  }
6445
6877
 
6446
6878
  // src/commands/setup.ts
6447
- import { Command as Command57 } from "commander";
6448
- import * as fs28 from "fs";
6879
+ import { Command as Command58 } from "commander";
6880
+ import * as fs29 from "fs";
6449
6881
  import * as os7 from "os";
6450
- import * as path46 from "path";
6451
- import chalk10 from "chalk";
6882
+ import * as path47 from "path";
6883
+ import chalk11 from "chalk";
6452
6884
 
6453
6885
  // src/utils/first-run.ts
6454
- import * as fs26 from "fs";
6886
+ import * as fs27 from "fs";
6455
6887
  import * as os6 from "os";
6456
- import * as path44 from "path";
6457
- var HARNESS_DIR = path44.join(os6.homedir(), ".harness");
6458
- var MARKER_FILE = path44.join(HARNESS_DIR, ".setup-complete");
6888
+ import * as path45 from "path";
6889
+ var HARNESS_DIR = path45.join(os6.homedir(), ".harness");
6890
+ var MARKER_FILE = path45.join(HARNESS_DIR, ".setup-complete");
6459
6891
  function isFirstRun() {
6460
- return !fs26.existsSync(MARKER_FILE);
6892
+ return !fs27.existsSync(MARKER_FILE);
6461
6893
  }
6462
6894
  function markSetupComplete() {
6463
- fs26.mkdirSync(HARNESS_DIR, { recursive: true });
6464
- fs26.writeFileSync(MARKER_FILE, "", "utf-8");
6895
+ fs27.mkdirSync(HARNESS_DIR, { recursive: true });
6896
+ fs27.writeFileSync(MARKER_FILE, "", "utf-8");
6465
6897
  }
6466
6898
  function printFirstRunWelcome() {
6467
6899
  try {
@@ -6474,31 +6906,31 @@ function printFirstRunWelcome() {
6474
6906
  }
6475
6907
 
6476
6908
  // src/commands/telemetry-wizard.ts
6477
- import * as fs27 from "fs";
6478
- import * as path45 from "path";
6479
- import readline from "readline";
6480
- import chalk9 from "chalk";
6481
- function prompt(question) {
6482
- const rl = readline.createInterface({
6909
+ import * as fs28 from "fs";
6910
+ import * as path46 from "path";
6911
+ import readline2 from "readline";
6912
+ import chalk10 from "chalk";
6913
+ function prompt2(question) {
6914
+ const rl = readline2.createInterface({
6483
6915
  input: process.stdin,
6484
6916
  output: process.stdout
6485
6917
  });
6486
- return new Promise((resolve36) => {
6918
+ return new Promise((resolve37) => {
6487
6919
  rl.question(question, (answer) => {
6488
6920
  rl.close();
6489
- resolve36(answer.trim().toLowerCase());
6921
+ resolve37(answer.trim().toLowerCase());
6490
6922
  });
6491
6923
  });
6492
6924
  }
6493
6925
  function promptRaw(question) {
6494
- const rl = readline.createInterface({
6926
+ const rl = readline2.createInterface({
6495
6927
  input: process.stdin,
6496
6928
  output: process.stdout
6497
6929
  });
6498
- return new Promise((resolve36) => {
6930
+ return new Promise((resolve37) => {
6499
6931
  rl.question(question, (answer) => {
6500
6932
  rl.close();
6501
- resolve36(answer.trim());
6933
+ resolve37(answer.trim());
6502
6934
  });
6503
6935
  });
6504
6936
  }
@@ -6506,21 +6938,21 @@ function isNo(answer) {
6506
6938
  return answer === "n" || answer === "no";
6507
6939
  }
6508
6940
  function isTelemetryConfigured(cwd) {
6509
- const configPath = path45.join(cwd, "harness.config.json");
6941
+ const configPath = path46.join(cwd, "harness.config.json");
6510
6942
  try {
6511
- const raw = JSON.parse(fs27.readFileSync(configPath, "utf-8"));
6943
+ const raw = JSON.parse(fs28.readFileSync(configPath, "utf-8"));
6512
6944
  return raw.telemetry !== void 0 && raw.adoption !== void 0;
6513
6945
  } catch {
6514
6946
  return false;
6515
6947
  }
6516
6948
  }
6517
6949
  function writeTelemetryConfig(cwd, result) {
6518
- const configPath = path45.join(cwd, "harness.config.json");
6950
+ const configPath = path46.join(cwd, "harness.config.json");
6519
6951
  try {
6520
- const raw = JSON.parse(fs27.readFileSync(configPath, "utf-8"));
6952
+ const raw = JSON.parse(fs28.readFileSync(configPath, "utf-8"));
6521
6953
  raw.telemetry = { enabled: result.telemetryEnabled };
6522
6954
  raw.adoption = { enabled: result.adoptionEnabled };
6523
- fs27.writeFileSync(configPath, JSON.stringify(raw, null, 2) + "\n");
6955
+ fs28.writeFileSync(configPath, JSON.stringify(raw, null, 2) + "\n");
6524
6956
  } catch (err) {
6525
6957
  console.warn(
6526
6958
  `\u26A0 Could not update ${configPath}: ${err instanceof Error ? err.message : String(err)}`
@@ -6528,18 +6960,18 @@ function writeTelemetryConfig(cwd, result) {
6528
6960
  }
6529
6961
  const hasIdentity = result.identity.project || result.identity.team || result.identity.alias;
6530
6962
  if (hasIdentity) {
6531
- const harnessDir = path45.join(cwd, ".harness");
6532
- fs27.mkdirSync(harnessDir, { recursive: true });
6533
- const telemetryFile = path45.join(harnessDir, "telemetry.json");
6534
- fs27.writeFileSync(telemetryFile, JSON.stringify({ identity: result.identity }, null, 2) + "\n");
6963
+ const harnessDir = path46.join(cwd, ".harness");
6964
+ fs28.mkdirSync(harnessDir, { recursive: true });
6965
+ const telemetryFile = path46.join(harnessDir, "telemetry.json");
6966
+ fs28.writeFileSync(telemetryFile, JSON.stringify({ identity: result.identity }, null, 2) + "\n");
6535
6967
  }
6536
6968
  }
6537
6969
  async function promptIdentity() {
6538
6970
  console.log(
6539
- ` ${chalk9.cyan("Identity")} (optional) \u2014 tag telemetry with project/team/alias for filtering.`
6971
+ ` ${chalk10.cyan("Identity")} (optional) \u2014 tag telemetry with project/team/alias for filtering.`
6540
6972
  );
6541
6973
  console.log(" Leave blank to keep anonymous.");
6542
- const answer = await prompt(" Set identity fields? (y/N) ");
6974
+ const answer = await prompt2(" Set identity fields? (y/N) ");
6543
6975
  const identity = {};
6544
6976
  if (answer === "y" || answer === "yes") {
6545
6977
  const projectName = await promptRaw(" Project name: ");
@@ -6554,31 +6986,31 @@ async function promptIdentity() {
6554
6986
  async function runTelemetryWizard() {
6555
6987
  if (!process.stdin.isTTY) return null;
6556
6988
  console.log("");
6557
- console.log(` ${chalk9.bold("Telemetry Configuration")}`);
6989
+ console.log(` ${chalk10.bold("Telemetry Configuration")}`);
6558
6990
  console.log("");
6559
6991
  console.log(" Harness can collect anonymous usage data to help improve the tool.");
6560
6992
  console.log(" You can change these settings anytime in harness.config.json.");
6561
6993
  console.log("");
6562
6994
  console.log(
6563
- ` ${chalk9.cyan("Anonymous telemetry")} \u2014 error rates, command usage, performance metrics.`
6995
+ ` ${chalk10.cyan("Anonymous telemetry")} \u2014 error rates, command usage, performance metrics.`
6564
6996
  );
6565
6997
  console.log(" No code, file contents, or personally identifiable info is sent.");
6566
- const telemetryAnswer = await prompt(" Enable anonymous telemetry? (Y/n) ");
6998
+ const telemetryAnswer = await prompt2(" Enable anonymous telemetry? (Y/n) ");
6567
6999
  const telemetryEnabled = !isNo(telemetryAnswer);
6568
7000
  console.log("");
6569
7001
  console.log(
6570
- ` ${chalk9.cyan("Adoption tracking")} \u2014 which skills are used, how often, and success rates.`
7002
+ ` ${chalk10.cyan("Adoption tracking")} \u2014 which skills are used, how often, and success rates.`
6571
7003
  );
6572
7004
  console.log(" Stored locally in .harness/adoption/. Never sent externally.");
6573
- const adoptionAnswer = await prompt(" Enable local adoption tracking? (Y/n) ");
7005
+ const adoptionAnswer = await prompt2(" Enable local adoption tracking? (Y/n) ");
6574
7006
  const adoptionEnabled = !isNo(adoptionAnswer);
6575
7007
  console.log("");
6576
7008
  const identity = await promptIdentity();
6577
7009
  return { telemetryEnabled, adoptionEnabled, identity };
6578
7010
  }
6579
7011
  async function ensureTelemetryConfigured(cwd) {
6580
- const configPath = path45.join(cwd, "harness.config.json");
6581
- if (!fs27.existsSync(configPath)) {
7012
+ const configPath = path46.join(cwd, "harness.config.json");
7013
+ if (!fs28.existsSync(configPath)) {
6582
7014
  return { status: "warn", message: "Not a harness project \u2014 skipped telemetry configuration" };
6583
7015
  }
6584
7016
  if (isTelemetryConfigured(cwd)) {
@@ -6624,7 +7056,7 @@ function runSlashCommandGeneration() {
6624
7056
  }
6625
7057
  }
6626
7058
  function detectClient(dirName) {
6627
- return fs28.existsSync(path46.join(os7.homedir(), dirName));
7059
+ return fs29.existsSync(path47.join(os7.homedir(), dirName));
6628
7060
  }
6629
7061
  async function runMcpSetup(cwd) {
6630
7062
  const results = [];
@@ -6661,12 +7093,12 @@ async function runMcpSetup(cwd) {
6661
7093
  return results;
6662
7094
  }
6663
7095
  function formatStep(result) {
6664
- const icon = result.status === "pass" ? chalk10.green("\u2713") : result.status === "warn" ? chalk10.yellow("\u26A0") : chalk10.red("\u2717");
7096
+ const icon = result.status === "pass" ? chalk11.green("\u2713") : result.status === "warn" ? chalk11.yellow("\u26A0") : chalk11.red("\u2717");
6665
7097
  return ` ${icon} ${result.message}`;
6666
7098
  }
6667
7099
  function configureTier0Integrations(cwd) {
6668
7100
  try {
6669
- const mcpPath = path46.join(cwd, ".mcp.json");
7101
+ const mcpPath = path47.join(cwd, ".mcp.json");
6670
7102
  const config = readMcpConfig(mcpPath);
6671
7103
  const tier0 = INTEGRATION_REGISTRY.filter((i) => i.tier === 0);
6672
7104
  const added = [];
@@ -6675,9 +7107,9 @@ function configureTier0Integrations(cwd) {
6675
7107
  writeMcpEntry(mcpPath, integration.name, integration.mcpConfig);
6676
7108
  added.push(integration.displayName);
6677
7109
  }
6678
- const geminiDir = path46.join(cwd, ".gemini");
6679
- if (fs28.existsSync(geminiDir)) {
6680
- const geminiPath = path46.join(geminiDir, "settings.json");
7110
+ const geminiDir = path47.join(cwd, ".gemini");
7111
+ if (fs29.existsSync(geminiDir)) {
7112
+ const geminiPath = path47.join(geminiDir, "settings.json");
6681
7113
  const geminiConfig = readMcpConfig(geminiPath);
6682
7114
  for (const integration of tier0) {
6683
7115
  if (!geminiConfig.mcpServers[integration.name]) {
@@ -6698,14 +7130,14 @@ function configureTier0Integrations(cwd) {
6698
7130
  }
6699
7131
  }
6700
7132
  function ensureHooks(cwd) {
6701
- const configPath = path46.join(cwd, "harness.config.json");
6702
- if (!fs28.existsSync(configPath)) {
7133
+ const configPath = path47.join(cwd, "harness.config.json");
7134
+ if (!fs29.existsSync(configPath)) {
6703
7135
  return { status: "warn", message: "Not a harness project \u2014 skipped hook installation" };
6704
7136
  }
6705
7137
  let profile = "standard";
6706
- const profilePath = path46.join(cwd, ".harness", "hooks", "profile.json");
7138
+ const profilePath = path47.join(cwd, ".harness", "hooks", "profile.json");
6707
7139
  try {
6708
- const data = JSON.parse(fs28.readFileSync(profilePath, "utf-8"));
7140
+ const data = JSON.parse(fs29.readFileSync(profilePath, "utf-8"));
6709
7141
  if (data.profile && ["minimal", "standard", "strict"].includes(data.profile)) {
6710
7142
  profile = data.profile;
6711
7143
  }
@@ -6722,9 +7154,22 @@ function ensureHooks(cwd) {
6722
7154
  return { status: "warn", message: `Hook installation skipped \u2014 ${msg}` };
6723
7155
  }
6724
7156
  }
7157
+ async function detectLegacyLayout(cwd) {
7158
+ const { adrLegacy, planLegacy } = await detectLegacyArtifacts(cwd);
7159
+ if (!adrLegacy && !planLegacy) {
7160
+ return { status: "pass", message: "Layout up to date" };
7161
+ }
7162
+ const parts = [];
7163
+ if (adrLegacy) parts.push(".harness/architecture/");
7164
+ if (planLegacy) parts.push("docs/plans/");
7165
+ return {
7166
+ status: "warn",
7167
+ message: `Legacy paths detected (${parts.join(", ")}) \u2014 run \`harness migrate\` to upgrade`
7168
+ };
7169
+ }
6725
7170
  async function runInitialGraphScan(cwd) {
6726
7171
  try {
6727
- const { runScan: runScan2 } = await import("./scan-M4EGDAQ2.js");
7172
+ const { runScan: runScan2 } = await import("./scan-XRGMTO6K.js");
6728
7173
  const result = await runScan2(cwd);
6729
7174
  return {
6730
7175
  status: "pass",
@@ -6754,6 +7199,8 @@ async function runSetup(cwd) {
6754
7199
  steps.push(telemetryResult);
6755
7200
  const graphResult = await runInitialGraphScan(cwd);
6756
7201
  steps.push(graphResult);
7202
+ const legacyResult = await detectLegacyLayout(cwd);
7203
+ steps.push(legacyResult);
6757
7204
  const success = steps.every((s) => s.status !== "fail");
6758
7205
  if (success) {
6759
7206
  markSetupComplete();
@@ -6761,10 +7208,10 @@ async function runSetup(cwd) {
6761
7208
  return { steps, success };
6762
7209
  }
6763
7210
  function createSetupCommand() {
6764
- return new Command57("setup").description("Configure harness environment: slash commands, MCP, and more").action(async () => {
7211
+ return new Command58("setup").description("Configure harness environment: slash commands, MCP, and more").action(async () => {
6765
7212
  const cwd = process.cwd();
6766
7213
  console.log("");
6767
- console.log(` ${chalk10.bold("harness setup")}`);
7214
+ console.log(` ${chalk11.bold("harness setup")}`);
6768
7215
  console.log("");
6769
7216
  const { steps, success } = await runSetup(cwd);
6770
7217
  for (const step of steps) {
@@ -6784,15 +7231,15 @@ function createSetupCommand() {
6784
7231
 
6785
7232
  // src/commands/share.ts
6786
7233
  init_dist();
6787
- import { Command as Command58 } from "commander";
6788
- import * as fs29 from "fs";
6789
- import * as path47 from "path";
7234
+ import { Command as Command59 } from "commander";
7235
+ import * as fs30 from "fs";
7236
+ import * as path48 from "path";
6790
7237
  import { parse as parseYaml } from "yaml";
6791
7238
  var MANIFEST_FILENAME = "constraints.yaml";
6792
7239
  async function runShareAction(projectPath, options) {
6793
- const rootDir = path47.resolve(projectPath);
6794
- const manifestPath = path47.join(rootDir, MANIFEST_FILENAME);
6795
- if (!fs29.existsSync(manifestPath)) {
7240
+ const rootDir = path48.resolve(projectPath);
7241
+ const manifestPath = path48.join(rootDir, MANIFEST_FILENAME);
7242
+ if (!fs30.existsSync(manifestPath)) {
6796
7243
  logger.error(
6797
7244
  `No ${MANIFEST_FILENAME} found at ${manifestPath}.
6798
7245
  Create a constraints.yaml in your project root to define what to share.`
@@ -6801,7 +7248,7 @@ Create a constraints.yaml in your project root to define what to share.`
6801
7248
  }
6802
7249
  let parsed;
6803
7250
  try {
6804
- const raw = fs29.readFileSync(manifestPath, "utf-8");
7251
+ const raw = fs30.readFileSync(manifestPath, "utf-8");
6805
7252
  parsed = parseYaml(raw);
6806
7253
  } catch (err) {
6807
7254
  logger.error(
@@ -6815,7 +7262,7 @@ Create a constraints.yaml in your project root to define what to share.`
6815
7262
  process.exit(1);
6816
7263
  }
6817
7264
  const manifest = manifestResult.value;
6818
- const configResult = resolveConfig(path47.join(rootDir, "harness.config.json"));
7265
+ const configResult = resolveConfig(path48.join(rootDir, "harness.config.json"));
6819
7266
  if (!configResult.ok) {
6820
7267
  logger.error(configResult.error.message);
6821
7268
  process.exit(1);
@@ -6833,8 +7280,8 @@ Create a constraints.yaml in your project root to define what to share.`
6833
7280
  );
6834
7281
  process.exit(1);
6835
7282
  }
6836
- const outputDir = path47.resolve(options.output);
6837
- const outputPath = path47.join(outputDir, `${manifest.name}.harness-constraints.json`);
7283
+ const outputDir = path48.resolve(options.output);
7284
+ const outputPath = path48.join(outputDir, `${manifest.name}.harness-constraints.json`);
6838
7285
  const writeResult = await writeConfig(outputPath, bundle);
6839
7286
  if (!writeResult.ok) {
6840
7287
  logger.error(`Failed to write bundle: ${writeResult.error.message}`);
@@ -6843,28 +7290,28 @@ Create a constraints.yaml in your project root to define what to share.`
6843
7290
  logger.success(`Bundle written to ${outputPath}`);
6844
7291
  }
6845
7292
  function createShareCommand() {
6846
- return new Command58("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) => {
7293
+ return new Command59("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) => {
6847
7294
  await runShareAction(projectPath, options);
6848
7295
  });
6849
7296
  }
6850
7297
 
6851
7298
  // src/commands/skill/index.ts
6852
- import { Command as Command66 } from "commander";
7299
+ import { Command as Command67 } from "commander";
6853
7300
 
6854
7301
  // src/commands/skill/list.ts
6855
- import { Command as Command59 } from "commander";
6856
- import * as fs30 from "fs";
6857
- import * as path48 from "path";
7302
+ import { Command as Command60 } from "commander";
7303
+ import * as fs31 from "fs";
7304
+ import * as path49 from "path";
6858
7305
  import { parse } from "yaml";
6859
7306
  function scanDirectory(dirPath, source) {
6860
- if (!fs30.existsSync(dirPath)) return [];
6861
- const entries = fs30.readdirSync(dirPath, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
7307
+ if (!fs31.existsSync(dirPath)) return [];
7308
+ const entries = fs31.readdirSync(dirPath, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
6862
7309
  const skills = [];
6863
7310
  for (const name of entries) {
6864
- const yamlPath = path48.join(dirPath, name, "skill.yaml");
6865
- if (!fs30.existsSync(yamlPath)) continue;
7311
+ const yamlPath = path49.join(dirPath, name, "skill.yaml");
7312
+ if (!fs31.existsSync(yamlPath)) continue;
6866
7313
  try {
6867
- const raw = fs30.readFileSync(yamlPath, "utf-8");
7314
+ const raw = fs31.readFileSync(yamlPath, "utf-8");
6868
7315
  const parsed = parse(raw);
6869
7316
  const result = SkillMetadataSchema.safeParse(parsed);
6870
7317
  if (result.success) {
@@ -6882,10 +7329,10 @@ function scanDirectory(dirPath, source) {
6882
7329
  }
6883
7330
  function collectCommunitySkills(seen, allSkills) {
6884
7331
  const globalDir = resolveGlobalSkillsDir();
6885
- const skillsDir = path48.dirname(globalDir);
6886
- const communityBase = path48.join(skillsDir, "community");
6887
- const communityPlatformDir = path48.join(communityBase, "claude-code");
6888
- const lockfilePath = path48.join(communityBase, "skills-lock.json");
7332
+ const skillsDir = path49.dirname(globalDir);
7333
+ const communityBase = path49.join(skillsDir, "community");
7334
+ const communityPlatformDir = path49.join(communityBase, "claude-code");
7335
+ const lockfilePath = path49.join(communityBase, "skills-lock.json");
6889
7336
  const lockfile = readLockfile2(lockfilePath);
6890
7337
  const communitySkills = scanDirectory(communityPlatformDir, "community");
6891
7338
  for (const skill of communitySkills) {
@@ -6955,7 +7402,7 @@ function printSkillsVerbose(skills) {
6955
7402
  for (const s of skills) printSkillEntry(s);
6956
7403
  }
6957
7404
  function createListCommand3() {
6958
- return new Command59("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) => {
7405
+ return new Command60("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) => {
6959
7406
  const globalOpts = cmd.optsWithGlobals();
6960
7407
  const skills = collectSkills({ filter: resolveFilter(opts) });
6961
7408
  if (globalOpts.json) {
@@ -6970,13 +7417,13 @@ function createListCommand3() {
6970
7417
  }
6971
7418
 
6972
7419
  // src/commands/skill/run.ts
6973
- import { Command as Command60 } from "commander";
6974
- import * as fs31 from "fs";
6975
- import * as path49 from "path";
7420
+ import { Command as Command61 } from "commander";
7421
+ import * as fs32 from "fs";
7422
+ import * as path50 from "path";
6976
7423
  import { parse as parse2 } from "yaml";
6977
7424
 
6978
7425
  // src/skill/complexity.ts
6979
- import { execFileSync as execFileSync4 } from "child_process";
7426
+ import { execFileSync as execFileSync5 } from "child_process";
6980
7427
  function evaluateSignals(signals) {
6981
7428
  if (signals.fileCount >= 3) return "thorough";
6982
7429
  if (signals.newDir) return "thorough";
@@ -6988,17 +7435,17 @@ function evaluateSignals(signals) {
6988
7435
  }
6989
7436
  function detectComplexity(projectPath) {
6990
7437
  try {
6991
- const base = execFileSync4("git", ["merge-base", "HEAD", "main"], {
7438
+ const base = execFileSync5("git", ["merge-base", "HEAD", "main"], {
6992
7439
  cwd: projectPath,
6993
7440
  encoding: "utf-8",
6994
7441
  stdio: ["pipe", "pipe", "pipe"]
6995
7442
  }).trim();
6996
- const diffFiles = execFileSync4("git", ["diff", "--name-only", base], {
7443
+ const diffFiles = execFileSync5("git", ["diff", "--name-only", base], {
6997
7444
  cwd: projectPath,
6998
7445
  encoding: "utf-8",
6999
7446
  stdio: ["pipe", "pipe", "pipe"]
7000
7447
  }).trim().split("\n").filter(Boolean);
7001
- const diffStat = execFileSync4("git", ["diff", "--stat", base], {
7448
+ const diffStat = execFileSync5("git", ["diff", "--stat", base], {
7002
7449
  cwd: projectPath,
7003
7450
  encoding: "utf-8",
7004
7451
  stdio: ["pipe", "pipe", "pipe"]
@@ -7068,10 +7515,10 @@ ${options.principles}`);
7068
7515
 
7069
7516
  // src/commands/skill/run.ts
7070
7517
  function loadSkillMetadata(skillDir) {
7071
- const yamlPath = path49.join(skillDir, "skill.yaml");
7072
- if (!fs31.existsSync(yamlPath)) return null;
7518
+ const yamlPath = path50.join(skillDir, "skill.yaml");
7519
+ if (!fs32.existsSync(yamlPath)) return null;
7073
7520
  try {
7074
- const result = SkillMetadataSchema.safeParse(parse2(fs31.readFileSync(yamlPath, "utf-8")));
7521
+ const result = SkillMetadataSchema.safeParse(parse2(fs32.readFileSync(yamlPath, "utf-8")));
7075
7522
  return result.success ? result.data : null;
7076
7523
  } catch {
7077
7524
  return null;
@@ -7083,22 +7530,22 @@ function resolveComplexity(metadata, requested, projectPath) {
7083
7530
  return requested;
7084
7531
  }
7085
7532
  function loadPrinciples(projectPath) {
7086
- const principlesPath = path49.join(projectPath, "docs", "principles.md");
7087
- return fs31.existsSync(principlesPath) ? fs31.readFileSync(principlesPath, "utf-8") : void 0;
7533
+ const principlesPath = path50.join(projectPath, "docs", "principles.md");
7534
+ return fs32.existsSync(principlesPath) ? fs32.readFileSync(principlesPath, "utf-8") : void 0;
7088
7535
  }
7089
7536
  function readMostRecentFileInDir(dirPath) {
7090
- const files = fs31.readdirSync(dirPath).map((f) => ({ name: f, mtime: fs31.statSync(path49.join(dirPath, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime);
7091
- if (files.length > 0) return fs31.readFileSync(path49.join(dirPath, files[0].name), "utf-8");
7537
+ const files = fs32.readdirSync(dirPath).map((f) => ({ name: f, mtime: fs32.statSync(path50.join(dirPath, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime);
7538
+ if (files.length > 0) return fs32.readFileSync(path50.join(dirPath, files[0].name), "utf-8");
7092
7539
  return void 0;
7093
7540
  }
7094
7541
  function loadPriorState(metadata, projectPath) {
7095
7542
  if (!metadata?.state.persistent || metadata.state.files.length === 0) return void 0;
7096
7543
  for (const stateFilePath of metadata.state.files) {
7097
- const fullPath = path49.join(projectPath, stateFilePath);
7098
- if (!fs31.existsSync(fullPath)) continue;
7099
- const stat = fs31.statSync(fullPath);
7544
+ const fullPath = path50.join(projectPath, stateFilePath);
7545
+ if (!fs32.existsSync(fullPath)) continue;
7546
+ const stat = fs32.statSync(fullPath);
7100
7547
  if (stat.isDirectory()) return readMostRecentFileInDir(fullPath);
7101
- return fs31.readFileSync(fullPath, "utf-8");
7548
+ return fs32.readFileSync(fullPath, "utf-8");
7102
7549
  }
7103
7550
  return void 0;
7104
7551
  }
@@ -7118,9 +7565,9 @@ function resolvePhaseState(metadata, projectPath, phase) {
7118
7565
  }
7119
7566
  function appendProjectState(content, metadata, projectPath, hasPathOpt) {
7120
7567
  if (!metadata?.state.persistent || !hasPathOpt) return content;
7121
- const stateFile = path49.join(projectPath, ".harness", "state.json");
7122
- if (!fs31.existsSync(stateFile)) return content;
7123
- const stateContent = fs31.readFileSync(stateFile, "utf-8");
7568
+ const stateFile = path50.join(projectPath, ".harness", "state.json");
7569
+ if (!fs32.existsSync(stateFile)) return content;
7570
+ const stateContent = fs32.readFileSync(stateFile, "utf-8");
7124
7571
  return content + `
7125
7572
 
7126
7573
  ---
@@ -7132,14 +7579,14 @@ ${stateContent}
7132
7579
  }
7133
7580
  async function runSkill(name, opts) {
7134
7581
  const skillsDir = resolveSkillsDir();
7135
- const skillDir = path49.join(skillsDir, name);
7136
- if (!fs31.existsSync(skillDir)) {
7582
+ const skillDir = path50.join(skillsDir, name);
7583
+ if (!fs32.existsSync(skillDir)) {
7137
7584
  logger.error(`Skill not found: ${name}`);
7138
7585
  process.exit(ExitCode.ERROR);
7139
7586
  return;
7140
7587
  }
7141
7588
  const metadata = loadSkillMetadata(skillDir);
7142
- const projectPath = opts.path ? path49.resolve(opts.path) : process.cwd();
7589
+ const projectPath = opts.path ? path50.resolve(opts.path) : process.cwd();
7143
7590
  const complexity = resolveComplexity(
7144
7591
  metadata,
7145
7592
  opts.complexity ?? "standard",
@@ -7166,14 +7613,14 @@ async function runSkill(name, opts) {
7166
7613
  ...stateWarning !== void 0 && { stateWarning },
7167
7614
  ...opts.party !== void 0 && { party: opts.party }
7168
7615
  });
7169
- const skillMdPath = path49.join(skillDir, "SKILL.md");
7170
- if (!fs31.existsSync(skillMdPath)) {
7616
+ const skillMdPath = path50.join(skillDir, "SKILL.md");
7617
+ if (!fs32.existsSync(skillMdPath)) {
7171
7618
  logger.error(`SKILL.md not found for skill: ${name}`);
7172
7619
  process.exit(ExitCode.ERROR);
7173
7620
  return;
7174
7621
  }
7175
7622
  const content = appendProjectState(
7176
- fs31.readFileSync(skillMdPath, "utf-8"),
7623
+ fs32.readFileSync(skillMdPath, "utf-8"),
7177
7624
  metadata,
7178
7625
  projectPath,
7179
7626
  !!opts.path
@@ -7182,13 +7629,13 @@ async function runSkill(name, opts) {
7182
7629
  process.exit(ExitCode.SUCCESS);
7183
7630
  }
7184
7631
  function createRunCommand2() {
7185
- return new Command60("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));
7632
+ return new Command61("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));
7186
7633
  }
7187
7634
 
7188
7635
  // src/commands/skill/validate.ts
7189
- import { Command as Command61 } from "commander";
7190
- import * as fs32 from "fs";
7191
- import * as path50 from "path";
7636
+ import { Command as Command62 } from "commander";
7637
+ import * as fs33 from "fs";
7638
+ import * as path51 from "path";
7192
7639
  import { parse as parse3 } from "yaml";
7193
7640
  var BEHAVIORAL_REQUIRED_SECTIONS = [
7194
7641
  "## When to Use",
@@ -7200,11 +7647,11 @@ var BEHAVIORAL_REQUIRED_SECTIONS = [
7200
7647
  ];
7201
7648
  var KNOWLEDGE_REQUIRED_SECTIONS = ["## Instructions"];
7202
7649
  function validateSkillMd(name, skillMdPath, skillType, errors) {
7203
- if (!fs32.existsSync(skillMdPath)) {
7650
+ if (!fs33.existsSync(skillMdPath)) {
7204
7651
  errors.push(`${name}: missing SKILL.md`);
7205
7652
  return;
7206
7653
  }
7207
- const mdContent = fs32.readFileSync(skillMdPath, "utf-8");
7654
+ const mdContent = fs33.readFileSync(skillMdPath, "utf-8");
7208
7655
  if (!mdContent.trim().startsWith("# ")) {
7209
7656
  errors.push(`${name}/SKILL.md: must start with an h1 heading`);
7210
7657
  }
@@ -7229,20 +7676,20 @@ function validateSkillMd(name, skillMdPath, skillType, errors) {
7229
7676
  }
7230
7677
  }
7231
7678
  function validateSkillEntry(name, skillsDir, errors) {
7232
- const skillDir = path50.join(skillsDir, name);
7233
- const yamlPath = path50.join(skillDir, "skill.yaml");
7234
- if (!fs32.existsSync(yamlPath)) {
7679
+ const skillDir = path51.join(skillsDir, name);
7680
+ const yamlPath = path51.join(skillDir, "skill.yaml");
7681
+ if (!fs33.existsSync(yamlPath)) {
7235
7682
  errors.push(`${name}: missing skill.yaml`);
7236
7683
  return false;
7237
7684
  }
7238
7685
  try {
7239
- const raw = fs32.readFileSync(yamlPath, "utf-8");
7686
+ const raw = fs33.readFileSync(yamlPath, "utf-8");
7240
7687
  const result = SkillMetadataSchema.safeParse(parse3(raw));
7241
7688
  if (!result.success) {
7242
7689
  errors.push(`${name}/skill.yaml: ${result.error.message}`);
7243
7690
  return false;
7244
7691
  }
7245
- validateSkillMd(name, path50.join(skillDir, "SKILL.md"), result.data.type, errors);
7692
+ validateSkillMd(name, path51.join(skillDir, "SKILL.md"), result.data.type, errors);
7246
7693
  return true;
7247
7694
  } catch (e) {
7248
7695
  errors.push(`${name}: parse error \u2014 ${e instanceof Error ? e.message : String(e)}`);
@@ -7250,15 +7697,15 @@ function validateSkillEntry(name, skillsDir, errors) {
7250
7697
  }
7251
7698
  }
7252
7699
  function createValidateCommand2() {
7253
- return new Command61("validate").description("Validate all skill.yaml files and SKILL.md structure").action(async (_opts, cmd) => {
7700
+ return new Command62("validate").description("Validate all skill.yaml files and SKILL.md structure").action(async (_opts, cmd) => {
7254
7701
  const globalOpts = cmd.optsWithGlobals();
7255
7702
  const skillsDir = resolveSkillsDir();
7256
- if (!fs32.existsSync(skillsDir)) {
7703
+ if (!fs33.existsSync(skillsDir)) {
7257
7704
  logger.info("No skills directory found.");
7258
7705
  process.exit(ExitCode.SUCCESS);
7259
7706
  return;
7260
7707
  }
7261
- const entries = fs32.readdirSync(skillsDir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
7708
+ const entries = fs33.readdirSync(skillsDir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
7262
7709
  const errors = [];
7263
7710
  let validated = 0;
7264
7711
  for (const name of entries) {
@@ -7280,24 +7727,24 @@ function createValidateCommand2() {
7280
7727
  }
7281
7728
 
7282
7729
  // src/commands/skill/info.ts
7283
- import { Command as Command62 } from "commander";
7284
- import * as fs33 from "fs";
7285
- import * as path51 from "path";
7730
+ import { Command as Command63 } from "commander";
7731
+ import * as fs34 from "fs";
7732
+ import * as path52 from "path";
7286
7733
  import { parse as parse4 } from "yaml";
7287
7734
  function loadSkillMetadata2(name) {
7288
7735
  const skillsDir = resolveSkillsDir();
7289
- const skillDir = path51.join(skillsDir, name);
7290
- if (!fs33.existsSync(skillDir)) {
7736
+ const skillDir = path52.join(skillsDir, name);
7737
+ if (!fs34.existsSync(skillDir)) {
7291
7738
  logger.error(`Skill not found: ${name}`);
7292
7739
  return { ok: false, exitCode: ExitCode.ERROR };
7293
7740
  }
7294
- const yamlPath = path51.join(skillDir, "skill.yaml");
7295
- if (!fs33.existsSync(yamlPath)) {
7741
+ const yamlPath = path52.join(skillDir, "skill.yaml");
7742
+ if (!fs34.existsSync(yamlPath)) {
7296
7743
  logger.error(`skill.yaml not found for skill: ${name}`);
7297
7744
  return { ok: false, exitCode: ExitCode.ERROR };
7298
7745
  }
7299
7746
  try {
7300
- const raw = fs33.readFileSync(yamlPath, "utf-8");
7747
+ const raw = fs34.readFileSync(yamlPath, "utf-8");
7301
7748
  const parsed = parse4(raw);
7302
7749
  const result = SkillMetadataSchema.safeParse(parsed);
7303
7750
  if (!result.success) {
@@ -7326,7 +7773,7 @@ function printSkillInfo(skill) {
7326
7773
  console.log(`Persistent: ${skill.state.persistent}`);
7327
7774
  }
7328
7775
  function createInfoCommand() {
7329
- return new Command62("info").description("Show metadata for a skill").argument("<name>", "Skill name (e.g., harness-tdd)").action(async (name, _opts, cmd) => {
7776
+ return new Command63("info").description("Show metadata for a skill").argument("<name>", "Skill name (e.g., harness-tdd)").action(async (name, _opts, cmd) => {
7330
7777
  const globalOpts = cmd.optsWithGlobals();
7331
7778
  const loaded = loadSkillMetadata2(name);
7332
7779
  if (!loaded.ok) {
@@ -7343,7 +7790,7 @@ function createInfoCommand() {
7343
7790
  }
7344
7791
 
7345
7792
  // src/commands/skill/search.ts
7346
- import { Command as Command63 } from "commander";
7793
+ import { Command as Command64 } from "commander";
7347
7794
  async function runSearch(query, opts) {
7348
7795
  const results = await searchNpmRegistry(query, opts.registry);
7349
7796
  return results.filter((r) => {
@@ -7388,15 +7835,15 @@ async function runSearchAction(query, opts, globalOpts) {
7388
7835
  }
7389
7836
  }
7390
7837
  function createSearchCommand() {
7391
- return new Command63("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) => {
7838
+ return new Command64("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) => {
7392
7839
  await runSearchAction(query, opts, cmd.optsWithGlobals());
7393
7840
  });
7394
7841
  }
7395
7842
 
7396
7843
  // src/commands/skill/create.ts
7397
- import { Command as Command64 } from "commander";
7398
- import * as path52 from "path";
7399
- import * as fs34 from "fs";
7844
+ import { Command as Command65 } from "commander";
7845
+ import * as path53 from "path";
7846
+ import * as fs35 from "fs";
7400
7847
  import YAML from "yaml";
7401
7848
  var KEBAB_CASE_RE = /^[a-z][a-z0-9]*(-[a-z0-9]+)*$/;
7402
7849
  function buildReadme(name, description) {
@@ -7480,22 +7927,22 @@ function runCreate(name, opts) {
7480
7927
  if (!KEBAB_CASE_RE.test(name)) {
7481
7928
  throw new Error(`Invalid skill name "${name}". Must be kebab-case (e.g., my-skill).`);
7482
7929
  }
7483
- const baseDir = opts.outputDir ?? path52.join(process.cwd(), "agents", "skills", "claude-code");
7484
- const skillDir = path52.join(baseDir, name);
7485
- if (fs34.existsSync(skillDir)) {
7930
+ const baseDir = opts.outputDir ?? path53.join(process.cwd(), "agents", "skills", "claude-code");
7931
+ const skillDir = path53.join(baseDir, name);
7932
+ if (fs35.existsSync(skillDir)) {
7486
7933
  throw new Error(`Skill directory already exists: ${skillDir}`);
7487
7934
  }
7488
- fs34.mkdirSync(skillDir, { recursive: true });
7935
+ fs35.mkdirSync(skillDir, { recursive: true });
7489
7936
  const description = opts.description || `A community skill: ${name}`;
7490
7937
  const skillYaml = buildSkillYaml(name, opts);
7491
- const skillYamlPath = path52.join(skillDir, "skill.yaml");
7492
- fs34.writeFileSync(skillYamlPath, YAML.stringify(skillYaml));
7938
+ const skillYamlPath = path53.join(skillDir, "skill.yaml");
7939
+ fs35.writeFileSync(skillYamlPath, YAML.stringify(skillYaml));
7493
7940
  const skillMd = buildSkillMd(name, description);
7494
- const skillMdPath = path52.join(skillDir, "SKILL.md");
7495
- fs34.writeFileSync(skillMdPath, skillMd);
7941
+ const skillMdPath = path53.join(skillDir, "SKILL.md");
7942
+ fs35.writeFileSync(skillMdPath, skillMd);
7496
7943
  const readme = buildReadme(name, description);
7497
- const readmePath = path52.join(skillDir, "README.md");
7498
- fs34.writeFileSync(readmePath, readme);
7944
+ const readmePath = path53.join(skillDir, "README.md");
7945
+ fs35.writeFileSync(readmePath, readme);
7499
7946
  return {
7500
7947
  name,
7501
7948
  directory: skillDir,
@@ -7509,12 +7956,12 @@ function printCreateResult(name, result) {
7509
7956
  }
7510
7957
  logger.info(`
7511
7958
  Next steps:`);
7512
- logger.info(` 1. Edit ${path52.join(result.directory, "SKILL.md")} with your skill content`);
7959
+ logger.info(` 1. Edit ${path53.join(result.directory, "SKILL.md")} with your skill content`);
7513
7960
  logger.info(` 2. Run: harness skill validate ${name}`);
7514
7961
  logger.info(` 3. Run: harness skills publish`);
7515
7962
  }
7516
7963
  function createCreateCommand() {
7517
- return new Command64("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) => {
7964
+ return new Command65("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) => {
7518
7965
  const globalOpts = cmd.optsWithGlobals();
7519
7966
  try {
7520
7967
  const result = runCreate(name, {
@@ -7537,26 +7984,26 @@ function createCreateCommand() {
7537
7984
  }
7538
7985
 
7539
7986
  // src/commands/skill/publish.ts
7540
- import { Command as Command65 } from "commander";
7541
- import * as fs36 from "fs";
7542
- import * as path54 from "path";
7543
- import { execFileSync as execFileSync5 } from "child_process";
7987
+ import { Command as Command66 } from "commander";
7988
+ import * as fs37 from "fs";
7989
+ import * as path55 from "path";
7990
+ import { execFileSync as execFileSync6 } from "child_process";
7544
7991
 
7545
7992
  // src/registry/validator.ts
7546
- import * as fs35 from "fs";
7547
- import * as path53 from "path";
7993
+ import * as fs36 from "fs";
7994
+ import * as path54 from "path";
7548
7995
  import { parse as parse5 } from "yaml";
7549
7996
  import semver4 from "semver";
7550
7997
  async function validateForPublish(skillDir, registryUrl) {
7551
7998
  const errors = [];
7552
- const skillYamlPath = path53.join(skillDir, "skill.yaml");
7553
- if (!fs35.existsSync(skillYamlPath)) {
7999
+ const skillYamlPath = path54.join(skillDir, "skill.yaml");
8000
+ if (!fs36.existsSync(skillYamlPath)) {
7554
8001
  errors.push("skill.yaml not found. Create one with: harness skill create <name>");
7555
8002
  return { valid: false, errors };
7556
8003
  }
7557
8004
  let skillMeta;
7558
8005
  try {
7559
- const raw = fs35.readFileSync(skillYamlPath, "utf-8");
8006
+ const raw = fs36.readFileSync(skillYamlPath, "utf-8");
7560
8007
  const parsed = parse5(raw);
7561
8008
  const result = SkillMetadataSchema.safeParse(parsed);
7562
8009
  if (!result.success) {
@@ -7578,11 +8025,11 @@ async function validateForPublish(skillDir, registryUrl) {
7578
8025
  if (!skillMeta.triggers || skillMeta.triggers.length === 0) {
7579
8026
  errors.push("At least one trigger is required. Add triggers to skill.yaml.");
7580
8027
  }
7581
- const skillMdPath = path53.join(skillDir, "SKILL.md");
7582
- if (!fs35.existsSync(skillMdPath)) {
8028
+ const skillMdPath = path54.join(skillDir, "SKILL.md");
8029
+ if (!fs36.existsSync(skillMdPath)) {
7583
8030
  errors.push("SKILL.md not found. Create it with content describing your skill.");
7584
8031
  } else {
7585
- const content = fs35.readFileSync(skillMdPath, "utf-8");
8032
+ const content = fs36.readFileSync(skillMdPath, "utf-8");
7586
8033
  if (!content.includes("## When to Use")) {
7587
8034
  errors.push('SKILL.md must contain a "## When to Use" section.');
7588
8035
  }
@@ -7662,11 +8109,11 @@ ${errorList}`);
7662
8109
  }
7663
8110
  const meta = validation.skillMeta;
7664
8111
  const pkg = derivePackageJson(meta);
7665
- const pkgPath = path54.join(skillDir, "package.json");
7666
- fs36.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + "\n");
7667
- const readmePath = path54.join(skillDir, "README.md");
7668
- if (!fs36.existsSync(readmePath)) {
7669
- const skillMdContent = fs36.readFileSync(path54.join(skillDir, "SKILL.md"), "utf-8");
8112
+ const pkgPath = path55.join(skillDir, "package.json");
8113
+ fs37.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + "\n");
8114
+ const readmePath = path55.join(skillDir, "README.md");
8115
+ if (!fs37.existsSync(readmePath)) {
8116
+ const skillMdContent = fs37.readFileSync(path55.join(skillDir, "SKILL.md"), "utf-8");
7670
8117
  const readme = `# ${pkg.name}
7671
8118
 
7672
8119
  ${meta.description}
@@ -7680,7 +8127,7 @@ harness install ${meta.name}
7680
8127
  ---
7681
8128
 
7682
8129
  ${skillMdContent}`;
7683
- fs36.writeFileSync(readmePath, readme);
8130
+ fs37.writeFileSync(readmePath, readme);
7684
8131
  }
7685
8132
  if (opts.dryRun) {
7686
8133
  return {
@@ -7694,7 +8141,7 @@ ${skillMdContent}`;
7694
8141
  if (opts.registry) {
7695
8142
  publishArgs.push("--registry", opts.registry);
7696
8143
  }
7697
- execFileSync5("npm", publishArgs, {
8144
+ execFileSync6("npm", publishArgs, {
7698
8145
  cwd: skillDir,
7699
8146
  stdio: "pipe",
7700
8147
  timeout: 6e4
@@ -7706,7 +8153,7 @@ ${skillMdContent}`;
7706
8153
  };
7707
8154
  }
7708
8155
  function createPublishCommand() {
7709
- return new Command65("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) => {
8156
+ return new Command66("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) => {
7710
8157
  const globalOpts = cmd.optsWithGlobals();
7711
8158
  const skillDir = opts.dir || process.cwd();
7712
8159
  try {
@@ -7731,7 +8178,7 @@ function createPublishCommand() {
7731
8178
 
7732
8179
  // src/commands/skill/index.ts
7733
8180
  function createSkillCommand() {
7734
- const command = new Command66("skill").description("Skill management commands");
8181
+ const command = new Command67("skill").description("Skill management commands");
7735
8182
  command.addCommand(createListCommand3());
7736
8183
  command.addCommand(createRunCommand2());
7737
8184
  command.addCommand(createValidateCommand2());
@@ -7744,9 +8191,9 @@ function createSkillCommand() {
7744
8191
 
7745
8192
  // src/commands/snapshot.ts
7746
8193
  init_dist();
7747
- import { Command as Command67 } from "commander";
8194
+ import { Command as Command68 } from "commander";
7748
8195
  import { execSync as execSync5 } from "child_process";
7749
- import chalk11 from "chalk";
8196
+ import chalk12 from "chalk";
7750
8197
  function getCommitHash3(cwd) {
7751
8198
  try {
7752
8199
  return execSync5("git rev-parse --short HEAD", { cwd, encoding: "utf-8" }).toString().trim();
@@ -7771,9 +8218,9 @@ function formatDelta(delta) {
7771
8218
  function directionSymbol(direction) {
7772
8219
  switch (direction) {
7773
8220
  case "improving":
7774
- return chalk11.green("improving");
8221
+ return chalk12.green("improving");
7775
8222
  case "declining":
7776
- return chalk11.red("declining");
8223
+ return chalk12.red("declining");
7777
8224
  case "stable":
7778
8225
  return "=";
7779
8226
  }
@@ -7926,7 +8373,7 @@ function registerListCommand(parent) {
7926
8373
  });
7927
8374
  }
7928
8375
  function createSnapshotCommand() {
7929
- const command = new Command67("snapshot").description("Architecture timeline snapshot commands");
8376
+ const command = new Command68("snapshot").description("Architecture timeline snapshot commands");
7930
8377
  registerCaptureCommand(command);
7931
8378
  registerTrendsCommand(command);
7932
8379
  registerListCommand(command);
@@ -7934,12 +8381,12 @@ function createSnapshotCommand() {
7934
8381
  }
7935
8382
 
7936
8383
  // src/commands/state/index.ts
7937
- import { Command as Command72 } from "commander";
8384
+ import { Command as Command73 } from "commander";
7938
8385
 
7939
8386
  // src/commands/state/show.ts
7940
8387
  init_dist();
7941
- import { Command as Command68 } from "commander";
7942
- import * as path55 from "path";
8388
+ import { Command as Command69 } from "commander";
8389
+ import * as path56 from "path";
7943
8390
  function printStateText(state, stream) {
7944
8391
  if (stream) console.log(`Stream: ${stream}`);
7945
8392
  console.log(`Schema Version: ${state.schemaVersion}`);
@@ -7963,9 +8410,9 @@ function printStateProgress(progress) {
7963
8410
  }
7964
8411
  }
7965
8412
  function createShowCommand() {
7966
- return new Command68("show").description("Show current project state").option("--path <path>", "Project root path", ".").option("--stream <name>", "Target a specific stream").action(async (opts, cmd) => {
8413
+ return new Command69("show").description("Show current project state").option("--path <path>", "Project root path", ".").option("--stream <name>", "Target a specific stream").action(async (opts, cmd) => {
7967
8414
  const globalOpts = cmd.optsWithGlobals();
7968
- const result = await loadState(path55.resolve(opts.path), opts.stream);
8415
+ const result = await loadState(path56.resolve(opts.path), opts.stream);
7969
8416
  if (!result.ok) {
7970
8417
  logger.error(result.error.message);
7971
8418
  process.exit(ExitCode.ERROR);
@@ -7981,10 +8428,10 @@ function createShowCommand() {
7981
8428
 
7982
8429
  // src/commands/state/reset.ts
7983
8430
  init_dist();
7984
- import { Command as Command69 } from "commander";
7985
- import * as fs37 from "fs";
7986
- import * as path56 from "path";
7987
- import * as readline2 from "readline";
8431
+ import { Command as Command70 } from "commander";
8432
+ import * as fs38 from "fs";
8433
+ import * as path57 from "path";
8434
+ import * as readline3 from "readline";
7988
8435
  async function resolveStatePath(projectPath, stream) {
7989
8436
  if (stream) {
7990
8437
  const streamResult = await resolveStreamPath(projectPath, { stream });
@@ -7992,22 +8439,22 @@ async function resolveStatePath(projectPath, stream) {
7992
8439
  logger.error(streamResult.error.message);
7993
8440
  process.exit(ExitCode.ERROR);
7994
8441
  }
7995
- return path56.join(streamResult.value, "state.json");
8442
+ return path57.join(streamResult.value, "state.json");
7996
8443
  }
7997
- return path56.join(projectPath, ".harness", "state.json");
8444
+ return path57.join(projectPath, ".harness", "state.json");
7998
8445
  }
7999
8446
  async function confirmReset() {
8000
- const rl = readline2.createInterface({ input: process.stdin, output: process.stdout });
8001
- const answer = await new Promise((resolve36) => {
8002
- rl.question("Reset project state? This cannot be undone. [y/N] ", resolve36);
8447
+ const rl = readline3.createInterface({ input: process.stdin, output: process.stdout });
8448
+ const answer = await new Promise((resolve37) => {
8449
+ rl.question("Reset project state? This cannot be undone. [y/N] ", resolve37);
8003
8450
  });
8004
8451
  rl.close();
8005
8452
  return answer.toLowerCase() === "y" || answer.toLowerCase() === "yes";
8006
8453
  }
8007
8454
  async function runReset(opts) {
8008
- const projectPath = path56.resolve(opts.path);
8455
+ const projectPath = path57.resolve(opts.path);
8009
8456
  const statePath = await resolveStatePath(projectPath, opts.stream);
8010
- if (!fs37.existsSync(statePath)) {
8457
+ if (!fs38.existsSync(statePath)) {
8011
8458
  logger.info("No state file found. Nothing to reset.");
8012
8459
  process.exit(ExitCode.SUCCESS);
8013
8460
  }
@@ -8016,7 +8463,7 @@ async function runReset(opts) {
8016
8463
  process.exit(ExitCode.SUCCESS);
8017
8464
  }
8018
8465
  try {
8019
- fs37.unlinkSync(statePath);
8466
+ fs38.unlinkSync(statePath);
8020
8467
  logger.success("Project state reset.");
8021
8468
  } catch (e) {
8022
8469
  logger.error(`Failed to reset state: ${e instanceof Error ? e.message : String(e)}`);
@@ -8025,16 +8472,16 @@ async function runReset(opts) {
8025
8472
  process.exit(ExitCode.SUCCESS);
8026
8473
  }
8027
8474
  function createResetCommand() {
8028
- return new Command69("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));
8475
+ return new Command70("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));
8029
8476
  }
8030
8477
 
8031
8478
  // src/commands/state/learn.ts
8032
8479
  init_dist();
8033
- import { Command as Command70 } from "commander";
8034
- import * as path57 from "path";
8480
+ import { Command as Command71 } from "commander";
8481
+ import * as path58 from "path";
8035
8482
  function createLearnCommand() {
8036
- return new Command70("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) => {
8037
- const projectPath = path57.resolve(opts.path);
8483
+ return new Command71("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) => {
8484
+ const projectPath = path58.resolve(opts.path);
8038
8485
  const result = await appendLearning(projectPath, message, void 0, void 0, opts.stream);
8039
8486
  if (!result.ok) {
8040
8487
  logger.error(result.error.message);
@@ -8048,10 +8495,10 @@ function createLearnCommand() {
8048
8495
 
8049
8496
  // src/commands/state/streams.ts
8050
8497
  init_dist();
8051
- import { Command as Command71 } from "commander";
8052
- import * as path58 from "path";
8498
+ import { Command as Command72 } from "commander";
8499
+ import * as path59 from "path";
8053
8500
  async function runListStreams(opts, globalOpts) {
8054
- const projectPath = path58.resolve(opts.path);
8501
+ const projectPath = path59.resolve(opts.path);
8055
8502
  const indexResult = await loadStreamIndex(projectPath);
8056
8503
  const result = await listStreams(projectPath);
8057
8504
  if (!result.ok) {
@@ -8072,7 +8519,7 @@ async function runListStreams(opts, globalOpts) {
8072
8519
  process.exit(ExitCode.SUCCESS);
8073
8520
  }
8074
8521
  async function runCreateStream(name, opts) {
8075
- const result = await createStream(path58.resolve(opts.path), name, opts.branch);
8522
+ const result = await createStream(path59.resolve(opts.path), name, opts.branch);
8076
8523
  if (!result.ok) {
8077
8524
  logger.error(result.error.message);
8078
8525
  process.exit(ExitCode.ERROR);
@@ -8081,7 +8528,7 @@ async function runCreateStream(name, opts) {
8081
8528
  process.exit(ExitCode.SUCCESS);
8082
8529
  }
8083
8530
  async function runArchiveStream(name, opts) {
8084
- const result = await archiveStream(path58.resolve(opts.path), name);
8531
+ const result = await archiveStream(path59.resolve(opts.path), name);
8085
8532
  if (!result.ok) {
8086
8533
  logger.error(result.error.message);
8087
8534
  process.exit(ExitCode.ERROR);
@@ -8090,7 +8537,7 @@ async function runArchiveStream(name, opts) {
8090
8537
  process.exit(ExitCode.SUCCESS);
8091
8538
  }
8092
8539
  async function runActivateStream(name, opts) {
8093
- const result = await setActiveStream(path58.resolve(opts.path), name);
8540
+ const result = await setActiveStream(path59.resolve(opts.path), name);
8094
8541
  if (!result.ok) {
8095
8542
  logger.error(result.error.message);
8096
8543
  process.exit(ExitCode.ERROR);
@@ -8099,7 +8546,7 @@ async function runActivateStream(name, opts) {
8099
8546
  process.exit(ExitCode.SUCCESS);
8100
8547
  }
8101
8548
  function createStreamsCommand() {
8102
- const command = new Command71("streams").description("Manage state streams");
8549
+ const command = new Command72("streams").description("Manage state streams");
8103
8550
  command.command("list").description("List all known streams").option("--path <path>", "Project root path", ".").action(async (opts, cmd) => runListStreams(opts, cmd.optsWithGlobals()));
8104
8551
  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));
8105
8552
  command.command("archive <name>").description("Archive a stream").option("--path <path>", "Project root path", ".").action(async (name, opts) => runArchiveStream(name, opts));
@@ -8109,7 +8556,7 @@ function createStreamsCommand() {
8109
8556
 
8110
8557
  // src/commands/state/index.ts
8111
8558
  function createStateCommand() {
8112
- const command = new Command72("state").description("Project state management commands");
8559
+ const command = new Command73("state").description("Project state management commands");
8113
8560
  command.addCommand(createShowCommand());
8114
8561
  command.addCommand(createResetCommand());
8115
8562
  command.addCommand(createLearnCommand());
@@ -8118,9 +8565,9 @@ function createStateCommand() {
8118
8565
  }
8119
8566
 
8120
8567
  // src/commands/sync-analyses.ts
8121
- import * as fs38 from "fs";
8122
- import * as path59 from "path";
8123
- import { Command as Command73 } from "commander";
8568
+ import * as fs39 from "fs";
8569
+ import * as path60 from "path";
8570
+ import { Command as Command74 } from "commander";
8124
8571
  init_dist();
8125
8572
  function isValidRecord(record) {
8126
8573
  return typeof record.issueId === "string" && !!record.issueId && typeof record.identifier === "string" && !!record.identifier && typeof record.analyzedAt === "string" && !/[/\\]/.test(record.issueId);
@@ -8146,7 +8593,7 @@ function extractAnalysisFromComments(comments) {
8146
8593
  return null;
8147
8594
  }
8148
8595
  function bootstrapTrackerCommand2(opts, verb) {
8149
- const projectPath = path59.resolve(opts.dir);
8596
+ const projectPath = path60.resolve(opts.dir);
8150
8597
  const trackerConfig = loadTrackerSyncConfig(projectPath);
8151
8598
  if (!trackerConfig) {
8152
8599
  logger.error(`No tracker config found in harness.config.json. Cannot ${verb}.`);
@@ -8158,8 +8605,8 @@ function bootstrapTrackerCommand2(opts, verb) {
8158
8605
  );
8159
8606
  return null;
8160
8607
  }
8161
- const projectEnvPath = path59.join(projectPath, ".env");
8162
- if (fs38.existsSync(projectEnvPath) && !process.env.GITHUB_TOKEN) {
8608
+ const projectEnvPath = path60.join(projectPath, ".env");
8609
+ if (fs39.existsSync(projectEnvPath) && !process.env.GITHUB_TOKEN) {
8163
8610
  __require("dotenv").config({ path: projectEnvPath });
8164
8611
  }
8165
8612
  const token = process.env.GITHUB_TOKEN;
@@ -8170,13 +8617,13 @@ function bootstrapTrackerCommand2(opts, verb) {
8170
8617
  return { token, projectPath, trackerConfig };
8171
8618
  }
8172
8619
  function loadRoadmapFeatures(projectPath) {
8173
- const roadmapFile = path59.join(projectPath, "docs", "roadmap.md");
8174
- if (!fs38.existsSync(roadmapFile)) {
8620
+ const roadmapFile = path60.join(projectPath, "docs", "roadmap.md");
8621
+ if (!fs39.existsSync(roadmapFile)) {
8175
8622
  logger.error("No docs/roadmap.md found. Cannot discover features with externalIds.");
8176
8623
  return null;
8177
8624
  }
8178
8625
  const { parseRoadmap } = (init_dist(), __toCommonJS(dist_exports));
8179
- const roadmapParsed = parseRoadmap(fs38.readFileSync(roadmapFile, "utf-8"));
8626
+ const roadmapParsed = parseRoadmap(fs39.readFileSync(roadmapFile, "utf-8"));
8180
8627
  if (!roadmapParsed.ok) {
8181
8628
  logger.error("Failed to parse docs/roadmap.md");
8182
8629
  return null;
@@ -8227,9 +8674,9 @@ async function runSyncAnalyses(opts) {
8227
8674
  return;
8228
8675
  }
8229
8676
  const { AnalysisArchive, loadPublishedIndex: loadPublishedIndex2, savePublishedIndex: savePublishedIndex2 } = await import("@harness-engineering/orchestrator");
8230
- const { GitHubIssuesSyncAdapter: GitHubIssuesSyncAdapter2 } = await import("./dist-CPKL5Y2R.js");
8677
+ const { GitHubIssuesSyncAdapter: GitHubIssuesSyncAdapter2 } = await import("./dist-46VOJIG4.js");
8231
8678
  const adapter = new GitHubIssuesSyncAdapter2({ token, config: trackerConfig });
8232
- const archive = new AnalysisArchive(path59.join(projectPath, ".harness", "analyses"));
8679
+ const archive = new AnalysisArchive(path60.join(projectPath, ".harness", "analyses"));
8233
8680
  const publishedIndex = loadPublishedIndex2(projectPath);
8234
8681
  const { syncedCount, skippedCount, warnCount } = await syncFeatureAnalyses(
8235
8682
  features,
@@ -8249,7 +8696,7 @@ async function runSyncAnalyses(opts) {
8249
8696
  }
8250
8697
  }
8251
8698
  function createSyncAnalysesCommand() {
8252
- const command = new Command73("sync-analyses").description(
8699
+ const command = new Command74("sync-analyses").description(
8253
8700
  "Pull published intelligence analyses from the external issue tracker into the local .harness/analyses/ directory"
8254
8701
  ).option("-d, --dir <path>", "Workspace directory", process.cwd()).action(async (opts) => {
8255
8702
  try {
@@ -8264,7 +8711,7 @@ function createSyncAnalysesCommand() {
8264
8711
 
8265
8712
  // src/commands/taint.ts
8266
8713
  init_dist();
8267
- import { Command as Command74 } from "commander";
8714
+ import { Command as Command75 } from "commander";
8268
8715
  function getProjectRoot() {
8269
8716
  return process.cwd();
8270
8717
  }
@@ -8336,28 +8783,28 @@ function registerStatusCommand(taint) {
8336
8783
  });
8337
8784
  }
8338
8785
  function createTaintCommand() {
8339
- const taint = new Command74("taint").description("Manage sentinel session taint state");
8786
+ const taint = new Command75("taint").description("Manage sentinel session taint state");
8340
8787
  registerClearCommand(taint);
8341
8788
  registerStatusCommand(taint);
8342
8789
  return taint;
8343
8790
  }
8344
8791
 
8345
8792
  // src/commands/telemetry/index.ts
8346
- import { Command as Command78 } from "commander";
8793
+ import { Command as Command79 } from "commander";
8347
8794
 
8348
8795
  // src/commands/telemetry/identify.ts
8349
8796
  init_dist();
8350
- import { Command as Command75 } from "commander";
8351
- import * as fs39 from "fs";
8352
- import * as path60 from "path";
8797
+ import { Command as Command76 } from "commander";
8798
+ import * as fs40 from "fs";
8799
+ import * as path61 from "path";
8353
8800
  function telemetryFilePath(cwd) {
8354
- return path60.join(cwd, ".harness", "telemetry.json");
8801
+ return path61.join(cwd, ".harness", "telemetry.json");
8355
8802
  }
8356
8803
  function writeTelemetryFile(cwd, data) {
8357
8804
  const filePath = telemetryFilePath(cwd);
8358
- const dir = path60.dirname(filePath);
8359
- fs39.mkdirSync(dir, { recursive: true });
8360
- fs39.writeFileSync(filePath, JSON.stringify(data, null, 2) + "\n", "utf-8");
8805
+ const dir = path61.dirname(filePath);
8806
+ fs40.mkdirSync(dir, { recursive: true });
8807
+ fs40.writeFileSync(filePath, JSON.stringify(data, null, 2) + "\n", "utf-8");
8361
8808
  }
8362
8809
  var IDENTITY_FIELDS = ["project", "team", "alias"];
8363
8810
  function applyIdentityFields(opts, identity) {
@@ -8371,7 +8818,7 @@ function printIdentity(identity) {
8371
8818
  }
8372
8819
  }
8373
8820
  function createIdentifyCommand() {
8374
- const cmd = new Command75("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) => {
8821
+ const cmd = new Command76("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) => {
8375
8822
  const cwd = process.cwd();
8376
8823
  if (opts.clear) {
8377
8824
  writeTelemetryFile(cwd, { identity: {} });
@@ -8396,7 +8843,7 @@ function createIdentifyCommand() {
8396
8843
 
8397
8844
  // src/commands/telemetry/status.ts
8398
8845
  init_dist();
8399
- import { Command as Command76 } from "commander";
8846
+ import { Command as Command77 } from "commander";
8400
8847
  function gatherEnvOverrides() {
8401
8848
  const overrides = {};
8402
8849
  if (process.env.DO_NOT_TRACK) overrides.DO_NOT_TRACK = process.env.DO_NOT_TRACK;
@@ -8438,7 +8885,7 @@ function printHumanStatus(result) {
8438
8885
  printEnvOverrides(result.envOverrides);
8439
8886
  }
8440
8887
  function createStatusCommand() {
8441
- const cmd = new Command76("status").description("Show current telemetry consent state, install ID, and identity").option("--json", "Output as JSON").action((opts) => {
8888
+ const cmd = new Command77("status").description("Show current telemetry consent state, install ID, and identity").option("--json", "Output as JSON").action((opts) => {
8442
8889
  const cwd = process.cwd();
8443
8890
  const envOverrides = gatherEnvOverrides();
8444
8891
  const consent = resolveConsent(cwd, void 0);
@@ -8471,20 +8918,20 @@ function createStatusCommand() {
8471
8918
 
8472
8919
  // src/commands/telemetry/test.ts
8473
8920
  init_dist();
8474
- import { Command as Command77 } from "commander";
8921
+ import { Command as Command78 } from "commander";
8475
8922
 
8476
8923
  // src/bin/command-telemetry.ts
8477
- import { existsSync as existsSync36, readFileSync as readFileSync25, mkdirSync as mkdirSync15, appendFileSync, writeFileSync as writeFileSync18 } from "fs";
8478
- import { join as join46, parse as parsePath, resolve as resolve33 } from "path";
8924
+ import { existsSync as existsSync37, readFileSync as readFileSync26, mkdirSync as mkdirSync16, appendFileSync, writeFileSync as writeFileSync19 } from "fs";
8925
+ import { join as join47, parse as parsePath, resolve as resolve34 } from "path";
8479
8926
  import { spawn as spawn2 } from "child_process";
8480
8927
  var POSTHOG_API_KEY = "phc_wNTdCMcfJXZPgdNeDociZW6vwoGGo4nb7vqEfWThFfsG";
8481
8928
  var EXCLUDED_COMMANDS = /* @__PURE__ */ new Set(["help", "completion"]);
8482
8929
  function findProjectRoot(cwd) {
8483
- let dir = resolve33(cwd);
8930
+ let dir = resolve34(cwd);
8484
8931
  const { root } = parsePath(dir);
8485
8932
  while (dir !== root) {
8486
- if (existsSync36(join46(dir, "harness.config.json"))) return dir;
8487
- dir = resolve33(dir, "..");
8933
+ if (existsSync37(join47(dir, "harness.config.json"))) return dir;
8934
+ dir = resolve34(dir, "..");
8488
8935
  }
8489
8936
  return cwd;
8490
8937
  }
@@ -8521,8 +8968,8 @@ function resolveCommandName(cmd) {
8521
8968
  }
8522
8969
  function writeCommandRecordSync(cwd, command, duration, outcome) {
8523
8970
  try {
8524
- const metricsDir = join46(cwd, ".harness", "metrics");
8525
- mkdirSync15(metricsDir, { recursive: true });
8971
+ const metricsDir = join47(cwd, ".harness", "metrics");
8972
+ mkdirSync16(metricsDir, { recursive: true });
8526
8973
  const record = {
8527
8974
  skill: command,
8528
8975
  session: `cli-${Date.now()}`,
@@ -8531,16 +8978,16 @@ function writeCommandRecordSync(cwd, command, duration, outcome) {
8531
8978
  outcome,
8532
8979
  phasesReached: []
8533
8980
  };
8534
- const adoptionFile = join46(metricsDir, "adoption.jsonl");
8981
+ const adoptionFile = join47(metricsDir, "adoption.jsonl");
8535
8982
  appendFileSync(adoptionFile, JSON.stringify(record) + "\n");
8536
8983
  } catch {
8537
8984
  }
8538
8985
  }
8539
8986
  function isTelemetryDisabledByConfig(cwd) {
8540
- const configPath = join46(cwd, "harness.config.json");
8541
- if (!existsSync36(configPath)) return false;
8987
+ const configPath = join47(cwd, "harness.config.json");
8988
+ if (!existsSync37(configPath)) return false;
8542
8989
  try {
8543
- const config = JSON.parse(readFileSync25(configPath, "utf-8"));
8990
+ const config = JSON.parse(readFileSync26(configPath, "utf-8"));
8544
8991
  return config?.telemetry?.enabled === false;
8545
8992
  } catch {
8546
8993
  return false;
@@ -8552,11 +8999,11 @@ function isTelemetryOptedOut(cwd) {
8552
8999
  }
8553
9000
  function flushTelemetryBackground(cwd) {
8554
9001
  try {
8555
- const adoptionFile = join46(cwd, ".harness", "metrics", "adoption.jsonl");
8556
- if (!existsSync36(adoptionFile)) return;
9002
+ const adoptionFile = join47(cwd, ".harness", "metrics", "adoption.jsonl");
9003
+ if (!existsSync37(adoptionFile)) return;
8557
9004
  if (isTelemetryOptedOut(cwd)) return;
8558
- const reporterPath = join46(cwd, ".harness", "hooks", "telemetry-reporter.js");
8559
- if (!existsSync36(reporterPath)) return;
9005
+ const reporterPath = join47(cwd, ".harness", "hooks", "telemetry-reporter.js");
9006
+ if (!existsSync37(reporterPath)) return;
8560
9007
  const child = spawn2(process.execPath, [reporterPath], {
8561
9008
  cwd,
8562
9009
  stdio: ["pipe", "ignore", "ignore"],
@@ -8593,7 +9040,7 @@ function reportTestSuccess(status, distinctId, identity) {
8593
9040
  if (identity.team) logger.info(` team: ${identity.team}`);
8594
9041
  }
8595
9042
  function createTestCommand() {
8596
- return new Command77("test").description("Send a test event to PostHog and verify connectivity").action(async () => {
9043
+ return new Command78("test").description("Send a test event to PostHog and verify connectivity").action(async () => {
8597
9044
  const cwd = process.cwd();
8598
9045
  const consent = resolveConsent(cwd, void 0);
8599
9046
  if (!consent.allowed) {
@@ -8630,7 +9077,7 @@ function createTestCommand() {
8630
9077
 
8631
9078
  // src/commands/telemetry/index.ts
8632
9079
  function createTelemetryCommand() {
8633
- const command = new Command78("telemetry").description("Telemetry identity and status management");
9080
+ const command = new Command79("telemetry").description("Telemetry identity and status management");
8634
9081
  command.addCommand(createIdentifyCommand());
8635
9082
  command.addCommand(createStatusCommand());
8636
9083
  command.addCommand(createTestCommand());
@@ -8638,8 +9085,8 @@ function createTelemetryCommand() {
8638
9085
  }
8639
9086
 
8640
9087
  // src/commands/traceability.ts
8641
- import { Command as Command79 } from "commander";
8642
- import chalk12 from "chalk";
9088
+ import { Command as Command80 } from "commander";
9089
+ import chalk13 from "chalk";
8643
9090
  function confidenceLabel(maxConfidence) {
8644
9091
  if (maxConfidence >= 0.8) return "explicit";
8645
9092
  if (maxConfidence > 0) return "inferred";
@@ -8648,13 +9095,13 @@ function confidenceLabel(maxConfidence) {
8648
9095
  function statusIcon(status) {
8649
9096
  switch (status) {
8650
9097
  case "full":
8651
- return chalk12.green("\u2713 full");
9098
+ return chalk13.green("\u2713 full");
8652
9099
  case "code-only":
8653
- return chalk12.yellow("\u25D0 code-only");
9100
+ return chalk13.yellow("\u25D0 code-only");
8654
9101
  case "test-only":
8655
- return chalk12.yellow("\u25D0 test-only");
9102
+ return chalk13.yellow("\u25D0 test-only");
8656
9103
  case "none":
8657
- return chalk12.red("\u2717 none");
9104
+ return chalk13.red("\u2717 none");
8658
9105
  default:
8659
9106
  return status;
8660
9107
  }
@@ -8701,14 +9148,14 @@ function handleEmptyResults(mode) {
8701
9148
  }
8702
9149
  function printResultTable(result, mode) {
8703
9150
  const specLabel = result.specPath || result.featureName || "Unknown";
8704
- console.log(` ${chalk12.cyan(specLabel)} ${chalk12.dim(`(${result.summary.total} requirements)`)}`);
9151
+ console.log(` ${chalk13.cyan(specLabel)} ${chalk13.dim(`(${result.summary.total} requirements)`)}`);
8705
9152
  console.log("");
8706
9153
  const numWidth = 4;
8707
9154
  const nameWidth = mode === OutputMode.VERBOSE ? 44 : 36;
8708
9155
  const codeWidth = 6;
8709
9156
  const testWidth = 7;
8710
9157
  const confWidth = 12;
8711
- const header = chalk12.dim(
9158
+ const header = chalk13.dim(
8712
9159
  ` ${pad("#", numWidth)}${pad("Requirement", nameWidth)}${pad("Code", codeWidth)}${pad("Tests", testWidth)}${pad("Confidence", confWidth)}Status`
8713
9160
  );
8714
9161
  console.log(header);
@@ -8737,10 +9184,10 @@ function printRequirementRows(requirements, mode, cols) {
8737
9184
  );
8738
9185
  if (mode === OutputMode.VERBOSE) {
8739
9186
  for (const f of req.codeFiles) {
8740
- console.log(chalk12.dim(` code: ${f.path} (${f.method})`));
9187
+ console.log(chalk13.dim(` code: ${f.path} (${f.method})`));
8741
9188
  }
8742
9189
  for (const f of req.testFiles) {
8743
- console.log(chalk12.dim(` test: ${f.path} (${f.method})`));
9190
+ console.log(chalk13.dim(` test: ${f.path} (${f.method})`));
8744
9191
  }
8745
9192
  }
8746
9193
  }
@@ -8751,7 +9198,7 @@ function printCoverageSummary(summary) {
8751
9198
  const codePct = s.total > 0 ? Math.round(s.withCode / s.total * 100) : 0;
8752
9199
  const testPct = s.total > 0 ? Math.round(s.withTests / s.total * 100) : 0;
8753
9200
  console.log(
8754
- ` ${chalk12.bold("Coverage:")} ${fullyPct}% fully traced (${s.fullyTraced}/${s.total}), ${codePct}% with code (${s.withCode}/${s.total}), ${testPct}% with tests (${s.withTests}/${s.total})`
9201
+ ` ${chalk13.bold("Coverage:")} ${fullyPct}% fully traced (${s.fullyTraced}/${s.total}), ${codePct}% with code (${s.withCode}/${s.total}), ${testPct}% with tests (${s.withTests}/${s.total})`
8755
9202
  );
8756
9203
  }
8757
9204
  async function runTraceability(options) {
@@ -8759,7 +9206,7 @@ async function runTraceability(options) {
8759
9206
  const projectPath = process.cwd();
8760
9207
  const store = await loadGraphStore(projectPath);
8761
9208
  if (!store) handleNoStore(mode);
8762
- const graphModule = await import("./dist-BZS2XRLG.js");
9209
+ const graphModule = await import("./dist-BP6E6QGG.js");
8763
9210
  const filterOptions = buildFilterOptions(options);
8764
9211
  const results = graphModule.queryTraceability(store, filterOptions);
8765
9212
  if (results.length === 0) handleEmptyResults(mode);
@@ -8767,14 +9214,14 @@ async function runTraceability(options) {
8767
9214
  console.log(JSON.stringify(results, null, 2));
8768
9215
  } else {
8769
9216
  console.log("");
8770
- console.log(chalk12.bold("Spec-to-Implementation Traceability"));
9217
+ console.log(chalk13.bold("Spec-to-Implementation Traceability"));
8771
9218
  console.log("");
8772
9219
  for (const result of results) printResultTable(result, mode);
8773
9220
  }
8774
9221
  process.exit(ExitCode.SUCCESS);
8775
9222
  }
8776
9223
  function createTraceabilityCommand() {
8777
- return new Command79("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) => {
9224
+ return new Command80("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) => {
8778
9225
  const globalOpts = cmd.optsWithGlobals();
8779
9226
  await runTraceability({
8780
9227
  spec: opts.spec,
@@ -8787,15 +9234,15 @@ function createTraceabilityCommand() {
8787
9234
  }
8788
9235
 
8789
9236
  // src/commands/uninstall.ts
8790
- import * as path61 from "path";
8791
- import { Command as Command80 } from "commander";
9237
+ import * as path62 from "path";
9238
+ import { Command as Command81 } from "commander";
8792
9239
  async function runUninstall(skillName, options) {
8793
9240
  const packageName = resolvePackageName(skillName);
8794
9241
  const shortName = extractSkillName(packageName);
8795
9242
  const globalDir = resolveGlobalSkillsDir();
8796
- const skillsDir = path61.dirname(globalDir);
8797
- const communityBase = path61.join(skillsDir, "community");
8798
- const lockfilePath = path61.join(communityBase, "skills-lock.json");
9243
+ const skillsDir = path62.dirname(globalDir);
9244
+ const communityBase = path62.join(skillsDir, "community");
9245
+ const lockfilePath = path62.join(communityBase, "skills-lock.json");
8799
9246
  const lockfile = readLockfile2(lockfilePath);
8800
9247
  const entry = lockfile.skills[packageName];
8801
9248
  if (!entry) {
@@ -8825,7 +9272,7 @@ async function runUninstall(skillName, options) {
8825
9272
  return result;
8826
9273
  }
8827
9274
  function createUninstallCommand() {
8828
- const cmd = new Command80("uninstall");
9275
+ const cmd = new Command81("uninstall");
8829
9276
  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) => {
8830
9277
  try {
8831
9278
  const result = await runUninstall(skill, opts);
@@ -8845,9 +9292,9 @@ function createUninstallCommand() {
8845
9292
 
8846
9293
  // src/commands/uninstall-constraints.ts
8847
9294
  init_dist();
8848
- import * as fs40 from "fs/promises";
8849
- import * as path62 from "path";
8850
- import { Command as Command81 } from "commander";
9295
+ import * as fs41 from "fs/promises";
9296
+ import * as path63 from "path";
9297
+ import { Command as Command82 } from "commander";
8851
9298
  async function runUninstallConstraints(options) {
8852
9299
  const { packageName, configPath, lockfilePath } = options;
8853
9300
  const lockfileResult = await readLockfile(lockfilePath);
@@ -8867,7 +9314,7 @@ async function runUninstallConstraints(options) {
8867
9314
  }
8868
9315
  let localConfig;
8869
9316
  try {
8870
- const raw = await fs40.readFile(configPath, "utf-8");
9317
+ const raw = await fs41.readFile(configPath, "utf-8");
8871
9318
  localConfig = JSON.parse(raw);
8872
9319
  } catch (err) {
8873
9320
  return {
@@ -8904,11 +9351,11 @@ async function runUninstallConstraints(options) {
8904
9351
  };
8905
9352
  }
8906
9353
  function createUninstallConstraintsCommand() {
8907
- const cmd = new Command81("uninstall-constraints");
9354
+ const cmd = new Command82("uninstall-constraints");
8908
9355
  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) => {
8909
9356
  let configPath;
8910
9357
  if (opts.config) {
8911
- configPath = path62.resolve(opts.config);
9358
+ configPath = path63.resolve(opts.config);
8912
9359
  } else {
8913
9360
  const found = findConfigFile();
8914
9361
  if (!found.ok) {
@@ -8917,8 +9364,8 @@ function createUninstallConstraintsCommand() {
8917
9364
  }
8918
9365
  configPath = found.value;
8919
9366
  }
8920
- const projectRoot = path62.dirname(configPath);
8921
- const lockfilePath = path62.join(projectRoot, ".harness", "constraints.lock.json");
9367
+ const projectRoot = path63.dirname(configPath);
9368
+ const lockfilePath = path63.join(projectRoot, ".harness", "constraints.lock.json");
8922
9369
  const result = await runUninstallConstraints({
8923
9370
  packageName: name,
8924
9371
  configPath,
@@ -8943,13 +9390,13 @@ function createUninstallConstraintsCommand() {
8943
9390
  }
8944
9391
 
8945
9392
  // src/commands/update.ts
8946
- import { Command as Command82 } from "commander";
8947
- import { execFile, execFileSync as execFileSync6 } from "child_process";
8948
- import { realpathSync, existsSync as existsSync37, readFileSync as readFileSync26 } from "fs";
8949
- import { join as join49 } from "path";
9393
+ import { Command as Command83 } from "commander";
9394
+ import { execFile, execFileSync as execFileSync7 } from "child_process";
9395
+ import { realpathSync, existsSync as existsSync38, readFileSync as readFileSync27 } from "fs";
9396
+ import { join as join50 } from "path";
8950
9397
  import { promisify } from "util";
8951
- import readline3 from "readline";
8952
- import chalk13 from "chalk";
9398
+ import readline4 from "readline";
9399
+ import chalk14 from "chalk";
8953
9400
  function detectPackageManager() {
8954
9401
  try {
8955
9402
  const argv1 = process.argv[1];
@@ -8978,7 +9425,7 @@ async function getLatestVersionAsync(pkg) {
8978
9425
  function getInstalledVersions(pm, packages) {
8979
9426
  const versions = {};
8980
9427
  try {
8981
- const output = execFileSync6(pm, ["list", "-g", "--json"], {
9428
+ const output = execFileSync7(pm, ["list", "-g", "--json"], {
8982
9429
  encoding: "utf-8",
8983
9430
  timeout: 15e3
8984
9431
  });
@@ -8996,7 +9443,7 @@ function getInstalledVersions(pm, packages) {
8996
9443
  }
8997
9444
  function getInstalledPackages(pm) {
8998
9445
  try {
8999
- const output = execFileSync6(pm, ["list", "-g", "--json"], {
9446
+ const output = execFileSync7(pm, ["list", "-g", "--json"], {
9000
9447
  encoding: "utf-8",
9001
9448
  timeout: 15e3
9002
9449
  });
@@ -9007,15 +9454,15 @@ function getInstalledPackages(pm) {
9007
9454
  return ["@harness-engineering/cli", "@harness-engineering/core"];
9008
9455
  }
9009
9456
  }
9010
- function prompt2(question) {
9011
- const rl = readline3.createInterface({
9457
+ function prompt3(question) {
9458
+ const rl = readline4.createInterface({
9012
9459
  input: process.stdin,
9013
9460
  output: process.stdout
9014
9461
  });
9015
- return new Promise((resolve36) => {
9462
+ return new Promise((resolve37) => {
9016
9463
  rl.question(question, (answer) => {
9017
9464
  rl.close();
9018
- resolve36(answer.trim().toLowerCase());
9465
+ resolve37(answer.trim().toLowerCase());
9019
9466
  });
9020
9467
  });
9021
9468
  }
@@ -9030,12 +9477,12 @@ async function ensureTelemetryIfNeeded() {
9030
9477
  }
9031
9478
  function refreshHooks() {
9032
9479
  const cwd = process.cwd();
9033
- const configPath = join49(cwd, "harness.config.json");
9034
- if (!existsSync37(configPath)) return;
9480
+ const configPath = join50(cwd, "harness.config.json");
9481
+ if (!existsSync38(configPath)) return;
9035
9482
  let profile = "standard";
9036
- const profilePath = join49(cwd, ".harness", "hooks", "profile.json");
9483
+ const profilePath = join50(cwd, ".harness", "hooks", "profile.json");
9037
9484
  try {
9038
- const data = JSON.parse(readFileSync26(profilePath, "utf-8"));
9485
+ const data = JSON.parse(readFileSync27(profilePath, "utf-8"));
9039
9486
  if (data.profile && ["minimal", "standard", "strict"].includes(data.profile)) {
9040
9487
  profile = data.profile;
9041
9488
  }
@@ -9052,27 +9499,27 @@ function refreshHooks() {
9052
9499
  function runLocalGraphScan() {
9053
9500
  try {
9054
9501
  logger.info("Scanning codebase to rebuild knowledge graph...");
9055
- execFileSync6("harness", ["graph", "scan", "."], { stdio: "inherit" });
9502
+ execFileSync7("harness", ["graph", "scan", "."], { stdio: "inherit" });
9056
9503
  } catch {
9057
9504
  logger.warn("Graph scan failed. Run manually:");
9058
- console.log(` ${chalk13.cyan("harness graph scan .")}`);
9505
+ console.log(` ${chalk14.cyan("harness graph scan .")}`);
9059
9506
  }
9060
9507
  }
9061
9508
  async function offerRegeneration() {
9062
9509
  console.log("");
9063
- const regenAnswer = await prompt2(
9510
+ const regenAnswer = await prompt3(
9064
9511
  "Regenerate slash commands, agent definitions, and knowledge graph? (Y/n) "
9065
9512
  );
9066
9513
  if (regenAnswer === "n" || regenAnswer === "no") return;
9067
- const scopeAnswer = await prompt2("Generate for (G)lobal or (l)ocal project? (G/l) ");
9514
+ const scopeAnswer = await prompt3("Generate for (G)lobal or (l)ocal project? (G/l) ");
9068
9515
  const isGlobal = scopeAnswer !== "l" && scopeAnswer !== "local";
9069
9516
  try {
9070
- execFileSync6("harness", ["generate", ...isGlobal ? ["--global"] : []], {
9517
+ execFileSync7("harness", ["generate", ...isGlobal ? ["--global"] : []], {
9071
9518
  stdio: "inherit"
9072
9519
  });
9073
9520
  } catch {
9074
9521
  logger.warn("Generation failed. Run manually:");
9075
- console.log(` ${chalk13.cyan(`harness generate${isGlobal ? " --global" : ""}`)}`);
9522
+ console.log(` ${chalk14.cyan(`harness generate${isGlobal ? " --global" : ""}`)}`);
9076
9523
  }
9077
9524
  if (!isGlobal) {
9078
9525
  runLocalGraphScan();
@@ -9135,8 +9582,8 @@ async function runUpdateAction(opts, globalOpts) {
9135
9582
  console.log("");
9136
9583
  for (const { pkg, current, latest } of outdated) {
9137
9584
  const shortName = pkg.replace("@harness-engineering/", "");
9138
- const currentStr = current ? chalk13.dim(`v${current}`) : chalk13.dim("not installed");
9139
- logger.info(`${shortName}: ${currentStr} \u2192 ${chalk13.green(`v${latest}`)}`);
9585
+ const currentStr = current ? chalk14.dim(`v${current}`) : chalk14.dim("not installed");
9586
+ logger.info(`${shortName}: ${currentStr} \u2192 ${chalk14.green(`v${latest}`)}`);
9140
9587
  }
9141
9588
  console.log("");
9142
9589
  }
@@ -9146,13 +9593,13 @@ async function runUpdateAction(opts, globalOpts) {
9146
9593
  }
9147
9594
  try {
9148
9595
  logger.info("Updating packages...");
9149
- execFileSync6(pm, ["install", "-g", ...installPkgs], { stdio: "inherit", timeout: 12e4 });
9596
+ execFileSync7(pm, ["install", "-g", ...installPkgs], { stdio: "inherit", timeout: 12e4 });
9150
9597
  console.log("");
9151
9598
  logger.success("Update complete");
9152
9599
  } catch {
9153
9600
  console.log("");
9154
9601
  logger.error("Update failed. You can try manually:");
9155
- console.log(` ${chalk13.cyan(installCmd)}`);
9602
+ console.log(` ${chalk14.cyan(installCmd)}`);
9156
9603
  process.exit(ExitCode.ERROR);
9157
9604
  }
9158
9605
  refreshHooks();
@@ -9161,7 +9608,7 @@ async function runUpdateAction(opts, globalOpts) {
9161
9608
  process.exit(ExitCode.SUCCESS);
9162
9609
  }
9163
9610
  function createUpdateCommand() {
9164
- return new Command82("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(
9611
+ return new Command83("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(
9165
9612
  "--regenerate",
9166
9613
  "Only regenerate slash commands and agent definitions (skip package updates)"
9167
9614
  ).action(async (opts, cmd) => {
@@ -9171,9 +9618,9 @@ function createUpdateCommand() {
9171
9618
  }
9172
9619
 
9173
9620
  // src/commands/usage.ts
9174
- import { Command as Command83 } from "commander";
9621
+ import { Command as Command84 } from "commander";
9175
9622
  async function loadAndPriceRecords(cwd, includeClaudeSessions = false) {
9176
- const { readCostRecords, loadPricingData, calculateCost, parseCCRecords } = await import("./dist-CPKL5Y2R.js");
9623
+ const { readCostRecords, loadPricingData, calculateCost, parseCCRecords } = await import("./dist-46VOJIG4.js");
9177
9624
  const records = readCostRecords(cwd);
9178
9625
  if (includeClaudeSessions) {
9179
9626
  const ccRecords = parseCCRecords();
@@ -9266,7 +9713,7 @@ function registerDailyCommand(usage) {
9266
9713
  else logger.info("No usage data found. Run some harness sessions first.");
9267
9714
  return;
9268
9715
  }
9269
- const { aggregateByDay } = await import("./dist-CPKL5Y2R.js");
9716
+ const { aggregateByDay } = await import("./dist-46VOJIG4.js");
9270
9717
  const limited = aggregateByDay(records).slice(0, days);
9271
9718
  if (globalOpts.json) {
9272
9719
  console.log(
@@ -9295,7 +9742,7 @@ function registerSessionsCommand(usage) {
9295
9742
  }
9296
9743
  return;
9297
9744
  }
9298
- const { aggregateBySession } = await import("./dist-CPKL5Y2R.js");
9745
+ const { aggregateBySession } = await import("./dist-46VOJIG4.js");
9299
9746
  const sessionData = aggregateBySession(records);
9300
9747
  const limited = sessionData.slice(0, limit);
9301
9748
  if (globalOpts.json) {
@@ -9375,7 +9822,7 @@ function registerSessionCommand(usage) {
9375
9822
  cwd,
9376
9823
  globalOpts.includeClaudeSessions
9377
9824
  );
9378
- const { aggregateBySession } = await import("./dist-CPKL5Y2R.js");
9825
+ const { aggregateBySession } = await import("./dist-46VOJIG4.js");
9379
9826
  const sessionData = aggregateBySession(records);
9380
9827
  const match = sessionData.find((s) => s.sessionId === id);
9381
9828
  if (!match) {
@@ -9410,7 +9857,7 @@ function registerLatestCommand(usage) {
9410
9857
  }
9411
9858
  return;
9412
9859
  }
9413
- const { aggregateBySession } = await import("./dist-CPKL5Y2R.js");
9860
+ const { aggregateBySession } = await import("./dist-46VOJIG4.js");
9414
9861
  const sessionData = aggregateBySession(records);
9415
9862
  const latest = sessionData[0];
9416
9863
  if (!latest) {
@@ -9436,7 +9883,7 @@ function registerLatestCommand(usage) {
9436
9883
  });
9437
9884
  }
9438
9885
  function createUsageCommand() {
9439
- const usage = new Command83("usage").description("Token usage and cost tracking");
9886
+ const usage = new Command84("usage").description("Token usage and cost tracking");
9440
9887
  usage.option(
9441
9888
  "--include-claude-sessions",
9442
9889
  "Include Claude Code session data from ~/.claude/projects/"
@@ -9451,15 +9898,15 @@ function createUsageCommand() {
9451
9898
  // src/commands/validate.ts
9452
9899
  init_dist();
9453
9900
  init_dist();
9454
- import { Command as Command84 } from "commander";
9455
- import * as path63 from "path";
9901
+ import { Command as Command85 } from "commander";
9902
+ import * as path64 from "path";
9456
9903
  async function runValidate(options) {
9457
9904
  const configResult = resolveConfig(options.configPath);
9458
9905
  if (!configResult.ok) {
9459
9906
  return configResult;
9460
9907
  }
9461
9908
  const config = configResult.value;
9462
- const cwd = options.cwd ?? (options.configPath ? path63.dirname(path63.resolve(options.configPath)) : process.cwd());
9909
+ const cwd = options.cwd ?? (options.configPath ? path64.dirname(path64.resolve(options.configPath)) : process.cwd());
9463
9910
  const result = {
9464
9911
  valid: true,
9465
9912
  checks: {
@@ -9469,7 +9916,7 @@ async function runValidate(options) {
9469
9916
  },
9470
9917
  issues: []
9471
9918
  };
9472
- const agentsMapPath = path63.resolve(cwd, config.agentsMapPath);
9919
+ const agentsMapPath = path64.resolve(cwd, config.agentsMapPath);
9473
9920
  const agentsResult = await validateAgentsMap(agentsMapPath);
9474
9921
  if (agentsResult.ok) {
9475
9922
  result.checks.agentsMap = true;
@@ -9534,11 +9981,11 @@ function resolveValidateMode(globalOpts) {
9534
9981
  return OutputMode.TEXT;
9535
9982
  }
9536
9983
  async function printCrossCheckWarnings(mode) {
9537
- const { runCrossCheck: runCrossCheck2 } = await import("./validate-cross-check-SPL3H4O5.js");
9984
+ const { runCrossCheck: runCrossCheck2 } = await import("./validate-cross-check-LUQYIA46.js");
9538
9985
  const cwd = process.cwd();
9539
9986
  const crossResult = await runCrossCheck2({
9540
- specsDir: path63.join(cwd, "docs", "specs"),
9541
- plansDir: path63.join(cwd, "docs", "plans"),
9987
+ specsDir: path64.join(cwd, "docs", "specs"),
9988
+ plansDir: path64.join(cwd, "docs", "plans"),
9542
9989
  projectPath: cwd
9543
9990
  });
9544
9991
  if (!crossResult.ok || crossResult.value.warnings === 0) return;
@@ -9550,7 +9997,7 @@ async function printCrossCheckWarnings(mode) {
9550
9997
  ${crossResult.value.warnings} warnings`);
9551
9998
  }
9552
9999
  function createValidateCommand3() {
9553
- const command = new Command84("validate").description("Run all validation checks").option("--cross-check", "Run cross-artifact consistency validation").option(
10000
+ const command = new Command85("validate").description("Run all validation checks").option("--cross-check", "Run cross-artifact consistency validation").option(
9554
10001
  "--agent-configs",
9555
10002
  "Validate agent configs (CLAUDE.md, hooks, skills) via agnix or built-in fallback rules"
9556
10003
  ).option("--strict", "Treat warnings as errors (applies to --agent-configs)").option("--agnix-bin <path>", "Override the agnix binary path discovered on PATH").action(async (opts, cmd) => runValidateAction(opts, cmd.optsWithGlobals()));
@@ -9600,8 +10047,8 @@ Agent configs checked via ${engineLabel}${note}`);
9600
10047
  // src/commands/_registry.ts
9601
10048
  var commandCreators = [
9602
10049
  createAddCommand,
9603
- createAdviseSkillsCommand,
9604
10050
  createAdoptionCommand,
10051
+ createAdviseSkillsCommand,
9605
10052
  createAgentCommand,
9606
10053
  createAuditProtectedCommand,
9607
10054
  createBlueprintCommand,
@@ -9633,6 +10080,7 @@ var commandCreators = [
9633
10080
  createLearningsCommand,
9634
10081
  createLinterCommand,
9635
10082
  createMcpCommand,
10083
+ createMigrateCommand,
9636
10084
  createOrchestratorCommand,
9637
10085
  createPerfCommand,
9638
10086
  createPersonaCommand,
@@ -9661,7 +10109,7 @@ var commandCreators = [
9661
10109
 
9662
10110
  // src/index.ts
9663
10111
  function createProgram() {
9664
- const program = new Command85();
10112
+ const program = new Command86();
9665
10113
  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");
9666
10114
  for (const creator of commandCreators) {
9667
10115
  program.addCommand(creator());