@planu/cli 0.23.2 → 0.25.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 (397) hide show
  1. package/dist/config/ai-model-pricing.json +81 -0
  2. package/dist/config/framework-registry/csharp-aspnet.json +67 -0
  3. package/dist/config/framework-registry/dart-flutter.json +61 -0
  4. package/dist/config/framework-registry/go-gin.json +62 -0
  5. package/dist/config/framework-registry/index.json +164 -0
  6. package/dist/config/framework-registry/java-springboot.json +67 -0
  7. package/dist/config/framework-registry/php-laravel.json +67 -0
  8. package/dist/config/framework-registry/python-django.json +72 -0
  9. package/dist/config/framework-registry/python-fastapi.json +72 -0
  10. package/dist/config/framework-registry/ruby-rails.json +67 -0
  11. package/dist/config/framework-registry/rust-actix.json +61 -0
  12. package/dist/config/framework-registry/swift-swiftui.json +67 -0
  13. package/dist/config/framework-registry/typescript-angular.json +67 -0
  14. package/dist/config/framework-registry/typescript-astro.json +61 -0
  15. package/dist/config/framework-registry/typescript-express.json +67 -0
  16. package/dist/config/framework-registry/typescript-nestjs.json +62 -0
  17. package/dist/config/framework-registry/typescript-nextjs.json +82 -0
  18. package/dist/config/framework-registry/typescript-nuxt.json +67 -0
  19. package/dist/config/framework-registry/typescript-react.json +77 -0
  20. package/dist/config/framework-registry/typescript-remix.json +61 -0
  21. package/dist/config/framework-registry/typescript-sveltekit.json +67 -0
  22. package/dist/config/framework-registry/typescript-vue.json +72 -0
  23. package/dist/config/license-plans.json +23 -3
  24. package/dist/engine/agile-config-builder.d.ts.map +1 -1
  25. package/dist/engine/agile-config-builder.js +3 -0
  26. package/dist/engine/agile-config-builder.js.map +1 -1
  27. package/dist/engine/ai-cost-estimator/core.d.ts +8 -0
  28. package/dist/engine/ai-cost-estimator/core.d.ts.map +1 -0
  29. package/dist/engine/ai-cost-estimator/core.js +257 -0
  30. package/dist/engine/ai-cost-estimator/core.js.map +1 -0
  31. package/dist/engine/ai-cost-estimator/index.d.ts +4 -0
  32. package/dist/engine/ai-cost-estimator/index.d.ts.map +1 -0
  33. package/dist/engine/ai-cost-estimator/index.js +5 -0
  34. package/dist/engine/ai-cost-estimator/index.js.map +1 -0
  35. package/dist/engine/ai-cost-estimator/model-pricing.d.ts +31 -0
  36. package/dist/engine/ai-cost-estimator/model-pricing.d.ts.map +1 -0
  37. package/dist/engine/ai-cost-estimator/model-pricing.js +96 -0
  38. package/dist/engine/ai-cost-estimator/model-pricing.js.map +1 -0
  39. package/dist/engine/ai-cost-estimator/token-estimator.d.ts +37 -0
  40. package/dist/engine/ai-cost-estimator/token-estimator.d.ts.map +1 -0
  41. package/dist/engine/ai-cost-estimator/token-estimator.js +194 -0
  42. package/dist/engine/ai-cost-estimator/token-estimator.js.map +1 -0
  43. package/dist/engine/ci-generator/context-builders.d.ts +4 -0
  44. package/dist/engine/ci-generator/context-builders.d.ts.map +1 -0
  45. package/dist/engine/ci-generator/context-builders.js +129 -0
  46. package/dist/engine/ci-generator/context-builders.js.map +1 -0
  47. package/dist/engine/ci-generator/index.d.ts +7 -0
  48. package/dist/engine/ci-generator/index.d.ts.map +1 -0
  49. package/dist/engine/ci-generator/index.js +44 -0
  50. package/dist/engine/ci-generator/index.js.map +1 -0
  51. package/dist/engine/ci-generator/stack-detector.d.ts +21 -0
  52. package/dist/engine/ci-generator/stack-detector.d.ts.map +1 -0
  53. package/dist/engine/ci-generator/stack-detector.js +203 -0
  54. package/dist/engine/ci-generator/stack-detector.js.map +1 -0
  55. package/dist/engine/ci-generator/yaml-builder.d.ts +8 -0
  56. package/dist/engine/ci-generator/yaml-builder.d.ts.map +1 -0
  57. package/dist/engine/ci-generator/yaml-builder.js +285 -0
  58. package/dist/engine/ci-generator/yaml-builder.js.map +1 -0
  59. package/dist/engine/dashboard/data-loader.d.ts +21 -0
  60. package/dist/engine/dashboard/data-loader.d.ts.map +1 -0
  61. package/dist/engine/dashboard/data-loader.js +196 -0
  62. package/dist/engine/dashboard/data-loader.js.map +1 -0
  63. package/dist/engine/dashboard/index.d.ts +5 -0
  64. package/dist/engine/dashboard/index.d.ts.map +1 -0
  65. package/dist/engine/dashboard/index.js +6 -0
  66. package/dist/engine/dashboard/index.js.map +1 -0
  67. package/dist/engine/dashboard/routes.d.ts +4 -0
  68. package/dist/engine/dashboard/routes.d.ts.map +1 -0
  69. package/dist/engine/dashboard/routes.js +120 -0
  70. package/dist/engine/dashboard/routes.js.map +1 -0
  71. package/dist/engine/dashboard/server.d.ts +14 -0
  72. package/dist/engine/dashboard/server.d.ts.map +1 -0
  73. package/dist/engine/dashboard/server.js +88 -0
  74. package/dist/engine/dashboard/server.js.map +1 -0
  75. package/dist/engine/dashboard/templates-layout.d.ts +11 -0
  76. package/dist/engine/dashboard/templates-layout.d.ts.map +1 -0
  77. package/dist/engine/dashboard/templates-layout.js +305 -0
  78. package/dist/engine/dashboard/templates-layout.js.map +1 -0
  79. package/dist/engine/dashboard/templates-project.d.ts +10 -0
  80. package/dist/engine/dashboard/templates-project.d.ts.map +1 -0
  81. package/dist/engine/dashboard/templates-project.js +163 -0
  82. package/dist/engine/dashboard/templates-project.js.map +1 -0
  83. package/dist/engine/dashboard/templates.d.ts +3 -0
  84. package/dist/engine/dashboard/templates.d.ts.map +1 -0
  85. package/dist/engine/dashboard/templates.js +4 -0
  86. package/dist/engine/dashboard/templates.js.map +1 -0
  87. package/dist/engine/focus-tracker.d.ts.map +1 -1
  88. package/dist/engine/focus-tracker.js +1 -0
  89. package/dist/engine/focus-tracker.js.map +1 -1
  90. package/dist/engine/hooks/core.d.ts +26 -0
  91. package/dist/engine/hooks/core.d.ts.map +1 -0
  92. package/dist/engine/hooks/core.js +164 -0
  93. package/dist/engine/hooks/core.js.map +1 -0
  94. package/dist/engine/hooks/git-hook-generator.d.ts +14 -0
  95. package/dist/engine/hooks/git-hook-generator.d.ts.map +1 -0
  96. package/dist/engine/hooks/git-hook-generator.js +119 -0
  97. package/dist/engine/hooks/git-hook-generator.js.map +1 -0
  98. package/dist/engine/hooks/index.d.ts +5 -0
  99. package/dist/engine/hooks/index.d.ts.map +1 -0
  100. package/dist/engine/hooks/index.js +6 -0
  101. package/dist/engine/hooks/index.js.map +1 -0
  102. package/dist/engine/hooks/templates.d.ts +14 -0
  103. package/dist/engine/hooks/templates.d.ts.map +1 -0
  104. package/dist/engine/hooks/templates.js +138 -0
  105. package/dist/engine/hooks/templates.js.map +1 -0
  106. package/dist/engine/hooks/triggers.d.ts +27 -0
  107. package/dist/engine/hooks/triggers.d.ts.map +1 -0
  108. package/dist/engine/hooks/triggers.js +104 -0
  109. package/dist/engine/hooks/triggers.js.map +1 -0
  110. package/dist/engine/license-validator/core.d.ts +1 -0
  111. package/dist/engine/license-validator/core.d.ts.map +1 -1
  112. package/dist/engine/license-validator/core.js +10 -1
  113. package/dist/engine/license-validator/core.js.map +1 -1
  114. package/dist/engine/license-validator/fingerprint.d.ts +3 -0
  115. package/dist/engine/license-validator/fingerprint.d.ts.map +1 -0
  116. package/dist/engine/license-validator/fingerprint.js +17 -0
  117. package/dist/engine/license-validator/fingerprint.js.map +1 -0
  118. package/dist/engine/license-validator.d.ts +2 -1
  119. package/dist/engine/license-validator.d.ts.map +1 -1
  120. package/dist/engine/license-validator.js +2 -1
  121. package/dist/engine/license-validator.js.map +1 -1
  122. package/dist/engine/registry/core.d.ts +32 -0
  123. package/dist/engine/registry/core.d.ts.map +1 -0
  124. package/dist/engine/registry/core.js +85 -0
  125. package/dist/engine/registry/core.js.map +1 -0
  126. package/dist/engine/registry/index.d.ts +6 -0
  127. package/dist/engine/registry/index.d.ts.map +1 -0
  128. package/dist/engine/registry/index.js +8 -0
  129. package/dist/engine/registry/index.js.map +1 -0
  130. package/dist/engine/registry/loader.d.ts +18 -0
  131. package/dist/engine/registry/loader.d.ts.map +1 -0
  132. package/dist/engine/registry/loader.js +81 -0
  133. package/dist/engine/registry/loader.js.map +1 -0
  134. package/dist/engine/registry/matcher.d.ts +19 -0
  135. package/dist/engine/registry/matcher.d.ts.map +1 -0
  136. package/dist/engine/registry/matcher.js +150 -0
  137. package/dist/engine/registry/matcher.js.map +1 -0
  138. package/dist/engine/registry/reporter.d.ts +10 -0
  139. package/dist/engine/registry/reporter.d.ts.map +1 -0
  140. package/dist/engine/registry/reporter.js +132 -0
  141. package/dist/engine/registry/reporter.js.map +1 -0
  142. package/dist/engine/registry/validator.d.ts +17 -0
  143. package/dist/engine/registry/validator.d.ts.map +1 -0
  144. package/dist/engine/registry/validator.js +103 -0
  145. package/dist/engine/registry/validator.js.map +1 -0
  146. package/dist/engine/spec-changelog/core.d.ts +16 -0
  147. package/dist/engine/spec-changelog/core.d.ts.map +1 -0
  148. package/dist/engine/spec-changelog/core.js +175 -0
  149. package/dist/engine/spec-changelog/core.js.map +1 -0
  150. package/dist/engine/spec-changelog/diff.d.ts +18 -0
  151. package/dist/engine/spec-changelog/diff.d.ts.map +1 -0
  152. package/dist/engine/spec-changelog/diff.js +116 -0
  153. package/dist/engine/spec-changelog/diff.js.map +1 -0
  154. package/dist/engine/spec-changelog/index.d.ts +3 -0
  155. package/dist/engine/spec-changelog/index.d.ts.map +1 -0
  156. package/dist/engine/spec-changelog/index.js +4 -0
  157. package/dist/engine/spec-changelog/index.js.map +1 -0
  158. package/dist/engine/spec-coverage/core.d.ts +14 -0
  159. package/dist/engine/spec-coverage/core.d.ts.map +1 -0
  160. package/dist/engine/spec-coverage/core.js +132 -0
  161. package/dist/engine/spec-coverage/core.js.map +1 -0
  162. package/dist/engine/spec-coverage/criteria-mapper.d.ts +18 -0
  163. package/dist/engine/spec-coverage/criteria-mapper.d.ts.map +1 -0
  164. package/dist/engine/spec-coverage/criteria-mapper.js +306 -0
  165. package/dist/engine/spec-coverage/criteria-mapper.js.map +1 -0
  166. package/dist/engine/spec-coverage/index.d.ts +4 -0
  167. package/dist/engine/spec-coverage/index.d.ts.map +1 -0
  168. package/dist/engine/spec-coverage/index.js +5 -0
  169. package/dist/engine/spec-coverage/index.js.map +1 -0
  170. package/dist/engine/spec-coverage/test-finder.d.ts +17 -0
  171. package/dist/engine/spec-coverage/test-finder.d.ts.map +1 -0
  172. package/dist/engine/spec-coverage/test-finder.js +250 -0
  173. package/dist/engine/spec-coverage/test-finder.js.map +1 -0
  174. package/dist/engine/spec-templates/catalog-extra.d.ts +4 -0
  175. package/dist/engine/spec-templates/catalog-extra.d.ts.map +1 -0
  176. package/dist/engine/spec-templates/catalog-extra.js +367 -0
  177. package/dist/engine/spec-templates/catalog-extra.js.map +1 -0
  178. package/dist/engine/spec-templates/catalog.d.ts +4 -0
  179. package/dist/engine/spec-templates/catalog.d.ts.map +1 -0
  180. package/dist/engine/spec-templates/catalog.js +386 -0
  181. package/dist/engine/spec-templates/catalog.js.map +1 -0
  182. package/dist/engine/spec-templates/index.d.ts +4 -0
  183. package/dist/engine/spec-templates/index.d.ts.map +1 -0
  184. package/dist/engine/spec-templates/index.js +5 -0
  185. package/dist/engine/spec-templates/index.js.map +1 -0
  186. package/dist/engine/spec-templates/query.d.ts +14 -0
  187. package/dist/engine/spec-templates/query.d.ts.map +1 -0
  188. package/dist/engine/spec-templates/query.js +56 -0
  189. package/dist/engine/spec-templates/query.js.map +1 -0
  190. package/dist/engine/spec-templates/renderer.d.ts +19 -0
  191. package/dist/engine/spec-templates/renderer.d.ts.map +1 -0
  192. package/dist/engine/spec-templates/renderer.js +45 -0
  193. package/dist/engine/spec-templates/renderer.js.map +1 -0
  194. package/dist/engine/usage-tracker/trial.d.ts +4 -4
  195. package/dist/engine/usage-tracker/trial.d.ts.map +1 -1
  196. package/dist/engine/usage-tracker/trial.js +4 -4
  197. package/dist/engine/usage-tracker/trial.js.map +1 -1
  198. package/dist/engine/webhook/event-handlers.d.ts +25 -0
  199. package/dist/engine/webhook/event-handlers.d.ts.map +1 -0
  200. package/dist/engine/webhook/event-handlers.js +89 -0
  201. package/dist/engine/webhook/event-handlers.js.map +1 -0
  202. package/dist/engine/webhook/index.d.ts +4 -0
  203. package/dist/engine/webhook/index.d.ts.map +1 -0
  204. package/dist/engine/webhook/index.js +5 -0
  205. package/dist/engine/webhook/index.js.map +1 -0
  206. package/dist/engine/webhook/server.d.ts +18 -0
  207. package/dist/engine/webhook/server.d.ts.map +1 -0
  208. package/dist/engine/webhook/server.js +187 -0
  209. package/dist/engine/webhook/server.js.map +1 -0
  210. package/dist/engine/webhook/signature.d.ts +16 -0
  211. package/dist/engine/webhook/signature.d.ts.map +1 -0
  212. package/dist/engine/webhook/signature.js +49 -0
  213. package/dist/engine/webhook/signature.js.map +1 -0
  214. package/dist/index.js +18 -0
  215. package/dist/index.js.map +1 -1
  216. package/dist/storage/hooks-store.d.ts +34 -0
  217. package/dist/storage/hooks-store.d.ts.map +1 -0
  218. package/dist/storage/hooks-store.js +128 -0
  219. package/dist/storage/hooks-store.js.map +1 -0
  220. package/dist/storage/index.d.ts +1 -0
  221. package/dist/storage/index.d.ts.map +1 -1
  222. package/dist/storage/index.js +1 -0
  223. package/dist/storage/index.js.map +1 -1
  224. package/dist/tools/activate-license.d.ts.map +1 -1
  225. package/dist/tools/activate-license.js +5 -2
  226. package/dist/tools/activate-license.js.map +1 -1
  227. package/dist/tools/check-spec-accuracy.d.ts +7 -0
  228. package/dist/tools/check-spec-accuracy.d.ts.map +1 -0
  229. package/dist/tools/check-spec-accuracy.js +28 -0
  230. package/dist/tools/check-spec-accuracy.js.map +1 -0
  231. package/dist/tools/ci-generator.d.ts +7 -0
  232. package/dist/tools/ci-generator.d.ts.map +1 -0
  233. package/dist/tools/ci-generator.js +49 -0
  234. package/dist/tools/ci-generator.js.map +1 -0
  235. package/dist/tools/create-spec.d.ts.map +1 -1
  236. package/dist/tools/create-spec.js +4 -0
  237. package/dist/tools/create-spec.js.map +1 -1
  238. package/dist/tools/dashboard.d.ts +6 -0
  239. package/dist/tools/dashboard.d.ts.map +1 -0
  240. package/dist/tools/dashboard.js +48 -0
  241. package/dist/tools/dashboard.js.map +1 -0
  242. package/dist/tools/detect-drift.d.ts.map +1 -1
  243. package/dist/tools/detect-drift.js +6 -0
  244. package/dist/tools/detect-drift.js.map +1 -1
  245. package/dist/tools/estimate-ai-cost.d.ts +8 -0
  246. package/dist/tools/estimate-ai-cost.d.ts.map +1 -0
  247. package/dist/tools/estimate-ai-cost.js +29 -0
  248. package/dist/tools/estimate-ai-cost.js.map +1 -0
  249. package/dist/tools/license-gate.d.ts.map +1 -1
  250. package/dist/tools/license-gate.js +27 -20
  251. package/dist/tools/license-gate.js.map +1 -1
  252. package/dist/tools/license-status.d.ts.map +1 -1
  253. package/dist/tools/license-status.js +3 -0
  254. package/dist/tools/license-status.js.map +1 -1
  255. package/dist/tools/list-specs.d.ts.map +1 -1
  256. package/dist/tools/list-specs.js +15 -0
  257. package/dist/tools/list-specs.js.map +1 -1
  258. package/dist/tools/manage-hooks.d.ts +5 -0
  259. package/dist/tools/manage-hooks.d.ts.map +1 -0
  260. package/dist/tools/manage-hooks.js +247 -0
  261. package/dist/tools/manage-hooks.js.map +1 -0
  262. package/dist/tools/reconcile-spec.d.ts.map +1 -1
  263. package/dist/tools/reconcile-spec.js +24 -0
  264. package/dist/tools/reconcile-spec.js.map +1 -1
  265. package/dist/tools/register-ai-cost-tools.d.ts +3 -0
  266. package/dist/tools/register-ai-cost-tools.d.ts.map +1 -0
  267. package/dist/tools/register-ai-cost-tools.js +25 -0
  268. package/dist/tools/register-ai-cost-tools.js.map +1 -0
  269. package/dist/tools/register-changelog-tools.d.ts +3 -0
  270. package/dist/tools/register-changelog-tools.d.ts.map +1 -0
  271. package/dist/tools/register-changelog-tools.js +23 -0
  272. package/dist/tools/register-changelog-tools.js.map +1 -0
  273. package/dist/tools/register-ci-tools.d.ts +3 -0
  274. package/dist/tools/register-ci-tools.d.ts.map +1 -0
  275. package/dist/tools/register-ci-tools.js +50 -0
  276. package/dist/tools/register-ci-tools.js.map +1 -0
  277. package/dist/tools/register-coverage-tools.d.ts +7 -0
  278. package/dist/tools/register-coverage-tools.d.ts.map +1 -0
  279. package/dist/tools/register-coverage-tools.js +27 -0
  280. package/dist/tools/register-coverage-tools.js.map +1 -0
  281. package/dist/tools/register-dashboard-tools.d.ts +3 -0
  282. package/dist/tools/register-dashboard-tools.d.ts.map +1 -0
  283. package/dist/tools/register-dashboard-tools.js +29 -0
  284. package/dist/tools/register-dashboard-tools.js.map +1 -0
  285. package/dist/tools/register-hooks-tools.d.ts +3 -0
  286. package/dist/tools/register-hooks-tools.d.ts.map +1 -0
  287. package/dist/tools/register-hooks-tools.js +107 -0
  288. package/dist/tools/register-hooks-tools.js.map +1 -0
  289. package/dist/tools/register-registry-tools.d.ts +3 -0
  290. package/dist/tools/register-registry-tools.d.ts.map +1 -0
  291. package/dist/tools/register-registry-tools.js +43 -0
  292. package/dist/tools/register-registry-tools.js.map +1 -0
  293. package/dist/tools/register-template-tools.d.ts +8 -0
  294. package/dist/tools/register-template-tools.d.ts.map +1 -0
  295. package/dist/tools/register-template-tools.js +71 -0
  296. package/dist/tools/register-template-tools.js.map +1 -0
  297. package/dist/tools/register-webhook-tools.d.ts +3 -0
  298. package/dist/tools/register-webhook-tools.d.ts.map +1 -0
  299. package/dist/tools/register-webhook-tools.js +49 -0
  300. package/dist/tools/register-webhook-tools.js.map +1 -0
  301. package/dist/tools/schemas/index.d.ts +1 -0
  302. package/dist/tools/schemas/index.d.ts.map +1 -1
  303. package/dist/tools/schemas/index.js +1 -0
  304. package/dist/tools/schemas/index.js.map +1 -1
  305. package/dist/tools/schemas/registry.d.ts +41 -0
  306. package/dist/tools/schemas/registry.d.ts.map +1 -0
  307. package/dist/tools/schemas/registry.js +62 -0
  308. package/dist/tools/schemas/registry.js.map +1 -0
  309. package/dist/tools/spec-coverage.d.ts +3 -0
  310. package/dist/tools/spec-coverage.d.ts.map +1 -0
  311. package/dist/tools/spec-coverage.js +176 -0
  312. package/dist/tools/spec-coverage.js.map +1 -0
  313. package/dist/tools/spec-history.d.ts +3 -0
  314. package/dist/tools/spec-history.d.ts.map +1 -0
  315. package/dist/tools/spec-history.js +67 -0
  316. package/dist/tools/spec-history.js.map +1 -0
  317. package/dist/tools/spec-templates.d.ts +10 -0
  318. package/dist/tools/spec-templates.d.ts.map +1 -0
  319. package/dist/tools/spec-templates.js +155 -0
  320. package/dist/tools/spec-templates.js.map +1 -0
  321. package/dist/tools/update-registry.d.ts +8 -0
  322. package/dist/tools/update-registry.d.ts.map +1 -0
  323. package/dist/tools/update-registry.js +53 -0
  324. package/dist/tools/update-registry.js.map +1 -0
  325. package/dist/tools/update-status.d.ts.map +1 -1
  326. package/dist/tools/update-status.js +24 -0
  327. package/dist/tools/update-status.js.map +1 -1
  328. package/dist/tools/webhook.d.ts +6 -0
  329. package/dist/tools/webhook.d.ts.map +1 -0
  330. package/dist/tools/webhook.js +150 -0
  331. package/dist/tools/webhook.js.map +1 -0
  332. package/dist/types/ai-cost.d.ts +98 -0
  333. package/dist/types/ai-cost.d.ts.map +1 -0
  334. package/dist/types/ai-cost.js +4 -0
  335. package/dist/types/ai-cost.js.map +1 -0
  336. package/dist/types/analysis.d.ts +64 -0
  337. package/dist/types/analysis.d.ts.map +1 -1
  338. package/dist/types/changelog.d.ts +49 -0
  339. package/dist/types/changelog.d.ts.map +1 -0
  340. package/dist/types/changelog.js +3 -0
  341. package/dist/types/changelog.js.map +1 -0
  342. package/dist/types/ci.d.ts +105 -0
  343. package/dist/types/ci.d.ts.map +1 -0
  344. package/dist/types/ci.js +3 -0
  345. package/dist/types/ci.js.map +1 -0
  346. package/dist/types/coverage.d.ts +95 -0
  347. package/dist/types/coverage.d.ts.map +1 -0
  348. package/dist/types/coverage.js +4 -0
  349. package/dist/types/coverage.js.map +1 -0
  350. package/dist/types/hooks.d.ts +139 -0
  351. package/dist/types/hooks.d.ts.map +1 -0
  352. package/dist/types/hooks.js +3 -0
  353. package/dist/types/hooks.js.map +1 -0
  354. package/dist/types/index.d.ts +8 -0
  355. package/dist/types/index.d.ts.map +1 -1
  356. package/dist/types/index.js +8 -0
  357. package/dist/types/index.js.map +1 -1
  358. package/dist/types/licensing.d.ts +6 -0
  359. package/dist/types/licensing.d.ts.map +1 -1
  360. package/dist/types/registry.d.ts +90 -0
  361. package/dist/types/registry.d.ts.map +1 -0
  362. package/dist/types/registry.js +5 -0
  363. package/dist/types/registry.js.map +1 -0
  364. package/dist/types/spec-templates.d.ts +87 -0
  365. package/dist/types/spec-templates.d.ts.map +1 -0
  366. package/dist/types/spec-templates.js +3 -0
  367. package/dist/types/spec-templates.js.map +1 -0
  368. package/dist/types/ui.d.ts +76 -0
  369. package/dist/types/ui.d.ts.map +1 -1
  370. package/dist/types/webhook.d.ts +62 -0
  371. package/dist/types/webhook.d.ts.map +1 -0
  372. package/dist/types/webhook.js +4 -0
  373. package/dist/types/webhook.js.map +1 -0
  374. package/package.json +1 -1
  375. package/src/config/ai-model-pricing.json +81 -0
  376. package/src/config/framework-registry/csharp-aspnet.json +67 -0
  377. package/src/config/framework-registry/dart-flutter.json +61 -0
  378. package/src/config/framework-registry/go-gin.json +62 -0
  379. package/src/config/framework-registry/index.json +164 -0
  380. package/src/config/framework-registry/java-springboot.json +67 -0
  381. package/src/config/framework-registry/php-laravel.json +67 -0
  382. package/src/config/framework-registry/python-django.json +72 -0
  383. package/src/config/framework-registry/python-fastapi.json +72 -0
  384. package/src/config/framework-registry/ruby-rails.json +67 -0
  385. package/src/config/framework-registry/rust-actix.json +61 -0
  386. package/src/config/framework-registry/swift-swiftui.json +67 -0
  387. package/src/config/framework-registry/typescript-angular.json +67 -0
  388. package/src/config/framework-registry/typescript-astro.json +61 -0
  389. package/src/config/framework-registry/typescript-express.json +67 -0
  390. package/src/config/framework-registry/typescript-nestjs.json +62 -0
  391. package/src/config/framework-registry/typescript-nextjs.json +82 -0
  392. package/src/config/framework-registry/typescript-nuxt.json +67 -0
  393. package/src/config/framework-registry/typescript-react.json +77 -0
  394. package/src/config/framework-registry/typescript-remix.json +61 -0
  395. package/src/config/framework-registry/typescript-sveltekit.json +67 -0
  396. package/src/config/framework-registry/typescript-vue.json +72 -0
  397. package/src/config/license-plans.json +23 -3
@@ -0,0 +1,81 @@
1
+ // engine/registry/loader.ts — Loads and merges framework registry entries
2
+ // Base entries come from src/config/framework-registry/*.json
3
+ // Custom entries come from data/global/registry-custom.json (user-added)
4
+ import { readFile, readdir } from 'node:fs/promises';
5
+ import { join, dirname } from 'node:path';
6
+ import { fileURLToPath } from 'node:url';
7
+ import { readJson } from '../../storage/base-store.js';
8
+ const REGISTRY_DIR = join(dirname(fileURLToPath(import.meta.url)), '../../config/framework-registry');
9
+ const CUSTOM_REGISTRY_PATH = 'data/global/registry-custom.json';
10
+ /**
11
+ * Load a single framework JSON file from the base registry directory.
12
+ * Returns null if the file is missing or malformed.
13
+ */
14
+ async function loadFrameworkFile(fileName) {
15
+ try {
16
+ const raw = await readFile(join(REGISTRY_DIR, fileName), 'utf-8');
17
+ const parsed = JSON.parse(raw);
18
+ return {
19
+ framework: parsed.framework,
20
+ displayName: parsed.displayName,
21
+ frameworkVersion: parsed.frameworkVersion,
22
+ lastUpdated: parsed.lastUpdated,
23
+ ecosystem: parsed.ecosystem,
24
+ customEntry: false,
25
+ correctPatterns: Array.isArray(parsed.correctPatterns)
26
+ ? parsed.correctPatterns
27
+ : [],
28
+ deprecatedPatterns: Array.isArray(parsed.deprecatedPatterns)
29
+ ? parsed.deprecatedPatterns
30
+ : [],
31
+ commonMistakes: Array.isArray(parsed.commonMistakes)
32
+ ? parsed.commonMistakes
33
+ : [],
34
+ };
35
+ }
36
+ catch {
37
+ return null;
38
+ }
39
+ }
40
+ /**
41
+ * Load all base framework entries from src/config/framework-registry/.
42
+ * Skips index.json and any file that fails to parse.
43
+ */
44
+ export async function loadBaseRegistry() {
45
+ let files;
46
+ try {
47
+ files = await readdir(REGISTRY_DIR);
48
+ }
49
+ catch {
50
+ return [];
51
+ }
52
+ const jsonFiles = files.filter((f) => f.endsWith('.json') && f !== 'index.json');
53
+ const results = await Promise.all(jsonFiles.map(loadFrameworkFile));
54
+ return results.filter((e) => e !== null);
55
+ }
56
+ /**
57
+ * Load user-defined custom registry entries from data/global/registry-custom.json.
58
+ * Returns an empty array when the file does not exist.
59
+ */
60
+ export async function loadCustomRegistry() {
61
+ const store = await readJson(CUSTOM_REGISTRY_PATH, { entries: [] });
62
+ return store.entries.map((e) => ({ ...e, customEntry: true }));
63
+ }
64
+ /**
65
+ * Load and merge the full registry: base + custom.
66
+ * Custom entries override base entries with the same framework ID.
67
+ * The merged map preserves custom entries for duplicates.
68
+ */
69
+ export async function loadRegistry() {
70
+ const [base, custom] = await Promise.all([loadBaseRegistry(), loadCustomRegistry()]);
71
+ const map = new Map();
72
+ for (const entry of base) {
73
+ map.set(entry.framework, entry);
74
+ }
75
+ // Custom overrides base for same framework ID
76
+ for (const entry of custom) {
77
+ map.set(entry.framework, { ...entry, customEntry: true });
78
+ }
79
+ return map;
80
+ }
81
+ //# sourceMappingURL=loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../../src/engine/registry/loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { RegistryEntry, FrameworkReference } from '../../types/index.js';
2
+ export type { FrameworkReference };
3
+ /**
4
+ * Detect which frameworks from the registry are mentioned in the spec text.
5
+ * A framework is considered mentioned if one of its aliases appears in the text
6
+ * (case-insensitive). Avoids single-word generic terms without API context.
7
+ */
8
+ export declare function detectFrameworks(specText: string, registry: Map<string, RegistryEntry>): string[];
9
+ /**
10
+ * Extract potential API/pattern references from spec text for specific frameworks.
11
+ * Returns deduplicated references with framework attribution.
12
+ */
13
+ export declare function extractReferences(specText: string, frameworkIds: string[], registry: Map<string, RegistryEntry>): FrameworkReference[];
14
+ /**
15
+ * Detect any framework names mentioned in the spec that are NOT in the registry.
16
+ * Scans for common framework keywords in text that don't map to known entries.
17
+ */
18
+ export declare function detectUnknownFrameworks(specText: string, registry: Map<string, RegistryEntry>): string[];
19
+ //# sourceMappingURL=matcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"matcher.d.ts","sourceRoot":"","sources":["../../../src/engine/registry/matcher.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE9E,YAAY,EAAE,kBAAkB,EAAE,CAAC;AA2DnC;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,GAAG,MAAM,EAAE,CAejG;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,EAAE,EACtB,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,GACnC,kBAAkB,EAAE,CA6BtB;AAgBD;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,GACnC,MAAM,EAAE,CAuBV"}
@@ -0,0 +1,150 @@
1
+ // engine/registry/matcher.ts — Detects framework mentions and API references in spec text
2
+ // Uses registry-aware keywords to avoid false positives on plain English words.
3
+ /** Mapping of framework ID → detection keywords (aliases / common spellings). */
4
+ const FRAMEWORK_ALIASES = {
5
+ nextjs: ['next.js', 'nextjs', 'next js', 'next/navigation', 'next/router', 'app router'],
6
+ react: ['react', 'react dom', 'reactdom', 'jsx', 'useState', 'useEffect', 'useCallback'],
7
+ vue: ['vue', 'vue 3', 'vue.js', 'vuejs', 'composition api', 'script setup'],
8
+ nuxt: ['nuxt', 'nuxt 3', 'nuxt.js', 'usefetch', 'definepageeta'],
9
+ angular: ['angular', 'angular 17', '@angular', 'standalone component', 'angularjs'],
10
+ sveltekit: ['sveltekit', 'svelte kit', 'svelte', '+page.server.ts', 'use:enhance'],
11
+ astro: ['astro', 'astro.js', 'astro 4', 'client:load', 'getcollection'],
12
+ remix: ['remix', 'remix 2', '@remix-run', 'useloaderdata', 'useactiondata'],
13
+ express: ['express', 'express.js', 'expressjs', 'express.router', 'app.get(', 'app.use('],
14
+ nestjs: ['nestjs', 'nest.js', '@nestjs', '@injectable', '@controller', '@module'],
15
+ django: ['django', 'django 5', 'django orm', 'models.model', 'views.py', 'urls.py'],
16
+ fastapi: [
17
+ 'fastapi',
18
+ 'fast api',
19
+ 'fastapi route',
20
+ '@app.get',
21
+ '@app.post',
22
+ 'pydantic v2',
23
+ 'basemodel',
24
+ ],
25
+ springboot: [
26
+ 'spring boot',
27
+ 'springboot',
28
+ '@springbootapplication',
29
+ '@restcontroller',
30
+ 'jparepository',
31
+ ],
32
+ rails: ['rails', 'ruby on rails', 'activerecord', 'activesupport', 'hotwire', 'turbo'],
33
+ laravel: ['laravel', 'laravel 11', 'eloquent', 'artisan', 'blade template'],
34
+ gin: ['gin framework', 'gin.new()', 'gin.default()', 'c.json(', 'gin.h{', 'c.shouldbindjson'],
35
+ actix: ['actix-web', 'actix web', 'actix 4', 'web::data', 'httpresponse', 'web::path'],
36
+ aspnet: ['asp.net', 'aspnet', '.net core', 'dotnet', '@controller', 'iactionresult', 'blazor'],
37
+ flutter: [
38
+ 'flutter',
39
+ 'dart flutter',
40
+ 'statefulwidget',
41
+ 'statelesswidget',
42
+ 'buildcontext',
43
+ 'scaffold(',
44
+ ],
45
+ swiftui: ['swiftui', 'swift ui', '@state', '@observedobject', '@stateobject', 'navigationstack'],
46
+ };
47
+ /** Regex patterns to detect API/pattern references in text. */
48
+ const API_PATTERNS = [
49
+ // Function calls: functionName() or method.call()
50
+ /\b([a-zA-Z$_][a-zA-Z0-9$_.]{2,})\s*\(/g,
51
+ // Import statements
52
+ /import\s+.*?\s+from\s+['"]([^'"]+)['"]/g,
53
+ // Config keys: key.subkey = value
54
+ /\b([a-z][a-z0-9-]{2,}\.[a-z][a-z0-9-.]{2,})\s*=/g,
55
+ // Decorator-like patterns: @SomeName
56
+ /@([A-Z][a-zA-Z0-9]+)/g,
57
+ ];
58
+ /**
59
+ * Detect which frameworks from the registry are mentioned in the spec text.
60
+ * A framework is considered mentioned if one of its aliases appears in the text
61
+ * (case-insensitive). Avoids single-word generic terms without API context.
62
+ */
63
+ export function detectFrameworks(specText, registry) {
64
+ const lower = specText.toLowerCase();
65
+ const detected = [];
66
+ for (const [frameworkId, aliases] of Object.entries(FRAMEWORK_ALIASES)) {
67
+ if (!registry.has(frameworkId)) {
68
+ continue;
69
+ }
70
+ const matched = aliases.some((alias) => lower.includes(alias.toLowerCase()));
71
+ if (matched) {
72
+ detected.push(frameworkId);
73
+ }
74
+ }
75
+ return [...new Set(detected)];
76
+ }
77
+ /**
78
+ * Extract potential API/pattern references from spec text for specific frameworks.
79
+ * Returns deduplicated references with framework attribution.
80
+ */
81
+ export function extractReferences(specText, frameworkIds, registry) {
82
+ const references = [];
83
+ const seen = new Set();
84
+ for (const frameworkId of frameworkIds) {
85
+ const entry = registry.get(frameworkId);
86
+ if (!entry) {
87
+ continue;
88
+ }
89
+ // Extract all pattern-like tokens from the text
90
+ for (const regex of API_PATTERNS) {
91
+ const cloned = new RegExp(regex.source, regex.flags);
92
+ let match;
93
+ while ((match = cloned.exec(specText)) !== null) {
94
+ const token = (match[1] ?? match[0]).trim();
95
+ const key = `${frameworkId}::${token}`;
96
+ if (seen.has(key) || token.length < 3) {
97
+ continue;
98
+ }
99
+ seen.add(key);
100
+ const kind = determineKind(match[0]);
101
+ references.push({ framework: frameworkId, text: token, kind });
102
+ }
103
+ }
104
+ }
105
+ return references;
106
+ }
107
+ /** Determine the kind of reference from the matched text. */
108
+ function determineKind(rawMatch) {
109
+ if (rawMatch.startsWith('import')) {
110
+ return 'import';
111
+ }
112
+ if (rawMatch.startsWith('@')) {
113
+ return 'api-call';
114
+ }
115
+ if (/=\s*$/.test(rawMatch)) {
116
+ return 'config-key';
117
+ }
118
+ return 'pattern-mention';
119
+ }
120
+ /**
121
+ * Detect any framework names mentioned in the spec that are NOT in the registry.
122
+ * Scans for common framework keywords in text that don't map to known entries.
123
+ */
124
+ export function detectUnknownFrameworks(specText, registry) {
125
+ const lower = specText.toLowerCase();
126
+ const knownFrameworkNames = new Set([...registry.values()].map((e) => e.displayName.toLowerCase()));
127
+ // Broad keyword scan for frameworks not in registry
128
+ const frameworkMentionRegex = /\b((?:[a-z][a-z0-9-]{1,}\.?(?:js|ts|py|rb|php|go|rs))|(?:fastify|hono|elysia|fiber|axum|rocket|gin|echo|koa|hapi|oak|deno|bun))\b/gi;
129
+ const unknown = [];
130
+ const seen = new Set();
131
+ let m;
132
+ while ((m = frameworkMentionRegex.exec(lower)) !== null) {
133
+ const name = (m[1] ?? '').toLowerCase();
134
+ if (!seen.has(name) && !knownFrameworkNames.has(name) && !isInRegistry(name, registry)) {
135
+ seen.add(name);
136
+ unknown.push(m[1] ?? name);
137
+ }
138
+ }
139
+ return unknown;
140
+ }
141
+ /** Check if a name matches any alias in the registry. */
142
+ function isInRegistry(name, registry) {
143
+ for (const aliases of Object.values(FRAMEWORK_ALIASES)) {
144
+ if (aliases.some((a) => a.toLowerCase() === name.toLowerCase())) {
145
+ return true;
146
+ }
147
+ }
148
+ return registry.has(name);
149
+ }
150
+ //# sourceMappingURL=matcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"matcher.js","sourceRoot":"","sources":["../../../src/engine/registry/matcher.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { SpecAccuracyReport, RegistryEntry, ValidationResult } from '../../types/index.js';
2
+ /**
3
+ * Build the full SpecAccuracyReport from validation results and metadata.
4
+ */
5
+ export declare function buildReport(results: ValidationResult[], frameworksDetected: string[], frameworksNotInRegistry: string[], registry: Map<string, RegistryEntry>): SpecAccuracyReport;
6
+ /**
7
+ * Format a SpecAccuracyReport as a Markdown string for display in MCP response.
8
+ */
9
+ export declare function formatReport(report: SpecAccuracyReport): string;
10
+ //# sourceMappingURL=reporter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reporter.d.ts","sourceRoot":"","sources":["../../../src/engine/registry/reporter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,kBAAkB,EAElB,aAAa,EACb,gBAAgB,EACjB,MAAM,sBAAsB,CAAC;AAkD9B;;GAEG;AACH,wBAAgB,WAAW,CACzB,OAAO,EAAE,gBAAgB,EAAE,EAC3B,kBAAkB,EAAE,MAAM,EAAE,EAC5B,uBAAuB,EAAE,MAAM,EAAE,EACjC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,GACnC,kBAAkB,CAepB;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,kBAAkB,GAAG,MAAM,CAkF/D"}
@@ -0,0 +1,132 @@
1
+ // engine/registry/reporter.ts — Builds the SpecAccuracyReport from validation results
2
+ /** Threshold (days) beyond which a registry entry is considered stale. */
3
+ const STALE_DAYS = 180;
4
+ const MS_PER_DAY = 86_400_000;
5
+ /** Calculate score as percentage of references that were validated (not unknown). */
6
+ function calculateScore(results) {
7
+ if (results.length === 0) {
8
+ return 100;
9
+ }
10
+ const validated = results.filter((r) => r.status !== 'unknown').length;
11
+ return Math.round((validated / results.length) * 100);
12
+ }
13
+ /** Extract unique issues from validation results (skip valid ones). */
14
+ function collectIssues(results) {
15
+ const seen = new Set();
16
+ const issues = [];
17
+ for (const result of results) {
18
+ if (result.status === 'valid' || !result.issue) {
19
+ continue;
20
+ }
21
+ const key = `${result.issue.type}::${result.issue.framework}::${result.issue.reference}`;
22
+ if (!seen.has(key)) {
23
+ seen.add(key);
24
+ issues.push(result.issue);
25
+ }
26
+ }
27
+ return issues;
28
+ }
29
+ /** Find registry entries that haven't been updated in more than 180 days. */
30
+ function detectStaleEntries(frameworkIds, registry) {
31
+ const now = Date.now();
32
+ return frameworkIds.filter((id) => {
33
+ const entry = registry.get(id);
34
+ /* v8 ignore next 2 — defensive guard; callers pass IDs from detectFrameworks() which already filters by registry */
35
+ if (!entry) {
36
+ return false;
37
+ }
38
+ const updated = new Date(entry.lastUpdated).getTime();
39
+ return !isNaN(updated) && now - updated > STALE_DAYS * MS_PER_DAY;
40
+ });
41
+ }
42
+ /**
43
+ * Build the full SpecAccuracyReport from validation results and metadata.
44
+ */
45
+ export function buildReport(results, frameworksDetected, frameworksNotInRegistry, registry) {
46
+ const issues = collectIssues(results);
47
+ const score = calculateScore(results);
48
+ const validatedReferences = results.filter((r) => r.status !== 'unknown').length;
49
+ const staleRegistryEntries = detectStaleEntries(frameworksDetected, registry);
50
+ return {
51
+ score,
52
+ issues,
53
+ frameworksDetected,
54
+ frameworksNotInRegistry,
55
+ totalReferencesChecked: results.length,
56
+ validatedReferences,
57
+ staleRegistryEntries,
58
+ };
59
+ }
60
+ /**
61
+ * Format a SpecAccuracyReport as a Markdown string for display in MCP response.
62
+ */
63
+ export function formatReport(report) {
64
+ const lines = [];
65
+ lines.push('## Spec Accuracy Report');
66
+ lines.push('');
67
+ lines.push(`**Score de confianza:** ${report.score}/100`);
68
+ lines.push(`**Referencias analizadas:** ${report.totalReferencesChecked}`);
69
+ lines.push(`**Referencias validadas:** ${report.validatedReferences}`);
70
+ lines.push('');
71
+ if (report.frameworksDetected.length > 0) {
72
+ lines.push(`**Frameworks detectados:** ${report.frameworksDetected.join(', ')}`);
73
+ }
74
+ if (report.frameworksNotInRegistry.length > 0) {
75
+ lines.push('');
76
+ lines.push('### Advertencias — Frameworks no en registry');
77
+ lines.push('');
78
+ for (const fw of report.frameworksNotInRegistry) {
79
+ lines.push(`- Framework '${fw}' no encontrado en el registry — las referencias a su API no pudieron ser validadas`);
80
+ }
81
+ }
82
+ if (report.staleRegistryEntries.length > 0) {
83
+ lines.push('');
84
+ lines.push('### Advertencias — Entradas desactualizadas');
85
+ lines.push('');
86
+ for (const fw of report.staleRegistryEntries) {
87
+ lines.push(`- La entrada de '${fw}' tiene mas de 180 dias sin actualizar — verificar si los patrones siguen vigentes`);
88
+ }
89
+ }
90
+ const errors = report.issues.filter((i) => i.severity === 'error');
91
+ const warnings = report.issues.filter((i) => i.severity === 'warning');
92
+ const infos = report.issues.filter((i) => i.severity === 'info');
93
+ if (errors.length > 0) {
94
+ lines.push('');
95
+ lines.push('### Errores detectados');
96
+ lines.push('');
97
+ for (const issue of errors) {
98
+ lines.push(`- **[${issue.framework}]** \`${issue.reference}\``);
99
+ if (issue.suggestion) {
100
+ lines.push(` - Sugerencia: ${issue.suggestion}`);
101
+ }
102
+ }
103
+ }
104
+ if (warnings.length > 0) {
105
+ lines.push('');
106
+ lines.push('### Advertencias de patrones');
107
+ lines.push('');
108
+ for (const issue of warnings) {
109
+ lines.push(`- **[${issue.framework}]** \`${issue.reference}\``);
110
+ if (issue.suggestion) {
111
+ lines.push(` - Sugerencia: ${issue.suggestion}`);
112
+ }
113
+ }
114
+ }
115
+ if (infos.length > 0) {
116
+ lines.push('');
117
+ lines.push('### Informacion adicional');
118
+ lines.push('');
119
+ for (const issue of infos) {
120
+ lines.push(`- **[${issue.framework}]** ${issue.reference}`);
121
+ if (issue.suggestion) {
122
+ lines.push(` - ${issue.suggestion}`);
123
+ }
124
+ }
125
+ }
126
+ if (report.issues.length === 0) {
127
+ lines.push('');
128
+ lines.push('No se detectaron problemas en las referencias analizadas.');
129
+ }
130
+ return lines.join('\n');
131
+ }
132
+ //# sourceMappingURL=reporter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reporter.js","sourceRoot":"","sources":["../../../src/engine/registry/reporter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { RegistryEntry, FrameworkReference, ValidationResult } from '../../types/index.js';
2
+ export type { ValidationResult };
3
+ /**
4
+ * Validate a single reference against its framework registry entry.
5
+ * Precedence: mistake > deprecated > correct > unknown
6
+ */
7
+ export declare function validateReference(ref: FrameworkReference, registry: Map<string, RegistryEntry>): ValidationResult;
8
+ /**
9
+ * Validate all references and return the classification results.
10
+ * References for frameworks not in the registry are skipped (handled separately).
11
+ */
12
+ export declare function validateReferences(references: FrameworkReference[], registry: Map<string, RegistryEntry>): ValidationResult[];
13
+ /**
14
+ * Detect registry entries that have not been updated in more than 180 days.
15
+ */
16
+ export declare function detectStaleEntries(registry: Map<string, RegistryEntry>): string[];
17
+ //# sourceMappingURL=validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../../src/engine/registry/validator.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,aAAa,EAEb,kBAAkB,EAClB,gBAAgB,EACjB,MAAM,sBAAsB,CAAC;AAE9B,YAAY,EAAE,gBAAgB,EAAE,CAAC;AAsCjC;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,kBAAkB,EACvB,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,GACnC,gBAAgB,CAiDlB;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,kBAAkB,EAAE,EAChC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,GACnC,gBAAgB,EAAE,CAEpB;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,GAAG,MAAM,EAAE,CAajF"}
@@ -0,0 +1,103 @@
1
+ // engine/registry/validator.ts — Compares extracted references against registry entries
2
+ // Classifies each reference as: valid, deprecated, mistake, or unknown
3
+ /** Search through all patterns in a registry entry to find a match. */
4
+ function findInPatterns(token, patterns) {
5
+ const lowerToken = token.toLowerCase();
6
+ return patterns.some((p) => {
7
+ const lowerPattern = p.pattern.toLowerCase();
8
+ const lowerExample = (p.example ?? '').toLowerCase();
9
+ return lowerPattern.includes(lowerToken) || lowerExample.includes(lowerToken);
10
+ });
11
+ }
12
+ /** Find a matching deprecated pattern and return its replacement. */
13
+ function findDeprecated(token, patterns) {
14
+ const lowerToken = token.toLowerCase();
15
+ return patterns.find((p) => {
16
+ const lowerPattern = p.pattern.toLowerCase();
17
+ const lowerExample = (p.example ?? '').toLowerCase();
18
+ return lowerPattern.includes(lowerToken) || lowerExample.includes(lowerToken);
19
+ });
20
+ }
21
+ /** Find a matching common mistake and return it. */
22
+ function findMistake(token, patterns) {
23
+ const lowerToken = token.toLowerCase();
24
+ return patterns.find((p) => {
25
+ const lowerPattern = p.pattern.toLowerCase();
26
+ const lowerExample = (p.example ?? '').toLowerCase();
27
+ return lowerPattern.includes(lowerToken) || lowerExample.includes(lowerToken);
28
+ });
29
+ }
30
+ /**
31
+ * Validate a single reference against its framework registry entry.
32
+ * Precedence: mistake > deprecated > correct > unknown
33
+ */
34
+ export function validateReference(ref, registry) {
35
+ const entry = registry.get(ref.framework);
36
+ if (!entry) {
37
+ return {
38
+ reference: ref,
39
+ status: 'unknown',
40
+ issue: {
41
+ type: 'unknown-framework',
42
+ framework: ref.framework,
43
+ reference: ref.text,
44
+ suggestion: `Framework '${ref.framework}' no encontrado en el registry`,
45
+ severity: 'warning',
46
+ },
47
+ };
48
+ }
49
+ // Check common mistakes first (highest priority — explicit errors)
50
+ const mistake = findMistake(ref.text, entry.commonMistakes);
51
+ if (mistake) {
52
+ const issue = {
53
+ type: 'invalid-api',
54
+ framework: ref.framework,
55
+ reference: ref.text,
56
+ suggestion: mistake.replacedBy ? `Usar en su lugar: ${mistake.replacedBy}` : mistake.pattern,
57
+ severity: mistake.severity ?? 'warning',
58
+ };
59
+ return { reference: ref, status: 'mistake', issue };
60
+ }
61
+ // Check deprecated patterns
62
+ const deprecated = findDeprecated(ref.text, entry.deprecatedPatterns);
63
+ if (deprecated) {
64
+ const issue = {
65
+ type: 'deprecated-pattern',
66
+ framework: ref.framework,
67
+ reference: ref.text,
68
+ suggestion: `Patron obsoleto. Reemplazar con: ${deprecated.replacedBy}`,
69
+ severity: deprecated.severity ?? 'warning',
70
+ };
71
+ return { reference: ref, status: 'deprecated', issue };
72
+ }
73
+ // Check correct patterns
74
+ if (findInPatterns(ref.text, entry.correctPatterns)) {
75
+ return { reference: ref, status: 'valid' };
76
+ }
77
+ // Not found in any pattern list — unknown but not an error
78
+ return { reference: ref, status: 'unknown' };
79
+ }
80
+ /**
81
+ * Validate all references and return the classification results.
82
+ * References for frameworks not in the registry are skipped (handled separately).
83
+ */
84
+ export function validateReferences(references, registry) {
85
+ return references.map((ref) => validateReference(ref, registry));
86
+ }
87
+ /**
88
+ * Detect registry entries that have not been updated in more than 180 days.
89
+ */
90
+ export function detectStaleEntries(registry) {
91
+ const now = Date.now();
92
+ const MS_PER_DAY = 86_400_000;
93
+ const STALE_DAYS = 180;
94
+ const stale = [];
95
+ for (const entry of registry.values()) {
96
+ const updated = new Date(entry.lastUpdated).getTime();
97
+ if (!isNaN(updated) && now - updated > STALE_DAYS * MS_PER_DAY) {
98
+ stale.push(entry.framework);
99
+ }
100
+ }
101
+ return stale;
102
+ }
103
+ //# sourceMappingURL=validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator.js","sourceRoot":"","sources":["../../../src/engine/registry/validator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { SpecChangelogEntry, SpecChangelogData, AppendChangelogOptions, ReadChangelogOptions } from '../../types/index.js';
2
+ /** Format a single changelog entry as Markdown. */
3
+ export declare function formatEntry(entry: SpecChangelogEntry, specId: string): string;
4
+ /** Parse the timestamp from the first entry in a CHANGELOG.md content. */
5
+ export declare function parseFirstEntryTimestamp(content: string): string | null;
6
+ /** Parse changelog entries from a CHANGELOG.md content string. */
7
+ export declare function parseChangelogEntries(content: string, specId: string): SpecChangelogEntry[];
8
+ /** Read the CHANGELOG.md for a spec directory. Returns null if not found. */
9
+ export declare function readChangelog(options: ReadChangelogOptions): Promise<SpecChangelogData | null>;
10
+ /** Read only the timestamp of the last (most recent) changelog entry. Optimized for list_specs. */
11
+ export declare function readLastModifiedTimestamp(specDir: string): Promise<string | null>;
12
+ /** Append a new entry to the CHANGELOG.md for a spec. Creates the file if it doesn't exist. */
13
+ export declare function appendChangelogEntry(options: AppendChangelogOptions): Promise<boolean>;
14
+ /** Format a relative date string (e.g. "hace 2 dias") for a timestamp. */
15
+ export declare function formatRelativeDate(timestamp: string): string;
16
+ //# sourceMappingURL=core.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../../src/engine/spec-changelog/core.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,kBAAkB,EAElB,iBAAiB,EACjB,sBAAsB,EACtB,oBAAoB,EACrB,MAAM,sBAAsB,CAAC;AAK9B,mDAAmD;AACnD,wBAAgB,WAAW,CAAC,KAAK,EAAE,kBAAkB,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAmD7E;AAQD,0EAA0E;AAC1E,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAIvE;AAED,kEAAkE;AAClE,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,kBAAkB,EAAE,CAqC3F;AAED,6EAA6E;AAC7E,wBAAsB,aAAa,CACjC,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAWnC;AAED,mGAAmG;AACnG,wBAAsB,yBAAyB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CASvF;AAED,+FAA+F;AAC/F,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,OAAO,CAAC,CAwC5F;AAED,0EAA0E;AAC1E,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAkB5D"}