@harness-engineering/cli 1.13.0 → 1.13.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 (267) hide show
  1. package/dist/agents/skills/claude-code/add-harness-component/skill.yaml +1 -0
  2. package/dist/agents/skills/claude-code/align-documentation/skill.yaml +1 -0
  3. package/dist/agents/skills/claude-code/check-mechanical-constraints/skill.yaml +1 -0
  4. package/dist/agents/skills/claude-code/cleanup-dead-code/skill.yaml +1 -0
  5. package/dist/agents/skills/claude-code/detect-doc-drift/skill.yaml +1 -0
  6. package/dist/agents/skills/claude-code/enforce-architecture/skill.yaml +1 -0
  7. package/dist/agents/skills/claude-code/harness-accessibility/skill.yaml +1 -0
  8. package/dist/agents/skills/claude-code/harness-api-design/SKILL.md +304 -0
  9. package/dist/agents/skills/claude-code/harness-api-design/skill.yaml +74 -0
  10. package/dist/agents/skills/claude-code/harness-architecture-advisor/skill.yaml +1 -0
  11. package/dist/agents/skills/claude-code/harness-auth/SKILL.md +279 -0
  12. package/dist/agents/skills/claude-code/harness-auth/skill.yaml +81 -0
  13. package/dist/agents/skills/claude-code/harness-autopilot/skill.yaml +1 -0
  14. package/dist/agents/skills/claude-code/harness-brainstorming/skill.yaml +1 -0
  15. package/dist/agents/skills/claude-code/harness-caching/SKILL.md +309 -0
  16. package/dist/agents/skills/claude-code/harness-caching/skill.yaml +73 -0
  17. package/dist/agents/skills/claude-code/harness-chaos/SKILL.md +295 -0
  18. package/dist/agents/skills/claude-code/harness-chaos/skill.yaml +72 -0
  19. package/dist/agents/skills/claude-code/harness-code-review/skill.yaml +1 -0
  20. package/dist/agents/skills/claude-code/harness-codebase-cleanup/skill.yaml +1 -0
  21. package/dist/agents/skills/claude-code/harness-compliance/SKILL.md +303 -0
  22. package/dist/agents/skills/claude-code/harness-compliance/skill.yaml +78 -0
  23. package/dist/agents/skills/claude-code/harness-containerization/SKILL.md +284 -0
  24. package/dist/agents/skills/claude-code/harness-containerization/skill.yaml +80 -0
  25. package/dist/agents/skills/claude-code/harness-data-pipeline/SKILL.md +274 -0
  26. package/dist/agents/skills/claude-code/harness-data-pipeline/skill.yaml +81 -0
  27. package/dist/agents/skills/claude-code/harness-data-validation/SKILL.md +343 -0
  28. package/dist/agents/skills/claude-code/harness-data-validation/skill.yaml +75 -0
  29. package/dist/agents/skills/claude-code/harness-database/SKILL.md +258 -0
  30. package/dist/agents/skills/claude-code/harness-database/skill.yaml +80 -0
  31. package/dist/agents/skills/claude-code/harness-debugging/skill.yaml +1 -0
  32. package/dist/agents/skills/claude-code/harness-dependency-health/skill.yaml +1 -0
  33. package/dist/agents/skills/claude-code/harness-deployment/SKILL.md +255 -0
  34. package/dist/agents/skills/claude-code/harness-deployment/skill.yaml +77 -0
  35. package/dist/agents/skills/claude-code/harness-design/skill.yaml +1 -0
  36. package/dist/agents/skills/claude-code/harness-design-mobile/skill.yaml +1 -0
  37. package/dist/agents/skills/claude-code/harness-design-system/skill.yaml +1 -0
  38. package/dist/agents/skills/claude-code/harness-design-web/skill.yaml +1 -0
  39. package/dist/agents/skills/claude-code/harness-diagnostics/skill.yaml +1 -0
  40. package/dist/agents/skills/claude-code/harness-docs-pipeline/skill.yaml +1 -0
  41. package/dist/agents/skills/claude-code/harness-dx/SKILL.md +276 -0
  42. package/dist/agents/skills/claude-code/harness-dx/skill.yaml +76 -0
  43. package/dist/agents/skills/claude-code/harness-e2e/SKILL.md +245 -0
  44. package/dist/agents/skills/claude-code/harness-e2e/skill.yaml +78 -0
  45. package/dist/agents/skills/claude-code/harness-event-driven/SKILL.md +280 -0
  46. package/dist/agents/skills/claude-code/harness-event-driven/skill.yaml +77 -0
  47. package/dist/agents/skills/claude-code/harness-execution/skill.yaml +1 -0
  48. package/dist/agents/skills/claude-code/harness-feature-flags/SKILL.md +287 -0
  49. package/dist/agents/skills/claude-code/harness-feature-flags/skill.yaml +74 -0
  50. package/dist/agents/skills/claude-code/harness-git-workflow/skill.yaml +1 -0
  51. package/dist/agents/skills/claude-code/harness-hotspot-detector/skill.yaml +1 -0
  52. package/dist/agents/skills/claude-code/harness-i18n/skill.yaml +1 -0
  53. package/dist/agents/skills/claude-code/harness-i18n-process/skill.yaml +1 -0
  54. package/dist/agents/skills/claude-code/harness-i18n-workflow/skill.yaml +1 -0
  55. package/dist/agents/skills/claude-code/harness-impact-analysis/skill.yaml +1 -0
  56. package/dist/agents/skills/claude-code/harness-incident-response/SKILL.md +223 -0
  57. package/dist/agents/skills/claude-code/harness-incident-response/skill.yaml +78 -0
  58. package/dist/agents/skills/claude-code/harness-infrastructure-as-code/SKILL.md +279 -0
  59. package/dist/agents/skills/claude-code/harness-infrastructure-as-code/skill.yaml +80 -0
  60. package/dist/agents/skills/claude-code/harness-integration-test/SKILL.md +271 -0
  61. package/dist/agents/skills/claude-code/harness-integration-test/skill.yaml +73 -0
  62. package/dist/agents/skills/claude-code/harness-integrity/skill.yaml +1 -0
  63. package/dist/agents/skills/claude-code/harness-knowledge-mapper/skill.yaml +1 -0
  64. package/dist/agents/skills/claude-code/harness-load-testing/SKILL.md +274 -0
  65. package/dist/agents/skills/claude-code/harness-load-testing/skill.yaml +79 -0
  66. package/dist/agents/skills/claude-code/harness-ml-ops/SKILL.md +341 -0
  67. package/dist/agents/skills/claude-code/harness-ml-ops/skill.yaml +79 -0
  68. package/dist/agents/skills/claude-code/harness-mobile-patterns/SKILL.md +326 -0
  69. package/dist/agents/skills/claude-code/harness-mobile-patterns/skill.yaml +82 -0
  70. package/dist/agents/skills/claude-code/harness-mutation-test/SKILL.md +251 -0
  71. package/dist/agents/skills/claude-code/harness-mutation-test/skill.yaml +70 -0
  72. package/dist/agents/skills/claude-code/harness-observability/SKILL.md +283 -0
  73. package/dist/agents/skills/claude-code/harness-observability/skill.yaml +78 -0
  74. package/dist/agents/skills/claude-code/harness-onboarding/skill.yaml +1 -0
  75. package/dist/agents/skills/claude-code/harness-parallel-agents/skill.yaml +1 -0
  76. package/dist/agents/skills/claude-code/harness-perf/skill.yaml +1 -0
  77. package/dist/agents/skills/claude-code/harness-perf-tdd/skill.yaml +1 -0
  78. package/dist/agents/skills/claude-code/harness-planning/skill.yaml +1 -0
  79. package/dist/agents/skills/claude-code/harness-pre-commit-review/skill.yaml +1 -0
  80. package/dist/agents/skills/claude-code/harness-product-spec/SKILL.md +285 -0
  81. package/dist/agents/skills/claude-code/harness-product-spec/skill.yaml +72 -0
  82. package/dist/agents/skills/claude-code/harness-property-test/SKILL.md +281 -0
  83. package/dist/agents/skills/claude-code/harness-property-test/skill.yaml +71 -0
  84. package/dist/agents/skills/claude-code/harness-refactoring/skill.yaml +1 -0
  85. package/dist/agents/skills/claude-code/harness-release-readiness/skill.yaml +1 -0
  86. package/dist/agents/skills/claude-code/harness-resilience/SKILL.md +255 -0
  87. package/dist/agents/skills/claude-code/harness-resilience/skill.yaml +76 -0
  88. package/dist/agents/skills/claude-code/harness-roadmap/skill.yaml +1 -0
  89. package/dist/agents/skills/claude-code/harness-secrets/SKILL.md +293 -0
  90. package/dist/agents/skills/claude-code/harness-secrets/skill.yaml +76 -0
  91. package/dist/agents/skills/claude-code/harness-security-review/skill.yaml +1 -0
  92. package/dist/agents/skills/claude-code/harness-security-scan/skill.yaml +1 -0
  93. package/dist/agents/skills/claude-code/harness-skill-authoring/skill.yaml +1 -0
  94. package/dist/agents/skills/claude-code/harness-soundness-review/skill.yaml +1 -0
  95. package/dist/agents/skills/claude-code/harness-sql-review/SKILL.md +315 -0
  96. package/dist/agents/skills/claude-code/harness-sql-review/skill.yaml +74 -0
  97. package/dist/agents/skills/claude-code/harness-state-management/skill.yaml +1 -0
  98. package/dist/agents/skills/claude-code/harness-tdd/skill.yaml +1 -0
  99. package/dist/agents/skills/claude-code/harness-test-advisor/skill.yaml +1 -0
  100. package/dist/agents/skills/claude-code/harness-test-data/SKILL.md +268 -0
  101. package/dist/agents/skills/claude-code/harness-test-data/skill.yaml +74 -0
  102. package/dist/agents/skills/claude-code/harness-ux-copy/SKILL.md +271 -0
  103. package/dist/agents/skills/claude-code/harness-ux-copy/skill.yaml +77 -0
  104. package/dist/agents/skills/claude-code/harness-verification/skill.yaml +1 -0
  105. package/dist/agents/skills/claude-code/harness-verify/skill.yaml +1 -0
  106. package/dist/agents/skills/claude-code/harness-visual-regression/SKILL.md +257 -0
  107. package/dist/agents/skills/claude-code/harness-visual-regression/skill.yaml +74 -0
  108. package/dist/agents/skills/claude-code/initialize-harness-project/skill.yaml +1 -0
  109. package/dist/agents/skills/claude-code/validate-context-engineering/skill.yaml +1 -0
  110. package/dist/agents/skills/gemini-cli/add-harness-component/skill.yaml +1 -0
  111. package/dist/agents/skills/gemini-cli/align-documentation/skill.yaml +1 -0
  112. package/dist/agents/skills/gemini-cli/check-mechanical-constraints/skill.yaml +1 -0
  113. package/dist/agents/skills/gemini-cli/cleanup-dead-code/skill.yaml +1 -0
  114. package/dist/agents/skills/gemini-cli/detect-doc-drift/skill.yaml +1 -0
  115. package/dist/agents/skills/gemini-cli/enforce-architecture/skill.yaml +1 -0
  116. package/dist/agents/skills/gemini-cli/harness-accessibility/skill.yaml +1 -0
  117. package/dist/agents/skills/gemini-cli/harness-api-design/SKILL.md +304 -0
  118. package/dist/agents/skills/gemini-cli/harness-api-design/skill.yaml +74 -0
  119. package/dist/agents/skills/gemini-cli/harness-architecture-advisor/skill.yaml +1 -0
  120. package/dist/agents/skills/gemini-cli/harness-auth/SKILL.md +279 -0
  121. package/dist/agents/skills/gemini-cli/harness-auth/skill.yaml +81 -0
  122. package/dist/agents/skills/gemini-cli/harness-autopilot/skill.yaml +1 -0
  123. package/dist/agents/skills/gemini-cli/harness-brainstorming/skill.yaml +1 -0
  124. package/dist/agents/skills/gemini-cli/harness-caching/SKILL.md +309 -0
  125. package/dist/agents/skills/gemini-cli/harness-caching/skill.yaml +73 -0
  126. package/dist/agents/skills/gemini-cli/harness-chaos/SKILL.md +295 -0
  127. package/dist/agents/skills/gemini-cli/harness-chaos/skill.yaml +72 -0
  128. package/dist/agents/skills/gemini-cli/harness-code-review/skill.yaml +1 -0
  129. package/dist/agents/skills/gemini-cli/harness-codebase-cleanup/skill.yaml +1 -0
  130. package/dist/agents/skills/gemini-cli/harness-compliance/SKILL.md +303 -0
  131. package/dist/agents/skills/gemini-cli/harness-compliance/skill.yaml +78 -0
  132. package/dist/agents/skills/gemini-cli/harness-containerization/SKILL.md +284 -0
  133. package/dist/agents/skills/gemini-cli/harness-containerization/skill.yaml +80 -0
  134. package/dist/agents/skills/gemini-cli/harness-data-pipeline/SKILL.md +274 -0
  135. package/dist/agents/skills/gemini-cli/harness-data-pipeline/skill.yaml +81 -0
  136. package/dist/agents/skills/gemini-cli/harness-data-validation/SKILL.md +343 -0
  137. package/dist/agents/skills/gemini-cli/harness-data-validation/skill.yaml +75 -0
  138. package/dist/agents/skills/gemini-cli/harness-database/SKILL.md +258 -0
  139. package/dist/agents/skills/gemini-cli/harness-database/skill.yaml +80 -0
  140. package/dist/agents/skills/gemini-cli/harness-debugging/skill.yaml +1 -0
  141. package/dist/agents/skills/gemini-cli/harness-dependency-health/skill.yaml +1 -0
  142. package/dist/agents/skills/gemini-cli/harness-deployment/SKILL.md +255 -0
  143. package/dist/agents/skills/gemini-cli/harness-deployment/skill.yaml +77 -0
  144. package/dist/agents/skills/gemini-cli/harness-design/skill.yaml +1 -0
  145. package/dist/agents/skills/gemini-cli/harness-design-mobile/skill.yaml +1 -0
  146. package/dist/agents/skills/gemini-cli/harness-design-system/skill.yaml +1 -0
  147. package/dist/agents/skills/gemini-cli/harness-design-web/skill.yaml +1 -0
  148. package/dist/agents/skills/gemini-cli/harness-diagnostics/skill.yaml +1 -0
  149. package/dist/agents/skills/gemini-cli/harness-docs-pipeline/skill.yaml +1 -0
  150. package/dist/agents/skills/gemini-cli/harness-dx/SKILL.md +276 -0
  151. package/dist/agents/skills/gemini-cli/harness-dx/skill.yaml +76 -0
  152. package/dist/agents/skills/gemini-cli/harness-e2e/SKILL.md +245 -0
  153. package/dist/agents/skills/gemini-cli/harness-e2e/skill.yaml +78 -0
  154. package/dist/agents/skills/gemini-cli/harness-event-driven/SKILL.md +280 -0
  155. package/dist/agents/skills/gemini-cli/harness-event-driven/skill.yaml +77 -0
  156. package/dist/agents/skills/gemini-cli/harness-execution/skill.yaml +1 -0
  157. package/dist/agents/skills/gemini-cli/harness-feature-flags/SKILL.md +287 -0
  158. package/dist/agents/skills/gemini-cli/harness-feature-flags/skill.yaml +74 -0
  159. package/dist/agents/skills/gemini-cli/harness-git-workflow/skill.yaml +1 -0
  160. package/dist/agents/skills/gemini-cli/harness-hotspot-detector/skill.yaml +1 -0
  161. package/dist/agents/skills/gemini-cli/harness-i18n/skill.yaml +1 -0
  162. package/dist/agents/skills/gemini-cli/harness-i18n-process/skill.yaml +1 -0
  163. package/dist/agents/skills/gemini-cli/harness-i18n-workflow/skill.yaml +1 -0
  164. package/dist/agents/skills/gemini-cli/harness-impact-analysis/skill.yaml +1 -0
  165. package/dist/agents/skills/gemini-cli/harness-incident-response/SKILL.md +223 -0
  166. package/dist/agents/skills/gemini-cli/harness-incident-response/skill.yaml +78 -0
  167. package/dist/agents/skills/gemini-cli/harness-infrastructure-as-code/SKILL.md +279 -0
  168. package/dist/agents/skills/gemini-cli/harness-infrastructure-as-code/skill.yaml +80 -0
  169. package/dist/agents/skills/gemini-cli/harness-integration-test/SKILL.md +271 -0
  170. package/dist/agents/skills/gemini-cli/harness-integration-test/skill.yaml +73 -0
  171. package/dist/agents/skills/gemini-cli/harness-integrity/skill.yaml +1 -0
  172. package/dist/agents/skills/gemini-cli/harness-knowledge-mapper/skill.yaml +1 -0
  173. package/dist/agents/skills/gemini-cli/harness-load-testing/SKILL.md +274 -0
  174. package/dist/agents/skills/gemini-cli/harness-load-testing/skill.yaml +79 -0
  175. package/dist/agents/skills/gemini-cli/harness-ml-ops/SKILL.md +341 -0
  176. package/dist/agents/skills/gemini-cli/harness-ml-ops/skill.yaml +79 -0
  177. package/dist/agents/skills/gemini-cli/harness-mobile-patterns/SKILL.md +326 -0
  178. package/dist/agents/skills/gemini-cli/harness-mobile-patterns/skill.yaml +82 -0
  179. package/dist/agents/skills/gemini-cli/harness-mutation-test/SKILL.md +251 -0
  180. package/dist/agents/skills/gemini-cli/harness-mutation-test/skill.yaml +70 -0
  181. package/dist/agents/skills/gemini-cli/harness-observability/SKILL.md +283 -0
  182. package/dist/agents/skills/gemini-cli/harness-observability/skill.yaml +78 -0
  183. package/dist/agents/skills/gemini-cli/harness-onboarding/skill.yaml +1 -0
  184. package/dist/agents/skills/gemini-cli/harness-parallel-agents/skill.yaml +1 -0
  185. package/dist/agents/skills/gemini-cli/harness-perf/skill.yaml +1 -0
  186. package/dist/agents/skills/gemini-cli/harness-perf-tdd/skill.yaml +1 -0
  187. package/dist/agents/skills/gemini-cli/harness-planning/skill.yaml +1 -0
  188. package/dist/agents/skills/gemini-cli/harness-pre-commit-review/skill.yaml +1 -0
  189. package/dist/agents/skills/gemini-cli/harness-product-spec/SKILL.md +285 -0
  190. package/dist/agents/skills/gemini-cli/harness-product-spec/skill.yaml +72 -0
  191. package/dist/agents/skills/gemini-cli/harness-property-test/SKILL.md +281 -0
  192. package/dist/agents/skills/gemini-cli/harness-property-test/skill.yaml +71 -0
  193. package/dist/agents/skills/gemini-cli/harness-refactoring/skill.yaml +1 -0
  194. package/dist/agents/skills/gemini-cli/harness-release-readiness/skill.yaml +1 -0
  195. package/dist/agents/skills/gemini-cli/harness-resilience/SKILL.md +255 -0
  196. package/dist/agents/skills/gemini-cli/harness-resilience/skill.yaml +76 -0
  197. package/dist/agents/skills/gemini-cli/harness-roadmap/skill.yaml +1 -0
  198. package/dist/agents/skills/gemini-cli/harness-secrets/SKILL.md +293 -0
  199. package/dist/agents/skills/gemini-cli/harness-secrets/skill.yaml +76 -0
  200. package/dist/agents/skills/gemini-cli/harness-security-review/SKILL.md +240 -0
  201. package/dist/agents/skills/gemini-cli/harness-security-review/skill.yaml +1 -0
  202. package/dist/agents/skills/gemini-cli/harness-security-scan/skill.yaml +1 -0
  203. package/dist/agents/skills/gemini-cli/harness-skill-authoring/skill.yaml +1 -0
  204. package/dist/agents/skills/gemini-cli/harness-soundness-review/skill.yaml +1 -0
  205. package/dist/agents/skills/gemini-cli/harness-sql-review/SKILL.md +315 -0
  206. package/dist/agents/skills/gemini-cli/harness-sql-review/skill.yaml +74 -0
  207. package/dist/agents/skills/gemini-cli/harness-state-management/skill.yaml +1 -0
  208. package/dist/agents/skills/gemini-cli/harness-tdd/skill.yaml +1 -0
  209. package/dist/agents/skills/gemini-cli/harness-test-advisor/skill.yaml +1 -0
  210. package/dist/agents/skills/gemini-cli/harness-test-data/SKILL.md +268 -0
  211. package/dist/agents/skills/gemini-cli/harness-test-data/skill.yaml +74 -0
  212. package/dist/agents/skills/gemini-cli/harness-ux-copy/SKILL.md +271 -0
  213. package/dist/agents/skills/gemini-cli/harness-ux-copy/skill.yaml +77 -0
  214. package/dist/agents/skills/gemini-cli/harness-verification/skill.yaml +1 -0
  215. package/dist/agents/skills/gemini-cli/harness-verify/skill.yaml +1 -0
  216. package/dist/agents/skills/gemini-cli/harness-visual-regression/SKILL.md +257 -0
  217. package/dist/agents/skills/gemini-cli/harness-visual-regression/skill.yaml +74 -0
  218. package/dist/agents/skills/gemini-cli/initialize-harness-project/skill.yaml +1 -0
  219. package/dist/agents/skills/gemini-cli/validate-context-engineering/skill.yaml +1 -0
  220. package/dist/{agents-md-P2RHSUV7.js → agents-md-XU3BHE22.js} +1 -1
  221. package/dist/{architecture-ESOOE26S.js → architecture-2R5Z4ZAF.js} +2 -2
  222. package/dist/bin/harness-mcp.js +14 -13
  223. package/dist/bin/harness.js +22 -21
  224. package/dist/{check-phase-gate-S2MZKLFQ.js → check-phase-gate-2OFZ7OWW.js} +3 -2
  225. package/dist/{chunk-LD3DKUK5.js → chunk-4ZMOCPYO.js} +1 -1
  226. package/dist/{chunk-5VY23YK3.js → chunk-65FRIL4D.js} +2 -2
  227. package/dist/{chunk-L2KLU56K.js → chunk-AOZRDOIP.js} +2 -2
  228. package/dist/{chunk-MACVXDZK.js → chunk-DZS7CJKL.js} +4 -4
  229. package/dist/{chunk-7PZWR4LI.js → chunk-IM32EEDM.js} +9 -9
  230. package/dist/{chunk-2YPZKGAG.js → chunk-IMFVFNJE.js} +1 -1
  231. package/dist/{chunk-HD4IBGLA.js → chunk-N5G5QMS3.js} +24 -1
  232. package/dist/{chunk-MI5XJQDY.js → chunk-ND6PNADU.js} +23 -9
  233. package/dist/{chunk-7KQSUZVG.js → chunk-NERR4TAO.js} +729 -436
  234. package/dist/{chunk-PSNN4LWX.js → chunk-NOPU4RZ4.js} +2 -2
  235. package/dist/{chunk-KELT6K6M.js → chunk-PQ5YK4AY.js} +287 -258
  236. package/dist/{chunk-WPPDRIJL.js → chunk-QY4T6YAZ.js} +3 -3
  237. package/dist/{chunk-RZSUJBZZ.js → chunk-SSKDAOX5.js} +31 -28
  238. package/dist/{chunk-2VU4MFM3.js → chunk-TKJZKICB.js} +6 -6
  239. package/dist/{chunk-GNGELAXY.js → chunk-TS3XWPW5.js} +1 -1
  240. package/dist/chunk-UAX4I5ZE.js +217 -0
  241. package/dist/{chunk-VRFZWGMS.js → chunk-XYLGHKG6.js} +5 -1
  242. package/dist/{chunk-6N4R6FVX.js → chunk-YBJ262QL.js} +1 -1
  243. package/dist/{chunk-3KOLLWWE.js → chunk-Z77YQRQT.js} +11 -207
  244. package/dist/{ci-workflow-4NYBUG6R.js → ci-workflow-EHV65NQB.js} +1 -1
  245. package/dist/{create-skill-WPXHSLX2.js → create-skill-XSWHMSM5.js} +2 -2
  246. package/dist/{dist-WF4C7A4A.js → dist-2B363XUH.js} +1 -1
  247. package/dist/{dist-M6BQODWC.js → dist-HXHWB7SV.js} +2 -2
  248. package/dist/{docs-BPYCN2DR.js → docs-FZOPM4GK.js} +4 -2
  249. package/dist/{engine-LXLIWQQ3.js → engine-OL4T6NZS.js} +1 -1
  250. package/dist/{entropy-4VDVV5CR.js → entropy-LVHJMFGH.js} +2 -2
  251. package/dist/{feedback-63QB5RCA.js → feedback-IHLVLMRD.js} +1 -1
  252. package/dist/{generate-agent-definitions-QABOJG56.js → generate-agent-definitions-64S3CLEZ.js} +3 -3
  253. package/dist/{glob-helper-5OHBUQAI.js → glob-helper-R5FXNUPS.js} +1 -1
  254. package/dist/{graph-loader-KO4GJ5N2.js → graph-loader-GJZ4FN4Y.js} +1 -1
  255. package/dist/index.d.ts +35 -8
  256. package/dist/index.js +23 -21
  257. package/dist/{loader-Z2IT7QX3.js → loader-DPYFB6R6.js} +1 -1
  258. package/dist/{mcp-KQHEL5IF.js → mcp-JQUI7BVZ.js} +14 -13
  259. package/dist/{performance-26BH47O4.js → performance-ZTVSUANN.js} +2 -2
  260. package/dist/{review-pipeline-GHR3WFBI.js → review-pipeline-76JHKGSV.js} +1 -1
  261. package/dist/{runtime-PDWD7UIK.js → runtime-X7U6SC7K.js} +1 -1
  262. package/dist/{security-UQFUZXEN.js → security-FWQZF2IZ.js} +1 -1
  263. package/dist/skill-executor-XZLYZYAK.js +8 -0
  264. package/dist/{validate-N7QJOKFZ.js → validate-GCHZJIL7.js} +2 -2
  265. package/dist/{validate-cross-check-EDQ5QGTM.js → validate-cross-check-STFHYMAZ.js} +1 -1
  266. package/package.json +3 -3
  267. package/dist/skill-executor-RG45LUO5.js +0 -8
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  detectEntropyDefinition,
3
3
  handleDetectEntropy
4
- } from "./chunk-MACVXDZK.js";
4
+ } from "./chunk-DZS7CJKL.js";
5
5
  import {
6
6
  checkPerformanceDefinition,
7
7
  getCriticalPathsDefinition,
@@ -11,7 +11,7 @@ import {
11
11
  handleGetPerfBaselines,
12
12
  handleUpdatePerfBaselines,
13
13
  updatePerfBaselinesDefinition
14
- } from "./chunk-2VU4MFM3.js";
14
+ } from "./chunk-TKJZKICB.js";
15
15
  import {
16
16
  analyzeDiffDefinition,
17
17
  createSelfReviewDefinition,
@@ -19,15 +19,15 @@ import {
19
19
  handleCreateSelfReview,
20
20
  handleRequestPeerReview,
21
21
  requestPeerReviewDefinition
22
- } from "./chunk-7PZWR4LI.js";
22
+ } from "./chunk-IM32EEDM.js";
23
23
  import {
24
24
  handleRunSecurityScan,
25
25
  runSecurityScanDefinition
26
- } from "./chunk-5VY23YK3.js";
26
+ } from "./chunk-65FRIL4D.js";
27
27
  import {
28
28
  handleRunCodeReview,
29
29
  runCodeReviewDefinition
30
- } from "./chunk-LD3DKUK5.js";
30
+ } from "./chunk-4ZMOCPYO.js";
31
31
  import {
32
32
  GENERATED_HEADER_CLAUDE,
33
33
  GENERATED_HEADER_GEMINI,
@@ -38,21 +38,24 @@ import {
38
38
  import {
39
39
  handleValidateProject,
40
40
  validateToolDefinition
41
- } from "./chunk-PSNN4LWX.js";
41
+ } from "./chunk-NOPU4RZ4.js";
42
42
  import {
43
43
  loadGraphStore
44
- } from "./chunk-2YPZKGAG.js";
44
+ } from "./chunk-IMFVFNJE.js";
45
45
  import {
46
46
  checkDependenciesDefinition,
47
47
  handleCheckDependencies
48
- } from "./chunk-WPPDRIJL.js";
48
+ } from "./chunk-QY4T6YAZ.js";
49
49
  import {
50
50
  resolveProjectConfig
51
51
  } from "./chunk-K6XAPGML.js";
52
52
  import {
53
53
  checkDocsDefinition,
54
54
  handleCheckDocs
55
- } from "./chunk-MI5XJQDY.js";
55
+ } from "./chunk-ND6PNADU.js";
56
+ import {
57
+ resolveConfig
58
+ } from "./chunk-Z77YQRQT.js";
56
59
  import {
57
60
  resultToMcpResponse
58
61
  } from "./chunk-IDZNPTYD.js";
@@ -60,13 +63,14 @@ import {
60
63
  sanitizePath
61
64
  } from "./chunk-W6Y7ZW3Y.js";
62
65
  import {
66
+ resolveAllSkillsDirs,
63
67
  resolveCommunitySkillsDir,
64
68
  resolveGlobalSkillsDir,
65
69
  resolvePersonasDir,
66
70
  resolveProjectSkillsDir,
67
71
  resolveSkillsDir,
68
72
  resolveTemplatesDir
69
- } from "./chunk-HD4IBGLA.js";
73
+ } from "./chunk-N5G5QMS3.js";
70
74
  import {
71
75
  CLIError,
72
76
  ExitCode,
@@ -74,7 +78,7 @@ import {
74
78
  } from "./chunk-3WGJMBKH.js";
75
79
  import {
76
80
  SkillMetadataSchema
77
- } from "./chunk-VRFZWGMS.js";
81
+ } from "./chunk-XYLGHKG6.js";
78
82
  import {
79
83
  Err,
80
84
  Ok
@@ -180,7 +184,7 @@ var initProjectDefinition = {
180
184
  };
181
185
  async function handleInitProject(input) {
182
186
  try {
183
- const { TemplateEngine } = await import("./engine-LXLIWQQ3.js");
187
+ const { TemplateEngine } = await import("./engine-OL4T6NZS.js");
184
188
  const templatesDir = resolveTemplatesDir();
185
189
  const engine = new TemplateEngine(templatesDir);
186
190
  const level = input.level ?? "basic";
@@ -218,7 +222,7 @@ var listPersonasDefinition = {
218
222
  inputSchema: { type: "object", properties: {} }
219
223
  };
220
224
  async function handleListPersonas() {
221
- const { listPersonas } = await import("./loader-Z2IT7QX3.js");
225
+ const { listPersonas } = await import("./loader-DPYFB6R6.js");
222
226
  const result = listPersonas(resolvePersonasDir());
223
227
  return resultToMcpResponse(result);
224
228
  }
@@ -242,10 +246,10 @@ async function handleGeneratePersonaArtifacts(input) {
242
246
  if (!/^[a-z0-9][a-z0-9._-]*$/i.test(input.name)) {
243
247
  return resultToMcpResponse(Err(new Error(`Invalid persona name: ${input.name}`)));
244
248
  }
245
- const { loadPersona } = await import("./loader-Z2IT7QX3.js");
246
- const { generateRuntime } = await import("./runtime-PDWD7UIK.js");
247
- const { generateAgentsMd } = await import("./agents-md-P2RHSUV7.js");
248
- const { generateCIWorkflow } = await import("./ci-workflow-4NYBUG6R.js");
249
+ const { loadPersona } = await import("./loader-DPYFB6R6.js");
250
+ const { generateRuntime } = await import("./runtime-X7U6SC7K.js");
251
+ const { generateAgentsMd } = await import("./agents-md-XU3BHE22.js");
252
+ const { generateCIWorkflow } = await import("./ci-workflow-EHV65NQB.js");
249
253
  const personasDir = resolvePersonasDir();
250
254
  const filePath = path2.join(personasDir, `${input.name}.yaml`);
251
255
  if (!filePath.startsWith(personasDir)) {
@@ -300,9 +304,9 @@ async function handleRunPersona(input) {
300
304
  if (!/^[a-z0-9][a-z0-9._-]*$/i.test(input.persona)) {
301
305
  return resultToMcpResponse(Err(new Error(`Invalid persona name: ${input.persona}`)));
302
306
  }
303
- const { loadPersona } = await import("./loader-Z2IT7QX3.js");
307
+ const { loadPersona } = await import("./loader-DPYFB6R6.js");
304
308
  const { runPersona } = await import("./runner-VMYLHWOC.js");
305
- const { executeSkill } = await import("./skill-executor-RG45LUO5.js");
309
+ const { executeSkill } = await import("./skill-executor-XZLYZYAK.js");
306
310
  const personasDir = resolvePersonasDir();
307
311
  const filePath = path2.join(personasDir, `${input.persona}.yaml`);
308
312
  if (!filePath.startsWith(personasDir)) {
@@ -466,8 +470,243 @@ async function handleRunAgentTask(input) {
466
470
  }
467
471
 
468
472
  // src/mcp/tools/skill.ts
469
- import * as fs from "fs";
470
- import * as path3 from "path";
473
+ import * as fs3 from "fs";
474
+ import * as path5 from "path";
475
+
476
+ // src/skill/dispatcher.ts
477
+ var TIER_1_SKILLS = /* @__PURE__ */ new Set([
478
+ "harness-brainstorming",
479
+ "harness-planning",
480
+ "harness-execution",
481
+ "harness-autopilot",
482
+ "harness-tdd",
483
+ "harness-debugging",
484
+ "harness-refactoring"
485
+ ]);
486
+ function isTier1Skill(skillName) {
487
+ return TIER_1_SKILLS.has(skillName);
488
+ }
489
+ function scoreSkill(entry, queryTerms, profile, recentFiles) {
490
+ const matchedKeywords = entry.keywords.filter(
491
+ (kw) => queryTerms.some(
492
+ (term) => kw.toLowerCase().includes(term.toLowerCase()) || term.toLowerCase().includes(kw.toLowerCase())
493
+ )
494
+ );
495
+ const keywordScore = queryTerms.length > 0 ? matchedKeywords.length / queryTerms.length : 0;
496
+ let stackScore = 0;
497
+ if (profile && entry.stackSignals.length > 0) {
498
+ const matchedSignals = entry.stackSignals.filter((signal) => {
499
+ if (profile.signals[signal]) return true;
500
+ return profile.detectedDomains.some(
501
+ (domain) => entry.keywords.some((kw) => kw.toLowerCase() === domain.toLowerCase())
502
+ );
503
+ });
504
+ stackScore = matchedSignals.length / entry.stackSignals.length;
505
+ }
506
+ let recencyBoost = 0;
507
+ if (recentFiles.length > 0) {
508
+ const hasRecentMatch = entry.stackSignals.some((signal) => {
509
+ const cleanSignal = signal.replace(/\*/g, "").replace(/\*\*/g, "");
510
+ return recentFiles.some((f) => f.includes(cleanSignal));
511
+ });
512
+ recencyBoost = hasRecentMatch ? 1 : 0;
513
+ }
514
+ return 0.5 * keywordScore + 0.3 * stackScore + 0.2 * recencyBoost;
515
+ }
516
+ function suggest(index, taskDescription, profile, recentFiles, config) {
517
+ const queryTerms = taskDescription.toLowerCase().split(/\s+/).filter((t) => t.length > 2);
518
+ const scored = [];
519
+ for (const [name, entry] of Object.entries(index.skills)) {
520
+ if (config?.neverSuggest?.includes(name)) continue;
521
+ const score = scoreSkill(entry, queryTerms, profile, recentFiles);
522
+ const isForced = config?.alwaysSuggest?.includes(name);
523
+ if (score >= 0.4 || isForced) {
524
+ scored.push({
525
+ name,
526
+ description: entry.description,
527
+ score: isForced ? Math.max(score, 1) : score
528
+ });
529
+ }
530
+ }
531
+ return scored.sort((a, b) => b.score - a.score).slice(0, 3);
532
+ }
533
+ function formatSuggestions(suggestions) {
534
+ if (suggestions.length === 0) return "";
535
+ const lines = suggestions.map((s) => `- **${s.name}** \u2014 ${s.description}`);
536
+ return [
537
+ "",
538
+ "---",
539
+ "## Suggested Domain Skills",
540
+ "Based on your task and project stack, these catalog skills may be relevant:",
541
+ ...lines,
542
+ "",
543
+ 'To load a skill: call search_skills("<skill-name>") for full details.',
544
+ "---"
545
+ ].join("\n");
546
+ }
547
+
548
+ // src/skill/index-builder.ts
549
+ import fs from "fs";
550
+ import path3 from "path";
551
+ import crypto from "crypto";
552
+ import { parse } from "yaml";
553
+ function computeSkillsDirHash(skillsDirs) {
554
+ const hash = crypto.createHash("sha256");
555
+ for (const dir of skillsDirs) {
556
+ if (!fs.existsSync(dir)) continue;
557
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
558
+ if (!entry.isDirectory()) continue;
559
+ const yamlPath = path3.join(dir, entry.name, "skill.yaml");
560
+ if (!fs.existsSync(yamlPath)) continue;
561
+ const stat = fs.statSync(yamlPath);
562
+ hash.update(`${yamlPath}:${stat.mtimeMs}`);
563
+ }
564
+ }
565
+ return hash.digest("hex");
566
+ }
567
+ function parseSkillEntry(yamlPath, source, tierOverrides) {
568
+ const raw = fs.readFileSync(yamlPath, "utf-8");
569
+ const parsed = parse(raw);
570
+ const result = SkillMetadataSchema.safeParse(parsed);
571
+ if (!result.success) return null;
572
+ const meta = result.data;
573
+ const effectiveTier = tierOverrides?.[meta.name] ?? meta.tier;
574
+ if (meta.internal) return null;
575
+ if (effectiveTier !== 3 && source !== "community") return null;
576
+ return {
577
+ tier: effectiveTier ?? 3,
578
+ description: meta.description,
579
+ keywords: meta.keywords ?? [],
580
+ stackSignals: meta.stack_signals ?? [],
581
+ cognitiveMode: meta.cognitive_mode,
582
+ phases: (meta.phases ?? []).map((p) => p.name),
583
+ source
584
+ };
585
+ }
586
+ function scanDirectory(dir, source, index, tierOverrides) {
587
+ if (!fs.existsSync(dir)) return;
588
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
589
+ if (!entry.isDirectory()) continue;
590
+ if (index.skills[entry.name]) continue;
591
+ const yamlPath = path3.join(dir, entry.name, "skill.yaml");
592
+ if (!fs.existsSync(yamlPath)) continue;
593
+ try {
594
+ const parsed = parseSkillEntry(yamlPath, source, tierOverrides);
595
+ if (parsed) index.skills[entry.name] = parsed;
596
+ } catch {
597
+ continue;
598
+ }
599
+ }
600
+ }
601
+ function buildIndex(platform, _projectRoot, tierOverrides) {
602
+ const skillsDirs = resolveAllSkillsDirs(platform);
603
+ const sourceMap = ["project", "community", "bundled"];
604
+ const index = {
605
+ version: 1,
606
+ hash: computeSkillsDirHash(skillsDirs),
607
+ generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
608
+ skills: {}
609
+ };
610
+ for (let i = 0; i < skillsDirs.length; i++) {
611
+ scanDirectory(skillsDirs[i], sourceMap[i] ?? "bundled", index, tierOverrides);
612
+ }
613
+ return index;
614
+ }
615
+ function loadOrRebuildIndex(platform, projectRoot, tierOverrides) {
616
+ const indexPath = path3.join(projectRoot, ".harness", "skills-index.json");
617
+ const skillsDirs = resolveAllSkillsDirs(platform);
618
+ const currentHash = computeSkillsDirHash(skillsDirs);
619
+ if (fs.existsSync(indexPath)) {
620
+ try {
621
+ const existing = JSON.parse(fs.readFileSync(indexPath, "utf-8"));
622
+ if (existing.hash === currentHash) return existing;
623
+ } catch {
624
+ }
625
+ }
626
+ const index = buildIndex(platform, projectRoot, tierOverrides);
627
+ fs.mkdirSync(path3.dirname(indexPath), { recursive: true });
628
+ fs.writeFileSync(indexPath, JSON.stringify(index, null, 2));
629
+ return index;
630
+ }
631
+
632
+ // src/skill/stack-profile.ts
633
+ import fs2 from "fs";
634
+ import path4 from "path";
635
+ var SIGNAL_DOMAIN_MAP = {
636
+ "prisma/schema.prisma": ["database"],
637
+ "drizzle.config.ts": ["database"],
638
+ "knexfile.js": ["database"],
639
+ "knexfile.ts": ["database"],
640
+ migrations: ["database"],
641
+ Dockerfile: ["containerization"],
642
+ "docker-compose.yml": ["containerization"],
643
+ "docker-compose.yaml": ["containerization"],
644
+ k8s: ["containerization"],
645
+ kubernetes: ["containerization"],
646
+ helm: ["containerization"],
647
+ ".github/workflows": ["deployment"],
648
+ ".gitlab-ci.yml": ["deployment"],
649
+ Jenkinsfile: ["deployment"],
650
+ terraform: ["infrastructure-as-code"],
651
+ "Pulumi.yaml": ["infrastructure-as-code"],
652
+ "cdk.json": ["infrastructure-as-code"],
653
+ "openapi.yaml": ["api-design"],
654
+ "openapi.json": ["api-design"],
655
+ "swagger.yaml": ["api-design"],
656
+ "swagger.json": ["api-design"],
657
+ "schema.graphql": ["api-design"],
658
+ ".env": ["secrets"],
659
+ ".env.example": ["secrets"],
660
+ "vault.hcl": ["secrets"],
661
+ e2e: ["e2e"],
662
+ cypress: ["e2e"],
663
+ "playwright.config.ts": ["e2e"],
664
+ "playwright.config.js": ["e2e"],
665
+ "stryker.conf.js": ["mutation-test"],
666
+ "stryker.conf.mjs": ["mutation-test"],
667
+ k6: ["load-testing"],
668
+ "artillery.yml": ["load-testing"],
669
+ "dbt_project.yml": ["data-pipeline"],
670
+ airflow: ["data-pipeline"],
671
+ ios: ["mobile-patterns"],
672
+ android: ["mobile-patterns"],
673
+ "pubspec.yaml": ["mobile-patterns"],
674
+ "App.tsx": ["mobile-patterns"],
675
+ runbooks: ["incident-response"],
676
+ "docs/runbooks": ["incident-response"]
677
+ };
678
+ function generateStackProfile(projectRoot) {
679
+ const signals = {};
680
+ const domainSet = /* @__PURE__ */ new Set();
681
+ for (const [pattern, domains] of Object.entries(SIGNAL_DOMAIN_MAP)) {
682
+ const fullPath = path4.join(projectRoot, pattern);
683
+ const exists = fs2.existsSync(fullPath);
684
+ signals[pattern] = exists;
685
+ if (exists) {
686
+ for (const domain of domains) domainSet.add(domain);
687
+ }
688
+ }
689
+ return {
690
+ generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
691
+ signals,
692
+ detectedDomains: [...domainSet].sort()
693
+ };
694
+ }
695
+ function loadOrGenerateProfile(projectRoot) {
696
+ const profilePath = path4.join(projectRoot, ".harness", "stack-profile.json");
697
+ if (fs2.existsSync(profilePath)) {
698
+ try {
699
+ return JSON.parse(fs2.readFileSync(profilePath, "utf-8"));
700
+ } catch {
701
+ }
702
+ }
703
+ const profile = generateStackProfile(projectRoot);
704
+ fs2.mkdirSync(path4.dirname(profilePath), { recursive: true });
705
+ fs2.writeFileSync(profilePath, JSON.stringify(profile, null, 2));
706
+ return profile;
707
+ }
708
+
709
+ // src/mcp/tools/skill.ts
471
710
  var runSkillDefinition = {
472
711
  name: "run_skill",
473
712
  description: "Load and return the content of a skill (SKILL.md), optionally with project state context",
@@ -492,23 +731,23 @@ async function handleRunSkill(input) {
492
731
  if (!/^[a-z0-9][a-z0-9._-]*$/i.test(input.skill)) {
493
732
  return resultToMcpResponse(Err(new Error(`Invalid skill name: ${input.skill}`)));
494
733
  }
495
- const skillDir = path3.join(skillsDir, input.skill);
734
+ const skillDir = path5.join(skillsDir, input.skill);
496
735
  if (!skillDir.startsWith(skillsDir)) {
497
736
  return resultToMcpResponse(Err(new Error(`Invalid skill path: ${input.skill}`)));
498
737
  }
499
- if (!fs.existsSync(skillDir)) {
738
+ if (!fs3.existsSync(skillDir)) {
500
739
  return resultToMcpResponse(Err(new Error(`Skill not found: ${input.skill}`)));
501
740
  }
502
- const skillMdPath = path3.join(skillDir, "SKILL.md");
503
- if (!fs.existsSync(skillMdPath)) {
741
+ const skillMdPath = path5.join(skillDir, "SKILL.md");
742
+ if (!fs3.existsSync(skillMdPath)) {
504
743
  return resultToMcpResponse(Err(new Error(`SKILL.md not found for skill: ${input.skill}`)));
505
744
  }
506
- let content = fs.readFileSync(skillMdPath, "utf-8");
745
+ let content = fs3.readFileSync(skillMdPath, "utf-8");
507
746
  if (input.path) {
508
747
  const projectPath = sanitizePath(input.path);
509
- const stateFile = path3.join(projectPath, ".harness", "state.json");
510
- if (fs.existsSync(stateFile)) {
511
- const stateContent = fs.readFileSync(stateFile, "utf-8");
748
+ const stateFile = path5.join(projectPath, ".harness", "state.json");
749
+ if (fs3.existsSync(stateFile)) {
750
+ const stateContent = fs3.readFileSync(stateFile, "utf-8");
512
751
  content += `
513
752
 
514
753
  ---
@@ -519,6 +758,23 @@ ${stateContent}
519
758
  `;
520
759
  }
521
760
  }
761
+ if (isTier1Skill(input.skill)) {
762
+ try {
763
+ const projectRoot = input.path ? sanitizePath(input.path) : process.cwd();
764
+ const platform = "claude-code";
765
+ const configResult = resolveConfig();
766
+ const skillsConfig = configResult.ok ? configResult.value.skills : void 0;
767
+ const index = loadOrRebuildIndex(platform, projectRoot, skillsConfig?.tierOverrides);
768
+ const profile = loadOrGenerateProfile(projectRoot);
769
+ const taskDesc = [input.skill, input.phase].filter(Boolean).join(" ");
770
+ const suggestions = suggest(index, taskDesc, profile, [], skillsConfig);
771
+ const suggestionText = formatSuggestions(suggestions);
772
+ if (suggestionText) {
773
+ content += suggestionText;
774
+ }
775
+ } catch {
776
+ }
777
+ }
522
778
  return resultToMcpResponse(Ok(content));
523
779
  }
524
780
  var createSkillDefinition = {
@@ -548,7 +804,7 @@ var createSkillDefinition = {
548
804
  };
549
805
  async function handleCreateSkill(input) {
550
806
  try {
551
- const { generateSkillFiles } = await import("./create-skill-WPXHSLX2.js");
807
+ const { generateSkillFiles } = await import("./create-skill-XSWHMSM5.js");
552
808
  const result = generateSkillFiles({
553
809
  name: input.name,
554
810
  description: input.description,
@@ -570,22 +826,22 @@ async function handleCreateSkill(input) {
570
826
  }
571
827
 
572
828
  // src/mcp/resources/skills.ts
573
- import * as fs2 from "fs";
574
- import * as path4 from "path";
829
+ import * as fs4 from "fs";
830
+ import * as path6 from "path";
575
831
  import * as yaml from "yaml";
576
832
  async function getSkillsResource(projectRoot) {
577
- const skillsDir = path4.join(projectRoot, "agents", "skills", "claude-code");
833
+ const skillsDir = path6.join(projectRoot, "agents", "skills", "claude-code");
578
834
  const skills = [];
579
- if (!fs2.existsSync(skillsDir)) {
835
+ if (!fs4.existsSync(skillsDir)) {
580
836
  return JSON.stringify(skills, null, 2);
581
837
  }
582
- const entries = fs2.readdirSync(skillsDir, { withFileTypes: true });
838
+ const entries = fs4.readdirSync(skillsDir, { withFileTypes: true });
583
839
  for (const entry of entries) {
584
840
  if (!entry.isDirectory()) continue;
585
- const skillYamlPath = path4.join(skillsDir, entry.name, "skill.yaml");
586
- if (!fs2.existsSync(skillYamlPath)) continue;
841
+ const skillYamlPath = path6.join(skillsDir, entry.name, "skill.yaml");
842
+ if (!fs4.existsSync(skillYamlPath)) continue;
587
843
  try {
588
- const content = fs2.readFileSync(skillYamlPath, "utf-8");
844
+ const content = fs4.readFileSync(skillYamlPath, "utf-8");
589
845
  const parsed = yaml.parse(content);
590
846
  skills.push({
591
847
  name: parsed.name,
@@ -601,14 +857,14 @@ async function getSkillsResource(projectRoot) {
601
857
  }
602
858
 
603
859
  // src/mcp/resources/rules.ts
604
- import * as fs3 from "fs";
605
- import * as path5 from "path";
860
+ import * as fs5 from "fs";
861
+ import * as path7 from "path";
606
862
  async function getRulesResource(projectRoot) {
607
863
  const rules = [];
608
- const configPath = path5.join(projectRoot, "harness.config.json");
609
- if (fs3.existsSync(configPath)) {
864
+ const configPath = path7.join(projectRoot, "harness.config.json");
865
+ if (fs5.existsSync(configPath)) {
610
866
  try {
611
- const config = JSON.parse(fs3.readFileSync(configPath, "utf-8"));
867
+ const config = JSON.parse(fs5.readFileSync(configPath, "utf-8"));
612
868
  if (config.layers) {
613
869
  rules.push({ type: "layer-enforcement", config: config.layers });
614
870
  }
@@ -621,10 +877,10 @@ async function getRulesResource(projectRoot) {
621
877
  } catch {
622
878
  }
623
879
  }
624
- const linterPath = path5.join(projectRoot, ".harness", "linter.json");
625
- if (fs3.existsSync(linterPath)) {
880
+ const linterPath = path7.join(projectRoot, ".harness", "linter.json");
881
+ if (fs5.existsSync(linterPath)) {
626
882
  try {
627
- const linterConfig = JSON.parse(fs3.readFileSync(linterPath, "utf-8"));
883
+ const linterConfig = JSON.parse(fs5.readFileSync(linterPath, "utf-8"));
628
884
  rules.push({ type: "linter", config: linterConfig });
629
885
  } catch {
630
886
  }
@@ -633,28 +889,28 @@ async function getRulesResource(projectRoot) {
633
889
  }
634
890
 
635
891
  // src/mcp/resources/project.ts
636
- import * as fs4 from "fs";
637
- import * as path6 from "path";
892
+ import * as fs6 from "fs";
893
+ import * as path8 from "path";
638
894
  async function getProjectResource(projectRoot) {
639
- const agentsPath = path6.join(projectRoot, "AGENTS.md");
640
- if (fs4.existsSync(agentsPath)) {
641
- return fs4.readFileSync(agentsPath, "utf-8");
895
+ const agentsPath = path8.join(projectRoot, "AGENTS.md");
896
+ if (fs6.existsSync(agentsPath)) {
897
+ return fs6.readFileSync(agentsPath, "utf-8");
642
898
  }
643
899
  return "# No AGENTS.md found";
644
900
  }
645
901
 
646
902
  // src/mcp/resources/learnings.ts
647
- import * as fs5 from "fs";
648
- import * as path7 from "path";
903
+ import * as fs7 from "fs";
904
+ import * as path9 from "path";
649
905
  async function getLearningsResource(projectRoot) {
650
906
  const sections = [];
651
- const reviewPath = path7.join(projectRoot, ".harness", "review-learnings.md");
652
- if (fs5.existsSync(reviewPath)) {
653
- sections.push("## Review Learnings\n\n" + fs5.readFileSync(reviewPath, "utf-8"));
907
+ const reviewPath = path9.join(projectRoot, ".harness", "review-learnings.md");
908
+ if (fs7.existsSync(reviewPath)) {
909
+ sections.push("## Review Learnings\n\n" + fs7.readFileSync(reviewPath, "utf-8"));
654
910
  }
655
- const antiPath = path7.join(projectRoot, ".harness", "anti-patterns.md");
656
- if (fs5.existsSync(antiPath)) {
657
- sections.push("## Anti-Pattern Log\n\n" + fs5.readFileSync(antiPath, "utf-8"));
911
+ const antiPath = path9.join(projectRoot, ".harness", "anti-patterns.md");
912
+ if (fs7.existsSync(antiPath)) {
913
+ sections.push("## Anti-Pattern Log\n\n" + fs7.readFileSync(antiPath, "utf-8"));
658
914
  }
659
915
  return sections.length > 0 ? sections.join("\n\n---\n\n") : "No learnings files found.";
660
916
  }
@@ -709,7 +965,7 @@ async function handleManageState(input) {
709
965
  archiveFailures,
710
966
  runMechanicalGate,
711
967
  DEFAULT_STATE
712
- } = await import("./dist-WF4C7A4A.js");
968
+ } = await import("./dist-2B363XUH.js");
713
969
  const projectPath = sanitizePath(input.path);
714
970
  switch (input.action) {
715
971
  case "show": {
@@ -795,7 +1051,7 @@ async function handleManageState(input) {
795
1051
  isError: true
796
1052
  };
797
1053
  }
798
- const { saveHandoff } = await import("./dist-WF4C7A4A.js");
1054
+ const { saveHandoff } = await import("./dist-2B363XUH.js");
799
1055
  const result = await saveHandoff(
800
1056
  projectPath,
801
1057
  input.handoff,
@@ -805,7 +1061,7 @@ async function handleManageState(input) {
805
1061
  return resultToMcpResponse(result.ok ? Ok({ saved: true }) : result);
806
1062
  }
807
1063
  case "load-handoff": {
808
- const { loadHandoff } = await import("./dist-WF4C7A4A.js");
1064
+ const { loadHandoff } = await import("./dist-2B363XUH.js");
809
1065
  const result = await loadHandoff(projectPath, input.stream, input.session);
810
1066
  return resultToMcpResponse(result);
811
1067
  }
@@ -841,7 +1097,7 @@ var listStreamsDefinition = {
841
1097
  };
842
1098
  async function handleListStreams(input) {
843
1099
  try {
844
- const { listStreams, loadStreamIndex } = await import("./dist-WF4C7A4A.js");
1100
+ const { listStreams, loadStreamIndex } = await import("./dist-2B363XUH.js");
845
1101
  const projectPath = sanitizePath(input.path);
846
1102
  const indexResult = await loadStreamIndex(projectPath);
847
1103
  const streamsResult = await listStreams(projectPath);
@@ -879,7 +1135,7 @@ var checkPhaseGateDefinition = {
879
1135
  };
880
1136
  async function handleCheckPhaseGate(input) {
881
1137
  try {
882
- const { runCheckPhaseGate } = await import("./check-phase-gate-S2MZKLFQ.js");
1138
+ const { runCheckPhaseGate } = await import("./check-phase-gate-2OFZ7OWW.js");
883
1139
  const result = await runCheckPhaseGate({ cwd: sanitizePath(input.path) });
884
1140
  if (result.ok) {
885
1141
  return { content: [{ type: "text", text: JSON.stringify(result.value) }] };
@@ -899,7 +1155,7 @@ async function handleCheckPhaseGate(input) {
899
1155
  }
900
1156
 
901
1157
  // src/mcp/tools/cross-check.ts
902
- import * as path8 from "path";
1158
+ import * as path10 from "path";
903
1159
  var validateCrossCheckDefinition = {
904
1160
  name: "validate_cross_check",
905
1161
  description: "Validate plan-to-implementation coverage: checks that specs have plans and plans have implementations, detects staleness",
@@ -935,15 +1191,15 @@ async function handleValidateCrossCheck(input) {
935
1191
  };
936
1192
  }
937
1193
  try {
938
- const { runCrossCheck } = await import("./validate-cross-check-EDQ5QGTM.js");
939
- const specsDir = path8.resolve(projectPath, input.specsDir ?? "docs/specs");
1194
+ const { runCrossCheck } = await import("./validate-cross-check-STFHYMAZ.js");
1195
+ const specsDir = path10.resolve(projectPath, input.specsDir ?? "docs/specs");
940
1196
  if (!specsDir.startsWith(projectPath)) {
941
1197
  return {
942
1198
  content: [{ type: "text", text: "Error: specsDir escapes project root" }],
943
1199
  isError: true
944
1200
  };
945
1201
  }
946
- const plansDir = path8.resolve(projectPath, input.plansDir ?? "docs/plans");
1202
+ const plansDir = path10.resolve(projectPath, input.plansDir ?? "docs/plans");
947
1203
  if (!plansDir.startsWith(projectPath)) {
948
1204
  return {
949
1205
  content: [{ type: "text", text: "Error: plansDir escapes project root" }],
@@ -974,15 +1230,15 @@ async function handleValidateCrossCheck(input) {
974
1230
 
975
1231
  // src/commands/generate-slash-commands.ts
976
1232
  import { Command } from "commander";
977
- import fs7 from "fs";
978
- import path10 from "path";
1233
+ import fs9 from "fs";
1234
+ import path12 from "path";
979
1235
  import os from "os";
980
1236
  import readline from "readline";
981
1237
 
982
1238
  // src/slash-commands/normalize.ts
983
- import fs6 from "fs";
984
- import path9 from "path";
985
- import { parse as parse2 } from "yaml";
1239
+ import fs8 from "fs";
1240
+ import path11 from "path";
1241
+ import { parse as parse3 } from "yaml";
986
1242
 
987
1243
  // src/slash-commands/normalize-name.ts
988
1244
  function normalizeName(skillName) {
@@ -1002,18 +1258,18 @@ function normalizeSkills(skillSources, platforms) {
1002
1258
  const specs = [];
1003
1259
  const nameMap = /* @__PURE__ */ new Map();
1004
1260
  for (const { dir: skillsDir, source } of skillSources) {
1005
- if (!fs6.existsSync(skillsDir)) continue;
1006
- const entries = fs6.readdirSync(skillsDir, { withFileTypes: true }).filter((d) => d.isDirectory());
1261
+ if (!fs8.existsSync(skillsDir)) continue;
1262
+ const entries = fs8.readdirSync(skillsDir, { withFileTypes: true }).filter((d) => d.isDirectory());
1007
1263
  for (const entry of entries) {
1008
- const yamlPath = path9.join(skillsDir, entry.name, "skill.yaml");
1009
- if (!fs6.existsSync(yamlPath)) continue;
1264
+ const yamlPath = path11.join(skillsDir, entry.name, "skill.yaml");
1265
+ if (!fs8.existsSync(yamlPath)) continue;
1010
1266
  let raw;
1011
1267
  try {
1012
- raw = fs6.readFileSync(yamlPath, "utf-8");
1268
+ raw = fs8.readFileSync(yamlPath, "utf-8");
1013
1269
  } catch {
1014
1270
  continue;
1015
1271
  }
1016
- const parsed = parse2(raw);
1272
+ const parsed = parse3(raw);
1017
1273
  const result = SkillMetadataSchema.safeParse(parsed);
1018
1274
  if (!result.success) {
1019
1275
  console.warn(`Skipping ${entry.name}: invalid skill.yaml`);
@@ -1022,6 +1278,9 @@ function normalizeSkills(skillSources, platforms) {
1022
1278
  const meta = result.data;
1023
1279
  const matchesPlatform = platforms.some((p) => meta.platforms.includes(p));
1024
1280
  if (!matchesPlatform) continue;
1281
+ const tier = meta.tier;
1282
+ const isInternal = meta.internal;
1283
+ if (tier === 3 || isInternal) continue;
1025
1284
  const normalized = normalizeName(meta.name);
1026
1285
  const existing = nameMap.get(normalized);
1027
1286
  if (existing) {
@@ -1033,16 +1292,10 @@ function normalizeSkills(skillSources, platforms) {
1033
1292
  continue;
1034
1293
  }
1035
1294
  nameMap.set(normalized, { skillName: meta.name, source });
1036
- const skillMdPath = path9.join(skillsDir, entry.name, "SKILL.md");
1037
- const skillMdContent = fs6.existsSync(skillMdPath) ? fs6.readFileSync(skillMdPath, "utf-8") : "";
1038
- const skillMdRelative = path9.relative(
1039
- process.cwd(),
1040
- path9.join(skillsDir, entry.name, "SKILL.md")
1041
- );
1042
- const skillYamlRelative = path9.relative(
1043
- process.cwd(),
1044
- path9.join(skillsDir, entry.name, "skill.yaml")
1045
- );
1295
+ const skillMdPath = path11.join(skillsDir, entry.name, "SKILL.md");
1296
+ const skillMdContent = fs8.existsSync(skillMdPath) ? fs8.readFileSync(skillMdPath, "utf-8") : "";
1297
+ const skillMdRelative = path11.relative(process.cwd(), path11.join(skillsDir, entry.name, "SKILL.md")).replaceAll("\\", "/");
1298
+ const skillYamlRelative = path11.relative(process.cwd(), path11.join(skillsDir, entry.name, "skill.yaml")).replaceAll("\\", "/");
1046
1299
  const args = (meta.cli?.args ?? []).map((a) => ({
1047
1300
  name: a.name,
1048
1301
  description: a.description ?? "",
@@ -1207,13 +1460,13 @@ function renderGemini(spec, skillMdContent, skillYamlContent) {
1207
1460
  // src/commands/generate-slash-commands.ts
1208
1461
  function resolveOutputDir(platform, opts) {
1209
1462
  if (opts.output) {
1210
- return path10.join(opts.output, "harness");
1463
+ return path12.join(opts.output, "harness");
1211
1464
  }
1212
1465
  if (opts.global) {
1213
1466
  const home = os.homedir();
1214
- return platform === "claude-code" ? path10.join(home, ".claude", "commands", "harness") : path10.join(home, ".gemini", "commands", "harness");
1467
+ return platform === "claude-code" ? path12.join(home, ".claude", "commands", "harness") : path12.join(home, ".gemini", "commands", "harness");
1215
1468
  }
1216
- return platform === "claude-code" ? path10.join("agents", "commands", "claude-code", "harness") : path10.join("agents", "commands", "gemini-cli", "harness");
1469
+ return platform === "claude-code" ? path12.join("agents", "commands", "claude-code", "harness") : path12.join("agents", "commands", "gemini-cli", "harness");
1217
1470
  }
1218
1471
  function fileExtension(platform) {
1219
1472
  return platform === "claude-code" ? ".md" : ".toml";
@@ -1238,12 +1491,12 @@ function generateSlashCommands(opts) {
1238
1491
  skillSources.push({ dir: projectDir, source: "project" });
1239
1492
  }
1240
1493
  const communityDir = resolveCommunitySkillsDir();
1241
- if (fs7.existsSync(communityDir)) {
1494
+ if (fs9.existsSync(communityDir)) {
1242
1495
  skillSources.push({ dir: communityDir, source: "community" });
1243
1496
  }
1244
1497
  if (opts.includeGlobal || skillSources.length === 0) {
1245
1498
  const globalDir = resolveGlobalSkillsDir();
1246
- if (!projectDir || path10.resolve(globalDir) !== path10.resolve(projectDir)) {
1499
+ if (!projectDir || path12.resolve(globalDir) !== path12.resolve(projectDir)) {
1247
1500
  skillSources.push({ dir: globalDir, source: "global" });
1248
1501
  }
1249
1502
  }
@@ -1265,7 +1518,7 @@ function generateSlashCommands(opts) {
1265
1518
  executionContext: spec.prompt.executionContext.split("\n").map((line) => {
1266
1519
  if (line.startsWith("@")) {
1267
1520
  const relPath = line.slice(1);
1268
- return `@${path10.resolve(relPath)}`;
1521
+ return `@${path12.resolve(relPath)}`;
1269
1522
  }
1270
1523
  return line;
1271
1524
  }).join("\n")
@@ -1273,10 +1526,10 @@ function generateSlashCommands(opts) {
1273
1526
  } : spec;
1274
1527
  rendered.set(filename, renderClaudeCode(renderSpec));
1275
1528
  } else {
1276
- const mdPath = path10.join(spec.skillsBaseDir, spec.sourceDir, "SKILL.md");
1277
- const yamlPath = path10.join(spec.skillsBaseDir, spec.sourceDir, "skill.yaml");
1278
- const mdContent = fs7.existsSync(mdPath) ? fs7.readFileSync(mdPath, "utf-8") : "";
1279
- const yamlContent = fs7.existsSync(yamlPath) ? fs7.readFileSync(yamlPath, "utf-8") : "";
1529
+ const mdPath = path12.join(spec.skillsBaseDir, spec.sourceDir, "SKILL.md");
1530
+ const yamlPath = path12.join(spec.skillsBaseDir, spec.sourceDir, "skill.yaml");
1531
+ const mdContent = fs9.existsSync(mdPath) ? fs9.readFileSync(mdPath, "utf-8") : "";
1532
+ const yamlContent = fs9.existsSync(yamlPath) ? fs9.readFileSync(yamlPath, "utf-8") : "";
1280
1533
  rendered.set(filename, renderGemini(spec, mdContent, yamlContent));
1281
1534
  }
1282
1535
  }
@@ -1302,9 +1555,9 @@ async function handleOrphanDeletion(results, opts) {
1302
1555
  const shouldDelete = opts.yes || await confirmDeletion(result.removed);
1303
1556
  if (shouldDelete) {
1304
1557
  for (const filename of result.removed) {
1305
- const filePath = path10.join(result.outputDir, filename);
1306
- if (fs7.existsSync(filePath)) {
1307
- fs7.unlinkSync(filePath);
1558
+ const filePath = path12.join(result.outputDir, filename);
1559
+ if (fs9.existsSync(filePath)) {
1560
+ fs9.unlinkSync(filePath);
1308
1561
  }
1309
1562
  }
1310
1563
  }
@@ -1430,7 +1683,7 @@ async function handleGenerateSlashCommands(input) {
1430
1683
  // src/mcp/resources/state.ts
1431
1684
  async function getStateResource(projectRoot) {
1432
1685
  try {
1433
- const { loadState, migrateToStreams } = await import("./dist-WF4C7A4A.js");
1686
+ const { loadState, migrateToStreams } = await import("./dist-2B363XUH.js");
1434
1687
  await migrateToStreams(projectRoot);
1435
1688
  const result = await loadState(projectRoot);
1436
1689
  if (result.ok) {
@@ -1454,8 +1707,7 @@ async function getStateResource(projectRoot) {
1454
1707
  }
1455
1708
  }
1456
1709
 
1457
- // src/mcp/tools/graph.ts
1458
- import * as path11 from "path";
1710
+ // src/mcp/tools/graph/shared.ts
1459
1711
  function graphNotFoundError() {
1460
1712
  return {
1461
1713
  content: [
@@ -1467,6 +1719,8 @@ function graphNotFoundError() {
1467
1719
  isError: true
1468
1720
  };
1469
1721
  }
1722
+
1723
+ // src/mcp/tools/graph/query-graph.ts
1470
1724
  var queryGraphDefinition = {
1471
1725
  name: "query_graph",
1472
1726
  description: "Query the project knowledge graph using ContextQL. Traverses from root nodes outward, filtering by node/edge types.",
@@ -1517,7 +1771,7 @@ async function handleQueryGraph(input) {
1517
1771
  const projectPath = sanitizePath(input.path);
1518
1772
  const store = await loadGraphStore(projectPath);
1519
1773
  if (!store) return graphNotFoundError();
1520
- const { ContextQL } = await import("./dist-M6BQODWC.js");
1774
+ const { ContextQL } = await import("./dist-HXHWB7SV.js");
1521
1775
  const cql = new ContextQL(store);
1522
1776
  const result = cql.execute({
1523
1777
  rootNodeIds: input.rootNodeIds,
@@ -1583,6 +1837,8 @@ async function handleQueryGraph(input) {
1583
1837
  };
1584
1838
  }
1585
1839
  }
1840
+
1841
+ // src/mcp/tools/graph/search-similar.ts
1586
1842
  var searchSimilarDefinition = {
1587
1843
  name: "search_similar",
1588
1844
  description: "Search the knowledge graph for nodes similar to a query string using keyword and semantic fusion.",
@@ -1606,7 +1862,7 @@ async function handleSearchSimilar(input) {
1606
1862
  const projectPath = sanitizePath(input.path);
1607
1863
  const store = await loadGraphStore(projectPath);
1608
1864
  if (!store) return graphNotFoundError();
1609
- const { FusionLayer } = await import("./dist-M6BQODWC.js");
1865
+ const { FusionLayer } = await import("./dist-HXHWB7SV.js");
1610
1866
  const fusion = new FusionLayer(store);
1611
1867
  const results = fusion.search(input.query, input.topK ?? 10);
1612
1868
  if (input.mode === "summary") {
@@ -1638,6 +1894,8 @@ async function handleSearchSimilar(input) {
1638
1894
  };
1639
1895
  }
1640
1896
  }
1897
+
1898
+ // src/mcp/tools/graph/find-context-for.ts
1641
1899
  var findContextForDefinition = {
1642
1900
  name: "find_context_for",
1643
1901
  description: "Find relevant context for a given intent by searching the graph and expanding around top results. Returns assembled context within a token budget.",
@@ -1659,7 +1917,7 @@ async function handleFindContextFor(input) {
1659
1917
  const projectPath = sanitizePath(input.path);
1660
1918
  const store = await loadGraphStore(projectPath);
1661
1919
  if (!store) return graphNotFoundError();
1662
- const { FusionLayer, ContextQL } = await import("./dist-M6BQODWC.js");
1920
+ const { FusionLayer, ContextQL } = await import("./dist-HXHWB7SV.js");
1663
1921
  const fusion = new FusionLayer(store);
1664
1922
  const cql = new ContextQL(store);
1665
1923
  const tokenBudget = input.tokenBudget ?? 4e3;
@@ -1725,6 +1983,8 @@ async function handleFindContextFor(input) {
1725
1983
  };
1726
1984
  }
1727
1985
  }
1986
+
1987
+ // src/mcp/tools/graph/get-relationships.ts
1728
1988
  var getRelationshipsDefinition = {
1729
1989
  name: "get_relationships",
1730
1990
  description: "Get relationships for a specific node in the knowledge graph, with configurable direction and depth.",
@@ -1753,7 +2013,7 @@ async function handleGetRelationships(input) {
1753
2013
  const projectPath = sanitizePath(input.path);
1754
2014
  const store = await loadGraphStore(projectPath);
1755
2015
  if (!store) return graphNotFoundError();
1756
- const { ContextQL } = await import("./dist-M6BQODWC.js");
2016
+ const { ContextQL } = await import("./dist-HXHWB7SV.js");
1757
2017
  const cql = new ContextQL(store);
1758
2018
  const direction = input.direction ?? "both";
1759
2019
  const bidirectional = direction === "both" || direction === "inbound";
@@ -1820,6 +2080,8 @@ async function handleGetRelationships(input) {
1820
2080
  };
1821
2081
  }
1822
2082
  }
2083
+
2084
+ // src/mcp/tools/graph/get-impact.ts
1823
2085
  var getImpactDefinition = {
1824
2086
  name: "get_impact",
1825
2087
  description: "Analyze the impact of changing a node or file. Returns affected tests, docs, code, and other nodes grouped by type.",
@@ -1857,7 +2119,7 @@ async function handleGetImpact(input) {
1857
2119
  const projectPath = sanitizePath(input.path);
1858
2120
  const store = await loadGraphStore(projectPath);
1859
2121
  if (!store) return graphNotFoundError();
1860
- const { ContextQL } = await import("./dist-M6BQODWC.js");
2122
+ const { ContextQL } = await import("./dist-HXHWB7SV.js");
1861
2123
  let targetNodeId = input.nodeId;
1862
2124
  if (!targetNodeId && input.filePath) {
1863
2125
  const fileNodes = store.findNodes({ type: "file" });
@@ -1966,6 +2228,9 @@ async function handleGetImpact(input) {
1966
2228
  };
1967
2229
  }
1968
2230
  }
2231
+
2232
+ // src/mcp/tools/graph/ingest-source.ts
2233
+ import * as path13 from "path";
1969
2234
  var ingestSourceDefinition = {
1970
2235
  name: "ingest_source",
1971
2236
  description: "Ingest sources into the project knowledge graph. Supports code analysis, knowledge documents, git history, or all at once.",
@@ -1985,10 +2250,10 @@ var ingestSourceDefinition = {
1985
2250
  async function handleIngestSource(input) {
1986
2251
  try {
1987
2252
  const projectPath = sanitizePath(input.path);
1988
- const graphDir = path11.join(projectPath, ".harness", "graph");
1989
- const { GraphStore, CodeIngestor, TopologicalLinker, KnowledgeIngestor, GitIngestor } = await import("./dist-M6BQODWC.js");
1990
- const fs10 = await import("fs/promises");
1991
- await fs10.mkdir(graphDir, { recursive: true });
2253
+ const graphDir = path13.join(projectPath, ".harness", "graph");
2254
+ const { GraphStore, CodeIngestor, TopologicalLinker, KnowledgeIngestor, GitIngestor } = await import("./dist-HXHWB7SV.js");
2255
+ const fs12 = await import("fs/promises");
2256
+ await fs12.mkdir(graphDir, { recursive: true });
1992
2257
  const store = new GraphStore();
1993
2258
  await store.load(graphDir);
1994
2259
  const results = [];
@@ -2037,6 +2302,8 @@ async function handleIngestSource(input) {
2037
2302
  };
2038
2303
  }
2039
2304
  }
2305
+
2306
+ // src/mcp/tools/graph/detect-anomalies.ts
2040
2307
  var detectAnomaliesDefinition = {
2041
2308
  name: "detect_anomalies",
2042
2309
  description: "Detect structural anomalies \u2014 statistical outliers across code metrics and topological single points of failure in the import graph",
@@ -2059,7 +2326,7 @@ async function handleDetectAnomalies(input) {
2059
2326
  const projectPath = sanitizePath(input.path);
2060
2327
  const store = await loadGraphStore(projectPath);
2061
2328
  if (!store) return graphNotFoundError();
2062
- const { GraphAnomalyAdapter } = await import("./dist-M6BQODWC.js");
2329
+ const { GraphAnomalyAdapter } = await import("./dist-HXHWB7SV.js");
2063
2330
  const adapter = new GraphAnomalyAdapter(store);
2064
2331
  const report = adapter.detect({
2065
2332
  ...input.threshold !== void 0 && { threshold: input.threshold },
@@ -2080,6 +2347,8 @@ async function handleDetectAnomalies(input) {
2080
2347
  };
2081
2348
  }
2082
2349
  }
2350
+
2351
+ // src/mcp/tools/graph/ask-graph.ts
2083
2352
  var askGraphDefinition = {
2084
2353
  name: "ask_graph",
2085
2354
  description: 'Ask a natural language question about the codebase knowledge graph. Supports questions about impact ("what breaks if I change X?"), finding entities ("where is the auth middleware?"), relationships ("what calls UserService?"), explanations ("what is GraphStore?"), and anomalies ("what looks wrong?"). Returns a human-readable summary and raw graph data.',
@@ -2097,7 +2366,7 @@ async function handleAskGraph(input) {
2097
2366
  const projectPath = sanitizePath(input.path);
2098
2367
  const store = await loadGraphStore(projectPath);
2099
2368
  if (!store) return graphNotFoundError();
2100
- const { askGraph } = await import("./dist-M6BQODWC.js");
2369
+ const { askGraph } = await import("./dist-HXHWB7SV.js");
2101
2370
  const result = await askGraph(store, input.question);
2102
2371
  return {
2103
2372
  content: [{ type: "text", text: JSON.stringify(result) }]
@@ -2116,8 +2385,8 @@ async function handleAskGraph(input) {
2116
2385
  }
2117
2386
 
2118
2387
  // src/mcp/resources/graph.ts
2119
- import * as fs8 from "fs/promises";
2120
- import * as path12 from "path";
2388
+ import * as fs10 from "fs/promises";
2389
+ import * as path14 from "path";
2121
2390
  var MAX_ITEMS = 5e3;
2122
2391
  function formatStaleness(isoTimestamp) {
2123
2392
  const then = new Date(isoTimestamp).getTime();
@@ -2140,11 +2409,11 @@ async function getGraphResource(projectRoot) {
2140
2409
  message: "No knowledge graph found. Run harness scan to build one."
2141
2410
  });
2142
2411
  }
2143
- const graphDir = path12.join(projectRoot, ".harness", "graph");
2144
- const metadataPath = path12.join(graphDir, "metadata.json");
2412
+ const graphDir = path14.join(projectRoot, ".harness", "graph");
2413
+ const metadataPath = path14.join(graphDir, "metadata.json");
2145
2414
  let lastScanTimestamp = null;
2146
2415
  try {
2147
- const raw = JSON.parse(await fs8.readFile(metadataPath, "utf-8"));
2416
+ const raw = JSON.parse(await fs10.readFile(metadataPath, "utf-8"));
2148
2417
  lastScanTimestamp = raw.lastScanTimestamp ?? null;
2149
2418
  } catch {
2150
2419
  }
@@ -2233,7 +2502,7 @@ var generateAgentDefinitionsDefinition = {
2233
2502
  }
2234
2503
  };
2235
2504
  async function handleGenerateAgentDefinitions(input) {
2236
- const { generateAgentDefinitions } = await import("./generate-agent-definitions-QABOJG56.js");
2505
+ const { generateAgentDefinitions } = await import("./generate-agent-definitions-64S3CLEZ.js");
2237
2506
  const platforms = input.platform === "all" || !input.platform ? ["claude-code", "gemini-cli"] : [input.platform];
2238
2507
  const results = generateAgentDefinitions({
2239
2508
  platforms: [...platforms],
@@ -2244,8 +2513,8 @@ async function handleGenerateAgentDefinitions(input) {
2244
2513
  }
2245
2514
 
2246
2515
  // src/mcp/tools/roadmap.ts
2247
- import * as fs9 from "fs";
2248
- import * as path13 from "path";
2516
+ import * as fs11 from "fs";
2517
+ import * as path15 from "path";
2249
2518
  var manageRoadmapDefinition = {
2250
2519
  name: "manage_roadmap",
2251
2520
  description: "Manage the project roadmap: show, add, update, remove, sync features, or query by filter. Reads and writes docs/roadmap.md.",
@@ -2300,309 +2569,261 @@ var manageRoadmapDefinition = {
2300
2569
  }
2301
2570
  };
2302
2571
  function roadmapPath(projectRoot) {
2303
- return path13.join(projectRoot, "docs", "roadmap.md");
2572
+ return path15.join(projectRoot, "docs", "roadmap.md");
2304
2573
  }
2305
2574
  function readRoadmapFile(projectRoot) {
2306
2575
  const filePath = roadmapPath(projectRoot);
2307
2576
  try {
2308
- return fs9.readFileSync(filePath, "utf-8");
2577
+ return fs11.readFileSync(filePath, "utf-8");
2309
2578
  } catch {
2310
2579
  return null;
2311
2580
  }
2312
2581
  }
2313
2582
  function writeRoadmapFile(projectRoot, content) {
2314
2583
  const filePath = roadmapPath(projectRoot);
2315
- const dir = path13.dirname(filePath);
2316
- fs9.mkdirSync(dir, { recursive: true });
2317
- fs9.writeFileSync(filePath, content, "utf-8");
2584
+ const dir = path15.dirname(filePath);
2585
+ fs11.mkdirSync(dir, { recursive: true });
2586
+ fs11.writeFileSync(filePath, content, "utf-8");
2587
+ }
2588
+ function roadmapNotFoundError() {
2589
+ return {
2590
+ content: [
2591
+ {
2592
+ type: "text",
2593
+ text: "Error: docs/roadmap.md not found. Create a roadmap first."
2594
+ }
2595
+ ],
2596
+ isError: true
2597
+ };
2598
+ }
2599
+ function handleShow(projectPath, input, deps) {
2600
+ const { parseRoadmap, Ok: Ok2 } = deps;
2601
+ const raw = readRoadmapFile(projectPath);
2602
+ if (raw === null) return roadmapNotFoundError();
2603
+ const result = parseRoadmap(raw);
2604
+ if (!result.ok) return resultToMcpResponse(result);
2605
+ let roadmap = result.value;
2606
+ if (input.milestone) {
2607
+ const milestoneFilter = input.milestone;
2608
+ roadmap = {
2609
+ ...roadmap,
2610
+ milestones: roadmap.milestones.filter(
2611
+ (m) => m.name.toLowerCase() === milestoneFilter.toLowerCase()
2612
+ )
2613
+ };
2614
+ }
2615
+ if (input.status) {
2616
+ const statusFilter = input.status;
2617
+ roadmap = {
2618
+ ...roadmap,
2619
+ milestones: roadmap.milestones.map((m) => ({
2620
+ ...m,
2621
+ features: m.features.filter((f) => f.status === statusFilter)
2622
+ })).filter((m) => m.features.length > 0)
2623
+ };
2624
+ }
2625
+ return resultToMcpResponse(Ok2(roadmap));
2626
+ }
2627
+ function handleAdd(projectPath, input, deps) {
2628
+ const { parseRoadmap, serializeRoadmap, Ok: Ok2 } = deps;
2629
+ if (!input.feature) {
2630
+ return {
2631
+ content: [{ type: "text", text: "Error: feature is required for add action" }],
2632
+ isError: true
2633
+ };
2634
+ }
2635
+ if (!input.milestone) {
2636
+ return {
2637
+ content: [{ type: "text", text: "Error: milestone is required for add action" }],
2638
+ isError: true
2639
+ };
2640
+ }
2641
+ if (!input.status) {
2642
+ return {
2643
+ content: [{ type: "text", text: "Error: status is required for add action" }],
2644
+ isError: true
2645
+ };
2646
+ }
2647
+ if (!input.summary) {
2648
+ return {
2649
+ content: [{ type: "text", text: "Error: summary is required for add action" }],
2650
+ isError: true
2651
+ };
2652
+ }
2653
+ const raw = readRoadmapFile(projectPath);
2654
+ if (raw === null) return roadmapNotFoundError();
2655
+ const result = parseRoadmap(raw);
2656
+ if (!result.ok) return resultToMcpResponse(result);
2657
+ const roadmap = result.value;
2658
+ const milestone = roadmap.milestones.find(
2659
+ (m) => m.name.toLowerCase() === input.milestone.toLowerCase()
2660
+ );
2661
+ if (!milestone) {
2662
+ return {
2663
+ content: [{ type: "text", text: `Error: milestone "${input.milestone}" not found` }],
2664
+ isError: true
2665
+ };
2666
+ }
2667
+ milestone.features.push({
2668
+ name: input.feature,
2669
+ status: input.status,
2670
+ spec: input.spec ?? null,
2671
+ plans: input.plans ?? [],
2672
+ blockedBy: input.blocked_by ?? [],
2673
+ summary: input.summary
2674
+ });
2675
+ roadmap.frontmatter.lastManualEdit = (/* @__PURE__ */ new Date()).toISOString();
2676
+ writeRoadmapFile(projectPath, serializeRoadmap(roadmap));
2677
+ return resultToMcpResponse(Ok2(roadmap));
2678
+ }
2679
+ function handleUpdate(projectPath, input, deps) {
2680
+ const { parseRoadmap, serializeRoadmap, Ok: Ok2 } = deps;
2681
+ if (!input.feature) {
2682
+ return {
2683
+ content: [{ type: "text", text: "Error: feature is required for update action" }],
2684
+ isError: true
2685
+ };
2686
+ }
2687
+ const raw = readRoadmapFile(projectPath);
2688
+ if (raw === null) return roadmapNotFoundError();
2689
+ const result = parseRoadmap(raw);
2690
+ if (!result.ok) return resultToMcpResponse(result);
2691
+ const roadmap = result.value;
2692
+ let found = false;
2693
+ for (const m of roadmap.milestones) {
2694
+ const feature = m.features.find((f) => f.name.toLowerCase() === input.feature.toLowerCase());
2695
+ if (feature) {
2696
+ if (input.status) feature.status = input.status;
2697
+ if (input.summary !== void 0) feature.summary = input.summary;
2698
+ if (input.spec !== void 0) feature.spec = input.spec || null;
2699
+ if (input.plans !== void 0) feature.plans = input.plans;
2700
+ if (input.blocked_by !== void 0) feature.blockedBy = input.blocked_by;
2701
+ found = true;
2702
+ break;
2703
+ }
2704
+ }
2705
+ if (!found) {
2706
+ return {
2707
+ content: [{ type: "text", text: `Error: feature "${input.feature}" not found` }],
2708
+ isError: true
2709
+ };
2710
+ }
2711
+ roadmap.frontmatter.lastManualEdit = (/* @__PURE__ */ new Date()).toISOString();
2712
+ writeRoadmapFile(projectPath, serializeRoadmap(roadmap));
2713
+ return resultToMcpResponse(Ok2(roadmap));
2714
+ }
2715
+ function handleRemove(projectPath, input, deps) {
2716
+ const { parseRoadmap, serializeRoadmap, Ok: Ok2 } = deps;
2717
+ if (!input.feature) {
2718
+ return {
2719
+ content: [{ type: "text", text: "Error: feature is required for remove action" }],
2720
+ isError: true
2721
+ };
2722
+ }
2723
+ const raw = readRoadmapFile(projectPath);
2724
+ if (raw === null) return roadmapNotFoundError();
2725
+ const result = parseRoadmap(raw);
2726
+ if (!result.ok) return resultToMcpResponse(result);
2727
+ const roadmap = result.value;
2728
+ let found = false;
2729
+ for (const m of roadmap.milestones) {
2730
+ const idx = m.features.findIndex((f) => f.name.toLowerCase() === input.feature.toLowerCase());
2731
+ if (idx !== -1) {
2732
+ m.features.splice(idx, 1);
2733
+ found = true;
2734
+ break;
2735
+ }
2736
+ }
2737
+ if (!found) {
2738
+ return {
2739
+ content: [{ type: "text", text: `Error: feature "${input.feature}" not found` }],
2740
+ isError: true
2741
+ };
2742
+ }
2743
+ roadmap.frontmatter.lastManualEdit = (/* @__PURE__ */ new Date()).toISOString();
2744
+ writeRoadmapFile(projectPath, serializeRoadmap(roadmap));
2745
+ return resultToMcpResponse(Ok2(roadmap));
2746
+ }
2747
+ function handleQuery(projectPath, input, deps) {
2748
+ const { parseRoadmap, Ok: Ok2 } = deps;
2749
+ if (!input.filter) {
2750
+ return {
2751
+ content: [{ type: "text", text: "Error: filter is required for query action" }],
2752
+ isError: true
2753
+ };
2754
+ }
2755
+ const raw = readRoadmapFile(projectPath);
2756
+ if (raw === null) return roadmapNotFoundError();
2757
+ const result = parseRoadmap(raw);
2758
+ if (!result.ok) return resultToMcpResponse(result);
2759
+ const roadmap = result.value;
2760
+ const allFeatures = roadmap.milestones.flatMap(
2761
+ (m) => m.features.map((f) => ({ ...f, milestone: m.name }))
2762
+ );
2763
+ const filter = input.filter.toLowerCase();
2764
+ let filtered;
2765
+ if (filter.startsWith("milestone:")) {
2766
+ const milestoneName = filter.slice("milestone:".length).trim();
2767
+ filtered = allFeatures.filter((f) => f.milestone.toLowerCase().includes(milestoneName));
2768
+ } else {
2769
+ filtered = allFeatures.filter((f) => f.status === filter);
2770
+ }
2771
+ return resultToMcpResponse(Ok2(filtered));
2772
+ }
2773
+ function handleSync(projectPath, input, deps) {
2774
+ const { parseRoadmap, serializeRoadmap, syncRoadmap, Ok: Ok2 } = deps;
2775
+ const raw = readRoadmapFile(projectPath);
2776
+ if (raw === null) return roadmapNotFoundError();
2777
+ const result = parseRoadmap(raw);
2778
+ if (!result.ok) return resultToMcpResponse(result);
2779
+ const roadmap = result.value;
2780
+ const syncResult = syncRoadmap({
2781
+ projectPath,
2782
+ roadmap,
2783
+ forceSync: input.force_sync ?? false
2784
+ });
2785
+ if (!syncResult.ok) return resultToMcpResponse(syncResult);
2786
+ const changes = syncResult.value;
2787
+ if (changes.length === 0) {
2788
+ return resultToMcpResponse(Ok2({ changes: [], message: "Roadmap is up to date." }));
2789
+ }
2790
+ if (input.apply) {
2791
+ for (const change of changes) {
2792
+ for (const m of roadmap.milestones) {
2793
+ const feature = m.features.find(
2794
+ (f) => f.name.toLowerCase() === change.feature.toLowerCase()
2795
+ );
2796
+ if (feature) {
2797
+ feature.status = change.to;
2798
+ break;
2799
+ }
2800
+ }
2801
+ }
2802
+ roadmap.frontmatter.lastSynced = (/* @__PURE__ */ new Date()).toISOString();
2803
+ writeRoadmapFile(projectPath, serializeRoadmap(roadmap));
2804
+ return resultToMcpResponse(Ok2({ changes, applied: true, roadmap }));
2805
+ }
2806
+ return resultToMcpResponse(Ok2({ changes, applied: false }));
2318
2807
  }
2319
2808
  async function handleManageRoadmap(input) {
2320
2809
  try {
2321
- const { parseRoadmap, serializeRoadmap, syncRoadmap } = await import("./dist-WF4C7A4A.js");
2810
+ const { parseRoadmap, serializeRoadmap, syncRoadmap } = await import("./dist-2B363XUH.js");
2322
2811
  const { Ok: Ok2 } = await import("./dist-D4RYGUZE.js");
2323
2812
  const projectPath = sanitizePath(input.path);
2813
+ const deps = { parseRoadmap, serializeRoadmap, syncRoadmap, Ok: Ok2 };
2324
2814
  switch (input.action) {
2325
- case "show": {
2326
- const raw = readRoadmapFile(projectPath);
2327
- if (raw === null) {
2328
- return {
2329
- content: [
2330
- {
2331
- type: "text",
2332
- text: "Error: docs/roadmap.md not found. Create a roadmap first."
2333
- }
2334
- ],
2335
- isError: true
2336
- };
2337
- }
2338
- const result = parseRoadmap(raw);
2339
- if (!result.ok) return resultToMcpResponse(result);
2340
- let roadmap = result.value;
2341
- if (input.milestone) {
2342
- const milestoneFilter = input.milestone;
2343
- roadmap = {
2344
- ...roadmap,
2345
- milestones: roadmap.milestones.filter(
2346
- (m) => m.name.toLowerCase() === milestoneFilter.toLowerCase()
2347
- )
2348
- };
2349
- }
2350
- if (input.status) {
2351
- const statusFilter = input.status;
2352
- roadmap = {
2353
- ...roadmap,
2354
- milestones: roadmap.milestones.map((m) => ({
2355
- ...m,
2356
- features: m.features.filter((f) => f.status === statusFilter)
2357
- })).filter((m) => m.features.length > 0)
2358
- };
2359
- }
2360
- return resultToMcpResponse(Ok2(roadmap));
2361
- }
2362
- case "add": {
2363
- if (!input.feature) {
2364
- return {
2365
- content: [{ type: "text", text: "Error: feature is required for add action" }],
2366
- isError: true
2367
- };
2368
- }
2369
- if (!input.milestone) {
2370
- return {
2371
- content: [
2372
- { type: "text", text: "Error: milestone is required for add action" }
2373
- ],
2374
- isError: true
2375
- };
2376
- }
2377
- if (!input.status) {
2378
- return {
2379
- content: [{ type: "text", text: "Error: status is required for add action" }],
2380
- isError: true
2381
- };
2382
- }
2383
- if (!input.summary) {
2384
- return {
2385
- content: [{ type: "text", text: "Error: summary is required for add action" }],
2386
- isError: true
2387
- };
2388
- }
2389
- const raw = readRoadmapFile(projectPath);
2390
- if (raw === null) {
2391
- return {
2392
- content: [
2393
- {
2394
- type: "text",
2395
- text: "Error: docs/roadmap.md not found. Create a roadmap first."
2396
- }
2397
- ],
2398
- isError: true
2399
- };
2400
- }
2401
- const result = parseRoadmap(raw);
2402
- if (!result.ok) return resultToMcpResponse(result);
2403
- const roadmap = result.value;
2404
- const milestone = roadmap.milestones.find(
2405
- (m) => m.name.toLowerCase() === input.milestone.toLowerCase()
2406
- );
2407
- if (!milestone) {
2408
- return {
2409
- content: [
2410
- { type: "text", text: `Error: milestone "${input.milestone}" not found` }
2411
- ],
2412
- isError: true
2413
- };
2414
- }
2415
- milestone.features.push({
2416
- name: input.feature,
2417
- status: input.status,
2418
- spec: input.spec ?? null,
2419
- plans: input.plans ?? [],
2420
- blockedBy: input.blocked_by ?? [],
2421
- summary: input.summary
2422
- });
2423
- roadmap.frontmatter.lastManualEdit = (/* @__PURE__ */ new Date()).toISOString();
2424
- writeRoadmapFile(projectPath, serializeRoadmap(roadmap));
2425
- return resultToMcpResponse(Ok2(roadmap));
2426
- }
2427
- case "update": {
2428
- if (!input.feature) {
2429
- return {
2430
- content: [
2431
- { type: "text", text: "Error: feature is required for update action" }
2432
- ],
2433
- isError: true
2434
- };
2435
- }
2436
- const raw = readRoadmapFile(projectPath);
2437
- if (raw === null) {
2438
- return {
2439
- content: [
2440
- {
2441
- type: "text",
2442
- text: "Error: docs/roadmap.md not found. Create a roadmap first."
2443
- }
2444
- ],
2445
- isError: true
2446
- };
2447
- }
2448
- const result = parseRoadmap(raw);
2449
- if (!result.ok) return resultToMcpResponse(result);
2450
- const roadmap = result.value;
2451
- let found = false;
2452
- for (const m of roadmap.milestones) {
2453
- const feature = m.features.find(
2454
- (f) => f.name.toLowerCase() === input.feature.toLowerCase()
2455
- );
2456
- if (feature) {
2457
- if (input.status) feature.status = input.status;
2458
- if (input.summary !== void 0) feature.summary = input.summary;
2459
- if (input.spec !== void 0) feature.spec = input.spec || null;
2460
- if (input.plans !== void 0) feature.plans = input.plans;
2461
- if (input.blocked_by !== void 0) feature.blockedBy = input.blocked_by;
2462
- found = true;
2463
- break;
2464
- }
2465
- }
2466
- if (!found) {
2467
- return {
2468
- content: [
2469
- { type: "text", text: `Error: feature "${input.feature}" not found` }
2470
- ],
2471
- isError: true
2472
- };
2473
- }
2474
- roadmap.frontmatter.lastManualEdit = (/* @__PURE__ */ new Date()).toISOString();
2475
- writeRoadmapFile(projectPath, serializeRoadmap(roadmap));
2476
- return resultToMcpResponse(Ok2(roadmap));
2477
- }
2478
- case "remove": {
2479
- if (!input.feature) {
2480
- return {
2481
- content: [
2482
- { type: "text", text: "Error: feature is required for remove action" }
2483
- ],
2484
- isError: true
2485
- };
2486
- }
2487
- const raw = readRoadmapFile(projectPath);
2488
- if (raw === null) {
2489
- return {
2490
- content: [
2491
- {
2492
- type: "text",
2493
- text: "Error: docs/roadmap.md not found. Create a roadmap first."
2494
- }
2495
- ],
2496
- isError: true
2497
- };
2498
- }
2499
- const result = parseRoadmap(raw);
2500
- if (!result.ok) return resultToMcpResponse(result);
2501
- const roadmap = result.value;
2502
- let found = false;
2503
- for (const m of roadmap.milestones) {
2504
- const idx = m.features.findIndex(
2505
- (f) => f.name.toLowerCase() === input.feature.toLowerCase()
2506
- );
2507
- if (idx !== -1) {
2508
- m.features.splice(idx, 1);
2509
- found = true;
2510
- break;
2511
- }
2512
- }
2513
- if (!found) {
2514
- return {
2515
- content: [
2516
- { type: "text", text: `Error: feature "${input.feature}" not found` }
2517
- ],
2518
- isError: true
2519
- };
2520
- }
2521
- roadmap.frontmatter.lastManualEdit = (/* @__PURE__ */ new Date()).toISOString();
2522
- writeRoadmapFile(projectPath, serializeRoadmap(roadmap));
2523
- return resultToMcpResponse(Ok2(roadmap));
2524
- }
2525
- case "query": {
2526
- if (!input.filter) {
2527
- return {
2528
- content: [
2529
- { type: "text", text: "Error: filter is required for query action" }
2530
- ],
2531
- isError: true
2532
- };
2533
- }
2534
- const raw = readRoadmapFile(projectPath);
2535
- if (raw === null) {
2536
- return {
2537
- content: [
2538
- {
2539
- type: "text",
2540
- text: "Error: docs/roadmap.md not found. Create a roadmap first."
2541
- }
2542
- ],
2543
- isError: true
2544
- };
2545
- }
2546
- const result = parseRoadmap(raw);
2547
- if (!result.ok) return resultToMcpResponse(result);
2548
- const roadmap = result.value;
2549
- const allFeatures = roadmap.milestones.flatMap(
2550
- (m) => m.features.map((f) => ({ ...f, milestone: m.name }))
2551
- );
2552
- const filter = input.filter.toLowerCase();
2553
- let filtered;
2554
- if (filter.startsWith("milestone:")) {
2555
- const milestoneName = filter.slice("milestone:".length).trim();
2556
- filtered = allFeatures.filter((f) => f.milestone.toLowerCase().includes(milestoneName));
2557
- } else {
2558
- filtered = allFeatures.filter((f) => f.status === filter);
2559
- }
2560
- return resultToMcpResponse(Ok2(filtered));
2561
- }
2562
- case "sync": {
2563
- const raw = readRoadmapFile(projectPath);
2564
- if (raw === null) {
2565
- return {
2566
- content: [
2567
- {
2568
- type: "text",
2569
- text: "Error: docs/roadmap.md not found. Create a roadmap first."
2570
- }
2571
- ],
2572
- isError: true
2573
- };
2574
- }
2575
- const result = parseRoadmap(raw);
2576
- if (!result.ok) return resultToMcpResponse(result);
2577
- const roadmap = result.value;
2578
- const syncResult = syncRoadmap({
2579
- projectPath,
2580
- roadmap,
2581
- forceSync: input.force_sync ?? false
2582
- });
2583
- if (!syncResult.ok) return resultToMcpResponse(syncResult);
2584
- const changes = syncResult.value;
2585
- if (changes.length === 0) {
2586
- return resultToMcpResponse(Ok2({ changes: [], message: "Roadmap is up to date." }));
2587
- }
2588
- if (input.apply) {
2589
- for (const change of changes) {
2590
- for (const m of roadmap.milestones) {
2591
- const feature = m.features.find(
2592
- (f) => f.name.toLowerCase() === change.feature.toLowerCase()
2593
- );
2594
- if (feature) {
2595
- feature.status = change.to;
2596
- break;
2597
- }
2598
- }
2599
- }
2600
- roadmap.frontmatter.lastSynced = (/* @__PURE__ */ new Date()).toISOString();
2601
- writeRoadmapFile(projectPath, serializeRoadmap(roadmap));
2602
- return resultToMcpResponse(Ok2({ changes, applied: true, roadmap }));
2603
- }
2604
- return resultToMcpResponse(Ok2({ changes, applied: false }));
2605
- }
2815
+ case "show":
2816
+ return handleShow(projectPath, input, deps);
2817
+ case "add":
2818
+ return handleAdd(projectPath, input, deps);
2819
+ case "update":
2820
+ return handleUpdate(projectPath, input, deps);
2821
+ case "remove":
2822
+ return handleRemove(projectPath, input, deps);
2823
+ case "query":
2824
+ return handleQuery(projectPath, input, deps);
2825
+ case "sync":
2826
+ return handleSync(projectPath, input, deps);
2606
2827
  default: {
2607
2828
  return {
2608
2829
  content: [{ type: "text", text: `Error: unknown action` }],
@@ -3089,7 +3310,7 @@ async function handleEmitInteraction(input) {
3089
3310
  const transition = transitionResult.data;
3090
3311
  const prompt = renderTransition(transition);
3091
3312
  try {
3092
- const { saveHandoff } = await import("./dist-WF4C7A4A.js");
3313
+ const { saveHandoff } = await import("./dist-2B363XUH.js");
3093
3314
  await saveHandoff(
3094
3315
  projectPath,
3095
3316
  {
@@ -3191,7 +3412,7 @@ async function handleEmitInteraction(input) {
3191
3412
  }
3192
3413
  async function recordInteraction(projectPath, id, type, decision, stream) {
3193
3414
  try {
3194
- const { loadState, saveState } = await import("./dist-WF4C7A4A.js");
3415
+ const { loadState, saveState } = await import("./dist-2B363XUH.js");
3195
3416
  const stateResult = await loadState(projectPath, stream);
3196
3417
  if (stateResult.ok) {
3197
3418
  const state = stateResult.value;
@@ -3271,10 +3492,10 @@ async function handleGatherContext(input) {
3271
3492
  input.include ?? ["state", "learnings", "handoff", "graph", "validation"]
3272
3493
  );
3273
3494
  const errors = [];
3274
- const statePromise = includeSet.has("state") ? import("./dist-WF4C7A4A.js").then(
3495
+ const statePromise = includeSet.has("state") ? import("./dist-2B363XUH.js").then(
3275
3496
  (core) => core.loadState(projectPath, void 0, input.session)
3276
3497
  ) : Promise.resolve(null);
3277
- const learningsPromise = includeSet.has("learnings") ? import("./dist-WF4C7A4A.js").then(
3498
+ const learningsPromise = includeSet.has("learnings") ? import("./dist-2B363XUH.js").then(
3278
3499
  (core) => core.loadBudgetedLearnings(projectPath, {
3279
3500
  intent: input.intent,
3280
3501
  tokenBudget: input.learningsBudget ?? 1e3,
@@ -3282,14 +3503,14 @@ async function handleGatherContext(input) {
3282
3503
  ...input.session !== void 0 && { session: input.session }
3283
3504
  })
3284
3505
  ) : Promise.resolve(null);
3285
- const handoffPromise = includeSet.has("handoff") ? import("./dist-WF4C7A4A.js").then(
3506
+ const handoffPromise = includeSet.has("handoff") ? import("./dist-2B363XUH.js").then(
3286
3507
  (core) => core.loadHandoff(projectPath, void 0, input.session)
3287
3508
  ) : Promise.resolve(null);
3288
3509
  const graphPromise = includeSet.has("graph") ? (async () => {
3289
- const { loadGraphStore: loadGraphStore2 } = await import("./graph-loader-KO4GJ5N2.js");
3510
+ const { loadGraphStore: loadGraphStore2 } = await import("./graph-loader-GJZ4FN4Y.js");
3290
3511
  const store = await loadGraphStore2(projectPath);
3291
3512
  if (!store) return null;
3292
- const { FusionLayer, ContextQL } = await import("./dist-M6BQODWC.js");
3513
+ const { FusionLayer, ContextQL } = await import("./dist-HXHWB7SV.js");
3293
3514
  const fusion = new FusionLayer(store);
3294
3515
  const cql = new ContextQL(store);
3295
3516
  const tokenBudget = input.tokenBudget ?? 4e3;
@@ -3327,7 +3548,7 @@ async function handleGatherContext(input) {
3327
3548
  };
3328
3549
  })() : Promise.resolve(null);
3329
3550
  const validationPromise = includeSet.has("validation") ? (async () => {
3330
- const { handleValidateProject: handleValidateProject2 } = await import("./validate-N7QJOKFZ.js");
3551
+ const { handleValidateProject: handleValidateProject2 } = await import("./validate-GCHZJIL7.js");
3331
3552
  const result = await handleValidateProject2({ path: projectPath });
3332
3553
  const first = result.content[0];
3333
3554
  return first ? JSON.parse(first.text) : null;
@@ -3401,7 +3622,7 @@ async function handleGatherContext(input) {
3401
3622
  };
3402
3623
  if (input.session) {
3403
3624
  try {
3404
- const core = await import("./dist-WF4C7A4A.js");
3625
+ const core = await import("./dist-2B363XUH.js");
3405
3626
  core.updateSessionIndex(
3406
3627
  projectPath,
3407
3628
  input.session,
@@ -3471,7 +3692,7 @@ async function handleAssessProject(input) {
3471
3692
  let validateResult = null;
3472
3693
  if (checksToRun.has("validate")) {
3473
3694
  try {
3474
- const { handleValidateProject: handleValidateProject2 } = await import("./validate-N7QJOKFZ.js");
3695
+ const { handleValidateProject: handleValidateProject2 } = await import("./validate-GCHZJIL7.js");
3475
3696
  const result = await handleValidateProject2({ path: projectPath });
3476
3697
  const first = result.content[0];
3477
3698
  const parsed = first ? JSON.parse(first.text) : {};
@@ -3496,7 +3717,7 @@ async function handleAssessProject(input) {
3496
3717
  parallelChecks.push(
3497
3718
  (async () => {
3498
3719
  try {
3499
- const { handleCheckDependencies: handleCheckDependencies2 } = await import("./architecture-ESOOE26S.js");
3720
+ const { handleCheckDependencies: handleCheckDependencies2 } = await import("./architecture-2R5Z4ZAF.js");
3500
3721
  const result = await handleCheckDependencies2({ path: projectPath });
3501
3722
  const first = result.content[0];
3502
3723
  const parsed = first ? JSON.parse(first.text) : {};
@@ -3523,7 +3744,7 @@ async function handleAssessProject(input) {
3523
3744
  parallelChecks.push(
3524
3745
  (async () => {
3525
3746
  try {
3526
- const { handleCheckDocs: handleCheckDocs2 } = await import("./docs-BPYCN2DR.js");
3747
+ const { handleCheckDocs: handleCheckDocs2 } = await import("./docs-FZOPM4GK.js");
3527
3748
  const result = await handleCheckDocs2({ path: projectPath, scope: "coverage" });
3528
3749
  const first = result.content[0];
3529
3750
  const parsed = first ? JSON.parse(first.text) : {};
@@ -3550,7 +3771,7 @@ async function handleAssessProject(input) {
3550
3771
  parallelChecks.push(
3551
3772
  (async () => {
3552
3773
  try {
3553
- const { handleDetectEntropy: handleDetectEntropy2 } = await import("./entropy-4VDVV5CR.js");
3774
+ const { handleDetectEntropy: handleDetectEntropy2 } = await import("./entropy-LVHJMFGH.js");
3554
3775
  const result = await handleDetectEntropy2({ path: projectPath, type: "all" });
3555
3776
  const first = result.content[0];
3556
3777
  const parsed = first ? JSON.parse(first.text) : {};
@@ -3577,7 +3798,7 @@ async function handleAssessProject(input) {
3577
3798
  parallelChecks.push(
3578
3799
  (async () => {
3579
3800
  try {
3580
- const { handleRunSecurityScan: handleRunSecurityScan2 } = await import("./security-UQFUZXEN.js");
3801
+ const { handleRunSecurityScan: handleRunSecurityScan2 } = await import("./security-FWQZF2IZ.js");
3581
3802
  const result = await handleRunSecurityScan2({ path: projectPath });
3582
3803
  const first = result.content[0];
3583
3804
  const parsed = first ? JSON.parse(first.text) : {};
@@ -3609,7 +3830,7 @@ async function handleAssessProject(input) {
3609
3830
  parallelChecks.push(
3610
3831
  (async () => {
3611
3832
  try {
3612
- const { handleCheckPerformance: handleCheckPerformance2 } = await import("./performance-26BH47O4.js");
3833
+ const { handleCheckPerformance: handleCheckPerformance2 } = await import("./performance-ZTVSUANN.js");
3613
3834
  const result = await handleCheckPerformance2({ path: projectPath });
3614
3835
  const first = result.content[0];
3615
3836
  const parsed = first ? JSON.parse(first.text) : {};
@@ -3784,7 +4005,7 @@ async function handleReviewChanges(input) {
3784
4005
  }
3785
4006
  try {
3786
4007
  if (effectiveDepth === "quick") {
3787
- const { handleAnalyzeDiff: handleAnalyzeDiff2 } = await import("./feedback-63QB5RCA.js");
4008
+ const { handleAnalyzeDiff: handleAnalyzeDiff2 } = await import("./feedback-IHLVLMRD.js");
3788
4009
  const result2 = await handleAnalyzeDiff2({ diff, path: projectPath });
3789
4010
  const firstContent = result2.content[0];
3790
4011
  if (!firstContent) throw new Error("Empty analyze_diff response");
@@ -3806,7 +4027,7 @@ async function handleReviewChanges(input) {
3806
4027
  };
3807
4028
  }
3808
4029
  if (effectiveDepth === "standard") {
3809
- const { handleAnalyzeDiff: handleAnalyzeDiff2, handleCreateSelfReview: handleCreateSelfReview2 } = await import("./feedback-63QB5RCA.js");
4030
+ const { handleAnalyzeDiff: handleAnalyzeDiff2, handleCreateSelfReview: handleCreateSelfReview2 } = await import("./feedback-IHLVLMRD.js");
3810
4031
  const [diffResult, reviewResult] = await Promise.all([
3811
4032
  handleAnalyzeDiff2({ diff, path: projectPath }),
3812
4033
  handleCreateSelfReview2({ path: projectPath, diff })
@@ -3837,7 +4058,7 @@ async function handleReviewChanges(input) {
3837
4058
  ]
3838
4059
  };
3839
4060
  }
3840
- const { handleRunCodeReview: handleRunCodeReview2 } = await import("./review-pipeline-GHR3WFBI.js");
4061
+ const { handleRunCodeReview: handleRunCodeReview2 } = await import("./review-pipeline-76JHKGSV.js");
3841
4062
  const result = await handleRunCodeReview2({ path: projectPath, diff });
3842
4063
  const deepContent = result.content[0];
3843
4064
  if (!deepContent) throw new Error("Empty code review response");
@@ -3914,7 +4135,7 @@ async function handleCheckTaskIndependence(input) {
3914
4135
  try {
3915
4136
  const projectPath = sanitizePath(input.path);
3916
4137
  const store = await loadGraphStore(projectPath);
3917
- const { TaskIndependenceAnalyzer } = await import("./dist-M6BQODWC.js");
4138
+ const { TaskIndependenceAnalyzer } = await import("./dist-HXHWB7SV.js");
3918
4139
  const analyzer = new TaskIndependenceAnalyzer(store ?? void 0);
3919
4140
  const result = analyzer.analyze({
3920
4141
  tasks: input.tasks,
@@ -4002,7 +4223,7 @@ async function handlePredictConflicts(input) {
4002
4223
  try {
4003
4224
  const projectPath = sanitizePath(input.path);
4004
4225
  const store = await loadGraphStore(projectPath);
4005
- const { ConflictPredictor } = await import("./dist-M6BQODWC.js");
4226
+ const { ConflictPredictor } = await import("./dist-HXHWB7SV.js");
4006
4227
  const predictor = new ConflictPredictor(store ?? void 0);
4007
4228
  const result = predictor.predict({
4008
4229
  tasks: input.tasks,
@@ -4108,7 +4329,7 @@ async function handleDetectStaleConstraints(input) {
4108
4329
  isError: true
4109
4330
  };
4110
4331
  }
4111
- const { loadGraphStore: loadGraphStore2 } = await import("./graph-loader-KO4GJ5N2.js");
4332
+ const { loadGraphStore: loadGraphStore2 } = await import("./graph-loader-GJZ4FN4Y.js");
4112
4333
  const store = await loadGraphStore2(projectPath);
4113
4334
  if (!store) {
4114
4335
  return {
@@ -4129,7 +4350,7 @@ async function handleDetectStaleConstraints(input) {
4129
4350
  ]
4130
4351
  };
4131
4352
  }
4132
- const { detectStaleConstraints } = await import("./dist-WF4C7A4A.js");
4353
+ const { detectStaleConstraints } = await import("./dist-2B363XUH.js");
4133
4354
  const result = detectStaleConstraints(
4134
4355
  store,
4135
4356
  windowDays,
@@ -4156,6 +4377,76 @@ async function handleDetectStaleConstraints(input) {
4156
4377
  }
4157
4378
  }
4158
4379
 
4380
+ // src/mcp/tools/search-skills.ts
4381
+ var searchSkillsDefinition = {
4382
+ name: "search_skills",
4383
+ description: "Search the skill catalog for domain-specific skills. Returns ranked results based on keyword and stack-signal matching. Use this to discover catalog skills that are not loaded as slash commands.",
4384
+ inputSchema: {
4385
+ type: "object",
4386
+ properties: {
4387
+ query: {
4388
+ type: "string",
4389
+ description: "Natural language or keyword query to search for skills"
4390
+ },
4391
+ path: {
4392
+ type: "string",
4393
+ description: "Project root path (defaults to cwd)"
4394
+ },
4395
+ platform: {
4396
+ type: "string",
4397
+ enum: ["claude-code", "gemini-cli"],
4398
+ description: "Target platform (defaults to claude-code)"
4399
+ }
4400
+ },
4401
+ required: ["query"]
4402
+ }
4403
+ };
4404
+ async function handleSearchSkills(input) {
4405
+ const query = input.query;
4406
+ const projectRoot = input.path || process.cwd();
4407
+ const platform = input.platform || "claude-code";
4408
+ const configResult = resolveConfig();
4409
+ const tierOverrides = configResult.ok ? configResult.value.skills?.tierOverrides : void 0;
4410
+ const index = loadOrRebuildIndex(platform, projectRoot, tierOverrides);
4411
+ const profile = loadOrGenerateProfile(projectRoot);
4412
+ const queryTerms = query.toLowerCase().split(/\s+/).filter((t) => t.length > 2);
4413
+ const results = [];
4414
+ for (const [name, entry] of Object.entries(index.skills)) {
4415
+ const matchedKeywords = entry.keywords.filter(
4416
+ (kw) => queryTerms.some(
4417
+ (term) => kw.toLowerCase().includes(term.toLowerCase()) || term.toLowerCase().includes(kw.toLowerCase())
4418
+ )
4419
+ );
4420
+ const keywordScore = queryTerms.length > 0 ? matchedKeywords.length / queryTerms.length : 0;
4421
+ let stackScore = 0;
4422
+ if (entry.stackSignals.length > 0) {
4423
+ const matchedSignals = entry.stackSignals.filter((signal) => profile.signals[signal]);
4424
+ stackScore = matchedSignals.length / entry.stackSignals.length;
4425
+ }
4426
+ const score = 0.6 * keywordScore + 0.4 * stackScore;
4427
+ if (score > 0 || queryTerms.length === 0) {
4428
+ results.push({
4429
+ name,
4430
+ description: entry.description,
4431
+ keywords: entry.keywords,
4432
+ phases: entry.phases,
4433
+ score: Math.round(score * 100) / 100,
4434
+ source: entry.source
4435
+ });
4436
+ }
4437
+ }
4438
+ results.sort((a, b) => b.score - a.score);
4439
+ const top5 = results.slice(0, 5);
4440
+ return {
4441
+ content: [
4442
+ {
4443
+ type: "text",
4444
+ text: JSON.stringify({ results: top5 }, null, 2)
4445
+ }
4446
+ ]
4447
+ };
4448
+ }
4449
+
4159
4450
  // src/mcp/server.ts
4160
4451
  var TOOL_DEFINITIONS = [
4161
4452
  validateToolDefinition,
@@ -4202,7 +4493,8 @@ var TOOL_DEFINITIONS = [
4202
4493
  askGraphDefinition,
4203
4494
  checkTaskIndependenceDefinition,
4204
4495
  predictConflictsDefinition,
4205
- detectStaleConstraintsDefinition
4496
+ detectStaleConstraintsDefinition,
4497
+ searchSkillsDefinition
4206
4498
  ];
4207
4499
  var TOOL_HANDLERS = {
4208
4500
  validate_project: handleValidateProject,
@@ -4249,7 +4541,8 @@ var TOOL_HANDLERS = {
4249
4541
  ask_graph: handleAskGraph,
4250
4542
  check_task_independence: handleCheckTaskIndependence,
4251
4543
  predict_conflicts: handlePredictConflicts,
4252
- detect_stale_constraints: handleDetectStaleConstraints
4544
+ detect_stale_constraints: handleDetectStaleConstraints,
4545
+ search_skills: handleSearchSkills
4253
4546
  };
4254
4547
  var RESOURCE_DEFINITIONS = [
4255
4548
  {
@@ -4340,7 +4633,7 @@ function createHarnessServer(projectRoot) {
4340
4633
  shouldRunCheck,
4341
4634
  readCheckState,
4342
4635
  spawnBackgroundCheck
4343
- } = await import("./dist-WF4C7A4A.js");
4636
+ } = await import("./dist-2B363XUH.js");
4344
4637
  const { CLI_VERSION: version } = await import("./version-KFFPOQAX.js");
4345
4638
  let CLI_VERSION = version;
4346
4639
  let configInterval;