@harness-engineering/cli 2.7.0 → 2.7.1

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 (52) hide show
  1. package/dist/agents/skills/claude-code/naming-craft/SKILL.md +74 -2
  2. package/dist/agents/skills/codex/naming-craft/SKILL.md +74 -2
  3. package/dist/agents/skills/cursor/naming-craft/SKILL.md +74 -2
  4. package/dist/agents/skills/gemini-cli/naming-craft/SKILL.md +74 -2
  5. package/dist/{agents-md-267R2NUJ.js → agents-md-FKMKH6ZF.js} +3 -3
  6. package/dist/{analyzer-VY6DJVOU-WYKV3TTW.js → analyzer-H3AHBFSL-KPOPJYRB.js} +7 -7
  7. package/dist/{architecture-ZTEHGIHD.js → architecture-LUR2I67H.js} +4 -4
  8. package/dist/{assess-project-OKDW3YSK.js → assess-project-OJWECOP2.js} +1 -1
  9. package/dist/bin/harness-mcp.js +14 -14
  10. package/dist/bin/harness.js +23 -23
  11. package/dist/{check-phase-gate-YJWFDW66.js → check-phase-gate-HS5KYLRO.js} +4 -4
  12. package/dist/{chunk-MQG7FHXX.js → chunk-7AF6C5GE.js} +3 -3
  13. package/dist/{chunk-4EGPFB7V.js → chunk-7PLIWP7U.js} +961 -256
  14. package/dist/{chunk-WOXR6I3R.js → chunk-B2VAYLYI.js} +1 -1
  15. package/dist/{chunk-67RP7MLR.js → chunk-CZPOPMMI.js} +2 -2
  16. package/dist/{chunk-OLTVDPA2.js → chunk-FC4JPM6W.js} +2 -2
  17. package/dist/{chunk-CXAHK5PJ.js → chunk-FEKBXX2J.js} +6 -6
  18. package/dist/{chunk-B4OLYXZ4.js → chunk-FXZI6NJ2.js} +39 -4
  19. package/dist/{chunk-6T5AYG5S.js → chunk-GGSNWH7P.js} +2 -2
  20. package/dist/{chunk-ZKA3TGYS.js → chunk-INBTDBV2.js} +1 -1
  21. package/dist/{chunk-HMMSWRWR.js → chunk-KN3EMDZ5.js} +2 -2
  22. package/dist/{chunk-OQE6ME2Z.js → chunk-LECXPXS3.js} +1 -1
  23. package/dist/{chunk-HLPY3RHE.js → chunk-LGYXR2KZ.js} +799 -515
  24. package/dist/{chunk-QUPC37UB.js → chunk-LYIPI2SJ.js} +3 -3
  25. package/dist/{chunk-S7GEONXL.js → chunk-N5NSSLMU.js} +1 -1
  26. package/dist/{chunk-P7EO7USC.js → chunk-NIVWM7OW.js} +5 -5
  27. package/dist/{chunk-PARV3G2F.js → chunk-O2ASYKA6.js} +1 -1
  28. package/dist/{chunk-XTIPZUPR.js → chunk-PTHX545Q.js} +1 -1
  29. package/dist/{chunk-B3B64OPD.js → chunk-RJ2WEES5.js} +1 -1
  30. package/dist/{chunk-TIZ3L6CU.js → chunk-VI4IS55S.js} +6 -6
  31. package/dist/{chunk-VG6UK6G6.js → chunk-VSIRUZQP.js} +1 -1
  32. package/dist/{chunk-IY2TZLY5.js → chunk-WZY5U6NS.js} +4 -4
  33. package/dist/{chunk-W3PDVZ4I.js → chunk-Y4T6ENKQ.js} +8 -8
  34. package/dist/{chunk-Z2GUITAS.js → chunk-Z3TMCCZB.js} +3 -3
  35. package/dist/{ci-workflow-YGTQTNVC.js → ci-workflow-MDSTHJOY.js} +3 -3
  36. package/dist/{dist-XIJWWQ5N.js → dist-72ID44UE.js} +2 -2
  37. package/dist/{docs-KCTLXK2G.js → docs-2RFOJ6XY.js} +4 -4
  38. package/dist/{engine-J64WPH5K.js → engine-BSFKOGPN.js} +3 -3
  39. package/dist/{entropy-M27JUL3V.js → entropy-3UX6644G.js} +3 -3
  40. package/dist/{feedback-W25QO3OL.js → feedback-CVCFYND4.js} +1 -1
  41. package/dist/{generate-agent-definitions-RNMU5U5R.js → generate-agent-definitions-HZ3XENWO.js} +4 -4
  42. package/dist/index.d.ts +425 -6
  43. package/dist/index.js +23 -23
  44. package/dist/{loader-HZKJ5ABV.js → loader-6RHWU5FH.js} +3 -3
  45. package/dist/{mcp-NEAPIDTT.js → mcp-OYR26JDI.js} +14 -14
  46. package/dist/{performance-3AVQUDRG.js → performance-JJMIRXCH.js} +4 -4
  47. package/dist/{review-pipeline-KA7SGUXJ.js → review-pipeline-BHQZIXWZ.js} +3 -3
  48. package/dist/{runtime-IP6FVV5M.js → runtime-DALTAVTN.js} +3 -3
  49. package/dist/{security-EAR4FJWI.js → security-RMLMYFPB.js} +1 -1
  50. package/dist/{validate-EVH3UXIC.js → validate-R7DZRDFK.js} +4 -4
  51. package/dist/{validate-cross-check-SNE3SQOB.js → validate-cross-check-AUUZFNVL.js} +3 -3
  52. package/package.json +4 -4
@@ -1,16 +1,16 @@
1
1
  import {
2
2
  generateRuntime
3
- } from "./chunk-S7GEONXL.js";
3
+ } from "./chunk-N5NSSLMU.js";
4
4
  import {
5
5
  generateAgentsMd
6
- } from "./chunk-OQE6ME2Z.js";
6
+ } from "./chunk-LECXPXS3.js";
7
7
  import {
8
8
  generateCIWorkflow
9
- } from "./chunk-B3B64OPD.js";
9
+ } from "./chunk-RJ2WEES5.js";
10
10
  import {
11
11
  createGenerateAgentDefinitionsCommand,
12
12
  generateAgentDefinitions
13
- } from "./chunk-ZKA3TGYS.js";
13
+ } from "./chunk-INBTDBV2.js";
14
14
  import {
15
15
  toKebabCase
16
16
  } from "./chunk-KET4QQZB.js";
@@ -20,7 +20,7 @@ import {
20
20
  } from "./chunk-6UHDQP2N.js";
21
21
  import {
22
22
  TemplateEngine
23
- } from "./chunk-WOXR6I3R.js";
23
+ } from "./chunk-B2VAYLYI.js";
24
24
  import {
25
25
  generate,
26
26
  validate
@@ -31,7 +31,7 @@ import {
31
31
  import {
32
32
  listPersonas,
33
33
  loadPersona
34
- } from "./chunk-XTIPZUPR.js";
34
+ } from "./chunk-PTHX545Q.js";
35
35
  import {
36
36
  runPersona
37
37
  } from "./chunk-GISMXMVL.js";
@@ -46,19 +46,21 @@ import {
46
46
  OutputMode,
47
47
  createCheckPhaseGateCommand,
48
48
  findFiles
49
- } from "./chunk-OLTVDPA2.js";
49
+ } from "./chunk-FC4JPM6W.js";
50
50
  import {
51
51
  appendFrameworkAgents,
52
52
  captureHealthSnapshot,
53
53
  createAdviseSkillsCommand,
54
54
  createGenerateSlashCommandsCommand,
55
55
  ensureHarnessGitignore,
56
+ findOrchestratorMd,
56
57
  generateSlashCommands,
57
58
  handleGetImpact,
58
59
  handleOrphanDeletion,
59
60
  isSnapshotFresh,
60
61
  loadCachedSnapshot,
61
62
  persistToolingConfig,
63
+ readBackendsFromOrchestratorMd,
62
64
  recommend,
63
65
  runAlignDesignSystem,
64
66
  runAudit,
@@ -72,7 +74,7 @@ import {
72
74
  runSecurityCraft,
73
75
  runSpecCraft,
74
76
  runTestCraft
75
- } from "./chunk-4EGPFB7V.js";
77
+ } from "./chunk-7PLIWP7U.js";
76
78
  import {
77
79
  VALID_PLATFORMS
78
80
  } from "./chunk-3ISINLYT.js";
@@ -97,7 +99,7 @@ import {
97
99
  BranchingConfigSchema,
98
100
  findConfigFile,
99
101
  resolveConfig
100
- } from "./chunk-B4OLYXZ4.js";
102
+ } from "./chunk-FXZI6NJ2.js";
101
103
  import {
102
104
  logger
103
105
  } from "./chunk-EBJQ6N4M.js";
@@ -191,7 +193,7 @@ import {
191
193
  validateSolutionsDir,
192
194
  writeConfig,
193
195
  writeLockfile
194
- } from "./chunk-IY2TZLY5.js";
196
+ } from "./chunk-WZY5U6NS.js";
195
197
  import {
196
198
  CLI_VERSION
197
199
  } from "./chunk-BM3PWGXQ.js";
@@ -204,7 +206,7 @@ import {
204
206
  detectDocDrift,
205
207
  generateSuggestions,
206
208
  validateDependencies
207
- } from "./chunk-W3PDVZ4I.js";
209
+ } from "./chunk-Y4T6ENKQ.js";
208
210
  import {
209
211
  Err,
210
212
  INDEXED_FILE_KINDS,
@@ -228,7 +230,7 @@ import {
228
230
  } from "./chunk-KFQGP6VL.js";
229
231
 
230
232
  // src/index.ts
231
- import { Command as Command118 } from "commander";
233
+ import { Command as Command120 } from "commander";
232
234
 
233
235
  // src/commands/add.ts
234
236
  init_dist3();
@@ -417,7 +419,7 @@ function registerSkillsCommand(adoption) {
417
419
  const globalOpts = cmd.optsWithGlobals();
418
420
  const limit = Math.max(parseInt(opts.limit, 10) || 20, 1);
419
421
  const cwd = process.cwd();
420
- const { readAdoptionRecords, aggregateBySkill } = await import("./dist-XIJWWQ5N.js");
422
+ const { readAdoptionRecords, aggregateBySkill } = await import("./dist-72ID44UE.js");
421
423
  const records = readAdoptionRecords(cwd);
422
424
  if (records.length === 0) {
423
425
  if (globalOpts.json) {
@@ -453,7 +455,7 @@ function registerRecentCommand(adoption) {
453
455
  const globalOpts = cmd.optsWithGlobals();
454
456
  const limit = Math.max(parseInt(opts.limit, 10) || 20, 1);
455
457
  const cwd = process.cwd();
456
- const { readAdoptionRecords } = await import("./dist-XIJWWQ5N.js");
458
+ const { readAdoptionRecords } = await import("./dist-72ID44UE.js");
457
459
  const records = readAdoptionRecords(cwd);
458
460
  if (records.length === 0) {
459
461
  if (globalOpts.json) {
@@ -531,7 +533,7 @@ function registerSkillCommand(adoption) {
531
533
  adoption.command("skill <name>").description("Show detail for a specific skill").action(async (name, _opts, cmd) => {
532
534
  const globalOpts = cmd.optsWithGlobals();
533
535
  const cwd = process.cwd();
534
- const { readAdoptionRecords, aggregateBySkill } = await import("./dist-XIJWWQ5N.js");
536
+ const { readAdoptionRecords, aggregateBySkill } = await import("./dist-72ID44UE.js");
535
537
  const records = readAdoptionRecords(cwd);
536
538
  const skillRecords = records.filter((r) => r.skill === name);
537
539
  if (skillRecords.length === 0) {
@@ -1124,7 +1126,7 @@ function runBackfillSkillProvenance(projectRoot2) {
1124
1126
  }
1125
1127
  function createBackfillSkillProvenanceCommand() {
1126
1128
  const cmd = new Command8("backfill-skill-provenance").description(
1127
- "Stamp `provenance: user-authored` on every catalog skill missing the field (Hermes Phase 4 one-shot)"
1129
+ "Stamp `provenance: user-authored` on every catalog skill missing the field (one-shot migration)"
1128
1130
  ).option("--root <path>", "Project root containing agents/skills/", process.cwd()).action((opts) => {
1129
1131
  const result = runBackfillSkillProvenance(opts.root);
1130
1132
  console.log(JSON.stringify(result, null, 2));
@@ -1652,9 +1654,9 @@ ${name} (${count} finding${count === 1 ? "" : "s"})`);
1652
1654
  }
1653
1655
  function printAnatomyFindings(findings, verbose) {
1654
1656
  const byFile = groupByFile(findings, (f) => f.file);
1655
- for (const [file, fs47] of byFile) {
1657
+ for (const [file, fs48] of byFile) {
1656
1658
  console.log(` ${file}`);
1657
- for (const f of fs47) {
1659
+ for (const f of fs48) {
1658
1660
  const line = f.line !== null && f.line !== void 0 ? `:${f.line}` : "";
1659
1661
  console.log(` ${f.code} [${f.severity}] line${line}: ${f.message}`);
1660
1662
  if (verbose) {
@@ -1665,9 +1667,9 @@ function printAnatomyFindings(findings, verbose) {
1665
1667
  }
1666
1668
  function printCraftFindings(findings, verbose) {
1667
1669
  const byFile = groupByFile(findings, (f) => f.target.file);
1668
- for (const [file, fs47] of byFile) {
1670
+ for (const [file, fs48] of byFile) {
1669
1671
  console.log(` ${file}`);
1670
- for (const f of fs47) {
1672
+ for (const f of fs48) {
1671
1673
  const line = f.target.line !== void 0 ? `:${f.target.line}` : "";
1672
1674
  const sev = craftTierToSeverity(f.tier);
1673
1675
  console.log(
@@ -1681,9 +1683,9 @@ function printCraftFindings(findings, verbose) {
1681
1683
  }
1682
1684
  function printDriftFindings(findings, verbose) {
1683
1685
  const byFile = groupByFile(findings, (f) => f.file);
1684
- for (const [file, fs47] of byFile) {
1686
+ for (const [file, fs48] of byFile) {
1685
1687
  console.log(` ${file}`);
1686
- for (const f of fs47) {
1688
+ for (const f of fs48) {
1687
1689
  const line = f.line !== null && f.line !== void 0 ? `:${f.line}` : "";
1688
1690
  console.log(` ${f.code} [${f.severity}] line${line}: ${f.message}`);
1689
1691
  if (verbose) {
@@ -1694,9 +1696,9 @@ function printDriftFindings(findings, verbose) {
1694
1696
  }
1695
1697
  function printBrandFindings(findings, verbose) {
1696
1698
  const byFile = groupByFile(findings, (f) => f.file);
1697
- for (const [file, fs47] of byFile) {
1699
+ for (const [file, fs48] of byFile) {
1698
1700
  console.log(` ${file}`);
1699
- for (const f of fs47) {
1701
+ for (const f of fs48) {
1700
1702
  const line = f.line !== null && f.line !== void 0 ? `:${f.line}` : "";
1701
1703
  console.log(` ${f.code} [${f.severity}] line${line}: ${f.message}`);
1702
1704
  if (verbose) {
@@ -2015,10 +2017,10 @@ async function runCheckSecurity(cwd, options) {
2015
2017
  const projectRoot2 = path9.resolve(cwd);
2016
2018
  let configData = {};
2017
2019
  try {
2018
- const fs47 = await import("fs");
2020
+ const fs48 = await import("fs");
2019
2021
  const configPath = path9.join(projectRoot2, "harness.config.json");
2020
- if (fs47.existsSync(configPath)) {
2021
- const raw = fs47.readFileSync(configPath, "utf-8");
2022
+ if (fs48.existsSync(configPath)) {
2023
+ const raw = fs48.readFileSync(configPath, "utf-8");
2022
2024
  const parsed = JSON.parse(raw);
2023
2025
  configData = parsed.security ?? {};
2024
2026
  }
@@ -2786,10 +2788,10 @@ ${dryRun ? "Would remove" : "Removed"} ${totalRemoved} stale entry(ies) across t
2786
2788
  function createCleanupSessionsCommand() {
2787
2789
  const command = new Command21("cleanup-sessions").description(
2788
2790
  "Remove stale entries from .harness/. Default: only .harness/sessions/ (no write in 24h)."
2789
- ).option("--dry-run", "List stale entries without deleting them", false).option("--path <path>", "Project root path", ".").option("--all", "Hermes Phase 2: sweep every registered .harness/ target").option(
2791
+ ).option("--dry-run", "List stale entries without deleting them", false).option("--path <path>", "Project root path", ".").option("--all", "Sweep every registered .harness/ target").option(
2790
2792
  "--include <list>",
2791
- "Hermes Phase 2: comma-separated target names (mutually-exclusive with --exclude/--all)"
2792
- ).option("--exclude <list>", "Hermes Phase 2: comma-separated target names to skip").action(async (opts, cmd) => {
2793
+ "Comma-separated target names (mutually-exclusive with --exclude/--all)"
2794
+ ).option("--exclude <list>", "Comma-separated target names to skip").action(async (opts, cmd) => {
2793
2795
  const globalOpts = cmd.optsWithGlobals();
2794
2796
  const cwd = path12.resolve(opts.path);
2795
2797
  const asJson = Boolean(globalOpts.json);
@@ -2979,10 +2981,10 @@ function printResult2(result, mode, _formatter) {
2979
2981
  list.push(f);
2980
2982
  bySurface.set(f.target.surface, list);
2981
2983
  }
2982
- for (const [surface, fs47] of bySurface) {
2984
+ for (const [surface, fs48] of bySurface) {
2983
2985
  console.log(`
2984
2986
  [${surface}]`);
2985
- for (const f of fs47) {
2987
+ for (const f of fs48) {
2986
2988
  const line = f.target.line !== void 0 ? `:${f.target.line}` : "";
2987
2989
  console.log(` ${f.code} [${f.tier}/${f.impact}/${f.confidence}] ${f.target.file}${line}`);
2988
2990
  console.log(` "${truncate(f.target.snippet, 80)}"`);
@@ -4210,11 +4212,11 @@ import { Command as Command35 } from "commander";
4210
4212
  // src/commands/graph/status.ts
4211
4213
  import * as path16 from "path";
4212
4214
  async function readConnectorSyncStatus(graphDir) {
4213
- const fs47 = await import("fs/promises");
4215
+ const fs48 = await import("fs/promises");
4214
4216
  const result = {};
4215
4217
  try {
4216
4218
  const syncMetaPath = path16.join(graphDir, "sync-metadata.json");
4217
- const syncMeta = JSON.parse(await fs47.readFile(syncMetaPath, "utf-8"));
4219
+ const syncMeta = JSON.parse(await fs48.readFile(syncMetaPath, "utf-8"));
4218
4220
  for (const [name, data] of Object.entries(syncMeta.connectors ?? {})) {
4219
4221
  result[name] = data.lastSyncTimestamp;
4220
4222
  }
@@ -4364,9 +4366,9 @@ import { Command as Command34 } from "commander";
4364
4366
  import * as path19 from "path";
4365
4367
  async function loadConnectorConfig(projectPath, source) {
4366
4368
  try {
4367
- const fs47 = await import("fs/promises");
4369
+ const fs48 = await import("fs/promises");
4368
4370
  const configPath = path19.join(projectPath, "harness.config.json");
4369
- const config = JSON.parse(await fs47.readFile(configPath, "utf-8"));
4371
+ const config = JSON.parse(await fs48.readFile(configPath, "utf-8"));
4370
4372
  const connector = config.graph?.connectors?.[source];
4371
4373
  return connector ?? {};
4372
4374
  } catch {
@@ -5356,6 +5358,7 @@ var ALL_MCP_TOOLS = [
5356
5358
  "run_design_pipeline",
5357
5359
  // craft-pipeline #1 — naming-craft LLM-judgment ceiling skill
5358
5360
  "naming_craft",
5361
+ "naming_craft_finalize",
5359
5362
  // craft-pipeline #6 — spec-craft LLM-judgment ceiling skill
5360
5363
  "spec_craft",
5361
5364
  // craft-pipeline #5 — copy-craft LLM-judgment ceiling skill (6 surfaces)
@@ -5738,12 +5741,10 @@ function renderPretty(report) {
5738
5741
  }
5739
5742
  }
5740
5743
  function createInsightsCommand() {
5741
- return new Command44("insights").description(
5742
- "Composite project report \u2014 health, entropy, decay, attention, impact (Hermes Phase 1)."
5743
- ).option("--json", "Emit JSON to stdout instead of pretty text").option("--skip <list>", `Comma-separated keys to skip (${INSIGHTS_KEYS.join(",")})`).action(async (opts) => {
5744
+ return new Command44("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) => {
5744
5745
  const cwd = process.cwd();
5745
5746
  const skip = parseSkip2(opts.skip);
5746
- const { composeInsights } = await import("./dist-XIJWWQ5N.js");
5747
+ const { composeInsights } = await import("./dist-72ID44UE.js");
5747
5748
  const report = await composeInsights(cwd, { skip });
5748
5749
  if (opts.json) {
5749
5750
  console.log(JSON.stringify(report, null, 2));
@@ -6915,10 +6916,10 @@ function printResult3(result, mode, _formatter) {
6915
6916
  list.push(f);
6916
6917
  byFile.set(f.target.file, list);
6917
6918
  }
6918
- for (const [file, fs47] of byFile) {
6919
+ for (const [file, fs48] of byFile) {
6919
6920
  console.log(`
6920
6921
  ${file}`);
6921
- for (const f of fs47) {
6922
+ for (const f of fs48) {
6922
6923
  console.log(` ${f.code} [${f.tier}/${f.impact}/${f.confidence}] ${f.target.relative}`);
6923
6924
  console.log(` ${f.message}`);
6924
6925
  if (verbose) console.log(` source: ${f.cite.source}`);
@@ -6941,8 +6942,8 @@ function createKnowledgePipelineCommand() {
6941
6942
  const projectDir = process.cwd();
6942
6943
  try {
6943
6944
  const graphDir = path39.join(projectDir, ".harness", "graph");
6944
- const fs47 = await import("fs/promises");
6945
- await fs47.mkdir(graphDir, { recursive: true });
6945
+ const fs48 = await import("fs/promises");
6946
+ await fs48.mkdir(graphDir, { recursive: true });
6946
6947
  const { GraphStore: GraphStore2, KnowledgePipelineRunner } = await import("./dist-R3TOOPJ7.js");
6947
6948
  const store = new GraphStore2();
6948
6949
  try {
@@ -7351,7 +7352,7 @@ function printListTable(rows) {
7351
7352
  }
7352
7353
  function createMaintenanceCommand() {
7353
7354
  const command = new Command59("maintenance").description(
7354
- "Hermes Phase 2 \u2014 inspect built-in + custom maintenance tasks and their persisted outputs"
7355
+ "Inspect built-in + custom maintenance tasks and their persisted outputs"
7355
7356
  );
7356
7357
  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) => {
7357
7358
  const cwd = path41.resolve(opts.path);
@@ -7445,7 +7446,7 @@ function createMcpCommand() {
7445
7446
  parseBudget
7446
7447
  ).action(async (opts) => {
7447
7448
  const [{ startServer: startServer2, getToolDefinitions: getToolDefinitions2 }, { selectTier }] = await Promise.all([
7448
- import("./mcp-NEAPIDTT.js"),
7449
+ import("./mcp-OYR26JDI.js"),
7449
7450
  import("./tool-tiers-B7JC2XC3.js")
7450
7451
  ]);
7451
7452
  if (opts.tools && opts.tools.length > 0) {
@@ -7606,14 +7607,150 @@ function createMcpGuardCommand() {
7606
7607
  }
7607
7608
 
7608
7609
  // src/commands/migrate.ts
7609
- init_dist3();
7610
- init_dist2();
7610
+ import { Command as Command63 } from "commander";
7611
+
7612
+ // src/commands/migrate-backends.ts
7611
7613
  import { Command as Command62 } from "commander";
7612
7614
  import * as fs27 from "fs";
7613
7615
  import * as path43 from "path";
7616
+ import chalk9 from "chalk";
7617
+ import { parse as parseYaml2 } from "yaml";
7618
+ async function runMigrateBackends(opts = {}) {
7619
+ const cwd = opts.cwd ?? process.cwd();
7620
+ const mdPath = findOrchestratorMd(cwd);
7621
+ if (mdPath === null) {
7622
+ return {
7623
+ status: "noop",
7624
+ message: "No harness.orchestrator.md found \u2014 nothing to migrate.",
7625
+ exitCode: ExitCode.SUCCESS
7626
+ };
7627
+ }
7628
+ const backends = readBackendsFromOrchestratorMd(cwd);
7629
+ if (backends === null) {
7630
+ return {
7631
+ status: "noop",
7632
+ message: `Found ${mdPath} but no agent.backends to migrate.`,
7633
+ exitCode: ExitCode.SUCCESS
7634
+ };
7635
+ }
7636
+ const routing = readRoutingFromOrchestratorMd(mdPath);
7637
+ const jsonPath = path43.join(path43.dirname(mdPath), "harness.config.json");
7638
+ if (!fs27.existsSync(jsonPath)) {
7639
+ return {
7640
+ status: "error",
7641
+ message: `harness.config.json not found at ${jsonPath}. Run \`harness init\` first, then re-run this migration.`,
7642
+ exitCode: ExitCode.ERROR
7643
+ };
7644
+ }
7645
+ let configRaw;
7646
+ try {
7647
+ configRaw = fs27.readFileSync(jsonPath, "utf-8");
7648
+ } catch (err) {
7649
+ return {
7650
+ status: "error",
7651
+ message: `Failed to read ${jsonPath}: ${err instanceof Error ? err.message : String(err)}`,
7652
+ exitCode: ExitCode.ERROR
7653
+ };
7654
+ }
7655
+ let configObj;
7656
+ try {
7657
+ configObj = JSON.parse(configRaw);
7658
+ } catch (err) {
7659
+ return {
7660
+ status: "error",
7661
+ message: `${jsonPath} is not valid JSON: ${err instanceof Error ? err.message : String(err)}`,
7662
+ exitCode: ExitCode.ERROR
7663
+ };
7664
+ }
7665
+ const agent = configObj.agent ?? {};
7666
+ const existingBackends = agent.backends;
7667
+ if (existingBackends !== void 0 && !opts.force) {
7668
+ return {
7669
+ status: "error",
7670
+ message: `${jsonPath} already declares agent.backends. Re-run with --force to overwrite, or merge manually.`,
7671
+ exitCode: ExitCode.ERROR
7672
+ };
7673
+ }
7674
+ const nextAgent = { ...agent, backends };
7675
+ if (routing !== null) nextAgent.routing = routing;
7676
+ const nextConfig = { ...configObj, agent: nextAgent };
7677
+ const nextJson = JSON.stringify(nextConfig, null, 2) + "\n";
7678
+ if (opts.dryRun) {
7679
+ logger.info(chalk9.bold("--- dry run ---"));
7680
+ logger.info(`Would write ${Object.keys(backends).length} backend(s) to ${jsonPath}:`);
7681
+ for (const name of Object.keys(backends)) {
7682
+ logger.info(` \u2022 ${name}`);
7683
+ }
7684
+ if (routing !== null) {
7685
+ logger.info("Would also copy agent.routing.");
7686
+ }
7687
+ return {
7688
+ status: "ok",
7689
+ message: "(dry-run) migration plan above \u2014 re-run without --dry-run to apply.",
7690
+ exitCode: ExitCode.SUCCESS
7691
+ };
7692
+ }
7693
+ try {
7694
+ fs27.writeFileSync(jsonPath, nextJson);
7695
+ } catch (err) {
7696
+ return {
7697
+ status: "error",
7698
+ message: `Failed to write ${jsonPath}: ${err instanceof Error ? err.message : String(err)}`,
7699
+ exitCode: ExitCode.ERROR
7700
+ };
7701
+ }
7702
+ return {
7703
+ status: "ok",
7704
+ message: `Migrated ${Object.keys(backends).length} backend(s)${routing !== null ? " + routing" : ""} from ${mdPath} to ${jsonPath}. You can leave the entries in harness.orchestrator.md (orchestrator still reads them) or remove them once the orchestrator config picks up the JSON source.`,
7705
+ exitCode: ExitCode.SUCCESS
7706
+ };
7707
+ }
7708
+ function readRoutingFromOrchestratorMd(mdPath) {
7709
+ let raw;
7710
+ try {
7711
+ raw = fs27.readFileSync(mdPath, "utf-8");
7712
+ } catch {
7713
+ return null;
7714
+ }
7715
+ const parts = raw.split("---");
7716
+ if (parts.length < 3) return null;
7717
+ let parsed;
7718
+ try {
7719
+ parsed = parseYaml2(parts[1].trim());
7720
+ } catch {
7721
+ return null;
7722
+ }
7723
+ if (parsed === null || typeof parsed !== "object") return null;
7724
+ const agent = parsed.agent;
7725
+ if (agent === null || typeof agent !== "object") return null;
7726
+ const routing = agent.routing;
7727
+ return routing ?? null;
7728
+ }
7729
+ function createBackendsSubcommand() {
7730
+ return new Command62("backends").description(
7731
+ "Copy agent.backends (and routing) from harness.orchestrator.md into harness.config.json."
7732
+ ).option("--dry-run", "Show what would change without writing", false).option("--force", "Overwrite existing agent.backends in harness.config.json", false).action(async (options) => {
7733
+ const result = await runMigrateBackends({
7734
+ dryRun: options.dryRun ?? false,
7735
+ force: options.force ?? false
7736
+ });
7737
+ if (result.status === "error") {
7738
+ logger.error(result.message);
7739
+ process.exit(result.exitCode);
7740
+ }
7741
+ logger.info(result.message);
7742
+ process.exit(result.exitCode);
7743
+ });
7744
+ }
7745
+
7746
+ // src/commands/migrate.ts
7747
+ init_dist3();
7748
+ init_dist2();
7749
+ import * as fs28 from "fs";
7750
+ import * as path44 from "path";
7614
7751
  import * as readline from "readline";
7615
7752
  import { execFileSync as execFileSync4 } from "child_process";
7616
- import chalk9 from "chalk";
7753
+ import chalk10 from "chalk";
7617
7754
  function isGitRepo(cwd) {
7618
7755
  try {
7619
7756
  execFileSync4("git", ["rev-parse", "--is-inside-work-tree"], { cwd, stdio: "pipe" });
@@ -7624,25 +7761,25 @@ function isGitRepo(cwd) {
7624
7761
  }
7625
7762
  function readJson2(p) {
7626
7763
  try {
7627
- return JSON.parse(fs27.readFileSync(p, "utf8"));
7764
+ return JSON.parse(fs28.readFileSync(p, "utf8"));
7628
7765
  } catch {
7629
7766
  return null;
7630
7767
  }
7631
7768
  }
7632
7769
  function listDirs(p) {
7633
- if (!fs27.existsSync(p)) return [];
7634
- return fs27.readdirSync(p, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name);
7770
+ if (!fs28.existsSync(p)) return [];
7771
+ return fs28.readdirSync(p, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name);
7635
7772
  }
7636
7773
  function listFiles(p, predicate) {
7637
- if (!fs27.existsSync(p)) return [];
7638
- return fs27.readdirSync(p, { withFileTypes: true }).filter((e) => e.isFile() && predicate(e.name)).map((e) => e.name);
7774
+ if (!fs28.existsSync(p)) return [];
7775
+ return fs28.readdirSync(p, { withFileTypes: true }).filter((e) => e.isFile() && predicate(e.name)).map((e) => e.name);
7639
7776
  }
7640
7777
  function walk(dir, predicate) {
7641
- if (!fs27.existsSync(dir)) return [];
7778
+ if (!fs28.existsSync(dir)) return [];
7642
7779
  const out = [];
7643
- for (const entry of fs27.readdirSync(dir, { withFileTypes: true })) {
7780
+ for (const entry of fs28.readdirSync(dir, { withFileTypes: true })) {
7644
7781
  if (DEFAULT_SKIP_DIRS.has(entry.name)) continue;
7645
- const full = path43.join(dir, entry.name);
7782
+ const full = path44.join(dir, entry.name);
7646
7783
  if (entry.isDirectory()) out.push(...walk(full, predicate));
7647
7784
  else if (predicate(full)) out.push(full);
7648
7785
  }
@@ -7654,11 +7791,11 @@ function extractAutopilotTopic(state) {
7654
7791
  }
7655
7792
  function buildAutopilotMap(cwd) {
7656
7793
  const map = /* @__PURE__ */ new Map();
7657
- const sessionsDir = path43.join(cwd, ".harness", "sessions");
7658
- if (!fs27.existsSync(sessionsDir)) return map;
7794
+ const sessionsDir = path44.join(cwd, ".harness", "sessions");
7795
+ if (!fs28.existsSync(sessionsDir)) return map;
7659
7796
  for (const session of listDirs(sessionsDir)) {
7660
7797
  if (!session.startsWith("changes--")) continue;
7661
- const state = readJson2(path43.join(sessionsDir, session, "autopilot-state.json"));
7798
+ const state = readJson2(path44.join(sessionsDir, session, "autopilot-state.json"));
7662
7799
  if (!state) continue;
7663
7800
  const topic = extractAutopilotTopic(state);
7664
7801
  if (!topic) continue;
@@ -7671,7 +7808,7 @@ function buildAutopilotMap(cwd) {
7671
7808
  function extractTopicFromHeader(planAbs, proposalTopics) {
7672
7809
  let text;
7673
7810
  try {
7674
- text = fs27.readFileSync(planAbs, "utf8").slice(0, 4e3);
7811
+ text = fs28.readFileSync(planAbs, "utf8").slice(0, 4e3);
7675
7812
  } catch {
7676
7813
  return null;
7677
7814
  }
@@ -7696,8 +7833,8 @@ function extractTopicFromFilename(filename, proposalTopics) {
7696
7833
  return best;
7697
7834
  }
7698
7835
  function resolveDocsDir(cwd) {
7699
- const configPath = path43.join(cwd, "harness.config.json");
7700
- const configResult = fs27.existsSync(configPath) ? resolveConfig(configPath) : null;
7836
+ const configPath = path44.join(cwd, "harness.config.json");
7837
+ const configResult = fs28.existsSync(configPath) ? resolveConfig(configPath) : null;
7701
7838
  let docsDir;
7702
7839
  if (configResult?.ok) {
7703
7840
  docsDir = configResult.value.docsDir;
@@ -7709,16 +7846,16 @@ function resolveDocsDir(cwd) {
7709
7846
  } else {
7710
7847
  docsDir = "./docs";
7711
7848
  }
7712
- const docsAbs = path43.resolve(cwd, docsDir);
7713
- const relRaw = path43.relative(cwd, docsAbs).replaceAll("\\", "/");
7849
+ const docsAbs = path44.resolve(cwd, docsDir);
7850
+ const relRaw = path44.relative(cwd, docsAbs).replaceAll("\\", "/");
7714
7851
  return relRaw === "" ? "docs" : relRaw;
7715
7852
  }
7716
7853
  function collectAdrMoves(cwd, docsRel) {
7717
7854
  const moves = [];
7718
- const legacyAdrDir = path43.join(cwd, ".harness", "architecture");
7719
- if (!fs27.existsSync(legacyAdrDir)) return moves;
7855
+ const legacyAdrDir = path44.join(cwd, ".harness", "architecture");
7856
+ if (!fs28.existsSync(legacyAdrDir)) return moves;
7720
7857
  for (const topic of listDirs(legacyAdrDir)) {
7721
- const topicSrc = path43.join(legacyAdrDir, topic);
7858
+ const topicSrc = path44.join(legacyAdrDir, topic);
7722
7859
  for (const file of listFiles(topicSrc, (n) => n.endsWith(".md"))) {
7723
7860
  moves.push({
7724
7861
  src: `.harness/architecture/${topic}/${file}`,
@@ -7730,9 +7867,9 @@ function collectAdrMoves(cwd, docsRel) {
7730
7867
  }
7731
7868
  function collectProposalTopics(cwd) {
7732
7869
  const topics = /* @__PURE__ */ new Set();
7733
- const changesDir = path43.join(cwd, "docs", "changes");
7870
+ const changesDir = path44.join(cwd, "docs", "changes");
7734
7871
  for (const topic of listDirs(changesDir)) {
7735
- if (fs27.existsSync(path43.join(changesDir, topic, "proposal.md"))) {
7872
+ if (fs28.existsSync(path44.join(changesDir, topic, "proposal.md"))) {
7736
7873
  topics.add(topic);
7737
7874
  }
7738
7875
  }
@@ -7759,12 +7896,12 @@ async function buildPlan(opts) {
7759
7896
  orphanPlans: [],
7760
7897
  proposalTopics: collectProposalTopics(cwd)
7761
7898
  };
7762
- const legacyPlanDir = path43.join(cwd, "docs", "plans");
7763
- if (!fs27.existsSync(legacyPlanDir)) return plan;
7899
+ const legacyPlanDir = path44.join(cwd, "docs", "plans");
7900
+ if (!fs28.existsSync(legacyPlanDir)) return plan;
7764
7901
  const autopilotMap = buildAutopilotMap(cwd);
7765
7902
  for (const file of listFiles(legacyPlanDir, (n) => n.endsWith(".md") && n !== "index.md")) {
7766
7903
  const planRel = `docs/plans/${file}`;
7767
- const planAbs = path43.join(legacyPlanDir, file);
7904
+ const planAbs = path44.join(legacyPlanDir, file);
7768
7905
  const subdir = file.includes("VERIFICATION") ? "verifications" : "plans";
7769
7906
  const classified = classifyPlan(planRel, planAbs, file, autopilotMap, plan.proposalTopics);
7770
7907
  if (classified) {
@@ -7782,8 +7919,8 @@ async function buildPlan(opts) {
7782
7919
  return plan;
7783
7920
  }
7784
7921
  function gitMv(cwd, src, dest, useGit) {
7785
- const destAbs = path43.join(cwd, dest);
7786
- fs27.mkdirSync(path43.dirname(destAbs), { recursive: true });
7922
+ const destAbs = path44.join(cwd, dest);
7923
+ fs28.mkdirSync(path44.dirname(destAbs), { recursive: true });
7787
7924
  if (useGit) {
7788
7925
  try {
7789
7926
  execFileSync4("git", ["mv", src, dest], { cwd, stdio: "pipe" });
@@ -7791,7 +7928,7 @@ function gitMv(cwd, src, dest, useGit) {
7791
7928
  } catch {
7792
7929
  }
7793
7930
  }
7794
- fs27.renameSync(path43.join(cwd, src), destAbs);
7931
+ fs28.renameSync(path44.join(cwd, src), destAbs);
7795
7932
  }
7796
7933
  function executeMigration(plan) {
7797
7934
  let moved = 0;
@@ -7823,13 +7960,13 @@ function updateReferences(plan) {
7823
7960
  let files = 0;
7824
7961
  let replacements = 0;
7825
7962
  const targets = [
7826
- ...walk(path43.join(plan.cwd, "docs"), (p) => p.endsWith(".md")),
7827
- ...walk(path43.join(plan.cwd, ".harness", "sessions"), (p) => p.endsWith(".json"))
7963
+ ...walk(path44.join(plan.cwd, "docs"), (p) => p.endsWith(".md")),
7964
+ ...walk(path44.join(plan.cwd, ".harness", "sessions"), (p) => p.endsWith(".json"))
7828
7965
  ];
7829
7966
  for (const target of targets) {
7830
7967
  let text;
7831
7968
  try {
7832
- text = fs27.readFileSync(target, "utf8");
7969
+ text = fs28.readFileSync(target, "utf8");
7833
7970
  } catch {
7834
7971
  continue;
7835
7972
  }
@@ -7842,7 +7979,7 @@ function updateReferences(plan) {
7842
7979
  count += occurrences;
7843
7980
  }
7844
7981
  if (count > 0 && result !== text) {
7845
- fs27.writeFileSync(target, result);
7982
+ fs28.writeFileSync(target, result);
7846
7983
  files++;
7847
7984
  replacements += count;
7848
7985
  }
@@ -7901,7 +8038,7 @@ async function resolveOrphans(plan, opts) {
7901
8038
  }
7902
8039
  function bucketOrphans(plan, topic) {
7903
8040
  for (const src of plan.orphanPlans) {
7904
- const file = path43.basename(src);
8041
+ const file = path44.basename(src);
7905
8042
  const isVerification = file.includes("VERIFICATION");
7906
8043
  const subdir = isVerification ? "verifications" : "plans";
7907
8044
  plan.planMoves.push({
@@ -7916,7 +8053,7 @@ function bucketOrphans(plan, topic) {
7916
8053
  }
7917
8054
  function summarize(plan) {
7918
8055
  console.log("");
7919
- console.log(chalk9.bold(" Migration plan"));
8056
+ console.log(chalk10.bold(" Migration plan"));
7920
8057
  console.log("");
7921
8058
  if (plan.adrMoves.length === 0 && plan.planMoves.length === 0 && plan.orphanPlans.length === 0) {
7922
8059
  logger.success(" Nothing to migrate. Layout is already up to date.");
@@ -7935,7 +8072,7 @@ function summarize(plan) {
7935
8072
  logger.info(
7936
8073
  ` Plan moves: ${plan.planMoves.length} file(s) \u2014 docs/plans/ \u2192 docs/changes/<topic>/{plans,verifications}/`
7937
8074
  );
7938
- for (const [via, n] of Object.entries(byVia)) console.log(chalk9.dim(` via ${via}: ${n}`));
8075
+ for (const [via, n] of Object.entries(byVia)) console.log(chalk10.dim(` via ${via}: ${n}`));
7939
8076
  }
7940
8077
  if (plan.orphanPlans.length > 0) {
7941
8078
  logger.warn(` Orphan plans: ${plan.orphanPlans.length} (no proposal match \u2014 needs decision)`);
@@ -7943,10 +8080,10 @@ function summarize(plan) {
7943
8080
  console.log("");
7944
8081
  }
7945
8082
  async function detectLegacyArtifacts(cwd) {
7946
- const adrLegacyDir = path43.join(cwd, ".harness", "architecture");
7947
- const adrLegacy = fs27.existsSync(adrLegacyDir) && listDirs(adrLegacyDir).length > 0;
7948
- const planLegacyDir = path43.join(cwd, "docs", "plans");
7949
- const planLegacy = fs27.existsSync(planLegacyDir) && listFiles(planLegacyDir, (n) => n.endsWith(".md") && n !== "index.md").length > 0;
8083
+ const adrLegacyDir = path44.join(cwd, ".harness", "architecture");
8084
+ const adrLegacy = fs28.existsSync(adrLegacyDir) && listDirs(adrLegacyDir).length > 0;
8085
+ const planLegacyDir = path44.join(cwd, "docs", "plans");
8086
+ const planLegacy = fs28.existsSync(planLegacyDir) && listFiles(planLegacyDir, (n) => n.endsWith(".md") && n !== "index.md").length > 0;
7950
8087
  return { adrLegacy, planLegacy };
7951
8088
  }
7952
8089
  async function confirmApply(opts) {
@@ -8014,7 +8151,7 @@ async function runMigrate(opts) {
8014
8151
  });
8015
8152
  }
8016
8153
  function createMigrateCommand() {
8017
- return new Command62("migrate").description("Migrate legacy harness artifact locations to current layout").option("--dry-run", "Show the migration plan without moving files", false).option("--yes", "Skip confirmation prompt", false).option(
8154
+ const cmd = new Command63("migrate").description("Migrate legacy harness artifact locations to current layout").option("--dry-run", "Show the migration plan without moving files", false).option("--yes", "Skip confirmation prompt", false).option(
8018
8155
  "--skip-references",
8019
8156
  "Do not update path references in docs/sessions after moves",
8020
8157
  false
@@ -8033,12 +8170,158 @@ function createMigrateCommand() {
8033
8170
  }
8034
8171
  process.exit(result.value.movesFailed === 0 ? ExitCode.SUCCESS : ExitCode.ERROR);
8035
8172
  });
8173
+ cmd.addCommand(createBackendsSubcommand());
8174
+ return cmd;
8175
+ }
8176
+
8177
+ // src/commands/models.ts
8178
+ import { Command as Command64 } from "commander";
8179
+ import { defaultFetchModels } from "@harness-engineering/orchestrator";
8180
+ function errorResult(message, partial) {
8181
+ return {
8182
+ status: "error",
8183
+ endpoint: "",
8184
+ configured: [],
8185
+ detected: [],
8186
+ resolved: null,
8187
+ error: message,
8188
+ exitCode: ExitCode.ERROR,
8189
+ ...partial
8190
+ };
8191
+ }
8192
+ function pickConfiguredList(model) {
8193
+ if (typeof model === "string") return [model];
8194
+ if (Array.isArray(model)) return model.filter((m) => typeof m === "string");
8195
+ return [];
8196
+ }
8197
+ function locateBackend(opts) {
8198
+ const resolved = resolveConfig(opts.configPath);
8199
+ if (!resolved.ok) {
8200
+ return errorResult(`Could not load harness.config.json: ${resolved.error.message}`);
8201
+ }
8202
+ const backends = resolved.value.agent?.backends;
8203
+ const name = opts.backend ?? defaultLocalBackend(backends);
8204
+ if (name === null) {
8205
+ return errorResult(
8206
+ 'No local backend in agent.backends. Declare one with type "local" or "pi", or pass --endpoint <url>.'
8207
+ );
8208
+ }
8209
+ const def = backends?.[name];
8210
+ if (def === void 0) {
8211
+ return errorResult(`agent.backends["${name}"] not found.`);
8212
+ }
8213
+ return { name, def };
8214
+ }
8215
+ function resolveProbeContext(opts) {
8216
+ if (opts.endpoint !== void 0) {
8217
+ return {
8218
+ endpoint: opts.endpoint,
8219
+ configured: [],
8220
+ apiKey: opts.apiKey ?? "local",
8221
+ backendLabel: opts.backend
8222
+ };
8223
+ }
8224
+ const located = locateBackend(opts);
8225
+ if ("status" in located) return located;
8226
+ const ep = located.def.endpoint;
8227
+ if (typeof ep !== "string") {
8228
+ return errorResult(`agent.backends["${located.name}"]: missing or invalid 'endpoint'.`);
8229
+ }
8230
+ const explicitKey = typeof located.def.apiKey === "string" ? located.def.apiKey : void 0;
8231
+ return {
8232
+ endpoint: ep,
8233
+ configured: pickConfiguredList(located.def.model),
8234
+ apiKey: opts.apiKey ?? explicitKey ?? "local",
8235
+ backendLabel: located.name
8236
+ };
8237
+ }
8238
+ async function runModelsProbe(opts) {
8239
+ const ctx = resolveProbeContext(opts);
8240
+ if ("status" in ctx) return ctx;
8241
+ let detected;
8242
+ try {
8243
+ detected = await defaultFetchModels(ctx.endpoint, ctx.apiKey);
8244
+ } catch (err) {
8245
+ return {
8246
+ status: "error",
8247
+ ...ctx.backendLabel !== void 0 ? { backend: ctx.backendLabel } : {},
8248
+ endpoint: ctx.endpoint,
8249
+ configured: ctx.configured,
8250
+ detected: [],
8251
+ resolved: null,
8252
+ error: err instanceof Error ? err.message : String(err),
8253
+ exitCode: ExitCode.ERROR
8254
+ };
8255
+ }
8256
+ const match = ctx.configured.find((id) => detected.includes(id)) ?? null;
8257
+ return {
8258
+ status: match !== null ? "ok" : "no-match",
8259
+ ...ctx.backendLabel !== void 0 ? { backend: ctx.backendLabel } : {},
8260
+ endpoint: ctx.endpoint,
8261
+ configured: ctx.configured,
8262
+ detected,
8263
+ resolved: match,
8264
+ exitCode: match !== null ? ExitCode.SUCCESS : ExitCode.ERROR
8265
+ };
8266
+ }
8267
+ function defaultLocalBackend(backends) {
8268
+ if (backends === void 0) return null;
8269
+ for (const [name, def] of Object.entries(backends)) {
8270
+ const t = def.type;
8271
+ if (t === "local" || t === "pi") return name;
8272
+ }
8273
+ return null;
8274
+ }
8275
+ function formatProbe(result) {
8276
+ if (result.status === "error") {
8277
+ return `error probing ${result.endpoint || "(no endpoint)"}: ${result.error}`;
8278
+ }
8279
+ const lines = [];
8280
+ lines.push(
8281
+ `endpoint: ${result.endpoint}${result.backend !== void 0 ? ` (agent.backends["${result.backend}"])` : ""}`
8282
+ );
8283
+ lines.push(`configured: [${result.configured.join(", ")}]`);
8284
+ lines.push(`detected: [${result.detected.join(", ")}]`);
8285
+ if (result.resolved !== null) {
8286
+ lines.push(`resolved: ${result.resolved}`);
8287
+ } else {
8288
+ lines.push("resolved: (no configured model is loaded)");
8289
+ lines.push(
8290
+ "hint: load one of the configured models or update agent.backends.<name>.model to include a detected id."
8291
+ );
8292
+ }
8293
+ return lines.join("\n");
8294
+ }
8295
+ function createModelsCommand() {
8296
+ const cmd = new Command64("models").description(
8297
+ "Inspect and manage local LLM backends. Currently ships `probe`; LMLM phases add status/suggest/pool/proposals."
8298
+ );
8299
+ cmd.command("probe").description(
8300
+ "Probe a local backend's /v1/models endpoint and report which configured model is loaded."
8301
+ ).option(
8302
+ "--backend <name>",
8303
+ "Name of an entry in agent.backends. Defaults to the first local/pi entry."
8304
+ ).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) => {
8305
+ const result = await runModelsProbe(options);
8306
+ if (options.json) {
8307
+ console.log(JSON.stringify(result, null, 2));
8308
+ } else {
8309
+ const text = formatProbe(result);
8310
+ if (result.status === "error" || result.status === "no-match") {
8311
+ logger.error(text);
8312
+ } else {
8313
+ logger.info(text);
8314
+ }
8315
+ }
8316
+ process.exit(result.exitCode);
8317
+ });
8318
+ return cmd;
8036
8319
  }
8037
8320
 
8038
8321
  // src/commands/naming-craft.ts
8039
- import { Command as Command63 } from "commander";
8322
+ import { Command as Command65 } from "commander";
8040
8323
  function createNamingCraftCommand() {
8041
- return new Command63("naming-craft").description(
8324
+ return new Command65("naming-craft").description(
8042
8325
  "LLM-judgment critique of identifier names (variables, functions, types, files). First craft-pipeline ceiling skill; uses curated rubric catalog from Martin/Beck/Karlton."
8043
8326
  ).option("-f, --files <files...>", "Optional file/glob scope").option(
8044
8327
  "-k, --kinds <kinds...>",
@@ -8088,10 +8371,10 @@ function printResult4(result, mode, _formatter) {
8088
8371
  list.push(f);
8089
8372
  byFile.set(f.target.file, list);
8090
8373
  }
8091
- for (const [file, fs47] of byFile) {
8374
+ for (const [file, fs48] of byFile) {
8092
8375
  console.log(`
8093
8376
  ${file}`);
8094
- for (const f of fs47) {
8377
+ for (const f of fs48) {
8095
8378
  const line = f.target.line !== void 0 ? `:${f.target.line}` : "";
8096
8379
  console.log(
8097
8380
  ` ${f.code} [${f.tier}/${f.impact}/${f.confidence}] ${f.target.kind} ${f.target.identifier}${line}`
@@ -8111,11 +8394,11 @@ ${file}`);
8111
8394
  }
8112
8395
 
8113
8396
  // src/commands/notifications/index.ts
8114
- import { Command as Command65 } from "commander";
8397
+ import { Command as Command67 } from "commander";
8115
8398
 
8116
8399
  // src/commands/notifications/test.ts
8117
8400
  init_dist3();
8118
- import { Command as Command64 } from "commander";
8401
+ import { Command as Command66 } from "commander";
8119
8402
  import { randomBytes } from "crypto";
8120
8403
  import { resolve as resolve28 } from "path";
8121
8404
  import { SinkRegistry, SinkConfigError, wrapAsEnvelope } from "@harness-engineering/orchestrator";
@@ -8167,7 +8450,7 @@ async function runNotificationsTest(sinkId, opts, projectRoot2 = process.cwd())
8167
8450
  return { ok: false, error: result.error };
8168
8451
  }
8169
8452
  function createNotificationsTestSubcommand() {
8170
- return new Command64("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) => {
8453
+ return new Command66("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) => {
8171
8454
  const globalOpts = cmd.optsWithGlobals();
8172
8455
  const projectRoot2 = typeof globalOpts["cwd"] === "string" ? resolve28(globalOpts["cwd"]) : process.cwd();
8173
8456
  const result = await runNotificationsTest(sinkId, opts, projectRoot2);
@@ -8184,7 +8467,7 @@ function createNotificationsTestSubcommand() {
8184
8467
 
8185
8468
  // src/commands/notifications/index.ts
8186
8469
  function createNotificationsCommand() {
8187
- const cmd = new Command65("notifications").description(
8470
+ const cmd = new Command67("notifications").description(
8188
8471
  "Manage notification sinks (Slack and others)"
8189
8472
  );
8190
8473
  cmd.addCommand(createNotificationsTestSubcommand());
@@ -8192,13 +8475,13 @@ function createNotificationsCommand() {
8192
8475
  }
8193
8476
 
8194
8477
  // src/commands/orchestrator.ts
8195
- import { Command as Command66 } from "commander";
8196
- import * as path44 from "path";
8478
+ import { Command as Command68 } from "commander";
8479
+ import * as path45 from "path";
8197
8480
  import { Orchestrator, WorkflowLoader as WorkflowLoader2, launchTUI } from "@harness-engineering/orchestrator";
8198
8481
  function createOrchestratorCommand() {
8199
- const orchestrator = new Command66("orchestrator");
8482
+ const orchestrator = new Command68("orchestrator");
8200
8483
  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) => {
8201
- const workflowPath = path44.resolve(process.cwd(), opts.workflow);
8484
+ const workflowPath = path45.resolve(process.cwd(), opts.workflow);
8202
8485
  const loader = new WorkflowLoader2();
8203
8486
  const result = await loader.loadWorkflow(workflowPath);
8204
8487
  if (!result.ok) {
@@ -8232,13 +8515,13 @@ function createOrchestratorCommand() {
8232
8515
 
8233
8516
  // src/commands/perf.ts
8234
8517
  init_dist3();
8235
- import { Command as Command67 } from "commander";
8236
- import * as path45 from "path";
8518
+ import { Command as Command69 } from "commander";
8519
+ import * as path46 from "path";
8237
8520
  function registerBenchCommand(perf) {
8238
8521
  perf.command("bench [glob]").description("Run benchmarks via vitest bench").action(async (glob2, _opts, cmd) => {
8239
8522
  const globalOpts = cmd.optsWithGlobals();
8240
8523
  const cwd = process.cwd();
8241
- const { BenchmarkRunner } = await import("./dist-XIJWWQ5N.js");
8524
+ const { BenchmarkRunner } = await import("./dist-72ID44UE.js");
8242
8525
  const runner = new BenchmarkRunner();
8243
8526
  const benchFiles = runner.discover(cwd, glob2);
8244
8527
  if (benchFiles.length === 0) {
@@ -8302,7 +8585,7 @@ async function runBaselinesShow(globalOpts) {
8302
8585
  }
8303
8586
  async function runBaselinesUpdate(globalOpts) {
8304
8587
  const cwd = process.cwd();
8305
- const { BenchmarkRunner } = await import("./dist-XIJWWQ5N.js");
8588
+ const { BenchmarkRunner } = await import("./dist-72ID44UE.js");
8306
8589
  const runner = new BenchmarkRunner();
8307
8590
  const manager = new BaselineManager(cwd);
8308
8591
  logger.info("Running benchmarks to update baselines...");
@@ -8343,9 +8626,9 @@ function registerReportCommand(perf) {
8343
8626
  perf.command("report").description("Full performance report with metrics, trends, and hotspots").action(async (_opts, cmd) => {
8344
8627
  const globalOpts = cmd.optsWithGlobals();
8345
8628
  const cwd = process.cwd();
8346
- const { EntropyAnalyzer: EntropyAnalyzer2 } = await import("./dist-XIJWWQ5N.js");
8629
+ const { EntropyAnalyzer: EntropyAnalyzer2 } = await import("./dist-72ID44UE.js");
8347
8630
  const analyzer = new EntropyAnalyzer2({
8348
- rootDir: path45.resolve(cwd),
8631
+ rootDir: path46.resolve(cwd),
8349
8632
  analyze: { complexity: true, coupling: true }
8350
8633
  });
8351
8634
  const result = await analyzer.analyze();
@@ -8404,7 +8687,7 @@ function registerCriticalPathsCommand(perf) {
8404
8687
  });
8405
8688
  }
8406
8689
  function createPerfCommand() {
8407
- const perf = new Command67("perf").description("Performance benchmark and baseline management");
8690
+ const perf = new Command69("perf").description("Performance benchmark and baseline management");
8408
8691
  registerBenchCommand(perf);
8409
8692
  registerBaselinesCommands(perf);
8410
8693
  registerReportCommand(perf);
@@ -8413,10 +8696,10 @@ function createPerfCommand() {
8413
8696
  }
8414
8697
 
8415
8698
  // src/commands/persona/index.ts
8416
- import { Command as Command70 } from "commander";
8699
+ import { Command as Command72 } from "commander";
8417
8700
 
8418
8701
  // src/commands/persona/list.ts
8419
- import { Command as Command68 } from "commander";
8702
+ import { Command as Command70 } from "commander";
8420
8703
  function printPersonaList(personas) {
8421
8704
  if (personas.length === 0) {
8422
8705
  logger.info("No personas found.");
@@ -8430,7 +8713,7 @@ function printPersonaList(personas) {
8430
8713
  }
8431
8714
  }
8432
8715
  function createListCommand2() {
8433
- return new Command68("list").description("List available agent personas").action(async (_opts, cmd) => {
8716
+ return new Command70("list").description("List available agent personas").action(async (_opts, cmd) => {
8434
8717
  const globalOpts = cmd.optsWithGlobals();
8435
8718
  const personasDir = resolvePersonasDir();
8436
8719
  const result = listPersonas(personasDir);
@@ -8450,51 +8733,51 @@ function createListCommand2() {
8450
8733
  }
8451
8734
 
8452
8735
  // src/commands/persona/generate.ts
8453
- import { Command as Command69 } from "commander";
8454
- import * as fs28 from "fs";
8455
- import * as path46 from "path";
8736
+ import { Command as Command71 } from "commander";
8737
+ import * as fs29 from "fs";
8738
+ import * as path47 from "path";
8456
8739
  function generatePersonaArtifacts(persona, outputDir, only) {
8457
8740
  const slug = toKebabCase(persona.name);
8458
8741
  const generated = [];
8459
8742
  if (!only || only === "runtime") {
8460
8743
  const result = generateRuntime(persona);
8461
8744
  if (result.ok) {
8462
- const outPath = path46.join(outputDir, `${slug}.runtime.json`);
8463
- fs28.mkdirSync(path46.dirname(outPath), { recursive: true });
8464
- fs28.writeFileSync(outPath, result.value);
8745
+ const outPath = path47.join(outputDir, `${slug}.runtime.json`);
8746
+ fs29.mkdirSync(path47.dirname(outPath), { recursive: true });
8747
+ fs29.writeFileSync(outPath, result.value);
8465
8748
  generated.push(outPath);
8466
8749
  }
8467
8750
  }
8468
8751
  if (!only || only === "agents-md") {
8469
8752
  const result = generateAgentsMd(persona);
8470
8753
  if (result.ok) {
8471
- const outPath = path46.join(outputDir, `${slug}.agents.md`);
8472
- fs28.writeFileSync(outPath, result.value);
8754
+ const outPath = path47.join(outputDir, `${slug}.agents.md`);
8755
+ fs29.writeFileSync(outPath, result.value);
8473
8756
  generated.push(outPath);
8474
8757
  }
8475
8758
  }
8476
8759
  if (!only || only === "ci") {
8477
8760
  const result = generateCIWorkflow(persona, "github");
8478
8761
  if (result.ok) {
8479
- const outPath = path46.join(outputDir, ".github", "workflows", `${slug}.yml`);
8480
- fs28.mkdirSync(path46.dirname(outPath), { recursive: true });
8481
- fs28.writeFileSync(outPath, result.value);
8762
+ const outPath = path47.join(outputDir, ".github", "workflows", `${slug}.yml`);
8763
+ fs29.mkdirSync(path47.dirname(outPath), { recursive: true });
8764
+ fs29.writeFileSync(outPath, result.value);
8482
8765
  generated.push(outPath);
8483
8766
  }
8484
8767
  }
8485
8768
  return generated;
8486
8769
  }
8487
8770
  function createGenerateCommand3() {
8488
- return new Command69("generate").description("Generate artifacts from a persona config").argument("<name>", "Persona name (e.g., architecture-enforcer)").option("--output-dir <dir>", "Output directory", ".").option("--only <type>", "Generate only: ci, agents-md, runtime").action(async (name, opts, cmd) => {
8771
+ return new Command71("generate").description("Generate artifacts from a persona config").argument("<name>", "Persona name (e.g., architecture-enforcer)").option("--output-dir <dir>", "Output directory", ".").option("--only <type>", "Generate only: ci, agents-md, runtime").action(async (name, opts, cmd) => {
8489
8772
  const globalOpts = cmd.optsWithGlobals();
8490
- const personaResult = loadPersona(path46.join(resolvePersonasDir(), `${name}.yaml`));
8773
+ const personaResult = loadPersona(path47.join(resolvePersonasDir(), `${name}.yaml`));
8491
8774
  if (!personaResult.ok) {
8492
8775
  logger.error(personaResult.error.message);
8493
8776
  process.exit(ExitCode.ERROR);
8494
8777
  }
8495
8778
  const generated = generatePersonaArtifacts(
8496
8779
  personaResult.value,
8497
- path46.resolve(opts.outputDir),
8780
+ path47.resolve(opts.outputDir),
8498
8781
  opts.only
8499
8782
  );
8500
8783
  if (!globalOpts.quiet) {
@@ -8507,7 +8790,7 @@ function createGenerateCommand3() {
8507
8790
 
8508
8791
  // src/commands/persona/index.ts
8509
8792
  function createPersonaCommand() {
8510
- const command = new Command70("persona").description("Agent persona management commands");
8793
+ const command = new Command72("persona").description("Agent persona management commands");
8511
8794
  command.addCommand(createListCommand2());
8512
8795
  command.addCommand(createGenerateCommand3());
8513
8796
  return command;
@@ -8515,8 +8798,8 @@ function createPersonaCommand() {
8515
8798
 
8516
8799
  // src/commands/predict.ts
8517
8800
  init_dist3();
8518
- import { Command as Command71 } from "commander";
8519
- import chalk10 from "chalk";
8801
+ import { Command as Command73 } from "commander";
8802
+ import chalk11 from "chalk";
8520
8803
  var CATEGORY_ORDER = [
8521
8804
  "circular-deps",
8522
8805
  "layer-violations",
@@ -8537,11 +8820,11 @@ function crossingLabel(weeks) {
8537
8820
  function severityPrefix(severity) {
8538
8821
  switch (severity) {
8539
8822
  case "critical":
8540
- return chalk10.red("[critical]");
8823
+ return chalk11.red("[critical]");
8541
8824
  case "warning":
8542
- return chalk10.yellow("[warning]");
8825
+ return chalk11.yellow("[warning]");
8543
8826
  case "info":
8544
- return chalk10.blue("[info]");
8827
+ return chalk11.blue("[info]");
8545
8828
  }
8546
8829
  }
8547
8830
  function printCategoryTable(result) {
@@ -8621,7 +8904,7 @@ function handlePredictError(err, mode) {
8621
8904
  process.exit(ExitCode.ERROR);
8622
8905
  }
8623
8906
  function createPredictCommand() {
8624
- const command = new Command71("predict").description("Predict which architectural constraints will break and when").option("--category <name>", "Filter to a single metric category").option("--no-roadmap", "Baseline only \u2014 skip roadmap spec impact").option("--horizon <weeks>", "Forecast horizon in weeks (default: 12)", "12").action(async (opts, cmd) => {
8907
+ const command = new Command73("predict").description("Predict which architectural constraints will break and when").option("--category <name>", "Filter to a single metric category").option("--no-roadmap", "Baseline only \u2014 skip roadmap spec impact").option("--horizon <weeks>", "Forecast horizon in weeks (default: 12)", "12").action(async (opts, cmd) => {
8625
8908
  const globalOpts = cmd.optsWithGlobals();
8626
8909
  const mode = globalOpts.json ? OutputMode.JSON : OutputMode.TEXT;
8627
8910
  try {
@@ -8645,7 +8928,7 @@ function createPredictCommand() {
8645
8928
 
8646
8929
  // src/commands/proposals.ts
8647
8930
  init_dist3();
8648
- import { Command as Command72 } from "commander";
8931
+ import { Command as Command74 } from "commander";
8649
8932
  import { resolve as resolve32 } from "path";
8650
8933
  function projectRoot() {
8651
8934
  return resolve32(process.env["HARNESS_PROJECT_ROOT"] ?? process.cwd());
@@ -8740,7 +9023,7 @@ async function actApproveCommand(id) {
8740
9023
  }
8741
9024
  }
8742
9025
  function createProposalsCommand() {
8743
- const cmd = new Command72("proposals").description("Skill-proposal review queue (Hermes Phase 4)");
9026
+ const cmd = new Command74("proposals").description("Skill-proposal review queue");
8744
9027
  cmd.command("list").description("List skill proposals in the local queue").option(
8745
9028
  "--status <status>",
8746
9029
  `Filter by status \u2014 one of ${ALLOWED_STATUSES.join(" | ")}`,
@@ -8755,9 +9038,9 @@ function createProposalsCommand() {
8755
9038
  }
8756
9039
 
8757
9040
  // src/commands/publish-analyses.ts
8758
- import * as fs29 from "fs";
8759
- import * as path47 from "path";
8760
- import { Command as Command73 } from "commander";
9041
+ import * as fs30 from "fs";
9042
+ import * as path48 from "path";
9043
+ import { Command as Command75 } from "commander";
8761
9044
  init_dist3();
8762
9045
  import {
8763
9046
  renderAnalysisComment,
@@ -8765,7 +9048,7 @@ import {
8765
9048
  savePublishedIndex
8766
9049
  } from "@harness-engineering/orchestrator";
8767
9050
  function bootstrapTrackerCommand(opts, verb) {
8768
- const projectPath = path47.resolve(opts.dir);
9051
+ const projectPath = path48.resolve(opts.dir);
8769
9052
  const trackerConfig = loadTrackerSyncConfig(projectPath);
8770
9053
  if (!trackerConfig) {
8771
9054
  logger.error(`No tracker config found in harness.config.json. Cannot ${verb}.`);
@@ -8777,8 +9060,8 @@ function bootstrapTrackerCommand(opts, verb) {
8777
9060
  );
8778
9061
  return null;
8779
9062
  }
8780
- const projectEnvPath = path47.join(projectPath, ".env");
8781
- if (fs29.existsSync(projectEnvPath) && !process.env.GITHUB_TOKEN) {
9063
+ const projectEnvPath = path48.join(projectPath, ".env");
9064
+ if (fs30.existsSync(projectEnvPath) && !process.env.GITHUB_TOKEN) {
8782
9065
  __require("dotenv").config({ path: projectEnvPath });
8783
9066
  }
8784
9067
  const token = process.env.GITHUB_TOKEN;
@@ -8814,13 +9097,13 @@ async function buildNameToExternalIdMap(projectPath) {
8814
9097
  }
8815
9098
  return fileLessMap;
8816
9099
  }
8817
- const roadmapFile = path47.join(projectPath, "docs", "roadmap.md");
8818
- if (!fs29.existsSync(roadmapFile)) {
9100
+ const roadmapFile = path48.join(projectPath, "docs", "roadmap.md");
9101
+ if (!fs30.existsSync(roadmapFile)) {
8819
9102
  logger.error("No docs/roadmap.md found. Cannot map issue hashes to external IDs.");
8820
9103
  return null;
8821
9104
  }
8822
9105
  const { parseRoadmap: parseRoadmap2 } = (init_dist3(), __toCommonJS(dist_exports));
8823
- const roadmapParsed = parseRoadmap2(fs29.readFileSync(roadmapFile, "utf-8"));
9106
+ const roadmapParsed = parseRoadmap2(fs30.readFileSync(roadmapFile, "utf-8"));
8824
9107
  if (!roadmapParsed.ok) {
8825
9108
  logger.error("Failed to parse docs/roadmap.md");
8826
9109
  return null;
@@ -8870,8 +9153,8 @@ async function runPublishAnalyses(opts) {
8870
9153
  const nameToExternalId = await buildNameToExternalIdMap(projectPath);
8871
9154
  if (!nameToExternalId) return process.exit(1);
8872
9155
  const { AnalysisArchive } = await import("@harness-engineering/orchestrator");
8873
- const { GitHubIssuesSyncAdapter: GitHubIssuesSyncAdapter2 } = await import("./dist-XIJWWQ5N.js");
8874
- const archive = new AnalysisArchive(path47.join(projectPath, ".harness", "analyses"));
9156
+ const { GitHubIssuesSyncAdapter: GitHubIssuesSyncAdapter2 } = await import("./dist-72ID44UE.js");
9157
+ const archive = new AnalysisArchive(path48.join(projectPath, ".harness", "analyses"));
8875
9158
  const analyses = await archive.list();
8876
9159
  if (analyses.length === 0) {
8877
9160
  logger.info("No analyses found to publish.");
@@ -8893,7 +9176,7 @@ async function runPublishAnalyses(opts) {
8893
9176
  }
8894
9177
  }
8895
9178
  function createPublishAnalysesCommand() {
8896
- const command = new Command73("publish-analyses").description(
9179
+ const command = new Command75("publish-analyses").description(
8897
9180
  "Publishes locally generated intelligence analyses to the external issue tracker (e.g., GitHub)"
8898
9181
  ).option("-d, --dir <path>", "Workspace directory", process.cwd()).action(async (opts) => {
8899
9182
  try {
@@ -8909,18 +9192,18 @@ function createPublishAnalysesCommand() {
8909
9192
  }
8910
9193
 
8911
9194
  // src/commands/pulse/index.ts
8912
- import { Command as Command75 } from "commander";
9195
+ import { Command as Command77 } from "commander";
8913
9196
 
8914
9197
  // src/commands/pulse/run.ts
8915
9198
  init_dist3();
8916
- import { readFileSync as readFileSync18, mkdirSync as mkdirSync13, writeFileSync as writeFileSync15 } from "fs";
8917
- import { dirname as dirname17, join as join38, resolve as resolve34 } from "path";
8918
- import { Command as Command74 } from "commander";
9199
+ import { readFileSync as readFileSync19, mkdirSync as mkdirSync13, writeFileSync as writeFileSync16 } from "fs";
9200
+ import { dirname as dirname18, join as join39, resolve as resolve34 } from "path";
9201
+ import { Command as Command76 } from "commander";
8919
9202
  async function runPulseRunCommand(opts) {
8920
9203
  const startedAt = Date.now();
8921
9204
  let raw;
8922
9205
  try {
8923
- raw = JSON.parse(readFileSync18(opts.configPath, "utf-8"));
9206
+ raw = JSON.parse(readFileSync19(opts.configPath, "utf-8"));
8924
9207
  } catch (err) {
8925
9208
  return emit2(
8926
9209
  {
@@ -8946,9 +9229,9 @@ async function runPulseRunCommand(opts) {
8946
9229
  const report = assembleReport(result, productName, lookback);
8947
9230
  const now = /* @__PURE__ */ new Date();
8948
9231
  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")}`;
8949
- const filePath = join38(opts.outputDir, `${ts}.md`);
8950
- mkdirSync13(dirname17(filePath), { recursive: true });
8951
- writeFileSync15(filePath, report);
9232
+ const filePath = join39(opts.outputDir, `${ts}.md`);
9233
+ mkdirSync13(dirname18(filePath), { recursive: true });
9234
+ writeFileSync16(filePath, report);
8952
9235
  const headlines = extractHeadlines(report);
8953
9236
  return emit2(
8954
9237
  {
@@ -8980,7 +9263,7 @@ function emit2(status, nonInteractive) {
8980
9263
  return status;
8981
9264
  }
8982
9265
  function createRunCommand2() {
8983
- return new Command74("run").description("Run a pulse: query configured adapters, sanitize, assemble single-page report").option(
9266
+ return new Command76("run").description("Run a pulse: query configured adapters, sanitize, assemble single-page report").option(
8984
9267
  "--lookback <window>",
8985
9268
  "Lookback window (e.g. 24h, 7d). Defaults to pulse.lookbackDefault."
8986
9269
  ).option(
@@ -9004,14 +9287,14 @@ function createRunCommand2() {
9004
9287
 
9005
9288
  // src/commands/pulse/index.ts
9006
9289
  function createPulseCommand() {
9007
- const command = new Command75("pulse").description("Pulse (read-side observability) commands");
9290
+ const command = new Command77("pulse").description("Pulse (read-side observability) commands");
9008
9291
  command.addCommand(createRunCommand2());
9009
9292
  return command;
9010
9293
  }
9011
9294
 
9012
9295
  // src/commands/recommend.ts
9013
- import { Command as Command76 } from "commander";
9014
- import chalk11 from "chalk";
9296
+ import { Command as Command78 } from "commander";
9297
+ import chalk12 from "chalk";
9015
9298
  async function resolveSnapshot(cwd, noCache) {
9016
9299
  if (!noCache) {
9017
9300
  const cached = loadCachedSnapshot(cwd);
@@ -9045,12 +9328,12 @@ async function runRecommend(options) {
9045
9328
  function formatRecommendation(rec) {
9046
9329
  const lines = [];
9047
9330
  if (rec.urgency === "critical") {
9048
- lines.push(` ${chalk11.red("[CRITICAL]")} ${rec.sequence}. ${rec.skillName}`);
9331
+ lines.push(` ${chalk12.red("[CRITICAL]")} ${rec.sequence}. ${rec.skillName}`);
9049
9332
  } else {
9050
9333
  lines.push(` ${rec.sequence}. ${rec.skillName} (${rec.score.toFixed(2)})`);
9051
9334
  }
9052
9335
  for (const reason of rec.reasons) {
9053
- lines.push(` ${chalk11.dim("\u2192")} ${reason}`);
9336
+ lines.push(` ${chalk12.dim("\u2192")} ${reason}`);
9054
9337
  }
9055
9338
  return lines.join("\n");
9056
9339
  }
@@ -9074,7 +9357,7 @@ function printRecommendations(result) {
9074
9357
  console.log("");
9075
9358
  }
9076
9359
  function createRecommendCommand() {
9077
- const command = new Command76("recommend").description("Recommend skills based on codebase health analysis").option("--no-cache", "Force fresh health snapshot").option("--top <n>", "Max recommendations (default 5)", "5").action(async (opts, cmd) => {
9360
+ const command = new Command78("recommend").description("Recommend skills based on codebase health analysis").option("--no-cache", "Force fresh health snapshot").option("--top <n>", "Max recommendations (default 5)", "5").action(async (opts, cmd) => {
9078
9361
  const globalOpts = cmd.optsWithGlobals();
9079
9362
  const mode = globalOpts.json ? OutputMode.JSON : OutputMode.TEXT;
9080
9363
  try {
@@ -9110,18 +9393,18 @@ function createRecommendCommand() {
9110
9393
  }
9111
9394
 
9112
9395
  // src/commands/roadmap/index.ts
9113
- import { Command as Command78 } from "commander";
9396
+ import { Command as Command80 } from "commander";
9114
9397
 
9115
9398
  // src/commands/roadmap/migrate.ts
9116
9399
  init_dist3();
9117
- import { Command as Command77 } from "commander";
9118
- import * as fs31 from "fs";
9119
- import * as path49 from "path";
9120
- import chalk12 from "chalk";
9400
+ import { Command as Command79 } from "commander";
9401
+ import * as fs32 from "fs";
9402
+ import * as path50 from "path";
9403
+ import chalk13 from "chalk";
9121
9404
 
9122
9405
  // src/commands/roadmap/migrate-lock.ts
9123
- import * as fs30 from "fs";
9124
- import * as path48 from "path";
9406
+ import * as fs31 from "fs";
9407
+ import * as path49 from "path";
9125
9408
  import * as os6 from "os";
9126
9409
  var LOCK_FILE_NAME = "migrate.lock";
9127
9410
  var STALE_LOCK_MS = 30 * 60 * 1e3;
@@ -9135,13 +9418,13 @@ function isPidAlive(pid) {
9135
9418
  }
9136
9419
  }
9137
9420
  function acquireMigrateLock(projectRoot2) {
9138
- const harnessDir = path48.join(projectRoot2, ".harness");
9139
- const lockPath = path48.join(harnessDir, LOCK_FILE_NAME);
9140
- if (!fs30.existsSync(harnessDir)) fs30.mkdirSync(harnessDir, { recursive: true });
9141
- if (fs30.existsSync(lockPath)) {
9421
+ const harnessDir = path49.join(projectRoot2, ".harness");
9422
+ const lockPath = path49.join(harnessDir, LOCK_FILE_NAME);
9423
+ if (!fs31.existsSync(harnessDir)) fs31.mkdirSync(harnessDir, { recursive: true });
9424
+ if (fs31.existsSync(lockPath)) {
9142
9425
  const existingRaw = (() => {
9143
9426
  try {
9144
- return fs30.readFileSync(lockPath, "utf-8");
9427
+ return fs31.readFileSync(lockPath, "utf-8");
9145
9428
  } catch {
9146
9429
  return null;
9147
9430
  }
@@ -9171,11 +9454,11 @@ function acquireMigrateLock(projectRoot2) {
9171
9454
  startedAt: (/* @__PURE__ */ new Date()).toISOString(),
9172
9455
  hostname: os6.hostname()
9173
9456
  };
9174
- fs30.writeFileSync(lockPath, JSON.stringify(payload, null, 2) + "\n");
9457
+ fs31.writeFileSync(lockPath, JSON.stringify(payload, null, 2) + "\n");
9175
9458
  return {
9176
9459
  release: () => {
9177
9460
  try {
9178
- fs30.unlinkSync(lockPath);
9461
+ fs31.unlinkSync(lockPath);
9179
9462
  } catch {
9180
9463
  }
9181
9464
  }
@@ -9206,7 +9489,7 @@ function reportToExitCode(report) {
9206
9489
  return MigrateExitCode.GENERIC_FAILURE;
9207
9490
  }
9208
9491
  function printPlanSummary(plan, dryRun) {
9209
- const banner = dryRun ? chalk12.cyan("DRY RUN ") : "";
9492
+ const banner = dryRun ? chalk13.cyan("DRY RUN ") : "";
9210
9493
  console.log(`${banner}Migration plan:`);
9211
9494
  console.log(` Would create: ${plan.toCreate.length}`);
9212
9495
  for (const e of plan.toCreate) console.log(` - ${e.name}`);
@@ -9335,11 +9618,11 @@ async function runRoadmapMigrate(opts) {
9335
9618
  if (!clientR.ok) return Err(new CLIError(clientR.error.message));
9336
9619
  client = clientR.value;
9337
9620
  }
9338
- const roadmapPath = path49.join(cwd, "docs", "roadmap.md");
9339
- if (!fs31.existsSync(roadmapPath)) {
9621
+ const roadmapPath = path50.join(cwd, "docs", "roadmap.md");
9622
+ if (!fs32.existsSync(roadmapPath)) {
9340
9623
  return Err(new CLIError(`docs/roadmap.md not found in ${cwd}`));
9341
9624
  }
9342
- const roadmapR = parseRoadmap(fs31.readFileSync(roadmapPath, "utf-8"));
9625
+ const roadmapR = parseRoadmap(fs32.readFileSync(roadmapPath, "utf-8"));
9343
9626
  if (!roadmapR.ok) {
9344
9627
  return Err(new CLIError(`failed to parse docs/roadmap.md: ${roadmapR.error.message}`));
9345
9628
  }
@@ -9360,10 +9643,10 @@ async function runRoadmapMigrate(opts) {
9360
9643
  if (!isJson) printPlanSummary(plan, opts.dryRun);
9361
9644
  const deps = {
9362
9645
  client,
9363
- readFile: (p) => fs31.readFileSync(p, "utf-8"),
9364
- writeFile: (p, b) => fs31.writeFileSync(p, b),
9365
- renameFile: (from, to) => fs31.renameSync(from, to),
9366
- existsFile: (p) => fs31.existsSync(p)
9646
+ readFile: (p) => fs32.readFileSync(p, "utf-8"),
9647
+ writeFile: (p, b) => fs32.writeFileSync(p, b),
9648
+ renameFile: (from, to) => fs32.renameSync(from, to),
9649
+ existsFile: (p) => fs32.existsSync(p)
9367
9650
  };
9368
9651
  const reportR = await migrate_exports.runMigrationPlan(plan, deps, {
9369
9652
  projectRoot: cwd,
@@ -9384,7 +9667,7 @@ async function runRoadmapMigrate(opts) {
9384
9667
  }
9385
9668
  }
9386
9669
  function createRoadmapMigrateCommand() {
9387
- return new Command77("migrate").description("Migrate the project roadmap to a different storage mode").requiredOption("--to <target>", 'Migration target (only "file-less" supported today)').option("--dry-run", "Print the migration plan without making any changes", false).option(
9670
+ return new Command79("migrate").description("Migrate the project roadmap to a different storage mode").requiredOption("--to <target>", 'Migration target (only "file-less" supported today)').option("--dry-run", "Print the migration plan without making any changes", false).option(
9388
9671
  "--format <fmt>",
9389
9672
  'Output format: "human" (default) or "json" (single JSON object for CI consumers)',
9390
9673
  "human"
@@ -9419,16 +9702,16 @@ function createRoadmapMigrateCommand() {
9419
9702
 
9420
9703
  // src/commands/roadmap/index.ts
9421
9704
  function createRoadmapCommand() {
9422
- const roadmap = new Command78("roadmap").description("Roadmap management");
9705
+ const roadmap = new Command80("roadmap").description("Roadmap management");
9423
9706
  roadmap.addCommand(createRoadmapMigrateCommand());
9424
9707
  return roadmap;
9425
9708
  }
9426
9709
 
9427
9710
  // src/commands/routing/index.ts
9428
- import { Command as Command82 } from "commander";
9711
+ import { Command as Command84 } from "commander";
9429
9712
 
9430
9713
  // src/commands/routing/config.ts
9431
- import { Command as Command79 } from "commander";
9714
+ import { Command as Command81 } from "commander";
9432
9715
 
9433
9716
  // src/commands/routing/http-client.ts
9434
9717
  function orchestratorBase() {
@@ -9438,9 +9721,9 @@ function authHeader() {
9438
9721
  const tok = process.env["HARNESS_API_TOKEN"];
9439
9722
  return tok ? { Authorization: `Bearer ${tok}` } : {};
9440
9723
  }
9441
- async function getJson(path71) {
9724
+ async function getJson(path72) {
9442
9725
  try {
9443
- const res = await fetch(`${orchestratorBase()}${path71}`, {
9726
+ const res = await fetch(`${orchestratorBase()}${path72}`, {
9444
9727
  headers: { ...authHeader() }
9445
9728
  });
9446
9729
  const text = await res.text();
@@ -9455,9 +9738,9 @@ async function getJson(path71) {
9455
9738
  };
9456
9739
  }
9457
9740
  }
9458
- async function postJson(path71, body) {
9741
+ async function postJson(path72, body) {
9459
9742
  try {
9460
- const res = await fetch(`${orchestratorBase()}${path71}`, {
9743
+ const res = await fetch(`${orchestratorBase()}${path72}`, {
9461
9744
  method: "POST",
9462
9745
  headers: { "Content-Type": "application/json", ...authHeader() },
9463
9746
  body: JSON.stringify(body)
@@ -9493,7 +9776,7 @@ function renderHuman(data) {
9493
9776
  }
9494
9777
  }
9495
9778
  function createConfigCommand() {
9496
- return new Command79("config").description("Print active routing config and resolved fallback chains").option("--json", "Emit JSON to stdout instead of human-readable text").action(async (opts) => {
9779
+ return new Command81("config").description("Print active routing config and resolved fallback chains").option("--json", "Emit JSON to stdout instead of human-readable text").action(async (opts) => {
9497
9780
  const r = await getJson("/api/v1/routing/config");
9498
9781
  if (!r.ok) {
9499
9782
  if (r.status === 0) {
@@ -9519,7 +9802,7 @@ function createConfigCommand() {
9519
9802
  }
9520
9803
 
9521
9804
  // src/commands/routing/trace.ts
9522
- import { Command as Command80 } from "commander";
9805
+ import { Command as Command82 } from "commander";
9523
9806
  function buildUseCase(opts) {
9524
9807
  if (opts.skill) {
9525
9808
  return opts.mode ? { kind: "skill", skillName: opts.skill, cognitiveMode: opts.mode } : { kind: "skill", skillName: opts.skill };
@@ -9540,7 +9823,7 @@ function renderHuman2(r) {
9540
9823
  }
9541
9824
  }
9542
9825
  function createTraceCommand() {
9543
- return new Command80("trace").description("Dry-run a routing decision without dispatching (Spec B F7)").option("--skill <name>", "Skill name to trace").option("--mode <m>", "Cognitive mode to trace (or attach to --skill per spec D12)").option("--json", "Emit JSON to stdout instead of human-readable text").action(async (opts) => {
9826
+ return new Command82("trace").description("Dry-run a routing decision without dispatching (Spec B F7)").option("--skill <name>", "Skill name to trace").option("--mode <m>", "Cognitive mode to trace (or attach to --skill per spec D12)").option("--json", "Emit JSON to stdout instead of human-readable text").action(async (opts) => {
9544
9827
  const useCase = buildUseCase(opts);
9545
9828
  if (!useCase) {
9546
9829
  logger.error("Either --skill <name> or --mode <m> is required");
@@ -9572,7 +9855,7 @@ function createTraceCommand() {
9572
9855
  }
9573
9856
 
9574
9857
  // src/commands/routing/decisions.ts
9575
- import { Command as Command81 } from "commander";
9858
+ import { Command as Command83 } from "commander";
9576
9859
  function summarizeUseCase(uc) {
9577
9860
  switch (uc.kind) {
9578
9861
  case "skill":
@@ -9620,7 +9903,7 @@ function buildQuery(opts) {
9620
9903
  return q ? `?${q}` : "";
9621
9904
  }
9622
9905
  function createDecisionsCommand() {
9623
- return new Command81("decisions").description("List recent routing decisions from the orchestrator ring buffer (Spec B F8)").option("--skill <name>", "Filter by useCase.skillName").option("--mode <m>", "Filter by useCase.cognitiveMode").option("--backend <name>", "Filter by chosen backendName").option("--last <N>", "Limit to the N most recent decisions").option("--json", "Emit JSON to stdout instead of human-readable text").action(
9906
+ return new Command83("decisions").description("List recent routing decisions from the orchestrator ring buffer (Spec B F8)").option("--skill <name>", "Filter by useCase.skillName").option("--mode <m>", "Filter by useCase.cognitiveMode").option("--backend <name>", "Filter by chosen backendName").option("--last <N>", "Limit to the N most recent decisions").option("--json", "Emit JSON to stdout instead of human-readable text").action(
9624
9907
  async (opts) => {
9625
9908
  const query = buildQuery(opts);
9626
9909
  const r = await getJson(`/api/v1/routing/decisions${query}`);
@@ -9650,7 +9933,7 @@ function createDecisionsCommand() {
9650
9933
 
9651
9934
  // src/commands/routing/index.ts
9652
9935
  function createRoutingCommand() {
9653
- const cmd = new Command82("routing").description(
9936
+ const cmd = new Command84("routing").description(
9654
9937
  "Inspect routing config, trace decisions, and read recent dispatches"
9655
9938
  );
9656
9939
  cmd.addCommand(createConfigCommand());
@@ -9661,9 +9944,9 @@ function createRoutingCommand() {
9661
9944
 
9662
9945
  // src/commands/scan-config.ts
9663
9946
  init_dist3();
9664
- import { Command as Command83 } from "commander";
9665
- import { existsSync as existsSync28, readFileSync as readFileSync21, writeFileSync as writeFileSync18 } from "fs";
9666
- import { join as join41, relative as relative3 } from "path";
9947
+ import { Command as Command85 } from "commander";
9948
+ import { existsSync as existsSync29, readFileSync as readFileSync22, writeFileSync as writeFileSync19 } from "fs";
9949
+ import { join as join42, relative as relative3 } from "path";
9667
9950
  var CONFIG_FILES = ["CLAUDE.md", "AGENTS.md", ".gemini/settings.json", "skill.yaml"];
9668
9951
  function stripHighSeverityPatterns(content, injectionFindings) {
9669
9952
  const highLines = /* @__PURE__ */ new Set();
@@ -9689,17 +9972,17 @@ function applyFix(filePath, targetDir, content, injectionFindings) {
9689
9972
  if (!hasHighSeverity) return;
9690
9973
  const { cleaned, linesStripped } = stripHighSeverityPatterns(content, injectionFindings);
9691
9974
  if (linesStripped > 0) {
9692
- writeFileSync18(filePath, cleaned);
9975
+ writeFileSync19(filePath, cleaned);
9693
9976
  logger.info(
9694
9977
  `scan-config --fix: stripped ${linesStripped} high-severity line(s) from ${relative3(targetDir, filePath).replaceAll("\\", "/")}`
9695
9978
  );
9696
9979
  }
9697
9980
  }
9698
9981
  function scanSingleFile(filePath, targetDir, scanner, options) {
9699
- if (!existsSync28(filePath)) return null;
9982
+ if (!existsSync29(filePath)) return null;
9700
9983
  let content;
9701
9984
  try {
9702
- content = readFileSync21(filePath, "utf8");
9985
+ content = readFileSync22(filePath, "utf8");
9703
9986
  } catch {
9704
9987
  return null;
9705
9988
  }
@@ -9720,7 +10003,7 @@ async function runScanConfig(targetDir, options) {
9720
10003
  const scanner = new SecurityScanner(parseSecurityConfig({}));
9721
10004
  const results = [];
9722
10005
  for (const configFile of CONFIG_FILES) {
9723
- const result = scanSingleFile(join41(targetDir, configFile), targetDir, scanner, options);
10006
+ const result = scanSingleFile(join42(targetDir, configFile), targetDir, scanner, options);
9724
10007
  if (result) results.push(result);
9725
10008
  }
9726
10009
  return { exitCode: computeScanExitCode(results), results };
@@ -9750,7 +10033,7 @@ function formatTextOutput(result) {
9750
10033
  }
9751
10034
  }
9752
10035
  function createScanConfigCommand() {
9753
- const command = new Command83("scan-config").description(
10036
+ const command = new Command85("scan-config").description(
9754
10037
  "Scan CLAUDE.md, AGENTS.md, .gemini/settings.json, and skill.yaml for prompt injection patterns"
9755
10038
  ).option("--path <dir>", "Target directory to scan (default: cwd)").option("--fix", "Strip high-severity patterns from files in-place").action(async (opts, cmd) => {
9756
10039
  const globalOpts = cmd.optsWithGlobals();
@@ -9768,7 +10051,7 @@ function createScanConfigCommand() {
9768
10051
 
9769
10052
  // src/commands/search.ts
9770
10053
  init_dist();
9771
- import { Command as Command84 } from "commander";
10054
+ import { Command as Command86 } from "commander";
9772
10055
  function parseFileKinds(raw) {
9773
10056
  if (!raw) return void 0;
9774
10057
  const set = /* @__PURE__ */ new Set();
@@ -9789,7 +10072,7 @@ function fmtBytes(n) {
9789
10072
  return n.toFixed(0);
9790
10073
  }
9791
10074
  function createSearchCommand() {
9792
- return new Command84("search").description("Full-text search over archived + live session content (Hermes Phase 1).").argument(
10075
+ return new Command86("search").description("Full-text search over archived + live session content.").argument(
9793
10076
  "<query>",
9794
10077
  "FTS5 query (bare words AND-joined; quotes/AND/OR/NOT/column: for advanced syntax)"
9795
10078
  ).option("-n, --limit <n>", "Max results", "20").option("--archived-only", "Skip live sessions, only search archived ones").option("--json", "Emit JSON to stdout instead of pretty text").option(
@@ -9849,9 +10132,9 @@ function createSearchCommand() {
9849
10132
  }
9850
10133
 
9851
10134
  // src/commands/security-craft.ts
9852
- import { Command as Command85 } from "commander";
10135
+ import { Command as Command87 } from "commander";
9853
10136
  function createSecurityCraftCommand() {
9854
- return new Command85("security-craft").description(
10137
+ return new Command87("security-craft").description(
9855
10138
  "LLM-judgment critique of security posture (TS/JS source). Sixth non-design craft-pipeline ceiling skill (the final sub-project). AST-driven signal detection fires only on files with security-relevant constructs; conservative confidence defaults manage the FP risk inherent in judgment-based security."
9856
10139
  ).option("-f, --files <files...>", "Optional file scope (overrides discovery)").option("-p, --packages <names...>", "Restrict to specific packages under packages/").option("--max-files <n>", "Cap source-file count (default: 100)").option("--max-signals-per-file <n>", "Cap per-file signal critique (default: 10)").action(async (opts, cmd) => {
9857
10140
  const globalOpts = cmd.optsWithGlobals();
@@ -9898,10 +10181,10 @@ function printResult5(result, mode, _formatter) {
9898
10181
  list.push(f);
9899
10182
  byFile.set(f.target.file, list);
9900
10183
  }
9901
- for (const [file, fs47] of byFile) {
10184
+ for (const [file, fs48] of byFile) {
9902
10185
  console.log(`
9903
10186
  ${file}`);
9904
- for (const f of fs47) {
10187
+ for (const f of fs48) {
9905
10188
  console.log(
9906
10189
  ` ${f.code} [${f.tier}/${f.impact}/${f.confidence}] ${f.target.signal}:${f.target.line}`
9907
10190
  );
@@ -9917,24 +10200,24 @@ ${file}`);
9917
10200
  }
9918
10201
 
9919
10202
  // src/commands/setup.ts
9920
- import { Command as Command86 } from "commander";
9921
- import * as fs34 from "fs";
10203
+ import { Command as Command88 } from "commander";
10204
+ import * as fs35 from "fs";
9922
10205
  import * as os8 from "os";
9923
- import * as path52 from "path";
9924
- import chalk14 from "chalk";
10206
+ import * as path53 from "path";
10207
+ import chalk15 from "chalk";
9925
10208
 
9926
10209
  // src/utils/first-run.ts
9927
- import * as fs32 from "fs";
10210
+ import * as fs33 from "fs";
9928
10211
  import * as os7 from "os";
9929
- import * as path50 from "path";
9930
- var HARNESS_DIR = path50.join(os7.homedir(), ".harness");
9931
- var MARKER_FILE = path50.join(HARNESS_DIR, ".setup-complete");
10212
+ import * as path51 from "path";
10213
+ var HARNESS_DIR = path51.join(os7.homedir(), ".harness");
10214
+ var MARKER_FILE = path51.join(HARNESS_DIR, ".setup-complete");
9932
10215
  function isFirstRun() {
9933
- return !fs32.existsSync(MARKER_FILE);
10216
+ return !fs33.existsSync(MARKER_FILE);
9934
10217
  }
9935
10218
  function markSetupComplete() {
9936
- fs32.mkdirSync(HARNESS_DIR, { recursive: true });
9937
- fs32.writeFileSync(MARKER_FILE, "", "utf-8");
10219
+ fs33.mkdirSync(HARNESS_DIR, { recursive: true });
10220
+ fs33.writeFileSync(MARKER_FILE, "", "utf-8");
9938
10221
  }
9939
10222
  function printFirstRunWelcome() {
9940
10223
  try {
@@ -9947,10 +10230,10 @@ function printFirstRunWelcome() {
9947
10230
  }
9948
10231
 
9949
10232
  // src/commands/telemetry-wizard.ts
9950
- import * as fs33 from "fs";
9951
- import * as path51 from "path";
10233
+ import * as fs34 from "fs";
10234
+ import * as path52 from "path";
9952
10235
  import readline2 from "readline";
9953
- import chalk13 from "chalk";
10236
+ import chalk14 from "chalk";
9954
10237
  function prompt2(question) {
9955
10238
  const rl = readline2.createInterface({
9956
10239
  input: process.stdin,
@@ -9979,21 +10262,21 @@ function isNo(answer) {
9979
10262
  return answer === "n" || answer === "no";
9980
10263
  }
9981
10264
  function isTelemetryConfigured(cwd) {
9982
- const configPath = path51.join(cwd, "harness.config.json");
10265
+ const configPath = path52.join(cwd, "harness.config.json");
9983
10266
  try {
9984
- const raw = JSON.parse(fs33.readFileSync(configPath, "utf-8"));
10267
+ const raw = JSON.parse(fs34.readFileSync(configPath, "utf-8"));
9985
10268
  return raw.telemetry !== void 0 && raw.adoption !== void 0;
9986
10269
  } catch {
9987
10270
  return false;
9988
10271
  }
9989
10272
  }
9990
10273
  function writeTelemetryConfig(cwd, result) {
9991
- const configPath = path51.join(cwd, "harness.config.json");
10274
+ const configPath = path52.join(cwd, "harness.config.json");
9992
10275
  try {
9993
- const raw = JSON.parse(fs33.readFileSync(configPath, "utf-8"));
10276
+ const raw = JSON.parse(fs34.readFileSync(configPath, "utf-8"));
9994
10277
  raw.telemetry = { enabled: result.telemetryEnabled };
9995
10278
  raw.adoption = { enabled: result.adoptionEnabled };
9996
- fs33.writeFileSync(configPath, JSON.stringify(raw, null, 2) + "\n");
10279
+ fs34.writeFileSync(configPath, JSON.stringify(raw, null, 2) + "\n");
9997
10280
  } catch (err) {
9998
10281
  console.warn(
9999
10282
  `\u26A0 Could not update ${configPath}: ${err instanceof Error ? err.message : String(err)}`
@@ -10001,15 +10284,15 @@ function writeTelemetryConfig(cwd, result) {
10001
10284
  }
10002
10285
  const hasIdentity = result.identity.project || result.identity.team || result.identity.alias;
10003
10286
  if (hasIdentity) {
10004
- const harnessDir = path51.join(cwd, ".harness");
10005
- fs33.mkdirSync(harnessDir, { recursive: true });
10006
- const telemetryFile = path51.join(harnessDir, "telemetry.json");
10007
- fs33.writeFileSync(telemetryFile, JSON.stringify({ identity: result.identity }, null, 2) + "\n");
10287
+ const harnessDir = path52.join(cwd, ".harness");
10288
+ fs34.mkdirSync(harnessDir, { recursive: true });
10289
+ const telemetryFile = path52.join(harnessDir, "telemetry.json");
10290
+ fs34.writeFileSync(telemetryFile, JSON.stringify({ identity: result.identity }, null, 2) + "\n");
10008
10291
  }
10009
10292
  }
10010
10293
  async function promptIdentity() {
10011
10294
  console.log(
10012
- ` ${chalk13.cyan("Identity")} (optional) \u2014 tag telemetry with project/team/alias for filtering.`
10295
+ ` ${chalk14.cyan("Identity")} (optional) \u2014 tag telemetry with project/team/alias for filtering.`
10013
10296
  );
10014
10297
  console.log(" Leave blank to keep anonymous.");
10015
10298
  const answer = await prompt2(" Set identity fields? (y/N) ");
@@ -10027,20 +10310,20 @@ async function promptIdentity() {
10027
10310
  async function runTelemetryWizard() {
10028
10311
  if (!process.stdin.isTTY) return null;
10029
10312
  console.log("");
10030
- console.log(` ${chalk13.bold("Telemetry Configuration")}`);
10313
+ console.log(` ${chalk14.bold("Telemetry Configuration")}`);
10031
10314
  console.log("");
10032
10315
  console.log(" Harness can collect anonymous usage data to help improve the tool.");
10033
10316
  console.log(" You can change these settings anytime in harness.config.json.");
10034
10317
  console.log("");
10035
10318
  console.log(
10036
- ` ${chalk13.cyan("Anonymous telemetry")} \u2014 error rates, command usage, performance metrics.`
10319
+ ` ${chalk14.cyan("Anonymous telemetry")} \u2014 error rates, command usage, performance metrics.`
10037
10320
  );
10038
10321
  console.log(" No code, file contents, or personally identifiable info is sent.");
10039
10322
  const telemetryAnswer = await prompt2(" Enable anonymous telemetry? (Y/n) ");
10040
10323
  const telemetryEnabled = !isNo(telemetryAnswer);
10041
10324
  console.log("");
10042
10325
  console.log(
10043
- ` ${chalk13.cyan("Adoption tracking")} \u2014 which skills are used, how often, and success rates.`
10326
+ ` ${chalk14.cyan("Adoption tracking")} \u2014 which skills are used, how often, and success rates.`
10044
10327
  );
10045
10328
  console.log(" Stored locally in .harness/adoption/. Never sent externally.");
10046
10329
  const adoptionAnswer = await prompt2(" Enable local adoption tracking? (Y/n) ");
@@ -10050,8 +10333,8 @@ async function runTelemetryWizard() {
10050
10333
  return { telemetryEnabled, adoptionEnabled, identity };
10051
10334
  }
10052
10335
  async function ensureTelemetryConfigured(cwd) {
10053
- const configPath = path51.join(cwd, "harness.config.json");
10054
- if (!fs33.existsSync(configPath)) {
10336
+ const configPath = path52.join(cwd, "harness.config.json");
10337
+ if (!fs34.existsSync(configPath)) {
10055
10338
  return { status: "warn", message: "Not a harness project \u2014 skipped telemetry configuration" };
10056
10339
  }
10057
10340
  if (isTelemetryConfigured(cwd)) {
@@ -10097,7 +10380,7 @@ function runSlashCommandGeneration() {
10097
10380
  }
10098
10381
  }
10099
10382
  function detectClient(dirName) {
10100
- return fs34.existsSync(path52.join(os8.homedir(), dirName));
10383
+ return fs35.existsSync(path53.join(os8.homedir(), dirName));
10101
10384
  }
10102
10385
  async function runMcpSetup(cwd) {
10103
10386
  const results = [];
@@ -10113,7 +10396,7 @@ async function runMcpSetup(cwd) {
10113
10396
  { name: "Cursor", dir: ".cursor", client: "cursor", configTarget: ".cursor/mcp.json" },
10114
10397
  {
10115
10398
  name: "OpenCode",
10116
- dir: path52.join(".config", "opencode"),
10399
+ dir: path53.join(".config", "opencode"),
10117
10400
  client: "opencode",
10118
10401
  configTarget: "opencode.json"
10119
10402
  }
@@ -10140,12 +10423,12 @@ async function runMcpSetup(cwd) {
10140
10423
  return results;
10141
10424
  }
10142
10425
  function formatStep(result) {
10143
- const icon = result.status === "pass" ? chalk14.green("\u2713") : result.status === "warn" ? chalk14.yellow("\u26A0") : chalk14.red("\u2717");
10426
+ const icon = result.status === "pass" ? chalk15.green("\u2713") : result.status === "warn" ? chalk15.yellow("\u26A0") : chalk15.red("\u2717");
10144
10427
  return ` ${icon} ${result.message}`;
10145
10428
  }
10146
10429
  function configureTier0Integrations(cwd) {
10147
10430
  try {
10148
- const mcpPath = path52.join(cwd, ".mcp.json");
10431
+ const mcpPath = path53.join(cwd, ".mcp.json");
10149
10432
  const config = readMcpConfig(mcpPath);
10150
10433
  const tier0 = INTEGRATION_REGISTRY.filter((i) => i.tier === 0);
10151
10434
  const added = [];
@@ -10154,9 +10437,9 @@ function configureTier0Integrations(cwd) {
10154
10437
  writeMcpEntry(mcpPath, integration.name, integration.mcpConfig);
10155
10438
  added.push(integration.displayName);
10156
10439
  }
10157
- const geminiDir = path52.join(cwd, ".gemini");
10158
- if (fs34.existsSync(geminiDir)) {
10159
- const geminiPath = path52.join(geminiDir, "settings.json");
10440
+ const geminiDir = path53.join(cwd, ".gemini");
10441
+ if (fs35.existsSync(geminiDir)) {
10442
+ const geminiPath = path53.join(geminiDir, "settings.json");
10160
10443
  const geminiConfig = readMcpConfig(geminiPath);
10161
10444
  for (const integration of tier0) {
10162
10445
  if (!geminiConfig.mcpServers[integration.name]) {
@@ -10164,9 +10447,9 @@ function configureTier0Integrations(cwd) {
10164
10447
  }
10165
10448
  }
10166
10449
  }
10167
- const opencodePath = path52.join(cwd, "opencode.json");
10168
- const opencodeGlobalDir = path52.join(os8.homedir(), ".config", "opencode");
10169
- if (fs34.existsSync(opencodePath) || fs34.existsSync(opencodeGlobalDir)) {
10450
+ const opencodePath = path53.join(cwd, "opencode.json");
10451
+ const opencodeGlobalDir = path53.join(os8.homedir(), ".config", "opencode");
10452
+ if (fs35.existsSync(opencodePath) || fs35.existsSync(opencodeGlobalDir)) {
10170
10453
  for (const integration of tier0) {
10171
10454
  writeOpencodeMcpEntry(opencodePath, integration.name, integration.mcpConfig);
10172
10455
  }
@@ -10184,14 +10467,14 @@ function configureTier0Integrations(cwd) {
10184
10467
  }
10185
10468
  }
10186
10469
  function ensureHooks(cwd) {
10187
- const configPath = path52.join(cwd, "harness.config.json");
10188
- if (!fs34.existsSync(configPath)) {
10470
+ const configPath = path53.join(cwd, "harness.config.json");
10471
+ if (!fs35.existsSync(configPath)) {
10189
10472
  return { status: "warn", message: "Not a harness project \u2014 skipped hook installation" };
10190
10473
  }
10191
10474
  let profile = "standard";
10192
- const profilePath = path52.join(cwd, ".harness", "hooks", "profile.json");
10475
+ const profilePath = path53.join(cwd, ".harness", "hooks", "profile.json");
10193
10476
  try {
10194
- const data = JSON.parse(fs34.readFileSync(profilePath, "utf-8"));
10477
+ const data = JSON.parse(fs35.readFileSync(profilePath, "utf-8"));
10195
10478
  if (data.profile && ["minimal", "standard", "strict"].includes(data.profile)) {
10196
10479
  profile = data.profile;
10197
10480
  }
@@ -10262,10 +10545,10 @@ async function runSetup(cwd) {
10262
10545
  return { steps, success };
10263
10546
  }
10264
10547
  function createSetupCommand() {
10265
- return new Command86("setup").description("Configure harness environment: slash commands, MCP, and more").action(async () => {
10548
+ return new Command88("setup").description("Configure harness environment: slash commands, MCP, and more").action(async () => {
10266
10549
  const cwd = process.cwd();
10267
10550
  console.log("");
10268
- console.log(` ${chalk14.bold("harness setup")}`);
10551
+ console.log(` ${chalk15.bold("harness setup")}`);
10269
10552
  console.log("");
10270
10553
  const { steps, success } = await runSetup(cwd);
10271
10554
  for (const step of steps) {
@@ -10285,15 +10568,15 @@ function createSetupCommand() {
10285
10568
 
10286
10569
  // src/commands/share.ts
10287
10570
  init_dist3();
10288
- import { Command as Command87 } from "commander";
10289
- import * as fs35 from "fs";
10290
- import * as path53 from "path";
10291
- import { parse as parseYaml2 } from "yaml";
10571
+ import { Command as Command89 } from "commander";
10572
+ import * as fs36 from "fs";
10573
+ import * as path54 from "path";
10574
+ import { parse as parseYaml3 } from "yaml";
10292
10575
  var MANIFEST_FILENAME = "constraints.yaml";
10293
10576
  async function runShareAction(projectPath, options) {
10294
- const rootDir = path53.resolve(projectPath);
10295
- const manifestPath = path53.join(rootDir, MANIFEST_FILENAME);
10296
- if (!fs35.existsSync(manifestPath)) {
10577
+ const rootDir = path54.resolve(projectPath);
10578
+ const manifestPath = path54.join(rootDir, MANIFEST_FILENAME);
10579
+ if (!fs36.existsSync(manifestPath)) {
10297
10580
  logger.error(
10298
10581
  `No ${MANIFEST_FILENAME} found at ${manifestPath}.
10299
10582
  Create a constraints.yaml in your project root to define what to share.`
@@ -10302,8 +10585,8 @@ Create a constraints.yaml in your project root to define what to share.`
10302
10585
  }
10303
10586
  let parsed;
10304
10587
  try {
10305
- const raw = fs35.readFileSync(manifestPath, "utf-8");
10306
- parsed = parseYaml2(raw);
10588
+ const raw = fs36.readFileSync(manifestPath, "utf-8");
10589
+ parsed = parseYaml3(raw);
10307
10590
  } catch (err) {
10308
10591
  logger.error(
10309
10592
  `Failed to read ${MANIFEST_FILENAME}: ${err instanceof Error ? err.message : String(err)}`
@@ -10316,7 +10599,7 @@ Create a constraints.yaml in your project root to define what to share.`
10316
10599
  process.exit(1);
10317
10600
  }
10318
10601
  const manifest = manifestResult.value;
10319
- const configResult = resolveConfig(path53.join(rootDir, "harness.config.json"));
10602
+ const configResult = resolveConfig(path54.join(rootDir, "harness.config.json"));
10320
10603
  if (!configResult.ok) {
10321
10604
  logger.error(configResult.error.message);
10322
10605
  process.exit(1);
@@ -10334,8 +10617,8 @@ Create a constraints.yaml in your project root to define what to share.`
10334
10617
  );
10335
10618
  process.exit(1);
10336
10619
  }
10337
- const outputDir = path53.resolve(options.output);
10338
- const outputPath = path53.join(outputDir, `${manifest.name}.harness-constraints.json`);
10620
+ const outputDir = path54.resolve(options.output);
10621
+ const outputPath = path54.join(outputDir, `${manifest.name}.harness-constraints.json`);
10339
10622
  const writeResult = await writeConfig(outputPath, bundle);
10340
10623
  if (!writeResult.ok) {
10341
10624
  logger.error(`Failed to write bundle: ${writeResult.error.message}`);
@@ -10344,28 +10627,28 @@ Create a constraints.yaml in your project root to define what to share.`
10344
10627
  logger.success(`Bundle written to ${outputPath}`);
10345
10628
  }
10346
10629
  function createShareCommand() {
10347
- return new Command87("share").description("Extract and publish a constraints bundle from constraints.yaml").argument("[path]", "Path to the project root", ".").option("-o, --output <dir>", "Output directory for the bundle", ".").action(async (projectPath, options) => {
10630
+ return new Command89("share").description("Extract and publish a constraints bundle from constraints.yaml").argument("[path]", "Path to the project root", ".").option("-o, --output <dir>", "Output directory for the bundle", ".").action(async (projectPath, options) => {
10348
10631
  await runShareAction(projectPath, options);
10349
10632
  });
10350
10633
  }
10351
10634
 
10352
10635
  // src/commands/skill/index.ts
10353
- import { Command as Command95 } from "commander";
10636
+ import { Command as Command97 } from "commander";
10354
10637
 
10355
10638
  // src/commands/skill/list.ts
10356
- import { Command as Command88 } from "commander";
10357
- import * as fs36 from "fs";
10358
- import * as path54 from "path";
10639
+ import { Command as Command90 } from "commander";
10640
+ import * as fs37 from "fs";
10641
+ import * as path55 from "path";
10359
10642
  import { parse } from "yaml";
10360
10643
  function scanDirectory(dirPath, source) {
10361
- if (!fs36.existsSync(dirPath)) return [];
10362
- const entries = fs36.readdirSync(dirPath, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
10644
+ if (!fs37.existsSync(dirPath)) return [];
10645
+ const entries = fs37.readdirSync(dirPath, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
10363
10646
  const skills = [];
10364
10647
  for (const name of entries) {
10365
- const yamlPath = path54.join(dirPath, name, "skill.yaml");
10366
- if (!fs36.existsSync(yamlPath)) continue;
10648
+ const yamlPath = path55.join(dirPath, name, "skill.yaml");
10649
+ if (!fs37.existsSync(yamlPath)) continue;
10367
10650
  try {
10368
- const raw = fs36.readFileSync(yamlPath, "utf-8");
10651
+ const raw = fs37.readFileSync(yamlPath, "utf-8");
10369
10652
  const parsed = parse(raw);
10370
10653
  const result = SkillMetadataSchema.safeParse(parsed);
10371
10654
  if (result.success) {
@@ -10383,10 +10666,10 @@ function scanDirectory(dirPath, source) {
10383
10666
  }
10384
10667
  function collectCommunitySkills(seen, allSkills) {
10385
10668
  const globalDir = resolveGlobalSkillsDir();
10386
- const skillsDir = path54.dirname(globalDir);
10387
- const communityBase = path54.join(skillsDir, "community");
10388
- const communityPlatformDir = path54.join(communityBase, "claude-code");
10389
- const lockfilePath = path54.join(communityBase, "skills-lock.json");
10669
+ const skillsDir = path55.dirname(globalDir);
10670
+ const communityBase = path55.join(skillsDir, "community");
10671
+ const communityPlatformDir = path55.join(communityBase, "claude-code");
10672
+ const lockfilePath = path55.join(communityBase, "skills-lock.json");
10390
10673
  const lockfile = readLockfile2(lockfilePath);
10391
10674
  const communitySkills = scanDirectory(communityPlatformDir, "community");
10392
10675
  for (const skill of communitySkills) {
@@ -10456,7 +10739,7 @@ function printSkillsVerbose(skills) {
10456
10739
  for (const s of skills) printSkillEntry(s);
10457
10740
  }
10458
10741
  function createListCommand3() {
10459
- return new Command88("list").description("List available skills").option("--installed", "Show only community-installed skills").option("--local", "Show only project-local skills").option("--all", "Show all skills (default)").action(async (opts, cmd) => {
10742
+ return new Command90("list").description("List available skills").option("--installed", "Show only community-installed skills").option("--local", "Show only project-local skills").option("--all", "Show all skills (default)").action(async (opts, cmd) => {
10460
10743
  const globalOpts = cmd.optsWithGlobals();
10461
10744
  const skills = collectSkills({ filter: resolveFilter(opts) });
10462
10745
  if (globalOpts.json) {
@@ -10471,9 +10754,9 @@ function createListCommand3() {
10471
10754
  }
10472
10755
 
10473
10756
  // src/commands/skill/run.ts
10474
- import { Command as Command89 } from "commander";
10475
- import * as fs37 from "fs";
10476
- import * as path55 from "path";
10757
+ import { Command as Command91 } from "commander";
10758
+ import * as fs38 from "fs";
10759
+ import * as path56 from "path";
10477
10760
  import { parse as parse2 } from "yaml";
10478
10761
 
10479
10762
  // src/skill/complexity.ts
@@ -10569,10 +10852,10 @@ ${options.principles}`);
10569
10852
 
10570
10853
  // src/commands/skill/run.ts
10571
10854
  function loadSkillMetadata(skillDir) {
10572
- const yamlPath = path55.join(skillDir, "skill.yaml");
10573
- if (!fs37.existsSync(yamlPath)) return null;
10855
+ const yamlPath = path56.join(skillDir, "skill.yaml");
10856
+ if (!fs38.existsSync(yamlPath)) return null;
10574
10857
  try {
10575
- const result = SkillMetadataSchema.safeParse(parse2(fs37.readFileSync(yamlPath, "utf-8")));
10858
+ const result = SkillMetadataSchema.safeParse(parse2(fs38.readFileSync(yamlPath, "utf-8")));
10576
10859
  return result.success ? result.data : null;
10577
10860
  } catch {
10578
10861
  return null;
@@ -10584,22 +10867,22 @@ function resolveComplexity(metadata, requested, projectPath) {
10584
10867
  return requested;
10585
10868
  }
10586
10869
  function loadPrinciples(projectPath) {
10587
- const principlesPath = path55.join(projectPath, "docs", "principles.md");
10588
- return fs37.existsSync(principlesPath) ? fs37.readFileSync(principlesPath, "utf-8") : void 0;
10870
+ const principlesPath = path56.join(projectPath, "docs", "principles.md");
10871
+ return fs38.existsSync(principlesPath) ? fs38.readFileSync(principlesPath, "utf-8") : void 0;
10589
10872
  }
10590
10873
  function readMostRecentFileInDir(dirPath) {
10591
- const files = fs37.readdirSync(dirPath).map((f) => ({ name: f, mtime: fs37.statSync(path55.join(dirPath, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime);
10592
- if (files.length > 0) return fs37.readFileSync(path55.join(dirPath, files[0].name), "utf-8");
10874
+ const files = fs38.readdirSync(dirPath).map((f) => ({ name: f, mtime: fs38.statSync(path56.join(dirPath, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime);
10875
+ if (files.length > 0) return fs38.readFileSync(path56.join(dirPath, files[0].name), "utf-8");
10593
10876
  return void 0;
10594
10877
  }
10595
10878
  function loadPriorState(metadata, projectPath) {
10596
10879
  if (!metadata?.state.persistent || metadata.state.files.length === 0) return void 0;
10597
10880
  for (const stateFilePath of metadata.state.files) {
10598
- const fullPath = path55.join(projectPath, stateFilePath);
10599
- if (!fs37.existsSync(fullPath)) continue;
10600
- const stat = fs37.statSync(fullPath);
10881
+ const fullPath = path56.join(projectPath, stateFilePath);
10882
+ if (!fs38.existsSync(fullPath)) continue;
10883
+ const stat = fs38.statSync(fullPath);
10601
10884
  if (stat.isDirectory()) return readMostRecentFileInDir(fullPath);
10602
- return fs37.readFileSync(fullPath, "utf-8");
10885
+ return fs38.readFileSync(fullPath, "utf-8");
10603
10886
  }
10604
10887
  return void 0;
10605
10888
  }
@@ -10619,9 +10902,9 @@ function resolvePhaseState(metadata, projectPath, phase) {
10619
10902
  }
10620
10903
  function appendProjectState(content, metadata, projectPath, hasPathOpt) {
10621
10904
  if (!metadata?.state.persistent || !hasPathOpt) return content;
10622
- const stateFile = path55.join(projectPath, ".harness", "state.json");
10623
- if (!fs37.existsSync(stateFile)) return content;
10624
- const stateContent = fs37.readFileSync(stateFile, "utf-8");
10905
+ const stateFile = path56.join(projectPath, ".harness", "state.json");
10906
+ if (!fs38.existsSync(stateFile)) return content;
10907
+ const stateContent = fs38.readFileSync(stateFile, "utf-8");
10625
10908
  return content + `
10626
10909
 
10627
10910
  ---
@@ -10633,14 +10916,14 @@ ${stateContent}
10633
10916
  }
10634
10917
  async function runSkill(name, opts) {
10635
10918
  const skillsDir = resolveSkillsDir();
10636
- const skillDir = path55.join(skillsDir, name);
10637
- if (!fs37.existsSync(skillDir)) {
10919
+ const skillDir = path56.join(skillsDir, name);
10920
+ if (!fs38.existsSync(skillDir)) {
10638
10921
  logger.error(`Skill not found: ${name}`);
10639
10922
  process.exit(ExitCode.ERROR);
10640
10923
  return;
10641
10924
  }
10642
10925
  const metadata = loadSkillMetadata(skillDir);
10643
- const projectPath = opts.path ? path55.resolve(opts.path) : process.cwd();
10926
+ const projectPath = opts.path ? path56.resolve(opts.path) : process.cwd();
10644
10927
  const complexity = resolveComplexity(
10645
10928
  metadata,
10646
10929
  opts.complexity ?? "standard",
@@ -10667,14 +10950,14 @@ async function runSkill(name, opts) {
10667
10950
  ...stateWarning !== void 0 && { stateWarning },
10668
10951
  ...opts.party !== void 0 && { party: opts.party }
10669
10952
  });
10670
- const skillMdPath = path55.join(skillDir, "SKILL.md");
10671
- if (!fs37.existsSync(skillMdPath)) {
10953
+ const skillMdPath = path56.join(skillDir, "SKILL.md");
10954
+ if (!fs38.existsSync(skillMdPath)) {
10672
10955
  logger.error(`SKILL.md not found for skill: ${name}`);
10673
10956
  process.exit(ExitCode.ERROR);
10674
10957
  return;
10675
10958
  }
10676
10959
  const content = appendProjectState(
10677
- fs37.readFileSync(skillMdPath, "utf-8"),
10960
+ fs38.readFileSync(skillMdPath, "utf-8"),
10678
10961
  metadata,
10679
10962
  projectPath,
10680
10963
  !!opts.path
@@ -10685,16 +10968,16 @@ async function runSkill(name, opts) {
10685
10968
  process.exit(ExitCode.SUCCESS);
10686
10969
  }
10687
10970
  function createRunCommand3() {
10688
- return new Command89("run").description("Run a skill (outputs SKILL.md content with context preamble)").argument("<name>", "Skill name (e.g., harness-tdd)").option("--path <path>", "Project root path for context injection").option("--complexity <level>", "Rigor level: fast, standard, thorough", "standard").option("--phase <name>", "Start at a specific phase (for re-entry)").option("--party", "Enable multi-perspective evaluation").option(
10971
+ return new Command91("run").description("Run a skill (outputs SKILL.md content with context preamble)").argument("<name>", "Skill name (e.g., harness-tdd)").option("--path <path>", "Project root path for context injection").option("--complexity <level>", "Rigor level: fast, standard, thorough", "standard").option("--phase <name>", "Start at a specific phase (for re-entry)").option("--party", "Enable multi-perspective evaluation").option(
10689
10972
  "--backend <name>",
10690
10973
  "Spec B: one-shot routing override forwarded to the orchestrator as HARNESS_BACKEND_OVERRIDE"
10691
10974
  ).action(async (name, opts) => runSkill(name, opts));
10692
10975
  }
10693
10976
 
10694
10977
  // src/commands/skill/validate.ts
10695
- import { Command as Command90 } from "commander";
10696
- import * as fs38 from "fs";
10697
- import * as path56 from "path";
10978
+ import { Command as Command92 } from "commander";
10979
+ import * as fs39 from "fs";
10980
+ import * as path57 from "path";
10698
10981
  import { parse as parse3 } from "yaml";
10699
10982
  var BEHAVIORAL_REQUIRED_SECTIONS = [
10700
10983
  "## When to Use",
@@ -10706,11 +10989,11 @@ var BEHAVIORAL_REQUIRED_SECTIONS = [
10706
10989
  ];
10707
10990
  var KNOWLEDGE_REQUIRED_SECTIONS = ["## Instructions"];
10708
10991
  function validateSkillMd(name, skillMdPath, skillType, errors) {
10709
- if (!fs38.existsSync(skillMdPath)) {
10992
+ if (!fs39.existsSync(skillMdPath)) {
10710
10993
  errors.push(`${name}: missing SKILL.md`);
10711
10994
  return;
10712
10995
  }
10713
- const mdContent = fs38.readFileSync(skillMdPath, "utf-8");
10996
+ const mdContent = fs39.readFileSync(skillMdPath, "utf-8");
10714
10997
  if (!mdContent.trim().startsWith("# ")) {
10715
10998
  errors.push(`${name}/SKILL.md: must start with an h1 heading`);
10716
10999
  }
@@ -10735,20 +11018,20 @@ function validateSkillMd(name, skillMdPath, skillType, errors) {
10735
11018
  }
10736
11019
  }
10737
11020
  function validateSkillEntry(name, skillsDir, errors) {
10738
- const skillDir = path56.join(skillsDir, name);
10739
- const yamlPath = path56.join(skillDir, "skill.yaml");
10740
- if (!fs38.existsSync(yamlPath)) {
11021
+ const skillDir = path57.join(skillsDir, name);
11022
+ const yamlPath = path57.join(skillDir, "skill.yaml");
11023
+ if (!fs39.existsSync(yamlPath)) {
10741
11024
  errors.push(`${name}: missing skill.yaml`);
10742
11025
  return false;
10743
11026
  }
10744
11027
  try {
10745
- const raw = fs38.readFileSync(yamlPath, "utf-8");
11028
+ const raw = fs39.readFileSync(yamlPath, "utf-8");
10746
11029
  const result = SkillMetadataSchema.safeParse(parse3(raw));
10747
11030
  if (!result.success) {
10748
11031
  errors.push(`${name}/skill.yaml: ${result.error.message}`);
10749
11032
  return false;
10750
11033
  }
10751
- validateSkillMd(name, path56.join(skillDir, "SKILL.md"), result.data.type, errors);
11034
+ validateSkillMd(name, path57.join(skillDir, "SKILL.md"), result.data.type, errors);
10752
11035
  return true;
10753
11036
  } catch (e) {
10754
11037
  errors.push(`${name}: parse error \u2014 ${e instanceof Error ? e.message : String(e)}`);
@@ -10756,15 +11039,15 @@ function validateSkillEntry(name, skillsDir, errors) {
10756
11039
  }
10757
11040
  }
10758
11041
  function createValidateCommand2() {
10759
- return new Command90("validate").description("Validate all skill.yaml files and SKILL.md structure").action(async (_opts, cmd) => {
11042
+ return new Command92("validate").description("Validate all skill.yaml files and SKILL.md structure").action(async (_opts, cmd) => {
10760
11043
  const globalOpts = cmd.optsWithGlobals();
10761
11044
  const skillsDir = resolveSkillsDir();
10762
- if (!fs38.existsSync(skillsDir)) {
11045
+ if (!fs39.existsSync(skillsDir)) {
10763
11046
  logger.info("No skills directory found.");
10764
11047
  process.exit(ExitCode.SUCCESS);
10765
11048
  return;
10766
11049
  }
10767
- const entries = fs38.readdirSync(skillsDir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
11050
+ const entries = fs39.readdirSync(skillsDir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
10768
11051
  const errors = [];
10769
11052
  let validated = 0;
10770
11053
  for (const name of entries) {
@@ -10786,24 +11069,24 @@ function createValidateCommand2() {
10786
11069
  }
10787
11070
 
10788
11071
  // src/commands/skill/info.ts
10789
- import { Command as Command91 } from "commander";
10790
- import * as fs39 from "fs";
10791
- import * as path57 from "path";
11072
+ import { Command as Command93 } from "commander";
11073
+ import * as fs40 from "fs";
11074
+ import * as path58 from "path";
10792
11075
  import { parse as parse4 } from "yaml";
10793
11076
  function loadSkillMetadata2(name) {
10794
11077
  const skillsDir = resolveSkillsDir();
10795
- const skillDir = path57.join(skillsDir, name);
10796
- if (!fs39.existsSync(skillDir)) {
11078
+ const skillDir = path58.join(skillsDir, name);
11079
+ if (!fs40.existsSync(skillDir)) {
10797
11080
  logger.error(`Skill not found: ${name}`);
10798
11081
  return { ok: false, exitCode: ExitCode.ERROR };
10799
11082
  }
10800
- const yamlPath = path57.join(skillDir, "skill.yaml");
10801
- if (!fs39.existsSync(yamlPath)) {
11083
+ const yamlPath = path58.join(skillDir, "skill.yaml");
11084
+ if (!fs40.existsSync(yamlPath)) {
10802
11085
  logger.error(`skill.yaml not found for skill: ${name}`);
10803
11086
  return { ok: false, exitCode: ExitCode.ERROR };
10804
11087
  }
10805
11088
  try {
10806
- const raw = fs39.readFileSync(yamlPath, "utf-8");
11089
+ const raw = fs40.readFileSync(yamlPath, "utf-8");
10807
11090
  const parsed = parse4(raw);
10808
11091
  const result = SkillMetadataSchema.safeParse(parsed);
10809
11092
  if (!result.success) {
@@ -10832,7 +11115,7 @@ function printSkillInfo(skill) {
10832
11115
  console.log(`Persistent: ${skill.state.persistent}`);
10833
11116
  }
10834
11117
  function createInfoCommand() {
10835
- return new Command91("info").description("Show metadata for a skill").argument("<name>", "Skill name (e.g., harness-tdd)").action(async (name, _opts, cmd) => {
11118
+ return new Command93("info").description("Show metadata for a skill").argument("<name>", "Skill name (e.g., harness-tdd)").action(async (name, _opts, cmd) => {
10836
11119
  const globalOpts = cmd.optsWithGlobals();
10837
11120
  const loaded = loadSkillMetadata2(name);
10838
11121
  if (!loaded.ok) {
@@ -10849,7 +11132,7 @@ function createInfoCommand() {
10849
11132
  }
10850
11133
 
10851
11134
  // src/commands/skill/search.ts
10852
- import { Command as Command92 } from "commander";
11135
+ import { Command as Command94 } from "commander";
10853
11136
  async function runSearch(query, opts) {
10854
11137
  const results = await searchNpmRegistry(query, opts.registry);
10855
11138
  return results.filter((r) => {
@@ -10894,15 +11177,15 @@ async function runSearchAction(query, opts, globalOpts) {
10894
11177
  }
10895
11178
  }
10896
11179
  function createSearchCommand2() {
10897
- return new Command92("search").description("Search for community skills on the @harness-skills registry").argument("<query>", "Search query").option("--platform <platform>", "Filter by platform (e.g., claude-code)").option("--trigger <trigger>", "Filter by trigger type (e.g., manual, automatic)").option("--registry <url>", "Use a custom npm registry URL").action(async (query, opts, cmd) => {
11180
+ return new Command94("search").description("Search for community skills on the @harness-skills registry").argument("<query>", "Search query").option("--platform <platform>", "Filter by platform (e.g., claude-code)").option("--trigger <trigger>", "Filter by trigger type (e.g., manual, automatic)").option("--registry <url>", "Use a custom npm registry URL").action(async (query, opts, cmd) => {
10898
11181
  await runSearchAction(query, opts, cmd.optsWithGlobals());
10899
11182
  });
10900
11183
  }
10901
11184
 
10902
11185
  // src/commands/skill/create.ts
10903
- import { Command as Command93 } from "commander";
10904
- import * as path58 from "path";
10905
- import * as fs40 from "fs";
11186
+ import { Command as Command95 } from "commander";
11187
+ import * as path59 from "path";
11188
+ import * as fs41 from "fs";
10906
11189
  import YAML from "yaml";
10907
11190
  var KEBAB_CASE_RE = /^[a-z][a-z0-9]*(-[a-z0-9]+)*$/;
10908
11191
  function buildReadme(name, description) {
@@ -10986,22 +11269,22 @@ function runCreate(name, opts) {
10986
11269
  if (!KEBAB_CASE_RE.test(name)) {
10987
11270
  throw new Error(`Invalid skill name "${name}". Must be kebab-case (e.g., my-skill).`);
10988
11271
  }
10989
- const baseDir = opts.outputDir ?? path58.join(process.cwd(), "agents", "skills", "claude-code");
10990
- const skillDir = path58.join(baseDir, name);
10991
- if (fs40.existsSync(skillDir)) {
11272
+ const baseDir = opts.outputDir ?? path59.join(process.cwd(), "agents", "skills", "claude-code");
11273
+ const skillDir = path59.join(baseDir, name);
11274
+ if (fs41.existsSync(skillDir)) {
10992
11275
  throw new Error(`Skill directory already exists: ${skillDir}`);
10993
11276
  }
10994
- fs40.mkdirSync(skillDir, { recursive: true });
11277
+ fs41.mkdirSync(skillDir, { recursive: true });
10995
11278
  const description = opts.description || `A community skill: ${name}`;
10996
11279
  const skillYaml = buildSkillYaml(name, opts);
10997
- const skillYamlPath = path58.join(skillDir, "skill.yaml");
10998
- fs40.writeFileSync(skillYamlPath, YAML.stringify(skillYaml));
11280
+ const skillYamlPath = path59.join(skillDir, "skill.yaml");
11281
+ fs41.writeFileSync(skillYamlPath, YAML.stringify(skillYaml));
10999
11282
  const skillMd = buildSkillMd(name, description);
11000
- const skillMdPath = path58.join(skillDir, "SKILL.md");
11001
- fs40.writeFileSync(skillMdPath, skillMd);
11283
+ const skillMdPath = path59.join(skillDir, "SKILL.md");
11284
+ fs41.writeFileSync(skillMdPath, skillMd);
11002
11285
  const readme = buildReadme(name, description);
11003
- const readmePath = path58.join(skillDir, "README.md");
11004
- fs40.writeFileSync(readmePath, readme);
11286
+ const readmePath = path59.join(skillDir, "README.md");
11287
+ fs41.writeFileSync(readmePath, readme);
11005
11288
  return {
11006
11289
  name,
11007
11290
  directory: skillDir,
@@ -11015,12 +11298,12 @@ function printCreateResult(name, result) {
11015
11298
  }
11016
11299
  logger.info(`
11017
11300
  Next steps:`);
11018
- logger.info(` 1. Edit ${path58.join(result.directory, "SKILL.md")} with your skill content`);
11301
+ logger.info(` 1. Edit ${path59.join(result.directory, "SKILL.md")} with your skill content`);
11019
11302
  logger.info(` 2. Run: harness skill validate ${name}`);
11020
11303
  logger.info(` 3. Run: harness skills publish`);
11021
11304
  }
11022
11305
  function createCreateCommand() {
11023
- return new Command93("create").description("Scaffold a new community skill").argument("<name>", "Skill name (kebab-case)").option("--description <desc>", "Skill description").option("--type <type>", "Skill type: rigid or flexible", "flexible").option("--platforms <platforms>", "Comma-separated platforms (default: claude-code)").option("--triggers <triggers>", "Comma-separated triggers (default: manual)").option("--output-dir <dir>", "Output directory (default: agents/skills/claude-code/)").action(async (name, opts, cmd) => {
11306
+ return new Command95("create").description("Scaffold a new community skill").argument("<name>", "Skill name (kebab-case)").option("--description <desc>", "Skill description").option("--type <type>", "Skill type: rigid or flexible", "flexible").option("--platforms <platforms>", "Comma-separated platforms (default: claude-code)").option("--triggers <triggers>", "Comma-separated triggers (default: manual)").option("--output-dir <dir>", "Output directory (default: agents/skills/claude-code/)").action(async (name, opts, cmd) => {
11024
11307
  const globalOpts = cmd.optsWithGlobals();
11025
11308
  try {
11026
11309
  const result = runCreate(name, {
@@ -11043,26 +11326,26 @@ function createCreateCommand() {
11043
11326
  }
11044
11327
 
11045
11328
  // src/commands/skill/publish.ts
11046
- import { Command as Command94 } from "commander";
11047
- import * as fs42 from "fs";
11048
- import * as path60 from "path";
11329
+ import { Command as Command96 } from "commander";
11330
+ import * as fs43 from "fs";
11331
+ import * as path61 from "path";
11049
11332
  import { execFileSync as execFileSync6 } from "child_process";
11050
11333
 
11051
11334
  // src/registry/validator.ts
11052
- import * as fs41 from "fs";
11053
- import * as path59 from "path";
11335
+ import * as fs42 from "fs";
11336
+ import * as path60 from "path";
11054
11337
  import { parse as parse5 } from "yaml";
11055
11338
  import semver4 from "semver";
11056
11339
  async function validateForPublish(skillDir, registryUrl) {
11057
11340
  const errors = [];
11058
- const skillYamlPath = path59.join(skillDir, "skill.yaml");
11059
- if (!fs41.existsSync(skillYamlPath)) {
11341
+ const skillYamlPath = path60.join(skillDir, "skill.yaml");
11342
+ if (!fs42.existsSync(skillYamlPath)) {
11060
11343
  errors.push("skill.yaml not found. Create one with: harness skill create <name>");
11061
11344
  return { valid: false, errors };
11062
11345
  }
11063
11346
  let skillMeta;
11064
11347
  try {
11065
- const raw = fs41.readFileSync(skillYamlPath, "utf-8");
11348
+ const raw = fs42.readFileSync(skillYamlPath, "utf-8");
11066
11349
  const parsed = parse5(raw);
11067
11350
  const result = SkillMetadataSchema.safeParse(parsed);
11068
11351
  if (!result.success) {
@@ -11084,11 +11367,11 @@ async function validateForPublish(skillDir, registryUrl) {
11084
11367
  if (!skillMeta.triggers || skillMeta.triggers.length === 0) {
11085
11368
  errors.push("At least one trigger is required. Add triggers to skill.yaml.");
11086
11369
  }
11087
- const skillMdPath = path59.join(skillDir, "SKILL.md");
11088
- if (!fs41.existsSync(skillMdPath)) {
11370
+ const skillMdPath = path60.join(skillDir, "SKILL.md");
11371
+ if (!fs42.existsSync(skillMdPath)) {
11089
11372
  errors.push("SKILL.md not found. Create it with content describing your skill.");
11090
11373
  } else {
11091
- const content = fs41.readFileSync(skillMdPath, "utf-8");
11374
+ const content = fs42.readFileSync(skillMdPath, "utf-8");
11092
11375
  if (!content.includes("## When to Use")) {
11093
11376
  errors.push('SKILL.md must contain a "## When to Use" section.');
11094
11377
  }
@@ -11168,11 +11451,11 @@ ${errorList}`);
11168
11451
  }
11169
11452
  const meta = validation.skillMeta;
11170
11453
  const pkg = derivePackageJson(meta);
11171
- const pkgPath = path60.join(skillDir, "package.json");
11172
- fs42.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + "\n");
11173
- const readmePath = path60.join(skillDir, "README.md");
11174
- if (!fs42.existsSync(readmePath)) {
11175
- const skillMdContent = fs42.readFileSync(path60.join(skillDir, "SKILL.md"), "utf-8");
11454
+ const pkgPath = path61.join(skillDir, "package.json");
11455
+ fs43.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + "\n");
11456
+ const readmePath = path61.join(skillDir, "README.md");
11457
+ if (!fs43.existsSync(readmePath)) {
11458
+ const skillMdContent = fs43.readFileSync(path61.join(skillDir, "SKILL.md"), "utf-8");
11176
11459
  const readme = `# ${pkg.name}
11177
11460
 
11178
11461
  ${meta.description}
@@ -11186,7 +11469,7 @@ harness install ${meta.name}
11186
11469
  ---
11187
11470
 
11188
11471
  ${skillMdContent}`;
11189
- fs42.writeFileSync(readmePath, readme);
11472
+ fs43.writeFileSync(readmePath, readme);
11190
11473
  }
11191
11474
  if (opts.dryRun) {
11192
11475
  return {
@@ -11212,7 +11495,7 @@ ${skillMdContent}`;
11212
11495
  };
11213
11496
  }
11214
11497
  function createPublishCommand() {
11215
- return new Command94("publish").description("Validate and publish a skill to @harness-skills on npm").option("--dry-run", "Run validation and generate package.json without publishing").option("--dir <dir>", "Skill directory (default: current directory)").option("--registry <url>", "Use a custom npm registry URL").action(async (opts, cmd) => {
11498
+ return new Command96("publish").description("Validate and publish a skill to @harness-skills on npm").option("--dry-run", "Run validation and generate package.json without publishing").option("--dir <dir>", "Skill directory (default: current directory)").option("--registry <url>", "Use a custom npm registry URL").action(async (opts, cmd) => {
11216
11499
  const globalOpts = cmd.optsWithGlobals();
11217
11500
  const skillDir = opts.dir || process.cwd();
11218
11501
  try {
@@ -11237,7 +11520,7 @@ function createPublishCommand() {
11237
11520
 
11238
11521
  // src/commands/skill/index.ts
11239
11522
  function createSkillCommand() {
11240
- const command = new Command95("skill").description("Skill management commands");
11523
+ const command = new Command97("skill").description("Skill management commands");
11241
11524
  command.addCommand(createListCommand3());
11242
11525
  command.addCommand(createRunCommand3());
11243
11526
  command.addCommand(createValidateCommand2());
@@ -11250,9 +11533,9 @@ function createSkillCommand() {
11250
11533
 
11251
11534
  // src/commands/snapshot.ts
11252
11535
  init_dist3();
11253
- import { Command as Command96 } from "commander";
11536
+ import { Command as Command98 } from "commander";
11254
11537
  import { execSync as execSync5 } from "child_process";
11255
- import chalk15 from "chalk";
11538
+ import chalk16 from "chalk";
11256
11539
  function getCommitHash3(cwd) {
11257
11540
  try {
11258
11541
  return execSync5("git rev-parse --short HEAD", { cwd, encoding: "utf-8" }).toString().trim();
@@ -11277,9 +11560,9 @@ function formatDelta(delta) {
11277
11560
  function directionSymbol(direction) {
11278
11561
  switch (direction) {
11279
11562
  case "improving":
11280
- return chalk15.green("improving");
11563
+ return chalk16.green("improving");
11281
11564
  case "declining":
11282
- return chalk15.red("declining");
11565
+ return chalk16.red("declining");
11283
11566
  case "stable":
11284
11567
  return "=";
11285
11568
  }
@@ -11432,7 +11715,7 @@ function registerListCommand(parent) {
11432
11715
  });
11433
11716
  }
11434
11717
  function createSnapshotCommand() {
11435
- const command = new Command96("snapshot").description("Architecture timeline snapshot commands");
11718
+ const command = new Command98("snapshot").description("Architecture timeline snapshot commands");
11436
11719
  registerCaptureCommand(command);
11437
11720
  registerTrendsCommand(command);
11438
11721
  registerListCommand(command);
@@ -11440,9 +11723,9 @@ function createSnapshotCommand() {
11440
11723
  }
11441
11724
 
11442
11725
  // src/commands/spec-craft.ts
11443
- import { Command as Command97 } from "commander";
11726
+ import { Command as Command99 } from "commander";
11444
11727
  function createSpecCraftCommand() {
11445
- return new Command97("spec-craft").description(
11728
+ return new Command99("spec-craft").description(
11446
11729
  "LLM-judgment critique of spec quality (proposals + ADRs). Second craft-pipeline ceiling skill; 7 seed rubrics from the spec-quality canon. Per-section critique."
11447
11730
  ).option("-f, --files <files...>", "Optional spec file/glob scope").option("-k, --kinds <kinds...>", "Restrict to proposal / adr (default: both)").option("-s, --sections <names...>", "Restrict to specific canonical section names").option("--max-files <n>", "Cap doc count (default: 50)").option("--max-sections-per-file <n>", "Cap per-doc section critique (default: 10)").action(async (opts, cmd) => {
11448
11731
  const globalOpts = cmd.optsWithGlobals();
@@ -11490,10 +11773,10 @@ function printResult6(result, mode, _formatter) {
11490
11773
  list.push(f);
11491
11774
  byFile.set(f.target.file, list);
11492
11775
  }
11493
- for (const [file, fs47] of byFile) {
11776
+ for (const [file, fs48] of byFile) {
11494
11777
  console.log(`
11495
11778
  ${file}`);
11496
- for (const f of fs47) {
11779
+ for (const f of fs48) {
11497
11780
  console.log(
11498
11781
  ` ${f.code} [${f.tier}/${f.impact}/${f.confidence}] ## ${f.target.section}:${f.target.line}`
11499
11782
  );
@@ -11509,12 +11792,12 @@ ${file}`);
11509
11792
  }
11510
11793
 
11511
11794
  // src/commands/state/index.ts
11512
- import { Command as Command102 } from "commander";
11795
+ import { Command as Command104 } from "commander";
11513
11796
 
11514
11797
  // src/commands/state/show.ts
11515
11798
  init_dist3();
11516
- import { Command as Command98 } from "commander";
11517
- import * as path61 from "path";
11799
+ import { Command as Command100 } from "commander";
11800
+ import * as path62 from "path";
11518
11801
  function printStateText(state, stream) {
11519
11802
  if (stream) console.log(`Stream: ${stream}`);
11520
11803
  console.log(`Schema Version: ${state.schemaVersion}`);
@@ -11538,9 +11821,9 @@ function printStateProgress(progress) {
11538
11821
  }
11539
11822
  }
11540
11823
  function createShowCommand() {
11541
- return new Command98("show").description("Show current project state").option("--path <path>", "Project root path", ".").option("--stream <name>", "Target a specific stream").action(async (opts, cmd) => {
11824
+ return new Command100("show").description("Show current project state").option("--path <path>", "Project root path", ".").option("--stream <name>", "Target a specific stream").action(async (opts, cmd) => {
11542
11825
  const globalOpts = cmd.optsWithGlobals();
11543
- const result = await loadState(path61.resolve(opts.path), opts.stream);
11826
+ const result = await loadState(path62.resolve(opts.path), opts.stream);
11544
11827
  if (!result.ok) {
11545
11828
  logger.error(result.error.message);
11546
11829
  process.exit(ExitCode.ERROR);
@@ -11556,9 +11839,9 @@ function createShowCommand() {
11556
11839
 
11557
11840
  // src/commands/state/reset.ts
11558
11841
  init_dist3();
11559
- import { Command as Command99 } from "commander";
11560
- import * as fs43 from "fs";
11561
- import * as path62 from "path";
11842
+ import { Command as Command101 } from "commander";
11843
+ import * as fs44 from "fs";
11844
+ import * as path63 from "path";
11562
11845
  import * as readline3 from "readline";
11563
11846
  async function resolveStatePath(projectPath, stream) {
11564
11847
  if (stream) {
@@ -11567,9 +11850,9 @@ async function resolveStatePath(projectPath, stream) {
11567
11850
  logger.error(streamResult.error.message);
11568
11851
  process.exit(ExitCode.ERROR);
11569
11852
  }
11570
- return path62.join(streamResult.value, "state.json");
11853
+ return path63.join(streamResult.value, "state.json");
11571
11854
  }
11572
- return path62.join(projectPath, ".harness", "state.json");
11855
+ return path63.join(projectPath, ".harness", "state.json");
11573
11856
  }
11574
11857
  async function confirmReset() {
11575
11858
  const rl = readline3.createInterface({ input: process.stdin, output: process.stdout });
@@ -11580,9 +11863,9 @@ async function confirmReset() {
11580
11863
  return answer.toLowerCase() === "y" || answer.toLowerCase() === "yes";
11581
11864
  }
11582
11865
  async function runReset(opts) {
11583
- const projectPath = path62.resolve(opts.path);
11866
+ const projectPath = path63.resolve(opts.path);
11584
11867
  const statePath = await resolveStatePath(projectPath, opts.stream);
11585
- if (!fs43.existsSync(statePath)) {
11868
+ if (!fs44.existsSync(statePath)) {
11586
11869
  logger.info("No state file found. Nothing to reset.");
11587
11870
  process.exit(ExitCode.SUCCESS);
11588
11871
  }
@@ -11591,7 +11874,7 @@ async function runReset(opts) {
11591
11874
  process.exit(ExitCode.SUCCESS);
11592
11875
  }
11593
11876
  try {
11594
- fs43.unlinkSync(statePath);
11877
+ fs44.unlinkSync(statePath);
11595
11878
  logger.success("Project state reset.");
11596
11879
  } catch (e) {
11597
11880
  logger.error(`Failed to reset state: ${e instanceof Error ? e.message : String(e)}`);
@@ -11600,16 +11883,16 @@ async function runReset(opts) {
11600
11883
  process.exit(ExitCode.SUCCESS);
11601
11884
  }
11602
11885
  function createResetCommand() {
11603
- return new Command99("reset").description("Reset project state (deletes .harness/state.json)").option("--path <path>", "Project root path", ".").option("--stream <name>", "Target a specific stream").option("--yes", "Skip confirmation prompt").action(async (opts) => runReset(opts));
11886
+ return new Command101("reset").description("Reset project state (deletes .harness/state.json)").option("--path <path>", "Project root path", ".").option("--stream <name>", "Target a specific stream").option("--yes", "Skip confirmation prompt").action(async (opts) => runReset(opts));
11604
11887
  }
11605
11888
 
11606
11889
  // src/commands/state/learn.ts
11607
11890
  init_dist3();
11608
- import { Command as Command100 } from "commander";
11609
- import * as path63 from "path";
11891
+ import { Command as Command102 } from "commander";
11892
+ import * as path64 from "path";
11610
11893
  function createLearnCommand() {
11611
- return new Command100("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) => {
11612
- const projectPath = path63.resolve(opts.path);
11894
+ return new Command102("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) => {
11895
+ const projectPath = path64.resolve(opts.path);
11613
11896
  const result = await appendLearning(projectPath, message, void 0, void 0, opts.stream);
11614
11897
  if (!result.ok) {
11615
11898
  logger.error(result.error.message);
@@ -11623,10 +11906,10 @@ function createLearnCommand() {
11623
11906
 
11624
11907
  // src/commands/state/streams.ts
11625
11908
  init_dist3();
11626
- import { Command as Command101 } from "commander";
11627
- import * as path64 from "path";
11909
+ import { Command as Command103 } from "commander";
11910
+ import * as path65 from "path";
11628
11911
  async function runListStreams(opts, globalOpts) {
11629
- const projectPath = path64.resolve(opts.path);
11912
+ const projectPath = path65.resolve(opts.path);
11630
11913
  const indexResult = await loadStreamIndex(projectPath);
11631
11914
  const result = await listStreams(projectPath);
11632
11915
  if (!result.ok) {
@@ -11647,7 +11930,7 @@ async function runListStreams(opts, globalOpts) {
11647
11930
  process.exit(ExitCode.SUCCESS);
11648
11931
  }
11649
11932
  async function runCreateStream(name, opts) {
11650
- const result = await createStream(path64.resolve(opts.path), name, opts.branch);
11933
+ const result = await createStream(path65.resolve(opts.path), name, opts.branch);
11651
11934
  if (!result.ok) {
11652
11935
  logger.error(result.error.message);
11653
11936
  process.exit(ExitCode.ERROR);
@@ -11656,7 +11939,7 @@ async function runCreateStream(name, opts) {
11656
11939
  process.exit(ExitCode.SUCCESS);
11657
11940
  }
11658
11941
  async function runArchiveStream(name, opts) {
11659
- const result = await archiveStream(path64.resolve(opts.path), name);
11942
+ const result = await archiveStream(path65.resolve(opts.path), name);
11660
11943
  if (!result.ok) {
11661
11944
  logger.error(result.error.message);
11662
11945
  process.exit(ExitCode.ERROR);
@@ -11665,7 +11948,7 @@ async function runArchiveStream(name, opts) {
11665
11948
  process.exit(ExitCode.SUCCESS);
11666
11949
  }
11667
11950
  async function runActivateStream(name, opts) {
11668
- const result = await setActiveStream(path64.resolve(opts.path), name);
11951
+ const result = await setActiveStream(path65.resolve(opts.path), name);
11669
11952
  if (!result.ok) {
11670
11953
  logger.error(result.error.message);
11671
11954
  process.exit(ExitCode.ERROR);
@@ -11674,7 +11957,7 @@ async function runActivateStream(name, opts) {
11674
11957
  process.exit(ExitCode.SUCCESS);
11675
11958
  }
11676
11959
  function createStreamsCommand() {
11677
- const command = new Command101("streams").description("Manage state streams");
11960
+ const command = new Command103("streams").description("Manage state streams");
11678
11961
  command.command("list").description("List all known streams").option("--path <path>", "Project root path", ".").action(async (opts, cmd) => runListStreams(opts, cmd.optsWithGlobals()));
11679
11962
  command.command("create <name>").description("Create a new stream").option("--path <path>", "Project root path", ".").option("--branch <branch>", "Associate with a git branch").action(async (name, opts) => runCreateStream(name, opts));
11680
11963
  command.command("archive <name>").description("Archive a stream").option("--path <path>", "Project root path", ".").action(async (name, opts) => runArchiveStream(name, opts));
@@ -11684,7 +11967,7 @@ function createStreamsCommand() {
11684
11967
 
11685
11968
  // src/commands/state/index.ts
11686
11969
  function createStateCommand() {
11687
- const command = new Command102("state").description("Project state management commands");
11970
+ const command = new Command104("state").description("Project state management commands");
11688
11971
  command.addCommand(createShowCommand());
11689
11972
  command.addCommand(createResetCommand());
11690
11973
  command.addCommand(createLearnCommand());
@@ -11693,9 +11976,9 @@ function createStateCommand() {
11693
11976
  }
11694
11977
 
11695
11978
  // src/commands/sync-analyses.ts
11696
- import * as fs44 from "fs";
11697
- import * as path65 from "path";
11698
- import { Command as Command103 } from "commander";
11979
+ import * as fs45 from "fs";
11980
+ import * as path66 from "path";
11981
+ import { Command as Command105 } from "commander";
11699
11982
  init_dist3();
11700
11983
  function isValidRecord(record) {
11701
11984
  return typeof record.issueId === "string" && !!record.issueId && typeof record.identifier === "string" && !!record.identifier && typeof record.analyzedAt === "string" && !/[/\\]/.test(record.issueId);
@@ -11721,7 +12004,7 @@ function extractAnalysisFromComments(comments) {
11721
12004
  return null;
11722
12005
  }
11723
12006
  function bootstrapTrackerCommand2(opts, verb) {
11724
- const projectPath = path65.resolve(opts.dir);
12007
+ const projectPath = path66.resolve(opts.dir);
11725
12008
  const trackerConfig = loadTrackerSyncConfig(projectPath);
11726
12009
  if (!trackerConfig) {
11727
12010
  logger.error(`No tracker config found in harness.config.json. Cannot ${verb}.`);
@@ -11733,8 +12016,8 @@ function bootstrapTrackerCommand2(opts, verb) {
11733
12016
  );
11734
12017
  return null;
11735
12018
  }
11736
- const projectEnvPath = path65.join(projectPath, ".env");
11737
- if (fs44.existsSync(projectEnvPath) && !process.env.GITHUB_TOKEN) {
12019
+ const projectEnvPath = path66.join(projectPath, ".env");
12020
+ if (fs45.existsSync(projectEnvPath) && !process.env.GITHUB_TOKEN) {
11738
12021
  __require("dotenv").config({ path: projectEnvPath });
11739
12022
  }
11740
12023
  const token = process.env.GITHUB_TOKEN;
@@ -11764,13 +12047,13 @@ async function loadRoadmapFeatures(projectPath) {
11764
12047
  }
11765
12048
  return r.value.features.filter((f) => !!f.externalId).map((f) => ({ name: f.name, externalId: f.externalId }));
11766
12049
  }
11767
- const roadmapFile = path65.join(projectPath, "docs", "roadmap.md");
11768
- if (!fs44.existsSync(roadmapFile)) {
12050
+ const roadmapFile = path66.join(projectPath, "docs", "roadmap.md");
12051
+ if (!fs45.existsSync(roadmapFile)) {
11769
12052
  logger.error("No docs/roadmap.md found. Cannot discover features with externalIds.");
11770
12053
  return null;
11771
12054
  }
11772
12055
  const { parseRoadmap: parseRoadmap2 } = (init_dist3(), __toCommonJS(dist_exports));
11773
- const roadmapParsed = parseRoadmap2(fs44.readFileSync(roadmapFile, "utf-8"));
12056
+ const roadmapParsed = parseRoadmap2(fs45.readFileSync(roadmapFile, "utf-8"));
11774
12057
  if (!roadmapParsed.ok) {
11775
12058
  logger.error("Failed to parse docs/roadmap.md");
11776
12059
  return null;
@@ -11821,9 +12104,9 @@ async function runSyncAnalyses(opts) {
11821
12104
  return;
11822
12105
  }
11823
12106
  const { AnalysisArchive, loadPublishedIndex: loadPublishedIndex2, savePublishedIndex: savePublishedIndex2 } = await import("@harness-engineering/orchestrator");
11824
- const { GitHubIssuesSyncAdapter: GitHubIssuesSyncAdapter2 } = await import("./dist-XIJWWQ5N.js");
12107
+ const { GitHubIssuesSyncAdapter: GitHubIssuesSyncAdapter2 } = await import("./dist-72ID44UE.js");
11825
12108
  const adapter = new GitHubIssuesSyncAdapter2({ token, config: trackerConfig });
11826
- const archive = new AnalysisArchive(path65.join(projectPath, ".harness", "analyses"));
12109
+ const archive = new AnalysisArchive(path66.join(projectPath, ".harness", "analyses"));
11827
12110
  const publishedIndex = loadPublishedIndex2(projectPath);
11828
12111
  const { syncedCount, skippedCount, warnCount } = await syncFeatureAnalyses(
11829
12112
  features,
@@ -11843,7 +12126,7 @@ async function runSyncAnalyses(opts) {
11843
12126
  }
11844
12127
  }
11845
12128
  function createSyncAnalysesCommand() {
11846
- const command = new Command103("sync-analyses").description(
12129
+ const command = new Command105("sync-analyses").description(
11847
12130
  "Pull published intelligence analyses from the external issue tracker into the local .harness/analyses/ directory"
11848
12131
  ).option("-d, --dir <path>", "Workspace directory", process.cwd()).action(async (opts) => {
11849
12132
  try {
@@ -11857,8 +12140,8 @@ function createSyncAnalysesCommand() {
11857
12140
  }
11858
12141
 
11859
12142
  // src/commands/sync-main.ts
11860
- import { Command as Command104 } from "commander";
11861
- import * as path66 from "path";
12143
+ import { Command as Command106 } from "commander";
12144
+ import * as path67 from "path";
11862
12145
  import {
11863
12146
  syncMain as defaultSyncMain
11864
12147
  } from "@harness-engineering/orchestrator";
@@ -11888,8 +12171,8 @@ function formatHuman2(r) {
11888
12171
  }
11889
12172
  }
11890
12173
  function createSyncMainCommand() {
11891
- return new Command104("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) => {
11892
- const cwd = path66.resolve(opts.path ?? ".");
12174
+ return new Command106("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) => {
12175
+ const cwd = path67.resolve(opts.path ?? ".");
11893
12176
  const exitCode = await runSyncMain({ cwd, json: Boolean(opts.json) });
11894
12177
  process.exit(exitCode);
11895
12178
  });
@@ -11897,7 +12180,7 @@ function createSyncMainCommand() {
11897
12180
 
11898
12181
  // src/commands/taint.ts
11899
12182
  init_dist3();
11900
- import { Command as Command105 } from "commander";
12183
+ import { Command as Command107 } from "commander";
11901
12184
  function getProjectRoot() {
11902
12185
  return process.cwd();
11903
12186
  }
@@ -11969,28 +12252,28 @@ function registerStatusCommand(taint) {
11969
12252
  });
11970
12253
  }
11971
12254
  function createTaintCommand() {
11972
- const taint = new Command105("taint").description("Manage sentinel session taint state");
12255
+ const taint = new Command107("taint").description("Manage sentinel session taint state");
11973
12256
  registerClearCommand(taint);
11974
12257
  registerStatusCommand(taint);
11975
12258
  return taint;
11976
12259
  }
11977
12260
 
11978
12261
  // src/commands/telemetry/index.ts
11979
- import { Command as Command109 } from "commander";
12262
+ import { Command as Command111 } from "commander";
11980
12263
 
11981
12264
  // src/commands/telemetry/identify.ts
11982
12265
  init_dist3();
11983
- import { Command as Command106 } from "commander";
11984
- import * as fs45 from "fs";
11985
- import * as path67 from "path";
12266
+ import { Command as Command108 } from "commander";
12267
+ import * as fs46 from "fs";
12268
+ import * as path68 from "path";
11986
12269
  function telemetryFilePath(cwd) {
11987
- return path67.join(cwd, ".harness", "telemetry.json");
12270
+ return path68.join(cwd, ".harness", "telemetry.json");
11988
12271
  }
11989
12272
  function writeTelemetryFile(cwd, data) {
11990
12273
  const filePath = telemetryFilePath(cwd);
11991
- const dir = path67.dirname(filePath);
11992
- fs45.mkdirSync(dir, { recursive: true });
11993
- fs45.writeFileSync(filePath, JSON.stringify(data, null, 2) + "\n", "utf-8");
12274
+ const dir = path68.dirname(filePath);
12275
+ fs46.mkdirSync(dir, { recursive: true });
12276
+ fs46.writeFileSync(filePath, JSON.stringify(data, null, 2) + "\n", "utf-8");
11994
12277
  }
11995
12278
  var IDENTITY_FIELDS = ["project", "team", "alias"];
11996
12279
  function applyIdentityFields(opts, identity) {
@@ -12004,7 +12287,7 @@ function printIdentity(identity) {
12004
12287
  }
12005
12288
  }
12006
12289
  function createIdentifyCommand() {
12007
- const cmd = new Command106("identify").description("Set or clear telemetry identity fields in .harness/telemetry.json").option("--project <name>", "Project name").option("--team <name>", "Team name").option("--alias <name>", "User alias").option("--clear", "Remove all identity fields").action((opts) => {
12290
+ const cmd = new Command108("identify").description("Set or clear telemetry identity fields in .harness/telemetry.json").option("--project <name>", "Project name").option("--team <name>", "Team name").option("--alias <name>", "User alias").option("--clear", "Remove all identity fields").action((opts) => {
12008
12291
  const cwd = process.cwd();
12009
12292
  if (opts.clear) {
12010
12293
  writeTelemetryFile(cwd, { identity: {} });
@@ -12029,7 +12312,7 @@ function createIdentifyCommand() {
12029
12312
 
12030
12313
  // src/commands/telemetry/status.ts
12031
12314
  init_dist3();
12032
- import { Command as Command107 } from "commander";
12315
+ import { Command as Command109 } from "commander";
12033
12316
  function gatherEnvOverrides() {
12034
12317
  const overrides = {};
12035
12318
  if (process.env.DO_NOT_TRACK) overrides.DO_NOT_TRACK = process.env.DO_NOT_TRACK;
@@ -12071,7 +12354,7 @@ function printHumanStatus(result) {
12071
12354
  printEnvOverrides(result.envOverrides);
12072
12355
  }
12073
12356
  function createStatusCommand() {
12074
- const cmd = new Command107("status").description("Show current telemetry consent state, install ID, and identity").option("--json", "Output as JSON").action((opts) => {
12357
+ const cmd = new Command109("status").description("Show current telemetry consent state, install ID, and identity").option("--json", "Output as JSON").action((opts) => {
12075
12358
  const cwd = process.cwd();
12076
12359
  const envOverrides = gatherEnvOverrides();
12077
12360
  const consent = resolveConsent(cwd, void 0);
@@ -12104,11 +12387,11 @@ function createStatusCommand() {
12104
12387
 
12105
12388
  // src/commands/telemetry/test.ts
12106
12389
  init_dist3();
12107
- import { Command as Command108 } from "commander";
12390
+ import { Command as Command110 } from "commander";
12108
12391
 
12109
12392
  // src/bin/command-telemetry.ts
12110
- import { existsSync as existsSync42, readFileSync as readFileSync32, mkdirSync as mkdirSync19, appendFileSync, writeFileSync as writeFileSync24 } from "fs";
12111
- import { join as join56, parse as parsePath, resolve as resolve43 } from "path";
12393
+ import { existsSync as existsSync43, readFileSync as readFileSync33, mkdirSync as mkdirSync19, appendFileSync, writeFileSync as writeFileSync25 } from "fs";
12394
+ import { join as join57, parse as parsePath, resolve as resolve43 } from "path";
12112
12395
  import { spawn as spawn2 } from "child_process";
12113
12396
  var POSTHOG_API_KEY = "phc_wNTdCMcfJXZPgdNeDociZW6vwoGGo4nb7vqEfWThFfsG";
12114
12397
  var EXCLUDED_COMMANDS = /* @__PURE__ */ new Set(["help", "completion"]);
@@ -12116,7 +12399,7 @@ function findProjectRoot(cwd) {
12116
12399
  let dir = resolve43(cwd);
12117
12400
  const { root } = parsePath(dir);
12118
12401
  while (dir !== root) {
12119
- if (existsSync42(join56(dir, "harness.config.json"))) return dir;
12402
+ if (existsSync43(join57(dir, "harness.config.json"))) return dir;
12120
12403
  dir = resolve43(dir, "..");
12121
12404
  }
12122
12405
  return cwd;
@@ -12154,7 +12437,7 @@ function resolveCommandName(cmd) {
12154
12437
  }
12155
12438
  function writeCommandRecordSync(cwd, command, duration, outcome) {
12156
12439
  try {
12157
- const metricsDir = join56(cwd, ".harness", "metrics");
12440
+ const metricsDir = join57(cwd, ".harness", "metrics");
12158
12441
  mkdirSync19(metricsDir, { recursive: true });
12159
12442
  const record = {
12160
12443
  skill: command,
@@ -12164,16 +12447,16 @@ function writeCommandRecordSync(cwd, command, duration, outcome) {
12164
12447
  outcome,
12165
12448
  phasesReached: []
12166
12449
  };
12167
- const adoptionFile = join56(metricsDir, "adoption.jsonl");
12450
+ const adoptionFile = join57(metricsDir, "adoption.jsonl");
12168
12451
  appendFileSync(adoptionFile, JSON.stringify(record) + "\n");
12169
12452
  } catch {
12170
12453
  }
12171
12454
  }
12172
12455
  function isTelemetryDisabledByConfig(cwd) {
12173
- const configPath = join56(cwd, "harness.config.json");
12174
- if (!existsSync42(configPath)) return false;
12456
+ const configPath = join57(cwd, "harness.config.json");
12457
+ if (!existsSync43(configPath)) return false;
12175
12458
  try {
12176
- const config = JSON.parse(readFileSync32(configPath, "utf-8"));
12459
+ const config = JSON.parse(readFileSync33(configPath, "utf-8"));
12177
12460
  return config?.telemetry?.enabled === false;
12178
12461
  } catch {
12179
12462
  return false;
@@ -12185,11 +12468,11 @@ function isTelemetryOptedOut(cwd) {
12185
12468
  }
12186
12469
  function flushTelemetryBackground(cwd) {
12187
12470
  try {
12188
- const adoptionFile = join56(cwd, ".harness", "metrics", "adoption.jsonl");
12189
- if (!existsSync42(adoptionFile)) return;
12471
+ const adoptionFile = join57(cwd, ".harness", "metrics", "adoption.jsonl");
12472
+ if (!existsSync43(adoptionFile)) return;
12190
12473
  if (isTelemetryOptedOut(cwd)) return;
12191
- const reporterPath = join56(cwd, ".harness", "hooks", "telemetry-reporter.js");
12192
- if (!existsSync42(reporterPath)) return;
12474
+ const reporterPath = join57(cwd, ".harness", "hooks", "telemetry-reporter.js");
12475
+ if (!existsSync43(reporterPath)) return;
12193
12476
  const child = spawn2(process.execPath, [reporterPath], {
12194
12477
  cwd,
12195
12478
  stdio: ["pipe", "ignore", "ignore"],
@@ -12226,7 +12509,7 @@ function reportTestSuccess(status, distinctId, identity) {
12226
12509
  if (identity.team) logger.info(` team: ${identity.team}`);
12227
12510
  }
12228
12511
  function createTestCommand() {
12229
- return new Command108("test").description("Send a test event to PostHog and verify connectivity").action(async () => {
12512
+ return new Command110("test").description("Send a test event to PostHog and verify connectivity").action(async () => {
12230
12513
  const cwd = process.cwd();
12231
12514
  const consent = resolveConsent(cwd, void 0);
12232
12515
  if (!consent.allowed) {
@@ -12263,7 +12546,7 @@ function createTestCommand() {
12263
12546
 
12264
12547
  // src/commands/telemetry/index.ts
12265
12548
  function createTelemetryCommand() {
12266
- const command = new Command109("telemetry").description("Telemetry identity and status management");
12549
+ const command = new Command111("telemetry").description("Telemetry identity and status management");
12267
12550
  command.addCommand(createIdentifyCommand());
12268
12551
  command.addCommand(createStatusCommand());
12269
12552
  command.addCommand(createTestCommand());
@@ -12271,9 +12554,9 @@ function createTelemetryCommand() {
12271
12554
  }
12272
12555
 
12273
12556
  // src/commands/test-craft.ts
12274
- import { Command as Command110 } from "commander";
12557
+ import { Command as Command112 } from "commander";
12275
12558
  function createTestCraftCommand() {
12276
- return new Command110("test-craft").description(
12559
+ return new Command112("test-craft").description(
12277
12560
  "LLM-judgment critique of test quality across vitest/jest/mocha/playwright. Fourth craft-pipeline ceiling skill. Per-test critique with best-effort source pairing."
12278
12561
  ).option("-f, --files <files...>", "Optional test file/glob scope").option("--frameworks <names...>", "Restrict to: vitest / jest / mocha / playwright").option("--max-files <n>", "Cap test file count (default: 100)").option("--max-tests-per-file <n>", "Cap per-file test critique (default: 20)").option("--no-source-pair", "Skip source-pairing resolution").action(async (opts, cmd) => {
12279
12562
  const globalOpts = cmd.optsWithGlobals();
@@ -12321,10 +12604,10 @@ function printResult7(result, mode, _formatter) {
12321
12604
  list.push(f);
12322
12605
  byFile.set(f.target.file, list);
12323
12606
  }
12324
- for (const [file, fs47] of byFile) {
12607
+ for (const [file, fs48] of byFile) {
12325
12608
  console.log(`
12326
12609
  ${file}`);
12327
- for (const f of fs47) {
12610
+ for (const f of fs48) {
12328
12611
  const nestingStr = f.target.nesting.length > 0 ? f.target.nesting.join(" > ") + " > " : "";
12329
12612
  console.log(
12330
12613
  ` ${f.code} [${f.tier}/${f.impact}/${f.confidence}] ${f.target.framework}:${f.target.line}`
@@ -12343,8 +12626,8 @@ ${file}`);
12343
12626
  }
12344
12627
 
12345
12628
  // src/commands/traceability.ts
12346
- import { Command as Command111 } from "commander";
12347
- import chalk16 from "chalk";
12629
+ import { Command as Command113 } from "commander";
12630
+ import chalk17 from "chalk";
12348
12631
  function confidenceLabel(maxConfidence) {
12349
12632
  if (maxConfidence >= 0.8) return "explicit";
12350
12633
  if (maxConfidence > 0) return "inferred";
@@ -12353,13 +12636,13 @@ function confidenceLabel(maxConfidence) {
12353
12636
  function statusIcon(status) {
12354
12637
  switch (status) {
12355
12638
  case "full":
12356
- return chalk16.green("\u2713 full");
12639
+ return chalk17.green("\u2713 full");
12357
12640
  case "code-only":
12358
- return chalk16.yellow("\u25D0 code-only");
12641
+ return chalk17.yellow("\u25D0 code-only");
12359
12642
  case "test-only":
12360
- return chalk16.yellow("\u25D0 test-only");
12643
+ return chalk17.yellow("\u25D0 test-only");
12361
12644
  case "none":
12362
- return chalk16.red("\u2717 none");
12645
+ return chalk17.red("\u2717 none");
12363
12646
  default:
12364
12647
  return status;
12365
12648
  }
@@ -12406,14 +12689,14 @@ function handleEmptyResults(mode) {
12406
12689
  }
12407
12690
  function printResultTable(result, mode) {
12408
12691
  const specLabel = result.specPath || result.featureName || "Unknown";
12409
- console.log(` ${chalk16.cyan(specLabel)} ${chalk16.dim(`(${result.summary.total} requirements)`)}`);
12692
+ console.log(` ${chalk17.cyan(specLabel)} ${chalk17.dim(`(${result.summary.total} requirements)`)}`);
12410
12693
  console.log("");
12411
12694
  const numWidth = 4;
12412
12695
  const nameWidth = mode === OutputMode.VERBOSE ? 44 : 36;
12413
12696
  const codeWidth = 6;
12414
12697
  const testWidth = 7;
12415
12698
  const confWidth = 12;
12416
- const header = chalk16.dim(
12699
+ const header = chalk17.dim(
12417
12700
  ` ${pad("#", numWidth)}${pad("Requirement", nameWidth)}${pad("Code", codeWidth)}${pad("Tests", testWidth)}${pad("Confidence", confWidth)}Status`
12418
12701
  );
12419
12702
  console.log(header);
@@ -12442,10 +12725,10 @@ function printRequirementRows(requirements, mode, cols) {
12442
12725
  );
12443
12726
  if (mode === OutputMode.VERBOSE) {
12444
12727
  for (const f of req.codeFiles) {
12445
- console.log(chalk16.dim(` code: ${f.path} (${f.method})`));
12728
+ console.log(chalk17.dim(` code: ${f.path} (${f.method})`));
12446
12729
  }
12447
12730
  for (const f of req.testFiles) {
12448
- console.log(chalk16.dim(` test: ${f.path} (${f.method})`));
12731
+ console.log(chalk17.dim(` test: ${f.path} (${f.method})`));
12449
12732
  }
12450
12733
  }
12451
12734
  }
@@ -12456,7 +12739,7 @@ function printCoverageSummary(summary) {
12456
12739
  const codePct = s.total > 0 ? Math.round(s.withCode / s.total * 100) : 0;
12457
12740
  const testPct = s.total > 0 ? Math.round(s.withTests / s.total * 100) : 0;
12458
12741
  console.log(
12459
- ` ${chalk16.bold("Coverage:")} ${fullyPct}% fully traced (${s.fullyTraced}/${s.total}), ${codePct}% with code (${s.withCode}/${s.total}), ${testPct}% with tests (${s.withTests}/${s.total})`
12742
+ ` ${chalk17.bold("Coverage:")} ${fullyPct}% fully traced (${s.fullyTraced}/${s.total}), ${codePct}% with code (${s.withCode}/${s.total}), ${testPct}% with tests (${s.withTests}/${s.total})`
12460
12743
  );
12461
12744
  }
12462
12745
  async function runTraceability(options) {
@@ -12472,14 +12755,14 @@ async function runTraceability(options) {
12472
12755
  console.log(JSON.stringify(results, null, 2));
12473
12756
  } else {
12474
12757
  console.log("");
12475
- console.log(chalk16.bold("Spec-to-Implementation Traceability"));
12758
+ console.log(chalk17.bold("Spec-to-Implementation Traceability"));
12476
12759
  console.log("");
12477
12760
  for (const result of results) printResultTable(result, mode);
12478
12761
  }
12479
12762
  process.exit(ExitCode.SUCCESS);
12480
12763
  }
12481
12764
  function createTraceabilityCommand() {
12482
- return new Command111("traceability").description("Show spec-to-implementation traceability from the knowledge graph").option("--spec <path>", "Filter by spec file path").option("--feature <name>", "Filter by feature name").action(async (opts, cmd) => {
12765
+ return new Command113("traceability").description("Show spec-to-implementation traceability from the knowledge graph").option("--spec <path>", "Filter by spec file path").option("--feature <name>", "Filter by feature name").action(async (opts, cmd) => {
12483
12766
  const globalOpts = cmd.optsWithGlobals();
12484
12767
  await runTraceability({
12485
12768
  spec: opts.spec,
@@ -12492,15 +12775,15 @@ function createTraceabilityCommand() {
12492
12775
  }
12493
12776
 
12494
12777
  // src/commands/uninstall.ts
12495
- import * as path68 from "path";
12496
- import { Command as Command112 } from "commander";
12778
+ import * as path69 from "path";
12779
+ import { Command as Command114 } from "commander";
12497
12780
  async function runUninstall(skillName, options) {
12498
12781
  const packageName = resolvePackageName(skillName);
12499
12782
  const shortName = extractSkillName(packageName);
12500
12783
  const globalDir = resolveGlobalSkillsDir();
12501
- const skillsDir = path68.dirname(globalDir);
12502
- const communityBase = path68.join(skillsDir, "community");
12503
- const lockfilePath = path68.join(communityBase, "skills-lock.json");
12784
+ const skillsDir = path69.dirname(globalDir);
12785
+ const communityBase = path69.join(skillsDir, "community");
12786
+ const lockfilePath = path69.join(communityBase, "skills-lock.json");
12504
12787
  const lockfile = readLockfile2(lockfilePath);
12505
12788
  const entry = lockfile.skills[packageName];
12506
12789
  if (!entry) {
@@ -12530,7 +12813,7 @@ async function runUninstall(skillName, options) {
12530
12813
  return result;
12531
12814
  }
12532
12815
  function createUninstallCommand() {
12533
- const cmd = new Command112("uninstall");
12816
+ const cmd = new Command114("uninstall");
12534
12817
  cmd.description("Uninstall a community skill").argument("<skill>", "Skill name or @harness-skills/scoped package name").option("--force", "Remove even if other skills depend on this one").action(async (skill, opts) => {
12535
12818
  try {
12536
12819
  const result = await runUninstall(skill, opts);
@@ -12550,9 +12833,9 @@ function createUninstallCommand() {
12550
12833
 
12551
12834
  // src/commands/uninstall-constraints.ts
12552
12835
  init_dist3();
12553
- import * as fs46 from "fs/promises";
12554
- import * as path69 from "path";
12555
- import { Command as Command113 } from "commander";
12836
+ import * as fs47 from "fs/promises";
12837
+ import * as path70 from "path";
12838
+ import { Command as Command115 } from "commander";
12556
12839
  async function runUninstallConstraints(options) {
12557
12840
  const { packageName, configPath, lockfilePath } = options;
12558
12841
  const lockfileResult = await readLockfile(lockfilePath);
@@ -12572,7 +12855,7 @@ async function runUninstallConstraints(options) {
12572
12855
  }
12573
12856
  let localConfig;
12574
12857
  try {
12575
- const raw = await fs46.readFile(configPath, "utf-8");
12858
+ const raw = await fs47.readFile(configPath, "utf-8");
12576
12859
  localConfig = JSON.parse(raw);
12577
12860
  } catch (err) {
12578
12861
  return {
@@ -12609,11 +12892,11 @@ async function runUninstallConstraints(options) {
12609
12892
  };
12610
12893
  }
12611
12894
  function createUninstallConstraintsCommand() {
12612
- const cmd = new Command113("uninstall-constraints");
12895
+ const cmd = new Command115("uninstall-constraints");
12613
12896
  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) => {
12614
12897
  let configPath;
12615
12898
  if (opts.config) {
12616
- configPath = path69.resolve(opts.config);
12899
+ configPath = path70.resolve(opts.config);
12617
12900
  } else {
12618
12901
  const found = findConfigFile();
12619
12902
  if (!found.ok) {
@@ -12622,8 +12905,8 @@ function createUninstallConstraintsCommand() {
12622
12905
  }
12623
12906
  configPath = found.value;
12624
12907
  }
12625
- const projectRoot2 = path69.dirname(configPath);
12626
- const lockfilePath = path69.join(projectRoot2, ".harness", "constraints.lock.json");
12908
+ const projectRoot2 = path70.dirname(configPath);
12909
+ const lockfilePath = path70.join(projectRoot2, ".harness", "constraints.lock.json");
12627
12910
  const result = await runUninstallConstraints({
12628
12911
  packageName: name,
12629
12912
  configPath,
@@ -12649,13 +12932,13 @@ function createUninstallConstraintsCommand() {
12649
12932
 
12650
12933
  // src/commands/update.ts
12651
12934
  init_dist3();
12652
- import { Command as Command114 } from "commander";
12935
+ import { Command as Command116 } from "commander";
12653
12936
  import { execFile, execFileSync as execFileSync7 } from "child_process";
12654
- import { realpathSync, existsSync as existsSync43, readFileSync as readFileSync33 } from "fs";
12655
- import { dirname as dirname22, join as join59 } from "path";
12937
+ import { realpathSync, existsSync as existsSync44, readFileSync as readFileSync34 } from "fs";
12938
+ import { dirname as dirname23, join as join60 } from "path";
12656
12939
  import { promisify } from "util";
12657
12940
  import readline4 from "readline";
12658
- import chalk17 from "chalk";
12941
+ import chalk18 from "chalk";
12659
12942
  var CLI_PACKAGE = "@harness-engineering/cli";
12660
12943
  function detectPackageManagerFromPath(resolvedPath) {
12661
12944
  const normalizedBin = resolvedPath.replace(/\\/g, "/");
@@ -12741,16 +13024,16 @@ function prompt3(question) {
12741
13024
  });
12742
13025
  }
12743
13026
  function findPackageDir(resolvedBin) {
12744
- let dir = dirname22(resolvedBin);
13027
+ let dir = dirname23(resolvedBin);
12745
13028
  for (let i = 0; i < 6; i++) {
12746
- if (existsSync43(join59(dir, "package.json"))) {
13029
+ if (existsSync44(join60(dir, "package.json"))) {
12747
13030
  try {
12748
- const pkg = JSON.parse(readFileSync33(join59(dir, "package.json"), "utf-8"));
13031
+ const pkg = JSON.parse(readFileSync34(join60(dir, "package.json"), "utf-8"));
12749
13032
  if (pkg?.name === CLI_PACKAGE) return dir;
12750
13033
  } catch {
12751
13034
  }
12752
13035
  }
12753
- const parent = dirname22(dir);
13036
+ const parent = dirname23(dir);
12754
13037
  if (parent === dir) return null;
12755
13038
  dir = parent;
12756
13039
  }
@@ -12790,7 +13073,7 @@ function findAllInstalls() {
12790
13073
  if (!packageDir) continue;
12791
13074
  let version = null;
12792
13075
  try {
12793
- const pkg = JSON.parse(readFileSync33(join59(packageDir, "package.json"), "utf-8"));
13076
+ const pkg = JSON.parse(readFileSync34(join60(packageDir, "package.json"), "utf-8"));
12794
13077
  if (typeof pkg?.version === "string") version = pkg.version;
12795
13078
  } catch {
12796
13079
  }
@@ -12824,7 +13107,7 @@ async function offerCleanupOfOtherInstalls(activeDir) {
12824
13107
  `Found ${installs.length} harness installs on PATH. Only the active one was updated.`
12825
13108
  );
12826
13109
  for (const install of installs) {
12827
- const tag = install.packageDir === activeDir ? chalk17.green(" (active, just updated)") : chalk17.yellow(" (stale)");
13110
+ const tag = install.packageDir === activeDir ? chalk18.green(" (active, just updated)") : chalk18.yellow(" (stale)");
12828
13111
  const versionStr = install.version ? `v${install.version}` : "unknown";
12829
13112
  console.log(` ${install.binPath} -> ${versionStr}${tag}`);
12830
13113
  }
@@ -12832,7 +13115,7 @@ async function offerCleanupOfOtherInstalls(activeDir) {
12832
13115
  const commands = others.map((install) => buildUninstallCommand(install));
12833
13116
  console.log("Cleanup commands:");
12834
13117
  for (const { display } of commands) {
12835
- console.log(` ${chalk17.cyan(display)}`);
13118
+ console.log(` ${chalk18.cyan(display)}`);
12836
13119
  }
12837
13120
  console.log("");
12838
13121
  const answer = await prompt3(`Run these now to remove stale installs? (y/N) `);
@@ -12840,7 +13123,7 @@ async function offerCleanupOfOtherInstalls(activeDir) {
12840
13123
  for (const cmd of commands) {
12841
13124
  if (!cmd.runnable) {
12842
13125
  logger.warn(`Skipped ${cmd.install.binPath} (no automatic uninstall for this layout).`);
12843
- console.log(` Run manually: ${chalk17.cyan(cmd.display)}`);
13126
+ console.log(` Run manually: ${chalk18.cyan(cmd.display)}`);
12844
13127
  continue;
12845
13128
  }
12846
13129
  try {
@@ -12848,7 +13131,7 @@ async function offerCleanupOfOtherInstalls(activeDir) {
12848
13131
  execFileSync7(cmd.bin, cmd.args, { stdio: "inherit", timeout: 12e4 });
12849
13132
  } catch {
12850
13133
  logger.warn(`Uninstall failed for ${cmd.install.binPath}.`);
12851
- console.log(` Run manually: ${chalk17.cyan(cmd.display)}`);
13134
+ console.log(` Run manually: ${chalk18.cyan(cmd.display)}`);
12852
13135
  }
12853
13136
  }
12854
13137
  }
@@ -12883,12 +13166,12 @@ async function ensureTelemetryIfNeeded() {
12883
13166
  }
12884
13167
  function refreshHooks() {
12885
13168
  const cwd = process.cwd();
12886
- const configPath = join59(cwd, "harness.config.json");
12887
- if (!existsSync43(configPath)) return;
13169
+ const configPath = join60(cwd, "harness.config.json");
13170
+ if (!existsSync44(configPath)) return;
12888
13171
  let profile = "standard";
12889
- const profilePath = join59(cwd, ".harness", "hooks", "profile.json");
13172
+ const profilePath = join60(cwd, ".harness", "hooks", "profile.json");
12890
13173
  try {
12891
- const data = JSON.parse(readFileSync33(profilePath, "utf-8"));
13174
+ const data = JSON.parse(readFileSync34(profilePath, "utf-8"));
12892
13175
  if (data.profile && ["minimal", "standard", "strict"].includes(data.profile)) {
12893
13176
  profile = data.profile;
12894
13177
  }
@@ -12908,7 +13191,7 @@ function runLocalGraphScan() {
12908
13191
  execFileSync7("harness", ["graph", "scan", "."], { stdio: "inherit" });
12909
13192
  } catch {
12910
13193
  logger.warn("Graph scan failed. Run manually:");
12911
- console.log(` ${chalk17.cyan("harness graph scan .")}`);
13194
+ console.log(` ${chalk18.cyan("harness graph scan .")}`);
12912
13195
  }
12913
13196
  }
12914
13197
  async function offerRegeneration() {
@@ -12925,7 +13208,7 @@ async function offerRegeneration() {
12925
13208
  });
12926
13209
  } catch {
12927
13210
  logger.warn("Generation failed. Run manually:");
12928
- console.log(` ${chalk17.cyan(`harness generate${isGlobal ? " --global" : ""}`)}`);
13211
+ console.log(` ${chalk18.cyan(`harness generate${isGlobal ? " --global" : ""}`)}`);
12929
13212
  }
12930
13213
  if (!isGlobal) {
12931
13214
  runLocalGraphScan();
@@ -12989,8 +13272,8 @@ async function runUpdateAction(opts, globalOpts) {
12989
13272
  console.log("");
12990
13273
  for (const { pkg, current, latest } of outdated) {
12991
13274
  const shortName = pkg.replace("@harness-engineering/", "");
12992
- const currentStr = current ? chalk17.dim(`v${current}`) : chalk17.dim("not installed");
12993
- logger.info(`${shortName}: ${currentStr} \u2192 ${chalk17.green(`v${latest}`)}`);
13275
+ const currentStr = current ? chalk18.dim(`v${current}`) : chalk18.dim("not installed");
13276
+ logger.info(`${shortName}: ${currentStr} \u2192 ${chalk18.green(`v${latest}`)}`);
12994
13277
  }
12995
13278
  console.log("");
12996
13279
  }
@@ -13007,7 +13290,7 @@ async function runUpdateAction(opts, globalOpts) {
13007
13290
  } catch {
13008
13291
  console.log("");
13009
13292
  logger.error("Update failed. You can try manually:");
13010
- console.log(` ${chalk17.cyan(installCmd)}`);
13293
+ console.log(` ${chalk18.cyan(installCmd)}`);
13011
13294
  process.exit(ExitCode.ERROR);
13012
13295
  }
13013
13296
  refreshHooks();
@@ -13017,7 +13300,7 @@ async function runUpdateAction(opts, globalOpts) {
13017
13300
  process.exit(ExitCode.SUCCESS);
13018
13301
  }
13019
13302
  function createUpdateCommand() {
13020
- return new Command114("update").description("Update all @harness-engineering packages to the latest version").option("--version <semver>", "Pin @harness-engineering/cli to a specific version").option("--force", "Force update even if versions match").option(
13303
+ return new Command116("update").description("Update all @harness-engineering packages to the latest version").option("--version <semver>", "Pin @harness-engineering/cli to a specific version").option("--force", "Force update even if versions match").option(
13021
13304
  "--regenerate",
13022
13305
  "Only regenerate slash commands and agent definitions (skip package updates)"
13023
13306
  ).action(async (opts, cmd) => {
@@ -13027,9 +13310,9 @@ function createUpdateCommand() {
13027
13310
  }
13028
13311
 
13029
13312
  // src/commands/usage.ts
13030
- import { Command as Command115 } from "commander";
13313
+ import { Command as Command117 } from "commander";
13031
13314
  async function loadAndPriceRecords(cwd, includeClaudeSessions = false) {
13032
- const { readCostRecords, loadPricingData, calculateCost, parseCCRecords } = await import("./dist-XIJWWQ5N.js");
13315
+ const { readCostRecords, loadPricingData, calculateCost, parseCCRecords } = await import("./dist-72ID44UE.js");
13033
13316
  const records = readCostRecords(cwd);
13034
13317
  if (includeClaudeSessions) {
13035
13318
  const ccRecords = parseCCRecords();
@@ -13122,7 +13405,7 @@ function registerDailyCommand(usage) {
13122
13405
  else logger.info("No usage data found. Run some harness sessions first.");
13123
13406
  return;
13124
13407
  }
13125
- const { aggregateByDay } = await import("./dist-XIJWWQ5N.js");
13408
+ const { aggregateByDay } = await import("./dist-72ID44UE.js");
13126
13409
  const limited = aggregateByDay(records).slice(0, days);
13127
13410
  if (globalOpts.json) {
13128
13411
  console.log(
@@ -13151,7 +13434,7 @@ function registerSessionsCommand(usage) {
13151
13434
  }
13152
13435
  return;
13153
13436
  }
13154
- const { aggregateBySession } = await import("./dist-XIJWWQ5N.js");
13437
+ const { aggregateBySession } = await import("./dist-72ID44UE.js");
13155
13438
  const sessionData = aggregateBySession(records);
13156
13439
  const limited = sessionData.slice(0, limit);
13157
13440
  if (globalOpts.json) {
@@ -13231,7 +13514,7 @@ function registerSessionCommand(usage) {
13231
13514
  cwd,
13232
13515
  globalOpts.includeClaudeSessions
13233
13516
  );
13234
- const { aggregateBySession } = await import("./dist-XIJWWQ5N.js");
13517
+ const { aggregateBySession } = await import("./dist-72ID44UE.js");
13235
13518
  const sessionData = aggregateBySession(records);
13236
13519
  const match = sessionData.find((s) => s.sessionId === id);
13237
13520
  if (!match) {
@@ -13266,7 +13549,7 @@ function registerLatestCommand(usage) {
13266
13549
  }
13267
13550
  return;
13268
13551
  }
13269
- const { aggregateBySession } = await import("./dist-XIJWWQ5N.js");
13552
+ const { aggregateBySession } = await import("./dist-72ID44UE.js");
13270
13553
  const sessionData = aggregateBySession(records);
13271
13554
  const latest = sessionData[0];
13272
13555
  if (!latest) {
@@ -13292,7 +13575,7 @@ function registerLatestCommand(usage) {
13292
13575
  });
13293
13576
  }
13294
13577
  function createUsageCommand() {
13295
- const usage = new Command115("usage").description("Token usage and cost tracking");
13578
+ const usage = new Command117("usage").description("Token usage and cost tracking");
13296
13579
  usage.option(
13297
13580
  "--include-claude-sessions",
13298
13581
  "Include Claude Code session data from ~/.claude/projects/"
@@ -13307,15 +13590,15 @@ function createUsageCommand() {
13307
13590
  // src/commands/validate.ts
13308
13591
  init_dist3();
13309
13592
  init_dist3();
13310
- import { Command as Command116 } from "commander";
13311
- import * as path70 from "path";
13593
+ import { Command as Command118 } from "commander";
13594
+ import * as path71 from "path";
13312
13595
  async function runValidate(options) {
13313
13596
  const configResult = resolveConfig(options.configPath);
13314
13597
  if (!configResult.ok) {
13315
13598
  return configResult;
13316
13599
  }
13317
13600
  const config = configResult.value;
13318
- const cwd = options.cwd ?? (options.configPath ? path70.dirname(path70.resolve(options.configPath)) : process.cwd());
13601
+ const cwd = options.cwd ?? (options.configPath ? path71.dirname(path71.resolve(options.configPath)) : process.cwd());
13319
13602
  const result = {
13320
13603
  valid: true,
13321
13604
  checks: {
@@ -13325,7 +13608,7 @@ async function runValidate(options) {
13325
13608
  },
13326
13609
  issues: []
13327
13610
  };
13328
- const agentsMapPath = path70.resolve(cwd, config.agentsMapPath);
13611
+ const agentsMapPath = path71.resolve(cwd, config.agentsMapPath);
13329
13612
  const agentsResult = await validateAgentsMap(agentsMapPath);
13330
13613
  if (agentsResult.ok) {
13331
13614
  result.checks.agentsMap = true;
@@ -13531,11 +13814,11 @@ function resolveValidateMode(globalOpts) {
13531
13814
  return OutputMode.TEXT;
13532
13815
  }
13533
13816
  async function printCrossCheckWarnings(mode) {
13534
- const { runCrossCheck: runCrossCheck2 } = await import("./validate-cross-check-SNE3SQOB.js");
13817
+ const { runCrossCheck: runCrossCheck2 } = await import("./validate-cross-check-AUUZFNVL.js");
13535
13818
  const cwd = process.cwd();
13536
13819
  const crossResult = await runCrossCheck2({
13537
- specsDir: path70.join(cwd, "docs", "specs"),
13538
- plansDir: path70.join(cwd, "docs", "plans"),
13820
+ specsDir: path71.join(cwd, "docs", "specs"),
13821
+ plansDir: path71.join(cwd, "docs", "plans"),
13539
13822
  projectPath: cwd
13540
13823
  });
13541
13824
  if (!crossResult.ok || crossResult.value.warnings === 0) return;
@@ -13547,7 +13830,7 @@ async function printCrossCheckWarnings(mode) {
13547
13830
  ${crossResult.value.warnings} warnings`);
13548
13831
  }
13549
13832
  function createValidateCommand3() {
13550
- const command = new Command116("validate").description("Run all validation checks").option("--cross-check", "Run cross-artifact consistency validation").option(
13833
+ const command = new Command118("validate").description("Run all validation checks").option("--cross-check", "Run cross-artifact consistency validation").option(
13551
13834
  "--agent-configs",
13552
13835
  "Validate agent configs (CLAUDE.md, hooks, skills) via agnix or built-in fallback rules"
13553
13836
  ).option("--strict", "Treat warnings as errors (applies to --agent-configs)").option("--agnix-bin <path>", "Override the agnix binary path discovered on PATH").action(async (opts, cmd) => runValidateAction(opts, cmd.optsWithGlobals()));
@@ -13596,7 +13879,7 @@ Agent configs checked via ${engineLabel}${note}`);
13596
13879
 
13597
13880
  // src/commands/verify.ts
13598
13881
  init_dist3();
13599
- import { Command as Command117 } from "commander";
13882
+ import { Command as Command119 } from "commander";
13600
13883
  import { execSync as execSync6 } from "child_process";
13601
13884
  function loadBranchingConfig(configPath) {
13602
13885
  const shouldLoad = configPath !== void 0 || findConfigFile().ok;
@@ -13659,7 +13942,7 @@ async function runVerify(options) {
13659
13942
  process.exit(ExitCode.VALIDATION_FAILED);
13660
13943
  }
13661
13944
  function createVerifyCommand() {
13662
- return new Command117("verify").description(
13945
+ return new Command119("verify").description(
13663
13946
  "Verify project conventions (currently: branch naming). Works with or without a harness.config.json."
13664
13947
  ).option(
13665
13948
  "--branch <name>",
@@ -13722,6 +14005,7 @@ var commandCreators = [
13722
14005
  createMcpCommand,
13723
14006
  createMcpGuardCommand,
13724
14007
  createMigrateCommand,
14008
+ createModelsCommand,
13725
14009
  createNamingCraftCommand,
13726
14010
  createNotificationsCommand,
13727
14011
  createOrchestratorCommand,
@@ -13762,7 +14046,7 @@ var commandCreators = [
13762
14046
 
13763
14047
  // src/index.ts
13764
14048
  function createProgram() {
13765
- const program = new Command118();
14049
+ const program = new Command120();
13766
14050
  program.name("harness").description("CLI for Harness Engineering toolkit").version(CLI_VERSION).option("-c, --config <path>", "Path to config file").option("--json", "Output as JSON").option("--verbose", "Verbose output").option("--quiet", "Minimal output");
13767
14051
  for (const creator of commandCreators) {
13768
14052
  program.addCommand(creator());