@contractspec/bundle.workspace 1.44.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 (425) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +79 -0
  3. package/dist/_virtual/rolldown_runtime.js +36 -0
  4. package/dist/adapters/ai.d.ts +12 -0
  5. package/dist/adapters/ai.d.ts.map +1 -0
  6. package/dist/adapters/ai.js +83 -0
  7. package/dist/adapters/ai.js.map +1 -0
  8. package/dist/adapters/factory.d.ts +29 -0
  9. package/dist/adapters/factory.d.ts.map +1 -0
  10. package/dist/adapters/factory.js +37 -0
  11. package/dist/adapters/factory.js.map +1 -0
  12. package/dist/adapters/fs.d.ts +11 -0
  13. package/dist/adapters/fs.d.ts.map +1 -0
  14. package/dist/adapters/fs.js +131 -0
  15. package/dist/adapters/fs.js.map +1 -0
  16. package/dist/adapters/git.d.ts +11 -0
  17. package/dist/adapters/git.d.ts.map +1 -0
  18. package/dist/adapters/git.js +55 -0
  19. package/dist/adapters/git.js.map +1 -0
  20. package/dist/adapters/index.d.ts +7 -0
  21. package/dist/adapters/index.js +7 -0
  22. package/dist/adapters/logger.d.ts +18 -0
  23. package/dist/adapters/logger.d.ts.map +1 -0
  24. package/dist/adapters/logger.js +81 -0
  25. package/dist/adapters/logger.js.map +1 -0
  26. package/dist/adapters/watcher.d.ts +11 -0
  27. package/dist/adapters/watcher.d.ts.map +1 -0
  28. package/dist/adapters/watcher.js +74 -0
  29. package/dist/adapters/watcher.js.map +1 -0
  30. package/dist/adapters/workspace.d.ts +148 -0
  31. package/dist/adapters/workspace.d.ts.map +1 -0
  32. package/dist/adapters/workspace.js +275 -0
  33. package/dist/adapters/workspace.js.map +1 -0
  34. package/dist/ai/agents/claude-code-agent.d.ts +22 -0
  35. package/dist/ai/agents/claude-code-agent.d.ts.map +1 -0
  36. package/dist/ai/agents/claude-code-agent.js +182 -0
  37. package/dist/ai/agents/claude-code-agent.js.map +1 -0
  38. package/dist/ai/agents/cursor-agent.d.ts +68 -0
  39. package/dist/ai/agents/cursor-agent.d.ts.map +1 -0
  40. package/dist/ai/agents/cursor-agent.js +436 -0
  41. package/dist/ai/agents/cursor-agent.js.map +1 -0
  42. package/dist/ai/agents/index.js +5 -0
  43. package/dist/ai/agents/openai-codex-agent.d.ts +22 -0
  44. package/dist/ai/agents/openai-codex-agent.d.ts.map +1 -0
  45. package/dist/ai/agents/openai-codex-agent.js +167 -0
  46. package/dist/ai/agents/openai-codex-agent.js.map +1 -0
  47. package/dist/ai/agents/orchestrator.d.ts +50 -0
  48. package/dist/ai/agents/orchestrator.d.ts.map +1 -0
  49. package/dist/ai/agents/orchestrator.js +143 -0
  50. package/dist/ai/agents/orchestrator.js.map +1 -0
  51. package/dist/ai/agents/simple-agent.d.ts +17 -0
  52. package/dist/ai/agents/simple-agent.d.ts.map +1 -0
  53. package/dist/ai/agents/simple-agent.js +92 -0
  54. package/dist/ai/agents/simple-agent.js.map +1 -0
  55. package/dist/ai/agents/types.d.ts +36 -0
  56. package/dist/ai/agents/types.d.ts.map +1 -0
  57. package/dist/ai/client.d.ts +83 -0
  58. package/dist/ai/client.d.ts.map +1 -0
  59. package/dist/ai/client.js +163 -0
  60. package/dist/ai/client.js.map +1 -0
  61. package/dist/ai/index.d.ts +17 -0
  62. package/dist/ai/index.d.ts.map +1 -0
  63. package/dist/ai/index.js +28 -0
  64. package/dist/ai/index.js.map +1 -0
  65. package/dist/ai/prompts/code-generation.d.ts +26 -0
  66. package/dist/ai/prompts/code-generation.d.ts.map +1 -0
  67. package/dist/ai/prompts/code-generation.js +143 -0
  68. package/dist/ai/prompts/code-generation.js.map +1 -0
  69. package/dist/ai/prompts/index.d.ts +10 -0
  70. package/dist/ai/prompts/index.d.ts.map +1 -0
  71. package/dist/ai/prompts/index.js +13 -0
  72. package/dist/ai/prompts/index.js.map +1 -0
  73. package/dist/ai/prompts/spec-creation.d.ts +29 -0
  74. package/dist/ai/prompts/spec-creation.d.ts.map +1 -0
  75. package/dist/ai/prompts/spec-creation.js +111 -0
  76. package/dist/ai/prompts/spec-creation.js.map +1 -0
  77. package/dist/ai/providers.d.ts +29 -0
  78. package/dist/ai/providers.d.ts.map +1 -0
  79. package/dist/ai/providers.js +39 -0
  80. package/dist/ai/providers.js.map +1 -0
  81. package/dist/formatters/index.d.ts +11 -0
  82. package/dist/formatters/index.d.ts.map +1 -0
  83. package/dist/formatters/index.js +19 -0
  84. package/dist/formatters/index.js.map +1 -0
  85. package/dist/formatters/json.d.ts +89 -0
  86. package/dist/formatters/json.d.ts.map +1 -0
  87. package/dist/formatters/json.js +72 -0
  88. package/dist/formatters/json.js.map +1 -0
  89. package/dist/formatters/sarif.d.ts +101 -0
  90. package/dist/formatters/sarif.d.ts.map +1 -0
  91. package/dist/formatters/sarif.js +163 -0
  92. package/dist/formatters/sarif.js.map +1 -0
  93. package/dist/formatters/text.d.ts +35 -0
  94. package/dist/formatters/text.d.ts.map +1 -0
  95. package/dist/formatters/text.js +209 -0
  96. package/dist/formatters/text.js.map +1 -0
  97. package/dist/index.d.ts +82 -0
  98. package/dist/index.d.ts.map +1 -0
  99. package/dist/index.js +204 -0
  100. package/dist/index.js.map +1 -0
  101. package/dist/ports/ai.d.ts +59 -0
  102. package/dist/ports/ai.d.ts.map +1 -0
  103. package/dist/ports/fs.d.ts +81 -0
  104. package/dist/ports/fs.d.ts.map +1 -0
  105. package/dist/ports/git.d.ts +33 -0
  106. package/dist/ports/git.d.ts.map +1 -0
  107. package/dist/ports/index.d.ts +5 -0
  108. package/dist/ports/logger.d.ts +88 -0
  109. package/dist/ports/logger.d.ts.map +1 -0
  110. package/dist/ports/watcher.d.ts +52 -0
  111. package/dist/ports/watcher.d.ts.map +1 -0
  112. package/dist/services/agent-guide/adapters/claude-code.d.ts +35 -0
  113. package/dist/services/agent-guide/adapters/claude-code.d.ts.map +1 -0
  114. package/dist/services/agent-guide/adapters/claude-code.js +144 -0
  115. package/dist/services/agent-guide/adapters/claude-code.js.map +1 -0
  116. package/dist/services/agent-guide/adapters/cursor-cli.d.ts +39 -0
  117. package/dist/services/agent-guide/adapters/cursor-cli.d.ts.map +1 -0
  118. package/dist/services/agent-guide/adapters/cursor-cli.js +135 -0
  119. package/dist/services/agent-guide/adapters/cursor-cli.js.map +1 -0
  120. package/dist/services/agent-guide/adapters/generic-mcp.d.ts +53 -0
  121. package/dist/services/agent-guide/adapters/generic-mcp.d.ts.map +1 -0
  122. package/dist/services/agent-guide/adapters/generic-mcp.js +159 -0
  123. package/dist/services/agent-guide/adapters/generic-mcp.js.map +1 -0
  124. package/dist/services/agent-guide/adapters/index.d.ts +23 -0
  125. package/dist/services/agent-guide/adapters/index.d.ts.map +1 -0
  126. package/dist/services/agent-guide/adapters/index.js +31 -0
  127. package/dist/services/agent-guide/adapters/index.js.map +1 -0
  128. package/dist/services/agent-guide/agent-guide-service.d.ts +56 -0
  129. package/dist/services/agent-guide/agent-guide-service.d.ts.map +1 -0
  130. package/dist/services/agent-guide/agent-guide-service.js +147 -0
  131. package/dist/services/agent-guide/agent-guide-service.js.map +1 -0
  132. package/dist/services/agent-guide/index.d.ts +6 -0
  133. package/dist/services/agent-guide/index.js +5 -0
  134. package/dist/services/agent-guide/types.d.ts +58 -0
  135. package/dist/services/agent-guide/types.d.ts.map +1 -0
  136. package/dist/services/build.d.ts +59 -0
  137. package/dist/services/build.d.ts.map +1 -0
  138. package/dist/services/build.js +140 -0
  139. package/dist/services/build.js.map +1 -0
  140. package/dist/services/ci-check/ci-check-service.d.ts +16 -0
  141. package/dist/services/ci-check/ci-check-service.d.ts.map +1 -0
  142. package/dist/services/ci-check/ci-check-service.js +392 -0
  143. package/dist/services/ci-check/ci-check-service.js.map +1 -0
  144. package/dist/services/ci-check/index.d.ts +2 -0
  145. package/dist/services/ci-check/index.js +2 -0
  146. package/dist/services/ci-check/types.d.ts +143 -0
  147. package/dist/services/ci-check/types.d.ts.map +1 -0
  148. package/dist/services/ci-check/types.js +29 -0
  149. package/dist/services/ci-check/types.js.map +1 -0
  150. package/dist/services/clean.d.ts +41 -0
  151. package/dist/services/clean.d.ts.map +1 -0
  152. package/dist/services/clean.js +72 -0
  153. package/dist/services/clean.js.map +1 -0
  154. package/dist/services/config.d.ts +26 -0
  155. package/dist/services/config.d.ts.map +1 -0
  156. package/dist/services/config.js +77 -0
  157. package/dist/services/config.js.map +1 -0
  158. package/dist/services/deps.d.ts +53 -0
  159. package/dist/services/deps.d.ts.map +1 -0
  160. package/dist/services/deps.js +62 -0
  161. package/dist/services/deps.js.map +1 -0
  162. package/dist/services/diff.d.ts +34 -0
  163. package/dist/services/diff.d.ts.map +1 -0
  164. package/dist/services/diff.js +34 -0
  165. package/dist/services/diff.js.map +1 -0
  166. package/dist/services/doctor/checks/ai.js +119 -0
  167. package/dist/services/doctor/checks/ai.js.map +1 -0
  168. package/dist/services/doctor/checks/cli.js +147 -0
  169. package/dist/services/doctor/checks/cli.js.map +1 -0
  170. package/dist/services/doctor/checks/config.js +171 -0
  171. package/dist/services/doctor/checks/config.js.map +1 -0
  172. package/dist/services/doctor/checks/deps.js +247 -0
  173. package/dist/services/doctor/checks/deps.js.map +1 -0
  174. package/dist/services/doctor/checks/index.js +6 -0
  175. package/dist/services/doctor/checks/mcp.js +145 -0
  176. package/dist/services/doctor/checks/mcp.js.map +1 -0
  177. package/dist/services/doctor/checks/workspace.js +244 -0
  178. package/dist/services/doctor/checks/workspace.js.map +1 -0
  179. package/dist/services/doctor/doctor-service.d.ts +24 -0
  180. package/dist/services/doctor/doctor-service.d.ts.map +1 -0
  181. package/dist/services/doctor/doctor-service.js +116 -0
  182. package/dist/services/doctor/doctor-service.js.map +1 -0
  183. package/dist/services/doctor/index.d.ts +2 -0
  184. package/dist/services/doctor/index.js +2 -0
  185. package/dist/services/doctor/types.d.ts +118 -0
  186. package/dist/services/doctor/types.d.ts.map +1 -0
  187. package/dist/services/doctor/types.js +27 -0
  188. package/dist/services/doctor/types.js.map +1 -0
  189. package/dist/services/impact/formatters.d.ts +27 -0
  190. package/dist/services/impact/formatters.d.ts.map +1 -0
  191. package/dist/services/impact/formatters.js +111 -0
  192. package/dist/services/impact/formatters.js.map +1 -0
  193. package/dist/services/impact/impact-detection-service.d.ts +22 -0
  194. package/dist/services/impact/impact-detection-service.d.ts.map +1 -0
  195. package/dist/services/impact/impact-detection-service.js +96 -0
  196. package/dist/services/impact/impact-detection-service.js.map +1 -0
  197. package/dist/services/impact/index.d.ts +11 -0
  198. package/dist/services/impact/index.d.ts.map +1 -0
  199. package/dist/services/impact/index.js +16 -0
  200. package/dist/services/impact/index.js.map +1 -0
  201. package/dist/services/impact/types.d.ts +58 -0
  202. package/dist/services/impact/types.d.ts.map +1 -0
  203. package/dist/services/implementation/discovery.d.ts +30 -0
  204. package/dist/services/implementation/discovery.d.ts.map +1 -0
  205. package/dist/services/implementation/discovery.js +144 -0
  206. package/dist/services/implementation/discovery.js.map +1 -0
  207. package/dist/services/implementation/index.d.ts +3 -0
  208. package/dist/services/implementation/index.js +2 -0
  209. package/dist/services/implementation/resolver.d.ts +44 -0
  210. package/dist/services/implementation/resolver.d.ts.map +1 -0
  211. package/dist/services/implementation/resolver.js +224 -0
  212. package/dist/services/implementation/resolver.js.map +1 -0
  213. package/dist/services/implementation/types.d.ts +79 -0
  214. package/dist/services/implementation/types.d.ts.map +1 -0
  215. package/dist/services/index.d.ts +60 -0
  216. package/dist/services/index.js +57 -0
  217. package/dist/services/integrity-diagram.d.ts +36 -0
  218. package/dist/services/integrity-diagram.d.ts.map +1 -0
  219. package/dist/services/integrity-diagram.js +275 -0
  220. package/dist/services/integrity-diagram.js.map +1 -0
  221. package/dist/services/integrity.d.ts +134 -0
  222. package/dist/services/integrity.d.ts.map +1 -0
  223. package/dist/services/integrity.js +272 -0
  224. package/dist/services/integrity.js.map +1 -0
  225. package/dist/services/list.d.ts +31 -0
  226. package/dist/services/list.d.ts.map +1 -0
  227. package/dist/services/list.js +36 -0
  228. package/dist/services/list.js.map +1 -0
  229. package/dist/services/openapi/export-service.d.ts +53 -0
  230. package/dist/services/openapi/export-service.d.ts.map +1 -0
  231. package/dist/services/openapi/export-service.js +50 -0
  232. package/dist/services/openapi/export-service.js.map +1 -0
  233. package/dist/services/openapi/import-service.d.ts +17 -0
  234. package/dist/services/openapi/import-service.d.ts.map +1 -0
  235. package/dist/services/openapi/import-service.js +74 -0
  236. package/dist/services/openapi/import-service.js.map +1 -0
  237. package/dist/services/openapi/index.d.ts +5 -0
  238. package/dist/services/openapi/index.js +4 -0
  239. package/dist/services/openapi/sync-service.d.ts +17 -0
  240. package/dist/services/openapi/sync-service.d.ts.map +1 -0
  241. package/dist/services/openapi/sync-service.js +120 -0
  242. package/dist/services/openapi/sync-service.js.map +1 -0
  243. package/dist/services/openapi/types.d.ts +162 -0
  244. package/dist/services/openapi/types.d.ts.map +1 -0
  245. package/dist/services/openapi/validate-service.d.ts +16 -0
  246. package/dist/services/openapi/validate-service.d.ts.map +1 -0
  247. package/dist/services/openapi/validate-service.js +130 -0
  248. package/dist/services/openapi/validate-service.js.map +1 -0
  249. package/dist/services/quickstart/dependencies.d.ts +31 -0
  250. package/dist/services/quickstart/dependencies.d.ts.map +1 -0
  251. package/dist/services/quickstart/dependencies.js +57 -0
  252. package/dist/services/quickstart/dependencies.js.map +1 -0
  253. package/dist/services/quickstart/index.js +2 -0
  254. package/dist/services/quickstart/quickstart-service.d.ts +20 -0
  255. package/dist/services/quickstart/quickstart-service.d.ts.map +1 -0
  256. package/dist/services/quickstart/quickstart-service.js +196 -0
  257. package/dist/services/quickstart/quickstart-service.js.map +1 -0
  258. package/dist/services/quickstart/types.d.ts +81 -0
  259. package/dist/services/quickstart/types.d.ts.map +1 -0
  260. package/dist/services/regenerator.d.ts +18 -0
  261. package/dist/services/regenerator.d.ts.map +1 -0
  262. package/dist/services/regenerator.js +23 -0
  263. package/dist/services/regenerator.js.map +1 -0
  264. package/dist/services/registry.d.ts +53 -0
  265. package/dist/services/registry.d.ts.map +1 -0
  266. package/dist/services/registry.js +74 -0
  267. package/dist/services/registry.js.map +1 -0
  268. package/dist/services/setup/config-generators.d.ts +42 -0
  269. package/dist/services/setup/config-generators.d.ts.map +1 -0
  270. package/dist/services/setup/config-generators.js +238 -0
  271. package/dist/services/setup/config-generators.js.map +1 -0
  272. package/dist/services/setup/file-merger.d.ts +27 -0
  273. package/dist/services/setup/file-merger.d.ts.map +1 -0
  274. package/dist/services/setup/file-merger.js +61 -0
  275. package/dist/services/setup/file-merger.js.map +1 -0
  276. package/dist/services/setup/index.js +4 -0
  277. package/dist/services/setup/setup-service.d.ts +12 -0
  278. package/dist/services/setup/setup-service.d.ts.map +1 -0
  279. package/dist/services/setup/setup-service.js +96 -0
  280. package/dist/services/setup/setup-service.js.map +1 -0
  281. package/dist/services/setup/targets/agents-md.js +47 -0
  282. package/dist/services/setup/targets/agents-md.js.map +1 -0
  283. package/dist/services/setup/targets/cli-config.js +60 -0
  284. package/dist/services/setup/targets/cli-config.js.map +1 -0
  285. package/dist/services/setup/targets/cursor-rules.js +48 -0
  286. package/dist/services/setup/targets/cursor-rules.js.map +1 -0
  287. package/dist/services/setup/targets/mcp-claude.js +60 -0
  288. package/dist/services/setup/targets/mcp-claude.js.map +1 -0
  289. package/dist/services/setup/targets/mcp-cursor.js +59 -0
  290. package/dist/services/setup/targets/mcp-cursor.js.map +1 -0
  291. package/dist/services/setup/targets/vscode-settings.js +63 -0
  292. package/dist/services/setup/targets/vscode-settings.js.map +1 -0
  293. package/dist/services/setup/types.d.ts +85 -0
  294. package/dist/services/setup/types.d.ts.map +1 -0
  295. package/dist/services/setup/types.js +27 -0
  296. package/dist/services/setup/types.js.map +1 -0
  297. package/dist/services/sync.d.ts +41 -0
  298. package/dist/services/sync.d.ts.map +1 -0
  299. package/dist/services/sync.js +63 -0
  300. package/dist/services/sync.js.map +1 -0
  301. package/dist/services/test.d.ts +15 -0
  302. package/dist/services/test.d.ts.map +1 -0
  303. package/dist/services/test.js +30 -0
  304. package/dist/services/test.js.map +1 -0
  305. package/dist/services/validate-implementation.d.ts +32 -0
  306. package/dist/services/validate-implementation.d.ts.map +1 -0
  307. package/dist/services/validate-implementation.js +64 -0
  308. package/dist/services/validate-implementation.js.map +1 -0
  309. package/dist/services/validate.d.ts +41 -0
  310. package/dist/services/validate.d.ts.map +1 -0
  311. package/dist/services/validate.js +48 -0
  312. package/dist/services/validate.js.map +1 -0
  313. package/dist/services/verification-cache/adapters/filesystem.d.ts +46 -0
  314. package/dist/services/verification-cache/adapters/filesystem.d.ts.map +1 -0
  315. package/dist/services/verification-cache/adapters/filesystem.js +120 -0
  316. package/dist/services/verification-cache/adapters/filesystem.js.map +1 -0
  317. package/dist/services/verification-cache/adapters/in-memory.d.ts +27 -0
  318. package/dist/services/verification-cache/adapters/in-memory.d.ts.map +1 -0
  319. package/dist/services/verification-cache/adapters/in-memory.js +46 -0
  320. package/dist/services/verification-cache/adapters/in-memory.js.map +1 -0
  321. package/dist/services/verification-cache/adapters/index.d.ts +3 -0
  322. package/dist/services/verification-cache/adapters/index.js +3 -0
  323. package/dist/services/verification-cache/adapters/workspace-state.d.ts +49 -0
  324. package/dist/services/verification-cache/adapters/workspace-state.d.ts.map +1 -0
  325. package/dist/services/verification-cache/adapters/workspace-state.js +91 -0
  326. package/dist/services/verification-cache/adapters/workspace-state.js.map +1 -0
  327. package/dist/services/verification-cache/cache-service.d.ts +70 -0
  328. package/dist/services/verification-cache/cache-service.d.ts.map +1 -0
  329. package/dist/services/verification-cache/cache-service.js +256 -0
  330. package/dist/services/verification-cache/cache-service.js.map +1 -0
  331. package/dist/services/verification-cache/index.d.ts +6 -0
  332. package/dist/services/verification-cache/index.js +6 -0
  333. package/dist/services/verification-cache/types.d.ts +124 -0
  334. package/dist/services/verification-cache/types.d.ts.map +1 -0
  335. package/dist/services/verification-cache/types.js +16 -0
  336. package/dist/services/verification-cache/types.js.map +1 -0
  337. package/dist/services/verify/ai-verifier.d.ts +25 -0
  338. package/dist/services/verify/ai-verifier.d.ts.map +1 -0
  339. package/dist/services/verify/ai-verifier.js +403 -0
  340. package/dist/services/verify/ai-verifier.js.map +1 -0
  341. package/dist/services/verify/behavior-verifier.d.ts +12 -0
  342. package/dist/services/verify/behavior-verifier.d.ts.map +1 -0
  343. package/dist/services/verify/behavior-verifier.js +186 -0
  344. package/dist/services/verify/behavior-verifier.js.map +1 -0
  345. package/dist/services/verify/index.d.ts +5 -0
  346. package/dist/services/verify/index.js +4 -0
  347. package/dist/services/verify/structure-verifier.d.ts +12 -0
  348. package/dist/services/verify/structure-verifier.d.ts.map +1 -0
  349. package/dist/services/verify/structure-verifier.js +196 -0
  350. package/dist/services/verify/structure-verifier.js.map +1 -0
  351. package/dist/services/verify/types.d.ts +137 -0
  352. package/dist/services/verify/types.d.ts.map +1 -0
  353. package/dist/services/verify/verify-service.d.ts +60 -0
  354. package/dist/services/verify/verify-service.d.ts.map +1 -0
  355. package/dist/services/verify/verify-service.js +204 -0
  356. package/dist/services/verify/verify-service.js.map +1 -0
  357. package/dist/services/watch.d.ts +25 -0
  358. package/dist/services/watch.d.ts.map +1 -0
  359. package/dist/services/watch.js +32 -0
  360. package/dist/services/watch.js.map +1 -0
  361. package/dist/services/workspace-info.d.ts +62 -0
  362. package/dist/services/workspace-info.d.ts.map +1 -0
  363. package/dist/services/workspace-info.js +103 -0
  364. package/dist/services/workspace-info.js.map +1 -0
  365. package/dist/templates/app-config.template.d.ts +7 -0
  366. package/dist/templates/app-config.template.d.ts.map +1 -0
  367. package/dist/templates/app-config.template.js +107 -0
  368. package/dist/templates/app-config.template.js.map +1 -0
  369. package/dist/templates/data-view.template.d.ts +7 -0
  370. package/dist/templates/data-view.template.d.ts.map +1 -0
  371. package/dist/templates/data-view.template.js +70 -0
  372. package/dist/templates/data-view.template.js.map +1 -0
  373. package/dist/templates/event.template.d.ts +11 -0
  374. package/dist/templates/event.template.d.ts.map +1 -0
  375. package/dist/templates/event.template.js +40 -0
  376. package/dist/templates/event.template.js.map +1 -0
  377. package/dist/templates/experiment.template.d.ts +7 -0
  378. package/dist/templates/experiment.template.d.ts.map +1 -0
  379. package/dist/templates/experiment.template.js +89 -0
  380. package/dist/templates/experiment.template.js.map +1 -0
  381. package/dist/templates/handler.template.d.ts +16 -0
  382. package/dist/templates/handler.template.d.ts.map +1 -0
  383. package/dist/templates/handler.template.js +100 -0
  384. package/dist/templates/handler.template.js.map +1 -0
  385. package/dist/templates/index.d.ts +21 -0
  386. package/dist/templates/index.d.ts.map +1 -0
  387. package/dist/templates/index.js +37 -0
  388. package/dist/templates/index.js.map +1 -0
  389. package/dist/templates/integration.template.d.ts +7 -0
  390. package/dist/templates/integration.template.d.ts.map +1 -0
  391. package/dist/templates/integration.template.js +160 -0
  392. package/dist/templates/integration.template.js.map +1 -0
  393. package/dist/templates/knowledge.template.d.ts +7 -0
  394. package/dist/templates/knowledge.template.d.ts.map +1 -0
  395. package/dist/templates/knowledge.template.js +75 -0
  396. package/dist/templates/knowledge.template.js.map +1 -0
  397. package/dist/templates/migration.template.d.ts +7 -0
  398. package/dist/templates/migration.template.d.ts.map +1 -0
  399. package/dist/templates/migration.template.js +62 -0
  400. package/dist/templates/migration.template.js.map +1 -0
  401. package/dist/templates/operation.template.d.ts +11 -0
  402. package/dist/templates/operation.template.d.ts.map +1 -0
  403. package/dist/templates/operation.template.js +105 -0
  404. package/dist/templates/operation.template.js.map +1 -0
  405. package/dist/templates/presentation.template.d.ts +11 -0
  406. package/dist/templates/presentation.template.d.ts.map +1 -0
  407. package/dist/templates/presentation.template.js +80 -0
  408. package/dist/templates/presentation.template.js.map +1 -0
  409. package/dist/templates/telemetry.template.d.ts +7 -0
  410. package/dist/templates/telemetry.template.d.ts.map +1 -0
  411. package/dist/templates/telemetry.template.js +91 -0
  412. package/dist/templates/telemetry.template.js.map +1 -0
  413. package/dist/templates/workflow-runner.template.d.ts +16 -0
  414. package/dist/templates/workflow-runner.template.d.ts.map +1 -0
  415. package/dist/templates/workflow-runner.template.js +50 -0
  416. package/dist/templates/workflow-runner.template.js.map +1 -0
  417. package/dist/templates/workflow.template.d.ts +7 -0
  418. package/dist/templates/workflow.template.d.ts.map +1 -0
  419. package/dist/templates/workflow.template.js +69 -0
  420. package/dist/templates/workflow.template.js.map +1 -0
  421. package/dist/types/config.d.ts +34 -0
  422. package/dist/types/config.d.ts.map +1 -0
  423. package/dist/types.d.ts +324 -0
  424. package/dist/types.d.ts.map +1 -0
  425. package/package.json +68 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace.js","names":["results: CheckResult[]"],"sources":["../../../../src/services/doctor/checks/workspace.ts"],"sourcesContent":["/**\n * Workspace structure health checks.\n *\n * Monorepo-aware checks for contracts and output directories.\n */\n\nimport type { FsAdapter } from '../../../ports/fs';\nimport type { CheckContext, CheckResult, FixResult } from '../types';\n\n/**\n * Common contract directory paths to check.\n */\nconst CONTRACT_PATHS = ['src/contracts', 'contracts', 'src/specs', 'specs'];\n\n/**\n * Run workspace-related health checks.\n */\nexport async function runWorkspaceChecks(\n fs: FsAdapter,\n ctx: CheckContext\n): Promise<CheckResult[]> {\n const results: CheckResult[] = [];\n\n // Check monorepo status first (informational)\n results.push(checkMonorepoStatus(ctx));\n\n // Check if this is a valid workspace (has package.json)\n results.push(await checkValidWorkspace(fs, ctx));\n\n // Check if contracts directory exists (monorepo-aware)\n results.push(await checkContractsDirectory(fs, ctx));\n\n // Check if any contract files exist\n results.push(await checkContractFiles(fs, ctx));\n\n // Check output directory (monorepo-aware)\n results.push(await checkOutputDirectory(fs, ctx));\n\n return results;\n}\n\n/**\n * Report monorepo detection status.\n */\nfunction checkMonorepoStatus(ctx: CheckContext): CheckResult {\n if (ctx.isMonorepo) {\n const pkgInfo = ctx.packageName ? ` in package \"${ctx.packageName}\"` : '';\n const locationInfo =\n ctx.packageRoot !== ctx.workspaceRoot\n ? ` (package root: ${ctx.packageRoot})`\n : '';\n return {\n category: 'workspace',\n name: 'Monorepo Detection',\n status: 'pass',\n message: `Monorepo detected${pkgInfo}`,\n details: ctx.verbose\n ? `Workspace root: ${ctx.workspaceRoot}${locationInfo}`\n : undefined,\n };\n }\n\n return {\n category: 'workspace',\n name: 'Monorepo Detection',\n status: 'pass',\n message: 'Single project (not a monorepo)',\n };\n}\n\n/**\n * Check if this is a valid workspace.\n */\nasync function checkValidWorkspace(\n fs: FsAdapter,\n ctx: CheckContext\n): Promise<CheckResult> {\n // In monorepo, check both workspace root and package root\n const pathsToCheck = ctx.isMonorepo\n ? [ctx.packageRoot, ctx.workspaceRoot]\n : [ctx.workspaceRoot];\n\n for (const root of pathsToCheck) {\n const packageJsonPath = fs.join(root, 'package.json');\n if (await fs.exists(packageJsonPath)) {\n return {\n category: 'workspace',\n name: 'Valid Workspace',\n status: 'pass',\n message: 'package.json found',\n details:\n ctx.verbose && ctx.isMonorepo ? `Found at: ${root}` : undefined,\n };\n }\n }\n\n return {\n category: 'workspace',\n name: 'Valid Workspace',\n status: 'fail',\n message: 'No package.json found',\n details: 'This does not appear to be a Node.js/TypeScript project',\n };\n}\n\n/**\n * Check if contracts directory exists.\n *\n * In monorepo: checks current package first, then workspace root.\n */\nasync function checkContractsDirectory(\n fs: FsAdapter,\n ctx: CheckContext\n): Promise<CheckResult> {\n // Determine where to look and where to create\n const searchRoots = ctx.isMonorepo\n ? [ctx.packageRoot, ctx.workspaceRoot]\n : [ctx.workspaceRoot];\n\n // Prefer creating in package root for monorepos\n const targetRoot = ctx.isMonorepo ? ctx.packageRoot : ctx.workspaceRoot;\n\n // Check each possible location\n for (const root of searchRoots) {\n for (const path of CONTRACT_PATHS) {\n const fullPath = fs.join(root, path);\n if (await fs.exists(fullPath)) {\n const relativeTo = root === ctx.packageRoot ? 'package' : 'workspace';\n return {\n category: 'workspace',\n name: 'Contracts Directory',\n status: 'pass',\n message: `Contracts directory found: ${path}`,\n details: ctx.isMonorepo ? `Found at ${relativeTo} level` : undefined,\n };\n }\n }\n }\n\n // Not found - suggest creating in appropriate location\n const createPath = ctx.isMonorepo ? 'src/contracts' : 'src/contracts';\n const locationHint = ctx.isMonorepo\n ? ` in package \"${ctx.packageName ?? ctx.packageRoot}\"`\n : '';\n\n return {\n category: 'workspace',\n name: 'Contracts Directory',\n status: 'warn',\n message: 'No contracts directory found',\n details: `Create ${createPath}/${locationHint} to organize your specs`,\n fix: {\n description: `Create ${createPath}/ directory${locationHint}`,\n apply: async (): Promise<FixResult> => {\n try {\n const contractsDir = fs.join(targetRoot, 'src', 'contracts');\n await fs.mkdir(contractsDir);\n return { success: true, message: `Created ${createPath}/` };\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n return { success: false, message: `Failed: ${msg}` };\n }\n },\n },\n };\n}\n\n/**\n * Check if any contract files exist.\n *\n * In monorepo: searches from current package root.\n */\nasync function checkContractFiles(\n fs: FsAdapter,\n ctx: CheckContext\n): Promise<CheckResult> {\n try {\n const patterns = [\n '**/*.operation.ts',\n '**/*.event.ts',\n '**/*.presentation.ts',\n '**/*.feature.ts',\n ];\n\n // In monorepo, search from package root; otherwise workspace root\n const searchRoot = ctx.isMonorepo ? ctx.packageRoot : ctx.workspaceRoot;\n\n const files = await fs.glob({\n patterns,\n ignore: ['node_modules/**', 'dist/**'],\n cwd: searchRoot,\n });\n\n if (files.length > 0) {\n const locationInfo = ctx.isMonorepo ? ' (in current package)' : '';\n return {\n category: 'workspace',\n name: 'Contract Files',\n status: 'pass',\n message: `Found ${files.length} contract file(s)${locationInfo}`,\n details: ctx.verbose ? files.slice(0, 5).join(', ') : undefined,\n };\n }\n\n const hint = ctx.isMonorepo\n ? `No contract files found in package \"${ctx.packageName ?? 'current'}\"`\n : 'No contract files found';\n\n return {\n category: 'workspace',\n name: 'Contract Files',\n status: 'warn',\n message: hint,\n details: 'Create specs using \"contractspec create\" or VS Code command',\n };\n } catch {\n return {\n category: 'workspace',\n name: 'Contract Files',\n status: 'skip',\n message: 'Could not search for contract files',\n };\n }\n}\n\n/**\n * Find the config file, checking package level first in monorepos.\n */\nasync function findConfigFile(\n fs: FsAdapter,\n ctx: CheckContext\n): Promise<{\n path: string;\n root: string;\n level: 'package' | 'workspace';\n} | null> {\n // In monorepo, check package level first\n if (ctx.isMonorepo && ctx.packageRoot !== ctx.workspaceRoot) {\n const pkgConfigPath = fs.join(ctx.packageRoot, '.contractsrc.json');\n if (await fs.exists(pkgConfigPath)) {\n return { path: pkgConfigPath, root: ctx.packageRoot, level: 'package' };\n }\n }\n\n // Check workspace level\n const wsConfigPath = fs.join(ctx.workspaceRoot, '.contractsrc.json');\n if (await fs.exists(wsConfigPath)) {\n return { path: wsConfigPath, root: ctx.workspaceRoot, level: 'workspace' };\n }\n\n return null;\n}\n\n/**\n * Check if output directory is configured and exists.\n *\n * In monorepo: checks package-level config first, then workspace-level.\n * Resolves outputDir relative to the config file location.\n */\nasync function checkOutputDirectory(\n fs: FsAdapter,\n ctx: CheckContext\n): Promise<CheckResult> {\n try {\n const configInfo = await findConfigFile(fs, ctx);\n\n if (!configInfo) {\n const hint = ctx.isMonorepo\n ? 'No config file found at package or workspace level'\n : 'No config file to check output directory';\n return {\n category: 'workspace',\n name: 'Output Directory',\n status: 'skip',\n message: hint,\n };\n }\n\n const content = await fs.readFile(configInfo.path);\n const config = JSON.parse(content) as { outputDir?: string };\n\n const outputDir = config.outputDir ?? './src';\n // Resolve outputDir relative to the config file's directory\n const outputPath = fs.join(configInfo.root, outputDir);\n\n const levelInfo = ctx.isMonorepo ? ` (${configInfo.level} level)` : '';\n\n const exists = await fs.exists(outputPath);\n if (exists) {\n return {\n category: 'workspace',\n name: 'Output Directory',\n status: 'pass',\n message: `Output directory exists: ${outputDir}${levelInfo}`,\n details: ctx.verbose ? `Resolved to: ${outputPath}` : undefined,\n };\n }\n\n return {\n category: 'workspace',\n name: 'Output Directory',\n status: 'warn',\n message: `Output directory not found: ${outputDir}${levelInfo}`,\n details: ctx.verbose ? `Expected at: ${outputPath}` : undefined,\n fix: {\n description: `Create ${outputDir} directory`,\n apply: async (): Promise<FixResult> => {\n try {\n await fs.mkdir(outputPath);\n return { success: true, message: `Created ${outputDir}` };\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n return { success: false, message: `Failed: ${msg}` };\n }\n },\n },\n };\n } catch {\n return {\n category: 'workspace',\n name: 'Output Directory',\n status: 'skip',\n message: 'Could not check output directory',\n };\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import { FsAdapter } from "../../ports/fs.js";
2
+ import { LoggerAdapter } from "../../ports/logger.js";
3
+ import { CheckResult, DoctorOptions, DoctorPromptCallbacks, DoctorResult } from "./types.js";
4
+
5
+ //#region src/services/doctor/doctor-service.d.ts
6
+
7
+ /**
8
+ * Run all health checks and optionally apply fixes.
9
+ */
10
+ declare function runDoctor(adapters: {
11
+ fs: FsAdapter;
12
+ logger: LoggerAdapter;
13
+ }, options: DoctorOptions, prompts?: DoctorPromptCallbacks): Promise<DoctorResult>;
14
+ /**
15
+ * Get a summary string for the doctor result.
16
+ */
17
+ declare function formatDoctorSummary(result: DoctorResult): string;
18
+ /**
19
+ * Format a single check result for display.
20
+ */
21
+ declare function formatCheckResult(result: CheckResult): string;
22
+ //#endregion
23
+ export { formatCheckResult, formatDoctorSummary, runDoctor };
24
+ //# sourceMappingURL=doctor-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor-service.d.ts","names":[],"sources":["../../../src/services/doctor/doctor-service.ts"],"sourcesContent":[],"mappings":";;;;;;;;;AA+CG,iBAJmB,SAAA,CAInB,QAAA,EAAA;EAAO,EAAA,EAHQ,SAGR;EAkHM,MAAA,EArHqB,aAqHrB;AAyBhB,CAAA,EAAA,OAAgB,EA7IL,aA6IsB,EAAA,OAAoB,CAApB,EA5ItB,qBA4I0C,CAAA,EA3IlD,OA2IkD,CA3I1C,YA2I0C,CAAA;;;;iBAzBrC,mBAAA,SAA4B;;;;iBAyB5B,iBAAA,SAA0B"}
@@ -0,0 +1,116 @@
1
+ import { findPackageRoot, findWorkspaceRoot, getPackageName, isMonorepo } from "../../adapters/workspace.js";
2
+ import { ALL_CHECK_CATEGORIES, CHECK_CATEGORY_LABELS } from "./types.js";
3
+ import { runCliChecks } from "./checks/cli.js";
4
+ import { runConfigChecks } from "./checks/config.js";
5
+ import { runMcpChecks } from "./checks/mcp.js";
6
+ import { runDepsChecks } from "./checks/deps.js";
7
+ import { runWorkspaceChecks } from "./checks/workspace.js";
8
+ import { runAiChecks } from "./checks/ai.js";
9
+ import "./checks/index.js";
10
+
11
+ //#region src/services/doctor/doctor-service.ts
12
+ /**
13
+ * Default prompt callbacks that always decline fixes.
14
+ */
15
+ const defaultPrompts = {
16
+ confirm: async () => false,
17
+ input: async () => ""
18
+ };
19
+ /**
20
+ * Run all health checks and optionally apply fixes.
21
+ */
22
+ async function runDoctor(adapters, options, prompts = defaultPrompts) {
23
+ const { fs, logger } = adapters;
24
+ const categories = options.categories ?? ALL_CHECK_CATEGORIES;
25
+ const workspaceRoot = findWorkspaceRoot(options.workspaceRoot);
26
+ const packageRoot = findPackageRoot(options.workspaceRoot);
27
+ const monorepo = isMonorepo(workspaceRoot);
28
+ const packageName = monorepo ? getPackageName(packageRoot) : void 0;
29
+ const ctx = {
30
+ workspaceRoot,
31
+ packageRoot,
32
+ isMonorepo: monorepo,
33
+ packageName,
34
+ verbose: options.verbose ?? false
35
+ };
36
+ if (monorepo) {
37
+ const pkgInfo = packageName ? ` (package: ${packageName})` : "";
38
+ logger.info(`Detected monorepo${pkgInfo}`);
39
+ }
40
+ const allResults = [];
41
+ for (const category of categories) {
42
+ if (options.skipAi && category === "ai") continue;
43
+ logger.info(`Checking ${CHECK_CATEGORY_LABELS[category]}...`);
44
+ const categoryResults = await runCategoryChecks(category, fs, ctx, prompts);
45
+ for (const result of categoryResults) {
46
+ if (result.fix && (result.status === "fail" || result.status === "warn")) {
47
+ if (options.autoFix ? true : await prompts.confirm(`Fix "${result.name}"? ${result.fix.description}`)) {
48
+ logger.info(`Applying fix: ${result.fix.description}`);
49
+ const fixResult = await result.fix.apply();
50
+ if (fixResult.success) {
51
+ logger.info(`✓ ${fixResult.message}`);
52
+ result.status = "pass";
53
+ result.message = `Fixed: ${fixResult.message}`;
54
+ result.fix = void 0;
55
+ } else logger.warn(`✗ ${fixResult.message}`);
56
+ }
57
+ }
58
+ allResults.push(result);
59
+ }
60
+ }
61
+ const passed = allResults.filter((r) => r.status === "pass").length;
62
+ const warnings = allResults.filter((r) => r.status === "warn").length;
63
+ const failures = allResults.filter((r) => r.status === "fail").length;
64
+ return {
65
+ checks: allResults,
66
+ passed,
67
+ warnings,
68
+ failures,
69
+ skipped: allResults.filter((r) => r.status === "skip").length,
70
+ healthy: failures === 0
71
+ };
72
+ }
73
+ /**
74
+ * Run checks for a specific category.
75
+ */
76
+ async function runCategoryChecks(category, fs, ctx, prompts) {
77
+ switch (category) {
78
+ case "cli": return runCliChecks(fs, ctx);
79
+ case "config": return runConfigChecks(fs, ctx);
80
+ case "mcp": return runMcpChecks(fs, ctx);
81
+ case "deps": return runDepsChecks(fs, ctx);
82
+ case "workspace": return runWorkspaceChecks(fs, ctx);
83
+ case "ai": return runAiChecks(fs, ctx, prompts);
84
+ default: return [];
85
+ }
86
+ }
87
+ /**
88
+ * Get a summary string for the doctor result.
89
+ */
90
+ function formatDoctorSummary(result) {
91
+ const lines = [];
92
+ lines.push("");
93
+ lines.push("=== Health Check Summary ===");
94
+ lines.push("");
95
+ if (result.healthy) lines.push("✓ All checks passed!");
96
+ else lines.push("✗ Some issues found");
97
+ lines.push("");
98
+ lines.push(` Passed: ${result.passed}`);
99
+ lines.push(` Warnings: ${result.warnings}`);
100
+ lines.push(` Failures: ${result.failures}`);
101
+ lines.push(` Skipped: ${result.skipped}`);
102
+ return lines.join("\n");
103
+ }
104
+ /**
105
+ * Format a single check result for display.
106
+ */
107
+ function formatCheckResult(result) {
108
+ let line = `${result.status === "pass" ? "✓" : result.status === "warn" ? "⚠" : result.status === "fail" ? "✗" : "○"} ${result.name}: ${result.message}`;
109
+ if (result.details) line += `\n ${result.details}`;
110
+ if (result.fix) line += `\n Fix available: ${result.fix.description}`;
111
+ return line;
112
+ }
113
+
114
+ //#endregion
115
+ export { formatCheckResult, formatDoctorSummary, runDoctor };
116
+ //# sourceMappingURL=doctor-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor-service.js","names":["defaultPrompts: DoctorPromptCallbacks","ctx: CheckContext","allResults: CheckResult[]","lines: string[]"],"sources":["../../../src/services/doctor/doctor-service.ts"],"sourcesContent":["/**\n * Doctor service.\n *\n * Orchestrates health checks and applies fixes.\n */\n\nimport type { FsAdapter } from '../../ports/fs';\nimport type { LoggerAdapter } from '../../ports/logger';\nimport type {\n CheckCategory,\n CheckResult,\n CheckContext,\n DoctorOptions,\n DoctorResult,\n DoctorPromptCallbacks,\n} from './types';\nimport { ALL_CHECK_CATEGORIES, CHECK_CATEGORY_LABELS } from './types';\nimport {\n runCliChecks,\n runConfigChecks,\n runMcpChecks,\n runDepsChecks,\n runWorkspaceChecks,\n runAiChecks,\n} from './checks/index';\nimport {\n findPackageRoot,\n findWorkspaceRoot,\n isMonorepo,\n getPackageName,\n} from '../../adapters/workspace';\n\n/**\n * Default prompt callbacks that always decline fixes.\n */\nconst defaultPrompts: DoctorPromptCallbacks = {\n confirm: async () => false,\n input: async () => '',\n};\n\n/**\n * Run all health checks and optionally apply fixes.\n */\nexport async function runDoctor(\n adapters: { fs: FsAdapter; logger: LoggerAdapter },\n options: DoctorOptions,\n prompts: DoctorPromptCallbacks = defaultPrompts\n): Promise<DoctorResult> {\n const { fs, logger } = adapters;\n const categories = options.categories ?? ALL_CHECK_CATEGORIES;\n\n // Detect monorepo context\n const workspaceRoot = findWorkspaceRoot(options.workspaceRoot);\n const packageRoot = findPackageRoot(options.workspaceRoot);\n const monorepo = isMonorepo(workspaceRoot);\n const packageName = monorepo ? getPackageName(packageRoot) : undefined;\n\n const ctx: CheckContext = {\n workspaceRoot,\n packageRoot,\n isMonorepo: monorepo,\n packageName,\n verbose: options.verbose ?? false,\n };\n\n // Log monorepo context if detected\n if (monorepo) {\n const pkgInfo = packageName ? ` (package: ${packageName})` : '';\n logger.info(`Detected monorepo${pkgInfo}`);\n }\n\n const allResults: CheckResult[] = [];\n\n // Run checks for each category\n for (const category of categories) {\n if (options.skipAi && category === 'ai') {\n continue;\n }\n\n logger.info(`Checking ${CHECK_CATEGORY_LABELS[category]}...`);\n\n const categoryResults = await runCategoryChecks(category, fs, ctx, prompts);\n\n // Apply fixes if enabled\n for (const result of categoryResults) {\n if (\n result.fix &&\n (result.status === 'fail' || result.status === 'warn')\n ) {\n const shouldFix = options.autoFix\n ? true\n : await prompts.confirm(\n `Fix \"${result.name}\"? ${result.fix.description}`\n );\n\n if (shouldFix) {\n logger.info(`Applying fix: ${result.fix.description}`);\n const fixResult = await result.fix.apply();\n\n if (fixResult.success) {\n logger.info(`✓ ${fixResult.message}`);\n // Update status to pass after successful fix\n result.status = 'pass';\n result.message = `Fixed: ${fixResult.message}`;\n result.fix = undefined;\n } else {\n logger.warn(`✗ ${fixResult.message}`);\n }\n }\n }\n\n allResults.push(result);\n }\n }\n\n // Calculate summary\n const passed = allResults.filter((r) => r.status === 'pass').length;\n const warnings = allResults.filter((r) => r.status === 'warn').length;\n const failures = allResults.filter((r) => r.status === 'fail').length;\n const skipped = allResults.filter((r) => r.status === 'skip').length;\n\n return {\n checks: allResults,\n passed,\n warnings,\n failures,\n skipped,\n healthy: failures === 0,\n };\n}\n\n/**\n * Run checks for a specific category.\n */\nasync function runCategoryChecks(\n category: CheckCategory,\n fs: FsAdapter,\n ctx: CheckContext,\n prompts: DoctorPromptCallbacks\n): Promise<CheckResult[]> {\n switch (category) {\n case 'cli':\n return runCliChecks(fs, ctx);\n case 'config':\n return runConfigChecks(fs, ctx);\n case 'mcp':\n return runMcpChecks(fs, ctx);\n case 'deps':\n return runDepsChecks(fs, ctx);\n case 'workspace':\n return runWorkspaceChecks(fs, ctx);\n case 'ai':\n return runAiChecks(fs, ctx, prompts);\n default:\n return [];\n }\n}\n\n/**\n * Get a summary string for the doctor result.\n */\nexport function formatDoctorSummary(result: DoctorResult): string {\n const lines: string[] = [];\n\n lines.push('');\n lines.push('=== Health Check Summary ===');\n lines.push('');\n\n if (result.healthy) {\n lines.push('✓ All checks passed!');\n } else {\n lines.push('✗ Some issues found');\n }\n\n lines.push('');\n lines.push(` Passed: ${result.passed}`);\n lines.push(` Warnings: ${result.warnings}`);\n lines.push(` Failures: ${result.failures}`);\n lines.push(` Skipped: ${result.skipped}`);\n\n return lines.join('\\n');\n}\n\n/**\n * Format a single check result for display.\n */\nexport function formatCheckResult(result: CheckResult): string {\n const icon =\n result.status === 'pass'\n ? '✓'\n : result.status === 'warn'\n ? '⚠'\n : result.status === 'fail'\n ? '✗'\n : '○';\n\n let line = `${icon} ${result.name}: ${result.message}`;\n\n if (result.details) {\n line += `\\n ${result.details}`;\n }\n\n if (result.fix) {\n line += `\\n Fix available: ${result.fix.description}`;\n }\n\n return line;\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { ALL_CHECK_CATEGORIES, CHECK_CATEGORY_LABELS, CheckCategory, CheckContext, CheckResult, CheckStatus, DoctorOptions, DoctorPromptCallbacks, DoctorResult, FixAction, FixResult } from "./types.js";
2
+ import { formatCheckResult, formatDoctorSummary, runDoctor } from "./doctor-service.js";
@@ -0,0 +1,2 @@
1
+ import { ALL_CHECK_CATEGORIES, CHECK_CATEGORY_LABELS } from "./types.js";
2
+ import { formatCheckResult, formatDoctorSummary, runDoctor } from "./doctor-service.js";
@@ -0,0 +1,118 @@
1
+ //#region src/services/doctor/types.d.ts
2
+ /**
3
+ * Doctor service types.
4
+ *
5
+ * Types for health checks and auto-fix functionality.
6
+ */
7
+ /**
8
+ * Categories of health checks.
9
+ */
10
+ type CheckCategory = 'cli' | 'config' | 'mcp' | 'deps' | 'workspace' | 'ai';
11
+ /**
12
+ * All available check categories.
13
+ */
14
+ declare const ALL_CHECK_CATEGORIES: CheckCategory[];
15
+ /**
16
+ * Human-readable labels for check categories.
17
+ */
18
+ declare const CHECK_CATEGORY_LABELS: Record<CheckCategory, string>;
19
+ /**
20
+ * Status of a health check.
21
+ */
22
+ type CheckStatus = 'pass' | 'warn' | 'fail' | 'skip';
23
+ /**
24
+ * Result of applying a fix.
25
+ */
26
+ interface FixResult {
27
+ /** Whether the fix was successful. */
28
+ success: boolean;
29
+ /** Message describing the result. */
30
+ message: string;
31
+ }
32
+ /**
33
+ * An action that can fix a failed check.
34
+ */
35
+ interface FixAction {
36
+ /** Description of what the fix will do. */
37
+ description: string;
38
+ /** Function to apply the fix. */
39
+ apply: () => Promise<FixResult>;
40
+ }
41
+ /**
42
+ * Result of a single health check.
43
+ */
44
+ interface CheckResult {
45
+ /** Category of the check. */
46
+ category: CheckCategory;
47
+ /** Name of the specific check. */
48
+ name: string;
49
+ /** Status of the check. */
50
+ status: CheckStatus;
51
+ /** Human-readable message. */
52
+ message: string;
53
+ /** Optional fix action if status is 'fail' or 'warn'. */
54
+ fix?: FixAction;
55
+ /** Additional details for debugging. */
56
+ details?: string;
57
+ }
58
+ /**
59
+ * Options for running the doctor.
60
+ */
61
+ interface DoctorOptions {
62
+ /** Root directory of the workspace. */
63
+ workspaceRoot: string;
64
+ /** Categories to check (defaults to all). */
65
+ categories?: CheckCategory[];
66
+ /** If true, auto-apply fixes without prompting. */
67
+ autoFix?: boolean;
68
+ /** Skip AI provider checks. */
69
+ skipAi?: boolean;
70
+ /** Verbose output. */
71
+ verbose?: boolean;
72
+ }
73
+ /**
74
+ * Summary of doctor results.
75
+ */
76
+ interface DoctorResult {
77
+ /** All check results. */
78
+ checks: CheckResult[];
79
+ /** Number of passing checks. */
80
+ passed: number;
81
+ /** Number of warnings. */
82
+ warnings: number;
83
+ /** Number of failures. */
84
+ failures: number;
85
+ /** Number of skipped checks. */
86
+ skipped: number;
87
+ /** Overall health status. */
88
+ healthy: boolean;
89
+ }
90
+ /**
91
+ * Callback for interactive prompts during doctor.
92
+ */
93
+ interface DoctorPromptCallbacks {
94
+ /** Confirm a fix action. */
95
+ confirm: (message: string) => Promise<boolean>;
96
+ /** Input a value (e.g., API key). */
97
+ input: (message: string, options?: {
98
+ password?: boolean;
99
+ }) => Promise<string>;
100
+ }
101
+ /**
102
+ * Context passed to check functions.
103
+ */
104
+ interface CheckContext {
105
+ /** Workspace root path (monorepo root or single project root). */
106
+ workspaceRoot: string;
107
+ /** Current package root (may differ from workspaceRoot in monorepos). */
108
+ packageRoot: string;
109
+ /** Whether this is a monorepo. */
110
+ isMonorepo: boolean;
111
+ /** Current package name (if in a monorepo package). */
112
+ packageName?: string;
113
+ /** Whether verbose output is enabled. */
114
+ verbose: boolean;
115
+ }
116
+ //#endregion
117
+ export { ALL_CHECK_CATEGORIES, CHECK_CATEGORY_LABELS, CheckCategory, CheckContext, CheckResult, CheckStatus, DoctorOptions, DoctorPromptCallbacks, DoctorResult, FixAction, FixResult };
118
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","names":[],"sources":["../../../src/services/doctor/types.ts"],"sourcesContent":[],"mappings":";;AASA;AAWA;AAYA;AAYA;AAKA;AAUA;AAUA;AAEY,KA9DA,aAAA,GA8DA,KAAA,GAAA,QAAA,GAAA,KAAA,GAAA,MAAA,GAAA,WAAA,GAAA,IAAA;;;;AAgBK,cAnEJ,oBAuEE,EAvEoB,aAuEP,EAAA;AAY5B;AAkBA;AAUA;cAnGa,uBAAuB,OAAO;;;;KAY/B,WAAA;;;;UAKK,SAAA;;;;;;;;;UAUA,SAAA;;;;eAIF,QAAQ;;;;;UAMN,WAAA;;YAEL;;;;UAIF;;;;QAIF;;;;;;;UAQS,aAAA;;;;eAIF;;;;;;;;;;;UAYE,YAAA;;UAEP;;;;;;;;;;;;;;;UAgBO,qBAAA;;gCAEe;;;;QAEgC;;;;;UAM/C,YAAA"}
@@ -0,0 +1,27 @@
1
+ //#region src/services/doctor/types.ts
2
+ /**
3
+ * All available check categories.
4
+ */
5
+ const ALL_CHECK_CATEGORIES = [
6
+ "cli",
7
+ "config",
8
+ "mcp",
9
+ "deps",
10
+ "workspace",
11
+ "ai"
12
+ ];
13
+ /**
14
+ * Human-readable labels for check categories.
15
+ */
16
+ const CHECK_CATEGORY_LABELS = {
17
+ cli: "CLI Installation",
18
+ config: "Configuration Files",
19
+ mcp: "MCP Server",
20
+ deps: "Dependencies",
21
+ workspace: "Workspace Structure",
22
+ ai: "AI Provider"
23
+ };
24
+
25
+ //#endregion
26
+ export { ALL_CHECK_CATEGORIES, CHECK_CATEGORY_LABELS };
27
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","names":["ALL_CHECK_CATEGORIES: CheckCategory[]","CHECK_CATEGORY_LABELS: Record<CheckCategory, string>"],"sources":["../../../src/services/doctor/types.ts"],"sourcesContent":["/**\n * Doctor service types.\n *\n * Types for health checks and auto-fix functionality.\n */\n\n/**\n * Categories of health checks.\n */\nexport type CheckCategory =\n | 'cli'\n | 'config'\n | 'mcp'\n | 'deps'\n | 'workspace'\n | 'ai';\n\n/**\n * All available check categories.\n */\nexport const ALL_CHECK_CATEGORIES: CheckCategory[] = [\n 'cli',\n 'config',\n 'mcp',\n 'deps',\n 'workspace',\n 'ai',\n];\n\n/**\n * Human-readable labels for check categories.\n */\nexport const CHECK_CATEGORY_LABELS: Record<CheckCategory, string> = {\n cli: 'CLI Installation',\n config: 'Configuration Files',\n mcp: 'MCP Server',\n deps: 'Dependencies',\n workspace: 'Workspace Structure',\n ai: 'AI Provider',\n};\n\n/**\n * Status of a health check.\n */\nexport type CheckStatus = 'pass' | 'warn' | 'fail' | 'skip';\n\n/**\n * Result of applying a fix.\n */\nexport interface FixResult {\n /** Whether the fix was successful. */\n success: boolean;\n /** Message describing the result. */\n message: string;\n}\n\n/**\n * An action that can fix a failed check.\n */\nexport interface FixAction {\n /** Description of what the fix will do. */\n description: string;\n /** Function to apply the fix. */\n apply: () => Promise<FixResult>;\n}\n\n/**\n * Result of a single health check.\n */\nexport interface CheckResult {\n /** Category of the check. */\n category: CheckCategory;\n /** Name of the specific check. */\n name: string;\n /** Status of the check. */\n status: CheckStatus;\n /** Human-readable message. */\n message: string;\n /** Optional fix action if status is 'fail' or 'warn'. */\n fix?: FixAction;\n /** Additional details for debugging. */\n details?: string;\n}\n\n/**\n * Options for running the doctor.\n */\nexport interface DoctorOptions {\n /** Root directory of the workspace. */\n workspaceRoot: string;\n /** Categories to check (defaults to all). */\n categories?: CheckCategory[];\n /** If true, auto-apply fixes without prompting. */\n autoFix?: boolean;\n /** Skip AI provider checks. */\n skipAi?: boolean;\n /** Verbose output. */\n verbose?: boolean;\n}\n\n/**\n * Summary of doctor results.\n */\nexport interface DoctorResult {\n /** All check results. */\n checks: CheckResult[];\n /** Number of passing checks. */\n passed: number;\n /** Number of warnings. */\n warnings: number;\n /** Number of failures. */\n failures: number;\n /** Number of skipped checks. */\n skipped: number;\n /** Overall health status. */\n healthy: boolean;\n}\n\n/**\n * Callback for interactive prompts during doctor.\n */\nexport interface DoctorPromptCallbacks {\n /** Confirm a fix action. */\n confirm: (message: string) => Promise<boolean>;\n /** Input a value (e.g., API key). */\n input: (message: string, options?: { password?: boolean }) => Promise<string>;\n}\n\n/**\n * Context passed to check functions.\n */\nexport interface CheckContext {\n /** Workspace root path (monorepo root or single project root). */\n workspaceRoot: string;\n /** Current package root (may differ from workspaceRoot in monorepos). */\n packageRoot: string;\n /** Whether this is a monorepo. */\n isMonorepo: boolean;\n /** Current package name (if in a monorepo package). */\n packageName?: string;\n /** Whether verbose output is enabled. */\n verbose: boolean;\n}\n"],"mappings":";;;;AAoBA,MAAaA,uBAAwC;CACnD;CACA;CACA;CACA;CACA;CACA;CACD;;;;AAKD,MAAaC,wBAAuD;CAClE,KAAK;CACL,QAAQ;CACR,KAAK;CACL,MAAM;CACN,WAAW;CACX,IAAI;CACL"}
@@ -0,0 +1,27 @@
1
+ import { CheckRunPayload, PrCommentOptions } from "./types.js";
2
+ import { index_d_exports } from "../../index.js";
3
+
4
+ //#region src/services/impact/formatters.d.ts
5
+
6
+ /**
7
+ * Format impact result as a PR comment (markdown).
8
+ */
9
+ declare function formatPrComment(result: index_d_exports.ImpactResult, options?: PrCommentOptions): string;
10
+ /**
11
+ * Format impact result for minimal PR comment.
12
+ */
13
+ declare function formatMinimalComment(result: index_d_exports.ImpactResult): string;
14
+ /**
15
+ * Format impact result as GitHub check run payload.
16
+ */
17
+ declare function formatCheckRun(result: index_d_exports.ImpactResult, headSha: string, options?: {
18
+ key?: string;
19
+ failOnBreaking?: boolean;
20
+ }): CheckRunPayload;
21
+ /**
22
+ * Format impact result as JSON.
23
+ */
24
+ declare function formatJson(result: index_d_exports.ImpactResult): string;
25
+ //#endregion
26
+ export { formatCheckRun, formatJson, formatMinimalComment, formatPrComment };
27
+ //# sourceMappingURL=formatters.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatters.d.ts","names":[],"sources":["../../../src/services/impact/formatters.ts"],"sourcesContent":[],"mappings":";;;;;;;;iBAegB,eAAA,SACN,eAAA,CAAA,wBACC;;;;iBAyGK,oBAAA,SAA6B,eAAA,CAAA;;;;iBAa7B,cAAA,SACN,eAAA,CAAA;;;IAGP;;;;iBA2Ca,UAAA,SAAmB,eAAA,CAAA"}
@@ -0,0 +1,111 @@
1
+ //#region src/services/impact/formatters.ts
2
+ /**
3
+ * Format impact result as a PR comment (markdown).
4
+ */
5
+ function formatPrComment(result, options = { template: "detailed" }) {
6
+ const lines = [];
7
+ lines.push("## 📋 ContractSpec Impact Analysis");
8
+ lines.push("");
9
+ if (result.hasBreaking) lines.push("❌ **Breaking changes detected**");
10
+ else if (result.hasNonBreaking) lines.push("⚠️ **Contract changed (non-breaking)**");
11
+ else lines.push("✅ **No contract impact**");
12
+ lines.push("");
13
+ if (result.summary.breaking > 0 || result.summary.nonBreaking > 0 || result.summary.info > 0) {
14
+ lines.push("### Summary");
15
+ lines.push("");
16
+ lines.push(`| Type | Count |`);
17
+ lines.push(`|------|-------|`);
18
+ if (result.summary.breaking > 0) lines.push(`| 🔴 Breaking | ${result.summary.breaking} |`);
19
+ if (result.summary.nonBreaking > 0) lines.push(`| 🟡 Non-breaking | ${result.summary.nonBreaking} |`);
20
+ if (result.summary.info > 0) lines.push(`| 🔵 Info | ${result.summary.info} |`);
21
+ if (result.summary.added > 0) lines.push(`| ➕ Added | ${result.summary.added} |`);
22
+ if (result.summary.removed > 0) lines.push(`| ➖ Removed | ${result.summary.removed} |`);
23
+ lines.push("");
24
+ }
25
+ if (options.template === "detailed" && result.deltas.length > 0) {
26
+ lines.push("### Changes");
27
+ lines.push("");
28
+ const breaking = result.deltas.filter((d) => d.severity === "breaking");
29
+ const nonBreaking = result.deltas.filter((d) => d.severity === "non_breaking");
30
+ if (breaking.length > 0) {
31
+ lines.push("#### 🔴 Breaking Changes");
32
+ lines.push("");
33
+ for (const delta of breaking) lines.push(`- **${delta.specKey}**: ${delta.description}`);
34
+ lines.push("");
35
+ }
36
+ if (nonBreaking.length > 0) {
37
+ lines.push("#### 🟡 Non-breaking Changes");
38
+ lines.push("");
39
+ for (const delta of nonBreaking) lines.push(`- **${delta.specKey}**: ${delta.description}`);
40
+ lines.push("");
41
+ }
42
+ }
43
+ if (result.addedSpecs.length > 0) {
44
+ lines.push("### Added Specs");
45
+ lines.push("");
46
+ for (const spec of result.addedSpecs) lines.push(`- \`${spec.key}\` v${spec.version} (${spec.type})`);
47
+ lines.push("");
48
+ }
49
+ if (result.removedSpecs.length > 0) {
50
+ lines.push("### Removed Specs");
51
+ lines.push("");
52
+ for (const spec of result.removedSpecs) lines.push(`- \`${spec.key}\` v${spec.version} (${spec.type})`);
53
+ lines.push("");
54
+ }
55
+ lines.push("---");
56
+ lines.push(`*Generated by ContractSpec at ${result.timestamp}*`);
57
+ return lines.join("\n");
58
+ }
59
+ /**
60
+ * Format impact result for minimal PR comment.
61
+ */
62
+ function formatMinimalComment(result) {
63
+ if (result.hasBreaking) return `❌ **Breaking changes detected** (${result.summary.breaking} breaking, ${result.summary.nonBreaking} non-breaking)`;
64
+ if (result.hasNonBreaking) return `⚠️ **Contract changed** (${result.summary.nonBreaking} non-breaking changes)`;
65
+ return "✅ **No contract impact**";
66
+ }
67
+ /**
68
+ * Format impact result as GitHub check run payload.
69
+ */
70
+ function formatCheckRun(result, headSha, options = {}) {
71
+ const name = options.key ?? "ContractSpec Impact";
72
+ const failOnBreaking = options.failOnBreaking ?? true;
73
+ let conclusion;
74
+ let title;
75
+ if (result.hasBreaking) {
76
+ conclusion = failOnBreaking ? "failure" : "neutral";
77
+ title = `Breaking changes detected (${result.summary.breaking})`;
78
+ } else if (result.hasNonBreaking) {
79
+ conclusion = "success";
80
+ title = `Non-breaking changes (${result.summary.nonBreaking})`;
81
+ } else {
82
+ conclusion = "success";
83
+ title = "No contract impact";
84
+ }
85
+ const summary = formatMinimalComment(result);
86
+ return {
87
+ name,
88
+ headSha,
89
+ conclusion,
90
+ title,
91
+ summary,
92
+ annotations: result.deltas.filter((d) => d.severity === "breaking").slice(0, 50).map((d) => ({
93
+ path: d.path,
94
+ startLine: 1,
95
+ endLine: 1,
96
+ annotationLevel: "failure",
97
+ message: d.description,
98
+ title: `Breaking: ${d.rule}`
99
+ }))
100
+ };
101
+ }
102
+ /**
103
+ * Format impact result as JSON.
104
+ */
105
+ function formatJson(result) {
106
+ return JSON.stringify(result, null, 2);
107
+ }
108
+
109
+ //#endregion
110
+ export { formatCheckRun, formatJson, formatMinimalComment, formatPrComment };
111
+ //# sourceMappingURL=formatters.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatters.js","names":["lines: string[]","conclusion: 'success' | 'failure' | 'neutral'","title: string"],"sources":["../../../src/services/impact/formatters.ts"],"sourcesContent":["/**\n * Impact result formatters.\n *\n * Formats impact detection results for various outputs:\n * - PR comments (markdown)\n * - GitHub check runs\n * - JSON output\n */\n\nimport type { ImpactResult } from '../../index';\nimport type { CheckRunPayload, PrCommentOptions } from './types';\n\n/**\n * Format impact result as a PR comment (markdown).\n */\nexport function formatPrComment(\n result: ImpactResult,\n options: PrCommentOptions = { template: 'detailed' }\n): string {\n const lines: string[] = [];\n\n // Header with status\n lines.push('## 📋 ContractSpec Impact Analysis');\n lines.push('');\n\n // Status badge\n if (result.hasBreaking) {\n lines.push('❌ **Breaking changes detected**');\n } else if (result.hasNonBreaking) {\n lines.push('⚠️ **Contract changed (non-breaking)**');\n } else {\n lines.push('✅ **No contract impact**');\n }\n lines.push('');\n\n // Summary\n if (\n result.summary.breaking > 0 ||\n result.summary.nonBreaking > 0 ||\n result.summary.info > 0\n ) {\n lines.push('### Summary');\n lines.push('');\n lines.push(`| Type | Count |`);\n lines.push(`|------|-------|`);\n if (result.summary.breaking > 0) {\n lines.push(`| 🔴 Breaking | ${result.summary.breaking} |`);\n }\n if (result.summary.nonBreaking > 0) {\n lines.push(`| 🟡 Non-breaking | ${result.summary.nonBreaking} |`);\n }\n if (result.summary.info > 0) {\n lines.push(`| 🔵 Info | ${result.summary.info} |`);\n }\n if (result.summary.added > 0) {\n lines.push(`| ➕ Added | ${result.summary.added} |`);\n }\n if (result.summary.removed > 0) {\n lines.push(`| ➖ Removed | ${result.summary.removed} |`);\n }\n lines.push('');\n }\n\n // Detailed changes (if detailed template)\n if (options.template === 'detailed' && result.deltas.length > 0) {\n lines.push('### Changes');\n lines.push('');\n\n // Group by severity\n const breaking = result.deltas.filter((d) => d.severity === 'breaking');\n const nonBreaking = result.deltas.filter(\n (d) => d.severity === 'non_breaking'\n );\n\n if (breaking.length > 0) {\n lines.push('#### 🔴 Breaking Changes');\n lines.push('');\n for (const delta of breaking) {\n lines.push(`- **${delta.specKey}**: ${delta.description}`);\n }\n lines.push('');\n }\n\n if (nonBreaking.length > 0) {\n lines.push('#### 🟡 Non-breaking Changes');\n lines.push('');\n for (const delta of nonBreaking) {\n lines.push(`- **${delta.specKey}**: ${delta.description}`);\n }\n lines.push('');\n }\n }\n\n // Added/removed specs\n if (result.addedSpecs.length > 0) {\n lines.push('### Added Specs');\n lines.push('');\n for (const spec of result.addedSpecs) {\n lines.push(`- \\`${spec.key}\\` v${spec.version} (${spec.type})`);\n }\n lines.push('');\n }\n\n if (result.removedSpecs.length > 0) {\n lines.push('### Removed Specs');\n lines.push('');\n for (const spec of result.removedSpecs) {\n lines.push(`- \\`${spec.key}\\` v${spec.version} (${spec.type})`);\n }\n lines.push('');\n }\n\n // Footer\n lines.push('---');\n lines.push(`*Generated by ContractSpec at ${result.timestamp}*`);\n\n return lines.join('\\n');\n}\n\n/**\n * Format impact result for minimal PR comment.\n */\nexport function formatMinimalComment(result: ImpactResult): string {\n if (result.hasBreaking) {\n return `❌ **Breaking changes detected** (${result.summary.breaking} breaking, ${result.summary.nonBreaking} non-breaking)`;\n }\n if (result.hasNonBreaking) {\n return `⚠️ **Contract changed** (${result.summary.nonBreaking} non-breaking changes)`;\n }\n return '✅ **No contract impact**';\n}\n\n/**\n * Format impact result as GitHub check run payload.\n */\nexport function formatCheckRun(\n result: ImpactResult,\n headSha: string,\n options: { key?: string; failOnBreaking?: boolean } = {}\n): CheckRunPayload {\n const name = options.key ?? 'ContractSpec Impact';\n const failOnBreaking = options.failOnBreaking ?? true;\n\n let conclusion: 'success' | 'failure' | 'neutral';\n let title: string;\n\n if (result.hasBreaking) {\n conclusion = failOnBreaking ? 'failure' : 'neutral';\n title = `Breaking changes detected (${result.summary.breaking})`;\n } else if (result.hasNonBreaking) {\n conclusion = 'success';\n title = `Non-breaking changes (${result.summary.nonBreaking})`;\n } else {\n conclusion = 'success';\n title = 'No contract impact';\n }\n\n const summary = formatMinimalComment(result);\n\n return {\n name,\n headSha,\n conclusion,\n title,\n summary,\n annotations: result.deltas\n .filter((d) => d.severity === 'breaking')\n .slice(0, 50) // GitHub limit\n .map((d) => ({\n path: d.path,\n startLine: 1,\n endLine: 1,\n annotationLevel: 'failure' as const,\n message: d.description,\n title: `Breaking: ${d.rule}`,\n })),\n };\n}\n\n/**\n * Format impact result as JSON.\n */\nexport function formatJson(result: ImpactResult): string {\n return JSON.stringify(result, null, 2);\n}\n"],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import { FsAdapter } from "../../ports/fs.js";
2
+ import { GitAdapter } from "../../ports/git.js";
3
+ import { LoggerAdapter } from "../../ports/logger.js";
4
+ import { ImpactDetectionOptions, ImpactDetectionResult } from "./types.js";
5
+
6
+ //#region src/services/impact/impact-detection-service.d.ts
7
+
8
+ /**
9
+ * Detect the impact of contract changes between baseline and current state.
10
+ *
11
+ * @param adapters - Required adapters (fs, git, logger)
12
+ * @param options - Detection options
13
+ * @returns Impact detection result
14
+ */
15
+ declare function detectImpact(adapters: {
16
+ fs: FsAdapter;
17
+ git: GitAdapter;
18
+ logger: LoggerAdapter;
19
+ }, options?: ImpactDetectionOptions): Promise<ImpactDetectionResult>;
20
+ //#endregion
21
+ export { detectImpact };
22
+ //# sourceMappingURL=impact-detection-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"impact-detection-service.d.ts","names":[],"sources":["../../../src/services/impact/impact-detection-service.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;;iBA2BsB,YAAA;MACJ;OAAgB;UAAoB;aAC3C,yBACR,QAAQ"}
@@ -0,0 +1,96 @@
1
+ import { src_exports } from "../../index.js";
2
+
3
+ //#region src/services/impact/impact-detection-service.ts
4
+ /**
5
+ * Impact detection service.
6
+ *
7
+ * Orchestrates contract snapshot generation, diff computation,
8
+ * and impact classification for CI/CD pipelines.
9
+ */
10
+ /**
11
+ * Detect the impact of contract changes between baseline and current state.
12
+ *
13
+ * @param adapters - Required adapters (fs, git, logger)
14
+ * @param options - Detection options
15
+ * @returns Impact detection result
16
+ */
17
+ async function detectImpact(adapters, options = {}) {
18
+ const { fs, git, logger } = adapters;
19
+ const workspaceRoot = options.workspaceRoot ?? process.cwd();
20
+ logger.info("Starting impact detection...", { baseline: options.baseline });
21
+ const specFiles = (await fs.glob({
22
+ pattern: options.pattern ?? "**/*.{operation,event}.ts",
23
+ cwd: workspaceRoot
24
+ })).filter((f) => !f.includes(".test.") && !f.includes(".spec.") && !f.includes("node_modules"));
25
+ logger.debug(`Found ${specFiles.length} spec files`);
26
+ const headSnapshot = (0, src_exports.generateSnapshot)(await loadSpecs(fs, specFiles, workspaceRoot));
27
+ let baseSnapshot;
28
+ if (options.baseline) baseSnapshot = (0, src_exports.generateSnapshot)(await loadBaselineSpecs(fs, git, specFiles, options.baseline, workspaceRoot));
29
+ else baseSnapshot = {
30
+ version: 1,
31
+ generatedAt: "",
32
+ specs: [],
33
+ hash: ""
34
+ };
35
+ const diffs = computeSnapshotDiffs(baseSnapshot.specs, headSnapshot.specs);
36
+ const impactResult = (0, src_exports.classifyImpact)(baseSnapshot.specs, headSnapshot.specs, diffs);
37
+ logger.info("Impact detection complete", {
38
+ status: impactResult.status,
39
+ breaking: impactResult.summary.breaking,
40
+ nonBreaking: impactResult.summary.nonBreaking
41
+ });
42
+ return {
43
+ ...impactResult,
44
+ workspaceRoot,
45
+ specsAnalyzed: specFiles.length,
46
+ baseRef: options.baseline
47
+ };
48
+ }
49
+ /**
50
+ * Load specs from current filesystem.
51
+ */
52
+ async function loadSpecs(fs, files, _workspaceRoot) {
53
+ const specs = [];
54
+ for (const file of files) {
55
+ const content = await fs.readFile(file);
56
+ specs.push({
57
+ path: file,
58
+ content
59
+ });
60
+ }
61
+ return specs;
62
+ }
63
+ /**
64
+ * Load specs from git baseline.
65
+ */
66
+ async function loadBaselineSpecs(_fs, git, files, baseline, _workspaceRoot) {
67
+ const specs = [];
68
+ for (const file of files) try {
69
+ const content = await git.showFile(baseline, file);
70
+ specs.push({
71
+ path: file,
72
+ content
73
+ });
74
+ } catch {}
75
+ return specs;
76
+ }
77
+ /**
78
+ * Compute diffs between two sets of spec snapshots.
79
+ */
80
+ function computeSnapshotDiffs(baseSpecs, headSpecs) {
81
+ const diffs = [];
82
+ const baseMap = new Map(baseSpecs.map((s) => [`${s.key}@${s.version}`, s]));
83
+ const headMap = new Map(headSpecs.map((s) => [`${s.key}@${s.version}`, s]));
84
+ for (const [key, headSpec] of headMap) {
85
+ const baseSpec = baseMap.get(key);
86
+ if (baseSpec && headSpec.type === "operation" && baseSpec.type === "operation") {
87
+ const ioDiffs = (0, src_exports.computeIoDiff)(baseSpec.io, headSpec.io);
88
+ diffs.push(...ioDiffs);
89
+ }
90
+ }
91
+ return diffs;
92
+ }
93
+
94
+ //#endregion
95
+ export { detectImpact };
96
+ //# sourceMappingURL=impact-detection-service.js.map