@harness-engineering/cli 1.25.4 → 1.25.6

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 (123) hide show
  1. package/dist/agents/skills/claude-code/enforce-architecture/SKILL.md +12 -0
  2. package/dist/agents/skills/claude-code/harness-api-design/SKILL.md +12 -0
  3. package/dist/agents/skills/claude-code/harness-architecture-advisor/SKILL.md +12 -0
  4. package/dist/agents/skills/claude-code/harness-auth/SKILL.md +12 -0
  5. package/dist/agents/skills/claude-code/harness-code-review/SKILL.md +30 -6
  6. package/dist/agents/skills/claude-code/harness-database/SKILL.md +12 -0
  7. package/dist/agents/skills/claude-code/harness-debugging/SKILL.md +38 -6
  8. package/dist/agents/skills/claude-code/harness-deployment/SKILL.md +12 -0
  9. package/dist/agents/skills/claude-code/harness-execution/SKILL.md +30 -6
  10. package/dist/agents/skills/claude-code/harness-planning/SKILL.md +20 -9
  11. package/dist/agents/skills/claude-code/harness-pre-commit-review/SKILL.md +59 -6
  12. package/dist/agents/skills/claude-code/harness-refactoring/SKILL.md +28 -7
  13. package/dist/agents/skills/claude-code/harness-security-scan/SKILL.md +12 -0
  14. package/dist/agents/skills/claude-code/harness-skill-authoring/SKILL.md +43 -8
  15. package/dist/agents/skills/claude-code/harness-soundness-review/SKILL.md +59 -7
  16. package/dist/agents/skills/claude-code/harness-tdd/SKILL.md +21 -0
  17. package/dist/agents/skills/claude-code/harness-verification/SKILL.md +31 -6
  18. package/dist/agents/skills/codex/enforce-architecture/SKILL.md +12 -0
  19. package/dist/agents/skills/codex/harness-api-design/SKILL.md +12 -0
  20. package/dist/agents/skills/codex/harness-architecture-advisor/SKILL.md +12 -0
  21. package/dist/agents/skills/codex/harness-auth/SKILL.md +12 -0
  22. package/dist/agents/skills/codex/harness-code-review/SKILL.md +30 -6
  23. package/dist/agents/skills/codex/harness-database/SKILL.md +12 -0
  24. package/dist/agents/skills/codex/harness-debugging/SKILL.md +38 -6
  25. package/dist/agents/skills/codex/harness-deployment/SKILL.md +12 -0
  26. package/dist/agents/skills/codex/harness-execution/SKILL.md +30 -6
  27. package/dist/agents/skills/codex/harness-planning/SKILL.md +20 -9
  28. package/dist/agents/skills/codex/harness-pre-commit-review/SKILL.md +59 -6
  29. package/dist/agents/skills/codex/harness-refactoring/SKILL.md +28 -7
  30. package/dist/agents/skills/codex/harness-security-scan/SKILL.md +12 -0
  31. package/dist/agents/skills/codex/harness-skill-authoring/SKILL.md +43 -8
  32. package/dist/agents/skills/codex/harness-soundness-review/SKILL.md +59 -7
  33. package/dist/agents/skills/codex/harness-tdd/SKILL.md +21 -0
  34. package/dist/agents/skills/codex/harness-verification/SKILL.md +31 -6
  35. package/dist/agents/skills/cursor/enforce-architecture/SKILL.md +12 -0
  36. package/dist/agents/skills/cursor/harness-api-design/SKILL.md +12 -0
  37. package/dist/agents/skills/cursor/harness-architecture-advisor/SKILL.md +12 -0
  38. package/dist/agents/skills/cursor/harness-auth/SKILL.md +12 -0
  39. package/dist/agents/skills/cursor/harness-code-review/SKILL.md +30 -6
  40. package/dist/agents/skills/cursor/harness-database/SKILL.md +12 -0
  41. package/dist/agents/skills/cursor/harness-debugging/SKILL.md +38 -6
  42. package/dist/agents/skills/cursor/harness-deployment/SKILL.md +12 -0
  43. package/dist/agents/skills/cursor/harness-execution/SKILL.md +30 -6
  44. package/dist/agents/skills/cursor/harness-planning/SKILL.md +20 -9
  45. package/dist/agents/skills/cursor/harness-pre-commit-review/SKILL.md +59 -6
  46. package/dist/agents/skills/cursor/harness-refactoring/SKILL.md +28 -7
  47. package/dist/agents/skills/cursor/harness-security-scan/SKILL.md +12 -0
  48. package/dist/agents/skills/cursor/harness-skill-authoring/SKILL.md +43 -8
  49. package/dist/agents/skills/cursor/harness-soundness-review/SKILL.md +59 -7
  50. package/dist/agents/skills/cursor/harness-tdd/SKILL.md +21 -0
  51. package/dist/agents/skills/cursor/harness-verification/SKILL.md +31 -6
  52. package/dist/agents/skills/gemini-cli/enforce-architecture/SKILL.md +12 -0
  53. package/dist/agents/skills/gemini-cli/harness-api-design/SKILL.md +12 -0
  54. package/dist/agents/skills/gemini-cli/harness-architecture-advisor/SKILL.md +12 -0
  55. package/dist/agents/skills/gemini-cli/harness-auth/SKILL.md +12 -0
  56. package/dist/agents/skills/gemini-cli/harness-code-review/SKILL.md +30 -6
  57. package/dist/agents/skills/gemini-cli/harness-database/SKILL.md +12 -0
  58. package/dist/agents/skills/gemini-cli/harness-debugging/SKILL.md +38 -6
  59. package/dist/agents/skills/gemini-cli/harness-deployment/SKILL.md +12 -0
  60. package/dist/agents/skills/gemini-cli/harness-execution/SKILL.md +30 -6
  61. package/dist/agents/skills/gemini-cli/harness-planning/SKILL.md +20 -9
  62. package/dist/agents/skills/gemini-cli/harness-pre-commit-review/SKILL.md +59 -6
  63. package/dist/agents/skills/gemini-cli/harness-refactoring/SKILL.md +28 -7
  64. package/dist/agents/skills/gemini-cli/harness-security-scan/SKILL.md +12 -0
  65. package/dist/agents/skills/gemini-cli/harness-skill-authoring/SKILL.md +43 -8
  66. package/dist/agents/skills/gemini-cli/harness-soundness-review/SKILL.md +59 -7
  67. package/dist/agents/skills/gemini-cli/harness-tdd/SKILL.md +21 -0
  68. package/dist/agents/skills/gemini-cli/harness-verification/SKILL.md +31 -6
  69. package/dist/{agents-md-MCUM4SIZ.js → agents-md-2PYJM2MK.js} +3 -3
  70. package/dist/{architecture-HNIO6AUX.js → architecture-VCLB7A23.js} +4 -4
  71. package/dist/{assess-project-6MV5TNY3.js → assess-project-64C6LIKN.js} +1 -1
  72. package/dist/bin/harness-mcp.js +16 -15
  73. package/dist/bin/harness.js +27 -115
  74. package/dist/business-knowledge-6RHYJOB3.js +7 -0
  75. package/dist/{check-phase-gate-VCBQHQAC.js → check-phase-gate-RT6PGEHY.js} +4 -4
  76. package/dist/{chunk-MI6MA6OP.js → chunk-42ZZLMYD.js} +169 -118
  77. package/dist/{chunk-BUYW3SA2.js → chunk-43VBX44J.js} +219 -107
  78. package/dist/{chunk-UV3BZMGT.js → chunk-4YEBV2FT.js} +2 -2
  79. package/dist/{chunk-5BQ5BOJL.js → chunk-7BAGSY5Q.js} +1 -1
  80. package/dist/{chunk-FSNPBT74.js → chunk-BUJOMC3O.js} +1 -1
  81. package/dist/{chunk-M55DGGF3.js → chunk-CBZECDCW.js} +5 -5
  82. package/dist/{chunk-XTITAVUR.js → chunk-EY6F2QXW.js} +1 -1
  83. package/dist/{chunk-6VZQJ5CX.js → chunk-FL6A72LV.js} +1 -1
  84. package/dist/{chunk-CXJTVICF.js → chunk-JQCS75DY.js} +4 -4
  85. package/dist/{chunk-WIQA4BSH.js → chunk-JUXFYB2K.js} +1 -1
  86. package/dist/{chunk-FES2YEQU.js → chunk-KJC4SE7C.js} +9 -9
  87. package/dist/{chunk-4NK7Z3BP.js → chunk-R2BI5UPK.js} +1 -1
  88. package/dist/{chunk-2KZAXESR.js → chunk-R7P2FMJT.js} +360 -183
  89. package/dist/chunk-RC5ZY3EV.js +82 -0
  90. package/dist/{chunk-K2SON7TI.js → chunk-RDQGCHKD.js} +252 -57
  91. package/dist/{chunk-EHRZMOQ2.js → chunk-RKZW3FDF.js} +1 -1
  92. package/dist/{chunk-BOQRTARD.js → chunk-SMY35HJM.js} +1 -1
  93. package/dist/{chunk-UQZBZINS.js → chunk-SZZ5UQL7.js} +6 -6
  94. package/dist/{chunk-AT74HEQM.js → chunk-U2OMWI7Z.js} +1 -1
  95. package/dist/{chunk-P7PANON5.js → chunk-VELT5VAG.js} +1 -1
  96. package/dist/{chunk-YTP2UDPV.js → chunk-WEOGCL7B.js} +3 -3
  97. package/dist/{chunk-TYV4EUAD.js → chunk-X2JJ3CPG.js} +8 -8
  98. package/dist/{chunk-GEEYCQDS.js → chunk-XLO4AXXM.js} +9 -9
  99. package/dist/{chunk-47N6R2F4.js → chunk-XMEEYMGE.js} +1 -1
  100. package/dist/{chunk-FIQL2HND.js → chunk-Y5JA4J2M.js} +2 -2
  101. package/dist/{chunk-F23H3U5U.js → chunk-ZAKUCM7O.js} +2 -2
  102. package/dist/{ci-workflow-RTM7VVTD.js → ci-workflow-SZL3KVUK.js} +3 -3
  103. package/dist/{dist-RADHOOXG.js → dist-GRW3X2ZQ.js} +3 -1
  104. package/dist/{dist-WCSJHQPK.js → dist-T3DGV5UN.js} +16 -2
  105. package/dist/{docs-UBOGGHTY.js → docs-WDLJORLK.js} +4 -4
  106. package/dist/{engine-MJJAP5CH.js → engine-2YWYRCKK.js} +3 -3
  107. package/dist/{entropy-EMSXF2PX.js → entropy-PJGTOORX.js} +3 -3
  108. package/dist/{feedback-ZLUX72HD.js → feedback-M5KCJKL2.js} +1 -1
  109. package/dist/{generate-agent-definitions-AWLPJ27C.js → generate-agent-definitions-MFDW6LZT.js} +4 -4
  110. package/dist/{graph-loader-JHQVQRUS.js → graph-loader-QMKXT454.js} +1 -1
  111. package/dist/hooks/telemetry-reporter.js +22 -1
  112. package/dist/index.d.ts +5 -5
  113. package/dist/index.js +26 -25
  114. package/dist/{loader-JVSJZSWZ.js → loader-6O52FYHE.js} +3 -3
  115. package/dist/{mcp-JZ7YB7TD.js → mcp-GGNFWKVC.js} +16 -15
  116. package/dist/{performance-7AGWJUY4.js → performance-337U5URQ.js} +4 -4
  117. package/dist/{review-pipeline-ZWVQJTJX.js → review-pipeline-DB5RD4SN.js} +3 -3
  118. package/dist/{runtime-D6YUQPP2.js → runtime-B74EN2WD.js} +3 -3
  119. package/dist/{scan-MPJ6JHUY.js → scan-DXQUHGTT.js} +1 -1
  120. package/dist/{security-JLZUAQYT.js → security-3AYN6FVU.js} +1 -1
  121. package/dist/{validate-TIIHRPMA.js → validate-35CD7VWN.js} +4 -4
  122. package/dist/{validate-cross-check-ZOWFA3DB.js → validate-cross-check-LJKXBQYH.js} +3 -3
  123. package/package.json +5 -5
@@ -1,19 +1,19 @@
1
1
  import {
2
2
  generateAgentsMd
3
- } from "./chunk-5BQ5BOJL.js";
3
+ } from "./chunk-7BAGSY5Q.js";
4
4
  import {
5
5
  generateCIWorkflow
6
- } from "./chunk-EHRZMOQ2.js";
6
+ } from "./chunk-RKZW3FDF.js";
7
7
  import {
8
8
  TemplateEngine
9
- } from "./chunk-FSNPBT74.js";
9
+ } from "./chunk-BUJOMC3O.js";
10
10
  import {
11
11
  generate,
12
12
  validate
13
13
  } from "./chunk-CQ553GZO.js";
14
14
  import {
15
15
  generateRuntime
16
- } from "./chunk-6VZQJ5CX.js";
16
+ } from "./chunk-FL6A72LV.js";
17
17
  import {
18
18
  runPersona
19
19
  } from "./chunk-GISMXMVL.js";
@@ -28,21 +28,21 @@ import {
28
28
  OutputMode,
29
29
  createCheckPhaseGateCommand,
30
30
  findFiles
31
- } from "./chunk-FIQL2HND.js";
31
+ } from "./chunk-Y5JA4J2M.js";
32
32
  import {
33
33
  createGenerateAgentDefinitionsCommand,
34
34
  generateAgentDefinitions
35
- } from "./chunk-AT74HEQM.js";
35
+ } from "./chunk-U2OMWI7Z.js";
36
36
  import {
37
37
  toKebabCase
38
38
  } from "./chunk-KET4QQZB.js";
39
39
  import {
40
40
  listPersonas,
41
41
  loadPersona
42
- } from "./chunk-P7PANON5.js";
42
+ } from "./chunk-VELT5VAG.js";
43
43
  import {
44
44
  createScanCommand
45
- } from "./chunk-4NK7Z3BP.js";
45
+ } from "./chunk-R2BI5UPK.js";
46
46
  import {
47
47
  appendFrameworkAgents,
48
48
  captureHealthSnapshot,
@@ -56,11 +56,11 @@ import {
56
56
  loadOrRebuildIndex,
57
57
  persistToolingConfig,
58
58
  recommend
59
- } from "./chunk-BUYW3SA2.js";
59
+ } from "./chunk-43VBX44J.js";
60
60
  import {
61
61
  findConfigFile,
62
62
  resolveConfig
63
- } from "./chunk-WIQA4BSH.js";
63
+ } from "./chunk-JUXFYB2K.js";
64
64
  import {
65
65
  VALID_PLATFORMS
66
66
  } from "./chunk-3ISINLYT.js";
@@ -74,7 +74,7 @@ import {
74
74
  } from "./chunk-6B6UN6SG.js";
75
75
  import {
76
76
  loadGraphStore
77
- } from "./chunk-BOQRTARD.js";
77
+ } from "./chunk-SMY35HJM.js";
78
78
  import {
79
79
  CLI_VERSION
80
80
  } from "./chunk-BM3PWGXQ.js";
@@ -148,7 +148,7 @@ import {
148
148
  validateKnowledgeMap,
149
149
  writeConfig,
150
150
  writeLockfile
151
- } from "./chunk-MI6MA6OP.js";
151
+ } from "./chunk-42ZZLMYD.js";
152
152
  import {
153
153
  Err,
154
154
  Ok
@@ -173,7 +173,7 @@ import {
173
173
  } from "./chunk-KFQGP6VL.js";
174
174
 
175
175
  // src/index.ts
176
- import { Command as Command83 } from "commander";
176
+ import { Command as Command84 } from "commander";
177
177
 
178
178
  // src/commands/add.ts
179
179
  init_dist();
@@ -362,7 +362,7 @@ function registerSkillsCommand(adoption) {
362
362
  const globalOpts = cmd.optsWithGlobals();
363
363
  const limit = Math.max(parseInt(opts.limit, 10) || 20, 1);
364
364
  const cwd = process.cwd();
365
- const { readAdoptionRecords, aggregateBySkill } = await import("./dist-WCSJHQPK.js");
365
+ const { readAdoptionRecords, aggregateBySkill } = await import("./dist-T3DGV5UN.js");
366
366
  const records = readAdoptionRecords(cwd);
367
367
  if (records.length === 0) {
368
368
  if (globalOpts.json) {
@@ -398,7 +398,7 @@ function registerRecentCommand(adoption) {
398
398
  const globalOpts = cmd.optsWithGlobals();
399
399
  const limit = Math.max(parseInt(opts.limit, 10) || 20, 1);
400
400
  const cwd = process.cwd();
401
- const { readAdoptionRecords } = await import("./dist-WCSJHQPK.js");
401
+ const { readAdoptionRecords } = await import("./dist-T3DGV5UN.js");
402
402
  const records = readAdoptionRecords(cwd);
403
403
  if (records.length === 0) {
404
404
  if (globalOpts.json) {
@@ -431,62 +431,68 @@ function registerRecentCommand(adoption) {
431
431
  Showing ${limited.length} of ${records.length} invocations`);
432
432
  });
433
433
  }
434
+ function computePhaseRates(skillRecords) {
435
+ const phaseMap = /* @__PURE__ */ new Map();
436
+ for (const r of skillRecords) {
437
+ for (const phase of r.phasesReached) {
438
+ phaseMap.set(phase, (phaseMap.get(phase) ?? 0) + 1);
439
+ }
440
+ }
441
+ return Array.from(phaseMap.entries()).map(([phase, count]) => ({ phase, count, rate: count / skillRecords.length })).sort((a, b) => b.count - a.count);
442
+ }
443
+ function computeOutcomes(skillRecords) {
444
+ const outcomes = { completed: 0, failed: 0, abandoned: 0 };
445
+ for (const r of skillRecords) {
446
+ if (r.outcome in outcomes) {
447
+ outcomes[r.outcome]++;
448
+ }
449
+ }
450
+ return outcomes;
451
+ }
452
+ function printSkillDetail(name, summary, phaseRates, skillRecords) {
453
+ console.log(`Skill: ${name}`);
454
+ console.log(`Invocations: ${summary.invocations}`);
455
+ console.log(`Success rate: ${formatRate(summary.successRate)}`);
456
+ console.log(`Avg duration: ${formatDuration(summary.avgDuration)}`);
457
+ console.log(`Last used: ${summary.lastUsed.slice(0, 10)}`);
458
+ if (summary.tier != null) {
459
+ console.log(`Tier: ${summary.tier}`);
460
+ }
461
+ if (phaseRates.length > 0) {
462
+ console.log("\nPhase completion rates:");
463
+ for (const p of phaseRates) {
464
+ console.log(
465
+ ` ${padRight(p.phase, 20)} ${formatRate(p.rate)} (${p.count}/${skillRecords.length})`
466
+ );
467
+ }
468
+ }
469
+ const outcomes = computeOutcomes(skillRecords);
470
+ console.log("\nOutcome breakdown:");
471
+ console.log(` Completed: ${outcomes.completed}`);
472
+ console.log(` Failed: ${outcomes.failed}`);
473
+ console.log(` Abandoned: ${outcomes.abandoned}`);
474
+ }
434
475
  function registerSkillCommand(adoption) {
435
476
  adoption.command("skill <name>").description("Show detail for a specific skill").action(async (name, _opts, cmd) => {
436
477
  const globalOpts = cmd.optsWithGlobals();
437
478
  const cwd = process.cwd();
438
- const { readAdoptionRecords, aggregateBySkill } = await import("./dist-WCSJHQPK.js");
479
+ const { readAdoptionRecords, aggregateBySkill } = await import("./dist-T3DGV5UN.js");
439
480
  const records = readAdoptionRecords(cwd);
440
481
  const skillRecords = records.filter((r) => r.skill === name);
441
482
  if (skillRecords.length === 0) {
442
- if (globalOpts.json) {
443
- console.log(JSON.stringify(null));
444
- } else {
445
- logger.info(`No adoption data found for skill "${name}".`);
446
- }
483
+ if (globalOpts.json) console.log(JSON.stringify(null));
484
+ else logger.info(`No adoption data found for skill "${name}".`);
447
485
  return;
448
486
  }
449
- const summaries = aggregateBySkill(skillRecords);
450
- const summary = summaries[0];
451
- const phaseMap = /* @__PURE__ */ new Map();
452
- for (const r of skillRecords) {
453
- for (const phase of r.phasesReached) {
454
- phaseMap.set(phase, (phaseMap.get(phase) ?? 0) + 1);
455
- }
456
- }
457
- const phaseRates = Array.from(phaseMap.entries()).map(([phase, count]) => ({ phase, count, rate: count / skillRecords.length })).sort((a, b) => b.count - a.count);
487
+ const summary = aggregateBySkill(skillRecords)[0];
488
+ const phaseRates = computePhaseRates(skillRecords);
458
489
  if (globalOpts.json) {
459
490
  console.log(
460
491
  JSON.stringify({ summary, phaseRates, totalRecords: skillRecords.length }, null, 2)
461
492
  );
462
493
  return;
463
494
  }
464
- console.log(`Skill: ${name}`);
465
- console.log(`Invocations: ${summary.invocations}`);
466
- console.log(`Success rate: ${formatRate(summary.successRate)}`);
467
- console.log(`Avg duration: ${formatDuration(summary.avgDuration)}`);
468
- console.log(`Last used: ${summary.lastUsed.slice(0, 10)}`);
469
- if (summary.tier != null) {
470
- console.log(`Tier: ${summary.tier}`);
471
- }
472
- if (phaseRates.length > 0) {
473
- console.log("\nPhase completion rates:");
474
- for (const p of phaseRates) {
475
- console.log(
476
- ` ${padRight(p.phase, 20)} ${formatRate(p.rate)} (${p.count}/${skillRecords.length})`
477
- );
478
- }
479
- }
480
- const outcomes = { completed: 0, failed: 0, abandoned: 0 };
481
- for (const r of skillRecords) {
482
- if (r.outcome in outcomes) {
483
- outcomes[r.outcome]++;
484
- }
485
- }
486
- console.log("\nOutcome breakdown:");
487
- console.log(` Completed: ${outcomes.completed}`);
488
- console.log(` Failed: ${outcomes.failed}`);
489
- console.log(` Abandoned: ${outcomes.abandoned}`);
495
+ printSkillDetail(name, summary, phaseRates, skillRecords);
490
496
  });
491
497
  }
492
498
  function createAdoptionCommand() {
@@ -2052,6 +2058,12 @@ async function runCleanupSessions(options) {
2052
2058
  }
2053
2059
  return Ok(result);
2054
2060
  }
2061
+ function printSessionList(label, sessions) {
2062
+ if (sessions.length === 0) return;
2063
+ console.log(`
2064
+ ${label} (${sessions.length}):`);
2065
+ for (const s of sessions) console.log(` - ${s}`);
2066
+ }
2055
2067
  function printResult(result, dryRun, asJson) {
2056
2068
  const { removed, kept } = result;
2057
2069
  if (asJson) {
@@ -2062,17 +2074,9 @@ function printResult(result, dryRun, asJson) {
2062
2074
  console.log("No sessions found.");
2063
2075
  return;
2064
2076
  }
2065
- if (removed.length > 0) {
2066
- const label = dryRun ? "Stale (would remove)" : "Removed";
2067
- console.log(`
2068
- ${label} (${removed.length}):`);
2069
- for (const s of removed) console.log(` - ${s}`);
2070
- }
2071
- if (kept.length > 0) {
2072
- console.log(`
2073
- Kept (${kept.length}):`);
2074
- for (const s of kept) console.log(` - ${s}`);
2075
- }
2077
+ const removeLabel = dryRun ? "Stale (would remove)" : "Removed";
2078
+ printSessionList(removeLabel, removed);
2079
+ printSessionList("Kept", kept);
2076
2080
  if (!dryRun && removed.length > 0) {
2077
2081
  console.log(`
2078
2082
  Cleaned up ${removed.length} stale session(s).`);
@@ -2146,16 +2150,7 @@ function spawnDashboardServer(server, env) {
2146
2150
  });
2147
2151
  return child;
2148
2152
  }
2149
- function runDashboard(opts) {
2150
- const clientPort = Number(opts.port ?? DEFAULT_CLIENT_PORT);
2151
- const apiPort = Number(opts.apiPort ?? DEFAULT_API_PORT);
2152
- const projectPath = resolve11(opts.cwd ?? process.cwd());
2153
- const url = `http://localhost:${apiPort}`;
2154
- const server = resolveServerScript();
2155
- if (!server) {
2156
- console.error("Could not locate the dashboard server. Run `pnpm build` in packages/dashboard.");
2157
- process.exit(1);
2158
- }
2153
+ function buildDashboardEnv(opts, clientPort, apiPort, projectPath) {
2159
2154
  const env = {
2160
2155
  ...process.env,
2161
2156
  DASHBOARD_API_PORT: String(apiPort),
@@ -2167,6 +2162,19 @@ function runDashboard(opts) {
2167
2162
  } else if (!env["ORCHESTRATOR_URL"] && !env["ORCHESTRATOR_PORT"]) {
2168
2163
  env["ORCHESTRATOR_PORT"] = "8080";
2169
2164
  }
2165
+ return env;
2166
+ }
2167
+ function runDashboard(opts) {
2168
+ const clientPort = Number(opts.port ?? DEFAULT_CLIENT_PORT);
2169
+ const apiPort = Number(opts.apiPort ?? DEFAULT_API_PORT);
2170
+ const projectPath = resolve11(opts.cwd ?? process.cwd());
2171
+ const url = `http://localhost:${apiPort}`;
2172
+ const server = resolveServerScript();
2173
+ if (!server) {
2174
+ console.error("Could not locate the dashboard server. Run `pnpm build` in packages/dashboard.");
2175
+ process.exit(1);
2176
+ }
2177
+ const env = buildDashboardEnv(opts, clientPort, apiPort, projectPath);
2170
2178
  spawnDashboardServer(server, env);
2171
2179
  console.log(`Dashboard API starting on http://localhost:${apiPort}`);
2172
2180
  console.log(`Open ${url} (pass --no-open to suppress)`);
@@ -2757,7 +2765,7 @@ import { Command as Command25 } from "commander";
2757
2765
  // src/commands/graph/status.ts
2758
2766
  import * as path15 from "path";
2759
2767
  async function runGraphStatus(projectPath) {
2760
- const { GraphStore } = await import("./dist-RADHOOXG.js");
2768
+ const { GraphStore } = await import("./dist-GRW3X2ZQ.js");
2761
2769
  const graphDir = path15.join(projectPath, ".harness", "graph");
2762
2770
  const store = new GraphStore();
2763
2771
  const loaded = await store.load(graphDir);
@@ -2797,7 +2805,7 @@ async function runGraphStatus(projectPath) {
2797
2805
  // src/commands/graph/export.ts
2798
2806
  import * as path16 from "path";
2799
2807
  async function runGraphExport(projectPath, format) {
2800
- const { GraphStore } = await import("./dist-RADHOOXG.js");
2808
+ const { GraphStore } = await import("./dist-GRW3X2ZQ.js");
2801
2809
  const graphDir = path16.join(projectPath, ".harness", "graph");
2802
2810
  const store = new GraphStore();
2803
2811
  const loaded = await store.load(graphDir);
@@ -2833,7 +2841,7 @@ import * as path19 from "path";
2833
2841
  import { Command as Command23 } from "commander";
2834
2842
  import * as path17 from "path";
2835
2843
  async function runQuery(projectPath, rootNodeId, opts) {
2836
- const { GraphStore, ContextQL } = await import("./dist-RADHOOXG.js");
2844
+ const { GraphStore, ContextQL } = await import("./dist-GRW3X2ZQ.js");
2837
2845
  const store = new GraphStore();
2838
2846
  const graphDir = path17.join(projectPath, ".harness", "graph");
2839
2847
  const loaded = await store.load(graphDir);
@@ -2927,7 +2935,7 @@ async function runIngest(projectPath, source, opts) {
2927
2935
  SlackConnector,
2928
2936
  CIConnector,
2929
2937
  ConfluenceConnector
2930
- } = await import("./dist-RADHOOXG.js");
2938
+ } = await import("./dist-GRW3X2ZQ.js");
2931
2939
  const graphDir = path18.join(projectPath, ".harness", "graph");
2932
2940
  const store = new GraphStore();
2933
2941
  await store.load(graphDir);
@@ -5428,7 +5436,7 @@ function createMcpCommand() {
5428
5436
  parseBudget
5429
5437
  ).action(async (opts) => {
5430
5438
  const [{ startServer: startServer2, getToolDefinitions: getToolDefinitions2 }, { selectTier }] = await Promise.all([
5431
- import("./mcp-JZ7YB7TD.js"),
5439
+ import("./mcp-GGNFWKVC.js"),
5432
5440
  import("./tool-tiers-7QGZ3FKY.js")
5433
5441
  ]);
5434
5442
  if (opts.tools && opts.tools.length > 0) {
@@ -5494,7 +5502,7 @@ function registerBenchCommand(perf) {
5494
5502
  perf.command("bench [glob]").description("Run benchmarks via vitest bench").action(async (glob2, _opts, cmd) => {
5495
5503
  const globalOpts = cmd.optsWithGlobals();
5496
5504
  const cwd = process.cwd();
5497
- const { BenchmarkRunner } = await import("./dist-WCSJHQPK.js");
5505
+ const { BenchmarkRunner } = await import("./dist-T3DGV5UN.js");
5498
5506
  const runner = new BenchmarkRunner();
5499
5507
  const benchFiles = runner.discover(cwd, glob2);
5500
5508
  if (benchFiles.length === 0) {
@@ -5558,7 +5566,7 @@ async function runBaselinesShow(globalOpts) {
5558
5566
  }
5559
5567
  async function runBaselinesUpdate(globalOpts) {
5560
5568
  const cwd = process.cwd();
5561
- const { BenchmarkRunner } = await import("./dist-WCSJHQPK.js");
5569
+ const { BenchmarkRunner } = await import("./dist-T3DGV5UN.js");
5562
5570
  const runner = new BenchmarkRunner();
5563
5571
  const manager = new BaselineManager(cwd);
5564
5572
  logger.info("Running benchmarks to update baselines...");
@@ -5599,7 +5607,7 @@ function registerReportCommand(perf) {
5599
5607
  perf.command("report").description("Full performance report with metrics, trends, and hotspots").action(async (_opts, cmd) => {
5600
5608
  const globalOpts = cmd.optsWithGlobals();
5601
5609
  const cwd = process.cwd();
5602
- const { EntropyAnalyzer: EntropyAnalyzer2 } = await import("./dist-WCSJHQPK.js");
5610
+ const { EntropyAnalyzer: EntropyAnalyzer2 } = await import("./dist-T3DGV5UN.js");
5603
5611
  const analyzer = new EntropyAnalyzer2({
5604
5612
  rootDir: path40.resolve(cwd),
5605
5613
  analyze: { complexity: true, coupling: true }
@@ -5990,7 +5998,7 @@ async function runPublishAnalyses(opts) {
5990
5998
  const nameToExternalId = buildNameToExternalIdMap(projectPath);
5991
5999
  if (!nameToExternalId) return process.exit(1);
5992
6000
  const { AnalysisArchive } = await import("@harness-engineering/orchestrator");
5993
- const { GitHubIssuesSyncAdapter: GitHubIssuesSyncAdapter2 } = await import("./dist-WCSJHQPK.js");
6001
+ const { GitHubIssuesSyncAdapter: GitHubIssuesSyncAdapter2 } = await import("./dist-T3DGV5UN.js");
5994
6002
  const archive = new AnalysisArchive(path42.join(projectPath, ".harness", "analyses"));
5995
6003
  const analyses = await archive.list();
5996
6004
  if (analyses.length === 0) {
@@ -6275,10 +6283,10 @@ function prompt(question) {
6275
6283
  input: process.stdin,
6276
6284
  output: process.stdout
6277
6285
  });
6278
- return new Promise((resolve35) => {
6286
+ return new Promise((resolve36) => {
6279
6287
  rl.question(question, (answer) => {
6280
6288
  rl.close();
6281
- resolve35(answer.trim().toLowerCase());
6289
+ resolve36(answer.trim().toLowerCase());
6282
6290
  });
6283
6291
  });
6284
6292
  }
@@ -6287,10 +6295,10 @@ function promptRaw(question) {
6287
6295
  input: process.stdin,
6288
6296
  output: process.stdout
6289
6297
  });
6290
- return new Promise((resolve35) => {
6298
+ return new Promise((resolve36) => {
6291
6299
  rl.question(question, (answer) => {
6292
6300
  rl.close();
6293
- resolve35(answer.trim());
6301
+ resolve36(answer.trim());
6294
6302
  });
6295
6303
  });
6296
6304
  }
@@ -6516,7 +6524,7 @@ function ensureHooks(cwd) {
6516
6524
  }
6517
6525
  async function runInitialGraphScan(cwd) {
6518
6526
  try {
6519
- const { runScan: runScan2 } = await import("./scan-MPJ6JHUY.js");
6527
+ const { runScan: runScan2 } = await import("./scan-DXQUHGTT.js");
6520
6528
  const result = await runScan2(cwd);
6521
6529
  return {
6522
6530
  status: "pass",
@@ -7790,8 +7798,8 @@ async function resolveStatePath(projectPath, stream) {
7790
7798
  }
7791
7799
  async function confirmReset() {
7792
7800
  const rl = readline2.createInterface({ input: process.stdin, output: process.stdout });
7793
- const answer = await new Promise((resolve35) => {
7794
- rl.question("Reset project state? This cannot be undone. [y/N] ", resolve35);
7801
+ const answer = await new Promise((resolve36) => {
7802
+ rl.question("Reset project state? This cannot be undone. [y/N] ", resolve36);
7795
7803
  });
7796
7804
  rl.close();
7797
7805
  return answer.toLowerCase() === "y" || answer.toLowerCase() === "yes";
@@ -8019,7 +8027,7 @@ async function runSyncAnalyses(opts) {
8019
8027
  return;
8020
8028
  }
8021
8029
  const { AnalysisArchive, loadPublishedIndex: loadPublishedIndex2, savePublishedIndex: savePublishedIndex2 } = await import("@harness-engineering/orchestrator");
8022
- const { GitHubIssuesSyncAdapter: GitHubIssuesSyncAdapter2 } = await import("./dist-WCSJHQPK.js");
8030
+ const { GitHubIssuesSyncAdapter: GitHubIssuesSyncAdapter2 } = await import("./dist-T3DGV5UN.js");
8023
8031
  const adapter = new GitHubIssuesSyncAdapter2({ token, config: trackerConfig });
8024
8032
  const archive = new AnalysisArchive(path58.join(projectPath, ".harness", "analyses"));
8025
8033
  const publishedIndex = loadPublishedIndex2(projectPath);
@@ -8135,7 +8143,7 @@ function createTaintCommand() {
8135
8143
  }
8136
8144
 
8137
8145
  // src/commands/telemetry/index.ts
8138
- import { Command as Command76 } from "commander";
8146
+ import { Command as Command77 } from "commander";
8139
8147
 
8140
8148
  // src/commands/telemetry/identify.ts
8141
8149
  init_dist();
@@ -8201,29 +8209,33 @@ function resolveDisabledReason() {
8201
8209
  if (process.env.HARNESS_TELEMETRY_OPTOUT === "1") return "HARNESS_TELEMETRY_OPTOUT=1";
8202
8210
  return "telemetry.enabled is false in config";
8203
8211
  }
8212
+ function printIdentity2(identity) {
8213
+ const hasIdentity = identity.project || identity.team || identity.alias;
8214
+ if (!hasIdentity) {
8215
+ logger.info("Identity: not configured");
8216
+ return;
8217
+ }
8218
+ logger.info("Identity:");
8219
+ for (const [key, value] of Object.entries(identity)) {
8220
+ if (value) logger.info(` ${key.padEnd(7)}: ${value}`);
8221
+ }
8222
+ }
8223
+ function printEnvOverrides(overrides) {
8224
+ const keys = Object.keys(overrides);
8225
+ if (keys.length === 0) return;
8226
+ logger.info("Env overrides:");
8227
+ for (const key of keys) {
8228
+ logger.info(` ${key}=${overrides[key]}`);
8229
+ }
8230
+ }
8204
8231
  function printHumanStatus(result) {
8205
8232
  logger.info(`Telemetry: ${result.consent.allowed ? "enabled" : "disabled"}`);
8206
8233
  if (!result.consent.allowed && result.consent.reason) {
8207
8234
  logger.info(` Reason: ${result.consent.reason}`);
8208
8235
  }
8209
8236
  logger.info(`Install ID: ${result.installId ?? "not yet created"}`);
8210
- const { identity } = result;
8211
- const hasIdentity = identity.project || identity.team || identity.alias;
8212
- if (hasIdentity) {
8213
- logger.info("Identity:");
8214
- for (const [key, value] of Object.entries(identity)) {
8215
- if (value) logger.info(` ${key.padEnd(7)}: ${value}`);
8216
- }
8217
- } else {
8218
- logger.info("Identity: not configured");
8219
- }
8220
- const overrideKeys = Object.keys(result.envOverrides);
8221
- if (overrideKeys.length > 0) {
8222
- logger.info("Env overrides:");
8223
- for (const key of overrideKeys) {
8224
- logger.info(` ${key}=${result.envOverrides[key]}`);
8225
- }
8226
- }
8237
+ printIdentity2(result.identity);
8238
+ printEnvOverrides(result.envOverrides);
8227
8239
  }
8228
8240
  function createStatusCommand() {
8229
8241
  const cmd = new Command75("status").description("Show current telemetry consent state, install ID, and identity").option("--json", "Output as JSON").action((opts) => {
@@ -8257,16 +8269,176 @@ function createStatusCommand() {
8257
8269
  return cmd;
8258
8270
  }
8259
8271
 
8272
+ // src/commands/telemetry/test.ts
8273
+ init_dist();
8274
+ import { Command as Command76 } from "commander";
8275
+
8276
+ // src/bin/command-telemetry.ts
8277
+ import { existsSync as existsSync36, readFileSync as readFileSync25, mkdirSync as mkdirSync15, appendFileSync, writeFileSync as writeFileSync18 } from "fs";
8278
+ import { join as join45, parse as parsePath, resolve as resolve33 } from "path";
8279
+ import { spawn as spawn2 } from "child_process";
8280
+ var POSTHOG_API_KEY = "phc_wNTdCMcfJXZPgdNeDociZW6vwoGGo4nb7vqEfWThFfsG";
8281
+ var EXCLUDED_COMMANDS = /* @__PURE__ */ new Set(["help", "completion"]);
8282
+ function findProjectRoot(cwd) {
8283
+ let dir = resolve33(cwd);
8284
+ const { root } = parsePath(dir);
8285
+ while (dir !== root) {
8286
+ if (existsSync36(join45(dir, "harness.config.json"))) return dir;
8287
+ dir = resolve33(dir, "..");
8288
+ }
8289
+ return cwd;
8290
+ }
8291
+ var commandName = "";
8292
+ var startTime = 0;
8293
+ var recorded = false;
8294
+ function installCommandTelemetry(program, cwd) {
8295
+ if (typeof program.hook !== "function") return;
8296
+ const projectRoot = findProjectRoot(cwd);
8297
+ flushTelemetryBackground(projectRoot);
8298
+ program.hook("preAction", (_thisCommand, actionCommand) => {
8299
+ commandName = resolveCommandName(actionCommand);
8300
+ startTime = Date.now();
8301
+ });
8302
+ process.on("exit", (code) => {
8303
+ if (recorded || !commandName || EXCLUDED_COMMANDS.has(commandName)) return;
8304
+ recorded = true;
8305
+ const duration = Date.now() - startTime;
8306
+ const outcome = code === 0 ? "completed" : "failed";
8307
+ writeCommandRecordSync(projectRoot, commandName, duration, outcome);
8308
+ });
8309
+ }
8310
+ function resolveCommandName(cmd) {
8311
+ const parts = [];
8312
+ let current = cmd;
8313
+ while (current) {
8314
+ const name = current.name();
8315
+ if (name && name !== "harness") {
8316
+ parts.unshift(name);
8317
+ }
8318
+ current = current.parent;
8319
+ }
8320
+ return parts.length > 0 ? `cli/${parts.join(".")}` : "";
8321
+ }
8322
+ function writeCommandRecordSync(cwd, command, duration, outcome) {
8323
+ try {
8324
+ const metricsDir = join45(cwd, ".harness", "metrics");
8325
+ mkdirSync15(metricsDir, { recursive: true });
8326
+ const record = {
8327
+ skill: command,
8328
+ session: `cli-${Date.now()}`,
8329
+ startedAt: new Date(Date.now() - duration).toISOString(),
8330
+ duration,
8331
+ outcome,
8332
+ phasesReached: []
8333
+ };
8334
+ const adoptionFile = join45(metricsDir, "adoption.jsonl");
8335
+ appendFileSync(adoptionFile, JSON.stringify(record) + "\n");
8336
+ } catch {
8337
+ }
8338
+ }
8339
+ function isTelemetryDisabledByConfig(cwd) {
8340
+ const configPath = join45(cwd, "harness.config.json");
8341
+ if (!existsSync36(configPath)) return false;
8342
+ try {
8343
+ const config = JSON.parse(readFileSync25(configPath, "utf-8"));
8344
+ return config?.telemetry?.enabled === false;
8345
+ } catch {
8346
+ return false;
8347
+ }
8348
+ }
8349
+ function isTelemetryOptedOut(cwd) {
8350
+ if (isTelemetryDisabledByConfig(cwd)) return true;
8351
+ return process.env.DO_NOT_TRACK === "1" || process.env.HARNESS_TELEMETRY_OPTOUT === "1";
8352
+ }
8353
+ function flushTelemetryBackground(cwd) {
8354
+ try {
8355
+ const adoptionFile = join45(cwd, ".harness", "metrics", "adoption.jsonl");
8356
+ if (!existsSync36(adoptionFile)) return;
8357
+ if (isTelemetryOptedOut(cwd)) return;
8358
+ const reporterPath = join45(cwd, ".harness", "hooks", "telemetry-reporter.js");
8359
+ if (!existsSync36(reporterPath)) return;
8360
+ const child = spawn2(process.execPath, [reporterPath], {
8361
+ cwd,
8362
+ stdio: ["pipe", "ignore", "ignore"],
8363
+ detached: true
8364
+ });
8365
+ child.stdin?.write("{}");
8366
+ child.stdin?.end();
8367
+ child.unref();
8368
+ } catch {
8369
+ }
8370
+ }
8371
+
8372
+ // src/commands/telemetry/test.ts
8373
+ var POSTHOG_BATCH_URL = "https://app.posthog.com/batch";
8374
+ function buildTestEvent(distinctId, installId, identity) {
8375
+ return {
8376
+ event: "telemetry_test",
8377
+ distinct_id: distinctId,
8378
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
8379
+ properties: {
8380
+ installId,
8381
+ os: process.platform,
8382
+ nodeVersion: process.version,
8383
+ test: true,
8384
+ ...identity.project ? { project: identity.project } : {},
8385
+ ...identity.team ? { team: identity.team } : {}
8386
+ }
8387
+ };
8388
+ }
8389
+ function reportTestSuccess(status, distinctId, identity) {
8390
+ logger.success(`PostHog responded ${status} OK \u2014 telemetry is working`);
8391
+ logger.info(` distinct_id: ${distinctId}`);
8392
+ if (identity.project) logger.info(` project: ${identity.project}`);
8393
+ if (identity.team) logger.info(` team: ${identity.team}`);
8394
+ }
8395
+ function createTestCommand() {
8396
+ return new Command76("test").description("Send a test event to PostHog and verify connectivity").action(async () => {
8397
+ const cwd = process.cwd();
8398
+ const consent = resolveConsent(cwd, void 0);
8399
+ if (!consent.allowed) {
8400
+ logger.error("Telemetry is disabled. Run `harness telemetry status` for details.");
8401
+ process.exitCode = 1;
8402
+ return;
8403
+ }
8404
+ const { installId, identity } = consent;
8405
+ const distinctId = identity.alias ?? installId;
8406
+ const event = buildTestEvent(distinctId, installId, identity);
8407
+ const payload = JSON.stringify({ api_key: POSTHOG_API_KEY, batch: [event] });
8408
+ logger.info(`Sending test event as "${distinctId}"...`);
8409
+ try {
8410
+ const res = await fetch(POSTHOG_BATCH_URL, {
8411
+ method: "POST",
8412
+ headers: { "Content-Type": "application/json" },
8413
+ body: payload,
8414
+ signal: AbortSignal.timeout(1e4)
8415
+ });
8416
+ const body = await res.text();
8417
+ if (res.ok) {
8418
+ reportTestSuccess(res.status, distinctId, identity);
8419
+ } else {
8420
+ logger.error(`PostHog responded ${res.status}: ${body}`);
8421
+ process.exitCode = 1;
8422
+ }
8423
+ } catch (err) {
8424
+ const msg = err instanceof Error ? err.message : String(err);
8425
+ logger.error(`Failed to reach PostHog: ${msg}`);
8426
+ process.exitCode = 1;
8427
+ }
8428
+ });
8429
+ }
8430
+
8260
8431
  // src/commands/telemetry/index.ts
8261
8432
  function createTelemetryCommand() {
8262
- const command = new Command76("telemetry").description("Telemetry identity and status management");
8433
+ const command = new Command77("telemetry").description("Telemetry identity and status management");
8263
8434
  command.addCommand(createIdentifyCommand());
8264
8435
  command.addCommand(createStatusCommand());
8436
+ command.addCommand(createTestCommand());
8265
8437
  return command;
8266
8438
  }
8267
8439
 
8268
8440
  // src/commands/traceability.ts
8269
- import { Command as Command77 } from "commander";
8441
+ import { Command as Command78 } from "commander";
8270
8442
  import chalk11 from "chalk";
8271
8443
  function confidenceLabel(maxConfidence) {
8272
8444
  if (maxConfidence >= 0.8) return "explicit";
@@ -8382,7 +8554,7 @@ async function runTraceability(options) {
8382
8554
  const projectPath = process.cwd();
8383
8555
  const store = await loadGraphStore(projectPath);
8384
8556
  if (!store) handleNoStore(mode);
8385
- const graphModule = await import("./dist-RADHOOXG.js");
8557
+ const graphModule = await import("./dist-GRW3X2ZQ.js");
8386
8558
  const filterOptions = buildFilterOptions(options);
8387
8559
  const results = graphModule.queryTraceability(store, filterOptions);
8388
8560
  if (results.length === 0) handleEmptyResults(mode);
@@ -8397,7 +8569,7 @@ async function runTraceability(options) {
8397
8569
  process.exit(ExitCode.SUCCESS);
8398
8570
  }
8399
8571
  function createTraceabilityCommand() {
8400
- return new Command77("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) => {
8572
+ return new Command78("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) => {
8401
8573
  const globalOpts = cmd.optsWithGlobals();
8402
8574
  await runTraceability({
8403
8575
  spec: opts.spec,
@@ -8411,7 +8583,7 @@ function createTraceabilityCommand() {
8411
8583
 
8412
8584
  // src/commands/uninstall.ts
8413
8585
  import * as path60 from "path";
8414
- import { Command as Command78 } from "commander";
8586
+ import { Command as Command79 } from "commander";
8415
8587
  async function runUninstall(skillName, options) {
8416
8588
  const packageName = resolvePackageName(skillName);
8417
8589
  const shortName = extractSkillName(packageName);
@@ -8448,7 +8620,7 @@ async function runUninstall(skillName, options) {
8448
8620
  return result;
8449
8621
  }
8450
8622
  function createUninstallCommand() {
8451
- const cmd = new Command78("uninstall");
8623
+ const cmd = new Command79("uninstall");
8452
8624
  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) => {
8453
8625
  try {
8454
8626
  const result = await runUninstall(skill, opts);
@@ -8470,7 +8642,7 @@ function createUninstallCommand() {
8470
8642
  init_dist();
8471
8643
  import * as fs40 from "fs/promises";
8472
8644
  import * as path61 from "path";
8473
- import { Command as Command79 } from "commander";
8645
+ import { Command as Command80 } from "commander";
8474
8646
  async function runUninstallConstraints(options) {
8475
8647
  const { packageName, configPath, lockfilePath } = options;
8476
8648
  const lockfileResult = await readLockfile(lockfilePath);
@@ -8527,7 +8699,7 @@ async function runUninstallConstraints(options) {
8527
8699
  };
8528
8700
  }
8529
8701
  function createUninstallConstraintsCommand() {
8530
- const cmd = new Command79("uninstall-constraints");
8702
+ const cmd = new Command80("uninstall-constraints");
8531
8703
  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) => {
8532
8704
  let configPath;
8533
8705
  if (opts.config) {
@@ -8566,10 +8738,10 @@ function createUninstallConstraintsCommand() {
8566
8738
  }
8567
8739
 
8568
8740
  // src/commands/update.ts
8569
- import { Command as Command80 } from "commander";
8741
+ import { Command as Command81 } from "commander";
8570
8742
  import { execFile, execFileSync as execFileSync6 } from "child_process";
8571
- import { realpathSync, existsSync as existsSync36, readFileSync as readFileSync25 } from "fs";
8572
- import { join as join47 } from "path";
8743
+ import { realpathSync, existsSync as existsSync37, readFileSync as readFileSync26 } from "fs";
8744
+ import { join as join48 } from "path";
8573
8745
  import { promisify } from "util";
8574
8746
  import readline3 from "readline";
8575
8747
  import chalk12 from "chalk";
@@ -8635,10 +8807,10 @@ function prompt2(question) {
8635
8807
  input: process.stdin,
8636
8808
  output: process.stdout
8637
8809
  });
8638
- return new Promise((resolve35) => {
8810
+ return new Promise((resolve36) => {
8639
8811
  rl.question(question, (answer) => {
8640
8812
  rl.close();
8641
- resolve35(answer.trim().toLowerCase());
8813
+ resolve36(answer.trim().toLowerCase());
8642
8814
  });
8643
8815
  });
8644
8816
  }
@@ -8653,12 +8825,12 @@ async function ensureTelemetryIfNeeded() {
8653
8825
  }
8654
8826
  function refreshHooks() {
8655
8827
  const cwd = process.cwd();
8656
- const configPath = join47(cwd, "harness.config.json");
8657
- if (!existsSync36(configPath)) return;
8828
+ const configPath = join48(cwd, "harness.config.json");
8829
+ if (!existsSync37(configPath)) return;
8658
8830
  let profile = "standard";
8659
- const profilePath = join47(cwd, ".harness", "hooks", "profile.json");
8831
+ const profilePath = join48(cwd, ".harness", "hooks", "profile.json");
8660
8832
  try {
8661
- const data = JSON.parse(readFileSync25(profilePath, "utf-8"));
8833
+ const data = JSON.parse(readFileSync26(profilePath, "utf-8"));
8662
8834
  if (data.profile && ["minimal", "standard", "strict"].includes(data.profile)) {
8663
8835
  profile = data.profile;
8664
8836
  }
@@ -8784,7 +8956,7 @@ async function runUpdateAction(opts, globalOpts) {
8784
8956
  process.exit(ExitCode.SUCCESS);
8785
8957
  }
8786
8958
  function createUpdateCommand() {
8787
- return new Command80("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(
8959
+ return new Command81("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(
8788
8960
  "--regenerate",
8789
8961
  "Only regenerate slash commands and agent definitions (skip package updates)"
8790
8962
  ).action(async (opts, cmd) => {
@@ -8794,9 +8966,9 @@ function createUpdateCommand() {
8794
8966
  }
8795
8967
 
8796
8968
  // src/commands/usage.ts
8797
- import { Command as Command81 } from "commander";
8969
+ import { Command as Command82 } from "commander";
8798
8970
  async function loadAndPriceRecords(cwd, includeClaudeSessions = false) {
8799
- const { readCostRecords, loadPricingData, calculateCost, parseCCRecords } = await import("./dist-WCSJHQPK.js");
8971
+ const { readCostRecords, loadPricingData, calculateCost, parseCCRecords } = await import("./dist-T3DGV5UN.js");
8800
8972
  const records = readCostRecords(cwd);
8801
8973
  if (includeClaudeSessions) {
8802
8974
  const ccRecords = parseCCRecords();
@@ -8840,6 +9012,41 @@ function formatModels(models) {
8840
9012
  if (models.length === 1) return models[0] ?? "unknown";
8841
9013
  return `${models[0] ?? "unknown"} and ${models.length - 1} other${models.length - 1 > 1 ? "s" : ""}`;
8842
9014
  }
9015
+ function enrichDayForJson(day, pricingData) {
9016
+ const hitRate = computeCacheHitRate(day.cacheReadTokens, day.tokens.inputTokens);
9017
+ const savings = computeCacheSavings(day.cacheReadTokens, day.models[0], pricingData);
9018
+ return {
9019
+ ...day,
9020
+ ...hitRate != null ? { cacheHitRate: Math.round(hitRate * 1e3) / 1e3 } : {},
9021
+ ...savings != null ? { cacheSavingsMicroUSD: savings } : {}
9022
+ };
9023
+ }
9024
+ function formatDayCacheColumns(day, pricingData) {
9025
+ const rate = computeCacheHitRate(day.cacheReadTokens, day.tokens.inputTokens);
9026
+ const savings = computeCacheSavings(day.cacheReadTokens, day.models[0], pricingData);
9027
+ const rateStr = rate != null ? formatPercent(rate).padStart(5) : " -";
9028
+ const savingsStr = savings != null ? formatMicroUSD(savings).padStart(7) : " N/A";
9029
+ return " | " + rateStr + " | " + savingsStr;
9030
+ }
9031
+ function printDailyTable(limited, pricingData) {
9032
+ const hasCacheData = limited.some((d) => d.cacheReadTokens != null && d.cacheReadTokens > 0);
9033
+ const cacheHeader = hasCacheData ? " | Cache | Saved " : "";
9034
+ const cacheDivider = hasCacheData ? " | ------ | -------" : "";
9035
+ const header = "Date | Sessions | Input | Output | Model(s) | Cost " + cacheHeader;
9036
+ const divider = "-------------|----------|-----------|-----------|------------------------------|-------" + cacheDivider;
9037
+ logger.info(header);
9038
+ logger.info(divider);
9039
+ for (const day of limited) {
9040
+ const date = day.date.padEnd(12);
9041
+ const sessions = String(day.sessionCount).padStart(8);
9042
+ const input = formatTokenCount(day.tokens.inputTokens).padStart(9);
9043
+ const output = formatTokenCount(day.tokens.outputTokens).padStart(9);
9044
+ const models = formatModels(day.models).padEnd(28);
9045
+ const cost = formatMicroUSD(day.costMicroUSD);
9046
+ const cacheCol = hasCacheData ? formatDayCacheColumns(day, pricingData) : "";
9047
+ logger.info(`${date} | ${sessions} | ${input} | ${output} | ${models} | ${cost}${cacheCol}`);
9048
+ }
9049
+ }
8843
9050
  function registerDailyCommand(usage) {
8844
9051
  usage.command("daily").description("Show per-day token usage and cost").option("--days <n>", "Number of days to show (default: 7, max: 90)", "7").action(async (opts, cmd) => {
8845
9052
  const globalOpts = cmd.optsWithGlobals();
@@ -8850,54 +9057,23 @@ function registerDailyCommand(usage) {
8850
9057
  globalOpts.includeClaudeSessions
8851
9058
  );
8852
9059
  if (records.length === 0) {
8853
- if (globalOpts.json) {
8854
- console.log(JSON.stringify([]));
8855
- } else {
8856
- logger.info("No usage data found. Run some harness sessions first.");
8857
- }
9060
+ if (globalOpts.json) console.log(JSON.stringify([]));
9061
+ else logger.info("No usage data found. Run some harness sessions first.");
8858
9062
  return;
8859
9063
  }
8860
- const { aggregateByDay } = await import("./dist-WCSJHQPK.js");
8861
- const dailyData = aggregateByDay(records);
8862
- const limited = dailyData.slice(0, days);
9064
+ const { aggregateByDay } = await import("./dist-T3DGV5UN.js");
9065
+ const limited = aggregateByDay(records).slice(0, days);
8863
9066
  if (globalOpts.json) {
8864
- const enriched = limited.map((day) => {
8865
- const hitRate = computeCacheHitRate(day.cacheReadTokens, day.tokens.inputTokens);
8866
- const savings = computeCacheSavings(day.cacheReadTokens, day.models[0], pricingData);
8867
- return {
8868
- ...day,
8869
- ...hitRate != null ? { cacheHitRate: Math.round(hitRate * 1e3) / 1e3 } : {},
8870
- ...savings != null ? { cacheSavingsMicroUSD: savings } : {}
8871
- };
8872
- });
8873
- console.log(JSON.stringify(enriched, null, 2));
8874
- return;
8875
- }
8876
- const hasCacheData = limited.some((d) => d.cacheReadTokens != null && d.cacheReadTokens > 0);
8877
- const cacheHeader = hasCacheData ? " | Cache | Saved " : "";
8878
- const cacheDivider = hasCacheData ? " | ------ | -------" : "";
8879
- const header = "Date | Sessions | Input | Output | Model(s) | Cost " + cacheHeader;
8880
- const divider = "-------------|----------|-----------|-----------|------------------------------|-------" + cacheDivider;
8881
- logger.info(header);
8882
- logger.info(divider);
8883
- for (const day of limited) {
8884
- const date = day.date.padEnd(12);
8885
- const sessions = String(day.sessionCount).padStart(8);
8886
- const input = formatTokenCount(day.tokens.inputTokens).padStart(9);
8887
- const output = formatTokenCount(day.tokens.outputTokens).padStart(9);
8888
- const models = formatModels(day.models).padEnd(28);
8889
- const cost = formatMicroUSD(day.costMicroUSD);
8890
- const cacheCol = hasCacheData ? (() => {
8891
- const rate = computeCacheHitRate(day.cacheReadTokens, day.tokens.inputTokens);
8892
- const savings = computeCacheSavings(day.cacheReadTokens, day.models[0], pricingData);
8893
- const rateStr = rate != null ? formatPercent(rate).padStart(5) : " -";
8894
- const savingsStr = savings != null ? formatMicroUSD(savings).padStart(7) : " N/A";
8895
- return " | " + rateStr + " | " + savingsStr;
8896
- })() : "";
8897
- logger.info(
8898
- `${date} | ${sessions} | ${input} | ${output} | ${models} | ${cost}${cacheCol}`
9067
+ console.log(
9068
+ JSON.stringify(
9069
+ limited.map((d) => enrichDayForJson(d, pricingData)),
9070
+ null,
9071
+ 2
9072
+ )
8899
9073
  );
9074
+ return;
8900
9075
  }
9076
+ printDailyTable(limited, pricingData);
8901
9077
  });
8902
9078
  }
8903
9079
  function registerSessionsCommand(usage) {
@@ -8914,7 +9090,7 @@ function registerSessionsCommand(usage) {
8914
9090
  }
8915
9091
  return;
8916
9092
  }
8917
- const { aggregateBySession } = await import("./dist-WCSJHQPK.js");
9093
+ const { aggregateBySession } = await import("./dist-T3DGV5UN.js");
8918
9094
  const sessionData = aggregateBySession(records);
8919
9095
  const limited = sessionData.slice(0, limit);
8920
9096
  if (globalOpts.json) {
@@ -8994,7 +9170,7 @@ function registerSessionCommand(usage) {
8994
9170
  cwd,
8995
9171
  globalOpts.includeClaudeSessions
8996
9172
  );
8997
- const { aggregateBySession } = await import("./dist-WCSJHQPK.js");
9173
+ const { aggregateBySession } = await import("./dist-T3DGV5UN.js");
8998
9174
  const sessionData = aggregateBySession(records);
8999
9175
  const match = sessionData.find((s) => s.sessionId === id);
9000
9176
  if (!match) {
@@ -9029,7 +9205,7 @@ function registerLatestCommand(usage) {
9029
9205
  }
9030
9206
  return;
9031
9207
  }
9032
- const { aggregateBySession } = await import("./dist-WCSJHQPK.js");
9208
+ const { aggregateBySession } = await import("./dist-T3DGV5UN.js");
9033
9209
  const sessionData = aggregateBySession(records);
9034
9210
  const latest = sessionData[0];
9035
9211
  if (!latest) {
@@ -9055,7 +9231,7 @@ function registerLatestCommand(usage) {
9055
9231
  });
9056
9232
  }
9057
9233
  function createUsageCommand() {
9058
- const usage = new Command81("usage").description("Token usage and cost tracking");
9234
+ const usage = new Command82("usage").description("Token usage and cost tracking");
9059
9235
  usage.option(
9060
9236
  "--include-claude-sessions",
9061
9237
  "Include Claude Code session data from ~/.claude/projects/"
@@ -9070,7 +9246,7 @@ function createUsageCommand() {
9070
9246
  // src/commands/validate.ts
9071
9247
  init_dist();
9072
9248
  init_dist();
9073
- import { Command as Command82 } from "commander";
9249
+ import { Command as Command83 } from "commander";
9074
9250
  import * as path62 from "path";
9075
9251
  async function runValidate(options) {
9076
9252
  const configResult = resolveConfig(options.configPath);
@@ -9153,7 +9329,7 @@ function resolveValidateMode(globalOpts) {
9153
9329
  return OutputMode.TEXT;
9154
9330
  }
9155
9331
  async function printCrossCheckWarnings(mode) {
9156
- const { runCrossCheck: runCrossCheck2 } = await import("./validate-cross-check-ZOWFA3DB.js");
9332
+ const { runCrossCheck: runCrossCheck2 } = await import("./validate-cross-check-LJKXBQYH.js");
9157
9333
  const cwd = process.cwd();
9158
9334
  const crossResult = await runCrossCheck2({
9159
9335
  specsDir: path62.join(cwd, "docs", "specs"),
@@ -9169,7 +9345,7 @@ async function printCrossCheckWarnings(mode) {
9169
9345
  ${crossResult.value.warnings} warnings`);
9170
9346
  }
9171
9347
  function createValidateCommand3() {
9172
- const command = new Command82("validate").description("Run all validation checks").option("--cross-check", "Run cross-artifact consistency validation").option(
9348
+ const command = new Command83("validate").description("Run all validation checks").option("--cross-check", "Run cross-artifact consistency validation").option(
9173
9349
  "--agent-configs",
9174
9350
  "Validate agent configs (CLAUDE.md, hooks, skills) via agnix or built-in fallback rules"
9175
9351
  ).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()));
@@ -9278,7 +9454,7 @@ var commandCreators = [
9278
9454
 
9279
9455
  // src/index.ts
9280
9456
  function createProgram() {
9281
- const program = new Command83();
9457
+ const program = new Command84();
9282
9458
  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");
9283
9459
  for (const creator of commandCreators) {
9284
9460
  program.addCommand(creator());
@@ -9298,6 +9474,7 @@ export {
9298
9474
  printFirstRunWelcome,
9299
9475
  buildPreamble,
9300
9476
  runSnapshotCapture,
9477
+ installCommandTelemetry,
9301
9478
  runUninstall,
9302
9479
  runUninstallConstraints,
9303
9480
  createProgram