@harness-engineering/cli 4.1.0 → 4.3.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 (75) hide show
  1. package/dist/agents/skills/claude-code/harness-autopilot/SKILL.md +31 -0
  2. package/dist/agents/skills/claude-code/harness-catalog-retrospective/SKILL.md +124 -0
  3. package/dist/agents/skills/claude-code/harness-catalog-retrospective/skill.yaml +48 -0
  4. package/dist/agents/skills/claude-code/harness-execution/SKILL.md +13 -0
  5. package/dist/agents/skills/claude-code/harness-parallel-agents/SKILL.md +3 -0
  6. package/dist/agents/skills/claude-code/harness-planning/SKILL.md +3 -1
  7. package/dist/agents/skills/codex/harness-autopilot/SKILL.md +31 -0
  8. package/dist/agents/skills/codex/harness-catalog-retrospective/SKILL.md +124 -0
  9. package/dist/agents/skills/codex/harness-catalog-retrospective/skill.yaml +48 -0
  10. package/dist/agents/skills/codex/harness-execution/SKILL.md +13 -0
  11. package/dist/agents/skills/codex/harness-parallel-agents/SKILL.md +3 -0
  12. package/dist/agents/skills/codex/harness-planning/SKILL.md +3 -1
  13. package/dist/agents/skills/cursor/harness-autopilot/SKILL.md +31 -0
  14. package/dist/agents/skills/cursor/harness-catalog-retrospective/SKILL.md +124 -0
  15. package/dist/agents/skills/cursor/harness-catalog-retrospective/skill.yaml +48 -0
  16. package/dist/agents/skills/cursor/harness-execution/SKILL.md +13 -0
  17. package/dist/agents/skills/cursor/harness-parallel-agents/SKILL.md +3 -0
  18. package/dist/agents/skills/cursor/harness-planning/SKILL.md +3 -1
  19. package/dist/agents/skills/gemini-cli/harness-autopilot/SKILL.md +31 -0
  20. package/dist/agents/skills/gemini-cli/harness-catalog-retrospective/SKILL.md +124 -0
  21. package/dist/agents/skills/gemini-cli/harness-catalog-retrospective/skill.yaml +48 -0
  22. package/dist/agents/skills/gemini-cli/harness-execution/SKILL.md +13 -0
  23. package/dist/agents/skills/gemini-cli/harness-parallel-agents/SKILL.md +3 -0
  24. package/dist/agents/skills/gemini-cli/harness-planning/SKILL.md +3 -1
  25. package/dist/{agents-md-7L4PKKOM.js → agents-md-N4ULMUAK.js} +4 -4
  26. package/dist/{analyzer-XRCV63KC-HLTEIKAJ.js → analyzer-XRCV63KC-WGRHW2ZM.js} +2 -2
  27. package/dist/{architecture-RCHFDI7E.js → architecture-OIMIBDJC.js} +5 -5
  28. package/dist/{assess-project-YUDPNRS6.js → assess-project-ITSB6W4L.js} +1 -1
  29. package/dist/bin/harness-mcp.js +15 -15
  30. package/dist/bin/harness.js +26 -26
  31. package/dist/{check-phase-gate-56GS3A72.js → check-phase-gate-GN4X7HT6.js} +5 -5
  32. package/dist/{chunk-N4AI2WFH.js → chunk-574JCBYH.js} +2 -2
  33. package/dist/{chunk-RY2U77OY.js → chunk-5BUHPOCP.js} +7 -7
  34. package/dist/{chunk-IGWJRAJT.js → chunk-6NEJPS7W.js} +2 -2
  35. package/dist/{chunk-NCMJXBEO.js → chunk-73QZ43DF.js} +2 -2
  36. package/dist/{chunk-YJYUJSWK.js → chunk-7RH2NTLA.js} +1 -1
  37. package/dist/{chunk-XZNCONFG.js → chunk-CMU4DNLY.js} +1 -1
  38. package/dist/{chunk-UACYZCW4.js → chunk-CRHQYBDA.js} +396 -13
  39. package/dist/{chunk-4SKWGVYD.js → chunk-D7A5JR7M.js} +2 -2
  40. package/dist/{chunk-P4NA5OQX.js → chunk-GTHL3TRZ.js} +2 -2
  41. package/dist/{chunk-ZU6T7W3U.js → chunk-H5GN7R43.js} +2 -2
  42. package/dist/{chunk-YXOPQEFZ.js → chunk-HJYAXAYQ.js} +2 -2
  43. package/dist/{chunk-Z4XWWNYX.js → chunk-HSYU3RUW.js} +203 -92
  44. package/dist/{chunk-Y33P35U3.js → chunk-JZL2O3RC.js} +5 -5
  45. package/dist/{chunk-XW5XVVMI.js → chunk-LP764MGR.js} +3 -3
  46. package/dist/{chunk-Y5HPJMTM.js → chunk-LTYVAKWK.js} +2 -2
  47. package/dist/{chunk-DGVT4DBI.js → chunk-MEDRUIRO.js} +3 -3
  48. package/dist/{chunk-GSYBGOY3.js → chunk-MIZQY35D.js} +2 -2
  49. package/dist/{chunk-YWRPQZL7.js → chunk-NEMB36N4.js} +2 -2
  50. package/dist/{chunk-GLHLXTKC.js → chunk-PT65VY4S.js} +6 -6
  51. package/dist/{chunk-AU4YPEIE.js → chunk-T46G6YNI.js} +3 -3
  52. package/dist/{chunk-ABRYIEWJ.js → chunk-TDPQZAEE.js} +1069 -853
  53. package/dist/{chunk-VG4G3R2V.js → chunk-TKPAOB2T.js} +2 -2
  54. package/dist/{chunk-RZQZXWEL.js → chunk-U2NOOATF.js} +6 -6
  55. package/dist/{chunk-BDGTZRZ6.js → chunk-VJDSB7CI.js} +159 -85
  56. package/dist/{chunk-OZSKLJQW.js → chunk-XKILFNRK.js} +2 -2
  57. package/dist/{ci-workflow-TFAA5BK7.js → ci-workflow-PA3WL6WK.js} +4 -4
  58. package/dist/{dist-MCTEX5QH.js → dist-BWFFVKEW.js} +34 -4
  59. package/dist/{dist-ICW4QUEW.js → dist-ISDDHDOR.js} +19 -3
  60. package/dist/{docs-BBMAN3CY.js → docs-HOTWQJQF.js} +5 -5
  61. package/dist/{engine-R2YH74AL.js → engine-MVG2SPGD.js} +4 -4
  62. package/dist/{entropy-5UP5N6AF.js → entropy-3B4U2BTF.js} +5 -5
  63. package/dist/{feedback-6MDCCFZL.js → feedback-WIWWDVUC.js} +1 -1
  64. package/dist/{generate-agent-definitions-KKAN5DB5.js → generate-agent-definitions-KPRHY6X3.js} +5 -5
  65. package/dist/index.js +25 -25
  66. package/dist/{loader-2WT2ZE2T.js → loader-SPJ2ZGYW.js} +4 -4
  67. package/dist/{mcp-5V4LPMB3.js → mcp-RIPEYDMU.js} +15 -15
  68. package/dist/{performance-2N3CFXLR.js → performance-JYFS27B3.js} +5 -5
  69. package/dist/{review-pipeline-XZIGBU3Q.js → review-pipeline-BDT6Y6QV.js} +4 -4
  70. package/dist/{runtime-POME3GTR.js → runtime-ZEPHPPQJ.js} +4 -4
  71. package/dist/{security-QLJLMSIW.js → security-FWSDTTEW.js} +1 -1
  72. package/dist/{state-events-YY5KBZTC.js → state-events-PBDNQPXT.js} +4 -4
  73. package/dist/{validate-VZORVK43.js → validate-XIMNCIKR.js} +5 -5
  74. package/dist/{validate-cross-check-OYKEDCST.js → validate-cross-check-H2OUHTID.js} +4 -4
  75. package/package.json +8 -8
@@ -1,22 +1,22 @@
1
1
  import {
2
2
  generateRuntime
3
- } from "./chunk-N4AI2WFH.js";
3
+ } from "./chunk-574JCBYH.js";
4
4
  import {
5
5
  generateAgentsMd
6
- } from "./chunk-VG4G3R2V.js";
6
+ } from "./chunk-TKPAOB2T.js";
7
7
  import {
8
8
  generateCIWorkflow
9
- } from "./chunk-P4NA5OQX.js";
9
+ } from "./chunk-GTHL3TRZ.js";
10
10
  import {
11
11
  readHarnessState
12
- } from "./chunk-YWRPQZL7.js";
12
+ } from "./chunk-NEMB36N4.js";
13
13
  import {
14
14
  runCrossCheck
15
- } from "./chunk-GSYBGOY3.js";
15
+ } from "./chunk-MIZQY35D.js";
16
16
  import {
17
17
  createGenerateAgentDefinitionsCommand,
18
18
  generateAgentDefinitions
19
- } from "./chunk-XZNCONFG.js";
19
+ } from "./chunk-CMU4DNLY.js";
20
20
  import {
21
21
  toKebabCase
22
22
  } from "./chunk-KET4QQZB.js";
@@ -26,7 +26,7 @@ import {
26
26
  } from "./chunk-YYFSFSB3.js";
27
27
  import {
28
28
  TemplateEngine
29
- } from "./chunk-IGWJRAJT.js";
29
+ } from "./chunk-6NEJPS7W.js";
30
30
  import {
31
31
  generate,
32
32
  validate
@@ -37,7 +37,7 @@ import {
37
37
  import {
38
38
  listPersonas,
39
39
  loadPersona
40
- } from "./chunk-NCMJXBEO.js";
40
+ } from "./chunk-73QZ43DF.js";
41
41
  import {
42
42
  runPersona
43
43
  } from "./chunk-GISMXMVL.js";
@@ -51,7 +51,7 @@ import {
51
51
  OutputFormatter,
52
52
  OutputMode,
53
53
  createCheckPhaseGateCommand
54
- } from "./chunk-XW5XVVMI.js";
54
+ } from "./chunk-LP764MGR.js";
55
55
  import {
56
56
  appendFrameworkAgents,
57
57
  captureHealthSnapshot,
@@ -79,7 +79,7 @@ import {
79
79
  runSecurityCraft,
80
80
  runSpecCraft,
81
81
  runTestCraft
82
- } from "./chunk-Z4XWWNYX.js";
82
+ } from "./chunk-HSYU3RUW.js";
83
83
  import {
84
84
  VALID_PLATFORMS
85
85
  } from "./chunk-3ISINLYT.js";
@@ -108,7 +108,7 @@ import {
108
108
  BranchingConfigSchema,
109
109
  findConfigFile,
110
110
  resolveConfig
111
- } from "./chunk-Y5HPJMTM.js";
111
+ } from "./chunk-LTYVAKWK.js";
112
112
  import {
113
113
  logger
114
114
  } from "./chunk-EBJQ6N4M.js";
@@ -225,7 +225,7 @@ import {
225
225
  writeConfig,
226
226
  writeLockfile,
227
227
  writeRegeneratedRoadmap
228
- } from "./chunk-UACYZCW4.js";
228
+ } from "./chunk-CRHQYBDA.js";
229
229
  import {
230
230
  CLI_VERSION
231
231
  } from "./chunk-BM3PWGXQ.js";
@@ -238,14 +238,14 @@ import {
238
238
  detectDocDrift,
239
239
  generateSuggestions,
240
240
  validateDependencies
241
- } from "./chunk-YJYUJSWK.js";
241
+ } from "./chunk-7RH2NTLA.js";
242
242
  import {
243
243
  Err,
244
244
  INDEXED_FILE_KINDS,
245
245
  INSIGHTS_KEYS,
246
246
  Ok,
247
247
  init_dist
248
- } from "./chunk-BDGTZRZ6.js";
248
+ } from "./chunk-VJDSB7CI.js";
249
249
  import {
250
250
  DEFAULT_SKIP_DIRS,
251
251
  DesignConstraintAdapter,
@@ -434,6 +434,8 @@ function createAddCommand() {
434
434
  }
435
435
 
436
436
  // src/commands/adoption.ts
437
+ import * as fs2 from "fs";
438
+ import * as path2 from "path";
437
439
  import { Command as Command2 } from "commander";
438
440
  function formatDuration(ms) {
439
441
  if (ms < 1e3) return `${ms}ms`;
@@ -451,7 +453,7 @@ function registerSkillsCommand(adoption) {
451
453
  const globalOpts = cmd.optsWithGlobals();
452
454
  const limit = Math.max(parseInt(opts.limit, 10) || 20, 1);
453
455
  const cwd = process.cwd();
454
- const { readAdoptionRecords, aggregateBySkill } = await import("./dist-MCTEX5QH.js");
456
+ const { readAdoptionRecords, aggregateBySkill } = await import("./dist-BWFFVKEW.js");
455
457
  const records = readAdoptionRecords(cwd);
456
458
  if (records.length === 0) {
457
459
  if (globalOpts.json) {
@@ -487,7 +489,7 @@ function registerRecentCommand(adoption) {
487
489
  const globalOpts = cmd.optsWithGlobals();
488
490
  const limit = Math.max(parseInt(opts.limit, 10) || 20, 1);
489
491
  const cwd = process.cwd();
490
- const { readAdoptionRecords } = await import("./dist-MCTEX5QH.js");
492
+ const { readAdoptionRecords } = await import("./dist-BWFFVKEW.js");
491
493
  const records = readAdoptionRecords(cwd);
492
494
  if (records.length === 0) {
493
495
  if (globalOpts.json) {
@@ -565,7 +567,7 @@ function registerSkillCommand(adoption) {
565
567
  adoption.command("skill <name>").description("Show detail for a specific skill").action(async (name, _opts, cmd) => {
566
568
  const globalOpts = cmd.optsWithGlobals();
567
569
  const cwd = process.cwd();
568
- const { readAdoptionRecords, aggregateBySkill } = await import("./dist-MCTEX5QH.js");
570
+ const { readAdoptionRecords, aggregateBySkill } = await import("./dist-BWFFVKEW.js");
569
571
  const records = readAdoptionRecords(cwd);
570
572
  const skillRecords = records.filter((r) => r.skill === name);
571
573
  if (skillRecords.length === 0) {
@@ -584,11 +586,55 @@ function registerSkillCommand(adoption) {
584
586
  printSkillDetail(name, summary, phaseRates, skillRecords);
585
587
  });
586
588
  }
589
+ function discoverCatalogSkills(projectRoot3) {
590
+ const skillsDir = path2.join(projectRoot3, "agents", "skills", "claude-code");
591
+ let entries;
592
+ try {
593
+ entries = fs2.readdirSync(skillsDir, { withFileTypes: true });
594
+ } catch {
595
+ return void 0;
596
+ }
597
+ const names = entries.filter((e) => e.isDirectory()).map((e) => e.name).filter((name) => fs2.existsSync(path2.join(skillsDir, name, "skill.yaml")));
598
+ return names.length > 0 ? names : void 0;
599
+ }
600
+ function registerRetrospectiveCommand(adoption) {
601
+ adoption.command("retrospective").description("Generate a catalog retrospective from adoption telemetry").option("--inactive-days <n>", "Inactivity threshold in days (default: 90)", "90").option("--top <n>", "Rows per ranked section (default: 10)", "10").option("--out <path>", "Output file path (default: docs/retrospectives/YYYY-MM-DD.md)").option("--no-write", "Print the report to stdout instead of writing a file").action(async (opts, cmd) => {
602
+ const globalOpts = cmd.optsWithGlobals();
603
+ const cwd = process.cwd();
604
+ const { readAdoptionRecords, getCatalogRetrospectiveReport, renderRetrospectiveMarkdown } = await import("./dist-BWFFVKEW.js");
605
+ const records = readAdoptionRecords(cwd);
606
+ const catalogSkills = discoverCatalogSkills(cwd);
607
+ const report = getCatalogRetrospectiveReport(records, {
608
+ inactiveDays: Math.max(parseInt(opts.inactiveDays, 10) || 90, 1),
609
+ topN: Math.max(parseInt(opts.top, 10) || 10, 1),
610
+ ...catalogSkills ? { catalogSkills } : {}
611
+ });
612
+ if (globalOpts.json) {
613
+ console.log(JSON.stringify(report, null, 2));
614
+ return;
615
+ }
616
+ const markdown = renderRetrospectiveMarkdown(report);
617
+ if (opts.write === false) {
618
+ console.log(markdown);
619
+ return;
620
+ }
621
+ const date = report.generatedAt.slice(0, 10);
622
+ const outPath = opts.out ? path2.resolve(cwd, opts.out) : path2.join(cwd, "docs", "retrospectives", `${date}.md`);
623
+ fs2.mkdirSync(path2.dirname(outPath), { recursive: true });
624
+ fs2.writeFileSync(outPath, markdown, "utf-8");
625
+ const relPath = path2.relative(cwd, outPath).replaceAll("\\", "/");
626
+ logger.info(`Catalog retrospective written to ${relPath}`);
627
+ logger.info(
628
+ `${report.totalRecords} records \xB7 ${report.distinctSkills} skills \xB7 window ${report.windowDays}d`
629
+ );
630
+ });
631
+ }
587
632
  function createAdoptionCommand() {
588
633
  const adoption = new Command2("adoption").description("View skill adoption telemetry").option("--json", "Output in JSON format");
589
634
  registerSkillsCommand(adoption);
590
635
  registerRecentCommand(adoption);
591
636
  registerSkillCommand(adoption);
637
+ registerRetrospectiveCommand(adoption);
592
638
  return adoption;
593
639
  }
594
640
 
@@ -599,7 +645,7 @@ import { Command as Command5 } from "commander";
599
645
  init_dist3();
600
646
  init_dist3();
601
647
  import { Command as Command3 } from "commander";
602
- import * as path2 from "path";
648
+ import * as path3 from "path";
603
649
  import * as childProcess from "child_process";
604
650
  async function runAgentTask(task, options) {
605
651
  const configResult = resolveConfig(options.configPath);
@@ -671,7 +717,7 @@ function createCommandExecutor() {
671
717
  }
672
718
  async function runPersonaMode(opts, quiet) {
673
719
  const personasDir = resolvePersonasDir();
674
- const filePath = path2.join(personasDir, `${opts.persona}.yaml`);
720
+ const filePath = path3.join(personasDir, `${opts.persona}.yaml`);
675
721
  const personaResult = loadPersona(filePath);
676
722
  if (!personaResult.ok) {
677
723
  logger.error(personaResult.error.message);
@@ -982,8 +1028,8 @@ function outcomeIcon(kind) {
982
1028
  // src/commands/audit-protected.ts
983
1029
  init_dist3();
984
1030
  import { Command as Command7 } from "commander";
985
- import * as path3 from "path";
986
- import * as fs2 from "fs";
1031
+ import * as path4 from "path";
1032
+ import * as fs3 from "fs";
987
1033
  import { glob } from "glob";
988
1034
  async function runAuditProtected(options) {
989
1035
  const cwd = options.cwd ?? process.cwd();
@@ -992,7 +1038,7 @@ async function runAuditProtected(options) {
992
1038
  return Err(configResult.error);
993
1039
  }
994
1040
  const config = configResult.value;
995
- const rootDir = path3.resolve(cwd, config.rootDir);
1041
+ const rootDir = path4.resolve(cwd, config.rootDir);
996
1042
  const excludePatterns = config.entropy?.excludePatterns ?? ["**/node_modules/**", "**/*.test.ts"];
997
1043
  let files;
998
1044
  try {
@@ -1006,10 +1052,10 @@ async function runAuditProtected(options) {
1006
1052
  const allRegions = [];
1007
1053
  const allIssues = [];
1008
1054
  for (const relativePath of files) {
1009
- const absolutePath = path3.resolve(rootDir, relativePath);
1055
+ const absolutePath = path4.resolve(rootDir, relativePath);
1010
1056
  let content;
1011
1057
  try {
1012
- content = fs2.readFileSync(absolutePath, "utf-8");
1058
+ content = fs3.readFileSync(absolutePath, "utf-8");
1013
1059
  } catch {
1014
1060
  continue;
1015
1061
  }
@@ -1079,41 +1125,41 @@ function createAuditProtectedCommand() {
1079
1125
 
1080
1126
  // src/commands/backfill-skill-provenance.ts
1081
1127
  import { Command as Command8 } from "commander";
1082
- import * as fs3 from "fs";
1083
- import * as path4 from "path";
1128
+ import * as fs4 from "fs";
1129
+ import * as path5 from "path";
1084
1130
  import { parse as parseYaml, stringify as stringifyYaml } from "yaml";
1085
1131
  function listSkillYamlFiles(skillsRoot) {
1086
1132
  const out = [];
1087
1133
  let hosts;
1088
1134
  try {
1089
- hosts = fs3.readdirSync(skillsRoot);
1135
+ hosts = fs4.readdirSync(skillsRoot);
1090
1136
  } catch {
1091
1137
  return out;
1092
1138
  }
1093
1139
  for (const host of hosts) {
1094
- const hostDir = path4.join(skillsRoot, host);
1140
+ const hostDir = path5.join(skillsRoot, host);
1095
1141
  let stat;
1096
1142
  try {
1097
- stat = fs3.statSync(hostDir);
1143
+ stat = fs4.statSync(hostDir);
1098
1144
  } catch {
1099
1145
  continue;
1100
1146
  }
1101
1147
  if (!stat.isDirectory()) continue;
1102
1148
  let skills;
1103
1149
  try {
1104
- skills = fs3.readdirSync(hostDir);
1150
+ skills = fs4.readdirSync(hostDir);
1105
1151
  } catch {
1106
1152
  continue;
1107
1153
  }
1108
1154
  for (const skill of skills) {
1109
- const skillDir = path4.join(hostDir, skill);
1155
+ const skillDir = path5.join(hostDir, skill);
1110
1156
  try {
1111
- if (!fs3.statSync(skillDir).isDirectory()) continue;
1157
+ if (!fs4.statSync(skillDir).isDirectory()) continue;
1112
1158
  } catch {
1113
1159
  continue;
1114
1160
  }
1115
- const yamlFile = path4.join(skillDir, "skill.yaml");
1116
- if (fs3.existsSync(yamlFile)) out.push(yamlFile);
1161
+ const yamlFile = path5.join(skillDir, "skill.yaml");
1162
+ if (fs4.existsSync(yamlFile)) out.push(yamlFile);
1117
1163
  }
1118
1164
  }
1119
1165
  return out;
@@ -1121,7 +1167,7 @@ function listSkillYamlFiles(skillsRoot) {
1121
1167
  function backfillFile(yamlFile) {
1122
1168
  let raw;
1123
1169
  try {
1124
- raw = fs3.readFileSync(yamlFile, "utf-8");
1170
+ raw = fs4.readFileSync(yamlFile, "utf-8");
1125
1171
  } catch (err) {
1126
1172
  return { error: err instanceof Error ? err.message : String(err) };
1127
1173
  }
@@ -1139,11 +1185,11 @@ function backfillFile(yamlFile) {
1139
1185
  return "skipped";
1140
1186
  }
1141
1187
  obj["provenance"] = "user-authored";
1142
- fs3.writeFileSync(yamlFile, stringifyYaml(obj));
1188
+ fs4.writeFileSync(yamlFile, stringifyYaml(obj));
1143
1189
  return "updated";
1144
1190
  }
1145
- function runBackfillSkillProvenance(projectRoot2) {
1146
- const skillsRoot = path4.join(projectRoot2, "agents", "skills");
1191
+ function runBackfillSkillProvenance(projectRoot3) {
1192
+ const skillsRoot = path5.join(projectRoot3, "agents", "skills");
1147
1193
  const files = listSkillYamlFiles(skillsRoot);
1148
1194
  const result = {
1149
1195
  scanned: files.length,
@@ -1179,19 +1225,19 @@ function createBackfillSkillProvenanceCommand() {
1179
1225
  // src/commands/blueprint.ts
1180
1226
  init_dist3();
1181
1227
  import { Command as Command9 } from "commander";
1182
- import * as path5 from "path";
1228
+ import * as path6 from "path";
1183
1229
  function createBlueprintCommand() {
1184
1230
  return new Command9("blueprint").description("Generate a self-contained, interactive blueprint of the codebase").argument("[path]", "Path to the project root", ".").option("-o, --output <dir>", "Output directory", "docs/blueprint").action(async (projectPath, options) => {
1185
1231
  try {
1186
- const rootDir = path5.resolve(projectPath);
1187
- const outputDir = path5.resolve(options.output);
1232
+ const rootDir = path6.resolve(projectPath);
1233
+ const outputDir = path6.resolve(options.output);
1188
1234
  logger.info(`Scanning project at ${rootDir}...`);
1189
1235
  const scanner = new ProjectScanner(rootDir);
1190
1236
  const data = await scanner.scan();
1191
1237
  logger.info(`Generating blueprint to ${outputDir}...`);
1192
1238
  const generator = new BlueprintGenerator();
1193
1239
  await generator.generate(data, { outputDir });
1194
- logger.success(`Blueprint generated successfully at ${path5.join(outputDir, "index.html")}`);
1240
+ logger.success(`Blueprint generated successfully at ${path6.join(outputDir, "index.html")}`);
1195
1241
  } catch (error) {
1196
1242
  logger.error(
1197
1243
  `Failed to generate blueprint: ${error instanceof Error ? error.message : String(error)}`
@@ -1373,7 +1419,7 @@ function createCheckArchCommand() {
1373
1419
  init_dist3();
1374
1420
  init_dist3();
1375
1421
  import { Command as Command11 } from "commander";
1376
- import * as path6 from "path";
1422
+ import * as path7 from "path";
1377
1423
  async function runCheckDeps(options) {
1378
1424
  const cwd = options.cwd ?? process.cwd();
1379
1425
  const configResult = resolveConfig(options.configPath);
@@ -1389,7 +1435,7 @@ async function runCheckDeps(options) {
1389
1435
  if (!config.layers || config.layers.length === 0) {
1390
1436
  return Ok(result);
1391
1437
  }
1392
- const rootDir = path6.resolve(cwd, config.rootDir);
1438
+ const rootDir = path7.resolve(cwd, config.rootDir);
1393
1439
  const parser = new TypeScriptParser();
1394
1440
  const layers = config.layers.map((l) => defineLayer(l.name, [l.pattern], l.allowedDependencies));
1395
1441
  const layerConfig = {
@@ -1703,9 +1749,9 @@ ${name} (${count} finding${count === 1 ? "" : "s"})`);
1703
1749
  }
1704
1750
  function printAnatomyFindings(findings, verbose) {
1705
1751
  const byFile = groupByFile(findings, (f) => f.file);
1706
- for (const [file, fs50] of byFile) {
1752
+ for (const [file, fs51] of byFile) {
1707
1753
  console.log(` ${file}`);
1708
- for (const f of fs50) {
1754
+ for (const f of fs51) {
1709
1755
  const line = f.line !== null && f.line !== void 0 ? `:${f.line}` : "";
1710
1756
  console.log(` ${f.code} [${f.severity}] line${line}: ${f.message}`);
1711
1757
  if (verbose) {
@@ -1716,9 +1762,9 @@ function printAnatomyFindings(findings, verbose) {
1716
1762
  }
1717
1763
  function printCraftFindings(findings, verbose) {
1718
1764
  const byFile = groupByFile(findings, (f) => f.target.file);
1719
- for (const [file, fs50] of byFile) {
1765
+ for (const [file, fs51] of byFile) {
1720
1766
  console.log(` ${file}`);
1721
- for (const f of fs50) {
1767
+ for (const f of fs51) {
1722
1768
  const line = f.target.line !== void 0 ? `:${f.target.line}` : "";
1723
1769
  const sev = craftTierToSeverity(f.tier);
1724
1770
  console.log(
@@ -1732,9 +1778,9 @@ function printCraftFindings(findings, verbose) {
1732
1778
  }
1733
1779
  function printDriftFindings(findings, verbose) {
1734
1780
  const byFile = groupByFile(findings, (f) => f.file);
1735
- for (const [file, fs50] of byFile) {
1781
+ for (const [file, fs51] of byFile) {
1736
1782
  console.log(` ${file}`);
1737
- for (const f of fs50) {
1783
+ for (const f of fs51) {
1738
1784
  const line = f.line !== null && f.line !== void 0 ? `:${f.line}` : "";
1739
1785
  console.log(` ${f.code} [${f.severity}] line${line}: ${f.message}`);
1740
1786
  if (verbose) {
@@ -1745,9 +1791,9 @@ function printDriftFindings(findings, verbose) {
1745
1791
  }
1746
1792
  function printBrandFindings(findings, verbose) {
1747
1793
  const byFile = groupByFile(findings, (f) => f.file);
1748
- for (const [file, fs50] of byFile) {
1794
+ for (const [file, fs51] of byFile) {
1749
1795
  console.log(` ${file}`);
1750
- for (const f of fs50) {
1796
+ for (const f of fs51) {
1751
1797
  const line = f.line !== null && f.line !== void 0 ? `:${f.line}` : "";
1752
1798
  console.log(` ${f.code} [${f.severity}] line${line}: ${f.message}`);
1753
1799
  if (verbose) {
@@ -1810,7 +1856,7 @@ function createCheckDesignCommand() {
1810
1856
  init_dist3();
1811
1857
  init_dist3();
1812
1858
  import { Command as Command13 } from "commander";
1813
- import * as path7 from "path";
1859
+ import * as path8 from "path";
1814
1860
  async function runCheckDocs(options) {
1815
1861
  const cwd = options.cwd ?? process.cwd();
1816
1862
  const minCoverage = options.minCoverage ?? 80;
@@ -1819,8 +1865,8 @@ async function runCheckDocs(options) {
1819
1865
  return configResult;
1820
1866
  }
1821
1867
  const config = configResult.value;
1822
- const docsDir = path7.resolve(cwd, config.docsDir);
1823
- const sourceDir = path7.resolve(cwd, config.rootDir);
1868
+ const docsDir = path8.resolve(cwd, config.docsDir);
1869
+ const sourceDir = path8.resolve(cwd, config.rootDir);
1824
1870
  const coverageResult = await checkDocCoverage("project", {
1825
1871
  docsDir,
1826
1872
  sourceDir,
@@ -1919,12 +1965,12 @@ function createCheckDocsCommand() {
1919
1965
  // src/commands/check-harness-strength.ts
1920
1966
  init_dist3();
1921
1967
  import { Command as Command14 } from "commander";
1922
- import * as path8 from "path";
1968
+ import * as path9 from "path";
1923
1969
  var SEVERITY_RANK = { error: 3, warning: 2, info: 1 };
1924
1970
  function runCheckHarnessStrength(cwd, options) {
1925
- const projectRoot2 = path8.resolve(cwd);
1971
+ const projectRoot3 = path9.resolve(cwd);
1926
1972
  const auditor = new HarnessStrengthAuditor();
1927
- const result = auditor.audit(projectRoot2, options.mode ? { mode: options.mode } : {});
1973
+ const result = auditor.audit(projectRoot3, options.mode ? { mode: options.mode } : {});
1928
1974
  if (!result.ok) return result;
1929
1975
  const audit = result.value;
1930
1976
  const threshold = options.severity ?? "warning";
@@ -1995,7 +2041,7 @@ function createCheckHarnessStrengthCommand() {
1995
2041
  // src/commands/check-perf.ts
1996
2042
  init_dist3();
1997
2043
  import { Command as Command15 } from "commander";
1998
- import * as path9 from "path";
2044
+ import * as path10 from "path";
1999
2045
  function resolveConfiguredEntryPoints(configPath) {
2000
2046
  const configResult = resolveConfig(configPath);
2001
2047
  if (!configResult.ok) return void 0;
@@ -2012,7 +2058,7 @@ async function runCheckPerf(cwd, options) {
2012
2058
  const runAll2 = !options.structural && !options.size && !options.coupling;
2013
2059
  const entryPoints = resolveConfiguredEntryPoints(options.configPath);
2014
2060
  const analyzer = new EntropyAnalyzer({
2015
- rootDir: path9.resolve(cwd),
2061
+ rootDir: path10.resolve(cwd),
2016
2062
  ...entryPoints && { entryPoints },
2017
2063
  analyze: {
2018
2064
  complexity: runAll2 || !!options.structural,
@@ -2134,7 +2180,7 @@ function createCheckPerfCommand() {
2134
2180
  // src/commands/check-security.ts
2135
2181
  init_dist3();
2136
2182
  import { Command as Command16 } from "commander";
2137
- import * as path10 from "path";
2183
+ import * as path11 from "path";
2138
2184
  import { execSync as execSync3 } from "child_process";
2139
2185
  var SEVERITY_RANK2 = {
2140
2186
  error: 3,
@@ -2147,19 +2193,19 @@ function getChangedFiles(cwd) {
2147
2193
  cwd,
2148
2194
  encoding: "utf-8"
2149
2195
  });
2150
- return output.trim().split("\n").filter((f) => f.length > 0).map((f) => path10.resolve(cwd, f));
2196
+ return output.trim().split("\n").filter((f) => f.length > 0).map((f) => path11.resolve(cwd, f));
2151
2197
  } catch {
2152
2198
  return [];
2153
2199
  }
2154
2200
  }
2155
2201
  async function runCheckSecurity(cwd, options) {
2156
- const projectRoot2 = path10.resolve(cwd);
2202
+ const projectRoot3 = path11.resolve(cwd);
2157
2203
  let configData = {};
2158
2204
  try {
2159
- const fs50 = await import("fs");
2160
- const configPath = path10.join(projectRoot2, "harness.config.json");
2161
- if (fs50.existsSync(configPath)) {
2162
- const raw = fs50.readFileSync(configPath, "utf-8");
2205
+ const fs51 = await import("fs");
2206
+ const configPath = path11.join(projectRoot3, "harness.config.json");
2207
+ if (fs51.existsSync(configPath)) {
2208
+ const raw = fs51.readFileSync(configPath, "utf-8");
2163
2209
  const parsed = JSON.parse(raw);
2164
2210
  configData = parsed.security ?? {};
2165
2211
  }
@@ -2167,10 +2213,10 @@ async function runCheckSecurity(cwd, options) {
2167
2213
  }
2168
2214
  const securityConfig = parseSecurityConfig(configData);
2169
2215
  const scanner = new SecurityScanner(securityConfig);
2170
- scanner.configureForProject(projectRoot2);
2216
+ scanner.configureForProject(projectRoot3);
2171
2217
  let filesToScan;
2172
2218
  if (options.changedOnly) {
2173
- filesToScan = getChangedFiles(projectRoot2);
2219
+ filesToScan = getChangedFiles(projectRoot3);
2174
2220
  } else {
2175
2221
  const { glob: glob2 } = await import("glob");
2176
2222
  const pattern = "**/*.{ts,tsx,js,jsx,go,py,java,rb}";
@@ -2180,15 +2226,15 @@ async function runCheckSecurity(cwd, options) {
2180
2226
  "**/*.test.ts",
2181
2227
  "**/fixtures/**"
2182
2228
  ];
2183
- filesToScan = await glob2(pattern, { cwd: projectRoot2, absolute: true, ignore });
2229
+ filesToScan = await glob2(pattern, { cwd: projectRoot3, absolute: true, ignore });
2184
2230
  }
2185
2231
  const result = await scanner.scanFiles(filesToScan);
2186
2232
  try {
2187
2233
  const commitHash = execSync3("git rev-parse HEAD", {
2188
- cwd: projectRoot2,
2234
+ cwd: projectRoot3,
2189
2235
  encoding: "utf-8"
2190
2236
  }).trim();
2191
- const timelineManager = new SecurityTimelineManager(projectRoot2);
2237
+ const timelineManager = new SecurityTimelineManager(projectRoot3);
2192
2238
  timelineManager.capture(result, commitHash);
2193
2239
  timelineManager.updateLifecycles(result.findings, commitHash);
2194
2240
  } catch {
@@ -2353,8 +2399,8 @@ function createCheckCommand() {
2353
2399
  // src/commands/ci/init.ts
2354
2400
  init_dist3();
2355
2401
  import { Command as Command18 } from "commander";
2356
- import * as fs4 from "fs";
2357
- import * as path11 from "path";
2402
+ import * as fs5 from "fs";
2403
+ import * as path12 from "path";
2358
2404
  var ALL_CHECKS = [
2359
2405
  "validate",
2360
2406
  "deps",
@@ -2525,17 +2571,17 @@ function generateCIConfig(options) {
2525
2571
  });
2526
2572
  }
2527
2573
  function detectPlatform() {
2528
- if (fs4.existsSync(".github")) return "github";
2529
- if (fs4.existsSync(".gitlab-ci.yml")) return "gitlab";
2574
+ if (fs5.existsSync(".github")) return "github";
2575
+ if (fs5.existsSync(".gitlab-ci.yml")) return "gitlab";
2530
2576
  return null;
2531
2577
  }
2532
2578
  function writeGeneratedConfig(filename, content, platform) {
2533
- const targetPath = path11.resolve(filename);
2534
- const dir = path11.dirname(targetPath);
2535
- fs4.mkdirSync(dir, { recursive: true });
2536
- fs4.writeFileSync(targetPath, content);
2579
+ const targetPath = path12.resolve(filename);
2580
+ const dir = path12.dirname(targetPath);
2581
+ fs5.mkdirSync(dir, { recursive: true });
2582
+ fs5.writeFileSync(targetPath, content);
2537
2583
  if (platform === "generic" && process.platform !== "win32") {
2538
- fs4.chmodSync(targetPath, "755");
2584
+ fs5.chmodSync(targetPath, "755");
2539
2585
  }
2540
2586
  }
2541
2587
  async function runInitAction(opts, globalOpts) {
@@ -2567,10 +2613,10 @@ function createInitCommand() {
2567
2613
  // src/commands/ci/notify.ts
2568
2614
  init_dist3();
2569
2615
  import { Command as Command19 } from "commander";
2570
- import * as fs5 from "fs";
2616
+ import * as fs6 from "fs";
2571
2617
  function loadReport(reportPath) {
2572
2618
  try {
2573
- const raw = fs5.readFileSync(reportPath, "utf-8");
2619
+ const raw = fs6.readFileSync(reportPath, "utf-8");
2574
2620
  return JSON.parse(raw);
2575
2621
  } catch {
2576
2622
  return null;
@@ -2680,7 +2726,7 @@ function createCICommand() {
2680
2726
  // src/commands/cleanup.ts
2681
2727
  init_dist3();
2682
2728
  import { Command as Command21 } from "commander";
2683
- import * as path12 from "path";
2729
+ import * as path13 from "path";
2684
2730
  async function runCleanup(options) {
2685
2731
  const cwd = options.cwd ?? process.cwd();
2686
2732
  const type = options.type ?? "all";
@@ -2695,14 +2741,14 @@ async function runCleanup(options) {
2695
2741
  patternViolations: [],
2696
2742
  totalIssues: 0
2697
2743
  };
2698
- const rootDir = path12.resolve(cwd, config.rootDir);
2699
- const docsDir = path12.resolve(cwd, config.docsDir);
2744
+ const rootDir = path13.resolve(cwd, config.rootDir);
2745
+ const docsDir = path13.resolve(cwd, config.docsDir);
2700
2746
  const driftEnabled = type === "all" || type === "drift";
2701
2747
  const driftConfig = config.entropy?.drift;
2702
2748
  const entropyConfig = {
2703
2749
  rootDir,
2704
2750
  ...config.entropy?.entryPoints && { entryPoints: config.entropy.entryPoints },
2705
- docPaths: [path12.join(docsDir, "**/*.md")],
2751
+ docPaths: [path13.join(docsDir, "**/*.md")],
2706
2752
  analyze: {
2707
2753
  drift: driftEnabled ? driftConfig ?? true : false,
2708
2754
  deadCode: type === "all" || type === "dead-code",
@@ -2802,8 +2848,8 @@ function createCleanupCommand() {
2802
2848
  // src/commands/cleanup-sessions.ts
2803
2849
  init_dist3();
2804
2850
  import { Command as Command22 } from "commander";
2805
- import * as fs6 from "fs";
2806
- import * as path13 from "path";
2851
+ import * as fs7 from "fs";
2852
+ import * as path14 from "path";
2807
2853
  var STALE_TTL_MS = 24 * 60 * 60 * 1e3;
2808
2854
  var ONE_HOUR_MS = 60 * 60 * 1e3;
2809
2855
  var ONE_DAY_MS = 24 * ONE_HOUR_MS;
@@ -2818,13 +2864,13 @@ var CLEANUP_TARGETS = [
2818
2864
  function getMostRecentMtime(dirPath) {
2819
2865
  let latest = 0;
2820
2866
  try {
2821
- const entries = fs6.readdirSync(dirPath, { withFileTypes: true });
2867
+ const entries = fs7.readdirSync(dirPath, { withFileTypes: true });
2822
2868
  for (const entry of entries) {
2823
- const fullPath = path13.join(dirPath, entry.name);
2824
- const stat = fs6.statSync(fullPath);
2869
+ const fullPath = path14.join(dirPath, entry.name);
2870
+ const stat = fs7.statSync(fullPath);
2825
2871
  if (stat.mtimeMs > latest) latest = stat.mtimeMs;
2826
2872
  }
2827
- const dirStat = fs6.statSync(dirPath);
2873
+ const dirStat = fs7.statSync(dirPath);
2828
2874
  if (dirStat.mtimeMs > latest) latest = dirStat.mtimeMs;
2829
2875
  } catch {
2830
2876
  }
@@ -2833,14 +2879,14 @@ function getMostRecentMtime(dirPath) {
2833
2879
  async function runCleanupSessions(options) {
2834
2880
  const cwd = options.cwd ?? process.cwd();
2835
2881
  const dryRun = options.dryRun ?? false;
2836
- const sessionsDir = path13.join(cwd, ".harness", "sessions");
2882
+ const sessionsDir = path14.join(cwd, ".harness", "sessions");
2837
2883
  const result = { removed: [], kept: [] };
2838
- if (!fs6.existsSync(sessionsDir)) {
2884
+ if (!fs7.existsSync(sessionsDir)) {
2839
2885
  return Ok(result);
2840
2886
  }
2841
2887
  let entries;
2842
2888
  try {
2843
- entries = fs6.readdirSync(sessionsDir, { withFileTypes: true });
2889
+ entries = fs7.readdirSync(sessionsDir, { withFileTypes: true });
2844
2890
  } catch (err) {
2845
2891
  return Err(
2846
2892
  new CLIError(
@@ -2852,14 +2898,14 @@ async function runCleanupSessions(options) {
2852
2898
  const now = Date.now();
2853
2899
  for (const entry of entries) {
2854
2900
  if (!entry.isDirectory()) continue;
2855
- const sessionPath = path13.join(sessionsDir, entry.name);
2901
+ const sessionPath = path14.join(sessionsDir, entry.name);
2856
2902
  const mostRecent = getMostRecentMtime(sessionPath);
2857
2903
  const ageMs = now - mostRecent;
2858
2904
  if (ageMs > STALE_TTL_MS) {
2859
2905
  result.removed.push(entry.name);
2860
2906
  if (!dryRun) {
2861
2907
  try {
2862
- fs6.rmSync(sessionPath, { recursive: true, force: true });
2908
+ fs7.rmSync(sessionPath, { recursive: true, force: true });
2863
2909
  } catch (err) {
2864
2910
  return Err(
2865
2911
  new CLIError(
@@ -2916,7 +2962,7 @@ async function runCleanupAll(opts) {
2916
2962
  const results = [];
2917
2963
  for (const target of targets) {
2918
2964
  const ttlMs = (ttlOverrides[target.name] ?? 0) > 0 ? ttlOverrides[target.name] * ONE_HOUR_MS : target.defaultTtlMs;
2919
- const dir = path13.join(cwd, ".harness", target.relativeDir);
2965
+ const dir = path14.join(cwd, ".harness", target.relativeDir);
2920
2966
  const sweepResult = await sweepDirectory(dir, ttlMs, dryRun);
2921
2967
  if (!sweepResult.ok) return Err(sweepResult.error);
2922
2968
  results.push({ target: target.name, ...sweepResult.value });
@@ -2926,10 +2972,10 @@ async function runCleanupAll(opts) {
2926
2972
  async function sweepDirectory(dir, ttlMs, dryRun) {
2927
2973
  const removed = [];
2928
2974
  const kept = [];
2929
- if (!fs6.existsSync(dir)) return Ok({ removed, kept });
2975
+ if (!fs7.existsSync(dir)) return Ok({ removed, kept });
2930
2976
  let entries;
2931
2977
  try {
2932
- entries = fs6.readdirSync(dir, { withFileTypes: true });
2978
+ entries = fs7.readdirSync(dir, { withFileTypes: true });
2933
2979
  } catch (err) {
2934
2980
  return Err(
2935
2981
  new CLIError(
@@ -2940,13 +2986,13 @@ async function sweepDirectory(dir, ttlMs, dryRun) {
2940
2986
  }
2941
2987
  const now = Date.now();
2942
2988
  for (const entry of entries) {
2943
- const entryPath = path13.join(dir, entry.name);
2989
+ const entryPath = path14.join(dir, entry.name);
2944
2990
  const ageMs = now - mtimeOf(entryPath);
2945
2991
  if (ageMs > ttlMs) {
2946
2992
  removed.push(entry.name);
2947
2993
  if (!dryRun) {
2948
2994
  try {
2949
- fs6.rmSync(entryPath, { recursive: true, force: true });
2995
+ fs7.rmSync(entryPath, { recursive: true, force: true });
2950
2996
  } catch (err) {
2951
2997
  return Err(
2952
2998
  new CLIError(
@@ -2964,7 +3010,7 @@ async function sweepDirectory(dir, ttlMs, dryRun) {
2964
3010
  }
2965
3011
  function mtimeOf(target) {
2966
3012
  try {
2967
- const stat = fs6.statSync(target);
3013
+ const stat = fs7.statSync(target);
2968
3014
  if (stat.isDirectory()) return getMostRecentMtime(target);
2969
3015
  return stat.mtimeMs;
2970
3016
  } catch {
@@ -3004,7 +3050,7 @@ function createCleanupSessionsCommand() {
3004
3050
  "Comma-separated target names (mutually-exclusive with --exclude/--all)"
3005
3051
  ).option("--exclude <list>", "Comma-separated target names to skip").action(async (opts, cmd) => {
3006
3052
  const globalOpts = cmd.optsWithGlobals();
3007
- const cwd = path13.resolve(opts.path);
3053
+ const cwd = path14.resolve(opts.path);
3008
3054
  const asJson = Boolean(globalOpts.json);
3009
3055
  if (opts.all || opts.include || opts.exclude) {
3010
3056
  await runExtendedSweep(cwd, opts, asJson);
@@ -3050,8 +3096,8 @@ import { Command as Command24 } from "commander";
3050
3096
 
3051
3097
  // src/commands/compound/scan-candidates.ts
3052
3098
  init_dist3();
3053
- import { mkdirSync as mkdirSync3, writeFileSync as writeFileSync4 } from "fs";
3054
- import { dirname as dirname2, join as join8, resolve as resolve12 } from "path";
3099
+ import { mkdirSync as mkdirSync4, writeFileSync as writeFileSync5 } from "fs";
3100
+ import { dirname as dirname3, join as join9, resolve as resolve13 } from "path";
3055
3101
  import { Command as Command23 } from "commander";
3056
3102
  var HOTSPOT_THRESHOLD = 7;
3057
3103
  var DEFAULT_LOOKBACK = "7d";
@@ -3078,9 +3124,9 @@ async function runCompoundScanCandidatesCommand(opts) {
3078
3124
  isoWeek: week,
3079
3125
  lookback
3080
3126
  });
3081
- const outputPath = opts.outputPath ?? join8(cwd, "docs/solutions/.candidates", `${formatIsoWeek(week)}.md`);
3082
- mkdirSync3(dirname2(outputPath), { recursive: true });
3083
- writeFileSync4(outputPath, report);
3127
+ const outputPath = opts.outputPath ?? join9(cwd, "docs/solutions/.candidates", `${formatIsoWeek(week)}.md`);
3128
+ mkdirSync4(dirname3(outputPath), { recursive: true });
3129
+ writeFileSync5(outputPath, report);
3084
3130
  const candidatesFound = undocumented.length + hotspots.length;
3085
3131
  const status = {
3086
3132
  status: candidatesFound === 0 ? "no-issues" : "success",
@@ -3120,9 +3166,9 @@ function createScanCandidatesCommand() {
3120
3166
  const nonInteractive = options.nonInteractive === true || !process.stdout.isTTY;
3121
3167
  const status = await runCompoundScanCandidatesCommand({
3122
3168
  lookback: options.lookback,
3123
- configPath: resolve12(process.cwd(), options.config),
3124
- outputPath: options.outputPath ? resolve12(process.cwd(), options.outputPath) : void 0,
3125
- solutionsDir: resolve12(process.cwd(), options.solutionsDir),
3169
+ configPath: resolve13(process.cwd(), options.config),
3170
+ outputPath: options.outputPath ? resolve13(process.cwd(), options.outputPath) : void 0,
3171
+ solutionsDir: resolve13(process.cwd(), options.solutionsDir),
3126
3172
  nonInteractive
3127
3173
  });
3128
3174
  if (status.status === "failure") process.exitCode = 1;
@@ -3192,10 +3238,10 @@ function printResult2(result, mode, _formatter) {
3192
3238
  list.push(f);
3193
3239
  bySurface.set(f.target.surface, list);
3194
3240
  }
3195
- for (const [surface, fs50] of bySurface) {
3241
+ for (const [surface, fs51] of bySurface) {
3196
3242
  console.log(`
3197
3243
  [${surface}]`);
3198
- for (const f of fs50) {
3244
+ for (const f of fs51) {
3199
3245
  const line = f.target.line !== void 0 ? `:${f.target.line}` : "";
3200
3246
  console.log(` ${f.code} [${f.tier}/${f.impact}/${f.confidence}] ${f.target.file}${line}`);
3201
3247
  console.log(` "${truncate(f.target.snippet, 80)}"`);
@@ -3222,7 +3268,7 @@ function truncate(s, n) {
3222
3268
 
3223
3269
  // src/commands/cross-check.ts
3224
3270
  import { Command as Command26 } from "commander";
3225
- import * as path14 from "path";
3271
+ import * as path15 from "path";
3226
3272
  import chalk from "chalk";
3227
3273
  function resolveOutputMode3(options) {
3228
3274
  if (options.json) return OutputMode.JSON;
@@ -3233,8 +3279,8 @@ function resolveOutputMode3(options) {
3233
3279
  async function runCrossCheckCommand(options) {
3234
3280
  const mode = resolveOutputMode3(options);
3235
3281
  const projectPath = process.cwd();
3236
- const specsDir = path14.resolve(projectPath, options.specsDir ?? "docs/specs");
3237
- const plansDir = path14.resolve(projectPath, options.plansDir ?? "docs/plans");
3282
+ const specsDir = path15.resolve(projectPath, options.specsDir ?? "docs/specs");
3283
+ const plansDir = path15.resolve(projectPath, options.plansDir ?? "docs/plans");
3238
3284
  const result = await runCrossCheck({ projectPath, specsDir, plansDir });
3239
3285
  if (!result.ok) {
3240
3286
  emitCrossCheckError(result.error.message, mode);
@@ -3287,13 +3333,13 @@ function createCrossCheckCommand() {
3287
3333
  // src/commands/dashboard.ts
3288
3334
  import { Command as Command27 } from "commander";
3289
3335
  import { spawn } from "child_process";
3290
- import { existsSync as existsSync5 } from "fs";
3336
+ import { existsSync as existsSync6 } from "fs";
3291
3337
  import { createRequire } from "module";
3292
- import { dirname as dirname3, join as join9, resolve as resolve14 } from "path";
3338
+ import { dirname as dirname4, join as join10, resolve as resolve15 } from "path";
3293
3339
  import { setTimeout } from "timers";
3294
3340
  import { fileURLToPath } from "url";
3295
3341
  var __filename = fileURLToPath(import.meta.url);
3296
- var __dirname = dirname3(__filename);
3342
+ var __dirname = dirname4(__filename);
3297
3343
  var require2 = createRequire(import.meta.url);
3298
3344
  var DEFAULT_CLIENT_PORT = 3700;
3299
3345
  var DEFAULT_API_PORT = 3701;
@@ -3304,22 +3350,22 @@ function openBrowser(url) {
3304
3350
  function resolveServerScript() {
3305
3351
  try {
3306
3352
  const pkgPath = require2.resolve("@harness-engineering/dashboard/package.json");
3307
- const pkgDir = dirname3(pkgPath);
3308
- const built2 = join9(pkgDir, "dist", "server", "serve.js");
3309
- if (existsSync5(built2)) return { script: built2, dev: false };
3310
- const dev2 = join9(pkgDir, "src", "server", "serve.ts");
3311
- if (existsSync5(dev2)) return { script: dev2, dev: true };
3353
+ const pkgDir = dirname4(pkgPath);
3354
+ const built2 = join10(pkgDir, "dist", "server", "serve.js");
3355
+ if (existsSync6(built2)) return { script: built2, dev: false };
3356
+ const dev2 = join10(pkgDir, "src", "server", "serve.ts");
3357
+ if (existsSync6(dev2)) return { script: dev2, dev: true };
3312
3358
  } catch {
3313
3359
  }
3314
3360
  const built = [
3315
- join9(__dirname, "..", "..", "..", "dashboard", "dist", "server", "serve.js"),
3316
- join9(__dirname, "..", "..", "..", "..", "packages", "dashboard", "dist", "server", "serve.js")
3317
- ].find((p) => existsSync5(p));
3361
+ join10(__dirname, "..", "..", "..", "dashboard", "dist", "server", "serve.js"),
3362
+ join10(__dirname, "..", "..", "..", "..", "packages", "dashboard", "dist", "server", "serve.js")
3363
+ ].find((p) => existsSync6(p));
3318
3364
  if (built) return { script: built, dev: false };
3319
3365
  const dev = [
3320
- join9(__dirname, "..", "..", "..", "dashboard", "src", "server", "serve.ts"),
3321
- join9(__dirname, "..", "..", "..", "..", "packages", "dashboard", "src", "server", "serve.ts")
3322
- ].find((p) => existsSync5(p));
3366
+ join10(__dirname, "..", "..", "..", "dashboard", "src", "server", "serve.ts"),
3367
+ join10(__dirname, "..", "..", "..", "..", "packages", "dashboard", "src", "server", "serve.ts")
3368
+ ].find((p) => existsSync6(p));
3323
3369
  return dev ? { script: dev, dev: true } : null;
3324
3370
  }
3325
3371
  function spawnDashboardServer(server, env) {
@@ -3353,7 +3399,7 @@ function buildDashboardEnv(opts, clientPort, apiPort, projectPath) {
3353
3399
  function runDashboard(opts) {
3354
3400
  const clientPort = Number(opts.port ?? DEFAULT_CLIENT_PORT);
3355
3401
  const apiPort = Number(opts.apiPort ?? DEFAULT_API_PORT);
3356
- const projectPath = resolve14(opts.cwd ?? process.cwd());
3402
+ const projectPath = resolve15(opts.cwd ?? process.cwd());
3357
3403
  const url = `http://localhost:${apiPort}`;
3358
3404
  const server = resolveServerScript();
3359
3405
  if (!server) {
@@ -3462,9 +3508,9 @@ function verdictBadge(verdict) {
3462
3508
 
3463
3509
  // src/commands/doctor.ts
3464
3510
  import { Command as Command29 } from "commander";
3465
- import * as fs8 from "fs";
3511
+ import * as fs9 from "fs";
3466
3512
  import * as os from "os";
3467
- import * as path16 from "path";
3513
+ import * as path17 from "path";
3468
3514
  import chalk2 from "chalk";
3469
3515
 
3470
3516
  // src/utils/node-version.ts
@@ -3547,24 +3593,24 @@ var INTEGRATION_REGISTRY = [
3547
3593
  ];
3548
3594
 
3549
3595
  // src/integrations/config.ts
3550
- import * as fs7 from "fs";
3551
- import * as path15 from "path";
3596
+ import * as fs8 from "fs";
3597
+ import * as path16 from "path";
3552
3598
  function readJsonSafe(filePath) {
3553
- if (!fs7.existsSync(filePath)) return null;
3599
+ if (!fs8.existsSync(filePath)) return null;
3554
3600
  try {
3555
- return JSON.parse(fs7.readFileSync(filePath, "utf-8"));
3601
+ return JSON.parse(fs8.readFileSync(filePath, "utf-8"));
3556
3602
  } catch {
3557
3603
  return null;
3558
3604
  }
3559
3605
  }
3560
3606
  function writeJson(filePath, data) {
3561
- const dir = path15.dirname(filePath);
3562
- if (!fs7.existsSync(dir)) {
3563
- fs7.mkdirSync(dir, { recursive: true });
3607
+ const dir = path16.dirname(filePath);
3608
+ if (!fs8.existsSync(dir)) {
3609
+ fs8.mkdirSync(dir, { recursive: true });
3564
3610
  }
3565
3611
  const tmp = filePath + ".tmp";
3566
- fs7.writeFileSync(tmp, JSON.stringify(data, null, 2) + "\n");
3567
- fs7.renameSync(tmp, filePath);
3612
+ fs8.writeFileSync(tmp, JSON.stringify(data, null, 2) + "\n");
3613
+ fs8.renameSync(tmp, filePath);
3568
3614
  }
3569
3615
  function readMcpConfig(filePath) {
3570
3616
  const config = readJsonSafe(filePath);
@@ -3594,7 +3640,7 @@ function writeOpencodeMcpEntry(filePath, name, entry) {
3594
3640
  writeJson(filePath, config);
3595
3641
  }
3596
3642
  function removeMcpEntry(filePath, name) {
3597
- if (!fs7.existsSync(filePath)) return;
3643
+ if (!fs8.existsSync(filePath)) return;
3598
3644
  const config = readMcpConfig(filePath);
3599
3645
  delete config.mcpServers[name];
3600
3646
  writeJson(filePath, config);
@@ -3633,7 +3679,7 @@ function checkNodeVersion2() {
3633
3679
  }
3634
3680
  function countCommandFiles(dir, ext) {
3635
3681
  try {
3636
- return fs8.readdirSync(dir).filter((f) => f.endsWith(ext)).length;
3682
+ return fs9.readdirSync(dir).filter((f) => f.endsWith(ext)).length;
3637
3683
  } catch {
3638
3684
  return 0;
3639
3685
  }
@@ -3642,13 +3688,13 @@ function checkSlashCommands() {
3642
3688
  const platforms = [
3643
3689
  {
3644
3690
  name: "Claude Code",
3645
- dir: path16.join(os.homedir(), ".claude", "commands", "harness"),
3691
+ dir: path17.join(os.homedir(), ".claude", "commands", "harness"),
3646
3692
  ext: ".md",
3647
3693
  client: "claude-code"
3648
3694
  },
3649
3695
  {
3650
3696
  name: "Gemini CLI",
3651
- dir: path16.join(os.homedir(), ".gemini", "commands", "harness"),
3697
+ dir: path17.join(os.homedir(), ".gemini", "commands", "harness"),
3652
3698
  ext: ".toml",
3653
3699
  client: "gemini-cli"
3654
3700
  }
@@ -3672,7 +3718,7 @@ function checkSlashCommands() {
3672
3718
  }
3673
3719
  function checkMcpConfig(cwd) {
3674
3720
  const results = [];
3675
- const claudeConfig = readMcpConfig(path16.join(cwd, ".mcp.json"));
3721
+ const claudeConfig = readMcpConfig(path17.join(cwd, ".mcp.json"));
3676
3722
  if (claudeConfig.mcpServers?.["harness"]) {
3677
3723
  results.push({
3678
3724
  name: "mcp-claude",
@@ -3687,9 +3733,9 @@ function checkMcpConfig(cwd) {
3687
3733
  fix: "Run: harness setup-mcp --client claude"
3688
3734
  });
3689
3735
  }
3690
- const geminiDir = path16.join(cwd, ".gemini");
3691
- if (fs8.existsSync(geminiDir)) {
3692
- const geminiConfig = readMcpConfig(path16.join(geminiDir, "settings.json"));
3736
+ const geminiDir = path17.join(cwd, ".gemini");
3737
+ if (fs9.existsSync(geminiDir)) {
3738
+ const geminiConfig = readMcpConfig(path17.join(geminiDir, "settings.json"));
3693
3739
  if (geminiConfig.mcpServers?.["harness"]) {
3694
3740
  results.push({
3695
3741
  name: "mcp-gemini",
@@ -3708,12 +3754,12 @@ function checkMcpConfig(cwd) {
3708
3754
  return results;
3709
3755
  }
3710
3756
  function loadMcpPresence(cwd) {
3711
- const mcpPath = path16.join(cwd, ".mcp.json");
3712
- const geminiDir = path16.join(cwd, ".gemini");
3713
- const hasGemini = fs8.existsSync(geminiDir);
3757
+ const mcpPath = path17.join(cwd, ".mcp.json");
3758
+ const geminiDir = path17.join(cwd, ".gemini");
3759
+ const hasGemini = fs9.existsSync(geminiDir);
3714
3760
  return {
3715
3761
  mcpConfig: readMcpConfig(mcpPath),
3716
- geminiConfig: hasGemini ? readMcpConfig(path16.join(geminiDir, "settings.json")) : null,
3762
+ geminiConfig: hasGemini ? readMcpConfig(path17.join(geminiDir, "settings.json")) : null,
3717
3763
  hasGemini
3718
3764
  };
3719
3765
  }
@@ -3745,7 +3791,7 @@ function checkTier0Presence(def, presence) {
3745
3791
  function checkIntegrations(cwd) {
3746
3792
  const results = [];
3747
3793
  const presence = loadMcpPresence(cwd);
3748
- const configPath = path16.join(cwd, "harness.config.json");
3794
+ const configPath = path17.join(cwd, "harness.config.json");
3749
3795
  const integrationsConfig = readIntegrationsConfig(configPath);
3750
3796
  for (const def of INTEGRATION_REGISTRY.filter((d) => d.tier === 0)) {
3751
3797
  results.push(checkTier0Presence(def, presence));
@@ -3813,12 +3859,12 @@ function checkLivePings(env = process.env) {
3813
3859
  return results;
3814
3860
  }
3815
3861
  function listHookFiles(cwd) {
3816
- const hooksDir = path16.join(cwd, ".harness", "hooks");
3817
- if (!fs8.existsSync(hooksDir)) return [];
3862
+ const hooksDir = path17.join(cwd, ".harness", "hooks");
3863
+ if (!fs9.existsSync(hooksDir)) return [];
3818
3864
  try {
3819
- return fs8.readdirSync(hooksDir).filter((f) => !f.startsWith(".")).map((f) => ({
3820
- relativePath: path16.join(".harness", "hooks", f),
3821
- absolutePath: path16.join(hooksDir, f)
3865
+ return fs9.readdirSync(hooksDir).filter((f) => !f.startsWith(".")).map((f) => ({
3866
+ relativePath: path17.join(".harness", "hooks", f),
3867
+ absolutePath: path17.join(hooksDir, f)
3822
3868
  }));
3823
3869
  } catch {
3824
3870
  return [];
@@ -3868,7 +3914,7 @@ function validateShellHook(entry, content) {
3868
3914
  function validateHookEntry(entry) {
3869
3915
  let content;
3870
3916
  try {
3871
- content = fs8.readFileSync(entry.absolutePath, "utf-8");
3917
+ content = fs9.readFileSync(entry.absolutePath, "utf-8");
3872
3918
  } catch (err) {
3873
3919
  return {
3874
3920
  name: `hook-validity-${entry.relativePath}`,
@@ -3915,8 +3961,8 @@ var DAY_MS = 24 * 60 * 60 * 1e3;
3915
3961
  function checkBaselineFreshness(cwd, now = Date.now()) {
3916
3962
  const results = [];
3917
3963
  for (const def of BASELINE_FILES) {
3918
- const absolutePath = path16.join(cwd, def.relativePath);
3919
- if (!fs8.existsSync(absolutePath)) {
3964
+ const absolutePath = path17.join(cwd, def.relativePath);
3965
+ if (!fs9.existsSync(absolutePath)) {
3920
3966
  results.push({
3921
3967
  name: `baseline-freshness-${def.relativePath}`,
3922
3968
  status: "info",
@@ -3926,7 +3972,7 @@ function checkBaselineFreshness(cwd, now = Date.now()) {
3926
3972
  }
3927
3973
  let mtimeMs;
3928
3974
  try {
3929
- mtimeMs = fs8.statSync(absolutePath).mtimeMs;
3975
+ mtimeMs = fs9.statSync(absolutePath).mtimeMs;
3930
3976
  } catch (err) {
3931
3977
  results.push({
3932
3978
  name: `baseline-freshness-${def.relativePath}`,
@@ -3963,20 +4009,20 @@ function checkBaselineFreshness(cwd, now = Date.now()) {
3963
4009
  }
3964
4010
  var SESSIONS_SAMPLE_SIZE = 5;
3965
4011
  function listRecentSessions(cwd) {
3966
- const sessionsDir = path16.join(cwd, ".harness", "sessions");
3967
- if (!fs8.existsSync(sessionsDir)) return [];
4012
+ const sessionsDir = path17.join(cwd, ".harness", "sessions");
4013
+ if (!fs9.existsSync(sessionsDir)) return [];
3968
4014
  let entries;
3969
4015
  try {
3970
- entries = fs8.readdirSync(sessionsDir);
4016
+ entries = fs9.readdirSync(sessionsDir);
3971
4017
  } catch {
3972
4018
  return [];
3973
4019
  }
3974
4020
  const dirs = [];
3975
4021
  for (const name of entries) {
3976
4022
  if (name.startsWith(".")) continue;
3977
- const absolutePath = path16.join(sessionsDir, name);
4023
+ const absolutePath = path17.join(sessionsDir, name);
3978
4024
  try {
3979
- const stat = fs8.statSync(absolutePath);
4025
+ const stat = fs9.statSync(absolutePath);
3980
4026
  if (!stat.isDirectory()) continue;
3981
4027
  dirs.push({ name, absolutePath, mtimeMs: stat.mtimeMs });
3982
4028
  } catch {
@@ -3991,13 +4037,13 @@ function scanSessionSummaries(sessions) {
3991
4037
  let missing = 0;
3992
4038
  const corrupt = [];
3993
4039
  for (const session of sessions) {
3994
- const summaryPath = path16.join(session.absolutePath, "session-summary.json");
3995
- if (!fs8.existsSync(summaryPath)) {
4040
+ const summaryPath = path17.join(session.absolutePath, "session-summary.json");
4041
+ if (!fs9.existsSync(summaryPath)) {
3996
4042
  missing += 1;
3997
4043
  continue;
3998
4044
  }
3999
4045
  try {
4000
- JSON.parse(fs8.readFileSync(summaryPath, "utf-8"));
4046
+ JSON.parse(fs9.readFileSync(summaryPath, "utf-8"));
4001
4047
  parsed += 1;
4002
4048
  } catch {
4003
4049
  corrupt.push(session.name);
@@ -4094,7 +4140,7 @@ function createDoctorCommand() {
4094
4140
  // src/commands/fix-drift.ts
4095
4141
  init_dist3();
4096
4142
  import { Command as Command30 } from "commander";
4097
- import * as path17 from "path";
4143
+ import * as path18 from "path";
4098
4144
  async function runFixDrift(options) {
4099
4145
  const cwd = options.cwd ?? process.cwd();
4100
4146
  const dryRun = options.dryRun !== false;
@@ -4103,12 +4149,12 @@ async function runFixDrift(options) {
4103
4149
  return Err(configResult.error);
4104
4150
  }
4105
4151
  const config = configResult.value;
4106
- const rootDir = path17.resolve(cwd, config.rootDir);
4107
- const docsDir = path17.resolve(cwd, config.docsDir);
4152
+ const rootDir = path18.resolve(cwd, config.rootDir);
4153
+ const docsDir = path18.resolve(cwd, config.docsDir);
4108
4154
  const entropyConfig = {
4109
4155
  rootDir,
4110
4156
  ...config.entropy?.entryPoints && { entryPoints: config.entropy.entryPoints },
4111
- docPaths: [path17.join(docsDir, "**/*.md")],
4157
+ docPaths: [path18.join(docsDir, "**/*.md")],
4112
4158
  analyze: {
4113
4159
  drift: true,
4114
4160
  deadCode: true,
@@ -4260,10 +4306,10 @@ import { Command as Command33 } from "commander";
4260
4306
 
4261
4307
  // src/commands/gateway/token.ts
4262
4308
  import { Command as Command31 } from "commander";
4263
- import { resolve as resolve16 } from "path";
4309
+ import { resolve as resolve17 } from "path";
4264
4310
  import { TokenStore } from "@harness-engineering/orchestrator";
4265
4311
  function getStore() {
4266
- const p = process.env["HARNESS_TOKENS_PATH"] ?? resolve16(".harness", "tokens.json");
4312
+ const p = process.env["HARNESS_TOKENS_PATH"] ?? resolve17(".harness", "tokens.json");
4267
4313
  return new TokenStore(p);
4268
4314
  }
4269
4315
  async function runTokenCreate(opts) {
@@ -4311,10 +4357,10 @@ function createTokenCommand() {
4311
4357
  // src/commands/gateway/deliveries.ts
4312
4358
  import { Command as Command32 } from "commander";
4313
4359
  import { createInterface } from "readline";
4314
- import { resolve as resolve17 } from "path";
4360
+ import { resolve as resolve18 } from "path";
4315
4361
  import { WebhookQueue } from "@harness-engineering/orchestrator";
4316
4362
  function resolveQueuePath() {
4317
- return process.env["HARNESS_WEBHOOK_QUEUE_PATH"] ?? resolve17(".harness", "webhook-queue.sqlite");
4363
+ return process.env["HARNESS_WEBHOOK_QUEUE_PATH"] ?? resolve18(".harness", "webhook-queue.sqlite");
4318
4364
  }
4319
4365
  function getQueue() {
4320
4366
  return new WebhookQueue(resolveQueuePath());
@@ -4499,13 +4545,13 @@ function createGenerateCommand() {
4499
4545
  import { Command as Command37 } from "commander";
4500
4546
 
4501
4547
  // src/commands/graph/status.ts
4502
- import * as path18 from "path";
4548
+ import * as path19 from "path";
4503
4549
  async function readConnectorSyncStatus(graphDir) {
4504
- const fs50 = await import("fs/promises");
4550
+ const fs51 = await import("fs/promises");
4505
4551
  const result = {};
4506
4552
  try {
4507
- const syncMetaPath = path18.join(graphDir, "sync-metadata.json");
4508
- const syncMeta = JSON.parse(await fs50.readFile(syncMetaPath, "utf-8"));
4553
+ const syncMetaPath = path19.join(graphDir, "sync-metadata.json");
4554
+ const syncMeta = JSON.parse(await fs51.readFile(syncMetaPath, "utf-8"));
4509
4555
  for (const [name, data] of Object.entries(syncMeta.connectors ?? {})) {
4510
4556
  result[name] = data.lastSyncTimestamp;
4511
4557
  }
@@ -4515,7 +4561,7 @@ async function readConnectorSyncStatus(graphDir) {
4515
4561
  }
4516
4562
  async function runGraphStatus(projectPath) {
4517
4563
  const { GraphStore: GraphStore2, loadGraphMetadata } = await import("./dist-DWBTZXR5.js");
4518
- const graphDir = path18.join(projectPath, ".harness", "graph");
4564
+ const graphDir = path19.join(projectPath, ".harness", "graph");
4519
4565
  const metaResult = await loadGraphMetadata(graphDir);
4520
4566
  if (metaResult.status === "not_found") {
4521
4567
  return { status: "no_graph", message: "No graph found. Run `harness graph scan` first." };
@@ -4564,10 +4610,10 @@ async function runGraphStatus(projectPath) {
4564
4610
  }
4565
4611
 
4566
4612
  // src/commands/graph/export.ts
4567
- import * as path19 from "path";
4613
+ import * as path20 from "path";
4568
4614
  async function runGraphExport(projectPath, format) {
4569
4615
  const { GraphStore: GraphStore2 } = await import("./dist-DWBTZXR5.js");
4570
- const graphDir = path19.join(projectPath, ".harness", "graph");
4616
+ const graphDir = path20.join(projectPath, ".harness", "graph");
4571
4617
  const store = new GraphStore2();
4572
4618
  const loaded = await store.load(graphDir);
4573
4619
  if (!loaded) throw new Error("No graph found. Run `harness graph scan` first.");
@@ -4597,11 +4643,11 @@ async function runGraphExport(projectPath, format) {
4597
4643
 
4598
4644
  // src/commands/graph/query.ts
4599
4645
  import { Command as Command35 } from "commander";
4600
- import * as path20 from "path";
4646
+ import * as path21 from "path";
4601
4647
  async function runQuery(projectPath, rootNodeId, opts) {
4602
4648
  const { GraphStore: GraphStore2, ContextQL } = await import("./dist-DWBTZXR5.js");
4603
4649
  const store = new GraphStore2();
4604
- const graphDir = path20.join(projectPath, ".harness", "graph");
4650
+ const graphDir = path21.join(projectPath, ".harness", "graph");
4605
4651
  const loaded = await store.load(graphDir);
4606
4652
  if (!loaded) throw new Error("No graph found. Run `harness graph scan` first.");
4607
4653
  const params = {
@@ -4623,7 +4669,7 @@ function printQueryResult(result) {
4623
4669
  }
4624
4670
  }
4625
4671
  async function runQueryAction(rootNodeId, opts, globalOpts) {
4626
- const projectPath = path20.resolve(globalOpts.config ? path20.dirname(globalOpts.config) : ".");
4672
+ const projectPath = path21.resolve(globalOpts.config ? path21.dirname(globalOpts.config) : ".");
4627
4673
  try {
4628
4674
  const result = await runQuery(projectPath, rootNodeId, {
4629
4675
  depth: parseInt(opts.depth),
@@ -4649,12 +4695,12 @@ function createQueryCommand() {
4649
4695
 
4650
4696
  // src/commands/graph/ingest.ts
4651
4697
  import { Command as Command36 } from "commander";
4652
- import * as path21 from "path";
4698
+ import * as path22 from "path";
4653
4699
  async function loadConnectorConfig(projectPath, source) {
4654
4700
  try {
4655
- const fs50 = await import("fs/promises");
4656
- const configPath = path21.join(projectPath, "harness.config.json");
4657
- const config = JSON.parse(await fs50.readFile(configPath, "utf-8"));
4701
+ const fs51 = await import("fs/promises");
4702
+ const configPath = path22.join(projectPath, "harness.config.json");
4703
+ const config = JSON.parse(await fs51.readFile(configPath, "utf-8"));
4658
4704
  const connector = config.graph?.connectors?.[source];
4659
4705
  return connector ?? {};
4660
4706
  } catch {
@@ -4663,9 +4709,9 @@ async function loadConnectorConfig(projectPath, source) {
4663
4709
  }
4664
4710
  async function ingestBusinessKnowledge(bk, projectPath) {
4665
4711
  return mergeResults(
4666
- await bk.ingest(path21.join(projectPath, "docs", "knowledge")),
4667
- await bk.ingestSolutions(path21.join(projectPath, "docs", "solutions")),
4668
- await bk.ingestStrategy(path21.join(projectPath, "STRATEGY.md"))
4712
+ await bk.ingest(path22.join(projectPath, "docs", "knowledge")),
4713
+ await bk.ingestSolutions(path22.join(projectPath, "docs", "solutions")),
4714
+ await bk.ingestStrategy(path22.join(projectPath, "STRATEGY.md"))
4669
4715
  );
4670
4716
  }
4671
4717
  function mergeResults(...results) {
@@ -4705,7 +4751,7 @@ async function runIngest(projectPath, source, opts) {
4705
4751
  FigmaConnector,
4706
4752
  MiroConnector
4707
4753
  } = await import("./dist-DWBTZXR5.js");
4708
- const graphDir = path21.join(projectPath, ".harness", "graph");
4754
+ const graphDir = path22.join(projectPath, ".harness", "graph");
4709
4755
  const store = new GraphStore2();
4710
4756
  await store.load(graphDir);
4711
4757
  const ingestOptions = loadIngestOptions(projectPath);
@@ -4717,11 +4763,11 @@ async function runIngest(projectPath, source, opts) {
4717
4763
  const bkInst = new BusinessKnowledgeIngestor(store);
4718
4764
  const bkResult = await ingestBusinessKnowledge(bkInst, projectPath);
4719
4765
  const reqResult = await new RequirementIngestor(store).ingestSpecs(
4720
- path21.join(projectPath, "docs", "changes")
4766
+ path22.join(projectPath, "docs", "changes")
4721
4767
  );
4722
4768
  const gitResult = await new GitIngestor(store).ingest(projectPath);
4723
4769
  const { createExtractionRunner } = await import("./dist-DWBTZXR5.js");
4724
- const extractedDir = path21.join(projectPath, ".harness", "knowledge", "extracted");
4770
+ const extractedDir = path22.join(projectPath, ".harness", "knowledge", "extracted");
4725
4771
  const signalsResult = await createExtractionRunner().run(projectPath, store, extractedDir);
4726
4772
  const syncManager = new SyncManager(store, graphDir);
4727
4773
  const connectorMap = {
@@ -4766,12 +4812,12 @@ async function runIngest(projectPath, source, opts) {
4766
4812
  break;
4767
4813
  case "requirements":
4768
4814
  result = await new RequirementIngestor(store).ingestSpecs(
4769
- path21.join(projectPath, "docs", "changes")
4815
+ path22.join(projectPath, "docs", "changes")
4770
4816
  );
4771
4817
  break;
4772
4818
  case "business-signals": {
4773
4819
  const { createExtractionRunner } = await import("./dist-DWBTZXR5.js");
4774
- const extractedDir = path21.join(projectPath, ".harness", "knowledge", "extracted");
4820
+ const extractedDir = path22.join(projectPath, ".harness", "knowledge", "extracted");
4775
4821
  result = await createExtractionRunner().run(projectPath, store, extractedDir);
4776
4822
  break;
4777
4823
  }
@@ -4820,7 +4866,7 @@ async function handleIngestAction(opts, cmd) {
4820
4866
  process.exit(1);
4821
4867
  }
4822
4868
  const globalOpts = cmd.optsWithGlobals();
4823
- const projectPath = path21.resolve(globalOpts.config ? path21.dirname(globalOpts.config) : ".");
4869
+ const projectPath = path22.resolve(globalOpts.config ? path22.dirname(globalOpts.config) : ".");
4824
4870
  try {
4825
4871
  const runOpts = {};
4826
4872
  if (opts.full !== void 0) runOpts.full = opts.full;
@@ -4844,9 +4890,9 @@ function createIngestCommand() {
4844
4890
  }
4845
4891
 
4846
4892
  // src/commands/graph/index.ts
4847
- import * as path22 from "path";
4893
+ import * as path23 from "path";
4848
4894
  function resolveProjectPath(globalOpts) {
4849
- return path22.resolve(globalOpts.config ? path22.dirname(globalOpts.config) : ".");
4895
+ return path23.resolve(globalOpts.config ? path23.dirname(globalOpts.config) : ".");
4850
4896
  }
4851
4897
  function printGraphStatus(result) {
4852
4898
  if (result.status === "no_graph" || result.status === "schema_mismatch") {
@@ -4906,8 +4952,8 @@ import { Command as Command42 } from "commander";
4906
4952
 
4907
4953
  // src/commands/hooks/init.ts
4908
4954
  import { Command as Command38 } from "commander";
4909
- import * as fs9 from "fs";
4910
- import * as path23 from "path";
4955
+ import * as fs10 from "fs";
4956
+ import * as path24 from "path";
4911
4957
  import { fileURLToPath as fileURLToPath2 } from "url";
4912
4958
 
4913
4959
  // src/hooks/profiles.ts
@@ -4958,17 +5004,17 @@ function supportFilesFor(hookNames) {
4958
5004
 
4959
5005
  // src/commands/hooks/init.ts
4960
5006
  var __filename2 = fileURLToPath2(import.meta.url);
4961
- var __dirname2 = path23.dirname(__filename2);
5007
+ var __dirname2 = path24.dirname(__filename2);
4962
5008
  var VALID_PROFILES = ["minimal", "standard", "strict"];
4963
5009
  function resolveHookSourceDir() {
4964
5010
  const candidates = [
4965
5011
  // Dev layout: src/commands/hooks/ → ../../hooks/
4966
- path23.resolve(__dirname2, "..", "..", "hooks"),
5012
+ path24.resolve(__dirname2, "..", "..", "hooks"),
4967
5013
  // Bundled layout: dist/ → ./hooks/ (copied by copy-assets.mjs)
4968
- path23.resolve(__dirname2, "hooks")
5014
+ path24.resolve(__dirname2, "hooks")
4969
5015
  ];
4970
5016
  for (const candidate of candidates) {
4971
- if (fs9.existsSync(candidate)) {
5017
+ if (fs10.existsSync(candidate)) {
4972
5018
  return candidate;
4973
5019
  }
4974
5020
  }
@@ -5005,12 +5051,12 @@ function mergeSettings(existing, hooksConfig) {
5005
5051
  }
5006
5052
  function initHooks(options) {
5007
5053
  const { profile, projectDir } = options;
5008
- const hooksDestDir = path23.join(projectDir, ".harness", "hooks");
5009
- fs9.mkdirSync(hooksDestDir, { recursive: true });
5010
- if (fs9.existsSync(hooksDestDir)) {
5011
- for (const entry of fs9.readdirSync(hooksDestDir)) {
5054
+ const hooksDestDir = path24.join(projectDir, ".harness", "hooks");
5055
+ fs10.mkdirSync(hooksDestDir, { recursive: true });
5056
+ if (fs10.existsSync(hooksDestDir)) {
5057
+ for (const entry of fs10.readdirSync(hooksDestDir)) {
5012
5058
  if (entry.endsWith(".js")) {
5013
- fs9.unlinkSync(path23.join(hooksDestDir, entry));
5059
+ fs10.unlinkSync(path24.join(hooksDestDir, entry));
5014
5060
  }
5015
5061
  }
5016
5062
  }
@@ -5019,29 +5065,29 @@ function initHooks(options) {
5019
5065
  const activeNames = PROFILES[profile];
5020
5066
  const activeScripts = HOOK_SCRIPTS.filter((h) => activeNames.includes(h.name));
5021
5067
  for (const script of activeScripts) {
5022
- const srcFile = path23.join(sourceDir, `${script.name}.js`);
5023
- const destFile = path23.join(hooksDestDir, `${script.name}.js`);
5024
- if (fs9.existsSync(srcFile)) {
5025
- fs9.copyFileSync(srcFile, destFile);
5068
+ const srcFile = path24.join(sourceDir, `${script.name}.js`);
5069
+ const destFile = path24.join(hooksDestDir, `${script.name}.js`);
5070
+ if (fs10.existsSync(srcFile)) {
5071
+ fs10.copyFileSync(srcFile, destFile);
5026
5072
  copiedScripts.push(script.name);
5027
5073
  }
5028
5074
  }
5029
5075
  for (const supportFile of supportFilesFor(activeNames)) {
5030
- const srcFile = path23.join(sourceDir, supportFile);
5031
- const destFile = path23.join(hooksDestDir, supportFile);
5032
- if (fs9.existsSync(srcFile)) {
5033
- fs9.copyFileSync(srcFile, destFile);
5076
+ const srcFile = path24.join(sourceDir, supportFile);
5077
+ const destFile = path24.join(hooksDestDir, supportFile);
5078
+ if (fs10.existsSync(srcFile)) {
5079
+ fs10.copyFileSync(srcFile, destFile);
5034
5080
  }
5035
5081
  }
5036
- const profilePath = path23.join(hooksDestDir, "profile.json");
5037
- fs9.writeFileSync(profilePath, JSON.stringify({ profile }, null, 2) + "\n");
5038
- const claudeDir = path23.join(projectDir, ".claude");
5039
- fs9.mkdirSync(claudeDir, { recursive: true });
5040
- const settingsPath = path23.join(claudeDir, "settings.json");
5082
+ const profilePath = path24.join(hooksDestDir, "profile.json");
5083
+ fs10.writeFileSync(profilePath, JSON.stringify({ profile }, null, 2) + "\n");
5084
+ const claudeDir = path24.join(projectDir, ".claude");
5085
+ fs10.mkdirSync(claudeDir, { recursive: true });
5086
+ const settingsPath = path24.join(claudeDir, "settings.json");
5041
5087
  let existing = {};
5042
- if (fs9.existsSync(settingsPath)) {
5088
+ if (fs10.existsSync(settingsPath)) {
5043
5089
  try {
5044
- existing = JSON.parse(fs9.readFileSync(settingsPath, "utf-8"));
5090
+ existing = JSON.parse(fs10.readFileSync(settingsPath, "utf-8"));
5045
5091
  } catch (e) {
5046
5092
  throw new Error(
5047
5093
  `Malformed .claude/settings.json \u2014 fix the JSON syntax before running hooks init. Parse error: ${e instanceof Error ? e.message : String(e)}`,
@@ -5051,7 +5097,7 @@ function initHooks(options) {
5051
5097
  }
5052
5098
  const hooksConfig = buildSettingsHooks(profile);
5053
5099
  const merged = mergeSettings(existing, hooksConfig);
5054
- fs9.writeFileSync(settingsPath, JSON.stringify(merged, null, 2) + "\n");
5100
+ fs10.writeFileSync(settingsPath, JSON.stringify(merged, null, 2) + "\n");
5055
5101
  return { copiedScripts, settingsPath, profilePath };
5056
5102
  }
5057
5103
  function createInitCommand2() {
@@ -5080,7 +5126,7 @@ function createInitCommand2() {
5080
5126
  );
5081
5127
  logger.info(`Profile: ${profile}`);
5082
5128
  logger.info(
5083
- `Settings: ${path23.relative(projectDir, result.settingsPath).replaceAll("\\", "/")}`
5129
+ `Settings: ${path24.relative(projectDir, result.settingsPath).replaceAll("\\", "/")}`
5084
5130
  );
5085
5131
  logger.dim("Run 'harness hooks list' to see installed hooks");
5086
5132
  }
@@ -5094,18 +5140,18 @@ function createInitCommand2() {
5094
5140
 
5095
5141
  // src/commands/hooks/list.ts
5096
5142
  import { Command as Command39 } from "commander";
5097
- import * as fs10 from "fs";
5098
- import * as path24 from "path";
5143
+ import * as fs11 from "fs";
5144
+ import * as path25 from "path";
5099
5145
  function listHooks(projectDir) {
5100
- const hooksDir = path24.join(projectDir, ".harness", "hooks");
5101
- const profilePath = path24.join(hooksDir, "profile.json");
5102
- if (!fs10.existsSync(profilePath)) {
5146
+ const hooksDir = path25.join(projectDir, ".harness", "hooks");
5147
+ const profilePath = path25.join(hooksDir, "profile.json");
5148
+ if (!fs11.existsSync(profilePath)) {
5103
5149
  return { installed: false, profile: null, hooks: [] };
5104
5150
  }
5105
5151
  let profile = "standard";
5106
5152
  let warning;
5107
5153
  try {
5108
- const data = JSON.parse(fs10.readFileSync(profilePath, "utf-8"));
5154
+ const data = JSON.parse(fs11.readFileSync(profilePath, "utf-8"));
5109
5155
  if (data.profile && ["minimal", "standard", "strict"].includes(data.profile)) {
5110
5156
  profile = data.profile;
5111
5157
  }
@@ -5117,7 +5163,7 @@ function listHooks(projectDir) {
5117
5163
  name: h.name,
5118
5164
  event: h.event,
5119
5165
  matcher: h.matcher,
5120
- scriptPath: path24.join(".harness", "hooks", `${h.name}.js`)
5166
+ scriptPath: path25.join(".harness", "hooks", `${h.name}.js`)
5121
5167
  }));
5122
5168
  const result = { installed: true, profile, hooks };
5123
5169
  if (warning) {
@@ -5148,27 +5194,27 @@ function createListCommand() {
5148
5194
 
5149
5195
  // src/commands/hooks/remove.ts
5150
5196
  import { Command as Command40 } from "commander";
5151
- import * as fs11 from "fs";
5152
- import * as path25 from "path";
5197
+ import * as fs12 from "fs";
5198
+ import * as path26 from "path";
5153
5199
  function removeHooks(projectDir) {
5154
- const hooksDir = path25.join(projectDir, ".harness", "hooks");
5155
- const settingsPath = path25.join(projectDir, ".claude", "settings.json");
5200
+ const hooksDir = path26.join(projectDir, ".harness", "hooks");
5201
+ const settingsPath = path26.join(projectDir, ".claude", "settings.json");
5156
5202
  let removed = false;
5157
5203
  let settingsCleaned = false;
5158
- if (fs11.existsSync(hooksDir)) {
5159
- fs11.rmSync(hooksDir, { recursive: true, force: true });
5204
+ if (fs12.existsSync(hooksDir)) {
5205
+ fs12.rmSync(hooksDir, { recursive: true, force: true });
5160
5206
  removed = true;
5161
5207
  }
5162
- if (fs11.existsSync(settingsPath)) {
5208
+ if (fs12.existsSync(settingsPath)) {
5163
5209
  try {
5164
- const settings = JSON.parse(fs11.readFileSync(settingsPath, "utf-8"));
5210
+ const settings = JSON.parse(fs12.readFileSync(settingsPath, "utf-8"));
5165
5211
  if (settings.hooks !== void 0) {
5166
5212
  delete settings.hooks;
5167
5213
  settingsCleaned = true;
5168
5214
  if (Object.keys(settings).length === 0) {
5169
- fs11.unlinkSync(settingsPath);
5215
+ fs12.unlinkSync(settingsPath);
5170
5216
  } else {
5171
- fs11.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
5217
+ fs12.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
5172
5218
  }
5173
5219
  }
5174
5220
  } catch {
@@ -5200,20 +5246,20 @@ function createRemoveCommand() {
5200
5246
 
5201
5247
  // src/commands/hooks/add.ts
5202
5248
  import { Command as Command41 } from "commander";
5203
- import * as fs12 from "fs";
5204
- import * as path26 from "path";
5249
+ import * as fs13 from "fs";
5250
+ import * as path27 from "path";
5205
5251
  import { fileURLToPath as fileURLToPath3 } from "url";
5206
- var __dirname3 = path26.dirname(fileURLToPath3(import.meta.url));
5252
+ var __dirname3 = path27.dirname(fileURLToPath3(import.meta.url));
5207
5253
  var ALIASES = {
5208
5254
  sentinel: ["sentinel-pre", "sentinel-post"]
5209
5255
  };
5210
5256
  function hookSourceDir() {
5211
- const d = path26.resolve(__dirname3, "..", "..", "hooks");
5212
- if (fs12.existsSync(d)) return d;
5257
+ const d = path27.resolve(__dirname3, "..", "..", "hooks");
5258
+ if (fs13.existsSync(d)) return d;
5213
5259
  throw new Error(`Hook scripts not found: ${d}`);
5214
5260
  }
5215
5261
  function readJson(p) {
5216
- return fs12.existsSync(p) ? JSON.parse(fs12.readFileSync(p, "utf-8")) : {};
5262
+ return fs13.existsSync(p) ? JSON.parse(fs13.readFileSync(p, "utf-8")) : {};
5217
5263
  }
5218
5264
  function registerHook(s, ev, matcher, name) {
5219
5265
  if (!s.hooks[ev]) s.hooks[ev] = [];
@@ -5226,11 +5272,11 @@ function addHooks(hookName, projectDir) {
5226
5272
  const names = ALIASES[hookName] ?? [hookName];
5227
5273
  const result = { added: [], alreadyInstalled: [], notFound: [] };
5228
5274
  const srcDir = hookSourceDir();
5229
- const destDir = path26.join(projectDir, ".harness", "hooks");
5230
- fs12.mkdirSync(destDir, { recursive: true });
5231
- const claudeDir = path26.join(projectDir, ".claude");
5232
- fs12.mkdirSync(claudeDir, { recursive: true });
5233
- const settingsPath = path26.join(claudeDir, "settings.json");
5275
+ const destDir = path27.join(projectDir, ".harness", "hooks");
5276
+ fs13.mkdirSync(destDir, { recursive: true });
5277
+ const claudeDir = path27.join(projectDir, ".claude");
5278
+ fs13.mkdirSync(claudeDir, { recursive: true });
5279
+ const settingsPath = path27.join(claudeDir, "settings.json");
5234
5280
  const settings = readJson(settingsPath);
5235
5281
  if (!settings.hooks) settings.hooks = {};
5236
5282
  for (const name of names) {
@@ -5239,27 +5285,27 @@ function addHooks(hookName, projectDir) {
5239
5285
  result.notFound.push(name);
5240
5286
  continue;
5241
5287
  }
5242
- const src = path26.join(srcDir, `${name}.js`);
5243
- const dest = path26.join(destDir, `${name}.js`);
5244
- if (fs12.existsSync(dest)) {
5288
+ const src = path27.join(srcDir, `${name}.js`);
5289
+ const dest = path27.join(destDir, `${name}.js`);
5290
+ if (fs13.existsSync(dest)) {
5245
5291
  result.alreadyInstalled.push(name);
5246
- } else if (!fs12.existsSync(src)) {
5292
+ } else if (!fs13.existsSync(src)) {
5247
5293
  result.notFound.push(name);
5248
5294
  continue;
5249
5295
  } else {
5250
- fs12.copyFileSync(src, dest);
5296
+ fs13.copyFileSync(src, dest);
5251
5297
  result.added.push(name);
5252
5298
  }
5253
5299
  registerHook(settings, def.event, def.matcher, name);
5254
5300
  }
5255
5301
  for (const supportFile of supportFilesFor(names)) {
5256
- const src = path26.join(srcDir, supportFile);
5257
- const dest = path26.join(destDir, supportFile);
5258
- if (fs12.existsSync(src)) {
5259
- fs12.copyFileSync(src, dest);
5302
+ const src = path27.join(srcDir, supportFile);
5303
+ const dest = path27.join(destDir, supportFile);
5304
+ if (fs13.existsSync(src)) {
5305
+ fs13.copyFileSync(src, dest);
5260
5306
  }
5261
5307
  }
5262
- fs12.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
5308
+ fs13.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
5263
5309
  return result;
5264
5310
  }
5265
5311
  function createAddCommand2() {
@@ -5299,8 +5345,8 @@ function createHooksCommand() {
5299
5345
  // src/commands/impact-preview.ts
5300
5346
  import { Command as Command43 } from "commander";
5301
5347
  import { execSync as execSync4 } from "child_process";
5302
- import * as path27 from "path";
5303
- import * as fs13 from "fs";
5348
+ import * as path28 from "path";
5349
+ import * as fs14 from "fs";
5304
5350
  function getStagedFiles(cwd) {
5305
5351
  try {
5306
5352
  const output = execSync4("git diff --cached --name-only", {
@@ -5314,7 +5360,7 @@ function getStagedFiles(cwd) {
5314
5360
  }
5315
5361
  function graphExists(projectPath) {
5316
5362
  try {
5317
- return fs13.existsSync(path27.join(projectPath, ".harness", "graph", "graph.json"));
5363
+ return fs14.existsSync(path28.join(projectPath, ".harness", "graph", "graph.json"));
5318
5364
  } catch {
5319
5365
  return false;
5320
5366
  }
@@ -5323,7 +5369,7 @@ function extractNodeName(id) {
5323
5369
  const parts = id.split(":");
5324
5370
  if (parts.length > 1) {
5325
5371
  const fullPath = parts.slice(1).join(":");
5326
- return path27.basename(fullPath);
5372
+ return path28.basename(fullPath);
5327
5373
  }
5328
5374
  return id;
5329
5375
  }
@@ -5478,7 +5524,7 @@ function formatImpactOutput(stagedFiles, acc, options) {
5478
5524
  return options.detailed ? formatDetailed(stagedFiles.length, merged, acc.aggregateCounts) : formatCompact(stagedFiles.length, merged, acc.aggregateCounts);
5479
5525
  }
5480
5526
  async function runImpactPreview(options) {
5481
- const projectPath = path27.resolve(options.path ?? process.cwd());
5527
+ const projectPath = path28.resolve(options.path ?? process.cwd());
5482
5528
  const stagedFiles = getStagedFiles(projectPath);
5483
5529
  if (stagedFiles.length === 0) return "Impact Preview: no staged changes";
5484
5530
  if (!graphExists(projectPath)) {
@@ -5512,26 +5558,26 @@ function createImpactPreviewCommand() {
5512
5558
  init_dist3();
5513
5559
  import { Command as Command45 } from "commander";
5514
5560
  import chalk4 from "chalk";
5515
- import * as fs16 from "fs";
5516
- import * as path30 from "path";
5561
+ import * as fs17 from "fs";
5562
+ import * as path31 from "path";
5517
5563
 
5518
5564
  // src/commands/setup-mcp.ts
5519
5565
  import { Command as Command44 } from "commander";
5520
- import * as fs15 from "fs";
5521
- import * as path29 from "path";
5566
+ import * as fs16 from "fs";
5567
+ import * as path30 from "path";
5522
5568
  import * as os2 from "os";
5523
5569
  import chalk3 from "chalk";
5524
5570
  import * as clack from "@clack/prompts";
5525
5571
 
5526
5572
  // src/integrations/toml.ts
5527
- import * as fs14 from "fs";
5528
- import * as path28 from "path";
5573
+ import * as fs15 from "fs";
5574
+ import * as path29 from "path";
5529
5575
  function writeTomlMcpEntry(filePath, name, entry) {
5530
- const dir = path28.dirname(filePath);
5531
- if (!fs14.existsSync(dir)) {
5532
- fs14.mkdirSync(dir, { recursive: true });
5576
+ const dir = path29.dirname(filePath);
5577
+ if (!fs15.existsSync(dir)) {
5578
+ fs15.mkdirSync(dir, { recursive: true });
5533
5579
  }
5534
- const existing = fs14.existsSync(filePath) ? fs14.readFileSync(filePath, "utf-8") : "";
5580
+ const existing = fs15.existsSync(filePath) ? fs15.readFileSync(filePath, "utf-8") : "";
5535
5581
  const blockHeader = `[mcp_servers.${name}]`;
5536
5582
  const newBlock = serializeTomlMcpBlock(name, entry);
5537
5583
  let updated;
@@ -5542,8 +5588,8 @@ function writeTomlMcpEntry(filePath, name, entry) {
5542
5588
  updated = existing + separator + newBlock;
5543
5589
  }
5544
5590
  const tmp = filePath + ".tmp";
5545
- fs14.writeFileSync(tmp, updated);
5546
- fs14.renameSync(tmp, filePath);
5591
+ fs15.writeFileSync(tmp, updated);
5592
+ fs15.renameSync(tmp, filePath);
5547
5593
  }
5548
5594
  function serializeTomlMcpBlock(name, entry) {
5549
5595
  const lines = [`[mcp_servers.${name}]`];
@@ -5664,6 +5710,7 @@ var ALL_MCP_TOOLS = [
5664
5710
  "ask_graph",
5665
5711
  "check_task_independence",
5666
5712
  "predict_conflicts",
5713
+ "plan_parallelization",
5667
5714
  "detect_stale_constraints",
5668
5715
  "search_skills",
5669
5716
  "code_outline",
@@ -5759,20 +5806,20 @@ function writeCursorMcpEntryWithTools(configPath, tools) {
5759
5806
  });
5760
5807
  }
5761
5808
  function readJsonFile(filePath) {
5762
- if (!fs15.existsSync(filePath)) return null;
5809
+ if (!fs16.existsSync(filePath)) return null;
5763
5810
  try {
5764
- return JSON.parse(fs15.readFileSync(filePath, "utf-8"));
5811
+ return JSON.parse(fs16.readFileSync(filePath, "utf-8"));
5765
5812
  } catch {
5766
- fs15.copyFileSync(filePath, filePath + ".bak");
5813
+ fs16.copyFileSync(filePath, filePath + ".bak");
5767
5814
  return null;
5768
5815
  }
5769
5816
  }
5770
5817
  function writeJsonFile(filePath, data) {
5771
- const dir = path29.dirname(filePath);
5772
- if (!fs15.existsSync(dir)) {
5773
- fs15.mkdirSync(dir, { recursive: true });
5818
+ const dir = path30.dirname(filePath);
5819
+ if (!fs16.existsSync(dir)) {
5820
+ fs16.mkdirSync(dir, { recursive: true });
5774
5821
  }
5775
- fs15.writeFileSync(filePath, JSON.stringify(data, null, 2) + "\n");
5822
+ fs16.writeFileSync(filePath, JSON.stringify(data, null, 2) + "\n");
5776
5823
  }
5777
5824
  function configureMcpServer(configPath) {
5778
5825
  const config = readJsonFile(configPath) ?? {};
@@ -5787,7 +5834,7 @@ function configureMcpServer(configPath) {
5787
5834
  return true;
5788
5835
  }
5789
5836
  function addGeminiTrustedFolder(cwd) {
5790
- const trustedPath = path29.join(os2.homedir(), ".gemini", "trustedFolders.json");
5837
+ const trustedPath = path30.join(os2.homedir(), ".gemini", "trustedFolders.json");
5791
5838
  const folders = readJsonFile(trustedPath) ?? {};
5792
5839
  if (folders[cwd] === "TRUST_FOLDER") {
5793
5840
  return false;
@@ -5801,7 +5848,7 @@ function setupMcp(cwd, client) {
5801
5848
  const skipped = [];
5802
5849
  let trustedFolder = false;
5803
5850
  if (client === "all" || client === "claude") {
5804
- const configPath = path29.join(cwd, ".mcp.json");
5851
+ const configPath = path30.join(cwd, ".mcp.json");
5805
5852
  if (configureMcpServer(configPath)) {
5806
5853
  configured.push("Claude Code");
5807
5854
  } else {
@@ -5809,7 +5856,7 @@ function setupMcp(cwd, client) {
5809
5856
  }
5810
5857
  }
5811
5858
  if (client === "all" || client === "gemini") {
5812
- const configPath = path29.join(cwd, ".gemini", "settings.json");
5859
+ const configPath = path30.join(cwd, ".gemini", "settings.json");
5813
5860
  if (configureMcpServer(configPath)) {
5814
5861
  configured.push("Gemini CLI");
5815
5862
  } else {
@@ -5818,10 +5865,10 @@ function setupMcp(cwd, client) {
5818
5865
  trustedFolder = addGeminiTrustedFolder(cwd);
5819
5866
  }
5820
5867
  if (client === "all" || client === "codex") {
5821
- const configPath = path29.join(cwd, ".codex", "config.toml");
5868
+ const configPath = path30.join(cwd, ".codex", "config.toml");
5822
5869
  const alreadyConfigured = (() => {
5823
- if (!fs15.existsSync(configPath)) return false;
5824
- const content = fs15.readFileSync(configPath, "utf-8");
5870
+ if (!fs16.existsSync(configPath)) return false;
5871
+ const content = fs16.readFileSync(configPath, "utf-8");
5825
5872
  return content.includes("[mcp_servers.harness]");
5826
5873
  })();
5827
5874
  if (alreadyConfigured) {
@@ -5836,7 +5883,7 @@ function setupMcp(cwd, client) {
5836
5883
  }
5837
5884
  }
5838
5885
  if (client === "all" || client === "cursor") {
5839
- const configPath = path29.join(cwd, ".cursor", "mcp.json");
5886
+ const configPath = path30.join(cwd, ".cursor", "mcp.json");
5840
5887
  const existing = readJsonFile(configPath);
5841
5888
  if (existing?.mcpServers?.["harness"]) {
5842
5889
  skipped.push("Cursor");
@@ -5846,7 +5893,7 @@ function setupMcp(cwd, client) {
5846
5893
  }
5847
5894
  }
5848
5895
  if (client === "all" || client === "opencode") {
5849
- const configPath = path29.join(cwd, "opencode.json");
5896
+ const configPath = path30.join(cwd, "opencode.json");
5850
5897
  const existing = readJsonFile(configPath);
5851
5898
  if (existing?.mcp?.["harness"]) {
5852
5899
  skipped.push("OpenCode");
@@ -5860,7 +5907,7 @@ function setupMcp(cwd, client) {
5860
5907
  async function resolveCursorWithPicker(cwd, pick) {
5861
5908
  const configured = [];
5862
5909
  const skipped = [];
5863
- const cursorConfigPath = path29.join(cwd, ".cursor", "mcp.json");
5910
+ const cursorConfigPath = path30.join(cwd, ".cursor", "mcp.json");
5864
5911
  const existing = readJsonFile(cursorConfigPath);
5865
5912
  if (existing?.mcpServers?.["harness"] && !pick) {
5866
5913
  skipped.push("Cursor");
@@ -5958,12 +6005,12 @@ function loadEngineAndTemplates(_options) {
5958
6005
  }
5959
6006
  function resolveInitDefaults(options) {
5960
6007
  const cwd = options.cwd ?? process.cwd();
5961
- return { cwd, name: options.name ?? path30.basename(cwd), force: options.force ?? false };
6008
+ return { cwd, name: options.name ?? path31.basename(cwd), force: options.force ?? false };
5962
6009
  }
5963
6010
  async function runInit(options) {
5964
6011
  const { cwd, name, force } = resolveInitDefaults(options);
5965
- const configPath = path30.join(cwd, "harness.config.json");
5966
- if (!force && fs16.existsSync(configPath)) {
6012
+ const configPath = path31.join(cwd, "harness.config.json");
6013
+ if (!force && fs17.existsSync(configPath)) {
5967
6014
  return Err(
5968
6015
  new CLIError("Project already initialized. Use --force to overwrite.", ExitCode.ERROR)
5969
6016
  );
@@ -6059,15 +6106,15 @@ async function scaffoldProject(engine, ctx) {
6059
6106
  }
6060
6107
  function scaffoldShardedRoadmap(cwd, name) {
6061
6108
  if (roadmapSourceExists(cwd)) return [];
6062
- const shardDir = path30.join(cwd, "docs", "roadmap.d");
6063
- fs16.mkdirSync(shardDir, { recursive: true });
6109
+ const shardDir = path31.join(cwd, "docs", "roadmap.d");
6110
+ fs17.mkdirSync(shardDir, { recursive: true });
6064
6111
  const nowIso = (/* @__PURE__ */ new Date()).toISOString();
6065
6112
  const meta = {
6066
6113
  frontmatter: { project: name, version: 1, lastSynced: nowIso, lastManualEdit: nowIso },
6067
6114
  milestones: []
6068
6115
  };
6069
- fs16.writeFileSync(path30.join(shardDir, "_meta.md"), serializeMeta(meta), "utf-8");
6070
- return [path30.join("docs", "roadmap.d", "_meta.md")];
6116
+ fs17.writeFileSync(path31.join(shardDir, "_meta.md"), serializeMeta(meta), "utf-8");
6117
+ return [path31.join("docs", "roadmap.d", "_meta.md")];
6071
6118
  }
6072
6119
  function printInitSuccess(filesCreated, mcpConfigured) {
6073
6120
  console.log("");
@@ -6162,7 +6209,7 @@ function createInsightsCommand() {
6162
6209
  return new Command46("insights").description("Composite project report \u2014 health, entropy, decay, attention, impact.").option("--json", "Emit JSON to stdout instead of pretty text").option("--skip <list>", `Comma-separated keys to skip (${INSIGHTS_KEYS.join(",")})`).action(async (opts) => {
6163
6210
  const cwd = process.cwd();
6164
6211
  const skip = parseSkip2(opts.skip);
6165
- const { composeInsights } = await import("./dist-MCTEX5QH.js");
6212
+ const { composeInsights } = await import("./dist-BWFFVKEW.js");
6166
6213
  const report = await composeInsights(cwd, { skip });
6167
6214
  if (opts.json) {
6168
6215
  console.log(JSON.stringify(report, null, 2));
@@ -6173,16 +6220,16 @@ function createInsightsCommand() {
6173
6220
  }
6174
6221
 
6175
6222
  // src/commands/install.ts
6176
- import * as fs21 from "fs";
6223
+ import * as fs22 from "fs";
6177
6224
  import * as os5 from "os";
6178
- import * as path35 from "path";
6225
+ import * as path36 from "path";
6179
6226
  import { execFileSync as execFileSync3 } from "child_process";
6180
6227
  import { Command as Command47 } from "commander";
6181
6228
  import { parse as yamlParse } from "yaml";
6182
6229
 
6183
6230
  // src/registry/npm-client.ts
6184
- import * as fs17 from "fs";
6185
- import * as path31 from "path";
6231
+ import * as fs18 from "fs";
6232
+ import * as path32 from "path";
6186
6233
  import * as os3 from "os";
6187
6234
  var NPM_REGISTRY = "https://registry.npmjs.org";
6188
6235
  var FETCH_TIMEOUT_MS = 3e4;
@@ -6205,10 +6252,10 @@ function extractSkillName(packageName) {
6205
6252
  function readNpmrcToken(registryUrl) {
6206
6253
  const { hostname: hostname2, pathname } = new URL(registryUrl);
6207
6254
  const registryPath = `//${hostname2}${pathname.replace(/\/$/, "")}/:_authToken=`;
6208
- const candidates = [path31.join(process.cwd(), ".npmrc"), path31.join(os3.homedir(), ".npmrc")];
6255
+ const candidates = [path32.join(process.cwd(), ".npmrc"), path32.join(os3.homedir(), ".npmrc")];
6209
6256
  for (const npmrcPath of candidates) {
6210
6257
  try {
6211
- const content = fs17.readFileSync(npmrcPath, "utf-8");
6258
+ const content = fs18.readFileSync(npmrcPath, "utf-8");
6212
6259
  for (const line of content.split("\n")) {
6213
6260
  const trimmed = line.trim();
6214
6261
  if (trimmed.startsWith(registryPath)) {
@@ -6303,19 +6350,19 @@ async function searchNpmRegistry(query, registryUrl) {
6303
6350
  }
6304
6351
 
6305
6352
  // src/registry/tarball.ts
6306
- import * as fs18 from "fs";
6307
- import * as path32 from "path";
6353
+ import * as fs19 from "fs";
6354
+ import * as path33 from "path";
6308
6355
  import * as os4 from "os";
6309
6356
  import { execFileSync as execFileSync2 } from "child_process";
6310
6357
  function extractTarball(tarballBuffer) {
6311
- const tmpDir = fs18.mkdtempSync(path32.join(os4.tmpdir(), "harness-skill-install-"));
6312
- const tarballPath = path32.join(tmpDir, "package.tgz");
6358
+ const tmpDir = fs19.mkdtempSync(path33.join(os4.tmpdir(), "harness-skill-install-"));
6359
+ const tarballPath = path33.join(tmpDir, "package.tgz");
6313
6360
  try {
6314
- fs18.writeFileSync(tarballPath, tarballBuffer);
6361
+ fs19.writeFileSync(tarballPath, tarballBuffer);
6315
6362
  execFileSync2("tar", ["-xzf", tarballPath, "-C", tmpDir], {
6316
6363
  timeout: 3e4
6317
6364
  });
6318
- fs18.unlinkSync(tarballPath);
6365
+ fs19.unlinkSync(tarballPath);
6319
6366
  } catch (err) {
6320
6367
  cleanupTempDir(tmpDir);
6321
6368
  throw new Error(
@@ -6326,37 +6373,37 @@ function extractTarball(tarballBuffer) {
6326
6373
  return tmpDir;
6327
6374
  }
6328
6375
  function placeSkillContent(extractedPkgDir, communityBaseDir, skillName, platforms) {
6329
- const files = fs18.readdirSync(extractedPkgDir);
6376
+ const files = fs19.readdirSync(extractedPkgDir);
6330
6377
  for (const platform of platforms) {
6331
- const targetDir = path32.join(communityBaseDir, platform, skillName);
6332
- if (fs18.existsSync(targetDir)) {
6333
- fs18.rmSync(targetDir, { recursive: true, force: true });
6378
+ const targetDir = path33.join(communityBaseDir, platform, skillName);
6379
+ if (fs19.existsSync(targetDir)) {
6380
+ fs19.rmSync(targetDir, { recursive: true, force: true });
6334
6381
  }
6335
- fs18.mkdirSync(targetDir, { recursive: true });
6382
+ fs19.mkdirSync(targetDir, { recursive: true });
6336
6383
  for (const file of files) {
6337
6384
  if (file === "package.json" || file === "node_modules") continue;
6338
- const srcPath = path32.join(extractedPkgDir, file);
6339
- const destPath = path32.join(targetDir, file);
6340
- const stat = fs18.statSync(srcPath);
6385
+ const srcPath = path33.join(extractedPkgDir, file);
6386
+ const destPath = path33.join(targetDir, file);
6387
+ const stat = fs19.statSync(srcPath);
6341
6388
  if (stat.isDirectory()) {
6342
- fs18.cpSync(srcPath, destPath, { recursive: true });
6389
+ fs19.cpSync(srcPath, destPath, { recursive: true });
6343
6390
  } else {
6344
- fs18.copyFileSync(srcPath, destPath);
6391
+ fs19.copyFileSync(srcPath, destPath);
6345
6392
  }
6346
6393
  }
6347
6394
  }
6348
6395
  }
6349
6396
  function removeSkillContent(communityBaseDir, skillName, platforms) {
6350
6397
  for (const platform of platforms) {
6351
- const targetDir = path32.join(communityBaseDir, platform, skillName);
6352
- if (fs18.existsSync(targetDir)) {
6353
- fs18.rmSync(targetDir, { recursive: true, force: true });
6398
+ const targetDir = path33.join(communityBaseDir, platform, skillName);
6399
+ if (fs19.existsSync(targetDir)) {
6400
+ fs19.rmSync(targetDir, { recursive: true, force: true });
6354
6401
  }
6355
6402
  }
6356
6403
  }
6357
6404
  function cleanupTempDir(dirPath) {
6358
6405
  try {
6359
- fs18.rmSync(dirPath, { recursive: true, force: true });
6406
+ fs19.rmSync(dirPath, { recursive: true, force: true });
6360
6407
  } catch {
6361
6408
  }
6362
6409
  }
@@ -6398,8 +6445,8 @@ function findDependentsOf(lockfile, targetPackageName) {
6398
6445
  }
6399
6446
 
6400
6447
  // src/registry/lockfile.ts
6401
- import * as fs19 from "fs";
6402
- import * as path33 from "path";
6448
+ import * as fs20 from "fs";
6449
+ import * as path34 from "path";
6403
6450
  function createEmptyLockfile() {
6404
6451
  return { version: 1, skills: {} };
6405
6452
  }
@@ -6419,10 +6466,10 @@ function sortedStringify(obj) {
6419
6466
  );
6420
6467
  }
6421
6468
  function readLockfile2(filePath) {
6422
- if (!fs19.existsSync(filePath)) {
6469
+ if (!fs20.existsSync(filePath)) {
6423
6470
  return createEmptyLockfile();
6424
6471
  }
6425
- const raw = fs19.readFileSync(filePath, "utf-8");
6472
+ const raw = fs20.readFileSync(filePath, "utf-8");
6426
6473
  let parsed;
6427
6474
  try {
6428
6475
  parsed = JSON.parse(raw);
@@ -6439,9 +6486,9 @@ function readLockfile2(filePath) {
6439
6486
  return parsed;
6440
6487
  }
6441
6488
  function writeLockfile2(filePath, lockfile) {
6442
- const dir = path33.dirname(filePath);
6443
- fs19.mkdirSync(dir, { recursive: true });
6444
- fs19.writeFileSync(filePath, sortedStringify(lockfile) + "\n", "utf-8");
6489
+ const dir = path34.dirname(filePath);
6490
+ fs20.mkdirSync(dir, { recursive: true });
6491
+ fs20.writeFileSync(filePath, sortedStringify(lockfile) + "\n", "utf-8");
6445
6492
  }
6446
6493
  function updateLockfileEntry(lockfile, name, entry) {
6447
6494
  return {
@@ -6464,17 +6511,17 @@ function removeLockfileEntry(lockfile, name) {
6464
6511
  }
6465
6512
 
6466
6513
  // src/registry/bundled-skills.ts
6467
- import * as fs20 from "fs";
6468
- import * as path34 from "path";
6514
+ import * as fs21 from "fs";
6515
+ import * as path35 from "path";
6469
6516
  function getBundledSkillNames(bundledSkillsDir) {
6470
- if (!fs20.existsSync(bundledSkillsDir)) {
6517
+ if (!fs21.existsSync(bundledSkillsDir)) {
6471
6518
  return /* @__PURE__ */ new Set();
6472
6519
  }
6473
- const entries = fs20.readdirSync(bundledSkillsDir);
6520
+ const entries = fs21.readdirSync(bundledSkillsDir);
6474
6521
  const names = /* @__PURE__ */ new Set();
6475
6522
  for (const entry of entries) {
6476
6523
  try {
6477
- const stat = fs20.statSync(path34.join(bundledSkillsDir, String(entry)));
6524
+ const stat = fs21.statSync(path35.join(bundledSkillsDir, String(entry)));
6478
6525
  if (stat.isDirectory()) {
6479
6526
  names.add(String(entry));
6480
6527
  }
@@ -6502,12 +6549,12 @@ function validateSkillYaml(parsed) {
6502
6549
  function resolveCommunityBase(global) {
6503
6550
  if (global) {
6504
6551
  const communityBase2 = resolveGlobalCommunityBaseDir();
6505
- return { communityBase: communityBase2, lockfilePath: path35.join(communityBase2, "skills-lock.json") };
6552
+ return { communityBase: communityBase2, lockfilePath: path36.join(communityBase2, "skills-lock.json") };
6506
6553
  }
6507
6554
  const globalDir = resolveGlobalSkillsDir();
6508
- const skillsDir = path35.dirname(globalDir);
6509
- const communityBase = path35.join(skillsDir, "community");
6510
- return { communityBase, lockfilePath: path35.join(communityBase, "skills-lock.json") };
6555
+ const skillsDir = path36.dirname(globalDir);
6556
+ const communityBase = path36.join(skillsDir, "community");
6557
+ return { communityBase, lockfilePath: path36.join(communityBase, "skills-lock.json") };
6511
6558
  }
6512
6559
  function parseGitHubRef(from) {
6513
6560
  const ghPrefix = from.match(/^github:([^/]+)\/([^#]+?)(?:#(.+))?$/);
@@ -6523,7 +6570,7 @@ function parseGitHubRef(from) {
6523
6570
  return null;
6524
6571
  }
6525
6572
  function cloneGitHubRepo(owner, repo, ref) {
6526
- const tmpDir = fs21.mkdtempSync(path35.join(os5.tmpdir(), "harness-gh-install-"));
6573
+ const tmpDir = fs22.mkdtempSync(path36.join(os5.tmpdir(), "harness-gh-install-"));
6527
6574
  const url = `https://github.com/${owner}/${repo}.git`;
6528
6575
  try {
6529
6576
  const cloneArgs = ["clone", "--depth", "1"];
@@ -6544,43 +6591,43 @@ function discoverSkillDirs(rootDir) {
6544
6591
  const skillDirs = [];
6545
6592
  function scan(dir, depth) {
6546
6593
  if (depth > 3) return;
6547
- if (!fs21.existsSync(dir)) return;
6548
- if (fs21.existsSync(path35.join(dir, "skill.yaml"))) {
6594
+ if (!fs22.existsSync(dir)) return;
6595
+ if (fs22.existsSync(path36.join(dir, "skill.yaml"))) {
6549
6596
  skillDirs.push(dir);
6550
6597
  return;
6551
6598
  }
6552
- const entries = fs21.readdirSync(dir, { withFileTypes: true });
6599
+ const entries = fs22.readdirSync(dir, { withFileTypes: true });
6553
6600
  for (const entry of entries) {
6554
6601
  if (!entry.isDirectory()) continue;
6555
6602
  if (entry.name.startsWith(".") || DEFAULT_SKIP_DIRS.has(entry.name)) continue;
6556
- scan(path35.join(dir, entry.name), depth + 1);
6603
+ scan(path36.join(dir, entry.name), depth + 1);
6557
6604
  }
6558
6605
  }
6559
6606
  scan(rootDir, 0);
6560
6607
  return skillDirs;
6561
6608
  }
6562
6609
  function resolveLocalPkgDir(fromPath) {
6563
- const resolvedPath = path35.resolve(fromPath);
6564
- if (!fs21.existsSync(resolvedPath)) {
6610
+ const resolvedPath = path36.resolve(fromPath);
6611
+ if (!fs22.existsSync(resolvedPath)) {
6565
6612
  throw new Error(`--from path does not exist: ${resolvedPath}`);
6566
6613
  }
6567
- const stat = fs21.statSync(resolvedPath);
6614
+ const stat = fs22.statSync(resolvedPath);
6568
6615
  if (stat.isDirectory()) {
6569
6616
  return { pkgDir: resolvedPath, extractDir: null };
6570
6617
  }
6571
6618
  if (resolvedPath.endsWith(".tgz") || resolvedPath.endsWith(".tar.gz")) {
6572
- const tarballBuffer = fs21.readFileSync(resolvedPath);
6619
+ const tarballBuffer = fs22.readFileSync(resolvedPath);
6573
6620
  const extractDir = extractTarball(tarballBuffer);
6574
- return { pkgDir: path35.join(extractDir, "package"), extractDir };
6621
+ return { pkgDir: path36.join(extractDir, "package"), extractDir };
6575
6622
  }
6576
6623
  throw new Error(`--from path must be a directory or .tgz file. Got: ${resolvedPath}`);
6577
6624
  }
6578
6625
  function installSkillDir(pkgDir, resolvedPath, options) {
6579
- const skillYamlPath = path35.join(pkgDir, "skill.yaml");
6580
- if (!fs21.existsSync(skillYamlPath)) {
6626
+ const skillYamlPath = path36.join(pkgDir, "skill.yaml");
6627
+ if (!fs22.existsSync(skillYamlPath)) {
6581
6628
  throw new Error(`No skill.yaml found at ${skillYamlPath}`);
6582
6629
  }
6583
- const skillYaml = validateSkillYaml(yamlParse(fs21.readFileSync(skillYamlPath, "utf-8")));
6630
+ const skillYaml = validateSkillYaml(yamlParse(fs22.readFileSync(skillYamlPath, "utf-8")));
6584
6631
  const shortName = skillYaml.name;
6585
6632
  const { communityBase, lockfilePath } = resolveCommunityBase(options.global ?? false);
6586
6633
  if (!options.global) {
@@ -6608,7 +6655,7 @@ function installSkillDir(pkgDir, resolvedPath, options) {
6608
6655
  async function runLocalInstall(fromPath, options) {
6609
6656
  const { pkgDir, extractDir } = resolveLocalPkgDir(fromPath);
6610
6657
  try {
6611
- return installSkillDir(pkgDir, path35.resolve(fromPath), options);
6658
+ return installSkillDir(pkgDir, path36.resolve(fromPath), options);
6612
6659
  } finally {
6613
6660
  if (extractDir) cleanupTempDir(extractDir);
6614
6661
  }
@@ -6651,8 +6698,8 @@ async function runInstall(skillName, options) {
6651
6698
  version: installed.map((r) => r.version).join(", ")
6652
6699
  };
6653
6700
  }
6654
- const resolvedFrom = path35.resolve(options.from);
6655
- if (fs21.existsSync(resolvedFrom) && fs21.statSync(resolvedFrom).isDirectory() && !fs21.existsSync(path35.join(resolvedFrom, "skill.yaml"))) {
6701
+ const resolvedFrom = path36.resolve(options.from);
6702
+ if (fs22.existsSync(resolvedFrom) && fs22.statSync(resolvedFrom).isDirectory() && !fs22.existsSync(path36.join(resolvedFrom, "skill.yaml"))) {
6656
6703
  const results = await runBulkInstall(resolvedFrom, options);
6657
6704
  const installed = results.filter((r) => r.installed);
6658
6705
  return {
@@ -6693,12 +6740,12 @@ async function runInstall(skillName, options) {
6693
6740
  const extractDir = extractTarball(tarballBuffer);
6694
6741
  let skillYaml;
6695
6742
  try {
6696
- const extractedPkgDir = path35.join(extractDir, "package");
6697
- const skillYamlPath = path35.join(extractedPkgDir, "skill.yaml");
6698
- if (!fs21.existsSync(skillYamlPath)) {
6743
+ const extractedPkgDir = path36.join(extractDir, "package");
6744
+ const skillYamlPath = path36.join(extractedPkgDir, "skill.yaml");
6745
+ if (!fs22.existsSync(skillYamlPath)) {
6699
6746
  throw new Error(`contains invalid skill.yaml: file not found in package`);
6700
6747
  }
6701
- const rawYaml = fs21.readFileSync(skillYamlPath, "utf-8");
6748
+ const rawYaml = fs22.readFileSync(skillYamlPath, "utf-8");
6702
6749
  const parsed = yamlParse(rawYaml);
6703
6750
  skillYaml = validateSkillYaml(parsed);
6704
6751
  placeSkillContent(extractedPkgDir, communityBase, shortName, skillYaml.platforms);
@@ -6772,15 +6819,15 @@ function createInstallCommand() {
6772
6819
 
6773
6820
  // src/commands/install-constraints.ts
6774
6821
  init_dist3();
6775
- import * as fs22 from "fs/promises";
6776
- import * as path36 from "path";
6822
+ import * as fs23 from "fs/promises";
6823
+ import * as path37 from "path";
6777
6824
  import { Command as Command48 } from "commander";
6778
6825
  import semver3 from "semver";
6779
6826
  async function runInstallConstraints(options) {
6780
6827
  const { source, configPath, lockfilePath } = options;
6781
6828
  let rawBundle;
6782
6829
  try {
6783
- rawBundle = await fs22.readFile(source, "utf-8");
6830
+ rawBundle = await fs23.readFile(source, "utf-8");
6784
6831
  } catch (err) {
6785
6832
  if (isNodeError(err) && err.code === "ENOENT") {
6786
6833
  return { ok: false, error: `Bundle file not found: ${source}` };
@@ -6823,7 +6870,7 @@ async function runInstallConstraints(options) {
6823
6870
  }
6824
6871
  let localConfig;
6825
6872
  try {
6826
- const raw = await fs22.readFile(configPath, "utf-8");
6873
+ const raw = await fs23.readFile(configPath, "utf-8");
6827
6874
  localConfig = JSON.parse(raw);
6828
6875
  } catch (err) {
6829
6876
  return {
@@ -6971,7 +7018,7 @@ function isNodeError(err) {
6971
7018
  return err instanceof Error && "code" in err;
6972
7019
  }
6973
7020
  function resolveConfigPath(opts) {
6974
- if (opts.config) return path36.resolve(opts.config);
7021
+ if (opts.config) return path37.resolve(opts.config);
6975
7022
  const found = findConfigFile();
6976
7023
  if (!found.ok) {
6977
7024
  logger.error(found.error.message);
@@ -7006,9 +7053,9 @@ function logInstallResult(val, opts) {
7006
7053
  }
7007
7054
  async function handleInstallConstraints(source, opts) {
7008
7055
  const configPath = resolveConfigPath(opts);
7009
- const projectRoot2 = path36.dirname(configPath);
7010
- const lockfilePath = path36.join(projectRoot2, ".harness", "constraints.lock.json");
7011
- const resolvedSource = path36.resolve(source);
7056
+ const projectRoot3 = path37.dirname(configPath);
7057
+ const lockfilePath = path37.join(projectRoot3, ".harness", "constraints.lock.json");
7058
+ const resolvedSource = path37.resolve(source);
7012
7059
  if (opts.forceLocal && opts.forcePackage) {
7013
7060
  logger.error("Cannot use both --force-local and --force-package.");
7014
7061
  process.exit(1);
@@ -7039,8 +7086,8 @@ import { Command as Command53 } from "commander";
7039
7086
  // src/commands/integrations/add.ts
7040
7087
  init_dist3();
7041
7088
  import { Command as Command49 } from "commander";
7042
- import * as fs23 from "fs";
7043
- import * as path37 from "path";
7089
+ import * as fs24 from "fs";
7090
+ import * as path38 from "path";
7044
7091
  import chalk5 from "chalk";
7045
7092
  function buildMcpEntry(def) {
7046
7093
  const entry = { command: def.mcpConfig.command };
@@ -7049,14 +7096,14 @@ function buildMcpEntry(def) {
7049
7096
  return entry;
7050
7097
  }
7051
7098
  function writeMcpEntries(cwd, defName, mcpEntry) {
7052
- writeMcpEntry(path37.join(cwd, ".mcp.json"), defName, mcpEntry);
7053
- const geminiDir = path37.join(cwd, ".gemini");
7054
- if (fs23.existsSync(geminiDir)) {
7055
- writeMcpEntry(path37.join(geminiDir, "settings.json"), defName, mcpEntry);
7099
+ writeMcpEntry(path38.join(cwd, ".mcp.json"), defName, mcpEntry);
7100
+ const geminiDir = path38.join(cwd, ".gemini");
7101
+ if (fs24.existsSync(geminiDir)) {
7102
+ writeMcpEntry(path38.join(geminiDir, "settings.json"), defName, mcpEntry);
7056
7103
  }
7057
7104
  }
7058
7105
  function updateIntegrationsConfig(cwd, defName) {
7059
- const configPath = path37.join(cwd, "harness.config.json");
7106
+ const configPath = path38.join(cwd, "harness.config.json");
7060
7107
  const integConfig = readIntegrationsConfig(configPath);
7061
7108
  if (!integConfig.enabled.includes(defName)) integConfig.enabled.push(defName);
7062
7109
  integConfig.dismissed = integConfig.dismissed.filter((d) => d !== defName);
@@ -7117,7 +7164,7 @@ function createAddIntegrationCommand() {
7117
7164
 
7118
7165
  // src/commands/integrations/list.ts
7119
7166
  import { Command as Command50 } from "commander";
7120
- import * as path38 from "path";
7167
+ import * as path39 from "path";
7121
7168
  import chalk6 from "chalk";
7122
7169
  function printTier0Integrations(tier0, mcpServers) {
7123
7170
  console.log(" Tier 0 (zero-config):");
@@ -7141,8 +7188,8 @@ function printTier1Integrations(tier1, mcpServers, dismissed) {
7141
7188
  }
7142
7189
  async function runListIntegrations(globalOpts) {
7143
7190
  const cwd = process.cwd();
7144
- const mcpConfig = readMcpConfig(path38.join(cwd, ".mcp.json"));
7145
- const integConfig = readIntegrationsConfig(path38.join(cwd, "harness.config.json"));
7191
+ const mcpConfig = readMcpConfig(path39.join(cwd, ".mcp.json"));
7192
+ const integConfig = readIntegrationsConfig(path39.join(cwd, "harness.config.json"));
7146
7193
  const mcpServers = mcpConfig.mcpServers ?? {};
7147
7194
  if (globalOpts.json) {
7148
7195
  const entries = INTEGRATION_REGISTRY.map((i) => ({
@@ -7179,8 +7226,8 @@ function createListIntegrationsCommand() {
7179
7226
  // src/commands/integrations/remove.ts
7180
7227
  init_dist3();
7181
7228
  import { Command as Command51 } from "commander";
7182
- import * as fs24 from "fs";
7183
- import * as path39 from "path";
7229
+ import * as fs25 from "fs";
7230
+ import * as path40 from "path";
7184
7231
  function removeIntegration(cwd, name) {
7185
7232
  const def = INTEGRATION_REGISTRY.find((i) => i.name === name);
7186
7233
  if (!def) {
@@ -7191,14 +7238,14 @@ function removeIntegration(cwd, name) {
7191
7238
  )
7192
7239
  );
7193
7240
  }
7194
- const mcpPath = path39.join(cwd, ".mcp.json");
7241
+ const mcpPath = path40.join(cwd, ".mcp.json");
7195
7242
  removeMcpEntry(mcpPath, def.name);
7196
- const geminiDir = path39.join(cwd, ".gemini");
7197
- if (fs24.existsSync(geminiDir)) {
7198
- const geminiPath = path39.join(geminiDir, "settings.json");
7243
+ const geminiDir = path40.join(cwd, ".gemini");
7244
+ if (fs25.existsSync(geminiDir)) {
7245
+ const geminiPath = path40.join(geminiDir, "settings.json");
7199
7246
  removeMcpEntry(geminiPath, def.name);
7200
7247
  }
7201
- const configPath = path39.join(cwd, "harness.config.json");
7248
+ const configPath = path40.join(cwd, "harness.config.json");
7202
7249
  const integConfig = readIntegrationsConfig(configPath);
7203
7250
  integConfig.enabled = integConfig.enabled.filter((e) => e !== def.name);
7204
7251
  writeIntegrationsConfig(configPath, integConfig);
@@ -7228,7 +7275,7 @@ function createRemoveIntegrationCommand() {
7228
7275
  // src/commands/integrations/dismiss.ts
7229
7276
  init_dist3();
7230
7277
  import { Command as Command52 } from "commander";
7231
- import * as path40 from "path";
7278
+ import * as path41 from "path";
7232
7279
  function dismissIntegration(cwd, name) {
7233
7280
  const def = INTEGRATION_REGISTRY.find((i) => i.name === name);
7234
7281
  if (!def) {
@@ -7239,7 +7286,7 @@ function dismissIntegration(cwd, name) {
7239
7286
  )
7240
7287
  );
7241
7288
  }
7242
- const configPath = path40.join(cwd, "harness.config.json");
7289
+ const configPath = path41.join(cwd, "harness.config.json");
7243
7290
  const integConfig = readIntegrationsConfig(configPath);
7244
7291
  if (!integConfig.dismissed.includes(def.name)) {
7245
7292
  integConfig.dismissed.push(def.name);
@@ -7334,10 +7381,10 @@ function printResult3(result, mode, _formatter) {
7334
7381
  list.push(f);
7335
7382
  byFile.set(f.target.file, list);
7336
7383
  }
7337
- for (const [file, fs50] of byFile) {
7384
+ for (const [file, fs51] of byFile) {
7338
7385
  console.log(`
7339
7386
  ${file}`);
7340
- for (const f of fs50) {
7387
+ for (const f of fs51) {
7341
7388
  console.log(` ${f.code} [${f.tier}/${f.impact}/${f.confidence}] ${f.target.relative}`);
7342
7389
  console.log(` ${f.message}`);
7343
7390
  if (verbose) console.log(` source: ${f.cite.source}`);
@@ -7352,7 +7399,7 @@ ${file}`);
7352
7399
 
7353
7400
  // src/commands/knowledge-pipeline.ts
7354
7401
  import { Command as Command55 } from "commander";
7355
- import * as path41 from "path";
7402
+ import * as path42 from "path";
7356
7403
  import chalk7 from "chalk";
7357
7404
  function resolveInferenceOptions(cfgKnowledge) {
7358
7405
  const patterns = cfgKnowledge?.domainPatterns;
@@ -7519,9 +7566,9 @@ function createKnowledgePipelineCommand() {
7519
7566
  const globalOpts = cmd.optsWithGlobals();
7520
7567
  const projectDir = process.cwd();
7521
7568
  try {
7522
- const graphDir = path41.join(projectDir, ".harness", "graph");
7523
- const fs50 = await import("fs/promises");
7524
- await fs50.mkdir(graphDir, { recursive: true });
7569
+ const graphDir = path42.join(projectDir, ".harness", "graph");
7570
+ const fs51 = await import("fs/promises");
7571
+ await fs51.mkdir(graphDir, { recursive: true });
7525
7572
  const { GraphStore: GraphStore2, KnowledgePipelineRunner } = await import("./dist-DWBTZXR5.js");
7526
7573
  const store = new GraphStore2();
7527
7574
  try {
@@ -7566,9 +7613,9 @@ import { Command as Command57 } from "commander";
7566
7613
  // src/commands/learnings/prune.ts
7567
7614
  init_dist3();
7568
7615
  import { Command as Command56 } from "commander";
7569
- import * as path42 from "path";
7616
+ import * as path43 from "path";
7570
7617
  async function handlePrune(opts) {
7571
- const projectPath = path42.resolve(opts.path);
7618
+ const projectPath = path43.resolve(opts.path);
7572
7619
  const result = await pruneLearnings(projectPath, opts.stream);
7573
7620
  if (!result.ok) {
7574
7621
  logger.error(result.error.message);
@@ -7720,21 +7767,21 @@ function createLinterCommand() {
7720
7767
 
7721
7768
  // src/commands/maintenance.ts
7722
7769
  import { Command as Command61 } from "commander";
7723
- import * as path45 from "path";
7770
+ import * as path46 from "path";
7724
7771
  import chalk8 from "chalk";
7725
7772
  import { TaskOutputStore as TaskOutputStore2 } from "@harness-engineering/orchestrator";
7726
7773
 
7727
7774
  // src/commands/maintenance-config.ts
7728
- import * as path43 from "path";
7729
- import * as fs25 from "fs";
7775
+ import * as path44 from "path";
7776
+ import * as fs26 from "fs";
7730
7777
  import {
7731
7778
  BUILT_IN_TASKS,
7732
7779
  WorkflowLoader,
7733
7780
  migrateAgentConfig
7734
7781
  } from "@harness-engineering/orchestrator";
7735
7782
  async function loadMaintenanceConfig(cwd) {
7736
- const workflowPath = path43.join(cwd, "harness.orchestrator.md");
7737
- if (!fs25.existsSync(workflowPath)) return null;
7783
+ const workflowPath = path44.join(cwd, "harness.orchestrator.md");
7784
+ if (!fs26.existsSync(workflowPath)) return null;
7738
7785
  const loader = new WorkflowLoader();
7739
7786
  const result = await loader.loadWorkflow(workflowPath);
7740
7787
  if (!result.ok) return null;
@@ -7742,8 +7789,8 @@ async function loadMaintenanceConfig(cwd) {
7742
7789
  return result.value.config.maintenance ?? null;
7743
7790
  }
7744
7791
  async function loadAgentBackends(cwd) {
7745
- const workflowPath = path43.join(cwd, "harness.orchestrator.md");
7746
- if (!fs25.existsSync(workflowPath)) return null;
7792
+ const workflowPath = path44.join(cwd, "harness.orchestrator.md");
7793
+ if (!fs26.existsSync(workflowPath)) return null;
7747
7794
  const loader = new WorkflowLoader();
7748
7795
  const result = await loader.loadWorkflow(workflowPath);
7749
7796
  if (!result.ok) return null;
@@ -7814,9 +7861,9 @@ function copyOptional(src, dst, keys) {
7814
7861
  }
7815
7862
 
7816
7863
  // src/commands/maintenance-run.ts
7817
- import * as path44 from "path";
7864
+ import * as path45 from "path";
7818
7865
  import * as os6 from "os";
7819
- import * as fs26 from "fs";
7866
+ import * as fs27 from "fs";
7820
7867
  import { execFile, execFileSync as execFileSync4 } from "child_process";
7821
7868
  import { promisify } from "util";
7822
7869
  import {
@@ -7909,7 +7956,7 @@ function createFixDispatcher(resolveBackend, git = realGit) {
7909
7956
  }
7910
7957
  function buildTaskRunner(cwd, config, mode, harnessEntry, resolveBackend = () => null) {
7911
7958
  const outputStore = new TaskOutputStore({
7912
- rootDir: path44.join(cwd, ".harness", "maintenance")
7959
+ rootDir: path45.join(cwd, ".harness", "maintenance")
7913
7960
  });
7914
7961
  return new TaskRunner({
7915
7962
  config,
@@ -7924,7 +7971,7 @@ function buildTaskRunner(cwd, config, mode, harnessEntry, resolveBackend = () =>
7924
7971
  }
7925
7972
  async function loadRunHistory(cwd) {
7926
7973
  const reporter = new MaintenanceReporter({
7927
- persistDir: path44.join(cwd, ".harness", "maintenance")
7974
+ persistDir: path45.join(cwd, ".harness", "maintenance")
7928
7975
  });
7929
7976
  await reporter.load();
7930
7977
  return reporter.getHistory(500, 0);
@@ -8032,16 +8079,16 @@ function renderTable(report) {
8032
8079
  var NO_BACKEND_FIX_WARNING = "--fix: no agent backend configured for maintenance dispatch \u2014 dispatch was skipped and nothing was fixed. Configure agent.backends in harness.orchestrator.md (and maintenance.aiBackend), or run maintenance via the orchestrator.";
8033
8080
  async function defaultRecord(cwd, results) {
8034
8081
  const reporter = new MaintenanceReporter({
8035
- persistDir: path44.join(cwd, ".harness", "maintenance")
8082
+ persistDir: path45.join(cwd, ".harness", "maintenance")
8036
8083
  });
8037
8084
  await reporter.load();
8038
8085
  for (const r of results) await reporter.record(r);
8039
8086
  }
8040
8087
  function writeSummary(cwd, report) {
8041
- const dir = path44.join(cwd, ".harness", "maintenance");
8042
- fs26.mkdirSync(dir, { recursive: true });
8043
- fs26.writeFileSync(
8044
- path44.join(dir, "last-run-summary.json"),
8088
+ const dir = path45.join(cwd, ".harness", "maintenance");
8089
+ fs27.mkdirSync(dir, { recursive: true });
8090
+ fs27.writeFileSync(
8091
+ path45.join(dir, "last-run-summary.json"),
8045
8092
  JSON.stringify(report, null, 2),
8046
8093
  "utf-8"
8047
8094
  );
@@ -8168,7 +8215,7 @@ function createMaintenanceCommand() {
8168
8215
  "Inspect built-in + custom maintenance tasks and their persisted outputs"
8169
8216
  );
8170
8217
  command.command("list").description("List all resolved maintenance tasks (built-in + customTasks)").option("--json", "Emit machine-readable JSON", false).option("--path <path>", "Project root path", ".").action(async (opts) => {
8171
- const cwd = path45.resolve(opts.path);
8218
+ const cwd = path46.resolve(opts.path);
8172
8219
  const config = await loadMaintenanceConfig(cwd);
8173
8220
  const tasks = mergeResolvedTasks(config);
8174
8221
  const rows = tasks.map((t) => ({
@@ -8189,7 +8236,7 @@ function createMaintenanceCommand() {
8189
8236
  process.exit(ExitCode.SUCCESS);
8190
8237
  });
8191
8238
  command.command("run [taskId...]").description("Run overdue (default) / selected maintenance tasks; report-first unless --fix").option("--all", "Run all sweep-eligible tasks (not just overdue)", false).option("--only <ids>", "Comma-separated task ids to run").option("--skip <ids>", "Comma-separated task ids to exclude").option("--fix", "Dispatch fixes per task type (default: report-only)", false).option("--concurrency <n>", "Max parallel tasks (report mode); --fix forces 1").option("--json", "Emit machine-readable consolidated report", false).option("--path <path>", "Project root path", ".").action(async (taskIds, opts, command2) => {
8192
- const cwd = path45.resolve(opts.path);
8239
+ const cwd = path46.resolve(opts.path);
8193
8240
  const json = Boolean(command2.optsWithGlobals().json);
8194
8241
  const result = await runMaintenanceRun(cwd, {
8195
8242
  positional: taskIds,
@@ -8209,10 +8256,10 @@ async function runShow(taskId, opts) {
8209
8256
  console.error(`Invalid task id '${taskId}' (must match ^[a-z0-9][a-z0-9-]*$).`);
8210
8257
  process.exit(ExitCode.ERROR);
8211
8258
  }
8212
- const cwd = path45.resolve(opts.path ?? ".");
8259
+ const cwd = path46.resolve(opts.path ?? ".");
8213
8260
  const limit = Math.max(1, parseInt(opts.limit ?? "5", 10) || 5);
8214
8261
  const store = new TaskOutputStore2({
8215
- rootDir: path45.join(cwd, ".harness", "maintenance")
8262
+ rootDir: path46.join(cwd, ".harness", "maintenance")
8216
8263
  });
8217
8264
  const entries = await store.list(taskId, limit, 0);
8218
8265
  renderShow(taskId, entries, Boolean(opts.json));
@@ -8273,7 +8320,7 @@ function createMcpCommand() {
8273
8320
  parseBudget
8274
8321
  ).action(async (opts) => {
8275
8322
  const [{ startServer: startServer2, getToolDefinitions: getToolDefinitions2 }, { selectTier }] = await Promise.all([
8276
- import("./mcp-5V4LPMB3.js"),
8323
+ import("./mcp-RIPEYDMU.js"),
8277
8324
  import("./tool-tiers-OKK5FE57.js")
8278
8325
  ]);
8279
8326
  if (opts.tools && opts.tools.length > 0) {
@@ -8296,8 +8343,8 @@ function createMcpCommand() {
8296
8343
  // src/commands/mcp-guard.ts
8297
8344
  init_dist3();
8298
8345
  import { Command as Command63 } from "commander";
8299
- import * as fs27 from "fs";
8300
- import * as path46 from "path";
8346
+ import * as fs28 from "fs";
8347
+ import * as path47 from "path";
8301
8348
  import chalk9 from "chalk";
8302
8349
  function extractNpmPackages(config) {
8303
8350
  const out = [];
@@ -8336,18 +8383,18 @@ function parseNpmSpec(spec) {
8336
8383
  }
8337
8384
  async function runMcpGuardCheck(options = {}) {
8338
8385
  const cwd = options.cwd ?? process.cwd();
8339
- const configPath = options.configPath ?? path46.join(cwd, ".mcp.json");
8340
- if (!fs27.existsSync(configPath)) {
8386
+ const configPath = options.configPath ?? path47.join(cwd, ".mcp.json");
8387
+ if (!fs28.existsSync(configPath)) {
8341
8388
  return { ok: true, checked: [] };
8342
8389
  }
8343
8390
  let config;
8344
8391
  try {
8345
- config = JSON.parse(fs27.readFileSync(configPath, "utf-8"));
8392
+ config = JSON.parse(fs28.readFileSync(configPath, "utf-8"));
8346
8393
  } catch {
8347
8394
  return { ok: true, checked: [] };
8348
8395
  }
8349
8396
  const pkgs = extractNpmPackages(config);
8350
- const cacheDir = path46.join(cwd, ".harness", "cache", "osv");
8397
+ const cacheDir = path47.join(cwd, ".harness", "cache", "osv");
8351
8398
  const warnLogger = {
8352
8399
  warn: (m, ctx) => logger.warn(ctx ? `${m} ${JSON.stringify(ctx)}` : m)
8353
8400
  };
@@ -8408,7 +8455,7 @@ function createMcpGuardCommand() {
8408
8455
  '\nUse "harness mcp-guard check" before launching MCP servers to block known malicious packages.'
8409
8456
  );
8410
8457
  command.command("check").description("Check every MCP/npx package in .mcp.json against OSV.dev advisories").option("--strict", "Fail closed on network errors (default: fail-open)", false).option("--json", "Emit machine-readable JSON", false).option("--path <path>", "Project root path", ".").action(async (opts) => {
8411
- const cwd = path46.resolve(opts.path);
8458
+ const cwd = path47.resolve(opts.path);
8412
8459
  const result = await runMcpGuardCheck({ cwd, strict: opts.strict, json: opts.json });
8413
8460
  if (opts.json) {
8414
8461
  console.log(JSON.stringify(result, null, 2));
@@ -8419,10 +8466,10 @@ function createMcpGuardCommand() {
8419
8466
  process.exit(result.ok ? ExitCode.SUCCESS : 2);
8420
8467
  });
8421
8468
  command.command("cache").description("Manage the on-disk OSV advisory cache").command("clear").option("--path <path>", "Project root path", ".").action(async (opts) => {
8422
- const cwd = path46.resolve(opts.path);
8423
- const cacheDir = path46.join(cwd, ".harness", "cache", "osv");
8469
+ const cwd = path47.resolve(opts.path);
8470
+ const cacheDir = path47.join(cwd, ".harness", "cache", "osv");
8424
8471
  try {
8425
- fs27.rmSync(cacheDir, { recursive: true, force: true });
8472
+ fs28.rmSync(cacheDir, { recursive: true, force: true });
8426
8473
  console.log(`Cleared ${cacheDir}`);
8427
8474
  } catch (err) {
8428
8475
  logger.error(`Failed to clear cache: ${err instanceof Error ? err.message : String(err)}`);
@@ -8438,8 +8485,8 @@ import { Command as Command65 } from "commander";
8438
8485
 
8439
8486
  // src/commands/migrate-backends.ts
8440
8487
  import { Command as Command64 } from "commander";
8441
- import * as fs28 from "fs";
8442
- import * as path47 from "path";
8488
+ import * as fs29 from "fs";
8489
+ import * as path48 from "path";
8443
8490
  import chalk10 from "chalk";
8444
8491
  import { parse as parseYaml2 } from "yaml";
8445
8492
  async function runMigrateBackends(opts = {}) {
@@ -8461,8 +8508,8 @@ async function runMigrateBackends(opts = {}) {
8461
8508
  };
8462
8509
  }
8463
8510
  const routing = readRoutingFromOrchestratorMd(mdPath);
8464
- const jsonPath = path47.join(path47.dirname(mdPath), "harness.config.json");
8465
- if (!fs28.existsSync(jsonPath)) {
8511
+ const jsonPath = path48.join(path48.dirname(mdPath), "harness.config.json");
8512
+ if (!fs29.existsSync(jsonPath)) {
8466
8513
  return {
8467
8514
  status: "error",
8468
8515
  message: `harness.config.json not found at ${jsonPath}. Run \`harness init\` first, then re-run this migration.`,
@@ -8471,7 +8518,7 @@ async function runMigrateBackends(opts = {}) {
8471
8518
  }
8472
8519
  let configRaw;
8473
8520
  try {
8474
- configRaw = fs28.readFileSync(jsonPath, "utf-8");
8521
+ configRaw = fs29.readFileSync(jsonPath, "utf-8");
8475
8522
  } catch (err) {
8476
8523
  return {
8477
8524
  status: "error",
@@ -8518,7 +8565,7 @@ async function runMigrateBackends(opts = {}) {
8518
8565
  };
8519
8566
  }
8520
8567
  try {
8521
- fs28.writeFileSync(jsonPath, nextJson);
8568
+ fs29.writeFileSync(jsonPath, nextJson);
8522
8569
  } catch (err) {
8523
8570
  return {
8524
8571
  status: "error",
@@ -8535,7 +8582,7 @@ async function runMigrateBackends(opts = {}) {
8535
8582
  function readRoutingFromOrchestratorMd(mdPath) {
8536
8583
  let raw;
8537
8584
  try {
8538
- raw = fs28.readFileSync(mdPath, "utf-8");
8585
+ raw = fs29.readFileSync(mdPath, "utf-8");
8539
8586
  } catch {
8540
8587
  return null;
8541
8588
  }
@@ -8573,8 +8620,8 @@ function createBackendsSubcommand() {
8573
8620
  // src/commands/migrate.ts
8574
8621
  init_dist3();
8575
8622
  init_dist2();
8576
- import * as fs29 from "fs";
8577
- import * as path48 from "path";
8623
+ import * as fs30 from "fs";
8624
+ import * as path49 from "path";
8578
8625
  import * as readline from "readline";
8579
8626
  import { execFileSync as execFileSync5 } from "child_process";
8580
8627
  import chalk11 from "chalk";
@@ -8588,25 +8635,25 @@ function isGitRepo(cwd) {
8588
8635
  }
8589
8636
  function readJson2(p) {
8590
8637
  try {
8591
- return JSON.parse(fs29.readFileSync(p, "utf8"));
8638
+ return JSON.parse(fs30.readFileSync(p, "utf8"));
8592
8639
  } catch {
8593
8640
  return null;
8594
8641
  }
8595
8642
  }
8596
8643
  function listDirs(p) {
8597
- if (!fs29.existsSync(p)) return [];
8598
- return fs29.readdirSync(p, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name);
8644
+ if (!fs30.existsSync(p)) return [];
8645
+ return fs30.readdirSync(p, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name);
8599
8646
  }
8600
8647
  function listFiles(p, predicate) {
8601
- if (!fs29.existsSync(p)) return [];
8602
- return fs29.readdirSync(p, { withFileTypes: true }).filter((e) => e.isFile() && predicate(e.name)).map((e) => e.name);
8648
+ if (!fs30.existsSync(p)) return [];
8649
+ return fs30.readdirSync(p, { withFileTypes: true }).filter((e) => e.isFile() && predicate(e.name)).map((e) => e.name);
8603
8650
  }
8604
8651
  function walk(dir, predicate) {
8605
- if (!fs29.existsSync(dir)) return [];
8652
+ if (!fs30.existsSync(dir)) return [];
8606
8653
  const out = [];
8607
- for (const entry of fs29.readdirSync(dir, { withFileTypes: true })) {
8654
+ for (const entry of fs30.readdirSync(dir, { withFileTypes: true })) {
8608
8655
  if (DEFAULT_SKIP_DIRS.has(entry.name)) continue;
8609
- const full = path48.join(dir, entry.name);
8656
+ const full = path49.join(dir, entry.name);
8610
8657
  if (entry.isDirectory()) out.push(...walk(full, predicate));
8611
8658
  else if (predicate(full)) out.push(full);
8612
8659
  }
@@ -8618,11 +8665,11 @@ function extractAutopilotTopic(state) {
8618
8665
  }
8619
8666
  function buildAutopilotMap(cwd) {
8620
8667
  const map = /* @__PURE__ */ new Map();
8621
- const sessionsDir = path48.join(cwd, ".harness", "sessions");
8622
- if (!fs29.existsSync(sessionsDir)) return map;
8668
+ const sessionsDir = path49.join(cwd, ".harness", "sessions");
8669
+ if (!fs30.existsSync(sessionsDir)) return map;
8623
8670
  for (const session of listDirs(sessionsDir)) {
8624
8671
  if (!session.startsWith("changes--")) continue;
8625
- const state = readJson2(path48.join(sessionsDir, session, "autopilot-state.json"));
8672
+ const state = readJson2(path49.join(sessionsDir, session, "autopilot-state.json"));
8626
8673
  if (!state) continue;
8627
8674
  const topic = extractAutopilotTopic(state);
8628
8675
  if (!topic) continue;
@@ -8635,7 +8682,7 @@ function buildAutopilotMap(cwd) {
8635
8682
  function extractTopicFromHeader(planAbs, proposalTopics) {
8636
8683
  let text;
8637
8684
  try {
8638
- text = fs29.readFileSync(planAbs, "utf8").slice(0, 4e3);
8685
+ text = fs30.readFileSync(planAbs, "utf8").slice(0, 4e3);
8639
8686
  } catch {
8640
8687
  return null;
8641
8688
  }
@@ -8660,8 +8707,8 @@ function extractTopicFromFilename(filename, proposalTopics) {
8660
8707
  return best;
8661
8708
  }
8662
8709
  function resolveDocsDir(cwd) {
8663
- const configPath = path48.join(cwd, "harness.config.json");
8664
- const configResult = fs29.existsSync(configPath) ? resolveConfig(configPath) : null;
8710
+ const configPath = path49.join(cwd, "harness.config.json");
8711
+ const configResult = fs30.existsSync(configPath) ? resolveConfig(configPath) : null;
8665
8712
  let docsDir;
8666
8713
  if (configResult?.ok) {
8667
8714
  docsDir = configResult.value.docsDir;
@@ -8673,16 +8720,16 @@ function resolveDocsDir(cwd) {
8673
8720
  } else {
8674
8721
  docsDir = "./docs";
8675
8722
  }
8676
- const docsAbs = path48.resolve(cwd, docsDir);
8677
- const relRaw = path48.relative(cwd, docsAbs).replaceAll("\\", "/");
8723
+ const docsAbs = path49.resolve(cwd, docsDir);
8724
+ const relRaw = path49.relative(cwd, docsAbs).replaceAll("\\", "/");
8678
8725
  return relRaw === "" ? "docs" : relRaw;
8679
8726
  }
8680
8727
  function collectAdrMoves(cwd, docsRel) {
8681
8728
  const moves = [];
8682
- const legacyAdrDir = path48.join(cwd, ".harness", "architecture");
8683
- if (!fs29.existsSync(legacyAdrDir)) return moves;
8729
+ const legacyAdrDir = path49.join(cwd, ".harness", "architecture");
8730
+ if (!fs30.existsSync(legacyAdrDir)) return moves;
8684
8731
  for (const topic of listDirs(legacyAdrDir)) {
8685
- const topicSrc = path48.join(legacyAdrDir, topic);
8732
+ const topicSrc = path49.join(legacyAdrDir, topic);
8686
8733
  for (const file of listFiles(topicSrc, (n) => n.endsWith(".md"))) {
8687
8734
  moves.push({
8688
8735
  src: `.harness/architecture/${topic}/${file}`,
@@ -8694,9 +8741,9 @@ function collectAdrMoves(cwd, docsRel) {
8694
8741
  }
8695
8742
  function collectProposalTopics(cwd) {
8696
8743
  const topics = /* @__PURE__ */ new Set();
8697
- const changesDir = path48.join(cwd, "docs", "changes");
8744
+ const changesDir = path49.join(cwd, "docs", "changes");
8698
8745
  for (const topic of listDirs(changesDir)) {
8699
- if (fs29.existsSync(path48.join(changesDir, topic, "proposal.md"))) {
8746
+ if (fs30.existsSync(path49.join(changesDir, topic, "proposal.md"))) {
8700
8747
  topics.add(topic);
8701
8748
  }
8702
8749
  }
@@ -8723,12 +8770,12 @@ async function buildPlan(opts) {
8723
8770
  orphanPlans: [],
8724
8771
  proposalTopics: collectProposalTopics(cwd)
8725
8772
  };
8726
- const legacyPlanDir = path48.join(cwd, "docs", "plans");
8727
- if (!fs29.existsSync(legacyPlanDir)) return plan;
8773
+ const legacyPlanDir = path49.join(cwd, "docs", "plans");
8774
+ if (!fs30.existsSync(legacyPlanDir)) return plan;
8728
8775
  const autopilotMap = buildAutopilotMap(cwd);
8729
8776
  for (const file of listFiles(legacyPlanDir, (n) => n.endsWith(".md") && n !== "index.md")) {
8730
8777
  const planRel = `docs/plans/${file}`;
8731
- const planAbs = path48.join(legacyPlanDir, file);
8778
+ const planAbs = path49.join(legacyPlanDir, file);
8732
8779
  const subdir = file.includes("VERIFICATION") ? "verifications" : "plans";
8733
8780
  const classified = classifyPlan(planRel, planAbs, file, autopilotMap, plan.proposalTopics);
8734
8781
  if (classified) {
@@ -8746,8 +8793,8 @@ async function buildPlan(opts) {
8746
8793
  return plan;
8747
8794
  }
8748
8795
  function gitMv(cwd, src, dest, useGit) {
8749
- const destAbs = path48.join(cwd, dest);
8750
- fs29.mkdirSync(path48.dirname(destAbs), { recursive: true });
8796
+ const destAbs = path49.join(cwd, dest);
8797
+ fs30.mkdirSync(path49.dirname(destAbs), { recursive: true });
8751
8798
  if (useGit) {
8752
8799
  try {
8753
8800
  execFileSync5("git", ["mv", src, dest], { cwd, stdio: "pipe" });
@@ -8755,7 +8802,7 @@ function gitMv(cwd, src, dest, useGit) {
8755
8802
  } catch {
8756
8803
  }
8757
8804
  }
8758
- fs29.renameSync(path48.join(cwd, src), destAbs);
8805
+ fs30.renameSync(path49.join(cwd, src), destAbs);
8759
8806
  }
8760
8807
  function executeMigration(plan) {
8761
8808
  let moved = 0;
@@ -8787,13 +8834,13 @@ function updateReferences(plan) {
8787
8834
  let files = 0;
8788
8835
  let replacements = 0;
8789
8836
  const targets = [
8790
- ...walk(path48.join(plan.cwd, "docs"), (p) => p.endsWith(".md")),
8791
- ...walk(path48.join(plan.cwd, ".harness", "sessions"), (p) => p.endsWith(".json"))
8837
+ ...walk(path49.join(plan.cwd, "docs"), (p) => p.endsWith(".md")),
8838
+ ...walk(path49.join(plan.cwd, ".harness", "sessions"), (p) => p.endsWith(".json"))
8792
8839
  ];
8793
8840
  for (const target of targets) {
8794
8841
  let text;
8795
8842
  try {
8796
- text = fs29.readFileSync(target, "utf8");
8843
+ text = fs30.readFileSync(target, "utf8");
8797
8844
  } catch {
8798
8845
  continue;
8799
8846
  }
@@ -8806,7 +8853,7 @@ function updateReferences(plan) {
8806
8853
  count += occurrences;
8807
8854
  }
8808
8855
  if (count > 0 && result !== text) {
8809
- fs29.writeFileSync(target, result);
8856
+ fs30.writeFileSync(target, result);
8810
8857
  files++;
8811
8858
  replacements += count;
8812
8859
  }
@@ -8815,7 +8862,7 @@ function updateReferences(plan) {
8815
8862
  }
8816
8863
  async function prompt(question, def = "n") {
8817
8864
  const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
8818
- const answer = await new Promise((resolve48) => rl.question(question, resolve48));
8865
+ const answer = await new Promise((resolve50) => rl.question(question, resolve50));
8819
8866
  rl.close();
8820
8867
  return (answer.trim() || def).toLowerCase();
8821
8868
  }
@@ -8865,7 +8912,7 @@ async function resolveOrphans(plan, opts) {
8865
8912
  }
8866
8913
  function bucketOrphans(plan, topic) {
8867
8914
  for (const src of plan.orphanPlans) {
8868
- const file = path48.basename(src);
8915
+ const file = path49.basename(src);
8869
8916
  const isVerification = file.includes("VERIFICATION");
8870
8917
  const subdir = isVerification ? "verifications" : "plans";
8871
8918
  plan.planMoves.push({
@@ -8907,10 +8954,10 @@ function summarize(plan) {
8907
8954
  console.log("");
8908
8955
  }
8909
8956
  async function detectLegacyArtifacts(cwd) {
8910
- const adrLegacyDir = path48.join(cwd, ".harness", "architecture");
8911
- const adrLegacy = fs29.existsSync(adrLegacyDir) && listDirs(adrLegacyDir).length > 0;
8912
- const planLegacyDir = path48.join(cwd, "docs", "plans");
8913
- const planLegacy = fs29.existsSync(planLegacyDir) && listFiles(planLegacyDir, (n) => n.endsWith(".md") && n !== "index.md").length > 0;
8957
+ const adrLegacyDir = path49.join(cwd, ".harness", "architecture");
8958
+ const adrLegacy = fs30.existsSync(adrLegacyDir) && listDirs(adrLegacyDir).length > 0;
8959
+ const planLegacyDir = path49.join(cwd, "docs", "plans");
8960
+ const planLegacy = fs30.existsSync(planLegacyDir) && listFiles(planLegacyDir, (n) => n.endsWith(".md") && n !== "index.md").length > 0;
8914
8961
  return { adrLegacy, planLegacy };
8915
8962
  }
8916
8963
  async function confirmApply(opts) {
@@ -9002,7 +9049,9 @@ function createMigrateCommand() {
9002
9049
  }
9003
9050
 
9004
9051
  // src/commands/models.ts
9052
+ init_dist3();
9005
9053
  import { Command as Command66 } from "commander";
9054
+ import { resolve as resolve31 } from "path";
9006
9055
  import { defaultFetchModels } from "@harness-engineering/orchestrator";
9007
9056
  function errorResult(message, partial) {
9008
9057
  return {
@@ -9119,29 +9168,183 @@ function formatProbe(result) {
9119
9168
  }
9120
9169
  return lines.join("\n");
9121
9170
  }
9122
- function createModelsCommand() {
9123
- const cmd = new Command66("models").description(
9124
- "Inspect and manage local LLM backends. Currently ships `probe`; LMLM phases add status/suggest/pool/proposals."
9125
- );
9171
+ function projectRoot() {
9172
+ return resolve31(process.env["HARNESS_PROJECT_ROOT"] ?? process.cwd());
9173
+ }
9174
+ function summarizeModelProposal(p) {
9175
+ const base = { id: p.id, status: p.status, proposedBy: p.proposedBy, createdAt: p.createdAt };
9176
+ if (p.kind !== "model") return { ...base, kind: p.kind };
9177
+ return {
9178
+ ...base,
9179
+ kind: "model",
9180
+ action: p.model.action,
9181
+ target: p.model.target.ollamaName,
9182
+ replaces: p.model.replaces?.ollamaName,
9183
+ scoreDelta: p.model.scoreDelta
9184
+ };
9185
+ }
9186
+ async function runModelsProposals(status = "open") {
9187
+ const opts = { kind: "model" };
9188
+ if (status !== "all") opts.status = status;
9189
+ const proposals = await listProposals(projectRoot(), opts);
9190
+ return proposals.map(summarizeModelProposal);
9191
+ }
9192
+ async function runModelsApprove(id) {
9193
+ const orchestratorUrl = process.env["HARNESS_ORCHESTRATOR_URL"] ?? "http://127.0.0.1:4577";
9194
+ const token = process.env["HARNESS_ADMIN_TOKEN"];
9195
+ if (!token) {
9196
+ return {
9197
+ ok: false,
9198
+ error: "HARNESS_ADMIN_TOKEN is required to approve proposals (manage-proposals scope)."
9199
+ };
9200
+ }
9201
+ try {
9202
+ const res = await fetch(`${orchestratorUrl}/api/v1/proposals/${id}/approve`, {
9203
+ method: "POST",
9204
+ headers: { authorization: `Bearer ${token}` }
9205
+ });
9206
+ return { ok: res.ok, status: res.status, body: await res.text() };
9207
+ } catch (err) {
9208
+ return { ok: false, error: err instanceof Error ? err.message : String(err) };
9209
+ }
9210
+ }
9211
+ async function runModelsReject(id, reason) {
9212
+ const orchestratorUrl = process.env["HARNESS_ORCHESTRATOR_URL"] ?? "http://127.0.0.1:4577";
9213
+ const token = process.env["HARNESS_ADMIN_TOKEN"];
9214
+ if (!token) {
9215
+ return {
9216
+ ok: false,
9217
+ error: "HARNESS_ADMIN_TOKEN is required to reject proposals (manage-proposals scope)."
9218
+ };
9219
+ }
9220
+ try {
9221
+ const res = await fetch(`${orchestratorUrl}/api/v1/proposals/${id}/reject`, {
9222
+ method: "POST",
9223
+ headers: { authorization: `Bearer ${token}`, "content-type": "application/json" },
9224
+ body: JSON.stringify({ reason })
9225
+ });
9226
+ return { ok: res.ok, status: res.status, body: await res.text() };
9227
+ } catch (err) {
9228
+ return { ok: false, error: err instanceof Error ? err.message : String(err) };
9229
+ }
9230
+ }
9231
+ async function runModelsRefresh() {
9232
+ const orchestratorUrl = process.env["HARNESS_ORCHESTRATOR_URL"] ?? "http://127.0.0.1:4577";
9233
+ const token = process.env["HARNESS_ADMIN_TOKEN"];
9234
+ if (!token) {
9235
+ return {
9236
+ ok: false,
9237
+ error: "HARNESS_ADMIN_TOKEN is required to trigger a refresh (manage-proposals scope)."
9238
+ };
9239
+ }
9240
+ try {
9241
+ const res = await fetch(`${orchestratorUrl}/api/v1/local-models/refresh`, {
9242
+ method: "POST",
9243
+ headers: { authorization: `Bearer ${token}` }
9244
+ });
9245
+ return buildRefreshResult(res, await res.text());
9246
+ } catch (err) {
9247
+ return { ok: false, error: err instanceof Error ? err.message : String(err) };
9248
+ }
9249
+ }
9250
+ function buildRefreshResult(res, body) {
9251
+ const parsed = safeParseObject(body);
9252
+ const emitted = parsed?.["emitted"];
9253
+ const warnings = parsed?.["warnings"];
9254
+ const error = parsed?.["error"];
9255
+ return {
9256
+ ok: res.ok,
9257
+ status: res.status,
9258
+ ...typeof emitted === "number" ? { emitted } : {},
9259
+ ...Array.isArray(warnings) ? { warnings } : {},
9260
+ ...res.ok ? {} : { error: typeof error === "string" ? error : `HTTP ${res.status}` },
9261
+ body
9262
+ };
9263
+ }
9264
+ function safeParseObject(body) {
9265
+ try {
9266
+ const v = JSON.parse(body);
9267
+ return v !== null && typeof v === "object" ? v : void 0;
9268
+ } catch {
9269
+ return void 0;
9270
+ }
9271
+ }
9272
+ function refreshExitCode(result) {
9273
+ return result.ok ? ExitCode.SUCCESS : ExitCode.ERROR;
9274
+ }
9275
+ function httpErrorLine(r) {
9276
+ return r.error ?? `HTTP ${r.status ?? "?"}: ${r.body ?? ""}`;
9277
+ }
9278
+ function reportMutation(result) {
9279
+ if (!result.ok) {
9280
+ logger.error(httpErrorLine(result));
9281
+ process.exit(ExitCode.ERROR);
9282
+ }
9283
+ console.log(result.body ?? "");
9284
+ }
9285
+ async function probeAction(options) {
9286
+ const result = await runModelsProbe(options);
9287
+ if (options.json) {
9288
+ console.log(JSON.stringify(result, null, 2));
9289
+ } else {
9290
+ const text = formatProbe(result);
9291
+ if (result.status === "error" || result.status === "no-match") logger.error(text);
9292
+ else logger.info(text);
9293
+ }
9294
+ process.exit(result.exitCode);
9295
+ }
9296
+ async function refreshAction() {
9297
+ const result = await runModelsRefresh();
9298
+ if (!result.ok) {
9299
+ logger.error(httpErrorLine(result));
9300
+ } else {
9301
+ logger.info(`refresh: emitted ${result.emitted ?? 0} proposal(s)`);
9302
+ for (const w of result.warnings ?? []) logger.warn(` warning: ${w}`);
9303
+ }
9304
+ process.exitCode = refreshExitCode(result);
9305
+ }
9306
+ function addProbeCommand(cmd) {
9126
9307
  cmd.command("probe").description(
9127
9308
  "Probe a local backend's /v1/models endpoint and report which configured model is loaded."
9128
9309
  ).option(
9129
9310
  "--backend <name>",
9130
9311
  "Name of an entry in agent.backends. Defaults to the first local/pi entry."
9131
- ).option("--endpoint <url>", "Override the backend endpoint (bypasses harness.config.json).").option("--api-key <key>", "Override the API key.").option("--json", "Print machine-readable JSON instead of a human summary.", false).action(async (options) => {
9132
- const result = await runModelsProbe(options);
9133
- if (options.json) {
9134
- console.log(JSON.stringify(result, null, 2));
9135
- } else {
9136
- const text = formatProbe(result);
9137
- if (result.status === "error" || result.status === "no-match") {
9138
- logger.error(text);
9139
- } else {
9140
- logger.info(text);
9141
- }
9142
- }
9143
- process.exit(result.exitCode);
9312
+ ).option("--endpoint <url>", "Override the backend endpoint (bypasses harness.config.json).").option("--api-key <key>", "Override the API key.").option("--json", "Print machine-readable JSON instead of a human summary.", false).action(probeAction);
9313
+ }
9314
+ function addProposalsCommand(cmd) {
9315
+ cmd.command("proposals").description("List model proposals in the local review queue (defaults to pending).").option("--status <status>", "Filter by status (open | approved | rejected | all).", "open").action(async (options) => {
9316
+ const rows = await runModelsProposals(options.status ?? "open");
9317
+ console.log(JSON.stringify(rows, null, 2));
9144
9318
  });
9319
+ }
9320
+ function addRejectCommand(cmd) {
9321
+ cmd.command("reject <id>").description(
9322
+ "Reject a model proposal with a one-line reason (records the decision + fires the bus event). Requires the orchestrator to be running and HARNESS_ADMIN_TOKEN."
9323
+ ).requiredOption("--reason <text>", "Why the proposal is being rejected").action(async (id, options) => {
9324
+ reportMutation(await runModelsReject(id, options.reason));
9325
+ });
9326
+ }
9327
+ function addApproveCommand(cmd) {
9328
+ cmd.command("approve <id>").description(
9329
+ "Approve a model proposal (drives the installer + pool update). Requires the orchestrator to be running and HARNESS_ADMIN_TOKEN."
9330
+ ).action(async (id) => {
9331
+ reportMutation(await runModelsApprove(id));
9332
+ });
9333
+ }
9334
+ function addRefreshCommand(cmd) {
9335
+ cmd.command("refresh").description(
9336
+ "Force a background-scheduler refresh tick now (emits any model proposals). Exits non-zero on an O4 hard failure (HuggingFace unreachable AND no benchmark snapshot). Requires the orchestrator running + HARNESS_ADMIN_TOKEN."
9337
+ ).action(refreshAction);
9338
+ }
9339
+ function createModelsCommand() {
9340
+ const cmd = new Command66("models").description(
9341
+ "Inspect and manage local LLM backends. Ships `probe`, model-proposal review (proposals/approve/reject), and `refresh` (force a scheduler tick)."
9342
+ );
9343
+ addProbeCommand(cmd);
9344
+ addProposalsCommand(cmd);
9345
+ addRejectCommand(cmd);
9346
+ addApproveCommand(cmd);
9347
+ addRefreshCommand(cmd);
9145
9348
  return cmd;
9146
9349
  }
9147
9350
 
@@ -9198,10 +9401,10 @@ function printResult4(result, mode, _formatter) {
9198
9401
  list.push(f);
9199
9402
  byFile.set(f.target.file, list);
9200
9403
  }
9201
- for (const [file, fs50] of byFile) {
9404
+ for (const [file, fs51] of byFile) {
9202
9405
  console.log(`
9203
9406
  ${file}`);
9204
- for (const f of fs50) {
9407
+ for (const f of fs51) {
9205
9408
  const line = f.target.line !== void 0 ? `:${f.target.line}` : "";
9206
9409
  console.log(
9207
9410
  ` ${f.code} [${f.tier}/${f.impact}/${f.confidence}] ${f.target.kind} ${f.target.identifier}${line}`
@@ -9227,7 +9430,7 @@ import { Command as Command69 } from "commander";
9227
9430
  init_dist3();
9228
9431
  import { Command as Command68 } from "commander";
9229
9432
  import { randomBytes } from "crypto";
9230
- import { resolve as resolve30 } from "path";
9433
+ import { resolve as resolve32 } from "path";
9231
9434
  import { SinkRegistry, SinkConfigError, wrapAsEnvelope } from "@harness-engineering/orchestrator";
9232
9435
  function makeTestEvent(message) {
9233
9436
  return {
@@ -9237,8 +9440,8 @@ function makeTestEvent(message) {
9237
9440
  data: { message, triggeredAt: (/* @__PURE__ */ new Date()).toISOString() }
9238
9441
  };
9239
9442
  }
9240
- async function runNotificationsTest(sinkId, opts, projectRoot2 = process.cwd()) {
9241
- const cfgResult = loadNotificationsConfig(projectRoot2);
9443
+ async function runNotificationsTest(sinkId, opts, projectRoot3 = process.cwd()) {
9444
+ const cfgResult = loadNotificationsConfig(projectRoot3);
9242
9445
  if (!cfgResult.ok) {
9243
9446
  return { ok: false, error: `Config error: ${cfgResult.error.message}` };
9244
9447
  }
@@ -9279,8 +9482,8 @@ async function runNotificationsTest(sinkId, opts, projectRoot2 = process.cwd())
9279
9482
  function createNotificationsTestSubcommand() {
9280
9483
  return new Command68("test").description("Send a synthetic notification.test event through the named sink").argument("<sink-id>", "Sink id from harness.config.json `notifications.sinks[].id`").option("--message <text>", "Override the default test message").action(async (sinkId, opts, cmd) => {
9281
9484
  const globalOpts = cmd.optsWithGlobals();
9282
- const projectRoot2 = typeof globalOpts["cwd"] === "string" ? resolve30(globalOpts["cwd"]) : process.cwd();
9283
- const result = await runNotificationsTest(sinkId, opts, projectRoot2);
9485
+ const projectRoot3 = typeof globalOpts["cwd"] === "string" ? resolve32(globalOpts["cwd"]) : process.cwd();
9486
+ const result = await runNotificationsTest(sinkId, opts, projectRoot3);
9284
9487
  if (globalOpts["json"]) {
9285
9488
  console.log(JSON.stringify(result, null, 2));
9286
9489
  } else if (result.ok) {
@@ -9303,12 +9506,12 @@ function createNotificationsCommand() {
9303
9506
 
9304
9507
  // src/commands/orchestrator.ts
9305
9508
  import { Command as Command70 } from "commander";
9306
- import * as path49 from "path";
9509
+ import * as path50 from "path";
9307
9510
  import { Orchestrator, WorkflowLoader as WorkflowLoader2, launchTUI } from "@harness-engineering/orchestrator";
9308
9511
  function createOrchestratorCommand() {
9309
9512
  const orchestrator = new Command70("orchestrator");
9310
9513
  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) => {
9311
- const workflowPath = path49.resolve(process.cwd(), opts.workflow);
9514
+ const workflowPath = path50.resolve(process.cwd(), opts.workflow);
9312
9515
  const loader = new WorkflowLoader2();
9313
9516
  const result = await loader.loadWorkflow(workflowPath);
9314
9517
  if (!result.ok) {
@@ -9343,12 +9546,12 @@ function createOrchestratorCommand() {
9343
9546
  // src/commands/perf.ts
9344
9547
  init_dist3();
9345
9548
  import { Command as Command71 } from "commander";
9346
- import * as path50 from "path";
9549
+ import * as path51 from "path";
9347
9550
  function registerBenchCommand(perf) {
9348
9551
  perf.command("bench [glob]").description("Run benchmarks via vitest bench").action(async (glob2, _opts, cmd) => {
9349
9552
  const globalOpts = cmd.optsWithGlobals();
9350
9553
  const cwd = process.cwd();
9351
- const { BenchmarkRunner } = await import("./dist-MCTEX5QH.js");
9554
+ const { BenchmarkRunner } = await import("./dist-BWFFVKEW.js");
9352
9555
  const runner = new BenchmarkRunner();
9353
9556
  const benchFiles = runner.discover(cwd, glob2);
9354
9557
  if (benchFiles.length === 0) {
@@ -9412,7 +9615,7 @@ async function runBaselinesShow(globalOpts) {
9412
9615
  }
9413
9616
  async function runBaselinesUpdate(globalOpts) {
9414
9617
  const cwd = process.cwd();
9415
- const { BenchmarkRunner } = await import("./dist-MCTEX5QH.js");
9618
+ const { BenchmarkRunner } = await import("./dist-BWFFVKEW.js");
9416
9619
  const runner = new BenchmarkRunner();
9417
9620
  const manager = new BaselineManager(cwd);
9418
9621
  logger.info("Running benchmarks to update baselines...");
@@ -9453,9 +9656,9 @@ function registerReportCommand(perf) {
9453
9656
  perf.command("report").description("Full performance report with metrics, trends, and hotspots").action(async (_opts, cmd) => {
9454
9657
  const globalOpts = cmd.optsWithGlobals();
9455
9658
  const cwd = process.cwd();
9456
- const { EntropyAnalyzer: EntropyAnalyzer2 } = await import("./dist-MCTEX5QH.js");
9659
+ const { EntropyAnalyzer: EntropyAnalyzer2 } = await import("./dist-BWFFVKEW.js");
9457
9660
  const analyzer = new EntropyAnalyzer2({
9458
- rootDir: path50.resolve(cwd),
9661
+ rootDir: path51.resolve(cwd),
9459
9662
  analyze: { complexity: true, coupling: true }
9460
9663
  });
9461
9664
  const result = await analyzer.analyze();
@@ -9561,34 +9764,34 @@ function createListCommand2() {
9561
9764
 
9562
9765
  // src/commands/persona/generate.ts
9563
9766
  import { Command as Command73, Option } from "commander";
9564
- import * as fs30 from "fs";
9565
- import * as path51 from "path";
9767
+ import * as fs31 from "fs";
9768
+ import * as path52 from "path";
9566
9769
  function generatePersonaArtifacts(persona, outputDir, only, platform) {
9567
9770
  const slug = toKebabCase(persona.name);
9568
9771
  const generated = [];
9569
9772
  if (!only || only === "runtime") {
9570
9773
  const result = generateRuntime(persona);
9571
9774
  if (result.ok) {
9572
- const outPath = path51.join(outputDir, `${slug}.runtime.json`);
9573
- fs30.mkdirSync(path51.dirname(outPath), { recursive: true });
9574
- fs30.writeFileSync(outPath, result.value);
9775
+ const outPath = path52.join(outputDir, `${slug}.runtime.json`);
9776
+ fs31.mkdirSync(path52.dirname(outPath), { recursive: true });
9777
+ fs31.writeFileSync(outPath, result.value);
9575
9778
  generated.push(outPath);
9576
9779
  }
9577
9780
  }
9578
9781
  if (!only || only === "agents-md") {
9579
9782
  const result = generateAgentsMd(persona);
9580
9783
  if (result.ok) {
9581
- const outPath = path51.join(outputDir, `${slug}.agents.md`);
9582
- fs30.writeFileSync(outPath, result.value);
9784
+ const outPath = path52.join(outputDir, `${slug}.agents.md`);
9785
+ fs31.writeFileSync(outPath, result.value);
9583
9786
  generated.push(outPath);
9584
9787
  }
9585
9788
  }
9586
9789
  if (!only || only === "ci") {
9587
9790
  const result = generateCIWorkflow(persona, platform);
9588
9791
  if (result.ok) {
9589
- const outPath = platform === "gitlab" ? path51.join(outputDir, `${slug}.gitlab-ci.yml`) : path51.join(outputDir, ".github", "workflows", `${slug}.yml`);
9590
- fs30.mkdirSync(path51.dirname(outPath), { recursive: true });
9591
- fs30.writeFileSync(outPath, result.value);
9792
+ const outPath = platform === "gitlab" ? path52.join(outputDir, `${slug}.gitlab-ci.yml`) : path52.join(outputDir, ".github", "workflows", `${slug}.yml`);
9793
+ fs31.mkdirSync(path52.dirname(outPath), { recursive: true });
9794
+ fs31.writeFileSync(outPath, result.value);
9592
9795
  generated.push(outPath);
9593
9796
  }
9594
9797
  }
@@ -9599,14 +9802,14 @@ function createGenerateCommand3() {
9599
9802
  new Option("--platform <platform>", "CI platform for the ci artifact").choices(["github", "gitlab"]).default("github")
9600
9803
  ).action(async (name, opts, cmd) => {
9601
9804
  const globalOpts = cmd.optsWithGlobals();
9602
- const personaResult = loadPersona(path51.join(resolvePersonasDir(), `${name}.yaml`));
9805
+ const personaResult = loadPersona(path52.join(resolvePersonasDir(), `${name}.yaml`));
9603
9806
  if (!personaResult.ok) {
9604
9807
  logger.error(personaResult.error.message);
9605
9808
  process.exit(ExitCode.ERROR);
9606
9809
  }
9607
9810
  const generated = generatePersonaArtifacts(
9608
9811
  personaResult.value,
9609
- path51.resolve(opts.outputDir),
9812
+ path52.resolve(opts.outputDir),
9610
9813
  opts.only,
9611
9814
  opts.platform
9612
9815
  );
@@ -9760,14 +9963,14 @@ function createPredictCommand() {
9760
9963
  init_dist2();
9761
9964
  import { execFileSync as execFileSync7 } from "child_process";
9762
9965
  import { readFileSync as readFileSync18 } from "fs";
9763
- import { join as join40 } from "path";
9966
+ import { join as join41 } from "path";
9764
9967
  import { Command as Command77 } from "commander";
9765
9968
  import { gatherSignals } from "@harness-engineering/signals";
9766
9969
 
9767
9970
  // src/commands/review-ci.ts
9768
9971
  init_dist3();
9769
9972
  import { execFileSync as execFileSync6 } from "child_process";
9770
- import { writeFileSync as writeFileSync18 } from "fs";
9973
+ import { writeFileSync as writeFileSync19 } from "fs";
9771
9974
  import { Command as Command76, Option as Option2 } from "commander";
9772
9975
 
9773
9976
  // src/commands/review-ci-local-adapter.ts
@@ -9940,7 +10143,7 @@ var defaultPostReview = (verdict) => {
9940
10143
  encoding: "utf-8"
9941
10144
  });
9942
10145
  };
9943
- function emitReviewCi(result, opts, writeFile2 = (p, d) => writeFileSync18(p, d), log = (m) => process.stdout.write(m + "\n"), postReview = defaultPostReview) {
10146
+ function emitReviewCi(result, opts, writeFile2 = (p, d) => writeFileSync19(p, d), log = (m) => process.stdout.write(m + "\n"), postReview = defaultPostReview) {
9944
10147
  const serialized = JSON.stringify(result.verdict, null, 2);
9945
10148
  const jsonToStdout = opts.jsonPath === true;
9946
10149
  if (!jsonToStdout) log(result.terminalOutput);
@@ -10121,11 +10324,11 @@ var defaultPostBrief = (body) => {
10121
10324
  }
10122
10325
  );
10123
10326
  };
10124
- var defaultReadFile = (path80) => readFileSync18(path80, "utf-8");
10125
- function readReview(path80, readFile4 = defaultReadFile) {
10126
- if (!path80) return void 0;
10327
+ var defaultReadFile = (path81) => readFileSync18(path81, "utf-8");
10328
+ function readReview(path81, readFile4 = defaultReadFile) {
10329
+ if (!path81) return void 0;
10127
10330
  try {
10128
- const parsed = JSON.parse(readFile4(path80));
10331
+ const parsed = JSON.parse(readFile4(path81));
10129
10332
  return parsed?.verdict && typeof parsed.verdict === "object" ? parsed.verdict : void 0;
10130
10333
  } catch {
10131
10334
  return void 0;
@@ -10143,7 +10346,7 @@ var GRAPH_DIR = ".harness/graph";
10143
10346
  async function loadOutcomeStore(projectPath) {
10144
10347
  try {
10145
10348
  const store = new GraphStore();
10146
- const loaded = await store.load(join40(projectPath, GRAPH_DIR));
10349
+ const loaded = await store.load(join41(projectPath, GRAPH_DIR));
10147
10350
  return loaded ? store : void 0;
10148
10351
  } catch {
10149
10352
  return void 0;
@@ -10240,31 +10443,44 @@ function createPreMergeBriefCommand() {
10240
10443
  // src/commands/proposals.ts
10241
10444
  init_dist3();
10242
10445
  import { Command as Command78 } from "commander";
10243
- import { resolve as resolve34 } from "path";
10244
- function projectRoot() {
10245
- return resolve34(process.env["HARNESS_PROJECT_ROOT"] ?? process.cwd());
10446
+ import { resolve as resolve36 } from "path";
10447
+ function projectRoot2() {
10448
+ return resolve36(process.env["HARNESS_PROJECT_ROOT"] ?? process.cwd());
10246
10449
  }
10247
10450
  function summarizeProposal(p) {
10248
- return {
10451
+ const base = {
10249
10452
  id: p.id,
10250
- kind: p.kind,
10251
- targetSkill: p.targetSkill,
10252
- name: p.content.name,
10253
10453
  status: p.status,
10254
10454
  proposedBy: p.proposedBy,
10255
- createdAt: p.createdAt,
10256
- gateLastRunAt: p.gate?.lastRunAt,
10257
- findings: p.gate?.findings?.length ?? 0
10455
+ createdAt: p.createdAt
10456
+ };
10457
+ if (p.kind === "skill") {
10458
+ return {
10459
+ ...base,
10460
+ kind: p.skillKind,
10461
+ targetSkill: p.targetSkill,
10462
+ name: p.content.name,
10463
+ gateLastRunAt: p.gate?.lastRunAt,
10464
+ findings: p.gate?.findings?.length ?? 0
10465
+ };
10466
+ }
10467
+ return {
10468
+ ...base,
10469
+ kind: p.kind,
10470
+ targetSkill: void 0,
10471
+ name: p.model.target.ollamaName,
10472
+ gateLastRunAt: void 0,
10473
+ findings: 0
10258
10474
  };
10259
10475
  }
10260
10476
  async function runProposalsList(status) {
10261
- const opts = {};
10477
+ const opts = { kind: "skill" };
10262
10478
  if (status) opts.status = status;
10263
- const proposals = await listProposals(projectRoot(), opts);
10479
+ const proposals = await listProposals(projectRoot2(), opts);
10264
10480
  return proposals.map(summarizeProposal);
10265
10481
  }
10266
10482
  async function runProposalsShow(id) {
10267
- return getProposal(projectRoot(), id);
10483
+ return getProposal(projectRoot2(), id);
10268
10484
  }
10269
10485
  async function runProposalsReject(id, reason) {
10270
10486
  const decision = {
@@ -10273,7 +10489,7 @@ async function runProposalsReject(id, reason) {
10273
10489
  action: "rejected",
10274
10490
  reason
10275
10491
  };
10276
- return updateProposal(projectRoot(), id, { status: "rejected", decision });
10492
+ return updateProposal(projectRoot2(), id, { status: "rejected", decision });
10277
10493
  }
10278
10494
  var ALLOWED_STATUSES = [
10279
10495
  "open",
@@ -10349,8 +10565,8 @@ function createProposalsCommand() {
10349
10565
  }
10350
10566
 
10351
10567
  // src/commands/publish-analyses.ts
10352
- import * as fs31 from "fs";
10353
- import * as path52 from "path";
10568
+ import * as fs32 from "fs";
10569
+ import * as path53 from "path";
10354
10570
  import { Command as Command79 } from "commander";
10355
10571
  init_dist3();
10356
10572
  import {
@@ -10359,7 +10575,7 @@ import {
10359
10575
  savePublishedIndex
10360
10576
  } from "@harness-engineering/orchestrator";
10361
10577
  function bootstrapTrackerCommand(opts, verb) {
10362
- const projectPath = path52.resolve(opts.dir);
10578
+ const projectPath = path53.resolve(opts.dir);
10363
10579
  const trackerConfig = loadTrackerSyncConfig(projectPath);
10364
10580
  if (!trackerConfig) {
10365
10581
  logger.error(`No tracker config found in harness.config.json. Cannot ${verb}.`);
@@ -10371,8 +10587,8 @@ function bootstrapTrackerCommand(opts, verb) {
10371
10587
  );
10372
10588
  return null;
10373
10589
  }
10374
- const projectEnvPath = path52.join(projectPath, ".env");
10375
- if (fs31.existsSync(projectEnvPath) && !process.env.GITHUB_TOKEN) {
10590
+ const projectEnvPath = path53.join(projectPath, ".env");
10591
+ if (fs32.existsSync(projectEnvPath) && !process.env.GITHUB_TOKEN) {
10376
10592
  __require("dotenv").config({ path: projectEnvPath });
10377
10593
  }
10378
10594
  const token = process.env.GITHUB_TOKEN;
@@ -10463,8 +10679,8 @@ async function runPublishAnalyses(opts) {
10463
10679
  const nameToExternalId = await buildNameToExternalIdMap(projectPath);
10464
10680
  if (!nameToExternalId) return process.exit(1);
10465
10681
  const { AnalysisArchive } = await import("@harness-engineering/orchestrator");
10466
- const { GitHubIssuesSyncAdapter: GitHubIssuesSyncAdapter2 } = await import("./dist-MCTEX5QH.js");
10467
- const archive = new AnalysisArchive(path52.join(projectPath, ".harness", "analyses"));
10682
+ const { GitHubIssuesSyncAdapter: GitHubIssuesSyncAdapter2 } = await import("./dist-BWFFVKEW.js");
10683
+ const archive = new AnalysisArchive(path53.join(projectPath, ".harness", "analyses"));
10468
10684
  const analyses = await archive.list();
10469
10685
  if (analyses.length === 0) {
10470
10686
  logger.info("No analyses found to publish.");
@@ -10506,8 +10722,8 @@ import { Command as Command81 } from "commander";
10506
10722
 
10507
10723
  // src/commands/pulse/run.ts
10508
10724
  init_dist3();
10509
- import { readFileSync as readFileSync19, mkdirSync as mkdirSync15, writeFileSync as writeFileSync19 } from "fs";
10510
- import { dirname as dirname18, join as join42, resolve as resolve36 } from "path";
10725
+ import { readFileSync as readFileSync19, mkdirSync as mkdirSync16, writeFileSync as writeFileSync20 } from "fs";
10726
+ import { dirname as dirname19, join as join43, resolve as resolve38 } from "path";
10511
10727
  import { Command as Command80 } from "commander";
10512
10728
  async function runPulseRunCommand(opts) {
10513
10729
  const startedAt = Date.now();
@@ -10539,9 +10755,9 @@ async function runPulseRunCommand(opts) {
10539
10755
  const report = assembleReport(result, productName, lookback);
10540
10756
  const now = /* @__PURE__ */ new Date();
10541
10757
  const ts = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, "0")}-${String(now.getDate()).padStart(2, "0")}_${String(now.getHours()).padStart(2, "0")}-${String(now.getMinutes()).padStart(2, "0")}`;
10542
- const filePath = join42(opts.outputDir, `${ts}.md`);
10543
- mkdirSync15(dirname18(filePath), { recursive: true });
10544
- writeFileSync19(filePath, report);
10758
+ const filePath = join43(opts.outputDir, `${ts}.md`);
10759
+ mkdirSync16(dirname19(filePath), { recursive: true });
10760
+ writeFileSync20(filePath, report);
10545
10761
  const headlines = extractHeadlines(report);
10546
10762
  return emit2(
10547
10763
  {
@@ -10583,8 +10799,8 @@ function createRunCommand2() {
10583
10799
  async (options) => {
10584
10800
  const nonInteractive = options.nonInteractive === true || !process.stdout.isTTY;
10585
10801
  const status = await runPulseRunCommand({
10586
- configPath: resolve36(process.cwd(), options.config),
10587
- outputDir: resolve36(process.cwd(), options.outputDir),
10802
+ configPath: resolve38(process.cwd(), options.config),
10803
+ outputDir: resolve38(process.cwd(), options.outputDir),
10588
10804
  nonInteractive,
10589
10805
  lookback: options.lookback
10590
10806
  });
@@ -10708,13 +10924,13 @@ import { Command as Command89 } from "commander";
10708
10924
  // src/commands/roadmap/migrate.ts
10709
10925
  init_dist3();
10710
10926
  import { Command as Command83 } from "commander";
10711
- import * as fs33 from "fs";
10712
- import * as path54 from "path";
10927
+ import * as fs34 from "fs";
10928
+ import * as path55 from "path";
10713
10929
  import chalk14 from "chalk";
10714
10930
 
10715
10931
  // src/commands/roadmap/migrate-lock.ts
10716
- import * as fs32 from "fs";
10717
- import * as path53 from "path";
10932
+ import * as fs33 from "fs";
10933
+ import * as path54 from "path";
10718
10934
  import * as os7 from "os";
10719
10935
  var LOCK_FILE_NAME = "migrate.lock";
10720
10936
  var STALE_LOCK_MS = 30 * 60 * 1e3;
@@ -10727,14 +10943,14 @@ function isPidAlive(pid) {
10727
10943
  return false;
10728
10944
  }
10729
10945
  }
10730
- function acquireMigrateLock(projectRoot2) {
10731
- const harnessDir = path53.join(projectRoot2, ".harness");
10732
- const lockPath = path53.join(harnessDir, LOCK_FILE_NAME);
10733
- if (!fs32.existsSync(harnessDir)) fs32.mkdirSync(harnessDir, { recursive: true });
10734
- if (fs32.existsSync(lockPath)) {
10946
+ function acquireMigrateLock(projectRoot3) {
10947
+ const harnessDir = path54.join(projectRoot3, ".harness");
10948
+ const lockPath = path54.join(harnessDir, LOCK_FILE_NAME);
10949
+ if (!fs33.existsSync(harnessDir)) fs33.mkdirSync(harnessDir, { recursive: true });
10950
+ if (fs33.existsSync(lockPath)) {
10735
10951
  const existingRaw = (() => {
10736
10952
  try {
10737
- return fs32.readFileSync(lockPath, "utf-8");
10953
+ return fs33.readFileSync(lockPath, "utf-8");
10738
10954
  } catch {
10739
10955
  return null;
10740
10956
  }
@@ -10764,11 +10980,11 @@ function acquireMigrateLock(projectRoot2) {
10764
10980
  startedAt: (/* @__PURE__ */ new Date()).toISOString(),
10765
10981
  hostname: os7.hostname()
10766
10982
  };
10767
- fs32.writeFileSync(lockPath, JSON.stringify(payload, null, 2) + "\n");
10983
+ fs33.writeFileSync(lockPath, JSON.stringify(payload, null, 2) + "\n");
10768
10984
  return {
10769
10985
  release: () => {
10770
10986
  try {
10771
- fs32.unlinkSync(lockPath);
10987
+ fs33.unlinkSync(lockPath);
10772
10988
  } catch {
10773
10989
  }
10774
10990
  }
@@ -10924,11 +11140,11 @@ async function runRoadmapMigrate(opts) {
10924
11140
  if (!clientR.ok) return Err(new CLIError(clientR.error.message));
10925
11141
  client = clientR.value;
10926
11142
  }
10927
- const roadmapPath = path54.join(cwd, "docs", "roadmap.md");
10928
- if (!fs33.existsSync(roadmapPath)) {
11143
+ const roadmapPath = path55.join(cwd, "docs", "roadmap.md");
11144
+ if (!fs34.existsSync(roadmapPath)) {
10929
11145
  return Err(new CLIError(`docs/roadmap.md not found in ${cwd}`));
10930
11146
  }
10931
- const roadmapR = parseRoadmap(fs33.readFileSync(roadmapPath, "utf-8"));
11147
+ const roadmapR = parseRoadmap(fs34.readFileSync(roadmapPath, "utf-8"));
10932
11148
  if (!roadmapR.ok) {
10933
11149
  return Err(new CLIError(`failed to parse docs/roadmap.md: ${roadmapR.error.message}`));
10934
11150
  }
@@ -10949,10 +11165,10 @@ async function runRoadmapMigrate(opts) {
10949
11165
  if (!isJson) printPlanSummary(plan, opts.dryRun);
10950
11166
  const deps = {
10951
11167
  client,
10952
- readFile: (p) => fs33.readFileSync(p, "utf-8"),
10953
- writeFile: (p, b) => fs33.writeFileSync(p, b),
10954
- renameFile: (from, to) => fs33.renameSync(from, to),
10955
- existsFile: (p) => fs33.existsSync(p)
11168
+ readFile: (p) => fs34.readFileSync(p, "utf-8"),
11169
+ writeFile: (p, b) => fs34.writeFileSync(p, b),
11170
+ renameFile: (from, to) => fs34.renameSync(from, to),
11171
+ existsFile: (p) => fs34.existsSync(p)
10956
11172
  };
10957
11173
  const reportR = await migrate_exports.runMigrationPlan(plan, deps, {
10958
11174
  projectRoot: cwd,
@@ -11010,7 +11226,7 @@ function featuresToRoadmap(features, project, nowIso) {
11010
11226
  }
11011
11227
  function readProjectName(configPath) {
11012
11228
  try {
11013
- const parsed = JSON.parse(fs33.readFileSync(configPath, "utf-8"));
11229
+ const parsed = JSON.parse(fs34.readFileSync(configPath, "utf-8"));
11014
11230
  return typeof parsed.name === "string" && parsed.name.length > 0 ? parsed.name : "Roadmap";
11015
11231
  } catch {
11016
11232
  return "Roadmap";
@@ -11057,8 +11273,8 @@ async function runReverseMigrate(opts) {
11057
11273
  const lockResult = acquireMigrateLock(cwd);
11058
11274
  if (isRefusal(lockResult)) return Err(new CLIError(lockResult.message));
11059
11275
  try {
11060
- const roadmapPath = path54.join(cwd, "docs", "roadmap.md");
11061
- if (fs33.existsSync(roadmapPath)) {
11276
+ const roadmapPath = path55.join(cwd, "docs", "roadmap.md");
11277
+ if (fs34.existsSync(roadmapPath)) {
11062
11278
  return Err(
11063
11279
  new CLIError(`docs/roadmap.md already exists; refusing to overwrite (${roadmapPath})`)
11064
11280
  );
@@ -11078,7 +11294,7 @@ async function runReverseMigrate(opts) {
11078
11294
  return Err(new CLIError(`failed to fetch tracker features: ${fetchR.error.message}`));
11079
11295
  }
11080
11296
  const features = fetchR.value.features;
11081
- const configPath = path54.join(cwd, "harness.config.json");
11297
+ const configPath = path55.join(cwd, "harness.config.json");
11082
11298
  const project = readProjectName(configPath);
11083
11299
  const nowIso = (/* @__PURE__ */ new Date()).toISOString();
11084
11300
  const markdown = serializeRoadmap(featuresToRoadmap(features, project, nowIso));
@@ -11096,19 +11312,19 @@ async function runReverseMigrate(opts) {
11096
11312
  emitReverseReport(report, features.length, isJson, true);
11097
11313
  return Ok(report);
11098
11314
  }
11099
- fs33.mkdirSync(path54.dirname(roadmapPath), { recursive: true });
11100
- fs33.writeFileSync(roadmapPath, markdown);
11315
+ fs34.mkdirSync(path55.dirname(roadmapPath), { recursive: true });
11316
+ fs34.writeFileSync(roadmapPath, markdown);
11101
11317
  report.archivedTo = roadmapPath;
11102
- if (fs33.existsSync(configPath)) {
11103
- const original = fs33.readFileSync(configPath, "utf-8");
11104
- const configBackupPath = path54.join(cwd, "harness.config.json.pre-migration");
11105
- fs33.writeFileSync(configBackupPath, original);
11318
+ if (fs34.existsSync(configPath)) {
11319
+ const original = fs34.readFileSync(configPath, "utf-8");
11320
+ const configBackupPath = path55.join(cwd, "harness.config.json.pre-migration");
11321
+ fs34.writeFileSync(configBackupPath, original);
11106
11322
  report.configBackup = configBackupPath;
11107
11323
  const parsed = JSON.parse(original);
11108
11324
  const roadmapSection = parsed.roadmap ?? {};
11109
11325
  roadmapSection.mode = "file-backed";
11110
11326
  parsed.roadmap = roadmapSection;
11111
- fs33.writeFileSync(configPath, JSON.stringify(parsed, null, 2) + "\n");
11327
+ fs34.writeFileSync(configPath, JSON.stringify(parsed, null, 2) + "\n");
11112
11328
  }
11113
11329
  emitReverseReport(report, features.length, isJson, false);
11114
11330
  return Ok(report);
@@ -11153,23 +11369,23 @@ function createRoadmapMigrateCommand() {
11153
11369
  // src/commands/roadmap/shard.ts
11154
11370
  init_dist3();
11155
11371
  import { Command as Command84 } from "commander";
11156
- import * as path55 from "path";
11372
+ import * as path56 from "path";
11157
11373
 
11158
11374
  // src/commands/roadmap/shard-io.ts
11159
11375
  import * as fsp from "fs/promises";
11160
11376
  function createNodeShardIO() {
11161
11377
  return {
11162
- readFile: (path80) => fsp.readFile(path80, "utf-8"),
11163
- writeFile: (path80, data) => fsp.writeFile(path80, data, "utf-8"),
11378
+ readFile: (path81) => fsp.readFile(path81, "utf-8"),
11379
+ writeFile: (path81, data) => fsp.writeFile(path81, data, "utf-8"),
11164
11380
  listDir: (dir) => fsp.readdir(dir),
11165
- deleteFile: (path80) => fsp.rm(path80),
11381
+ deleteFile: (path81) => fsp.rm(path81),
11166
11382
  mkdirp: async (dir) => {
11167
11383
  await fsp.mkdir(dir, { recursive: true });
11168
11384
  },
11169
- rmrf: (path80) => fsp.rm(path80, { recursive: true, force: true }),
11170
- exists: async (path80) => {
11385
+ rmrf: (path81) => fsp.rm(path81, { recursive: true, force: true }),
11386
+ exists: async (path81) => {
11171
11387
  try {
11172
- await fsp.access(path80);
11388
+ await fsp.access(path81);
11173
11389
  return true;
11174
11390
  } catch {
11175
11391
  return false;
@@ -11186,8 +11402,8 @@ async function runRoadmapShard(opts = {}) {
11186
11402
  const force = Boolean(opts.force);
11187
11403
  const format = opts.format === "json" ? "json" : "human";
11188
11404
  const assertRoundTrip = opts.assertRoundTrip ?? assertSemanticRoundTrip;
11189
- const roadmapPath = path55.join(cwd, "docs", "roadmap.md").replaceAll("\\", "/");
11190
- const shardDir = path55.join(cwd, "docs", "roadmap.d").replaceAll("\\", "/");
11405
+ const roadmapPath = path56.join(cwd, "docs", "roadmap.md").replaceAll("\\", "/");
11406
+ const shardDir = path56.join(cwd, "docs", "roadmap.d").replaceAll("\\", "/");
11191
11407
  if (!await io.exists(roadmapPath)) {
11192
11408
  return Err(new CLIError("docs/roadmap.md not found", ExitCode.ERROR));
11193
11409
  }
@@ -11279,14 +11495,14 @@ function createRoadmapShardCommand() {
11279
11495
  // src/commands/roadmap/unshard.ts
11280
11496
  init_dist3();
11281
11497
  import { Command as Command85 } from "commander";
11282
- import * as path56 from "path";
11498
+ import * as path57 from "path";
11283
11499
  async function runRoadmapUnshard(opts = {}) {
11284
11500
  const cwd = opts.cwd ?? process.cwd();
11285
11501
  const io = opts.io ?? createNodeShardIO();
11286
11502
  const dryRun = Boolean(opts.dryRun);
11287
11503
  const format = opts.format === "json" ? "json" : "human";
11288
- const shardDir = path56.join(cwd, "docs", "roadmap.d");
11289
- const roadmapPath = path56.join(cwd, "docs", "roadmap.md");
11504
+ const shardDir = path57.join(cwd, "docs", "roadmap.d");
11505
+ const roadmapPath = path57.join(cwd, "docs", "roadmap.md");
11290
11506
  if (!await io.exists(shardDir)) {
11291
11507
  return Err(new CLIError("docs/roadmap.d not found; nothing to unshard", ExitCode.ERROR));
11292
11508
  }
@@ -11335,14 +11551,14 @@ function createRoadmapUnshardCommand() {
11335
11551
  // src/commands/roadmap/regen.ts
11336
11552
  init_dist3();
11337
11553
  import { Command as Command86 } from "commander";
11338
- import * as path57 from "path";
11554
+ import * as path58 from "path";
11339
11555
  async function runRoadmapRegen(opts = {}) {
11340
11556
  const cwd = opts.cwd ?? process.cwd();
11341
11557
  const io = opts.io ?? createNodeShardIO();
11342
11558
  const dryRun = Boolean(opts.dryRun);
11343
11559
  const format = opts.format === "json" ? "json" : "human";
11344
- const shardDir = path57.join(cwd, "docs", "roadmap.d");
11345
- const roadmapPath = path57.join(cwd, "docs", "roadmap.md");
11560
+ const shardDir = path58.join(cwd, "docs", "roadmap.d");
11561
+ const roadmapPath = path58.join(cwd, "docs", "roadmap.md");
11346
11562
  if (!await io.exists(shardDir)) {
11347
11563
  return Err(new CLIError("docs/roadmap.d not found; project is not sharded", ExitCode.ERROR));
11348
11564
  }
@@ -11388,8 +11604,8 @@ function createRoadmapRegenCommand() {
11388
11604
  // src/commands/roadmap/reconcile.ts
11389
11605
  init_dist3();
11390
11606
  import { Command as Command87 } from "commander";
11391
- import * as fs34 from "fs";
11392
- import * as path58 from "path";
11607
+ import * as fs35 from "fs";
11608
+ import * as path59 from "path";
11393
11609
  async function runRoadmapReconcile(opts = {}) {
11394
11610
  const cwd = opts.cwd ?? process.cwd();
11395
11611
  if (!opts.store && !roadmapSourceExists(cwd)) {
@@ -11467,8 +11683,8 @@ async function resolveAdapter(opts, cwd) {
11467
11683
  )
11468
11684
  );
11469
11685
  }
11470
- const envPath = path58.join(cwd, ".env");
11471
- if (fs34.existsSync(envPath) && !process.env.GITHUB_TOKEN) {
11686
+ const envPath = path59.join(cwd, ".env");
11687
+ if (fs35.existsSync(envPath) && !process.env.GITHUB_TOKEN) {
11472
11688
  const { config: loadDotenv } = await import("dotenv");
11473
11689
  loadDotenv({ path: envPath });
11474
11690
  }
@@ -11580,9 +11796,9 @@ function authHeader() {
11580
11796
  const tok = process.env["HARNESS_API_TOKEN"];
11581
11797
  return tok ? { Authorization: `Bearer ${tok}` } : {};
11582
11798
  }
11583
- async function getJson(path80) {
11799
+ async function getJson(path81) {
11584
11800
  try {
11585
- const res = await fetch(`${orchestratorBase()}${path80}`, {
11801
+ const res = await fetch(`${orchestratorBase()}${path81}`, {
11586
11802
  headers: { ...authHeader() }
11587
11803
  });
11588
11804
  const text = await res.text();
@@ -11597,9 +11813,9 @@ async function getJson(path80) {
11597
11813
  };
11598
11814
  }
11599
11815
  }
11600
- async function postJson(path80, body) {
11816
+ async function postJson(path81, body) {
11601
11817
  try {
11602
- const res = await fetch(`${orchestratorBase()}${path80}`, {
11818
+ const res = await fetch(`${orchestratorBase()}${path81}`, {
11603
11819
  method: "POST",
11604
11820
  headers: { "Content-Type": "application/json", ...authHeader() },
11605
11821
  body: JSON.stringify(body)
@@ -11804,8 +12020,8 @@ function createRoutingCommand() {
11804
12020
  // src/commands/scan-config.ts
11805
12021
  init_dist3();
11806
12022
  import { Command as Command94 } from "commander";
11807
- import { existsSync as existsSync30, readFileSync as readFileSync22, writeFileSync as writeFileSync22 } from "fs";
11808
- import { join as join49, relative as relative3 } from "path";
12023
+ import { existsSync as existsSync31, readFileSync as readFileSync22, writeFileSync as writeFileSync23 } from "fs";
12024
+ import { join as join50, relative as relative4 } from "path";
11809
12025
  var CONFIG_FILES = ["CLAUDE.md", "AGENTS.md", ".gemini/settings.json", "skill.yaml"];
11810
12026
  function stripHighSeverityPatterns(content, injectionFindings) {
11811
12027
  const highLines = /* @__PURE__ */ new Set();
@@ -11831,14 +12047,14 @@ function applyFix(filePath, targetDir, content, injectionFindings) {
11831
12047
  if (!hasHighSeverity) return;
11832
12048
  const { cleaned, linesStripped } = stripHighSeverityPatterns(content, injectionFindings);
11833
12049
  if (linesStripped > 0) {
11834
- writeFileSync22(filePath, cleaned);
12050
+ writeFileSync23(filePath, cleaned);
11835
12051
  logger.info(
11836
- `scan-config --fix: stripped ${linesStripped} high-severity line(s) from ${relative3(targetDir, filePath).replaceAll("\\", "/")}`
12052
+ `scan-config --fix: stripped ${linesStripped} high-severity line(s) from ${relative4(targetDir, filePath).replaceAll("\\", "/")}`
11837
12053
  );
11838
12054
  }
11839
12055
  }
11840
12056
  function scanSingleFile(filePath, targetDir, scanner, options) {
11841
- if (!existsSync30(filePath)) return null;
12057
+ if (!existsSync31(filePath)) return null;
11842
12058
  let content;
11843
12059
  try {
11844
12060
  content = readFileSync22(filePath, "utf8");
@@ -11853,7 +12069,7 @@ function scanSingleFile(filePath, targetDir, scanner, options) {
11853
12069
  applyFix(filePath, targetDir, content, injectionFindings);
11854
12070
  }
11855
12071
  return {
11856
- file: relative3(targetDir, filePath).replaceAll("\\", "/"),
12072
+ file: relative4(targetDir, filePath).replaceAll("\\", "/"),
11857
12073
  findings,
11858
12074
  overallSeverity: computeOverallSeverity(findings)
11859
12075
  };
@@ -11862,7 +12078,7 @@ async function runScanConfig(targetDir, options) {
11862
12078
  const scanner = new SecurityScanner(parseSecurityConfig({}));
11863
12079
  const results = [];
11864
12080
  for (const configFile of CONFIG_FILES) {
11865
- const result = scanSingleFile(join49(targetDir, configFile), targetDir, scanner, options);
12081
+ const result = scanSingleFile(join50(targetDir, configFile), targetDir, scanner, options);
11866
12082
  if (result) results.push(result);
11867
12083
  }
11868
12084
  return { exitCode: computeScanExitCode(results), results };
@@ -12040,10 +12256,10 @@ function printResult5(result, mode, _formatter) {
12040
12256
  list.push(f);
12041
12257
  byFile.set(f.target.file, list);
12042
12258
  }
12043
- for (const [file, fs50] of byFile) {
12259
+ for (const [file, fs51] of byFile) {
12044
12260
  console.log(`
12045
12261
  ${file}`);
12046
- for (const f of fs50) {
12262
+ for (const f of fs51) {
12047
12263
  console.log(
12048
12264
  ` ${f.code} [${f.tier}/${f.impact}/${f.confidence}] ${f.target.signal}:${f.target.line}`
12049
12265
  );
@@ -12060,23 +12276,23 @@ ${file}`);
12060
12276
 
12061
12277
  // src/commands/setup.ts
12062
12278
  import { Command as Command97 } from "commander";
12063
- import * as fs37 from "fs";
12279
+ import * as fs38 from "fs";
12064
12280
  import * as os9 from "os";
12065
- import * as path61 from "path";
12281
+ import * as path62 from "path";
12066
12282
  import chalk16 from "chalk";
12067
12283
 
12068
12284
  // src/utils/first-run.ts
12069
- import * as fs35 from "fs";
12285
+ import * as fs36 from "fs";
12070
12286
  import * as os8 from "os";
12071
- import * as path59 from "path";
12072
- var HARNESS_DIR = path59.join(os8.homedir(), ".harness");
12073
- var MARKER_FILE = path59.join(HARNESS_DIR, ".setup-complete");
12287
+ import * as path60 from "path";
12288
+ var HARNESS_DIR = path60.join(os8.homedir(), ".harness");
12289
+ var MARKER_FILE = path60.join(HARNESS_DIR, ".setup-complete");
12074
12290
  function isFirstRun() {
12075
- return !fs35.existsSync(MARKER_FILE);
12291
+ return !fs36.existsSync(MARKER_FILE);
12076
12292
  }
12077
12293
  function markSetupComplete() {
12078
- fs35.mkdirSync(HARNESS_DIR, { recursive: true });
12079
- fs35.writeFileSync(MARKER_FILE, "", "utf-8");
12294
+ fs36.mkdirSync(HARNESS_DIR, { recursive: true });
12295
+ fs36.writeFileSync(MARKER_FILE, "", "utf-8");
12080
12296
  }
12081
12297
  function printFirstRunWelcome() {
12082
12298
  try {
@@ -12089,8 +12305,8 @@ function printFirstRunWelcome() {
12089
12305
  }
12090
12306
 
12091
12307
  // src/commands/telemetry-wizard.ts
12092
- import * as fs36 from "fs";
12093
- import * as path60 from "path";
12308
+ import * as fs37 from "fs";
12309
+ import * as path61 from "path";
12094
12310
  import readline2 from "readline";
12095
12311
  import chalk15 from "chalk";
12096
12312
  function prompt2(question) {
@@ -12098,10 +12314,10 @@ function prompt2(question) {
12098
12314
  input: process.stdin,
12099
12315
  output: process.stdout
12100
12316
  });
12101
- return new Promise((resolve48) => {
12317
+ return new Promise((resolve50) => {
12102
12318
  rl.question(question, (answer) => {
12103
12319
  rl.close();
12104
- resolve48(answer.trim().toLowerCase());
12320
+ resolve50(answer.trim().toLowerCase());
12105
12321
  });
12106
12322
  });
12107
12323
  }
@@ -12110,10 +12326,10 @@ function promptRaw(question) {
12110
12326
  input: process.stdin,
12111
12327
  output: process.stdout
12112
12328
  });
12113
- return new Promise((resolve48) => {
12329
+ return new Promise((resolve50) => {
12114
12330
  rl.question(question, (answer) => {
12115
12331
  rl.close();
12116
- resolve48(answer.trim());
12332
+ resolve50(answer.trim());
12117
12333
  });
12118
12334
  });
12119
12335
  }
@@ -12121,21 +12337,21 @@ function isNo(answer) {
12121
12337
  return answer === "n" || answer === "no";
12122
12338
  }
12123
12339
  function isTelemetryConfigured(cwd) {
12124
- const configPath = path60.join(cwd, "harness.config.json");
12340
+ const configPath = path61.join(cwd, "harness.config.json");
12125
12341
  try {
12126
- const raw = JSON.parse(fs36.readFileSync(configPath, "utf-8"));
12342
+ const raw = JSON.parse(fs37.readFileSync(configPath, "utf-8"));
12127
12343
  return raw.telemetry !== void 0 && raw.adoption !== void 0;
12128
12344
  } catch {
12129
12345
  return false;
12130
12346
  }
12131
12347
  }
12132
12348
  function writeTelemetryConfig(cwd, result) {
12133
- const configPath = path60.join(cwd, "harness.config.json");
12349
+ const configPath = path61.join(cwd, "harness.config.json");
12134
12350
  try {
12135
- const raw = JSON.parse(fs36.readFileSync(configPath, "utf-8"));
12351
+ const raw = JSON.parse(fs37.readFileSync(configPath, "utf-8"));
12136
12352
  raw.telemetry = { enabled: result.telemetryEnabled };
12137
12353
  raw.adoption = { enabled: result.adoptionEnabled };
12138
- fs36.writeFileSync(configPath, JSON.stringify(raw, null, 2) + "\n");
12354
+ fs37.writeFileSync(configPath, JSON.stringify(raw, null, 2) + "\n");
12139
12355
  } catch (err) {
12140
12356
  console.warn(
12141
12357
  `\u26A0 Could not update ${configPath}: ${err instanceof Error ? err.message : String(err)}`
@@ -12143,10 +12359,10 @@ function writeTelemetryConfig(cwd, result) {
12143
12359
  }
12144
12360
  const hasIdentity = result.identity.project || result.identity.team || result.identity.alias;
12145
12361
  if (hasIdentity) {
12146
- const harnessDir = path60.join(cwd, ".harness");
12147
- fs36.mkdirSync(harnessDir, { recursive: true });
12148
- const telemetryFile = path60.join(harnessDir, "telemetry.json");
12149
- fs36.writeFileSync(telemetryFile, JSON.stringify({ identity: result.identity }, null, 2) + "\n");
12362
+ const harnessDir = path61.join(cwd, ".harness");
12363
+ fs37.mkdirSync(harnessDir, { recursive: true });
12364
+ const telemetryFile = path61.join(harnessDir, "telemetry.json");
12365
+ fs37.writeFileSync(telemetryFile, JSON.stringify({ identity: result.identity }, null, 2) + "\n");
12150
12366
  }
12151
12367
  }
12152
12368
  async function promptIdentity() {
@@ -12192,8 +12408,8 @@ async function runTelemetryWizard() {
12192
12408
  return { telemetryEnabled, adoptionEnabled, identity };
12193
12409
  }
12194
12410
  async function ensureTelemetryConfigured(cwd) {
12195
- const configPath = path60.join(cwd, "harness.config.json");
12196
- if (!fs36.existsSync(configPath)) {
12411
+ const configPath = path61.join(cwd, "harness.config.json");
12412
+ if (!fs37.existsSync(configPath)) {
12197
12413
  return { status: "warn", message: "Not a harness project \u2014 skipped telemetry configuration" };
12198
12414
  }
12199
12415
  if (isTelemetryConfigured(cwd)) {
@@ -12239,7 +12455,7 @@ function runSlashCommandGeneration() {
12239
12455
  }
12240
12456
  }
12241
12457
  function detectClient(dirName) {
12242
- return fs37.existsSync(path61.join(os9.homedir(), dirName));
12458
+ return fs38.existsSync(path62.join(os9.homedir(), dirName));
12243
12459
  }
12244
12460
  async function runMcpSetup(cwd) {
12245
12461
  const results = [];
@@ -12255,7 +12471,7 @@ async function runMcpSetup(cwd) {
12255
12471
  { name: "Cursor", dir: ".cursor", client: "cursor", configTarget: ".cursor/mcp.json" },
12256
12472
  {
12257
12473
  name: "OpenCode",
12258
- dir: path61.join(".config", "opencode"),
12474
+ dir: path62.join(".config", "opencode"),
12259
12475
  client: "opencode",
12260
12476
  configTarget: "opencode.json"
12261
12477
  }
@@ -12287,7 +12503,7 @@ function formatStep(result) {
12287
12503
  }
12288
12504
  function configureTier0Integrations(cwd) {
12289
12505
  try {
12290
- const mcpPath = path61.join(cwd, ".mcp.json");
12506
+ const mcpPath = path62.join(cwd, ".mcp.json");
12291
12507
  const config = readMcpConfig(mcpPath);
12292
12508
  const tier0 = INTEGRATION_REGISTRY.filter((i) => i.tier === 0);
12293
12509
  const added = [];
@@ -12296,9 +12512,9 @@ function configureTier0Integrations(cwd) {
12296
12512
  writeMcpEntry(mcpPath, integration.name, integration.mcpConfig);
12297
12513
  added.push(integration.displayName);
12298
12514
  }
12299
- const geminiDir = path61.join(cwd, ".gemini");
12300
- if (fs37.existsSync(geminiDir)) {
12301
- const geminiPath = path61.join(geminiDir, "settings.json");
12515
+ const geminiDir = path62.join(cwd, ".gemini");
12516
+ if (fs38.existsSync(geminiDir)) {
12517
+ const geminiPath = path62.join(geminiDir, "settings.json");
12302
12518
  const geminiConfig = readMcpConfig(geminiPath);
12303
12519
  for (const integration of tier0) {
12304
12520
  if (!geminiConfig.mcpServers[integration.name]) {
@@ -12306,9 +12522,9 @@ function configureTier0Integrations(cwd) {
12306
12522
  }
12307
12523
  }
12308
12524
  }
12309
- const opencodePath = path61.join(cwd, "opencode.json");
12310
- const opencodeGlobalDir = path61.join(os9.homedir(), ".config", "opencode");
12311
- if (fs37.existsSync(opencodePath) || fs37.existsSync(opencodeGlobalDir)) {
12525
+ const opencodePath = path62.join(cwd, "opencode.json");
12526
+ const opencodeGlobalDir = path62.join(os9.homedir(), ".config", "opencode");
12527
+ if (fs38.existsSync(opencodePath) || fs38.existsSync(opencodeGlobalDir)) {
12312
12528
  for (const integration of tier0) {
12313
12529
  writeOpencodeMcpEntry(opencodePath, integration.name, integration.mcpConfig);
12314
12530
  }
@@ -12326,14 +12542,14 @@ function configureTier0Integrations(cwd) {
12326
12542
  }
12327
12543
  }
12328
12544
  function ensureHooks(cwd) {
12329
- const configPath = path61.join(cwd, "harness.config.json");
12330
- if (!fs37.existsSync(configPath)) {
12545
+ const configPath = path62.join(cwd, "harness.config.json");
12546
+ if (!fs38.existsSync(configPath)) {
12331
12547
  return { status: "warn", message: "Not a harness project \u2014 skipped hook installation" };
12332
12548
  }
12333
12549
  let profile = "standard";
12334
- const profilePath = path61.join(cwd, ".harness", "hooks", "profile.json");
12550
+ const profilePath = path62.join(cwd, ".harness", "hooks", "profile.json");
12335
12551
  try {
12336
- const data = JSON.parse(fs37.readFileSync(profilePath, "utf-8"));
12552
+ const data = JSON.parse(fs38.readFileSync(profilePath, "utf-8"));
12337
12553
  if (data.profile && ["minimal", "standard", "strict"].includes(data.profile)) {
12338
12554
  profile = data.profile;
12339
12555
  }
@@ -12428,14 +12644,14 @@ function createSetupCommand() {
12428
12644
  // src/commands/share.ts
12429
12645
  init_dist3();
12430
12646
  import { Command as Command98 } from "commander";
12431
- import * as fs38 from "fs";
12432
- import * as path62 from "path";
12647
+ import * as fs39 from "fs";
12648
+ import * as path63 from "path";
12433
12649
  import { parse as parseYaml3 } from "yaml";
12434
12650
  var MANIFEST_FILENAME = "constraints.yaml";
12435
12651
  async function runShareAction(projectPath, options) {
12436
- const rootDir = path62.resolve(projectPath);
12437
- const manifestPath = path62.join(rootDir, MANIFEST_FILENAME);
12438
- if (!fs38.existsSync(manifestPath)) {
12652
+ const rootDir = path63.resolve(projectPath);
12653
+ const manifestPath = path63.join(rootDir, MANIFEST_FILENAME);
12654
+ if (!fs39.existsSync(manifestPath)) {
12439
12655
  logger.error(
12440
12656
  `No ${MANIFEST_FILENAME} found at ${manifestPath}.
12441
12657
  Create a constraints.yaml in your project root to define what to share.`
@@ -12444,7 +12660,7 @@ Create a constraints.yaml in your project root to define what to share.`
12444
12660
  }
12445
12661
  let parsed;
12446
12662
  try {
12447
- const raw = fs38.readFileSync(manifestPath, "utf-8");
12663
+ const raw = fs39.readFileSync(manifestPath, "utf-8");
12448
12664
  parsed = parseYaml3(raw);
12449
12665
  } catch (err) {
12450
12666
  logger.error(
@@ -12458,7 +12674,7 @@ Create a constraints.yaml in your project root to define what to share.`
12458
12674
  process.exit(1);
12459
12675
  }
12460
12676
  const manifest = manifestResult.value;
12461
- const configResult = resolveConfig(path62.join(rootDir, "harness.config.json"));
12677
+ const configResult = resolveConfig(path63.join(rootDir, "harness.config.json"));
12462
12678
  if (!configResult.ok) {
12463
12679
  logger.error(configResult.error.message);
12464
12680
  process.exit(1);
@@ -12476,8 +12692,8 @@ Create a constraints.yaml in your project root to define what to share.`
12476
12692
  );
12477
12693
  process.exit(1);
12478
12694
  }
12479
- const outputDir = path62.resolve(options.output);
12480
- const outputPath = path62.join(outputDir, `${manifest.name}.harness-constraints.json`);
12695
+ const outputDir = path63.resolve(options.output);
12696
+ const outputPath = path63.join(outputDir, `${manifest.name}.harness-constraints.json`);
12481
12697
  const writeResult = await writeConfig(outputPath, bundle);
12482
12698
  if (!writeResult.ok) {
12483
12699
  logger.error(`Failed to write bundle: ${writeResult.error.message}`);
@@ -12496,18 +12712,18 @@ import { Command as Command106 } from "commander";
12496
12712
 
12497
12713
  // src/commands/skill/list.ts
12498
12714
  import { Command as Command99 } from "commander";
12499
- import * as fs39 from "fs";
12500
- import * as path63 from "path";
12715
+ import * as fs40 from "fs";
12716
+ import * as path64 from "path";
12501
12717
  import { parse } from "yaml";
12502
12718
  function scanDirectory(dirPath, source) {
12503
- if (!fs39.existsSync(dirPath)) return [];
12504
- const entries = fs39.readdirSync(dirPath, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
12719
+ if (!fs40.existsSync(dirPath)) return [];
12720
+ const entries = fs40.readdirSync(dirPath, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
12505
12721
  const skills = [];
12506
12722
  for (const name of entries) {
12507
- const yamlPath = path63.join(dirPath, name, "skill.yaml");
12508
- if (!fs39.existsSync(yamlPath)) continue;
12723
+ const yamlPath = path64.join(dirPath, name, "skill.yaml");
12724
+ if (!fs40.existsSync(yamlPath)) continue;
12509
12725
  try {
12510
- const raw = fs39.readFileSync(yamlPath, "utf-8");
12726
+ const raw = fs40.readFileSync(yamlPath, "utf-8");
12511
12727
  const parsed = parse(raw);
12512
12728
  const result = SkillMetadataSchema.safeParse(parsed);
12513
12729
  if (result.success) {
@@ -12525,10 +12741,10 @@ function scanDirectory(dirPath, source) {
12525
12741
  }
12526
12742
  function collectCommunitySkills(seen, allSkills) {
12527
12743
  const globalDir = resolveGlobalSkillsDir();
12528
- const skillsDir = path63.dirname(globalDir);
12529
- const communityBase = path63.join(skillsDir, "community");
12530
- const communityPlatformDir = path63.join(communityBase, "claude-code");
12531
- const lockfilePath = path63.join(communityBase, "skills-lock.json");
12744
+ const skillsDir = path64.dirname(globalDir);
12745
+ const communityBase = path64.join(skillsDir, "community");
12746
+ const communityPlatformDir = path64.join(communityBase, "claude-code");
12747
+ const lockfilePath = path64.join(communityBase, "skills-lock.json");
12532
12748
  const lockfile = readLockfile2(lockfilePath);
12533
12749
  const communitySkills = scanDirectory(communityPlatformDir, "community");
12534
12750
  for (const skill of communitySkills) {
@@ -12614,8 +12830,8 @@ function createListCommand3() {
12614
12830
 
12615
12831
  // src/commands/skill/run.ts
12616
12832
  import { Command as Command100 } from "commander";
12617
- import * as fs40 from "fs";
12618
- import * as path64 from "path";
12833
+ import * as fs41 from "fs";
12834
+ import * as path65 from "path";
12619
12835
  import { parse as parse2 } from "yaml";
12620
12836
 
12621
12837
  // src/skill/complexity.ts
@@ -12711,10 +12927,10 @@ ${options.principles}`);
12711
12927
 
12712
12928
  // src/commands/skill/run.ts
12713
12929
  function loadSkillMetadata(skillDir) {
12714
- const yamlPath = path64.join(skillDir, "skill.yaml");
12715
- if (!fs40.existsSync(yamlPath)) return null;
12930
+ const yamlPath = path65.join(skillDir, "skill.yaml");
12931
+ if (!fs41.existsSync(yamlPath)) return null;
12716
12932
  try {
12717
- const result = SkillMetadataSchema.safeParse(parse2(fs40.readFileSync(yamlPath, "utf-8")));
12933
+ const result = SkillMetadataSchema.safeParse(parse2(fs41.readFileSync(yamlPath, "utf-8")));
12718
12934
  return result.success ? result.data : null;
12719
12935
  } catch {
12720
12936
  return null;
@@ -12726,22 +12942,22 @@ function resolveComplexity(metadata, requested, projectPath) {
12726
12942
  return requested;
12727
12943
  }
12728
12944
  function loadPrinciples(projectPath) {
12729
- const principlesPath = path64.join(projectPath, "docs", "principles.md");
12730
- return fs40.existsSync(principlesPath) ? fs40.readFileSync(principlesPath, "utf-8") : void 0;
12945
+ const principlesPath = path65.join(projectPath, "docs", "principles.md");
12946
+ return fs41.existsSync(principlesPath) ? fs41.readFileSync(principlesPath, "utf-8") : void 0;
12731
12947
  }
12732
12948
  function readMostRecentFileInDir(dirPath) {
12733
- const files = fs40.readdirSync(dirPath).map((f) => ({ name: f, mtime: fs40.statSync(path64.join(dirPath, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime);
12734
- if (files.length > 0) return fs40.readFileSync(path64.join(dirPath, files[0].name), "utf-8");
12949
+ const files = fs41.readdirSync(dirPath).map((f) => ({ name: f, mtime: fs41.statSync(path65.join(dirPath, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime);
12950
+ if (files.length > 0) return fs41.readFileSync(path65.join(dirPath, files[0].name), "utf-8");
12735
12951
  return void 0;
12736
12952
  }
12737
12953
  function loadPriorState(metadata, projectPath) {
12738
12954
  if (!metadata?.state.persistent || metadata.state.files.length === 0) return void 0;
12739
12955
  for (const stateFilePath of metadata.state.files) {
12740
- const fullPath = path64.join(projectPath, stateFilePath);
12741
- if (!fs40.existsSync(fullPath)) continue;
12742
- const stat = fs40.statSync(fullPath);
12956
+ const fullPath = path65.join(projectPath, stateFilePath);
12957
+ if (!fs41.existsSync(fullPath)) continue;
12958
+ const stat = fs41.statSync(fullPath);
12743
12959
  if (stat.isDirectory()) return readMostRecentFileInDir(fullPath);
12744
- return fs40.readFileSync(fullPath, "utf-8");
12960
+ return fs41.readFileSync(fullPath, "utf-8");
12745
12961
  }
12746
12962
  return void 0;
12747
12963
  }
@@ -12761,7 +12977,7 @@ function resolvePhaseState(metadata, projectPath, phase) {
12761
12977
  }
12762
12978
  async function appendProjectState(content, metadata, projectPath, hasPathOpt) {
12763
12979
  if (!metadata?.state.persistent || !hasPathOpt) return content;
12764
- const { readHarnessState: readHarnessState2, isEmptyHarnessState } = await import("./state-events-YY5KBZTC.js");
12980
+ const { readHarnessState: readHarnessState2, isEmptyHarnessState } = await import("./state-events-PBDNQPXT.js");
12765
12981
  const stateResult = await readHarnessState2(projectPath);
12766
12982
  if (!stateResult.ok || isEmptyHarnessState(stateResult.value)) return content;
12767
12983
  const stateContent = JSON.stringify(stateResult.value, null, 2);
@@ -12782,7 +12998,7 @@ async function runSkill(name, opts) {
12782
12998
  return;
12783
12999
  }
12784
13000
  const metadata = loadSkillMetadata(skillDir);
12785
- const projectPath = opts.path ? path64.resolve(opts.path) : process.cwd();
13001
+ const projectPath = opts.path ? path65.resolve(opts.path) : process.cwd();
12786
13002
  const complexity = resolveComplexity(
12787
13003
  metadata,
12788
13004
  opts.complexity ?? "standard",
@@ -12809,14 +13025,14 @@ async function runSkill(name, opts) {
12809
13025
  ...stateWarning !== void 0 && { stateWarning },
12810
13026
  ...opts.party !== void 0 && { party: opts.party }
12811
13027
  });
12812
- const skillMdPath = path64.join(skillDir, "SKILL.md");
12813
- if (!fs40.existsSync(skillMdPath)) {
13028
+ const skillMdPath = path65.join(skillDir, "SKILL.md");
13029
+ if (!fs41.existsSync(skillMdPath)) {
12814
13030
  logger.error(`SKILL.md not found for skill: ${name}`);
12815
13031
  process.exit(ExitCode.ERROR);
12816
13032
  return;
12817
13033
  }
12818
13034
  const content = await appendProjectState(
12819
- fs40.readFileSync(skillMdPath, "utf-8"),
13035
+ fs41.readFileSync(skillMdPath, "utf-8"),
12820
13036
  metadata,
12821
13037
  projectPath,
12822
13038
  !!opts.path
@@ -12835,8 +13051,8 @@ function createRunCommand3() {
12835
13051
 
12836
13052
  // src/commands/skill/validate.ts
12837
13053
  import { Command as Command101 } from "commander";
12838
- import * as fs41 from "fs";
12839
- import * as path65 from "path";
13054
+ import * as fs42 from "fs";
13055
+ import * as path66 from "path";
12840
13056
  import { parse as parse3 } from "yaml";
12841
13057
  var BEHAVIORAL_REQUIRED_SECTIONS = [
12842
13058
  "## When to Use",
@@ -12848,11 +13064,11 @@ var BEHAVIORAL_REQUIRED_SECTIONS = [
12848
13064
  ];
12849
13065
  var KNOWLEDGE_REQUIRED_SECTIONS = ["## Instructions"];
12850
13066
  function validateSkillMd(name, skillMdPath, skillType, errors) {
12851
- if (!fs41.existsSync(skillMdPath)) {
13067
+ if (!fs42.existsSync(skillMdPath)) {
12852
13068
  errors.push(`${name}: missing SKILL.md`);
12853
13069
  return;
12854
13070
  }
12855
- const mdContent = fs41.readFileSync(skillMdPath, "utf-8");
13071
+ const mdContent = fs42.readFileSync(skillMdPath, "utf-8");
12856
13072
  if (!mdContent.trim().startsWith("# ")) {
12857
13073
  errors.push(`${name}/SKILL.md: must start with an h1 heading`);
12858
13074
  }
@@ -12877,20 +13093,20 @@ function validateSkillMd(name, skillMdPath, skillType, errors) {
12877
13093
  }
12878
13094
  }
12879
13095
  function validateSkillEntry(name, skillsDir, errors) {
12880
- const skillDir = path65.join(skillsDir, name);
12881
- const yamlPath = path65.join(skillDir, "skill.yaml");
12882
- if (!fs41.existsSync(yamlPath)) {
13096
+ const skillDir = path66.join(skillsDir, name);
13097
+ const yamlPath = path66.join(skillDir, "skill.yaml");
13098
+ if (!fs42.existsSync(yamlPath)) {
12883
13099
  errors.push(`${name}: missing skill.yaml`);
12884
13100
  return false;
12885
13101
  }
12886
13102
  try {
12887
- const raw = fs41.readFileSync(yamlPath, "utf-8");
13103
+ const raw = fs42.readFileSync(yamlPath, "utf-8");
12888
13104
  const result = SkillMetadataSchema.safeParse(parse3(raw));
12889
13105
  if (!result.success) {
12890
13106
  errors.push(`${name}/skill.yaml: ${result.error.message}`);
12891
13107
  return false;
12892
13108
  }
12893
- validateSkillMd(name, path65.join(skillDir, "SKILL.md"), result.data.type, errors);
13109
+ validateSkillMd(name, path66.join(skillDir, "SKILL.md"), result.data.type, errors);
12894
13110
  return true;
12895
13111
  } catch (e) {
12896
13112
  errors.push(`${name}: parse error \u2014 ${e instanceof Error ? e.message : String(e)}`);
@@ -12901,12 +13117,12 @@ function createValidateCommand2() {
12901
13117
  return new Command101("validate").description("Validate all skill.yaml files and SKILL.md structure").action(async (_opts, cmd) => {
12902
13118
  const globalOpts = cmd.optsWithGlobals();
12903
13119
  const skillsDir = resolveSkillsDir();
12904
- if (!fs41.existsSync(skillsDir)) {
13120
+ if (!fs42.existsSync(skillsDir)) {
12905
13121
  logger.info("No skills directory found.");
12906
13122
  process.exit(ExitCode.SUCCESS);
12907
13123
  return;
12908
13124
  }
12909
- const entries = fs41.readdirSync(skillsDir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
13125
+ const entries = fs42.readdirSync(skillsDir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
12910
13126
  const errors = [];
12911
13127
  let validated = 0;
12912
13128
  for (const name of entries) {
@@ -12929,8 +13145,8 @@ function createValidateCommand2() {
12929
13145
 
12930
13146
  // src/commands/skill/info.ts
12931
13147
  import { Command as Command102 } from "commander";
12932
- import * as fs42 from "fs";
12933
- import * as path66 from "path";
13148
+ import * as fs43 from "fs";
13149
+ import * as path67 from "path";
12934
13150
  import { parse as parse4 } from "yaml";
12935
13151
  function loadSkillMetadata2(name) {
12936
13152
  const skillDir = resolveSkillDir(name);
@@ -12938,13 +13154,13 @@ function loadSkillMetadata2(name) {
12938
13154
  logger.error(`Skill not found: ${name}`);
12939
13155
  return { ok: false, exitCode: ExitCode.ERROR };
12940
13156
  }
12941
- const yamlPath = path66.join(skillDir, "skill.yaml");
12942
- if (!fs42.existsSync(yamlPath)) {
13157
+ const yamlPath = path67.join(skillDir, "skill.yaml");
13158
+ if (!fs43.existsSync(yamlPath)) {
12943
13159
  logger.error(`skill.yaml not found for skill: ${name}`);
12944
13160
  return { ok: false, exitCode: ExitCode.ERROR };
12945
13161
  }
12946
13162
  try {
12947
- const raw = fs42.readFileSync(yamlPath, "utf-8");
13163
+ const raw = fs43.readFileSync(yamlPath, "utf-8");
12948
13164
  const parsed = parse4(raw);
12949
13165
  const result = SkillMetadataSchema.safeParse(parsed);
12950
13166
  if (!result.success) {
@@ -13042,8 +13258,8 @@ function createSearchCommand2() {
13042
13258
 
13043
13259
  // src/commands/skill/create.ts
13044
13260
  import { Command as Command104 } from "commander";
13045
- import * as path67 from "path";
13046
- import * as fs43 from "fs";
13261
+ import * as path68 from "path";
13262
+ import * as fs44 from "fs";
13047
13263
  import YAML from "yaml";
13048
13264
  var KEBAB_CASE_RE = /^[a-z][a-z0-9]*(-[a-z0-9]+)*$/;
13049
13265
  function buildReadme(name, description) {
@@ -13127,22 +13343,22 @@ function runCreate(name, opts) {
13127
13343
  if (!KEBAB_CASE_RE.test(name)) {
13128
13344
  throw new Error(`Invalid skill name "${name}". Must be kebab-case (e.g., my-skill).`);
13129
13345
  }
13130
- const baseDir = opts.outputDir ?? path67.join(process.cwd(), "agents", "skills", "claude-code");
13131
- const skillDir = path67.join(baseDir, name);
13132
- if (fs43.existsSync(skillDir)) {
13346
+ const baseDir = opts.outputDir ?? path68.join(process.cwd(), "agents", "skills", "claude-code");
13347
+ const skillDir = path68.join(baseDir, name);
13348
+ if (fs44.existsSync(skillDir)) {
13133
13349
  throw new Error(`Skill directory already exists: ${skillDir}`);
13134
13350
  }
13135
- fs43.mkdirSync(skillDir, { recursive: true });
13351
+ fs44.mkdirSync(skillDir, { recursive: true });
13136
13352
  const description = opts.description || `A community skill: ${name}`;
13137
13353
  const skillYaml = buildSkillYaml(name, opts);
13138
- const skillYamlPath = path67.join(skillDir, "skill.yaml");
13139
- fs43.writeFileSync(skillYamlPath, YAML.stringify(skillYaml));
13354
+ const skillYamlPath = path68.join(skillDir, "skill.yaml");
13355
+ fs44.writeFileSync(skillYamlPath, YAML.stringify(skillYaml));
13140
13356
  const skillMd = buildSkillMd(name, description);
13141
- const skillMdPath = path67.join(skillDir, "SKILL.md");
13142
- fs43.writeFileSync(skillMdPath, skillMd);
13357
+ const skillMdPath = path68.join(skillDir, "SKILL.md");
13358
+ fs44.writeFileSync(skillMdPath, skillMd);
13143
13359
  const readme = buildReadme(name, description);
13144
- const readmePath = path67.join(skillDir, "README.md");
13145
- fs43.writeFileSync(readmePath, readme);
13360
+ const readmePath = path68.join(skillDir, "README.md");
13361
+ fs44.writeFileSync(readmePath, readme);
13146
13362
  return {
13147
13363
  name,
13148
13364
  directory: skillDir,
@@ -13156,7 +13372,7 @@ function printCreateResult(name, result) {
13156
13372
  }
13157
13373
  logger.info(`
13158
13374
  Next steps:`);
13159
- logger.info(` 1. Edit ${path67.join(result.directory, "SKILL.md")} with your skill content`);
13375
+ logger.info(` 1. Edit ${path68.join(result.directory, "SKILL.md")} with your skill content`);
13160
13376
  logger.info(` 2. Run: harness skill validate ${name}`);
13161
13377
  logger.info(` 3. Run: harness skills publish`);
13162
13378
  }
@@ -13185,25 +13401,25 @@ function createCreateCommand() {
13185
13401
 
13186
13402
  // src/commands/skill/publish.ts
13187
13403
  import { Command as Command105 } from "commander";
13188
- import * as fs45 from "fs";
13189
- import * as path69 from "path";
13404
+ import * as fs46 from "fs";
13405
+ import * as path70 from "path";
13190
13406
  import { execFileSync as execFileSync9 } from "child_process";
13191
13407
 
13192
13408
  // src/registry/validator.ts
13193
- import * as fs44 from "fs";
13194
- import * as path68 from "path";
13409
+ import * as fs45 from "fs";
13410
+ import * as path69 from "path";
13195
13411
  import { parse as parse5 } from "yaml";
13196
13412
  import semver4 from "semver";
13197
13413
  async function validateForPublish(skillDir, registryUrl) {
13198
13414
  const errors = [];
13199
- const skillYamlPath = path68.join(skillDir, "skill.yaml");
13200
- if (!fs44.existsSync(skillYamlPath)) {
13415
+ const skillYamlPath = path69.join(skillDir, "skill.yaml");
13416
+ if (!fs45.existsSync(skillYamlPath)) {
13201
13417
  errors.push("skill.yaml not found. Create one with: harness skill create <name>");
13202
13418
  return { valid: false, errors };
13203
13419
  }
13204
13420
  let skillMeta;
13205
13421
  try {
13206
- const raw = fs44.readFileSync(skillYamlPath, "utf-8");
13422
+ const raw = fs45.readFileSync(skillYamlPath, "utf-8");
13207
13423
  const parsed = parse5(raw);
13208
13424
  const result = SkillMetadataSchema.safeParse(parsed);
13209
13425
  if (!result.success) {
@@ -13225,11 +13441,11 @@ async function validateForPublish(skillDir, registryUrl) {
13225
13441
  if (!skillMeta.triggers || skillMeta.triggers.length === 0) {
13226
13442
  errors.push("At least one trigger is required. Add triggers to skill.yaml.");
13227
13443
  }
13228
- const skillMdPath = path68.join(skillDir, "SKILL.md");
13229
- if (!fs44.existsSync(skillMdPath)) {
13444
+ const skillMdPath = path69.join(skillDir, "SKILL.md");
13445
+ if (!fs45.existsSync(skillMdPath)) {
13230
13446
  errors.push("SKILL.md not found. Create it with content describing your skill.");
13231
13447
  } else {
13232
- const content = fs44.readFileSync(skillMdPath, "utf-8");
13448
+ const content = fs45.readFileSync(skillMdPath, "utf-8");
13233
13449
  if (!content.includes("## When to Use")) {
13234
13450
  errors.push('SKILL.md must contain a "## When to Use" section.');
13235
13451
  }
@@ -13309,11 +13525,11 @@ ${errorList}`);
13309
13525
  }
13310
13526
  const meta = validation.skillMeta;
13311
13527
  const pkg = derivePackageJson(meta);
13312
- const pkgPath = path69.join(skillDir, "package.json");
13313
- fs45.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + "\n");
13314
- const readmePath = path69.join(skillDir, "README.md");
13315
- if (!fs45.existsSync(readmePath)) {
13316
- const skillMdContent = fs45.readFileSync(path69.join(skillDir, "SKILL.md"), "utf-8");
13528
+ const pkgPath = path70.join(skillDir, "package.json");
13529
+ fs46.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + "\n");
13530
+ const readmePath = path70.join(skillDir, "README.md");
13531
+ if (!fs46.existsSync(readmePath)) {
13532
+ const skillMdContent = fs46.readFileSync(path70.join(skillDir, "SKILL.md"), "utf-8");
13317
13533
  const readme = `# ${pkg.name}
13318
13534
 
13319
13535
  ${meta.description}
@@ -13327,7 +13543,7 @@ harness install ${meta.name}
13327
13543
  ---
13328
13544
 
13329
13545
  ${skillMdContent}`;
13330
- fs45.writeFileSync(readmePath, readme);
13546
+ fs46.writeFileSync(readmePath, readme);
13331
13547
  }
13332
13548
  if (opts.dryRun) {
13333
13549
  return {
@@ -13631,10 +13847,10 @@ function printResult6(result, mode, _formatter) {
13631
13847
  list.push(f);
13632
13848
  byFile.set(f.target.file, list);
13633
13849
  }
13634
- for (const [file, fs50] of byFile) {
13850
+ for (const [file, fs51] of byFile) {
13635
13851
  console.log(`
13636
13852
  ${file}`);
13637
- for (const f of fs50) {
13853
+ for (const f of fs51) {
13638
13854
  console.log(
13639
13855
  ` ${f.code} [${f.tier}/${f.impact}/${f.confidence}] ## ${f.target.section}:${f.target.line}`
13640
13856
  );
@@ -13760,7 +13976,7 @@ import { Command as Command114 } from "commander";
13760
13976
 
13761
13977
  // src/commands/state/show.ts
13762
13978
  import { Command as Command110 } from "commander";
13763
- import * as path70 from "path";
13979
+ import * as path71 from "path";
13764
13980
  function printStateText(state, stream) {
13765
13981
  if (stream) console.log(`Stream: ${stream}`);
13766
13982
  console.log(`Schema Version: ${state.schemaVersion}`);
@@ -13786,7 +14002,7 @@ function printStateProgress(progress) {
13786
14002
  function createShowCommand() {
13787
14003
  return new Command110("show").description("Show current project state").option("--path <path>", "Project root path", ".").option("--stream <name>", "Target a specific stream").action(async (opts, cmd) => {
13788
14004
  const globalOpts = cmd.optsWithGlobals();
13789
- const result = await readHarnessState(path70.resolve(opts.path), { stream: opts.stream });
14005
+ const result = await readHarnessState(path71.resolve(opts.path), { stream: opts.stream });
13790
14006
  if (!result.ok) {
13791
14007
  logger.error(result.error.message);
13792
14008
  process.exit(ExitCode.ERROR);
@@ -13803,18 +14019,18 @@ function createShowCommand() {
13803
14019
  // src/commands/state/reset.ts
13804
14020
  init_dist3();
13805
14021
  import { Command as Command111 } from "commander";
13806
- import * as path71 from "path";
14022
+ import * as path72 from "path";
13807
14023
  import * as readline3 from "readline";
13808
14024
  async function confirmReset() {
13809
14025
  const rl = readline3.createInterface({ input: process.stdin, output: process.stdout });
13810
- const answer = await new Promise((resolve48) => {
13811
- rl.question("Reset project state? This cannot be undone. [y/N] ", resolve48);
14026
+ const answer = await new Promise((resolve50) => {
14027
+ rl.question("Reset project state? This cannot be undone. [y/N] ", resolve50);
13812
14028
  });
13813
14029
  rl.close();
13814
14030
  return answer.toLowerCase() === "y" || answer.toLowerCase() === "yes";
13815
14031
  }
13816
14032
  async function runReset(opts) {
13817
- const projectPath = path71.resolve(opts.path);
14033
+ const projectPath = path72.resolve(opts.path);
13818
14034
  if (!opts.yes && !await confirmReset()) {
13819
14035
  logger.info("Reset cancelled.");
13820
14036
  process.exit(ExitCode.SUCCESS);
@@ -13834,10 +14050,10 @@ function createResetCommand() {
13834
14050
  // src/commands/state/learn.ts
13835
14051
  init_dist3();
13836
14052
  import { Command as Command112 } from "commander";
13837
- import * as path72 from "path";
14053
+ import * as path73 from "path";
13838
14054
  function createLearnCommand() {
13839
14055
  return new Command112("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) => {
13840
- const projectPath = path72.resolve(opts.path);
14056
+ const projectPath = path73.resolve(opts.path);
13841
14057
  const result = await appendLearning(projectPath, message, void 0, void 0, opts.stream);
13842
14058
  if (!result.ok) {
13843
14059
  logger.error(result.error.message);
@@ -13852,9 +14068,9 @@ function createLearnCommand() {
13852
14068
  // src/commands/state/streams.ts
13853
14069
  init_dist3();
13854
14070
  import { Command as Command113 } from "commander";
13855
- import * as path73 from "path";
14071
+ import * as path74 from "path";
13856
14072
  async function runListStreams(opts, globalOpts) {
13857
- const projectPath = path73.resolve(opts.path);
14073
+ const projectPath = path74.resolve(opts.path);
13858
14074
  const indexResult = await loadStreamIndex(projectPath);
13859
14075
  const result = await listStreams(projectPath);
13860
14076
  if (!result.ok) {
@@ -13875,7 +14091,7 @@ async function runListStreams(opts, globalOpts) {
13875
14091
  process.exit(ExitCode.SUCCESS);
13876
14092
  }
13877
14093
  async function runCreateStream(name, opts) {
13878
- const result = await createStream(path73.resolve(opts.path), name, opts.branch);
14094
+ const result = await createStream(path74.resolve(opts.path), name, opts.branch);
13879
14095
  if (!result.ok) {
13880
14096
  logger.error(result.error.message);
13881
14097
  process.exit(ExitCode.ERROR);
@@ -13884,7 +14100,7 @@ async function runCreateStream(name, opts) {
13884
14100
  process.exit(ExitCode.SUCCESS);
13885
14101
  }
13886
14102
  async function runArchiveStream(name, opts) {
13887
- const result = await archiveStream(path73.resolve(opts.path), name);
14103
+ const result = await archiveStream(path74.resolve(opts.path), name);
13888
14104
  if (!result.ok) {
13889
14105
  logger.error(result.error.message);
13890
14106
  process.exit(ExitCode.ERROR);
@@ -13893,7 +14109,7 @@ async function runArchiveStream(name, opts) {
13893
14109
  process.exit(ExitCode.SUCCESS);
13894
14110
  }
13895
14111
  async function runActivateStream(name, opts) {
13896
- const result = await setActiveStream(path73.resolve(opts.path), name);
14112
+ const result = await setActiveStream(path74.resolve(opts.path), name);
13897
14113
  if (!result.ok) {
13898
14114
  logger.error(result.error.message);
13899
14115
  process.exit(ExitCode.ERROR);
@@ -13921,8 +14137,8 @@ function createStateCommand() {
13921
14137
  }
13922
14138
 
13923
14139
  // src/commands/sync-analyses.ts
13924
- import * as fs46 from "fs";
13925
- import * as path74 from "path";
14140
+ import * as fs47 from "fs";
14141
+ import * as path75 from "path";
13926
14142
  import { Command as Command115 } from "commander";
13927
14143
  init_dist3();
13928
14144
  function isValidRecord(record) {
@@ -13949,7 +14165,7 @@ function extractAnalysisFromComments(comments) {
13949
14165
  return null;
13950
14166
  }
13951
14167
  function bootstrapTrackerCommand2(opts, verb) {
13952
- const projectPath = path74.resolve(opts.dir);
14168
+ const projectPath = path75.resolve(opts.dir);
13953
14169
  const trackerConfig = loadTrackerSyncConfig(projectPath);
13954
14170
  if (!trackerConfig) {
13955
14171
  logger.error(`No tracker config found in harness.config.json. Cannot ${verb}.`);
@@ -13961,8 +14177,8 @@ function bootstrapTrackerCommand2(opts, verb) {
13961
14177
  );
13962
14178
  return null;
13963
14179
  }
13964
- const projectEnvPath = path74.join(projectPath, ".env");
13965
- if (fs46.existsSync(projectEnvPath) && !process.env.GITHUB_TOKEN) {
14180
+ const projectEnvPath = path75.join(projectPath, ".env");
14181
+ if (fs47.existsSync(projectEnvPath) && !process.env.GITHUB_TOKEN) {
13966
14182
  __require("dotenv").config({ path: projectEnvPath });
13967
14183
  }
13968
14184
  const token = process.env.GITHUB_TOKEN;
@@ -14048,9 +14264,9 @@ async function runSyncAnalyses(opts) {
14048
14264
  return;
14049
14265
  }
14050
14266
  const { AnalysisArchive, loadPublishedIndex: loadPublishedIndex2, savePublishedIndex: savePublishedIndex2 } = await import("@harness-engineering/orchestrator");
14051
- const { GitHubIssuesSyncAdapter: GitHubIssuesSyncAdapter2 } = await import("./dist-MCTEX5QH.js");
14267
+ const { GitHubIssuesSyncAdapter: GitHubIssuesSyncAdapter2 } = await import("./dist-BWFFVKEW.js");
14052
14268
  const adapter = new GitHubIssuesSyncAdapter2({ token, config: trackerConfig });
14053
- const archive = new AnalysisArchive(path74.join(projectPath, ".harness", "analyses"));
14269
+ const archive = new AnalysisArchive(path75.join(projectPath, ".harness", "analyses"));
14054
14270
  const publishedIndex = loadPublishedIndex2(projectPath);
14055
14271
  const { syncedCount, skippedCount, warnCount } = await syncFeatureAnalyses(
14056
14272
  features,
@@ -14085,7 +14301,7 @@ function createSyncAnalysesCommand() {
14085
14301
 
14086
14302
  // src/commands/sync-main.ts
14087
14303
  import { Command as Command116 } from "commander";
14088
- import * as path75 from "path";
14304
+ import * as path76 from "path";
14089
14305
  import {
14090
14306
  syncMain as defaultSyncMain
14091
14307
  } from "@harness-engineering/orchestrator";
@@ -14116,7 +14332,7 @@ function formatHuman2(r) {
14116
14332
  }
14117
14333
  function createSyncMainCommand() {
14118
14334
  return new Command116("sync-main").description("Fast-forward the local default branch from origin (no-op on conflict)").option("--json", "Emit a SyncMainResult JSON object", false).option("--path <path>", "Project root path", ".").action(async (opts) => {
14119
- const cwd = path75.resolve(opts.path ?? ".");
14335
+ const cwd = path76.resolve(opts.path ?? ".");
14120
14336
  const exitCode = await runSyncMain({ cwd, json: Boolean(opts.json) });
14121
14337
  process.exit(exitCode);
14122
14338
  });
@@ -14132,8 +14348,8 @@ function registerClearCommand(taint) {
14132
14348
  taint.command("clear [sessionId]").description(
14133
14349
  "Clear session taint \u2014 removes taint file(s) and re-enables destructive operations"
14134
14350
  ).action((sessionId) => {
14135
- const projectRoot2 = getProjectRoot();
14136
- const count = clearTaint(projectRoot2, sessionId);
14351
+ const projectRoot3 = getProjectRoot();
14352
+ const count = clearTaint(projectRoot3, sessionId);
14137
14353
  if (count === 0) {
14138
14354
  if (sessionId) {
14139
14355
  logger.info(`No taint found for session "${sessionId}".`);
@@ -14151,8 +14367,8 @@ function registerClearCommand(taint) {
14151
14367
  }
14152
14368
  });
14153
14369
  }
14154
- function printSingleSessionStatus(projectRoot2, sessionId) {
14155
- const result = checkTaint(projectRoot2, sessionId);
14370
+ function printSingleSessionStatus(projectRoot3, sessionId) {
14371
+ const result = checkTaint(projectRoot3, sessionId);
14156
14372
  if (result.expired) {
14157
14373
  logger.info(`Session "${sessionId}": taint expired (cleared).`);
14158
14374
  } else if (result.tainted && result.state) {
@@ -14167,15 +14383,15 @@ function printSingleSessionStatus(projectRoot2, sessionId) {
14167
14383
  logger.info(`Session "${sessionId}": clean (no taint).`);
14168
14384
  }
14169
14385
  }
14170
- function printAllSessionsStatus(projectRoot2) {
14171
- const sessions = listTaintedSessions(projectRoot2);
14386
+ function printAllSessionsStatus(projectRoot3) {
14387
+ const sessions = listTaintedSessions(projectRoot3);
14172
14388
  if (sessions.length === 0) {
14173
14389
  logger.info("No active taint sessions.");
14174
14390
  return;
14175
14391
  }
14176
14392
  logger.info(`Active taint sessions (${sessions.length}):`);
14177
14393
  for (const id of sessions) {
14178
- const result = checkTaint(projectRoot2, id);
14394
+ const result = checkTaint(projectRoot3, id);
14179
14395
  if (result.tainted && result.state) {
14180
14396
  const remaining = Math.max(
14181
14397
  0,
@@ -14187,11 +14403,11 @@ function printAllSessionsStatus(projectRoot2) {
14187
14403
  }
14188
14404
  function registerStatusCommand(taint) {
14189
14405
  taint.command("status [sessionId]").description("Show current taint status for a session or all sessions").action((sessionId) => {
14190
- const projectRoot2 = getProjectRoot();
14406
+ const projectRoot3 = getProjectRoot();
14191
14407
  if (sessionId) {
14192
- printSingleSessionStatus(projectRoot2, sessionId);
14408
+ printSingleSessionStatus(projectRoot3, sessionId);
14193
14409
  } else {
14194
- printAllSessionsStatus(projectRoot2);
14410
+ printAllSessionsStatus(projectRoot3);
14195
14411
  }
14196
14412
  });
14197
14413
  }
@@ -14208,16 +14424,16 @@ import { Command as Command121 } from "commander";
14208
14424
  // src/commands/telemetry/identify.ts
14209
14425
  init_dist3();
14210
14426
  import { Command as Command118 } from "commander";
14211
- import * as fs47 from "fs";
14212
- import * as path76 from "path";
14427
+ import * as fs48 from "fs";
14428
+ import * as path77 from "path";
14213
14429
  function telemetryFilePath(cwd) {
14214
- return path76.join(cwd, ".harness", "telemetry.json");
14430
+ return path77.join(cwd, ".harness", "telemetry.json");
14215
14431
  }
14216
14432
  function writeTelemetryFile(cwd, data) {
14217
14433
  const filePath = telemetryFilePath(cwd);
14218
- const dir = path76.dirname(filePath);
14219
- fs47.mkdirSync(dir, { recursive: true });
14220
- fs47.writeFileSync(filePath, JSON.stringify(data, null, 2) + "\n", "utf-8");
14434
+ const dir = path77.dirname(filePath);
14435
+ fs48.mkdirSync(dir, { recursive: true });
14436
+ fs48.writeFileSync(filePath, JSON.stringify(data, null, 2) + "\n", "utf-8");
14221
14437
  }
14222
14438
  var IDENTITY_FIELDS = ["project", "team", "alias"];
14223
14439
  function applyIdentityFields(opts, identity) {
@@ -14334,17 +14550,17 @@ init_dist3();
14334
14550
  import { Command as Command120 } from "commander";
14335
14551
 
14336
14552
  // src/bin/command-telemetry.ts
14337
- import { existsSync as existsSync43, readFileSync as readFileSync32, mkdirSync as mkdirSync22, appendFileSync, writeFileSync as writeFileSync28 } from "fs";
14338
- import { join as join63, parse as parsePath, resolve as resolve45 } from "path";
14553
+ import { existsSync as existsSync44, readFileSync as readFileSync32, mkdirSync as mkdirSync23, appendFileSync, writeFileSync as writeFileSync29 } from "fs";
14554
+ import { join as join64, parse as parsePath, resolve as resolve47 } from "path";
14339
14555
  import { spawn as spawn2 } from "child_process";
14340
14556
  var POSTHOG_API_KEY = "phc_wNTdCMcfJXZPgdNeDociZW6vwoGGo4nb7vqEfWThFfsG";
14341
14557
  var EXCLUDED_COMMANDS = /* @__PURE__ */ new Set(["help", "completion"]);
14342
14558
  function findProjectRoot(cwd) {
14343
- let dir = resolve45(cwd);
14559
+ let dir = resolve47(cwd);
14344
14560
  const { root } = parsePath(dir);
14345
14561
  while (dir !== root) {
14346
- if (existsSync43(join63(dir, "harness.config.json"))) return dir;
14347
- dir = resolve45(dir, "..");
14562
+ if (existsSync44(join64(dir, "harness.config.json"))) return dir;
14563
+ dir = resolve47(dir, "..");
14348
14564
  }
14349
14565
  return cwd;
14350
14566
  }
@@ -14353,8 +14569,8 @@ var startTime = 0;
14353
14569
  var recorded = false;
14354
14570
  function installCommandTelemetry(program, cwd) {
14355
14571
  if (typeof program.hook !== "function") return;
14356
- const projectRoot2 = findProjectRoot(cwd);
14357
- flushTelemetryBackground(projectRoot2);
14572
+ const projectRoot3 = findProjectRoot(cwd);
14573
+ flushTelemetryBackground(projectRoot3);
14358
14574
  program.hook("preAction", (_thisCommand, actionCommand) => {
14359
14575
  commandName = resolveCommandName(actionCommand);
14360
14576
  startTime = Date.now();
@@ -14364,7 +14580,7 @@ function installCommandTelemetry(program, cwd) {
14364
14580
  recorded = true;
14365
14581
  const duration = Date.now() - startTime;
14366
14582
  const outcome = code === 0 ? "completed" : "failed";
14367
- writeCommandRecordSync(projectRoot2, commandName, duration, outcome);
14583
+ writeCommandRecordSync(projectRoot3, commandName, duration, outcome);
14368
14584
  });
14369
14585
  }
14370
14586
  function resolveCommandName(cmd) {
@@ -14381,8 +14597,8 @@ function resolveCommandName(cmd) {
14381
14597
  }
14382
14598
  function writeCommandRecordSync(cwd, command, duration, outcome) {
14383
14599
  try {
14384
- const metricsDir = join63(cwd, ".harness", "metrics");
14385
- mkdirSync22(metricsDir, { recursive: true });
14600
+ const metricsDir = join64(cwd, ".harness", "metrics");
14601
+ mkdirSync23(metricsDir, { recursive: true });
14386
14602
  const record = {
14387
14603
  skill: command,
14388
14604
  session: `cli-${Date.now()}`,
@@ -14391,14 +14607,14 @@ function writeCommandRecordSync(cwd, command, duration, outcome) {
14391
14607
  outcome,
14392
14608
  phasesReached: []
14393
14609
  };
14394
- const adoptionFile = join63(metricsDir, "adoption.jsonl");
14610
+ const adoptionFile = join64(metricsDir, "adoption.jsonl");
14395
14611
  appendFileSync(adoptionFile, JSON.stringify(record) + "\n");
14396
14612
  } catch {
14397
14613
  }
14398
14614
  }
14399
14615
  function isTelemetryDisabledByConfig(cwd) {
14400
- const configPath = join63(cwd, "harness.config.json");
14401
- if (!existsSync43(configPath)) return false;
14616
+ const configPath = join64(cwd, "harness.config.json");
14617
+ if (!existsSync44(configPath)) return false;
14402
14618
  try {
14403
14619
  const config = JSON.parse(readFileSync32(configPath, "utf-8"));
14404
14620
  return config?.telemetry?.enabled === false;
@@ -14412,11 +14628,11 @@ function isTelemetryOptedOut(cwd) {
14412
14628
  }
14413
14629
  function flushTelemetryBackground(cwd) {
14414
14630
  try {
14415
- const adoptionFile = join63(cwd, ".harness", "metrics", "adoption.jsonl");
14416
- if (!existsSync43(adoptionFile)) return;
14631
+ const adoptionFile = join64(cwd, ".harness", "metrics", "adoption.jsonl");
14632
+ if (!existsSync44(adoptionFile)) return;
14417
14633
  if (isTelemetryOptedOut(cwd)) return;
14418
- const reporterPath = join63(cwd, ".harness", "hooks", "telemetry-reporter.js");
14419
- if (!existsSync43(reporterPath)) return;
14634
+ const reporterPath = join64(cwd, ".harness", "hooks", "telemetry-reporter.js");
14635
+ if (!existsSync44(reporterPath)) return;
14420
14636
  const child = spawn2(process.execPath, [reporterPath], {
14421
14637
  cwd,
14422
14638
  stdio: ["pipe", "ignore", "ignore"],
@@ -14548,10 +14764,10 @@ function printResult7(result, mode, _formatter) {
14548
14764
  list.push(f);
14549
14765
  byFile.set(f.target.file, list);
14550
14766
  }
14551
- for (const [file, fs50] of byFile) {
14767
+ for (const [file, fs51] of byFile) {
14552
14768
  console.log(`
14553
14769
  ${file}`);
14554
- for (const f of fs50) {
14770
+ for (const f of fs51) {
14555
14771
  const nestingStr = f.target.nesting.length > 0 ? f.target.nesting.join(" > ") + " > " : "";
14556
14772
  console.log(
14557
14773
  ` ${f.code} [${f.tier}/${f.impact}/${f.confidence}] ${f.target.framework}:${f.target.line}`
@@ -14723,15 +14939,15 @@ function createTraceabilityCommand() {
14723
14939
  }
14724
14940
 
14725
14941
  // src/commands/uninstall.ts
14726
- import * as path77 from "path";
14942
+ import * as path78 from "path";
14727
14943
  import { Command as Command124 } from "commander";
14728
14944
  async function runUninstall(skillName, options) {
14729
14945
  const packageName = resolvePackageName(skillName);
14730
14946
  const shortName = extractSkillName(packageName);
14731
14947
  const globalDir = resolveGlobalSkillsDir();
14732
- const skillsDir = path77.dirname(globalDir);
14733
- const communityBase = path77.join(skillsDir, "community");
14734
- const lockfilePath = path77.join(communityBase, "skills-lock.json");
14948
+ const skillsDir = path78.dirname(globalDir);
14949
+ const communityBase = path78.join(skillsDir, "community");
14950
+ const lockfilePath = path78.join(communityBase, "skills-lock.json");
14735
14951
  const lockfile = readLockfile2(lockfilePath);
14736
14952
  const entry = lockfile.skills[packageName];
14737
14953
  if (!entry) {
@@ -14781,8 +14997,8 @@ function createUninstallCommand() {
14781
14997
 
14782
14998
  // src/commands/uninstall-constraints.ts
14783
14999
  init_dist3();
14784
- import * as fs48 from "fs/promises";
14785
- import * as path78 from "path";
15000
+ import * as fs49 from "fs/promises";
15001
+ import * as path79 from "path";
14786
15002
  import { Command as Command125 } from "commander";
14787
15003
  async function runUninstallConstraints(options) {
14788
15004
  const { packageName, configPath, lockfilePath } = options;
@@ -14803,7 +15019,7 @@ async function runUninstallConstraints(options) {
14803
15019
  }
14804
15020
  let localConfig;
14805
15021
  try {
14806
- const raw = await fs48.readFile(configPath, "utf-8");
15022
+ const raw = await fs49.readFile(configPath, "utf-8");
14807
15023
  localConfig = JSON.parse(raw);
14808
15024
  } catch (err) {
14809
15025
  return {
@@ -14844,7 +15060,7 @@ function createUninstallConstraintsCommand() {
14844
15060
  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) => {
14845
15061
  let configPath;
14846
15062
  if (opts.config) {
14847
- configPath = path78.resolve(opts.config);
15063
+ configPath = path79.resolve(opts.config);
14848
15064
  } else {
14849
15065
  const found = findConfigFile();
14850
15066
  if (!found.ok) {
@@ -14853,8 +15069,8 @@ function createUninstallConstraintsCommand() {
14853
15069
  }
14854
15070
  configPath = found.value;
14855
15071
  }
14856
- const projectRoot2 = path78.dirname(configPath);
14857
- const lockfilePath = path78.join(projectRoot2, ".harness", "constraints.lock.json");
15072
+ const projectRoot3 = path79.dirname(configPath);
15073
+ const lockfilePath = path79.join(projectRoot3, ".harness", "constraints.lock.json");
14858
15074
  const result = await runUninstallConstraints({
14859
15075
  packageName: name,
14860
15076
  configPath,
@@ -14882,8 +15098,8 @@ function createUninstallConstraintsCommand() {
14882
15098
  init_dist3();
14883
15099
  import { Command as Command126 } from "commander";
14884
15100
  import { execFile as execFile2, execFileSync as execFileSync10 } from "child_process";
14885
- import { realpathSync, existsSync as existsSync44, readFileSync as readFileSync33 } from "fs";
14886
- import { dirname as dirname24, join as join66 } from "path";
15101
+ import { realpathSync, existsSync as existsSync45, readFileSync as readFileSync33 } from "fs";
15102
+ import { dirname as dirname25, join as join67 } from "path";
14887
15103
  import { promisify as promisify2 } from "util";
14888
15104
  import readline4 from "readline";
14889
15105
  import chalk20 from "chalk";
@@ -14964,24 +15180,24 @@ function prompt3(question) {
14964
15180
  input: process.stdin,
14965
15181
  output: process.stdout
14966
15182
  });
14967
- return new Promise((resolve48) => {
15183
+ return new Promise((resolve50) => {
14968
15184
  rl.question(question, (answer) => {
14969
15185
  rl.close();
14970
- resolve48(answer.trim().toLowerCase());
15186
+ resolve50(answer.trim().toLowerCase());
14971
15187
  });
14972
15188
  });
14973
15189
  }
14974
15190
  function findPackageDir(resolvedBin) {
14975
- let dir = dirname24(resolvedBin);
15191
+ let dir = dirname25(resolvedBin);
14976
15192
  for (let i = 0; i < 6; i++) {
14977
- if (existsSync44(join66(dir, "package.json"))) {
15193
+ if (existsSync45(join67(dir, "package.json"))) {
14978
15194
  try {
14979
- const pkg = JSON.parse(readFileSync33(join66(dir, "package.json"), "utf-8"));
15195
+ const pkg = JSON.parse(readFileSync33(join67(dir, "package.json"), "utf-8"));
14980
15196
  if (pkg?.name === CLI_PACKAGE) return dir;
14981
15197
  } catch {
14982
15198
  }
14983
15199
  }
14984
- const parent = dirname24(dir);
15200
+ const parent = dirname25(dir);
14985
15201
  if (parent === dir) return null;
14986
15202
  dir = parent;
14987
15203
  }
@@ -15021,7 +15237,7 @@ function findAllInstalls() {
15021
15237
  if (!packageDir) continue;
15022
15238
  let version = null;
15023
15239
  try {
15024
- const pkg = JSON.parse(readFileSync33(join66(packageDir, "package.json"), "utf-8"));
15240
+ const pkg = JSON.parse(readFileSync33(join67(packageDir, "package.json"), "utf-8"));
15025
15241
  if (typeof pkg?.version === "string") version = pkg.version;
15026
15242
  } catch {
15027
15243
  }
@@ -15114,10 +15330,10 @@ async function ensureTelemetryIfNeeded() {
15114
15330
  }
15115
15331
  function refreshHooks() {
15116
15332
  const cwd = process.cwd();
15117
- const configPath = join66(cwd, "harness.config.json");
15118
- if (!existsSync44(configPath)) return;
15333
+ const configPath = join67(cwd, "harness.config.json");
15334
+ if (!existsSync45(configPath)) return;
15119
15335
  let profile = "standard";
15120
- const profilePath = join66(cwd, ".harness", "hooks", "profile.json");
15336
+ const profilePath = join67(cwd, ".harness", "hooks", "profile.json");
15121
15337
  try {
15122
15338
  const data = JSON.parse(readFileSync33(profilePath, "utf-8"));
15123
15339
  if (data.profile && ["minimal", "standard", "strict"].includes(data.profile)) {
@@ -15260,7 +15476,7 @@ function createUpdateCommand() {
15260
15476
  // src/commands/usage.ts
15261
15477
  import { Command as Command127 } from "commander";
15262
15478
  async function loadAndPriceRecords(cwd, includeClaudeSessions = false) {
15263
- const { readCostRecords, loadPricingData, calculateCost, parseCCRecords } = await import("./dist-MCTEX5QH.js");
15479
+ const { readCostRecords, loadPricingData, calculateCost, parseCCRecords } = await import("./dist-BWFFVKEW.js");
15264
15480
  const records = readCostRecords(cwd);
15265
15481
  if (includeClaudeSessions) {
15266
15482
  const ccRecords = parseCCRecords();
@@ -15353,7 +15569,7 @@ function registerDailyCommand(usage) {
15353
15569
  else logger.info("No usage data found. Run some harness sessions first.");
15354
15570
  return;
15355
15571
  }
15356
- const { aggregateByDay } = await import("./dist-MCTEX5QH.js");
15572
+ const { aggregateByDay } = await import("./dist-BWFFVKEW.js");
15357
15573
  const limited = aggregateByDay(records).slice(0, days);
15358
15574
  if (globalOpts.json) {
15359
15575
  console.log(
@@ -15382,7 +15598,7 @@ function registerSessionsCommand(usage) {
15382
15598
  }
15383
15599
  return;
15384
15600
  }
15385
- const { aggregateBySession } = await import("./dist-MCTEX5QH.js");
15601
+ const { aggregateBySession } = await import("./dist-BWFFVKEW.js");
15386
15602
  const sessionData = aggregateBySession(records);
15387
15603
  const limited = sessionData.slice(0, limit);
15388
15604
  if (globalOpts.json) {
@@ -15462,7 +15678,7 @@ function registerSessionCommand(usage) {
15462
15678
  cwd,
15463
15679
  globalOpts.includeClaudeSessions
15464
15680
  );
15465
- const { aggregateBySession } = await import("./dist-MCTEX5QH.js");
15681
+ const { aggregateBySession } = await import("./dist-BWFFVKEW.js");
15466
15682
  const sessionData = aggregateBySession(records);
15467
15683
  const match = sessionData.find((s) => s.sessionId === id);
15468
15684
  if (!match) {
@@ -15497,7 +15713,7 @@ function registerLatestCommand(usage) {
15497
15713
  }
15498
15714
  return;
15499
15715
  }
15500
- const { aggregateBySession } = await import("./dist-MCTEX5QH.js");
15716
+ const { aggregateBySession } = await import("./dist-BWFFVKEW.js");
15501
15717
  const sessionData = aggregateBySession(records);
15502
15718
  const latest = sessionData[0];
15503
15719
  if (!latest) {
@@ -15539,8 +15755,8 @@ function createUsageCommand() {
15539
15755
  init_dist3();
15540
15756
  init_dist3();
15541
15757
  import { Command as Command128 } from "commander";
15542
- import * as fs49 from "fs";
15543
- import * as path79 from "path";
15758
+ import * as fs50 from "fs";
15759
+ import * as path80 from "path";
15544
15760
  import { execFileSync as execFileSync11 } from "child_process";
15545
15761
  async function runValidate(options) {
15546
15762
  const configResult = resolveConfig(options.configPath);
@@ -15548,7 +15764,7 @@ async function runValidate(options) {
15548
15764
  return configResult;
15549
15765
  }
15550
15766
  const config = configResult.value;
15551
- const cwd = options.cwd ?? (options.configPath ? path79.dirname(path79.resolve(options.configPath)) : process.cwd());
15767
+ const cwd = options.cwd ?? (options.configPath ? path80.dirname(path80.resolve(options.configPath)) : process.cwd());
15552
15768
  const result = {
15553
15769
  valid: true,
15554
15770
  checks: {
@@ -15558,7 +15774,7 @@ async function runValidate(options) {
15558
15774
  },
15559
15775
  issues: []
15560
15776
  };
15561
- const agentsMapPath = path79.resolve(cwd, config.agentsMapPath);
15777
+ const agentsMapPath = path80.resolve(cwd, config.agentsMapPath);
15562
15778
  const agentsResult = await validateAgentsMap(agentsMapPath);
15563
15779
  if (agentsResult.ok) {
15564
15780
  result.checks.agentsMap = true;
@@ -15655,9 +15871,9 @@ async function runValidate(options) {
15655
15871
  }
15656
15872
  });
15657
15873
  }
15658
- const gitattributesPath = path79.join(cwd, ".gitattributes");
15659
- if (fs49.existsSync(gitattributesPath)) {
15660
- const gitattributesContent = fs49.readFileSync(gitattributesPath, "utf-8");
15874
+ const gitattributesPath = path80.join(cwd, ".gitattributes");
15875
+ if (fs50.existsSync(gitattributesPath)) {
15876
+ const gitattributesContent = fs50.readFileSync(gitattributesPath, "utf-8");
15661
15877
  let driverConfigured = false;
15662
15878
  try {
15663
15879
  const out = execFileSync11("git", ["config", "--get", "merge.ours.driver"], {
@@ -15681,10 +15897,10 @@ async function runValidate(options) {
15681
15897
  }
15682
15898
  }
15683
15899
  if (detectRoadmapStorageMode(cwd) === "sharded") {
15684
- const shardDir = path79.join(cwd, "docs", "roadmap.d");
15900
+ const shardDir = path80.join(cwd, "docs", "roadmap.d");
15685
15901
  const regenerated = await regenerate(shardDir, createNodeRoadmapIO());
15686
- const aggregatePath = path79.join(cwd, "docs", "roadmap.md");
15687
- const committedAggregate = fs49.existsSync(aggregatePath) ? fs49.readFileSync(aggregatePath, "utf-8") : null;
15902
+ const aggregatePath = path80.join(cwd, "docs", "roadmap.md");
15903
+ const committedAggregate = fs50.existsSync(aggregatePath) ? fs50.readFileSync(aggregatePath, "utf-8") : null;
15688
15904
  const drift = checkRoadmapAggregateDrift({
15689
15905
  shardDirExists: true,
15690
15906
  committedAggregate,
@@ -15702,9 +15918,9 @@ async function runValidate(options) {
15702
15918
  result.checks.roadmapAggregateDrift = true;
15703
15919
  }
15704
15920
  }
15705
- const roadmapPath = path79.join(cwd, "docs", "roadmap.md");
15706
- if (fs49.existsSync(roadmapPath)) {
15707
- const parsed = parseRoadmap(fs49.readFileSync(roadmapPath, "utf-8"));
15921
+ const roadmapPath = path80.join(cwd, "docs", "roadmap.md");
15922
+ if (fs50.existsSync(roadmapPath)) {
15923
+ const parsed = parseRoadmap(fs50.readFileSync(roadmapPath, "utf-8"));
15708
15924
  if (parsed.ok) {
15709
15925
  const findings = checkRoadmapHealth(parsed.value);
15710
15926
  result.checks.roadmapHealth = !findings.some((f) => f.severity === "error");
@@ -15846,11 +16062,11 @@ function resolveValidateMode(globalOpts) {
15846
16062
  return OutputMode.TEXT;
15847
16063
  }
15848
16064
  async function printCrossCheckWarnings(mode) {
15849
- const { runCrossCheck: runCrossCheck2 } = await import("./validate-cross-check-OYKEDCST.js");
16065
+ const { runCrossCheck: runCrossCheck2 } = await import("./validate-cross-check-H2OUHTID.js");
15850
16066
  const cwd = process.cwd();
15851
16067
  const crossResult = await runCrossCheck2({
15852
- specsDir: path79.join(cwd, "docs", "specs"),
15853
- plansDir: path79.join(cwd, "docs", "plans"),
16068
+ specsDir: path80.join(cwd, "docs", "specs"),
16069
+ plansDir: path80.join(cwd, "docs", "plans"),
15854
16070
  projectPath: cwd
15855
16071
  });
15856
16072
  if (!crossResult.ok || crossResult.value.warnings === 0) return;