@harness-engineering/cli 1.26.0 → 1.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (266) hide show
  1. package/dist/agents/skills/README.md +1 -0
  2. package/dist/agents/skills/claude-code/cleanup-dead-code/SKILL.md +3 -1
  3. package/dist/agents/skills/claude-code/detect-doc-drift/SKILL.md +3 -1
  4. package/dist/agents/skills/claude-code/harness-architecture-advisor/SKILL.md +4 -0
  5. package/dist/agents/skills/claude-code/harness-autopilot/SKILL.md +55 -24
  6. package/dist/agents/skills/claude-code/harness-brainstorming/SKILL.md +49 -10
  7. package/dist/agents/skills/claude-code/harness-code-review/SKILL.md +21 -6
  8. package/dist/agents/skills/claude-code/harness-codebase-cleanup/SKILL.md +2 -0
  9. package/dist/agents/skills/claude-code/harness-debugging/SKILL.md +13 -1
  10. package/dist/agents/skills/claude-code/harness-dependency-health/SKILL.md +4 -0
  11. package/dist/agents/skills/claude-code/harness-execution/SKILL.md +22 -6
  12. package/dist/agents/skills/claude-code/harness-impact-analysis/SKILL.md +2 -0
  13. package/dist/agents/skills/claude-code/harness-integration/SKILL.md +560 -0
  14. package/dist/agents/skills/claude-code/harness-integration/skill.yaml +65 -0
  15. package/dist/agents/skills/claude-code/harness-integrity/SKILL.md +2 -0
  16. package/dist/agents/skills/claude-code/harness-onboarding/SKILL.md +4 -0
  17. package/dist/agents/skills/claude-code/harness-perf/SKILL.md +9 -7
  18. package/dist/agents/skills/claude-code/harness-planning/SKILL.md +102 -11
  19. package/dist/agents/skills/claude-code/harness-refactoring/SKILL.md +13 -4
  20. package/dist/agents/skills/claude-code/harness-security-scan/SKILL.md +3 -1
  21. package/dist/agents/skills/claude-code/harness-soundness-review/SKILL.md +4 -0
  22. package/dist/agents/skills/claude-code/harness-tdd/SKILL.md +5 -2
  23. package/dist/agents/skills/claude-code/harness-verification/SKILL.md +4 -0
  24. package/dist/agents/skills/claude-code/initialize-harness-project/SKILL.md +22 -6
  25. package/dist/agents/skills/claude-code/initialize-harness-project/skill.yaml +2 -1
  26. package/dist/agents/skills/claude-code/initialize-test-suite-project/SKILL.md +415 -0
  27. package/dist/agents/skills/claude-code/initialize-test-suite-project/skill.yaml +35 -0
  28. package/dist/agents/skills/codex/cleanup-dead-code/SKILL.md +3 -1
  29. package/dist/agents/skills/codex/detect-doc-drift/SKILL.md +3 -1
  30. package/dist/agents/skills/codex/harness-architecture-advisor/SKILL.md +4 -0
  31. package/dist/agents/skills/codex/harness-autopilot/SKILL.md +55 -24
  32. package/dist/agents/skills/codex/harness-brainstorming/SKILL.md +49 -10
  33. package/dist/agents/skills/codex/harness-code-review/SKILL.md +21 -6
  34. package/dist/agents/skills/codex/harness-codebase-cleanup/SKILL.md +2 -0
  35. package/dist/agents/skills/codex/harness-debugging/SKILL.md +13 -1
  36. package/dist/agents/skills/codex/harness-dependency-health/SKILL.md +4 -0
  37. package/dist/agents/skills/codex/harness-execution/SKILL.md +22 -6
  38. package/dist/agents/skills/codex/harness-impact-analysis/SKILL.md +2 -0
  39. package/dist/agents/skills/codex/harness-integration/SKILL.md +560 -0
  40. package/dist/agents/skills/codex/harness-integration/skill.yaml +65 -0
  41. package/dist/agents/skills/codex/harness-integrity/SKILL.md +2 -0
  42. package/dist/agents/skills/codex/harness-onboarding/SKILL.md +4 -0
  43. package/dist/agents/skills/codex/harness-perf/SKILL.md +9 -7
  44. package/dist/agents/skills/codex/harness-planning/SKILL.md +102 -11
  45. package/dist/agents/skills/codex/harness-refactoring/SKILL.md +13 -4
  46. package/dist/agents/skills/codex/harness-security-scan/SKILL.md +3 -1
  47. package/dist/agents/skills/codex/harness-soundness-review/SKILL.md +4 -0
  48. package/dist/agents/skills/codex/harness-tdd/SKILL.md +5 -2
  49. package/dist/agents/skills/codex/harness-verification/SKILL.md +4 -0
  50. package/dist/agents/skills/codex/initialize-harness-project/SKILL.md +22 -6
  51. package/dist/agents/skills/codex/initialize-harness-project/skill.yaml +2 -1
  52. package/dist/agents/skills/codex/initialize-test-suite-project/SKILL.md +415 -0
  53. package/dist/agents/skills/codex/initialize-test-suite-project/skill.yaml +35 -0
  54. package/dist/agents/skills/cursor/cleanup-dead-code/SKILL.md +3 -1
  55. package/dist/agents/skills/cursor/detect-doc-drift/SKILL.md +3 -1
  56. package/dist/agents/skills/cursor/harness-architecture-advisor/SKILL.md +4 -0
  57. package/dist/agents/skills/cursor/harness-autopilot/SKILL.md +55 -24
  58. package/dist/agents/skills/cursor/harness-brainstorming/SKILL.md +49 -10
  59. package/dist/agents/skills/cursor/harness-code-review/SKILL.md +21 -6
  60. package/dist/agents/skills/cursor/harness-codebase-cleanup/SKILL.md +2 -0
  61. package/dist/agents/skills/cursor/harness-debugging/SKILL.md +13 -1
  62. package/dist/agents/skills/cursor/harness-dependency-health/SKILL.md +4 -0
  63. package/dist/agents/skills/cursor/harness-execution/SKILL.md +22 -6
  64. package/dist/agents/skills/cursor/harness-impact-analysis/SKILL.md +2 -0
  65. package/dist/agents/skills/cursor/harness-integration/SKILL.md +560 -0
  66. package/dist/agents/skills/cursor/harness-integration/skill.yaml +65 -0
  67. package/dist/agents/skills/cursor/harness-integrity/SKILL.md +2 -0
  68. package/dist/agents/skills/cursor/harness-onboarding/SKILL.md +4 -0
  69. package/dist/agents/skills/cursor/harness-perf/SKILL.md +9 -7
  70. package/dist/agents/skills/cursor/harness-planning/SKILL.md +102 -11
  71. package/dist/agents/skills/cursor/harness-refactoring/SKILL.md +13 -4
  72. package/dist/agents/skills/cursor/harness-security-scan/SKILL.md +3 -1
  73. package/dist/agents/skills/cursor/harness-soundness-review/SKILL.md +4 -0
  74. package/dist/agents/skills/cursor/harness-tdd/SKILL.md +5 -2
  75. package/dist/agents/skills/cursor/harness-verification/SKILL.md +4 -0
  76. package/dist/agents/skills/cursor/initialize-harness-project/SKILL.md +22 -6
  77. package/dist/agents/skills/cursor/initialize-harness-project/skill.yaml +2 -1
  78. package/dist/agents/skills/cursor/initialize-test-suite-project/SKILL.md +415 -0
  79. package/dist/agents/skills/cursor/initialize-test-suite-project/skill.yaml +35 -0
  80. package/dist/agents/skills/gemini-cli/cleanup-dead-code/SKILL.md +3 -1
  81. package/dist/agents/skills/gemini-cli/detect-doc-drift/SKILL.md +3 -1
  82. package/dist/agents/skills/gemini-cli/harness-architecture-advisor/SKILL.md +4 -0
  83. package/dist/agents/skills/gemini-cli/harness-autopilot/SKILL.md +55 -24
  84. package/dist/agents/skills/gemini-cli/harness-brainstorming/SKILL.md +49 -10
  85. package/dist/agents/skills/gemini-cli/harness-code-review/SKILL.md +21 -6
  86. package/dist/agents/skills/gemini-cli/harness-codebase-cleanup/SKILL.md +2 -0
  87. package/dist/agents/skills/gemini-cli/harness-debugging/SKILL.md +13 -1
  88. package/dist/agents/skills/gemini-cli/harness-dependency-health/SKILL.md +4 -0
  89. package/dist/agents/skills/gemini-cli/harness-execution/SKILL.md +22 -6
  90. package/dist/agents/skills/gemini-cli/harness-impact-analysis/SKILL.md +2 -0
  91. package/dist/agents/skills/gemini-cli/harness-integration/SKILL.md +560 -0
  92. package/dist/agents/skills/gemini-cli/harness-integration/skill.yaml +65 -0
  93. package/dist/agents/skills/gemini-cli/harness-integrity/SKILL.md +2 -0
  94. package/dist/agents/skills/gemini-cli/harness-onboarding/SKILL.md +4 -0
  95. package/dist/agents/skills/gemini-cli/harness-perf/SKILL.md +9 -7
  96. package/dist/agents/skills/gemini-cli/harness-planning/SKILL.md +102 -11
  97. package/dist/agents/skills/gemini-cli/harness-refactoring/SKILL.md +13 -4
  98. package/dist/agents/skills/gemini-cli/harness-security-scan/SKILL.md +3 -1
  99. package/dist/agents/skills/gemini-cli/harness-soundness-review/SKILL.md +4 -0
  100. package/dist/agents/skills/gemini-cli/harness-tdd/SKILL.md +5 -2
  101. package/dist/agents/skills/gemini-cli/harness-verification/SKILL.md +4 -0
  102. package/dist/agents/skills/gemini-cli/initialize-harness-project/SKILL.md +22 -6
  103. package/dist/agents/skills/gemini-cli/initialize-harness-project/skill.yaml +2 -1
  104. package/dist/agents/skills/gemini-cli/initialize-test-suite-project/SKILL.md +415 -0
  105. package/dist/agents/skills/gemini-cli/initialize-test-suite-project/skill.yaml +35 -0
  106. package/dist/agents/skills/tests/initialize-test-suite-project.test.ts +152 -0
  107. package/dist/{agents-md-OPOZA5L7.js → agents-md-2RN666DE.js} +3 -3
  108. package/dist/{architecture-PMVMO6SF.js → architecture-ZR33YKJB.js} +4 -4
  109. package/dist/{assess-project-ZW7EKNIT.js → assess-project-LLWWEQEV.js} +1 -1
  110. package/dist/bin/harness-mcp.js +18 -16
  111. package/dist/bin/harness.js +29 -28
  112. package/dist/{business-knowledge-6RHYJOB3.js → business-knowledge-EISPR7FU.js} +1 -1
  113. package/dist/{check-phase-gate-NTLAU3LO.js → check-phase-gate-ZVG56NT2.js} +4 -4
  114. package/dist/chunk-27AJKSQY.js +107 -0
  115. package/dist/{chunk-G6SYTGOH.js → chunk-2FOLD76X.js} +2 -2
  116. package/dist/{chunk-IFHAUFJX.js → chunk-3AJW7VQ3.js} +2 -2
  117. package/dist/{chunk-KXIAHHHP.js → chunk-3XMOWLK3.js} +2 -2
  118. package/dist/{chunk-Z2JORLRT.js → chunk-776JFSPK.js} +1 -1
  119. package/dist/{chunk-4KSKV5MK.js → chunk-A4ETL34H.js} +7 -2
  120. package/dist/{chunk-JWSVLC4I.js → chunk-BO4AJZRE.js} +1 -1
  121. package/dist/{chunk-UBRD5FH4.js → chunk-BZZNYHRY.js} +9 -9
  122. package/dist/{chunk-6SCA4NEZ.js → chunk-C7RPQWBG.js} +1 -1
  123. package/dist/{chunk-NVGQO4VM.js → chunk-CJYNZMOP.js} +8 -8
  124. package/dist/{chunk-7JNZXJKY.js → chunk-EGRQHLDM.js} +5 -5
  125. package/dist/{chunk-EXTWTJRF.js → chunk-EICASBYP.js} +1 -1
  126. package/dist/{chunk-RNAGPTKF.js → chunk-F3Y64VNF.js} +6 -6
  127. package/dist/{chunk-HAOBHL3W.js → chunk-FUS4OOGC.js} +1 -1
  128. package/dist/{chunk-VV2PJT4K.js → chunk-GAIOIINV.js} +1353 -707
  129. package/dist/{chunk-77EZGPSR.js → chunk-IBTHD2UA.js} +139 -78
  130. package/dist/{chunk-RC5ZY3EV.js → chunk-IOW3MW2K.js} +2 -2
  131. package/dist/{chunk-JZ6GORAK.js → chunk-L3Y7L4EG.js} +1 -1
  132. package/dist/{chunk-KFE2X7LG.js → chunk-MGPVA2EM.js} +27 -4
  133. package/dist/{chunk-JBJ4AVE4.js → chunk-Q5DKIL46.js} +3 -3
  134. package/dist/{chunk-NIOB6FTG.js → chunk-QTXW5TIS.js} +1 -1
  135. package/dist/{chunk-ZBQ3ZY75.js → chunk-SA57FVGX.js} +100 -60
  136. package/dist/{chunk-KSFUJT5B.js → chunk-SDDQPMZK.js} +1 -1
  137. package/dist/{chunk-QYSWNPXZ.js → chunk-SDPHFDQS.js} +1 -1
  138. package/dist/{chunk-FI3D6D7U.js → chunk-T7UZOJF4.js} +9 -9
  139. package/dist/{chunk-CAS3TS4Y.js → chunk-TCMVZ3B7.js} +1142 -348
  140. package/dist/{chunk-J3O64D2A.js → chunk-YZH4I4JO.js} +1 -1
  141. package/dist/{ci-workflow-H52EMCL6.js → ci-workflow-JFOL4YWW.js} +3 -3
  142. package/dist/{create-skill-6QWJHQYS.js → create-skill-4T5CBSJ2.js} +2 -2
  143. package/dist/{dist-PGQ32ZI7.js → dist-BZS2XRLG.js} +5 -1
  144. package/dist/{dist-TG63OKA5.js → dist-CPKL5Y2R.js} +2 -2
  145. package/dist/{docs-GP4VUSIB.js → docs-FUTRJQHA.js} +4 -4
  146. package/dist/{engine-KQG5RVXX.js → engine-FB3HCNVT.js} +3 -3
  147. package/dist/{entropy-RXESIYKC.js → entropy-FIEE4YDA.js} +3 -3
  148. package/dist/{feedback-HS7ZYXOU.js → feedback-7EC4T6XG.js} +1 -1
  149. package/dist/{generate-agent-definitions-I4B7CVOB.js → generate-agent-definitions-FOSFADNR.js} +4 -4
  150. package/dist/{graph-loader-TIVI6NQ7.js → graph-loader-QEI7SYOQ.js} +1 -1
  151. package/dist/hooks/adoption-tracker.js +36 -8
  152. package/dist/hooks/sentinel-pre.js +3 -2
  153. package/dist/hooks/telemetry-reporter.js +34 -15
  154. package/dist/index-builder-3AOQ3ZII.js +13 -0
  155. package/dist/index.d.ts +15 -0
  156. package/dist/index.js +31 -30
  157. package/dist/{loader-CWAH6B4H.js → loader-HXUOBTYA.js} +3 -3
  158. package/dist/mcp-ICXMTAD3.js +41 -0
  159. package/dist/{performance-WDW5WS3J.js → performance-TYXBCTR7.js} +4 -4
  160. package/dist/{review-pipeline-QOZGWCTY.js → review-pipeline-B4WPU6BQ.js} +3 -3
  161. package/dist/{runtime-SFEFRPLX.js → runtime-HQQNOARD.js} +3 -3
  162. package/dist/{scan-IJ7EYTF7.js → scan-TX55R6QS.js} +1 -1
  163. package/dist/{security-2K7UUK6T.js → security-25VFLIAO.js} +1 -1
  164. package/dist/templates/orchestrator/harness.orchestrator.md +18 -8
  165. package/dist/{validate-HXM6DXRZ.js → validate-EAVGKZQB.js} +4 -4
  166. package/dist/{validate-cross-check-ULQLEOME.js → validate-cross-check-SPL3H4O5.js} +3 -3
  167. package/package.json +14 -6
  168. package/dist/agents/commands/claude-code/harness/harness.md +0 -36
  169. package/dist/agents/commands/codex/AGENTS.md +0 -39
  170. package/dist/agents/commands/codex/harness/add-harness-component/SKILL.md +0 -204
  171. package/dist/agents/commands/codex/harness/add-harness-component/agents/openai.yaml +0 -3
  172. package/dist/agents/commands/codex/harness/cleanup-dead-code/SKILL.md +0 -257
  173. package/dist/agents/commands/codex/harness/cleanup-dead-code/agents/openai.yaml +0 -3
  174. package/dist/agents/commands/codex/harness/detect-doc-drift/SKILL.md +0 -191
  175. package/dist/agents/commands/codex/harness/detect-doc-drift/agents/openai.yaml +0 -3
  176. package/dist/agents/commands/codex/harness/enforce-architecture/SKILL.md +0 -289
  177. package/dist/agents/commands/codex/harness/enforce-architecture/agents/openai.yaml +0 -3
  178. package/dist/agents/commands/codex/harness/harness-architecture-advisor/SKILL.md +0 -442
  179. package/dist/agents/commands/codex/harness/harness-architecture-advisor/agents/openai.yaml +0 -3
  180. package/dist/agents/commands/codex/harness/harness-autopilot/SKILL.md +0 -929
  181. package/dist/agents/commands/codex/harness/harness-autopilot/agents/openai.yaml +0 -3
  182. package/dist/agents/commands/codex/harness/harness-brainstorming/SKILL.md +0 -418
  183. package/dist/agents/commands/codex/harness/harness-brainstorming/agents/openai.yaml +0 -3
  184. package/dist/agents/commands/codex/harness/harness-code-review/SKILL.md +0 -850
  185. package/dist/agents/commands/codex/harness/harness-code-review/agents/openai.yaml +0 -3
  186. package/dist/agents/commands/codex/harness/harness-codebase-cleanup/SKILL.md +0 -236
  187. package/dist/agents/commands/codex/harness/harness-codebase-cleanup/agents/openai.yaml +0 -3
  188. package/dist/agents/commands/codex/harness/harness-debugging/SKILL.md +0 -378
  189. package/dist/agents/commands/codex/harness/harness-debugging/agents/openai.yaml +0 -3
  190. package/dist/agents/commands/codex/harness/harness-dependency-health/SKILL.md +0 -190
  191. package/dist/agents/commands/codex/harness/harness-dependency-health/agents/openai.yaml +0 -3
  192. package/dist/agents/commands/codex/harness/harness-docs-pipeline/SKILL.md +0 -472
  193. package/dist/agents/commands/codex/harness/harness-docs-pipeline/agents/openai.yaml +0 -3
  194. package/dist/agents/commands/codex/harness/harness-execution/SKILL.md +0 -522
  195. package/dist/agents/commands/codex/harness/harness-execution/agents/openai.yaml +0 -3
  196. package/dist/agents/commands/codex/harness/harness-hotspot-detector/SKILL.md +0 -172
  197. package/dist/agents/commands/codex/harness/harness-hotspot-detector/agents/openai.yaml +0 -3
  198. package/dist/agents/commands/codex/harness/harness-impact-analysis/SKILL.md +0 -195
  199. package/dist/agents/commands/codex/harness/harness-impact-analysis/agents/openai.yaml +0 -3
  200. package/dist/agents/commands/codex/harness/harness-integrity/SKILL.md +0 -178
  201. package/dist/agents/commands/codex/harness/harness-integrity/agents/openai.yaml +0 -3
  202. package/dist/agents/commands/codex/harness/harness-onboarding/SKILL.md +0 -299
  203. package/dist/agents/commands/codex/harness/harness-onboarding/agents/openai.yaml +0 -3
  204. package/dist/agents/commands/codex/harness/harness-perf/SKILL.md +0 -272
  205. package/dist/agents/commands/codex/harness/harness-perf/agents/openai.yaml +0 -3
  206. package/dist/agents/commands/codex/harness/harness-planning/SKILL.md +0 -592
  207. package/dist/agents/commands/codex/harness/harness-planning/agents/openai.yaml +0 -3
  208. package/dist/agents/commands/codex/harness/harness-refactoring/SKILL.md +0 -181
  209. package/dist/agents/commands/codex/harness/harness-refactoring/agents/openai.yaml +0 -3
  210. package/dist/agents/commands/codex/harness/harness-release-readiness/SKILL.md +0 -701
  211. package/dist/agents/commands/codex/harness/harness-release-readiness/agents/openai.yaml +0 -3
  212. package/dist/agents/commands/codex/harness/harness-roadmap/SKILL.md +0 -607
  213. package/dist/agents/commands/codex/harness/harness-roadmap/agents/openai.yaml +0 -3
  214. package/dist/agents/commands/codex/harness/harness-security-scan/SKILL.md +0 -147
  215. package/dist/agents/commands/codex/harness/harness-security-scan/agents/openai.yaml +0 -3
  216. package/dist/agents/commands/codex/harness/harness-skill-authoring/SKILL.md +0 -314
  217. package/dist/agents/commands/codex/harness/harness-skill-authoring/agents/openai.yaml +0 -3
  218. package/dist/agents/commands/codex/harness/harness-soundness-review/SKILL.md +0 -1280
  219. package/dist/agents/commands/codex/harness/harness-soundness-review/agents/openai.yaml +0 -3
  220. package/dist/agents/commands/codex/harness/harness-supply-chain-audit/SKILL.md +0 -255
  221. package/dist/agents/commands/codex/harness/harness-supply-chain-audit/agents/openai.yaml +0 -3
  222. package/dist/agents/commands/codex/harness/harness-tdd/SKILL.md +0 -189
  223. package/dist/agents/commands/codex/harness/harness-tdd/agents/openai.yaml +0 -3
  224. package/dist/agents/commands/codex/harness/harness-test-advisor/SKILL.md +0 -171
  225. package/dist/agents/commands/codex/harness/harness-test-advisor/agents/openai.yaml +0 -3
  226. package/dist/agents/commands/codex/harness/harness-verification/SKILL.md +0 -433
  227. package/dist/agents/commands/codex/harness/harness-verification/agents/openai.yaml +0 -3
  228. package/dist/agents/commands/codex/harness/harness-verify/SKILL.md +0 -170
  229. package/dist/agents/commands/codex/harness/harness-verify/agents/openai.yaml +0 -3
  230. package/dist/agents/commands/codex/harness/initialize-harness-project/SKILL.md +0 -244
  231. package/dist/agents/commands/codex/harness/initialize-harness-project/agents/openai.yaml +0 -3
  232. package/dist/agents/commands/cursor/harness/add-harness-component.mdc +0 -200
  233. package/dist/agents/commands/cursor/harness/cleanup-dead-code.mdc +0 -253
  234. package/dist/agents/commands/cursor/harness/detect-doc-drift.mdc +0 -187
  235. package/dist/agents/commands/cursor/harness/enforce-architecture.mdc +0 -304
  236. package/dist/agents/commands/cursor/harness/harness-architecture-advisor.mdc +0 -457
  237. package/dist/agents/commands/cursor/harness/harness-autopilot.mdc +0 -924
  238. package/dist/agents/commands/cursor/harness/harness-brainstorming.mdc +0 -414
  239. package/dist/agents/commands/cursor/harness/harness-code-review.mdc +0 -865
  240. package/dist/agents/commands/cursor/harness/harness-codebase-cleanup.mdc +0 -232
  241. package/dist/agents/commands/cursor/harness/harness-debugging.mdc +0 -374
  242. package/dist/agents/commands/cursor/harness/harness-dependency-health.mdc +0 -187
  243. package/dist/agents/commands/cursor/harness/harness-docs-pipeline.mdc +0 -468
  244. package/dist/agents/commands/cursor/harness/harness-execution.mdc +0 -518
  245. package/dist/agents/commands/cursor/harness/harness-hotspot-detector.mdc +0 -169
  246. package/dist/agents/commands/cursor/harness/harness-impact-analysis.mdc +0 -192
  247. package/dist/agents/commands/cursor/harness/harness-integrity.mdc +0 -175
  248. package/dist/agents/commands/cursor/harness/harness-onboarding.mdc +0 -296
  249. package/dist/agents/commands/cursor/harness/harness-perf.mdc +0 -268
  250. package/dist/agents/commands/cursor/harness/harness-planning.mdc +0 -587
  251. package/dist/agents/commands/cursor/harness/harness-refactoring.mdc +0 -177
  252. package/dist/agents/commands/cursor/harness/harness-release-readiness.mdc +0 -697
  253. package/dist/agents/commands/cursor/harness/harness-roadmap.mdc +0 -603
  254. package/dist/agents/commands/cursor/harness/harness-security-scan.mdc +0 -162
  255. package/dist/agents/commands/cursor/harness/harness-skill-authoring.mdc +0 -300
  256. package/dist/agents/commands/cursor/harness/harness-soundness-review.mdc +0 -1275
  257. package/dist/agents/commands/cursor/harness/harness-supply-chain-audit.mdc +0 -252
  258. package/dist/agents/commands/cursor/harness/harness-tdd.mdc +0 -185
  259. package/dist/agents/commands/cursor/harness/harness-test-advisor.mdc +0 -168
  260. package/dist/agents/commands/cursor/harness/harness-verification.mdc +0 -429
  261. package/dist/agents/commands/cursor/harness/harness-verify.mdc +0 -167
  262. package/dist/agents/commands/cursor/harness/initialize-harness-project.mdc +0 -240
  263. package/dist/agents/commands/gemini-cli/harness/harness.toml +0 -277
  264. package/dist/hooks/profiles.ts +0 -48
  265. package/dist/mcp-KHK5KYER.js +0 -39
  266. package/dist/{chunk-RRHUCDRD.js → chunk-ZP5E7YET.js} +3 -3
@@ -1,10 +1,15 @@
1
+ import {
2
+ handleRunCodeReview,
3
+ runCodeReviewDefinition,
4
+ sortFindingsBySeverity
5
+ } from "./chunk-2FOLD76X.js";
1
6
  import {
2
7
  assessProjectDefinition,
3
8
  handleAssessProject
4
- } from "./chunk-RNAGPTKF.js";
9
+ } from "./chunk-F3Y64VNF.js";
5
10
  import {
6
11
  getBusinessKnowledgeResource
7
- } from "./chunk-RC5ZY3EV.js";
12
+ } from "./chunk-IOW3MW2K.js";
8
13
  import {
9
14
  analyzeDiffDefinition,
10
15
  createSelfReviewDefinition,
@@ -12,37 +17,35 @@ import {
12
17
  handleCreateSelfReview,
13
18
  handleRequestPeerReview,
14
19
  requestPeerReviewDefinition
15
- } from "./chunk-UBRD5FH4.js";
20
+ } from "./chunk-BZZNYHRY.js";
16
21
  import {
17
22
  getSecurityTrendsDefinition,
18
23
  handleGetSecurityTrends,
19
24
  handleRunSecurityScan,
20
25
  runSecurityScanDefinition
21
- } from "./chunk-IFHAUFJX.js";
26
+ } from "./chunk-3AJW7VQ3.js";
22
27
  import {
23
- handleRunCodeReview,
24
- runCodeReviewDefinition,
25
- sortFindingsBySeverity
26
- } from "./chunk-G6SYTGOH.js";
28
+ loadGraphStore
29
+ } from "./chunk-776JFSPK.js";
27
30
  import {
28
31
  handleValidateProject,
29
32
  validateToolDefinition
30
- } from "./chunk-JBJ4AVE4.js";
33
+ } from "./chunk-Q5DKIL46.js";
31
34
  import {
32
35
  checkDependenciesDefinition,
33
36
  handleCheckDependencies
34
- } from "./chunk-KFE2X7LG.js";
37
+ } from "./chunk-MGPVA2EM.js";
35
38
  import {
36
39
  resolveProjectConfig
37
- } from "./chunk-J3O64D2A.js";
40
+ } from "./chunk-YZH4I4JO.js";
38
41
  import {
39
42
  checkDocsDefinition,
40
43
  handleCheckDocs
41
- } from "./chunk-FI3D6D7U.js";
44
+ } from "./chunk-T7UZOJF4.js";
42
45
  import {
43
46
  detectEntropyDefinition,
44
47
  handleDetectEntropy
45
- } from "./chunk-7JNZXJKY.js";
48
+ } from "./chunk-EGRQHLDM.js";
46
49
  import {
47
50
  checkPerformanceDefinition,
48
51
  getCriticalPathsDefinition,
@@ -52,16 +55,19 @@ import {
52
55
  handleGetPerfBaselines,
53
56
  handleUpdatePerfBaselines,
54
57
  updatePerfBaselinesDefinition
55
- } from "./chunk-NVGQO4VM.js";
58
+ } from "./chunk-CJYNZMOP.js";
56
59
  import {
57
60
  resultToMcpResponse
58
61
  } from "./chunk-EPUKTTJZ.js";
59
62
  import {
60
63
  sanitizePath
61
64
  } from "./chunk-W6Y7ZW3Y.js";
65
+ import {
66
+ loadOrRebuildIndex
67
+ } from "./chunk-27AJKSQY.js";
62
68
  import {
63
69
  resolveConfig
64
- } from "./chunk-4KSKV5MK.js";
70
+ } from "./chunk-A4ETL34H.js";
65
71
  import {
66
72
  GENERATED_HEADER_CLAUDE,
67
73
  GENERATED_HEADER_CODEX,
@@ -72,7 +78,6 @@ import {
72
78
  computeSyncPlan
73
79
  } from "./chunk-3ISINLYT.js";
74
80
  import {
75
- resolveAllSkillsDirs,
76
81
  resolveCommunitySkillsDir,
77
82
  resolveGlobalCommunitySkillsDir,
78
83
  resolveGlobalSkillsDir,
@@ -81,9 +86,6 @@ import {
81
86
  resolveSkillsDir,
82
87
  resolveTemplatesDir
83
88
  } from "./chunk-6B6UN6SG.js";
84
- import {
85
- loadGraphStore
86
- } from "./chunk-Z2JORLRT.js";
87
89
  import {
88
90
  CompactionPipeline,
89
91
  DEFAULT_TOKEN_BUDGET,
@@ -101,7 +103,7 @@ import {
101
103
  scanForInjection,
102
104
  serializeEnvelope,
103
105
  writeTaint
104
- } from "./chunk-77EZGPSR.js";
106
+ } from "./chunk-IBTHD2UA.js";
105
107
  import {
106
108
  Err,
107
109
  Ok
@@ -109,6 +111,9 @@ import {
109
111
  import {
110
112
  SkillMetadataSchema
111
113
  } from "./chunk-HIK6OEUF.js";
114
+ import {
115
+ logger
116
+ } from "./chunk-EBJQ6N4M.js";
112
117
  import {
113
118
  CLIError,
114
119
  ExitCode,
@@ -701,7 +706,7 @@ ${skippedMsg}`
701
706
  async function handleInitProject(input) {
702
707
  const i = input;
703
708
  try {
704
- const { TemplateEngine } = await import("./engine-KQG5RVXX.js");
709
+ const { TemplateEngine } = await import("./engine-FB3HCNVT.js");
705
710
  const engine = new TemplateEngine(resolveTemplatesDir());
706
711
  const safePath = sanitizePath(i.path);
707
712
  const detected = tryDetectFramework(engine, safePath, i);
@@ -723,7 +728,7 @@ var listPersonasDefinition = {
723
728
  inputSchema: { type: "object", properties: {} }
724
729
  };
725
730
  async function handleListPersonas() {
726
- const { listPersonas } = await import("./loader-CWAH6B4H.js");
731
+ const { listPersonas } = await import("./loader-HXUOBTYA.js");
727
732
  const result = listPersonas(resolvePersonasDir());
728
733
  return resultToMcpResponse(result);
729
734
  }
@@ -747,10 +752,10 @@ async function handleGeneratePersonaArtifacts(input) {
747
752
  if (!/^[a-z0-9][a-z0-9._-]*$/i.test(input.name)) {
748
753
  return resultToMcpResponse(Err(new Error(`Invalid persona name: ${input.name}`)));
749
754
  }
750
- const { loadPersona } = await import("./loader-CWAH6B4H.js");
751
- const { generateRuntime } = await import("./runtime-SFEFRPLX.js");
752
- const { generateAgentsMd } = await import("./agents-md-OPOZA5L7.js");
753
- const { generateCIWorkflow } = await import("./ci-workflow-H52EMCL6.js");
755
+ const { loadPersona } = await import("./loader-HXUOBTYA.js");
756
+ const { generateRuntime } = await import("./runtime-HQQNOARD.js");
757
+ const { generateAgentsMd } = await import("./agents-md-2RN666DE.js");
758
+ const { generateCIWorkflow } = await import("./ci-workflow-JFOL4YWW.js");
754
759
  const personasDir = resolvePersonasDir();
755
760
  const filePath = path3.join(personasDir, `${input.name}.yaml`);
756
761
  if (!filePath.startsWith(personasDir)) {
@@ -805,7 +810,7 @@ async function handleRunPersona(input) {
805
810
  if (!/^[a-z0-9][a-z0-9._-]*$/i.test(input.persona)) {
806
811
  return resultToMcpResponse(Err(new Error(`Invalid persona name: ${input.persona}`)));
807
812
  }
808
- const { loadPersona } = await import("./loader-CWAH6B4H.js");
813
+ const { loadPersona } = await import("./loader-HXUOBTYA.js");
809
814
  const { runPersona } = await import("./runner-AAEF2TXY.js");
810
815
  const { executeSkill } = await import("./skill-executor-MOCUIAYS.js");
811
816
  const personasDir = resolvePersonasDir();
@@ -972,8 +977,8 @@ async function handleRunAgentTask(input) {
972
977
 
973
978
  // src/mcp/tools/skill.ts
974
979
  init_dist();
975
- import * as fs5 from "fs";
976
- import * as path6 from "path";
980
+ import * as fs4 from "fs";
981
+ import * as path5 from "path";
977
982
  import { parse as parseYaml } from "yaml";
978
983
 
979
984
  // src/skill/dispatcher.ts
@@ -1159,103 +1164,9 @@ function formatSuggestions(suggestions) {
1159
1164
  ].join("\n");
1160
1165
  }
1161
1166
 
1162
- // src/skill/index-builder.ts
1167
+ // src/skill/stack-profile.ts
1163
1168
  import fs3 from "fs";
1164
1169
  import path4 from "path";
1165
- import crypto from "crypto";
1166
- import { parse } from "yaml";
1167
- function computeSkillsDirHash(skillsDirs) {
1168
- const hash = crypto.createHash("sha256");
1169
- for (const dir of skillsDirs) {
1170
- if (!fs3.existsSync(dir)) continue;
1171
- for (const entry of fs3.readdirSync(dir, { withFileTypes: true })) {
1172
- if (!entry.isDirectory()) continue;
1173
- const yamlPath = path4.join(dir, entry.name, "skill.yaml");
1174
- if (!fs3.existsSync(yamlPath)) continue;
1175
- const stat = fs3.statSync(yamlPath);
1176
- hash.update(`${yamlPath}:${stat.mtimeMs}`);
1177
- }
1178
- }
1179
- return hash.digest("hex");
1180
- }
1181
- function parseSkillEntry(yamlPath, source, tierOverrides) {
1182
- const raw = fs3.readFileSync(yamlPath, "utf-8");
1183
- const parsed = parse(raw);
1184
- const result = SkillMetadataSchema.safeParse(parsed);
1185
- if (!result.success) return null;
1186
- const meta = result.data;
1187
- const effectiveTier = tierOverrides?.[meta.name] ?? meta.tier;
1188
- if (meta.internal) return null;
1189
- return {
1190
- tier: effectiveTier ?? 3,
1191
- type: meta.type,
1192
- description: meta.description,
1193
- keywords: meta.keywords ?? [],
1194
- stackSignals: meta.stack_signals ?? [],
1195
- cognitiveMode: meta.cognitive_mode,
1196
- phases: (meta.phases ?? []).map((p) => p.name),
1197
- paths: meta.paths ?? [],
1198
- relatedSkills: meta.related_skills ?? [],
1199
- source,
1200
- addresses: meta.addresses ?? [],
1201
- dependsOn: meta.depends_on ?? [],
1202
- ...meta.context_budget && {
1203
- contextBudget: {
1204
- maxTokens: meta.context_budget.max_tokens,
1205
- priority: meta.context_budget.priority
1206
- }
1207
- }
1208
- };
1209
- }
1210
- function scanDirectory(dir, source, index, tierOverrides) {
1211
- if (!fs3.existsSync(dir)) return;
1212
- for (const entry of fs3.readdirSync(dir, { withFileTypes: true })) {
1213
- if (!entry.isDirectory()) continue;
1214
- if (index.skills[entry.name]) continue;
1215
- const yamlPath = path4.join(dir, entry.name, "skill.yaml");
1216
- if (!fs3.existsSync(yamlPath)) continue;
1217
- try {
1218
- const parsed = parseSkillEntry(yamlPath, source, tierOverrides);
1219
- if (parsed) index.skills[entry.name] = parsed;
1220
- } catch {
1221
- continue;
1222
- }
1223
- }
1224
- }
1225
- function buildIndex(platform, _projectRoot, tierOverrides) {
1226
- const skillsDirs = resolveAllSkillsDirs(platform);
1227
- const sourceMap = ["project", "community", "bundled"];
1228
- const index = {
1229
- version: 1,
1230
- hash: computeSkillsDirHash(skillsDirs),
1231
- generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
1232
- skills: {}
1233
- };
1234
- for (let i = 0; i < skillsDirs.length; i++) {
1235
- scanDirectory(skillsDirs[i], sourceMap[i] ?? "bundled", index, tierOverrides);
1236
- }
1237
- return index;
1238
- }
1239
- function loadOrRebuildIndex(platform, projectRoot, tierOverrides) {
1240
- const indexPath = path4.join(projectRoot, ".harness", "skills-index.json");
1241
- const skillsDirs = resolveAllSkillsDirs(platform);
1242
- const currentHash = computeSkillsDirHash(skillsDirs);
1243
- if (fs3.existsSync(indexPath)) {
1244
- try {
1245
- const existing = JSON.parse(fs3.readFileSync(indexPath, "utf-8"));
1246
- if (existing.hash === currentHash) return existing;
1247
- } catch {
1248
- }
1249
- }
1250
- const index = buildIndex(platform, projectRoot, tierOverrides);
1251
- fs3.mkdirSync(path4.dirname(indexPath), { recursive: true });
1252
- fs3.writeFileSync(indexPath, JSON.stringify(index, null, 2));
1253
- return index;
1254
- }
1255
-
1256
- // src/skill/stack-profile.ts
1257
- import fs4 from "fs";
1258
- import path5 from "path";
1259
1170
  var SIGNAL_DOMAIN_MAP = {
1260
1171
  "prisma/schema.prisma": ["database"],
1261
1172
  "drizzle.config.ts": ["database"],
@@ -1314,8 +1225,8 @@ function generateStackProfile(projectRoot) {
1314
1225
  const signals = {};
1315
1226
  const domainSet = /* @__PURE__ */ new Set();
1316
1227
  for (const [pattern, domains] of Object.entries(SIGNAL_DOMAIN_MAP)) {
1317
- const fullPath = path5.join(projectRoot, pattern);
1318
- const exists = fs4.existsSync(fullPath);
1228
+ const fullPath = path4.join(projectRoot, pattern);
1229
+ const exists = fs3.existsSync(fullPath);
1319
1230
  signals[pattern] = exists;
1320
1231
  if (exists) {
1321
1232
  for (const domain of domains) domainSet.add(domain);
@@ -1328,23 +1239,23 @@ function generateStackProfile(projectRoot) {
1328
1239
  };
1329
1240
  }
1330
1241
  function loadOrGenerateProfile(projectRoot) {
1331
- const profilePath = path5.join(projectRoot, ".harness", "stack-profile.json");
1332
- if (fs4.existsSync(profilePath)) {
1242
+ const profilePath = path4.join(projectRoot, ".harness", "stack-profile.json");
1243
+ if (fs3.existsSync(profilePath)) {
1333
1244
  try {
1334
- return JSON.parse(fs4.readFileSync(profilePath, "utf-8"));
1245
+ return JSON.parse(fs3.readFileSync(profilePath, "utf-8"));
1335
1246
  } catch {
1336
1247
  }
1337
1248
  }
1338
1249
  const profile = generateStackProfile(projectRoot);
1339
- fs4.mkdirSync(path5.dirname(profilePath), { recursive: true });
1340
- fs4.writeFileSync(profilePath, JSON.stringify(profile, null, 2));
1250
+ fs3.mkdirSync(path4.dirname(profilePath), { recursive: true });
1251
+ fs3.writeFileSync(profilePath, JSON.stringify(profile, null, 2));
1341
1252
  return profile;
1342
1253
  }
1343
1254
 
1344
1255
  // src/mcp/tools/event-emitter.ts
1345
1256
  async function emitSkillEvent(projectPath, event) {
1346
1257
  try {
1347
- const { emitEvent } = await import("./dist-TG63OKA5.js");
1258
+ const { emitEvent } = await import("./dist-CPKL5Y2R.js");
1348
1259
  await emitEvent(projectPath, event);
1349
1260
  } catch {
1350
1261
  }
@@ -1379,18 +1290,18 @@ async function handleRunSkill(input) {
1379
1290
  if (!/^[a-z0-9][a-z0-9._-]*$/i.test(input.skill)) {
1380
1291
  return resultToMcpResponse(Err(new Error(`Invalid skill name: ${input.skill}`)));
1381
1292
  }
1382
- const skillDir = path6.join(skillsDir, input.skill);
1293
+ const skillDir = path5.join(skillsDir, input.skill);
1383
1294
  if (!skillDir.startsWith(skillsDir)) {
1384
1295
  return resultToMcpResponse(Err(new Error(`Invalid skill path: ${input.skill}`)));
1385
1296
  }
1386
- if (!fs5.existsSync(skillDir)) {
1297
+ if (!fs4.existsSync(skillDir)) {
1387
1298
  return resultToMcpResponse(Err(new Error(`Skill not found: ${input.skill}`)));
1388
1299
  }
1389
- const skillMdPath = path6.join(skillDir, "SKILL.md");
1390
- if (!fs5.existsSync(skillMdPath)) {
1300
+ const skillMdPath = path5.join(skillDir, "SKILL.md");
1301
+ if (!fs4.existsSync(skillMdPath)) {
1391
1302
  return resultToMcpResponse(Err(new Error(`SKILL.md not found for skill: ${input.skill}`)));
1392
1303
  }
1393
- let content = fs5.readFileSync(skillMdPath, "utf-8");
1304
+ let content = fs4.readFileSync(skillMdPath, "utf-8");
1394
1305
  const projectRoot = input.path ? sanitizePath(input.path) : process.cwd();
1395
1306
  const configResult = resolveConfig();
1396
1307
  const skillsConfig = configResult.ok ? configResult.value.skills : void 0;
@@ -1417,9 +1328,9 @@ async function handleRunSkill(input) {
1417
1328
  }
1418
1329
  if (input.path) {
1419
1330
  const projectPath = sanitizePath(input.path);
1420
- const stateFile = path6.join(projectPath, ".harness", "state.json");
1421
- if (fs5.existsSync(stateFile)) {
1422
- const stateContent = fs5.readFileSync(stateFile, "utf-8");
1331
+ const stateFile = path5.join(projectPath, ".harness", "state.json");
1332
+ if (fs4.existsSync(stateFile)) {
1333
+ const stateContent = fs4.readFileSync(stateFile, "utf-8");
1423
1334
  content += `
1424
1335
 
1425
1336
  ---
@@ -1430,10 +1341,10 @@ ${stateContent}
1430
1341
  `;
1431
1342
  }
1432
1343
  }
1433
- const skillYamlPath = path6.join(skillDir, "skill.yaml");
1434
- if (fs5.existsSync(skillYamlPath)) {
1344
+ const skillYamlPath = path5.join(skillDir, "skill.yaml");
1345
+ if (fs4.existsSync(skillYamlPath)) {
1435
1346
  try {
1436
- const rawYaml = fs5.readFileSync(skillYamlPath, "utf-8");
1347
+ const rawYaml = fs4.readFileSync(skillYamlPath, "utf-8");
1437
1348
  const skillMeta = parseYaml(rawYaml);
1438
1349
  if (skillMeta.type === "knowledge") {
1439
1350
  const boundary = content.indexOf("\n## Details");
@@ -1494,7 +1405,7 @@ var createSkillDefinition = {
1494
1405
  };
1495
1406
  async function handleCreateSkill(input) {
1496
1407
  try {
1497
- const { generateSkillFiles } = await import("./create-skill-6QWJHQYS.js");
1408
+ const { generateSkillFiles } = await import("./create-skill-4T5CBSJ2.js");
1498
1409
  const result = generateSkillFiles({
1499
1410
  name: input.name,
1500
1411
  description: input.description,
@@ -1516,22 +1427,22 @@ async function handleCreateSkill(input) {
1516
1427
  }
1517
1428
 
1518
1429
  // src/mcp/resources/skills.ts
1519
- import * as fs6 from "fs";
1520
- import * as path7 from "path";
1430
+ import * as fs5 from "fs";
1431
+ import * as path6 from "path";
1521
1432
  import * as yaml from "yaml";
1522
1433
  async function getSkillsResource(projectRoot) {
1523
- const skillsDir = path7.join(projectRoot, "agents", "skills", "claude-code");
1434
+ const skillsDir = path6.join(projectRoot, "agents", "skills", "claude-code");
1524
1435
  const skills = [];
1525
- if (!fs6.existsSync(skillsDir)) {
1436
+ if (!fs5.existsSync(skillsDir)) {
1526
1437
  return JSON.stringify(skills, null, 2);
1527
1438
  }
1528
- const entries = fs6.readdirSync(skillsDir, { withFileTypes: true });
1439
+ const entries = fs5.readdirSync(skillsDir, { withFileTypes: true });
1529
1440
  for (const entry of entries) {
1530
1441
  if (!entry.isDirectory()) continue;
1531
- const skillYamlPath = path7.join(skillsDir, entry.name, "skill.yaml");
1532
- if (!fs6.existsSync(skillYamlPath)) continue;
1442
+ const skillYamlPath = path6.join(skillsDir, entry.name, "skill.yaml");
1443
+ if (!fs5.existsSync(skillYamlPath)) continue;
1533
1444
  try {
1534
- const content = fs6.readFileSync(skillYamlPath, "utf-8");
1445
+ const content = fs5.readFileSync(skillYamlPath, "utf-8");
1535
1446
  const parsed = yaml.parse(content);
1536
1447
  skills.push({
1537
1448
  name: parsed.name,
@@ -1547,14 +1458,14 @@ async function getSkillsResource(projectRoot) {
1547
1458
  }
1548
1459
 
1549
1460
  // src/mcp/resources/rules.ts
1550
- import * as fs7 from "fs";
1551
- import * as path8 from "path";
1461
+ import * as fs6 from "fs";
1462
+ import * as path7 from "path";
1552
1463
  async function getRulesResource(projectRoot) {
1553
1464
  const rules = [];
1554
- const configPath = path8.join(projectRoot, "harness.config.json");
1555
- if (fs7.existsSync(configPath)) {
1465
+ const configPath = path7.join(projectRoot, "harness.config.json");
1466
+ if (fs6.existsSync(configPath)) {
1556
1467
  try {
1557
- const config = JSON.parse(fs7.readFileSync(configPath, "utf-8"));
1468
+ const config = JSON.parse(fs6.readFileSync(configPath, "utf-8"));
1558
1469
  if (config.layers) {
1559
1470
  rules.push({ type: "layer-enforcement", config: config.layers });
1560
1471
  }
@@ -1567,10 +1478,10 @@ async function getRulesResource(projectRoot) {
1567
1478
  } catch {
1568
1479
  }
1569
1480
  }
1570
- const linterPath = path8.join(projectRoot, ".harness", "linter.json");
1571
- if (fs7.existsSync(linterPath)) {
1481
+ const linterPath = path7.join(projectRoot, ".harness", "linter.json");
1482
+ if (fs6.existsSync(linterPath)) {
1572
1483
  try {
1573
- const linterConfig = JSON.parse(fs7.readFileSync(linterPath, "utf-8"));
1484
+ const linterConfig = JSON.parse(fs6.readFileSync(linterPath, "utf-8"));
1574
1485
  rules.push({ type: "linter", config: linterConfig });
1575
1486
  } catch {
1576
1487
  }
@@ -1579,28 +1490,28 @@ async function getRulesResource(projectRoot) {
1579
1490
  }
1580
1491
 
1581
1492
  // src/mcp/resources/project.ts
1582
- import * as fs8 from "fs";
1583
- import * as path9 from "path";
1493
+ import * as fs7 from "fs";
1494
+ import * as path8 from "path";
1584
1495
  async function getProjectResource(projectRoot) {
1585
- const agentsPath = path9.join(projectRoot, "AGENTS.md");
1586
- if (fs8.existsSync(agentsPath)) {
1587
- return fs8.readFileSync(agentsPath, "utf-8");
1496
+ const agentsPath = path8.join(projectRoot, "AGENTS.md");
1497
+ if (fs7.existsSync(agentsPath)) {
1498
+ return fs7.readFileSync(agentsPath, "utf-8");
1588
1499
  }
1589
1500
  return "# No AGENTS.md found";
1590
1501
  }
1591
1502
 
1592
1503
  // src/mcp/resources/learnings.ts
1593
- import * as fs9 from "fs";
1594
- import * as path10 from "path";
1504
+ import * as fs8 from "fs";
1505
+ import * as path9 from "path";
1595
1506
  async function getLearningsResource(projectRoot) {
1596
1507
  const sections = [];
1597
- const reviewPath = path10.join(projectRoot, ".harness", "review-learnings.md");
1598
- if (fs9.existsSync(reviewPath)) {
1599
- sections.push("## Review Learnings\n\n" + fs9.readFileSync(reviewPath, "utf-8"));
1508
+ const reviewPath = path9.join(projectRoot, ".harness", "review-learnings.md");
1509
+ if (fs8.existsSync(reviewPath)) {
1510
+ sections.push("## Review Learnings\n\n" + fs8.readFileSync(reviewPath, "utf-8"));
1600
1511
  }
1601
- const antiPath = path10.join(projectRoot, ".harness", "anti-patterns.md");
1602
- if (fs9.existsSync(antiPath)) {
1603
- sections.push("## Anti-Pattern Log\n\n" + fs9.readFileSync(antiPath, "utf-8"));
1512
+ const antiPath = path9.join(projectRoot, ".harness", "anti-patterns.md");
1513
+ if (fs8.existsSync(antiPath)) {
1514
+ sections.push("## Anti-Pattern Log\n\n" + fs8.readFileSync(antiPath, "utf-8"));
1604
1515
  }
1605
1516
  return sections.length > 0 ? sections.join("\n\n---\n\n") : "No learnings files found.";
1606
1517
  }
@@ -1610,14 +1521,14 @@ init_dist();
1610
1521
 
1611
1522
  // src/mcp/tools/roadmap-auto-sync.ts
1612
1523
  init_dist();
1613
- import * as fs10 from "fs";
1614
- import * as path11 from "path";
1524
+ import * as fs9 from "fs";
1525
+ import * as path10 from "path";
1615
1526
  async function autoSyncRoadmap(projectPath) {
1616
1527
  try {
1617
- const roadmapFile = path11.join(projectPath, "docs", "roadmap.md");
1618
- if (!fs10.existsSync(roadmapFile)) return;
1619
- const { parseRoadmap, serializeRoadmap, syncRoadmap, applySyncChanges } = await import("./dist-TG63OKA5.js");
1620
- const raw = fs10.readFileSync(roadmapFile, "utf-8");
1528
+ const roadmapFile = path10.join(projectPath, "docs", "roadmap.md");
1529
+ if (!fs9.existsSync(roadmapFile)) return;
1530
+ const { parseRoadmap, serializeRoadmap, syncRoadmap, applySyncChanges } = await import("./dist-CPKL5Y2R.js");
1531
+ const raw = fs9.readFileSync(roadmapFile, "utf-8");
1621
1532
  const parseResult = parseRoadmap(raw);
1622
1533
  if (!parseResult.ok) return;
1623
1534
  const roadmap = parseResult.value;
@@ -1627,7 +1538,7 @@ async function autoSyncRoadmap(projectPath) {
1627
1538
  return;
1628
1539
  }
1629
1540
  applySyncChanges(roadmap, syncResult.value);
1630
- fs10.writeFileSync(roadmapFile, serializeRoadmap(roadmap), "utf-8");
1541
+ fs9.writeFileSync(roadmapFile, serializeRoadmap(roadmap), "utf-8");
1631
1542
  await triggerExternalSync(projectPath, roadmapFile);
1632
1543
  } catch {
1633
1544
  }
@@ -1636,8 +1547,8 @@ async function triggerExternalSync(projectPath, roadmapFile) {
1636
1547
  try {
1637
1548
  const trackerConfig = loadTrackerSyncConfig(projectPath);
1638
1549
  if (!trackerConfig) return;
1639
- const projectEnvPath = path11.join(projectPath, ".env");
1640
- if (fs10.existsSync(projectEnvPath) && !process.env.GITHUB_TOKEN) {
1550
+ const projectEnvPath = path10.join(projectPath, ".env");
1551
+ if (fs9.existsSync(projectEnvPath) && !process.env.GITHUB_TOKEN) {
1641
1552
  const { config: loadDotenv } = await import("dotenv");
1642
1553
  loadDotenv({ path: projectEnvPath });
1643
1554
  }
@@ -1646,7 +1557,7 @@ async function triggerExternalSync(projectPath, roadmapFile) {
1646
1557
  console.warn("[roadmap-sync] GITHUB_TOKEN not found \u2014 external sync skipped");
1647
1558
  return;
1648
1559
  }
1649
- const { fullSync, GitHubIssuesSyncAdapter } = await import("./dist-TG63OKA5.js");
1560
+ const { fullSync, GitHubIssuesSyncAdapter } = await import("./dist-CPKL5Y2R.js");
1650
1561
  const adapter = new GitHubIssuesSyncAdapter({
1651
1562
  token,
1652
1563
  config: trackerConfig
@@ -1743,12 +1654,12 @@ var manageStateDefinition = {
1743
1654
  }
1744
1655
  };
1745
1656
  async function handleShow(projectPath, input) {
1746
- const { loadState } = await import("./dist-TG63OKA5.js");
1657
+ const { loadState } = await import("./dist-CPKL5Y2R.js");
1747
1658
  return resultToMcpResponse(await loadState(projectPath, input.stream, input.session));
1748
1659
  }
1749
1660
  async function handleLearn(projectPath, input) {
1750
1661
  if (!input.learning) return mcpError("Error: learning is required for learn action");
1751
- const { appendLearning } = await import("./dist-TG63OKA5.js");
1662
+ const { appendLearning } = await import("./dist-CPKL5Y2R.js");
1752
1663
  const result = await appendLearning(
1753
1664
  projectPath,
1754
1665
  input.learning,
@@ -1763,7 +1674,7 @@ async function handleLearn(projectPath, input) {
1763
1674
  async function handleFailure(projectPath, input) {
1764
1675
  if (!input.description) return mcpError("Error: description is required for failure action");
1765
1676
  if (!input.failureType) return mcpError("Error: failureType is required for failure action");
1766
- const { appendFailure } = await import("./dist-TG63OKA5.js");
1677
+ const { appendFailure } = await import("./dist-CPKL5Y2R.js");
1767
1678
  const result = await appendFailure(
1768
1679
  projectPath,
1769
1680
  input.description,
@@ -1782,19 +1693,19 @@ async function handleFailure(projectPath, input) {
1782
1693
  return resultToMcpResponse(Ok({ recorded: true }));
1783
1694
  }
1784
1695
  async function handleArchive(projectPath, input) {
1785
- const { archiveFailures } = await import("./dist-TG63OKA5.js");
1696
+ const { archiveFailures } = await import("./dist-CPKL5Y2R.js");
1786
1697
  const result = await archiveFailures(projectPath, input.stream, input.session);
1787
1698
  if (!result.ok) return resultToMcpResponse(result);
1788
1699
  return resultToMcpResponse(Ok({ archived: true }));
1789
1700
  }
1790
1701
  async function handleReset(projectPath, input) {
1791
- const { saveState, DEFAULT_STATE } = await import("./dist-TG63OKA5.js");
1702
+ const { saveState, DEFAULT_STATE } = await import("./dist-CPKL5Y2R.js");
1792
1703
  const result = await saveState(projectPath, { ...DEFAULT_STATE }, input.stream, input.session);
1793
1704
  if (!result.ok) return resultToMcpResponse(result);
1794
1705
  return resultToMcpResponse(Ok({ reset: true }));
1795
1706
  }
1796
1707
  async function handleGate(projectPath, input) {
1797
- const { runMechanicalGate } = await import("./dist-TG63OKA5.js");
1708
+ const { runMechanicalGate } = await import("./dist-CPKL5Y2R.js");
1798
1709
  const result = await runMechanicalGate(projectPath);
1799
1710
  if (result.ok) {
1800
1711
  await emitSkillEvent(projectPath, {
@@ -1814,7 +1725,7 @@ async function handleGate(projectPath, input) {
1814
1725
  }
1815
1726
  async function handleSaveHandoff(projectPath, input) {
1816
1727
  if (!input.handoff) return mcpError("Error: handoff is required for save-handoff action");
1817
- const { saveHandoff } = await import("./dist-TG63OKA5.js");
1728
+ const { saveHandoff } = await import("./dist-CPKL5Y2R.js");
1818
1729
  const result = await saveHandoff(
1819
1730
  projectPath,
1820
1731
  input.handoff,
@@ -1836,7 +1747,7 @@ async function handleSaveHandoff(projectPath, input) {
1836
1747
  return resultToMcpResponse(Ok({ saved: true }));
1837
1748
  }
1838
1749
  async function handleLoadHandoff(projectPath, input) {
1839
- const { loadHandoff } = await import("./dist-TG63OKA5.js");
1750
+ const { loadHandoff } = await import("./dist-CPKL5Y2R.js");
1840
1751
  return resultToMcpResponse(await loadHandoff(projectPath, input.stream, input.session));
1841
1752
  }
1842
1753
  async function handleAppendEntry(projectPath, input) {
@@ -1844,7 +1755,7 @@ async function handleAppendEntry(projectPath, input) {
1844
1755
  if (!input.authorSkill) return mcpError("Error: authorSkill is required for append_entry action");
1845
1756
  if (!input.content) return mcpError("Error: content is required for append_entry action");
1846
1757
  if (input.session) {
1847
- const { appendSessionEntry } = await import("./dist-TG63OKA5.js");
1758
+ const { appendSessionEntry } = await import("./dist-CPKL5Y2R.js");
1848
1759
  const result = await appendSessionEntry(
1849
1760
  projectPath,
1850
1761
  input.session,
@@ -1857,7 +1768,7 @@ async function handleAppendEntry(projectPath, input) {
1857
1768
  if (input.section !== "decisions") {
1858
1769
  return mcpError("Error: session is required for non-decisions sections");
1859
1770
  }
1860
- const { loadState, saveState } = await import("./dist-TG63OKA5.js");
1771
+ const { loadState, saveState } = await import("./dist-CPKL5Y2R.js");
1861
1772
  const lr = await loadState(projectPath, input.stream);
1862
1773
  if (!lr.ok) return resultToMcpResponse(lr);
1863
1774
  lr.value.decisions.push({
@@ -1875,7 +1786,7 @@ async function handleUpdateEntryStatus(projectPath, input) {
1875
1786
  if (!input.entryId) return mcpError("Error: entryId is required for update_entry_status action");
1876
1787
  if (!input.newStatus)
1877
1788
  return mcpError("Error: newStatus is required for update_entry_status action");
1878
- const { updateSessionEntryStatus } = await import("./dist-TG63OKA5.js");
1789
+ const { updateSessionEntryStatus } = await import("./dist-CPKL5Y2R.js");
1879
1790
  const result = await updateSessionEntryStatus(
1880
1791
  projectPath,
1881
1792
  input.session,
@@ -1888,7 +1799,7 @@ async function handleUpdateEntryStatus(projectPath, input) {
1888
1799
  async function handleReadSection(projectPath, input) {
1889
1800
  if (!input.session) return mcpError("Error: session is required for read_section action");
1890
1801
  if (!input.section) return mcpError("Error: section is required for read_section action");
1891
- const { readSessionSection } = await import("./dist-TG63OKA5.js");
1802
+ const { readSessionSection } = await import("./dist-CPKL5Y2R.js");
1892
1803
  const result = await readSessionSection(
1893
1804
  projectPath,
1894
1805
  input.session,
@@ -1898,13 +1809,13 @@ async function handleReadSection(projectPath, input) {
1898
1809
  }
1899
1810
  async function handleReadSections(projectPath, input) {
1900
1811
  if (!input.session) return mcpError("Error: session is required for read_sections action");
1901
- const { readSessionSections } = await import("./dist-TG63OKA5.js");
1812
+ const { readSessionSections } = await import("./dist-CPKL5Y2R.js");
1902
1813
  const result = await readSessionSections(projectPath, input.session);
1903
1814
  return resultToMcpResponse(result);
1904
1815
  }
1905
1816
  async function handleArchiveSession(projectPath, input) {
1906
1817
  if (!input.session) return mcpError("Error: session is required for archive_session action");
1907
- const { archiveSession } = await import("./dist-TG63OKA5.js");
1818
+ const { archiveSession } = await import("./dist-CPKL5Y2R.js");
1908
1819
  const result = await archiveSession(projectPath, input.session);
1909
1820
  if (!result.ok) return resultToMcpResponse(result);
1910
1821
  await autoSyncRoadmap(projectPath);
@@ -1984,7 +1895,7 @@ var listStreamsDefinition = {
1984
1895
  };
1985
1896
  async function handleListStreams(input) {
1986
1897
  try {
1987
- const { listStreams, loadStreamIndex } = await import("./dist-TG63OKA5.js");
1898
+ const { listStreams, loadStreamIndex } = await import("./dist-CPKL5Y2R.js");
1988
1899
  const projectPath = sanitizePath(input.path);
1989
1900
  const indexResult = await loadStreamIndex(projectPath);
1990
1901
  const streamsResult = await listStreams(projectPath);
@@ -2022,7 +1933,7 @@ var checkPhaseGateDefinition = {
2022
1933
  };
2023
1934
  async function handleCheckPhaseGate(input) {
2024
1935
  try {
2025
- const { runCheckPhaseGate } = await import("./check-phase-gate-NTLAU3LO.js");
1936
+ const { runCheckPhaseGate } = await import("./check-phase-gate-ZVG56NT2.js");
2026
1937
  const result = await runCheckPhaseGate({ cwd: sanitizePath(input.path) });
2027
1938
  if (result.ok) {
2028
1939
  return { content: [{ type: "text", text: JSON.stringify(result.value) }] };
@@ -2042,7 +1953,7 @@ async function handleCheckPhaseGate(input) {
2042
1953
  }
2043
1954
 
2044
1955
  // src/mcp/tools/cross-check.ts
2045
- import * as path12 from "path";
1956
+ import * as path11 from "path";
2046
1957
  var validateCrossCheckDefinition = {
2047
1958
  name: "validate_cross_check",
2048
1959
  description: "Validate plan-to-implementation coverage: checks that specs have plans and plans have implementations, detects staleness",
@@ -2078,15 +1989,15 @@ async function handleValidateCrossCheck(input) {
2078
1989
  };
2079
1990
  }
2080
1991
  try {
2081
- const { runCrossCheck } = await import("./validate-cross-check-ULQLEOME.js");
2082
- const specsDir = path12.resolve(projectPath, input.specsDir ?? "docs/specs");
1992
+ const { runCrossCheck } = await import("./validate-cross-check-SPL3H4O5.js");
1993
+ const specsDir = path11.resolve(projectPath, input.specsDir ?? "docs/specs");
2083
1994
  if (!specsDir.startsWith(projectPath)) {
2084
1995
  return {
2085
1996
  content: [{ type: "text", text: "Error: specsDir escapes project root" }],
2086
1997
  isError: true
2087
1998
  };
2088
1999
  }
2089
- const plansDir = path12.resolve(projectPath, input.plansDir ?? "docs/plans");
2000
+ const plansDir = path11.resolve(projectPath, input.plansDir ?? "docs/plans");
2090
2001
  if (!plansDir.startsWith(projectPath)) {
2091
2002
  return {
2092
2003
  content: [{ type: "text", text: "Error: plansDir escapes project root" }],
@@ -2120,15 +2031,15 @@ init_dist();
2120
2031
 
2121
2032
  // src/commands/generate-slash-commands.ts
2122
2033
  import { Command } from "commander";
2123
- import fs13 from "fs";
2124
- import path15 from "path";
2034
+ import fs12 from "fs";
2035
+ import path14 from "path";
2125
2036
  import os from "os";
2126
2037
  import readline from "readline";
2127
2038
 
2128
2039
  // src/slash-commands/normalize.ts
2129
- import fs11 from "fs";
2130
- import path13 from "path";
2131
- import { parse as parse3 } from "yaml";
2040
+ import fs10 from "fs";
2041
+ import path12 from "path";
2042
+ import { parse as parse2 } from "yaml";
2132
2043
 
2133
2044
  // src/slash-commands/normalize-name.ts
2134
2045
  function normalizeName(skillName) {
@@ -2147,11 +2058,11 @@ function normalizeName(skillName) {
2147
2058
  function readSkillYaml(yamlPath) {
2148
2059
  let raw;
2149
2060
  try {
2150
- raw = fs11.readFileSync(yamlPath, "utf-8");
2061
+ raw = fs10.readFileSync(yamlPath, "utf-8");
2151
2062
  } catch {
2152
2063
  return null;
2153
2064
  }
2154
- return SkillMetadataSchema.safeParse(parse3(raw));
2065
+ return SkillMetadataSchema.safeParse(parse2(raw));
2155
2066
  }
2156
2067
  var DERIVED_FROM_CLAUDE_CODE = ["cursor", "codex"];
2157
2068
  function shouldSkipSkill(meta, platforms) {
@@ -2211,10 +2122,10 @@ function buildProcessLines(meta) {
2211
2122
  ];
2212
2123
  }
2213
2124
  function buildSpec(meta, normalized, entry, skillsDir, source) {
2214
- const skillMdPath = path13.join(skillsDir, entry.name, "SKILL.md");
2215
- const skillMdContent = fs11.existsSync(skillMdPath) ? fs11.readFileSync(skillMdPath, "utf-8") : "";
2216
- const skillMdRelative = path13.relative(process.cwd(), skillMdPath).replaceAll("\\", "/");
2217
- const skillYamlRelative = path13.relative(process.cwd(), path13.join(skillsDir, entry.name, "skill.yaml")).replaceAll("\\", "/");
2125
+ const skillMdPath = path12.join(skillsDir, entry.name, "SKILL.md");
2126
+ const skillMdContent = fs10.existsSync(skillMdPath) ? fs10.readFileSync(skillMdPath, "utf-8") : "";
2127
+ const skillMdRelative = path12.relative(process.cwd(), skillMdPath).replaceAll("\\", "/");
2128
+ const skillYamlRelative = path12.relative(process.cwd(), path12.join(skillsDir, entry.name, "skill.yaml")).replaceAll("\\", "/");
2218
2129
  const args = (meta.cli?.args ?? []).map((a) => ({
2219
2130
  name: a.name,
2220
2131
  description: a.description ?? "",
@@ -2269,11 +2180,11 @@ function normalizeSkills(skillSources, platforms) {
2269
2180
  const specs = [];
2270
2181
  const nameMap = /* @__PURE__ */ new Map();
2271
2182
  for (const { dir: skillsDir, source } of skillSources) {
2272
- if (!fs11.existsSync(skillsDir)) continue;
2273
- const entries = fs11.readdirSync(skillsDir, { withFileTypes: true }).filter((d) => d.isDirectory());
2183
+ if (!fs10.existsSync(skillsDir)) continue;
2184
+ const entries = fs10.readdirSync(skillsDir, { withFileTypes: true }).filter((d) => d.isDirectory());
2274
2185
  for (const entry of entries) {
2275
- const yamlPath = path13.join(skillsDir, entry.name, "skill.yaml");
2276
- if (!fs11.existsSync(yamlPath)) continue;
2186
+ const yamlPath = path12.join(skillsDir, entry.name, "skill.yaml");
2187
+ if (!fs10.existsSync(yamlPath)) continue;
2277
2188
  const result = readSkillYaml(yamlPath);
2278
2189
  if (!result) continue;
2279
2190
  if (!result.success) {
@@ -2443,27 +2354,27 @@ function renderCodexAgentsMd(specs) {
2443
2354
  }
2444
2355
 
2445
2356
  // src/slash-commands/sync-codex.ts
2446
- import fs12 from "fs";
2447
- import path14 from "path";
2357
+ import fs11 from "fs";
2358
+ import path13 from "path";
2448
2359
  function computeCodexSync(outputDir, specs, dryRun) {
2449
2360
  const added = [];
2450
2361
  const updated = [];
2451
2362
  const unchanged = [];
2452
2363
  const specSkillNames = /* @__PURE__ */ new Set();
2453
2364
  for (const spec of specs) {
2454
- const mdPath = path14.join(spec.skillsBaseDir, spec.sourceDir, "SKILL.md");
2455
- const skillMd = fs12.existsSync(mdPath) ? fs12.readFileSync(mdPath, "utf-8") : "";
2456
- const skillDir = path14.join(outputDir, spec.skillYamlName);
2365
+ const mdPath = path13.join(spec.skillsBaseDir, spec.sourceDir, "SKILL.md");
2366
+ const skillMd = fs11.existsSync(mdPath) ? fs11.readFileSync(mdPath, "utf-8") : "";
2367
+ const skillDir = path13.join(outputDir, spec.skillYamlName);
2457
2368
  specSkillNames.add(spec.skillYamlName);
2458
2369
  const renderedSkillMd = renderCodexSkill(skillMd);
2459
2370
  const renderedOpenaiYaml = renderCodexOpenaiYaml(spec);
2460
- const existingSkillMdPath = path14.join(skillDir, "SKILL.md");
2461
- const existingOpenaiYamlPath = path14.join(skillDir, "agents", "openai.yaml");
2462
- if (!fs12.existsSync(skillDir)) {
2371
+ const existingSkillMdPath = path13.join(skillDir, "SKILL.md");
2372
+ const existingOpenaiYamlPath = path13.join(skillDir, "agents", "openai.yaml");
2373
+ if (!fs11.existsSync(skillDir)) {
2463
2374
  added.push(spec.skillYamlName);
2464
2375
  } else {
2465
- const existingSkillMd = fs12.existsSync(existingSkillMdPath) ? fs12.readFileSync(existingSkillMdPath, "utf-8") : "";
2466
- const existingOpenaiYaml = fs12.existsSync(existingOpenaiYamlPath) ? fs12.readFileSync(existingOpenaiYamlPath, "utf-8") : "";
2376
+ const existingSkillMd = fs11.existsSync(existingSkillMdPath) ? fs11.readFileSync(existingSkillMdPath, "utf-8") : "";
2377
+ const existingOpenaiYaml = fs11.existsSync(existingOpenaiYamlPath) ? fs11.readFileSync(existingOpenaiYamlPath, "utf-8") : "";
2467
2378
  if (existingSkillMd === renderedSkillMd && existingOpenaiYaml === renderedOpenaiYaml) {
2468
2379
  unchanged.push(spec.skillYamlName);
2469
2380
  } else {
@@ -2471,10 +2382,10 @@ function computeCodexSync(outputDir, specs, dryRun) {
2471
2382
  }
2472
2383
  }
2473
2384
  if (!dryRun && !unchanged.includes(spec.skillYamlName)) {
2474
- const agentsSubDir = path14.join(skillDir, "agents");
2475
- fs12.mkdirSync(agentsSubDir, { recursive: true });
2476
- fs12.writeFileSync(existingSkillMdPath, renderedSkillMd, "utf-8");
2477
- fs12.writeFileSync(existingOpenaiYamlPath, renderedOpenaiYaml, "utf-8");
2385
+ const agentsSubDir = path13.join(skillDir, "agents");
2386
+ fs11.mkdirSync(agentsSubDir, { recursive: true });
2387
+ fs11.writeFileSync(existingSkillMdPath, renderedSkillMd, "utf-8");
2388
+ fs11.writeFileSync(existingOpenaiYamlPath, renderedOpenaiYaml, "utf-8");
2478
2389
  }
2479
2390
  }
2480
2391
  const removed = detectCodexOrphans(outputDir, specSkillNames);
@@ -2482,13 +2393,13 @@ function computeCodexSync(outputDir, specs, dryRun) {
2482
2393
  }
2483
2394
  function detectCodexOrphans(outputDir, specSkillNames) {
2484
2395
  const removed = [];
2485
- if (!fs12.existsSync(outputDir)) return removed;
2486
- const existingDirs = fs12.readdirSync(outputDir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
2396
+ if (!fs11.existsSync(outputDir)) return removed;
2397
+ const existingDirs = fs11.readdirSync(outputDir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
2487
2398
  for (const dirName of existingDirs) {
2488
2399
  if (specSkillNames.has(dirName)) continue;
2489
- const skillMdPath = path14.join(outputDir, dirName, "SKILL.md");
2490
- if (fs12.existsSync(skillMdPath)) {
2491
- const content = fs12.readFileSync(skillMdPath, "utf-8");
2400
+ const skillMdPath = path13.join(outputDir, dirName, "SKILL.md");
2401
+ if (fs11.existsSync(skillMdPath)) {
2402
+ const content = fs11.readFileSync(skillMdPath, "utf-8");
2492
2403
  if (content.includes(GENERATED_HEADER_CODEX)) {
2493
2404
  removed.push(dirName);
2494
2405
  }
@@ -2500,19 +2411,19 @@ function detectCodexOrphans(outputDir, specSkillNames) {
2500
2411
  // src/commands/generate-slash-commands.ts
2501
2412
  function resolveOutputDir(platform, opts) {
2502
2413
  if (opts.output) {
2503
- return path15.join(opts.output, "harness");
2414
+ return path14.join(opts.output, "harness");
2504
2415
  }
2505
2416
  if (opts.global) {
2506
2417
  const home = os.homedir();
2507
- if (platform === "claude-code") return path15.join(home, ".claude", "commands", "harness");
2508
- if (platform === "gemini-cli") return path15.join(home, ".gemini", "commands", "harness");
2509
- if (platform === "cursor") return path15.join(home, ".cursor", "rules", "harness");
2510
- return path15.join(home, ".codex", "harness");
2418
+ if (platform === "claude-code") return path14.join(home, ".claude", "commands", "harness");
2419
+ if (platform === "gemini-cli") return path14.join(home, ".gemini", "commands", "harness");
2420
+ if (platform === "cursor") return path14.join(home, ".cursor", "rules", "harness");
2421
+ return path14.join(home, ".codex", "harness");
2511
2422
  }
2512
- if (platform === "claude-code") return path15.join("agents", "commands", "claude-code", "harness");
2513
- if (platform === "gemini-cli") return path15.join("agents", "commands", "gemini-cli", "harness");
2514
- if (platform === "cursor") return path15.join("agents", "commands", "cursor", "harness");
2515
- return path15.join("agents", "commands", "codex", "harness");
2423
+ if (platform === "claude-code") return path14.join("agents", "commands", "claude-code", "harness");
2424
+ if (platform === "gemini-cli") return path14.join("agents", "commands", "gemini-cli", "harness");
2425
+ if (platform === "cursor") return path14.join("agents", "commands", "cursor", "harness");
2426
+ return path14.join("agents", "commands", "codex", "harness");
2516
2427
  }
2517
2428
  async function confirmDeletion(files) {
2518
2429
  const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
@@ -2528,8 +2439,8 @@ function resolveSkillSources(opts) {
2528
2439
  const sources = [];
2529
2440
  const seenPaths = /* @__PURE__ */ new Set();
2530
2441
  function addSource(dir, source) {
2531
- const resolved = path15.resolve(dir);
2532
- if (!seenPaths.has(resolved) && fs13.existsSync(dir)) {
2442
+ const resolved = path14.resolve(dir);
2443
+ if (!seenPaths.has(resolved) && fs12.existsSync(dir)) {
2533
2444
  seenPaths.add(resolved);
2534
2445
  sources.push({ dir, source });
2535
2446
  }
@@ -2556,32 +2467,32 @@ function resolveAbsoluteExecutionContext(spec) {
2556
2467
  ...spec,
2557
2468
  prompt: {
2558
2469
  ...spec.prompt,
2559
- executionContext: spec.prompt.executionContext.split("\n").map((line) => line.startsWith("@") ? `@${path15.resolve(line.slice(1))}` : line).join("\n")
2470
+ executionContext: spec.prompt.executionContext.split("\n").map((line) => line.startsWith("@") ? `@${path14.resolve(line.slice(1))}` : line).join("\n")
2560
2471
  }
2561
2472
  };
2562
2473
  }
2563
2474
  function renderSpec(platform, spec, useAbsolutePaths) {
2564
2475
  if (platform === "cursor") {
2565
- const mdPath2 = path15.join(spec.skillsBaseDir, spec.sourceDir, "SKILL.md");
2566
- const skillMd = fs13.existsSync(mdPath2) ? fs13.readFileSync(mdPath2, "utf-8") : "";
2476
+ const mdPath2 = path14.join(spec.skillsBaseDir, spec.sourceDir, "SKILL.md");
2477
+ const skillMd = fs12.existsSync(mdPath2) ? fs12.readFileSync(mdPath2, "utf-8") : "";
2567
2478
  return [`${spec.skillYamlName}.mdc`, renderCursor(spec, skillMd, spec.cursor)];
2568
2479
  }
2569
2480
  if (platform === "claude-code") {
2570
2481
  const renderSpecValue = useAbsolutePaths ? resolveAbsoluteExecutionContext(spec) : spec;
2571
2482
  return [`${spec.name}.md`, renderClaudeCode(renderSpecValue)];
2572
2483
  }
2573
- const mdPath = path15.join(spec.skillsBaseDir, spec.sourceDir, "SKILL.md");
2574
- const yamlPath = path15.join(spec.skillsBaseDir, spec.sourceDir, "skill.yaml");
2575
- const mdContent = fs13.existsSync(mdPath) ? fs13.readFileSync(mdPath, "utf-8") : "";
2576
- const yamlContent = fs13.existsSync(yamlPath) ? fs13.readFileSync(yamlPath, "utf-8") : "";
2484
+ const mdPath = path14.join(spec.skillsBaseDir, spec.sourceDir, "SKILL.md");
2485
+ const yamlPath = path14.join(spec.skillsBaseDir, spec.sourceDir, "skill.yaml");
2486
+ const mdContent = fs12.existsSync(mdPath) ? fs12.readFileSync(mdPath, "utf-8") : "";
2487
+ const yamlContent = fs12.existsSync(yamlPath) ? fs12.readFileSync(yamlPath, "utf-8") : "";
2577
2488
  return [`${spec.name}.toml`, renderGemini(spec, mdContent, yamlContent)];
2578
2489
  }
2579
2490
  function generateForCodex(platform, outputDir, specs, dryRun) {
2580
2491
  const codexSync = computeCodexSync(outputDir, specs, dryRun);
2581
- const codexRoot = path15.dirname(outputDir);
2492
+ const codexRoot = path14.dirname(outputDir);
2582
2493
  if (!dryRun) {
2583
- fs13.mkdirSync(codexRoot, { recursive: true });
2584
- fs13.writeFileSync(path15.join(codexRoot, "AGENTS.md"), renderCodexAgentsMd(specs), "utf-8");
2494
+ fs12.mkdirSync(codexRoot, { recursive: true });
2495
+ fs12.writeFileSync(path14.join(codexRoot, "AGENTS.md"), renderCodexAgentsMd(specs), "utf-8");
2585
2496
  }
2586
2497
  return { platform, ...codexSync, outputDir };
2587
2498
  }
@@ -2612,9 +2523,9 @@ function generateForPlatform(platform, outputDir, specs, opts) {
2612
2523
  const allUpdated = [...plan.updated];
2613
2524
  const allRemoved = [...plan.removed];
2614
2525
  const allUnchanged = [...plan.unchanged];
2615
- const parentDir = path15.dirname(outputDir);
2526
+ const parentDir = path14.dirname(outputDir);
2616
2527
  for (const [ns, nsRendered] of customNamespaceRendered) {
2617
- const nsDir = path15.join(parentDir, ns);
2528
+ const nsDir = path14.join(parentDir, ns);
2618
2529
  const nsPlan = computeSyncPlan(nsDir, nsRendered);
2619
2530
  if (!opts.dryRun) {
2620
2531
  applySyncPlan(nsDir, nsRendered, nsPlan, false);
@@ -2664,13 +2575,13 @@ async function handleOrphanDeletion(results, opts) {
2664
2575
  const shouldDelete = opts.yes || await confirmDeletion(result.removed);
2665
2576
  if (!shouldDelete) continue;
2666
2577
  for (const filename of result.removed) {
2667
- const filePath = path15.join(result.outputDir, filename);
2668
- if (!fs13.existsSync(filePath)) continue;
2669
- const stat = fs13.statSync(filePath);
2578
+ const filePath = path14.join(result.outputDir, filename);
2579
+ if (!fs12.existsSync(filePath)) continue;
2580
+ const stat = fs12.statSync(filePath);
2670
2581
  if (stat.isDirectory()) {
2671
- fs13.rmSync(filePath, { recursive: true, force: true });
2582
+ fs12.rmSync(filePath, { recursive: true, force: true });
2672
2583
  } else {
2673
- fs13.unlinkSync(filePath);
2584
+ fs12.unlinkSync(filePath);
2674
2585
  }
2675
2586
  }
2676
2587
  }
@@ -2801,7 +2712,7 @@ async function handleGenerateSlashCommands(input) {
2801
2712
  // src/mcp/resources/state.ts
2802
2713
  async function getStateResource(projectRoot) {
2803
2714
  try {
2804
- const { loadState, migrateToStreams } = await import("./dist-TG63OKA5.js");
2715
+ const { loadState, migrateToStreams } = await import("./dist-CPKL5Y2R.js");
2805
2716
  await migrateToStreams(projectRoot);
2806
2717
  const result = await loadState(projectRoot);
2807
2718
  if (result.ok) {
@@ -2919,7 +2830,7 @@ async function handleQueryGraph(input) {
2919
2830
  const projectPath = sanitizePath(input.path);
2920
2831
  const store = await loadGraphStore(projectPath);
2921
2832
  if (!store) return graphNotFoundError();
2922
- const { ContextQL } = await import("./dist-PGQ32ZI7.js");
2833
+ const { ContextQL } = await import("./dist-BZS2XRLG.js");
2923
2834
  const cql = new ContextQL(store);
2924
2835
  const result = cql.execute({
2925
2836
  rootNodeIds: input.rootNodeIds,
@@ -3001,7 +2912,7 @@ async function handleSearchSimilar(input) {
3001
2912
  const projectPath = sanitizePath(input.path);
3002
2913
  const store = await loadGraphStore(projectPath);
3003
2914
  if (!store) return graphNotFoundError();
3004
- const { FusionLayer } = await import("./dist-PGQ32ZI7.js");
2915
+ const { FusionLayer } = await import("./dist-BZS2XRLG.js");
3005
2916
  const fusion = new FusionLayer(store);
3006
2917
  const results = fusion.search(input.query, input.topK ?? 10);
3007
2918
  if (input.mode === "summary") {
@@ -3056,7 +2967,7 @@ async function handleFindContextFor(input) {
3056
2967
  const projectPath = sanitizePath(input.path);
3057
2968
  const store = await loadGraphStore(projectPath);
3058
2969
  if (!store) return graphNotFoundError();
3059
- const { FusionLayer, ContextQL } = await import("./dist-PGQ32ZI7.js");
2970
+ const { FusionLayer, ContextQL } = await import("./dist-BZS2XRLG.js");
3060
2971
  const fusion = new FusionLayer(store);
3061
2972
  const cql = new ContextQL(store);
3062
2973
  const tokenBudget = input.tokenBudget ?? 4e3;
@@ -3161,7 +3072,7 @@ async function handleGetRelationships(input) {
3161
3072
  const projectPath = sanitizePath(input.path);
3162
3073
  const store = await loadGraphStore(projectPath);
3163
3074
  if (!store) return graphNotFoundError();
3164
- const { ContextQL } = await import("./dist-PGQ32ZI7.js");
3075
+ const { ContextQL } = await import("./dist-BZS2XRLG.js");
3165
3076
  const cql = new ContextQL(store);
3166
3077
  const direction = input.direction ?? "both";
3167
3078
  const bidirectional = direction === "both" || direction === "inbound";
@@ -3279,7 +3190,7 @@ async function handleGetImpact(input) {
3279
3190
  const projectPath = sanitizePath(input.path);
3280
3191
  const store = await loadGraphStore(projectPath);
3281
3192
  if (!store) return graphNotFoundError();
3282
- const { ContextQL } = await import("./dist-PGQ32ZI7.js");
3193
+ const { ContextQL } = await import("./dist-BZS2XRLG.js");
3283
3194
  let targetNodeId = input.nodeId;
3284
3195
  if (!targetNodeId && input.filePath) {
3285
3196
  const fileNodes = store.findNodes({ type: "file" });
@@ -3390,7 +3301,7 @@ async function handleGetImpact(input) {
3390
3301
  }
3391
3302
 
3392
3303
  // src/mcp/tools/graph/ingest-source.ts
3393
- import * as path16 from "path";
3304
+ import * as path15 from "path";
3394
3305
  var ingestSourceDefinition = {
3395
3306
  name: "ingest_source",
3396
3307
  description: "Ingest sources into the project knowledge graph. Supports code analysis, knowledge documents, git history, or all at once.",
@@ -3410,8 +3321,8 @@ var ingestSourceDefinition = {
3410
3321
  async function handleIngestSource(input) {
3411
3322
  try {
3412
3323
  const projectPath = sanitizePath(input.path);
3413
- const graphDir = path16.join(projectPath, ".harness", "graph");
3414
- const { GraphStore, CodeIngestor, TopologicalLinker, KnowledgeIngestor, GitIngestor } = await import("./dist-PGQ32ZI7.js");
3324
+ const graphDir = path15.join(projectPath, ".harness", "graph");
3325
+ const { GraphStore, CodeIngestor, TopologicalLinker, KnowledgeIngestor, GitIngestor } = await import("./dist-BZS2XRLG.js");
3415
3326
  const fs17 = await import("fs/promises");
3416
3327
  await fs17.mkdir(graphDir, { recursive: true });
3417
3328
  const store = new GraphStore();
@@ -3435,13 +3346,13 @@ async function handleIngestSource(input) {
3435
3346
  results.push(gitResult);
3436
3347
  }
3437
3348
  if (input.source === "business-signals" || input.source === "all") {
3438
- const { createExtractionRunner } = await import("./dist-PGQ32ZI7.js");
3439
- const extractedDir = path16.join(projectPath, ".harness", "knowledge", "extracted");
3349
+ const { createExtractionRunner } = await import("./dist-BZS2XRLG.js");
3350
+ const extractedDir = path15.join(projectPath, ".harness", "knowledge", "extracted");
3440
3351
  const signalsResult = await createExtractionRunner().run(projectPath, store, extractedDir);
3441
3352
  results.push(signalsResult);
3442
3353
  }
3443
3354
  if (input.source === "diagrams" || input.source === "all") {
3444
- const { DiagramParser } = await import("./dist-PGQ32ZI7.js");
3355
+ const { DiagramParser } = await import("./dist-BZS2XRLG.js");
3445
3356
  const diagramParser = new DiagramParser(store);
3446
3357
  const diagramResult = await diagramParser.ingest(projectPath);
3447
3358
  results.push(diagramResult);
@@ -3507,7 +3418,7 @@ async function handleDetectAnomalies(input) {
3507
3418
  const projectPath = sanitizePath(input.path);
3508
3419
  const store = await loadGraphStore(projectPath);
3509
3420
  if (!store) return graphNotFoundError();
3510
- const { GraphAnomalyAdapter } = await import("./dist-PGQ32ZI7.js");
3421
+ const { GraphAnomalyAdapter } = await import("./dist-BZS2XRLG.js");
3511
3422
  const adapter = new GraphAnomalyAdapter(store);
3512
3423
  const report = adapter.detect({
3513
3424
  ...input.threshold !== void 0 && { threshold: input.threshold },
@@ -3556,7 +3467,7 @@ async function handleAskGraph(input) {
3556
3467
  const projectPath = sanitizePath(input.path);
3557
3468
  const store = await loadGraphStore(projectPath);
3558
3469
  if (!store) return graphNotFoundError();
3559
- const { askGraph } = await import("./dist-PGQ32ZI7.js");
3470
+ const { askGraph } = await import("./dist-BZS2XRLG.js");
3560
3471
  const result = await askGraph(store, input.question);
3561
3472
  return {
3562
3473
  content: [{ type: "text", text: JSON.stringify(result) }]
@@ -3620,7 +3531,7 @@ async function handleComputeBlastRadius(input) {
3620
3531
  const projectPath = sanitizePath(input.path);
3621
3532
  const store = await loadGraphStore(projectPath);
3622
3533
  if (!store) return graphNotFoundError();
3623
- const { CascadeSimulator } = await import("./dist-PGQ32ZI7.js");
3534
+ const { CascadeSimulator } = await import("./dist-BZS2XRLG.js");
3624
3535
  let targetNodeId = input.nodeId;
3625
3536
  if (!targetNodeId && input.file) {
3626
3537
  const fileNodes = store.findNodes({ type: "file" });
@@ -3707,8 +3618,8 @@ async function handleComputeBlastRadius(input) {
3707
3618
  }
3708
3619
 
3709
3620
  // src/mcp/resources/graph.ts
3710
- import * as fs14 from "fs/promises";
3711
- import * as path17 from "path";
3621
+ import * as fs13 from "fs/promises";
3622
+ import * as path16 from "path";
3712
3623
  var MAX_ITEMS = 5e3;
3713
3624
  function formatStaleness(isoTimestamp) {
3714
3625
  const then = new Date(isoTimestamp).getTime();
@@ -3731,9 +3642,9 @@ function countByType(items) {
3731
3642
  return counts;
3732
3643
  }
3733
3644
  async function readLastScanTimestamp(projectRoot) {
3734
- const metadataPath = path17.join(projectRoot, ".harness", "graph", "metadata.json");
3645
+ const metadataPath = path16.join(projectRoot, ".harness", "graph", "metadata.json");
3735
3646
  try {
3736
- const raw = JSON.parse(await fs14.readFile(metadataPath, "utf-8"));
3647
+ const raw = JSON.parse(await fs13.readFile(metadataPath, "utf-8"));
3737
3648
  return raw.lastScanTimestamp ?? null;
3738
3649
  } catch {
3739
3650
  return null;
@@ -3821,7 +3732,7 @@ var generateAgentDefinitionsDefinition = {
3821
3732
  }
3822
3733
  };
3823
3734
  async function handleGenerateAgentDefinitions(input) {
3824
- const { generateAgentDefinitions } = await import("./generate-agent-definitions-I4B7CVOB.js");
3735
+ const { generateAgentDefinitions } = await import("./generate-agent-definitions-FOSFADNR.js");
3825
3736
  const platforms = input.platform === "all" || !input.platform ? ["claude-code", "gemini-cli"] : [input.platform];
3826
3737
  const results = generateAgentDefinitions({
3827
3738
  platforms: [...platforms],
@@ -3832,8 +3743,8 @@ async function handleGenerateAgentDefinitions(input) {
3832
3743
  }
3833
3744
 
3834
3745
  // src/mcp/tools/roadmap.ts
3835
- import * as fs15 from "fs";
3836
- import * as path18 from "path";
3746
+ import * as fs14 from "fs";
3747
+ import * as path17 from "path";
3837
3748
  var manageRoadmapDefinition = {
3838
3749
  name: "manage_roadmap",
3839
3750
  description: "Manage the project roadmap: show, add, update, remove, sync features, or query by filter. Reads and writes docs/roadmap.md.",
@@ -3892,21 +3803,21 @@ var manageRoadmapDefinition = {
3892
3803
  }
3893
3804
  };
3894
3805
  function roadmapPath(projectRoot) {
3895
- return path18.join(projectRoot, "docs", "roadmap.md");
3806
+ return path17.join(projectRoot, "docs", "roadmap.md");
3896
3807
  }
3897
3808
  function readRoadmapFile(projectRoot) {
3898
3809
  const filePath = roadmapPath(projectRoot);
3899
3810
  try {
3900
- return fs15.readFileSync(filePath, "utf-8");
3811
+ return fs14.readFileSync(filePath, "utf-8");
3901
3812
  } catch {
3902
3813
  return null;
3903
3814
  }
3904
3815
  }
3905
3816
  function writeRoadmapFile(projectRoot, content) {
3906
3817
  const filePath = roadmapPath(projectRoot);
3907
- const dir = path18.dirname(filePath);
3908
- fs15.mkdirSync(dir, { recursive: true });
3909
- fs15.writeFileSync(filePath, content, "utf-8");
3818
+ const dir = path17.dirname(filePath);
3819
+ fs14.mkdirSync(dir, { recursive: true });
3820
+ fs14.writeFileSync(filePath, content, "utf-8");
3910
3821
  }
3911
3822
  function roadmapNotFoundError() {
3912
3823
  return {
@@ -4149,7 +4060,7 @@ function shouldTriggerExternalSync(input, response) {
4149
4060
  }
4150
4061
  async function handleManageRoadmap(input) {
4151
4062
  try {
4152
- const { parseRoadmap, serializeRoadmap, syncRoadmap, applySyncChanges, assignFeature } = await import("./dist-TG63OKA5.js");
4063
+ const { parseRoadmap, serializeRoadmap, syncRoadmap, applySyncChanges, assignFeature } = await import("./dist-CPKL5Y2R.js");
4153
4064
  const { Ok: Ok2 } = await import("./dist-3EWNRFFQ.js");
4154
4065
  const projectPath = sanitizePath(input.path);
4155
4066
  const deps = {
@@ -4588,7 +4499,7 @@ async function handleTransition(validInput, projectPath, id) {
4588
4499
  const transition = transitionResult.data;
4589
4500
  const prompt = renderTransition(transition);
4590
4501
  try {
4591
- const { saveHandoff } = await import("./dist-TG63OKA5.js");
4502
+ const { saveHandoff } = await import("./dist-CPKL5Y2R.js");
4592
4503
  await saveHandoff(
4593
4504
  projectPath,
4594
4505
  {
@@ -4669,7 +4580,7 @@ async function handleEmitInteraction(input) {
4669
4580
  }
4670
4581
  async function recordInteraction(projectPath, id, type, decision, stream) {
4671
4582
  try {
4672
- const { loadState, saveState } = await import("./dist-TG63OKA5.js");
4583
+ const { loadState, saveState } = await import("./dist-CPKL5Y2R.js");
4673
4584
  const stateResult = await loadState(projectPath, stream);
4674
4585
  if (stateResult.ok) {
4675
4586
  const state = stateResult.value;
@@ -4827,13 +4738,13 @@ async function handleGatherContext(input) {
4827
4738
  };
4828
4739
  }
4829
4740
  const includeSet = new Set(
4830
- input.include ?? ["state", "learnings", "handoff", "graph", "validation"]
4741
+ input.include ?? ["state", "learnings", "handoff", "graph", "validation", "businessKnowledge"]
4831
4742
  );
4832
4743
  const errors = [];
4833
- const statePromise = includeSet.has("state") ? import("./dist-TG63OKA5.js").then(
4744
+ const statePromise = includeSet.has("state") ? import("./dist-CPKL5Y2R.js").then(
4834
4745
  (core) => core.loadState(projectPath, void 0, input.session)
4835
4746
  ) : Promise.resolve(null);
4836
- const learningsPromise = includeSet.has("learnings") ? import("./dist-TG63OKA5.js").then(
4747
+ const learningsPromise = includeSet.has("learnings") ? import("./dist-CPKL5Y2R.js").then(
4837
4748
  (core) => core.loadBudgetedLearnings(projectPath, {
4838
4749
  intent: input.intent,
4839
4750
  tokenBudget: input.learningsBudget ?? 1e3,
@@ -4842,14 +4753,14 @@ async function handleGatherContext(input) {
4842
4753
  ...input.depth !== void 0 && { depth: input.depth }
4843
4754
  })
4844
4755
  ) : Promise.resolve(null);
4845
- const handoffPromise = includeSet.has("handoff") ? import("./dist-TG63OKA5.js").then(
4756
+ const handoffPromise = includeSet.has("handoff") ? import("./dist-CPKL5Y2R.js").then(
4846
4757
  (core) => core.loadHandoff(projectPath, void 0, input.session)
4847
4758
  ) : Promise.resolve(null);
4848
4759
  const graphPromise = includeSet.has("graph") ? (async () => {
4849
- const { loadGraphStore: loadGraphStore2 } = await import("./graph-loader-TIVI6NQ7.js");
4760
+ const { loadGraphStore: loadGraphStore2 } = await import("./graph-loader-QEI7SYOQ.js");
4850
4761
  const store = await loadGraphStore2(projectPath);
4851
4762
  if (!store) return null;
4852
- const { FusionLayer, ContextQL } = await import("./dist-PGQ32ZI7.js");
4763
+ const { FusionLayer, ContextQL } = await import("./dist-BZS2XRLG.js");
4853
4764
  const fusion = new FusionLayer(store);
4854
4765
  const cql = new ContextQL(store);
4855
4766
  const tokenBudget = input.tokenBudget ?? 4e3;
@@ -4886,11 +4797,11 @@ async function handleGatherContext(input) {
4886
4797
  context: contextBlocks
4887
4798
  };
4888
4799
  })() : Promise.resolve(null);
4889
- const sessionsPromise = includeSet.has("sessions") && input.session ? import("./dist-TG63OKA5.js").then(
4800
+ const sessionsPromise = includeSet.has("sessions") && input.session ? import("./dist-CPKL5Y2R.js").then(
4890
4801
  (core) => core.readSessionSections(projectPath, input.session)
4891
4802
  ) : Promise.resolve(null);
4892
4803
  const shouldIncludeEvents = input.includeEvents !== void 0 ? input.includeEvents : includeSet.has("events") || !!input.session && !input.include;
4893
- const eventsPromise = shouldIncludeEvents ? import("./dist-TG63OKA5.js").then(async (core) => {
4804
+ const eventsPromise = shouldIncludeEvents ? import("./dist-CPKL5Y2R.js").then(async (core) => {
4894
4805
  const result = await core.loadEvents(projectPath, {
4895
4806
  session: input.session
4896
4807
  });
@@ -4898,13 +4809,13 @@ async function handleGatherContext(input) {
4898
4809
  return core.formatEventTimeline(result.value);
4899
4810
  }) : Promise.resolve(null);
4900
4811
  const validationPromise = includeSet.has("validation") ? (async () => {
4901
- const { handleValidateProject: handleValidateProject2 } = await import("./validate-HXM6DXRZ.js");
4812
+ const { handleValidateProject: handleValidateProject2 } = await import("./validate-EAVGKZQB.js");
4902
4813
  const result = await handleValidateProject2({ path: projectPath });
4903
4814
  const first = result.content[0];
4904
4815
  return first ? JSON.parse(first.text) : null;
4905
4816
  })() : Promise.resolve(null);
4906
4817
  const businessKnowledgePromise = includeSet.has("businessKnowledge") ? (async () => {
4907
- const { getBusinessKnowledgeResource: getBusinessKnowledgeResource2 } = await import("./business-knowledge-6RHYJOB3.js");
4818
+ const { getBusinessKnowledgeResource: getBusinessKnowledgeResource2 } = await import("./business-knowledge-EISPR7FU.js");
4908
4819
  const raw = await getBusinessKnowledgeResource2(projectPath);
4909
4820
  return JSON.parse(raw);
4910
4821
  })() : Promise.resolve(null);
@@ -5001,7 +4912,7 @@ async function handleGatherContext(input) {
5001
4912
  };
5002
4913
  if (input.session) {
5003
4914
  try {
5004
- const core = await import("./dist-TG63OKA5.js");
4915
+ const core = await import("./dist-CPKL5Y2R.js");
5005
4916
  core.updateSessionIndex(
5006
4917
  projectPath,
5007
4918
  input.session,
@@ -5153,7 +5064,7 @@ async function handleReviewChanges(input) {
5153
5064
  }
5154
5065
  }
5155
5066
  async function runQuickReview(projectPath, diff, diffLines, downgraded, offset, limit) {
5156
- const { handleAnalyzeDiff: handleAnalyzeDiff2 } = await import("./feedback-HS7ZYXOU.js");
5067
+ const { handleAnalyzeDiff: handleAnalyzeDiff2 } = await import("./feedback-7EC4T6XG.js");
5157
5068
  const result = await handleAnalyzeDiff2({ diff, path: projectPath });
5158
5069
  const firstContent = result.content[0];
5159
5070
  if (!firstContent) throw new Error("Empty analyze_diff response");
@@ -5188,7 +5099,7 @@ function extractFileCount(diffParsed) {
5188
5099
  return files?.length ?? 0;
5189
5100
  }
5190
5101
  async function runStandardReview(projectPath, diff, diffLines, downgraded, offset, limit) {
5191
- const { handleAnalyzeDiff: handleAnalyzeDiff2, handleCreateSelfReview: handleCreateSelfReview2 } = await import("./feedback-HS7ZYXOU.js");
5102
+ const { handleAnalyzeDiff: handleAnalyzeDiff2, handleCreateSelfReview: handleCreateSelfReview2 } = await import("./feedback-7EC4T6XG.js");
5192
5103
  const [diffResult, reviewResult] = await Promise.all([
5193
5104
  handleAnalyzeDiff2({ diff, path: projectPath }),
5194
5105
  handleCreateSelfReview2({ path: projectPath, diff })
@@ -5223,7 +5134,7 @@ async function runStandardReview(projectPath, diff, diffLines, downgraded, offse
5223
5134
  };
5224
5135
  }
5225
5136
  async function runDeepReview(projectPath, diff, diffLines, _downgraded, offset, limit) {
5226
- const { handleRunCodeReview: handleRunCodeReview2 } = await import("./review-pipeline-QOZGWCTY.js");
5137
+ const { handleRunCodeReview: handleRunCodeReview2 } = await import("./review-pipeline-B4WPU6BQ.js");
5227
5138
  const result = await handleRunCodeReview2({
5228
5139
  path: projectPath,
5229
5140
  diff,
@@ -5302,7 +5213,7 @@ async function handleCheckTaskIndependence(input) {
5302
5213
  try {
5303
5214
  const projectPath = sanitizePath(input.path);
5304
5215
  const store = await loadGraphStore(projectPath);
5305
- const { TaskIndependenceAnalyzer } = await import("./dist-PGQ32ZI7.js");
5216
+ const { TaskIndependenceAnalyzer } = await import("./dist-BZS2XRLG.js");
5306
5217
  const analyzer = new TaskIndependenceAnalyzer(store ?? void 0);
5307
5218
  const result = analyzer.analyze({
5308
5219
  tasks: input.tasks,
@@ -5390,7 +5301,7 @@ async function handlePredictConflicts(input) {
5390
5301
  try {
5391
5302
  const projectPath = sanitizePath(input.path);
5392
5303
  const store = await loadGraphStore(projectPath);
5393
- const { ConflictPredictor } = await import("./dist-PGQ32ZI7.js");
5304
+ const { ConflictPredictor } = await import("./dist-BZS2XRLG.js");
5394
5305
  const predictor = new ConflictPredictor(store ?? void 0);
5395
5306
  const result = predictor.predict({
5396
5307
  tasks: input.tasks,
@@ -5496,7 +5407,7 @@ async function handleDetectStaleConstraints(input) {
5496
5407
  isError: true
5497
5408
  };
5498
5409
  }
5499
- const { loadGraphStore: loadGraphStore2 } = await import("./graph-loader-TIVI6NQ7.js");
5410
+ const { loadGraphStore: loadGraphStore2 } = await import("./graph-loader-QEI7SYOQ.js");
5500
5411
  const store = await loadGraphStore2(projectPath);
5501
5412
  if (!store) {
5502
5413
  return {
@@ -5517,7 +5428,7 @@ async function handleDetectStaleConstraints(input) {
5517
5428
  ]
5518
5429
  };
5519
5430
  }
5520
- const { detectStaleConstraints } = await import("./dist-TG63OKA5.js");
5431
+ const { detectStaleConstraints } = await import("./dist-CPKL5Y2R.js");
5521
5432
  const result = detectStaleConstraints(
5522
5433
  store,
5523
5434
  windowDays,
@@ -5549,8 +5460,8 @@ init_dist();
5549
5460
 
5550
5461
  // src/skill/health-snapshot.ts
5551
5462
  import { execSync } from "child_process";
5552
- import * as fs16 from "fs";
5553
- import * as path19 from "path";
5463
+ import * as fs15 from "fs";
5464
+ import * as path18 from "path";
5554
5465
  var CACHE_FILE = "health-snapshot.json";
5555
5466
  var STALENESS_MS = 36e5;
5556
5467
  function isSnapshotFresh(snapshot, projectPath) {
@@ -5567,19 +5478,19 @@ function isSnapshotFresh(snapshot, projectPath) {
5567
5478
  return age < STALENESS_MS;
5568
5479
  }
5569
5480
  function loadCachedSnapshot(projectPath) {
5570
- const filePath = path19.join(projectPath, ".harness", CACHE_FILE);
5481
+ const filePath = path18.join(projectPath, ".harness", CACHE_FILE);
5571
5482
  try {
5572
- const raw = fs16.readFileSync(filePath, "utf-8");
5483
+ const raw = fs15.readFileSync(filePath, "utf-8");
5573
5484
  return JSON.parse(raw);
5574
5485
  } catch {
5575
5486
  return null;
5576
5487
  }
5577
5488
  }
5578
5489
  function saveCachedSnapshot(snapshot, projectPath) {
5579
- const dir = path19.join(projectPath, ".harness");
5580
- fs16.mkdirSync(dir, { recursive: true });
5581
- const filePath = path19.join(dir, CACHE_FILE);
5582
- fs16.writeFileSync(filePath, JSON.stringify(snapshot, null, 2));
5490
+ const dir = path18.join(projectPath, ".harness");
5491
+ fs15.mkdirSync(dir, { recursive: true });
5492
+ const filePath = path18.join(dir, CACHE_FILE);
5493
+ fs15.writeFileSync(filePath, JSON.stringify(snapshot, null, 2));
5583
5494
  }
5584
5495
  var SIGNAL_RULES = [
5585
5496
  ["circular-deps", (c) => c.deps.circularDeps > 0],
@@ -5637,10 +5548,10 @@ function countCriticalFindings(securityData) {
5637
5548
  return findings.filter((f) => f.severity === "error").length;
5638
5549
  }
5639
5550
  async function runHealthChecks(projectPath) {
5640
- const { handleAssessProject: handleAssessProject2 } = await import("./assess-project-ZW7EKNIT.js");
5641
- const { handleCheckDependencies: handleCheckDependencies2 } = await import("./architecture-PMVMO6SF.js");
5642
- const { handleDetectEntropy: handleDetectEntropy2 } = await import("./entropy-RXESIYKC.js");
5643
- const { handleRunSecurityScan: handleRunSecurityScan2 } = await import("./security-2K7UUK6T.js");
5551
+ const { handleAssessProject: handleAssessProject2 } = await import("./assess-project-LLWWEQEV.js");
5552
+ const { handleCheckDependencies: handleCheckDependencies2 } = await import("./architecture-ZR33YKJB.js");
5553
+ const { handleDetectEntropy: handleDetectEntropy2 } = await import("./entropy-FIEE4YDA.js");
5554
+ const { handleRunSecurityScan: handleRunSecurityScan2 } = await import("./security-25VFLIAO.js");
5644
5555
  const [assessResult, depsResult, entropyResult, securityResult] = await Promise.all([
5645
5556
  handleAssessProject2({
5646
5557
  path: projectPath,
@@ -5695,10 +5606,10 @@ function avg(values) {
5695
5606
  }
5696
5607
  async function runGraphMetrics(projectPath) {
5697
5608
  try {
5698
- const { loadGraphStore: loadGraphStore2 } = await import("./graph-loader-TIVI6NQ7.js");
5609
+ const { loadGraphStore: loadGraphStore2 } = await import("./graph-loader-QEI7SYOQ.js");
5699
5610
  const store = await loadGraphStore2(projectPath);
5700
5611
  if (!store) return ZERO_METRICS;
5701
- const { GraphCouplingAdapter, GraphComplexityAdapter, GraphAnomalyAdapter } = await import("./dist-PGQ32ZI7.js");
5612
+ const { GraphCouplingAdapter, GraphComplexityAdapter, GraphAnomalyAdapter } = await import("./dist-BZS2XRLG.js");
5702
5613
  const couplingAdapter = new GraphCouplingAdapter(store);
5703
5614
  const couplingData = couplingAdapter.computeCouplingData();
5704
5615
  const files = couplingData.files;
@@ -5927,7 +5838,8 @@ function resolveMetricValue(metrics, metricName) {
5927
5838
  function buildSkillAddressIndex(skills) {
5928
5839
  const index = /* @__PURE__ */ new Map();
5929
5840
  for (const [name, entry] of Object.entries(skills)) {
5930
- const addresses = entry.addresses.length > 0 ? entry.addresses : FALLBACK_RULES[name] ?? [];
5841
+ const canonicalName = name.replace(/^harness-/, "");
5842
+ const addresses = entry.addresses.length > 0 ? entry.addresses : FALLBACK_RULES[name] ?? FALLBACK_RULES[canonicalName] ?? [];
5931
5843
  index.set(name, { addresses, dependsOn: entry.dependsOn });
5932
5844
  }
5933
5845
  for (const [name, addresses] of Object.entries(FALLBACK_RULES)) {
@@ -6087,7 +5999,14 @@ function recommend(snapshot, skills, options = {}) {
6087
5999
  const hardRecs = matchHardRules(snapshot, addressIndex);
6088
6000
  const softRecs = scoreByHealth(snapshot, addressIndex);
6089
6001
  const hardSkills = new Set(hardRecs.map((r) => r.skillName));
6090
- const merged = [...hardRecs, ...softRecs.filter((r) => !hardSkills.has(r.skillName))];
6002
+ let merged = [...hardRecs, ...softRecs.filter((r) => !hardSkills.has(r.skillName))];
6003
+ const { trigger, skillTriggers } = options;
6004
+ if (trigger && skillTriggers) {
6005
+ merged = merged.filter((r) => {
6006
+ const triggers = skillTriggers.get(r.skillName);
6007
+ return triggers ? triggers.includes(trigger) : true;
6008
+ });
6009
+ }
6091
6010
  merged.sort((a, b) => b.score - a.score);
6092
6011
  const limited = merged.slice(0, top);
6093
6012
  const depMap = /* @__PURE__ */ new Map();
@@ -6252,7 +6171,12 @@ function dispatchSkills(context, options = {}) {
6252
6171
  const { snapshot, changeType, domains, allSignals } = context;
6253
6172
  const limit = options.limit ?? 5;
6254
6173
  const enrichedSnapshot = { ...snapshot, signals: allSignals };
6255
- const recResult = recommend(enrichedSnapshot, {}, { top: limit });
6174
+ const recOpts = {
6175
+ top: limit
6176
+ };
6177
+ if (options.trigger) recOpts.trigger = options.trigger;
6178
+ if (options.skillTriggers) recOpts.skillTriggers = options.skillTriggers;
6179
+ const recResult = recommend(enrichedSnapshot, {}, recOpts);
6256
6180
  const addressIndex = buildSkillAddressIndex({});
6257
6181
  const skills = recResult.recommendations.map((rec, i) => {
6258
6182
  const prevRec = i > 0 ? recResult.recommendations[i - 1] : null;
@@ -6303,6 +6227,8 @@ async function dispatchSkillsFromGit(projectPath, options = {}) {
6303
6227
  const ctx = await enrichSnapshotForDispatch(projectPath, enrichOpts);
6304
6228
  const dispatchOpts = {};
6305
6229
  if (options.limit !== void 0) dispatchOpts.limit = options.limit;
6230
+ if (options.trigger) dispatchOpts.trigger = options.trigger;
6231
+ if (options.skillTriggers) dispatchOpts.skillTriggers = options.skillTriggers;
6306
6232
  return dispatchSkills(ctx, dispatchOpts);
6307
6233
  }
6308
6234
 
@@ -6333,6 +6259,10 @@ var dispatchSkillsDefinition = {
6333
6259
  limit: {
6334
6260
  type: "number",
6335
6261
  description: "Maximum number of skills to return (default: 5)"
6262
+ },
6263
+ trigger: {
6264
+ type: "string",
6265
+ description: "Filter to skills declaring this trigger (e.g. on_pr, on_commit, on_milestone, on_task_complete, on_refactor, on_review). Only skills whose triggers array includes this value are returned."
6336
6266
  }
6337
6267
  },
6338
6268
  required: []
@@ -6345,19 +6275,23 @@ function buildEnrichOpts(files, commitMessage, fresh) {
6345
6275
  if (fresh) opts.fresh = fresh;
6346
6276
  return opts;
6347
6277
  }
6348
- async function dispatchWithExplicitInput(projectRoot, files, commitMessage, fresh, limit) {
6278
+ async function dispatchWithExplicitInput(projectRoot, files, commitMessage, fresh, limit, trigger, skillTriggers) {
6349
6279
  const ctx = await enrichSnapshotForDispatch(
6350
6280
  projectRoot,
6351
6281
  buildEnrichOpts(files, commitMessage, fresh)
6352
6282
  );
6353
6283
  const dispatchOpts = {};
6354
6284
  if (limit !== 5) dispatchOpts.limit = limit;
6285
+ if (trigger) dispatchOpts.trigger = trigger;
6286
+ if (skillTriggers) dispatchOpts.skillTriggers = skillTriggers;
6355
6287
  return dispatchSkills(ctx, dispatchOpts);
6356
6288
  }
6357
- async function dispatchFromGit(projectRoot, fresh, limit) {
6289
+ async function dispatchFromGit(projectRoot, fresh, limit, trigger, skillTriggers) {
6358
6290
  const opts = {};
6359
6291
  if (fresh) opts.fresh = fresh;
6360
6292
  if (limit !== 5) opts.limit = limit;
6293
+ if (trigger) opts.trigger = trigger;
6294
+ if (skillTriggers) opts.skillTriggers = skillTriggers;
6361
6295
  return dispatchSkillsFromGit(projectRoot, opts);
6362
6296
  }
6363
6297
  async function handleDispatchSkills(input) {
@@ -6366,9 +6300,30 @@ async function handleDispatchSkills(input) {
6366
6300
  const commitMessage = input.commitMessage;
6367
6301
  const fresh = input.fresh ?? false;
6368
6302
  const limit = input.limit ?? 5;
6303
+ const trigger = input.trigger;
6369
6304
  try {
6305
+ let skillTriggers;
6306
+ if (trigger) {
6307
+ try {
6308
+ const { loadOrRebuildIndex: loadOrRebuildIndex2 } = await import("./index-builder-3AOQ3ZII.js");
6309
+ const index = loadOrRebuildIndex2("claude-code", projectRoot);
6310
+ skillTriggers = /* @__PURE__ */ new Map();
6311
+ for (const [name, entry] of Object.entries(index.skills)) {
6312
+ skillTriggers.set(name, entry.triggers ?? ["manual"]);
6313
+ }
6314
+ } catch {
6315
+ }
6316
+ }
6370
6317
  const hasExplicitInput = files !== void 0 || commitMessage !== void 0;
6371
- const result = hasExplicitInput ? await dispatchWithExplicitInput(projectRoot, files, commitMessage, fresh, limit) : await dispatchFromGit(projectRoot, fresh, limit);
6318
+ const result = hasExplicitInput ? await dispatchWithExplicitInput(
6319
+ projectRoot,
6320
+ files,
6321
+ commitMessage,
6322
+ fresh,
6323
+ limit,
6324
+ trigger,
6325
+ skillTriggers
6326
+ ) : await dispatchFromGit(projectRoot, fresh, limit, trigger, skillTriggers);
6372
6327
  if (result.skills.length > limit) {
6373
6328
  result.skills = result.skills.slice(0, limit);
6374
6329
  }
@@ -6437,7 +6392,7 @@ async function handleGetDecayTrends(input) {
6437
6392
  };
6438
6393
  }
6439
6394
  try {
6440
- const core = await import("./dist-TG63OKA5.js");
6395
+ const core = await import("./dist-CPKL5Y2R.js");
6441
6396
  const { TimelineManager } = core;
6442
6397
  const manager = new TimelineManager(projectPath);
6443
6398
  const timeline = manager.load();
@@ -6572,7 +6527,7 @@ async function handleCodeOutline(input) {
6572
6527
  };
6573
6528
  }
6574
6529
  try {
6575
- const { getOutline, formatOutline, EXTENSION_MAP } = await import("./dist-TG63OKA5.js");
6530
+ const { getOutline, formatOutline, EXTENSION_MAP } = await import("./dist-CPKL5Y2R.js");
6576
6531
  const { stat } = await import("fs/promises");
6577
6532
  const stats = await stat(targetPath).catch(() => null);
6578
6533
  if (stats?.isFile()) {
@@ -6591,7 +6546,7 @@ async function handleCodeOutline(input) {
6591
6546
  })
6592
6547
  );
6593
6548
  fileStats.sort((a, b) => b.mtimeMs - a.mtimeMs);
6594
- const { paginate: paginate2 } = await import("./dist-TG63OKA5.js");
6549
+ const { paginate: paginate2 } = await import("./dist-CPKL5Y2R.js");
6595
6550
  const paged = paginate2(fileStats, input.offset ?? 0, input.limit ?? 30);
6596
6551
  const results = [];
6597
6552
  for (const entry of paged.items) {
@@ -6664,7 +6619,7 @@ async function handleCodeSearch(input) {
6664
6619
  };
6665
6620
  }
6666
6621
  try {
6667
- const { searchSymbols } = await import("./dist-TG63OKA5.js");
6622
+ const { searchSymbols } = await import("./dist-CPKL5Y2R.js");
6668
6623
  const result = await searchSymbols(input.query, directory, input.glob);
6669
6624
  const lines = [`Search: "${result.query}" \u2014 ${result.matches.length} matches`];
6670
6625
  for (const match of result.matches) {
@@ -6733,7 +6688,7 @@ async function handleCodeUnfold(input) {
6733
6688
  }
6734
6689
  try {
6735
6690
  if (input.symbol) {
6736
- const { unfoldSymbol } = await import("./dist-TG63OKA5.js");
6691
+ const { unfoldSymbol } = await import("./dist-CPKL5Y2R.js");
6737
6692
  const result = await unfoldSymbol(filePath, input.symbol);
6738
6693
  const header = result.warning ? `${result.file}:${result.startLine}-${result.endLine} ${result.warning}
6739
6694
  ` : `${result.file}:${result.startLine}-${result.endLine}
@@ -6741,7 +6696,7 @@ async function handleCodeUnfold(input) {
6741
6696
  return { content: [{ type: "text", text: header + result.content }] };
6742
6697
  }
6743
6698
  if (input.startLine != null && input.endLine != null) {
6744
- const { unfoldRange } = await import("./dist-TG63OKA5.js");
6699
+ const { unfoldRange } = await import("./dist-CPKL5Y2R.js");
6745
6700
  const result = await unfoldRange(filePath, input.startLine, input.endLine);
6746
6701
  const header = `${result.file}:${result.startLine}-${result.endLine}
6747
6702
  `;
@@ -6803,7 +6758,7 @@ async function handleCheckTraceability(input) {
6803
6758
  isError: true
6804
6759
  };
6805
6760
  }
6806
- const { queryTraceability } = await import("./dist-PGQ32ZI7.js");
6761
+ const { queryTraceability } = await import("./dist-BZS2XRLG.js");
6807
6762
  const options = {};
6808
6763
  if (input.spec) options.specPath = input.spec;
6809
6764
  if (input.feature) options.featureName = input.feature;
@@ -6926,7 +6881,7 @@ async function handlePredictFailures(input) {
6926
6881
  };
6927
6882
  }
6928
6883
  try {
6929
- const core = await import("./dist-TG63OKA5.js");
6884
+ const core = await import("./dist-CPKL5Y2R.js");
6930
6885
  const { TimelineManager, PredictionEngine, SpecImpactEstimator } = core;
6931
6886
  const manager = new TimelineManager(projectPath);
6932
6887
  const includeRoadmap = input.includeRoadmap !== false;
@@ -7028,6 +6983,699 @@ async function handleRecommendSkills(input) {
7028
6983
  };
7029
6984
  }
7030
6985
 
6986
+ // src/mcp/tools/advise-skills.ts
6987
+ import path20 from "path";
6988
+
6989
+ // src/commands/advise-skills.ts
6990
+ import { Command as Command2 } from "commander";
6991
+ import fs16 from "fs";
6992
+ import path19 from "path";
6993
+ import chalk from "chalk";
6994
+
6995
+ // src/skill/content-matcher-types.ts
6996
+ var TIER_THRESHOLDS = {
6997
+ apply: 0.6,
6998
+ reference: 0.35,
6999
+ consider: 0.15
7000
+ };
7001
+ var SCORING_WEIGHTS = {
7002
+ keyword: 0.35,
7003
+ stack: 0.25,
7004
+ termOverlap: 0.25,
7005
+ domain: 0.15
7006
+ };
7007
+ var DOMAIN_KEYWORD_MAP = {
7008
+ design: [
7009
+ "layout",
7010
+ "responsive",
7011
+ "typography",
7012
+ "color",
7013
+ "theme",
7014
+ "dark mode",
7015
+ "ui",
7016
+ "ux",
7017
+ "component",
7018
+ "palette",
7019
+ "breakpoint",
7020
+ "grid",
7021
+ "elevation",
7022
+ "shadow",
7023
+ "motion",
7024
+ "animation",
7025
+ "css"
7026
+ ],
7027
+ auth: [
7028
+ "authentication",
7029
+ "authorization",
7030
+ "oauth",
7031
+ "session",
7032
+ "token",
7033
+ "jwt",
7034
+ "login",
7035
+ "signup",
7036
+ "password",
7037
+ "credential",
7038
+ "rbac",
7039
+ "permission",
7040
+ "identity"
7041
+ ],
7042
+ data: [
7043
+ "database",
7044
+ "schema",
7045
+ "migration",
7046
+ "query",
7047
+ "sql",
7048
+ "nosql",
7049
+ "orm",
7050
+ "model",
7051
+ "table",
7052
+ "transaction",
7053
+ "prisma",
7054
+ "drizzle"
7055
+ ],
7056
+ security: [
7057
+ "security",
7058
+ "vulnerability",
7059
+ "xss",
7060
+ "csrf",
7061
+ "injection",
7062
+ "sanitiz",
7063
+ "encrypt",
7064
+ "hash",
7065
+ "owasp",
7066
+ "cve",
7067
+ "audit"
7068
+ ],
7069
+ a11y: [
7070
+ "accessibility",
7071
+ "a11y",
7072
+ "aria",
7073
+ "screen reader",
7074
+ "screen-reader",
7075
+ "wcag",
7076
+ "contrast",
7077
+ "keyboard navigation",
7078
+ "focus management"
7079
+ ],
7080
+ perf: [
7081
+ "performance",
7082
+ "latency",
7083
+ "throughput",
7084
+ "cache",
7085
+ "lazy load",
7086
+ "bundle size",
7087
+ "tree shaking",
7088
+ "code splitting",
7089
+ "lighthouse",
7090
+ "optimization",
7091
+ "bundle"
7092
+ ],
7093
+ testing: [
7094
+ "test",
7095
+ "coverage",
7096
+ "mock",
7097
+ "stub",
7098
+ "fixture",
7099
+ "assertion",
7100
+ "snapshot",
7101
+ "e2e",
7102
+ "integration test",
7103
+ "unit test",
7104
+ "tdd"
7105
+ ],
7106
+ api: [
7107
+ "api",
7108
+ "endpoint",
7109
+ "rest",
7110
+ "graphql",
7111
+ "openapi",
7112
+ "swagger",
7113
+ "route",
7114
+ "middleware",
7115
+ "webhook",
7116
+ "grpc"
7117
+ ],
7118
+ infra: [
7119
+ "docker",
7120
+ "kubernetes",
7121
+ "ci/cd",
7122
+ "ci",
7123
+ "cd",
7124
+ "deploy",
7125
+ "terraform",
7126
+ "aws",
7127
+ "gcp",
7128
+ "azure",
7129
+ "cloud",
7130
+ "container",
7131
+ "helm"
7132
+ ],
7133
+ mobile: [
7134
+ "mobile",
7135
+ "ios",
7136
+ "android",
7137
+ "react native",
7138
+ "react-native",
7139
+ "flutter",
7140
+ "app store",
7141
+ "push notification"
7142
+ ]
7143
+ };
7144
+
7145
+ // src/skill/signal-extractor.ts
7146
+ var STEM_SUFFIXES = [
7147
+ "ation",
7148
+ "tion",
7149
+ "sion",
7150
+ "ment",
7151
+ "ness",
7152
+ "ible",
7153
+ "able",
7154
+ "ive",
7155
+ "ous",
7156
+ "ful",
7157
+ "ing",
7158
+ "ity",
7159
+ "ly",
7160
+ "ed",
7161
+ "er",
7162
+ "es",
7163
+ "s"
7164
+ ];
7165
+ function simpleStem(word) {
7166
+ const w = word.toLowerCase();
7167
+ if (w.length <= 4) return w;
7168
+ for (const suffix of STEM_SUFFIXES) {
7169
+ if (w.endsWith(suffix) && w.length - suffix.length >= 3) {
7170
+ return w.slice(0, -suffix.length);
7171
+ }
7172
+ }
7173
+ return w;
7174
+ }
7175
+ function extractSpecKeywords(specText) {
7176
+ const match = specText.match(/\*\*Keywords?:\*\*\s*(.+)/i);
7177
+ if (!match?.[1]) return [];
7178
+ return match[1].split(",").map((k) => k.trim()).filter((k) => k.length > 0);
7179
+ }
7180
+ var STACK_SIGNAL_MAP = {
7181
+ react: "react",
7182
+ "react-dom": "react",
7183
+ "react-native": "react-native",
7184
+ next: "next",
7185
+ vue: "vue",
7186
+ nuxt: "nuxt",
7187
+ angular: "angular",
7188
+ svelte: "svelte",
7189
+ express: "express",
7190
+ fastify: "fastify",
7191
+ nestjs: "nest",
7192
+ "@nestjs/core": "nest",
7193
+ typescript: "typescript",
7194
+ tailwindcss: "tailwind",
7195
+ prisma: "prisma",
7196
+ "@prisma/client": "prisma",
7197
+ "drizzle-orm": "drizzle",
7198
+ graphql: "graphql",
7199
+ "@trpc/server": "trpc",
7200
+ trpc: "trpc",
7201
+ vitest: "vitest",
7202
+ jest: "jest",
7203
+ playwright: "playwright",
7204
+ cypress: "cypress",
7205
+ vite: "vite",
7206
+ webpack: "webpack",
7207
+ zod: "zod",
7208
+ mongoose: "mongoose",
7209
+ redis: "redis",
7210
+ ioredis: "redis",
7211
+ "socket.io": "websocket",
7212
+ ws: "websocket"
7213
+ };
7214
+ function detectStackFromDeps(dependencies, devDependencies) {
7215
+ const signals = /* @__PURE__ */ new Set();
7216
+ const allDeps = { ...dependencies, ...devDependencies };
7217
+ for (const pkgName of Object.keys(allDeps)) {
7218
+ const signal = STACK_SIGNAL_MAP[pkgName];
7219
+ if (signal) {
7220
+ signals.add(signal);
7221
+ }
7222
+ }
7223
+ return [...signals].sort();
7224
+ }
7225
+ function inferDomain(specText) {
7226
+ const lower = specText.toLowerCase();
7227
+ const domains = [];
7228
+ for (const [domain, markers] of Object.entries(DOMAIN_KEYWORD_MAP)) {
7229
+ const hits = markers.filter((m) => lower.includes(m)).length;
7230
+ if (hits >= 2) {
7231
+ domains.push(domain);
7232
+ }
7233
+ }
7234
+ return domains.sort();
7235
+ }
7236
+ function extractSignals(specText, dependencies, devDependencies, contextKeywords, taskText) {
7237
+ const specKeywords = extractSpecKeywords(specText);
7238
+ if (contextKeywords) {
7239
+ const existing = new Set(specKeywords);
7240
+ for (const kw of contextKeywords) {
7241
+ if (!existing.has(kw)) {
7242
+ specKeywords.push(kw);
7243
+ existing.add(kw);
7244
+ }
7245
+ }
7246
+ }
7247
+ const stackSignals = detectStackFromDeps(dependencies, devDependencies);
7248
+ const featureDomain = inferDomain(specText);
7249
+ return {
7250
+ specKeywords,
7251
+ specText,
7252
+ stackSignals,
7253
+ featureDomain,
7254
+ ...taskText !== void 0 && { taskText }
7255
+ };
7256
+ }
7257
+
7258
+ // src/skill/content-matcher.ts
7259
+ function computeKeywordOverlap(skillKeywords, specKeywords) {
7260
+ if (skillKeywords.length === 0 || specKeywords.length === 0) return 0;
7261
+ const stemTokens = (keywords) => {
7262
+ const tokens = /* @__PURE__ */ new Set();
7263
+ for (const kw of keywords) {
7264
+ const parts = kw.toLowerCase().split(/[-_\s]+/);
7265
+ for (const part of parts) {
7266
+ if (part.length > 0) {
7267
+ tokens.add(simpleStem(part));
7268
+ }
7269
+ }
7270
+ }
7271
+ return tokens;
7272
+ };
7273
+ const skillStems = stemTokens(skillKeywords);
7274
+ const specStems = stemTokens(specKeywords);
7275
+ let intersectionCount = 0;
7276
+ for (const stem of skillStems) {
7277
+ if (specStems.has(stem)) intersectionCount++;
7278
+ }
7279
+ const unionSize = (/* @__PURE__ */ new Set([...skillStems, ...specStems])).size;
7280
+ return unionSize > 0 ? intersectionCount / unionSize : 0;
7281
+ }
7282
+ function computeStackMatch(skillSignals, projectSignals) {
7283
+ if (skillSignals.length === 0) return 0;
7284
+ const projectSet = new Set(projectSignals.map((s) => s.toLowerCase()));
7285
+ const matched = skillSignals.filter((s) => projectSet.has(s.toLowerCase())).length;
7286
+ return matched / skillSignals.length;
7287
+ }
7288
+ function computeTermOverlap(skillDescription, specText) {
7289
+ if (!skillDescription || !specText) return 0;
7290
+ const tokenize = (text) => text.toLowerCase().split(/[\s\-_,.;:!?()[\]{}"'`]+/).filter((t) => t.length > 3).map(simpleStem);
7291
+ const descTokens = tokenize(skillDescription);
7292
+ if (descTokens.length === 0) return 0;
7293
+ const specTokenSet = new Set(tokenize(specText));
7294
+ const matched = descTokens.filter((t) => specTokenSet.has(t)).length;
7295
+ return matched / descTokens.length;
7296
+ }
7297
+ function computeDomainMatch(entry, featureDomains) {
7298
+ if (featureDomains.length === 0 || entry.keywords.length === 0) return 0;
7299
+ const skillKeywordsLower = entry.keywords.map((k) => k.toLowerCase());
7300
+ for (const domain of featureDomains) {
7301
+ const domainKeywords = DOMAIN_KEYWORD_MAP[domain];
7302
+ if (!domainKeywords) continue;
7303
+ const hasMatch = skillKeywordsLower.some(
7304
+ (kw) => domainKeywords.some((dk) => kw.includes(dk) || dk.includes(kw))
7305
+ );
7306
+ if (hasMatch) return 1;
7307
+ }
7308
+ return 0;
7309
+ }
7310
+ function classifyTier(score) {
7311
+ if (score >= TIER_THRESHOLDS.apply) return "apply";
7312
+ if (score >= TIER_THRESHOLDS.reference) return "reference";
7313
+ if (score >= TIER_THRESHOLDS.consider) return "consider";
7314
+ return null;
7315
+ }
7316
+ var WHEN_RULES = [
7317
+ { name: /scan|audit|i18n|lint/, when: "End of phase" },
7318
+ { name: /test/, keywords: /test|tdd|coverage|mock|e2e|snapshot/, when: "Testing" },
7319
+ {
7320
+ name: /a11y|contrast|wcag|color.accessib/,
7321
+ keywords: /contrast|wcag/,
7322
+ when: "After styling"
7323
+ },
7324
+ { keywords: /css|tailwind|typography|font|color|palette/, when: "During styling" },
7325
+ { keywords: /alignment|whitespace|spacing|grid/, when: "Layout review" },
7326
+ { keywords: /motion|animation|transition|parallax/, when: "During polish" },
7327
+ { keywords: /architect|pattern|api|schema|data.model/, when: "Architecture decisions" },
7328
+ { name: /^(gof-|js-)/, when: "Architecture decisions" }
7329
+ ];
7330
+ function matchesWhenRule(rule, nameLower, keywordsLower) {
7331
+ const nameHit = rule.name ? rule.name.test(nameLower) : false;
7332
+ const kwHit = rule.keywords ? rule.keywords.test(keywordsLower) : false;
7333
+ if (rule.name && rule.keywords) return nameHit || kwHit;
7334
+ return nameHit || kwHit;
7335
+ }
7336
+ function inferWhen(name, entry) {
7337
+ const nameLower = name.toLowerCase();
7338
+ const keywordsLower = entry.keywords.map((k) => k.toLowerCase()).join(" ");
7339
+ for (const rule of WHEN_RULES) {
7340
+ if (matchesWhenRule(rule, nameLower, keywordsLower)) return rule.when;
7341
+ }
7342
+ return "During implementation";
7343
+ }
7344
+ function scoreSkillByContent(entry, signals) {
7345
+ const keywordScore = computeKeywordOverlap(entry.keywords, signals.specKeywords);
7346
+ const stackScore = computeStackMatch(entry.stackSignals, signals.stackSignals);
7347
+ const textToMatch = signals.taskText ?? signals.specText;
7348
+ const descScore = computeTermOverlap(entry.description, textToMatch);
7349
+ const domainScore = computeDomainMatch(entry, signals.featureDomain);
7350
+ return SCORING_WEIGHTS.keyword * keywordScore + SCORING_WEIGHTS.stack * stackScore + SCORING_WEIGHTS.termOverlap * descScore + SCORING_WEIGHTS.domain * domainScore;
7351
+ }
7352
+ function buildMatchReasons(entry, signals) {
7353
+ const reasons = [];
7354
+ const matchedKeywords = entry.keywords.filter(
7355
+ (kw) => signals.specKeywords.some(
7356
+ (sk) => kw.toLowerCase().includes(sk.toLowerCase()) || sk.toLowerCase().includes(kw.toLowerCase())
7357
+ )
7358
+ );
7359
+ if (matchedKeywords.length > 0) {
7360
+ reasons.push(`Keywords: ${matchedKeywords.join(", ")}`);
7361
+ }
7362
+ const projectSignalSet = new Set(signals.stackSignals.map((s) => s.toLowerCase()));
7363
+ const matchedStack = entry.stackSignals.filter((s) => projectSignalSet.has(s.toLowerCase()));
7364
+ if (matchedStack.length > 0) {
7365
+ reasons.push(`Stack: ${matchedStack.join(", ")}`);
7366
+ }
7367
+ if (signals.featureDomain.length > 0) {
7368
+ reasons.push(`Domain: ${signals.featureDomain.join(", ")}`);
7369
+ }
7370
+ return reasons;
7371
+ }
7372
+ function inferCategory(entry) {
7373
+ const keywordsLower = entry.keywords.map((k) => k.toLowerCase()).join(" ");
7374
+ if (/design|layout|responsive|css|ui|ux|theme|color/.test(keywordsLower)) return "design";
7375
+ if (/auth|oauth|session|token|jwt|login/.test(keywordsLower)) return "security";
7376
+ if (/a11y|accessibility|aria|wcag/.test(keywordsLower)) return "a11y";
7377
+ if (/perf|performance|cache|optimization|lighthouse/.test(keywordsLower)) return "perf";
7378
+ if (/test|tdd|coverage|mock|e2e/.test(keywordsLower)) return "testing";
7379
+ if (/database|sql|orm|migration|schema/.test(keywordsLower)) return "data";
7380
+ if (/api|rest|graphql|endpoint/.test(keywordsLower)) return "api";
7381
+ if (/docker|kubernetes|deploy|ci|terraform/.test(keywordsLower)) return "infra";
7382
+ if (/react|vue|angular|svelte|next/.test(keywordsLower)) return "framework";
7383
+ return "patterns";
7384
+ }
7385
+ function scoreAllSkills(index, signals) {
7386
+ const scored = [];
7387
+ for (const [name, entry] of Object.entries(index.skills)) {
7388
+ const score = scoreSkillByContent(entry, signals);
7389
+ if (score >= TIER_THRESHOLDS.consider) {
7390
+ scored.push({ name, entry, score });
7391
+ }
7392
+ }
7393
+ return scored;
7394
+ }
7395
+ function expandRelatedSkills(scored, index) {
7396
+ const matchedNames = new Set(scored.map((s) => s.name));
7397
+ const expansions = [];
7398
+ for (const match of scored) {
7399
+ if (match.score < TIER_THRESHOLDS.reference) continue;
7400
+ for (const relatedName of match.entry.relatedSkills) {
7401
+ if (matchedNames.has(relatedName)) continue;
7402
+ const relatedEntry = index.skills[relatedName];
7403
+ if (!relatedEntry) continue;
7404
+ const boostedScore = match.score * 0.6;
7405
+ if (boostedScore >= TIER_THRESHOLDS.consider) {
7406
+ matchedNames.add(relatedName);
7407
+ expansions.push({
7408
+ name: relatedName,
7409
+ entry: relatedEntry,
7410
+ score: boostedScore,
7411
+ parentName: match.name
7412
+ });
7413
+ }
7414
+ }
7415
+ }
7416
+ return expansions;
7417
+ }
7418
+ function buildMatchList(scored, expansions, signals) {
7419
+ const matches = [];
7420
+ for (const { name, entry, score } of scored) {
7421
+ const tier = classifyTier(score);
7422
+ if (!tier) continue;
7423
+ matches.push({
7424
+ skillName: name,
7425
+ score: Math.round(score * 100) / 100,
7426
+ tier,
7427
+ matchReasons: buildMatchReasons(entry, signals),
7428
+ category: inferCategory(entry),
7429
+ when: inferWhen(name, entry)
7430
+ });
7431
+ }
7432
+ for (const { name, entry, score, parentName } of expansions) {
7433
+ const tier = classifyTier(score);
7434
+ if (!tier) continue;
7435
+ matches.push({
7436
+ skillName: name,
7437
+ score: Math.round(score * 100) / 100,
7438
+ tier,
7439
+ matchReasons: [`Related to: ${parentName}`, ...buildMatchReasons(entry, signals)],
7440
+ category: inferCategory(entry),
7441
+ when: inferWhen(name, entry)
7442
+ });
7443
+ }
7444
+ matches.sort((a, b) => b.score - a.score);
7445
+ return matches;
7446
+ }
7447
+ function matchContent(index, signals) {
7448
+ const startTime = performance.now();
7449
+ const scored = scoreAllSkills(index, signals);
7450
+ const expansions = expandRelatedSkills(scored, index);
7451
+ const matches = buildMatchList(scored, expansions, signals);
7452
+ return {
7453
+ matches,
7454
+ signalsUsed: signals,
7455
+ scanDuration: Math.round(performance.now() - startTime)
7456
+ };
7457
+ }
7458
+
7459
+ // src/skill/skills-md-writer.ts
7460
+ function generateSkillsMd(featureName, result, totalSkillCount) {
7461
+ const lines = [];
7462
+ lines.push(`# Recommended Skills: ${featureName}`);
7463
+ lines.push("");
7464
+ lines.push("> Auto-generated by Pipeline Skill Advisor. Review and adjust as needed.");
7465
+ const apply = result.matches.filter((m) => m.tier === "apply");
7466
+ const reference = result.matches.filter((m) => m.tier === "reference");
7467
+ const consider = result.matches.filter((m) => m.tier === "consider");
7468
+ if (apply.length > 0) {
7469
+ lines.push("");
7470
+ lines.push("## Apply (invoke during execution)");
7471
+ lines.push("");
7472
+ lines.push(...renderTable(apply));
7473
+ }
7474
+ if (reference.length > 0) {
7475
+ lines.push("");
7476
+ lines.push("## Reference (load as context)");
7477
+ lines.push("");
7478
+ lines.push(...renderTable(reference));
7479
+ }
7480
+ if (consider.length > 0) {
7481
+ lines.push("");
7482
+ lines.push("## Consider");
7483
+ lines.push("");
7484
+ lines.push(...renderTable(consider));
7485
+ }
7486
+ lines.push("");
7487
+ lines.push("---");
7488
+ const skillsScanned = totalSkillCount ?? result.matches.length;
7489
+ const keywords = result.signalsUsed.specKeywords.length;
7490
+ const stack = result.signalsUsed.stackSignals.length;
7491
+ const domains = result.signalsUsed.featureDomain.length;
7492
+ lines.push(
7493
+ `*Scanned ${skillsScanned} skills in ${result.scanDuration}ms. Signals: ${keywords} keywords, ${stack} stack markers, ${domains} domains.*`
7494
+ );
7495
+ lines.push("");
7496
+ return lines.join("\n");
7497
+ }
7498
+ function renderTable(matches) {
7499
+ const lines = [];
7500
+ lines.push("| Skill | Purpose | When | Relevance |");
7501
+ lines.push("|-------|---------|------|-----------|");
7502
+ for (const match of matches) {
7503
+ const purpose = match.matchReasons.join("; ");
7504
+ lines.push(`| \`${match.skillName}\` | ${purpose} | ${match.when} | ${match.score} |`);
7505
+ }
7506
+ return lines;
7507
+ }
7508
+
7509
+ // src/commands/advise-skills.ts
7510
+ function readPackageDeps(cwd) {
7511
+ const pkgPath = path19.join(cwd, "package.json");
7512
+ if (!fs16.existsSync(pkgPath)) return { deps: {}, devDeps: {} };
7513
+ try {
7514
+ const pkg = JSON.parse(fs16.readFileSync(pkgPath, "utf-8"));
7515
+ const deps = typeof pkg.dependencies === "object" && pkg.dependencies !== null ? pkg.dependencies : {};
7516
+ const devDeps = typeof pkg.devDependencies === "object" && pkg.devDependencies !== null ? pkg.devDependencies : {};
7517
+ return { deps, devDeps };
7518
+ } catch {
7519
+ return { deps: {}, devDeps: {} };
7520
+ }
7521
+ }
7522
+ function readSpecText(specPath) {
7523
+ if (!fs16.existsSync(specPath)) {
7524
+ throw new Error(`Spec not found: ${specPath}`);
7525
+ }
7526
+ return fs16.readFileSync(specPath, "utf-8");
7527
+ }
7528
+ function filterMatchesByTier(result, top, thorough) {
7529
+ const applySkills = result.matches.filter((m) => m.tier === "apply").slice(0, top);
7530
+ const refSkills = result.matches.filter((m) => m.tier === "reference").slice(0, top * 2);
7531
+ const considerSkills = thorough ? result.matches.filter((m) => m.tier === "consider").slice(0, top) : [];
7532
+ return { ...result, matches: [...applySkills, ...refSkills, ...considerSkills] };
7533
+ }
7534
+ function extractFeatureName(specText, specPath) {
7535
+ const titleMatch = specText.match(/^#\s+(.+)/m);
7536
+ return titleMatch?.[1] ?? path19.basename(path19.dirname(specPath));
7537
+ }
7538
+ async function runAdviseSkills(options) {
7539
+ const cwd = options.cwd ?? process.cwd();
7540
+ const specPath = path19.resolve(cwd, options.specPath);
7541
+ const specText = readSpecText(specPath);
7542
+ const { deps, devDeps } = readPackageDeps(cwd);
7543
+ const signals = extractSignals(specText, deps, devDeps);
7544
+ const configResult = resolveConfig();
7545
+ const tierOverrides = configResult.ok ? configResult.value.skills?.tierOverrides : void 0;
7546
+ const index = loadOrRebuildIndex("claude-code", cwd, tierOverrides);
7547
+ const totalSkills = Object.keys(index.skills).length;
7548
+ const result = matchContent(index, signals);
7549
+ const filteredResult = filterMatchesByTier(result, options.top ?? 5, !!options.thorough);
7550
+ const featureName = extractFeatureName(specText, specPath);
7551
+ const skillsMdPath = path19.join(path19.dirname(specPath), "SKILLS.md");
7552
+ const md = generateSkillsMd(featureName, filteredResult, totalSkills);
7553
+ fs16.writeFileSync(skillsMdPath, md, "utf-8");
7554
+ return { result: filteredResult, skillsMdPath, featureName, totalSkills };
7555
+ }
7556
+ function formatOutput(featureName, result, skillsMdPath, totalSkills) {
7557
+ const apply = result.matches.filter((m) => m.tier === "apply");
7558
+ const ref = result.matches.filter((m) => m.tier === "reference");
7559
+ const consider = result.matches.filter((m) => m.tier === "consider");
7560
+ const lines = [];
7561
+ lines.push(`Skill Advisor: Found ${result.matches.length} relevant skills for "${featureName}"`);
7562
+ lines.push("");
7563
+ if (apply.length > 0) {
7564
+ lines.push(chalk.green(` Apply (${apply.length}):`));
7565
+ for (const m of apply) {
7566
+ lines.push(` ${m.skillName} (${m.score}) \u2014 ${m.when}`);
7567
+ }
7568
+ }
7569
+ if (ref.length > 0) {
7570
+ lines.push(chalk.blue(` Reference (${ref.length}):`));
7571
+ for (const m of ref) {
7572
+ lines.push(` ${m.skillName} (${m.score}) \u2014 ${m.when}`);
7573
+ }
7574
+ }
7575
+ if (consider.length > 0) {
7576
+ lines.push(chalk.dim(` Consider (${consider.length}):`));
7577
+ for (const m of consider) {
7578
+ lines.push(` ${m.skillName} (${m.score}) \u2014 ${m.when}`);
7579
+ }
7580
+ }
7581
+ lines.push("");
7582
+ lines.push(`Scanned ${totalSkills} skills in ${result.scanDuration}ms`);
7583
+ lines.push(`Written to ${skillsMdPath}`);
7584
+ return lines.join("\n");
7585
+ }
7586
+ function createAdviseSkillsCommand() {
7587
+ return new Command2("advise-skills").description("Content-based skill recommendations for a spec").requiredOption("--spec-path <path>", "Path to the spec (proposal.md)").option("--thorough", "Include Consider tier in output").option("--top <n>", "Max skills per tier (default 5)", parseInt).option("--json", "Output as JSON").action(async (opts) => {
7588
+ try {
7589
+ const { result, skillsMdPath, featureName, totalSkills } = await runAdviseSkills({
7590
+ specPath: opts.specPath,
7591
+ thorough: opts.thorough,
7592
+ top: opts.top
7593
+ });
7594
+ if (opts.json) {
7595
+ logger.info(JSON.stringify(result, null, 2));
7596
+ } else {
7597
+ logger.info(formatOutput(featureName, result, skillsMdPath, totalSkills));
7598
+ }
7599
+ } catch (err) {
7600
+ logger.error(err.message);
7601
+ process.exit(1);
7602
+ }
7603
+ });
7604
+ }
7605
+
7606
+ // src/mcp/tools/advise-skills.ts
7607
+ var adviseSkillsDefinition = {
7608
+ name: "advise_skills",
7609
+ description: "Content-based skill recommendations for a spec or feature description. Returns tiered matches with purpose and timing guidance.",
7610
+ inputSchema: {
7611
+ type: "object",
7612
+ properties: {
7613
+ path: {
7614
+ type: "string",
7615
+ description: "Project root path (defaults to cwd)"
7616
+ },
7617
+ specPath: {
7618
+ type: "string",
7619
+ description: "Path to the spec file (proposal.md), relative to project root"
7620
+ },
7621
+ thorough: {
7622
+ type: "boolean",
7623
+ description: "Include Consider tier in output"
7624
+ },
7625
+ top: {
7626
+ type: "number",
7627
+ description: "Max skills per tier (default 5 apply, 10 reference)"
7628
+ }
7629
+ },
7630
+ required: ["specPath"]
7631
+ }
7632
+ };
7633
+ async function handleAdviseSkills(input) {
7634
+ const projectRoot = input.path || process.cwd();
7635
+ const specRelPath = input.specPath;
7636
+ const thorough = input.thorough || false;
7637
+ const top = input.top || 5;
7638
+ try {
7639
+ const { result, skillsMdPath, featureName, totalSkills } = await runAdviseSkills({
7640
+ specPath: specRelPath,
7641
+ cwd: projectRoot,
7642
+ thorough,
7643
+ top
7644
+ });
7645
+ const response = {
7646
+ featureName,
7647
+ skillsPath: path20.relative(projectRoot, skillsMdPath).replaceAll("\\", "/"),
7648
+ totalScanned: totalSkills,
7649
+ scanDuration: result.scanDuration,
7650
+ apply: result.matches.filter((m) => m.tier === "apply").map((m) => ({
7651
+ skill: m.skillName,
7652
+ score: m.score,
7653
+ when: m.when,
7654
+ reasons: m.matchReasons
7655
+ })),
7656
+ reference: result.matches.filter((m) => m.tier === "reference").map((m) => ({
7657
+ skill: m.skillName,
7658
+ score: m.score,
7659
+ when: m.when,
7660
+ reasons: m.matchReasons
7661
+ })),
7662
+ consider: result.matches.filter((m) => m.tier === "consider").map((m) => ({
7663
+ skill: m.skillName,
7664
+ score: m.score,
7665
+ when: m.when,
7666
+ reasons: m.matchReasons
7667
+ }))
7668
+ };
7669
+ return {
7670
+ content: [{ type: "text", text: JSON.stringify(response, null, 2) }]
7671
+ };
7672
+ } catch (err) {
7673
+ return {
7674
+ content: [{ type: "text", text: JSON.stringify({ error: err.message }) }]
7675
+ };
7676
+ }
7677
+ }
7678
+
7031
7679
  // src/mcp/tools/compact.ts
7032
7680
  init_dist();
7033
7681
  var COMPACT_TOOL_DEFAULT_BUDGET = 2e3;
@@ -7116,7 +7764,7 @@ function handleContentMode(content, pipeline, budget, source) {
7116
7764
  };
7117
7765
  }
7118
7766
  async function handleIntentMode(projectPath, intent, pipeline, budget, filterContent) {
7119
- const { loadGraphStore: loadGraphStore2 } = await import("./graph-loader-TIVI6NQ7.js");
7767
+ const { loadGraphStore: loadGraphStore2 } = await import("./graph-loader-QEI7SYOQ.js");
7120
7768
  const store = await loadGraphStore2(projectPath);
7121
7769
  if (!store) {
7122
7770
  return {
@@ -7129,7 +7777,7 @@ async function handleIntentMode(projectPath, intent, pipeline, budget, filterCon
7129
7777
  isError: true
7130
7778
  };
7131
7779
  }
7132
- const { PackedSummaryCache, FusionLayer, ContextQL } = await import("./dist-PGQ32ZI7.js");
7780
+ const { PackedSummaryCache, FusionLayer, ContextQL } = await import("./dist-BZS2XRLG.js");
7133
7781
  const cache = new PackedSummaryCache(store);
7134
7782
  const cachedEnvelope = cache.get(intent);
7135
7783
  if (cachedEnvelope) {
@@ -7342,7 +7990,7 @@ async function handleDetectConstraintEmergence(input) {
7342
7990
  }
7343
7991
  const nodePath = await import("path");
7344
7992
  const historyPath = nodePath.resolve(projectPath, ".harness/arch/violation-history.json");
7345
- const { ViolationHistoryManager, detectEmergentConstraints } = await import("./dist-TG63OKA5.js");
7993
+ const { ViolationHistoryManager, detectEmergentConstraints } = await import("./dist-CPKL5Y2R.js");
7346
7994
  const manager = new ViolationHistoryManager(historyPath);
7347
7995
  const history = manager.load();
7348
7996
  const options = { windowWeeks, minOccurrences };
@@ -7371,6 +8019,146 @@ async function handleDetectConstraintEmergence(input) {
7371
8019
  }
7372
8020
  }
7373
8021
 
8022
+ // src/mcp/tools/ci.ts
8023
+ var VALID_CHECKS = [
8024
+ "validate",
8025
+ "deps",
8026
+ "docs",
8027
+ "entropy",
8028
+ "security",
8029
+ "perf",
8030
+ "phase-gate",
8031
+ "arch",
8032
+ "traceability"
8033
+ ];
8034
+ var runCIChecksDefinition = {
8035
+ name: "run_ci_checks",
8036
+ description: "Run CI/CD validation checks on a harness project. Returns pass/fail results per check with issues. Checks: validate, deps, docs, entropy, security, perf, phase-gate, arch, traceability.",
8037
+ inputSchema: {
8038
+ type: "object",
8039
+ properties: {
8040
+ path: { type: "string", description: "Path to project root directory" },
8041
+ checks: {
8042
+ type: "array",
8043
+ items: {
8044
+ type: "string",
8045
+ enum: VALID_CHECKS
8046
+ },
8047
+ description: "Subset of checks to run (default: all)"
8048
+ }
8049
+ },
8050
+ required: ["path"]
8051
+ }
8052
+ };
8053
+ async function handleRunCIChecks(input) {
8054
+ let projectPath;
8055
+ try {
8056
+ projectPath = sanitizePath(input.path);
8057
+ } catch (error) {
8058
+ return {
8059
+ content: [
8060
+ {
8061
+ type: "text",
8062
+ text: `Error: ${error instanceof Error ? error.message : String(error)}`
8063
+ }
8064
+ ],
8065
+ isError: true
8066
+ };
8067
+ }
8068
+ const configResult = resolveProjectConfig(projectPath);
8069
+ if (!configResult.ok) {
8070
+ return {
8071
+ content: [
8072
+ {
8073
+ type: "text",
8074
+ text: `Error: ${configResult.error.message}`
8075
+ }
8076
+ ],
8077
+ isError: true
8078
+ };
8079
+ }
8080
+ try {
8081
+ const { runCIChecks } = await import("./dist-CPKL5Y2R.js");
8082
+ const skip = input.checks ? VALID_CHECKS.filter((c) => !input.checks.includes(c)) : [];
8083
+ const result = await runCIChecks({
8084
+ projectRoot: projectPath,
8085
+ config: configResult.value,
8086
+ ...skip.length > 0 ? { skip } : {}
8087
+ });
8088
+ if (!result.ok) {
8089
+ return {
8090
+ content: [
8091
+ {
8092
+ type: "text",
8093
+ text: `Error: ${result.error.message}`
8094
+ }
8095
+ ],
8096
+ isError: true
8097
+ };
8098
+ }
8099
+ return {
8100
+ content: [{ type: "text", text: JSON.stringify(result.value) }]
8101
+ };
8102
+ } catch (error) {
8103
+ return {
8104
+ content: [
8105
+ {
8106
+ type: "text",
8107
+ text: `Error running CI checks: ${error instanceof Error ? error.message : String(error)}`
8108
+ }
8109
+ ],
8110
+ isError: true
8111
+ };
8112
+ }
8113
+ }
8114
+
8115
+ // src/mcp/tools/blueprint.ts
8116
+ var generateBlueprintDefinition = {
8117
+ name: "generate_blueprint",
8118
+ description: "Scan a project and return its blueprint data (modules, hotspots, dependencies). Returns the scan results as JSON without writing files.",
8119
+ inputSchema: {
8120
+ type: "object",
8121
+ properties: {
8122
+ path: { type: "string", description: "Path to project root directory" }
8123
+ },
8124
+ required: ["path"]
8125
+ }
8126
+ };
8127
+ async function handleGenerateBlueprint(input) {
8128
+ let projectPath;
8129
+ try {
8130
+ projectPath = sanitizePath(input.path);
8131
+ } catch (error) {
8132
+ return {
8133
+ content: [
8134
+ {
8135
+ type: "text",
8136
+ text: `Error: ${error instanceof Error ? error.message : String(error)}`
8137
+ }
8138
+ ],
8139
+ isError: true
8140
+ };
8141
+ }
8142
+ try {
8143
+ const { ProjectScanner } = await import("./dist-CPKL5Y2R.js");
8144
+ const scanner = new ProjectScanner(projectPath);
8145
+ const data = await scanner.scan();
8146
+ return {
8147
+ content: [{ type: "text", text: JSON.stringify(data) }]
8148
+ };
8149
+ } catch (error) {
8150
+ return {
8151
+ content: [
8152
+ {
8153
+ type: "text",
8154
+ text: `Error generating blueprint: ${error instanceof Error ? error.message : String(error)}`
8155
+ }
8156
+ ],
8157
+ isError: true
8158
+ };
8159
+ }
8160
+ }
8161
+
7374
8162
  // src/mcp/server.ts
7375
8163
  var TOOL_DEFINITIONS = [
7376
8164
  validateToolDefinition,
@@ -7427,10 +8215,13 @@ var TOOL_DEFINITIONS = [
7427
8215
  checkTraceabilityDefinition,
7428
8216
  predictFailuresDefinition,
7429
8217
  recommendSkillsDefinition,
8218
+ adviseSkillsDefinition,
7430
8219
  computeBlastRadiusDefinition,
7431
8220
  dispatchSkillsDefinition,
7432
8221
  compactToolDefinition,
7433
- detectConstraintEmergenceDefinition
8222
+ detectConstraintEmergenceDefinition,
8223
+ runCIChecksDefinition,
8224
+ generateBlueprintDefinition
7434
8225
  ].map((def) => ({ ...def, trustedOutput: true }));
7435
8226
  var TOOL_HANDLERS = {
7436
8227
  validate_project: handleValidateProject,
@@ -7487,10 +8278,13 @@ var TOOL_HANDLERS = {
7487
8278
  check_traceability: handleCheckTraceability,
7488
8279
  predict_failures: handlePredictFailures,
7489
8280
  recommend_skills: handleRecommendSkills,
8281
+ advise_skills: handleAdviseSkills,
7490
8282
  compute_blast_radius: handleComputeBlastRadius,
7491
8283
  dispatch_skills: handleDispatchSkills,
7492
8284
  compact: handleCompact,
7493
- detect_constraint_emergence: handleDetectConstraintEmergence
8285
+ detect_constraint_emergence: handleDetectConstraintEmergence,
8286
+ run_ci_checks: handleRunCIChecks,
8287
+ generate_blueprint: handleGenerateBlueprint
7494
8288
  };
7495
8289
  var RESOURCE_DEFINITIONS = [
7496
8290
  {
@@ -7592,7 +8386,7 @@ async function appendUpdateNotification(result, resolvedRoot) {
7592
8386
  shouldRunCheck,
7593
8387
  readCheckState,
7594
8388
  spawnBackgroundCheck
7595
- } = await import("./dist-TG63OKA5.js");
8389
+ } = await import("./dist-CPKL5Y2R.js");
7596
8390
  const { CLI_VERSION } = await import("./version-CUI434OP.js");
7597
8391
  const configInterval = readConfigInterval(resolvedRoot);
7598
8392
  const DEFAULT_INTERVAL = 864e5;
@@ -7686,6 +8480,7 @@ async function startServer(toolFilter) {
7686
8480
  }
7687
8481
 
7688
8482
  export {
8483
+ createAdviseSkillsCommand,
7689
8484
  generateSlashCommands,
7690
8485
  handleOrphanDeletion,
7691
8486
  createGenerateSlashCommandsCommand,
@@ -7693,7 +8488,6 @@ export {
7693
8488
  persistToolingConfig,
7694
8489
  ensureHarnessGitignore,
7695
8490
  appendFrameworkAgents,
7696
- loadOrRebuildIndex,
7697
8491
  isSnapshotFresh,
7698
8492
  loadCachedSnapshot,
7699
8493
  captureHealthSnapshot,