@harness-engineering/cli 1.25.3 → 1.25.5

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 (115) 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-COWXFHR5.js} +2 -2
  70. package/dist/{architecture-HNIO6AUX.js → architecture-EYPG4ZMC.js} +3 -3
  71. package/dist/{assess-project-6MV5TNY3.js → assess-project-JQPEVJIA.js} +1 -1
  72. package/dist/bin/harness-mcp.js +13 -13
  73. package/dist/bin/harness.js +23 -112
  74. package/dist/{check-phase-gate-VCBQHQAC.js → check-phase-gate-AJRMDGYW.js} +3 -3
  75. package/dist/{chunk-6VZQJ5CX.js → chunk-24ZGGCIW.js} +1 -1
  76. package/dist/{chunk-GEEYCQDS.js → chunk-2OIPQMU5.js} +5 -5
  77. package/dist/{chunk-6WFSSYZG.js → chunk-2OM5TA56.js} +211 -56
  78. package/dist/{chunk-FES2YEQU.js → chunk-2TFT7XRX.js} +3 -3
  79. package/dist/{chunk-AT74HEQM.js → chunk-2X336Q7J.js} +1 -1
  80. package/dist/{chunk-IAMXXLUT.js → chunk-2X42NMPD.js} +71 -68
  81. package/dist/{chunk-WIQA4BSH.js → chunk-5R2LFUU3.js} +1 -1
  82. package/dist/{chunk-FIQL2HND.js → chunk-BVRWLK5U.js} +2 -2
  83. package/dist/{chunk-F23H3U5U.js → chunk-HWLHJSJQ.js} +2 -2
  84. package/dist/{chunk-CXJTVICF.js → chunk-JD4FGVHH.js} +2 -2
  85. package/dist/{chunk-FSNPBT74.js → chunk-KDHZAL4B.js} +1 -1
  86. package/dist/{chunk-MI6MA6OP.js → chunk-KHMKAC6E.js} +71 -32
  87. package/dist/{chunk-UQZBZINS.js → chunk-KVK3KAFQ.js} +6 -6
  88. package/dist/{chunk-P7PANON5.js → chunk-KWQTMJ3B.js} +1 -1
  89. package/dist/{chunk-XTITAVUR.js → chunk-KXUCIAM4.js} +1 -1
  90. package/dist/{chunk-TYV4EUAD.js → chunk-PVRKHUTA.js} +6 -6
  91. package/dist/{chunk-YTP2UDPV.js → chunk-Q6ZEUMOF.js} +3 -3
  92. package/dist/{chunk-UV3BZMGT.js → chunk-UB6NZNJJ.js} +2 -2
  93. package/dist/{chunk-47N6R2F4.js → chunk-UI6NWJJK.js} +1 -1
  94. package/dist/{chunk-EHRZMOQ2.js → chunk-WN6YIQ66.js} +1 -1
  95. package/dist/{chunk-M55DGGF3.js → chunk-YFIALHGI.js} +3 -3
  96. package/dist/{chunk-5BQ5BOJL.js → chunk-ZYYVDA5K.js} +1 -1
  97. package/dist/{ci-workflow-RTM7VVTD.js → ci-workflow-35KBJC2U.js} +2 -2
  98. package/dist/{dist-WCSJHQPK.js → dist-UMONICND.js} +15 -1
  99. package/dist/{docs-UBOGGHTY.js → docs-T5J2AJH6.js} +3 -3
  100. package/dist/{engine-MJJAP5CH.js → engine-KWHV2LUX.js} +2 -2
  101. package/dist/{entropy-EMSXF2PX.js → entropy-GEBHWBPR.js} +2 -2
  102. package/dist/{feedback-ZLUX72HD.js → feedback-I4QPE3RI.js} +1 -1
  103. package/dist/{generate-agent-definitions-AWLPJ27C.js → generate-agent-definitions-3XNR77ET.js} +3 -3
  104. package/dist/hooks/telemetry-reporter.js +22 -1
  105. package/dist/index.d.ts +5 -5
  106. package/dist/index.js +22 -22
  107. package/dist/{loader-JVSJZSWZ.js → loader-MN2CZXPG.js} +2 -2
  108. package/dist/{mcp-PMMA53ZX.js → mcp-XSU77BZY.js} +13 -13
  109. package/dist/{performance-7AGWJUY4.js → performance-7I5MCEFP.js} +3 -3
  110. package/dist/{review-pipeline-ZWVQJTJX.js → review-pipeline-PWPKJXSN.js} +2 -2
  111. package/dist/{runtime-D6YUQPP2.js → runtime-ZYEFJSGS.js} +2 -2
  112. package/dist/{security-JLZUAQYT.js → security-OVTGS7DL.js} +1 -1
  113. package/dist/{validate-TIIHRPMA.js → validate-ACIP5BUO.js} +3 -3
  114. package/dist/{validate-cross-check-ZOWFA3DB.js → validate-cross-check-OWITNCHN.js} +2 -2
  115. package/package.json +5 -5
@@ -1,19 +1,19 @@
1
1
  import {
2
2
  generateAgentsMd
3
- } from "./chunk-5BQ5BOJL.js";
3
+ } from "./chunk-ZYYVDA5K.js";
4
4
  import {
5
5
  generateCIWorkflow
6
- } from "./chunk-EHRZMOQ2.js";
6
+ } from "./chunk-WN6YIQ66.js";
7
7
  import {
8
8
  TemplateEngine
9
- } from "./chunk-FSNPBT74.js";
9
+ } from "./chunk-KDHZAL4B.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-24ZGGCIW.js";
17
17
  import {
18
18
  runPersona
19
19
  } from "./chunk-GISMXMVL.js";
@@ -28,18 +28,18 @@ import {
28
28
  OutputMode,
29
29
  createCheckPhaseGateCommand,
30
30
  findFiles
31
- } from "./chunk-FIQL2HND.js";
31
+ } from "./chunk-BVRWLK5U.js";
32
32
  import {
33
33
  createGenerateAgentDefinitionsCommand,
34
34
  generateAgentDefinitions
35
- } from "./chunk-AT74HEQM.js";
35
+ } from "./chunk-2X336Q7J.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-KWQTMJ3B.js";
43
43
  import {
44
44
  createScanCommand
45
45
  } from "./chunk-4NK7Z3BP.js";
@@ -56,11 +56,11 @@ import {
56
56
  loadOrRebuildIndex,
57
57
  persistToolingConfig,
58
58
  recommend
59
- } from "./chunk-IAMXXLUT.js";
59
+ } from "./chunk-2X42NMPD.js";
60
60
  import {
61
61
  findConfigFile,
62
62
  resolveConfig
63
- } from "./chunk-WIQA4BSH.js";
63
+ } from "./chunk-5R2LFUU3.js";
64
64
  import {
65
65
  VALID_PLATFORMS
66
66
  } from "./chunk-3ISINLYT.js";
@@ -148,7 +148,7 @@ import {
148
148
  validateKnowledgeMap,
149
149
  writeConfig,
150
150
  writeLockfile
151
- } from "./chunk-MI6MA6OP.js";
151
+ } from "./chunk-KHMKAC6E.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-UMONICND.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-UMONICND.js");
402
402
  const records = readAdoptionRecords(cwd);
403
403
  if (records.length === 0) {
404
404
  if (globalOpts.json) {
@@ -435,7 +435,7 @@ function registerSkillCommand(adoption) {
435
435
  adoption.command("skill <name>").description("Show detail for a specific skill").action(async (name, _opts, cmd) => {
436
436
  const globalOpts = cmd.optsWithGlobals();
437
437
  const cwd = process.cwd();
438
- const { readAdoptionRecords, aggregateBySkill } = await import("./dist-WCSJHQPK.js");
438
+ const { readAdoptionRecords, aggregateBySkill } = await import("./dist-UMONICND.js");
439
439
  const records = readAdoptionRecords(cwd);
440
440
  const skillRecords = records.filter((r) => r.skill === name);
441
441
  if (skillRecords.length === 0) {
@@ -2162,6 +2162,11 @@ function runDashboard(opts) {
2162
2162
  DASHBOARD_CLIENT_PORT: String(clientPort),
2163
2163
  HARNESS_PROJECT_PATH: projectPath
2164
2164
  };
2165
+ if (opts.orchestratorUrl) {
2166
+ env["ORCHESTRATOR_URL"] = opts.orchestratorUrl;
2167
+ } else if (!env["ORCHESTRATOR_URL"] && !env["ORCHESTRATOR_PORT"]) {
2168
+ env["ORCHESTRATOR_PORT"] = "8080";
2169
+ }
2165
2170
  spawnDashboardServer(server, env);
2166
2171
  console.log(`Dashboard API starting on http://localhost:${apiPort}`);
2167
2172
  console.log(`Open ${url} (pass --no-open to suppress)`);
@@ -2170,7 +2175,7 @@ function runDashboard(opts) {
2170
2175
  }
2171
2176
  }
2172
2177
  function createDashboardCommand() {
2173
- return new Command19("dashboard").description("Start the Harness local web dashboard").option("--port <port>", "Client dev server port", String(DEFAULT_CLIENT_PORT)).option("--api-port <port>", "API server port", String(DEFAULT_API_PORT)).option("--no-open", "Do not automatically open browser").option("--cwd <path>", "Project directory (defaults to cwd)").action((opts) => runDashboard(opts));
2178
+ return new Command19("dashboard").description("Start the Harness local web dashboard").option("--port <port>", "Client dev server port", String(DEFAULT_CLIENT_PORT)).option("--api-port <port>", "API server port", String(DEFAULT_API_PORT)).option("--orchestrator-url <url>", "Orchestrator URL (default: http://localhost:8080)").option("--no-open", "Do not automatically open browser").option("--cwd <path>", "Project directory (defaults to cwd)").action((opts) => runDashboard(opts));
2174
2179
  }
2175
2180
 
2176
2181
  // src/commands/doctor.ts
@@ -5423,7 +5428,7 @@ function createMcpCommand() {
5423
5428
  parseBudget
5424
5429
  ).action(async (opts) => {
5425
5430
  const [{ startServer: startServer2, getToolDefinitions: getToolDefinitions2 }, { selectTier }] = await Promise.all([
5426
- import("./mcp-PMMA53ZX.js"),
5431
+ import("./mcp-XSU77BZY.js"),
5427
5432
  import("./tool-tiers-7QGZ3FKY.js")
5428
5433
  ]);
5429
5434
  if (opts.tools && opts.tools.length > 0) {
@@ -5489,7 +5494,7 @@ function registerBenchCommand(perf) {
5489
5494
  perf.command("bench [glob]").description("Run benchmarks via vitest bench").action(async (glob2, _opts, cmd) => {
5490
5495
  const globalOpts = cmd.optsWithGlobals();
5491
5496
  const cwd = process.cwd();
5492
- const { BenchmarkRunner } = await import("./dist-WCSJHQPK.js");
5497
+ const { BenchmarkRunner } = await import("./dist-UMONICND.js");
5493
5498
  const runner = new BenchmarkRunner();
5494
5499
  const benchFiles = runner.discover(cwd, glob2);
5495
5500
  if (benchFiles.length === 0) {
@@ -5553,7 +5558,7 @@ async function runBaselinesShow(globalOpts) {
5553
5558
  }
5554
5559
  async function runBaselinesUpdate(globalOpts) {
5555
5560
  const cwd = process.cwd();
5556
- const { BenchmarkRunner } = await import("./dist-WCSJHQPK.js");
5561
+ const { BenchmarkRunner } = await import("./dist-UMONICND.js");
5557
5562
  const runner = new BenchmarkRunner();
5558
5563
  const manager = new BaselineManager(cwd);
5559
5564
  logger.info("Running benchmarks to update baselines...");
@@ -5594,7 +5599,7 @@ function registerReportCommand(perf) {
5594
5599
  perf.command("report").description("Full performance report with metrics, trends, and hotspots").action(async (_opts, cmd) => {
5595
5600
  const globalOpts = cmd.optsWithGlobals();
5596
5601
  const cwd = process.cwd();
5597
- const { EntropyAnalyzer: EntropyAnalyzer2 } = await import("./dist-WCSJHQPK.js");
5602
+ const { EntropyAnalyzer: EntropyAnalyzer2 } = await import("./dist-UMONICND.js");
5598
5603
  const analyzer = new EntropyAnalyzer2({
5599
5604
  rootDir: path40.resolve(cwd),
5600
5605
  analyze: { complexity: true, coupling: true }
@@ -5985,7 +5990,7 @@ async function runPublishAnalyses(opts) {
5985
5990
  const nameToExternalId = buildNameToExternalIdMap(projectPath);
5986
5991
  if (!nameToExternalId) return process.exit(1);
5987
5992
  const { AnalysisArchive } = await import("@harness-engineering/orchestrator");
5988
- const { GitHubIssuesSyncAdapter: GitHubIssuesSyncAdapter2 } = await import("./dist-WCSJHQPK.js");
5993
+ const { GitHubIssuesSyncAdapter: GitHubIssuesSyncAdapter2 } = await import("./dist-UMONICND.js");
5989
5994
  const archive = new AnalysisArchive(path42.join(projectPath, ".harness", "analyses"));
5990
5995
  const analyses = await archive.list();
5991
5996
  if (analyses.length === 0) {
@@ -6270,10 +6275,10 @@ function prompt(question) {
6270
6275
  input: process.stdin,
6271
6276
  output: process.stdout
6272
6277
  });
6273
- return new Promise((resolve35) => {
6278
+ return new Promise((resolve36) => {
6274
6279
  rl.question(question, (answer) => {
6275
6280
  rl.close();
6276
- resolve35(answer.trim().toLowerCase());
6281
+ resolve36(answer.trim().toLowerCase());
6277
6282
  });
6278
6283
  });
6279
6284
  }
@@ -6282,10 +6287,10 @@ function promptRaw(question) {
6282
6287
  input: process.stdin,
6283
6288
  output: process.stdout
6284
6289
  });
6285
- return new Promise((resolve35) => {
6290
+ return new Promise((resolve36) => {
6286
6291
  rl.question(question, (answer) => {
6287
6292
  rl.close();
6288
- resolve35(answer.trim());
6293
+ resolve36(answer.trim());
6289
6294
  });
6290
6295
  });
6291
6296
  }
@@ -7785,8 +7790,8 @@ async function resolveStatePath(projectPath, stream) {
7785
7790
  }
7786
7791
  async function confirmReset() {
7787
7792
  const rl = readline2.createInterface({ input: process.stdin, output: process.stdout });
7788
- const answer = await new Promise((resolve35) => {
7789
- rl.question("Reset project state? This cannot be undone. [y/N] ", resolve35);
7793
+ const answer = await new Promise((resolve36) => {
7794
+ rl.question("Reset project state? This cannot be undone. [y/N] ", resolve36);
7790
7795
  });
7791
7796
  rl.close();
7792
7797
  return answer.toLowerCase() === "y" || answer.toLowerCase() === "yes";
@@ -8014,7 +8019,7 @@ async function runSyncAnalyses(opts) {
8014
8019
  return;
8015
8020
  }
8016
8021
  const { AnalysisArchive, loadPublishedIndex: loadPublishedIndex2, savePublishedIndex: savePublishedIndex2 } = await import("@harness-engineering/orchestrator");
8017
- const { GitHubIssuesSyncAdapter: GitHubIssuesSyncAdapter2 } = await import("./dist-WCSJHQPK.js");
8022
+ const { GitHubIssuesSyncAdapter: GitHubIssuesSyncAdapter2 } = await import("./dist-UMONICND.js");
8018
8023
  const adapter = new GitHubIssuesSyncAdapter2({ token, config: trackerConfig });
8019
8024
  const archive = new AnalysisArchive(path58.join(projectPath, ".harness", "analyses"));
8020
8025
  const publishedIndex = loadPublishedIndex2(projectPath);
@@ -8130,7 +8135,7 @@ function createTaintCommand() {
8130
8135
  }
8131
8136
 
8132
8137
  // src/commands/telemetry/index.ts
8133
- import { Command as Command76 } from "commander";
8138
+ import { Command as Command77 } from "commander";
8134
8139
 
8135
8140
  // src/commands/telemetry/identify.ts
8136
8141
  init_dist();
@@ -8252,16 +8257,165 @@ function createStatusCommand() {
8252
8257
  return cmd;
8253
8258
  }
8254
8259
 
8260
+ // src/commands/telemetry/test.ts
8261
+ init_dist();
8262
+ import { Command as Command76 } from "commander";
8263
+
8264
+ // src/bin/command-telemetry.ts
8265
+ import { existsSync as existsSync36, readFileSync as readFileSync25, mkdirSync as mkdirSync15, appendFileSync, writeFileSync as writeFileSync18 } from "fs";
8266
+ import { join as join45, parse as parsePath, resolve as resolve33 } from "path";
8267
+ import { spawn as spawn2 } from "child_process";
8268
+ var POSTHOG_API_KEY = "phc_wNTdCMcfJXZPgdNeDociZW6vwoGGo4nb7vqEfWThFfsG";
8269
+ var EXCLUDED_COMMANDS = /* @__PURE__ */ new Set(["help", "completion"]);
8270
+ function findProjectRoot(cwd) {
8271
+ let dir = resolve33(cwd);
8272
+ const { root } = parsePath(dir);
8273
+ while (dir !== root) {
8274
+ if (existsSync36(join45(dir, "harness.config.json"))) return dir;
8275
+ dir = resolve33(dir, "..");
8276
+ }
8277
+ return cwd;
8278
+ }
8279
+ var commandName = "";
8280
+ var startTime = 0;
8281
+ var recorded = false;
8282
+ function installCommandTelemetry(program, cwd) {
8283
+ if (typeof program.hook !== "function") return;
8284
+ const projectRoot = findProjectRoot(cwd);
8285
+ flushTelemetryBackground(projectRoot);
8286
+ program.hook("preAction", (thisCommand) => {
8287
+ commandName = resolveCommandName(thisCommand);
8288
+ startTime = Date.now();
8289
+ });
8290
+ process.on("exit", (code) => {
8291
+ if (recorded || !commandName || EXCLUDED_COMMANDS.has(commandName)) return;
8292
+ recorded = true;
8293
+ const duration = Date.now() - startTime;
8294
+ const outcome = code === 0 ? "completed" : "failed";
8295
+ writeCommandRecordSync(projectRoot, commandName, duration, outcome);
8296
+ });
8297
+ }
8298
+ function resolveCommandName(cmd) {
8299
+ const parts = [];
8300
+ let current = cmd;
8301
+ while (current) {
8302
+ const name = current.name();
8303
+ if (name && name !== "harness") {
8304
+ parts.unshift(name);
8305
+ }
8306
+ current = current.parent;
8307
+ }
8308
+ return parts.length > 0 ? `cli/${parts.join(".")}` : "";
8309
+ }
8310
+ function writeCommandRecordSync(cwd, command, duration, outcome) {
8311
+ try {
8312
+ const metricsDir = join45(cwd, ".harness", "metrics");
8313
+ mkdirSync15(metricsDir, { recursive: true });
8314
+ const record = {
8315
+ skill: command,
8316
+ session: `cli-${Date.now()}`,
8317
+ startedAt: new Date(Date.now() - duration).toISOString(),
8318
+ duration,
8319
+ outcome,
8320
+ phasesReached: []
8321
+ };
8322
+ const adoptionFile = join45(metricsDir, "adoption.jsonl");
8323
+ appendFileSync(adoptionFile, JSON.stringify(record) + "\n");
8324
+ } catch {
8325
+ }
8326
+ }
8327
+ function flushTelemetryBackground(cwd) {
8328
+ try {
8329
+ const adoptionFile = join45(cwd, ".harness", "metrics", "adoption.jsonl");
8330
+ if (!existsSync36(adoptionFile)) return;
8331
+ const configPath = join45(cwd, "harness.config.json");
8332
+ if (existsSync36(configPath)) {
8333
+ try {
8334
+ const config = JSON.parse(readFileSync25(configPath, "utf-8"));
8335
+ if (config?.telemetry?.enabled === false) return;
8336
+ } catch {
8337
+ }
8338
+ }
8339
+ if (process.env.DO_NOT_TRACK === "1") return;
8340
+ if (process.env.HARNESS_TELEMETRY_OPTOUT === "1") return;
8341
+ const reporterPath = join45(cwd, ".harness", "hooks", "telemetry-reporter.js");
8342
+ if (!existsSync36(reporterPath)) return;
8343
+ const child = spawn2(process.execPath, [reporterPath], {
8344
+ cwd,
8345
+ stdio: ["pipe", "ignore", "ignore"],
8346
+ detached: true
8347
+ });
8348
+ child.stdin?.write("{}");
8349
+ child.stdin?.end();
8350
+ child.unref();
8351
+ } catch {
8352
+ }
8353
+ }
8354
+
8355
+ // src/commands/telemetry/test.ts
8356
+ var POSTHOG_BATCH_URL = "https://app.posthog.com/batch";
8357
+ function createTestCommand() {
8358
+ return new Command76("test").description("Send a test event to PostHog and verify connectivity").action(async () => {
8359
+ const cwd = process.cwd();
8360
+ const consent = resolveConsent(cwd, void 0);
8361
+ if (!consent.allowed) {
8362
+ logger.error("Telemetry is disabled. Run `harness telemetry status` for details.");
8363
+ process.exitCode = 1;
8364
+ return;
8365
+ }
8366
+ const { installId, identity } = consent;
8367
+ const distinctId = identity.alias ?? installId;
8368
+ const event = {
8369
+ event: "telemetry_test",
8370
+ distinct_id: distinctId,
8371
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
8372
+ properties: {
8373
+ installId,
8374
+ os: process.platform,
8375
+ nodeVersion: process.version,
8376
+ test: true,
8377
+ ...identity.project ? { project: identity.project } : {},
8378
+ ...identity.team ? { team: identity.team } : {}
8379
+ }
8380
+ };
8381
+ const payload = JSON.stringify({ api_key: POSTHOG_API_KEY, batch: [event] });
8382
+ logger.info(`Sending test event as "${distinctId}"...`);
8383
+ try {
8384
+ const res = await fetch(POSTHOG_BATCH_URL, {
8385
+ method: "POST",
8386
+ headers: { "Content-Type": "application/json" },
8387
+ body: payload,
8388
+ signal: AbortSignal.timeout(1e4)
8389
+ });
8390
+ const body = await res.text();
8391
+ if (res.ok) {
8392
+ logger.success(`PostHog responded ${res.status} OK \u2014 telemetry is working`);
8393
+ logger.info(` distinct_id: ${distinctId}`);
8394
+ if (identity.project) logger.info(` project: ${identity.project}`);
8395
+ if (identity.team) logger.info(` team: ${identity.team}`);
8396
+ } else {
8397
+ logger.error(`PostHog responded ${res.status}: ${body}`);
8398
+ process.exitCode = 1;
8399
+ }
8400
+ } catch (err) {
8401
+ const msg = err instanceof Error ? err.message : String(err);
8402
+ logger.error(`Failed to reach PostHog: ${msg}`);
8403
+ process.exitCode = 1;
8404
+ }
8405
+ });
8406
+ }
8407
+
8255
8408
  // src/commands/telemetry/index.ts
8256
8409
  function createTelemetryCommand() {
8257
- const command = new Command76("telemetry").description("Telemetry identity and status management");
8410
+ const command = new Command77("telemetry").description("Telemetry identity and status management");
8258
8411
  command.addCommand(createIdentifyCommand());
8259
8412
  command.addCommand(createStatusCommand());
8413
+ command.addCommand(createTestCommand());
8260
8414
  return command;
8261
8415
  }
8262
8416
 
8263
8417
  // src/commands/traceability.ts
8264
- import { Command as Command77 } from "commander";
8418
+ import { Command as Command78 } from "commander";
8265
8419
  import chalk11 from "chalk";
8266
8420
  function confidenceLabel(maxConfidence) {
8267
8421
  if (maxConfidence >= 0.8) return "explicit";
@@ -8392,7 +8546,7 @@ async function runTraceability(options) {
8392
8546
  process.exit(ExitCode.SUCCESS);
8393
8547
  }
8394
8548
  function createTraceabilityCommand() {
8395
- 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) => {
8549
+ 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) => {
8396
8550
  const globalOpts = cmd.optsWithGlobals();
8397
8551
  await runTraceability({
8398
8552
  spec: opts.spec,
@@ -8406,7 +8560,7 @@ function createTraceabilityCommand() {
8406
8560
 
8407
8561
  // src/commands/uninstall.ts
8408
8562
  import * as path60 from "path";
8409
- import { Command as Command78 } from "commander";
8563
+ import { Command as Command79 } from "commander";
8410
8564
  async function runUninstall(skillName, options) {
8411
8565
  const packageName = resolvePackageName(skillName);
8412
8566
  const shortName = extractSkillName(packageName);
@@ -8443,7 +8597,7 @@ async function runUninstall(skillName, options) {
8443
8597
  return result;
8444
8598
  }
8445
8599
  function createUninstallCommand() {
8446
- const cmd = new Command78("uninstall");
8600
+ const cmd = new Command79("uninstall");
8447
8601
  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) => {
8448
8602
  try {
8449
8603
  const result = await runUninstall(skill, opts);
@@ -8465,7 +8619,7 @@ function createUninstallCommand() {
8465
8619
  init_dist();
8466
8620
  import * as fs40 from "fs/promises";
8467
8621
  import * as path61 from "path";
8468
- import { Command as Command79 } from "commander";
8622
+ import { Command as Command80 } from "commander";
8469
8623
  async function runUninstallConstraints(options) {
8470
8624
  const { packageName, configPath, lockfilePath } = options;
8471
8625
  const lockfileResult = await readLockfile(lockfilePath);
@@ -8522,7 +8676,7 @@ async function runUninstallConstraints(options) {
8522
8676
  };
8523
8677
  }
8524
8678
  function createUninstallConstraintsCommand() {
8525
- const cmd = new Command79("uninstall-constraints");
8679
+ const cmd = new Command80("uninstall-constraints");
8526
8680
  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) => {
8527
8681
  let configPath;
8528
8682
  if (opts.config) {
@@ -8561,10 +8715,10 @@ function createUninstallConstraintsCommand() {
8561
8715
  }
8562
8716
 
8563
8717
  // src/commands/update.ts
8564
- import { Command as Command80 } from "commander";
8718
+ import { Command as Command81 } from "commander";
8565
8719
  import { execFile, execFileSync as execFileSync6 } from "child_process";
8566
- import { realpathSync, existsSync as existsSync36, readFileSync as readFileSync25 } from "fs";
8567
- import { join as join47 } from "path";
8720
+ import { realpathSync, existsSync as existsSync37, readFileSync as readFileSync26 } from "fs";
8721
+ import { join as join48 } from "path";
8568
8722
  import { promisify } from "util";
8569
8723
  import readline3 from "readline";
8570
8724
  import chalk12 from "chalk";
@@ -8630,10 +8784,10 @@ function prompt2(question) {
8630
8784
  input: process.stdin,
8631
8785
  output: process.stdout
8632
8786
  });
8633
- return new Promise((resolve35) => {
8787
+ return new Promise((resolve36) => {
8634
8788
  rl.question(question, (answer) => {
8635
8789
  rl.close();
8636
- resolve35(answer.trim().toLowerCase());
8790
+ resolve36(answer.trim().toLowerCase());
8637
8791
  });
8638
8792
  });
8639
8793
  }
@@ -8648,12 +8802,12 @@ async function ensureTelemetryIfNeeded() {
8648
8802
  }
8649
8803
  function refreshHooks() {
8650
8804
  const cwd = process.cwd();
8651
- const configPath = join47(cwd, "harness.config.json");
8652
- if (!existsSync36(configPath)) return;
8805
+ const configPath = join48(cwd, "harness.config.json");
8806
+ if (!existsSync37(configPath)) return;
8653
8807
  let profile = "standard";
8654
- const profilePath = join47(cwd, ".harness", "hooks", "profile.json");
8808
+ const profilePath = join48(cwd, ".harness", "hooks", "profile.json");
8655
8809
  try {
8656
- const data = JSON.parse(readFileSync25(profilePath, "utf-8"));
8810
+ const data = JSON.parse(readFileSync26(profilePath, "utf-8"));
8657
8811
  if (data.profile && ["minimal", "standard", "strict"].includes(data.profile)) {
8658
8812
  profile = data.profile;
8659
8813
  }
@@ -8779,7 +8933,7 @@ async function runUpdateAction(opts, globalOpts) {
8779
8933
  process.exit(ExitCode.SUCCESS);
8780
8934
  }
8781
8935
  function createUpdateCommand() {
8782
- 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(
8936
+ 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(
8783
8937
  "--regenerate",
8784
8938
  "Only regenerate slash commands and agent definitions (skip package updates)"
8785
8939
  ).action(async (opts, cmd) => {
@@ -8789,9 +8943,9 @@ function createUpdateCommand() {
8789
8943
  }
8790
8944
 
8791
8945
  // src/commands/usage.ts
8792
- import { Command as Command81 } from "commander";
8946
+ import { Command as Command82 } from "commander";
8793
8947
  async function loadAndPriceRecords(cwd, includeClaudeSessions = false) {
8794
- const { readCostRecords, loadPricingData, calculateCost, parseCCRecords } = await import("./dist-WCSJHQPK.js");
8948
+ const { readCostRecords, loadPricingData, calculateCost, parseCCRecords } = await import("./dist-UMONICND.js");
8795
8949
  const records = readCostRecords(cwd);
8796
8950
  if (includeClaudeSessions) {
8797
8951
  const ccRecords = parseCCRecords();
@@ -8852,7 +9006,7 @@ function registerDailyCommand(usage) {
8852
9006
  }
8853
9007
  return;
8854
9008
  }
8855
- const { aggregateByDay } = await import("./dist-WCSJHQPK.js");
9009
+ const { aggregateByDay } = await import("./dist-UMONICND.js");
8856
9010
  const dailyData = aggregateByDay(records);
8857
9011
  const limited = dailyData.slice(0, days);
8858
9012
  if (globalOpts.json) {
@@ -8909,7 +9063,7 @@ function registerSessionsCommand(usage) {
8909
9063
  }
8910
9064
  return;
8911
9065
  }
8912
- const { aggregateBySession } = await import("./dist-WCSJHQPK.js");
9066
+ const { aggregateBySession } = await import("./dist-UMONICND.js");
8913
9067
  const sessionData = aggregateBySession(records);
8914
9068
  const limited = sessionData.slice(0, limit);
8915
9069
  if (globalOpts.json) {
@@ -8989,7 +9143,7 @@ function registerSessionCommand(usage) {
8989
9143
  cwd,
8990
9144
  globalOpts.includeClaudeSessions
8991
9145
  );
8992
- const { aggregateBySession } = await import("./dist-WCSJHQPK.js");
9146
+ const { aggregateBySession } = await import("./dist-UMONICND.js");
8993
9147
  const sessionData = aggregateBySession(records);
8994
9148
  const match = sessionData.find((s) => s.sessionId === id);
8995
9149
  if (!match) {
@@ -9024,7 +9178,7 @@ function registerLatestCommand(usage) {
9024
9178
  }
9025
9179
  return;
9026
9180
  }
9027
- const { aggregateBySession } = await import("./dist-WCSJHQPK.js");
9181
+ const { aggregateBySession } = await import("./dist-UMONICND.js");
9028
9182
  const sessionData = aggregateBySession(records);
9029
9183
  const latest = sessionData[0];
9030
9184
  if (!latest) {
@@ -9050,7 +9204,7 @@ function registerLatestCommand(usage) {
9050
9204
  });
9051
9205
  }
9052
9206
  function createUsageCommand() {
9053
- const usage = new Command81("usage").description("Token usage and cost tracking");
9207
+ const usage = new Command82("usage").description("Token usage and cost tracking");
9054
9208
  usage.option(
9055
9209
  "--include-claude-sessions",
9056
9210
  "Include Claude Code session data from ~/.claude/projects/"
@@ -9065,7 +9219,7 @@ function createUsageCommand() {
9065
9219
  // src/commands/validate.ts
9066
9220
  init_dist();
9067
9221
  init_dist();
9068
- import { Command as Command82 } from "commander";
9222
+ import { Command as Command83 } from "commander";
9069
9223
  import * as path62 from "path";
9070
9224
  async function runValidate(options) {
9071
9225
  const configResult = resolveConfig(options.configPath);
@@ -9148,7 +9302,7 @@ function resolveValidateMode(globalOpts) {
9148
9302
  return OutputMode.TEXT;
9149
9303
  }
9150
9304
  async function printCrossCheckWarnings(mode) {
9151
- const { runCrossCheck: runCrossCheck2 } = await import("./validate-cross-check-ZOWFA3DB.js");
9305
+ const { runCrossCheck: runCrossCheck2 } = await import("./validate-cross-check-OWITNCHN.js");
9152
9306
  const cwd = process.cwd();
9153
9307
  const crossResult = await runCrossCheck2({
9154
9308
  specsDir: path62.join(cwd, "docs", "specs"),
@@ -9164,7 +9318,7 @@ async function printCrossCheckWarnings(mode) {
9164
9318
  ${crossResult.value.warnings} warnings`);
9165
9319
  }
9166
9320
  function createValidateCommand3() {
9167
- const command = new Command82("validate").description("Run all validation checks").option("--cross-check", "Run cross-artifact consistency validation").option(
9321
+ const command = new Command83("validate").description("Run all validation checks").option("--cross-check", "Run cross-artifact consistency validation").option(
9168
9322
  "--agent-configs",
9169
9323
  "Validate agent configs (CLAUDE.md, hooks, skills) via agnix or built-in fallback rules"
9170
9324
  ).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()));
@@ -9273,7 +9427,7 @@ var commandCreators = [
9273
9427
 
9274
9428
  // src/index.ts
9275
9429
  function createProgram() {
9276
- const program = new Command83();
9430
+ const program = new Command84();
9277
9431
  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");
9278
9432
  for (const creator of commandCreators) {
9279
9433
  program.addCommand(creator());
@@ -9293,6 +9447,7 @@ export {
9293
9447
  printFirstRunWelcome,
9294
9448
  buildPreamble,
9295
9449
  runSnapshotCapture,
9450
+ installCommandTelemetry,
9296
9451
  runUninstall,
9297
9452
  runUninstallConstraints,
9298
9453
  createProgram
@@ -33,7 +33,7 @@ var createSelfReviewDefinition = {
33
33
  };
34
34
  async function handleCreateSelfReview(input) {
35
35
  try {
36
- const { parseDiff, createSelfReview } = await import("./dist-WCSJHQPK.js");
36
+ const { parseDiff, createSelfReview } = await import("./dist-UMONICND.js");
37
37
  const parseResult = parseDiff(input.diff);
38
38
  if (!parseResult.ok) {
39
39
  return resultToMcpResponse(parseResult);
@@ -119,7 +119,7 @@ var analyzeDiffDefinition = {
119
119
  };
120
120
  async function handleAnalyzeDiff(input) {
121
121
  try {
122
- const { parseDiff, analyzeDiff } = await import("./dist-WCSJHQPK.js");
122
+ const { parseDiff, analyzeDiff } = await import("./dist-UMONICND.js");
123
123
  const parseResult = parseDiff(input.diff);
124
124
  if (!parseResult.ok) {
125
125
  return resultToMcpResponse(parseResult);
@@ -195,7 +195,7 @@ var requestPeerReviewDefinition = {
195
195
  };
196
196
  async function handleRequestPeerReview(input) {
197
197
  try {
198
- const { parseDiff, requestPeerReview } = await import("./dist-WCSJHQPK.js");
198
+ const { parseDiff, requestPeerReview } = await import("./dist-UMONICND.js");
199
199
  const parseResult = parseDiff(input.diff);
200
200
  if (!parseResult.ok) {
201
201
  return resultToMcpResponse(parseResult);
@@ -4,7 +4,7 @@ import {
4
4
  import {
5
5
  listPersonas,
6
6
  loadPersona
7
- } from "./chunk-P7PANON5.js";
7
+ } from "./chunk-KWQTMJ3B.js";
8
8
  import {
9
9
  GENERATED_HEADER_AGENT,
10
10
  VALID_PLATFORMS,