@harness-engineering/cli 1.17.0 → 1.19.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 (35) hide show
  1. package/dist/{agents-md-DUYNKHJZ.js → agents-md-DFY5W2DJ.js} +1 -1
  2. package/dist/{architecture-UBO5KKUV.js → architecture-E6PIU27A.js} +2 -2
  3. package/dist/bin/harness-mcp.js +12 -11
  4. package/dist/bin/harness.js +16 -13
  5. package/dist/{check-phase-gate-OSHN2AEL.js → check-phase-gate-PRCIABVA.js} +3 -3
  6. package/dist/{chunk-2DMIQ35P.js → chunk-4KE55XRN.js} +62 -62
  7. package/dist/{chunk-QSRRBNLY.js → chunk-7KGLJ74A.js} +4 -4
  8. package/dist/{chunk-GWXP3JVA.js → chunk-7WS7GIOW.js} +1 -1
  9. package/dist/{chunk-5FM64G6D.js → chunk-DEMZ3JKK.js} +2 -2
  10. package/dist/{chunk-OHZVGIPE.js → chunk-DYY3YKA6.js} +3 -3
  11. package/dist/{chunk-ABQUCXRE.js → chunk-E7N77TZW.js} +1 -1
  12. package/dist/{chunk-ZA2I7S3E.js → chunk-FUQDDES3.js} +1 -1
  13. package/dist/{chunk-TG7IUJ3J.js → chunk-I2NEJO3P.js} +1 -1
  14. package/dist/{chunk-OA3MOZGG.js → chunk-OIPVOH5E.js} +14 -14
  15. package/dist/{chunk-TZIHFNEG.js → chunk-TCTYRFWX.js} +5 -5
  16. package/dist/{chunk-UX3JHYEA.js → chunk-WWXD6MAR.js} +1 -1
  17. package/dist/{chunk-VF23UTNB.js → chunk-XULGZC2A.js} +118 -28
  18. package/dist/{chunk-APNPXLB2.js → chunk-ZR2C5FG2.js} +2 -2
  19. package/dist/{ci-workflow-FJZMNZPT.js → ci-workflow-N2TJ7B7G.js} +1 -1
  20. package/dist/{dist-MF5BK5AD.js → dist-WABFDP2V.js} +1 -1
  21. package/dist/{docs-WZHW4N4P.js → docs-UOCKFYBH.js} +3 -3
  22. package/dist/{engine-VS6ZJ2VZ.js → engine-R24ZLV44.js} +1 -1
  23. package/dist/{entropy-FCIGJIIT.js → entropy-5Y32Q6UO.js} +2 -2
  24. package/dist/{feedback-O3FYTZIE.js → feedback-NANNPO22.js} +1 -1
  25. package/dist/{generate-agent-definitions-EYG263XD.js → generate-agent-definitions-BDHDLUZK.js} +1 -1
  26. package/dist/index.js +13 -13
  27. package/dist/{loader-B4XWX4K6.js → loader-NOLQCQGX.js} +1 -1
  28. package/dist/{mcp-DVVUODN7.js → mcp-SDUVCYMR.js} +11 -11
  29. package/dist/{performance-NMJDV6HF.js → performance-AN4AJVEF.js} +3 -3
  30. package/dist/{review-pipeline-MSEJWTKM.js → review-pipeline-UBXJ4IAH.js} +1 -1
  31. package/dist/{runtime-YHVLJNPG.js → runtime-23OFHLCZ.js} +1 -1
  32. package/dist/{security-HTDKKGMX.js → security-NNEE7IQT.js} +1 -1
  33. package/dist/{validate-SPSTH2YW.js → validate-YLMMPRUI.js} +2 -2
  34. package/dist/{validate-cross-check-YTDWIMFI.js → validate-cross-check-MM23HXVY.js} +1 -1
  35. package/package.json +5 -4
@@ -38,7 +38,7 @@ async function handleCheckDependencies(input) {
38
38
  const configResult = resolveProjectConfig(projectPath);
39
39
  if (!configResult.ok) return resultToMcpResponse(configResult);
40
40
  try {
41
- const { validateDependencies, TypeScriptParser } = await import("./dist-MF5BK5AD.js");
41
+ const { validateDependencies, TypeScriptParser } = await import("./dist-WABFDP2V.js");
42
42
  const config = configResult.value;
43
43
  const rawLayers = Array.isArray(config.layers) ? config.layers : [];
44
44
  const layers = rawLayers.map((l) => ({
@@ -49,7 +49,7 @@ async function handleValidateProject(input) {
49
49
  checks.config = "pass";
50
50
  const config = configResult.value;
51
51
  try {
52
- const core = await import("./dist-MF5BK5AD.js");
52
+ const core = await import("./dist-WABFDP2V.js");
53
53
  if (typeof core.validateFileStructure === "function" && Array.isArray(config.conventions)) {
54
54
  const conventions = config.conventions;
55
55
  const structureResult = await core.validateFileStructure(projectPath, conventions);
@@ -68,7 +68,7 @@ async function handleValidateProject(input) {
68
68
  } catch {
69
69
  }
70
70
  try {
71
- const core = await import("./dist-MF5BK5AD.js");
71
+ const core = await import("./dist-WABFDP2V.js");
72
72
  if (typeof core.validateAgentsMap === "function") {
73
73
  const agentsMapPath = path.join(projectPath, "AGENTS.md");
74
74
  const agentsResult = await core.validateAgentsMap(agentsMapPath);
@@ -33,7 +33,7 @@ var createSelfReviewDefinition = {
33
33
  };
34
34
  async function handleCreateSelfReview(input) {
35
35
  try {
36
- const { parseDiff, createSelfReview } = await import("./dist-MF5BK5AD.js");
36
+ const { parseDiff, createSelfReview } = await import("./dist-WABFDP2V.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-MF5BK5AD.js");
122
+ const { parseDiff, analyzeDiff } = await import("./dist-WABFDP2V.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-MF5BK5AD.js");
198
+ const { parseDiff, requestPeerReview } = await import("./dist-WABFDP2V.js");
199
199
  const parseResult = parseDiff(input.diff);
200
200
  if (!parseResult.ok) {
201
201
  return resultToMcpResponse(parseResult);
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-EBJQ6N4M.js";
4
4
  import {
5
5
  resolveConfig
6
- } from "./chunk-ZA2I7S3E.js";
6
+ } from "./chunk-FUQDDES3.js";
7
7
  import {
8
8
  ExitCode
9
9
  } from "./chunk-3WGJMBKH.js";
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-3WGJMBKH.js";
5
5
  import {
6
6
  ArchConfigSchema
7
- } from "./chunk-VF23UTNB.js";
7
+ } from "./chunk-XULGZC2A.js";
8
8
  import {
9
9
  Err,
10
10
  Ok
@@ -26,7 +26,7 @@ var runSecurityScanDefinition = {
26
26
  };
27
27
  async function handleRunSecurityScan(input) {
28
28
  try {
29
- const core = await import("./dist-MF5BK5AD.js");
29
+ const core = await import("./dist-WABFDP2V.js");
30
30
  const projectRoot = sanitizePath(input.path);
31
31
  let configData = {};
32
32
  try {
@@ -6,7 +6,7 @@ import {
6
6
  OutputMode,
7
7
  createCheckPhaseGateCommand,
8
8
  findFiles
9
- } from "./chunk-ABQUCXRE.js";
9
+ } from "./chunk-E7N77TZW.js";
10
10
  import {
11
11
  createGenerateAgentDefinitionsCommand,
12
12
  generateAgentDefinitions
@@ -50,14 +50,14 @@ import {
50
50
  handleGetImpact,
51
51
  handleOrphanDeletion,
52
52
  persistToolingConfig
53
- } from "./chunk-2DMIQ35P.js";
53
+ } from "./chunk-4KE55XRN.js";
54
54
  import {
55
55
  VALID_PLATFORMS
56
56
  } from "./chunk-CJDVBBPB.js";
57
57
  import {
58
58
  findConfigFile,
59
59
  resolveConfig
60
- } from "./chunk-ZA2I7S3E.js";
60
+ } from "./chunk-FUQDDES3.js";
61
61
  import {
62
62
  resolveGlobalSkillsDir,
63
63
  resolvePersonasDir,
@@ -135,7 +135,7 @@ import {
135
135
  validateKnowledgeMap,
136
136
  writeConfig,
137
137
  writeLockfile
138
- } from "./chunk-VF23UTNB.js";
138
+ } from "./chunk-XULGZC2A.js";
139
139
  import {
140
140
  Err,
141
141
  Ok
@@ -221,7 +221,7 @@ function createValidateCommand() {
221
221
  process.exit(result.error.exitCode);
222
222
  }
223
223
  if (opts.crossCheck) {
224
- const { runCrossCheck: runCrossCheck2 } = await import("./validate-cross-check-YTDWIMFI.js");
224
+ const { runCrossCheck: runCrossCheck2 } = await import("./validate-cross-check-MM23HXVY.js");
225
225
  const cwd = process.cwd();
226
226
  const specsDir = path.join(cwd, "docs", "specs");
227
227
  const plansDir = path.join(cwd, "docs", "plans");
@@ -578,7 +578,7 @@ function registerBenchCommand(perf) {
578
578
  perf.command("bench [glob]").description("Run benchmarks via vitest bench").action(async (glob, _opts, cmd) => {
579
579
  const globalOpts = cmd.optsWithGlobals();
580
580
  const cwd = process.cwd();
581
- const { BenchmarkRunner } = await import("./dist-MF5BK5AD.js");
581
+ const { BenchmarkRunner } = await import("./dist-WABFDP2V.js");
582
582
  const runner = new BenchmarkRunner();
583
583
  const benchFiles = runner.discover(cwd, glob);
584
584
  if (benchFiles.length === 0) {
@@ -646,7 +646,7 @@ function registerBaselinesCommands(perf) {
646
646
  baselines.command("update").description("Update baselines from latest benchmark run").action(async (_opts, cmd) => {
647
647
  const globalOpts = cmd.optsWithGlobals();
648
648
  const cwd = process.cwd();
649
- const { BenchmarkRunner } = await import("./dist-MF5BK5AD.js");
649
+ const { BenchmarkRunner } = await import("./dist-WABFDP2V.js");
650
650
  const runner = new BenchmarkRunner();
651
651
  const manager = new BaselineManager(cwd);
652
652
  logger.info("Running benchmarks to update baselines...");
@@ -679,7 +679,7 @@ function registerReportCommand(perf) {
679
679
  perf.command("report").description("Full performance report with metrics, trends, and hotspots").action(async (_opts, cmd) => {
680
680
  const globalOpts = cmd.optsWithGlobals();
681
681
  const cwd = process.cwd();
682
- const { EntropyAnalyzer: EntropyAnalyzer2 } = await import("./dist-MF5BK5AD.js");
682
+ const { EntropyAnalyzer: EntropyAnalyzer2 } = await import("./dist-WABFDP2V.js");
683
683
  const analyzer = new EntropyAnalyzer2({
684
684
  rootDir: path5.resolve(cwd),
685
685
  analyze: { complexity: true, coupling: true }
@@ -5095,7 +5095,7 @@ function createGraphCommand() {
5095
5095
  import { Command as Command50 } from "commander";
5096
5096
  function createMcpCommand() {
5097
5097
  return new Command50("mcp").description("Start the MCP (Model Context Protocol) server on stdio").option("--tools <tools...>", "Only register the specified tools (used by Cursor integration)").action(async (opts) => {
5098
- const { startServer: startServer2 } = await import("./mcp-DVVUODN7.js");
5098
+ const { startServer: startServer2 } = await import("./mcp-SDUVCYMR.js");
5099
5099
  await startServer2(opts.tools);
5100
5100
  });
5101
5101
  }
@@ -6594,7 +6594,7 @@ function createIntegrationsCommand() {
6594
6594
  // src/commands/usage.ts
6595
6595
  import { Command as Command67 } from "commander";
6596
6596
  async function loadAndPriceRecords(cwd, includeClaudeSessions = false) {
6597
- const { readCostRecords, loadPricingData, calculateCost, parseCCRecords } = await import("./dist-MF5BK5AD.js");
6597
+ const { readCostRecords, loadPricingData, calculateCost, parseCCRecords } = await import("./dist-WABFDP2V.js");
6598
6598
  const records = readCostRecords(cwd);
6599
6599
  if (includeClaudeSessions) {
6600
6600
  const ccRecords = parseCCRecords();
@@ -6638,7 +6638,7 @@ function registerDailyCommand(usage) {
6638
6638
  }
6639
6639
  return;
6640
6640
  }
6641
- const { aggregateByDay } = await import("./dist-MF5BK5AD.js");
6641
+ const { aggregateByDay } = await import("./dist-WABFDP2V.js");
6642
6642
  const dailyData = aggregateByDay(records);
6643
6643
  const limited = dailyData.slice(0, days);
6644
6644
  if (globalOpts.json) {
@@ -6674,7 +6674,7 @@ function registerSessionsCommand(usage) {
6674
6674
  }
6675
6675
  return;
6676
6676
  }
6677
- const { aggregateBySession } = await import("./dist-MF5BK5AD.js");
6677
+ const { aggregateBySession } = await import("./dist-WABFDP2V.js");
6678
6678
  const sessionData = aggregateBySession(records);
6679
6679
  const limited = sessionData.slice(0, limit);
6680
6680
  if (globalOpts.json) {
@@ -6703,7 +6703,7 @@ function registerSessionCommand(usage) {
6703
6703
  const globalOpts = cmd.optsWithGlobals();
6704
6704
  const cwd = process.cwd();
6705
6705
  const records = await loadAndPriceRecords(cwd, globalOpts.includeClaudeSessions);
6706
- const { aggregateBySession } = await import("./dist-MF5BK5AD.js");
6706
+ const { aggregateBySession } = await import("./dist-WABFDP2V.js");
6707
6707
  const sessionData = aggregateBySession(records);
6708
6708
  const match = sessionData.find((s) => s.sessionId === id);
6709
6709
  if (!match) {
@@ -6769,7 +6769,7 @@ function registerLatestCommand(usage) {
6769
6769
  }
6770
6770
  return;
6771
6771
  }
6772
- const { aggregateBySession } = await import("./dist-MF5BK5AD.js");
6772
+ const { aggregateBySession } = await import("./dist-WABFDP2V.js");
6773
6773
  const sessionData = aggregateBySession(records);
6774
6774
  const latest = sessionData[0];
6775
6775
  if (!latest) {
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  findConfigFile,
3
3
  loadConfig
4
- } from "./chunk-ZA2I7S3E.js";
4
+ } from "./chunk-FUQDDES3.js";
5
5
  import {
6
6
  resultToMcpResponse
7
7
  } from "./chunk-IDZNPTYD.js";
@@ -31,7 +31,7 @@ var checkPerformanceDefinition = {
31
31
  };
32
32
  async function handleCheckPerformance(input) {
33
33
  try {
34
- const { EntropyAnalyzer } = await import("./dist-MF5BK5AD.js");
34
+ const { EntropyAnalyzer } = await import("./dist-WABFDP2V.js");
35
35
  const typeFilter = input.type ?? "all";
36
36
  const projectPath = sanitizePath(input.path);
37
37
  let entryPoints;
@@ -94,7 +94,7 @@ var getPerfBaselinesDefinition = {
94
94
  };
95
95
  async function handleGetPerfBaselines(input) {
96
96
  try {
97
- const { BaselineManager } = await import("./dist-MF5BK5AD.js");
97
+ const { BaselineManager } = await import("./dist-WABFDP2V.js");
98
98
  const manager = new BaselineManager(sanitizePath(input.path));
99
99
  const baselines = manager.load();
100
100
  return resultToMcpResponse(
@@ -142,7 +142,7 @@ var updatePerfBaselinesDefinition = {
142
142
  };
143
143
  async function handleUpdatePerfBaselines(input) {
144
144
  try {
145
- const { BaselineManager } = await import("./dist-MF5BK5AD.js");
145
+ const { BaselineManager } = await import("./dist-WABFDP2V.js");
146
146
  const manager = new BaselineManager(sanitizePath(input.path));
147
147
  manager.save(input.results, input.commitHash);
148
148
  const updated = manager.load();
@@ -172,7 +172,7 @@ var getCriticalPathsDefinition = {
172
172
  };
173
173
  async function handleGetCriticalPaths(input) {
174
174
  try {
175
- const { CriticalPathResolver } = await import("./dist-MF5BK5AD.js");
175
+ const { CriticalPathResolver } = await import("./dist-WABFDP2V.js");
176
176
  const resolver = new CriticalPathResolver(sanitizePath(input.path));
177
177
  const result = await resolver.resolve();
178
178
  return resultToMcpResponse(Ok(result));
@@ -45,7 +45,7 @@ var runCodeReviewDefinition = {
45
45
  };
46
46
  async function handleRunCodeReview(input) {
47
47
  try {
48
- const { parseDiff, runReviewPipeline } = await import("./dist-MF5BK5AD.js");
48
+ const { parseDiff, runReviewPipeline } = await import("./dist-WABFDP2V.js");
49
49
  const parseResult = parseDiff(input.diff);
50
50
  if (!parseResult.ok) {
51
51
  return {
@@ -11979,6 +11979,29 @@ function labelsForStatus(status, config) {
11979
11979
  }
11980
11980
  return [...base];
11981
11981
  }
11982
+ var RETRY_DEFAULTS = { maxRetries: 5, baseDelayMs: 1e3 };
11983
+ function sleep(ms) {
11984
+ return new Promise((resolve5) => setTimeout(resolve5, ms));
11985
+ }
11986
+ async function fetchWithRetry(fetchFn, input, init, opts = RETRY_DEFAULTS) {
11987
+ let lastResponse;
11988
+ for (let attempt = 0; attempt <= opts.maxRetries; attempt++) {
11989
+ const response = await fetchFn(input, init);
11990
+ if (response.status !== 403 && response.status !== 429) return response;
11991
+ lastResponse = response;
11992
+ if (attempt === opts.maxRetries) break;
11993
+ const retryAfter = response.headers.get("Retry-After");
11994
+ let delayMs;
11995
+ if (retryAfter) {
11996
+ const seconds = parseInt(retryAfter, 10);
11997
+ delayMs = isNaN(seconds) ? opts.baseDelayMs : seconds * 1e3;
11998
+ } else {
11999
+ delayMs = opts.baseDelayMs * Math.pow(2, attempt) + Math.random() * 500;
12000
+ }
12001
+ await sleep(delayMs);
12002
+ }
12003
+ return lastResponse;
12004
+ }
11982
12005
  var GitHubIssuesSyncAdapter = class {
11983
12006
  token;
11984
12007
  config;
@@ -11986,11 +12009,18 @@ var GitHubIssuesSyncAdapter = class {
11986
12009
  apiBase;
11987
12010
  owner;
11988
12011
  repo;
12012
+ retryOpts;
12013
+ /** Cached GitHub milestone name -> ID mapping */
12014
+ milestoneCache = null;
11989
12015
  constructor(options) {
11990
12016
  this.token = options.token;
11991
12017
  this.config = options.config;
11992
12018
  this.fetchFn = options.fetchFn ?? globalThis.fetch;
11993
12019
  this.apiBase = options.apiBase ?? "https://api.github.com";
12020
+ this.retryOpts = {
12021
+ maxRetries: options.maxRetries ?? RETRY_DEFAULTS.maxRetries,
12022
+ baseDelayMs: options.baseDelayMs ?? RETRY_DEFAULTS.baseDelayMs
12023
+ };
11994
12024
  const repoParts = (options.config.repo ?? "").split("/");
11995
12025
  if (repoParts.length !== 2 || !repoParts[0] || !repoParts[1]) {
11996
12026
  throw new Error(`Invalid repo format: "${options.config.repo}". Expected "owner/repo".`);
@@ -11998,6 +12028,43 @@ var GitHubIssuesSyncAdapter = class {
11998
12028
  this.owner = repoParts[0];
11999
12029
  this.repo = repoParts[1];
12000
12030
  }
12031
+ /**
12032
+ * Fetch all GitHub milestones and build the name -> ID cache.
12033
+ */
12034
+ async loadMilestones() {
12035
+ if (this.milestoneCache) return this.milestoneCache;
12036
+ this.milestoneCache = /* @__PURE__ */ new Map();
12037
+ const response = await fetchWithRetry(
12038
+ this.fetchFn,
12039
+ `${this.apiBase}/repos/${this.owner}/${this.repo}/milestones?state=all&per_page=100`,
12040
+ { method: "GET", headers: this.headers() },
12041
+ this.retryOpts
12042
+ );
12043
+ if (response.ok) {
12044
+ const data = await response.json();
12045
+ for (const m of data) {
12046
+ this.milestoneCache.set(m.title, m.number);
12047
+ }
12048
+ }
12049
+ return this.milestoneCache;
12050
+ }
12051
+ /**
12052
+ * Get or create a GitHub milestone by name. Returns the milestone number.
12053
+ */
12054
+ async ensureMilestone(name) {
12055
+ const cache = await this.loadMilestones();
12056
+ if (cache.has(name)) return cache.get(name);
12057
+ const response = await fetchWithRetry(
12058
+ this.fetchFn,
12059
+ `${this.apiBase}/repos/${this.owner}/${this.repo}/milestones`,
12060
+ { method: "POST", headers: this.headers(), body: JSON.stringify({ title: name }) },
12061
+ this.retryOpts
12062
+ );
12063
+ if (!response.ok) return null;
12064
+ const data = await response.json();
12065
+ cache.set(name, data.number);
12066
+ return data.number;
12067
+ }
12001
12068
  headers() {
12002
12069
  return {
12003
12070
  Authorization: `Bearer ${this.token}`,
@@ -12006,26 +12073,32 @@ var GitHubIssuesSyncAdapter = class {
12006
12073
  "X-GitHub-Api-Version": "2022-11-28"
12007
12074
  };
12008
12075
  }
12076
+ /**
12077
+ * Close an issue if the feature status maps to 'closed'.
12078
+ * GitHub Issues API doesn't accept state on POST — requires a follow-up PATCH.
12079
+ */
12080
+ async closeIfDone(issueNumber, featureStatus) {
12081
+ const externalStatus = this.config.statusMap[featureStatus];
12082
+ if (externalStatus !== "closed") return;
12083
+ await fetchWithRetry(
12084
+ this.fetchFn,
12085
+ `${this.apiBase}/repos/${this.owner}/${this.repo}/issues/${issueNumber}`,
12086
+ { method: "PATCH", headers: this.headers(), body: JSON.stringify({ state: "closed" }) },
12087
+ this.retryOpts
12088
+ );
12089
+ }
12009
12090
  async createTicket(feature, milestone) {
12010
12091
  try {
12011
- const labels = labelsForStatus(feature.status, this.config);
12012
- const body = [
12013
- feature.summary,
12014
- "",
12015
- `**Milestone:** ${milestone}`,
12016
- feature.spec ? `**Spec:** ${feature.spec}` : ""
12017
- ].filter(Boolean).join("\n");
12018
- const response = await this.fetchFn(
12092
+ const labels = [...labelsForStatus(feature.status, this.config), "feature"];
12093
+ const body = [feature.summary, "", feature.spec ? `**Spec:** ${feature.spec}` : ""].filter(Boolean).join("\n");
12094
+ const milestoneId = await this.ensureMilestone(milestone);
12095
+ const issuePayload = { title: feature.name, body, labels };
12096
+ if (milestoneId) issuePayload.milestone = milestoneId;
12097
+ const response = await fetchWithRetry(
12098
+ this.fetchFn,
12019
12099
  `${this.apiBase}/repos/${this.owner}/${this.repo}/issues`,
12020
- {
12021
- method: "POST",
12022
- headers: this.headers(),
12023
- body: JSON.stringify({
12024
- title: feature.name,
12025
- body,
12026
- labels
12027
- })
12028
- }
12100
+ { method: "POST", headers: this.headers(), body: JSON.stringify(issuePayload) },
12101
+ this.retryOpts
12029
12102
  );
12030
12103
  if (!response.ok) {
12031
12104
  const text = await response.text();
@@ -12033,12 +12106,13 @@ var GitHubIssuesSyncAdapter = class {
12033
12106
  }
12034
12107
  const data = await response.json();
12035
12108
  const externalId = buildExternalId(this.owner, this.repo, data.number);
12109
+ await this.closeIfDone(data.number, feature.status);
12036
12110
  return Ok({ externalId, url: data.html_url });
12037
12111
  } catch (error) {
12038
12112
  return Err(error instanceof Error ? error : new Error(String(error)));
12039
12113
  }
12040
12114
  }
12041
- async updateTicket(externalId, changes) {
12115
+ async updateTicket(externalId, changes, milestone) {
12042
12116
  try {
12043
12117
  const parsed = parseExternalId(externalId);
12044
12118
  if (!parsed) return Err(new Error(`Invalid externalId format: "${externalId}"`));
@@ -12051,15 +12125,21 @@ var GitHubIssuesSyncAdapter = class {
12051
12125
  if (changes.status !== void 0) {
12052
12126
  const externalStatus = this.config.statusMap[changes.status];
12053
12127
  patch.state = externalStatus;
12054
- patch.labels = labelsForStatus(changes.status, this.config);
12128
+ patch.labels = [...labelsForStatus(changes.status, this.config), "feature"];
12129
+ }
12130
+ if (milestone) {
12131
+ const milestoneId = await this.ensureMilestone(milestone);
12132
+ if (milestoneId) patch.milestone = milestoneId;
12055
12133
  }
12056
- const response = await this.fetchFn(
12134
+ const response = await fetchWithRetry(
12135
+ this.fetchFn,
12057
12136
  `${this.apiBase}/repos/${parsed.owner}/${parsed.repo}/issues/${parsed.number}`,
12058
12137
  {
12059
12138
  method: "PATCH",
12060
12139
  headers: this.headers(),
12061
12140
  body: JSON.stringify(patch)
12062
- }
12141
+ },
12142
+ this.retryOpts
12063
12143
  );
12064
12144
  if (!response.ok) {
12065
12145
  const text = await response.text();
@@ -12075,12 +12155,14 @@ var GitHubIssuesSyncAdapter = class {
12075
12155
  try {
12076
12156
  const parsed = parseExternalId(externalId);
12077
12157
  if (!parsed) return Err(new Error(`Invalid externalId format: "${externalId}"`));
12078
- const response = await this.fetchFn(
12158
+ const response = await fetchWithRetry(
12159
+ this.fetchFn,
12079
12160
  `${this.apiBase}/repos/${parsed.owner}/${parsed.repo}/issues/${parsed.number}`,
12080
12161
  {
12081
12162
  method: "GET",
12082
12163
  headers: this.headers()
12083
- }
12164
+ },
12165
+ this.retryOpts
12084
12166
  );
12085
12167
  if (!response.ok) {
12086
12168
  const text = await response.text();
@@ -12105,12 +12187,14 @@ var GitHubIssuesSyncAdapter = class {
12105
12187
  let page = 1;
12106
12188
  const perPage = 100;
12107
12189
  while (true) {
12108
- const response = await this.fetchFn(
12190
+ const response = await fetchWithRetry(
12191
+ this.fetchFn,
12109
12192
  `${this.apiBase}/repos/${this.owner}/${this.repo}/issues?state=all&per_page=${perPage}&page=${page}${labelsParam}`,
12110
12193
  {
12111
12194
  method: "GET",
12112
12195
  headers: this.headers()
12113
- }
12196
+ },
12197
+ this.retryOpts
12114
12198
  );
12115
12199
  if (!response.ok) {
12116
12200
  const text = await response.text();
@@ -12139,13 +12223,15 @@ var GitHubIssuesSyncAdapter = class {
12139
12223
  const parsed = parseExternalId(externalId);
12140
12224
  if (!parsed) return Err(new Error(`Invalid externalId format: "${externalId}"`));
12141
12225
  const login = assignee.startsWith("@") ? assignee.slice(1) : assignee;
12142
- const response = await this.fetchFn(
12226
+ const response = await fetchWithRetry(
12227
+ this.fetchFn,
12143
12228
  `${this.apiBase}/repos/${parsed.owner}/${parsed.repo}/issues/${parsed.number}/assignees`,
12144
12229
  {
12145
12230
  method: "POST",
12146
12231
  headers: this.headers(),
12147
12232
  body: JSON.stringify({ assignees: [login] })
12148
- }
12233
+ },
12234
+ this.retryOpts
12149
12235
  );
12150
12236
  if (!response.ok) {
12151
12237
  const text = await response.text();
@@ -12173,7 +12259,11 @@ async function syncToExternal(roadmap, adapter, _config) {
12173
12259
  result.errors.push({ featureOrId: feature.name, error: createResult.error });
12174
12260
  }
12175
12261
  } else {
12176
- const updateResult = await adapter.updateTicket(feature.externalId, feature);
12262
+ const updateResult = await adapter.updateTicket(
12263
+ feature.externalId,
12264
+ feature,
12265
+ milestone.name
12266
+ );
12177
12267
  if (updateResult.ok) {
12178
12268
  result.updated.push(feature.externalId);
12179
12269
  } else {
@@ -123,7 +123,7 @@ function buildSummaryResponse(report) {
123
123
  }
124
124
  async function handleDetectEntropy(input) {
125
125
  try {
126
- const { EntropyAnalyzer } = await import("./dist-MF5BK5AD.js");
126
+ const { EntropyAnalyzer } = await import("./dist-WABFDP2V.js");
127
127
  const typeFilter = input.type ?? "all";
128
128
  const analyzer = new EntropyAnalyzer({
129
129
  rootDir: sanitizePath(input.path),
@@ -142,7 +142,7 @@ async function handleDetectEntropy(input) {
142
142
  return resultToMcpResponse(result);
143
143
  }
144
144
  if (!result.ok) return resultToMcpResponse(result);
145
- const { createFixes, applyFixes, generateSuggestions } = await import("./dist-MF5BK5AD.js");
145
+ const { createFixes, applyFixes, generateSuggestions } = await import("./dist-WABFDP2V.js");
146
146
  const report = result.value;
147
147
  const deadCode = report.deadCode;
148
148
  const fixTypesConfig = input.fixTypes ? { fixTypes: input.fixTypes } : void 0;
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  generateCIWorkflow
3
3
  } from "./chunk-SD3SQOZ2.js";
4
- import "./chunk-VF23UTNB.js";
4
+ import "./chunk-XULGZC2A.js";
5
5
  import "./chunk-ERS5EVUZ.js";
6
6
  export {
7
7
  generateCIWorkflow
@@ -291,7 +291,7 @@ import {
291
291
  writeSessionSummary,
292
292
  writeTaint,
293
293
  xssRules
294
- } from "./chunk-VF23UTNB.js";
294
+ } from "./chunk-XULGZC2A.js";
295
295
  import {
296
296
  Err,
297
297
  Ok,
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  checkDocsDefinition,
3
3
  handleCheckDocs
4
- } from "./chunk-QSRRBNLY.js";
5
- import "./chunk-ZA2I7S3E.js";
4
+ } from "./chunk-7KGLJ74A.js";
5
+ import "./chunk-FUQDDES3.js";
6
6
  import "./chunk-IDZNPTYD.js";
7
7
  import "./chunk-W6Y7ZW3Y.js";
8
8
  import "./chunk-3WGJMBKH.js";
9
- import "./chunk-VF23UTNB.js";
9
+ import "./chunk-XULGZC2A.js";
10
10
  import "./chunk-ERS5EVUZ.js";
11
11
  export {
12
12
  checkDocsDefinition,
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  TemplateEngine
3
3
  } from "./chunk-YLN34N65.js";
4
- import "./chunk-VF23UTNB.js";
4
+ import "./chunk-XULGZC2A.js";
5
5
  import "./chunk-ERS5EVUZ.js";
6
6
  export {
7
7
  TemplateEngine
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  detectEntropyDefinition,
3
3
  handleDetectEntropy
4
- } from "./chunk-APNPXLB2.js";
4
+ } from "./chunk-ZR2C5FG2.js";
5
5
  import "./chunk-IDZNPTYD.js";
6
6
  import "./chunk-W6Y7ZW3Y.js";
7
- import "./chunk-VF23UTNB.js";
7
+ import "./chunk-XULGZC2A.js";
8
8
  import "./chunk-ERS5EVUZ.js";
9
9
  export {
10
10
  detectEntropyDefinition,
@@ -5,7 +5,7 @@ import {
5
5
  handleCreateSelfReview,
6
6
  handleRequestPeerReview,
7
7
  requestPeerReviewDefinition
8
- } from "./chunk-OHZVGIPE.js";
8
+ } from "./chunk-DYY3YKA6.js";
9
9
  import "./chunk-IDZNPTYD.js";
10
10
  import "./chunk-W6Y7ZW3Y.js";
11
11
  export {
@@ -7,7 +7,7 @@ import "./chunk-KET4QQZB.js";
7
7
  import "./chunk-CJDVBBPB.js";
8
8
  import "./chunk-N5G5QMS3.js";
9
9
  import "./chunk-3WGJMBKH.js";
10
- import "./chunk-VF23UTNB.js";
10
+ import "./chunk-XULGZC2A.js";
11
11
  import "./chunk-ERS5EVUZ.js";
12
12
  export {
13
13
  createGenerateAgentDefinitionsCommand,
package/dist/index.js CHANGED
@@ -12,7 +12,7 @@ import {
12
12
  runScan,
13
13
  runUninstall,
14
14
  runUninstallConstraints
15
- } from "./chunk-OA3MOZGG.js";
15
+ } from "./chunk-OIPVOH5E.js";
16
16
  import {
17
17
  generateCIWorkflow
18
18
  } from "./chunk-SD3SQOZ2.js";
@@ -20,7 +20,7 @@ import {
20
20
  OutputFormatter,
21
21
  OutputMode,
22
22
  runCheckPhaseGate
23
- } from "./chunk-ABQUCXRE.js";
23
+ } from "./chunk-E7N77TZW.js";
24
24
  import {
25
25
  AGENT_DESCRIPTIONS,
26
26
  DEFAULT_TOOLS,
@@ -63,23 +63,23 @@ import {
63
63
  generateSlashCommands,
64
64
  getToolDefinitions,
65
65
  startServer
66
- } from "./chunk-2DMIQ35P.js";
67
- import "./chunk-APNPXLB2.js";
68
- import "./chunk-TZIHFNEG.js";
69
- import "./chunk-OHZVGIPE.js";
70
- import "./chunk-TG7IUJ3J.js";
71
- import "./chunk-UX3JHYEA.js";
66
+ } from "./chunk-4KE55XRN.js";
67
+ import "./chunk-ZR2C5FG2.js";
68
+ import "./chunk-TCTYRFWX.js";
69
+ import "./chunk-DYY3YKA6.js";
70
+ import "./chunk-I2NEJO3P.js";
71
+ import "./chunk-WWXD6MAR.js";
72
72
  import "./chunk-CJDVBBPB.js";
73
- import "./chunk-5FM64G6D.js";
73
+ import "./chunk-DEMZ3JKK.js";
74
74
  import "./chunk-CZZXE6BL.js";
75
- import "./chunk-GWXP3JVA.js";
75
+ import "./chunk-7WS7GIOW.js";
76
76
  import "./chunk-H7Y5CKTM.js";
77
- import "./chunk-QSRRBNLY.js";
77
+ import "./chunk-7KGLJ74A.js";
78
78
  import {
79
79
  findConfigFile,
80
80
  loadConfig,
81
81
  resolveConfig
82
- } from "./chunk-ZA2I7S3E.js";
82
+ } from "./chunk-FUQDDES3.js";
83
83
  import "./chunk-IDZNPTYD.js";
84
84
  import "./chunk-W6Y7ZW3Y.js";
85
85
  import "./chunk-N5G5QMS3.js";
@@ -96,7 +96,7 @@ import {
96
96
  import {
97
97
  TemplateEngine
98
98
  } from "./chunk-YLN34N65.js";
99
- import "./chunk-VF23UTNB.js";
99
+ import "./chunk-XULGZC2A.js";
100
100
  import "./chunk-ERS5EVUZ.js";
101
101
  export {
102
102
  AGENT_DESCRIPTIONS,