@harness-engineering/cli 4.3.3 → 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/dist/agents/skills/claude-code/harness-brainstorming/SKILL.md +3 -1
  2. package/dist/agents/skills/claude-code/harness-roadmap-pilot/SKILL.md +5 -0
  3. package/dist/agents/skills/claude-code/harness-rollback/SKILL.md +124 -0
  4. package/dist/agents/skills/claude-code/harness-rollback/skill.yaml +52 -0
  5. package/dist/agents/skills/claude-code/product-requirements/SKILL.md +150 -0
  6. package/dist/agents/skills/claude-code/product-requirements/skill.yaml +70 -0
  7. package/dist/agents/skills/codex/harness-brainstorming/SKILL.md +3 -1
  8. package/dist/agents/skills/codex/harness-roadmap-pilot/SKILL.md +5 -0
  9. package/dist/agents/skills/codex/harness-rollback/SKILL.md +124 -0
  10. package/dist/agents/skills/codex/harness-rollback/skill.yaml +52 -0
  11. package/dist/agents/skills/codex/product-requirements/SKILL.md +150 -0
  12. package/dist/agents/skills/codex/product-requirements/skill.yaml +70 -0
  13. package/dist/agents/skills/cursor/harness-brainstorming/SKILL.md +3 -1
  14. package/dist/agents/skills/cursor/harness-roadmap-pilot/SKILL.md +5 -0
  15. package/dist/agents/skills/cursor/harness-rollback/SKILL.md +124 -0
  16. package/dist/agents/skills/cursor/harness-rollback/skill.yaml +52 -0
  17. package/dist/agents/skills/cursor/product-requirements/SKILL.md +150 -0
  18. package/dist/agents/skills/cursor/product-requirements/skill.yaml +70 -0
  19. package/dist/agents/skills/gemini-cli/harness-brainstorming/SKILL.md +3 -1
  20. package/dist/agents/skills/gemini-cli/harness-roadmap-pilot/SKILL.md +5 -0
  21. package/dist/agents/skills/gemini-cli/harness-rollback/SKILL.md +124 -0
  22. package/dist/agents/skills/gemini-cli/harness-rollback/skill.yaml +52 -0
  23. package/dist/agents/skills/gemini-cli/product-requirements/SKILL.md +150 -0
  24. package/dist/agents/skills/gemini-cli/product-requirements/skill.yaml +70 -0
  25. package/dist/{agents-md-N4ULMUAK.js → agents-md-OTKZE5HH.js} +4 -4
  26. package/dist/{analyzer-XRCV63KC-WGRHW2ZM.js → analyzer-XRCV63KC-FALMS3MO.js} +2 -2
  27. package/dist/{architecture-OIMIBDJC.js → architecture-3VYDN7MQ.js} +5 -5
  28. package/dist/{assess-project-ITSB6W4L.js → assess-project-27X2FSZZ.js} +1 -1
  29. package/dist/bin/harness-mcp.js +15 -15
  30. package/dist/bin/harness.js +25 -25
  31. package/dist/{check-phase-gate-GN4X7HT6.js → check-phase-gate-IXLFZ6YH.js} +5 -5
  32. package/dist/{chunk-MEDRUIRO.js → chunk-354MCPT3.js} +3 -3
  33. package/dist/{chunk-5BUHPOCP.js → chunk-3H7JA24B.js} +7 -7
  34. package/dist/{chunk-PT65VY4S.js → chunk-3MKQKNY3.js} +6 -6
  35. package/dist/{chunk-LP764MGR.js → chunk-6Y6M3AZA.js} +3 -3
  36. package/dist/{chunk-D7A5JR7M.js → chunk-BMNHLKBA.js} +2 -2
  37. package/dist/{chunk-CRHQYBDA.js → chunk-CTMHHMHQ.js} +101 -4
  38. package/dist/{chunk-MIZQY35D.js → chunk-D7QXGI6E.js} +2 -2
  39. package/dist/{chunk-F3GNBRGL.js → chunk-EFWRZHZ7.js} +101 -97
  40. package/dist/{chunk-LTYVAKWK.js → chunk-IOJGLIEQ.js} +20 -2
  41. package/dist/{chunk-CMU4DNLY.js → chunk-IXGYIQSR.js} +1 -1
  42. package/dist/{chunk-6NEJPS7W.js → chunk-JJLOWMGC.js} +2 -2
  43. package/dist/{chunk-73QZ43DF.js → chunk-KPBGAB35.js} +2 -2
  44. package/dist/{chunk-HJYAXAYQ.js → chunk-L5UKNGC5.js} +2 -2
  45. package/dist/{chunk-VJDSB7CI.js → chunk-LHWBQD7F.js} +24 -1
  46. package/dist/{chunk-JZL2O3RC.js → chunk-LISEPDVT.js} +5 -5
  47. package/dist/{chunk-NEMB36N4.js → chunk-MEIUXTFY.js} +2 -2
  48. package/dist/{chunk-7RH2NTLA.js → chunk-NZ5AXKRA.js} +1 -1
  49. package/dist/{chunk-H5GN7R43.js → chunk-QHFXVVUY.js} +2 -2
  50. package/dist/{chunk-U2NOOATF.js → chunk-S2ETJDQJ.js} +6 -6
  51. package/dist/{chunk-574JCBYH.js → chunk-TM4KFUWP.js} +2 -2
  52. package/dist/{chunk-YVI7ZV73.js → chunk-VGDZAWCJ.js} +803 -214
  53. package/dist/{chunk-TKPAOB2T.js → chunk-VRA64HYI.js} +2 -2
  54. package/dist/{chunk-T46G6YNI.js → chunk-WAFTJFT3.js} +3 -3
  55. package/dist/{chunk-GTHL3TRZ.js → chunk-XF6RE3JQ.js} +2 -2
  56. package/dist/{chunk-XKILFNRK.js → chunk-XNHKXELN.js} +2 -2
  57. package/dist/{ci-workflow-PA3WL6WK.js → ci-workflow-Y5GBKNZP.js} +4 -4
  58. package/dist/{dist-BWFFVKEW.js → dist-4CZLCE33.js} +7 -3
  59. package/dist/{dist-ISDDHDOR.js → dist-S3KCRI7X.js} +3 -1
  60. package/dist/{docs-HOTWQJQF.js → docs-3MWDPK4S.js} +5 -5
  61. package/dist/{engine-MVG2SPGD.js → engine-RJXQ5DHK.js} +4 -4
  62. package/dist/{entropy-3B4U2BTF.js → entropy-OX5LSM4S.js} +5 -5
  63. package/dist/{feedback-WIWWDVUC.js → feedback-OODAP2G2.js} +1 -1
  64. package/dist/{generate-agent-definitions-KPRHY6X3.js → generate-agent-definitions-CCREQZEA.js} +5 -5
  65. package/dist/hooks/adoption-tracker.js +41 -25
  66. package/dist/hooks/pre-compact-state.js +45 -27
  67. package/dist/hooks/sentinel-post.js +125 -102
  68. package/dist/hooks/sentinel-pre.js +70 -53
  69. package/dist/hooks/telemetry-reporter.js +44 -25
  70. package/dist/index.d.ts +66 -0
  71. package/dist/index.js +25 -25
  72. package/dist/{loader-SPJ2ZGYW.js → loader-ZICOJBVX.js} +4 -4
  73. package/dist/{mcp-VSSIWTII.js → mcp-XX6EIBLL.js} +15 -15
  74. package/dist/{performance-JYFS27B3.js → performance-OLZVGMAY.js} +5 -5
  75. package/dist/{review-pipeline-BDT6Y6QV.js → review-pipeline-3QPHMWPC.js} +4 -4
  76. package/dist/{runtime-ZEPHPPQJ.js → runtime-ZFFIH76Z.js} +4 -4
  77. package/dist/{security-FWSDTTEW.js → security-7YW3UK2C.js} +1 -1
  78. package/dist/{state-events-PBDNQPXT.js → state-events-PTWAEGJ2.js} +4 -4
  79. package/dist/{validate-XIMNCIKR.js → validate-H5SB7X3Z.js} +5 -5
  80. package/dist/{validate-cross-check-H2OUHTID.js → validate-cross-check-YYVYMSPA.js} +4 -4
  81. package/package.json +8 -8
@@ -1,22 +1,22 @@
1
1
  import {
2
2
  generateRuntime
3
- } from "./chunk-574JCBYH.js";
3
+ } from "./chunk-TM4KFUWP.js";
4
4
  import {
5
5
  generateAgentsMd
6
- } from "./chunk-TKPAOB2T.js";
6
+ } from "./chunk-VRA64HYI.js";
7
7
  import {
8
8
  generateCIWorkflow
9
- } from "./chunk-GTHL3TRZ.js";
9
+ } from "./chunk-XF6RE3JQ.js";
10
10
  import {
11
11
  readHarnessState
12
- } from "./chunk-NEMB36N4.js";
12
+ } from "./chunk-MEIUXTFY.js";
13
13
  import {
14
14
  runCrossCheck
15
- } from "./chunk-MIZQY35D.js";
15
+ } from "./chunk-D7QXGI6E.js";
16
16
  import {
17
17
  createGenerateAgentDefinitionsCommand,
18
18
  generateAgentDefinitions
19
- } from "./chunk-CMU4DNLY.js";
19
+ } from "./chunk-IXGYIQSR.js";
20
20
  import {
21
21
  toKebabCase
22
22
  } from "./chunk-KET4QQZB.js";
@@ -26,7 +26,7 @@ import {
26
26
  } from "./chunk-YYFSFSB3.js";
27
27
  import {
28
28
  TemplateEngine
29
- } from "./chunk-6NEJPS7W.js";
29
+ } from "./chunk-JJLOWMGC.js";
30
30
  import {
31
31
  generate,
32
32
  validate
@@ -37,7 +37,7 @@ import {
37
37
  import {
38
38
  listPersonas,
39
39
  loadPersona
40
- } from "./chunk-73QZ43DF.js";
40
+ } from "./chunk-KPBGAB35.js";
41
41
  import {
42
42
  runPersona
43
43
  } from "./chunk-GISMXMVL.js";
@@ -51,7 +51,7 @@ import {
51
51
  OutputFormatter,
52
52
  OutputMode,
53
53
  createCheckPhaseGateCommand
54
- } from "./chunk-LP764MGR.js";
54
+ } from "./chunk-6Y6M3AZA.js";
55
55
  import {
56
56
  appendFrameworkAgents,
57
57
  captureHealthSnapshot,
@@ -79,7 +79,7 @@ import {
79
79
  runSecurityCraft,
80
80
  runSpecCraft,
81
81
  runTestCraft
82
- } from "./chunk-F3GNBRGL.js";
82
+ } from "./chunk-EFWRZHZ7.js";
83
83
  import {
84
84
  VALID_PLATFORMS
85
85
  } from "./chunk-3ISINLYT.js";
@@ -108,7 +108,7 @@ import {
108
108
  BranchingConfigSchema,
109
109
  findConfigFile,
110
110
  resolveConfig
111
- } from "./chunk-LTYVAKWK.js";
111
+ } from "./chunk-IOJGLIEQ.js";
112
112
  import {
113
113
  logger
114
114
  } from "./chunk-EBJQ6N4M.js";
@@ -146,6 +146,7 @@ import {
146
146
  checkRoadmapAggregateDrift,
147
147
  checkRoadmapHealth,
148
148
  checkTaint,
149
+ classifyRevert,
149
150
  clearTaint,
150
151
  computeHotspots,
151
152
  computeOverallSeverity,
@@ -225,7 +226,7 @@ import {
225
226
  writeConfig,
226
227
  writeLockfile,
227
228
  writeRegeneratedRoadmap
228
- } from "./chunk-CRHQYBDA.js";
229
+ } from "./chunk-CTMHHMHQ.js";
229
230
  import {
230
231
  CLI_VERSION
231
232
  } from "./chunk-BM3PWGXQ.js";
@@ -238,14 +239,14 @@ import {
238
239
  detectDocDrift,
239
240
  generateSuggestions,
240
241
  validateDependencies
241
- } from "./chunk-7RH2NTLA.js";
242
+ } from "./chunk-NZ5AXKRA.js";
242
243
  import {
243
244
  Err,
244
245
  INDEXED_FILE_KINDS,
245
246
  INSIGHTS_KEYS,
246
247
  Ok,
247
248
  init_dist
248
- } from "./chunk-VJDSB7CI.js";
249
+ } from "./chunk-LHWBQD7F.js";
249
250
  import {
250
251
  DEFAULT_SKIP_DIRS,
251
252
  DesignConstraintAdapter,
@@ -262,7 +263,7 @@ import {
262
263
  } from "./chunk-KFQGP6VL.js";
263
264
 
264
265
  // src/index.ts
265
- import { Command as Command130 } from "commander";
266
+ import { Command as Command133 } from "commander";
266
267
 
267
268
  // src/commands/add.ts
268
269
  init_dist3();
@@ -453,7 +454,7 @@ function registerSkillsCommand(adoption) {
453
454
  const globalOpts = cmd.optsWithGlobals();
454
455
  const limit = Math.max(parseInt(opts.limit, 10) || 20, 1);
455
456
  const cwd = process.cwd();
456
- const { readAdoptionRecords, aggregateBySkill } = await import("./dist-BWFFVKEW.js");
457
+ const { readAdoptionRecords, aggregateBySkill } = await import("./dist-4CZLCE33.js");
457
458
  const records = readAdoptionRecords(cwd);
458
459
  if (records.length === 0) {
459
460
  if (globalOpts.json) {
@@ -489,7 +490,7 @@ function registerRecentCommand(adoption) {
489
490
  const globalOpts = cmd.optsWithGlobals();
490
491
  const limit = Math.max(parseInt(opts.limit, 10) || 20, 1);
491
492
  const cwd = process.cwd();
492
- const { readAdoptionRecords } = await import("./dist-BWFFVKEW.js");
493
+ const { readAdoptionRecords } = await import("./dist-4CZLCE33.js");
493
494
  const records = readAdoptionRecords(cwd);
494
495
  if (records.length === 0) {
495
496
  if (globalOpts.json) {
@@ -567,7 +568,7 @@ function registerSkillCommand(adoption) {
567
568
  adoption.command("skill <name>").description("Show detail for a specific skill").action(async (name, _opts, cmd) => {
568
569
  const globalOpts = cmd.optsWithGlobals();
569
570
  const cwd = process.cwd();
570
- const { readAdoptionRecords, aggregateBySkill } = await import("./dist-BWFFVKEW.js");
571
+ const { readAdoptionRecords, aggregateBySkill } = await import("./dist-4CZLCE33.js");
571
572
  const records = readAdoptionRecords(cwd);
572
573
  const skillRecords = records.filter((r) => r.skill === name);
573
574
  if (skillRecords.length === 0) {
@@ -601,7 +602,7 @@ function registerRetrospectiveCommand(adoption) {
601
602
  adoption.command("retrospective").description("Generate a catalog retrospective from adoption telemetry").option("--inactive-days <n>", "Inactivity threshold in days (default: 90)", "90").option("--top <n>", "Rows per ranked section (default: 10)", "10").option("--out <path>", "Output file path (default: docs/retrospectives/YYYY-MM-DD.md)").option("--no-write", "Print the report to stdout instead of writing a file").action(async (opts, cmd) => {
602
603
  const globalOpts = cmd.optsWithGlobals();
603
604
  const cwd = process.cwd();
604
- const { readAdoptionRecords, getCatalogRetrospectiveReport, renderRetrospectiveMarkdown } = await import("./dist-BWFFVKEW.js");
605
+ const { readAdoptionRecords, getCatalogRetrospectiveReport, renderRetrospectiveMarkdown } = await import("./dist-4CZLCE33.js");
605
606
  const records = readAdoptionRecords(cwd);
606
607
  const catalogSkills = discoverCatalogSkills(cwd);
607
608
  const report = getCatalogRetrospectiveReport(records, {
@@ -5248,16 +5249,9 @@ function createRemoveCommand() {
5248
5249
  import { Command as Command41 } from "commander";
5249
5250
  import * as fs13 from "fs";
5250
5251
  import * as path27 from "path";
5251
- import { fileURLToPath as fileURLToPath3 } from "url";
5252
- var __dirname3 = path27.dirname(fileURLToPath3(import.meta.url));
5253
5252
  var ALIASES = {
5254
5253
  sentinel: ["sentinel-pre", "sentinel-post"]
5255
5254
  };
5256
- function hookSourceDir() {
5257
- const d = path27.resolve(__dirname3, "..", "..", "hooks");
5258
- if (fs13.existsSync(d)) return d;
5259
- throw new Error(`Hook scripts not found: ${d}`);
5260
- }
5261
5255
  function readJson(p) {
5262
5256
  return fs13.existsSync(p) ? JSON.parse(fs13.readFileSync(p, "utf-8")) : {};
5263
5257
  }
@@ -5271,7 +5265,7 @@ function registerHook(s, ev, matcher, name) {
5271
5265
  function addHooks(hookName, projectDir) {
5272
5266
  const names = ALIASES[hookName] ?? [hookName];
5273
5267
  const result = { added: [], alreadyInstalled: [], notFound: [] };
5274
- const srcDir = hookSourceDir();
5268
+ const srcDir = resolveHookSourceDir();
5275
5269
  const destDir = path27.join(projectDir, ".harness", "hooks");
5276
5270
  fs13.mkdirSync(destDir, { recursive: true });
5277
5271
  const claudeDir = path27.join(projectDir, ".claude");
@@ -6209,7 +6203,7 @@ function createInsightsCommand() {
6209
6203
  return new Command46("insights").description("Composite project report \u2014 health, entropy, decay, attention, impact.").option("--json", "Emit JSON to stdout instead of pretty text").option("--skip <list>", `Comma-separated keys to skip (${INSIGHTS_KEYS.join(",")})`).action(async (opts) => {
6210
6204
  const cwd = process.cwd();
6211
6205
  const skip = parseSkip2(opts.skip);
6212
- const { composeInsights } = await import("./dist-BWFFVKEW.js");
6206
+ const { composeInsights } = await import("./dist-4CZLCE33.js");
6213
6207
  const report = await composeInsights(cwd, { skip });
6214
6208
  if (opts.json) {
6215
6209
  console.log(JSON.stringify(report, null, 2));
@@ -7944,10 +7938,10 @@ function reportDispatcher() {
7944
7938
  function realGit(args, cwd) {
7945
7939
  return execFileSync4("git", args, { cwd, encoding: "utf-8" }).toString().trim();
7946
7940
  }
7947
- function createFixDispatcher(resolveBackend, git = realGit) {
7941
+ function createFixDispatcher(resolveBackend, git2 = realGit) {
7948
7942
  return createAgentDispatcher({
7949
7943
  resolveBackend,
7950
- git,
7944
+ git: git2,
7951
7945
  logger: {
7952
7946
  info: (message) => logger.info(message),
7953
7947
  warn: (message) => logger.warn(message)
@@ -8320,7 +8314,7 @@ function createMcpCommand() {
8320
8314
  parseBudget
8321
8315
  ).action(async (opts) => {
8322
8316
  const [{ startServer: startServer2, getToolDefinitions: getToolDefinitions2 }, { selectTier }] = await Promise.all([
8323
- import("./mcp-VSSIWTII.js"),
8317
+ import("./mcp-XX6EIBLL.js"),
8324
8318
  import("./tool-tiers-OKK5FE57.js")
8325
8319
  ]);
8326
8320
  if (opts.tools && opts.tools.length > 0) {
@@ -8862,7 +8856,7 @@ function updateReferences(plan) {
8862
8856
  }
8863
8857
  async function prompt(question, def = "n") {
8864
8858
  const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
8865
- const answer = await new Promise((resolve50) => rl.question(question, resolve50));
8859
+ const answer = await new Promise((resolve49) => rl.question(question, resolve49));
8866
8860
  rl.close();
8867
8861
  return (answer.trim() || def).toLowerCase();
8868
8862
  }
@@ -9051,7 +9045,7 @@ function createMigrateCommand() {
9051
9045
  // src/commands/models.ts
9052
9046
  init_dist3();
9053
9047
  import { Command as Command66 } from "commander";
9054
- import { resolve as resolve31 } from "path";
9048
+ import { resolve as resolve30 } from "path";
9055
9049
  import { defaultFetchModels } from "@harness-engineering/orchestrator";
9056
9050
  function errorResult(message, partial) {
9057
9051
  return {
@@ -9169,7 +9163,7 @@ function formatProbe(result) {
9169
9163
  return lines.join("\n");
9170
9164
  }
9171
9165
  function projectRoot() {
9172
- return resolve31(process.env["HARNESS_PROJECT_ROOT"] ?? process.cwd());
9166
+ return resolve30(process.env["HARNESS_PROJECT_ROOT"] ?? process.cwd());
9173
9167
  }
9174
9168
  function summarizeModelProposal(p) {
9175
9169
  const base = { id: p.id, status: p.status, proposedBy: p.proposedBy, createdAt: p.createdAt };
@@ -9430,7 +9424,7 @@ import { Command as Command69 } from "commander";
9430
9424
  init_dist3();
9431
9425
  import { Command as Command68 } from "commander";
9432
9426
  import { randomBytes } from "crypto";
9433
- import { resolve as resolve32 } from "path";
9427
+ import { resolve as resolve31 } from "path";
9434
9428
  import { SinkRegistry, SinkConfigError, wrapAsEnvelope } from "@harness-engineering/orchestrator";
9435
9429
  function makeTestEvent(message) {
9436
9430
  return {
@@ -9482,7 +9476,7 @@ async function runNotificationsTest(sinkId, opts, projectRoot3 = process.cwd())
9482
9476
  function createNotificationsTestSubcommand() {
9483
9477
  return new Command68("test").description("Send a synthetic notification.test event through the named sink").argument("<sink-id>", "Sink id from harness.config.json `notifications.sinks[].id`").option("--message <text>", "Override the default test message").action(async (sinkId, opts, cmd) => {
9484
9478
  const globalOpts = cmd.optsWithGlobals();
9485
- const projectRoot3 = typeof globalOpts["cwd"] === "string" ? resolve32(globalOpts["cwd"]) : process.cwd();
9479
+ const projectRoot3 = typeof globalOpts["cwd"] === "string" ? resolve31(globalOpts["cwd"]) : process.cwd();
9486
9480
  const result = await runNotificationsTest(sinkId, opts, projectRoot3);
9487
9481
  if (globalOpts["json"]) {
9488
9482
  console.log(JSON.stringify(result, null, 2));
@@ -9507,7 +9501,12 @@ function createNotificationsCommand() {
9507
9501
  // src/commands/orchestrator.ts
9508
9502
  import { Command as Command70 } from "commander";
9509
9503
  import * as path50 from "path";
9510
- import { Orchestrator, WorkflowLoader as WorkflowLoader2, launchTUI } from "@harness-engineering/orchestrator";
9504
+ import {
9505
+ Orchestrator,
9506
+ WorkflowLoader as WorkflowLoader2,
9507
+ launchTUI,
9508
+ discoverCandidates
9509
+ } from "@harness-engineering/orchestrator";
9511
9510
  function createOrchestratorCommand() {
9512
9511
  const orchestrator = new Command70("orchestrator");
9513
9512
  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) => {
@@ -9520,7 +9519,7 @@ function createOrchestratorCommand() {
9520
9519
  }
9521
9520
  const { config, promptTemplate, warnings } = result.value;
9522
9521
  for (const w of warnings) logger.warn(w);
9523
- const daemon = new Orchestrator(config, promptTemplate);
9522
+ const daemon = new Orchestrator(config, promptTemplate, { discoverCandidates });
9524
9523
  const shutdown = () => {
9525
9524
  daemon.stop();
9526
9525
  process.exit(ExitCode.SUCCESS);
@@ -9551,7 +9550,7 @@ function registerBenchCommand(perf) {
9551
9550
  perf.command("bench [glob]").description("Run benchmarks via vitest bench").action(async (glob2, _opts, cmd) => {
9552
9551
  const globalOpts = cmd.optsWithGlobals();
9553
9552
  const cwd = process.cwd();
9554
- const { BenchmarkRunner } = await import("./dist-BWFFVKEW.js");
9553
+ const { BenchmarkRunner } = await import("./dist-4CZLCE33.js");
9555
9554
  const runner = new BenchmarkRunner();
9556
9555
  const benchFiles = runner.discover(cwd, glob2);
9557
9556
  if (benchFiles.length === 0) {
@@ -9615,7 +9614,7 @@ async function runBaselinesShow(globalOpts) {
9615
9614
  }
9616
9615
  async function runBaselinesUpdate(globalOpts) {
9617
9616
  const cwd = process.cwd();
9618
- const { BenchmarkRunner } = await import("./dist-BWFFVKEW.js");
9617
+ const { BenchmarkRunner } = await import("./dist-4CZLCE33.js");
9619
9618
  const runner = new BenchmarkRunner();
9620
9619
  const manager = new BaselineManager(cwd);
9621
9620
  logger.info("Running benchmarks to update baselines...");
@@ -9656,7 +9655,7 @@ function registerReportCommand(perf) {
9656
9655
  perf.command("report").description("Full performance report with metrics, trends, and hotspots").action(async (_opts, cmd) => {
9657
9656
  const globalOpts = cmd.optsWithGlobals();
9658
9657
  const cwd = process.cwd();
9659
- const { EntropyAnalyzer: EntropyAnalyzer2 } = await import("./dist-BWFFVKEW.js");
9658
+ const { EntropyAnalyzer: EntropyAnalyzer2 } = await import("./dist-4CZLCE33.js");
9660
9659
  const analyzer = new EntropyAnalyzer2({
9661
9660
  rootDir: path51.resolve(cwd),
9662
9661
  analyze: { complexity: true, coupling: true }
@@ -10443,9 +10442,9 @@ function createPreMergeBriefCommand() {
10443
10442
  // src/commands/proposals.ts
10444
10443
  init_dist3();
10445
10444
  import { Command as Command78 } from "commander";
10446
- import { resolve as resolve36 } from "path";
10445
+ import { resolve as resolve35 } from "path";
10447
10446
  function projectRoot2() {
10448
- return resolve36(process.env["HARNESS_PROJECT_ROOT"] ?? process.cwd());
10447
+ return resolve35(process.env["HARNESS_PROJECT_ROOT"] ?? process.cwd());
10449
10448
  }
10450
10449
  function summarizeProposal(p) {
10451
10450
  const base = {
@@ -10679,7 +10678,7 @@ async function runPublishAnalyses(opts) {
10679
10678
  const nameToExternalId = await buildNameToExternalIdMap(projectPath);
10680
10679
  if (!nameToExternalId) return process.exit(1);
10681
10680
  const { AnalysisArchive } = await import("@harness-engineering/orchestrator");
10682
- const { GitHubIssuesSyncAdapter: GitHubIssuesSyncAdapter2 } = await import("./dist-BWFFVKEW.js");
10681
+ const { GitHubIssuesSyncAdapter: GitHubIssuesSyncAdapter2 } = await import("./dist-4CZLCE33.js");
10683
10682
  const archive = new AnalysisArchive(path53.join(projectPath, ".harness", "analyses"));
10684
10683
  const analyses = await archive.list();
10685
10684
  if (analyses.length === 0) {
@@ -10723,7 +10722,7 @@ import { Command as Command81 } from "commander";
10723
10722
  // src/commands/pulse/run.ts
10724
10723
  init_dist3();
10725
10724
  import { readFileSync as readFileSync19, mkdirSync as mkdirSync16, writeFileSync as writeFileSync20 } from "fs";
10726
- import { dirname as dirname19, join as join43, resolve as resolve38 } from "path";
10725
+ import { dirname as dirname18, join as join43, resolve as resolve37 } from "path";
10727
10726
  import { Command as Command80 } from "commander";
10728
10727
  async function runPulseRunCommand(opts) {
10729
10728
  const startedAt = Date.now();
@@ -10756,7 +10755,7 @@ async function runPulseRunCommand(opts) {
10756
10755
  const now = /* @__PURE__ */ new Date();
10757
10756
  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")}`;
10758
10757
  const filePath = join43(opts.outputDir, `${ts}.md`);
10759
- mkdirSync16(dirname19(filePath), { recursive: true });
10758
+ mkdirSync16(dirname18(filePath), { recursive: true });
10760
10759
  writeFileSync20(filePath, report);
10761
10760
  const headlines = extractHeadlines(report);
10762
10761
  return emit2(
@@ -10799,8 +10798,8 @@ function createRunCommand2() {
10799
10798
  async (options) => {
10800
10799
  const nonInteractive = options.nonInteractive === true || !process.stdout.isTTY;
10801
10800
  const status = await runPulseRunCommand({
10802
- configPath: resolve38(process.cwd(), options.config),
10803
- outputDir: resolve38(process.cwd(), options.outputDir),
10801
+ configPath: resolve37(process.cwd(), options.config),
10802
+ outputDir: resolve37(process.cwd(), options.outputDir),
10804
10803
  nonInteractive,
10805
10804
  lookback: options.lookback
10806
10805
  });
@@ -11782,11 +11781,435 @@ function createRoadmapCommand() {
11782
11781
  return roadmap;
11783
11782
  }
11784
11783
 
11784
+ // src/commands/rollback.ts
11785
+ init_dist3();
11786
+ import { execFileSync as execFileSync10 } from "child_process";
11787
+ import { Command as Command90, Option as Option3, InvalidArgumentError } from "commander";
11788
+
11789
+ // src/rollback/compose.ts
11790
+ var ROLLBACK_LABEL = "harness:rollback";
11791
+ function buildRevertBody(d, originalTitle, reason) {
11792
+ const lines = [
11793
+ `## Automated rollback proposal`,
11794
+ ``,
11795
+ `**Trigger:** ${d.trigger}`,
11796
+ `**Target PR:** #${d.targetPr} \u2014 ${originalTitle}`,
11797
+ `**Revert-ready:** ${d.revertReady}`,
11798
+ d.blastRadius !== void 0 ? `**Blast radius:** ${d.blastRadius}` : void 0,
11799
+ // #4: surface the human-provided --reason when present (help text promises it).
11800
+ reason && reason.trim() !== "" ? `**Reason:** ${reason.trim()}` : void 0,
11801
+ ``,
11802
+ `### Classification`,
11803
+ ...d.reasons.map((r) => `- ${r}`)
11804
+ ];
11805
+ if (d.migrationWarnings.length > 0) {
11806
+ lines.push(
11807
+ ``,
11808
+ `### Migration / irreversibility warnings`,
11809
+ ...d.migrationWarnings.map((w) => `- ${w}`)
11810
+ );
11811
+ }
11812
+ if (d.dependentMerges.length > 0) {
11813
+ lines.push(
11814
+ ``,
11815
+ `### Dependent later merges`,
11816
+ `- ${d.dependentMerges.map((n) => `#${n}`).join(", ")}`
11817
+ );
11818
+ }
11819
+ return lines.filter((l) => l !== void 0).join("\n");
11820
+ }
11821
+ async function composeRevertPr(decision, originalTitle, opts) {
11822
+ if (!decision.revertReady) return { action: decision.action };
11823
+ const body = buildRevertBody(decision, originalTitle, opts.reason);
11824
+ if (opts.dryRun) {
11825
+ const print = opts.print ?? ((s) => process.stdout.write(`${s}
11826
+ `));
11827
+ print(body);
11828
+ return { action: "proposed" };
11829
+ }
11830
+ const existing = await opts.gh.findOpenRevertPr(decision.targetPr, ROLLBACK_LABEL);
11831
+ if (existing !== null) {
11832
+ return { action: "skipped", ...existing.url ? { prUrl: existing.url } : {} };
11833
+ }
11834
+ const prUrl = await opts.gh.openPr({
11835
+ title: `revert: ${originalTitle} (automated rollback)`,
11836
+ body,
11837
+ label: ROLLBACK_LABEL,
11838
+ targetPr: decision.targetPr
11839
+ });
11840
+ return { action: "proposed", prUrl };
11841
+ }
11842
+
11843
+ // src/rollback/breadcrumb.ts
11844
+ import { appendFileSync, mkdirSync as mkdirSync19 } from "fs";
11845
+ import { dirname as dirname20, join as join50 } from "path";
11846
+ var ROLLBACK_EVENTS_FILE = join50(".harness", "signals", "rollback-events.jsonl");
11847
+ async function appendRollbackEvent(event, opts = {}) {
11848
+ const root = opts.root ?? process.cwd();
11849
+ const ts = (opts.now ?? (() => (/* @__PURE__ */ new Date()).toISOString()))();
11850
+ const file = join50(root, ROLLBACK_EVENTS_FILE);
11851
+ mkdirSync19(dirname20(file), { recursive: true });
11852
+ appendFileSync(file, `${JSON.stringify({ ...event, ts })}
11853
+ `, "utf-8");
11854
+ }
11855
+ async function linkRollbackEventToGraph(event, opts = {}) {
11856
+ const root = opts.root ?? process.cwd();
11857
+ try {
11858
+ const { loadGraphStore: loadGraphStore2 } = await import("./graph-loader-STFGYKZH.js");
11859
+ const store = await loadGraphStore2(root);
11860
+ if (!store) return;
11861
+ const ts = (opts.now ?? (() => (/* @__PURE__ */ new Date()).toISOString()))();
11862
+ const nodeId = `rollback_event:${event.targetPr}:${ts}`;
11863
+ store.addNode({
11864
+ id: nodeId,
11865
+ type: "learning",
11866
+ name: `rollback ${event.action} for PR #${event.targetPr}`,
11867
+ metadata: { kind: "rollback_event", ...event, ts },
11868
+ lastModified: ts
11869
+ });
11870
+ const outcomes = store.findNodes({ type: "execution_outcome" });
11871
+ const target = outcomes.find(
11872
+ (n) => n.metadata.pr === event.targetPr
11873
+ );
11874
+ if (target) {
11875
+ store.addEdge({ from: nodeId, to: target.id, type: "references" });
11876
+ }
11877
+ await store.save(join50(root, ".harness", "graph"));
11878
+ } catch {
11879
+ }
11880
+ }
11881
+
11882
+ // src/rollback/io.ts
11883
+ import { execFileSync as execFileSync8 } from "child_process";
11884
+ var git = (args) => execFileSync8("git", args, { encoding: "utf-8" }).toString();
11885
+ var nodeGitSeam = {
11886
+ run: (args) => git(args).trim(),
11887
+ tryMergeTree: (args) => {
11888
+ try {
11889
+ const stdout = execFileSync8("git", args, {
11890
+ encoding: "utf-8",
11891
+ stdio: ["ignore", "pipe", "ignore"]
11892
+ }).toString();
11893
+ return { status: 0, stdout };
11894
+ } catch (err) {
11895
+ const e = err;
11896
+ return { status: e?.status ?? 1, stdout: e?.stdout?.toString?.() ?? "" };
11897
+ }
11898
+ }
11899
+ };
11900
+ var gh = (args) => execFileSync8("gh", args, { encoding: "utf-8" }).toString();
11901
+ function parseConflictPaths(stdout) {
11902
+ const lines = stdout.split("\n");
11903
+ const paths = /* @__PURE__ */ new Set();
11904
+ for (let i = 1; i < lines.length; i++) {
11905
+ const line = lines[i];
11906
+ if (line === void 0 || line.trim() === "") break;
11907
+ const tab = line.indexOf(" ");
11908
+ if (tab === -1) continue;
11909
+ const path81 = line.slice(tab + 1).trim();
11910
+ if (path81) paths.add(path81);
11911
+ }
11912
+ return [...paths];
11913
+ }
11914
+ async function computeRevertDryRun(mergeSha, gitSeam = nodeGitSeam) {
11915
+ const revList = gitSeam.run(["rev-list", "--parents", "-n", "1", mergeSha]);
11916
+ const parents = revList.trim().split(/\s+/).slice(1);
11917
+ if (parents.length === 0) {
11918
+ throw new Error(`cannot revert ${mergeSha}: commit has no parent (root commit)`);
11919
+ }
11920
+ const parent = parents[0];
11921
+ const { status, stdout } = gitSeam.tryMergeTree([
11922
+ "merge-tree",
11923
+ "--write-tree",
11924
+ "--merge-base",
11925
+ mergeSha,
11926
+ "HEAD",
11927
+ parent
11928
+ ]);
11929
+ if (status === 0) return { clean: true, conflictPaths: [] };
11930
+ if (status === 1) return { clean: false, conflictPaths: parseConflictPaths(stdout) };
11931
+ throw new Error(
11932
+ `git merge-tree failed for ${mergeSha} (exit ${status})${stdout ? `: ${stdout.trim()}` : ""}`
11933
+ );
11934
+ }
11935
+ async function revertDryRun(mergeSha) {
11936
+ return computeRevertDryRun(mergeSha, nodeGitSeam);
11937
+ }
11938
+ async function resolveTarget(pr) {
11939
+ const raw = gh(["pr", "view", String(pr), "--json", "mergeCommit,files,title"]);
11940
+ const parsed = JSON.parse(raw);
11941
+ return {
11942
+ mergeSha: parsed.mergeCommit?.oid ?? "",
11943
+ changedFiles: (parsed.files ?? []).map((f) => f.path),
11944
+ title: parsed.title ?? `PR #${pr}`
11945
+ };
11946
+ }
11947
+ async function listLaterMerges(pr) {
11948
+ const targetRaw = gh(["pr", "view", String(pr), "--json", "mergedAt"]);
11949
+ const targetMergedAt = JSON.parse(targetRaw).mergedAt;
11950
+ if (!targetMergedAt) return [];
11951
+ const raw = gh([
11952
+ "pr",
11953
+ "list",
11954
+ "--state",
11955
+ "merged",
11956
+ "--limit",
11957
+ "100",
11958
+ "--json",
11959
+ "number,files,mergedAt"
11960
+ ]);
11961
+ const list = JSON.parse(raw);
11962
+ return list.filter((p) => p.number !== pr && p.mergedAt > targetMergedAt).map((p) => ({ pr: p.number, changedFiles: (p.files ?? []).map((f) => f.path) }));
11963
+ }
11964
+ function createNodeRollbackIO() {
11965
+ return { revertDryRun, resolveTarget, listLaterMerges };
11966
+ }
11967
+
11968
+ // src/rollback/sweep.ts
11969
+ import { execFileSync as execFileSync9 } from "child_process";
11970
+ import { SignalTimelineStore } from "@harness-engineering/signals";
11971
+ var WINDOW_UNIT_MS = {
11972
+ h: 36e5,
11973
+ d: 864e5,
11974
+ w: 6048e5
11975
+ };
11976
+ function parseWindow(window) {
11977
+ const match = /^(\d+)([hdw])$/.exec(window);
11978
+ if (!match) throw new Error(`invalid window: ${window}`);
11979
+ const count = Number.parseInt(match[1] ?? "", 10);
11980
+ const unit = match[2];
11981
+ return count * WINDOW_UNIT_MS[unit];
11982
+ }
11983
+ function detectCrossing(points, rule) {
11984
+ const prev = points.at(-2);
11985
+ const curr = points.at(-1);
11986
+ if (!prev || !curr) return false;
11987
+ if (rule.direction === "above") {
11988
+ return prev.value < rule.threshold && curr.value >= rule.threshold;
11989
+ }
11990
+ return prev.value > rule.threshold && curr.value <= rule.threshold;
11991
+ }
11992
+ function windowStart(now, window) {
11993
+ return new Date(now.getTime() - parseWindow(window)).toISOString();
11994
+ }
11995
+ function pointsInWindow(points, now, window) {
11996
+ const startDate = windowStart(now, window).slice(0, 10);
11997
+ const nowDate = now.toISOString().slice(0, 10);
11998
+ return points.filter((p) => p.date >= startDate && p.date <= nowDate);
11999
+ }
12000
+ async function runRollbackSweep(signals, deps) {
12001
+ const now = (deps.now ?? (() => /* @__PURE__ */ new Date()))();
12002
+ for (const [name, rule] of Object.entries(signals)) {
12003
+ const pts = pointsInWindow(deps.readTimeline(name), now, rule.window);
12004
+ const crossed = detectCrossing(pts, rule);
12005
+ const forwarded = [];
12006
+ if (crossed) {
12007
+ const prs = await deps.resolveMergedPrs(windowStart(now, rule.window), now.toISOString());
12008
+ for (const pr of prs) {
12009
+ const decision = await deps.evaluate(pr);
12010
+ forwarded.push({
12011
+ pr,
12012
+ action: decision.action,
12013
+ ...decision.prUrl ? { prUrl: decision.prUrl } : {}
12014
+ });
12015
+ }
12016
+ }
12017
+ deps.report?.({ signal: name, window: rule.window, crossed, forwarded });
12018
+ }
12019
+ }
12020
+ function createTimelineReader(root) {
12021
+ const store = new SignalTimelineStore(root);
12022
+ return (name) => store.read(name);
12023
+ }
12024
+ function createPrResolver() {
12025
+ return async (startIso, nowIso) => {
12026
+ try {
12027
+ const raw = execFileSync9(
12028
+ "gh",
12029
+ [
12030
+ "pr",
12031
+ "list",
12032
+ "--state",
12033
+ "merged",
12034
+ "--search",
12035
+ `merged:${startIso}..${nowIso}`,
12036
+ "--json",
12037
+ "number",
12038
+ "--limit",
12039
+ "100"
12040
+ ],
12041
+ { encoding: "utf-8" }
12042
+ );
12043
+ return JSON.parse(raw).map((p) => p.number);
12044
+ } catch {
12045
+ return [];
12046
+ }
12047
+ };
12048
+ }
12049
+
12050
+ // src/commands/rollback.ts
12051
+ async function runRollbackEvaluate(args, deps) {
12052
+ const trigger = args.trigger ?? "signal";
12053
+ const target = await deps.io.resolveTarget(args.pr);
12054
+ const laterMerges = await deps.io.listLaterMerges(args.pr);
12055
+ const decision = await classifyRevert(
12056
+ {
12057
+ targetPr: args.pr,
12058
+ trigger,
12059
+ mergeSha: target.mergeSha,
12060
+ changedFiles: target.changedFiles,
12061
+ laterMerges
12062
+ },
12063
+ deps.io
12064
+ );
12065
+ const composed = await composeRevertPr(decision, target.title, {
12066
+ gh: deps.gh,
12067
+ ...args.dryRun ? { dryRun: true } : {},
12068
+ ...deps.print ? { print: deps.print } : {},
12069
+ ...args.reason !== void 0 ? { reason: args.reason } : {}
12070
+ });
12071
+ const finalDecision = {
12072
+ ...decision,
12073
+ action: composed.action,
12074
+ ...composed.prUrl ? { prUrl: composed.prUrl } : {}
12075
+ };
12076
+ await appendRollbackEvent(
12077
+ {
12078
+ targetPr: finalDecision.targetPr,
12079
+ trigger: finalDecision.trigger,
12080
+ revertReady: finalDecision.revertReady,
12081
+ action: finalDecision.action,
12082
+ ...finalDecision.prUrl ? { prUrl: finalDecision.prUrl } : {},
12083
+ // #4: record the human-provided reason on the breadcrumb (help text promises it).
12084
+ ...args.reason !== void 0 ? { reason: args.reason } : {}
12085
+ },
12086
+ deps.root !== void 0 ? { root: deps.root } : {}
12087
+ );
12088
+ return finalDecision;
12089
+ }
12090
+ var gh2 = (args) => execFileSync10("gh", args, { encoding: "utf-8" }).toString();
12091
+ function referencesTargetPr(text, targetPr) {
12092
+ if (!text) return false;
12093
+ return new RegExp(`(?<!\\d)#${targetPr}(?!\\d)`).test(text);
12094
+ }
12095
+ function findOpenRevertPrNode(targetPr) {
12096
+ try {
12097
+ const raw = gh2([
12098
+ "pr",
12099
+ "list",
12100
+ "--state",
12101
+ "open",
12102
+ "--label",
12103
+ ROLLBACK_LABEL,
12104
+ "--search",
12105
+ `#${targetPr}`,
12106
+ "--json",
12107
+ "number,url,body,title"
12108
+ ]);
12109
+ const list = JSON.parse(raw);
12110
+ const match = list.find(
12111
+ (p) => referencesTargetPr(p.body, targetPr) || referencesTargetPr(p.title, targetPr)
12112
+ );
12113
+ return match ? { number: match.number, url: match.url } : null;
12114
+ } catch {
12115
+ return null;
12116
+ }
12117
+ }
12118
+ function createGhSeam() {
12119
+ return {
12120
+ async findOpenRevertPr(targetPr) {
12121
+ return findOpenRevertPrNode(targetPr);
12122
+ },
12123
+ async openPr({ title, body, label }) {
12124
+ return execFileSync10(
12125
+ "gh",
12126
+ ["pr", "create", "--title", title, "--body-file", "-", "--label", label],
12127
+ { input: body, encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }
12128
+ ).toString().trim();
12129
+ }
12130
+ };
12131
+ }
12132
+ function summarizeSweepReport(r) {
12133
+ if (!r.crossed) {
12134
+ return `rollback sweep: ${r.signal} (${r.window}) \u2014 no crossing`;
12135
+ }
12136
+ if (r.forwarded.length === 0) {
12137
+ return `rollback sweep: ${r.signal} (${r.window}) \u2014 crossed, no PRs in window`;
12138
+ }
12139
+ const parts = r.forwarded.map((f) => `#${f.pr} \u2192 ${f.action}${f.prUrl ? ` (${f.prUrl})` : ""}`);
12140
+ return `rollback sweep: ${r.signal} (${r.window}) \u2014 crossed; forwarded ${parts.join(", ")}`;
12141
+ }
12142
+ async function runRollbackSweepCommand(deps) {
12143
+ const cfg = deps.resolveConfig();
12144
+ if (!cfg.ok) {
12145
+ deps.warn(`rollback sweep: config error, breaker inactive: ${cfg.error.message}`);
12146
+ }
12147
+ const signals = cfg.ok ? cfg.value.rollback?.signals ?? {} : {};
12148
+ await deps.runSweep(signals, {
12149
+ readTimeline: deps.makeReader(deps.root),
12150
+ resolveMergedPrs: deps.makeResolver(),
12151
+ evaluate: deps.evaluate,
12152
+ report: (r) => deps.info(summarizeSweepReport(r))
12153
+ });
12154
+ }
12155
+ function createRollbackCommand() {
12156
+ const rollback = new Command90("rollback").description(
12157
+ "Post-ship revert circuit breaker (propose-only in v1)"
12158
+ );
12159
+ rollback.command("evaluate").description("Classify a merged PR for revert-readiness and, if ready, propose a revert PR").requiredOption("--pr <n>", "target merged PR number", (v) => {
12160
+ const n = Number.parseInt(v, 10);
12161
+ if (Number.isNaN(n)) throw new InvalidArgumentError("--pr must be a number");
12162
+ return n;
12163
+ }).addOption(
12164
+ new Option3("--trigger <trigger>", "what fired this evaluation").choices(["signal", "eval"]).default("signal")
12165
+ ).option("--reason <str>", "human-readable reason recorded on the proposal").option("--dry-run", "print the revert PR body without opening a PR", false).action(async (opts) => {
12166
+ const reason = opts.reason;
12167
+ const dryRun = opts.dryRun;
12168
+ const decision = await runRollbackEvaluate(
12169
+ {
12170
+ pr: opts.pr,
12171
+ trigger: opts.trigger,
12172
+ ...reason !== void 0 ? { reason } : {},
12173
+ ...dryRun !== void 0 ? { dryRun } : {}
12174
+ },
12175
+ { io: createNodeRollbackIO(), gh: createGhSeam() }
12176
+ );
12177
+ await linkRollbackEventToGraph({
12178
+ targetPr: decision.targetPr,
12179
+ trigger: decision.trigger,
12180
+ revertReady: decision.revertReady,
12181
+ action: decision.action,
12182
+ ...decision.prUrl ? { prUrl: decision.prUrl } : {}
12183
+ });
12184
+ logger.info(JSON.stringify(decision, null, 2));
12185
+ });
12186
+ rollback.command("sweep").description(
12187
+ "Read the signal timeline and propose reverts for threshold crossings (signal arm)"
12188
+ ).action(async () => {
12189
+ await runRollbackSweepCommand({
12190
+ resolveConfig,
12191
+ runSweep: runRollbackSweep,
12192
+ makeReader: createTimelineReader,
12193
+ makeResolver: createPrResolver,
12194
+ evaluate: (pr) => runRollbackEvaluate(
12195
+ { pr, trigger: "signal" },
12196
+ { io: createNodeRollbackIO(), gh: createGhSeam() }
12197
+ ),
12198
+ root: process.cwd(),
12199
+ // #S4: per-signal summary on stdout so the sweep's work is auditable.
12200
+ info: (line) => logger.info(line),
12201
+ // #I2: config error → disarm warning on stderr, never silent.
12202
+ warn: (line) => logger.error(line)
12203
+ });
12204
+ });
12205
+ return rollback;
12206
+ }
12207
+
11785
12208
  // src/commands/routing/index.ts
11786
- import { Command as Command93 } from "commander";
12209
+ import { Command as Command96 } from "commander";
11787
12210
 
11788
12211
  // src/commands/routing/config.ts
11789
- import { Command as Command90 } from "commander";
12212
+ import { Command as Command91 } from "commander";
11790
12213
 
11791
12214
  // src/commands/routing/http-client.ts
11792
12215
  function orchestratorBase() {
@@ -11851,7 +12274,7 @@ function renderHuman(data) {
11851
12274
  }
11852
12275
  }
11853
12276
  function createConfigCommand() {
11854
- return new Command90("config").description("Print active routing config and resolved fallback chains").option("--json", "Emit JSON to stdout instead of human-readable text").action(async (opts) => {
12277
+ return new Command91("config").description("Print active routing config and resolved fallback chains").option("--json", "Emit JSON to stdout instead of human-readable text").action(async (opts) => {
11855
12278
  const r = await getJson("/api/v1/routing/config");
11856
12279
  if (!r.ok) {
11857
12280
  if (r.status === 0) {
@@ -11877,7 +12300,13 @@ function createConfigCommand() {
11877
12300
  }
11878
12301
 
11879
12302
  // src/commands/routing/trace.ts
11880
- import { Command as Command91 } from "commander";
12303
+ import { Command as Command92 } from "commander";
12304
+ var COMPLEXITY_VALUES = ["trivial", "simple", "moderate", "complex"];
12305
+ var RISK_VALUES = ["low", "high"];
12306
+ function validateEnum(flag, value, allowed) {
12307
+ if (value === void 0 || allowed.includes(value)) return null;
12308
+ return `Invalid ${flag} "${value}". Allowed values: ${allowed.join(", ")}.`;
12309
+ }
11881
12310
  function buildUseCase(opts) {
11882
12311
  if (opts.skill) {
11883
12312
  return opts.mode ? { kind: "skill", skillName: opts.skill, cognitiveMode: opts.mode } : { kind: "skill", skillName: opts.skill };
@@ -11896,41 +12325,60 @@ function renderHuman2(r) {
11896
12325
  for (const step of r.decision.resolutionPath) {
11897
12326
  console.log(` ${step.source}:${step.candidate} -> ${step.outcome}`);
11898
12327
  }
12328
+ if (r.tierRequired !== void 0) {
12329
+ console.log(`Tier required: ${r.tierRequired}`);
12330
+ }
12331
+ if (r.estCostUsd !== void 0) {
12332
+ console.log(`Est cost: $${r.estCostUsd.toFixed(4)}`);
12333
+ }
11899
12334
  }
11900
- function createTraceCommand() {
11901
- return new Command91("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) => {
11902
- const useCase = buildUseCase(opts);
11903
- if (!useCase) {
11904
- logger.error("Either --skill <name> or --mode <m> is required");
11905
- process.exit(ExitCode.ERROR);
11906
- return;
11907
- }
11908
- const r = await postJson("/api/v1/routing/trace", { useCase });
11909
- if (!r.ok) {
11910
- if (r.status === 0) {
11911
- logger.error(
11912
- `Failed to reach orchestrator at ${orchestratorBase()}: ${r.error ?? "unknown error"}`
11913
- );
11914
- } else if (r.status === 503) {
11915
- logger.error(
11916
- "Routing observability not available \u2014 orchestrator has no BackendRouter (legacy single-backend config)"
11917
- );
11918
- } else {
11919
- logger.error(`Trace failed (${r.status}): ${r.error ?? ""}`);
11920
- }
11921
- process.exit(ExitCode.ERROR);
11922
- return;
11923
- }
11924
- if (opts.json) {
11925
- console.log(JSON.stringify(r.body, null, 2));
11926
- return;
11927
- }
11928
- if (r.body) renderHuman2(r.body);
12335
+ function traceErrorMessage(r) {
12336
+ if (r.status === 0) {
12337
+ return `Failed to reach orchestrator at ${orchestratorBase()}: ${r.error ?? "unknown error"}`;
12338
+ }
12339
+ if (r.status === 503) {
12340
+ return "Routing observability not available \u2014 orchestrator has no BackendRouter (legacy single-backend config)";
12341
+ }
12342
+ return `Trace failed (${r.status}): ${r.error ?? ""}`;
12343
+ }
12344
+ async function runTrace(opts) {
12345
+ const useCase = buildUseCase(opts);
12346
+ if (!useCase) {
12347
+ logger.error("Either --skill <name> or --mode <m> is required");
12348
+ process.exit(ExitCode.ERROR);
12349
+ return;
12350
+ }
12351
+ const enumError = validateEnum("--complexity", opts.complexity, COMPLEXITY_VALUES) ?? validateEnum("--risk", opts.risk, RISK_VALUES);
12352
+ if (enumError) {
12353
+ logger.error(enumError);
12354
+ process.exit(ExitCode.ERROR);
12355
+ return;
12356
+ }
12357
+ const r = await postJson("/api/v1/routing/trace", {
12358
+ useCase,
12359
+ ...opts.complexity ? { complexity: opts.complexity } : {},
12360
+ ...opts.risk ? { risk: opts.risk } : {}
11929
12361
  });
12362
+ if (!r.ok) {
12363
+ logger.error(traceErrorMessage(r));
12364
+ process.exit(ExitCode.ERROR);
12365
+ return;
12366
+ }
12367
+ if (opts.json) {
12368
+ console.log(JSON.stringify(r.body, null, 2));
12369
+ return;
12370
+ }
12371
+ if (r.body) renderHuman2(r.body);
12372
+ }
12373
+ function createTraceCommand() {
12374
+ return new Command92("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(
12375
+ "--complexity <level>",
12376
+ "Synthetic complexity (trivial|simple|moderate|complex) \u2014 dry-run only"
12377
+ ).option("--risk <band>", "Synthetic risk band (low|high) \u2014 dry-run only").option("--json", "Emit JSON to stdout instead of human-readable text").action(runTrace);
11930
12378
  }
11931
12379
 
11932
12380
  // src/commands/routing/decisions.ts
11933
- import { Command as Command92 } from "commander";
12381
+ import { Command as Command93 } from "commander";
11934
12382
  function summarizeUseCase(uc) {
11935
12383
  switch (uc.kind) {
11936
12384
  case "skill":
@@ -11978,7 +12426,7 @@ function buildQuery(opts) {
11978
12426
  return q ? `?${q}` : "";
11979
12427
  }
11980
12428
  function createDecisionsCommand() {
11981
- return new Command92("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(
12429
+ return new Command93("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(
11982
12430
  async (opts) => {
11983
12431
  const query = buildQuery(opts);
11984
12432
  const r = await getJson(`/api/v1/routing/decisions${query}`);
@@ -12006,22 +12454,162 @@ function createDecisionsCommand() {
12006
12454
  );
12007
12455
  }
12008
12456
 
12457
+ // src/commands/routing/telemetry.ts
12458
+ import { Command as Command94 } from "commander";
12459
+ var TIERS = ["fast", "standard", "strong"];
12460
+ function shortIso2(iso) {
12461
+ const tail = iso.split("T")[1] ?? iso;
12462
+ return tail.replace("Z", "");
12463
+ }
12464
+ function renderHuman4(data, tableLimit) {
12465
+ if (data.decisions.length === 0) {
12466
+ console.log("(no routing telemetry \u2014 AMR is off or no decisions recorded yet)");
12467
+ return;
12468
+ }
12469
+ const byTier = /* @__PURE__ */ new Map();
12470
+ for (const t of TIERS) byTier.set(t, { count: 0, cost: 0 });
12471
+ for (const d of data.decisions) {
12472
+ const bucket = byTier.get(d.tierRequired);
12473
+ if (bucket) {
12474
+ bucket.count += 1;
12475
+ bucket.cost += d.estCostUsd;
12476
+ }
12477
+ }
12478
+ console.log(`Decisions (retained ring): ${data.decisions.length}`);
12479
+ console.log(`Ring spend total: $${data.spentUsd.toFixed(4)}`);
12480
+ console.log("");
12481
+ console.log("TIER COUNT SHARE COST");
12482
+ for (const t of TIERS) {
12483
+ const b = byTier.get(t);
12484
+ const share = Math.round(b.count / data.decisions.length * 100);
12485
+ console.log(
12486
+ `${t.padEnd(9)} ${String(b.count).padStart(5)} ${String(share).padStart(4)}% $${b.cost.toFixed(4)}`
12487
+ );
12488
+ }
12489
+ console.log("");
12490
+ const rows = tableLimit !== void 0 ? data.decisions.slice(0, tableLimit) : data.decisions;
12491
+ console.log(
12492
+ `TIMESTAMP TIER BACKEND COST${tableLimit !== void 0 ? ` (latest ${rows.length} of ${data.decisions.length})` : ""}`
12493
+ );
12494
+ for (const d of rows) {
12495
+ const ts = shortIso2(d.decisionTs).padEnd(13);
12496
+ const tier = d.tierRequired.padEnd(9);
12497
+ const be = d.backend.padEnd(15);
12498
+ console.log(`${ts} ${tier} ${be} $${d.estCostUsd.toFixed(4)}`);
12499
+ }
12500
+ }
12501
+ function createTelemetryCommand() {
12502
+ return new Command94("telemetry").description("Routing telemetry: per-decision tier/backend/cost + tier distribution (AMR)").option("--last <N>", "Show only the N most recent decisions in the per-decision table").option("--json", "Emit JSON to stdout instead of human-readable text").action(async (opts) => {
12503
+ const r = await getJson("/api/v1/routing/telemetry");
12504
+ if (!r.ok) {
12505
+ if (r.status === 0) {
12506
+ logger.error(
12507
+ `Failed to reach orchestrator at ${orchestratorBase()}: ${r.error ?? "unknown error"}`
12508
+ );
12509
+ } else {
12510
+ logger.error(`Request failed (${r.status}): ${r.error ?? ""}`);
12511
+ }
12512
+ process.exit(ExitCode.ERROR);
12513
+ return;
12514
+ }
12515
+ const body = r.body ?? { decisions: [], spentUsd: 0 };
12516
+ if (opts.json) {
12517
+ console.log(JSON.stringify(body, null, 2));
12518
+ return;
12519
+ }
12520
+ const tableLimit = opts.last && Number.isFinite(Number(opts.last)) && Number(opts.last) > 0 ? Math.floor(Number(opts.last)) : void 0;
12521
+ renderHuman4(body, tableLimit);
12522
+ });
12523
+ }
12524
+
12525
+ // src/commands/routing/status.ts
12526
+ import { Command as Command95 } from "commander";
12527
+ function bar(pct, width = 24) {
12528
+ const clamped = Math.max(0, Math.min(100, pct));
12529
+ const filled = Math.round(clamped / 100 * width);
12530
+ return `[${"#".repeat(filled)}${"-".repeat(width - filled)}]`;
12531
+ }
12532
+ function renderHuman5(s) {
12533
+ if (!s.active) {
12534
+ console.log("Adaptive routing: OFF (no routing.policy configured \u2014 dispatch is unchanged)");
12535
+ return;
12536
+ }
12537
+ console.log("Adaptive routing: ON");
12538
+ if (s.budget) {
12539
+ const b = s.budget;
12540
+ const state = b.exhausted ? "EXHAUSTED (hard cap \u2014 forcing fast / surfacing to steward)" : b.degrading ? "DEGRADING (clamping tiers down)" : "ok";
12541
+ console.log("");
12542
+ console.log("Budget:");
12543
+ console.log(
12544
+ ` $${b.spentUsd.toFixed(4)} / $${b.capUsd.toFixed(2)} ${bar(b.spentPct)} ${b.spentPct}%`
12545
+ );
12546
+ console.log(` degrade at ${b.degradeAtPct}% \u2192 ${state}`);
12547
+ } else {
12548
+ console.log("Budget: (none configured)");
12549
+ }
12550
+ console.log("");
12551
+ if (s.escalation.length === 0) {
12552
+ console.log("Escalation: (no units have climbed above the fast floor)");
12553
+ } else {
12554
+ console.log(`Escalation: ${s.escalation.length} unit(s) climbed`);
12555
+ console.log(" UNIT FLOOR");
12556
+ for (const u of s.escalation) {
12557
+ console.log(` ${u.coherenceUnit.padEnd(38)} ${u.floor}`);
12558
+ }
12559
+ }
12560
+ console.log("");
12561
+ console.log(
12562
+ `Allowlist: ${s.allowedProviders && s.allowedProviders.length > 0 ? s.allowedProviders.join(", ") : "(all providers allowed)"}`
12563
+ );
12564
+ }
12565
+ function createStatusCommand() {
12566
+ return new Command95("status").description(
12567
+ "Live routing status: budget spend-vs-cap, escalated units, provider allowlist (AMR)"
12568
+ ).option("--json", "Emit JSON to stdout instead of human-readable text").action(async (opts) => {
12569
+ const r = await getJson("/api/v1/routing/status");
12570
+ if (!r.ok) {
12571
+ if (r.status === 0) {
12572
+ logger.error(
12573
+ `Failed to reach orchestrator at ${orchestratorBase()}: ${r.error ?? "unknown error"}`
12574
+ );
12575
+ } else {
12576
+ logger.error(`Request failed (${r.status}): ${r.error ?? ""}`);
12577
+ }
12578
+ process.exit(ExitCode.ERROR);
12579
+ return;
12580
+ }
12581
+ const body = r.body ?? {
12582
+ active: false,
12583
+ budget: null,
12584
+ escalation: [],
12585
+ allowedProviders: null
12586
+ };
12587
+ if (opts.json) {
12588
+ console.log(JSON.stringify(body, null, 2));
12589
+ return;
12590
+ }
12591
+ renderHuman5(body);
12592
+ });
12593
+ }
12594
+
12009
12595
  // src/commands/routing/index.ts
12010
12596
  function createRoutingCommand() {
12011
- const cmd = new Command93("routing").description(
12012
- "Inspect routing config, trace decisions, and read recent dispatches"
12597
+ const cmd = new Command96("routing").description(
12598
+ "Inspect routing config, trace decisions, and read AMR telemetry + status"
12013
12599
  );
12014
12600
  cmd.addCommand(createConfigCommand());
12015
12601
  cmd.addCommand(createTraceCommand());
12016
12602
  cmd.addCommand(createDecisionsCommand());
12603
+ cmd.addCommand(createTelemetryCommand());
12604
+ cmd.addCommand(createStatusCommand());
12017
12605
  return cmd;
12018
12606
  }
12019
12607
 
12020
12608
  // src/commands/scan-config.ts
12021
12609
  init_dist3();
12022
- import { Command as Command94 } from "commander";
12610
+ import { Command as Command97 } from "commander";
12023
12611
  import { existsSync as existsSync31, readFileSync as readFileSync22, writeFileSync as writeFileSync23 } from "fs";
12024
- import { join as join50, relative as relative4 } from "path";
12612
+ import { join as join51, relative as relative4 } from "path";
12025
12613
  var CONFIG_FILES = ["CLAUDE.md", "AGENTS.md", ".gemini/settings.json", "skill.yaml"];
12026
12614
  function stripHighSeverityPatterns(content, injectionFindings) {
12027
12615
  const highLines = /* @__PURE__ */ new Set();
@@ -12078,7 +12666,7 @@ async function runScanConfig(targetDir, options) {
12078
12666
  const scanner = new SecurityScanner(parseSecurityConfig({}));
12079
12667
  const results = [];
12080
12668
  for (const configFile of CONFIG_FILES) {
12081
- const result = scanSingleFile(join50(targetDir, configFile), targetDir, scanner, options);
12669
+ const result = scanSingleFile(join51(targetDir, configFile), targetDir, scanner, options);
12082
12670
  if (result) results.push(result);
12083
12671
  }
12084
12672
  return { exitCode: computeScanExitCode(results), results };
@@ -12108,7 +12696,7 @@ function formatTextOutput(result) {
12108
12696
  }
12109
12697
  }
12110
12698
  function createScanConfigCommand() {
12111
- const command = new Command94("scan-config").description(
12699
+ const command = new Command97("scan-config").description(
12112
12700
  "Scan CLAUDE.md, AGENTS.md, .gemini/settings.json, and skill.yaml for prompt injection patterns"
12113
12701
  ).option("--path <dir>", "Target directory to scan (default: cwd)").option("--fix", "Strip high-severity patterns from files in-place").action(async (opts, cmd) => {
12114
12702
  const globalOpts = cmd.optsWithGlobals();
@@ -12126,7 +12714,7 @@ function createScanConfigCommand() {
12126
12714
 
12127
12715
  // src/commands/search.ts
12128
12716
  init_dist();
12129
- import { Command as Command95 } from "commander";
12717
+ import { Command as Command98 } from "commander";
12130
12718
  function parseFileKinds(raw) {
12131
12719
  if (!raw) return void 0;
12132
12720
  const set = /* @__PURE__ */ new Set();
@@ -12147,7 +12735,7 @@ function fmtBytes(n) {
12147
12735
  return n.toFixed(0);
12148
12736
  }
12149
12737
  function createSearchCommand() {
12150
- return new Command95("search").description("Full-text search over archived + live session content.").argument(
12738
+ return new Command98("search").description("Full-text search over archived + live session content.").argument(
12151
12739
  "<query>",
12152
12740
  "FTS5 query (bare words AND-joined; quotes/AND/OR/NOT/column: for advanced syntax)"
12153
12741
  ).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(
@@ -12207,9 +12795,9 @@ function createSearchCommand() {
12207
12795
  }
12208
12796
 
12209
12797
  // src/commands/security-craft.ts
12210
- import { Command as Command96 } from "commander";
12798
+ import { Command as Command99 } from "commander";
12211
12799
  function createSecurityCraftCommand() {
12212
- return new Command96("security-craft").description(
12800
+ return new Command99("security-craft").description(
12213
12801
  "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."
12214
12802
  ).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) => {
12215
12803
  const globalOpts = cmd.optsWithGlobals();
@@ -12275,7 +12863,7 @@ ${file}`);
12275
12863
  }
12276
12864
 
12277
12865
  // src/commands/setup.ts
12278
- import { Command as Command97 } from "commander";
12866
+ import { Command as Command100 } from "commander";
12279
12867
  import * as fs38 from "fs";
12280
12868
  import * as os9 from "os";
12281
12869
  import * as path62 from "path";
@@ -12314,10 +12902,10 @@ function prompt2(question) {
12314
12902
  input: process.stdin,
12315
12903
  output: process.stdout
12316
12904
  });
12317
- return new Promise((resolve50) => {
12905
+ return new Promise((resolve49) => {
12318
12906
  rl.question(question, (answer) => {
12319
12907
  rl.close();
12320
- resolve50(answer.trim().toLowerCase());
12908
+ resolve49(answer.trim().toLowerCase());
12321
12909
  });
12322
12910
  });
12323
12911
  }
@@ -12326,10 +12914,10 @@ function promptRaw(question) {
12326
12914
  input: process.stdin,
12327
12915
  output: process.stdout
12328
12916
  });
12329
- return new Promise((resolve50) => {
12917
+ return new Promise((resolve49) => {
12330
12918
  rl.question(question, (answer) => {
12331
12919
  rl.close();
12332
- resolve50(answer.trim());
12920
+ resolve49(answer.trim());
12333
12921
  });
12334
12922
  });
12335
12923
  }
@@ -12620,7 +13208,7 @@ async function runSetup(cwd) {
12620
13208
  return { steps, success };
12621
13209
  }
12622
13210
  function createSetupCommand() {
12623
- return new Command97("setup").description("Configure harness environment: slash commands, MCP, and more").action(async () => {
13211
+ return new Command100("setup").description("Configure harness environment: slash commands, MCP, and more").action(async () => {
12624
13212
  const cwd = process.cwd();
12625
13213
  console.log("");
12626
13214
  console.log(` ${chalk16.bold("harness setup")}`);
@@ -12643,7 +13231,7 @@ function createSetupCommand() {
12643
13231
 
12644
13232
  // src/commands/share.ts
12645
13233
  init_dist3();
12646
- import { Command as Command98 } from "commander";
13234
+ import { Command as Command101 } from "commander";
12647
13235
  import * as fs39 from "fs";
12648
13236
  import * as path63 from "path";
12649
13237
  import { parse as parseYaml3 } from "yaml";
@@ -12702,16 +13290,16 @@ Create a constraints.yaml in your project root to define what to share.`
12702
13290
  logger.success(`Bundle written to ${outputPath}`);
12703
13291
  }
12704
13292
  function createShareCommand() {
12705
- return new Command98("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) => {
13293
+ return new Command101("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) => {
12706
13294
  await runShareAction(projectPath, options);
12707
13295
  });
12708
13296
  }
12709
13297
 
12710
13298
  // src/commands/skill/index.ts
12711
- import { Command as Command106 } from "commander";
13299
+ import { Command as Command109 } from "commander";
12712
13300
 
12713
13301
  // src/commands/skill/list.ts
12714
- import { Command as Command99 } from "commander";
13302
+ import { Command as Command102 } from "commander";
12715
13303
  import * as fs40 from "fs";
12716
13304
  import * as path64 from "path";
12717
13305
  import { parse } from "yaml";
@@ -12814,7 +13402,7 @@ function printSkillsVerbose(skills) {
12814
13402
  for (const s of skills) printSkillEntry(s);
12815
13403
  }
12816
13404
  function createListCommand3() {
12817
- return new Command99("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) => {
13405
+ return new Command102("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) => {
12818
13406
  const globalOpts = cmd.optsWithGlobals();
12819
13407
  const skills = collectSkills({ filter: resolveFilter(opts) });
12820
13408
  if (globalOpts.json) {
@@ -12829,13 +13417,13 @@ function createListCommand3() {
12829
13417
  }
12830
13418
 
12831
13419
  // src/commands/skill/run.ts
12832
- import { Command as Command100 } from "commander";
13420
+ import { Command as Command103 } from "commander";
12833
13421
  import * as fs41 from "fs";
12834
13422
  import * as path65 from "path";
12835
13423
  import { parse as parse2 } from "yaml";
12836
13424
 
12837
13425
  // src/skill/complexity.ts
12838
- import { execFileSync as execFileSync8 } from "child_process";
13426
+ import { execFileSync as execFileSync11 } from "child_process";
12839
13427
  function evaluateSignals(signals) {
12840
13428
  if (signals.fileCount >= 3) return "thorough";
12841
13429
  if (signals.newDir) return "thorough";
@@ -12847,17 +13435,17 @@ function evaluateSignals(signals) {
12847
13435
  }
12848
13436
  function detectComplexity(projectPath) {
12849
13437
  try {
12850
- const base = execFileSync8("git", ["merge-base", "HEAD", "main"], {
13438
+ const base = execFileSync11("git", ["merge-base", "HEAD", "main"], {
12851
13439
  cwd: projectPath,
12852
13440
  encoding: "utf-8",
12853
13441
  stdio: ["pipe", "pipe", "pipe"]
12854
13442
  }).trim();
12855
- const diffFiles = execFileSync8("git", ["diff", "--name-only", base], {
13443
+ const diffFiles = execFileSync11("git", ["diff", "--name-only", base], {
12856
13444
  cwd: projectPath,
12857
13445
  encoding: "utf-8",
12858
13446
  stdio: ["pipe", "pipe", "pipe"]
12859
13447
  }).trim().split("\n").filter(Boolean);
12860
- const diffStat = execFileSync8("git", ["diff", "--stat", base], {
13448
+ const diffStat = execFileSync11("git", ["diff", "--stat", base], {
12861
13449
  cwd: projectPath,
12862
13450
  encoding: "utf-8",
12863
13451
  stdio: ["pipe", "pipe", "pipe"]
@@ -12977,7 +13565,7 @@ function resolvePhaseState(metadata, projectPath, phase) {
12977
13565
  }
12978
13566
  async function appendProjectState(content, metadata, projectPath, hasPathOpt) {
12979
13567
  if (!metadata?.state.persistent || !hasPathOpt) return content;
12980
- const { readHarnessState: readHarnessState2, isEmptyHarnessState } = await import("./state-events-PBDNQPXT.js");
13568
+ const { readHarnessState: readHarnessState2, isEmptyHarnessState } = await import("./state-events-PTWAEGJ2.js");
12981
13569
  const stateResult = await readHarnessState2(projectPath);
12982
13570
  if (!stateResult.ok || isEmptyHarnessState(stateResult.value)) return content;
12983
13571
  const stateContent = JSON.stringify(stateResult.value, null, 2);
@@ -13043,14 +13631,14 @@ async function runSkill(name, opts) {
13043
13631
  process.exit(ExitCode.SUCCESS);
13044
13632
  }
13045
13633
  function createRunCommand3() {
13046
- return new Command100("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(
13634
+ return new Command103("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(
13047
13635
  "--backend <name>",
13048
13636
  "Spec B: one-shot routing override forwarded to the orchestrator as HARNESS_BACKEND_OVERRIDE"
13049
13637
  ).action(async (name, opts) => runSkill(name, opts));
13050
13638
  }
13051
13639
 
13052
13640
  // src/commands/skill/validate.ts
13053
- import { Command as Command101 } from "commander";
13641
+ import { Command as Command104 } from "commander";
13054
13642
  import * as fs42 from "fs";
13055
13643
  import * as path66 from "path";
13056
13644
  import { parse as parse3 } from "yaml";
@@ -13114,7 +13702,7 @@ function validateSkillEntry(name, skillsDir, errors) {
13114
13702
  }
13115
13703
  }
13116
13704
  function createValidateCommand2() {
13117
- return new Command101("validate").description("Validate all skill.yaml files and SKILL.md structure").action(async (_opts, cmd) => {
13705
+ return new Command104("validate").description("Validate all skill.yaml files and SKILL.md structure").action(async (_opts, cmd) => {
13118
13706
  const globalOpts = cmd.optsWithGlobals();
13119
13707
  const skillsDir = resolveSkillsDir();
13120
13708
  if (!fs42.existsSync(skillsDir)) {
@@ -13144,7 +13732,7 @@ function createValidateCommand2() {
13144
13732
  }
13145
13733
 
13146
13734
  // src/commands/skill/info.ts
13147
- import { Command as Command102 } from "commander";
13735
+ import { Command as Command105 } from "commander";
13148
13736
  import * as fs43 from "fs";
13149
13737
  import * as path67 from "path";
13150
13738
  import { parse as parse4 } from "yaml";
@@ -13189,7 +13777,7 @@ function printSkillInfo(skill) {
13189
13777
  console.log(`Persistent: ${skill.state.persistent}`);
13190
13778
  }
13191
13779
  function createInfoCommand() {
13192
- return new Command102("info").description("Show metadata for a skill").argument("<name>", "Skill name (e.g., harness-tdd)").action(async (name, _opts, cmd) => {
13780
+ return new Command105("info").description("Show metadata for a skill").argument("<name>", "Skill name (e.g., harness-tdd)").action(async (name, _opts, cmd) => {
13193
13781
  const globalOpts = cmd.optsWithGlobals();
13194
13782
  const loaded = loadSkillMetadata2(name);
13195
13783
  if (!loaded.ok) {
@@ -13206,7 +13794,7 @@ function createInfoCommand() {
13206
13794
  }
13207
13795
 
13208
13796
  // src/commands/skill/search.ts
13209
- import { Command as Command103 } from "commander";
13797
+ import { Command as Command106 } from "commander";
13210
13798
  async function runSearch(query, opts) {
13211
13799
  const results = await searchNpmRegistry(query, opts.registry);
13212
13800
  return results.filter((r) => {
@@ -13251,13 +13839,13 @@ async function runSearchAction(query, opts, globalOpts) {
13251
13839
  }
13252
13840
  }
13253
13841
  function createSearchCommand2() {
13254
- return new Command103("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) => {
13842
+ return new Command106("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) => {
13255
13843
  await runSearchAction(query, opts, cmd.optsWithGlobals());
13256
13844
  });
13257
13845
  }
13258
13846
 
13259
13847
  // src/commands/skill/create.ts
13260
- import { Command as Command104 } from "commander";
13848
+ import { Command as Command107 } from "commander";
13261
13849
  import * as path68 from "path";
13262
13850
  import * as fs44 from "fs";
13263
13851
  import YAML from "yaml";
@@ -13377,7 +13965,7 @@ Next steps:`);
13377
13965
  logger.info(` 3. Run: harness skills publish`);
13378
13966
  }
13379
13967
  function createCreateCommand() {
13380
- return new Command104("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) => {
13968
+ return new Command107("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) => {
13381
13969
  const globalOpts = cmd.optsWithGlobals();
13382
13970
  try {
13383
13971
  const result = runCreate(name, {
@@ -13400,10 +13988,10 @@ function createCreateCommand() {
13400
13988
  }
13401
13989
 
13402
13990
  // src/commands/skill/publish.ts
13403
- import { Command as Command105 } from "commander";
13991
+ import { Command as Command108 } from "commander";
13404
13992
  import * as fs46 from "fs";
13405
13993
  import * as path70 from "path";
13406
- import { execFileSync as execFileSync9 } from "child_process";
13994
+ import { execFileSync as execFileSync12 } from "child_process";
13407
13995
 
13408
13996
  // src/registry/validator.ts
13409
13997
  import * as fs45 from "fs";
@@ -13557,7 +14145,7 @@ ${skillMdContent}`;
13557
14145
  if (opts.registry) {
13558
14146
  publishArgs.push("--registry", opts.registry);
13559
14147
  }
13560
- execFileSync9("npm", publishArgs, {
14148
+ execFileSync12("npm", publishArgs, {
13561
14149
  cwd: skillDir,
13562
14150
  stdio: "pipe",
13563
14151
  timeout: 6e4
@@ -13569,7 +14157,7 @@ ${skillMdContent}`;
13569
14157
  };
13570
14158
  }
13571
14159
  function createPublishCommand() {
13572
- return new Command105("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) => {
14160
+ return new Command108("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) => {
13573
14161
  const globalOpts = cmd.optsWithGlobals();
13574
14162
  const skillDir = opts.dir || process.cwd();
13575
14163
  try {
@@ -13594,7 +14182,7 @@ function createPublishCommand() {
13594
14182
 
13595
14183
  // src/commands/skill/index.ts
13596
14184
  function createSkillCommand() {
13597
- const command = new Command106("skill").description("Skill management commands");
14185
+ const command = new Command109("skill").description("Skill management commands");
13598
14186
  command.addCommand(createListCommand3());
13599
14187
  command.addCommand(createRunCommand3());
13600
14188
  command.addCommand(createValidateCommand2());
@@ -13607,7 +14195,7 @@ function createSkillCommand() {
13607
14195
 
13608
14196
  // src/commands/snapshot.ts
13609
14197
  init_dist3();
13610
- import { Command as Command107 } from "commander";
14198
+ import { Command as Command110 } from "commander";
13611
14199
  import { execSync as execSync5 } from "child_process";
13612
14200
  import chalk17 from "chalk";
13613
14201
  function getCommitHash3(cwd) {
@@ -13789,7 +14377,7 @@ function registerListCommand2(parent) {
13789
14377
  });
13790
14378
  }
13791
14379
  function createSnapshotCommand() {
13792
- const command = new Command107("snapshot").description("Architecture timeline snapshot commands");
14380
+ const command = new Command110("snapshot").description("Architecture timeline snapshot commands");
13793
14381
  registerCaptureCommand(command);
13794
14382
  registerTrendsCommand(command);
13795
14383
  registerListCommand2(command);
@@ -13797,9 +14385,9 @@ function createSnapshotCommand() {
13797
14385
  }
13798
14386
 
13799
14387
  // src/commands/spec-craft.ts
13800
- import { Command as Command108 } from "commander";
14388
+ import { Command as Command111 } from "commander";
13801
14389
  function createSpecCraftCommand() {
13802
- return new Command108("spec-craft").description(
14390
+ return new Command111("spec-craft").description(
13803
14391
  "LLM-judgment critique of spec quality (proposals + ADRs). Second craft-pipeline ceiling skill; 7 seed rubrics from the spec-quality canon. Per-section critique."
13804
14392
  ).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) => {
13805
14393
  const globalOpts = cmd.optsWithGlobals();
@@ -13867,7 +14455,7 @@ ${file}`);
13867
14455
 
13868
14456
  // src/commands/stale-constraints.ts
13869
14457
  init_dist3();
13870
- import { Command as Command109 } from "commander";
14458
+ import { Command as Command112 } from "commander";
13871
14459
  import chalk18 from "chalk";
13872
14460
  var CATEGORIES = [
13873
14461
  "circular-deps",
@@ -13954,7 +14542,7 @@ async function runStaleConstraintsCommand(options) {
13954
14542
  );
13955
14543
  }
13956
14544
  function createStaleConstraintsCommand() {
13957
- return new Command109("stale-constraints").description(
14545
+ return new Command112("stale-constraints").description(
13958
14546
  "Detect architectural constraints not violated within a window (candidates for removal)"
13959
14547
  ).option(
13960
14548
  "--window <days>",
@@ -13972,10 +14560,10 @@ function createStaleConstraintsCommand() {
13972
14560
  }
13973
14561
 
13974
14562
  // src/commands/state/index.ts
13975
- import { Command as Command114 } from "commander";
14563
+ import { Command as Command117 } from "commander";
13976
14564
 
13977
14565
  // src/commands/state/show.ts
13978
- import { Command as Command110 } from "commander";
14566
+ import { Command as Command113 } from "commander";
13979
14567
  import * as path71 from "path";
13980
14568
  function printStateText(state, stream) {
13981
14569
  if (stream) console.log(`Stream: ${stream}`);
@@ -14000,7 +14588,7 @@ function printStateProgress(progress) {
14000
14588
  }
14001
14589
  }
14002
14590
  function createShowCommand() {
14003
- return new Command110("show").description("Show current project state").option("--path <path>", "Project root path", ".").option("--stream <name>", "Target a specific stream").action(async (opts, cmd) => {
14591
+ return new Command113("show").description("Show current project state").option("--path <path>", "Project root path", ".").option("--stream <name>", "Target a specific stream").action(async (opts, cmd) => {
14004
14592
  const globalOpts = cmd.optsWithGlobals();
14005
14593
  const result = await readHarnessState(path71.resolve(opts.path), { stream: opts.stream });
14006
14594
  if (!result.ok) {
@@ -14018,13 +14606,13 @@ function createShowCommand() {
14018
14606
 
14019
14607
  // src/commands/state/reset.ts
14020
14608
  init_dist3();
14021
- import { Command as Command111 } from "commander";
14609
+ import { Command as Command114 } from "commander";
14022
14610
  import * as path72 from "path";
14023
14611
  import * as readline3 from "readline";
14024
14612
  async function confirmReset() {
14025
14613
  const rl = readline3.createInterface({ input: process.stdin, output: process.stdout });
14026
- const answer = await new Promise((resolve50) => {
14027
- rl.question("Reset project state? This cannot be undone. [y/N] ", resolve50);
14614
+ const answer = await new Promise((resolve49) => {
14615
+ rl.question("Reset project state? This cannot be undone. [y/N] ", resolve49);
14028
14616
  });
14029
14617
  rl.close();
14030
14618
  return answer.toLowerCase() === "y" || answer.toLowerCase() === "yes";
@@ -14044,15 +14632,15 @@ async function runReset(opts) {
14044
14632
  process.exit(ExitCode.SUCCESS);
14045
14633
  }
14046
14634
  function createResetCommand() {
14047
- return new Command111("reset").description("Reset project state (truncates the event log to a fresh default)").option("--path <path>", "Project root path", ".").option("--stream <name>", "Target a specific stream").option("--yes", "Skip confirmation prompt").action(async (opts) => runReset(opts));
14635
+ return new Command114("reset").description("Reset project state (truncates the event log to a fresh default)").option("--path <path>", "Project root path", ".").option("--stream <name>", "Target a specific stream").option("--yes", "Skip confirmation prompt").action(async (opts) => runReset(opts));
14048
14636
  }
14049
14637
 
14050
14638
  // src/commands/state/learn.ts
14051
14639
  init_dist3();
14052
- import { Command as Command112 } from "commander";
14640
+ import { Command as Command115 } from "commander";
14053
14641
  import * as path73 from "path";
14054
14642
  function createLearnCommand() {
14055
- return new Command112("learn").description("Append a learning to .harness/learnings.md").argument("<message>", "The learning to record").option("--path <path>", "Project root path", ".").option("--stream <name>", "Target a specific stream").action(async (message, opts, _cmd) => {
14643
+ return new Command115("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) => {
14056
14644
  const projectPath = path73.resolve(opts.path);
14057
14645
  const result = await appendLearning(projectPath, message, void 0, void 0, opts.stream);
14058
14646
  if (!result.ok) {
@@ -14067,7 +14655,7 @@ function createLearnCommand() {
14067
14655
 
14068
14656
  // src/commands/state/streams.ts
14069
14657
  init_dist3();
14070
- import { Command as Command113 } from "commander";
14658
+ import { Command as Command116 } from "commander";
14071
14659
  import * as path74 from "path";
14072
14660
  async function runListStreams(opts, globalOpts) {
14073
14661
  const projectPath = path74.resolve(opts.path);
@@ -14118,7 +14706,7 @@ async function runActivateStream(name, opts) {
14118
14706
  process.exit(ExitCode.SUCCESS);
14119
14707
  }
14120
14708
  function createStreamsCommand() {
14121
- const command = new Command113("streams").description("Manage state streams");
14709
+ const command = new Command116("streams").description("Manage state streams");
14122
14710
  command.command("list").description("List all known streams").option("--path <path>", "Project root path", ".").action(async (opts, cmd) => runListStreams(opts, cmd.optsWithGlobals()));
14123
14711
  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));
14124
14712
  command.command("archive <name>").description("Archive a stream").option("--path <path>", "Project root path", ".").action(async (name, opts) => runArchiveStream(name, opts));
@@ -14128,7 +14716,7 @@ function createStreamsCommand() {
14128
14716
 
14129
14717
  // src/commands/state/index.ts
14130
14718
  function createStateCommand() {
14131
- const command = new Command114("state").description("Project state management commands");
14719
+ const command = new Command117("state").description("Project state management commands");
14132
14720
  command.addCommand(createShowCommand());
14133
14721
  command.addCommand(createResetCommand());
14134
14722
  command.addCommand(createLearnCommand());
@@ -14139,7 +14727,7 @@ function createStateCommand() {
14139
14727
  // src/commands/sync-analyses.ts
14140
14728
  import * as fs47 from "fs";
14141
14729
  import * as path75 from "path";
14142
- import { Command as Command115 } from "commander";
14730
+ import { Command as Command118 } from "commander";
14143
14731
  init_dist3();
14144
14732
  function isValidRecord(record) {
14145
14733
  return typeof record.issueId === "string" && !!record.issueId && typeof record.identifier === "string" && !!record.identifier && typeof record.analyzedAt === "string" && !/[/\\]/.test(record.issueId);
@@ -14264,7 +14852,7 @@ async function runSyncAnalyses(opts) {
14264
14852
  return;
14265
14853
  }
14266
14854
  const { AnalysisArchive, loadPublishedIndex: loadPublishedIndex2, savePublishedIndex: savePublishedIndex2 } = await import("@harness-engineering/orchestrator");
14267
- const { GitHubIssuesSyncAdapter: GitHubIssuesSyncAdapter2 } = await import("./dist-BWFFVKEW.js");
14855
+ const { GitHubIssuesSyncAdapter: GitHubIssuesSyncAdapter2 } = await import("./dist-4CZLCE33.js");
14268
14856
  const adapter = new GitHubIssuesSyncAdapter2({ token, config: trackerConfig });
14269
14857
  const archive = new AnalysisArchive(path75.join(projectPath, ".harness", "analyses"));
14270
14858
  const publishedIndex = loadPublishedIndex2(projectPath);
@@ -14286,7 +14874,7 @@ async function runSyncAnalyses(opts) {
14286
14874
  }
14287
14875
  }
14288
14876
  function createSyncAnalysesCommand() {
14289
- const command = new Command115("sync-analyses").description(
14877
+ const command = new Command118("sync-analyses").description(
14290
14878
  "Pull published intelligence analyses from the external issue tracker into the local .harness/analyses/ directory"
14291
14879
  ).option("-d, --dir <path>", "Workspace directory", process.cwd()).action(async (opts) => {
14292
14880
  try {
@@ -14300,7 +14888,7 @@ function createSyncAnalysesCommand() {
14300
14888
  }
14301
14889
 
14302
14890
  // src/commands/sync-main.ts
14303
- import { Command as Command116 } from "commander";
14891
+ import { Command as Command119 } from "commander";
14304
14892
  import * as path76 from "path";
14305
14893
  import {
14306
14894
  syncMain as defaultSyncMain
@@ -14331,7 +14919,7 @@ function formatHuman2(r) {
14331
14919
  }
14332
14920
  }
14333
14921
  function createSyncMainCommand() {
14334
- return new Command116("sync-main").description("Fast-forward the local default branch from origin (no-op on conflict)").option("--json", "Emit a SyncMainResult JSON object", false).option("--path <path>", "Project root path", ".").action(async (opts) => {
14922
+ return new Command119("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) => {
14335
14923
  const cwd = path76.resolve(opts.path ?? ".");
14336
14924
  const exitCode = await runSyncMain({ cwd, json: Boolean(opts.json) });
14337
14925
  process.exit(exitCode);
@@ -14340,7 +14928,7 @@ function createSyncMainCommand() {
14340
14928
 
14341
14929
  // src/commands/taint.ts
14342
14930
  init_dist3();
14343
- import { Command as Command117 } from "commander";
14931
+ import { Command as Command120 } from "commander";
14344
14932
  function getProjectRoot() {
14345
14933
  return process.cwd();
14346
14934
  }
@@ -14412,18 +15000,18 @@ function registerStatusCommand(taint) {
14412
15000
  });
14413
15001
  }
14414
15002
  function createTaintCommand() {
14415
- const taint = new Command117("taint").description("Manage sentinel session taint state");
15003
+ const taint = new Command120("taint").description("Manage sentinel session taint state");
14416
15004
  registerClearCommand(taint);
14417
15005
  registerStatusCommand(taint);
14418
15006
  return taint;
14419
15007
  }
14420
15008
 
14421
15009
  // src/commands/telemetry/index.ts
14422
- import { Command as Command121 } from "commander";
15010
+ import { Command as Command124 } from "commander";
14423
15011
 
14424
15012
  // src/commands/telemetry/identify.ts
14425
15013
  init_dist3();
14426
- import { Command as Command118 } from "commander";
15014
+ import { Command as Command121 } from "commander";
14427
15015
  import * as fs48 from "fs";
14428
15016
  import * as path77 from "path";
14429
15017
  function telemetryFilePath(cwd) {
@@ -14447,7 +15035,7 @@ function printIdentity(identity) {
14447
15035
  }
14448
15036
  }
14449
15037
  function createIdentifyCommand() {
14450
- const cmd = new Command118("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) => {
15038
+ const cmd = new Command121("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) => {
14451
15039
  const cwd = process.cwd();
14452
15040
  if (opts.clear) {
14453
15041
  writeTelemetryFile(cwd, { identity: {} });
@@ -14472,7 +15060,7 @@ function createIdentifyCommand() {
14472
15060
 
14473
15061
  // src/commands/telemetry/status.ts
14474
15062
  init_dist3();
14475
- import { Command as Command119 } from "commander";
15063
+ import { Command as Command122 } from "commander";
14476
15064
  function gatherEnvOverrides() {
14477
15065
  const overrides = {};
14478
15066
  if (process.env.DO_NOT_TRACK) overrides.DO_NOT_TRACK = process.env.DO_NOT_TRACK;
@@ -14513,8 +15101,8 @@ function printHumanStatus(result) {
14513
15101
  printIdentity2(result.identity);
14514
15102
  printEnvOverrides(result.envOverrides);
14515
15103
  }
14516
- function createStatusCommand() {
14517
- const cmd = new Command119("status").description("Show current telemetry consent state, install ID, and identity").option("--json", "Output as JSON").action((opts) => {
15104
+ function createStatusCommand2() {
15105
+ const cmd = new Command122("status").description("Show current telemetry consent state, install ID, and identity").option("--json", "Output as JSON").action((opts) => {
14518
15106
  const cwd = process.cwd();
14519
15107
  const envOverrides = gatherEnvOverrides();
14520
15108
  const consent = resolveConsent(cwd, void 0);
@@ -14547,20 +15135,20 @@ function createStatusCommand() {
14547
15135
 
14548
15136
  // src/commands/telemetry/test.ts
14549
15137
  init_dist3();
14550
- import { Command as Command120 } from "commander";
15138
+ import { Command as Command123 } from "commander";
14551
15139
 
14552
15140
  // src/bin/command-telemetry.ts
14553
- import { existsSync as existsSync44, readFileSync as readFileSync32, mkdirSync as mkdirSync23, appendFileSync, writeFileSync as writeFileSync29 } from "fs";
14554
- import { join as join64, parse as parsePath, resolve as resolve47 } from "path";
15141
+ import { existsSync as existsSync44, readFileSync as readFileSync32, mkdirSync as mkdirSync24, appendFileSync as appendFileSync2, writeFileSync as writeFileSync29 } from "fs";
15142
+ import { join as join65, parse as parsePath, resolve as resolve46 } from "path";
14555
15143
  import { spawn as spawn2 } from "child_process";
14556
15144
  var POSTHOG_API_KEY = "phc_wNTdCMcfJXZPgdNeDociZW6vwoGGo4nb7vqEfWThFfsG";
14557
15145
  var EXCLUDED_COMMANDS = /* @__PURE__ */ new Set(["help", "completion"]);
14558
15146
  function findProjectRoot(cwd) {
14559
- let dir = resolve47(cwd);
15147
+ let dir = resolve46(cwd);
14560
15148
  const { root } = parsePath(dir);
14561
15149
  while (dir !== root) {
14562
- if (existsSync44(join64(dir, "harness.config.json"))) return dir;
14563
- dir = resolve47(dir, "..");
15150
+ if (existsSync44(join65(dir, "harness.config.json"))) return dir;
15151
+ dir = resolve46(dir, "..");
14564
15152
  }
14565
15153
  return cwd;
14566
15154
  }
@@ -14597,8 +15185,8 @@ function resolveCommandName(cmd) {
14597
15185
  }
14598
15186
  function writeCommandRecordSync(cwd, command, duration, outcome) {
14599
15187
  try {
14600
- const metricsDir = join64(cwd, ".harness", "metrics");
14601
- mkdirSync23(metricsDir, { recursive: true });
15188
+ const metricsDir = join65(cwd, ".harness", "metrics");
15189
+ mkdirSync24(metricsDir, { recursive: true });
14602
15190
  const record = {
14603
15191
  skill: command,
14604
15192
  session: `cli-${Date.now()}`,
@@ -14607,13 +15195,13 @@ function writeCommandRecordSync(cwd, command, duration, outcome) {
14607
15195
  outcome,
14608
15196
  phasesReached: []
14609
15197
  };
14610
- const adoptionFile = join64(metricsDir, "adoption.jsonl");
14611
- appendFileSync(adoptionFile, JSON.stringify(record) + "\n");
15198
+ const adoptionFile = join65(metricsDir, "adoption.jsonl");
15199
+ appendFileSync2(adoptionFile, JSON.stringify(record) + "\n");
14612
15200
  } catch {
14613
15201
  }
14614
15202
  }
14615
15203
  function isTelemetryDisabledByConfig(cwd) {
14616
- const configPath = join64(cwd, "harness.config.json");
15204
+ const configPath = join65(cwd, "harness.config.json");
14617
15205
  if (!existsSync44(configPath)) return false;
14618
15206
  try {
14619
15207
  const config = JSON.parse(readFileSync32(configPath, "utf-8"));
@@ -14628,10 +15216,10 @@ function isTelemetryOptedOut(cwd) {
14628
15216
  }
14629
15217
  function flushTelemetryBackground(cwd) {
14630
15218
  try {
14631
- const adoptionFile = join64(cwd, ".harness", "metrics", "adoption.jsonl");
15219
+ const adoptionFile = join65(cwd, ".harness", "metrics", "adoption.jsonl");
14632
15220
  if (!existsSync44(adoptionFile)) return;
14633
15221
  if (isTelemetryOptedOut(cwd)) return;
14634
- const reporterPath = join64(cwd, ".harness", "hooks", "telemetry-reporter.js");
15222
+ const reporterPath = join65(cwd, ".harness", "hooks", "telemetry-reporter.js");
14635
15223
  if (!existsSync44(reporterPath)) return;
14636
15224
  const child = spawn2(process.execPath, [reporterPath], {
14637
15225
  cwd,
@@ -14669,7 +15257,7 @@ function reportTestSuccess(status, distinctId, identity) {
14669
15257
  if (identity.team) logger.info(` team: ${identity.team}`);
14670
15258
  }
14671
15259
  function createTestCommand() {
14672
- return new Command120("test").description("Send a test event to PostHog and verify connectivity").action(async () => {
15260
+ return new Command123("test").description("Send a test event to PostHog and verify connectivity").action(async () => {
14673
15261
  const cwd = process.cwd();
14674
15262
  const consent = resolveConsent(cwd, void 0);
14675
15263
  if (!consent.allowed) {
@@ -14705,18 +15293,18 @@ function createTestCommand() {
14705
15293
  }
14706
15294
 
14707
15295
  // src/commands/telemetry/index.ts
14708
- function createTelemetryCommand() {
14709
- const command = new Command121("telemetry").description("Telemetry identity and status management");
15296
+ function createTelemetryCommand2() {
15297
+ const command = new Command124("telemetry").description("Telemetry identity and status management");
14710
15298
  command.addCommand(createIdentifyCommand());
14711
- command.addCommand(createStatusCommand());
15299
+ command.addCommand(createStatusCommand2());
14712
15300
  command.addCommand(createTestCommand());
14713
15301
  return command;
14714
15302
  }
14715
15303
 
14716
15304
  // src/commands/test-craft.ts
14717
- import { Command as Command122 } from "commander";
15305
+ import { Command as Command125 } from "commander";
14718
15306
  function createTestCraftCommand() {
14719
- return new Command122("test-craft").description(
15307
+ return new Command125("test-craft").description(
14720
15308
  "LLM-judgment critique of test quality across vitest/jest/mocha/playwright. Fourth craft-pipeline ceiling skill. Per-test critique with best-effort source pairing."
14721
15309
  ).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) => {
14722
15310
  const globalOpts = cmd.optsWithGlobals();
@@ -14786,7 +15374,7 @@ ${file}`);
14786
15374
  }
14787
15375
 
14788
15376
  // src/commands/traceability.ts
14789
- import { Command as Command123 } from "commander";
15377
+ import { Command as Command126 } from "commander";
14790
15378
  import chalk19 from "chalk";
14791
15379
  function confidenceLabel(maxConfidence) {
14792
15380
  if (maxConfidence >= 0.8) return "explicit";
@@ -14926,7 +15514,7 @@ async function runTraceability(options) {
14926
15514
  process.exit(ExitCode.SUCCESS);
14927
15515
  }
14928
15516
  function createTraceabilityCommand() {
14929
- return new Command123("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) => {
15517
+ return new Command126("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) => {
14930
15518
  const globalOpts = cmd.optsWithGlobals();
14931
15519
  await runTraceability({
14932
15520
  spec: opts.spec,
@@ -14940,7 +15528,7 @@ function createTraceabilityCommand() {
14940
15528
 
14941
15529
  // src/commands/uninstall.ts
14942
15530
  import * as path78 from "path";
14943
- import { Command as Command124 } from "commander";
15531
+ import { Command as Command127 } from "commander";
14944
15532
  async function runUninstall(skillName, options) {
14945
15533
  const packageName = resolvePackageName(skillName);
14946
15534
  const shortName = extractSkillName(packageName);
@@ -14977,7 +15565,7 @@ async function runUninstall(skillName, options) {
14977
15565
  return result;
14978
15566
  }
14979
15567
  function createUninstallCommand() {
14980
- const cmd = new Command124("uninstall");
15568
+ const cmd = new Command127("uninstall");
14981
15569
  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) => {
14982
15570
  try {
14983
15571
  const result = await runUninstall(skill, opts);
@@ -14999,7 +15587,7 @@ function createUninstallCommand() {
14999
15587
  init_dist3();
15000
15588
  import * as fs49 from "fs/promises";
15001
15589
  import * as path79 from "path";
15002
- import { Command as Command125 } from "commander";
15590
+ import { Command as Command128 } from "commander";
15003
15591
  async function runUninstallConstraints(options) {
15004
15592
  const { packageName, configPath, lockfilePath } = options;
15005
15593
  const lockfileResult = await readLockfile(lockfilePath);
@@ -15056,7 +15644,7 @@ async function runUninstallConstraints(options) {
15056
15644
  };
15057
15645
  }
15058
15646
  function createUninstallConstraintsCommand() {
15059
- const cmd = new Command125("uninstall-constraints");
15647
+ const cmd = new Command128("uninstall-constraints");
15060
15648
  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) => {
15061
15649
  let configPath;
15062
15650
  if (opts.config) {
@@ -15096,10 +15684,10 @@ function createUninstallConstraintsCommand() {
15096
15684
 
15097
15685
  // src/commands/update.ts
15098
15686
  init_dist3();
15099
- import { Command as Command126 } from "commander";
15100
- import { execFile as execFile2, execFileSync as execFileSync10 } from "child_process";
15687
+ import { Command as Command129 } from "commander";
15688
+ import { execFile as execFile2, execFileSync as execFileSync13 } from "child_process";
15101
15689
  import { realpathSync, existsSync as existsSync45, readFileSync as readFileSync33 } from "fs";
15102
- import { dirname as dirname25, join as join67 } from "path";
15690
+ import { dirname as dirname25, join as join68 } from "path";
15103
15691
  import { promisify as promisify2 } from "util";
15104
15692
  import readline4 from "readline";
15105
15693
  import chalk20 from "chalk";
@@ -15139,7 +15727,7 @@ async function getLatestVersionAsync(pkg) {
15139
15727
  function getInstalledVersions(pm, packages) {
15140
15728
  const versions = {};
15141
15729
  try {
15142
- const output = execFileSync10(pm, ["list", "-g", "--json"], {
15730
+ const output = execFileSync13(pm, ["list", "-g", "--json"], {
15143
15731
  encoding: "utf-8",
15144
15732
  timeout: 15e3
15145
15733
  });
@@ -15160,7 +15748,7 @@ function getInstalledVersions(pm, packages) {
15160
15748
  }
15161
15749
  function getInstalledPackages(pm) {
15162
15750
  try {
15163
- const output = execFileSync10(pm, ["list", "-g", "--json"], {
15751
+ const output = execFileSync13(pm, ["list", "-g", "--json"], {
15164
15752
  encoding: "utf-8",
15165
15753
  timeout: 15e3
15166
15754
  });
@@ -15180,19 +15768,19 @@ function prompt3(question) {
15180
15768
  input: process.stdin,
15181
15769
  output: process.stdout
15182
15770
  });
15183
- return new Promise((resolve50) => {
15771
+ return new Promise((resolve49) => {
15184
15772
  rl.question(question, (answer) => {
15185
15773
  rl.close();
15186
- resolve50(answer.trim().toLowerCase());
15774
+ resolve49(answer.trim().toLowerCase());
15187
15775
  });
15188
15776
  });
15189
15777
  }
15190
15778
  function findPackageDir(resolvedBin) {
15191
15779
  let dir = dirname25(resolvedBin);
15192
15780
  for (let i = 0; i < 6; i++) {
15193
- if (existsSync45(join67(dir, "package.json"))) {
15781
+ if (existsSync45(join68(dir, "package.json"))) {
15194
15782
  try {
15195
- const pkg = JSON.parse(readFileSync33(join67(dir, "package.json"), "utf-8"));
15783
+ const pkg = JSON.parse(readFileSync33(join68(dir, "package.json"), "utf-8"));
15196
15784
  if (pkg?.name === CLI_PACKAGE) return dir;
15197
15785
  } catch {
15198
15786
  }
@@ -15215,7 +15803,7 @@ function findAllInstalls() {
15215
15803
  const args = isWindows ? ["harness"] : ["-a", "harness"];
15216
15804
  let output;
15217
15805
  try {
15218
- const raw = execFileSync10(cmd, args, { encoding: "utf-8", timeout: 5e3 });
15806
+ const raw = execFileSync13(cmd, args, { encoding: "utf-8", timeout: 5e3 });
15219
15807
  if (typeof raw !== "string") return [];
15220
15808
  output = raw;
15221
15809
  } catch {
@@ -15237,7 +15825,7 @@ function findAllInstalls() {
15237
15825
  if (!packageDir) continue;
15238
15826
  let version = null;
15239
15827
  try {
15240
- const pkg = JSON.parse(readFileSync33(join67(packageDir, "package.json"), "utf-8"));
15828
+ const pkg = JSON.parse(readFileSync33(join68(packageDir, "package.json"), "utf-8"));
15241
15829
  if (typeof pkg?.version === "string") version = pkg.version;
15242
15830
  } catch {
15243
15831
  }
@@ -15292,7 +15880,7 @@ async function offerCleanupOfOtherInstalls(activeDir) {
15292
15880
  }
15293
15881
  try {
15294
15882
  logger.info(`Uninstalling: ${cmd.display}`);
15295
- execFileSync10(cmd.bin, cmd.args, { stdio: "inherit", timeout: 12e4 });
15883
+ execFileSync13(cmd.bin, cmd.args, { stdio: "inherit", timeout: 12e4 });
15296
15884
  } catch {
15297
15885
  logger.warn(`Uninstall failed for ${cmd.install.binPath}.`);
15298
15886
  console.log(` Run manually: ${chalk20.cyan(cmd.display)}`);
@@ -15330,10 +15918,10 @@ async function ensureTelemetryIfNeeded() {
15330
15918
  }
15331
15919
  function refreshHooks() {
15332
15920
  const cwd = process.cwd();
15333
- const configPath = join67(cwd, "harness.config.json");
15921
+ const configPath = join68(cwd, "harness.config.json");
15334
15922
  if (!existsSync45(configPath)) return;
15335
15923
  let profile = "standard";
15336
- const profilePath = join67(cwd, ".harness", "hooks", "profile.json");
15924
+ const profilePath = join68(cwd, ".harness", "hooks", "profile.json");
15337
15925
  try {
15338
15926
  const data = JSON.parse(readFileSync33(profilePath, "utf-8"));
15339
15927
  if (data.profile && ["minimal", "standard", "strict"].includes(data.profile)) {
@@ -15352,7 +15940,7 @@ function refreshHooks() {
15352
15940
  function runLocalGraphScan() {
15353
15941
  try {
15354
15942
  logger.info("Scanning codebase to rebuild knowledge graph...");
15355
- execFileSync10("harness", ["graph", "scan", "."], { stdio: "inherit" });
15943
+ execFileSync13("harness", ["graph", "scan", "."], { stdio: "inherit" });
15356
15944
  } catch {
15357
15945
  logger.warn("Graph scan failed. Run manually:");
15358
15946
  console.log(` ${chalk20.cyan("harness graph scan .")}`);
@@ -15367,7 +15955,7 @@ async function offerRegeneration() {
15367
15955
  const scopeAnswer = await prompt3("Generate for (G)lobal or (l)ocal project? (G/l) ");
15368
15956
  const isGlobal = scopeAnswer !== "l" && scopeAnswer !== "local";
15369
15957
  try {
15370
- execFileSync10("harness", ["generate", ...isGlobal ? ["--global"] : []], {
15958
+ execFileSync13("harness", ["generate", ...isGlobal ? ["--global"] : []], {
15371
15959
  stdio: "inherit"
15372
15960
  });
15373
15961
  } catch {
@@ -15447,7 +16035,7 @@ async function runUpdateAction(opts, globalOpts) {
15447
16035
  }
15448
16036
  try {
15449
16037
  logger.info("Updating packages...");
15450
- execFileSync10(pm, ["install", "-g", ...installPkgs], { stdio: "inherit", timeout: 12e4 });
16038
+ execFileSync13(pm, ["install", "-g", ...installPkgs], { stdio: "inherit", timeout: 12e4 });
15451
16039
  console.log("");
15452
16040
  logger.success("Update complete");
15453
16041
  invalidateCheckState();
@@ -15464,7 +16052,7 @@ async function runUpdateAction(opts, globalOpts) {
15464
16052
  process.exit(ExitCode.SUCCESS);
15465
16053
  }
15466
16054
  function createUpdateCommand() {
15467
- return new Command126("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(
16055
+ return new Command129("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(
15468
16056
  "--regenerate",
15469
16057
  "Only regenerate slash commands and agent definitions (skip package updates)"
15470
16058
  ).action(async (opts, cmd) => {
@@ -15474,9 +16062,9 @@ function createUpdateCommand() {
15474
16062
  }
15475
16063
 
15476
16064
  // src/commands/usage.ts
15477
- import { Command as Command127 } from "commander";
16065
+ import { Command as Command130 } from "commander";
15478
16066
  async function loadAndPriceRecords(cwd, includeClaudeSessions = false) {
15479
- const { readCostRecords, loadPricingData, calculateCost, parseCCRecords } = await import("./dist-BWFFVKEW.js");
16067
+ const { readCostRecords, loadPricingData, calculateCost, parseCCRecords } = await import("./dist-4CZLCE33.js");
15480
16068
  const records = readCostRecords(cwd);
15481
16069
  if (includeClaudeSessions) {
15482
16070
  const ccRecords = parseCCRecords();
@@ -15569,7 +16157,7 @@ function registerDailyCommand(usage) {
15569
16157
  else logger.info("No usage data found. Run some harness sessions first.");
15570
16158
  return;
15571
16159
  }
15572
- const { aggregateByDay } = await import("./dist-BWFFVKEW.js");
16160
+ const { aggregateByDay } = await import("./dist-4CZLCE33.js");
15573
16161
  const limited = aggregateByDay(records).slice(0, days);
15574
16162
  if (globalOpts.json) {
15575
16163
  console.log(
@@ -15598,7 +16186,7 @@ function registerSessionsCommand(usage) {
15598
16186
  }
15599
16187
  return;
15600
16188
  }
15601
- const { aggregateBySession } = await import("./dist-BWFFVKEW.js");
16189
+ const { aggregateBySession } = await import("./dist-4CZLCE33.js");
15602
16190
  const sessionData = aggregateBySession(records);
15603
16191
  const limited = sessionData.slice(0, limit);
15604
16192
  if (globalOpts.json) {
@@ -15678,7 +16266,7 @@ function registerSessionCommand(usage) {
15678
16266
  cwd,
15679
16267
  globalOpts.includeClaudeSessions
15680
16268
  );
15681
- const { aggregateBySession } = await import("./dist-BWFFVKEW.js");
16269
+ const { aggregateBySession } = await import("./dist-4CZLCE33.js");
15682
16270
  const sessionData = aggregateBySession(records);
15683
16271
  const match = sessionData.find((s) => s.sessionId === id);
15684
16272
  if (!match) {
@@ -15713,7 +16301,7 @@ function registerLatestCommand(usage) {
15713
16301
  }
15714
16302
  return;
15715
16303
  }
15716
- const { aggregateBySession } = await import("./dist-BWFFVKEW.js");
16304
+ const { aggregateBySession } = await import("./dist-4CZLCE33.js");
15717
16305
  const sessionData = aggregateBySession(records);
15718
16306
  const latest = sessionData[0];
15719
16307
  if (!latest) {
@@ -15739,7 +16327,7 @@ function registerLatestCommand(usage) {
15739
16327
  });
15740
16328
  }
15741
16329
  function createUsageCommand() {
15742
- const usage = new Command127("usage").description("Token usage and cost tracking");
16330
+ const usage = new Command130("usage").description("Token usage and cost tracking");
15743
16331
  usage.option(
15744
16332
  "--include-claude-sessions",
15745
16333
  "Include Claude Code session data from ~/.claude/projects/"
@@ -15754,10 +16342,10 @@ function createUsageCommand() {
15754
16342
  // src/commands/validate.ts
15755
16343
  init_dist3();
15756
16344
  init_dist3();
15757
- import { Command as Command128 } from "commander";
16345
+ import { Command as Command131 } from "commander";
15758
16346
  import * as fs50 from "fs";
15759
16347
  import * as path80 from "path";
15760
- import { execFileSync as execFileSync11 } from "child_process";
16348
+ import { execFileSync as execFileSync14 } from "child_process";
15761
16349
  async function runValidate(options) {
15762
16350
  const configResult = resolveConfig(options.configPath);
15763
16351
  if (!configResult.ok) {
@@ -15876,7 +16464,7 @@ async function runValidate(options) {
15876
16464
  const gitattributesContent = fs50.readFileSync(gitattributesPath, "utf-8");
15877
16465
  let driverConfigured = false;
15878
16466
  try {
15879
- const out = execFileSync11("git", ["config", "--get", "merge.ours.driver"], {
16467
+ const out = execFileSync14("git", ["config", "--get", "merge.ours.driver"], {
15880
16468
  cwd,
15881
16469
  encoding: "utf-8",
15882
16470
  stdio: ["ignore", "pipe", "ignore"]
@@ -16062,7 +16650,7 @@ function resolveValidateMode(globalOpts) {
16062
16650
  return OutputMode.TEXT;
16063
16651
  }
16064
16652
  async function printCrossCheckWarnings(mode) {
16065
- const { runCrossCheck: runCrossCheck2 } = await import("./validate-cross-check-H2OUHTID.js");
16653
+ const { runCrossCheck: runCrossCheck2 } = await import("./validate-cross-check-YYVYMSPA.js");
16066
16654
  const cwd = process.cwd();
16067
16655
  const crossResult = await runCrossCheck2({
16068
16656
  specsDir: path80.join(cwd, "docs", "specs"),
@@ -16078,7 +16666,7 @@ async function printCrossCheckWarnings(mode) {
16078
16666
  ${crossResult.value.warnings} warnings`);
16079
16667
  }
16080
16668
  function createValidateCommand3() {
16081
- const command = new Command128("validate").description("Run all validation checks").option("--cross-check", "Run cross-artifact consistency validation").option(
16669
+ const command = new Command131("validate").description("Run all validation checks").option("--cross-check", "Run cross-artifact consistency validation").option(
16082
16670
  "--agent-configs",
16083
16671
  "Validate agent configs (CLAUDE.md, hooks, skills) via agnix or built-in fallback rules"
16084
16672
  ).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()));
@@ -16127,7 +16715,7 @@ Agent configs checked via ${engineLabel}${note}`);
16127
16715
 
16128
16716
  // src/commands/verify.ts
16129
16717
  init_dist3();
16130
- import { Command as Command129 } from "commander";
16718
+ import { Command as Command132 } from "commander";
16131
16719
  import { execSync as execSync6 } from "child_process";
16132
16720
  function loadBranchingConfig(configPath) {
16133
16721
  const shouldLoad = configPath !== void 0 || findConfigFile().ok;
@@ -16190,7 +16778,7 @@ async function runVerify(options) {
16190
16778
  process.exit(ExitCode.VALIDATION_FAILED);
16191
16779
  }
16192
16780
  function createVerifyCommand() {
16193
- return new Command129("verify").description(
16781
+ return new Command132("verify").description(
16194
16782
  "Verify project conventions (currently: branch naming). Works with or without a harness.config.json."
16195
16783
  ).option(
16196
16784
  "--branch <name>",
@@ -16268,6 +16856,7 @@ var commandCreators = [
16268
16856
  createRecommendCommand,
16269
16857
  createReviewCiCommand,
16270
16858
  createRoadmapCommand,
16859
+ createRollbackCommand,
16271
16860
  createRoutingCommand,
16272
16861
  createScanConfigCommand,
16273
16862
  createSearchCommand,
@@ -16283,7 +16872,7 @@ var commandCreators = [
16283
16872
  createSyncAnalysesCommand,
16284
16873
  createSyncMainCommand,
16285
16874
  createTaintCommand,
16286
- createTelemetryCommand,
16875
+ createTelemetryCommand2,
16287
16876
  createTestCraftCommand,
16288
16877
  createTraceabilityCommand,
16289
16878
  createUninstallCommand,
@@ -16317,7 +16906,7 @@ function registerDeprecatedGraphAliases(program) {
16317
16906
 
16318
16907
  // src/index.ts
16319
16908
  function createProgram() {
16320
- const program = new Command130();
16909
+ const program = new Command133();
16321
16910
  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");
16322
16911
  for (const creator of commandCreators) {
16323
16912
  program.addCommand(creator());