@harness-engineering/cli 4.2.0 → 4.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/dist/{agents-md-BK2UPKUC.js → agents-md-N4ULMUAK.js} +4 -4
  2. package/dist/{analyzer-XRCV63KC-6T2Z32XC.js → analyzer-XRCV63KC-WGRHW2ZM.js} +2 -2
  3. package/dist/{architecture-7PNQZOWV.js → architecture-OIMIBDJC.js} +5 -5
  4. package/dist/{assess-project-2QPCNN7N.js → assess-project-ITSB6W4L.js} +1 -1
  5. package/dist/bin/harness-mcp.js +15 -15
  6. package/dist/bin/harness.js +25 -25
  7. package/dist/{check-phase-gate-RZUSDB3O.js → check-phase-gate-GN4X7HT6.js} +5 -5
  8. package/dist/{chunk-ZIJABBGZ.js → chunk-574JCBYH.js} +2 -2
  9. package/dist/{chunk-E5KJOUHI.js → chunk-5BUHPOCP.js} +7 -7
  10. package/dist/{chunk-YTJIRQON.js → chunk-6NEJPS7W.js} +2 -2
  11. package/dist/{chunk-MHHISNS2.js → chunk-73QZ43DF.js} +2 -2
  12. package/dist/{chunk-RZTLXZHJ.js → chunk-7RH2NTLA.js} +1 -1
  13. package/dist/{chunk-DVG6DDX6.js → chunk-CMU4DNLY.js} +1 -1
  14. package/dist/{chunk-33OU3LYX.js → chunk-CRHQYBDA.js} +48 -12
  15. package/dist/{chunk-J7H5I4FO.js → chunk-D7A5JR7M.js} +2 -2
  16. package/dist/{chunk-SI4O2W4H.js → chunk-GTHL3TRZ.js} +2 -2
  17. package/dist/{chunk-J5MFNKE7.js → chunk-H5GN7R43.js} +2 -2
  18. package/dist/{chunk-D5YCPIK6.js → chunk-HJYAXAYQ.js} +2 -2
  19. package/dist/{chunk-K5R2I37T.js → chunk-HSYU3RUW.js} +85 -85
  20. package/dist/{chunk-DBCC7KIW.js → chunk-JZL2O3RC.js} +5 -5
  21. package/dist/{chunk-V2GJE5J5.js → chunk-LP764MGR.js} +3 -3
  22. package/dist/{chunk-6STDKKAM.js → chunk-LTYVAKWK.js} +2 -2
  23. package/dist/{chunk-KYFXXEK3.js → chunk-MEDRUIRO.js} +3 -3
  24. package/dist/{chunk-DW6HE5DH.js → chunk-MIZQY35D.js} +2 -2
  25. package/dist/{chunk-KHL6WFRL.js → chunk-NEMB36N4.js} +2 -2
  26. package/dist/{chunk-BJDT3VGQ.js → chunk-PT65VY4S.js} +6 -6
  27. package/dist/{chunk-HUC73DZC.js → chunk-T46G6YNI.js} +3 -3
  28. package/dist/{chunk-RRCS27GT.js → chunk-TDPQZAEE.js} +284 -115
  29. package/dist/{chunk-VC2B275U.js → chunk-TKPAOB2T.js} +2 -2
  30. package/dist/{chunk-HU7NS7JA.js → chunk-U2NOOATF.js} +6 -6
  31. package/dist/{chunk-UEXQMI6K.js → chunk-VJDSB7CI.js} +112 -50
  32. package/dist/{chunk-XACP5P2J.js → chunk-XKILFNRK.js} +2 -2
  33. package/dist/{ci-workflow-LGN7LHHO.js → ci-workflow-PA3WL6WK.js} +4 -4
  34. package/dist/{dist-LE5AU7FR.js → dist-BWFFVKEW.js} +20 -4
  35. package/dist/{dist-FBBADRYS.js → dist-ISDDHDOR.js} +17 -3
  36. package/dist/{docs-3BTPSHKE.js → docs-HOTWQJQF.js} +5 -5
  37. package/dist/{engine-GWGU4AMH.js → engine-MVG2SPGD.js} +4 -4
  38. package/dist/{entropy-35XURODP.js → entropy-3B4U2BTF.js} +5 -5
  39. package/dist/{feedback-NDGZZ37W.js → feedback-WIWWDVUC.js} +1 -1
  40. package/dist/{generate-agent-definitions-PYZ3E7SP.js → generate-agent-definitions-KPRHY6X3.js} +5 -5
  41. package/dist/index.js +25 -25
  42. package/dist/{loader-QK2OJXKB.js → loader-SPJ2ZGYW.js} +4 -4
  43. package/dist/{mcp-Z5YMV7TA.js → mcp-RIPEYDMU.js} +15 -15
  44. package/dist/{performance-VAYOYPVK.js → performance-JYFS27B3.js} +5 -5
  45. package/dist/{review-pipeline-UETEOWSS.js → review-pipeline-BDT6Y6QV.js} +4 -4
  46. package/dist/{runtime-J7KFACTK.js → runtime-ZEPHPPQJ.js} +4 -4
  47. package/dist/{security-6AIUZXF5.js → security-FWSDTTEW.js} +1 -1
  48. package/dist/{state-events-XQPHGLG5.js → state-events-PBDNQPXT.js} +4 -4
  49. package/dist/{validate-ON7YMVLY.js → validate-XIMNCIKR.js} +5 -5
  50. package/dist/{validate-cross-check-HKKQA7K5.js → validate-cross-check-H2OUHTID.js} +4 -4
  51. package/package.json +8 -8
@@ -1,22 +1,22 @@
1
1
  import {
2
2
  generateRuntime
3
- } from "./chunk-ZIJABBGZ.js";
3
+ } from "./chunk-574JCBYH.js";
4
4
  import {
5
5
  generateAgentsMd
6
- } from "./chunk-VC2B275U.js";
6
+ } from "./chunk-TKPAOB2T.js";
7
7
  import {
8
8
  generateCIWorkflow
9
- } from "./chunk-SI4O2W4H.js";
9
+ } from "./chunk-GTHL3TRZ.js";
10
10
  import {
11
11
  readHarnessState
12
- } from "./chunk-KHL6WFRL.js";
12
+ } from "./chunk-NEMB36N4.js";
13
13
  import {
14
14
  runCrossCheck
15
- } from "./chunk-DW6HE5DH.js";
15
+ } from "./chunk-MIZQY35D.js";
16
16
  import {
17
17
  createGenerateAgentDefinitionsCommand,
18
18
  generateAgentDefinitions
19
- } from "./chunk-DVG6DDX6.js";
19
+ } from "./chunk-CMU4DNLY.js";
20
20
  import {
21
21
  toKebabCase
22
22
  } from "./chunk-KET4QQZB.js";
@@ -26,7 +26,7 @@ import {
26
26
  } from "./chunk-YYFSFSB3.js";
27
27
  import {
28
28
  TemplateEngine
29
- } from "./chunk-YTJIRQON.js";
29
+ } from "./chunk-6NEJPS7W.js";
30
30
  import {
31
31
  generate,
32
32
  validate
@@ -37,7 +37,7 @@ import {
37
37
  import {
38
38
  listPersonas,
39
39
  loadPersona
40
- } from "./chunk-MHHISNS2.js";
40
+ } from "./chunk-73QZ43DF.js";
41
41
  import {
42
42
  runPersona
43
43
  } from "./chunk-GISMXMVL.js";
@@ -51,7 +51,7 @@ import {
51
51
  OutputFormatter,
52
52
  OutputMode,
53
53
  createCheckPhaseGateCommand
54
- } from "./chunk-V2GJE5J5.js";
54
+ } from "./chunk-LP764MGR.js";
55
55
  import {
56
56
  appendFrameworkAgents,
57
57
  captureHealthSnapshot,
@@ -79,7 +79,7 @@ import {
79
79
  runSecurityCraft,
80
80
  runSpecCraft,
81
81
  runTestCraft
82
- } from "./chunk-K5R2I37T.js";
82
+ } from "./chunk-HSYU3RUW.js";
83
83
  import {
84
84
  VALID_PLATFORMS
85
85
  } from "./chunk-3ISINLYT.js";
@@ -108,7 +108,7 @@ import {
108
108
  BranchingConfigSchema,
109
109
  findConfigFile,
110
110
  resolveConfig
111
- } from "./chunk-6STDKKAM.js";
111
+ } from "./chunk-LTYVAKWK.js";
112
112
  import {
113
113
  logger
114
114
  } from "./chunk-EBJQ6N4M.js";
@@ -225,7 +225,7 @@ import {
225
225
  writeConfig,
226
226
  writeLockfile,
227
227
  writeRegeneratedRoadmap
228
- } from "./chunk-33OU3LYX.js";
228
+ } from "./chunk-CRHQYBDA.js";
229
229
  import {
230
230
  CLI_VERSION
231
231
  } from "./chunk-BM3PWGXQ.js";
@@ -238,14 +238,14 @@ import {
238
238
  detectDocDrift,
239
239
  generateSuggestions,
240
240
  validateDependencies
241
- } from "./chunk-RZTLXZHJ.js";
241
+ } from "./chunk-7RH2NTLA.js";
242
242
  import {
243
243
  Err,
244
244
  INDEXED_FILE_KINDS,
245
245
  INSIGHTS_KEYS,
246
246
  Ok,
247
247
  init_dist
248
- } from "./chunk-UEXQMI6K.js";
248
+ } from "./chunk-VJDSB7CI.js";
249
249
  import {
250
250
  DEFAULT_SKIP_DIRS,
251
251
  DesignConstraintAdapter,
@@ -453,7 +453,7 @@ function registerSkillsCommand(adoption) {
453
453
  const globalOpts = cmd.optsWithGlobals();
454
454
  const limit = Math.max(parseInt(opts.limit, 10) || 20, 1);
455
455
  const cwd = process.cwd();
456
- const { readAdoptionRecords, aggregateBySkill } = await import("./dist-LE5AU7FR.js");
456
+ const { readAdoptionRecords, aggregateBySkill } = await import("./dist-BWFFVKEW.js");
457
457
  const records = readAdoptionRecords(cwd);
458
458
  if (records.length === 0) {
459
459
  if (globalOpts.json) {
@@ -489,7 +489,7 @@ function registerRecentCommand(adoption) {
489
489
  const globalOpts = cmd.optsWithGlobals();
490
490
  const limit = Math.max(parseInt(opts.limit, 10) || 20, 1);
491
491
  const cwd = process.cwd();
492
- const { readAdoptionRecords } = await import("./dist-LE5AU7FR.js");
492
+ const { readAdoptionRecords } = await import("./dist-BWFFVKEW.js");
493
493
  const records = readAdoptionRecords(cwd);
494
494
  if (records.length === 0) {
495
495
  if (globalOpts.json) {
@@ -567,7 +567,7 @@ function registerSkillCommand(adoption) {
567
567
  adoption.command("skill <name>").description("Show detail for a specific skill").action(async (name, _opts, cmd) => {
568
568
  const globalOpts = cmd.optsWithGlobals();
569
569
  const cwd = process.cwd();
570
- const { readAdoptionRecords, aggregateBySkill } = await import("./dist-LE5AU7FR.js");
570
+ const { readAdoptionRecords, aggregateBySkill } = await import("./dist-BWFFVKEW.js");
571
571
  const records = readAdoptionRecords(cwd);
572
572
  const skillRecords = records.filter((r) => r.skill === name);
573
573
  if (skillRecords.length === 0) {
@@ -586,8 +586,8 @@ function registerSkillCommand(adoption) {
586
586
  printSkillDetail(name, summary, phaseRates, skillRecords);
587
587
  });
588
588
  }
589
- function discoverCatalogSkills(projectRoot2) {
590
- const skillsDir = path2.join(projectRoot2, "agents", "skills", "claude-code");
589
+ function discoverCatalogSkills(projectRoot3) {
590
+ const skillsDir = path2.join(projectRoot3, "agents", "skills", "claude-code");
591
591
  let entries;
592
592
  try {
593
593
  entries = fs2.readdirSync(skillsDir, { withFileTypes: true });
@@ -601,7 +601,7 @@ function registerRetrospectiveCommand(adoption) {
601
601
  adoption.command("retrospective").description("Generate a catalog retrospective from adoption telemetry").option("--inactive-days <n>", "Inactivity threshold in days (default: 90)", "90").option("--top <n>", "Rows per ranked section (default: 10)", "10").option("--out <path>", "Output file path (default: docs/retrospectives/YYYY-MM-DD.md)").option("--no-write", "Print the report to stdout instead of writing a file").action(async (opts, cmd) => {
602
602
  const globalOpts = cmd.optsWithGlobals();
603
603
  const cwd = process.cwd();
604
- const { readAdoptionRecords, getCatalogRetrospectiveReport, renderRetrospectiveMarkdown } = await import("./dist-LE5AU7FR.js");
604
+ const { readAdoptionRecords, getCatalogRetrospectiveReport, renderRetrospectiveMarkdown } = await import("./dist-BWFFVKEW.js");
605
605
  const records = readAdoptionRecords(cwd);
606
606
  const catalogSkills = discoverCatalogSkills(cwd);
607
607
  const report = getCatalogRetrospectiveReport(records, {
@@ -1188,8 +1188,8 @@ function backfillFile(yamlFile) {
1188
1188
  fs4.writeFileSync(yamlFile, stringifyYaml(obj));
1189
1189
  return "updated";
1190
1190
  }
1191
- function runBackfillSkillProvenance(projectRoot2) {
1192
- const skillsRoot = path5.join(projectRoot2, "agents", "skills");
1191
+ function runBackfillSkillProvenance(projectRoot3) {
1192
+ const skillsRoot = path5.join(projectRoot3, "agents", "skills");
1193
1193
  const files = listSkillYamlFiles(skillsRoot);
1194
1194
  const result = {
1195
1195
  scanned: files.length,
@@ -1968,9 +1968,9 @@ import { Command as Command14 } from "commander";
1968
1968
  import * as path9 from "path";
1969
1969
  var SEVERITY_RANK = { error: 3, warning: 2, info: 1 };
1970
1970
  function runCheckHarnessStrength(cwd, options) {
1971
- const projectRoot2 = path9.resolve(cwd);
1971
+ const projectRoot3 = path9.resolve(cwd);
1972
1972
  const auditor = new HarnessStrengthAuditor();
1973
- const result = auditor.audit(projectRoot2, options.mode ? { mode: options.mode } : {});
1973
+ const result = auditor.audit(projectRoot3, options.mode ? { mode: options.mode } : {});
1974
1974
  if (!result.ok) return result;
1975
1975
  const audit = result.value;
1976
1976
  const threshold = options.severity ?? "warning";
@@ -2199,11 +2199,11 @@ function getChangedFiles(cwd) {
2199
2199
  }
2200
2200
  }
2201
2201
  async function runCheckSecurity(cwd, options) {
2202
- const projectRoot2 = path11.resolve(cwd);
2202
+ const projectRoot3 = path11.resolve(cwd);
2203
2203
  let configData = {};
2204
2204
  try {
2205
2205
  const fs51 = await import("fs");
2206
- const configPath = path11.join(projectRoot2, "harness.config.json");
2206
+ const configPath = path11.join(projectRoot3, "harness.config.json");
2207
2207
  if (fs51.existsSync(configPath)) {
2208
2208
  const raw = fs51.readFileSync(configPath, "utf-8");
2209
2209
  const parsed = JSON.parse(raw);
@@ -2213,10 +2213,10 @@ async function runCheckSecurity(cwd, options) {
2213
2213
  }
2214
2214
  const securityConfig = parseSecurityConfig(configData);
2215
2215
  const scanner = new SecurityScanner(securityConfig);
2216
- scanner.configureForProject(projectRoot2);
2216
+ scanner.configureForProject(projectRoot3);
2217
2217
  let filesToScan;
2218
2218
  if (options.changedOnly) {
2219
- filesToScan = getChangedFiles(projectRoot2);
2219
+ filesToScan = getChangedFiles(projectRoot3);
2220
2220
  } else {
2221
2221
  const { glob: glob2 } = await import("glob");
2222
2222
  const pattern = "**/*.{ts,tsx,js,jsx,go,py,java,rb}";
@@ -2226,15 +2226,15 @@ async function runCheckSecurity(cwd, options) {
2226
2226
  "**/*.test.ts",
2227
2227
  "**/fixtures/**"
2228
2228
  ];
2229
- filesToScan = await glob2(pattern, { cwd: projectRoot2, absolute: true, ignore });
2229
+ filesToScan = await glob2(pattern, { cwd: projectRoot3, absolute: true, ignore });
2230
2230
  }
2231
2231
  const result = await scanner.scanFiles(filesToScan);
2232
2232
  try {
2233
2233
  const commitHash = execSync3("git rev-parse HEAD", {
2234
- cwd: projectRoot2,
2234
+ cwd: projectRoot3,
2235
2235
  encoding: "utf-8"
2236
2236
  }).trim();
2237
- const timelineManager = new SecurityTimelineManager(projectRoot2);
2237
+ const timelineManager = new SecurityTimelineManager(projectRoot3);
2238
2238
  timelineManager.capture(result, commitHash);
2239
2239
  timelineManager.updateLifecycles(result.findings, commitHash);
2240
2240
  } catch {
@@ -6209,7 +6209,7 @@ function createInsightsCommand() {
6209
6209
  return new Command46("insights").description("Composite project report \u2014 health, entropy, decay, attention, impact.").option("--json", "Emit JSON to stdout instead of pretty text").option("--skip <list>", `Comma-separated keys to skip (${INSIGHTS_KEYS.join(",")})`).action(async (opts) => {
6210
6210
  const cwd = process.cwd();
6211
6211
  const skip = parseSkip2(opts.skip);
6212
- const { composeInsights } = await import("./dist-LE5AU7FR.js");
6212
+ const { composeInsights } = await import("./dist-BWFFVKEW.js");
6213
6213
  const report = await composeInsights(cwd, { skip });
6214
6214
  if (opts.json) {
6215
6215
  console.log(JSON.stringify(report, null, 2));
@@ -7053,8 +7053,8 @@ function logInstallResult(val, opts) {
7053
7053
  }
7054
7054
  async function handleInstallConstraints(source, opts) {
7055
7055
  const configPath = resolveConfigPath(opts);
7056
- const projectRoot2 = path37.dirname(configPath);
7057
- const lockfilePath = path37.join(projectRoot2, ".harness", "constraints.lock.json");
7056
+ const projectRoot3 = path37.dirname(configPath);
7057
+ const lockfilePath = path37.join(projectRoot3, ".harness", "constraints.lock.json");
7058
7058
  const resolvedSource = path37.resolve(source);
7059
7059
  if (opts.forceLocal && opts.forcePackage) {
7060
7060
  logger.error("Cannot use both --force-local and --force-package.");
@@ -8320,7 +8320,7 @@ function createMcpCommand() {
8320
8320
  parseBudget
8321
8321
  ).action(async (opts) => {
8322
8322
  const [{ startServer: startServer2, getToolDefinitions: getToolDefinitions2 }, { selectTier }] = await Promise.all([
8323
- import("./mcp-Z5YMV7TA.js"),
8323
+ import("./mcp-RIPEYDMU.js"),
8324
8324
  import("./tool-tiers-OKK5FE57.js")
8325
8325
  ]);
8326
8326
  if (opts.tools && opts.tools.length > 0) {
@@ -8862,7 +8862,7 @@ function updateReferences(plan) {
8862
8862
  }
8863
8863
  async function prompt(question, def = "n") {
8864
8864
  const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
8865
- const answer = await new Promise((resolve49) => rl.question(question, resolve49));
8865
+ const answer = await new Promise((resolve50) => rl.question(question, resolve50));
8866
8866
  rl.close();
8867
8867
  return (answer.trim() || def).toLowerCase();
8868
8868
  }
@@ -9049,7 +9049,9 @@ function createMigrateCommand() {
9049
9049
  }
9050
9050
 
9051
9051
  // src/commands/models.ts
9052
+ init_dist3();
9052
9053
  import { Command as Command66 } from "commander";
9054
+ import { resolve as resolve31 } from "path";
9053
9055
  import { defaultFetchModels } from "@harness-engineering/orchestrator";
9054
9056
  function errorResult(message, partial) {
9055
9057
  return {
@@ -9166,29 +9168,183 @@ function formatProbe(result) {
9166
9168
  }
9167
9169
  return lines.join("\n");
9168
9170
  }
9169
- function createModelsCommand() {
9170
- const cmd = new Command66("models").description(
9171
- "Inspect and manage local LLM backends. Currently ships `probe`; LMLM phases add status/suggest/pool/proposals."
9172
- );
9171
+ function projectRoot() {
9172
+ return resolve31(process.env["HARNESS_PROJECT_ROOT"] ?? process.cwd());
9173
+ }
9174
+ function summarizeModelProposal(p) {
9175
+ const base = { id: p.id, status: p.status, proposedBy: p.proposedBy, createdAt: p.createdAt };
9176
+ if (p.kind !== "model") return { ...base, kind: p.kind };
9177
+ return {
9178
+ ...base,
9179
+ kind: "model",
9180
+ action: p.model.action,
9181
+ target: p.model.target.ollamaName,
9182
+ replaces: p.model.replaces?.ollamaName,
9183
+ scoreDelta: p.model.scoreDelta
9184
+ };
9185
+ }
9186
+ async function runModelsProposals(status = "open") {
9187
+ const opts = { kind: "model" };
9188
+ if (status !== "all") opts.status = status;
9189
+ const proposals = await listProposals(projectRoot(), opts);
9190
+ return proposals.map(summarizeModelProposal);
9191
+ }
9192
+ async function runModelsApprove(id) {
9193
+ const orchestratorUrl = process.env["HARNESS_ORCHESTRATOR_URL"] ?? "http://127.0.0.1:4577";
9194
+ const token = process.env["HARNESS_ADMIN_TOKEN"];
9195
+ if (!token) {
9196
+ return {
9197
+ ok: false,
9198
+ error: "HARNESS_ADMIN_TOKEN is required to approve proposals (manage-proposals scope)."
9199
+ };
9200
+ }
9201
+ try {
9202
+ const res = await fetch(`${orchestratorUrl}/api/v1/proposals/${id}/approve`, {
9203
+ method: "POST",
9204
+ headers: { authorization: `Bearer ${token}` }
9205
+ });
9206
+ return { ok: res.ok, status: res.status, body: await res.text() };
9207
+ } catch (err) {
9208
+ return { ok: false, error: err instanceof Error ? err.message : String(err) };
9209
+ }
9210
+ }
9211
+ async function runModelsReject(id, reason) {
9212
+ const orchestratorUrl = process.env["HARNESS_ORCHESTRATOR_URL"] ?? "http://127.0.0.1:4577";
9213
+ const token = process.env["HARNESS_ADMIN_TOKEN"];
9214
+ if (!token) {
9215
+ return {
9216
+ ok: false,
9217
+ error: "HARNESS_ADMIN_TOKEN is required to reject proposals (manage-proposals scope)."
9218
+ };
9219
+ }
9220
+ try {
9221
+ const res = await fetch(`${orchestratorUrl}/api/v1/proposals/${id}/reject`, {
9222
+ method: "POST",
9223
+ headers: { authorization: `Bearer ${token}`, "content-type": "application/json" },
9224
+ body: JSON.stringify({ reason })
9225
+ });
9226
+ return { ok: res.ok, status: res.status, body: await res.text() };
9227
+ } catch (err) {
9228
+ return { ok: false, error: err instanceof Error ? err.message : String(err) };
9229
+ }
9230
+ }
9231
+ async function runModelsRefresh() {
9232
+ const orchestratorUrl = process.env["HARNESS_ORCHESTRATOR_URL"] ?? "http://127.0.0.1:4577";
9233
+ const token = process.env["HARNESS_ADMIN_TOKEN"];
9234
+ if (!token) {
9235
+ return {
9236
+ ok: false,
9237
+ error: "HARNESS_ADMIN_TOKEN is required to trigger a refresh (manage-proposals scope)."
9238
+ };
9239
+ }
9240
+ try {
9241
+ const res = await fetch(`${orchestratorUrl}/api/v1/local-models/refresh`, {
9242
+ method: "POST",
9243
+ headers: { authorization: `Bearer ${token}` }
9244
+ });
9245
+ return buildRefreshResult(res, await res.text());
9246
+ } catch (err) {
9247
+ return { ok: false, error: err instanceof Error ? err.message : String(err) };
9248
+ }
9249
+ }
9250
+ function buildRefreshResult(res, body) {
9251
+ const parsed = safeParseObject(body);
9252
+ const emitted = parsed?.["emitted"];
9253
+ const warnings = parsed?.["warnings"];
9254
+ const error = parsed?.["error"];
9255
+ return {
9256
+ ok: res.ok,
9257
+ status: res.status,
9258
+ ...typeof emitted === "number" ? { emitted } : {},
9259
+ ...Array.isArray(warnings) ? { warnings } : {},
9260
+ ...res.ok ? {} : { error: typeof error === "string" ? error : `HTTP ${res.status}` },
9261
+ body
9262
+ };
9263
+ }
9264
+ function safeParseObject(body) {
9265
+ try {
9266
+ const v = JSON.parse(body);
9267
+ return v !== null && typeof v === "object" ? v : void 0;
9268
+ } catch {
9269
+ return void 0;
9270
+ }
9271
+ }
9272
+ function refreshExitCode(result) {
9273
+ return result.ok ? ExitCode.SUCCESS : ExitCode.ERROR;
9274
+ }
9275
+ function httpErrorLine(r) {
9276
+ return r.error ?? `HTTP ${r.status ?? "?"}: ${r.body ?? ""}`;
9277
+ }
9278
+ function reportMutation(result) {
9279
+ if (!result.ok) {
9280
+ logger.error(httpErrorLine(result));
9281
+ process.exit(ExitCode.ERROR);
9282
+ }
9283
+ console.log(result.body ?? "");
9284
+ }
9285
+ async function probeAction(options) {
9286
+ const result = await runModelsProbe(options);
9287
+ if (options.json) {
9288
+ console.log(JSON.stringify(result, null, 2));
9289
+ } else {
9290
+ const text = formatProbe(result);
9291
+ if (result.status === "error" || result.status === "no-match") logger.error(text);
9292
+ else logger.info(text);
9293
+ }
9294
+ process.exit(result.exitCode);
9295
+ }
9296
+ async function refreshAction() {
9297
+ const result = await runModelsRefresh();
9298
+ if (!result.ok) {
9299
+ logger.error(httpErrorLine(result));
9300
+ } else {
9301
+ logger.info(`refresh: emitted ${result.emitted ?? 0} proposal(s)`);
9302
+ for (const w of result.warnings ?? []) logger.warn(` warning: ${w}`);
9303
+ }
9304
+ process.exitCode = refreshExitCode(result);
9305
+ }
9306
+ function addProbeCommand(cmd) {
9173
9307
  cmd.command("probe").description(
9174
9308
  "Probe a local backend's /v1/models endpoint and report which configured model is loaded."
9175
9309
  ).option(
9176
9310
  "--backend <name>",
9177
9311
  "Name of an entry in agent.backends. Defaults to the first local/pi entry."
9178
- ).option("--endpoint <url>", "Override the backend endpoint (bypasses harness.config.json).").option("--api-key <key>", "Override the API key.").option("--json", "Print machine-readable JSON instead of a human summary.", false).action(async (options) => {
9179
- const result = await runModelsProbe(options);
9180
- if (options.json) {
9181
- console.log(JSON.stringify(result, null, 2));
9182
- } else {
9183
- const text = formatProbe(result);
9184
- if (result.status === "error" || result.status === "no-match") {
9185
- logger.error(text);
9186
- } else {
9187
- logger.info(text);
9188
- }
9189
- }
9190
- process.exit(result.exitCode);
9312
+ ).option("--endpoint <url>", "Override the backend endpoint (bypasses harness.config.json).").option("--api-key <key>", "Override the API key.").option("--json", "Print machine-readable JSON instead of a human summary.", false).action(probeAction);
9313
+ }
9314
+ function addProposalsCommand(cmd) {
9315
+ cmd.command("proposals").description("List model proposals in the local review queue (defaults to pending).").option("--status <status>", "Filter by status (open | approved | rejected | all).", "open").action(async (options) => {
9316
+ const rows = await runModelsProposals(options.status ?? "open");
9317
+ console.log(JSON.stringify(rows, null, 2));
9318
+ });
9319
+ }
9320
+ function addRejectCommand(cmd) {
9321
+ cmd.command("reject <id>").description(
9322
+ "Reject a model proposal with a one-line reason (records the decision + fires the bus event). Requires the orchestrator to be running and HARNESS_ADMIN_TOKEN."
9323
+ ).requiredOption("--reason <text>", "Why the proposal is being rejected").action(async (id, options) => {
9324
+ reportMutation(await runModelsReject(id, options.reason));
9191
9325
  });
9326
+ }
9327
+ function addApproveCommand(cmd) {
9328
+ cmd.command("approve <id>").description(
9329
+ "Approve a model proposal (drives the installer + pool update). Requires the orchestrator to be running and HARNESS_ADMIN_TOKEN."
9330
+ ).action(async (id) => {
9331
+ reportMutation(await runModelsApprove(id));
9332
+ });
9333
+ }
9334
+ function addRefreshCommand(cmd) {
9335
+ cmd.command("refresh").description(
9336
+ "Force a background-scheduler refresh tick now (emits any model proposals). Exits non-zero on an O4 hard failure (HuggingFace unreachable AND no benchmark snapshot). Requires the orchestrator running + HARNESS_ADMIN_TOKEN."
9337
+ ).action(refreshAction);
9338
+ }
9339
+ function createModelsCommand() {
9340
+ const cmd = new Command66("models").description(
9341
+ "Inspect and manage local LLM backends. Ships `probe`, model-proposal review (proposals/approve/reject), and `refresh` (force a scheduler tick)."
9342
+ );
9343
+ addProbeCommand(cmd);
9344
+ addProposalsCommand(cmd);
9345
+ addRejectCommand(cmd);
9346
+ addApproveCommand(cmd);
9347
+ addRefreshCommand(cmd);
9192
9348
  return cmd;
9193
9349
  }
9194
9350
 
@@ -9274,7 +9430,7 @@ import { Command as Command69 } from "commander";
9274
9430
  init_dist3();
9275
9431
  import { Command as Command68 } from "commander";
9276
9432
  import { randomBytes } from "crypto";
9277
- import { resolve as resolve31 } from "path";
9433
+ import { resolve as resolve32 } from "path";
9278
9434
  import { SinkRegistry, SinkConfigError, wrapAsEnvelope } from "@harness-engineering/orchestrator";
9279
9435
  function makeTestEvent(message) {
9280
9436
  return {
@@ -9284,8 +9440,8 @@ function makeTestEvent(message) {
9284
9440
  data: { message, triggeredAt: (/* @__PURE__ */ new Date()).toISOString() }
9285
9441
  };
9286
9442
  }
9287
- async function runNotificationsTest(sinkId, opts, projectRoot2 = process.cwd()) {
9288
- const cfgResult = loadNotificationsConfig(projectRoot2);
9443
+ async function runNotificationsTest(sinkId, opts, projectRoot3 = process.cwd()) {
9444
+ const cfgResult = loadNotificationsConfig(projectRoot3);
9289
9445
  if (!cfgResult.ok) {
9290
9446
  return { ok: false, error: `Config error: ${cfgResult.error.message}` };
9291
9447
  }
@@ -9326,8 +9482,8 @@ async function runNotificationsTest(sinkId, opts, projectRoot2 = process.cwd())
9326
9482
  function createNotificationsTestSubcommand() {
9327
9483
  return new Command68("test").description("Send a synthetic notification.test event through the named sink").argument("<sink-id>", "Sink id from harness.config.json `notifications.sinks[].id`").option("--message <text>", "Override the default test message").action(async (sinkId, opts, cmd) => {
9328
9484
  const globalOpts = cmd.optsWithGlobals();
9329
- const projectRoot2 = typeof globalOpts["cwd"] === "string" ? resolve31(globalOpts["cwd"]) : process.cwd();
9330
- const result = await runNotificationsTest(sinkId, opts, projectRoot2);
9485
+ const projectRoot3 = typeof globalOpts["cwd"] === "string" ? resolve32(globalOpts["cwd"]) : process.cwd();
9486
+ const result = await runNotificationsTest(sinkId, opts, projectRoot3);
9331
9487
  if (globalOpts["json"]) {
9332
9488
  console.log(JSON.stringify(result, null, 2));
9333
9489
  } else if (result.ok) {
@@ -9395,7 +9551,7 @@ function registerBenchCommand(perf) {
9395
9551
  perf.command("bench [glob]").description("Run benchmarks via vitest bench").action(async (glob2, _opts, cmd) => {
9396
9552
  const globalOpts = cmd.optsWithGlobals();
9397
9553
  const cwd = process.cwd();
9398
- const { BenchmarkRunner } = await import("./dist-LE5AU7FR.js");
9554
+ const { BenchmarkRunner } = await import("./dist-BWFFVKEW.js");
9399
9555
  const runner = new BenchmarkRunner();
9400
9556
  const benchFiles = runner.discover(cwd, glob2);
9401
9557
  if (benchFiles.length === 0) {
@@ -9459,7 +9615,7 @@ async function runBaselinesShow(globalOpts) {
9459
9615
  }
9460
9616
  async function runBaselinesUpdate(globalOpts) {
9461
9617
  const cwd = process.cwd();
9462
- const { BenchmarkRunner } = await import("./dist-LE5AU7FR.js");
9618
+ const { BenchmarkRunner } = await import("./dist-BWFFVKEW.js");
9463
9619
  const runner = new BenchmarkRunner();
9464
9620
  const manager = new BaselineManager(cwd);
9465
9621
  logger.info("Running benchmarks to update baselines...");
@@ -9500,7 +9656,7 @@ function registerReportCommand(perf) {
9500
9656
  perf.command("report").description("Full performance report with metrics, trends, and hotspots").action(async (_opts, cmd) => {
9501
9657
  const globalOpts = cmd.optsWithGlobals();
9502
9658
  const cwd = process.cwd();
9503
- const { EntropyAnalyzer: EntropyAnalyzer2 } = await import("./dist-LE5AU7FR.js");
9659
+ const { EntropyAnalyzer: EntropyAnalyzer2 } = await import("./dist-BWFFVKEW.js");
9504
9660
  const analyzer = new EntropyAnalyzer2({
9505
9661
  rootDir: path51.resolve(cwd),
9506
9662
  analyze: { complexity: true, coupling: true }
@@ -10287,31 +10443,44 @@ function createPreMergeBriefCommand() {
10287
10443
  // src/commands/proposals.ts
10288
10444
  init_dist3();
10289
10445
  import { Command as Command78 } from "commander";
10290
- import { resolve as resolve35 } from "path";
10291
- function projectRoot() {
10292
- return resolve35(process.env["HARNESS_PROJECT_ROOT"] ?? process.cwd());
10446
+ import { resolve as resolve36 } from "path";
10447
+ function projectRoot2() {
10448
+ return resolve36(process.env["HARNESS_PROJECT_ROOT"] ?? process.cwd());
10293
10449
  }
10294
10450
  function summarizeProposal(p) {
10295
- return {
10451
+ const base = {
10296
10452
  id: p.id,
10297
- kind: p.kind,
10298
- targetSkill: p.targetSkill,
10299
- name: p.content.name,
10300
10453
  status: p.status,
10301
10454
  proposedBy: p.proposedBy,
10302
- createdAt: p.createdAt,
10303
- gateLastRunAt: p.gate?.lastRunAt,
10304
- findings: p.gate?.findings?.length ?? 0
10455
+ createdAt: p.createdAt
10456
+ };
10457
+ if (p.kind === "skill") {
10458
+ return {
10459
+ ...base,
10460
+ kind: p.skillKind,
10461
+ targetSkill: p.targetSkill,
10462
+ name: p.content.name,
10463
+ gateLastRunAt: p.gate?.lastRunAt,
10464
+ findings: p.gate?.findings?.length ?? 0
10465
+ };
10466
+ }
10467
+ return {
10468
+ ...base,
10469
+ kind: p.kind,
10470
+ targetSkill: void 0,
10471
+ name: p.model.target.ollamaName,
10472
+ gateLastRunAt: void 0,
10473
+ findings: 0
10305
10474
  };
10306
10475
  }
10307
10476
  async function runProposalsList(status) {
10308
- const opts = {};
10477
+ const opts = { kind: "skill" };
10309
10478
  if (status) opts.status = status;
10310
- const proposals = await listProposals(projectRoot(), opts);
10479
+ const proposals = await listProposals(projectRoot2(), opts);
10311
10480
  return proposals.map(summarizeProposal);
10312
10481
  }
10313
10482
  async function runProposalsShow(id) {
10314
- return getProposal(projectRoot(), id);
10483
+ return getProposal(projectRoot2(), id);
10315
10484
  }
10316
10485
  async function runProposalsReject(id, reason) {
10317
10486
  const decision = {
@@ -10320,7 +10489,7 @@ async function runProposalsReject(id, reason) {
10320
10489
  action: "rejected",
10321
10490
  reason
10322
10491
  };
10323
- return updateProposal(projectRoot(), id, { status: "rejected", decision });
10492
+ return updateProposal(projectRoot2(), id, { status: "rejected", decision });
10324
10493
  }
10325
10494
  var ALLOWED_STATUSES = [
10326
10495
  "open",
@@ -10510,7 +10679,7 @@ async function runPublishAnalyses(opts) {
10510
10679
  const nameToExternalId = await buildNameToExternalIdMap(projectPath);
10511
10680
  if (!nameToExternalId) return process.exit(1);
10512
10681
  const { AnalysisArchive } = await import("@harness-engineering/orchestrator");
10513
- const { GitHubIssuesSyncAdapter: GitHubIssuesSyncAdapter2 } = await import("./dist-LE5AU7FR.js");
10682
+ const { GitHubIssuesSyncAdapter: GitHubIssuesSyncAdapter2 } = await import("./dist-BWFFVKEW.js");
10514
10683
  const archive = new AnalysisArchive(path53.join(projectPath, ".harness", "analyses"));
10515
10684
  const analyses = await archive.list();
10516
10685
  if (analyses.length === 0) {
@@ -10554,7 +10723,7 @@ import { Command as Command81 } from "commander";
10554
10723
  // src/commands/pulse/run.ts
10555
10724
  init_dist3();
10556
10725
  import { readFileSync as readFileSync19, mkdirSync as mkdirSync16, writeFileSync as writeFileSync20 } from "fs";
10557
- import { dirname as dirname19, join as join43, resolve as resolve37 } from "path";
10726
+ import { dirname as dirname19, join as join43, resolve as resolve38 } from "path";
10558
10727
  import { Command as Command80 } from "commander";
10559
10728
  async function runPulseRunCommand(opts) {
10560
10729
  const startedAt = Date.now();
@@ -10630,8 +10799,8 @@ function createRunCommand2() {
10630
10799
  async (options) => {
10631
10800
  const nonInteractive = options.nonInteractive === true || !process.stdout.isTTY;
10632
10801
  const status = await runPulseRunCommand({
10633
- configPath: resolve37(process.cwd(), options.config),
10634
- outputDir: resolve37(process.cwd(), options.outputDir),
10802
+ configPath: resolve38(process.cwd(), options.config),
10803
+ outputDir: resolve38(process.cwd(), options.outputDir),
10635
10804
  nonInteractive,
10636
10805
  lookback: options.lookback
10637
10806
  });
@@ -10774,8 +10943,8 @@ function isPidAlive(pid) {
10774
10943
  return false;
10775
10944
  }
10776
10945
  }
10777
- function acquireMigrateLock(projectRoot2) {
10778
- const harnessDir = path54.join(projectRoot2, ".harness");
10946
+ function acquireMigrateLock(projectRoot3) {
10947
+ const harnessDir = path54.join(projectRoot3, ".harness");
10779
10948
  const lockPath = path54.join(harnessDir, LOCK_FILE_NAME);
10780
10949
  if (!fs33.existsSync(harnessDir)) fs33.mkdirSync(harnessDir, { recursive: true });
10781
10950
  if (fs33.existsSync(lockPath)) {
@@ -12145,10 +12314,10 @@ function prompt2(question) {
12145
12314
  input: process.stdin,
12146
12315
  output: process.stdout
12147
12316
  });
12148
- return new Promise((resolve49) => {
12317
+ return new Promise((resolve50) => {
12149
12318
  rl.question(question, (answer) => {
12150
12319
  rl.close();
12151
- resolve49(answer.trim().toLowerCase());
12320
+ resolve50(answer.trim().toLowerCase());
12152
12321
  });
12153
12322
  });
12154
12323
  }
@@ -12157,10 +12326,10 @@ function promptRaw(question) {
12157
12326
  input: process.stdin,
12158
12327
  output: process.stdout
12159
12328
  });
12160
- return new Promise((resolve49) => {
12329
+ return new Promise((resolve50) => {
12161
12330
  rl.question(question, (answer) => {
12162
12331
  rl.close();
12163
- resolve49(answer.trim());
12332
+ resolve50(answer.trim());
12164
12333
  });
12165
12334
  });
12166
12335
  }
@@ -12808,7 +12977,7 @@ function resolvePhaseState(metadata, projectPath, phase) {
12808
12977
  }
12809
12978
  async function appendProjectState(content, metadata, projectPath, hasPathOpt) {
12810
12979
  if (!metadata?.state.persistent || !hasPathOpt) return content;
12811
- const { readHarnessState: readHarnessState2, isEmptyHarnessState } = await import("./state-events-XQPHGLG5.js");
12980
+ const { readHarnessState: readHarnessState2, isEmptyHarnessState } = await import("./state-events-PBDNQPXT.js");
12812
12981
  const stateResult = await readHarnessState2(projectPath);
12813
12982
  if (!stateResult.ok || isEmptyHarnessState(stateResult.value)) return content;
12814
12983
  const stateContent = JSON.stringify(stateResult.value, null, 2);
@@ -13854,8 +14023,8 @@ import * as path72 from "path";
13854
14023
  import * as readline3 from "readline";
13855
14024
  async function confirmReset() {
13856
14025
  const rl = readline3.createInterface({ input: process.stdin, output: process.stdout });
13857
- const answer = await new Promise((resolve49) => {
13858
- rl.question("Reset project state? This cannot be undone. [y/N] ", resolve49);
14026
+ const answer = await new Promise((resolve50) => {
14027
+ rl.question("Reset project state? This cannot be undone. [y/N] ", resolve50);
13859
14028
  });
13860
14029
  rl.close();
13861
14030
  return answer.toLowerCase() === "y" || answer.toLowerCase() === "yes";
@@ -14095,7 +14264,7 @@ async function runSyncAnalyses(opts) {
14095
14264
  return;
14096
14265
  }
14097
14266
  const { AnalysisArchive, loadPublishedIndex: loadPublishedIndex2, savePublishedIndex: savePublishedIndex2 } = await import("@harness-engineering/orchestrator");
14098
- const { GitHubIssuesSyncAdapter: GitHubIssuesSyncAdapter2 } = await import("./dist-LE5AU7FR.js");
14267
+ const { GitHubIssuesSyncAdapter: GitHubIssuesSyncAdapter2 } = await import("./dist-BWFFVKEW.js");
14099
14268
  const adapter = new GitHubIssuesSyncAdapter2({ token, config: trackerConfig });
14100
14269
  const archive = new AnalysisArchive(path75.join(projectPath, ".harness", "analyses"));
14101
14270
  const publishedIndex = loadPublishedIndex2(projectPath);
@@ -14179,8 +14348,8 @@ function registerClearCommand(taint) {
14179
14348
  taint.command("clear [sessionId]").description(
14180
14349
  "Clear session taint \u2014 removes taint file(s) and re-enables destructive operations"
14181
14350
  ).action((sessionId) => {
14182
- const projectRoot2 = getProjectRoot();
14183
- const count = clearTaint(projectRoot2, sessionId);
14351
+ const projectRoot3 = getProjectRoot();
14352
+ const count = clearTaint(projectRoot3, sessionId);
14184
14353
  if (count === 0) {
14185
14354
  if (sessionId) {
14186
14355
  logger.info(`No taint found for session "${sessionId}".`);
@@ -14198,8 +14367,8 @@ function registerClearCommand(taint) {
14198
14367
  }
14199
14368
  });
14200
14369
  }
14201
- function printSingleSessionStatus(projectRoot2, sessionId) {
14202
- const result = checkTaint(projectRoot2, sessionId);
14370
+ function printSingleSessionStatus(projectRoot3, sessionId) {
14371
+ const result = checkTaint(projectRoot3, sessionId);
14203
14372
  if (result.expired) {
14204
14373
  logger.info(`Session "${sessionId}": taint expired (cleared).`);
14205
14374
  } else if (result.tainted && result.state) {
@@ -14214,15 +14383,15 @@ function printSingleSessionStatus(projectRoot2, sessionId) {
14214
14383
  logger.info(`Session "${sessionId}": clean (no taint).`);
14215
14384
  }
14216
14385
  }
14217
- function printAllSessionsStatus(projectRoot2) {
14218
- const sessions = listTaintedSessions(projectRoot2);
14386
+ function printAllSessionsStatus(projectRoot3) {
14387
+ const sessions = listTaintedSessions(projectRoot3);
14219
14388
  if (sessions.length === 0) {
14220
14389
  logger.info("No active taint sessions.");
14221
14390
  return;
14222
14391
  }
14223
14392
  logger.info(`Active taint sessions (${sessions.length}):`);
14224
14393
  for (const id of sessions) {
14225
- const result = checkTaint(projectRoot2, id);
14394
+ const result = checkTaint(projectRoot3, id);
14226
14395
  if (result.tainted && result.state) {
14227
14396
  const remaining = Math.max(
14228
14397
  0,
@@ -14234,11 +14403,11 @@ function printAllSessionsStatus(projectRoot2) {
14234
14403
  }
14235
14404
  function registerStatusCommand(taint) {
14236
14405
  taint.command("status [sessionId]").description("Show current taint status for a session or all sessions").action((sessionId) => {
14237
- const projectRoot2 = getProjectRoot();
14406
+ const projectRoot3 = getProjectRoot();
14238
14407
  if (sessionId) {
14239
- printSingleSessionStatus(projectRoot2, sessionId);
14408
+ printSingleSessionStatus(projectRoot3, sessionId);
14240
14409
  } else {
14241
- printAllSessionsStatus(projectRoot2);
14410
+ printAllSessionsStatus(projectRoot3);
14242
14411
  }
14243
14412
  });
14244
14413
  }
@@ -14382,16 +14551,16 @@ import { Command as Command120 } from "commander";
14382
14551
 
14383
14552
  // src/bin/command-telemetry.ts
14384
14553
  import { existsSync as existsSync44, readFileSync as readFileSync32, mkdirSync as mkdirSync23, appendFileSync, writeFileSync as writeFileSync29 } from "fs";
14385
- import { join as join64, parse as parsePath, resolve as resolve46 } from "path";
14554
+ import { join as join64, parse as parsePath, resolve as resolve47 } from "path";
14386
14555
  import { spawn as spawn2 } from "child_process";
14387
14556
  var POSTHOG_API_KEY = "phc_wNTdCMcfJXZPgdNeDociZW6vwoGGo4nb7vqEfWThFfsG";
14388
14557
  var EXCLUDED_COMMANDS = /* @__PURE__ */ new Set(["help", "completion"]);
14389
14558
  function findProjectRoot(cwd) {
14390
- let dir = resolve46(cwd);
14559
+ let dir = resolve47(cwd);
14391
14560
  const { root } = parsePath(dir);
14392
14561
  while (dir !== root) {
14393
14562
  if (existsSync44(join64(dir, "harness.config.json"))) return dir;
14394
- dir = resolve46(dir, "..");
14563
+ dir = resolve47(dir, "..");
14395
14564
  }
14396
14565
  return cwd;
14397
14566
  }
@@ -14400,8 +14569,8 @@ var startTime = 0;
14400
14569
  var recorded = false;
14401
14570
  function installCommandTelemetry(program, cwd) {
14402
14571
  if (typeof program.hook !== "function") return;
14403
- const projectRoot2 = findProjectRoot(cwd);
14404
- flushTelemetryBackground(projectRoot2);
14572
+ const projectRoot3 = findProjectRoot(cwd);
14573
+ flushTelemetryBackground(projectRoot3);
14405
14574
  program.hook("preAction", (_thisCommand, actionCommand) => {
14406
14575
  commandName = resolveCommandName(actionCommand);
14407
14576
  startTime = Date.now();
@@ -14411,7 +14580,7 @@ function installCommandTelemetry(program, cwd) {
14411
14580
  recorded = true;
14412
14581
  const duration = Date.now() - startTime;
14413
14582
  const outcome = code === 0 ? "completed" : "failed";
14414
- writeCommandRecordSync(projectRoot2, commandName, duration, outcome);
14583
+ writeCommandRecordSync(projectRoot3, commandName, duration, outcome);
14415
14584
  });
14416
14585
  }
14417
14586
  function resolveCommandName(cmd) {
@@ -14900,8 +15069,8 @@ function createUninstallConstraintsCommand() {
14900
15069
  }
14901
15070
  configPath = found.value;
14902
15071
  }
14903
- const projectRoot2 = path79.dirname(configPath);
14904
- const lockfilePath = path79.join(projectRoot2, ".harness", "constraints.lock.json");
15072
+ const projectRoot3 = path79.dirname(configPath);
15073
+ const lockfilePath = path79.join(projectRoot3, ".harness", "constraints.lock.json");
14905
15074
  const result = await runUninstallConstraints({
14906
15075
  packageName: name,
14907
15076
  configPath,
@@ -15011,10 +15180,10 @@ function prompt3(question) {
15011
15180
  input: process.stdin,
15012
15181
  output: process.stdout
15013
15182
  });
15014
- return new Promise((resolve49) => {
15183
+ return new Promise((resolve50) => {
15015
15184
  rl.question(question, (answer) => {
15016
15185
  rl.close();
15017
- resolve49(answer.trim().toLowerCase());
15186
+ resolve50(answer.trim().toLowerCase());
15018
15187
  });
15019
15188
  });
15020
15189
  }
@@ -15307,7 +15476,7 @@ function createUpdateCommand() {
15307
15476
  // src/commands/usage.ts
15308
15477
  import { Command as Command127 } from "commander";
15309
15478
  async function loadAndPriceRecords(cwd, includeClaudeSessions = false) {
15310
- const { readCostRecords, loadPricingData, calculateCost, parseCCRecords } = await import("./dist-LE5AU7FR.js");
15479
+ const { readCostRecords, loadPricingData, calculateCost, parseCCRecords } = await import("./dist-BWFFVKEW.js");
15311
15480
  const records = readCostRecords(cwd);
15312
15481
  if (includeClaudeSessions) {
15313
15482
  const ccRecords = parseCCRecords();
@@ -15400,7 +15569,7 @@ function registerDailyCommand(usage) {
15400
15569
  else logger.info("No usage data found. Run some harness sessions first.");
15401
15570
  return;
15402
15571
  }
15403
- const { aggregateByDay } = await import("./dist-LE5AU7FR.js");
15572
+ const { aggregateByDay } = await import("./dist-BWFFVKEW.js");
15404
15573
  const limited = aggregateByDay(records).slice(0, days);
15405
15574
  if (globalOpts.json) {
15406
15575
  console.log(
@@ -15429,7 +15598,7 @@ function registerSessionsCommand(usage) {
15429
15598
  }
15430
15599
  return;
15431
15600
  }
15432
- const { aggregateBySession } = await import("./dist-LE5AU7FR.js");
15601
+ const { aggregateBySession } = await import("./dist-BWFFVKEW.js");
15433
15602
  const sessionData = aggregateBySession(records);
15434
15603
  const limited = sessionData.slice(0, limit);
15435
15604
  if (globalOpts.json) {
@@ -15509,7 +15678,7 @@ function registerSessionCommand(usage) {
15509
15678
  cwd,
15510
15679
  globalOpts.includeClaudeSessions
15511
15680
  );
15512
- const { aggregateBySession } = await import("./dist-LE5AU7FR.js");
15681
+ const { aggregateBySession } = await import("./dist-BWFFVKEW.js");
15513
15682
  const sessionData = aggregateBySession(records);
15514
15683
  const match = sessionData.find((s) => s.sessionId === id);
15515
15684
  if (!match) {
@@ -15544,7 +15713,7 @@ function registerLatestCommand(usage) {
15544
15713
  }
15545
15714
  return;
15546
15715
  }
15547
- const { aggregateBySession } = await import("./dist-LE5AU7FR.js");
15716
+ const { aggregateBySession } = await import("./dist-BWFFVKEW.js");
15548
15717
  const sessionData = aggregateBySession(records);
15549
15718
  const latest = sessionData[0];
15550
15719
  if (!latest) {
@@ -15893,7 +16062,7 @@ function resolveValidateMode(globalOpts) {
15893
16062
  return OutputMode.TEXT;
15894
16063
  }
15895
16064
  async function printCrossCheckWarnings(mode) {
15896
- const { runCrossCheck: runCrossCheck2 } = await import("./validate-cross-check-HKKQA7K5.js");
16065
+ const { runCrossCheck: runCrossCheck2 } = await import("./validate-cross-check-H2OUHTID.js");
15897
16066
  const cwd = process.cwd();
15898
16067
  const crossResult = await runCrossCheck2({
15899
16068
  specsDir: path80.join(cwd, "docs", "specs"),