@inharness-ai/claude4spec 1.0.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 (552) hide show
  1. package/.claude/skills/c4s-brief-implementer/SKILL.md +105 -0
  2. package/.claude/skills/c4s-spec-reader/SKILL.md +46 -0
  3. package/CHANGELOG.md +19 -0
  4. package/LICENSE +21 -0
  5. package/README.md +50 -0
  6. package/dist/bin/agent-md-template.d.ts +1 -0
  7. package/dist/bin/agent-md-template.js +76 -0
  8. package/dist/bin/agent-md-template.js.map +1 -0
  9. package/dist/bin/bootstrap-template.d.ts +1 -0
  10. package/dist/bin/bootstrap-template.js +12 -0
  11. package/dist/bin/bootstrap-template.js.map +1 -0
  12. package/dist/bin/c4s/args.d.ts +13 -0
  13. package/dist/bin/c4s/args.js +82 -0
  14. package/dist/bin/c4s/args.js.map +1 -0
  15. package/dist/bin/c4s/commands/_meta.d.ts +2 -0
  16. package/dist/bin/c4s/commands/_meta.js +13 -0
  17. package/dist/bin/c4s/commands/_meta.js.map +1 -0
  18. package/dist/bin/c4s/commands/catalog.d.ts +2 -0
  19. package/dist/bin/c4s/commands/catalog.js +38 -0
  20. package/dist/bin/c4s/commands/catalog.js.map +1 -0
  21. package/dist/bin/c4s/commands/detail.d.ts +2 -0
  22. package/dist/bin/c4s/commands/detail.js +22 -0
  23. package/dist/bin/c4s/commands/detail.js.map +1 -0
  24. package/dist/bin/c4s/commands/element-list.d.ts +2 -0
  25. package/dist/bin/c4s/commands/element-list.js +23 -0
  26. package/dist/bin/c4s/commands/element-list.js.map +1 -0
  27. package/dist/bin/c4s/commands/inline-mention.d.ts +2 -0
  28. package/dist/bin/c4s/commands/inline-mention.js +22 -0
  29. package/dist/bin/c4s/commands/inline-mention.js.map +1 -0
  30. package/dist/bin/c4s/commands/list-slugs.d.ts +2 -0
  31. package/dist/bin/c4s/commands/list-slugs.js +16 -0
  32. package/dist/bin/c4s/commands/list-slugs.js.map +1 -0
  33. package/dist/bin/c4s/commands/list-tags.d.ts +2 -0
  34. package/dist/bin/c4s/commands/list-tags.js +13 -0
  35. package/dist/bin/c4s/commands/list-tags.js.map +1 -0
  36. package/dist/bin/c4s/commands/resolve.d.ts +2 -0
  37. package/dist/bin/c4s/commands/resolve.js +40 -0
  38. package/dist/bin/c4s/commands/resolve.js.map +1 -0
  39. package/dist/bin/c4s/commands/section-ref.d.ts +2 -0
  40. package/dist/bin/c4s/commands/section-ref.js +25 -0
  41. package/dist/bin/c4s/commands/section-ref.js.map +1 -0
  42. package/dist/bin/c4s/commands/single-element.d.ts +2 -0
  43. package/dist/bin/c4s/commands/single-element.js +22 -0
  44. package/dist/bin/c4s/commands/single-element.js.map +1 -0
  45. package/dist/bin/c4s/commands/tagged-list-mixed.d.ts +2 -0
  46. package/dist/bin/c4s/commands/tagged-list-mixed.js +39 -0
  47. package/dist/bin/c4s/commands/tagged-list-mixed.js.map +1 -0
  48. package/dist/bin/c4s/commands/tagged-list.d.ts +2 -0
  49. package/dist/bin/c4s/commands/tagged-list.js +24 -0
  50. package/dist/bin/c4s/commands/tagged-list.js.map +1 -0
  51. package/dist/bin/c4s/context.d.ts +12 -0
  52. package/dist/bin/c4s/context.js +27 -0
  53. package/dist/bin/c4s/context.js.map +1 -0
  54. package/dist/bin/c4s/errors.d.ts +6 -0
  55. package/dist/bin/c4s/errors.js +11 -0
  56. package/dist/bin/c4s/errors.js.map +1 -0
  57. package/dist/bin/c4s/output.d.ts +4 -0
  58. package/dist/bin/c4s/output.js +57 -0
  59. package/dist/bin/c4s/output.js.map +1 -0
  60. package/dist/bin/c4s/project.d.ts +1 -0
  61. package/dist/bin/c4s/project.js +23 -0
  62. package/dist/bin/c4s/project.js.map +1 -0
  63. package/dist/bin/c4s/type-validation.d.ts +3 -0
  64. package/dist/bin/c4s/type-validation.js +11 -0
  65. package/dist/bin/c4s/type-validation.js.map +1 -0
  66. package/dist/bin/c4s-mcp.d.ts +2 -0
  67. package/dist/bin/c4s-mcp.js +118 -0
  68. package/dist/bin/c4s-mcp.js.map +1 -0
  69. package/dist/bin/c4s.d.ts +2 -0
  70. package/dist/bin/c4s.js +134 -0
  71. package/dist/bin/c4s.js.map +1 -0
  72. package/dist/bin/claude4spec.d.ts +2 -0
  73. package/dist/bin/claude4spec.js +132 -0
  74. package/dist/bin/claude4spec.js.map +1 -0
  75. package/dist/bin/gitignore.d.ts +1 -0
  76. package/dist/bin/gitignore.js +44 -0
  77. package/dist/bin/gitignore.js.map +1 -0
  78. package/dist/client/assets/arc-D8brDDag.js +1 -0
  79. package/dist/client/assets/architectureDiagram-3BPJPVTR-Bmh1uTQZ.js +36 -0
  80. package/dist/client/assets/blockDiagram-GPEHLZMM-55jaVWwd.js +132 -0
  81. package/dist/client/assets/c4Diagram-AAUBKEIU-Dxm0tLsZ.js +10 -0
  82. package/dist/client/assets/channel-ArVcv4Yl.js +1 -0
  83. package/dist/client/assets/chunk-2J33WTMH-vDJ1slcJ.js +1 -0
  84. package/dist/client/assets/chunk-4BX2VUAB-DP6CC-Qn.js +1 -0
  85. package/dist/client/assets/chunk-55IACEB6-SgOSJYkL.js +1 -0
  86. package/dist/client/assets/chunk-727SXJPM-BtRfbjBO.js +206 -0
  87. package/dist/client/assets/chunk-AQP2D5EJ-yIRaTgFg.js +231 -0
  88. package/dist/client/assets/chunk-FMBD7UC4-B_VD4t8N.js +15 -0
  89. package/dist/client/assets/chunk-ND2GUHAM-BvJdtX82.js +1 -0
  90. package/dist/client/assets/chunk-QZHKN3VN-BLNWKymD.js +1 -0
  91. package/dist/client/assets/classDiagram-4FO5ZUOK-B3nmPR7w.js +1 -0
  92. package/dist/client/assets/classDiagram-v2-Q7XG4LA2-B3nmPR7w.js +1 -0
  93. package/dist/client/assets/cose-bilkent-S5V4N54A-BQyA-r-y.js +1 -0
  94. package/dist/client/assets/cytoscape.esm-D_LviqZs.js +331 -0
  95. package/dist/client/assets/dagre-BM42HDAG-CAh0mTzA.js +4 -0
  96. package/dist/client/assets/defaultLocale-DX6XiGOO.js +1 -0
  97. package/dist/client/assets/diagram-2AECGRRQ-C83TGK4o.js +43 -0
  98. package/dist/client/assets/diagram-5GNKFQAL-2L6uowvf.js +10 -0
  99. package/dist/client/assets/diagram-KO2AKTUF-Cj5n4jdq.js +3 -0
  100. package/dist/client/assets/diagram-LMA3HP47-Bp5SDMjg.js +24 -0
  101. package/dist/client/assets/diagram-OG6HWLK6-cFsDQ8Qk.js +24 -0
  102. package/dist/client/assets/erDiagram-TEJ5UH35-D8G5xpg3.js +85 -0
  103. package/dist/client/assets/flowDiagram-I6XJVG4X-CuNudlCD.js +162 -0
  104. package/dist/client/assets/ganttDiagram-6RSMTGT7-CtFlsB15.js +292 -0
  105. package/dist/client/assets/gitGraphDiagram-PVQCEYII-h66Tso4O.js +106 -0
  106. package/dist/client/assets/graph-CAnANduQ.js +1 -0
  107. package/dist/client/assets/index-CZOpb3O7.css +1 -0
  108. package/dist/client/assets/index-D5ljIkCJ.js +727 -0
  109. package/dist/client/assets/index-aJE-l7h7.js +11 -0
  110. package/dist/client/assets/index-aPVup1Re.js +51 -0
  111. package/dist/client/assets/infoDiagram-5YYISTIA-CO_BLfuW.js +2 -0
  112. package/dist/client/assets/init-Gi6I4Gst.js +1 -0
  113. package/dist/client/assets/ishikawaDiagram-YF4QCWOH-D4rSRnQA.js +70 -0
  114. package/dist/client/assets/journeyDiagram-JHISSGLW-GyHI6dB8.js +139 -0
  115. package/dist/client/assets/kanban-definition-UN3LZRKU-CrH33WLe.js +89 -0
  116. package/dist/client/assets/katex-CQk2-UhE.js +257 -0
  117. package/dist/client/assets/layout-DGIYPm2g.js +1 -0
  118. package/dist/client/assets/linear-Dh1OyvSm.js +1 -0
  119. package/dist/client/assets/mermaid.core-C45sMDhS.js +309 -0
  120. package/dist/client/assets/mindmap-definition-RKZ34NQL-Bgwb0vwA.js +96 -0
  121. package/dist/client/assets/ordinal-Cboi1Yqb.js +1 -0
  122. package/dist/client/assets/pieDiagram-4H26LBE5-l9cCpVfG.js +30 -0
  123. package/dist/client/assets/quadrantDiagram-W4KKPZXB-BCPSUbC3.js +7 -0
  124. package/dist/client/assets/requirementDiagram-4Y6WPE33-TEGOe-vV.js +84 -0
  125. package/dist/client/assets/sankeyDiagram-5OEKKPKP-C69pv_7D.js +40 -0
  126. package/dist/client/assets/sequenceDiagram-3UESZ5HK-arinzeCk.js +162 -0
  127. package/dist/client/assets/stateDiagram-AJRCARHV-C2YENpmw.js +1 -0
  128. package/dist/client/assets/stateDiagram-v2-BHNVJYJU-CS6ocDH6.js +1 -0
  129. package/dist/client/assets/timeline-definition-PNZ67QCA-h5qtI99f.js +120 -0
  130. package/dist/client/assets/vennDiagram-CIIHVFJN-CnuK75Ut.js +34 -0
  131. package/dist/client/assets/wardley-L42UT6IY-B4bQ0Xyy.js +173 -0
  132. package/dist/client/assets/wardleyDiagram-YWT4CUSO-apV8olQc.js +78 -0
  133. package/dist/client/assets/xychartDiagram-2RQKCTM6-OTP6zeEy.js +7 -0
  134. package/dist/client/index.html +19 -0
  135. package/dist/server/config.d.ts +59 -0
  136. package/dist/server/config.js +211 -0
  137. package/dist/server/config.js.map +1 -0
  138. package/dist/server/core/plugin-host/cross-cutting.d.ts +8 -0
  139. package/dist/server/core/plugin-host/cross-cutting.js +14 -0
  140. package/dist/server/core/plugin-host/cross-cutting.js.map +1 -0
  141. package/dist/server/core/plugin-host/entities-router.d.ts +11 -0
  142. package/dist/server/core/plugin-host/entities-router.js +77 -0
  143. package/dist/server/core/plugin-host/entities-router.js.map +1 -0
  144. package/dist/server/core/plugin-host/host.d.ts +11 -0
  145. package/dist/server/core/plugin-host/host.js +128 -0
  146. package/dist/server/core/plugin-host/host.js.map +1 -0
  147. package/dist/server/core/plugin-host/legacy-adapter.d.ts +31 -0
  148. package/dist/server/core/plugin-host/legacy-adapter.js +88 -0
  149. package/dist/server/core/plugin-host/legacy-adapter.js.map +1 -0
  150. package/dist/server/core/plugin-host/serialization-engine.d.ts +35 -0
  151. package/dist/server/core/plugin-host/serialization-engine.js +132 -0
  152. package/dist/server/core/plugin-host/serialization-engine.js.map +1 -0
  153. package/dist/server/core/plugin-host/types.d.ts +143 -0
  154. package/dist/server/core/plugin-host/types.js +10 -0
  155. package/dist/server/core/plugin-host/types.js.map +1 -0
  156. package/dist/server/db/fixups/backfill-plan-titles.d.ts +2 -0
  157. package/dist/server/db/fixups/backfill-plan-titles.js +22 -0
  158. package/dist/server/db/fixups/backfill-plan-titles.js.map +1 -0
  159. package/dist/server/db/index.d.ts +6 -0
  160. package/dist/server/db/index.js +26 -0
  161. package/dist/server/db/index.js.map +1 -0
  162. package/dist/server/db/migrate.d.ts +2 -0
  163. package/dist/server/db/migrate.js +33 -0
  164. package/dist/server/db/migrate.js.map +1 -0
  165. package/dist/server/db/migrations/000_init.sql +7 -0
  166. package/dist/server/db/migrations/001_endpoint.sql +51 -0
  167. package/dist/server/db/migrations/002_dto.sql +23 -0
  168. package/dist/server/db/migrations/003_drop_endpoint_body.sql +5 -0
  169. package/dist/server/db/migrations/004_drop_module_and_status.sql +31 -0
  170. package/dist/server/db/migrations/005_chat.sql +23 -0
  171. package/dist/server/db/migrations/006_database_table.sql +10 -0
  172. package/dist/server/db/migrations/007_sections.sql +30 -0
  173. package/dist/server/db/migrations/008_subagent_task.sql +20 -0
  174. package/dist/server/db/migrations/009_chat_todo_snapshot.sql +4 -0
  175. package/dist/server/db/migrations/010_chat_plan_mode.sql +5 -0
  176. package/dist/server/db/migrations/011_chat_initial_system_prompt.sql +4 -0
  177. package/dist/server/db/migrations/012_chat_message_status.sql +5 -0
  178. package/dist/server/db/migrations/013_chat_usage_snapshot.sql +7 -0
  179. package/dist/server/db/migrations/014_plans.sql +33 -0
  180. package/dist/server/db/migrations/015_dto_examples.sql +4 -0
  181. package/dist/server/db/migrations/016_ui_view.sql +10 -0
  182. package/dist/server/db/migrations/017_entity_version_m17.sql +23 -0
  183. package/dist/server/db/migrations/018_page_version.sql +20 -0
  184. package/dist/server/db/migrations/019_spec_release.sql +13 -0
  185. package/dist/server/db/migrations/020_drop_plan_status.sql +10 -0
  186. package/dist/server/db/migrations/021_plans_n1.sql +36 -0
  187. package/dist/server/db/migrations/022_brief_chat_columns.sql +23 -0
  188. package/dist/server/db/migrations/023_page_version_kind.sql +26 -0
  189. package/dist/server/db/migrations/024_chat_context_size.sql +10 -0
  190. package/dist/server/db/migrations/025_ac.sql +19 -0
  191. package/dist/server/db/migrations/026_ac_seed.sql +75 -0
  192. package/dist/server/db/migrations/027_page_version_change_summary.sql +10 -0
  193. package/dist/server/db/readonly.d.ts +12 -0
  194. package/dist/server/db/readonly.js +32 -0
  195. package/dist/server/db/readonly.js.map +1 -0
  196. package/dist/server/domain/raw-entity-reader.d.ts +76 -0
  197. package/dist/server/domain/raw-entity-reader.js +240 -0
  198. package/dist/server/domain/raw-entity-reader.js.map +1 -0
  199. package/dist/server/entities/ac/mcp-server.d.ts +10 -0
  200. package/dist/server/entities/ac/mcp-server.js +154 -0
  201. package/dist/server/entities/ac/mcp-server.js.map +1 -0
  202. package/dist/server/entities/ac/plugin.d.ts +2 -0
  203. package/dist/server/entities/ac/plugin.js +33 -0
  204. package/dist/server/entities/ac/plugin.js.map +1 -0
  205. package/dist/server/entities/ac/routes.d.ts +4 -0
  206. package/dist/server/entities/ac/routes.js +92 -0
  207. package/dist/server/entities/ac/routes.js.map +1 -0
  208. package/dist/server/entities/ac/serializer.d.ts +13 -0
  209. package/dist/server/entities/ac/serializer.js +124 -0
  210. package/dist/server/entities/ac/serializer.js.map +1 -0
  211. package/dist/server/entities/ac/services.d.ts +35 -0
  212. package/dist/server/entities/ac/services.js +261 -0
  213. package/dist/server/entities/ac/services.js.map +1 -0
  214. package/dist/server/entities/ac/system-prompt.d.ts +2 -0
  215. package/dist/server/entities/ac/system-prompt.js +18 -0
  216. package/dist/server/entities/ac/system-prompt.js.map +1 -0
  217. package/dist/server/entities/database-table/mcp-server.d.ts +10 -0
  218. package/dist/server/entities/database-table/mcp-server.js +184 -0
  219. package/dist/server/entities/database-table/mcp-server.js.map +1 -0
  220. package/dist/server/entities/database-table/plugin.d.ts +2 -0
  221. package/dist/server/entities/database-table/plugin.js +33 -0
  222. package/dist/server/entities/database-table/plugin.js.map +1 -0
  223. package/dist/server/entities/database-table/routes.d.ts +5 -0
  224. package/dist/server/entities/database-table/routes.js +86 -0
  225. package/dist/server/entities/database-table/routes.js.map +1 -0
  226. package/dist/server/entities/database-table/serializer.d.ts +12 -0
  227. package/dist/server/entities/database-table/serializer.js +192 -0
  228. package/dist/server/entities/database-table/serializer.js.map +1 -0
  229. package/dist/server/entities/database-table/services.d.ts +45 -0
  230. package/dist/server/entities/database-table/services.js +323 -0
  231. package/dist/server/entities/database-table/services.js.map +1 -0
  232. package/dist/server/entities/database-table/system-prompt.d.ts +2 -0
  233. package/dist/server/entities/database-table/system-prompt.js +11 -0
  234. package/dist/server/entities/database-table/system-prompt.js.map +1 -0
  235. package/dist/server/entities/dto/mcp-server.d.ts +10 -0
  236. package/dist/server/entities/dto/mcp-server.js +141 -0
  237. package/dist/server/entities/dto/mcp-server.js.map +1 -0
  238. package/dist/server/entities/dto/plugin.d.ts +2 -0
  239. package/dist/server/entities/dto/plugin.js +33 -0
  240. package/dist/server/entities/dto/plugin.js.map +1 -0
  241. package/dist/server/entities/dto/routes.d.ts +4 -0
  242. package/dist/server/entities/dto/routes.js +74 -0
  243. package/dist/server/entities/dto/routes.js.map +1 -0
  244. package/dist/server/entities/dto/serializer.d.ts +12 -0
  245. package/dist/server/entities/dto/serializer.js +184 -0
  246. package/dist/server/entities/dto/serializer.js.map +1 -0
  247. package/dist/server/entities/dto/services.d.ts +30 -0
  248. package/dist/server/entities/dto/services.js +242 -0
  249. package/dist/server/entities/dto/services.js.map +1 -0
  250. package/dist/server/entities/dto/system-prompt.d.ts +2 -0
  251. package/dist/server/entities/dto/system-prompt.js +11 -0
  252. package/dist/server/entities/dto/system-prompt.js.map +1 -0
  253. package/dist/server/entities/endpoint/mcp-server.d.ts +10 -0
  254. package/dist/server/entities/endpoint/mcp-server.js +156 -0
  255. package/dist/server/entities/endpoint/mcp-server.js.map +1 -0
  256. package/dist/server/entities/endpoint/plugin.d.ts +2 -0
  257. package/dist/server/entities/endpoint/plugin.js +36 -0
  258. package/dist/server/entities/endpoint/plugin.js.map +1 -0
  259. package/dist/server/entities/endpoint/routes.d.ts +4 -0
  260. package/dist/server/entities/endpoint/routes.js +107 -0
  261. package/dist/server/entities/endpoint/routes.js.map +1 -0
  262. package/dist/server/entities/endpoint/serializer.d.ts +17 -0
  263. package/dist/server/entities/endpoint/serializer.js +217 -0
  264. package/dist/server/entities/endpoint/serializer.js.map +1 -0
  265. package/dist/server/entities/endpoint/services.d.ts +30 -0
  266. package/dist/server/entities/endpoint/services.js +260 -0
  267. package/dist/server/entities/endpoint/services.js.map +1 -0
  268. package/dist/server/entities/endpoint/system-prompt.d.ts +2 -0
  269. package/dist/server/entities/endpoint/system-prompt.js +11 -0
  270. package/dist/server/entities/endpoint/system-prompt.js.map +1 -0
  271. package/dist/server/entities/ui-view/mcp-server.d.ts +10 -0
  272. package/dist/server/entities/ui-view/mcp-server.js +161 -0
  273. package/dist/server/entities/ui-view/mcp-server.js.map +1 -0
  274. package/dist/server/entities/ui-view/plugin.d.ts +2 -0
  275. package/dist/server/entities/ui-view/plugin.js +33 -0
  276. package/dist/server/entities/ui-view/plugin.js.map +1 -0
  277. package/dist/server/entities/ui-view/routes.d.ts +5 -0
  278. package/dist/server/entities/ui-view/routes.js +82 -0
  279. package/dist/server/entities/ui-view/routes.js.map +1 -0
  280. package/dist/server/entities/ui-view/serializer.d.ts +12 -0
  281. package/dist/server/entities/ui-view/serializer.js +262 -0
  282. package/dist/server/entities/ui-view/serializer.js.map +1 -0
  283. package/dist/server/entities/ui-view/services.d.ts +35 -0
  284. package/dist/server/entities/ui-view/services.js +255 -0
  285. package/dist/server/entities/ui-view/services.js.map +1 -0
  286. package/dist/server/entities/ui-view/system-prompt.d.ts +7 -0
  287. package/dist/server/entities/ui-view/system-prompt.js +15 -0
  288. package/dist/server/entities/ui-view/system-prompt.js.map +1 -0
  289. package/dist/server/external-skills/brief-implementer-template.d.ts +2 -0
  290. package/dist/server/external-skills/brief-implementer-template.js +123 -0
  291. package/dist/server/external-skills/brief-implementer-template.js.map +1 -0
  292. package/dist/server/external-skills/external-skills-service.d.ts +3 -0
  293. package/dist/server/external-skills/external-skills-service.js +47 -0
  294. package/dist/server/external-skills/external-skills-service.js.map +1 -0
  295. package/dist/server/external-skills/spec-reader-template.d.ts +2 -0
  296. package/dist/server/external-skills/spec-reader-template.js +47 -0
  297. package/dist/server/external-skills/spec-reader-template.js.map +1 -0
  298. package/dist/server/fs/watcher.d.ts +26 -0
  299. package/dist/server/fs/watcher.js +64 -0
  300. package/dist/server/fs/watcher.js.map +1 -0
  301. package/dist/server/index.d.ts +18 -0
  302. package/dist/server/index.js +474 -0
  303. package/dist/server/index.js.map +1 -0
  304. package/dist/server/mcp/brief-tools.d.ts +19 -0
  305. package/dist/server/mcp/brief-tools.js +189 -0
  306. package/dist/server/mcp/brief-tools.js.map +1 -0
  307. package/dist/server/mcp/c4s-reader.d.ts +12 -0
  308. package/dist/server/mcp/c4s-reader.js +263 -0
  309. package/dist/server/mcp/c4s-reader.js.map +1 -0
  310. package/dist/server/mcp/database-tools.d.ts +10 -0
  311. package/dist/server/mcp/database-tools.js +184 -0
  312. package/dist/server/mcp/database-tools.js.map +1 -0
  313. package/dist/server/mcp/dependency-tools.d.ts +12 -0
  314. package/dist/server/mcp/dependency-tools.js +205 -0
  315. package/dist/server/mcp/dependency-tools.js.map +1 -0
  316. package/dist/server/mcp/dto-tools.d.ts +10 -0
  317. package/dist/server/mcp/dto-tools.js +141 -0
  318. package/dist/server/mcp/dto-tools.js.map +1 -0
  319. package/dist/server/mcp/endpoint-tools.d.ts +10 -0
  320. package/dist/server/mcp/endpoint-tools.js +156 -0
  321. package/dist/server/mcp/endpoint-tools.js.map +1 -0
  322. package/dist/server/mcp/ensure-mcp-json.d.ts +6 -0
  323. package/dist/server/mcp/ensure-mcp-json.js +30 -0
  324. package/dist/server/mcp/ensure-mcp-json.js.map +1 -0
  325. package/dist/server/mcp/index.d.ts +29 -0
  326. package/dist/server/mcp/index.js +40 -0
  327. package/dist/server/mcp/index.js.map +1 -0
  328. package/dist/server/mcp/plan-tools.d.ts +7 -0
  329. package/dist/server/mcp/plan-tools.js +105 -0
  330. package/dist/server/mcp/plan-tools.js.map +1 -0
  331. package/dist/server/mcp/reference-tools.d.ts +17 -0
  332. package/dist/server/mcp/reference-tools.js +630 -0
  333. package/dist/server/mcp/reference-tools.js.map +1 -0
  334. package/dist/server/mcp/release-tools/index.d.ts +21 -0
  335. package/dist/server/mcp/release-tools/index.js +140 -0
  336. package/dist/server/mcp/release-tools/index.js.map +1 -0
  337. package/dist/server/mcp/release-tools/projection.d.ts +32 -0
  338. package/dist/server/mcp/release-tools/projection.js +278 -0
  339. package/dist/server/mcp/release-tools/projection.js.map +1 -0
  340. package/dist/server/mcp/release-tools/types.d.ts +91 -0
  341. package/dist/server/mcp/release-tools/types.js +11 -0
  342. package/dist/server/mcp/release-tools/types.js.map +1 -0
  343. package/dist/server/mcp/release-tools.d.ts +14 -0
  344. package/dist/server/mcp/release-tools.js +83 -0
  345. package/dist/server/mcp/release-tools.js.map +1 -0
  346. package/dist/server/mcp/ui-view-tools.d.ts +10 -0
  347. package/dist/server/mcp/ui-view-tools.js +161 -0
  348. package/dist/server/mcp/ui-view-tools.js.map +1 -0
  349. package/dist/server/routes/briefs.d.ts +8 -0
  350. package/dist/server/routes/briefs.js +178 -0
  351. package/dist/server/routes/briefs.js.map +1 -0
  352. package/dist/server/routes/chat.d.ts +29 -0
  353. package/dist/server/routes/chat.js +604 -0
  354. package/dist/server/routes/chat.js.map +1 -0
  355. package/dist/server/routes/database-tables.d.ts +5 -0
  356. package/dist/server/routes/database-tables.js +86 -0
  357. package/dist/server/routes/database-tables.js.map +1 -0
  358. package/dist/server/routes/dependencies.d.ts +6 -0
  359. package/dist/server/routes/dependencies.js +164 -0
  360. package/dist/server/routes/dependencies.js.map +1 -0
  361. package/dist/server/routes/dtos.d.ts +4 -0
  362. package/dist/server/routes/dtos.js +74 -0
  363. package/dist/server/routes/dtos.js.map +1 -0
  364. package/dist/server/routes/endpoints.d.ts +4 -0
  365. package/dist/server/routes/endpoints.js +107 -0
  366. package/dist/server/routes/endpoints.js.map +1 -0
  367. package/dist/server/routes/entities.d.ts +8 -0
  368. package/dist/server/routes/entities.js +84 -0
  369. package/dist/server/routes/entities.js.map +1 -0
  370. package/dist/server/routes/errors.d.ts +2 -0
  371. package/dist/server/routes/errors.js +37 -0
  372. package/dist/server/routes/errors.js.map +1 -0
  373. package/dist/server/routes/page-links.d.ts +3 -0
  374. package/dist/server/routes/page-links.js +40 -0
  375. package/dist/server/routes/page-links.js.map +1 -0
  376. package/dist/server/routes/pages.d.ts +5 -0
  377. package/dist/server/routes/pages.js +142 -0
  378. package/dist/server/routes/pages.js.map +1 -0
  379. package/dist/server/routes/plans.d.ts +3 -0
  380. package/dist/server/routes/plans.js +192 -0
  381. package/dist/server/routes/plans.js.map +1 -0
  382. package/dist/server/routes/references.d.ts +3 -0
  383. package/dist/server/routes/references.js +34 -0
  384. package/dist/server/routes/references.js.map +1 -0
  385. package/dist/server/routes/releases.d.ts +4 -0
  386. package/dist/server/routes/releases.js +122 -0
  387. package/dist/server/routes/releases.js.map +1 -0
  388. package/dist/server/routes/sections.d.ts +3 -0
  389. package/dist/server/routes/sections.js +32 -0
  390. package/dist/server/routes/sections.js.map +1 -0
  391. package/dist/server/routes/tags.d.ts +4 -0
  392. package/dist/server/routes/tags.js +56 -0
  393. package/dist/server/routes/tags.js.map +1 -0
  394. package/dist/server/routes/threads.d.ts +3 -0
  395. package/dist/server/routes/threads.js +78 -0
  396. package/dist/server/routes/threads.js.map +1 -0
  397. package/dist/server/routes/todos.d.ts +3 -0
  398. package/dist/server/routes/todos.js +28 -0
  399. package/dist/server/routes/todos.js.map +1 -0
  400. package/dist/server/routes/ui-views.d.ts +5 -0
  401. package/dist/server/routes/ui-views.js +82 -0
  402. package/dist/server/routes/ui-views.js.map +1 -0
  403. package/dist/server/serialization/auto-schema.d.ts +3 -0
  404. package/dist/server/serialization/auto-schema.js +55 -0
  405. package/dist/server/serialization/auto-schema.js.map +1 -0
  406. package/dist/server/serialization/fallback.d.ts +4 -0
  407. package/dist/server/serialization/fallback.js +27 -0
  408. package/dist/server/serialization/fallback.js.map +1 -0
  409. package/dist/server/serialization/inline-renderer.d.ts +4 -0
  410. package/dist/server/serialization/inline-renderer.js +151 -0
  411. package/dist/server/serialization/inline-renderer.js.map +1 -0
  412. package/dist/server/serialization/registerAll.d.ts +6 -0
  413. package/dist/server/serialization/registerAll.js +7 -0
  414. package/dist/server/serialization/registerAll.js.map +1 -0
  415. package/dist/server/serialization/registry.d.ts +26 -0
  416. package/dist/server/serialization/registry.js +121 -0
  417. package/dist/server/serialization/registry.js.map +1 -0
  418. package/dist/server/serialization/resolve-page.d.ts +24 -0
  419. package/dist/server/serialization/resolve-page.js +192 -0
  420. package/dist/server/serialization/resolve-page.js.map +1 -0
  421. package/dist/server/serialization/serializers/database-table.d.ts +1 -0
  422. package/dist/server/serialization/serializers/database-table.js +46 -0
  423. package/dist/server/serialization/serializers/database-table.js.map +1 -0
  424. package/dist/server/serialization/serializers/dto.d.ts +1 -0
  425. package/dist/server/serialization/serializers/dto.js +48 -0
  426. package/dist/server/serialization/serializers/dto.js.map +1 -0
  427. package/dist/server/serialization/serializers/endpoint.d.ts +1 -0
  428. package/dist/server/serialization/serializers/endpoint.js +93 -0
  429. package/dist/server/serialization/serializers/endpoint.js.map +1 -0
  430. package/dist/server/serialization/serializers/section.d.ts +1 -0
  431. package/dist/server/serialization/serializers/section.js +24 -0
  432. package/dist/server/serialization/serializers/section.js.map +1 -0
  433. package/dist/server/serialization/serializers/ui-view.d.ts +1 -0
  434. package/dist/server/serialization/serializers/ui-view.js +124 -0
  435. package/dist/server/serialization/serializers/ui-view.js.map +1 -0
  436. package/dist/server/serialization/snapshot.d.ts +22 -0
  437. package/dist/server/serialization/snapshot.js +102 -0
  438. package/dist/server/serialization/snapshot.js.map +1 -0
  439. package/dist/server/serialization/types.d.ts +70 -0
  440. package/dist/server/serialization/types.js +7 -0
  441. package/dist/server/serialization/types.js.map +1 -0
  442. package/dist/server/serialization/writer.d.ts +41 -0
  443. package/dist/server/serialization/writer.js +13 -0
  444. package/dist/server/serialization/writer.js.map +1 -0
  445. package/dist/server/services/brief.d.ts +86 -0
  446. package/dist/server/services/brief.js +218 -0
  447. package/dist/server/services/brief.js.map +1 -0
  448. package/dist/server/services/chat-context.d.ts +26 -0
  449. package/dist/server/services/chat-context.js +434 -0
  450. package/dist/server/services/chat-context.js.map +1 -0
  451. package/dist/server/services/chat.d.ts +50 -0
  452. package/dist/server/services/chat.js +309 -0
  453. package/dist/server/services/chat.js.map +1 -0
  454. package/dist/server/services/database-table.d.ts +36 -0
  455. package/dist/server/services/database-table.js +303 -0
  456. package/dist/server/services/database-table.js.map +1 -0
  457. package/dist/server/services/dependencies.d.ts +45 -0
  458. package/dist/server/services/dependencies.js +302 -0
  459. package/dist/server/services/dependencies.js.map +1 -0
  460. package/dist/server/services/dto.d.ts +22 -0
  461. package/dist/server/services/dto.js +222 -0
  462. package/dist/server/services/dto.js.map +1 -0
  463. package/dist/server/services/endpoint.d.ts +22 -0
  464. package/dist/server/services/endpoint.js +239 -0
  465. package/dist/server/services/endpoint.js.map +1 -0
  466. package/dist/server/services/entity-writer.d.ts +46 -0
  467. package/dist/server/services/entity-writer.js +137 -0
  468. package/dist/server/services/entity-writer.js.map +1 -0
  469. package/dist/server/services/page-serializer.d.ts +109 -0
  470. package/dist/server/services/page-serializer.js +359 -0
  471. package/dist/server/services/page-serializer.js.map +1 -0
  472. package/dist/server/services/page-version.d.ts +75 -0
  473. package/dist/server/services/page-version.js +159 -0
  474. package/dist/server/services/page-version.js.map +1 -0
  475. package/dist/server/services/pages-frontmatter-indexer.d.ts +51 -0
  476. package/dist/server/services/pages-frontmatter-indexer.js +138 -0
  477. package/dist/server/services/pages-frontmatter-indexer.js.map +1 -0
  478. package/dist/server/services/pages-link-indexer.d.ts +36 -0
  479. package/dist/server/services/pages-link-indexer.js +474 -0
  480. package/dist/server/services/pages-link-indexer.js.map +1 -0
  481. package/dist/server/services/pages.d.ts +16 -0
  482. package/dist/server/services/pages.js +149 -0
  483. package/dist/server/services/pages.js.map +1 -0
  484. package/dist/server/services/plan.d.ts +59 -0
  485. package/dist/server/services/plan.js +459 -0
  486. package/dist/server/services/plan.js.map +1 -0
  487. package/dist/server/services/references.d.ts +17 -0
  488. package/dist/server/services/references.js +175 -0
  489. package/dist/server/services/references.js.map +1 -0
  490. package/dist/server/services/release.d.ts +146 -0
  491. package/dist/server/services/release.js +602 -0
  492. package/dist/server/services/release.js.map +1 -0
  493. package/dist/server/services/section-indexer.d.ts +20 -0
  494. package/dist/server/services/section-indexer.js +276 -0
  495. package/dist/server/services/section-indexer.js.map +1 -0
  496. package/dist/server/services/sections.d.ts +34 -0
  497. package/dist/server/services/sections.js +136 -0
  498. package/dist/server/services/sections.js.map +1 -0
  499. package/dist/server/services/skill-registry.d.ts +38 -0
  500. package/dist/server/services/skill-registry.js +171 -0
  501. package/dist/server/services/skill-registry.js.map +1 -0
  502. package/dist/server/services/slug.d.ts +7 -0
  503. package/dist/server/services/slug.js +41 -0
  504. package/dist/server/services/slug.js.map +1 -0
  505. package/dist/server/services/tags.d.ts +27 -0
  506. package/dist/server/services/tags.js +153 -0
  507. package/dist/server/services/tags.js.map +1 -0
  508. package/dist/server/services/todos-indexer.d.ts +21 -0
  509. package/dist/server/services/todos-indexer.js +123 -0
  510. package/dist/server/services/todos-indexer.js.map +1 -0
  511. package/dist/server/services/ui-view.d.ts +26 -0
  512. package/dist/server/services/ui-view.js +235 -0
  513. package/dist/server/services/ui-view.js.map +1 -0
  514. package/dist/server/services/versions.d.ts +59 -0
  515. package/dist/server/services/versions.js +181 -0
  516. package/dist/server/services/versions.js.map +1 -0
  517. package/dist/server/skills/brief-author/SKILL.md +117 -0
  518. package/dist/server/skills/layered-vertical-slices/SKILL.md +135 -0
  519. package/dist/server/skills/layered-vertical-slices/templates/index.md +97 -0
  520. package/dist/server/skills/layered-vertical-slices/templates/layer.md +42 -0
  521. package/dist/server/skills/layered-vertical-slices/templates/module.md +52 -0
  522. package/dist/server/skills/layered-vertical-slices/workflows/bootstrap.md +116 -0
  523. package/dist/server/skills/layered-vertical-slices/workflows/brief.md +154 -0
  524. package/dist/server/skills/layered-vertical-slices/workflows/daily.md +77 -0
  525. package/dist/server/ws/gateway.d.ts +10 -0
  526. package/dist/server/ws/gateway.js +35 -0
  527. package/dist/server/ws/gateway.js.map +1 -0
  528. package/dist/shared/anchor-pattern.d.ts +15 -0
  529. package/dist/shared/anchor-pattern.js +16 -0
  530. package/dist/shared/anchor-pattern.js.map +1 -0
  531. package/dist/shared/diagram-source-escape.d.ts +2 -0
  532. package/dist/shared/diagram-source-escape.js +19 -0
  533. package/dist/shared/diagram-source-escape.js.map +1 -0
  534. package/dist/shared/entities.d.ts +622 -0
  535. package/dist/shared/entities.js +9 -0
  536. package/dist/shared/entities.js.map +1 -0
  537. package/dist/shared/page-links.d.ts +40 -0
  538. package/dist/shared/page-links.js +2 -0
  539. package/dist/shared/page-links.js.map +1 -0
  540. package/dist/shared/plugin-host/types.d.ts +66 -0
  541. package/dist/shared/plugin-host/types.js +11 -0
  542. package/dist/shared/plugin-host/types.js.map +1 -0
  543. package/dist/shared/reference-extensions.d.ts +13 -0
  544. package/dist/shared/reference-extensions.js +17 -0
  545. package/dist/shared/reference-extensions.js.map +1 -0
  546. package/dist/shared/types.d.ts +86 -0
  547. package/dist/shared/types.js +2 -0
  548. package/dist/shared/types.js.map +1 -0
  549. package/dist/shared/xml-tags.d.ts +16 -0
  550. package/dist/shared/xml-tags.js +101 -0
  551. package/dist/shared/xml-tags.js.map +1 -0
  552. package/package.json +110 -0
@@ -0,0 +1,630 @@
1
+ import { createAdapter, createMcpServer, extractText, mcpTool } from '@inharness-ai/agent-adapters';
2
+ import { z } from 'zod';
3
+ import { DomainError } from '../services/tags.js';
4
+ import { pluginHost } from '../core/plugin-host/host.js';
5
+ import { RawEntityReader, isRawEntityType } from '../domain/raw-entity-reader.js';
6
+ import { parseXmlTags } from '../../shared/xml-tags.js';
7
+ import { listExtensionReferenceTypes } from '../../shared/reference-extensions.js';
8
+ import { readConfig } from '../config.js';
9
+ export function createReferenceToolsServer(deps) {
10
+ const ok = (payload) => ({
11
+ content: [{ type: 'text', text: JSON.stringify(payload) }],
12
+ });
13
+ const fail = (err) => {
14
+ const code = err instanceof DomainError ? err.code : 'INTERNAL';
15
+ const message = err instanceof Error ? err.message : String(err);
16
+ return {
17
+ content: [{ type: 'text', text: JSON.stringify({ error: message, code }) }],
18
+ isError: true,
19
+ };
20
+ };
21
+ // entityType is open-ended now — runtime validation against the host's
22
+ // available manifests, not a literal-union schema. Keeps the tool schema
23
+ // stable when plugins are added/removed.
24
+ const entityTypeSchema = z.string();
25
+ const validateActiveType = (type) => {
26
+ if (!pluginHost.getEntity(type)) {
27
+ const known = pluginHost.listAvailable().map((m) => m.type);
28
+ throw new DomainError('VALIDATION', `unsupported or inactive entity type '${type}'. Active: [${known.join(', ')}]`);
29
+ }
30
+ // Cast: EntityType is a literal union pinned to the four core plugins.
31
+ // Runtime validation is via pluginHost.getEntity(); the narrowing exists
32
+ // only to satisfy TagsService / ReferencesService signatures until
33
+ // EntityType is relaxed to `string` (Phase 4 follow-up).
34
+ return type;
35
+ };
36
+ const createTag = mcpTool('create_tag', 'Create a new tag for classifying entities.', {
37
+ name: z.string().describe('Display name'),
38
+ color: z.string().optional().describe('Hex color (e.g. #4A90D9)'),
39
+ description: z.string().optional(),
40
+ }, async (args) => {
41
+ try {
42
+ const tag = deps.tagsService.create({
43
+ name: String(args.name),
44
+ color: args.color,
45
+ description: args.description,
46
+ });
47
+ deps.ws.broadcast({ kind: 'tag:changed', slug: tag.slug });
48
+ return ok({ slug: tag.slug, name: tag.name });
49
+ }
50
+ catch (err) {
51
+ return fail(err);
52
+ }
53
+ });
54
+ const updateTag = mcpTool('update_tag', 'Update tag properties (name, color, description). If name changes, slug is regenerated and references in pages are updated.', {
55
+ slug: z.string(),
56
+ data: z.object({
57
+ name: z.string().optional(),
58
+ color: z.string().nullable().optional(),
59
+ description: z.string().nullable().optional(),
60
+ }),
61
+ }, async (args) => {
62
+ try {
63
+ const data = args.data;
64
+ const oldSlug = String(args.slug);
65
+ const tag = deps.tagsService.update(oldSlug, {
66
+ name: data.name,
67
+ color: data.color,
68
+ description: data.description,
69
+ });
70
+ if (tag.slug !== oldSlug) {
71
+ await deps.referencesService.propagateTagSlugChange(oldSlug, tag.slug);
72
+ }
73
+ deps.ws.broadcast({ kind: 'tag:changed', slug: tag.slug });
74
+ return ok({ slug: tag.slug, updated: true });
75
+ }
76
+ catch (err) {
77
+ return fail(err);
78
+ }
79
+ });
80
+ const deleteTag = mcpTool('delete_tag', 'Delete a tag. Removes all entity-tag assignments (CASCADE).', { slug: z.string() }, async (args) => {
81
+ try {
82
+ const result = deps.tagsService.remove(String(args.slug));
83
+ deps.ws.broadcast({ kind: 'tag:changed', slug: String(args.slug) });
84
+ return ok(result);
85
+ }
86
+ catch (err) {
87
+ return fail(err);
88
+ }
89
+ });
90
+ const listTags = mcpTool('list_tags', 'List all tags with usage counts (per active plugin entity type).', {}, async () => {
91
+ try {
92
+ const tags = deps.tagsService.list();
93
+ return ok({
94
+ tags: tags.map((t) => ({
95
+ slug: t.slug,
96
+ name: t.name,
97
+ color: t.color,
98
+ description: t.description,
99
+ counts: t.counts,
100
+ })),
101
+ });
102
+ }
103
+ catch (err) {
104
+ return fail(err);
105
+ }
106
+ });
107
+ const tagEntity = mcpTool('tag_entity', 'Add tags to an entity. Idempotent — already assigned tags are skipped. Creates tags if they do not exist. Replaces the entity tag set with the union of existing + new.', {
108
+ type: entityTypeSchema,
109
+ slug: z.string(),
110
+ tags: z.array(z.string()),
111
+ }, async (args) => {
112
+ try {
113
+ const type = validateActiveType(String(args.type));
114
+ const slug = String(args.slug);
115
+ const newTags = args.tags;
116
+ const id = pluginHost.resolveEntityId(type, slug);
117
+ if (!id)
118
+ throw new DomainError('NOT_FOUND', `${type} '${slug}' not found`);
119
+ const existing = deps.tagsService.getEntityTagSlugs(type, id);
120
+ const union = [...new Set([...existing, ...newTags])];
121
+ deps.tagsService.assignTags(type, id, union);
122
+ deps.ws.broadcast({ kind: 'entity:changed', entityType: type, slug });
123
+ return ok({ tagged: true, addedCount: union.length - existing.length });
124
+ }
125
+ catch (err) {
126
+ return fail(err);
127
+ }
128
+ });
129
+ const untagEntity = mcpTool('untag_entity', 'Remove tags from an entity.', {
130
+ type: entityTypeSchema,
131
+ slug: z.string(),
132
+ tags: z.array(z.string()),
133
+ }, async (args) => {
134
+ try {
135
+ const type = validateActiveType(String(args.type));
136
+ const slug = String(args.slug);
137
+ const toRemove = new Set(args.tags);
138
+ const id = pluginHost.resolveEntityId(type, slug);
139
+ if (!id)
140
+ throw new DomainError('NOT_FOUND', `${type} '${slug}' not found`);
141
+ const existing = deps.tagsService.getEntityTagSlugs(type, id);
142
+ const remaining = existing.filter((s) => !toRemove.has(s));
143
+ deps.tagsService.assignTags(type, id, remaining);
144
+ deps.ws.broadcast({ kind: 'entity:changed', entityType: type, slug });
145
+ return ok({ untagged: true, removedCount: existing.length - remaining.length });
146
+ }
147
+ catch (err) {
148
+ return fail(err);
149
+ }
150
+ });
151
+ const findReferences = mcpTool('find_references', 'Find all pages that reference a specific entity. Static refs match by (type, slug); when `includeTagMatches` is true, dynamic refs are also reported — pages with <tagged_list/> or <tagged_list_mixed/> whose `tags` attribute intersects the entity\'s tag set (rows include `via: string[]` listing matched tags). Use to understand where an entity is used before modifying or deleting it.', {
152
+ type: entityTypeSchema,
153
+ slug: z.string(),
154
+ includeTagMatches: z.boolean().optional(),
155
+ }, async (args) => {
156
+ try {
157
+ const type = validateActiveType(String(args.type));
158
+ const slug = String(args.slug);
159
+ const includeTagMatches = args.includeTagMatches === true;
160
+ const hits = await deps.referencesService.findReferences(type, slug);
161
+ const references = hits.map((h) => ({ pagePath: h.pagePath, tagType: h.tagType, line: h.line }));
162
+ if (includeTagMatches) {
163
+ const id = pluginHost.resolveEntityId(type, slug);
164
+ if (id) {
165
+ const entityTagSlugs = deps.tagsService.getEntityTagSlugs(type, id);
166
+ const entityTags = new Set(entityTagSlugs);
167
+ if (entityTags.size > 0) {
168
+ const tree = await deps.pagesService.listTree();
169
+ const pagePaths = [];
170
+ (function collect(nodes) {
171
+ for (const n of nodes) {
172
+ if (n.type === 'file')
173
+ pagePaths.push(n.path);
174
+ else if (n.children)
175
+ collect(n.children);
176
+ }
177
+ })(tree);
178
+ for (const p of pagePaths) {
179
+ const page = await deps.pagesService.read(p);
180
+ for (const tag of parseXmlTags(page.body)) {
181
+ if (tag.kind !== 'tagged_list' && tag.kind !== 'tagged_list_mixed')
182
+ continue;
183
+ if (tag.kind === 'tagged_list' && tag.attrs.type !== type)
184
+ continue;
185
+ const pageTags = (tag.attrs.tags ?? '')
186
+ .split(',')
187
+ .map((t) => t.trim())
188
+ .filter(Boolean);
189
+ const via = pageTags.filter((t) => entityTags.has(t));
190
+ if (via.length === 0)
191
+ continue;
192
+ references.push({
193
+ pagePath: p,
194
+ tagType: tag.kind,
195
+ line: tag.line,
196
+ via,
197
+ });
198
+ }
199
+ }
200
+ }
201
+ }
202
+ }
203
+ return ok({ references });
204
+ }
205
+ catch (err) {
206
+ return fail(err);
207
+ }
208
+ });
209
+ const checkConsistency = mcpTool('check_consistency', 'Run a full consistency check across pages, entities, and tags. Reports broken references in 3 categories (broken-reference / inactive-plugin / unknown-type), plus orphaned entity_tag rows, unreferenced entities, broken extension references (rule 8 — e.g. <section_ref/> with unknown anchor), broken AC verifies (rule 9 — always on when AC plugin active), entity-without-AC-coverage (rule 10 — config-flagged via config.consistency.requireAcCoverage), module-without-AC (rule 11 — config-flagged via config.consistency.requireModuleAc).', {}, async () => {
210
+ try {
211
+ // Build slug sets generically — iterate the host's available plugins and
212
+ // pull rows from SQLite via the shared RawEntityReader. Active vs.
213
+ // inactive distinction comes from `pluginHost.getEntity(type)`.
214
+ // Listed types stay in scope for unreferenced-entity reporting below.
215
+ const reader = new RawEntityReader(deps.db);
216
+ const slugSetsByType = {};
217
+ const referencedByType = {};
218
+ const entitiesByType = {};
219
+ for (const m of pluginHost.listEntities()) {
220
+ if (!isRawEntityType(m.type))
221
+ continue;
222
+ const slugs = reader.listSlugs(m.type);
223
+ entitiesByType[m.type] = slugs.map((s) => ({ slug: s }));
224
+ slugSetsByType[m.type] = new Set(slugs);
225
+ referencedByType[m.type] = new Set();
226
+ }
227
+ const tagSlugs = new Set(deps.tagsService.list().map((t) => t.slug));
228
+ const brokenReferences = [];
229
+ const invalidTagReferences = [];
230
+ const brokenExtensionReferences = [];
231
+ const tree = await deps.pagesService.listTree();
232
+ const pagePaths = [];
233
+ (function collect(nodes) {
234
+ for (const n of nodes) {
235
+ if (n.type === 'file')
236
+ pagePaths.push(n.path);
237
+ else if (n.children)
238
+ collect(n.children);
239
+ }
240
+ })(tree);
241
+ const categorise = (type) => {
242
+ if (pluginHost.getEntity(type))
243
+ return 'active';
244
+ if (pluginHost.getAvailable(type))
245
+ return 'inactive-plugin';
246
+ return 'unknown-type';
247
+ };
248
+ for (const p of pagePaths) {
249
+ const page = await deps.pagesService.read(p);
250
+ for (const tag of parseXmlTags(page.body)) {
251
+ const tagType = tag.attrs.type;
252
+ if (tag.kind !== 'tagged_list_mixed' && tagType) {
253
+ const cat = categorise(tagType);
254
+ const slugs = tag.kind === 'element_list'
255
+ ? (tag.attrs.slugs ?? '').split(',').map((s) => s.trim()).filter(Boolean)
256
+ : tag.attrs.slug
257
+ ? [tag.attrs.slug]
258
+ : [];
259
+ if (cat !== 'active') {
260
+ // Whole tag is broken because the type itself is not addressable.
261
+ for (const s of slugs) {
262
+ brokenReferences.push({
263
+ pagePath: p,
264
+ tagType: tag.kind,
265
+ type: tagType,
266
+ slug: s,
267
+ line: tag.line,
268
+ category: cat,
269
+ });
270
+ }
271
+ continue;
272
+ }
273
+ const set = slugSetsByType[tagType];
274
+ const referenced = referencedByType[tagType];
275
+ if (!set)
276
+ continue; // Active plugin but not raw-readable (shouldn't happen).
277
+ for (const s of slugs) {
278
+ if (set.has(s)) {
279
+ referenced?.add(s);
280
+ }
281
+ else {
282
+ brokenReferences.push({
283
+ pagePath: p,
284
+ tagType: tag.kind,
285
+ type: tagType,
286
+ slug: s,
287
+ line: tag.line,
288
+ category: 'broken-reference',
289
+ });
290
+ }
291
+ }
292
+ }
293
+ if (tag.kind === 'tagged_list' || tag.kind === 'tagged_list_mixed') {
294
+ for (const t of (tag.attrs.tags ?? '').split(',').map((x) => x.trim()).filter(Boolean)) {
295
+ if (!tagSlugs.has(t))
296
+ invalidTagReferences.push({ pagePath: p, tagType: tag.kind, tag: t, line: tag.line });
297
+ }
298
+ }
299
+ // Rule 8 — broken extension reference (e.g. <section_ref/> with unknown anchor).
300
+ // Validation is delegated to the slot owner via the registered `validate` callback;
301
+ // M19 does not know section_index. Owners surface a `category` like 'unknown-anchor'.
302
+ if (tag.source === 'extension') {
303
+ const ext = listExtensionReferenceTypes().find((e) => e.tag === tag.kind);
304
+ if (ext?.validate) {
305
+ const result = ext.validate(tag.attrs);
306
+ if (!result.ok) {
307
+ brokenExtensionReferences.push({
308
+ pagePath: p,
309
+ tagType: tag.kind,
310
+ attrs: tag.attrs,
311
+ line: tag.line,
312
+ category: result.category,
313
+ });
314
+ }
315
+ }
316
+ }
317
+ }
318
+ }
319
+ const unreferencedEntities = [];
320
+ for (const [type, list] of Object.entries(entitiesByType)) {
321
+ const referenced = referencedByType[type];
322
+ if (!referenced)
323
+ continue;
324
+ for (const e of list)
325
+ if (!referenced.has(e.slug))
326
+ unreferencedEntities.push({ type, slug: e.slug });
327
+ }
328
+ // Rules 9/10/11 — AC-specific. Silent skip when AC plugin is not active
329
+ // (host.getEntity('ac') === null) so projects without AC don't crash.
330
+ const brokenAcVerifies = [];
331
+ const entitiesWithoutAcCoverage = [];
332
+ const modulesWithoutAc = [];
333
+ const acActive = pluginHost.getEntity('ac');
334
+ if (acActive) {
335
+ const acService = pluginHost.getEntityService('ac');
336
+ const config = readConfig(deps.cwd);
337
+ const requireAcCoverage = config.consistency?.requireAcCoverage ?? 'off';
338
+ const requireModuleAc = config.consistency?.requireModuleAc ?? 'off';
339
+ if (acService) {
340
+ const activeAcs = acService.list({ status: 'active' });
341
+ // Rule 9 — broken AC verifies. AcService.classifyVerifies already
342
+ // categorises into missing|inactive|unknown via the plugin host.
343
+ for (const ac of activeAcs) {
344
+ const broken = acService.classifyVerifies(ac.verifies);
345
+ for (const b of broken) {
346
+ brokenAcVerifies.push({
347
+ acSlug: ac.slug,
348
+ verifyType: b.type,
349
+ verifySlug: b.slug,
350
+ category: b.reason,
351
+ });
352
+ }
353
+ }
354
+ // Rule 10 — entity-without-AC-coverage. Coverage = at least one AC
355
+ // either lists the entity in `verifies[]` or carries an `entity-{slug}` tag.
356
+ if (requireAcCoverage !== 'off') {
357
+ const coveredByVerifies = new Set();
358
+ const coveredByTag = new Set();
359
+ for (const ac of activeAcs) {
360
+ for (const v of ac.verifies) {
361
+ coveredByVerifies.add(`${v.type}:${v.slug}`);
362
+ }
363
+ for (const t of ac.tags) {
364
+ if (t.startsWith('entity-')) {
365
+ coveredByTag.add(t.slice('entity-'.length));
366
+ }
367
+ }
368
+ }
369
+ for (const [type, list] of Object.entries(entitiesByType)) {
370
+ if (type === 'ac')
371
+ continue;
372
+ for (const e of list) {
373
+ const key = `${type}:${e.slug}`;
374
+ if (coveredByVerifies.has(key))
375
+ continue;
376
+ if (coveredByTag.has(e.slug))
377
+ continue;
378
+ entitiesWithoutAcCoverage.push({
379
+ type,
380
+ slug: e.slug,
381
+ severity: requireAcCoverage,
382
+ });
383
+ }
384
+ }
385
+ }
386
+ // Rule 11 — module-without-AC. Module = `mNN` derived from a
387
+ // `modules/mNN-…\.md` page path. Coverage = AC carrying that mNN tag.
388
+ if (requireModuleAc !== 'off') {
389
+ const moduleRe = /modules\/(m\d{2})-[^/]+\.md$/;
390
+ const modules = new Set();
391
+ for (const p of pagePaths) {
392
+ const m = moduleRe.exec(p);
393
+ if (m && m[1])
394
+ modules.add(m[1]);
395
+ }
396
+ const taggedModules = new Set();
397
+ for (const ac of activeAcs) {
398
+ for (const t of ac.tags) {
399
+ if (/^m\d{2}$/.test(t))
400
+ taggedModules.add(t);
401
+ }
402
+ }
403
+ for (const mod of modules) {
404
+ if (!taggedModules.has(mod)) {
405
+ modulesWithoutAc.push({ module: mod, severity: requireModuleAc });
406
+ }
407
+ }
408
+ }
409
+ }
410
+ }
411
+ const acErrorRows = brokenAcVerifies.length +
412
+ entitiesWithoutAcCoverage.filter((e) => e.severity === 'error').length +
413
+ modulesWithoutAc.filter((m) => m.severity === 'error').length;
414
+ const acWarningRows = entitiesWithoutAcCoverage.filter((e) => e.severity === 'warn').length +
415
+ modulesWithoutAc.filter((m) => m.severity === 'warn').length;
416
+ const errors = brokenReferences.length +
417
+ invalidTagReferences.length +
418
+ brokenExtensionReferences.length +
419
+ acErrorRows;
420
+ const warnings = unreferencedEntities.length + acWarningRows;
421
+ const counts = brokenReferences.reduce((acc, r) => {
422
+ acc[r.category] = (acc[r.category] ?? 0) + 1;
423
+ return acc;
424
+ }, {});
425
+ const extensionCounts = brokenExtensionReferences.reduce((acc, r) => {
426
+ const key = `${r.tagType}:${r.category}`;
427
+ acc[key] = (acc[key] ?? 0) + 1;
428
+ return acc;
429
+ }, {});
430
+ const acVerifyCounts = brokenAcVerifies.reduce((acc, r) => {
431
+ acc[r.category] = (acc[r.category] ?? 0) + 1;
432
+ return acc;
433
+ }, {});
434
+ return ok({
435
+ brokenReferences,
436
+ brokenReferenceCounts: counts,
437
+ orphanedEntityTags: [],
438
+ unreferencedEntities,
439
+ invalidTagReferences,
440
+ brokenExtensionReferences,
441
+ brokenExtensionReferenceCounts: extensionCounts,
442
+ brokenAcVerifies,
443
+ brokenAcVerifyCounts: acVerifyCounts,
444
+ entitiesWithoutAcCoverage,
445
+ modulesWithoutAc,
446
+ summary: { total: errors + warnings, errors, warnings },
447
+ });
448
+ }
449
+ catch (err) {
450
+ return fail(err);
451
+ }
452
+ });
453
+ const analyzeAcAgainstEntities = mcpTool('analyze_ac_against_entities', 'LLM-based on-demand semantic check: for each active AC, load its `text` + `verifies[]` + the linked entity snapshots and ask the model whether the AC text matches the shape of those entities. Non-deterministic and expensive — call deliberately, not in a loop. Distinct from `check_consistency` (which is deterministic and structural). Output: { issues: [{ ac_slug, issue_type, details, affected_entity?, confidence, suggested_correction? }] }.', {
454
+ acSlug: z.string().optional().describe('Limit analysis to a single AC by slug. Omit to analyse all active ACs.'),
455
+ }, async (args) => {
456
+ try {
457
+ if (!pluginHost.getEntity('ac')) {
458
+ throw new DomainError('VALIDATION', 'ac plugin is not active in this project');
459
+ }
460
+ const acService = pluginHost.getEntityService('ac');
461
+ if (!acService)
462
+ throw new DomainError('INTERNAL', 'ac service not registered');
463
+ const filterSlug = args.acSlug ? String(args.acSlug) : undefined;
464
+ const allActive = acService.list({ status: 'active' });
465
+ const targets = filterSlug ? allActive.filter((a) => a.slug === filterSlug) : allActive;
466
+ if (targets.length === 0) {
467
+ return ok({ issues: [] });
468
+ }
469
+ const reader = new RawEntityReader(deps.db);
470
+ const dossier = targets.map((ac) => {
471
+ const linked = ac.verifies.map((v) => {
472
+ if (!isRawEntityType(v.type)) {
473
+ return { type: v.type, slug: v.slug, status: 'unknown-type' };
474
+ }
475
+ const entity = reader.getEntity(v.type, v.slug);
476
+ if (!entity) {
477
+ return { type: v.type, slug: v.slug, status: 'missing' };
478
+ }
479
+ return {
480
+ type: v.type,
481
+ slug: v.slug,
482
+ status: 'active',
483
+ data: entity.data,
484
+ };
485
+ });
486
+ return { slug: ac.slug, text: ac.text, kind: ac.kind, linked };
487
+ });
488
+ const prompt = [
489
+ 'You are a specification consistency auditor.',
490
+ '',
491
+ 'For each Acceptance Criterion (AC) below, decide whether its `text` is semantically consistent with the linked entities (their fields, params, shape).',
492
+ '',
493
+ 'Return ONLY a JSON object on a single line, no prose, matching:',
494
+ '{"issues":[{"ac_slug":string,"issue_type":string,"details":string,"affected_entity"?:{"type":string,"slug":string},"confidence":number,"suggested_correction"?:string}]}',
495
+ '',
496
+ 'Rules:',
497
+ '- If an AC has no issues, do not emit a row for it.',
498
+ '- `confidence` is between 0 and 1.',
499
+ '- `issue_type` is a short kebab-case label (e.g. "field-mismatch", "verb-mismatch", "missing-coverage", "stale-shape").',
500
+ '- Skip ACs whose linked entities are missing or unknown-type (those are caught by check_consistency rule 9).',
501
+ '',
502
+ 'Dossier:',
503
+ JSON.stringify(dossier),
504
+ ].join('\n');
505
+ const adapter = createAdapter('claude-code');
506
+ const stream = adapter.execute({
507
+ prompt,
508
+ systemPrompt: 'You output only a single JSON object on one line. No commentary, no code fences.',
509
+ model: 'sonnet-4.6',
510
+ cwd: deps.cwd,
511
+ maxTurns: 1,
512
+ });
513
+ const text = await extractText(stream);
514
+ const issues = parseIssuesJson(text);
515
+ return ok({ issues });
516
+ }
517
+ catch (err) {
518
+ return fail(err);
519
+ }
520
+ });
521
+ const listSections = mcpTool('list_sections', 'List sections from the section index. Filter by `anchor` (exact match), `query` (substring match on heading_text/heading_path), or `pagePath` (sections of a single page). Thin proxy over SectionsService — `section_index` is owned by M06.', {
522
+ anchor: z.string().optional(),
523
+ query: z.string().optional(),
524
+ pagePath: z.string().optional(),
525
+ limit: z.number().int().positive().max(2000).optional(),
526
+ }, async (args) => {
527
+ try {
528
+ const anchor = args.anchor ? String(args.anchor) : undefined;
529
+ if (anchor) {
530
+ const entry = deps.sectionsService.getByAnchor(anchor);
531
+ return ok({
532
+ sections: entry
533
+ ? [
534
+ {
535
+ anchor: entry.anchor,
536
+ pagePath: entry.pagePath,
537
+ headingText: entry.headingText,
538
+ headingPath: entry.headingPath,
539
+ headingLevel: entry.headingLevel,
540
+ lineStart: entry.lineStart,
541
+ lineEnd: entry.lineEnd,
542
+ },
543
+ ]
544
+ : [],
545
+ });
546
+ }
547
+ const entries = deps.sectionsService.list({
548
+ pagePath: args.pagePath ? String(args.pagePath) : undefined,
549
+ search: args.query ? String(args.query) : undefined,
550
+ limit: args.limit,
551
+ });
552
+ return ok({
553
+ sections: entries.map((e) => ({
554
+ anchor: e.anchor,
555
+ pagePath: e.pagePath,
556
+ headingText: e.headingText,
557
+ headingPath: e.headingPath,
558
+ headingLevel: e.headingLevel,
559
+ lineStart: e.lineStart,
560
+ lineEnd: e.lineEnd,
561
+ })),
562
+ });
563
+ }
564
+ catch (err) {
565
+ return fail(err);
566
+ }
567
+ });
568
+ return createMcpServer({
569
+ name: 'reference-tools',
570
+ tools: [
571
+ createTag,
572
+ updateTag,
573
+ deleteTag,
574
+ listTags,
575
+ tagEntity,
576
+ untagEntity,
577
+ findReferences,
578
+ checkConsistency,
579
+ analyzeAcAgainstEntities,
580
+ listSections,
581
+ ],
582
+ });
583
+ }
584
+ function parseIssuesJson(text) {
585
+ const start = text.indexOf('{');
586
+ const end = text.lastIndexOf('}');
587
+ if (start < 0 || end <= start)
588
+ return [];
589
+ const slice = text.slice(start, end + 1);
590
+ let parsed;
591
+ try {
592
+ parsed = JSON.parse(slice);
593
+ }
594
+ catch {
595
+ return [];
596
+ }
597
+ if (!parsed || typeof parsed !== 'object')
598
+ return [];
599
+ const rawIssues = parsed.issues;
600
+ if (!Array.isArray(rawIssues))
601
+ return [];
602
+ const out = [];
603
+ for (const raw of rawIssues) {
604
+ if (!raw || typeof raw !== 'object')
605
+ continue;
606
+ const r = raw;
607
+ if (typeof r.ac_slug !== 'string' || typeof r.issue_type !== 'string')
608
+ continue;
609
+ const details = typeof r.details === 'string' ? r.details : '';
610
+ const confidence = typeof r.confidence === 'number' ? r.confidence : 0;
611
+ const issue = {
612
+ ac_slug: r.ac_slug,
613
+ issue_type: r.issue_type,
614
+ details,
615
+ confidence,
616
+ };
617
+ if (r.affected_entity && typeof r.affected_entity === 'object') {
618
+ const ae = r.affected_entity;
619
+ if (typeof ae.type === 'string' && typeof ae.slug === 'string') {
620
+ issue.affected_entity = { type: ae.type, slug: ae.slug };
621
+ }
622
+ }
623
+ if (typeof r.suggested_correction === 'string') {
624
+ issue.suggested_correction = r.suggested_correction;
625
+ }
626
+ out.push(issue);
627
+ }
628
+ return out;
629
+ }
630
+ //# sourceMappingURL=reference-tools.js.map