@harness-engineering/cli 2.5.0 → 2.6.1

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-KAD3L2NO.js → agents-md-2JUQ4FE2.js} +4 -4
  2. package/dist/{analyzer-VY6DJVOU-NI56JRFK.js → analyzer-VY6DJVOU-4AHIJLNS.js} +2 -2
  3. package/dist/{architecture-OC7TFCFF.js → architecture-CXAVNB5X.js} +5 -5
  4. package/dist/{assess-project-ZGMRPTS3.js → assess-project-M626SSPN.js} +1 -1
  5. package/dist/bin/harness-mcp.js +15 -15
  6. package/dist/bin/harness.js +24 -24
  7. package/dist/{check-phase-gate-PD5MVEZT.js → check-phase-gate-XMU6LLUQ.js} +5 -5
  8. package/dist/{chunk-N6VWCISQ.js → chunk-24KCOJJG.js} +2 -2
  9. package/dist/{chunk-LT244Y6E.js → chunk-372MGNTI.js} +207 -76
  10. package/dist/{chunk-XIW24BJY.js → chunk-43M3RLFQ.js} +3 -3
  11. package/dist/{chunk-2RNGLYOG.js → chunk-5JNSFYZU.js} +2 -2
  12. package/dist/{chunk-XSI3RDH6.js → chunk-6AX6R3LM.js} +7 -7
  13. package/dist/{chunk-UCL3UZIC.js → chunk-CQOMVZDC.js} +1588 -925
  14. package/dist/{chunk-DOUS4ULX.js → chunk-GWE5LL3R.js} +6 -6
  15. package/dist/{chunk-7DOGGXQU.js → chunk-GWF2OILZ.js} +2 -2
  16. package/dist/{chunk-TCSNO7YW.js → chunk-HFOB2MPQ.js} +2 -2
  17. package/dist/{chunk-6SRKI77C.js → chunk-HMW3VKUF.js} +3 -3
  18. package/dist/{chunk-NOOPJD5R.js → chunk-I6K43QQS.js} +3 -3
  19. package/dist/{chunk-IGBQIXPS.js → chunk-JFZOWO7D.js} +2 -2
  20. package/dist/{chunk-57TS3UGN.js → chunk-K246XQ2L.js} +2 -2
  21. package/dist/{chunk-A3EBWI7U.js → chunk-L5BCZ5XS.js} +2 -2
  22. package/dist/{chunk-65MJPWFN.js → chunk-OA6SWTU4.js} +6 -6
  23. package/dist/{chunk-2LPUIBVH.js → chunk-OH3NXXUY.js} +121 -2
  24. package/dist/{chunk-4CWFVEVV.js → chunk-PFZEADQM.js} +1 -1
  25. package/dist/{chunk-JE5GQVCQ.js → chunk-Q6ZR2L6Q.js} +2 -2
  26. package/dist/{chunk-UF7BKRH4.js → chunk-QOKMDDBJ.js} +4 -4
  27. package/dist/{chunk-IWRYCUDO.js → chunk-SZEFU6XC.js} +1 -1
  28. package/dist/{chunk-HIZXUWWC.js → chunk-VTTNIZJL.js} +21 -2
  29. package/dist/{chunk-IXKGMPMT.js → chunk-VUCGB2KH.js} +4 -2
  30. package/dist/{chunk-ELMV6QU2.js → chunk-YP7I25SL.js} +2 -2
  31. package/dist/{chunk-KQ6TDRPS.js → chunk-YYRQCQPZ.js} +425 -173
  32. package/dist/{ci-workflow-WAG4TOV6.js → ci-workflow-3JNDZQYD.js} +4 -4
  33. package/dist/{dist-HVJUGPSY.js → dist-E3SAAHCM.js} +23 -1
  34. package/dist/{dist-TKHVYUWZ.js → dist-OHDQBTSO.js} +43 -3
  35. package/dist/{docs-4WPBYSCF.js → docs-5RYMDHN3.js} +5 -5
  36. package/dist/{engine-5BXDQT5T.js → engine-GKGT5ULT.js} +4 -4
  37. package/dist/{entropy-7FIUFACI.js → entropy-DQTAPSSE.js} +4 -4
  38. package/dist/{feedback-ER2HRTFD.js → feedback-WH6XPQJS.js} +1 -1
  39. package/dist/{generate-agent-definitions-5PV4O3BD.js → generate-agent-definitions-SZA4QIHN.js} +5 -5
  40. package/dist/index.d.ts +47 -0
  41. package/dist/index.js +24 -24
  42. package/dist/{loader-6RTEYN5Q.js → loader-BNKGM23C.js} +4 -4
  43. package/dist/{mcp-QWSDEYMN.js → mcp-YKKPWUMH.js} +15 -15
  44. package/dist/{performance-AZJAT35R.js → performance-54TMJOEU.js} +5 -5
  45. package/dist/{review-pipeline-4VF73V4V.js → review-pipeline-OTDDVPNY.js} +4 -4
  46. package/dist/{runtime-SAZGLILX.js → runtime-W5THSNAL.js} +4 -4
  47. package/dist/{security-ZWRABJNE.js → security-27HW7CYT.js} +1 -1
  48. package/dist/{tool-tiers-LTQNNAFU.js → tool-tiers-B7JC2XC3.js} +3 -1
  49. package/dist/{validate-AFJVI4OX.js → validate-QRVCD4GP.js} +5 -5
  50. package/dist/{validate-cross-check-7PO7CBVT.js → validate-cross-check-BUAGBAPO.js} +4 -4
  51. package/package.json +7 -7
@@ -3,20 +3,20 @@ import {
3
3
  handleGetSecurityTrends,
4
4
  handleRunSecurityScan,
5
5
  runSecurityScanDefinition
6
- } from "./chunk-TCSNO7YW.js";
6
+ } from "./chunk-HFOB2MPQ.js";
7
7
  import {
8
8
  handleRunCodeReview,
9
9
  runCodeReviewDefinition,
10
10
  sortFindingsBySeverity
11
- } from "./chunk-JE5GQVCQ.js";
11
+ } from "./chunk-Q6ZR2L6Q.js";
12
12
  import {
13
13
  assessProjectDefinition,
14
14
  handleAssessProject
15
- } from "./chunk-65MJPWFN.js";
15
+ } from "./chunk-OA6SWTU4.js";
16
16
  import {
17
17
  detectEntropyDefinition,
18
18
  handleDetectEntropy
19
- } from "./chunk-UF7BKRH4.js";
19
+ } from "./chunk-QOKMDDBJ.js";
20
20
  import {
21
21
  checkPerformanceDefinition,
22
22
  getCriticalPathsDefinition,
@@ -26,7 +26,7 @@ import {
26
26
  handleGetPerfBaselines,
27
27
  handleUpdatePerfBaselines,
28
28
  updatePerfBaselinesDefinition
29
- } from "./chunk-XSI3RDH6.js";
29
+ } from "./chunk-6AX6R3LM.js";
30
30
  import {
31
31
  getBusinessKnowledgeResource
32
32
  } from "./chunk-IOW3MW2K.js";
@@ -37,7 +37,7 @@ import {
37
37
  handleCreateSelfReview,
38
38
  handleRequestPeerReview,
39
39
  requestPeerReviewDefinition
40
- } from "./chunk-6SRKI77C.js";
40
+ } from "./chunk-HMW3VKUF.js";
41
41
  import {
42
42
  GENERATED_HEADER_CLAUDE,
43
43
  GENERATED_HEADER_CODEX,
@@ -53,18 +53,18 @@ import {
53
53
  import {
54
54
  handleValidateProject,
55
55
  validateToolDefinition
56
- } from "./chunk-NOOPJD5R.js";
56
+ } from "./chunk-I6K43QQS.js";
57
57
  import {
58
58
  checkDependenciesDefinition,
59
59
  handleCheckDependencies
60
- } from "./chunk-2RNGLYOG.js";
60
+ } from "./chunk-5JNSFYZU.js";
61
61
  import {
62
62
  resolveProjectConfig
63
- } from "./chunk-7DOGGXQU.js";
63
+ } from "./chunk-GWF2OILZ.js";
64
64
  import {
65
65
  checkDocsDefinition,
66
66
  handleCheckDocs
67
- } from "./chunk-DOUS4ULX.js";
67
+ } from "./chunk-GWE5LL3R.js";
68
68
  import {
69
69
  resultToMcpResponse
70
70
  } from "./chunk-EPUKTTJZ.js";
@@ -88,7 +88,7 @@ import {
88
88
  } from "./chunk-HIK6OEUF.js";
89
89
  import {
90
90
  resolveConfig
91
- } from "./chunk-HIZXUWWC.js";
91
+ } from "./chunk-VTTNIZJL.js";
92
92
  import {
93
93
  logger
94
94
  } from "./chunk-EBJQ6N4M.js";
@@ -118,14 +118,14 @@ import {
118
118
  scanForInjection,
119
119
  serializeEnvelope,
120
120
  writeTaint
121
- } from "./chunk-KQ6TDRPS.js";
121
+ } from "./chunk-YYRQCQPZ.js";
122
122
  import {
123
123
  Err,
124
124
  INDEXED_FILE_KINDS,
125
125
  INSIGHTS_KEYS,
126
126
  Ok,
127
127
  init_dist
128
- } from "./chunk-2LPUIBVH.js";
128
+ } from "./chunk-OH3NXXUY.js";
129
129
 
130
130
  // src/mcp/server.ts
131
131
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
@@ -331,7 +331,17 @@ security/*
331
331
  !security/timeline.json
332
332
  `;
333
333
  fs.mkdirSync(path.dirname(gitignorePath), { recursive: true });
334
- fs.writeFileSync(gitignorePath, content);
334
+ if (!fs.existsSync(gitignorePath)) {
335
+ fs.writeFileSync(gitignorePath, content);
336
+ return;
337
+ }
338
+ const existing = fs.readFileSync(gitignorePath, "utf8");
339
+ const existingLines = new Set(existing.split("\n").map((l) => l.trim()));
340
+ const missing = content.split("\n").filter((l) => l.trim() && !l.startsWith("#") && !existingLines.has(l.trim()));
341
+ if (missing.length > 0) {
342
+ const prefix = existing.endsWith("\n") ? "" : "\n";
343
+ fs.appendFileSync(gitignorePath, prefix + missing.join("\n") + "\n");
344
+ }
335
345
  }
336
346
  function appendFrameworkAgents(targetDir, framework, language) {
337
347
  if (!framework) return;
@@ -725,7 +735,7 @@ async function handleInsightsSummary(input) {
725
735
  const skip = Array.isArray(input.skip) ? input.skip.filter(
726
736
  (k) => typeof k === "string" && INSIGHTS_KEYS.includes(k)
727
737
  ) : void 0;
728
- const { composeInsights } = await import("./dist-TKHVYUWZ.js");
738
+ const { composeInsights } = await import("./dist-OHDQBTSO.js");
729
739
  const report = await composeInsights(projectPath, {
730
740
  ...skip && skip.length > 0 && { skip }
731
741
  });
@@ -901,7 +911,7 @@ ${skippedMsg}`
901
911
  async function handleInitProject(input) {
902
912
  const i = input;
903
913
  try {
904
- const { TemplateEngine } = await import("./engine-5BXDQT5T.js");
914
+ const { TemplateEngine } = await import("./engine-GKGT5ULT.js");
905
915
  const engine = new TemplateEngine(resolveTemplatesDir());
906
916
  const safePath = sanitizePath(i.path);
907
917
  const detected = tryDetectFramework(engine, safePath, i);
@@ -923,7 +933,7 @@ var listPersonasDefinition = {
923
933
  inputSchema: { type: "object", properties: {} }
924
934
  };
925
935
  async function handleListPersonas() {
926
- const { listPersonas } = await import("./loader-6RTEYN5Q.js");
936
+ const { listPersonas } = await import("./loader-BNKGM23C.js");
927
937
  const result = listPersonas(resolvePersonasDir());
928
938
  return resultToMcpResponse(result);
929
939
  }
@@ -947,10 +957,10 @@ async function handleGeneratePersonaArtifacts(input) {
947
957
  if (!/^[a-z0-9][a-z0-9._-]*$/i.test(input.name)) {
948
958
  return resultToMcpResponse(Err(new Error(`Invalid persona name: ${input.name}`)));
949
959
  }
950
- const { loadPersona } = await import("./loader-6RTEYN5Q.js");
951
- const { generateRuntime } = await import("./runtime-SAZGLILX.js");
952
- const { generateAgentsMd } = await import("./agents-md-KAD3L2NO.js");
953
- const { generateCIWorkflow } = await import("./ci-workflow-WAG4TOV6.js");
960
+ const { loadPersona } = await import("./loader-BNKGM23C.js");
961
+ const { generateRuntime } = await import("./runtime-W5THSNAL.js");
962
+ const { generateAgentsMd } = await import("./agents-md-2JUQ4FE2.js");
963
+ const { generateCIWorkflow } = await import("./ci-workflow-3JNDZQYD.js");
954
964
  const personasDir = resolvePersonasDir();
955
965
  const filePath = path4.join(personasDir, `${input.name}.yaml`);
956
966
  if (!filePath.startsWith(personasDir)) {
@@ -1005,7 +1015,7 @@ async function handleRunPersona(input) {
1005
1015
  if (!/^[a-z0-9][a-z0-9._-]*$/i.test(input.persona)) {
1006
1016
  return resultToMcpResponse(Err(new Error(`Invalid persona name: ${input.persona}`)));
1007
1017
  }
1008
- const { loadPersona } = await import("./loader-6RTEYN5Q.js");
1018
+ const { loadPersona } = await import("./loader-BNKGM23C.js");
1009
1019
  const { runPersona } = await import("./runner-AAEF2TXY.js");
1010
1020
  const { executeSkill } = await import("./skill-executor-MOCUIAYS.js");
1011
1021
  const personasDir = resolvePersonasDir();
@@ -1450,7 +1460,7 @@ function loadOrGenerateProfile(projectRoot) {
1450
1460
  // src/mcp/tools/event-emitter.ts
1451
1461
  async function emitSkillEvent(projectPath, event) {
1452
1462
  try {
1453
- const { emitEvent } = await import("./dist-TKHVYUWZ.js");
1463
+ const { emitEvent } = await import("./dist-OHDQBTSO.js");
1454
1464
  await emitEvent(projectPath, event);
1455
1465
  } catch {
1456
1466
  }
@@ -1722,7 +1732,7 @@ async function autoSyncRoadmap(projectPath) {
1722
1732
  try {
1723
1733
  const roadmapFile = path11.join(projectPath, "docs", "roadmap.md");
1724
1734
  if (!fs10.existsSync(roadmapFile)) return;
1725
- const { parseRoadmap, serializeRoadmap, syncRoadmap, applySyncChanges } = await import("./dist-TKHVYUWZ.js");
1735
+ const { parseRoadmap, serializeRoadmap, syncRoadmap, applySyncChanges } = await import("./dist-OHDQBTSO.js");
1726
1736
  const raw = fs10.readFileSync(roadmapFile, "utf-8");
1727
1737
  const parseResult = parseRoadmap(raw);
1728
1738
  if (!parseResult.ok) return;
@@ -1752,7 +1762,7 @@ async function triggerExternalSync(projectPath, roadmapFile) {
1752
1762
  console.warn("[roadmap-sync] GITHUB_TOKEN not found \u2014 external sync skipped");
1753
1763
  return;
1754
1764
  }
1755
- const { fullSync, GitHubIssuesSyncAdapter } = await import("./dist-TKHVYUWZ.js");
1765
+ const { fullSync, GitHubIssuesSyncAdapter } = await import("./dist-OHDQBTSO.js");
1756
1766
  const adapter = new GitHubIssuesSyncAdapter({
1757
1767
  token,
1758
1768
  config: trackerConfig
@@ -1849,12 +1859,12 @@ var manageStateDefinition = {
1849
1859
  }
1850
1860
  };
1851
1861
  async function handleShow(projectPath, input) {
1852
- const { loadState } = await import("./dist-TKHVYUWZ.js");
1862
+ const { loadState } = await import("./dist-OHDQBTSO.js");
1853
1863
  return resultToMcpResponse(await loadState(projectPath, input.stream, input.session));
1854
1864
  }
1855
1865
  async function handleLearn(projectPath, input) {
1856
1866
  if (!input.learning) return mcpError("Error: learning is required for learn action");
1857
- const { appendLearning } = await import("./dist-TKHVYUWZ.js");
1867
+ const { appendLearning } = await import("./dist-OHDQBTSO.js");
1858
1868
  const result = await appendLearning(
1859
1869
  projectPath,
1860
1870
  input.learning,
@@ -1869,7 +1879,7 @@ async function handleLearn(projectPath, input) {
1869
1879
  async function handleFailure(projectPath, input) {
1870
1880
  if (!input.description) return mcpError("Error: description is required for failure action");
1871
1881
  if (!input.failureType) return mcpError("Error: failureType is required for failure action");
1872
- const { appendFailure } = await import("./dist-TKHVYUWZ.js");
1882
+ const { appendFailure } = await import("./dist-OHDQBTSO.js");
1873
1883
  const result = await appendFailure(
1874
1884
  projectPath,
1875
1885
  input.description,
@@ -1888,19 +1898,19 @@ async function handleFailure(projectPath, input) {
1888
1898
  return resultToMcpResponse(Ok({ recorded: true }));
1889
1899
  }
1890
1900
  async function handleArchive(projectPath, input) {
1891
- const { archiveFailures } = await import("./dist-TKHVYUWZ.js");
1901
+ const { archiveFailures } = await import("./dist-OHDQBTSO.js");
1892
1902
  const result = await archiveFailures(projectPath, input.stream, input.session);
1893
1903
  if (!result.ok) return resultToMcpResponse(result);
1894
1904
  return resultToMcpResponse(Ok({ archived: true }));
1895
1905
  }
1896
1906
  async function handleReset(projectPath, input) {
1897
- const { saveState, DEFAULT_STATE } = await import("./dist-TKHVYUWZ.js");
1907
+ const { saveState, DEFAULT_STATE } = await import("./dist-OHDQBTSO.js");
1898
1908
  const result = await saveState(projectPath, { ...DEFAULT_STATE }, input.stream, input.session);
1899
1909
  if (!result.ok) return resultToMcpResponse(result);
1900
1910
  return resultToMcpResponse(Ok({ reset: true }));
1901
1911
  }
1902
1912
  async function handleGate(projectPath, input) {
1903
- const { runMechanicalGate } = await import("./dist-TKHVYUWZ.js");
1913
+ const { runMechanicalGate } = await import("./dist-OHDQBTSO.js");
1904
1914
  const result = await runMechanicalGate(projectPath);
1905
1915
  if (result.ok) {
1906
1916
  await emitSkillEvent(projectPath, {
@@ -1920,7 +1930,7 @@ async function handleGate(projectPath, input) {
1920
1930
  }
1921
1931
  async function handleSaveHandoff(projectPath, input) {
1922
1932
  if (!input.handoff) return mcpError("Error: handoff is required for save-handoff action");
1923
- const { saveHandoff } = await import("./dist-TKHVYUWZ.js");
1933
+ const { saveHandoff } = await import("./dist-OHDQBTSO.js");
1924
1934
  const result = await saveHandoff(
1925
1935
  projectPath,
1926
1936
  input.handoff,
@@ -1942,7 +1952,7 @@ async function handleSaveHandoff(projectPath, input) {
1942
1952
  return resultToMcpResponse(Ok({ saved: true }));
1943
1953
  }
1944
1954
  async function handleLoadHandoff(projectPath, input) {
1945
- const { loadHandoff } = await import("./dist-TKHVYUWZ.js");
1955
+ const { loadHandoff } = await import("./dist-OHDQBTSO.js");
1946
1956
  return resultToMcpResponse(await loadHandoff(projectPath, input.stream, input.session));
1947
1957
  }
1948
1958
  async function handleAppendEntry(projectPath, input) {
@@ -1950,7 +1960,7 @@ async function handleAppendEntry(projectPath, input) {
1950
1960
  if (!input.authorSkill) return mcpError("Error: authorSkill is required for append_entry action");
1951
1961
  if (!input.content) return mcpError("Error: content is required for append_entry action");
1952
1962
  if (input.session) {
1953
- const { appendSessionEntry } = await import("./dist-TKHVYUWZ.js");
1963
+ const { appendSessionEntry } = await import("./dist-OHDQBTSO.js");
1954
1964
  const result = await appendSessionEntry(
1955
1965
  projectPath,
1956
1966
  input.session,
@@ -1963,7 +1973,7 @@ async function handleAppendEntry(projectPath, input) {
1963
1973
  if (input.section !== "decisions") {
1964
1974
  return mcpError("Error: session is required for non-decisions sections");
1965
1975
  }
1966
- const { loadState, saveState } = await import("./dist-TKHVYUWZ.js");
1976
+ const { loadState, saveState } = await import("./dist-OHDQBTSO.js");
1967
1977
  const lr = await loadState(projectPath, input.stream);
1968
1978
  if (!lr.ok) return resultToMcpResponse(lr);
1969
1979
  lr.value.decisions.push({
@@ -1981,7 +1991,7 @@ async function handleUpdateEntryStatus(projectPath, input) {
1981
1991
  if (!input.entryId) return mcpError("Error: entryId is required for update_entry_status action");
1982
1992
  if (!input.newStatus)
1983
1993
  return mcpError("Error: newStatus is required for update_entry_status action");
1984
- const { updateSessionEntryStatus } = await import("./dist-TKHVYUWZ.js");
1994
+ const { updateSessionEntryStatus } = await import("./dist-OHDQBTSO.js");
1985
1995
  const result = await updateSessionEntryStatus(
1986
1996
  projectPath,
1987
1997
  input.session,
@@ -1994,7 +2004,7 @@ async function handleUpdateEntryStatus(projectPath, input) {
1994
2004
  async function handleReadSection(projectPath, input) {
1995
2005
  if (!input.session) return mcpError("Error: session is required for read_section action");
1996
2006
  if (!input.section) return mcpError("Error: section is required for read_section action");
1997
- const { readSessionSection } = await import("./dist-TKHVYUWZ.js");
2007
+ const { readSessionSection } = await import("./dist-OHDQBTSO.js");
1998
2008
  const result = await readSessionSection(
1999
2009
  projectPath,
2000
2010
  input.session,
@@ -2004,13 +2014,13 @@ async function handleReadSection(projectPath, input) {
2004
2014
  }
2005
2015
  async function handleReadSections(projectPath, input) {
2006
2016
  if (!input.session) return mcpError("Error: session is required for read_sections action");
2007
- const { readSessionSections } = await import("./dist-TKHVYUWZ.js");
2017
+ const { readSessionSections } = await import("./dist-OHDQBTSO.js");
2008
2018
  const result = await readSessionSections(projectPath, input.session);
2009
2019
  return resultToMcpResponse(result);
2010
2020
  }
2011
2021
  async function handleArchiveSession(projectPath, input) {
2012
2022
  if (!input.session) return mcpError("Error: session is required for archive_session action");
2013
- const { archiveSession } = await import("./dist-TKHVYUWZ.js");
2023
+ const { archiveSession } = await import("./dist-OHDQBTSO.js");
2014
2024
  const { buildArchiveHooks } = await import("@harness-engineering/orchestrator");
2015
2025
  const hooks = buildArchiveHooks({ projectPath });
2016
2026
  const result = await archiveSession(projectPath, input.session, { hooks });
@@ -2092,7 +2102,7 @@ var listStreamsDefinition = {
2092
2102
  };
2093
2103
  async function handleListStreams(input) {
2094
2104
  try {
2095
- const { listStreams, loadStreamIndex } = await import("./dist-TKHVYUWZ.js");
2105
+ const { listStreams, loadStreamIndex } = await import("./dist-OHDQBTSO.js");
2096
2106
  const projectPath = sanitizePath(input.path);
2097
2107
  const indexResult = await loadStreamIndex(projectPath);
2098
2108
  const streamsResult = await listStreams(projectPath);
@@ -2130,7 +2140,7 @@ var checkPhaseGateDefinition = {
2130
2140
  };
2131
2141
  async function handleCheckPhaseGate(input) {
2132
2142
  try {
2133
- const { runCheckPhaseGate } = await import("./check-phase-gate-PD5MVEZT.js");
2143
+ const { runCheckPhaseGate } = await import("./check-phase-gate-XMU6LLUQ.js");
2134
2144
  const result = await runCheckPhaseGate({ cwd: sanitizePath(input.path) });
2135
2145
  if (result.ok) {
2136
2146
  return { content: [{ type: "text", text: JSON.stringify(result.value) }] };
@@ -2186,7 +2196,7 @@ async function handleValidateCrossCheck(input) {
2186
2196
  };
2187
2197
  }
2188
2198
  try {
2189
- const { runCrossCheck } = await import("./validate-cross-check-7PO7CBVT.js");
2199
+ const { runCrossCheck } = await import("./validate-cross-check-BUAGBAPO.js");
2190
2200
  const specsDir = path12.resolve(projectPath, input.specsDir ?? "docs/specs");
2191
2201
  if (!specsDir.startsWith(projectPath)) {
2192
2202
  return {
@@ -2953,7 +2963,7 @@ async function handleGenerateSlashCommands(input) {
2953
2963
  // src/mcp/resources/state.ts
2954
2964
  async function getStateResource(projectRoot) {
2955
2965
  try {
2956
- const { loadState, migrateToStreams } = await import("./dist-TKHVYUWZ.js");
2966
+ const { loadState, migrateToStreams } = await import("./dist-OHDQBTSO.js");
2957
2967
  await migrateToStreams(projectRoot);
2958
2968
  const result = await loadState(projectRoot);
2959
2969
  if (result.ok) {
@@ -3973,7 +3983,7 @@ var generateAgentDefinitionsDefinition = {
3973
3983
  }
3974
3984
  };
3975
3985
  async function handleGenerateAgentDefinitions(input) {
3976
- const { generateAgentDefinitions } = await import("./generate-agent-definitions-5PV4O3BD.js");
3986
+ const { generateAgentDefinitions } = await import("./generate-agent-definitions-SZA4QIHN.js");
3977
3987
  const platforms = input.platform === "all" || !input.platform ? ["claude-code", "gemini-cli"] : [input.platform];
3978
3988
  const results = generateAgentDefinitions({
3979
3989
  platforms: [...platforms],
@@ -4467,8 +4477,8 @@ async function handleManageRoadmap(input) {
4467
4477
  return handleManageRoadmapFileLess(input, clientResult.value);
4468
4478
  }
4469
4479
  try {
4470
- const { parseRoadmap, serializeRoadmap, syncRoadmap, applySyncChanges, assignFeature } = await import("./dist-TKHVYUWZ.js");
4471
- const { Ok: Ok2 } = await import("./dist-HVJUGPSY.js");
4480
+ const { parseRoadmap, serializeRoadmap, syncRoadmap, applySyncChanges, assignFeature } = await import("./dist-OHDQBTSO.js");
4481
+ const { Ok: Ok2 } = await import("./dist-E3SAAHCM.js");
4472
4482
  const projectPath = projectPathPre;
4473
4483
  const deps = {
4474
4484
  parseRoadmap,
@@ -4906,7 +4916,7 @@ async function handleTransition(validInput, projectPath, id) {
4906
4916
  const transition = transitionResult.data;
4907
4917
  const prompt = renderTransition(transition);
4908
4918
  try {
4909
- const { saveHandoff } = await import("./dist-TKHVYUWZ.js");
4919
+ const { saveHandoff } = await import("./dist-OHDQBTSO.js");
4910
4920
  await saveHandoff(
4911
4921
  projectPath,
4912
4922
  {
@@ -4987,7 +4997,7 @@ async function handleEmitInteraction(input) {
4987
4997
  }
4988
4998
  async function recordInteraction(projectPath, id, type, decision, stream) {
4989
4999
  try {
4990
- const { loadState, saveState } = await import("./dist-TKHVYUWZ.js");
5000
+ const { loadState, saveState } = await import("./dist-OHDQBTSO.js");
4991
5001
  const stateResult = await loadState(projectPath, stream);
4992
5002
  if (stateResult.ok) {
4993
5003
  const state = stateResult.value;
@@ -5148,10 +5158,10 @@ async function handleGatherContext(input) {
5148
5158
  input.include ?? ["state", "learnings", "handoff", "graph", "validation", "businessKnowledge"]
5149
5159
  );
5150
5160
  const errors = [];
5151
- const statePromise = includeSet.has("state") ? import("./dist-TKHVYUWZ.js").then(
5161
+ const statePromise = includeSet.has("state") ? import("./dist-OHDQBTSO.js").then(
5152
5162
  (core) => core.loadState(projectPath, void 0, input.session)
5153
5163
  ) : Promise.resolve(null);
5154
- const learningsPromise = includeSet.has("learnings") ? import("./dist-TKHVYUWZ.js").then(
5164
+ const learningsPromise = includeSet.has("learnings") ? import("./dist-OHDQBTSO.js").then(
5155
5165
  (core) => core.loadBudgetedLearnings(projectPath, {
5156
5166
  intent: input.intent,
5157
5167
  tokenBudget: input.learningsBudget ?? 1e3,
@@ -5160,7 +5170,7 @@ async function handleGatherContext(input) {
5160
5170
  ...input.depth !== void 0 && { depth: input.depth }
5161
5171
  })
5162
5172
  ) : Promise.resolve(null);
5163
- const handoffPromise = includeSet.has("handoff") ? import("./dist-TKHVYUWZ.js").then(
5173
+ const handoffPromise = includeSet.has("handoff") ? import("./dist-OHDQBTSO.js").then(
5164
5174
  (core) => core.loadHandoff(projectPath, void 0, input.session)
5165
5175
  ) : Promise.resolve(null);
5166
5176
  const graphPromise = includeSet.has("graph") ? (async () => {
@@ -5204,11 +5214,11 @@ async function handleGatherContext(input) {
5204
5214
  context: contextBlocks
5205
5215
  };
5206
5216
  })() : Promise.resolve(null);
5207
- const sessionsPromise = includeSet.has("sessions") && input.session ? import("./dist-TKHVYUWZ.js").then(
5217
+ const sessionsPromise = includeSet.has("sessions") && input.session ? import("./dist-OHDQBTSO.js").then(
5208
5218
  (core) => core.readSessionSections(projectPath, input.session)
5209
5219
  ) : Promise.resolve(null);
5210
5220
  const shouldIncludeEvents = input.includeEvents !== void 0 ? input.includeEvents : includeSet.has("events") || !!input.session && !input.include;
5211
- const eventsPromise = shouldIncludeEvents ? import("./dist-TKHVYUWZ.js").then(async (core) => {
5221
+ const eventsPromise = shouldIncludeEvents ? import("./dist-OHDQBTSO.js").then(async (core) => {
5212
5222
  const result = await core.loadEvents(projectPath, {
5213
5223
  session: input.session
5214
5224
  });
@@ -5216,7 +5226,7 @@ async function handleGatherContext(input) {
5216
5226
  return core.formatEventTimeline(result.value);
5217
5227
  }) : Promise.resolve(null);
5218
5228
  const validationPromise = includeSet.has("validation") ? (async () => {
5219
- const { handleValidateProject: handleValidateProject2 } = await import("./validate-AFJVI4OX.js");
5229
+ const { handleValidateProject: handleValidateProject2 } = await import("./validate-QRVCD4GP.js");
5220
5230
  const result = await handleValidateProject2({ path: projectPath });
5221
5231
  const first = result.content[0];
5222
5232
  return first ? JSON.parse(first.text) : null;
@@ -5319,7 +5329,7 @@ async function handleGatherContext(input) {
5319
5329
  };
5320
5330
  if (input.session) {
5321
5331
  try {
5322
- const core = await import("./dist-TKHVYUWZ.js");
5332
+ const core = await import("./dist-OHDQBTSO.js");
5323
5333
  core.updateSessionIndex(
5324
5334
  projectPath,
5325
5335
  input.session,
@@ -5471,7 +5481,7 @@ async function handleReviewChanges(input) {
5471
5481
  }
5472
5482
  }
5473
5483
  async function runQuickReview(projectPath, diff, diffLines, downgraded, offset, limit) {
5474
- const { handleAnalyzeDiff: handleAnalyzeDiff2 } = await import("./feedback-ER2HRTFD.js");
5484
+ const { handleAnalyzeDiff: handleAnalyzeDiff2 } = await import("./feedback-WH6XPQJS.js");
5475
5485
  const result = await handleAnalyzeDiff2({ diff, path: projectPath });
5476
5486
  const firstContent = result.content[0];
5477
5487
  if (!firstContent) throw new Error("Empty analyze_diff response");
@@ -5506,7 +5516,7 @@ function extractFileCount(diffParsed) {
5506
5516
  return files?.length ?? 0;
5507
5517
  }
5508
5518
  async function runStandardReview(projectPath, diff, diffLines, downgraded, offset, limit) {
5509
- const { handleAnalyzeDiff: handleAnalyzeDiff2, handleCreateSelfReview: handleCreateSelfReview2 } = await import("./feedback-ER2HRTFD.js");
5519
+ const { handleAnalyzeDiff: handleAnalyzeDiff2, handleCreateSelfReview: handleCreateSelfReview2 } = await import("./feedback-WH6XPQJS.js");
5510
5520
  const [diffResult, reviewResult] = await Promise.all([
5511
5521
  handleAnalyzeDiff2({ diff, path: projectPath }),
5512
5522
  handleCreateSelfReview2({ path: projectPath, diff })
@@ -5541,7 +5551,7 @@ async function runStandardReview(projectPath, diff, diffLines, downgraded, offse
5541
5551
  };
5542
5552
  }
5543
5553
  async function runDeepReview(projectPath, diff, diffLines, _downgraded, offset, limit) {
5544
- const { handleRunCodeReview: handleRunCodeReview2 } = await import("./review-pipeline-4VF73V4V.js");
5554
+ const { handleRunCodeReview: handleRunCodeReview2 } = await import("./review-pipeline-OTDDVPNY.js");
5545
5555
  const result = await handleRunCodeReview2({
5546
5556
  path: projectPath,
5547
5557
  diff,
@@ -5835,7 +5845,7 @@ async function handleDetectStaleConstraints(input) {
5835
5845
  ]
5836
5846
  };
5837
5847
  }
5838
- const { detectStaleConstraints } = await import("./dist-TKHVYUWZ.js");
5848
+ const { detectStaleConstraints } = await import("./dist-OHDQBTSO.js");
5839
5849
  const result = detectStaleConstraints(
5840
5850
  store,
5841
5851
  windowDays,
@@ -5955,10 +5965,10 @@ function countCriticalFindings(securityData) {
5955
5965
  return findings.filter((f) => f.severity === "error").length;
5956
5966
  }
5957
5967
  async function runHealthChecks(projectPath) {
5958
- const { handleAssessProject: handleAssessProject2 } = await import("./assess-project-ZGMRPTS3.js");
5959
- const { handleCheckDependencies: handleCheckDependencies2 } = await import("./architecture-OC7TFCFF.js");
5960
- const { handleDetectEntropy: handleDetectEntropy2 } = await import("./entropy-7FIUFACI.js");
5961
- const { handleRunSecurityScan: handleRunSecurityScan2 } = await import("./security-ZWRABJNE.js");
5968
+ const { handleAssessProject: handleAssessProject2 } = await import("./assess-project-M626SSPN.js");
5969
+ const { handleCheckDependencies: handleCheckDependencies2 } = await import("./architecture-CXAVNB5X.js");
5970
+ const { handleDetectEntropy: handleDetectEntropy2 } = await import("./entropy-DQTAPSSE.js");
5971
+ const { handleRunSecurityScan: handleRunSecurityScan2 } = await import("./security-27HW7CYT.js");
5962
5972
  const [assessResult, depsResult, entropyResult, securityResult] = await Promise.all([
5963
5973
  handleAssessProject2({
5964
5974
  path: projectPath,
@@ -6799,7 +6809,7 @@ async function handleGetDecayTrends(input) {
6799
6809
  };
6800
6810
  }
6801
6811
  try {
6802
- const core = await import("./dist-TKHVYUWZ.js");
6812
+ const core = await import("./dist-OHDQBTSO.js");
6803
6813
  const { TimelineManager } = core;
6804
6814
  const manager = new TimelineManager(projectPath);
6805
6815
  const timeline = manager.load();
@@ -6934,7 +6944,7 @@ async function handleCodeOutline(input) {
6934
6944
  };
6935
6945
  }
6936
6946
  try {
6937
- const { getOutline, formatOutline, EXTENSION_MAP } = await import("./dist-TKHVYUWZ.js");
6947
+ const { getOutline, formatOutline, EXTENSION_MAP } = await import("./dist-OHDQBTSO.js");
6938
6948
  const { stat } = await import("fs/promises");
6939
6949
  const stats = await stat(targetPath).catch(() => null);
6940
6950
  if (stats?.isFile()) {
@@ -6953,7 +6963,7 @@ async function handleCodeOutline(input) {
6953
6963
  })
6954
6964
  );
6955
6965
  fileStats.sort((a, b) => b.mtimeMs - a.mtimeMs);
6956
- const { paginate: paginate2 } = await import("./dist-TKHVYUWZ.js");
6966
+ const { paginate: paginate2 } = await import("./dist-OHDQBTSO.js");
6957
6967
  const paged = paginate2(fileStats, input.offset ?? 0, input.limit ?? 30);
6958
6968
  const results = [];
6959
6969
  for (const entry of paged.items) {
@@ -7026,7 +7036,7 @@ async function handleCodeSearch(input) {
7026
7036
  };
7027
7037
  }
7028
7038
  try {
7029
- const { searchSymbols } = await import("./dist-TKHVYUWZ.js");
7039
+ const { searchSymbols } = await import("./dist-OHDQBTSO.js");
7030
7040
  const result = await searchSymbols(input.query, directory, input.glob);
7031
7041
  const lines = [`Search: "${result.query}" \u2014 ${result.matches.length} matches`];
7032
7042
  for (const match of result.matches) {
@@ -7095,7 +7105,7 @@ async function handleCodeUnfold(input) {
7095
7105
  }
7096
7106
  try {
7097
7107
  if (input.symbol) {
7098
- const { unfoldSymbol } = await import("./dist-TKHVYUWZ.js");
7108
+ const { unfoldSymbol } = await import("./dist-OHDQBTSO.js");
7099
7109
  const result = await unfoldSymbol(filePath, input.symbol);
7100
7110
  const header = result.warning ? `${result.file}:${result.startLine}-${result.endLine} ${result.warning}
7101
7111
  ` : `${result.file}:${result.startLine}-${result.endLine}
@@ -7103,7 +7113,7 @@ async function handleCodeUnfold(input) {
7103
7113
  return { content: [{ type: "text", text: header + result.content }] };
7104
7114
  }
7105
7115
  if (input.startLine != null && input.endLine != null) {
7106
- const { unfoldRange } = await import("./dist-TKHVYUWZ.js");
7116
+ const { unfoldRange } = await import("./dist-OHDQBTSO.js");
7107
7117
  const result = await unfoldRange(filePath, input.startLine, input.endLine);
7108
7118
  const header = `${result.file}:${result.startLine}-${result.endLine}
7109
7119
  `;
@@ -7288,7 +7298,7 @@ async function handlePredictFailures(input) {
7288
7298
  };
7289
7299
  }
7290
7300
  try {
7291
- const core = await import("./dist-TKHVYUWZ.js");
7301
+ const core = await import("./dist-OHDQBTSO.js");
7292
7302
  const { TimelineManager, PredictionEngine, SpecImpactEstimator } = core;
7293
7303
  const manager = new TimelineManager(projectPath);
7294
7304
  const includeRoadmap = input.includeRoadmap !== false;
@@ -8397,7 +8407,7 @@ async function handleDetectConstraintEmergence(input) {
8397
8407
  }
8398
8408
  const nodePath = await import("path");
8399
8409
  const historyPath = nodePath.resolve(projectPath, ".harness/arch/violation-history.json");
8400
- const { ViolationHistoryManager, detectEmergentConstraints } = await import("./dist-TKHVYUWZ.js");
8410
+ const { ViolationHistoryManager, detectEmergentConstraints } = await import("./dist-OHDQBTSO.js");
8401
8411
  const manager = new ViolationHistoryManager(historyPath);
8402
8412
  const history = manager.load();
8403
8413
  const options = { windowWeeks, minOccurrences };
@@ -8485,7 +8495,7 @@ async function handleRunCIChecks(input) {
8485
8495
  };
8486
8496
  }
8487
8497
  try {
8488
- const { runCIChecks } = await import("./dist-TKHVYUWZ.js");
8498
+ const { runCIChecks } = await import("./dist-OHDQBTSO.js");
8489
8499
  const skip = input.checks ? VALID_CHECKS.filter((c) => !input.checks.includes(c)) : [];
8490
8500
  const result = await runCIChecks({
8491
8501
  projectRoot: projectPath,
@@ -8547,7 +8557,7 @@ async function handleGenerateBlueprint(input) {
8547
8557
  };
8548
8558
  }
8549
8559
  try {
8550
- const { ProjectScanner } = await import("./dist-TKHVYUWZ.js");
8560
+ const { ProjectScanner } = await import("./dist-OHDQBTSO.js");
8551
8561
  const scanner = new ProjectScanner(projectPath);
8552
8562
  const data = await scanner.scan();
8553
8563
  return {
@@ -8669,6 +8679,125 @@ async function handleSubscribeWebhook(input) {
8669
8679
  return { content: [{ type: "text", text }] };
8670
8680
  }
8671
8681
 
8682
+ // src/mcp/tools/skill-proposal.ts
8683
+ var emitSkillProposalDefinition = {
8684
+ name: "emit_skill_proposal",
8685
+ description: "Emit a skill proposal (new-skill or refinement) into the review queue. Writes `.harness/proposals/<id>.json` and returns the queue URL. The proposal does not gate the agent \u2014 soundness-review runs at approval time.",
8686
+ inputSchema: {
8687
+ type: "object",
8688
+ properties: {
8689
+ path: { type: "string", description: "Path to project root" },
8690
+ kind: {
8691
+ type: "string",
8692
+ enum: ["new-skill", "refinement"],
8693
+ description: "new-skill = full content; refinement = unified-diff against targetSkill"
8694
+ },
8695
+ targetSkill: {
8696
+ type: "string",
8697
+ description: "Existing skill name (required when kind is refinement)"
8698
+ },
8699
+ proposedBy: {
8700
+ type: "string",
8701
+ description: 'Agent identifier, e.g. "claude-code:harness-execution"'
8702
+ },
8703
+ justification: {
8704
+ type: "string",
8705
+ description: "Why this skill / refinement is worth promoting (20\u20132000 chars)"
8706
+ },
8707
+ sessionId: { type: "string", description: "Originating session id (optional)" },
8708
+ taskId: { type: "string", description: "Originating maintenance task id (optional)" },
8709
+ content: {
8710
+ type: "object",
8711
+ description: "Proposal content. new-skill \u21D2 skillYaml+skillMd; refinement \u21D2 diff",
8712
+ properties: {
8713
+ name: {
8714
+ type: "string",
8715
+ description: "kebab-case skill name (matches /^[a-z][a-z0-9-]*$/, \u226464 chars)"
8716
+ },
8717
+ description: { type: "string", description: "20\u2013280 chars" },
8718
+ skillYaml: { type: "string", description: "Full skill.yaml (new-skill only)" },
8719
+ skillMd: { type: "string", description: "Full SKILL.md (new-skill only)" },
8720
+ diff: { type: "string", description: "Unified diff (refinement only)" }
8721
+ },
8722
+ required: ["name", "description"]
8723
+ }
8724
+ },
8725
+ required: ["path", "kind", "proposedBy", "justification", "content"]
8726
+ }
8727
+ };
8728
+ async function handleEmitSkillProposal(input) {
8729
+ let projectPath;
8730
+ try {
8731
+ projectPath = sanitizePath(input.path);
8732
+ } catch (err2) {
8733
+ return mcpError(err2 instanceof Error ? err2.message : "Invalid path");
8734
+ }
8735
+ if (input.kind === "new-skill") {
8736
+ if (!input.content.skillYaml || !input.content.skillMd) {
8737
+ return mcpError("new-skill proposals require both skillYaml and skillMd");
8738
+ }
8739
+ if (input.targetSkill) {
8740
+ return mcpError("targetSkill is forbidden on new-skill proposals");
8741
+ }
8742
+ if (input.content.diff) {
8743
+ return mcpError("diff is forbidden on new-skill proposals (use skillYaml/skillMd)");
8744
+ }
8745
+ } else if (input.kind === "refinement") {
8746
+ if (!input.targetSkill) {
8747
+ return mcpError("refinement proposals require targetSkill");
8748
+ }
8749
+ if (!input.content.diff) {
8750
+ return mcpError("refinement proposals require a unified diff");
8751
+ }
8752
+ if (input.content.skillYaml || input.content.skillMd) {
8753
+ return mcpError("skillYaml/skillMd are forbidden on refinement proposals (encode in diff)");
8754
+ }
8755
+ }
8756
+ let createProposal;
8757
+ let ProposalConflictError;
8758
+ try {
8759
+ const core = await import("./dist-OHDQBTSO.js");
8760
+ createProposal = core.createProposal;
8761
+ ProposalConflictError = core.ProposalConflictError;
8762
+ } catch (err2) {
8763
+ return mcpError(
8764
+ `Failed to load proposal store: ${err2 instanceof Error ? err2.message : "unknown error"}`
8765
+ );
8766
+ }
8767
+ try {
8768
+ const proposal = await createProposal(projectPath, {
8769
+ kind: input.kind,
8770
+ targetSkill: input.targetSkill,
8771
+ proposedBy: input.proposedBy,
8772
+ justification: input.justification,
8773
+ sessionId: input.sessionId,
8774
+ taskId: input.taskId,
8775
+ content: input.content
8776
+ });
8777
+ const result = {
8778
+ id: proposal.id,
8779
+ path: `.harness/proposals/${proposal.id}.json`,
8780
+ queueUrl: "/s/proposals",
8781
+ status: proposal.status
8782
+ };
8783
+ return {
8784
+ content: [
8785
+ {
8786
+ type: "text",
8787
+ text: JSON.stringify(result, null, 2)
8788
+ }
8789
+ ]
8790
+ };
8791
+ } catch (err2) {
8792
+ if (err2 instanceof ProposalConflictError) {
8793
+ return mcpError(err2.message);
8794
+ }
8795
+ return mcpError(
8796
+ `Failed to write proposal: ${err2 instanceof Error ? err2.message : "unknown error"}`
8797
+ );
8798
+ }
8799
+ }
8800
+
8672
8801
  // src/mcp/server.ts
8673
8802
  var TOOL_DEFINITIONS = [
8674
8803
  validateToolDefinition,
@@ -8737,7 +8866,8 @@ var TOOL_DEFINITIONS = [
8737
8866
  subscribeWebhookDefinition,
8738
8867
  searchSessionsDefinition,
8739
8868
  summarizeSessionDefinition,
8740
- insightsSummaryDefinition
8869
+ insightsSummaryDefinition,
8870
+ emitSkillProposalDefinition
8741
8871
  ].map((def) => ({ ...def, trustedOutput: true }));
8742
8872
  var TOOL_HANDLERS = {
8743
8873
  validate_project: handleValidateProject,
@@ -8806,7 +8936,8 @@ var TOOL_HANDLERS = {
8806
8936
  subscribe_webhook: handleSubscribeWebhook,
8807
8937
  search_sessions: handleSearchSessions,
8808
8938
  summarize_session: handleSummarizeSession,
8809
- insights_summary: handleInsightsSummary
8939
+ insights_summary: handleInsightsSummary,
8940
+ emit_skill_proposal: handleEmitSkillProposal
8810
8941
  };
8811
8942
  var RESOURCE_DEFINITIONS = [
8812
8943
  {
@@ -8908,7 +9039,7 @@ async function appendUpdateNotification(result, resolvedRoot) {
8908
9039
  shouldRunCheck,
8909
9040
  readCheckState,
8910
9041
  spawnBackgroundCheck
8911
- } = await import("./dist-TKHVYUWZ.js");
9042
+ } = await import("./dist-OHDQBTSO.js");
8912
9043
  const { CLI_VERSION } = await import("./version-CUI434OP.js");
8913
9044
  const configInterval = readConfigInterval(resolvedRoot);
8914
9045
  const DEFAULT_INTERVAL = 864e5;